软著申报材料三件套生成 (ruanzhu-kit)
为软件著作权登记生成三件套 PDF:用户操作手册、源程序(代码)、软件著作权登记申请表。
全部用 reportlab 离线生成(不依赖 Word / 浏览器 headless / 在线 CDN),中文字体走系统 Heiti SC / Songti SC。
三件套定位
- 用户操作手册 — 产品介绍 + 安装 + 界面 + 功能 + 真实截图 + FAQ + 架构 + 部署 + 附录。要求:封面、页眉页脚、目录、配图(真实截图,禁止纯占位/循环灌水)、36 页。避免大段空白。
- 源程序(源代码) — 完整源文件,带行号、等宽字体、中文注释完整。要求:封面、页眉页脚、36 页(软著常见提交量)。
- 软件著作权登记申请表 — 软件全称/简称/版本、著作权人、权利取得方式、鉴别材料、待填项用下划线占位。2 页。
默认页数:手册 36 / 源程序 36 / 申请表 2。封面均写「共 36 页」(申请表除外)。用户若指定其他页数,以用户为准。
关键踩坑点(必读,省数小时)
- PingFang 不能嵌入:PingFang.ttc 是 CFF/PostScript 轮廓,reportlab 的
TTFont无法嵌入 → 报错。改用 Heiti SC(黑体,正文) 与 Songti SC(宋体,标题/封面),它们是 TrueType 轮廓可被 reportlab 嵌入。注册示例:from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont pdfmetrics.registerFont(TTFont("Heiti", "/System/Library/Fonts/STHeiti Medium.ttc", subfontIndex=1)) pdfmetrics.registerFont(TTFont("Songti", "/System/Library/Fonts/Supplemental/Songti.ttc", subfontIndex=6)) pdfmetrics.registerFont(TTFont("SongtiSB", "/System/Library/Fonts/Supplemental/Songti.ttc", subfontIndex=1)) - 中文行必须换字体:等宽
Courier不含中文字形。代码 PDF 中,若某行含中文(注释/字符串),整行用Heiti渲染,否则用Courier。逐行用正则[\u4e00-\u9fff]判断切换。 - 手册必须先截真实图再排版:桌面应用用 1440×900、deviceScaleFactor=2;手机壳应用才用 420×900。按 App 实际选择器点页签(
.nav-btn[data-view]/.tab[data-view]/switchView())。脚本见scripts/shot_app_tabs.js。必须dangerouslyDisableSandbox:true才能启动本机 Edge。 - 图片嵌入与防空白:桌面截图宽约 450–500pt,高按 1440×900 比例;
KeepTogether(Image + 图注),避免图与标题跨页拉开大空白。不要用空touch出来的假 PNG。不要用「第 N 章功能模块详解 N」这种循环灌水凑页。 - 目标页数微调(必须用 pypdf 闭环,禁止目测):
- 源代码:整文件一张大 Table 自动分页。用
FS/LH/padding 循环试到正好 36 页(长源码先略降 FS/LH;短源码略升)。2414 行量级可从FS≈6.15, LH≈9.2起步。 - 用户手册:先写真实章节 + 真实截图,再用 pypdf 读页数;少则补「图册 / 教案 / 速查表」,多则略收 leading 或缩小截图,直到 36。禁止删页凑数。
- 源代码:整文件一张大 Table 自动分页。用
Polygon坐标要平铺列表:reportlab 的Polygon(points)接收[x0,y0,x1,y1,...],不是[(x,y),...]元组列表。传元组会静默错位或空图形。- 目录页码:
TableOfContents必须doc.multiBuild()两次排版才能回填。目录可用更稳妥的手动Table+ 固定页码。 - 单表自动分页优于手动每页 50 行:手动把 50 行塞进一张 Table 再
PageBreak,长行折行会溢出页数。
整体流程
- 确认素材:目标 App/网页(单文件 HTML 最佳)、项目名、软件全称/简称、版本号、著作权人。
- 真实截图:用
scripts/shot_app_tabs.js(或项目内专用脚本)截各模块 PNG。桌面默认 1440×900。核对 PNG 尺寸与画面,禁止空文件。 - 生成用户手册:基于
scripts/build_manual_template.py改写成当前项目文案(不要留「航程雷达」占位),嵌入真实截图,调到 36 页,避免大段空白。 - 生成源代码:基于
scripts/build_source_pdf_template.py,读源码自动分页带行号、封面(项目名 / 源代码 / V1.0 / 著作权人 / 共 36 页),循环微调到 36 页。 - 生成申请表:基于
scripts/build_application_form_template.py,填软件信息、著作权人、鉴别材料页码(手册 1–36、源程序 1–36)。 - 校验:
pypdf查页数;pymupdf.get_text()核封面(项目名、用户手册/源代码、著作权人、共 36 页)。必要时渲染关键页。
封面定稿样式
- 大标题:项目名
- 小标题:仅 用户手册 / 源代码(不带产品名)
- 元数据:软件版本 V1.0、著作权人
- 手册与源程序封面均写:共 36 页(不放英文行、不放开发语言行)
校验清单
- 页数达标(手册 36 / 代码 36 / 申请表 2)
- 封面中文、项目名、著作权人、共 36 页正确
- 操作手册:目录页码正确、配图为真实截图、页眉页脚完整、无大段空白、无循环灌水章节
- 源代码:行号连续、中文注释完整、等宽字体、末页可不足整页
- 申请表:待填字段用下划线占位,鉴别材料页码范围与另两份一致
复用模板
scripts/build_manual_template.py— 操作手册骨架(须改成当前项目文案 + 真实截图)scripts/build_source_pdf_template.py— 源代码生成(整文件单表自动分页 + 行号)scripts/build_application_form_template.py— 登记申请表生成scripts/shot_app_tabs.js— puppeteer-core 截单文件 App 各页签;支持桌面/手机视口与 data-view 自动发现
模板内项目名/著作权人等为占位值,使用前按实际申报信息改封面与元数据。不要把某个 App 的页签名写死进通用脚本后不改回来。