
Lovstudio:Any2pdf
- 6 installs
- Updated May 8, 2026
- lovstudio/any2pdf-skill
Helps with ai & agent building tasks.
About
lovstudio:any2pdf is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- lovstudio:any2pdf
- AI & Agent Building
- AI-coding skill
Lovstudio:Any2pdf by the numbers
- 6 all-time installs (skills.sh)
- Ranked #12,825 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lovstudio/any2pdf-skill --skill lovstudioany2pdfAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 6 |
|---|---|
| Last updated | May 8, 2026 |
| Repository | lovstudio/any2pdf-skill ↗ |
What it does
Helps with ai & agent building tasks.
Files
any2pdf — Markdown to Professional PDF
This skill converts any Markdown file into a publication-quality PDF using Python's reportlab library. It was developed through extensive iteration on real Chinese technical reports and solves several hard problems that naive MD→PDF converters get wrong.
When to Use
- User wants to convert
.md→.pdf - User has a markdown report/document and wants professional typesetting
- Document contains CJK characters (Chinese/Japanese/Korean) mixed with Latin text
- Document has fenced code blocks, markdown tables, or nested lists
- User wants a cover page, table of contents, or watermark in their PDF
Quick Start
python md2pdf/scripts/md2pdf.py \
--input report.md \
--output report.pdf \
--title "My Report" \
--author "Author Name" \
--theme warm-academicAll parameters except --input are optional — sensible defaults are applied.
Pre-Conversion Options (MANDATORY)
IMPORTANT: You MUST use the `AskUserQuestion` tool to ask these questions BEFORE running the conversion. Do NOT list options as plain text — use the tool so the user gets a proper interactive prompt. Ask all options in a SINGLE `AskUserQuestion` call.
Use AskUserQuestion with the following template. The tone should be friendly and concise — like a design assistant, not a config form:
开始转 PDF!先帮你确认几个选项 👇
━━━ 📐 设计风格 ━━━
a) 暖学术 — 陶土色调,温润典雅,适合人文/社科报告
b) 经典论文 — 棕色调,灵感源自 LaTeX classicthesis,适合学术论文
c) Tufte — 极简留白,深红点缀,适合数据叙事/技术写作
d) 期刊蓝 — 藏蓝严谨,灵感源自 IEEE,适合正式发表风格
e) 精装书 — 咖啡色调,书卷气,适合长篇专著/技术书
f) 中国红 — 朱红配暖纸,适合中文正式报告/白皮书
g) 水墨 — 纯灰黑,素雅克制,适合文学/设计类内容
h) GitHub — 蓝白极简,程序员熟悉的风格
i) Nord 冰霜 — 蓝灰北欧风,清爽现代
j) 海洋 — 青绿色调,清新自然
k) LaTeX 清爽 — pandoc+XeLaTeX 原生排版,无封面无装饰,干净学术风(需装 pandoc+texlive)
l) 咨询深蓝 — 深海军蓝色块 + 白底 + 大写左对齐标题,麦肯锡 / BCG / Deloitte 研究报告风格
━━━ 🖼 扉页图片(封面之后的全页插图) ━━━
1) 跳过
2) 我提供本地图片路径
3) AI 根据内容自动生成一张
━━━ 💧 水印 ━━━
1) 不加
2) 自定义文字(如 "DRAFT"、"内部资料")
可选调整:字号(默认52)、透明度(0-1)、角度(默认35°)、间距
━━━ 📇 封底物料(名片/二维码/品牌) ━━━
1) 跳过
2) 我提供图片
3) 纯文字信息
示例回复:"a, 扉页跳过, 水印:仅供学习参考, 封底图片:/path/qr.png"
直接说人话就行,不用记编号 😄Mapping User Choices to CLI Args
| Choice | CLI arg |
|---|---|
| Design style a-k | --theme with value from table below (k uses pandoc engine) |
| Frontispiece local | --frontispiece <path> |
| Frontispiece AI | Generate image first, then --frontispiece /tmp/frontispiece.png |
| Watermark text | --watermark "文字" |
| Watermark style | --wm-size 30 --wm-opacity 0.1 --wm-angle 45 (all optional) |
| Image as cover | --image-cover true (requires --frontispiece) |
| Back cover image | --banner <path> |
| Back cover text | --disclaimer "声明" and/or --copyright "© 信息" |
Theme Name Mapping
| Choice | --theme value | Inspiration |
|---|---|---|
| a) 暖学术 | warm-academic | Lovstudio design system |
| b) 经典论文 | classic-thesis | LaTeX classicthesis |
| c) Tufte | tufte | Edward Tufte's books |
| d) 期刊蓝 | ieee-journal | IEEE journal format |
| e) 精装书 | elegant-book | LaTeX ElegantBook |
| f) 中国红 | chinese-red | Chinese formal documents |
| g) 水墨 | ink-wash | 水墨画 / ink wash painting |
| h) GitHub | github-light | GitHub Markdown style |
| i) Nord | nord-frost | Nord color scheme |
| j) 海洋 | ocean-breeze | — |
| k) LaTeX 清爽 | latex-clean | pandoc+XeLaTeX 原生排版,无封面 |
| l) 咨询深蓝 | consulting-navy | McKinsey / BCG / Deloitte deep-research report |
Handling AI-Generated Frontispiece
If user chose AI generation: read the document title + first paragraphs, use an image generation tool to create a themed illustration matching the chosen design style, show for approval, then pass via --frontispiece /path/to/image.png
Architecture
Markdown → Preprocess (split merged headings) → Parse (code-fence-aware) → Story (reportlab flowables) → PDF buildKey components: 1. Font system: Palatino (Latin body), Songti SC (CJK body), Menlo (code) on macOS; auto-fallback on Linux 2. CJK wrapper: _font_wrap() wraps CJK character runs in <font> tags for automatic font switching 3. Mixed text renderer: _draw_mixed() handles CJK/Latin mixed text on canvas (cover, headers, footers) 4. Code block handler: esc_code() preserves indentation and line breaks in reportlab Paragraphs 5. Smart table widths: Proportional column widths based on content length, with 18mm minimum 6. Bookmark system: ChapterMark flowable creates PDF sidebar bookmarks + named anchors 7. Heading preprocessor: _preprocess_md() splits merged headings like # Part## Chapter into separate lines
Hard-Won Lessons
CJK Characters Rendering as □
reportlab's Paragraph only uses the font in ParagraphStyle. If fontName="Mono" but text contains Chinese, they render as □. Fix: Always apply _font_wrap() to ALL text that might contain CJK, including code blocks.
Code Blocks Losing Line Breaks
reportlab treats \n as whitespace. Fix: esc_code() converts \n → <br/> and leading spaces → , applied BEFORE _font_wrap().
CJK/Latin Word Wrapping
Default reportlab breaks lines only at spaces, causing ugly splits like "Claude\nCode". Fix: Set wordWrap='CJK' on body/bullet styles to allow breaks at CJK character boundaries.
Canvas Text with CJK (Cover/Footer)
drawString() / drawCentredString() with a Latin font can't render 年/月/日 etc. Fix: Use _draw_mixed() for ALL user-content canvas text (dates, stats, disclaimers).
Images Silently Dropped (Relative Paths)
 in a markdown file used to get skipped without warning because the image path was resolved against the current working directory, not the markdown's directory. Fix: main() now passes input_dir (the .md's directory) into the builder, and the image handler resolves relative paths against it. Missing images now also emit a WARN: image not found: ... to stderr instead of silently dropping.
