hkr-render · git:20260815.db7fa50 · 2026-08-15 · sha256 6f46661d5c2bb2d4
hkr-render git:20260815.db7fa50C
Immutable. This exact content is served forever at /api/v1/blob/6f46661d5c2bb2d4.
# xiaohu-wechat-format
公众号一键排版技能。把任意文本内容(Markdown、纯文本、格式粗糙的笔记)转成微信公众号兼容的排版 HTML,AI 自动理解内容结构并增强排版,可视化选择主题后一键复制粘贴到微信后台。可选生成封面图、推送草稿箱。
## Skill Description For Claude
公众号完整管线:排版 → 封面(可选)→ 推送(可选)。把 Markdown 文章转为微信公众号兼容的内联样式 HTML,支持纯文本输入,AI 自动补充结构和排版增强。当用户说"排版""微信排版""格式化文章""format"时使用。
## 脚本目录
`{baseDir}` = 本 SKILL.md 所在目录。执行脚本时用 `{baseDir}/scripts/xxx.py` 替换为实际绝对路径。
| 脚本 | 用途 |
|------|------|
| `scripts/format.py` | 排版:Markdown → 微信兼容 HTML |
| `scripts/publish.py` | 推送:HTML → 公众号草稿箱 |
| `scripts/comment_reply.py` | 评论自动回复(可选) |
## 配置
首次使用需创建 `config.json`(参考 `config.example.json`):
```json
{
"output_dir": "/tmp/wechat-format",
"vault_root": "/path/to/your/obsidian/vault",
"settings": {
"default_theme": "newspaper",
"auto_open_browser": true
},
"wechat": {
"app_id": "YOUR_APP_ID",
"app_secret": "YOUR_APP_SECRET",
"author": "作者名"
},
"cover": {
"output_dir": "~/Documents/covers",
"image_generation_script": ""
}
}
```
- `wechat` 部分仅推送时需要,纯排版可不填
- `cover` 部分仅生成封面时需要
- `config.json` 已在 `.gitignore` 中,不会被提交
## Instructions
### 触发条件
用户说以下任何一种:
- `/format 文件路径`
- `排版这篇文章`
- `微信排版`
- `格式化为公众号格式`
- `把这篇转成微信格式`
### 完整工作流
#### 第 1 步:确认文章
1. 如果用户给了文件路径,直接读取
2. 如果没给路径,问用户要文章路径
3. 读取文章内容,确认标题和字数
#### 第 1.5 步:结构化预处理(仅在需要时)
读取文章后,先检测输入内容的 Markdown 结构完整度,决定是否需要 AI 结构化预处理。
**检测方法**:扫描全文,统计 `##` 标题、`**加粗**`、`- 列表`、`> 引用`、`` ` 代码 ` `` 等格式标记的数量。
**判断规则**:
- 有 `##` 标题且格式标记分布合理 → **跳过**,直接进入第 2 步
- 缺少 `##` 标题,或几乎没有格式标记(纯文本/粗糙笔记)→ **执行结构化**
**结构化规则(底线:只加标记,不改内容)**:
1. **加标题**:识别文章的逻辑段落和主题转换点,在转换处插入 `##` 标题。标题从内容中提炼,不编造。三段内容不硬拆五个标题——尊重原文信息密度
2. **分段落**:确保段落之间有空行分隔,长段落在语义转换处拆分
3. **加列表**:识别并列/枚举性质的内容,加 `- ` 或 `1. ` 标记
4. **加强调**:识别关键词、产品名、核心概念,加 `**加粗**`
5. **清理格式**:去除多余空行、修正缩进、统一标点
6. **不改措辞**:不调语序、不增删内容、不润色文字。用户写什么就是什么,只加结构标记
**保存与告知**:
- 结构化后保存为 `/tmp/wechat-format/xxx-structured.md`
- 告知用户:"检测到输入缺少 Markdown 格式标记,已自动补充标题和结构,保存在 xxx-structured.md,可检查调整"
- 后续第 2 步基于 structured.md 继续处理
---
#### 第 2 步:AI 内容分析 + 自动套格式
读取文章(或上一步输出的 structured.md),Claude 分析内容结构,在 Markdown 层面自动套用合适的排版容器。这是我们比纯手动排版工具强的核心——AI 理解内容,自动匹配最佳呈现方式。
**分析维度**:文章类型(访谈/教程/产品介绍/深度分析)、内容元素(对话/图片/代码/数据)、节奏感(密集段 vs 留白段)。
**自动套用规则**(按优先级):
1. **对话/访谈** → `:::dialogue[标题]`
- 检测到 `**名字:**` 或 `名字:` 交替出现 → 用 `:::dialogue` 包裹
- 格式:`名字: 对话内容`(中英文冒号都支持)
- 不是所有对话都要套——独白段落、叙述性段落保持原样
- 同一场景的连续对话放一个 dialogue 块,换场景换一个新块
2. **连续双图并排** → `:::duo`
- 检测:连续 2 张图片,中间最多隔一段 ≤ 60 字短文字,且两图比例相近(不是一明显横一明显竖)
- 动作:把两张图包进 `:::duo`(标题通常留空,例:`:::duo\n\n\n\n:::`)
- **图说处理(方案 B 折叠)**:
- 紧邻图片的句子若在"讲这张图"(描述内容/举例/"我试了...") → 折成 `*斜体*` 紧跟对应图片(作为图说)
- 若是过渡/总括句("这创意太绝了""还有人..."作为章节承接) → **保留**在 `:::duo` 容器上方正文,不吃
- 无相邻描述句时 → 自动用 `alt` 文字(`alt` 长度 1–20 字)
- **尊重作者**:作者已手写 `*斜体*` 图说 → 绝不吃相邻句子
- 3 张及以上连续图走第 3 条(`:::gallery`)
3. **连续多图 / HTML 图片组** → `:::gallery[标题]`
- 3 张以上连续图片 → 自动套 `:::gallery`
- 文章里已有的 `<div align=center><img ...></div>` 图片组会被脚本自动识别
- 脚本会自动区分顺序型 / 展示型图组:有有效 alt/图说、数量少、或不像同一批素材时保持原序;4 张以上、无有效图说、文件名像同一批素材时判定为展示型,可为版面重排
- 渲染时按每张图片真实比例选择宽度:特别宽的横图通栏,其他图片最多两列;展示型图组会把尺寸相近的图片放在同一水平栏里,让整组尽量接近矩形,减少大块留白和锯齿形边界;保留完整画面,不做裁剪
- 适合产品截图、对比图、系列图;不要把所有图片机械堆成纵向列表,也不要强行裁成固定九宫格
4. **超长图片** → `:::longimage[标题]`
- 流程图、架构图、长截图 → 固定高度容器,纵向滚动
- 一般需要用户标注或 AI 判断图片内容
5. **核心观点/金句** → callout 格式
- 核心观点 → `> [!important] 标题`
- 小技巧/提示 → `> [!tip] 标题`
- 注意事项 → `> [!warning] 标题`
- 普通引用 → `> [!callout] 标题`(使用主题色)
- 不要过度使用,一篇文章 1-3 处即可
6. **分隔符** → 在章节转换处确保有 `---` 分隔
7. **图说标记** → 图片后紧跟的说明用斜体:`*这是图片说明*`
- 在 `:::duo` 内若作者未写 `*斜体*`,AI 可按方案 B 折叠相邻描述句作为图说
8. **外部链接** → 无需处理(脚本自动转脚注)
**处理完成后**,把增强后的 Markdown **直接写回原文件**(图片所在目录)。禁止保存到 `/tmp/` 等其他目录,否则图片相对路径会失效。
#### 第 2.5 步:推荐主题
根据内容分析结果,推荐 2-3 个最适合的主题(不确定时默认 hanzhang):
| 内容类型 | 推荐主题 |
|----------|----------|
| 深度长文/分析/调查 | hanzhang, newspaper, magazine |
| 科技产品/AI工具/教程 | hanzhang, github |
| 文艺/随笔/观点 | terracotta, ink |
| 传统文化/国风题材 | chinese |
推荐的主题 ID 通过 `--recommend` 参数传给脚本,在 gallery 中高亮显示。
#### 第 3 步:打开主题画廊(默认流程)
```bash
python3 {baseDir}/scripts/format.py \
--input "文章路径.md" \
--gallery \
--recommend hanzhang newspaper github
```
这会用用户的**真实文章**渲染全部精品主题,在浏览器打开画廊页面。用户点按钮切换主题预览,选中后点「用这个风格排版」一键复制到剪贴板。
#### 第 3 步(备选):直接指定主题排版
如果用户已经知道想用哪个主题,可以跳过画廊直接排版:
```bash
python3 {baseDir}/scripts/format.py \
--input "文章路径.md" \
--theme terracotta
```
#### 第 4 步:确认结果
告诉用户:
- Gallery 模式:在浏览器中切换主题预览,选中后点按钮复制,粘贴到公众号后台
- 直接模式:在浏览器中检查预览,点「复制到微信」按钮
---
### 封面图生成(可选)
排版完成后,用户说"配封面""生成封面"时执行。
#### 封面硬规则(生成图和现成图裁切都必须遵守)
微信会在两个场景二次加工封面,不满足下面规则的封面会在这两个场景翻车(2026-08 实测踩坑):
1. **主封面下沿会被压白字标题**。分享卡片/发表预览会把文章标题用白色文字叠在封面下部约 1/3 区域。因此**封面下部 40% 必须是深色或中深色**——浅色/纯白底封面标题直接隐形。用现成截图当封面且底部偏浅时,必须加"从中部向底部渐深的黑色遮罩"(PIL 渐变合成即可,publish.py 提供 `--darken-cover` 自动处理),或换深色素材。
2. **多图文次条封面是小方图**。第 2 篇起的封面在卡片里以约 1:1 小尺寸展示,**只能用大主体、大色块、粗轮廓的图**;细字截图、密集图表、白底细线图缩小后糊成白块,一律禁用。给次条选封面先问一句:缩到 100px 见方还认得出吗?
3. 主封面 2.35:1(900×383 或等比高清),次条建议同时准备 1:1 裁切版本。
4. 推送前用 publish.py 的封面亮度检查结果确认,警告未消除不要发布。
#### 封面提示词模板
```
请根据提供的内容创建一张吸引眼球的公众号封面图,遵循以下规范:
视觉风格
- Notion插画风格,比例为 2.35:1(公众号封面标准尺寸)
- 色彩鲜明、对比强烈,确保在小尺寸预览时依然醒目
- 风格统一,避免写实元素,保持整体手绘质感
构图要求
- 主视觉元素居中或偏左(右侧预留标题区域)
- 添加 1-2 个简洁的卡通形象、图标或知名人物剪影,增强记忆点
- 大量留白,突出核心信息,避免画面拥挤
- 画面下部 40% 使用深色或中深色调(微信分享卡片会在封面下沿叠加白色标题文字,浅底会让标题隐形)
文字处理
- 标题文字大而醒目,控制在 8 字以内
- 可添加 1 行副标题或关键词标签
- 字体风格与手绘插画协调统一
吸引力法则
- 使用悬念、数字、痛点等钩子元素激发点击欲望
- 视觉元素夸张有反差
- 色彩搭配参考爆款封面:橙黄、蓝紫、红黑等高对比组合
语言
- 除非另有说明,默认使用中文
- 画面内所有可读文字必须使用简体中文,英文只能作为点缀出现
内容主题:{从文章中提炼的一句话主题描述}
```
#### 封面工作流
1. 从文章提炼一句话主题
2. 用上述模板生成提示词,保存为 `prompt.md`(YAML 头 `aspect_ratio: "21:9"`, `image_size: "2K"`)
3. 调用图片生成服务(需在 `config.json` 中配置 `cover.image_generation_script`,或手动使用任意 AI 生图工具)
4. 生成后默认插入文章标题下方
---
### 推送到公众号草稿箱(可选)
排版完成后,用户说"推送""发公众号"时执行。需要在 `config.json` 配置 `wechat.app_id` 和 `wechat.app_secret`。
```bash
python3 {baseDir}/scripts/publish.py \
--dir "排版输出目录" \
--cover "封面图路径(可选)"
```
推送流程:
1. 读取排版后的 HTML(`article.html`)
2. 上传文章内图片到微信 CDN
3. 上传封面图为素材
4. 创建草稿(自动填充标题、摘要、作者)
5. 返回 media_id,可在公众号后台「内容管理→草稿箱」查看
也支持从 Markdown 直接推送(自动排版再推):
```bash
python3 {baseDir}/scripts/publish.py \
--input "文章.md" \
--theme hanzhang
```
多图文(一条草稿多篇文章,微信上限 8 篇):
```bash
python3 {baseDir}/scripts/publish.py \
--input 第一篇.md 第二篇.md \
--cover 封面1.jpg 封面2.jpg \
--theme hanzhang --yes
```
---
### 参数说明
**format.py**:
- `--input` / `-i`:Markdown 文件路径(必须)
- `--gallery`:打开主题画廊(推荐,默认使用)
- `--theme` / `-t`:直接指定主题名(跳过画廊)
- `--output` / `-o`:输出目录(默认 /tmp/wechat-format)
- `--vault-root`:Obsidian Vault 根目录(用于搜索 wikilink 图片)
- `--recommend`:推荐的主题 ID 列表,gallery 中高亮显示
- `--no-open`:不自动打开浏览器
- `--format`:输出格式 wechat/html/plain
**publish.py**:
- `--dir`:排版输出目录路径(已排版好的 HTML,单篇)
- `--input`:Markdown 文件路径,**可传多个**(多个文件 = 一条多图文草稿,微信上限 8 篇)
- `--cover` / `-c`:封面图路径,可传多个与 `--input` 一一对应(省略则自动搜索)
- `--title` / `-t`:文章标题(默认从 HTML 提取;多图文时仅作用于第一篇)
- `--digest`:文章摘要(默认自动取首段前 100 字;多图文时仅作用于第一篇)
- `--theme`:排版主题(仅 `--input` 模式有效)
- `--author` / `-a`:作者名(默认读 config.json)
- `--darken-cover`:封面下部自动加渐暗遮罩(浅底封面必开,见封面硬规则)
- `--yes` / `-y`:跳过交互确认(非交互环境下部分图片失败时默认中止,需此参数放行)
- `--dry-run`:只做排版和图片上传,不推送草稿箱
- `--source-dir`:源文件目录(仅 `--dir` 模式需要,用于查找封面图)
**封面图搜索逻辑**:默认按以下顺序查找封面图 `*-cover.png`:
1. `--cover` 指定路径
2. `--dir` 目录的子目录 `images/`
3. `--source-dir` 目录(`--dir` 模式)或 `--input` 文件同级目录(`--input` 模式)
**推荐目录结构**:文章 `.md` 与图片 `images/` 同级平铺,封面图放在 `images/` 内。
### 可用主题(精品 7 个)
2026-08 从 34 个精简而来,只保留互相拉得开差距、手机端验证过的主题;被删主题可从 git 历史找回。
| 主题 | 命令值 | 风格 | 适用 |
|------|--------|------|------|
| 含彰(默认) | hanzhang | 克制现代,单一靛蓝强调,零渐变,深色模式原生安全 | 所有内容的首选 |
| 报纸 | newspaper | 纽约时报风 | 严肃深度长文 |
| GitHub | github | 开发者风,浅色代码块 | 技术文章、代码分享 |
| 杂志 | magazine | 超大留白 | 品质长文 |
| 墨韵 | ink | 纯黑水墨,极简留白 | 极简审美 |
| 中国风 | chinese | 朱砂红,古典雅致 | 传统文化题材 |
| 赤陶 | terracotta | 暖橙色 | 文艺随笔 |
### 内置排版增强
脚本自动处理以下内容:
- **CJK 间距修复**:中英文/中数字之间自动加空格
- **加粗标点修复**:`**文字,**` → `**文字**,`,中文标点移到标记外
- **纯内联样式**:所有 CSS 直接写在每个标签的 `style="..."` 属性上
- **列表模拟**:`<ul>/<ol>` 改为 `<section>` + flexbox 模拟
- **外链转脚注**:`[text](url)` 自动变成正文 `text[1]` + 文末脚注列表
- **图片处理**:`![[image.jpg]]` 自动搜索 Vault 并复制到输出目录
- **图片自适应宽度**:单图按真实长宽比自动映射渲染宽度(横图 100%、近方形 75%、轻竖图 60%、长竖图 45%),避免竖图在手机上占满屏幕。测量失败回退 70%。
- **HTML 图片组自适应图墙**:自动处理 `<div align=center><img ...></div>` 这类原生 HTML 图片组,按每张图片比例分配通栏 / 双列;顺序型保持原序,展示型允许自动重排,把尺寸相近的图配成水平栏来减少留白;保留原图比例,不使用 `object-fit: cover` 裁剪。
- **多类型提示框**:`[!tip]`/`[!note]`/`[!important]`/`[!warning]`/`[!caution]` 各有独立配色
- **图说识别**:图片后紧跟的斜体段落自动变为居中灰色图说
- **对话气泡**:`:::dialogue[标题]` → 左右交替聊天气泡
- **图片画廊**:`:::gallery[标题]` → 多图自适应图墙,按图片比例分配宽度;手写 gallery 默认保持原序,自动识别到的展示型 HTML 图组可重排以减少留白,并保留完整画面
- **长图展示**:`:::longimage[标题]` → 固定高度纵向滚动容器
- **两栏并排**:`:::duo[标题]` → 两图左右并排 + 下方居中图说,适合成对对比图(AI 在连续双图时自动套用)
### 注意事项
- 依赖 Python `markdown` 库和 `Pillow`(`pip install markdown Pillow`)
- 图片在预览中可见,但粘贴到微信后需要手动上传(或用推送功能自动上传)
- 如果用户对排版不满意,可以切换主题重新生成
- 画廊模式渲染 20 个主题,用的是用户的真实文章
### 图片路径规则(必须遵守)
脚本的 `--input` 文件必须和图片在同一目录。脚本按 `--input` 文件所在目录解析相对路径的图片引用(如 ``)。
**禁止**以下操作:
- 把增强版 Markdown 保存到 `/tmp/` 等不含图片的目录
- 用 `--input` 指向一个不在图片目录中的文件
- 带远程图片 URL(``)直接排版——外链图无法测量尺寸(一律回退 70%),且公众号后台不加载外链图。发现外链图先下载到本地 `images/` 并改为相对路径,再继续排版
**正确做法**:始终用原始文章文件的路径作为 `--input`。如需做排版增强(加 callout、分隔符等),直接写回原文件。