Document Gen Dual Backend
HKUDS/OpenSpace
Document generation with direct pandoc/ReportLab execution (lightweight default) and optional shellagent fallback for complex scenarios
PDF 相关的所有操作:从零生成(reportlab / pypdf)、格式转化(md/html → PDF)、修改(合并 / 拆分 / 旋转 / 加水印 / 提图片 / 元数据)、读内容(pdfplumber / extractdocumenttext)、OCR 扫描件、加密解密。触发场景:用户说"生成 PDF" / "做份 PDF 简历" / "合并这几份 PDF" / "给 PDF…
$ npx skills add guyi-a/pi-ling --skill pdf -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install guyi-a/pi-ling pdf --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/guyi-a/pi-ling.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/pdf .claude/skills/pdf && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "pdf" agent skill from https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdf into .claude/skills/pdf/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pdf", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdfType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add guyi-a/pi-ling --skill pdf -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install guyi-a/pi-ling pdf --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/guyi-a/pi-ling.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/pdf .agents/skills/pdf && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "pdf" agent skill from https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdf into .agents/skills/pdf/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pdf", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add guyi-a/pi-ling --skill pdf -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install guyi-a/pi-ling pdf --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/guyi-a/pi-ling.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/pdf .cursor/skills/pdf && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "pdf" agent skill from https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdf into .cursor/skills/pdf/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pdf", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/guyi-a/pi-ling.git --path .agents/skills/pdf--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add guyi-a/pi-ling --skill pdf -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install guyi-a/pi-ling pdf --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/guyi-a/pi-ling.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/pdf .gemini/skills/pdf && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "pdf" agent skill from https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdf into .gemini/skills/pdf/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pdf", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install guyi-a/pi-ling pdfInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add guyi-a/pi-ling --skill pdf -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/guyi-a/pi-ling.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/pdf .github/skills/pdf && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "pdf" agent skill from https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdf into .github/skills/pdf/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pdf", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add guyi-a/pi-ling --skill pdf -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install guyi-a/pi-ling pdf --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/guyi-a/pi-ling.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/pdf .opencode/skills/pdf && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "pdf" agent skill from https://github.com/guyi-a/pi-ling/tree/main/.agents/skills/pdf into .opencode/skills/pdf/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "pdf", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
pdfPDF 相关的所有操作:从零生成(reportlab / pypdf)、格式转化(md/html → PDF)、修改(合并 / 拆分 / 旋转 / 加水印 / 提图片 / 元数据)、读内容(pdfplumber / extractdocumenttext)、OCR 扫描件、加密解密。触发场景:用户说"生成 PDF" / "做份 PDF 简历" / "合并这几份 PDF" / "给 PDF…
PDF is an agent skill from guyi-a/pi-ling. PDF 相关的所有操作:从零生成(reportlab / pypdf)、格式转化(md/html → PDF)、修改(合并 / 拆分 / 旋转 / 加水印 / 提图片 / 元数据)、读内容(pdfplumber / extractdocumenttext)、OCR 扫描件、加密解密。触发场景:用户说"生成 PDF" / "做份 PDF 简历" / "合并这几份 PDF" / "给 PDF 加水印" / "这份扫描 PDF 转文字" / "提取 PDF 表格" / "精调 PDF 样式"等一切跟 .pdf 文件相关的活。这个 skill 是工具箱:说明书 + 预置可执行脚本 + 命令模板。冷门场景看 REFERENCE.md。
Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including scripts (for example `REFERENCE.md`, `scripts/html_to_pdf.py` and `scripts/merge_pdfs.py`).
It sits in Documents & Office, covering PDF. It works with pypdf and Pandoc. The licence is MIT.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 17a71f6. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 3 files in scripts/ (Python), which the agent can run.
Shell commands in SKILL.md call:
pandocqpdfbrewuvpdftotextFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
google.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
PDF loads about 3.3k tokens when it runs. Until then it costs about 81 tokens; SKILL.md has 558 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from guyi-a/pi-ling at commit 17a71f6, republished under its MIT licence (© guyi-a). 558 words, ~3,270 tokens.
.claude/skills/pdf/SKILL.md (or your agent's skills folder). This skill also uses 4 other files; get the full folder from GitHub.skill 目录布局:
SKILL.md(本文档)—— 日常够用的核心REFERENCE.md —— 进阶:详细库用法、复杂场景、性能优化。遇冷门需求时 read_file <skill_path>/REFERENCE.mdscripts/ —— 预置可执行脚本,用 run_command uv run <scripts_path>/xxx.py <args> 调用cp 到 workspace/scripts/ 再改| 任务 | 首选路径 | 备注 |
|---|---|---|
| md → PDF(快速,样式默认) | pandoc a.md -o a.pdf --pdf-engine=xelatex -V CJKmainfont='PingFang SC' -V fontsize=12pt -V linestretch=1.4 -V geometry:margin=2cm | 需 pandoc + xelatex/typst |
| md/html → PDF(精调,重视觉) | agent 写完整 html(内嵌 CSS)→ uv run <scripts_path>/html_to_pdf.py --input a.html --output a.pdf | Chromium headless |
| 从零画 PDF(发票/证书/精确布局) | reportlab(下方"从零 draw"章节) | Canvas 或 Platypus |
| 读 PDF 内容(提文字) | 用 agent 已有的 extract_document_text 工具 | 不走脚本 |
| 提取表格 | pdfplumber(下方"提取内容"章节) | 保留结构 |
| 合并多个 PDF | uv run <scripts_path>/merge_pdfs.py --output merged.pdf a.pdf b.pdf c.pdf | pypdf |
| PDF 拆成图片 | uv run <scripts_path>/pdf_to_images.py --input a.pdf --output-dir images/ | pypdfium2 |
| PDF 按页拆分 | qpdf --split-pages=1 input.pdf out_%d.pdf | 一条命令 |
| 旋转某页 | qpdf input.pdf output.pdf --rotate=+90:1 | 一条命令 |
| 加水印 | reportlab 造水印 PDF + pypdf 叠加(下方"加水印"章节) | 需要写点脚本 |
| 提元数据 | pypdf reader.metadata(下方"元数据"章节) | |
| 加密/解密 | pypdf writer.encrypt / qpdf --decrypt | 见下方 |
| OCR 扫描 PDF | pytesseract + pdf2image(下方"OCR"章节) | brew install tesseract tesseract-lang |
| 提取内嵌图片 | pdfimages -all input.pdf images/img | poppler-utils |
| 复杂/冷门场景 | 看 REFERENCE.md | JS 库、pypdfium2 高级、qpdf 高级、性能 |
md/html → PDF 总是有"快速一发"和"精调 HTML"两种走法,agent 无法从技术层面替用户决定 —— 必须调 ask_user 让用户挑一次,除非用户已经明说了偏好。
ask_user(questions=[{
"question": "PDF 样式偏好?",
"options": [
"精调样式,走 HTML 渲染,排版最好 (Recommended)",
"快速一发,pandoc 默认样式就够"
]
}])推荐项是精调:HTML → Chromium 的排版质量明显高于 pandoc 默认(CSS 精调空间大、字体渲染细腻、可控 layout),除非用户明确要"快速临时看看",都应该默认走 HTML。
选"精调" → 路径 B(html→Chromium) 选"快速" → 路径 A(pandoc)
不能跳过 ask_user:即使你觉得"根据上下文能猜到用户想要精调",也要问一次 —— PDF 是要交付的产物,用户对排版预期比 agent 猜测准。唯一可跳过的情况是用户在这条消息里已经写明了"快速一发 / 就要好看 / 用于投递 / 用于打印"这类明确信号,直接按信号走对应路径。
适用:agent 判断"用户只是快速看看,不在意视觉设计"。
pandoc INPUT.md -o OUTPUT.pdf \
--pdf-engine=xelatex \
-V CJKmainfont='PingFang SC' \
-V fontsize=12pt \
-V linestretch=1.4 \
-V geometry:margin=2cm依赖:brew install pandoc && brew install --cask basictex(或 brew install typst 换 --pdf-engine=typst)。
适用:用户在意视觉设计。简历自评报告分享、演讲讲义、需要"设计感"的产物。
流程:
read_file 看 md 内容和结构write_file 写一份完整的 html(内嵌 <style> + @page 规则 + 中文字体 + 精调 layout),md 内容手动搬进 <h1> / <p> / <table> 等run_command uv run <scripts_path>/html_to_pdf.py --input a.html --output a.pdf关键:不要走 pandoc a.md -o a.html 再转 PDF。pandoc 的默认 html template 没有精调样式,跟直接 pandoc→PDF 一样素。html 必须是agent 亲手编排的。
html 骨架模板(agent 起点):
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>标题</title>
<style>
@page { size: A4; margin: 2cm; }
body {
font-family: 'PingFang SC', 'Microsoft YaHei', -apple-system, sans-serif;
font-size: 12pt; line-height: 1.7; color: #222;
}
h1 { color: #1e3c78; border-bottom: 2px solid #1e3c78; padding-bottom: 0.3em; margin-top: 1.5em; }
h2 { color: #2c5aa0; margin-top: 1.2em; padding-left: 8px; border-left: 4px solid #2c5aa0; }
code { background: #f4f7fa; padding: 2px 6px; border-radius: 3px; font-family: 'SF Mono', Menlo, monospace; }
pre { background: #f4f7fa; padding: 12px 16px; border-radius: 6px; overflow-x: auto; }
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; }
th { background: #f4f7fa; font-weight: 600; }
blockquote { border-left: 4px solid #ccc; padding-left: 1em; color: #666; margin-left: 0; }
.page-break { page-break-before: always; }
</style>
</head>
<body>
<!-- 内容 -->
</body>
</html>依赖:用户装了 Chrome(macOS 几乎必装)。没装引导 https://www.google.com/chrome/。
适用:发票 / 证书 / 结业通知 / 精确布局的表单——需要 pixel-精确定位的产物。
依赖 PEP 723 声明:"reportlab>=4.0"
# /// script
# dependencies = ["reportlab>=4.0"]
# ///
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# 注册 CJK 字体(macOS)
pdfmetrics.registerFont(TTFont('CN', '/System/Library/Fonts/STHeiti Light.ttc'))
c = canvas.Canvas("out.pdf", pagesize=A4)
w, h = A4 # 595 x 842 pt
c.setFont('CN', 24)
c.drawString(50, h - 80, "标题")
c.setFont('CN', 12)
c.drawString(50, h - 120, "正文段落 —— 靠 drawString 精确定位")
# 画线 / 矩形 / 圆
c.line(50, h - 140, w - 50, h - 140)
c.rect(50, h - 200, 200, 40, stroke=1, fill=0)
c.setFillColorRGB(0.9, 0.9, 0.9)
c.rect(50, h - 260, 200, 40, stroke=0, fill=1)
c.showPage() # 结束当前页
c.save()# /// script
# dependencies = ["reportlab>=4.0"]
# ///
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak, Table, TableStyle
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('CN', '/System/Library/Fonts/STHeiti Light.ttc'))
doc = SimpleDocTemplate("report.pdf", pagesize=A4,
leftMargin=50, rightMargin=50, topMargin=60, bottomMargin=60)
# 自定义中文样式(默认样式没设 CJK 字体)
styles = getSampleStyleSheet()
cn_title = ParagraphStyle('CNTitle', parent=styles['Title'], fontName='CN', fontSize=22)
cn_body = ParagraphStyle('CNBody', parent=styles['Normal'], fontName='CN', fontSize=11, leading=18)
story = []
story.append(Paragraph("报告标题", cn_title))
story.append(Spacer(1, 20))
story.append(Paragraph("这是正文内容 —— Platypus 会自动分页、换行、对齐。" * 5, cn_body))
story.append(PageBreak())
# 表格
data = [
['项目', 'Q1', 'Q2', 'Q3', 'Q4'],
['营收', '100', '120', '135', '160'],
['利润', '20', '25', '30', '40'],
]
table = Table(data)
table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#1e3c78')),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('FONTNAME', (0, 0), (-1, -1), 'CN'),
('FONTSIZE', (0, 0), (-1, 0), 13),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
('BACKGROUND', (0, 1), (-1, -1), colors.HexColor('#f4f7fa')),
]))
story.append(table)
doc.build(story)Never 在 reportlab 里用 Unicode 上下标(x²、H₂O 的 ² ₂)—— 内置字体没有这些 glyph,会渲染成黑色实心方块。用 <sub> / <super> Paragraph 标签:
Paragraph("H<sub>2</sub>O 和 x<super>2</super>", cn_body)用预置脚本:
uv run <scripts_path>/merge_pdfs.py --output merged.pdf a.pdf b.pdf c.pdf即席代码:
# /// script
# dependencies = ["pypdf>=4.0"]
# ///
from pypdf import PdfReader, PdfWriter
writer = PdfWriter()
for path in ["a.pdf", "b.pdf", "c.pdf"]:
for page in PdfReader(path).pages:
writer.add_page(page)
with open("merged.pdf", "wb") as f:
writer.write(f)reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
w = PdfWriter()
w.add_page(page)
with open(f"page_{i+1}.pdf", "wb") as f:
w.write(f)或者命令行:qpdf --split-pages=1 input.pdf out_%d.pdf
reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
page.rotate(90) # 90 / 180 / 270
writer.add_page(page)
with open("rotated.pdf", "wb") as f:
writer.write(f)或命令行:qpdf input.pdf out.pdf --rotate=+90:1-3(1-3 页转 90 度)
reader = PdfReader("input.pdf")
m = reader.metadata
print(m.title, m.author, m.subject, m.creator)
print(f"页数: {len(reader.pages)}")# 加密
writer = PdfWriter()
for page in PdfReader("input.pdf").pages:
writer.add_page(page)
writer.encrypt(user_password="user", owner_password="owner")
with open("encrypted.pdf", "wb") as f:
writer.write(f)
# 解密
reader = PdfReader("encrypted.pdf")
if reader.is_encrypted:
reader.decrypt("user")
# 之后正常读命令行解密:qpdf --password=secret --decrypt encrypted.pdf out.pdf
两步:用 reportlab 造一张透明水印 PDF,再用 pypdf 叠加。
# /// script
# dependencies = ["reportlab>=4.0", "pypdf>=4.0"]
# ///
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from pypdf import PdfReader, PdfWriter
# Step 1: 造水印 PDF
pdfmetrics.registerFont(TTFont('CN', '/System/Library/Fonts/STHeiti Light.ttc'))
c = canvas.Canvas("_wm.pdf", pagesize=A4)
w, h = A4
c.saveState()
c.translate(w / 2, h / 2)
c.rotate(45)
c.setFillColorRGB(0.6, 0.6, 0.6, alpha=0.25) # 灰色 25% 透明
c.setFont('CN', 60)
c.drawCentredString(0, 0, "CONFIDENTIAL")
c.restoreState()
c.save()
# Step 2: 叠加到每一页
watermark = PdfReader("_wm.pdf").pages[0]
reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark)
writer.add_page(page)
with open("watermarked.pdf", "wb") as f:
writer.write(f)用 agent 已有的 extract_document_text 工具(不走本 skill)。
# /// script
# dependencies = ["pdfplumber>=0.11"]
# ///
import pdfplumber
with pdfplumber.open("input.pdf") as pdf:
for i, page in enumerate(pdf.pages):
print(f"--- Page {i+1} ---")
print(page.extract_text())命令行版:pdftotext -layout input.pdf output.txt
# /// script
# dependencies = ["pdfplumber>=0.11", "pandas>=2.0"]
# ///
import pdfplumber
import pandas as pd
with pdfplumber.open("input.pdf") as pdf:
all_tables = []
for page in pdf.pages:
for table in page.extract_tables():
if table and len(table) > 1:
df = pd.DataFrame(table[1:], columns=table[0])
all_tables.append(df)
if all_tables:
combined = pd.concat(all_tables, ignore_index=True)
combined.to_excel("tables.xlsx", index=False)命令行:pdfimages -all input.pdf images/img(poppler-utils,最快)
依赖:brew install tesseract tesseract-lang poppler。中文语言包(chi_sim)在 tesseract-lang 里。
# /// script
# dependencies = ["pytesseract", "pdf2image"]
# ///
from pytesseract import image_to_string
from pdf2image import convert_from_path
for i, img in enumerate(convert_from_path("scanned.pdf")):
print(f"--- Page {i+1} ---")
print(image_to_string(img, lang="chi_sim+eng"))⚠️ reportlab 独家坑:PingFang.ttc 内部是 PostScript CFF outlines 格式,
reportlab 的 TTFont 只支持 TrueType,加载 PingFang 会失败(报 not a supported TrueType font file 或类似错误)。给 reportlab 用 CJK 字体时不要选 PingFang,
用 STHeiti 或 Songti。
reportlab 能用的 macOS 系统 CJK 字体路径(都是 TrueType):
/System/Library/Fonts/STHeiti Light.ttc — 华文黑体细体,推荐/System/Library/Fonts/STHeiti Medium.ttc — 华文黑体中等/System/Library/Fonts/Supplemental/Songti.ttc — 宋体(可能不在,视系统版本)pandoc / html→Chromium 场景没这个限制(xelatex 走 fontspec 支持 PS,Chromium
直接用系统渲染),可以直接用 PingFang SC。
各场景字体传法总表:
| 场景 | 字体名 / 传法 | 说明 |
|---|---|---|
| pandoc | -V CJKmainfont='PingFang SC' | 系统字体名,PS 也行 |
| html + Chromium | CSS font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; | 系统字体名,PS 也行 |
| reportlab | pdfmetrics.registerFont(TTFont('CN', '/System/Library/Fonts/STHeiti Light.ttc')) 再 setFont('CN', 12) | 绝对路径,且必须 TrueType,不能用 PingFang.ttc |
| Pillow | ImageFont.truetype('/System/Library/Fonts/STHeiti Light.ttc', 24) | 绝对路径,Pillow 也不支持 PS outlines |
macOS 默认可用字体名(pandoc / CSS 场景直接叫名字,不用路径):
PingFang SC — 苹方,推荐Heiti SC — 黑体Songti SC — 宋体STHeiti — 华文黑体pandoc md → html → chromium PDF —— pandoc 默认 html template 没精调样式,等于白转cp 到 workspace 再改<sub> / <super>)生成完必跑:
ls -lh <output.pdf> && file <output.pdf>ls -lh 看文件存在 + 大小合理(<1KB 是空文件)file 看 magic 是否 PDF document装了 poppler 可以 pdfinfo <output.pdf> 拿页数。
pandoc xelatex / html + Chromium / reportlab Canvas / 具体脚本名)© guyi-a, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 4 other files (scripts) in .agents/skills/pdf of guyi-a/pi-ling.
Open the folder on GitHubat commit 17a71f6
PDF next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| PDF this skillguyi-a/pi-ling | 106 | — | ~3.3k | Automated safety check: Pass | MIT | |
| Document Gen Dual BackendHKUDS/OpenSpace | 7.7k | — | ~4.6k | Automated safety check: Pass | MIT | |
| Document Gen Resilient MultiformatHKUDS/OpenSpace | 7.7k | — | ~3.5k | Automated safety check: Pass | MIT | |
| PDF Generation TroubleshootingHKUDS/OpenSpace | 7.7k | — | ~926 | Automated safety check: Pass | MIT | |
| Harness Book Best Practicewquguru/harness-books | 3.2k | — | ~4.1k | Automated safety check: Pass | None | |
| Huashu Markdown Publishing Pipelinealchaincyf/huashu-md-html | 908 | — | ~4.8k | Automated safety check: Pass | MIT |
HKUDS/OpenSpace
Document generation with direct pandoc/ReportLab execution (lightweight default) and optional shellagent fallback for complex scenarios
HKUDS/OpenSpace
Resilient multi-format document generation with environment checks, auto-sanitization, and fallback engines
HKUDS/OpenSpace
Systematic fallback workflow for PDF generation through pandoc, reportlab, and fpdf2 with installation verification
wquguru/harness-books
Best practices for working on the Harness books repo. An agent skill from wquguru/harness-books.
alchaincyf/huashu-md-html
Converts files and web pages into clean Markdown, then turns Markdown into polished HTML, Word, PDF and EPUB using four templates.
nuoyimanaituling/manus-x
Process PDF files - extract text, read content, create PDFs, merge or split documents.
guyi-a/pi-ling
PowerPoint 幻灯片(.pptx / .potx)的所有操作:从零生成(pptxgenjs Node 库)、基于模板编辑(unpack XML → 改 → clean → pack)、格式转化(pptx → PDF / 图片、.ppt → .pptx)、读取分析。触发场景:用户说"做份 PPT" / "生成幻灯片" / "演讲 slide" / "培训材料" / "项目汇报" /…
guyi-a/pi-ling
Boss 直聘岗位搜索的完整操作手册。触发场景:用户说"找工作"/"看岗位"/"搜招聘"/"投简历"/"跳槽"/"Boss 直聘"/"看看有什么工作"/"帮我看下 XX 岗位"等。前提:必须走 browserbridge(Boss 需要用户 Chrome 登录态;browseruse 独立环境登不上)。包含 URL 模板、城市编码表、Vue data 抽取…
guyi-a/pi-ling
Word 文档(.docx)的日常处理:md → docx(生成简历/报告)、docx → PDF/图片(分享预览)、.doc → .docx(老格式升级)。触发场景:用户说"生成 Word 版" / "做份 Word 简历" / "把这份报告转 Word" / "这份 .doc 打不开" / "docx 转 PDF" 等。读 docx 内容走 agent 已有的…
guyi-a/pi-ling
当回答涉及流程、架构、机制、因果、对比、时间线、状态机、层级关系,或用户明确要求画图 / 图解 / 示意图时使用。把内容画成对话内直接渲染的图(自包含 HTML/SVG),而不是用文字罗列。不承接数值图表(折线/柱状/饼图,当前无图表库)、海报、头像、写实插画、地图。
Categories
PDF 相关的所有操作:从零生成(reportlab / pypdf)、格式转化(md/html → PDF)、修改(合并 / 拆分 / 旋转 / 加水印 / 提图片 / 元数据)、读内容(pdfplumber / extractdocumenttext)、OCR 扫描件、加密解密。触发场景:用户说"生成 PDF" / "做份 PDF 简历" / "合并这几份 PDF" / "给 PDF…. PDF is an agent skill from guyi-a/pi-ling.
PDF fits situations like: tasks that involve PDF.
Run `npx skills add guyi-a/pi-ling --skill pdf -a claude-code`. Or copy the skill folder (.agents/skills/pdf in guyi-a/pi-ling) into .claude/skills/pdf in your project. Claude Code loads it when a task matches its description.
Run `npx skills add guyi-a/pi-ling --skill pdf -a codex`. Or copy the skill folder (.agents/skills/pdf in guyi-a/pi-ling) into .agents/skills/pdf in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add guyi-a/pi-ling --skill pdf -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/pdf, .gemini/skills/pdf, .github/skills/pdf and .opencode/skills/pdf in your project.
Going by SKILL.md and its folder, PDF needs Python for the scripts in its folder and the command-line tools its instructions call (pandoc, qpdf, brew, uv and pdftotext). Our summary lists: Python 3.
SKILL.md names 1 domain. In commands or code: google.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
PDF is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with PDF: Document Gen Dual Backend (HKUDS/OpenSpace, 7.7k stars), Document Gen Resilient Multiformat (HKUDS/OpenSpace, 7.7k stars), PDF Generation Troubleshooting (HKUDS/OpenSpace, 7.7k stars) and Harness Book Best Practice (wquguru/harness-books, 3.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
guyi-a (a GitHub user) maintains it in guyi-a/pi-ling, which has 106 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on September 16, 2026.
Source: guyi-a/pi-ling on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.