md2star 2.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.
Files changed (82) hide show
  1. md2star-2.0.0/.gitignore +140 -0
  2. md2star-2.0.0/CHANGELOG.md +338 -0
  3. md2star-2.0.0/CONTRIBUTING.md +148 -0
  4. md2star-2.0.0/EXAMPLES.md +150 -0
  5. md2star-2.0.0/LANDSCAPE.md +168 -0
  6. md2star-2.0.0/LICENSE +30 -0
  7. md2star-2.0.0/LISEZMOI.md +430 -0
  8. md2star-2.0.0/Makefile +86 -0
  9. md2star-2.0.0/PKG-INFO +475 -0
  10. md2star-2.0.0/README.md +438 -0
  11. md2star-2.0.0/ROADMAP.md +113 -0
  12. md2star-2.0.0/SECURITY.md +94 -0
  13. md2star-2.0.0/assets/README.md +45 -0
  14. md2star-2.0.0/assets/docx/basic.md +4 -0
  15. md2star-2.0.0/assets/docx/math.md +12 -0
  16. md2star-2.0.0/assets/docx/with_author.md +2 -0
  17. md2star-2.0.0/assets/docx/with_bib.md +2 -0
  18. md2star-2.0.0/assets/docx/with_lang.md +3 -0
  19. md2star-2.0.0/assets/example.md +17 -0
  20. md2star-2.0.0/assets/logo.png +0 -0
  21. md2star-2.0.0/assets/pptx/example.md +181 -0
  22. md2star-2.0.0/assets/references.bib +323 -0
  23. md2star-2.0.0/assets/run.sh +37 -0
  24. md2star-2.0.0/docs/audit.md +223 -0
  25. md2star-2.0.0/docs/developer_guide.md +238 -0
  26. md2star-2.0.0/docs/installation.md +178 -0
  27. md2star-2.0.0/md2star/__init__.py +42 -0
  28. md2star-2.0.0/md2star/__main__.py +31 -0
  29. md2star-2.0.0/md2star/cache.py +93 -0
  30. md2star-2.0.0/md2star/cli.py +680 -0
  31. md2star-2.0.0/md2star/data/defaults/docx-star.yaml +26 -0
  32. md2star-2.0.0/md2star/data/defaults/pptx-star.yaml +26 -0
  33. md2star-2.0.0/md2star/data/example.md +17 -0
  34. md2star-2.0.0/md2star/data/filters/md2star.lua +315 -0
  35. md2star-2.0.0/md2star/data/mermaid-config.json +60 -0
  36. md2star-2.0.0/md2star/data/metadata.yaml +2 -0
  37. md2star-2.0.0/md2star/data/puppeteer-config.json +3 -0
  38. md2star-2.0.0/md2star/data/template.docx +0 -0
  39. md2star-2.0.0/md2star/data/template.pptx +0 -0
  40. md2star-2.0.0/md2star/doctor.py +405 -0
  41. md2star-2.0.0/md2star/errors.py +127 -0
  42. md2star-2.0.0/md2star/postprocess.py +259 -0
  43. md2star-2.0.0/md2star/preprocessing/__init__.py +33 -0
  44. md2star-2.0.0/md2star/preprocessing/alt_text.py +212 -0
  45. md2star-2.0.0/md2star/preprocessing/images.py +525 -0
  46. md2star-2.0.0/md2star/preprocessing/language.py +54 -0
  47. md2star-2.0.0/md2star/preprocessing/lint.py +261 -0
  48. md2star-2.0.0/md2star/preprocessing/math.py +145 -0
  49. md2star-2.0.0/md2star/preprocessing/mermaid.py +186 -0
  50. md2star-2.0.0/md2star/preprocessing/pipeline.py +409 -0
  51. md2star-2.0.0/md2star/preprocessing/regexes.py +21 -0
  52. md2star-2.0.0/md2star/preprocessing/tables.py +519 -0
  53. md2star-2.0.0/pyproject.toml +127 -0
  54. md2star-2.0.0/scripts/README.md +27 -0
  55. md2star-2.0.0/scripts/install.ps1 +88 -0
  56. md2star-2.0.0/scripts/install.sh +308 -0
  57. md2star-2.0.0/scripts/test.sh +146 -0
  58. md2star-2.0.0/scripts/uninstall.ps1 +65 -0
  59. md2star-2.0.0/scripts/uninstall.sh +84 -0
  60. md2star-2.0.0/scripts/update.ps1 +15 -0
  61. md2star-2.0.0/tests/README.md +40 -0
  62. md2star-2.0.0/tests/conftest.py +19 -0
  63. md2star-2.0.0/tests/examples/branded_slides.md +35 -0
  64. md2star-2.0.0/tests/examples/comprehensive_document.md +58 -0
  65. md2star-2.0.0/tests/examples/comprehensive_presentation.md +70 -0
  66. md2star-2.0.0/tests/examples/guide_complet_document_fr.md +58 -0
  67. md2star-2.0.0/tests/examples/run.sh +34 -0
  68. md2star-2.0.0/tests/examples/table_zoo.md +52 -0
  69. md2star-2.0.0/tests/fixtures/bibliography.md +15 -0
  70. md2star-2.0.0/tests/fixtures/images.md +22 -0
  71. md2star-2.0.0/tests/fixtures/mermaid.md +22 -0
  72. md2star-2.0.0/tests/fixtures/metadata.md +18 -0
  73. md2star-2.0.0/tests/fixtures/refs.bib +15 -0
  74. md2star-2.0.0/tests/fixtures/simple.md +17 -0
  75. md2star-2.0.0/tests/test_alt_text.py +194 -0
  76. md2star-2.0.0/tests/test_bibliography_localization.py +80 -0
  77. md2star-2.0.0/tests/test_doctor.py +172 -0
  78. md2star-2.0.0/tests/test_integration.py +204 -0
  79. md2star-2.0.0/tests/test_lua_filter.py +203 -0
  80. md2star-2.0.0/tests/test_offline_security.py +216 -0
  81. md2star-2.0.0/tests/test_postprocess.py +230 -0
  82. md2star-2.0.0/tests/test_preprocessing.py +1047 -0
@@ -0,0 +1,140 @@
1
+ # Tests & temp files
2
+ temp/
3
+ temp_*
4
+ ~$*
5
+ test_list_extracted/
6
+
7
+ # Private working notes (per-developer scratch, not for main)
8
+ .private/
9
+
10
+ # Credentials directory. The real files (e.g. pypi.env with the
11
+ # TWINE_PASSWORD token) are gitignored; the matching *.example
12
+ # templates are committed so a fresh clone can see what shape to
13
+ # expect. Matches the project style guide rule 8 — see CONTRIBUTING.md.
14
+ .secrets/*
15
+ !.secrets/*.example
16
+
17
+ # Debug scripts (should not be committed)
18
+ debug.lua
19
+
20
+ assets/nexton-template.pptx
21
+
22
+ # Template adaptation temp files
23
+ pptx-templates/_extracted/
24
+ pptx-templates/*-pandoc.pptx
25
+ pptx-templates/pandoc_base.pptx
26
+ pptx-templates/*.pdf
27
+
28
+ # macOS
29
+ .DS_Store
30
+ .AppleDouble
31
+ .LSOverride
32
+ Icon?
33
+ ._*
34
+ .DocumentRevisions-V100
35
+ .fseventsd
36
+ .Spotlight-V100
37
+ .TemporaryItems
38
+ .Trashes
39
+ .VolumeIcon.icns
40
+ .com.apple.timemachine.donotpresent
41
+
42
+ # Windows
43
+ Thumbs.db
44
+ Thumbs.db:encryptable
45
+ ehthumbs.db
46
+ ehthumbs_vista.db
47
+ *.stackdump
48
+ [Dd]esktop.ini
49
+ $RECYCLE.BIN/
50
+ *.cab
51
+ *.msi
52
+ *.msix
53
+ *.msm
54
+ *.msp
55
+ *.lnk
56
+
57
+ # Linux
58
+ *~
59
+ .fuse_hidden*
60
+ .directory
61
+ .trash
62
+ .nfs*
63
+
64
+ # VS Code
65
+ .vscode/*
66
+ !.vscode/settings.json
67
+ !.vscode/tasks.json
68
+ !.vscode/launch.json
69
+ !.vscode/extensions.json
70
+ !.vscode/code-actions.json
71
+ *.code-workspace
72
+
73
+ # JetBrains
74
+ .idea/
75
+
76
+ # Sublime Text
77
+ *.sublime-project
78
+ *.sublime-workspace
79
+
80
+ # Vim
81
+ [._]*.s[a-v][a-z]
82
+ [._]*.sw[a-p]
83
+ [._]s[a-rt-v][a-z]
84
+ [._]ss[a-z]
85
+ *.un~
86
+ Session.vim
87
+ .netrwhist
88
+
89
+ # Project Specific
90
+ *.docx
91
+ !assets/template.docx
92
+ !assets/docx/*.docx
93
+ !md2star/data/template.docx
94
+ *.pptx
95
+ !assets/template.pptx
96
+ !assets/pptx/*.pptx
97
+ !md2star/data/template.pptx
98
+ !pptx-templates/*.pptx
99
+ pptx-templates/Jellysmack-Presentation-Template.pptx
100
+ !tests/examples/Presentation1.pptx
101
+ tests/*.pptx
102
+ tests/*.docx
103
+ *.log
104
+ *.tmp
105
+ *.bak
106
+ .remote_*
107
+ .mermaid_*
108
+
109
+ !assets/docx/.*.docx
110
+ !assets/docx/.*.md
111
+ !assets/docx/.*.pptx
112
+
113
+
114
+ # Python
115
+ __pycache__/
116
+ *.py[cod]
117
+ *.egg-info/
118
+ .pytest_cache/
119
+ .venv/
120
+ dist/
121
+ build/
122
+
123
+
124
+ .preprocessed_*
125
+
126
+ # Scratch screenshots from local playwright runs / manual captures.
127
+ # The curated set that ships with the docs lives at assets/screenshots/
128
+ # (tracked) — anything dropped at the repo root is treated as iteration
129
+ # noise and stays local.
130
+ /screenshots/
131
+
132
+ .ruff_cache/
133
+
134
+ .deepeval/
135
+
136
+ .claude/
137
+
138
+ .secrets/
139
+
140
+
@@ -0,0 +1,338 @@
1
+ # Changelog
2
+
3
+ All notable changes to **md2star** are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [2.0.0] — 2026-06-29
10
+
11
+ This is the PyPI debut. Two breaking changes drive the major bump.
12
+
13
+ ### Breaking
14
+ - **Licence is now BSD 3-Clause** (was The Unlicense / public domain).
15
+ Aligned with scikit-learn and the broader scientific-Python
16
+ conventions. Downstream redistributors must now ship the copyright
17
+ notice + disclaimer alongside the binary. The change is permissive
18
+ → permissive, so existing usage is unaffected; only redistribution
19
+ obligations change.
20
+ - **GUI removed.** The Overleaf-style local web editor (`md2star gui`),
21
+ the `md2star html` subcommand, and the ~3 MB vendored frontend tree
22
+ (Tailwind, CodeMirror, PDF.js, Roboto Serif) have been removed for
23
+ the PyPI debut so the wheel stays under 250 KB. The GUI lives in
24
+ git history and is slated to return as an opt-in extra:
25
+ `pipx install 'md2star[gui]'` in v2.1.
26
+
27
+ ### Added
28
+ - **PyPI distribution.** Install with `pipx install md2star` — no
29
+ clone required for end users. `make install` from a clone still
30
+ works for the development path.
31
+ - **Style guide formalised in CONTRIBUTING.md.** NumPy docstrings,
32
+ module headers with an Author link, and full type annotations
33
+ are now enforced for new and modified code.
34
+
35
+ ### Changed
36
+ - **Package description** mentions PDF alongside DOCX/PPTX.
37
+ - **README + LISEZMOI installation sections** restructured around the
38
+ three-OS pattern with the `brew.sh` hint for macOS and `pipx
39
+ install md2star` as the recommended path.
40
+ - **`md2star doctor`** no longer reports a "GUI" feature target.
41
+
42
+ ### Fixed
43
+ - **PDF tables render correctly via headless LibreOffice.** The
44
+ bundled template's `TableNormal0` custom-style caused soffice to
45
+ spill table cell content out of the table as a vertical paragraph
46
+ dump (Word rendered the same DOCX fine — the bug was the style +
47
+ soffice's interpretation). The PDF pipeline now strips
48
+ `TableNormal0` from the intermediate DOCX before invoking
49
+ soffice (`md2star/postprocess.py:strip_table_normal_for_pdf`).
50
+ DOCX output (`md2docx`) is untouched, so Word users keep the
51
+ styled tables. Test coverage in
52
+ `tests/test_postprocess.py`. Resolves the `[1.1.1] — Known
53
+ issues` entry below.
54
+
55
+ ### Removed
56
+ - `md2star/gui_server.py` (the GUI HTTP server).
57
+ - `md2star/data/gui/` (vendored Tailwind / CodeMirror / PDF.js / fonts).
58
+ - `tests/test_gui_security.py` (`/fs/*` path-confinement tests).
59
+ - `scripts/vendor_gui.sh` and the `make vendor` target.
60
+ - `md2star html` standalone-HTML subcommand (it existed solely for
61
+ the GUI preview pane).
62
+ - The `[Public Domain]` classifier in `pyproject.toml`, replaced by
63
+ `[OSI Approved :: BSD License]`.
64
+
65
+ ## [1.3.0] — 2026-06-23
66
+
67
+ ### Added
68
+ - **AI-drafted alt-text for empty image alts** — when `--lint` is on
69
+ and Ollama is reachable, every `![](src)` whose alt is empty is
70
+ described by a local vision model and the rewritten `![<alt>](src)`
71
+ is what Pandoc sees. URLs, missing files, and non-empty alts pass
72
+ through untouched. Same opt-in surface as the LLM Markdown lint —
73
+ alt-text drafting *is* a form of lint, so it sits behind the same
74
+ `--lint` flag (and `--offline` blocks it just like the text lint).
75
+ Default vision model is whatever the text lint already uses
76
+ (`gemma4:e2b-mlx` on macOS, `gemma4:e2b` elsewhere) — the gemma4
77
+ family is multimodal, so a single `ollama pull` powers both passes.
78
+ Override with `MD2STAR_ALT_TEXT_MODEL` to point alt-text at a
79
+ different vision model. Per-image results are cached at
80
+ `$XDG_CACHE_HOME/md2star/alt-text/<image-md5>_<model>.txt` so reruns
81
+ over the same source tree do not re-query Ollama.
82
+
83
+ ## [1.2.0] — 2026-06-23
84
+
85
+ ### Added
86
+ - **Branded Mermaid palette** — every rendered diagram now uses the
87
+ Warith colour system from
88
+ [harchaoui.org/warith/colors](https://harchaoui.org/warith/colors):
89
+ light-blue node fills (`#CCE4FF`) with blue borders (`#007AFF`),
90
+ grey edges (`#808080`), light-yellow notes (`#FFF5CC`), and matching
91
+ actor / activation / cluster colours for sequence and gantt
92
+ diagrams. The bundled `mermaid-config.json` switched from `neutral`
93
+ to `base` plus a full `themeVariables` block. Re-rendering is
94
+ automatic — the render-cache key now folds in the resolved config
95
+ hash, so palette edits invalidate stale PNGs on the next run.
96
+ - **Aspect-ratio-aware image cap (A4)** — bare `![](…)` images get a
97
+ `{width=15cm}` *or* `{height=17cm}` block based on the image's
98
+ pixel aspect ratio, so the rendered diagram or photo fits an A4
99
+ page in *both* dimensions. Applies uniformly to mermaid renders,
100
+ embedded photos, downloaded remote images, and SVG-to-PNG
101
+ conversions. URLs and unreadable files keep the previous
102
+ `{width=100%}` fallback.
103
+
104
+ ### Fixed
105
+ - **Pandoc 3.6 Lua filter crash on tables** — `pandoc.utils.stringify`
106
+ no longer accepts a `Cell` userdata directly; the filter now passes
107
+ `cell.contents` so DOCX / PPTX builds work on Pandoc 3.6+ across
108
+ the whole table-styling path.
109
+ - **Python 3.10 / 3.11 `_data_path` crash** —
110
+ `MultiplexedPath.joinpath` only accepted one argument per call on
111
+ 3.10–3.11; walking the components one at a time restores the
112
+ multi-segment `_data_path("filters", "md2star.lua")` form.
113
+ - **Windows date-format crash** — Windows' MSVCRT `strftime` rejects
114
+ `%e` (a GNU extension). The Lua filter now expands `%e` to the
115
+ literal day-of-month before handing the format string to
116
+ `os.date`.
117
+ - **Mermaid rendering on Ubuntu 24.04+ CI runners** — Puppeteer's
118
+ default sandbox is blocked by AppArmor user-namespace restrictions
119
+ on recent Linux distros. A bundled `puppeteer-config.json` passes
120
+ `--no-sandbox --disable-setuid-sandbox` to mmdc so headless Chrome
121
+ starts cleanly.
122
+ - **Bundled templates ship in the wheel** — `template.docx` and
123
+ `template.pptx` were silently excluded by the blanket `*.docx` /
124
+ `*.pptx` gitignore rules. Allow-listed under `md2star/data/` so
125
+ the built sdist / wheel always carry them.
126
+
127
+ ## [1.1.1] — 2026-06-21
128
+
129
+ ### Added
130
+ - **`assets/example.md`** — the canonical default demo content. The
131
+ GUI's `/example` endpoint serves it; the editor loads it as the
132
+ initial document when no localStorage / server draft is present.
133
+ Also used as the default in screenshots and any future demo runs.
134
+ - **`md2star html`** (and `md2html` if you alias it) — pandoc-only
135
+ HTML5 output path. Standalone document with MathML, inline CSS via
136
+ the bundled `preview.css`. Useful as a fast preview or for
137
+ publishing markdown to a website without the full Office pipeline.
138
+ - **GUI Save button** (replaces the old Clear button) — forces the
139
+ 4 s auto-save to run RIGHT NOW. Writes to `/fs/save` when a real
140
+ file is loaded; falls back to the XDG draft cache otherwise. Status
141
+ bar confirms the destination.
142
+
143
+ ### Fixed
144
+ - **`md2pdf` first-invocation crash** — the collision check used
145
+ `Path.samefile(out_path)` which raises `FileNotFoundError` when the
146
+ output PDF doesn't exist yet (i.e. every first run). Replaced with
147
+ an unconditional `.md2star.tmp.docx` sidecar so md2pdf can never
148
+ stomp a user's real `.docx` even on a repeat run.
149
+ - **GUI pane-header heights are now uniform** (`min-h-9` on every
150
+ sidebar / editor / preview header bar) so the three columns'
151
+ filename rows line up regardless of which buttons live in each.
152
+
153
+ ### Known issues
154
+ - **Tables in the live PDF preview render with empty cells** in some
155
+ environments — the cell contents leak below the table border as a
156
+ vertical paragraph dump. Root cause is an interaction between the
157
+ bundled `template.docx` styles (specifically the `TableNormal0`
158
+ custom-style on top of pandoc's "Compact" cell paragraph) and
159
+ LibreOffice's headless renderer. Workarounds while a deeper fix
160
+ lands: (a) export to DOCX and open in Word, which renders the
161
+ table correctly; (b) write tables as raw `<table>` HTML inside the
162
+ markdown — those are passed through and styled by your reference
163
+ template; (c) avoid the preview rendering of tables and trust the
164
+ DOCX export. The DOCX itself is well-formed; only the soffice →
165
+ PDF intermediate stumbles.
166
+
167
+ ## [1.1.0] — 2026-06-21
168
+
169
+ ### Added
170
+ - **`md2pdf` / `md2star pdf`** — first-class PDF output. Internally runs
171
+ the DOCX pipeline (so mermaid, table styles, slide-aware tweaks all
172
+ apply) then renders to PDF via headless LibreOffice
173
+ (`soffice --headless --convert-to pdf`). Honors every flag `md2docx`
174
+ accepts (`--author`, `--bib`, `--lang`, `--date`, `--skip-phase`,
175
+ `--lint`, `--reference-doc`).
176
+ - **`--date "string"` CLI flag** (and matching GUI field) overrides
177
+ the auto-localized date in the subtitle. Lets authors backdate,
178
+ post-date, or stamp a non-date label ("Draft 2", "Q2 2026",
179
+ "submitted 14 March") without fighting the auto-locale path. The
180
+ Lua filter gains a `date_override` metadata branch that takes
181
+ priority over `date_format`.
182
+ - **`md2star gui`** — Overleaf-style local web editor. Highlights:
183
+ - CodeMirror 6 Markdown editor (left) + PDF.js preview (right).
184
+ - Debounced auto-render ~2.5 s after typing pause; **⌘↵** / **Ctrl ↵**
185
+ forces a preview-only render (never downloads).
186
+ - Format pill (PDF / DOCX / PPTX) with uniform **"Export X"** buttons.
187
+ Clicking exports + downloads in the chosen format and refreshes the
188
+ PDF preview.
189
+ - **Folder browser sidebar**: Open a folder (native macOS picker via
190
+ `osascript`, `zenity`/`kdialog` on Linux, `FolderBrowserDialog` on
191
+ Windows, or paste a path). Sidebar shows the tree with expandable
192
+ subdirectories. Click an `.md` to load (and any edits auto-save
193
+ back to that file). Non-`.md` files are visible but click-disabled.
194
+ `+` creates a new `.md`, `🗑` deletes selected files (multi-select
195
+ via checkboxes; only `.md` is ever deleted as a safety guard).
196
+ - **Server-side auto-save**: every edit persists 4 s after the last
197
+ keystroke. Routes to `/fs/save` when a real file is open;
198
+ otherwise to `$XDG_CACHE_HOME/md2star/drafts/last.md` as a
199
+ safety net. `navigator.sendBeacon` fires on tab close so the
200
+ very last edit can't get lost in the debounce window.
201
+ - **Theme toggle** (🌗 Auto / 🌞 Light / 🌚 Dark). Auto follows the
202
+ system `prefers-color-scheme`; choice persists in localStorage.
203
+ - **Custom reference templates**: two upload buttons in the options
204
+ drawer ("Load DOCX template" / "Load PPTX template") let the user
205
+ swap the bundled defaults for the active session. The uploaded
206
+ file lives in a per-process tempdir and is removed on
207
+ `/template/clear`.
208
+ - Backend is stdlib `http.server` on 127.0.0.1 only; no
209
+ authentication (single-user laptop tool, same model as Jupyter).
210
+ - **WCAG-AA-compliant color tokens** lifted from
211
+ `https://harchaoui.org/warith/colors/` (full base palette + light
212
+ variants, semantic aliases for surface / label / brand). Uniform
213
+ **10 px corner radius** across every container, button, input,
214
+ drawer, chip, and PDF-page card.
215
+ - **Install-time LibreOffice check**: `scripts/install.sh` /
216
+ `scripts/install.ps1` auto-install LibreOffice via Homebrew /
217
+ apt / dnf / pacman / winget when `soffice` is missing, so
218
+ `md2pdf` and the GUI preview pane work out of the box. Pass
219
+ `--no-libreoffice` (or `-NoLibreOffice` on Windows) to opt out.
220
+ - **Two-line subtitle** (authors on line 1, date on line 2) — the
221
+ Lua filter emits two `<w:p>` paragraphs inside the `Subtitle`
222
+ custom-style Div, both styled identically. Long author lists no
223
+ longer collide with the date on a single line.
224
+ - **Natural-language author list**: a comma-separated `--author`
225
+ string is rewritten as "X" / "X and Y" / "X, Y and Z". The
226
+ conjunction follows the document language: English "and",
227
+ French "et", Spanish "y", German "und", Italian/Portuguese "e",
228
+ Dutch "en", Russian "и"; falls back to "and" for any other.
229
+
230
+ ### Changed
231
+ - **GUI is now fully offline.** Tailwind, CodeMirror, PDF.js (worker
232
+ included), Montserrat, and Roboto Serif are vendored under
233
+ `md2star/data/gui/vendor/` (~3.1 MB) and served from the local
234
+ `/vendor/*` paths. `md2star gui` makes zero CDN calls at runtime.
235
+ Refresh script: `make vendor` (requires `curl` + `node`).
236
+ - **CodeMirror is bundled as one esbuild artifact** (not 5 separate
237
+ esm.sh URLs) — separate bundles would each carry their own
238
+ `EditorState` constructor and `instanceof` checks would silently
239
+ break the editor.
240
+ - **Dropped JetBrains Mono** as the editor font; the OS's own system
241
+ monospace stack (`ui-monospace`, `SFMono-Regular`, `Menlo`,
242
+ `Monaco`, `Consolas`) is enough and saves ~100 kB of vendored
243
+ fonts. Added **Roboto Serif** as the serif token
244
+ (`class="font-serif"`) alongside Montserrat for sans.
245
+ - **deraison.ai template fetch** now caches the downloaded template
246
+ in `$XDG_CACHE_HOME/md2star/templates/` instead of dropping a
247
+ ~2 MB / 16 MB file next to every source `.md`. First download
248
+ prints one breadcrumb; subsequent runs are silent. Users still
249
+ get per-project branding by placing their own `template.{docx,pptx}`
250
+ next to the source.
251
+
252
+ ### Fixed
253
+ - **`pyproject.toml` wheel-build failure**: removed the
254
+ `[tool.hatch.build.targets.wheel.force-include]` block that was
255
+ duplicating `md2star/data/` (already covered by `packages =
256
+ ["md2star"]`) and breaking `pipx install`.
257
+ - **GUI preview-empty placeholder stayed visible** after the first
258
+ successful render. Tailwind's `display: grid` on the placeholder
259
+ beat the browser's `[hidden] { display: none }` UA rule. Switched
260
+ to `.classList.add("hidden")` (Tailwind's `display: none
261
+ !important`).
262
+ - **Cache-busting**: GUI server splices a per-process random tag
263
+ into every static-asset URL so stale browsers can't keep serving
264
+ pre-restart `app.js` / `codemirror.js` / `pdf.min.mjs`.
265
+
266
+ ### Notes
267
+ - The folder-browser endpoints (`/fs/*`) confine every operation to
268
+ the user-chosen root via `_safe_within_root` (rejects `..`,
269
+ absolute paths, symlink escapes). Delete refuses anything that
270
+ isn't `.md`/`.markdown`. Localhost-only, no auth — same trust
271
+ model as Jupyter or Vite dev. Don't expose to the LAN.
272
+
273
+ ## [1.0.0] — 2026-06-20
274
+
275
+ The first proper release. The legacy "git clone + `make install`" workflow
276
+ is replaced by a real Python package; the bash / PowerShell / cmd CLI
277
+ wrappers are replaced by a single Python entry-point module.
278
+
279
+ ### Added
280
+ - **`pyproject.toml`** — md2star is now a real installable Python package
281
+ (`pip install -e .` for dev, `pipx install .` for end users).
282
+ - **Console scripts** `md2docx`, `md2pptx`, and `md2star` are registered
283
+ via `[project.scripts]` and implemented once in `md2star/cli.py`.
284
+ - **`md2star/cache.py`** — every on-disk artifact (downloaded remote
285
+ images, downscaled rasters, cell-fitted images, SVG→PNG renders, mermaid
286
+ PNGs) now lives under `$XDG_CACHE_HOME/md2star/` (or the platform
287
+ equivalent on macOS / Windows). The user's source directories stay clean.
288
+ - **`md2star clear-cache`** and **`md2star cache-dir`** subcommands.
289
+ - **`--skip-phase NAME`** CLI flag (repeatable) and matching
290
+ `md2star_skip:` YAML front-matter key. Twelve named phases are
291
+ addressable: `lint`, `remote_images`, `html_tables`, `html_images`,
292
+ `absolutize`, `image_assets`, `language`, `line_pass`, `table_resize`,
293
+ `table_normalize`, `image_widths`, `pptx_isolation`.
294
+ - **`MD2STAR_LINT_MODEL`** environment variable to override the default
295
+ Ollama lint model without editing code.
296
+ - **GitHub Actions CI** (`.github/workflows/ci.yml`) — pytest matrix on
297
+ Python 3.10–3.13, integration suite on Ubuntu + macOS + Windows,
298
+ `shellcheck` on the install scripts.
299
+ - **Lua filter unit tests** (`tests/test_lua_filter.py`) — title
300
+ extraction, subtitle injection, French date rendering, heading-ID
301
+ strip, DOCX horizontal-rule → page break.
302
+ - **Postprocess unit tests** (`tests/test_postprocess.py`) —
303
+ `inject_table_styles` idempotency, partial-pre-existence, byte-identical
304
+ preservation of unrelated zip entries.
305
+ - **`CONTRIBUTING.md`** with quickstart (`make dev` + pytest) and PR
306
+ checklist.
307
+
308
+ ### Changed
309
+ - **Install path** is now `pipx install .` (or `make install`). The old
310
+ `bash scripts/install.sh` writes a thin wrapper that just shells to
311
+ pipx; the 150+ lines of heredoc'd shell CLI are gone.
312
+ - **`scripts/test.sh`** no longer mutates `pandoc/metadata.yaml` mid-run
313
+ (which left the repo dirty on Ctrl-C). French date / language is now
314
+ passed via `--lang fr-FR --metadata date_format=...` per call.
315
+ - **Repo size shrunk by ~40 MB** — the regenerable `.docx` / `.pptx`
316
+ fixtures under `tests/examples/` are no longer committed (sources are
317
+ kept; outputs are produced by `tests/examples/run.sh`).
318
+ - **Default reference templates** are now bundled inside the wheel
319
+ (`md2star/data/template.{docx,pptx}`) so a fresh install works fully
320
+ offline. The `https://deraison.ai/template.{docx,pptx}` fallback is
321
+ still consulted when no `template.{docx,pptx}` sits next to the input
322
+ Markdown (preserved per project owner's request).
323
+ - **`make uninstall`** now prints what it will remove and prompts `[y/N]`.
324
+ Pass `--yes` to skip the prompt in CI.
325
+
326
+ ### Fixed
327
+ - The committed `tests/examples/.preprocessed_63am_59p.md` artifact (a
328
+ stale temp file) is removed from the repo. The `.gitignore` rule that
329
+ excludes it was already in place.
330
+ - Image cache filenames now use a hash of the source path, eliminating
331
+ the rare collision when two source files with the same basename lived
332
+ in different directories.
333
+
334
+ ### Notes
335
+ - The `gemma4:e2b` (Linux/Windows) and `gemma4:e2b-mlx` (macOS) default
336
+ lint models are confirmed published Ollama tags and remain the default.
337
+ - A WYSIWYG markdown editor / local GUI is planned for v1.1.0, building
338
+ on the `front-ui` + `front-cli-gui` Claude Skills.
@@ -0,0 +1,148 @@
1
+ # Contributing to md2star
2
+
3
+ Thanks for considering a contribution. md2star is a small project with one
4
+ maintainer — small, well-scoped PRs are very welcome.
5
+
6
+ ## Quickstart
7
+
8
+ ```bash
9
+ git clone https://github.com/warith-harchaoui/md2star.git
10
+ cd md2star
11
+
12
+ # Create a dev venv at .venv/ and install the package editable + dev extras.
13
+ make dev
14
+
15
+ # Activate it (or use ./.venv/bin/<tool> directly).
16
+ source .venv/bin/activate
17
+
18
+ # Run the test suite.
19
+ python -m pytest tests/ -v
20
+
21
+ # Run the integration suite (needs pandoc + the package installed).
22
+ make test
23
+ ```
24
+
25
+ `make dev` is the only setup step. `pyproject.toml` declares everything
26
+ else (runtime deps, dev deps, console scripts, package data).
27
+
28
+ ## Project layout
29
+
30
+ - `md2star/` — the importable Python package.
31
+ - `cli.py` — the single source of truth for `md2docx` / `md2pptx` /
32
+ `md2pdf` / `md2star`. There used to be a bash wrapper, a PowerShell
33
+ wrapper, and a `.cmd` wrapper. Don't bring them back.
34
+ - `doctor.py` — `md2star doctor` environment diagnostic.
35
+ - `preprocessing/` — the 12-phase Markdown preprocessor. The order
36
+ is in `pipeline.py` and is *load-bearing*; reordering needs a
37
+ correctness argument.
38
+ - `postprocess.py` — DOCX-only zip rewrite that re-injects the
39
+ `MyTable` / `MyTableSmall` styles Pandoc strips. Idempotent.
40
+ - `cache.py` — XDG cache dir resolver. Override with
41
+ `MD2STAR_CACHE_DIR` (tests do this via the autouse fixture).
42
+ - `data/` — bundled package data (Lua filter, defaults YAMLs,
43
+ templates, Mermaid config).
44
+ - `tests/` — pytest suite. `conftest.py` redirects the cache to `tmp_path`
45
+ for every test. The three files:
46
+ - `test_preprocessing.py` (~80 tests) — the line-level pipeline.
47
+ - `test_postprocess.py` — DOCX style re-injection.
48
+ - `test_lua_filter.py` — the Pandoc Lua filter (drives pandoc as a
49
+ subprocess; skipped when pandoc is not on PATH).
50
+ - `scripts/` — `install.sh` / `uninstall.sh` / `test.sh` and their
51
+ PowerShell siblings. Thin wrappers; the real install path is `pipx`.
52
+ - `docs/developer_guide.md` — architectural notes (the why, not the what).
53
+
54
+ ## PR checklist
55
+
56
+ Before opening a PR:
57
+
58
+ - [ ] `python -m pytest tests/ -v` is green.
59
+ - [ ] `ruff check md2star/ tests/` is clean (no new warnings).
60
+ - [ ] If you touched the Lua filter, the integration suite still passes
61
+ (`make test`) — pytest alone does not cover end-to-end DOCX output.
62
+ - [ ] If you added a new preprocessing phase, register its name in
63
+ `md2star.preprocessing.pipeline.PHASES` so `--skip-phase` knows
64
+ about it, and add at least one test in `tests/test_preprocessing.py`
65
+ covering the skip behavior.
66
+ - [ ] No new files in `tests/examples/` larger than ~50 kB unless you've
67
+ checked it in via Git LFS. The regenerable demos live there as
68
+ Markdown only; their `.docx` / `.pptx` outputs are produced by
69
+ `tests/examples/run.sh` and intentionally not committed.
70
+ - [ ] If you added user-facing flags, update both `README.md` and
71
+ `LISEZMOI.md` (and `CHANGELOG.md`'s `## [Unreleased]` section).
72
+ - [ ] If you added a network-touching code path, route it through the
73
+ `--offline` / `--allow-remote-*` gates (see `md2star/cli.py`
74
+ and the contract in `SECURITY.md`).
75
+ - [ ] All `.py` files you add or modify keep a module header docstring
76
+ with an Author block linking to
77
+ [Warith HARCHAOUI](https://linkedin.com/in/warith-harchaoui/),
78
+ NumPy-style docstrings on every public function/class, and full
79
+ type annotations.
80
+
81
+ ## Conventions
82
+
83
+ - **One short docstring per module / public function.** The codebase
84
+ already documents *why*, not *what* — keep that bias.
85
+ - **No backward-compat shims** unless you can name a real outside caller
86
+ that relies on the old API. This is a small, single-author project; do
87
+ the rename and update the imports.
88
+ - **Don't add features beyond the PR's stated scope.** A bug fix doesn't
89
+ need surrounding cleanup; a refactor doesn't need to also touch the
90
+ CHANGELOG format. Smaller diffs review faster.
91
+
92
+ ## Rebuilding the bundled templates
93
+
94
+ `md2star/data/template.docx` and `md2star/data/template.pptx` ship the
95
+ branded reference docs that every conversion picks up by default. They
96
+ were rebuilt in v2.0.0 from a Pandoc-clean baseline so soffice renders
97
+ tables as proper grids (vs the v1.x vertical-dump bug).
98
+
99
+ To regenerate either from scratch:
100
+
101
+ 1. Dump Pandoc's built-in reference (has every named style /
102
+ layout):
103
+
104
+ pandoc --print-default-data-file reference.docx > /tmp/ref.docx
105
+ pandoc --print-default-data-file reference.pptx > /tmp/ref.pptx
106
+
107
+ 2. Write a comprehensive markdown source that exercises every
108
+ element you want to style. The two we used for v2.0 live in
109
+ `.private/template-source.md` (DOCX) and
110
+ `.private/template-pptx-source.md` (PPTX) — copy them as a
111
+ starting point.
112
+
113
+ 3. Render with the default ref:
114
+
115
+ pandoc src.md -o branded.docx --reference-doc=/tmp/ref.docx
116
+ pandoc src.md -o branded.pptx --reference-doc=/tmp/ref.pptx
117
+
118
+ 4. Open in Word / PowerPoint / Keynote / LibreOffice and brand:
119
+ fonts, colours, margins, logo in headers / slide masters,
120
+ etc. Don't rename existing styles — pandoc looks them up by
121
+ name (`Heading1`, `Title`, `Hyperlink`, ...). For PPTX, the
122
+ layout names must match the pandoc set: `Title Slide`,
123
+ `Section Header`, `Title and Content`, `Two Content`,
124
+ `Comparison`, `Content with Caption`, `Blank`, `Title Only`,
125
+ `Picture with Caption`.
126
+
127
+ 5. Save back to `md2star/data/template.docx` /
128
+ `md2star/data/template.pptx` and verify:
129
+
130
+ md2docx assets/docx/basic.md && md2pdf assets/docx/basic.md
131
+ md2pptx assets/pptx/example.md
132
+
133
+ The tables in the PDF should render as a proper grid (not a
134
+ column-major vertical dump); pandoc should not warn about
135
+ missing layout names on the PPTX.
136
+
137
+ ## Reporting bugs
138
+
139
+ Open an issue with: the input Markdown that triggers the bug, the exact
140
+ command you ran, the full stderr output, and your `md2star --version` /
141
+ `pandoc --version`. If the bug is in DOCX/PPTX output, attaching the
142
+ produced file is much faster than a long description.
143
+
144
+ ## Licence
145
+
146
+ By contributing you agree your contributions are released under the
147
+ **BSD 3-Clause License**, the same licence as the rest of the project.
148
+ See [LICENSE](LICENSE) for the full text.