# AWS Wechat Article Formatting

> 公众号排版｜Markdown 转 HTML｜排版主题｜段落样式 — 公众号一键排版工具，Markdown 文稿转微信后台可粘贴 HTML，多主题、多字号、段落样式切换，所见即所得。面向公众号编辑、独立作者、排版岗。触发词：「排版」「版式」「美化」「格式化」「字号」「段落样式」「换个排版主题」「换个版式」「转 HTML」「弄好看点」「调整格式」。换预设包/品牌包/整套主题配色请走 aws-wechat-article-assets；需要多环节串联（写+审+排+配图+发）请走 aws-wechat-article-main。

- Skill: `aiworkskills/aws-wechat-article-formatting` (Agent Skill, multi-file: 81 files)
- Install (CLI): `npx skillmds@latest add aiworkskills/aws-wechat-article-formatting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aiworkskills/aws-wechat-article-formatting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: aiworkskills (https://skillmd.com/u/aiworkskills)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/aiworkskills/aws-wechat-article-formatting

---


# 排版

**公众号一键排版** —— Markdown 转微信后台可粘贴 HTML，多主题、多字号、所见即所得。

> **套件说明** · 本 skill 属 `aws-wechat-article-*` 一条龙套件（共 9 个 slug，入口 `aws-wechat-article-main`）。跨 skill 的相对引用依赖同一 `skills/` 目录，建议一并 `clawhub install` 全套。源码：<https://github.com/aiworkskills/wechat-article-skills>

## 能力披露（Capabilities）

本 skill 为**纯本地** Markdown → HTML 转换，零网络、零凭证。

- **凭证**：无
- **网络**：无
- **文件读（仓库内）**：`.aws-article/config.yaml`、本篇 `article.yaml`、`article.md`、可选 `closing.md`、`.aws-article/presets/formatting/<名>.yaml`
- **文件读（仓库外）**：`format.py` 还会检查用户家目录 `~/.aws-article/presets/formatting/`（跨项目共享的自定义排版主题；**只读预设文件，不读凭证**）。不需要这个能力可清空 / 不创建该目录
- **文件写**：本篇 `article.html`
- **shell**：仅 `{python} {baseDir}/scripts/format.py`（`{python}` = 本机 Python 3 解释器，见 [main SKILL 第 0 步](../aws-wechat-article-main/SKILL.md)：Windows 用 `py -3 -X utf8`，macOS / Linux 用 `python3`）

## 配套 skill（informational）

本 skill 是 `aws-wechat-article-*` 一条龙公众号套件的**排版环节**（入口 `aws-wechat-article-main`）。

- **单独安装可直接使用**：本 skill 的脚本 `format.py` 零依赖、纯本地，无跨 skill 脚本调用。
- 工作流文档中会链接到 `../aws-wechat-article-main/references/*.md`（首次引导等）。套件未装齐时，链接跳转会断，但排版功能本身可用。

完整 9 slug 清单见 [源码仓库](https://github.com/aiworkskills/wechat-article-skills)。

## 路由

一键发文且未明确只要排版 → [aws-wechat-article-main](../aws-wechat-article-main/SKILL.md)。

将 Markdown 文章转换为微信公众号兼容的 HTML，所有样式 inline。

## 脚本目录

**Agent 执行**：确定本 SKILL.md 所在目录为 `{baseDir}`。

| 脚本 | 用途 |
|------|------|
| `scripts/format.py` | Markdown → 微信兼容 HTML |

## 配置检查 ⛔

任何操作执行前，**必须**按 **[首次引导](../aws-wechat-article-main/references/first-time-setup.md)** 执行其中的 **「检测顺序」**。**单独启用本 skill** 时同上。检测通过后才能进行以下操作（或用户明确书面确认「本次不检查」）。

## 内置模版

排版 = **模版**（骨架：标题装饰、导语、金句卡、图片处理、分隔、文末）× **配色**（一组主色/次色，派生色自动重算）。名字即用途，选之前先看「适合」：

| 模版 | 适合 | 不适合 | 配色（第一个是默认） |
|------|------|--------|---------|
| `亲和` | 教程、职场、面向新手的解释性长文 | 严肃议题、极简冷硬的品牌 | 黛紫 / 松绿 / 靛蓝 |
| `资讯` | 快讯、评测、行业观察 | 抒情散文、碎片化短段 | 墨绿 / 绛红 / 藏青 |
| `书卷` | 人文、读书、历史、深度长文 | 工程文档、数据密集的评测 | 朱砂 / 黛蓝 / 苍绿 |
| `杂志` | 品牌故事、人物访谈、生活方式 | 没有配图的稿子、信息型短文 | 石青 / 驼褐 / 铁锈 |

另外四套不随 skill 内置，在 aiworkskills.cn 选好模版和配色后随 `.aws` 预设包下发到 `.aws-article/presets/formatting/`（见 assets skill）：`活力`（产品发布、增长复盘）、`手账`（个人笔记、复盘）、`硬朗`（观点、宣言）、`技术`（工程实践、代码讲解）。网站上选的配色会烘进 YAML 顶层 `variables`，落地后不需要额外配置。

**选之前先跑一次**，判据、色值、每套配色的口径都在输出里，别只按名字猜：

```bash
{python} {baseDir}/scripts/format.py --list-themes
```

**说不清就看**：`--preview` 把样张渲成并列对照页（每栏 375px，与真机同宽），写成 HTML 用浏览器打开。

```bash
{python} {baseDir}/scripts/format.py --preview 亲和 -o preview.html   # 该模版的每套配色并列
{python} {baseDir}/scripts/format.py --preview -o preview.html        # 所有模版的默认色并列
```

线上同一批预览：`https://aiworkskills.cn/format-previews/<骨架>/<配色序号>.html`，骨架名见 `--list-themes`。

**换配色**：`--scheme <配色名>`，或本篇 `article.yaml` 写 `default_format_scheme: [松绿]`（单元素列表，由 main 的本篇预设落盘步骤写入）。

## 图注只认显式写的 title ⛔

```
![信息图：画面指令给生图模型看](imgs/x.png "图注给读者看")
```

括号里路径之后引号中的才是图注。**alt 冒号后那段是画面指令，不会显示给读者。**

早先的实现拿画面指令兼任图注，产出过这种东西：图上画着一个人站在 99.9 的牌子前
望向远方，图注写「开发者站在巨型 99.9 分数牌前，视线越过分数望向复杂而开放的城市与
工作现场」——把读者眼睛已经看见的复述一遍，零信息；图没生成出来时更会同一句话出现
两次（破图 alt 一次、图注一次）。

**没写 title 就不出图注**，这是有意的：绝大多数图不需要图注，错的图注比没有更糟。
图注该补充画面之外的东西——数据出处、一句判断、反常识的细节。

## 从标准 markdown 认形态（主路径）

**写作侧只产出标准 markdown**，识别结构是排版层的事。让写手同时掌握标准 markdown
和一套私有语法就是耦合，而且那套语法只有本套件认得，稿子换个工具就废了。

渲染器会认这些形态，作者不用写任何特殊语法：

| 作者写的标准 markdown | 排版层做的事 |
|---|---|
| `- **标签**：说明` | 标签在视觉上提出来（真稿里 62% 的列表项是这个形状） |
| `- [ ]` / `- [x]` | 换成该骨架的三态图标 |
| `> 引文` | 前面补一个大引号 |
| `![图](x.png "图注")` | 四角标 + 图注 |
| `---` | 装饰分隔 |
| `##` | 标题装饰（笔锋 / 折角块） |

**只认形态，不推断语义。** 有序列表在 markdown 里只表示「枚举」不表示「顺序」，
所以不会因为看见 `1. 2. 3.` 就渲染成「第一步 第二步」——那是替作者断言一个他没说的
顺序。真稿实测：三组多项有序列表里只有一组真有先后。

## 版式组件（:::块，手写可用，不再写进写作提示词）

⚠️ **2026-09-07 起 `:::` 语法不再写进写作提示词**（原 `write.py::build_components_block`
已移除）。排版侧仍然认它——存量草稿不会废，用户手写也有效——但写手不会再产出它。
代价是 `stat`（大数字对）和 `layers`（层级图）这两个 markdown 表达不了的组件，
除非手写否则不会出现。这是「解耦」这个取舍明确付出的成本。

主题只能给标签配内联样式，表达不了结构——而微信没有伪元素，「标题前的角标」
「引用块的大引号」必须**真的插元素**。组件补的就是这一层：

```
:::section-title[01]
同一个模型，两个分数
:::

:::quote-card[AWS 团队]
基准分数衡量的是你缺哪个 harness，不是模型的能力上限。
:::
```

**`lead`（导语）与 `closing`（文末区块）几乎每篇都该有**——实测本账号 7/7 篇文章
开头都有一段导语、结尾都有互动引导与署名，此前一律是裸文本或借用引用块的样式。
导语刻意不做成带底色的卡片，就是为了和 `blockquote` 分开：两者语义不同
（作者的开场白 vs 引用别人的话），此前共用样式导致长得一模一样。

### `:::highlight` / `:::note`（提示框）

```
:::highlight
先确定行高、段距、留白这三个数，再考虑换模板。顺序反了，换多少套都没用。
:::
```

它不是组件文件，而是直接套用主题里的 `highlight` 样式——16 套主题全都定义了它。
**此前没有任何语法能产出它**：主题写了样式、门户预览也一直在渲染，但真实文章里
做不出来，预览承诺了交付不了的东西。想给它做结构的骨架，放一个同名组件文件即可覆盖。

内置组件在 [references/components/](references/components/)，用户自定义放
`.aws-article/presets/components/<名>.yaml`，同名覆盖内置。
组件还可以**按骨架整套替换**：`references/components/<骨架名>/<组件名>.yaml`，
查找顺序是「内置基础版 → 骨架专属 → 用户自定义」，后者覆盖前者。每个组件的 YAML 里带
`when_to_use` / `when_not_to_use` / `anti_pattern`——**选组件前先读这三项**，
它们和配图方法里的判据是同一个作用：拦住「因为好看所以用」。

组件模板里的 `{primary-color}` `{text-color}` 等占位符从当前主题取值，所以组件
与任何主题组合都不会脱节。未知组件名或缺少结尾 `:::` 时按原文输出并告警，不吞内容。

## 设计新版式前必读 ⛔

微信正文只认**内联样式**，没有伪元素、没有伪类、`position` 与 `id` 会被整条删掉。
这决定了「装饰必须作为真实元素插进 HTML」，而不能靠 CSS 变出来。
能用什么、什么会被剥离，见 [wechat-html-constraints.md](references/wechat-html-constraints.md)。

## 工作流

```
排版进度：
- [ ] 第0步：配置检查（见本节「配置检查」）⛔
- [ ] 第1步：确定主题（与合并配置 / 用户指定）
- [ ] 第2步：转换
- [ ] 第3步：输出 HTML
```

### 第1步：确定主题

主题解析顺序（**`format.py` 行为**与智能体择一）：

1. **命令行** `--theme <名称>`：显式指定时**始终优先**。
2. **未传 `--theme`**：`format.py` 仅读取 **与 `article.md` 同目录的 `article.yaml`** 中 **`default_format_preset`**（**须为 YAML 列表**：`[]` 或单元素 `[主题名]`）；为空则用内置主题名 **`default`**。
3. 智能体在对话中帮用户选主题时，按：用户口述 → 本篇 `article.yaml.default_format_preset` → `.aws-article/presets/formatting/` 自定义 → 内置 `default`。`custom_* / default_*` 候选池解析由 main 在“本篇准备”阶段完成并写回 `article.yaml`。

主题名须对应 **内置主题** 或 **`.aws-article/presets/formatting/<名>.yaml`**。字段说明见 [articlescreening-schema.md](../aws-wechat-article-main/references/articlescreening-schema.md)（与仓库 `config.yaml` 顶层字段对齐）。

### 第2步：转换

在**仓库根**执行（路径按实际本篇目录调整）：

```bash
# 不传 --theme：使用合并配置中的 default_format_preset，否则 default
{python} {baseDir}/scripts/format.py drafts/YYYYMMDD-slug/article.md -o drafts/YYYYMMDD-slug/article.html

# 显式指定模版 / 配色（覆盖配置）
{python} {baseDir}/scripts/format.py drafts/YYYYMMDD-slug/article.md --theme 资讯 --scheme 绛红 -o drafts/YYYYMMDD-slug/article.html

# 自定义主色 / 字号
{python} {baseDir}/scripts/format.py article.md --theme 资讯 --scheme 绛红
{python} {baseDir}/scripts/format.py article.md --font-size 15px

# 列出可用主题
{python} {baseDir}/scripts/format.py --list-themes
```

### 嵌入元素 `{embed:...}`

- **`format.py`**：**名片 / 小程序** 的 `embeds` 以 **`.aws-article/config.yaml`** 为准；**仅「往期链接」**：本篇 `article.yaml` 可写 **`embeds.related_articles`**，与全局 **`related_articles` 深度合并**（用于每篇不同推荐）。合并结果中非空 **`embeds`** 时解析 `{embed:profile|miniprogram|miniprogram_card|link:名称}`；否则不对嵌入占位符做替换（视为无配置）。
- 与 [writing 结构模板](../aws-wechat-article-writing/references/structure-template.md) 中的占位说明一致。

### 第3步：输出 HTML

输出的 HTML 特性：
- 所有样式 inline（微信编辑器兼容）
- **正文不含文章标题**：Markdown 中第一个 `#`（h1）在转换时被跳过，标题在公众号后台单独填写，正文不重复
- 配图标记 `![类型：描述](placeholder)` 保留为 `<img>` 标签，待 images skill 替换
- 图注自动从标记描述中提取
- 同目录存在 **`closing.md`** 时，`format.py` 会追加到文末（脚本既有行为）；`closing.md` 自己的首个 `#` 标题会保留，只有 `article.md` 的首个 `#` 被视为文章标题跳过
- 预格式化（中英文加空格、ASCII 引号转「」、合并空行）只作用于正文文字：围栏代码块、行内代码、链接/图片目标、`{embed:…}`、原生 HTML 标签与裸 URL 原样保留，行内代码内容做 HTML 转义。不需要预格式化时加 `--no-preformat`
- 表格支持 `|:---:|` 这类对齐行

## 选项

| 选项 | 说明 | 默认值 |
|------|------|--------|
| `--theme <名称>` | 模版/主题；**省略则按合并配置 → 内置默认 `块`** | 见上文 |
| `--scheme <配色名>` | 模版的配色方案（见 `--list-themes`）；省略则读本篇 `default_format_scheme`，再无则模版默认色 | 模版默认 |
| `--color <hex>` | 自定义主色 | 主题默认 |
| `--font-size <px>` | 正文字号（同时覆盖主题 p / li 里的字号） | 16px |
| `-o <路径>` | 输出路径 | 同名 .html |
| `--list-themes` | 列出模版：长相、适合/不适合、每套配色的色值与口径 | |
| `--preview [模版名]` | 把样张渲成并列对照页（给模版名则并列它的每套配色，不给则并列所有模版） | |
| `--export-theme <名称>` | 以 YAML 导出主题（合并默认变量与样式），重定向到文件即可作为自定义主题起点 | |
| `--no-preformat` | 跳过 Markdown 预格式化 | |

## 自定义主题

在 `.aws-article/presets/formatting/` 下新建主题文件即可。快速起步：

```bash
{python} {baseDir}/scripts/format.py --export-theme 亲和 > .aws-article/presets/formatting/my-brand.yaml
```

主题文件格式和扩展方式详见：[references/presets/README.md](references/presets/README.md)

## 过程文件

| 读取 | 产出 |
|------|------|
| `article.md`、**`.aws-article/config.yaml` + 同目录 `article.yaml`**（默认主题与 `embeds`）、`closing.md`（可选） | `article.html` |

