markpublish 1.0.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.
- markpublish-1.0.0/LICENSE +22 -0
- markpublish-1.0.0/PKG-INFO +339 -0
- markpublish-1.0.0/README.md +291 -0
- markpublish-1.0.0/pyproject.toml +104 -0
- markpublish-1.0.0/setup.cfg +4 -0
- markpublish-1.0.0/src/markpublish/__init__.py +6 -0
- markpublish-1.0.0/src/markpublish/cli.py +759 -0
- markpublish-1.0.0/src/markpublish/config/loader.py +68 -0
- markpublish-1.0.0/src/markpublish/config/models.py +469 -0
- markpublish-1.0.0/src/markpublish/data/fonts.conf +68 -0
- markpublish-1.0.0/src/markpublish/docs/cheatsheet/de/01_config.md +66 -0
- markpublish-1.0.0/src/markpublish/docs/cheatsheet/de/02_templates.md +44 -0
- markpublish-1.0.0/src/markpublish/docs/cheatsheet/de/markpublish.yaml +32 -0
- markpublish-1.0.0/src/markpublish/docs/cheatsheet/en/01_config.md +66 -0
- markpublish-1.0.0/src/markpublish/docs/cheatsheet/en/02_templates.md +43 -0
- markpublish-1.0.0/src/markpublish/docs/cheatsheet/en/markpublish.yaml +29 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/01_introduction.md +24 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/02_quickstart.md +81 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/03_cli_reference.md +165 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/04_configuration_guide.md +95 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/05_template_system.md +350 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/06_markdown_features.md +59 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/07_appendix_yaml_spec.md +209 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/chapters/08_appendix_troubleshooting.md +12 -0
- markpublish-1.0.0/src/markpublish/docs/manual/de/markpublish.yaml +77 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/01_introduction.md +23 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/02_quickstart.md +74 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/03_cli_reference.md +135 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/04_configuration_guide.md +94 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/05_template_system.md +305 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/06_markdown_features.md +61 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/07_appendix_yaml_spec.md +177 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/chapters/08_appendix_troubleshooting.md +12 -0
- markpublish-1.0.0/src/markpublish/docs/manual/en/markpublish.yaml +76 -0
- markpublish-1.0.0/src/markpublish/i18n.py +518 -0
- markpublish-1.0.0/src/markpublish/i18n.yaml +73 -0
- markpublish-1.0.0/src/markpublish/markdown/__init__.py +4 -0
- markpublish-1.0.0/src/markpublish/markdown/alerts.py +106 -0
- markpublish-1.0.0/src/markpublish/markdown/assets.py +93 -0
- markpublish-1.0.0/src/markpublish/markdown/engine.py +453 -0
- markpublish-1.0.0/src/markpublish/markdown/toc.py +228 -0
- markpublish-1.0.0/src/markpublish/renderers/__init__.py +4 -0
- markpublish-1.0.0/src/markpublish/renderers/base.py +159 -0
- markpublish-1.0.0/src/markpublish/renderers/html.py +25 -0
- markpublish-1.0.0/src/markpublish/renderers/pdf.py +139 -0
- markpublish-1.0.0/src/markpublish/templates/__init__.py +4 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/assets/icons/caution.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/assets/icons/checkbox-check.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/assets/icons/important.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/assets/icons/note.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/assets/icons/tip.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/assets/icons/warning.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/chapter_divider.html +30 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/cover.html +33 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/fonts/OFL.txt +93 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/fonts/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/fonts/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/i18n.yaml +23 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/layout.html +116 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/part_divider.html +10 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/styles.css +547 -0
- markpublish-1.0.0/src/markpublish/templates/default/html/toc.html +26 -0
- markpublish-1.0.0/src/markpublish/templates/default/i18n.yaml +40 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/assets/icons/caution.svg +4 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/assets/icons/checkbox-check.svg +3 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/assets/icons/important.svg +4 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/assets/icons/note.svg +4 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/assets/icons/tip.svg +4 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/assets/icons/warning.svg +4 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/chapter_divider.html +33 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/cover.html +51 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/fonts/OFL.txt +93 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/fonts/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/fonts/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/i18n.yaml +22 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/layout.html +108 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/part_divider.html +31 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/styles.css +805 -0
- markpublish-1.0.0/src/markpublish/templates/default/pdf/toc.html +37 -0
- markpublish-1.0.0/src/markpublish/templates/resolver.py +184 -0
- markpublish-1.0.0/src/markpublish.egg-info/PKG-INFO +339 -0
- markpublish-1.0.0/src/markpublish.egg-info/SOURCES.txt +97 -0
- markpublish-1.0.0/src/markpublish.egg-info/dependency_links.txt +1 -0
- markpublish-1.0.0/src/markpublish.egg-info/entry_points.txt +3 -0
- markpublish-1.0.0/src/markpublish.egg-info/requires.txt +19 -0
- markpublish-1.0.0/src/markpublish.egg-info/top_level.txt +1 -0
- markpublish-1.0.0/tests/test_cli.py +298 -0
- markpublish-1.0.0/tests/test_config.py +166 -0
- markpublish-1.0.0/tests/test_fontconfig.py +72 -0
- markpublish-1.0.0/tests/test_header_footer.py +392 -0
- markpublish-1.0.0/tests/test_i18n.py +292 -0
- markpublish-1.0.0/tests/test_i18n_cascade.py +568 -0
- markpublish-1.0.0/tests/test_markdown.py +117 -0
- markpublish-1.0.0/tests/test_packaging.py +102 -0
- markpublish-1.0.0/tests/test_regressions.py +355 -0
- markpublish-1.0.0/tests/test_renderers.py +280 -0
- markpublish-1.0.0/tests/test_templates.py +67 -0
- markpublish-1.0.0/tests/test_theme_layout.py +472 -0
- markpublish-1.0.0/tests/test_toc.py +727 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Frank Winter
|
|
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.
|
|
22
|
+
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: markpublish
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Modern, modular, and extensible Markdown-to-PDF/HTML publishing tool powered by WeasyPrint
|
|
5
|
+
Author-email: Frank Winter <studio@frankwinter.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/fwdotcom/markpublish
|
|
8
|
+
Project-URL: Documentation, https://github.com/fwdotcom/markpublish#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/fwdotcom/markpublish.git
|
|
10
|
+
Project-URL: Issues, https://github.com/fwdotcom/markpublish/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/fwdotcom/markpublish/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: markdown,pdf,html,weasyprint,publishing,converter,cli
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Information Technology
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
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: Programming Language :: Python :: 3.14
|
|
25
|
+
Classifier: Topic :: Documentation
|
|
26
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
27
|
+
Classifier: Topic :: Printing
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: weasyprint>=60.0
|
|
32
|
+
Requires-Dist: jinja2>=3.1.0
|
|
33
|
+
Requires-Dist: markdown>=3.5.0
|
|
34
|
+
Requires-Dist: pymdown-extensions>=10.0
|
|
35
|
+
Requires-Dist: pygments>=2.15.0
|
|
36
|
+
Requires-Dist: pydantic>=2.0.0
|
|
37
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
38
|
+
Requires-Dist: typer>=0.9.0
|
|
39
|
+
Requires-Dist: rich>=13.0.0
|
|
40
|
+
Requires-Dist: platformdirs>=3.0.0
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pypdfium2>=4.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
46
|
+
Requires-Dist: tomli>=2.0.0; python_version < "3.11" and extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# markpublish
|
|
50
|
+
|
|
51
|
+
[](https://opensource.org/licenses/MIT)
|
|
52
|
+
[](https://www.python.org/downloads/)
|
|
53
|
+
|
|
54
|
+
**markpublish** is a modern, modular, and extensible publishing tool for Markdown documents. It compiles structured Markdown chapters into print-ready **PDFs** (powered by [WeasyPrint](https://weasyprint.org/) and W3C CSS Paged Media) and standalone **HTML** previews, fully configured via a clean YAML manifest.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Key Features
|
|
59
|
+
|
|
60
|
+
- 📄 **WeasyPrint PDF Engine**: Native support for CSS Paged Media (`@page`, `@top-left`, `@top-right`, `@bottom-left`, `@bottom-right`, page counters, leaders, target counters).
|
|
61
|
+
- 🌐 **Multi-Format Pipeline**: First-class support for **PDF** and **HTML** (extensible architecture for EPUB, DOCX).
|
|
62
|
+
- ⚙️ **Declarative YAML Configuration**: Configure metadata, covers, TOCs, headers, and footers in `markpublish.yaml`.
|
|
63
|
+
- 📁 **Modular Chapters & Parts**: Split your content into separate `.md` files, organize them hierarchically, and group them under overarching **Parts** (e.g. *Appendices*).
|
|
64
|
+
- 🎨 **Target-Based Template Hierarchy**:
|
|
65
|
+
- `templates/<theme>/pdf` and `templates/<theme>/html`
|
|
66
|
+
- 3-tier resolution: **User directory** > **Common/Project folder** > **Package built-ins**.
|
|
67
|
+
- 🔤 **Bundled font**: Open Sans ships with the theme as a variable font and is embedded into the PDF, so output does not depend on what is installed on the build machine.
|
|
68
|
+
- 📑 **Running Headers & Footers**: Real markup in the page margins via CSS running elements -- any number of lines, per-line styling, columns top-aligned.
|
|
69
|
+
- 🔢 **Autonumbering & TOC**:
|
|
70
|
+
- Global TOC reflecting chapter depth and heading levels.
|
|
71
|
+
- Per-chapter local TOCs with configurable `max_depth` (rendered on the PDF divider page).
|
|
72
|
+
- Configurable autonumbering schemes (`decimal`, `roman`, `legal`, `none`).
|
|
73
|
+
- 💻 **Cross-Platform**: Works seamlessly on Linux, macOS, and Windows.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Showcase / Sample Output
|
|
78
|
+
|
|
79
|
+
The entire official user guide was written in Markdown and rendered directly with `markpublish` — two languages, both target formats, all four built by `python build_manuals.py`:
|
|
80
|
+
|
|
81
|
+
| Document | PDF | HTML |
|
|
82
|
+
| :--- | :--- | :--- |
|
|
83
|
+
| 🇩🇪 markpublish Benutzerhandbuch | **[view](https://github.com/fwdotcom/markpublish/blob/main/manual/markpublish_benutzerhandbuch.pdf)** | [download](https://raw.githubusercontent.com/fwdotcom/markpublish/main/manual/markpublish_benutzerhandbuch.html) |
|
|
84
|
+
| 🇬🇧 markpublish User Guide | **[view](https://github.com/fwdotcom/markpublish/blob/main/manual/markpublish_user_guide.pdf)** | [download](https://raw.githubusercontent.com/fwdotcom/markpublish/main/manual/markpublish_user_guide.html) |
|
|
85
|
+
|
|
86
|
+
The PDFs open straight in the browser. The HTML files are **single, self-contained
|
|
87
|
+
documents** — fonts and images are embedded as data URIs, so one file is the whole
|
|
88
|
+
publication, with nothing to unpack and no assets folder beside it. GitHub serves
|
|
89
|
+
them as plain text rather than rendering them, so save the file and open it locally.
|
|
90
|
+
|
|
91
|
+
Together they demonstrate the built-in capabilities in practice: cover layout,
|
|
92
|
+
multi-level global TOC, running multi-line headers and footers, GitHub callout
|
|
93
|
+
admonitions, Pygments syntax highlighting, task lists, and the part/chapter
|
|
94
|
+
hierarchy — and in the HTML case a sidebar TOC and a responsive layout instead of
|
|
95
|
+
the print furniture.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Installation
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install markpublish
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For development:
|
|
106
|
+
```bash
|
|
107
|
+
git clone https://github.com/fwdotcom/markpublish.git
|
|
108
|
+
cd markpublish
|
|
109
|
+
pip install -e ".[dev]"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Quickstart
|
|
115
|
+
|
|
116
|
+
### 1. Initialize a new project
|
|
117
|
+
```bash
|
|
118
|
+
markpublish init my-book --title "My Architecture Guide"
|
|
119
|
+
cd my-book
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
This creates a minimal stub: `markpublish.yaml` plus one chapter, both directly
|
|
123
|
+
in the directory. It is meant to be replaced by your own content.
|
|
124
|
+
|
|
125
|
+
### 2. Look things up
|
|
126
|
+
```bash
|
|
127
|
+
markpublish cheatsheet [--lang de|en] # two-page reference card
|
|
128
|
+
markpublish manual [--lang de|en] # the full user guide
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`cheatsheet` renders a two-page reference -- every key of `markpublish.yaml` on
|
|
132
|
+
page one, themes and templates on page two. `manual` renders the complete user
|
|
133
|
+
guide. Both ship in German and English, their sources inside the package, and
|
|
134
|
+
are rendered on demand -- so they describe the version you actually have rather
|
|
135
|
+
than whatever was current when someone last rebuilt a PDF, and a successful run
|
|
136
|
+
also confirms that the rendering toolchain works.
|
|
137
|
+
|
|
138
|
+
`--lang` selects the source, not just the labels: each translation carries its
|
|
139
|
+
own `language:` and pulls in the matching static texts by itself. Without it,
|
|
140
|
+
your system language decides; where no translation exists, English appears.
|
|
141
|
+
|
|
142
|
+
### 3. Build PDF and HTML
|
|
143
|
+
```bash
|
|
144
|
+
# Build PDF
|
|
145
|
+
markpublish build
|
|
146
|
+
|
|
147
|
+
# Build standalone HTML
|
|
148
|
+
markpublish build --target html
|
|
149
|
+
|
|
150
|
+
# Build both PDF and HTML
|
|
151
|
+
markpublish build --target all
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Configuration Reference (`markpublish.yaml`)
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
# Document Metadata & Layout
|
|
160
|
+
document:
|
|
161
|
+
title: "Cloud Architecture Guide"
|
|
162
|
+
subtitle: "Best Practices & Standards"
|
|
163
|
+
summary: "Comprehensive guide for modern enterprise cloud environments."
|
|
164
|
+
author: "Frank Mustermann"
|
|
165
|
+
date: "auto" # "auto" for current date, or "2026-08-31"
|
|
166
|
+
version: "1.0.0" # optional; omitted -> no version on the cover
|
|
167
|
+
language: "de" # Localization and hyphenation; omit it and
|
|
168
|
+
# your system language applies
|
|
169
|
+
|
|
170
|
+
# Layout Toggles
|
|
171
|
+
cover: true # Enable cover page
|
|
172
|
+
document_toc: 2 # Large TOC, two levels deep
|
|
173
|
+
autonum_style: "decimal" # "decimal" (1, 1.1), "roman", "legal", "none"
|
|
174
|
+
chapter_toc: 2 # Default for the chapters' divider-page TOC
|
|
175
|
+
header: true # Enable running header (laid out in the theme)
|
|
176
|
+
footer: true # Enable running footer (laid out in the theme)
|
|
177
|
+
|
|
178
|
+
# Template selection
|
|
179
|
+
theme: "default"
|
|
180
|
+
templates_dir: "./templates" # Optional: custom shared templates directory
|
|
181
|
+
|
|
182
|
+
# Parts and Chapters (hierarchical structure)
|
|
183
|
+
parts:
|
|
184
|
+
# Main part (no part divider page, chapters listed directly in TOC)
|
|
185
|
+
- title: "Main"
|
|
186
|
+
break_before: "none"
|
|
187
|
+
document_toc: "none"
|
|
188
|
+
chapters:
|
|
189
|
+
- file: "chapters/01_introduction.md"
|
|
190
|
+
title: "Introduction"
|
|
191
|
+
summary: "Scope and motivation."
|
|
192
|
+
break_before: "divider" # Dedicated divider/separator page
|
|
193
|
+
chapter_toc: "none"
|
|
194
|
+
|
|
195
|
+
- file: "chapters/02_architecture.md"
|
|
196
|
+
title: "Core Architecture"
|
|
197
|
+
summary: "System components and flows."
|
|
198
|
+
break_before: "divider"
|
|
199
|
+
chapter_toc: 2 # Local chapter TOC up to depth 2
|
|
200
|
+
|
|
201
|
+
# Overarching Part / Section (e.g. Appendices)
|
|
202
|
+
- title: "Appendices"
|
|
203
|
+
summary: "Glossary and reference tables."
|
|
204
|
+
break_before: "divider" # Dedicated Part separator page
|
|
205
|
+
autonum_from_level: 2 # Number sub-headings (A.1, A.2)
|
|
206
|
+
document_toc: 2 # Include down to depth 2 in front TOC
|
|
207
|
+
chapters:
|
|
208
|
+
- file: "chapters/appendix_a.md"
|
|
209
|
+
title: "Appendix A: Reference"
|
|
210
|
+
autonum_prefix: "A."
|
|
211
|
+
- file: "chapters/appendix_b.md"
|
|
212
|
+
title: "Appendix B: Troubleshooting"
|
|
213
|
+
autonum_prefix: "B."
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
For simple documents (e.g. leaflets or short reports), the `parts:` layer is optional; you can also write `chapters: [...]` directly at the top level.
|
|
217
|
+
|
|
218
|
+
`break_before` decides how far a chapter is set off from the one before it, on a
|
|
219
|
+
single axis: `page` (the default) starts it at the top of a fresh page,
|
|
220
|
+
`divider` gives it a separator page of its own, and `none` lets it run on.
|
|
221
|
+
|
|
222
|
+
A document has two tables of contents and one key each, written the same way in
|
|
223
|
+
the `document` block and on a chapter: `document_toc` for the large one at the
|
|
224
|
+
front, `chapter_toc` for the small ones on the divider pages. Under `document`
|
|
225
|
+
they set the default, on a chapter or part they override it. Both take `none`, `full` or
|
|
226
|
+
a depth counted from the chapter's own heading, so `document_toc: 1` contributes
|
|
227
|
+
the chapter title and nothing below it.
|
|
228
|
+
|
|
229
|
+
`document_toc`, `autonum_style`, `autonum_from_level`, and `autonum_prefix` are inherited downwards from a part, which is why one line on the `Appendices` part configures every appendix at once. `chapter_toc` is not chained; it falls back to `document.chapter_toc`.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Template System
|
|
234
|
+
|
|
235
|
+
Templates are organized by theme first, then by target format:
|
|
236
|
+
```
|
|
237
|
+
templates/
|
|
238
|
+
└── default/
|
|
239
|
+
├── pdf/
|
|
240
|
+
│ ├── layout.html # Jinja2 layout
|
|
241
|
+
│ ├── styles.css # CSS Paged Media (@page, @top-left, @bottom-right)
|
|
242
|
+
│ ├── cover.html # Cover page
|
|
243
|
+
│ ├── part_divider.html # Part separator page
|
|
244
|
+
│ ├── chapter_divider.html # Chapter separator page & local TOC (PDF only)
|
|
245
|
+
│ └── toc.html # Global TOC
|
|
246
|
+
└── html/
|
|
247
|
+
└── ...
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Template Resolution Order:
|
|
251
|
+
When rendering `pdf` with theme `default`:
|
|
252
|
+
1. **User directory**: `~/.markpublish/templates/default/pdf/` (or OS config dir)
|
|
253
|
+
2. **Common / Project directory**: `<templates_dir>/default/pdf/` (configured via `--templates-dir`, YAML `templates_dir`, `MARKPUBLISH_TEMPLATES_DIR`, or `./templates`)
|
|
254
|
+
3. **Package built-ins**: Embedded inside `markpublish`.
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
### Static texts and language
|
|
258
|
+
|
|
259
|
+
Fixed labels (table of contents heading, chapter tags, cover labels, page footer,
|
|
260
|
+
callout titles) live in `i18n.yaml` files rather than in the templates. The language
|
|
261
|
+
comes from `document.language`; `de` and `en` ship with the package, regional forms map
|
|
262
|
+
onto them (`de-AT` -> `de`), and an unknown language falls back to English. Leave the key
|
|
263
|
+
out and the system language applies -- `markpublish init` writes it down, so a document
|
|
264
|
+
builds the same on every machine.
|
|
265
|
+
|
|
266
|
+
*i18n* is the source data across all languages; *labels* is what it resolves to for one
|
|
267
|
+
document in one language, i.e. what a template sees as `{{ labels.chapter }}`.
|
|
268
|
+
|
|
269
|
+
Three levels, all built the same way -- language code, then key/text. Each level
|
|
270
|
+
overrides the one above it, and only for the keys it actually sets:
|
|
271
|
+
|
|
272
|
+
| Level | Location |
|
|
273
|
+
| :--- | :--- |
|
|
274
|
+
| 1 | `markpublish/i18n.yaml` (complete, `de` + `en`) |
|
|
275
|
+
| 2 | `<templates>/<theme>/i18n.yaml` |
|
|
276
|
+
| 3 | `<templates>/<theme>/<target>/i18n.yaml` |
|
|
277
|
+
|
|
278
|
+
Levels 2 and 3 always come from the **one** theme the template resolution picked
|
|
279
|
+
(user > project > package); a project theme does not inherit the texts of the
|
|
280
|
+
package theme of the same name. A document cannot override texts -- give it its
|
|
281
|
+
own theme (`markpublish export-template`) instead.
|
|
282
|
+
|
|
283
|
+
```yaml
|
|
284
|
+
# any of the three levels
|
|
285
|
+
"*": # applies to every language
|
|
286
|
+
version: "Rev."
|
|
287
|
+
de:
|
|
288
|
+
part: "Abschnitt"
|
|
289
|
+
en:
|
|
290
|
+
part: "Section"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
A flat mapping without the language level is shorthand for `"*"`. Levels 2 and 3 apply
|
|
294
|
+
**only to the selected language**, so a theme's English block never leaks into German
|
|
295
|
+
output. Level 1 additionally layers English underneath the document language, so every
|
|
296
|
+
program text always resolves. A missing `i18n.yaml` is fine; a malformed one aborts the
|
|
297
|
+
build naming the file.
|
|
298
|
+
|
|
299
|
+
#### Free labels
|
|
300
|
+
|
|
301
|
+
A theme may define keys the program knows nothing about -- for the static texts of the
|
|
302
|
+
template itself -- and read them back with `{{ labels.imprint_title }}`. There is no
|
|
303
|
+
program default to fall back on for those, so the rule is strict: a label written in a
|
|
304
|
+
template must resolve in the cascade, otherwise the build **aborts** and names the key,
|
|
305
|
+
the file and line that used it, the document language, and the `i18n.yaml` files that
|
|
306
|
+
were searched. Keep every language of a free label filled in, or put it under `"*"`.
|
|
307
|
+
An empty string in a finished PDF goes unnoticed; an abort does not.
|
|
308
|
+
|
|
309
|
+
The bundled `default` theme ships all three template-side files as commented patterns,
|
|
310
|
+
and `markpublish export-template` copies them along with the templates.
|
|
311
|
+
|
|
312
|
+
Run `markpublish labels [--target html] [--overridden]` to see the resolved table and
|
|
313
|
+
which level supplied each value.
|
|
314
|
+
|
|
315
|
+
### Exporting Templates for Customization:
|
|
316
|
+
```bash
|
|
317
|
+
markpublish export-template default
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## CLI Commands
|
|
323
|
+
|
|
324
|
+
| Command | Description |
|
|
325
|
+
| :--- | :--- |
|
|
326
|
+
| `markpublish build [config.yaml]` | Builds PDF/HTML outputs (`-t pdf`, `-t html`, `-t all`) |
|
|
327
|
+
| `markpublish init [path]` | Scaffolds a new project with chapters and configuration |
|
|
328
|
+
| `markpublish cheatsheet` | Renders the two-page reference card (`--lang`, `--target`) |
|
|
329
|
+
| `markpublish manual` | Renders the full user guide (`--lang`, `--target`) |
|
|
330
|
+
| `markpublish templates` | Lists available templates across User, Common, and Package sources |
|
|
331
|
+
| `markpublish export-template [theme]` | Copies a built-in template to project directory |
|
|
332
|
+
| `markpublish labels` | Shows the resolved static texts and their cascade origin |
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## License
|
|
337
|
+
|
|
338
|
+
MIT License. See [LICENSE](https://github.com/fwdotcom/markpublish/blob/main/LICENSE) for details.
|
|
339
|
+
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# markpublish
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
|
|
6
|
+
**markpublish** is a modern, modular, and extensible publishing tool for Markdown documents. It compiles structured Markdown chapters into print-ready **PDFs** (powered by [WeasyPrint](https://weasyprint.org/) and W3C CSS Paged Media) and standalone **HTML** previews, fully configured via a clean YAML manifest.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Key Features
|
|
11
|
+
|
|
12
|
+
- 📄 **WeasyPrint PDF Engine**: Native support for CSS Paged Media (`@page`, `@top-left`, `@top-right`, `@bottom-left`, `@bottom-right`, page counters, leaders, target counters).
|
|
13
|
+
- 🌐 **Multi-Format Pipeline**: First-class support for **PDF** and **HTML** (extensible architecture for EPUB, DOCX).
|
|
14
|
+
- ⚙️ **Declarative YAML Configuration**: Configure metadata, covers, TOCs, headers, and footers in `markpublish.yaml`.
|
|
15
|
+
- 📁 **Modular Chapters & Parts**: Split your content into separate `.md` files, organize them hierarchically, and group them under overarching **Parts** (e.g. *Appendices*).
|
|
16
|
+
- 🎨 **Target-Based Template Hierarchy**:
|
|
17
|
+
- `templates/<theme>/pdf` and `templates/<theme>/html`
|
|
18
|
+
- 3-tier resolution: **User directory** > **Common/Project folder** > **Package built-ins**.
|
|
19
|
+
- 🔤 **Bundled font**: Open Sans ships with the theme as a variable font and is embedded into the PDF, so output does not depend on what is installed on the build machine.
|
|
20
|
+
- 📑 **Running Headers & Footers**: Real markup in the page margins via CSS running elements -- any number of lines, per-line styling, columns top-aligned.
|
|
21
|
+
- 🔢 **Autonumbering & TOC**:
|
|
22
|
+
- Global TOC reflecting chapter depth and heading levels.
|
|
23
|
+
- Per-chapter local TOCs with configurable `max_depth` (rendered on the PDF divider page).
|
|
24
|
+
- Configurable autonumbering schemes (`decimal`, `roman`, `legal`, `none`).
|
|
25
|
+
- 💻 **Cross-Platform**: Works seamlessly on Linux, macOS, and Windows.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Showcase / Sample Output
|
|
30
|
+
|
|
31
|
+
The entire official user guide was written in Markdown and rendered directly with `markpublish` — two languages, both target formats, all four built by `python build_manuals.py`:
|
|
32
|
+
|
|
33
|
+
| Document | PDF | HTML |
|
|
34
|
+
| :--- | :--- | :--- |
|
|
35
|
+
| 🇩🇪 markpublish Benutzerhandbuch | **[view](https://github.com/fwdotcom/markpublish/blob/main/manual/markpublish_benutzerhandbuch.pdf)** | [download](https://raw.githubusercontent.com/fwdotcom/markpublish/main/manual/markpublish_benutzerhandbuch.html) |
|
|
36
|
+
| 🇬🇧 markpublish User Guide | **[view](https://github.com/fwdotcom/markpublish/blob/main/manual/markpublish_user_guide.pdf)** | [download](https://raw.githubusercontent.com/fwdotcom/markpublish/main/manual/markpublish_user_guide.html) |
|
|
37
|
+
|
|
38
|
+
The PDFs open straight in the browser. The HTML files are **single, self-contained
|
|
39
|
+
documents** — fonts and images are embedded as data URIs, so one file is the whole
|
|
40
|
+
publication, with nothing to unpack and no assets folder beside it. GitHub serves
|
|
41
|
+
them as plain text rather than rendering them, so save the file and open it locally.
|
|
42
|
+
|
|
43
|
+
Together they demonstrate the built-in capabilities in practice: cover layout,
|
|
44
|
+
multi-level global TOC, running multi-line headers and footers, GitHub callout
|
|
45
|
+
admonitions, Pygments syntax highlighting, task lists, and the part/chapter
|
|
46
|
+
hierarchy — and in the HTML case a sidebar TOC and a responsive layout instead of
|
|
47
|
+
the print furniture.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install markpublish
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For development:
|
|
58
|
+
```bash
|
|
59
|
+
git clone https://github.com/fwdotcom/markpublish.git
|
|
60
|
+
cd markpublish
|
|
61
|
+
pip install -e ".[dev]"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Quickstart
|
|
67
|
+
|
|
68
|
+
### 1. Initialize a new project
|
|
69
|
+
```bash
|
|
70
|
+
markpublish init my-book --title "My Architecture Guide"
|
|
71
|
+
cd my-book
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This creates a minimal stub: `markpublish.yaml` plus one chapter, both directly
|
|
75
|
+
in the directory. It is meant to be replaced by your own content.
|
|
76
|
+
|
|
77
|
+
### 2. Look things up
|
|
78
|
+
```bash
|
|
79
|
+
markpublish cheatsheet [--lang de|en] # two-page reference card
|
|
80
|
+
markpublish manual [--lang de|en] # the full user guide
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`cheatsheet` renders a two-page reference -- every key of `markpublish.yaml` on
|
|
84
|
+
page one, themes and templates on page two. `manual` renders the complete user
|
|
85
|
+
guide. Both ship in German and English, their sources inside the package, and
|
|
86
|
+
are rendered on demand -- so they describe the version you actually have rather
|
|
87
|
+
than whatever was current when someone last rebuilt a PDF, and a successful run
|
|
88
|
+
also confirms that the rendering toolchain works.
|
|
89
|
+
|
|
90
|
+
`--lang` selects the source, not just the labels: each translation carries its
|
|
91
|
+
own `language:` and pulls in the matching static texts by itself. Without it,
|
|
92
|
+
your system language decides; where no translation exists, English appears.
|
|
93
|
+
|
|
94
|
+
### 3. Build PDF and HTML
|
|
95
|
+
```bash
|
|
96
|
+
# Build PDF
|
|
97
|
+
markpublish build
|
|
98
|
+
|
|
99
|
+
# Build standalone HTML
|
|
100
|
+
markpublish build --target html
|
|
101
|
+
|
|
102
|
+
# Build both PDF and HTML
|
|
103
|
+
markpublish build --target all
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Configuration Reference (`markpublish.yaml`)
|
|
109
|
+
|
|
110
|
+
```yaml
|
|
111
|
+
# Document Metadata & Layout
|
|
112
|
+
document:
|
|
113
|
+
title: "Cloud Architecture Guide"
|
|
114
|
+
subtitle: "Best Practices & Standards"
|
|
115
|
+
summary: "Comprehensive guide for modern enterprise cloud environments."
|
|
116
|
+
author: "Frank Mustermann"
|
|
117
|
+
date: "auto" # "auto" for current date, or "2026-08-31"
|
|
118
|
+
version: "1.0.0" # optional; omitted -> no version on the cover
|
|
119
|
+
language: "de" # Localization and hyphenation; omit it and
|
|
120
|
+
# your system language applies
|
|
121
|
+
|
|
122
|
+
# Layout Toggles
|
|
123
|
+
cover: true # Enable cover page
|
|
124
|
+
document_toc: 2 # Large TOC, two levels deep
|
|
125
|
+
autonum_style: "decimal" # "decimal" (1, 1.1), "roman", "legal", "none"
|
|
126
|
+
chapter_toc: 2 # Default for the chapters' divider-page TOC
|
|
127
|
+
header: true # Enable running header (laid out in the theme)
|
|
128
|
+
footer: true # Enable running footer (laid out in the theme)
|
|
129
|
+
|
|
130
|
+
# Template selection
|
|
131
|
+
theme: "default"
|
|
132
|
+
templates_dir: "./templates" # Optional: custom shared templates directory
|
|
133
|
+
|
|
134
|
+
# Parts and Chapters (hierarchical structure)
|
|
135
|
+
parts:
|
|
136
|
+
# Main part (no part divider page, chapters listed directly in TOC)
|
|
137
|
+
- title: "Main"
|
|
138
|
+
break_before: "none"
|
|
139
|
+
document_toc: "none"
|
|
140
|
+
chapters:
|
|
141
|
+
- file: "chapters/01_introduction.md"
|
|
142
|
+
title: "Introduction"
|
|
143
|
+
summary: "Scope and motivation."
|
|
144
|
+
break_before: "divider" # Dedicated divider/separator page
|
|
145
|
+
chapter_toc: "none"
|
|
146
|
+
|
|
147
|
+
- file: "chapters/02_architecture.md"
|
|
148
|
+
title: "Core Architecture"
|
|
149
|
+
summary: "System components and flows."
|
|
150
|
+
break_before: "divider"
|
|
151
|
+
chapter_toc: 2 # Local chapter TOC up to depth 2
|
|
152
|
+
|
|
153
|
+
# Overarching Part / Section (e.g. Appendices)
|
|
154
|
+
- title: "Appendices"
|
|
155
|
+
summary: "Glossary and reference tables."
|
|
156
|
+
break_before: "divider" # Dedicated Part separator page
|
|
157
|
+
autonum_from_level: 2 # Number sub-headings (A.1, A.2)
|
|
158
|
+
document_toc: 2 # Include down to depth 2 in front TOC
|
|
159
|
+
chapters:
|
|
160
|
+
- file: "chapters/appendix_a.md"
|
|
161
|
+
title: "Appendix A: Reference"
|
|
162
|
+
autonum_prefix: "A."
|
|
163
|
+
- file: "chapters/appendix_b.md"
|
|
164
|
+
title: "Appendix B: Troubleshooting"
|
|
165
|
+
autonum_prefix: "B."
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
For simple documents (e.g. leaflets or short reports), the `parts:` layer is optional; you can also write `chapters: [...]` directly at the top level.
|
|
169
|
+
|
|
170
|
+
`break_before` decides how far a chapter is set off from the one before it, on a
|
|
171
|
+
single axis: `page` (the default) starts it at the top of a fresh page,
|
|
172
|
+
`divider` gives it a separator page of its own, and `none` lets it run on.
|
|
173
|
+
|
|
174
|
+
A document has two tables of contents and one key each, written the same way in
|
|
175
|
+
the `document` block and on a chapter: `document_toc` for the large one at the
|
|
176
|
+
front, `chapter_toc` for the small ones on the divider pages. Under `document`
|
|
177
|
+
they set the default, on a chapter or part they override it. Both take `none`, `full` or
|
|
178
|
+
a depth counted from the chapter's own heading, so `document_toc: 1` contributes
|
|
179
|
+
the chapter title and nothing below it.
|
|
180
|
+
|
|
181
|
+
`document_toc`, `autonum_style`, `autonum_from_level`, and `autonum_prefix` are inherited downwards from a part, which is why one line on the `Appendices` part configures every appendix at once. `chapter_toc` is not chained; it falls back to `document.chapter_toc`.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Template System
|
|
186
|
+
|
|
187
|
+
Templates are organized by theme first, then by target format:
|
|
188
|
+
```
|
|
189
|
+
templates/
|
|
190
|
+
└── default/
|
|
191
|
+
├── pdf/
|
|
192
|
+
│ ├── layout.html # Jinja2 layout
|
|
193
|
+
│ ├── styles.css # CSS Paged Media (@page, @top-left, @bottom-right)
|
|
194
|
+
│ ├── cover.html # Cover page
|
|
195
|
+
│ ├── part_divider.html # Part separator page
|
|
196
|
+
│ ├── chapter_divider.html # Chapter separator page & local TOC (PDF only)
|
|
197
|
+
│ └── toc.html # Global TOC
|
|
198
|
+
└── html/
|
|
199
|
+
└── ...
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Template Resolution Order:
|
|
203
|
+
When rendering `pdf` with theme `default`:
|
|
204
|
+
1. **User directory**: `~/.markpublish/templates/default/pdf/` (or OS config dir)
|
|
205
|
+
2. **Common / Project directory**: `<templates_dir>/default/pdf/` (configured via `--templates-dir`, YAML `templates_dir`, `MARKPUBLISH_TEMPLATES_DIR`, or `./templates`)
|
|
206
|
+
3. **Package built-ins**: Embedded inside `markpublish`.
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
### Static texts and language
|
|
210
|
+
|
|
211
|
+
Fixed labels (table of contents heading, chapter tags, cover labels, page footer,
|
|
212
|
+
callout titles) live in `i18n.yaml` files rather than in the templates. The language
|
|
213
|
+
comes from `document.language`; `de` and `en` ship with the package, regional forms map
|
|
214
|
+
onto them (`de-AT` -> `de`), and an unknown language falls back to English. Leave the key
|
|
215
|
+
out and the system language applies -- `markpublish init` writes it down, so a document
|
|
216
|
+
builds the same on every machine.
|
|
217
|
+
|
|
218
|
+
*i18n* is the source data across all languages; *labels* is what it resolves to for one
|
|
219
|
+
document in one language, i.e. what a template sees as `{{ labels.chapter }}`.
|
|
220
|
+
|
|
221
|
+
Three levels, all built the same way -- language code, then key/text. Each level
|
|
222
|
+
overrides the one above it, and only for the keys it actually sets:
|
|
223
|
+
|
|
224
|
+
| Level | Location |
|
|
225
|
+
| :--- | :--- |
|
|
226
|
+
| 1 | `markpublish/i18n.yaml` (complete, `de` + `en`) |
|
|
227
|
+
| 2 | `<templates>/<theme>/i18n.yaml` |
|
|
228
|
+
| 3 | `<templates>/<theme>/<target>/i18n.yaml` |
|
|
229
|
+
|
|
230
|
+
Levels 2 and 3 always come from the **one** theme the template resolution picked
|
|
231
|
+
(user > project > package); a project theme does not inherit the texts of the
|
|
232
|
+
package theme of the same name. A document cannot override texts -- give it its
|
|
233
|
+
own theme (`markpublish export-template`) instead.
|
|
234
|
+
|
|
235
|
+
```yaml
|
|
236
|
+
# any of the three levels
|
|
237
|
+
"*": # applies to every language
|
|
238
|
+
version: "Rev."
|
|
239
|
+
de:
|
|
240
|
+
part: "Abschnitt"
|
|
241
|
+
en:
|
|
242
|
+
part: "Section"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
A flat mapping without the language level is shorthand for `"*"`. Levels 2 and 3 apply
|
|
246
|
+
**only to the selected language**, so a theme's English block never leaks into German
|
|
247
|
+
output. Level 1 additionally layers English underneath the document language, so every
|
|
248
|
+
program text always resolves. A missing `i18n.yaml` is fine; a malformed one aborts the
|
|
249
|
+
build naming the file.
|
|
250
|
+
|
|
251
|
+
#### Free labels
|
|
252
|
+
|
|
253
|
+
A theme may define keys the program knows nothing about -- for the static texts of the
|
|
254
|
+
template itself -- and read them back with `{{ labels.imprint_title }}`. There is no
|
|
255
|
+
program default to fall back on for those, so the rule is strict: a label written in a
|
|
256
|
+
template must resolve in the cascade, otherwise the build **aborts** and names the key,
|
|
257
|
+
the file and line that used it, the document language, and the `i18n.yaml` files that
|
|
258
|
+
were searched. Keep every language of a free label filled in, or put it under `"*"`.
|
|
259
|
+
An empty string in a finished PDF goes unnoticed; an abort does not.
|
|
260
|
+
|
|
261
|
+
The bundled `default` theme ships all three template-side files as commented patterns,
|
|
262
|
+
and `markpublish export-template` copies them along with the templates.
|
|
263
|
+
|
|
264
|
+
Run `markpublish labels [--target html] [--overridden]` to see the resolved table and
|
|
265
|
+
which level supplied each value.
|
|
266
|
+
|
|
267
|
+
### Exporting Templates for Customization:
|
|
268
|
+
```bash
|
|
269
|
+
markpublish export-template default
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## CLI Commands
|
|
275
|
+
|
|
276
|
+
| Command | Description |
|
|
277
|
+
| :--- | :--- |
|
|
278
|
+
| `markpublish build [config.yaml]` | Builds PDF/HTML outputs (`-t pdf`, `-t html`, `-t all`) |
|
|
279
|
+
| `markpublish init [path]` | Scaffolds a new project with chapters and configuration |
|
|
280
|
+
| `markpublish cheatsheet` | Renders the two-page reference card (`--lang`, `--target`) |
|
|
281
|
+
| `markpublish manual` | Renders the full user guide (`--lang`, `--target`) |
|
|
282
|
+
| `markpublish templates` | Lists available templates across User, Common, and Package sources |
|
|
283
|
+
| `markpublish export-template [theme]` | Copies a built-in template to project directory |
|
|
284
|
+
| `markpublish labels` | Shows the resolved static texts and their cascade origin |
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
MIT License. See [LICENSE](https://github.com/fwdotcom/markpublish/blob/main/LICENSE) for details.
|
|
291
|
+
|