{"id":27889989,"url":"https://github.com/nuew/ebooktool","last_synced_at":"2026-02-23T16:09:28.558Z","repository":{"id":288881653,"uuid":"969437701","full_name":"nuew/ebooktool","owner":"nuew","description":"Common files for ebook building","archived":false,"fork":false,"pushed_at":"2025-08-18T16:11:43.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-28T22:34:59.060Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PostScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nuew.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-20T06:24:09.000Z","updated_at":"2025-08-18T16:11:46.000Z","dependencies_parsed_at":"2025-05-05T10:42:53.972Z","dependency_job_id":"13755c35-4bfe-4146-a08b-095337e7564a","html_url":"https://github.com/nuew/ebooktool","commit_stats":null,"previous_names":["nuew/ebooktool"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nuew/ebooktool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuew%2Febooktool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuew%2Febooktool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuew%2Febooktool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuew%2Febooktool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nuew","download_url":"https://codeload.github.com/nuew/ebooktool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nuew%2Febooktool/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29747985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-23T07:44:07.782Z","status":"ssl_error","status_checked_at":"2026-02-23T07:44:07.432Z","response_time":90,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-05-05T10:42:49.590Z","updated_at":"2026-02-23T16:09:28.526Z","avatar_url":"https://github.com/nuew.png","language":"PostScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nuew's ebooktool\n\n## Requirements and Building\n\n[GNU Make], [Pandoc] and [TeX Live] must be installed and be located in your `$PATH`. This\nrepository is intended for, and has only been tested in the context of a Unix and/or [WSL]\nenvironment.\n\nTo build everything, simply run `make` in this directory. To build a single book or ebook, run\n`make $filename`, where `$filename` is the name of the target file. To build:\n- all covers, run `make covers`.\n- all EPUBs, run `make epub`\n- all PDFs, run `make pdf`\n- all DOCXs, run `make docx`\n- all ODTs, run `make odt`\n\nTo delete all generated files, run `make clean`.\n\n## Creating a Project\nTo create a project, create a git repository as follows:\n\n```sh\ngit init\ngit submodule add https://github.com/nuew/ebooktool\n```\n\nThen, create a Makefile in the directory as follows:\n```make\n# To add a book, add the name of the output files here, with a variable name matching the name of\n# the book's directory under chapters/. Then add that variable name to the `books` list below.\n\ncovers\t\t::=\nbooks\t\t::=\n\nEBOOKTOOL\t::= ebooktool\ninclude $(EBOOKTOOL)/ebooktool.mk\n```\n\n## Directory Structure\n\nThe book and ebook sources in your project should be arranged into several folders.\n\n| Filename  | Description                                                                                                           |\n|-----------|-----------------------------------------------------------------------------------------------------------------------|\n| .github/  | CI configuration.                                                                                                     |\n| back/     | The backmatter of the (e)book; included in alphanumeric order.                                                        |\n| chapters/ | Every chapter of each book. Books are in individual subfolders. Inserted in alphanumeric order.                       |\n| covers/   | Cover images for PDF, EPUB, and in original resolution, as well as PostScript source for the PDFs of physical covers. |\n| metadata/ | Metadata for each book. Separated into shared, PDF, and EPUB. There is also some global PDF metadata.                 |\n| style/    | CSS files for EPUBs. Each book can have an individual file, but most just use the global style.                       |\n\n## Adding a new book\nTo add a new book, first update the Makefile; you'll want to add a line to establish an association\nbetween the target name and the output file basename:\n\n```make\ntargetname\t::= OutputFileBasename\n```\n\nYou'll also need to add the new book's target name to the end of the `books` variable.\nIf the book has a PostScript cover wrap, you'll need to add it to the `covers` variable too.\n\n```make\ncovers\t\t::= foo bar mynewbook\nbooks\t\t::= foo bar baz qux mynewbook\n```\n\nFrom here, you need to add files to contain the book's metadata. These go under the `metadata`\nfolder, and should be two YAML files: `\u003ctarget\u003e.yaml` and `\u003ctarget\u003e.epub.yaml`. EPUBs have a\nsecond metadata file, which is combined with the primary one, as EPUB files have substantially\nricher metadata capabilities, in some cases requiring different values for certain fields. It's\nprobably easiest to copy an existing book's files, but be sure to replace the UUID identifier in the\nEPUB metadata file (it's used to identify a specific title) and the `group-position` value (it's\neasy to forget).\n\nThe EPUB cover and EPUB CSS files are discovered and added to metadata automatically. Their location\nmust match the patterns of `covers/\u003ctarget\u003e.epub.jpg` and `style/\u003ctarget\u003e.css`. As a matter of\nconvention, the highest quality cover should be stored at `covers/\u003ctarget\u003e.png` (in some cases, only\na JPEG image is available, in which case `covers/\u003ctarget\u003e.jpg` is acceptable), and a CSS file common\namong all EPUBs is located at `style/style.css`. The EPUB cover should have dimensions of\napproximately 2560x1600, with a filesize of about 600 kiB; `magick \u003ctarget\u003e.png -resize 1600x2560\n-quality 80 \u003ctarget\u003e.epub.jpg` is a good start for the command to produce such an image.\n\nIf you're using a PostScript cover wrap, it also goes into covers, as `covers/\u003ctarget\u003e.ps`. The\nraster cover image used for the PostScript cover wrap should be located at\n`covers/\u003ctarget\u003e.cover.jpg`, but this can reasonably be a symlink to `covers/\u003ctarget\u003e.jpg`. Note\nthat this is the only external file that the PostScript script will be allowed to read. The\n`PDFX_def.ps`, `conf.ps`, and `lib.ps` scripts from `covers/common` are injected into the cover wrap\ncompilation as libraries. In general, you probably shouldn't use this feature; it exists solely for\nlegacy reasons.\n\nNow that the book is set up, we can add the content. Create a directory under `chapters` with the\ntarget name (e.g. `chapters/mynewbook`), and create an individual markdown file in that directory\nfor each chapter. There are two helper scripts for this: `prepareDocx.sh` and `processRR.sh`, which\nare a complete script to convert a docx file into a chapter subdirectory without requiring much\nfurther processing, and a vague template to help give an idea of what to do with chapters scraped\nfrom Royal Road, respectively. Chapter files are inserted into the book in alphanumeric order; as a\nmatter of convention, they should be named matching the format `\u003cchapter number\u003e-\u003clowercase chapter\nname with '-'s instead of spaces\u003e.md`.\n\nThere are a few things in chapters that can only be manually processed; these include conversion of\nchat messages to div blocks for custom styling and postprocessing (implemented in\n`filters/chat.lua`), and conversion of baked small-caps to normal text styled by CSS (improving\nfull-text search/a11y in the ebook, and making things work at all in the PDF). Doing the first of\nthese automatically has been considered, but determining what is intended to be a chat message\nautomatically is hard™. Doing the second automatically is substantially easier; the only real\nconcern is that it isn't directly doable by `sed` (though it is by a Perl oneliner), and that\ndetermining the bounds for the span is *probably* best done manually. This is a feature to look out\nfor (or implement yourself), though!\n\n### Chat Message Conversion\nBefore:\n```markdown\n**\\[Alice\\]: The quick brown fox jumps over the lazy dog.**\n\n**\\[Bob\\]: Jackdaws love my big sphinx of quartz.**\n\n**\\[Charlie\\]: How quickly daft jumping zebras vex!**\n```\n\nAfter:\n```markdown\n::: {.chat .discord}\n[Alice]{.username .alice}\nThe quick brown fox jumps over the lazy dog.\n\n[Bob]{.username .bob}\nJackdaws love my big sphinx of quartz.\n\n[Charlie]{.username .charlie}\nHow quickly daft jumping zebras vex!\n```\n\n`style/style.css` has both `.discord` and `.twitch` classes, which approximate the appearance of\nchat messages on those platforms. In any case, this makes chat messages much more amenable to custom\nstyling, including individual colors for each user. Styling can also be used to avoid substantially\nchanging the appearance of chat messages at all, if desired by the author.\n\n### Small Caps Conversion\nVim:\n```vimscript\ndt\"\"='[' . tr(@@, 'ᴀʙᴄᴅᴇꜰғɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ', 'abcdeffghijklmnoprstuvwyz') . ']{.smallcaps}'\u003cCR\u003ep\n```\n\nPerl oneliner\n```bash\nperl -Mopen=locale -Mutf8 -pe 'y/ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ/abcdefghijklmnoprstuvwyz/'\n```\n\n[GNU Make]: https://www.gnu.org/software/make/\n[Pandoc]: https://pandoc.org/\n[WSL]: https://docs.microsoft.com/en-us/windows/wsl/about\n[TeX Live]: https://tug.org/texlive/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuew%2Febooktool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnuew%2Febooktool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnuew%2Febooktool/lists"}