Skip to content
Back to skills

Hkr Render

ASecurity

WeChat Official Account (微信公众号) publishing pipeline: format Markdown or plain text into WeChat-compatible inline-style HTML with 7 polished themes (dark mode and mobile font sizes tuned), optionally generate a cover image with brightness check and auto-darkening, and push one or many articles to the WeChat draft box (多图文). Use when the user wants to format, typeset or publish a WeChat article, or says 排版, 微信排版, 公众号排版, 公众号发布, 格式化文章, format, /format. Requires a config.json with WeChat AppID/Sec...

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
ai-agentspythonbashgit

Works with

  • claude code

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 17 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add hanzhangzzz/agent-skills-zh --skill hkr-render --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hkr Render?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hkr Render
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hanzhangzzz-hkr-render/badge)](https://www.skillsdirectory.com/skills/hanzhangzzz-hkr-render)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: hkr-render
description: |
  WeChat Official Account (微信公众号) publishing pipeline: format Markdown or plain text into WeChat-compatible inline-style HTML with 7 polished themes (dark mode and mobile font sizes tuned), optionally generate a cover image with brightness check and auto-darkening, and push one or many articles to the WeChat draft box (多图文). Use when the user wants to format, typeset or publish a WeChat article, or says 排版, 微信排版, 公众号排版, 公众号发布, 格式化文章, format, /format. Requires a config.json with WeChat AppID/Secret (see SKILL.md).
trigger: /format
compatibility: Claude Code, Codex
license: MIT
---

# 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![...](a.jpg)\n\n![...](b.jpg)\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` 文件所在目录解析相对路径的图片引用(如 `![alt](photo.jpg)`)。

**禁止**以下操作:
- 把增强版 Markdown 保存到 `/tmp/` 等不含图片的目录
- 用 `--input` 指向一个不在图片目录中的文件
- 带远程图片 URL(`![...](http...)`)直接排版——外链图无法测量尺寸(一律回退 70%),且公众号后台不加载外链图。发现外链图先下载到本地 `images/` 并改为相对路径,再继续排版

**正确做法**:始终用原始文章文件的路径作为 `--input`。如需做排版增强(加 callout、分隔符等),直接写回原文件。

Files in this skill

  • .gitignore83 B
  • README.md5.7 KB
  • README_CN.md4.9 KB
  • SKILL.md18 KB
  • config.example.json544 B
  • references/cover-config.example.json1.3 KB
  • references/cover-generation.md4.5 KB
  • scripts/comment_reply.py11.5 KB
  • scripts/format.py86.9 KB
  • scripts/generate.py24.8 KB
  • scripts/publish.py23.3 KB
  • templates/gallery.html10.9 KB
  • templates/preview.html7 KB
  • themes/chinese.json8.4 KB
  • themes/github.json8.3 KB
  • themes/hanzhang.json7.7 KB
  • themes/ink.json7.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.