Markdown to polished .docx output, without the cleanup pass.
Project description
Folio
Markdown to polished .docx output, without the cleanup pass.
Folio is a cross-platform desktop application and Rust workspace for turning Markdown into Microsoft Word documents with native Word structures instead of brittle export artifacts. The focus is practical fidelity: editable equations, sane image sizing, readable tables, predictable heading hierarchy, and output that looks intentional when it opens in Word or LibreOffice.
Quick Start
For most users
The simplest way to use Folio on both macOS and Windows is to download a prebuilt installer from GitHub Releases.
At the moment, the published desktop releases are still experimental and may not work reliably on every machine. If you need the most dependable path today, use the CLI from source instead.
- macOS: download the
.dmgthat matches your CPU. - Apple Silicon: choose the
aarch64/arm64build. - Intel Mac: choose the
x64build. - Open the
.dmg, then drag Folio into Applications. - Windows: download the NSIS
.exeinstaller for the simplest setup.
Because Folio is still pre-alpha and may be unsigned, the first launch may show a platform warning:
- macOS: right-click Folio in Applications and choose Open the first time if Gatekeeper blocks it.
- Windows: if SmartScreen appears, click More info -> Run anyway.
If you want to build from source
Use the development setup below only if you want to contribute or run the app from source.
Recommended CLI Usage
If the desktop release does not work for you yet, the CLI is the recommended fallback.
macOS:
cd /path/to/Folio
cargo run -p scribe-cli -- "/absolute/path/input.md" -o "/absolute/path/output.docx"
Windows (PowerShell):
cd C:\path\to\Folio
cargo run -p scribe-cli -- "C:\absolute\path\input.md" -o "C:\absolute\path\output.docx"
You can also omit -o, and Folio will write <input>.docx next to the source Markdown file.
Python (preview)
Folio is also published as a Python wheel for users who want to embed the conversion in scripts, notebooks, or pipelines.
pip install folio-docx
import folio
# Markdown string -> .docx bytes
docx_bytes = folio.convert("# Hello\n\n$E = mc^2$")
# Markdown file -> .docx file (relative image paths are resolved
# against the input file's parent directory)
folio.convert_file("paper.md", "paper.docx")
# Live HTML preview
html = folio.preview_html("# Title\n\nbody")
The wheel ships as cp38-abi3, so a single download works on every CPython 3.8+ on macOS (Apple Silicon + Intel), Linux x86_64 + aarch64, and Windows x64. The conversion runs entirely in Rust — convert() releases the GIL, so multiple threads can render in parallel.
Templates
The output's fonts, sizes, headings, code style, and paragraph spacing all come from a Word style sheet. Folio ships built-in themes for the common cases and accepts your own reference .docx for everything else.
Built-in themes
# Pick a theme by name. Use --list-themes to see what ships.
scribe-cli paper.md --theme academic -o paper.docx
scribe-cli paper.md --theme thesis-cn -o paper.docx
scribe-cli --list-themes
import folio
folio.convert(md, theme="academic")
folio.list_themes() # ["academic", "thesis-cn"]
| Theme | Use it for |
|---|---|
academic |
English academic paper. Times New Roman 12pt body, 1.5 line height, classic heading hierarchy. |
thesis-cn |
中文学位论文。宋体正文 + 黑体标题,1.5 倍行距,首行缩进 2 字符。 |
report |
Modern business report. Calibri sans-serif, blue heading accents, tighter line spacing. |
Bring your own template
Pandoc-style: hand a styled .docx to Folio and your output adopts its styles wholesale.
scribe-cli paper.md --reference-doc thesis-template.docx -o paper.docx
folio.convert(md, reference_doc="thesis-template.docx")
Anything you can do in Word — fonts, colors, paragraph spacing, table styles, list bullets — flows through verbatim. Open the template in Word, edit the styles, save, and Folio's next run picks them up. --reference-doc and --theme are mutually exclusive.
Why Folio
Most Markdown-to-DOCX workflows break down in the last 10%:
- math is flattened into images or mangled XML
- lists and tables need manual repair
- images overflow, shrink unpredictably, or lose aspect ratio
- report and academic formatting still needs hand cleanup in Word
Folio is built to close that gap with a pure Rust pipeline and a desktop UX around it.
Sample Export
The samples below are generated from the comprehensive regression fixture in test/folio-comprehensive.md, exported to test/output/folio-comprehensive.docx, and rendered from the corresponding PDF.
|
|
|
|
| Page 1 Formatting, lists, code, and tables |
Page 2 Math and raster logo embedding |
Page 3 SVG assets and footnotes |
Download DOCX · Open PDF · View Source Markdown
The current sample exercises:
- heading hierarchy
- inline emphasis, code, and links
- unordered, ordered, and task lists
- blockquotes and code blocks
- aligned tables
- inline and display LaTeX math rendered as editable OMML
- raster and SVG image embedding
- footnotes
WPS Spot Check vs Pandoc
The comparison below uses the same source note rendered as .docx, then opened in WPS Office for a practical end-user check.
|
|
|
| Folio | Pandoc |
In this note, Folio is materially stronger than Pandoc in the places that matter most for technical writing:
- formula-heavy sections stay closer to the intended reading order instead of collapsing into inline-like fragments
- image + heading + paragraph blocks hold together more predictably across pages
- long structured notes stay denser and cleaner instead of ballooning into many extra pages
What Works Today
Folio is still pre-alpha, but the core conversion path is already structured as a serious multi-crate system rather than a prototype script.
Implemented today:
- Markdown parsing with CommonMark and GFM features
- typed AST for downstream transforms
- LaTeX -> MathML -> OMML conversion
- image loading, normalization, and SVG rasterization
- DOCX emission with styles, numbering, footnotes, tables, and images
- HTML preview rendering for the desktop app
- Tauri desktop shell with a Svelte frontend
Not complete yet:
- reference-template ingestion from user
reference.docx - richer academic presets and style packs
- cross-references and auto-numbered figures, tables, and equations
- batch conversion UX polish
- higher-fidelity preview parity
Technology Stack
Core conversion engine
- Rust stable workspace
pulldown-cmarkfor Markdown parsinglatex2mathmlplus a customMathML -> OMMLtransformerdocx-rsfor OpenXML document generationimageandresvgfor raster and SVG asset handlingsyntectfor syntax highlightingzipandquick-xmlfor DOCX package post-processing
Desktop app
- Tauri 2 for the native desktop shell
- Svelte 5 + SvelteKit for the frontend
- Vite for frontend build tooling
- Tailwind CSS 4 for styling
- TypeScript for the UI layer
Output model
- native Word paragraphs, runs, numbering, and footnotes
- editable OMML equations instead of screenshots
- embedded raster media for portable image rendering
- HTML preview generated from the same AST used for DOCX emission
Repository Layout
The product is branded as Folio. Internal crate and package names still use the historical scribe-* prefix for now so the workspace can evolve without a broad package rename.
crates/
scribe-ast Typed Markdown AST
scribe-parser Markdown -> AST
scribe-math LaTeX -> MathML -> OMML
scribe-images Image loading and sizing
scribe-highlight Code highlighting
scribe-template Template/style plumbing
scribe-docx AST -> .docx emission
scribe-preview AST -> HTML preview
scribe-core Shared orchestration API
scribe-tauri Desktop shell and frontend bridge
scribe-cli/ CLI wrapper for fixture testing
fixtures/ Focused sample inputs
test/ Comprehensive regression fixture and export artifacts
docs/ Design docs and README assets
Development
Requirements
- Rust stable
- Node.js 20+
pnpm
Install frontend dependencies
pnpm --dir crates/scribe-tauri/frontend install
Run tests
cargo test --workspace
pnpm --dir crates/scribe-tauri/frontend check
Start the desktop app
cd crates/scribe-tauri
cargo tauri dev
Build the frontend only
pnpm --dir crates/scribe-tauri/frontend build
Shipping Releases
For end users, GitHub Releases should be the default distribution channel.
- Bump the workspace version in
Cargo.toml. - Create and push a tag such as
v0.1.2. - GitHub Actions will build and publish:
- macOS Apple Silicon
.dmg - macOS Intel
.dmg - Windows NSIS
.exe
- macOS Apple Silicon
The release workflow also generates platform icon assets from crates/scribe-tauri/icons/icon.png before bundling.
Fixture-Based Testing
The repository includes focused fixtures under fixtures/ and a comprehensive all-in-one regression fixture under test/.
Useful local commands:
cargo run -p scribe-cli -- fixtures/english/m2-kitchen-sink.md -o /tmp/folio-m2.docx
cargo run -p scribe-cli -- fixtures/english/m3-math.md -o /tmp/folio-m3.docx
cargo run -p scribe-cli -- test/folio-comprehensive.md -o test/output/folio-comprehensive.docx
soffice --headless --convert-to pdf --outdir test/output test/output/folio-comprehensive.docx
If you have LibreOffice installed, rendering generated .docx files to PDF and PNG is a practical way to inspect layout regressions before shipping changes.
Design Notes
Longer-form planning and design material lives here:
docs/superpowers/specs/2026-04-17-scribe-md-to-docx-design.mddocs/superpowers/plans/2026-04-17-scribe-v1-plan.md
GitHub Activity
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file folio_docx-0.2.0-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: folio_docx-0.2.0-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 3.3 MB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
128c2d8d566017514372cce2546b898d905947909b2ec78e9d64d3b7c8426b6a
|
|
| MD5 |
85a207fcb2da0853cf9a93419748dae7
|
|
| BLAKE2b-256 |
249b7cbe267db7652eb34fb07d9b4d654b681479a886ccd50e3939e0ebad5b39
|
Provenance
The following attestation bundles were made for folio_docx-0.2.0-cp38-abi3-win_amd64.whl:
Publisher:
python.yml on Livia-Tassel/Folio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
folio_docx-0.2.0-cp38-abi3-win_amd64.whl -
Subject digest:
128c2d8d566017514372cce2546b898d905947909b2ec78e9d64d3b7c8426b6a - Sigstore transparency entry: 1417931086
- Sigstore integration time:
-
Permalink:
Livia-Tassel/Folio@f932a97cc14f6a6064753d214b16a042f947d423 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Livia-Tassel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@f932a97cc14f6a6064753d214b16a042f947d423 -
Trigger Event:
push
-
Statement type:
File details
Details for the file folio_docx-0.2.0-cp38-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: folio_docx-0.2.0-cp38-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.5 MB
- Tags: CPython 3.8+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a5f3e03268c22c1f452f985711a6bf991eaea1eeb4c9e303df6d8f62ed37e7d
|
|
| MD5 |
6a1665c7bc7e1141f32340ddeb7bf0b9
|
|
| BLAKE2b-256 |
c8ef1f8312728f337adb35dbde5d9b6487c81d25d662ab2e151d83fa57a768e8
|
Provenance
The following attestation bundles were made for folio_docx-0.2.0-cp38-abi3-manylinux_2_28_x86_64.whl:
Publisher:
python.yml on Livia-Tassel/Folio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
folio_docx-0.2.0-cp38-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
3a5f3e03268c22c1f452f985711a6bf991eaea1eeb4c9e303df6d8f62ed37e7d - Sigstore transparency entry: 1417931208
- Sigstore integration time:
-
Permalink:
Livia-Tassel/Folio@f932a97cc14f6a6064753d214b16a042f947d423 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Livia-Tassel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@f932a97cc14f6a6064753d214b16a042f947d423 -
Trigger Event:
push
-
Statement type:
File details
Details for the file folio_docx-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: folio_docx-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.8+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e1206621aeebbbab621a0802469f7eb638f3e9ee79fbe1af200bafc63e8e8d5
|
|
| MD5 |
c71425e09e4500567d55231e0e8faf7b
|
|
| BLAKE2b-256 |
17eff79b6310f65e5feb0d3da92afd6c18b180031e418a3d1a678b44bcae5a8f
|
Provenance
The following attestation bundles were made for folio_docx-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl:
Publisher:
python.yml on Livia-Tassel/Folio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
folio_docx-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
5e1206621aeebbbab621a0802469f7eb638f3e9ee79fbe1af200bafc63e8e8d5 - Sigstore transparency entry: 1417931142
- Sigstore integration time:
-
Permalink:
Livia-Tassel/Folio@f932a97cc14f6a6064753d214b16a042f947d423 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Livia-Tassel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@f932a97cc14f6a6064753d214b16a042f947d423 -
Trigger Event:
push
-
Statement type:
File details
Details for the file folio_docx-0.2.0-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: folio_docx-0.2.0-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.2 MB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61506bc147691554cda04532b81eba925dc52b0a13716186c9e3b60c3c9b8d18
|
|
| MD5 |
b807bba46a9447207888e5093017ed32
|
|
| BLAKE2b-256 |
45dac1d120e5395f276b9ebc5e9026e53fdf0d694d9b1c708944a93943404fc6
|
Provenance
The following attestation bundles were made for folio_docx-0.2.0-cp38-abi3-macosx_11_0_arm64.whl:
Publisher:
python.yml on Livia-Tassel/Folio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
folio_docx-0.2.0-cp38-abi3-macosx_11_0_arm64.whl -
Subject digest:
61506bc147691554cda04532b81eba925dc52b0a13716186c9e3b60c3c9b8d18 - Sigstore transparency entry: 1417931011
- Sigstore integration time:
-
Permalink:
Livia-Tassel/Folio@f932a97cc14f6a6064753d214b16a042f947d423 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Livia-Tassel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python.yml@f932a97cc14f6a6064753d214b16a042f947d423 -
Trigger Event:
push
-
Statement type: