PostPress — Format & Package Articles for WeChat Publishing
PostPress formats and packages Markdown articles for WeChat Official Account (公众号) publishing. It handles all the painful WeChat editor constraints automatically — inline styles, base64 images, link-to-footnote conversion, code formatting — so you can write in Markdown, publish to WeChat in one step.
Also supports X/Twitter Articles as a secondary target.
Key Features
- One-command WeChat publishing — Markdown → clipboard-ready HTML, paste directly into the WeChat MP editor
- Full WeChat compatibility — inline styles only, base64-encoded images, tag sanitization, footnoted links
- Image processing — local images auto-compressed and embedded as base64 data URIs (≤ 2MB)
- Mermaid diagrams — code blocks rendered to PNG via Playwright (optional)
- Code highlighting — syntax colors inlined, whitespace preserved for WeChat's quirky rendering
- X/Twitter Articles mode — semantic HTML subset for X Articles editor
Installation
npm install -g @liustack/postpress@latest
Version check: Before converting, run postpress --version. If the command is not found or the version is outdated, re-run the install command above.
Playwright Chromium (Required for Mermaid)
mermaid and playwright are bundled as dependencies. After installing, download the Chromium browser binary:
npx playwright install chromium
Without Chromium, mermaid code blocks will trigger an error. All other features work without it.
Usage
# Format Markdown for WeChat and save to file
postpress -i article.md -o output.html
# Format and copy to clipboard — paste directly into WeChat MP editor
postpress -i article.md -o output.html --copy
# Format for X/Twitter Articles
postpress -i article.md -o output.html --target x
Output is JSON:
{
"input": "/absolute/path/to/article.md",
"output": "/absolute/path/to/output.html",
"size": 12345
}
Options
-i, --input <path> — Input Markdown file path (required)
-o, --output <path> — Output HTML file path (required)
-t, --target <target> — wechat (default), x, or twitter (alias of x)
-c, --copy — Copy rendered HTML to system clipboard as rich text (for direct paste into WeChat editor)
Mandatory Workflow (AI Agent MUST Follow)
[!CAUTION]
Every Markdown-to-WeChat conversion MUST follow these steps. Do NOT skip or reorder.
- Prepare Markdown — Write or locate the Markdown file. Ensure all images use relative paths from the Markdown file's directory.
- Confirm output path — Decide where the HTML should be saved (the
-o path).
- Run PostPress — Execute the conversion:
postpress -i article.md -o output.html
Or with clipboard copy:postpress -i article.md -o output.html --copy
- Check result — Verify the JSON output shows a successful result with
size > 0.
- Deliver — Tell the user the output HTML path. If
--copy was used, inform them the HTML is ready to paste directly into the WeChat MP editor.
What PostPress Handles for WeChat
[!IMPORTANT]
The WeChat MP editor has strict limitations. PostPress handles all of these automatically so you don't have to.
| WeChat Constraint |
How PostPress Solves It |
Inline styles only — no <style>, <link>, <script> |
All CSS converted to style attributes |
| No external images |
Local images compressed (sharp) → base64 data URIs (≤ 2MB) |
| Limited tag support |
<div> → <section>, dangerous tags removed, tag whitelist enforced |
| Code formatting breaks |
\n → <br>, spaces → NBSP, tabs → NBSP pairs, text-align: left |
| External links blocked |
Links → text + <sup>[N]</sup> footnotes; mp.weixin.qq.com links preserved |
| No class attributes |
All className removed; hljs colors → inline styles |
Image Handling
| Source |
Behavior |
| Local file (relative path) |
Compressed via sharp → base64 data URI (PNG preferred, ≤ 2MB) |
data: URI |
Skipped (already inline) |
http:// / https:// URL |
Skipped (passed through as-is) |
| GIF |
Preserved as animated GIF, resized if > 2MB |
| SVG |
Rasterized to PNG via sharp (WeChat doesn't support data:image/svg+xml) |
[!CAUTION]
Images must use relative paths from the Markdown file location. Absolute paths or URLs to local files won't resolve correctly.
X/Twitter Articles Mode
Use --target x (or --target twitter) for X Articles editor:
- Keep only semantic subset:
h2, p, strong/b, em/i, s/del, a, blockquote, ul/ol/li, br
- Convert every image to placeholder text:
[Image: ...]
- Remove unsupported structure/style tags
- Keep only
https:// links as <a href="...">
- Convert
//... links to https://...
- Downgrade non-HTTPS links to plain text
Pipeline Processing Order
Markdown → remarkParse → remarkGfm → remarkRehype → rehypeRaw
→ 1. rehypeSanitizeTags (tag whitelist, div→section, checkbox→Unicode, attribute cleanup)
→ 2. rehypeMermaid (mermaid code blocks → Playwright render → PNG base64, optional)
→ 3. rehypeBase64Images (local images → sharp compress → base64 data URI)
→ 4. rehypeCodeHighlight (syntax highlighting + whitespace protection)
→ 5. rehypeFootnoteLinks (external links → footnotes, preserve mp.weixin.qq.com)
→ 6. rehypeInlineStyles (default styles + hljs colors → inline style attr, remove className)
→ rehypeStringify → HTML
Output Verification Checklist
After conversion, the output HTML should have:
1---2name: postpress3description: Use when the user wants to convert Markdown into editor-ready HTML for WeChat Official Accounts or X Articles, including inline styles, embedded local images, rich-text clipboard output, or platform-safe link handling.4---56# PostPress — Format & Package Articles for WeChat Publishing78**PostPress** formats and packages Markdown articles for **WeChat Official Account (公众号) publishing**. It handles all the painful WeChat editor constraints automatically — inline styles, base64 images, link-to-footnote conversion, code formatting — so you can **write in Markdown, publish to WeChat in one step**.910Also supports X/Twitter Articles as a secondary target.1112## Key Features1314- **One-command WeChat publishing** — Markdown → clipboard-ready HTML, paste directly into the WeChat MP editor15- **Full WeChat compatibility** — inline styles only, base64-encoded images, tag sanitization, footnoted links16- **Image processing** — local images auto-compressed and embedded as base64 data URIs (≤ 2MB)17- **Mermaid diagrams** — code blocks rendered to PNG via Playwright (optional)18- **Code highlighting** — syntax colors inlined, whitespace preserved for WeChat's quirky rendering19- **X/Twitter Articles mode** — semantic HTML subset for X Articles editor2021## Installation2223```bash24npm install -g @liustack/postpress@latest25```2627> **Version check**: Before converting, run `postpress --version`. If the command is not found or the version is outdated, re-run the install command above.2829### Playwright Chromium (Required for Mermaid)3031`mermaid` and `playwright` are bundled as dependencies. After installing, download the Chromium browser binary:3233```bash34npx playwright install chromium35```3637> Without Chromium, mermaid code blocks will trigger an error. All other features work without it.3839## Usage4041```bash42# Format Markdown for WeChat and save to file43postpress -i article.md -o output.html4445# Format and copy to clipboard — paste directly into WeChat MP editor46postpress -i article.md -o output.html --copy4748# Format for X/Twitter Articles49postpress -i article.md -o output.html --target x50```5152Output is JSON:5354```json55{56 "input": "/absolute/path/to/article.md",57 "output": "/absolute/path/to/output.html",58 "size": 1234559}60```6162## Options6364- `-i, --input <path>` — Input Markdown file path (required)65- `-o, --output <path>` — Output HTML file path (required)66- `-t, --target <target>` — `wechat` (default), `x`, or `twitter` (alias of `x`)67- `-c, --copy` — Copy rendered HTML to system clipboard as rich text (for direct paste into WeChat editor)6869## Mandatory Workflow (AI Agent MUST Follow)7071> [!CAUTION]72> **Every Markdown-to-WeChat conversion MUST follow these steps. Do NOT skip or reorder.**73741. **Prepare Markdown** — Write or locate the Markdown file. Ensure all images use **relative paths** from the Markdown file's directory.752. **Confirm output path** — Decide where the HTML should be saved (the `-o` path).763. **Run PostPress** — Execute the conversion:77 ```bash78 postpress -i article.md -o output.html79 ```80 Or with clipboard copy:81 ```bash82 postpress -i article.md -o output.html --copy83 ```844. **Check result** — Verify the JSON output shows a successful result with `size > 0`.855. **Deliver** — Tell the user the output HTML path. If `--copy` was used, inform them the HTML is ready to paste directly into the WeChat MP editor.8687## What PostPress Handles for WeChat8889> [!IMPORTANT]90> The WeChat MP editor has strict limitations. PostPress handles all of these automatically so you don't have to.9192| WeChat Constraint | How PostPress Solves It |93|---|---|94| **Inline styles only** — no `<style>`, `<link>`, `<script>` | All CSS converted to `style` attributes |95| **No external images** | Local images compressed (sharp) → base64 data URIs (≤ 2MB) |96| **Limited tag support** | `<div>` → `<section>`, dangerous tags removed, tag whitelist enforced |97| **Code formatting breaks** | `\n` → `<br>`, spaces → NBSP, tabs → NBSP pairs, `text-align: left` |98| **External links blocked** | Links → text + `<sup>[N]</sup>` footnotes; `mp.weixin.qq.com` links preserved |99| **No class attributes** | All `className` removed; hljs colors → inline styles |100101## Image Handling102103| Source | Behavior |104|--------|----------|105| Local file (relative path) | Compressed via sharp → base64 data URI (PNG preferred, ≤ 2MB) |106| `data:` URI | Skipped (already inline) |107| `http://` / `https://` URL | Skipped (passed through as-is) |108| GIF | Preserved as animated GIF, resized if > 2MB |109| SVG | Rasterized to PNG via sharp (WeChat doesn't support `data:image/svg+xml`) |110111> [!CAUTION]112> **Images must use relative paths** from the Markdown file location. Absolute paths or URLs to local files won't resolve correctly.113114## X/Twitter Articles Mode115116Use `--target x` (or `--target twitter`) for X Articles editor:117118- Keep only semantic subset: `h2`, `p`, `strong/b`, `em/i`, `s/del`, `a`, `blockquote`, `ul/ol/li`, `br`119- Convert every image to placeholder text: `[Image: ...]`120- Remove unsupported structure/style tags121- Keep only `https://` links as `<a href="...">`122- Convert `//...` links to `https://...`123- Downgrade non-HTTPS links to plain text124125## Pipeline Processing Order126127```128Markdown → remarkParse → remarkGfm → remarkRehype → rehypeRaw129 → 1. rehypeSanitizeTags (tag whitelist, div→section, checkbox→Unicode, attribute cleanup)130 → 2. rehypeMermaid (mermaid code blocks → Playwright render → PNG base64, optional)131 → 3. rehypeBase64Images (local images → sharp compress → base64 data URI)132 → 4. rehypeCodeHighlight (syntax highlighting + whitespace protection)133 → 5. rehypeFootnoteLinks (external links → footnotes, preserve mp.weixin.qq.com)134 → 6. rehypeInlineStyles (default styles + hljs colors → inline style attr, remove className)135 → rehypeStringify → HTML136```137138## Output Verification Checklist139140After conversion, the output HTML should have:141142- [ ] No `class=` attributes143- [ ] No `<script>`, `<style>`, `<link>`, `<iframe>`, `<input>`, `<div>` tags144- [ ] All visible elements have `style=` attributes145- [ ] External links replaced with footnote references (`<sup>[N]</sup>`)146- [ ] A `References` section at the end (if external links existed)147- [ ] Code blocks use `<br>` for line breaks and NBSP for indentation148- [ ] Local images converted to `data:image/...;base64,...`149- [ ] Task list checkboxes rendered as ☑ / ☐150- [ ] Mermaid code blocks converted to PNG `<img>` (if mermaid + playwright installed)