← 返回 Skills 市场
shimonxin

Markdown to PDF (CJK)

作者 Shimon Xin · GitHub ↗ · v1.0.1 · MIT-0
cross-platform ✓ 安全检测通过
63
总下载
0
收藏
0
当前安装
2
版本数
在 OpenClaw 中安装
/install md2pdf-cjk
功能描述
Markdown to PDF converter with CJK (Chinese/Japanese/Korean) support. Uses WeasyPrint + Noto CJK fonts for proper rendering. Features: emoji replacement, cus...
使用说明 (SKILL.md)

Markdown to PDF (CJK)

Convert Markdown files to well-formatted PDF with full CJK (Chinese/Japanese/Korean) support, code blocks, and tables.

Toolchain

  • Rendering engine: WeasyPrint (pre-installed, /usr/local/bin/weasyprint)
  • Fonts: Noto Sans CJK SC / Noto Serif CJK SC (system-installed)
  • Pipeline: Markdown → HTML (emoji replacement) → WeasyPrint → PDF

Steps

1. Emoji Processing

WeasyPrint does not render emoji characters. Replace them with text labels:

emoji_map = {
    '🦞': '[Lobster]', '🌅': '[Morning]', '🌙': '[Moon]', '🏛': '[Architecture]',
    '🔧': '[Tool]', '🔄': '[Restart]', '📰': '[Report]', '💪': '[Strong]',
    '⚡': '[Lightning]', '⏰': '[Alarm]', '👆': '[Up]', '⬆️': '[Up]',
    '🌟': '[Star]', '👇': '[Down]', '✅': '[Done]', '📊': '[Chart]',
    '🎯': '[Target]', '💡': '[Idea]', '🧰': '[Toolbox]', '🤖': '[AI]',
    '🏗️': '[Build]', '📅': '[Calendar]', '🧘': '[Meditation]', '📖': '[Read]',
    '📝': '[Note]', '🏃': '[Run]', '⭐': '[Fav]', '📬': '[Mail]',
    '🌐': '[Web]', '🐙': '[GitHub]', '💬': '[Chat]', '▪': '·',
    '❌': '[X]', '⚠️': '[!]', '📌': '[PIN]', '🔔': '[Bell]',
    '🤔': '[Think]', '😂': '[Laugh]', '🔒': '[Lock]', '📁': '[Folder]',
    '💰': '[Money]', '👨‍👧‍👦': '[Family]', '😴': '[Sleep]', '👶': '[Baby]',
    '1️⃣': '1.', '2️⃣': '2.', '3️⃣': '3.', '4️⃣': '4.', '5️⃣': '5.',
}

For emoji not in the map, strip variant selectors (\ufe0f) and replace with [?]. Preserve CJK punctuation marks (·…——''""etc.).

2. Markdown → HTML Conversion

Lightweight conversion using Python regex (no extra dependencies):

import re
html = md_content
html = re.sub(r'^# (.+)$', r'\x3Ch1>\1\x3C/h1>', html, flags=re.MULTILINE)
html = re.sub(r'^## (.+)$', r'\x3Ch2>\1\x3C/h2>', html, flags=re.MULTILINE)
html = re.sub(r'^### (.+)$', r'\x3Ch3>\1\x3C/h3>', html, flags=re.MULTILINE)
html = re.sub(r'\*\*(.+?)\*\*', r'\x3Cstrong>\1\x3C/strong>', html)
html = re.sub(r'\*(.+?)\*', r'\x3Cem>\1\x3C/em>', html)
html = re.sub(r'^> (.+)$', r'\x3Cblockquote>\1\x3C/blockquote>', html, flags=re.MULTILINE)
html = re.sub(r'^---$', r'\x3Chr/>', html, flags=re.MULTILINE)
html = re.sub(r'^- (.+)$', r'\x3Cli>\1\x3C/li>', html, flags=re.MULTILINE)
html = re.sub(r'`([^`]+)`', r'\x3Ccode>\1\x3C/code>', html)
html = re.sub(r'```(\w*)\
(.*?)```', r'\x3Cpre>\x3Ccode>\2\x3C/code>\x3C/pre>', html, flags=re.DOTALL)
# Paragraphs
html = re.sub(r'\
\
', r'\x3C/p>\x3Cp>', html)
html = '\x3Cp>' + html + '\x3C/p>'
# Clean empty tags
html = re.sub(r'\x3Cp>\s*\x3C/p>', '', html)
html = re.sub(r'\x3Cp>\s*(\x3Ch[123]>.*?\x3C/h[123]>)\s*\x3C/p>', r'\1', html, flags=re.DOTALL)
html = re.sub(r'\x3Cp>\s*(\x3Chr/>)\s*\x3C/p>', r'\1', html)
html = re.sub(r'\x3Cp>\s*(\x3Cblockquote>.*?\x3C/blockquote>)\s*\x3C/p>', r'\1', html, flags=re.DOTALL)