Multi-Line Image References (pandoc --wrap=auto)
When feeding pandoc's output into md2pdf, pandoc's default --wrap=auto (72 cols) wraps long  across multiple lines, which defeated the single-line image regex. Fix: _preprocess_md() now collapses multi-line image references into one line (outside code fences) before parsing.
Pipeline tip: If you're piping HTML → markdown via pandoc, use pandoc --wrap=none input.html -o output.md to avoid wrap-related parsing issues for images and tables alike.
Input Format
This skill takes Markdown files only as input. If you have HTML, DOCX, or other formats, convert them to markdown first (e.g. pandoc --wrap=none). Embedded HTML blocks in markdown are passed through as text — pre-process any visual content (charts, complex tables) into plain markdown tables or image references before invoking md2pdf.
Configuration Reference
| Argument | Default | Description |
|---|---|---|
--input | (required) | Path to markdown file |
--output | output.pdf | Output PDF path |
--title | From first H1 | Document title for cover page |
--subtitle | "" | Subtitle text |
--author | "" | Author name |
--date | Today | Date string |
--version | "" | Version string for cover |
--watermark | "" | Watermark text (empty = none) |
--theme | warm-academic | Color theme name |
--theme-file | "" | Custom theme JSON file path |
--cover | true | Generate cover page |
--toc | true | Generate table of contents |
--page-size | A4 | Page size (A4 or Letter) |
--frontispiece | "" | Full-page image after cover |
--banner | bundled assets/backcover-banner.jpg | Back cover banner image (pass none to disable) |
--header-title | "" | Report title in page header |
--footer-left | author | Brand/author in footer |
--stats-line | "" | Stats on cover |
--stats-line2 | "" | Second stats line |
--edition-line | "" | Edition line at cover bottom |
--disclaimer | "" | Back cover disclaimer |
--copyright | "" | Back cover copyright |
--code-max-lines | 30 | Max lines per code block |
--image-cover | false | Use frontispiece as full-bleed cover (page 1), text cover becomes page 2 |
--heading-top-spacer | 5 | Top spacer before H1/H2 chapter titles in mm |
--wm-size | auto (half page width) | Watermark font size; auto-scales so text width ≈ 50% of page width |
--wm-opacity | 0.1 | Watermark opacity (0.0–1.0) |
--wm-angle | 35 | Watermark rotation angle in degrees |
--wm-spacing-x | 9999 | Watermark horizontal spacing in pt (≥2000 = single centered per page) |
--wm-spacing-y | 9999 | Watermark vertical spacing in pt (≥2000 = single centered per page) |
Themes
Available: warm-academic, nord-frost, github-light, solarized-light, paper-classic, ocean-breeze, consulting-navy.
Each theme defines: page background, ink color, accent color, faded text, border, code background, watermark tint.
Fallback: pandoc + XeLaTeX
When reportlab fails (e.g. wide/complex tables cause infinite loops in table width calculation), fall back to pandoc with XeLaTeX. This produces high-quality CJK PDFs with proper table handling.
When to use pandoc engine
- User chose
latex-cleantheme (k) — pandoc is the primary engine, not a fallback - Document has many wide multi-column tables (reportlab's table layout may hang)
- Document needs LaTeX-quality typesetting (justified text, hyphenation)
- reportlab md2pdf.py hangs or crashes on the input
Basic command
pandoc input.md -o output.pdf \ --pdf-engine=xelatex \ -V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \ -V geometry:margin=2.5cm -V fontsize=11pt \ --toc -V toc-title="目录" -V documentclass=article
Adding watermark + headers/footers
pandoc input.md -o output.pdf \ --pdf-engine=xelatex \ -V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \ -V geometry:margin=2.5cm -V fontsize=11pt \ -V colorlinks=true -V linkcolor=red -V toccolor=red -V urlcolor=red \ --toc -V toc-title="目录" -V documentclass=article \ -V header-includes=' \usepackage{fancyhdr} \pagestyle{fancy} \fancyhf{} \fancyhead[L]{\small 页眉左侧文字} \fancyhead[R]{\small 页眉右侧文字} \fancyfoot[C]{\thepage} \usepackage{draftwatermark} \SetWatermarkText{水印文字} \SetWatermarkScale{0.5} \SetWatermarkColor[gray]{0.9} '
Pandoc theme presets
Each preset defines a complete set of pandoc -V flags. Use the full command from "Adding watermark + headers/footers" above, replacing the color/link flags per preset.
| Theme | linkcolor | toccolor | urlcolor | Watermark color | Notes |
|---|---|---|---|---|---|
| chinese-red | red | red | red | [gray]{0.9} | 朱红正式,适合政企报告、白皮书 |
| warm-academic | brown | brown | brown | [gray]{0.9} | 陶土色调,温润学术风 |
| classic-thesis | brown | brown | brown | [gray]{0.85} | LaTeX classicthesis 灵感 |
| ieee-journal | blue | blue | blue | [gray]{0.9} | 藏蓝严谨,期刊风格 |
| github-light | blue | blue | blue | [gray]{0.92} | 极简蓝白,程序员友好 |
| ink-wash | black | black | black | [gray]{0.92} | 水墨素雅,文学/设计类 |
| nord-frost | teal | teal | teal | [gray]{0.9} | 北欧冰霜蓝灰 |
| consulting-navy | blue | blue | blue | [gray]{0.88} | 咨询深蓝,研究报告风 |
chinese-red 完整示例(本次一滕项目实际使用)
pandoc input.md -o output.pdf \ --pdf-engine=xelatex \ -V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \ -V geometry:margin=2.5cm -V fontsize=11pt \ -V colorlinks=true -V linkcolor=red -V toccolor=red -V urlcolor=red \ --toc -V toc-title="目录" -V documentclass=article \ -V header-includes=' \usepackage{fancyhdr} \pagestyle{fancy} \fancyhf{} \fancyhead[L]{\small 报告标题 | 品牌名} \fancyhead[R]{\small 商业机密} \fancyfoot[C]{\thepage} \usepackage{draftwatermark} \SetWatermarkText{商业机密} \SetWatermarkScale{0.5} \SetWatermarkColor[gray]{0.9} '
latex-clean 完整示例(最简洁的 LaTeX 学术风格)
选择 latex-clean 时,跳过 reportlab,直接使用 pandoc 生成。特点:无封面、无扉页、 无装饰色块,纯 LaTeX 排版 + 点线 TOC 引导符,适合内容为王的学术/技术文档。
pandoc input.md -o output.pdf \ --pdf-engine=xelatex \ -V CJKmainfont="Songti SC" -V mainfont="Palatino" -V monofont="Menlo" \ -V geometry:margin=2.5cm -V fontsize=11pt \ -V colorlinks=true -V linkcolor=brown -V toccolor=brown -V urlcolor=brown \ --toc -V toc-title="目录" -V documentclass=article
如需添加页眉页脚或水印,参考上方 "Adding watermark + headers/footers" 追加 -V header-includes。
Known limitations (pandoc fallback)
- No cover page (pandoc article class has no built-in cover — use
--include-before-bodywith a LaTeX snippet if needed) - Frontispiece/back cover not supported (use md2pdf.py for these)
→★☆symbols may warn in Palatino — they render via CJK font fallback, safe to ignore- ASCII art diagrams render as code blocks (same as md2pdf.py)
Dependencies (pandoc fallback)
Requires pandoc and a TeX distribution with XeLaTeX:
brew install pandoc brew install --cask mactex-no-gui # or basictex
Dependencies
pip install reportlab --break-system-packagesname: Auto Tag on main
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- '.github/**'
- 'cases/**'
- 'references/**'
permissions:
contents: write
jobs:
tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Skip if commit is from auto-tagger
id: skip
run: |
MSG=$(git log -1 --pretty=%s)
if echo "$MSG" | grep -qE '^(chore: bump version|v[0-9])'; then
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "skip=false" >> $GITHUB_OUTPUT
fi
- name: Read version from SKILL.md
if: steps.skip.outputs.skip == 'false'
id: ver
run: |
VER=$(grep -E '^ version:' SKILL.md | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
echo "version=$VER" >> $GITHUB_OUTPUT
echo "Current SKILL.md version: $VER"
- name: Bump patch version
if: steps.skip.outputs.skip == 'false'
id: bump
run: |
CUR="${{ steps.ver.outputs.version }}"
IFS='.' read -r MAJ MIN PAT <<< "$CUR"
NEW="$MAJ.$MIN.$((PAT+1))"
echo "new=$NEW" >> $GITHUB_OUTPUT
echo "Bumping: $CUR -> $NEW"
- name: Check tag doesn't already exist
if: steps.skip.outputs.skip == 'false'
id: check
run: |
TAG="v${{ steps.bump.outputs.new }}"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
- name: Update SKILL.md version and tag
if: steps.skip.outputs.skip == 'false' && steps.check.outputs.exists == 'false'
run: |
NEW="${{ steps.bump.outputs.new }}"
sed -i -E "s/(^ version: )\"[^\"]+\"/\1\"$NEW\"/" SKILL.md
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add SKILL.md
git commit -m "chore: bump version to $NEW"
git tag "v$NEW"
git push origin main --tags
- name: Extract release notes from CHANGELOG
if: steps.skip.outputs.skip == 'false' && steps.check.outputs.exists == 'false'
id: notes
run: |
NEW="${{ steps.bump.outputs.new }}"
if [ -f CHANGELOG.md ]; then
NOTES=$(awk -v ver="[$NEW]" '
/^## / { if (found) exit; if (index($0, ver)) { found=1; next } }
found { print }
' CHANGELOG.md)
fi
if [ -z "$NOTES" ]; then NOTES="Release v$NEW"; fi
{
echo 'notes<<EOF_NOTES'
echo "$NOTES"
echo 'EOF_NOTES'
} >> $GITHUB_OUTPUT
- uses: softprops/action-gh-release@v2
if: steps.skip.outputs.skip == 'false' && steps.check.outputs.exists == 'false'
with:
tag_name: v${{ steps.bump.outputs.new }}
name: v${{ steps.bump.outputs.new }}
body: ${{ steps.notes.outputs.notes }}
name: Release
on:
push:
tags: ['v*']
workflow_dispatch:
inputs:
tag:
description: 'Tag (e.g. v1.3.0)'
required: true
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get tag
id: tag
run: echo "tag=${{ github.event.inputs.tag || github.ref_name }}" >> $GITHUB_OUTPUT
- name: Extract release notes
id: notes
run: |
VERSION="${{ steps.tag.outputs.tag }}"
VERSION_NUM="${VERSION#v}"
if [ -f CHANGELOG.md ]; then
NOTES=$(awk -v ver="[$VERSION_NUM]" '
/^## / { if (found) exit; if (index($0, ver)) { found=1; next } }
found { print }
' CHANGELOG.md)
fi
if [ -z "$NOTES" ]; then NOTES="Release $VERSION"; fi
echo 'notes<<EOF' >> $GITHUB_OUTPUT
echo "$NOTES" >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.tag }}
name: ${{ steps.tag.outputs.tag }}
body: ${{ steps.notes.outputs.notes }}
[
{
"title": "季度技术复盘报告",
"description": "将团队技术复盘的 Markdown 笔记转为 warm-academic 主题 PDF,含封面、目录、水印,直接发给领导。",
"testimonial": "以前用 Word 排版一份报告要半天,现在一条命令 30 秒搞定,而且比 Word 好看太多了。",
"author": "赵工 · 技术主管"
},
{
"title": "开源项目文档 PDF 化",
"description": "把 GitHub 上的 README + 设计文档合并转为 ieee-journal 风格 PDF,用于学术引用和归档。",
"testimonial": "CJK 混排终于不用操心了,中英文、代码块、表格全部自动处理,排版效果堪比 LaTeX。",
"author": "Mike · 开源作者"
},
{
"title": "客户方案 PDF 交付",
"description": "用 chinese-red 主题将商务方案 Markdown 转为正式 PDF,带封面和公司水印,直接交付客户。",
"testimonial": "客户拿到 PDF 后以为我们有专门的设计师排版,其实就是一条命令。",
"author": "林总 · 咨询公司"
}
]
Changelog
All notable changes to this skill are documented here. Format: Keep a Changelog · Versioning: SemVer
[1.3.2] - 2026-04-20
Changed
- Watermark defaults: single centered mark per page at 0.1 opacity, auto-sized so text width ≈ half page width (previously a tiled grid at theme-dependent opacity with fixed font size 52). Override with
--wm-size / --wm-opacity / --wm-spacing-x / --wm-spacing-yas before. - Back cover banner defaults to the bundled
assets/backcover-banner.jpg(手工川 brand banner). Pass--banner noneto disable, or--banner <path>to use your own.
Added
assets/backcover-banner.jpg— bundled 手工川 branding banner so the default works for any user who clones the repo..github/workflows/auto-tag.yml— on push tomain, CI auto-bumps the patch version in SKILL.md, tags it, and pushes the tag (which triggers the existingrelease.yml).
[1.3.1] - 2026-04-20
Fixed
- Watermark: when
--wm-spacing-xand--wm-spacing-yare both ≥ 2000, render a single horizontally + vertically centered watermark (with baseline compensation) instead of tiling. Enables large single-mark watermarks (e.g.--wm-size 200 --wm-spacing-x 9999 --wm-spacing-y 9999).
[1.3.0] - 2026-04-20
Added
- New theme
consulting-navy— McKinsey / BCG / Deloitte deep-research-report aesthetic: navy hero cover block, ALL-CAPS section banners with thick left bar, left page-stripe, white canvas + serif body - New
cover_style: consulting-block— solid navy hero with white title + meta column strip (MODE / SOURCES / CONFIDENCE / DATE) - New
heading_decoration: banner— H2 renders as tinted box with thick accent left bar (inline, no page break) - New
SectionBannerflowable supporting CJK + Latin in section titles - Theme picker option
l) 咨询深蓝and pandoc preset row for the new theme
Fixed
_preprocess_mdnow strips full leading YAML frontmatter (--- ... ---); previously onlytitle:/subtitle:/author:/date:lines were filtered, so fields likemode:/tagline:leaked into the body as prose
[1.2.0] - 2026-04-13
Added
- Add latex-clean as official theme option (k) using pandoc+XeLaTeX engine
- New theme: latex-clean — pure LaTeX typography, no cover/decoration, clean academic style
- Pandoc is now a first-class engine choice, not just a fallback
[1.1.1] - 2026-04-13
Fixed
- Expand pandoc theme presets from link-color-only to full parameter sets
- Add complete pandoc -V flags table for 7 themes (linkcolor, toccolor, urlcolor, watermark)
- Add chinese-red full working example from 一滕 project
[1.1.0] - 2026-04-13
Added
- Add pandoc + XeLaTeX fallback engine for complex documents
- Document pandoc fallback with watermark, headers/footers, and theme-specific link colors
- Fallback triggered when reportlab hangs on wide/complex tables
- Updated skill description to mention dual-engine support
[1.0.1] - 2026-04-10
Fixed
- fix silent image drops: resolve relative paths against input md dir
- resolve relative image paths against the input markdown's directory (not cwd)
- warn on missing images instead of silently dropping them (stderr)
- collapse multi-line image refs in _preprocess_md so pandoc --wrap=auto output parses correctly
- SKILL.md: add Input Format section (markdown-only), document pandoc --wrap=none tip
- README.md: add version badge
lovstudio:any2pdf
Markdown to professionally typeset PDF with reportlab. CJK/Latin mixed text, code blocks, tables, cover pages, TOC, bookmarks, watermarks, and 14 color themes.
Part of lovstudio/skills — by lovstudio.ai
Install
npx skills add lovstudio/skills --skill lovstudio:any2pdfRequires: Python 3.8+ and pip install reportlab
Usage
python md2pdf.py --input report.md --output report.pdf --theme warm-academic| Option | Default | Description |
|---|---|---|
--input | (required) | Markdown file path |
--output | output.pdf | Output PDF path |
--title | From H1 | Cover page title |
--subtitle | Subtitle | |
--author | Author name | |
--theme | warm-academic | Color theme |
--watermark | Watermark text | |
--cover | true | Generate cover page |
--toc | true | Generate table of contents |
--frontispiece | Full-page image after cover |
Themes
| warm-academic | nord-frost | github-light | solarized-light |
|---|---|---|---|
| !warm-academic | !nord-frost | !github-light | !solarized-light |
| paper-classic | ocean-breeze | tufte | classic-thesis |
|---|---|---|---|
| !paper-classic | !ocean-breeze | !tufte | !classic-thesis |
| ieee-journal | elegant-book | chinese-red | ink-wash |
|---|---|---|---|
| !ieee-journal | !elegant-book | !chinese-red | !ink-wash |
| monokai-warm | dracula-soft |
|---|---|
| !monokai-warm | !dracula-soft |
License
MIT
Theme Reference
Each theme is a Python dict with these keys. All values are hex color strings.
Theme Structure
THEME = {
"canvas": "#F9F9F7", # page background
"canvas_sec": "#F0EEE6", # secondary bg (code blocks, alternating rows)
"ink": "#181818", # primary text
"ink_faded": "#87867F", # secondary text (subtitles, captions)
"accent": "#CC785C", # primary accent (headings, rules, table headers)
"accent_light":"#D99A82", # lighter accent
"border": "#E8E6DC", # borders, horizontal rules
"code_bg": "#F0EEE6", # code block background (usually = canvas_sec)
"watermark": (0.82, 0.80, 0.76, 0.12), # RGBA tuple for watermark
}Available Themes
warm-academic (default)
Warm ivory canvas with terracotta accents. Inspired by academic papers on aged paper. Best for: Chinese technical reports, research papers, documentation.
{"canvas":"#F9F9F7","canvas_sec":"#F0EEE6","ink":"#181818","ink_faded":"#87867F",
"accent":"#CC785C","accent_light":"#D99A82","border":"#E8E6DC"}nord-frost
Cool blue-gray palette from the Nord color scheme. Best for: Developer documentation, technical specs.
{"canvas":"#ECEFF4","canvas_sec":"#E5E9F0","ink":"#2E3440","ink_faded":"#4C566A",
"accent":"#5E81AC","accent_light":"#81A1C1","border":"#D8DEE9"}github-light
Clean white with blue accents, matching GitHub's documentation style. Best for: Open-source project docs, README-style reports.
{"canvas":"#FFFFFF","canvas_sec":"#F6F8FA","ink":"#1F2328","ink_faded":"#656D76",
"accent":"#0969DA","accent_light":"#218BFF","border":"#D0D7DE"}monokai-warm
Dark background with warm accent colors. Best for: Code-heavy reports, developer presentations.
{"canvas":"#272822","canvas_sec":"#1E1F1C","ink":"#F8F8F2","ink_faded":"#75715E",
"accent":"#F92672","accent_light":"#FD971F","border":"#49483E"}solarized-light
Ethan Schoonover's Solarized Light palette. Best for: Long-form reading, academic papers.
{"canvas":"#FDF6E3","canvas_sec":"#EEE8D5","ink":"#657B83","ink_faded":"#93A1A1",
"accent":"#CB4B16","accent_light":"#DC322F","border":"#EEE8D5"}dracula-soft
Softened Dracula theme with muted dark purple background. Best for: Evening reading, dark-mode preference reports.
{"canvas":"#282A36","canvas_sec":"#21222C","ink":"#F8F8F2","ink_faded":"#6272A4",
"accent":"#BD93F9","accent_light":"#FF79C6","border":"#44475A"}paper-classic
Pure white with black text and minimal red accents. Traditional print look. Best for: Formal documents, print-ready reports, submissions.
{"canvas":"#FFFFFF","canvas_sec":"#FAFAFA","ink":"#000000","ink_faded":"#666666",
"accent":"#CC0000","accent_light":"#FF3333","border":"#DDDDDD"}ocean-breeze
Light teal/aqua tones for a fresh, modern feel. Best for: Product reports, marketing docs, light technical content.
{"canvas":"#F0F7F4","canvas_sec":"#E0EDE8","ink":"#1A2E35","ink_faded":"#5A7D7C",
"accent":"#2A9D8F","accent_light":"#64CCBF","border":"#C8DDD6"}consulting-navy
White canvas, dark navy accent. ALL-CAPS left-aligned section headings with underline rule, left page-stripe, serif body. Cover is a solid navy block with white title. Best for: McKinsey / BCG / Deloitte-style deep-research reports, market analyses, white papers.
{"canvas":"#FFFFFF","canvas_sec":"#F4F6F9","ink":"#1A1A1A","ink_faded":"#5A6573",
"accent":"#1E3A5F","accent_light":"#3A5C82","border":"#D6DCE5"}Custom Theme
Pass a JSON file path to --theme-file:
{
"canvas": "#FEFEFE",
"canvas_sec": "#F5F5F5",
"ink": "#222222",
"ink_faded": "#888888",
"accent": "#E74C3C",
"accent_light": "#F39C12",
"border": "#DDDDDD"
}