mdbindery 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mdbindery-0.1.0/CHANGELOG.md +16 -0
- mdbindery-0.1.0/LICENSE +21 -0
- mdbindery-0.1.0/MANIFEST.in +5 -0
- mdbindery-0.1.0/PKG-INFO +159 -0
- mdbindery-0.1.0/README.md +125 -0
- mdbindery-0.1.0/examples/sample-book/01-why-markdown.md +23 -0
- mdbindery-0.1.0/examples/sample-book/02-structure.md +33 -0
- mdbindery-0.1.0/examples/sample-book/03-publishing.md +22 -0
- mdbindery-0.1.0/examples/sample-book/LICENSE +5 -0
- mdbindery-0.1.0/examples/sample-book/README.md +22 -0
- mdbindery-0.1.0/examples/sample-book/appendix-a-checklist.md +12 -0
- mdbindery-0.1.0/examples/sample-book/images/cover.jpg +0 -0
- mdbindery-0.1.0/examples/sample-book/images/icon.png +0 -0
- mdbindery-0.1.0/examples/sample-book/images/night-desk.jpg +0 -0
- mdbindery-0.1.0/examples/sample-book/images/pipeline.png +0 -0
- mdbindery-0.1.0/examples/sample-book/mdbindery.yaml +37 -0
- mdbindery-0.1.0/pyproject.toml +55 -0
- mdbindery-0.1.0/setup.cfg +4 -0
- mdbindery-0.1.0/src/mdbindery/__init__.py +2 -0
- mdbindery-0.1.0/src/mdbindery/__main__.py +5 -0
- mdbindery-0.1.0/src/mdbindery/build.py +707 -0
- mdbindery-0.1.0/src/mdbindery/check.py +933 -0
- mdbindery-0.1.0/src/mdbindery/cli.py +286 -0
- mdbindery-0.1.0/src/mdbindery/config.py +740 -0
- mdbindery-0.1.0/src/mdbindery/cover.py +97 -0
- mdbindery-0.1.0/src/mdbindery/data/book.lua +852 -0
- mdbindery-0.1.0/src/mdbindery/data/epub.css +145 -0
- mdbindery-0.1.0/src/mdbindery/data/plaintext.lua +19 -0
- mdbindery-0.1.0/src/mdbindery/installer.py +354 -0
- mdbindery-0.1.0/src/mdbindery/markdown.py +479 -0
- mdbindery-0.1.0/src/mdbindery/preview.py +91 -0
- mdbindery-0.1.0/src/mdbindery/tools.py +249 -0
- mdbindery-0.1.0/src/mdbindery.egg-info/PKG-INFO +159 -0
- mdbindery-0.1.0/src/mdbindery.egg-info/SOURCES.txt +51 -0
- mdbindery-0.1.0/src/mdbindery.egg-info/dependency_links.txt +1 -0
- mdbindery-0.1.0/src/mdbindery.egg-info/entry_points.txt +2 -0
- mdbindery-0.1.0/src/mdbindery.egg-info/requires.txt +5 -0
- mdbindery-0.1.0/src/mdbindery.egg-info/top_level.txt +1 -0
- mdbindery-0.1.0/tests/ci_unicode_paths.py +20 -0
- mdbindery-0.1.0/tests/conftest.py +30 -0
- mdbindery-0.1.0/tests/fixtures/broken-book/01-intro.md +25 -0
- mdbindery-0.1.0/tests/fixtures/broken-book/02-body.md +10 -0
- mdbindery-0.1.0/tests/fixtures/broken-book/03-latin.md +3 -0
- mdbindery-0.1.0/tests/fixtures/broken-book/images/ok.png +0 -0
- mdbindery-0.1.0/tests/fixtures/broken-book/images/photo.bmp +0 -0
- mdbindery-0.1.0/tests/fixtures/broken-book/mdbindery.yaml +10 -0
- mdbindery-0.1.0/tests/fixtures/ru-book/01-nachalo.md +25 -0
- mdbindery-0.1.0/tests/fixtures/ru-book/02-materialy.md +13 -0
- mdbindery-0.1.0/tests/fixtures/ru-book/mdbindery.yaml +13 -0
- mdbindery-0.1.0/tests/test_check_build.py +136 -0
- mdbindery-0.1.0/tests/test_config.py +181 -0
- mdbindery-0.1.0/tests/test_markdown.py +133 -0
- mdbindery-0.1.0/tests/test_regressions.py +317 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-09-26)
|
|
4
|
+
|
|
5
|
+
First public release.
|
|
6
|
+
|
|
7
|
+
- `mdbindery build`: turns a folder or GitHub repository of Markdown chapters into an EPUB 3, one chapter per file. Supports links between files with GitHub anchors, numbered citations linked to a generated reference list, footnotes as numbered endnotes, figures and full-page images, a supplied or generated cover, Mermaid charts rendered to PNG, wide tables as cards, GitHub alerts, math as MathML, code highlighting, and GitHub-style HTML.
|
|
8
|
+
- Repairs for common repository layouts: a chapter title for files without a level-1 heading, content above the title moved below it, anchors moved out of headings, links to files outside the book pointed at `source_url` (or kept as text), `.html` links resolved to `.md` files, and image URLs of the same repository replaced by the local files.
|
|
9
|
+
- Reading order from `files:` in `mdbindery.yaml`, or inferred from a table of contents file, the README's links, or the file names (with front and back matter recognized).
|
|
10
|
+
- mdBook books: `book.toml`, `SUMMARY.md`, `{{#include}}` and related directives, and hidden lines in Rust code.
|
|
11
|
+
- Gates that fail the build: links, images, charts, includes, EPUBCheck, DAISY Ace, and a per-file word count that catches lost or duplicated text. Output is reproducible, and the EPUB carries accessibility metadata.
|
|
12
|
+
- `mdbindery check`: a dry run for a local folder, a GitHub URL, or another git URL, with a Markdown or JSON report (MB codes, file, line, and a fix for each finding), a suggested configuration, and an optional trial build.
|
|
13
|
+
- `mdbindery init`, `install-tools`, `doctor`, and `preview` (phone-size screenshots).
|
|
14
|
+
- Installers for Linux, macOS, and Windows that need nothing preinstalled and no admin rights. uv, pandoc, EPUBCheck, and Node.js downloads are pinned and checksum-verified.
|
|
15
|
+
- Packages on PyPI, a Homebrew tap (`sagol/tap`), and a GitHub Action (`uses: sagol/mdbindery@v0.1.0`) that installs mdbindery and its tools with caching.
|
|
16
|
+
- Agent skills for running mdbindery and for preparing a repository for it.
|
mdbindery-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Taras Baranyuk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mdbindery-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mdbindery
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Turn a folder or GitHub repository of Markdown chapters into a validated EPUB 3 ebook.
|
|
5
|
+
Author: Taras Baranyuk
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/sagol/mdbindery
|
|
8
|
+
Project-URL: Documentation, https://github.com/sagol/mdbindery/tree/main/docs
|
|
9
|
+
Project-URL: Changelog, https://github.com/sagol/mdbindery/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/sagol/mdbindery/issues
|
|
11
|
+
Keywords: epub,ebook,markdown,pandoc,publishing,book,epubcheck,mdbook
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
25
|
+
Classifier: Topic :: Printing
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: PyYAML>=6.0
|
|
30
|
+
Requires-Dist: Pillow>=9.0
|
|
31
|
+
Provides-Extra: test
|
|
32
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# mdbindery
|
|
36
|
+
|
|
37
|
+
Turn a folder or GitHub repository of Markdown chapters into a validated EPUB 3 ebook.
|
|
38
|
+
|
|
39
|
+
mdbindery is built for books written the GitHub way: one Markdown file per chapter, relative links between files, images in the repository, citations as `[1]` with reference definitions. The book stays readable on GitHub, and the EPUB passes EPUBCheck and the DAISY Ace accessibility check without hand editing.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
mdbindery check https://github.com/OWNER/REPO # what to fix, file by file and line by line
|
|
43
|
+
mdbindery build path/to/your-book # dist/<slug>.epub, validated
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## What it does
|
|
47
|
+
|
|
48
|
+
- Links between chapters, including links to headings in other files and custom `<a id>` anchors, become internal EPUB links. A link that has no target fails the build.
|
|
49
|
+
- Citations written as `[1]` with `[1]: url "Title"` definitions (invisible on GitHub) become visible numbered reference lists with working links.
|
|
50
|
+
- Images become inline icons, block images, figures with captions (the image title), or full-page images (`"full-page"` title). The cover can be any common image format, or mdbindery generates a typographic one. Missing and remote images fail the build.
|
|
51
|
+
- Mermaid charts become PNG images with alt text taken from the chart.
|
|
52
|
+
- Wide tables can become cards (one block per row), so they read on a phone.
|
|
53
|
+
- Footnotes become numbered endnotes; math becomes MathML; GitHub alerts, task lists, and code blocks (with monochrome highlighting) are supported.
|
|
54
|
+
- Raw HTML from GitHub READMEs (`<br>`, `<sup>`, `<img>`, `<p align>`, `<details>`, and more) becomes valid EPUB markup; tags with no EPUB equivalent are removed and reported.
|
|
55
|
+
- mdBook books work as they are: `book.toml` gives the metadata, `SUMMARY.md` the reading order, and `{{#include}}` directives are expanded.
|
|
56
|
+
- The book gets its title, subtitle, authors, language, rights, a permanent identifier, and schema.org accessibility metadata.
|
|
57
|
+
- Builds are reproducible: the same commit built twice with the same tools gives byte-identical files.
|
|
58
|
+
|
|
59
|
+
## Checking and validation
|
|
60
|
+
|
|
61
|
+
`mdbindery check` is a dry run on a local folder or a repository URL. It changes nothing and prints a Markdown report: every problem with its code, severity (error, warning, or note), file, line, and fix; the reading order and where it came from; and, for a book without one, a suggested `mdbindery.yaml`. `--build` adds a trial build with all the gates, and `--json FILE` writes the same report as JSON. The exit status is 0 when there are no errors, 1 when there are, and 2 when the target cannot be read.
|
|
62
|
+
|
|
63
|
+
`mdbindery build` writes the EPUB and then runs the gates: links, images, charts, mdBook includes, EPUBCheck, Ace, and a word count that catches text lost in conversion. If any gate fails, the build ends with `BUILD FAILED` and exit status 1; the EPUB is still written so you can inspect it. A missing Ace (after an install with `--no-node`) is a warning, not a failure.
|
|
64
|
+
|
|
65
|
+
## Supported inputs
|
|
66
|
+
|
|
67
|
+
- A folder of Markdown files, one per chapter. The reading order comes from `files:` in `mdbindery.yaml`, or else from a `SUMMARY.md` or other table-of-contents file, from the README's links when the chapter file names are not all numbered, or from the file names.
|
|
68
|
+
- A GitHub repository. `mdbindery check` accepts `https://github.com/OWNER/REPO`, `.../tree/BRANCH/FOLDER` for a book in a subfolder, and other git URLs. To build it, clone it and build the folder.
|
|
69
|
+
- An mdBook book, found by its `book.toml`.
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
|
|
73
|
+
Linux and macOS:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
curl -fsSL https://raw.githubusercontent.com/sagol/mdbindery/main/install/install.sh | bash
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Windows (PowerShell):
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
irm https://raw.githubusercontent.com/sagol/mdbindery/main/install/install.ps1 | iex
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The installer needs nothing preinstalled. It fetches [uv](https://github.com/astral-sh/uv), installs mdbindery in an isolated environment (with its own Python if needed), then downloads pandoc, EPUBCheck, a Java runtime if none is present, Node.js, mermaid-cli, and Ace into a per-user folder. pandoc, EPUBCheck, Node.js, and uv are pinned to exact versions and verified against SHA-256 checksums; the Java runtime comes from Eclipse Temurin's API with its published checksum; mermaid-cli and Ace are pinned by version. Nothing needs administrator rights, and nothing asks questions, so the same commands work in scripts and CI.
|
|
86
|
+
|
|
87
|
+
To pin a release, pass its tag: `curl -fsSL https://raw.githubusercontent.com/sagol/mdbindery/v0.1.0/install/install.sh | bash -s -- --ref v0.1.0`.
|
|
88
|
+
|
|
89
|
+
Other ways to install:
|
|
90
|
+
|
|
91
|
+
| Channel | Command |
|
|
92
|
+
|---|---|
|
|
93
|
+
| PyPI (pipx, uv, pip) | `pipx install mdbindery` or `uv tool install mdbindery`, then `mdbindery install-tools` |
|
|
94
|
+
| Homebrew (macOS, Linux) | `brew install sagol/tap/mdbindery`, then `mdbindery install-tools` |
|
|
95
|
+
| GitHub Actions | `- uses: sagol/mdbindery@v0.1.0`, then run `mdbindery` in later steps |
|
|
96
|
+
| Release files | wheel, source archive, and both installers on the [releases page](https://github.com/sagol/mdbindery/releases) |
|
|
97
|
+
|
|
98
|
+
In a workflow:
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
- uses: sagol/mdbindery@v0.1.0 # installs mdbindery and its tools, cached between runs
|
|
102
|
+
- run: mdbindery build path/to/book # exit 1 when a gate fails
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Details, options, manual installation, and uninstalling: [docs/installation.md](https://github.com/sagol/mdbindery/blob/main/docs/installation.md).
|
|
106
|
+
|
|
107
|
+
## Quick start
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
mdbindery doctor # which tools are installed and working
|
|
111
|
+
cd your-book
|
|
112
|
+
mdbindery init # write mdbindery.yaml from what it finds
|
|
113
|
+
mdbindery check . # fix what it reports
|
|
114
|
+
mdbindery build # dist/<slug>.epub and dist/reports/
|
|
115
|
+
mdbindery preview dist/<slug>.epub shots # phone-size screenshots
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
To try it on the sample book in this repository:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
git clone https://github.com/sagol/mdbindery
|
|
122
|
+
cd mdbindery/examples/sample-book
|
|
123
|
+
mdbindery check . --build
|
|
124
|
+
mdbindery build
|
|
125
|
+
mdbindery preview dist/writing-a-book-in-markdown.epub shots
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The full walk-through is in [docs/tutorial.md](https://github.com/sagol/mdbindery/blob/main/docs/tutorial.md).
|
|
129
|
+
|
|
130
|
+
## Requirements
|
|
131
|
+
|
|
132
|
+
- Linux (x64 or arm64, glibc-based), macOS (Intel or Apple silicon), or Windows 10/11 (x64 or arm64).
|
|
133
|
+
- About 1.5 GB of disk for the full tool set; mermaid-cli, Ace, and their two headless Chrome builds take most of it. With `--no-node` (no charts, no Ace, no `preview`), a whole install including uv and Python took about 370 MB. A downloaded Java runtime adds about 130 MB.
|
|
134
|
+
- An internet connection to install. Building works offline.
|
|
135
|
+
|
|
136
|
+
## Documentation
|
|
137
|
+
|
|
138
|
+
| Document | Contents |
|
|
139
|
+
|---|---|
|
|
140
|
+
| [Tutorial](https://github.com/sagol/mdbindery/blob/main/docs/tutorial.md) | From an existing repository to a validated EPUB, step by step |
|
|
141
|
+
| [Book structure rules](https://github.com/sagol/mdbindery/blob/main/docs/book-structure.md) | Files, headings, links, citations, images (cover, inline, figures, full-page), tables, charts |
|
|
142
|
+
| [Configuration](https://github.com/sagol/mdbindery/blob/main/docs/configuration.md) | Every `mdbindery.yaml` key |
|
|
143
|
+
| [Checking](https://github.com/sagol/mdbindery/blob/main/docs/checking.md) | `mdbindery check`, the report, and every check code with its fix |
|
|
144
|
+
| [Building](https://github.com/sagol/mdbindery/blob/main/docs/building.md) | The pipeline, outputs, gates, reproducibility, covers, preview, uploading to stores |
|
|
145
|
+
| [Installation](https://github.com/sagol/mdbindery/blob/main/docs/installation.md) | Linux, macOS, Windows, manual and offline setups, updating, uninstalling |
|
|
146
|
+
| [Troubleshooting](https://github.com/sagol/mdbindery/blob/main/docs/troubleshooting.md) | Common errors and what to do |
|
|
147
|
+
| [Design](https://github.com/sagol/mdbindery/blob/main/docs/design.md) | How it works inside, for contributors |
|
|
148
|
+
|
|
149
|
+
## For AI coding agents
|
|
150
|
+
|
|
151
|
+
[`skills/mdbindery-prepare-repo/SKILL.md`](https://github.com/sagol/mdbindery/blob/main/skills/mdbindery-prepare-repo/SKILL.md) teaches an LLM agent (Claude Code, Codex, Cursor, and similar) how to restructure a repository for mdbindery and loop on `mdbindery check` until it is clean. [`skills/mdbindery/SKILL.md`](https://github.com/sagol/mdbindery/blob/main/skills/mdbindery/SKILL.md) covers running the tool: installing, checking, building, previewing, and reading the reports. Both are plain Markdown and can be copied into any agent's skill or rules folder.
|
|
152
|
+
|
|
153
|
+
## Credits
|
|
154
|
+
|
|
155
|
+
mdbindery orchestrates [pandoc](https://pandoc.org), [EPUBCheck](https://www.w3.org/publishing/epubcheck/), [DAISY Ace](https://daisy.github.io/ace/), [mermaid-cli](https://github.com/mermaid-js/mermaid-cli), [Eclipse Temurin](https://adoptium.net), and [uv](https://github.com/astral-sh/uv). Each keeps its own license.
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT. See [LICENSE](https://github.com/sagol/mdbindery/blob/main/LICENSE).
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# mdbindery
|
|
2
|
+
|
|
3
|
+
Turn a folder or GitHub repository of Markdown chapters into a validated EPUB 3 ebook.
|
|
4
|
+
|
|
5
|
+
mdbindery is built for books written the GitHub way: one Markdown file per chapter, relative links between files, images in the repository, citations as `[1]` with reference definitions. The book stays readable on GitHub, and the EPUB passes EPUBCheck and the DAISY Ace accessibility check without hand editing.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
mdbindery check https://github.com/OWNER/REPO # what to fix, file by file and line by line
|
|
9
|
+
mdbindery build path/to/your-book # dist/<slug>.epub, validated
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- Links between chapters, including links to headings in other files and custom `<a id>` anchors, become internal EPUB links. A link that has no target fails the build.
|
|
15
|
+
- Citations written as `[1]` with `[1]: url "Title"` definitions (invisible on GitHub) become visible numbered reference lists with working links.
|
|
16
|
+
- Images become inline icons, block images, figures with captions (the image title), or full-page images (`"full-page"` title). The cover can be any common image format, or mdbindery generates a typographic one. Missing and remote images fail the build.
|
|
17
|
+
- Mermaid charts become PNG images with alt text taken from the chart.
|
|
18
|
+
- Wide tables can become cards (one block per row), so they read on a phone.
|
|
19
|
+
- Footnotes become numbered endnotes; math becomes MathML; GitHub alerts, task lists, and code blocks (with monochrome highlighting) are supported.
|
|
20
|
+
- Raw HTML from GitHub READMEs (`<br>`, `<sup>`, `<img>`, `<p align>`, `<details>`, and more) becomes valid EPUB markup; tags with no EPUB equivalent are removed and reported.
|
|
21
|
+
- mdBook books work as they are: `book.toml` gives the metadata, `SUMMARY.md` the reading order, and `{{#include}}` directives are expanded.
|
|
22
|
+
- The book gets its title, subtitle, authors, language, rights, a permanent identifier, and schema.org accessibility metadata.
|
|
23
|
+
- Builds are reproducible: the same commit built twice with the same tools gives byte-identical files.
|
|
24
|
+
|
|
25
|
+
## Checking and validation
|
|
26
|
+
|
|
27
|
+
`mdbindery check` is a dry run on a local folder or a repository URL. It changes nothing and prints a Markdown report: every problem with its code, severity (error, warning, or note), file, line, and fix; the reading order and where it came from; and, for a book without one, a suggested `mdbindery.yaml`. `--build` adds a trial build with all the gates, and `--json FILE` writes the same report as JSON. The exit status is 0 when there are no errors, 1 when there are, and 2 when the target cannot be read.
|
|
28
|
+
|
|
29
|
+
`mdbindery build` writes the EPUB and then runs the gates: links, images, charts, mdBook includes, EPUBCheck, Ace, and a word count that catches text lost in conversion. If any gate fails, the build ends with `BUILD FAILED` and exit status 1; the EPUB is still written so you can inspect it. A missing Ace (after an install with `--no-node`) is a warning, not a failure.
|
|
30
|
+
|
|
31
|
+
## Supported inputs
|
|
32
|
+
|
|
33
|
+
- A folder of Markdown files, one per chapter. The reading order comes from `files:` in `mdbindery.yaml`, or else from a `SUMMARY.md` or other table-of-contents file, from the README's links when the chapter file names are not all numbered, or from the file names.
|
|
34
|
+
- A GitHub repository. `mdbindery check` accepts `https://github.com/OWNER/REPO`, `.../tree/BRANCH/FOLDER` for a book in a subfolder, and other git URLs. To build it, clone it and build the folder.
|
|
35
|
+
- An mdBook book, found by its `book.toml`.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
Linux and macOS:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
curl -fsSL https://raw.githubusercontent.com/sagol/mdbindery/main/install/install.sh | bash
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Windows (PowerShell):
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
irm https://raw.githubusercontent.com/sagol/mdbindery/main/install/install.ps1 | iex
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The installer needs nothing preinstalled. It fetches [uv](https://github.com/astral-sh/uv), installs mdbindery in an isolated environment (with its own Python if needed), then downloads pandoc, EPUBCheck, a Java runtime if none is present, Node.js, mermaid-cli, and Ace into a per-user folder. pandoc, EPUBCheck, Node.js, and uv are pinned to exact versions and verified against SHA-256 checksums; the Java runtime comes from Eclipse Temurin's API with its published checksum; mermaid-cli and Ace are pinned by version. Nothing needs administrator rights, and nothing asks questions, so the same commands work in scripts and CI.
|
|
52
|
+
|
|
53
|
+
To pin a release, pass its tag: `curl -fsSL https://raw.githubusercontent.com/sagol/mdbindery/v0.1.0/install/install.sh | bash -s -- --ref v0.1.0`.
|
|
54
|
+
|
|
55
|
+
Other ways to install:
|
|
56
|
+
|
|
57
|
+
| Channel | Command |
|
|
58
|
+
|---|---|
|
|
59
|
+
| PyPI (pipx, uv, pip) | `pipx install mdbindery` or `uv tool install mdbindery`, then `mdbindery install-tools` |
|
|
60
|
+
| Homebrew (macOS, Linux) | `brew install sagol/tap/mdbindery`, then `mdbindery install-tools` |
|
|
61
|
+
| GitHub Actions | `- uses: sagol/mdbindery@v0.1.0`, then run `mdbindery` in later steps |
|
|
62
|
+
| Release files | wheel, source archive, and both installers on the [releases page](https://github.com/sagol/mdbindery/releases) |
|
|
63
|
+
|
|
64
|
+
In a workflow:
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
- uses: sagol/mdbindery@v0.1.0 # installs mdbindery and its tools, cached between runs
|
|
68
|
+
- run: mdbindery build path/to/book # exit 1 when a gate fails
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Details, options, manual installation, and uninstalling: [docs/installation.md](https://github.com/sagol/mdbindery/blob/main/docs/installation.md).
|
|
72
|
+
|
|
73
|
+
## Quick start
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
mdbindery doctor # which tools are installed and working
|
|
77
|
+
cd your-book
|
|
78
|
+
mdbindery init # write mdbindery.yaml from what it finds
|
|
79
|
+
mdbindery check . # fix what it reports
|
|
80
|
+
mdbindery build # dist/<slug>.epub and dist/reports/
|
|
81
|
+
mdbindery preview dist/<slug>.epub shots # phone-size screenshots
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
To try it on the sample book in this repository:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
git clone https://github.com/sagol/mdbindery
|
|
88
|
+
cd mdbindery/examples/sample-book
|
|
89
|
+
mdbindery check . --build
|
|
90
|
+
mdbindery build
|
|
91
|
+
mdbindery preview dist/writing-a-book-in-markdown.epub shots
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The full walk-through is in [docs/tutorial.md](https://github.com/sagol/mdbindery/blob/main/docs/tutorial.md).
|
|
95
|
+
|
|
96
|
+
## Requirements
|
|
97
|
+
|
|
98
|
+
- Linux (x64 or arm64, glibc-based), macOS (Intel or Apple silicon), or Windows 10/11 (x64 or arm64).
|
|
99
|
+
- About 1.5 GB of disk for the full tool set; mermaid-cli, Ace, and their two headless Chrome builds take most of it. With `--no-node` (no charts, no Ace, no `preview`), a whole install including uv and Python took about 370 MB. A downloaded Java runtime adds about 130 MB.
|
|
100
|
+
- An internet connection to install. Building works offline.
|
|
101
|
+
|
|
102
|
+
## Documentation
|
|
103
|
+
|
|
104
|
+
| Document | Contents |
|
|
105
|
+
|---|---|
|
|
106
|
+
| [Tutorial](https://github.com/sagol/mdbindery/blob/main/docs/tutorial.md) | From an existing repository to a validated EPUB, step by step |
|
|
107
|
+
| [Book structure rules](https://github.com/sagol/mdbindery/blob/main/docs/book-structure.md) | Files, headings, links, citations, images (cover, inline, figures, full-page), tables, charts |
|
|
108
|
+
| [Configuration](https://github.com/sagol/mdbindery/blob/main/docs/configuration.md) | Every `mdbindery.yaml` key |
|
|
109
|
+
| [Checking](https://github.com/sagol/mdbindery/blob/main/docs/checking.md) | `mdbindery check`, the report, and every check code with its fix |
|
|
110
|
+
| [Building](https://github.com/sagol/mdbindery/blob/main/docs/building.md) | The pipeline, outputs, gates, reproducibility, covers, preview, uploading to stores |
|
|
111
|
+
| [Installation](https://github.com/sagol/mdbindery/blob/main/docs/installation.md) | Linux, macOS, Windows, manual and offline setups, updating, uninstalling |
|
|
112
|
+
| [Troubleshooting](https://github.com/sagol/mdbindery/blob/main/docs/troubleshooting.md) | Common errors and what to do |
|
|
113
|
+
| [Design](https://github.com/sagol/mdbindery/blob/main/docs/design.md) | How it works inside, for contributors |
|
|
114
|
+
|
|
115
|
+
## For AI coding agents
|
|
116
|
+
|
|
117
|
+
[`skills/mdbindery-prepare-repo/SKILL.md`](https://github.com/sagol/mdbindery/blob/main/skills/mdbindery-prepare-repo/SKILL.md) teaches an LLM agent (Claude Code, Codex, Cursor, and similar) how to restructure a repository for mdbindery and loop on `mdbindery check` until it is clean. [`skills/mdbindery/SKILL.md`](https://github.com/sagol/mdbindery/blob/main/skills/mdbindery/SKILL.md) covers running the tool: installing, checking, building, previewing, and reading the reports. Both are plain Markdown and can be copied into any agent's skill or rules folder.
|
|
118
|
+
|
|
119
|
+
## Credits
|
|
120
|
+
|
|
121
|
+
mdbindery orchestrates [pandoc](https://pandoc.org), [EPUBCheck](https://www.w3.org/publishing/epubcheck/), [DAISY Ace](https://daisy.github.io/ace/), [mermaid-cli](https://github.com/mermaid-js/mermaid-cli), [Eclipse Temurin](https://adoptium.net), and [uv](https://github.com/astral-sh/uv). Each keeps its own license.
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT. See [LICENSE](https://github.com/sagol/mdbindery/blob/main/LICENSE).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 1. Why Markdown
|
|
2
|
+
|
|
3
|
+
*Scenario, a kitchen table, 2031.* The draft lives in a folder of plain text files. Nothing about it depends on one program.
|
|
4
|
+
|
|
5
|
+
Markdown keeps a manuscript readable as plain text and renders cleanly on GitHub [1]. Pandoc can turn the same files into an EPUB 3 publication [2], the format most ebook stores accept.
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
> This paragraph is a GitHub alert. In the EPUB it becomes a tinted box with a "Note" label.
|
|
9
|
+
|
|
10
|
+
## Plain text lasts
|
|
11
|
+
|
|
12
|
+
A text file written today will open in fifty years.[^durable] The icon  sits inline with this sentence, and its alt text describes it for screen readers.
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
The image above has a title in its Markdown source, so it becomes a figure with a caption. [Chapter 2](02-structure.md#tables-and-code) shows the other building blocks.
|
|
17
|
+
|
|
18
|
+
## References
|
|
19
|
+
|
|
20
|
+
[1]: https://github.github.com/gfm/ "GitHub, GitHub Flavored Markdown Spec, version 0.29-gfm"
|
|
21
|
+
[2]: https://pandoc.org/MANUAL.html "John MacFarlane, Pandoc User's Guide"
|
|
22
|
+
|
|
23
|
+
[^durable]: Plain UTF-8 text is the most durable format a writer can choose.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# 2. Structure
|
|
2
|
+
|
|
3
|
+
Every chapter file starts with one level-1 heading. Sections use `##`, subsections `###`, and levels are never skipped.
|
|
4
|
+
|
|
5
|
+
## Tables and code
|
|
6
|
+
|
|
7
|
+
| Element | Markdown | EPUB result |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Table | pipes and dashes | an HTML table |
|
|
10
|
+
| Code | three backticks | a preformatted block |
|
|
11
|
+
| Math | `$...$` | MathML |
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
def greet(name):
|
|
15
|
+
return f"Hello, {name}"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The area of a circle is $A = \pi r^2$.
|
|
19
|
+
|
|
20
|
+
## A chart
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
flowchart LR
|
|
24
|
+
A[Draft] --> B[Check] --> C[Build] --> D[Publish]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## A full-page image
|
|
28
|
+
|
|
29
|
+
The next image fills its own page in the EPUB, because its title starts with `full-page`.
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
Back to [chapter 1](01-why-markdown.md), or on to [publishing](03-publishing.md).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# 3. Publishing
|
|
2
|
+
|
|
3
|
+
Links between chapters use relative file paths, exactly as on GitHub. This one goes to [the plain-text section](01-why-markdown.md#plain-text-lasts), and this one to the [checklist](appendix-a-checklist.md#a1-before-you-build).
|
|
4
|
+
|
|
5
|
+
## Inline HTML
|
|
6
|
+
|
|
7
|
+
A few HTML tags are converted: press <kbd>Ctrl</kbd>+<kbd>S</kbd>, write H<sub>2</sub>O and E = mc<sup>2</sup>,<br>or break a line.
|
|
8
|
+
|
|
9
|
+
## A task list
|
|
10
|
+
|
|
11
|
+
- [x] Write the chapters
|
|
12
|
+
- [x] Add the images
|
|
13
|
+
- [ ] Run `mdbindery check`
|
|
14
|
+
- [ ] Build the EPUB
|
|
15
|
+
|
|
16
|
+
## Publishing checklist
|
|
17
|
+
|
|
18
|
+
Validation matters because ebook stores reject files that fail EPUBCheck [1].
|
|
19
|
+
|
|
20
|
+
## References
|
|
21
|
+
|
|
22
|
+
[1]: https://www.w3.org/publishing/epubcheck/ "W3C, EPUBCheck"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Writing a Book in Markdown
|
|
2
|
+
|
|
3
|
+
*A small sample book that shows every feature mdbindery supports.*
|
|
4
|
+
|
|
5
|
+
This repository is a complete book. Read it on GitHub as Markdown, or build it into an EPUB with `mdbindery build`. Each chapter demonstrates one part of the structure rules, so you can copy what you need.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
| Chapter | What it shows |
|
|
10
|
+
|---|---|
|
|
11
|
+
| [1. Why Markdown](01-why-markdown.md) | Citations, footnotes, alerts, inline images, figures |
|
|
12
|
+
| [2. Structure](02-structure.md) | Headings, tables, code, math, a Mermaid chart, a full-page image |
|
|
13
|
+
| [3. Publishing](03-publishing.md) | Links between chapters, inline HTML, task lists |
|
|
14
|
+
| [Appendix A. Checklist](appendix-a-checklist.md) | A wide table rendered as cards |
|
|
15
|
+
|
|
16
|
+
## Contributing
|
|
17
|
+
|
|
18
|
+
Pull requests are welcome. This section is for GitHub readers only; the book's config drops it from the EPUB.
|
|
19
|
+
|
|
20
|
+
## License
|
|
21
|
+
|
|
22
|
+
Text and images are licensed under [CC BY 4.0](LICENSE).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Appendix A. Checklist
|
|
2
|
+
|
|
3
|
+
The table below has ten columns. On a phone that is unreadable, so the book's config renders it as cards: one block per row.
|
|
4
|
+
|
|
5
|
+
## A1. Before you build
|
|
6
|
+
|
|
7
|
+
| ID | Item | Where | Rule | Tool | Severity | Owner | Status | Notes | Link |
|
|
8
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
9
|
+
| C1 | One level-1 heading per file | Every chapter | Structure | check | Warning | Author | Done | First line of the file | [chapter 2](02-structure.md) |
|
|
10
|
+
| C2 | Images have alt text | Every image | Accessibility | check, Ace | Warning | Author | Done | Describe what it shows | [chapter 1](01-why-markdown.md) |
|
|
11
|
+
| C3 | Links resolve | Whole book | Navigation | check, build | Error | Editor | Done | Relative paths only | [chapter 3](03-publishing.md) |
|
|
12
|
+
| C4 | Cover is 1600x2560 | images/cover.jpg | Stores | check | Warning | Designer | Done | JPEG, RGB | [README](README.md) |
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# mdbindery configuration for the sample book
|
|
2
|
+
slug: writing-a-book-in-markdown
|
|
3
|
+
output_dir: dist
|
|
4
|
+
source_url: https://github.com/sagol/mdbindery/blob/main/examples/sample-book/
|
|
5
|
+
|
|
6
|
+
metadata:
|
|
7
|
+
title: Writing a Book in Markdown
|
|
8
|
+
subtitle: A small sample book for mdbindery
|
|
9
|
+
authors: [Sample Author]
|
|
10
|
+
lang: en-US
|
|
11
|
+
identifier: urn:uuid:5f0f1c2e-8a4b-4d6e-9c1a-3b7e2d9f0a11
|
|
12
|
+
date: 2026-09-26
|
|
13
|
+
rights: Text and images licensed under CC BY 4.0
|
|
14
|
+
description: A short book that demonstrates every feature of mdbindery.
|
|
15
|
+
subjects: [Markdown, EPUB, Publishing]
|
|
16
|
+
|
|
17
|
+
cover:
|
|
18
|
+
image: images/cover.jpg
|
|
19
|
+
|
|
20
|
+
files:
|
|
21
|
+
- file: README.md
|
|
22
|
+
role: front
|
|
23
|
+
title: About this book
|
|
24
|
+
drop_sections: [Contributing]
|
|
25
|
+
- 01-why-markdown.md
|
|
26
|
+
- 02-structure.md
|
|
27
|
+
- 03-publishing.md
|
|
28
|
+
- file: appendix-a-checklist.md
|
|
29
|
+
role: appendix
|
|
30
|
+
|
|
31
|
+
options:
|
|
32
|
+
citations: refdefs
|
|
33
|
+
toc_depth: 2
|
|
34
|
+
cards:
|
|
35
|
+
files: [appendix-a-checklist.md]
|
|
36
|
+
min_columns: 9
|
|
37
|
+
title_columns: 2
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mdbindery"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Turn a folder or GitHub repository of Markdown chapters into a validated EPUB 3 ebook."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
authors = [{ name = "Taras Baranyuk" }]
|
|
14
|
+
keywords = ["epub", "ebook", "markdown", "pandoc", "publishing", "book", "epubcheck", "mdbook"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: End Users/Desktop",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Topic :: Text Processing :: Markup :: Markdown",
|
|
29
|
+
"Topic :: Printing",
|
|
30
|
+
]
|
|
31
|
+
dependencies = ["PyYAML>=6.0", "Pillow>=9.0"]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
test = ["pytest>=7"]
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
mdbindery = "mdbindery.cli:main"
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/sagol/mdbindery"
|
|
41
|
+
Documentation = "https://github.com/sagol/mdbindery/tree/main/docs"
|
|
42
|
+
Changelog = "https://github.com/sagol/mdbindery/blob/main/CHANGELOG.md"
|
|
43
|
+
Issues = "https://github.com/sagol/mdbindery/issues"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.dynamic]
|
|
46
|
+
version = { attr = "mdbindery.__version__" }
|
|
47
|
+
|
|
48
|
+
[tool.setuptools.packages.find]
|
|
49
|
+
where = ["src"]
|
|
50
|
+
|
|
51
|
+
[tool.setuptools.package-data]
|
|
52
|
+
mdbindery = ["data/*"]
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
testpaths = ["tests"]
|