3. HTML Template

\x3C!DOCTYPE html>
\x3Chtml>
\x3Chead>
\x3Cmeta charset="utf-8">
\x3Cstyle>
@page { size: A4; margin: 2cm 2.5cm 2cm 2.5cm; }
body {
    font-family: "Noto Sans CJK SC", "Noto Serif CJK SC", sans-serif;
    font-size: 11pt; line-height: 1.8; color: #333;
    max-width: 100%; word-wrap: break-word;
}
h1 { font-size: 20pt; color: #d32f2f; border-bottom: 2px solid #d32f2f; padding-bottom: 8px; margin-top: 30px; }
h2 { font-size: 15pt; color: #333; margin-top: 25px; border-left: 4px solid #d32f2f; padding-left: 10px; }
h3 { font-size: 13pt; color: #555; margin-top: 20px; }
blockquote { border-left: 3px solid #ccc; padding-left: 15px; color: #666; margin: 15px 0; font-style: italic; }
code { background: #f5f5f5; padding: 2px 6px; border-radius: 3px; font-size: 10pt; }
pre { background: #f8f8f8; padding: 12px; border-radius: 5px; font-size: 9.5pt; line-height: 1.6; }
pre code { background: none; padding: 0; }
strong { color: #d32f2f; }
hr { border: none; border-top: 1px solid #ddd; margin: 25px 0; }
li { margin: 5px 0; }
table { border-collapse: collapse; width: 100%; margin: 15px 0; }
th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; }
th { background: #f5f5f5; font-weight: bold; }
\x3C/style>
\x3C/head>
\x3Cbody>{{HTML_CONTENT}}\x3C/body>
\x3C/html>

4. Generate PDF

weasyprint /tmp/input.html /tmp/output.pdf

One-line Script

All steps are wrapped into a single script:

#!/bin/bash
# Usage: md2pdf.sh input.md [output.pdf]
# Markdown → PDF (weasyprint + CJK + emoji replacement)
INPUT="${1:-/dev/stdin}"
OUTPUT="${2:-/tmp/output.pdf}"
python3 /path/to/md2pdf.py "$INPUT" "$OUTPUT"

Important Notes

  • Do NOT use pandoc + xelatex: Emoji renders as blank, and compilation is slow
  • Do NOT use pandoc + wkhtmltopdf: Not installed by default
  • Always use WeasyPrint: The only solution that supports CJK + emoji replacement
  • Output path: Always use absolute paths under /tmp/
  • Pre-send check: Verify PDF file exists and is > 10KB before sending
安全使用建议
Install this if you want Markdown-to-PDF conversion with CJK rendering. Consider narrowing its trigger phrases to Markdown-specific requests, and avoid processing sensitive untrusted Markdown if you are not comfortable with local HTML/PDF rendering of that content.
能力评估
Purpose & Capability
The artifact’s stated purpose and instructions consistently describe converting Markdown to PDF with CJK font support using local WeasyPrint processing.
Instruction Scope
The description includes broad triggers such as "generate PDF" and "convert PDF", which could route non-Markdown PDF requests to this skill, but the behavior remains related to document conversion.
Install Mechanism
The package contains only a SKILL.md instruction file and no bundled executable, installer, dependency install step, or automatic setup mechanism.
Credentials
The instructions use local Markdown input, temporary HTML/PDF files under /tmp, Python text processing, and WeasyPrint; they do not request credentials, network APIs, or broad filesystem access.
Persistence & Privilege
No persistence, background workers, privilege escalation, startup hooks, or long-running services are described.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install md2pdf-cjk
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /md2pdf-cjk 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.1
Full English translation of SKILL.md and all content
v1.0.0
首个公开版本:WeasyPrint+Noto CJK,支持中文排版、emoji替换、自定义CSS样式
元数据
Slug md2pdf-cjk
版本 1.0.1
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 2
常见问题

Markdown to PDF (CJK) 是什么?

Markdown to PDF converter with CJK (Chinese/Japanese/Korean) support. Uses WeasyPrint + Noto CJK fonts for proper rendering. Features: emoji replacement, cus... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 63 次。

如何安装 Markdown to PDF (CJK)?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install md2pdf-cjk」即可一键安装,无需额外配置。

Markdown to PDF (CJK) 是免费的吗?

是的,Markdown to PDF (CJK) 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Markdown to PDF (CJK) 支持哪些平台?

Markdown to PDF (CJK) 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Markdown to PDF (CJK)?

由 Shimon Xin(@shimonxin)开发并维护,当前版本 v1.0.1。

💬 留言讨论