{"id":15016484,"url":"https://github.com/marisademeglio/eleventypub","last_synced_at":"2025-04-12T09:30:53.394Z","repository":{"id":146210874,"uuid":"175758582","full_name":"marisademeglio/eleventypub","owner":"marisademeglio","description":"Create EPUBs with markdown or plain HTML (and more). Built on 11ty.","archived":false,"fork":false,"pushed_at":"2022-10-04T22:19:46.000Z","size":14481,"stargazers_count":83,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-26T04:34:24.012Z","etag":null,"topics":["11ty","a11y","accessibility","ebooks","eleventy","eprdctn","epub","static-site-generator"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marisademeglio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-15T06:01:44.000Z","updated_at":"2025-03-16T21:18:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"7d409d1a-0d87-436b-94e8-cb6e54aa2c08","html_url":"https://github.com/marisademeglio/eleventypub","commit_stats":{"total_commits":30,"total_committers":2,"mean_commits":15.0,"dds":0.1333333333333333,"last_synced_commit":"ff601fe281238e6d5a4a140df93934975fea96d3"},"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marisademeglio%2Feleventypub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marisademeglio%2Feleventypub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marisademeglio%2Feleventypub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marisademeglio%2Feleventypub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marisademeglio","download_url":"https://codeload.github.com/marisademeglio/eleventypub/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248545977,"owners_count":21122241,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["11ty","a11y","accessibility","ebooks","eleventy","eprdctn","epub","static-site-generator"],"created_at":"2024-09-24T19:48:58.370Z","updated_at":"2025-04-12T09:30:53.383Z","avatar_url":"https://github.com/marisademeglio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eleventypub\n\nCreate an EPUB by authoring your pages as simple [markdown](https://www.markdownguide.org/basic-syntax/) files and then letting a script do the rest. \n\n(Note that you could also use XHTML or templates -- see the [FAQ](#faq).)\n\nThis is an [11ty](https://11ty.io) project template, configured to build an [EPUB 3](https://w3c.github.io/publ-epub-revision/epub32/spec/epub-spec.html) fileset. It also validates with [EPUBCheck](https://github.com/w3c/epubcheck) and runs accessibility checks with [Ace](https://daisy.github.io/ace).\n\n## Quickstart\nMake sure you have already installed a reasonably recent version of [nodejs](https://nodejs.org). \n\nClone this repo and start editing:\n```\n$ mkdir my-epub-project \u0026\u0026 cd my-epub-project\n$ npx degit marisademeglio/eleventypub\n$ npm install\n```\n### Edit your files\nAll the files you will be editing are in the `src` directory.\n\n#### 1. Create your EPUB's pages as markdown files in `src/pages`.\n\nE.g. `page.md`:\n```\n---\ntitle: Chapter One\n---\n# Chapter One\n\n\"Laborum culpa mollit id,\" she thought. \"Do eu cillum eu magna? \nDolor voluptate laborum reprehenderit esse labore occaecat.\"\n\nConsectetur id ad sit excepteur commodo id pariatur ipsum voluptate \net do pariatur. Et id nisi enim veniam ea non in dolor. Elit eu \npariatur magna veniam consectetur sit deserunt excepteur.\n\n\"Hey! Non ullamco proident!\"\n```\n\n#### 2. Edit the metadata in `src/_data/metadata.json`.\n```\n{\n  \"dc\": {\n    \"title\": \"eleventypub-demo\",\n    \"creator\": \"Marisa DeMeglio\"\n  },\n  \"properties\": {\n    \"dcterms:modified\": \"2019-03-13T00:00:00Z\",\n    \"schema:accessibilityHazard\": \"none\",\n    \"schema:accessMode\": [\"textual\", \"visual\"]\n  }\n}\n```\n\n#### 3. Edit the values in `src/_data/pub.json`.\n\n* Specify the cover image `src` and `alt` properties (you can leave `page` as-is)\n* List pages in order in `src/pub.json` by listing the [file slugs](https://github.com/simov/slugify) (in their simplest form, these are the markdown filenames w/o  extensions). \n\n```\n{\n  \"cover\": {\n    \"page\": \"cover/index.xhtml\",\n    \"src\": \"resources/images/under-construction.jpg\",\n    \"alt\": \"Cartoon bear with construction tools\"\n  },\n  \"readingOrder\": [\n    \"intro\", \"chapter1\", \"end\"\n  ],\n  ...\n}\n```\n\n### Build your EPUB\nIn the terminal:\n\n    $ npm run all\n\nThe following output is created:\n\n1. `build/epub`: the expanded EPUB fileset\n2. `build/\u003ctitle\u003e.epub`: the EPUB file itself\n3. `build/report`: an [Ace](https://daisy.github.io/ace) report about accessibility\n\nYou will see any [EPUBCheck](https://github.com/w3c/epubcheck) validation issues in the terminal.\n\n## Advanced\n\nIf your page has scripting in it, add `scripted` to the block of front-matter data, e.g. \n```\n---\nscripted: true\ntitle: Chapter One\n---\n```\n\nto make sure it gets noted as such in the package document.\n\nIf your page template (e.g. `page.njk`) has scripting, you can put the `scripted` property there instead, in the same kind of block, e.g. \n\n```\n---\nscripted: true\n---\n{% extends 'base.njk' %}\n...\n```\n\nAlso note that the gulp plugin `gulp-pretty-data` that is automatically included as part of the `npm run all` build process does not like `CDATA`, often used in XHTML script blocks. So, you can just take it out of the command chain by editing `package.json` and removing `pretty-xml` from the list:\n\n```\n...\n\"all\": \"./node_modules/.bin/npm-run-all build save ace rename\",\n...\n```\n\n## Conventions\n\nThis part assumes you are familiar with [11ty](https://11ty.io). It discusses project structure and options.\n\nYou have as much freedom as you have with 11ty to mix and match templates and options. It's up to you to make sure the resulting output passes EPUB 3 validation.\n\nThis project uses the following fileset conventions:\n\n### `src/pages`\nChapter files live in this directory.\n\nIn the pages-wide configuration file, `pages.json`, it says, among other things:\n\n```\ntags: pages\n```\n\nDon't change this.\n\n### `src/index.md`\nThis becomes the package document. Don't touch this file.\n\n### `src/toc.md`\nTable of contents. The filename isn't special, just reference the output correctly from `pub.json` and use a TOC template (in this case, `toc.njk`).\n\n### `src/cover.md`\nCover. The filename isn't special, just reference the output correctly from `pub.json`.\n\n### `src/_data`\nThe data in this directory ends up in the package document.\n  - `metadata.json`: as many `dc` terms, `properties`, and `links` as you want. Use arrays for metadata properties that should appear more than once, e.g. \n  ```\n  \"schema:accessibilityFeature\": [\"alternativeText\", \"readingOrder\"]\n  ```\n  will create this in `package.opf`:\n  ```\n  \u003cmeta property=\"schema:accessibilityFeature\"\u003ealternativeText\u003c/meta\u003e\n  \u003cmeta property=\"schema:accessibilityFeature\"\u003ereadingOrder\u003c/meta\u003e      \n  ```\n  - `pub.json`: Says which files are the `toc` and `cover`, describes the cover image, and lists the `readingOrder`\n\n### `src/resources`\nThis directory is for fonts, CSS, images, etc; basically, anything you want listed in the manifest and copied over.\n\n### `_includes`\nThis directory is for all the layout templates, which create XHTML, OPF, and navigation documents. You can edit and replace these with your own, using any markup syntax supported by [11ty](https://11ty.io). If you use your own templates, it's up to you to make sure you're producing valid EPUB 3 output.\n\n## Scripts\n\n    $ npm run [something from the list below]\n\n- `all`: build, prettify, validate+save, and check accessibility\n- `all-no-stylelint`: same as the above, but without running stylelint on the CSS\n\nYou may want to run just a single step of the larger process, for which you can use these commands:\n\n- `build`: create the EPUB fileset in `build/epub`\n- `epubcheck`: run EPUBCheck on the output in `build/epub`\n- `save`: run EPUBCheck on `build/epub` and if valid, save an EPUB file as `build/\u003ctitle\u003e.epub`\n- `ace`: run the Ace accessibility checker on the files in `build/epub`. The report will be in `build/report`\n\n    \n## FAQ\n\n### Can I use other formats for my templates?\n\nYes absolutely! You can do whatever's possible with [11ty](https://11ty.io), which is a lot.\n\nThe templates in this project are nunjucks and markdown. The configuration I use for markdown includes having it [output XHTML](https://github.com/marisademeglio/eleventypub/blob/5af185071780aa650ea79939b671177e1db3591f/.eleventy.js#L22). Then, in the `postbuild` step, all `html` files are [renamed to `xhtml`](https://github.com/marisademeglio/eleventypub/blob/5af185071780aa650ea79939b671177e1db3591f/postbuild.js#L16). Even so, there are surely still ways to produce EPUB-invalid XHTML with this setup.\n\nSo, whatever you try, it's up to you to make sure that your output is valid.\n\n### What are the TOC options?\n\nReference your TOC file from `pub.json`. Use the name of the output file, e.g. `toc/index.html`, not the source `toc.md`.\n\n```\n{\n  \"cover\": {\n    \"page\": \"cover/index.xhtml\",\n    \"src\": \"resources/images/under-construction.jpg\",\n    \"alt\": \"Cartoon bear with construction tools\"\n  },\n  \"toc\": {\n    \"page\": \"toc/index.xhtml\"\n  },\n  \"readingOrder\": [\n    \"intro\", \"chapter1\", \"end\"\n  ]\n}\n```\n\nIn this basic example, the TOC is the file generated by [`src/toc.md`](https://github.com/marisademeglio/eleventypub/blob/master/src/toc.md). Because it is set to autogenerate (`auto: true`), the file is intentionally empty after the front matter data. It gets filled in by the automated process, which makes one entry per markdown file in `pages`.\n\nIf I wanted to write a TOC manually, I would write something like:\n\n```\n---\nlayout: toc.njk\ntitle: Table of contents\nEPUBRoot: \"..\"\nauto: false\n---\n1. [Introduction]({{EPUBRoot}}/pages/intro/index.html)\n1. [Chapter 1]({{EPUBRoot}}/pages/chapter1/index.html)\n1. [The end]({{EPUBRoot}}/pages/end/index.html)\n```\n\n`auto: true` the TOC will be autogenerated. Each chapter file will get an entry with its title, in a flat hierarchy.\n\n`auto: false`: you provide everything that's going to go between `\u003cnav\u003e` and `\u003c/nav\u003e` in your TOC file. It's up to you to make sure these contents are EPUB 3 compliant (e.g. a valid XHTML ordered list).\n\nIf you're providing your own TOC, triple-check the file references to make sure the relative path is correct (use `EPUBRoot` to help). Also, make sure you point to `xhtml` files, as that's what they'll be in the end, as a result of our `postbuild` step.\n\n### What are the reading order options?\n\nYou can add a `readingOrder` in `pub.json`. It's an array of [file slugs](https://github.com/simov/slugify) of the files in order. If `readingOrder` is not specified, a reading order gets generated automatically in alphabetical order based on what's in `pages/`.\n\nAll file slugs in a custom reading order have to be for files in `pages/`.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarisademeglio%2Feleventypub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarisademeglio%2Feleventypub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarisademeglio%2Feleventypub/lists"}