WeChat Official Account Article Formatting Skill
Convert a Markdown article into HTML that can be directly copied and pasted into the WeChat Official Account editor without losing formatting.
The core assets are the theme component libraries under references/ (each theme: design variables + complete HTML for each component + template skeleton + mapping rules) plus one shared common components library (code blocks, images/GIFs, small label titles, shared by all themes). The theme list is sourced solely from references/theme-index.md. This SKILL.md is only responsible for the workflow and decisions; all specific HTML code must be taken from the component libraries, not written from memory.
Workflow
0. Input and Format Normalization
The user may provide: Markdown text or a .md path (proceed directly to Step 1), .docx, .pdf, .txt/unmarked plain text, or web rich text. Non-Markdown input must first read references/format-normalize.md and follow its rules to convert into a Markdown draft and confirm the structure (use scripts/extract_docx.py for docx, Read PDF page by page and clean noise for PDF, infer structure from headings heuristically for plain text). If nothing is provided, ask the user for it.
If the user says "directly format / auto format / one-click / don't ask," go into full auto mode: skip structure confirmation and theme selection questions, automatically infer the structure, auto-select a theme based on the subject, format and validate, and deliver with a decision explanation (chapter structure, auto-generated title, rationale for theme selection).
1. Select Theme (Auto-Recommendation System)
Read references/theme-index.md (the single source of theme information). Proactively recommend the most suitable theme based on the article's subject, then ask the user to confirm—recommend but don't force:
- User has already specified a theme in the request → use it directly, no question.
- Subject has a clear match → ask for a single confirmation: "Suggest using XX (reason), confirm or switch?" Options include the recommended item + 1–2 alternatives + "See all." Subject→theme matching reference from theme-index's "Applicable Scenarios" column:
- Tutorials / reviews / checklists / tool roundups / knowledge organization / methodology breakdowns (high information density) → Mofu Green (摸鱼绿)
- In-depth analysis / opinions / topics with impact → Red-and-white series
- Design / tech commentary / professional opinions / high-end brands → Graphite Minimalist (石墨极简风)
- Zen / minimalist living / deep essays → White Space Zen (留白禅意风)
- Tool comparisons / creative reviews (ticket visual metaphor) → Mofu Ticket (摸鱼票据风)
- Internal journal notes / in-depth reviews / case studies → Olive Notes (橄榄手记)
- No clear inclination → default to the first entry in theme-index (Mofu Green) as the recommended item, placed first, and use AskUserQuestion to let the user choose from several sets (if there are more than 4 themes, first group by style and ask, then ask for the theme under that group).
- Full auto mode (user explicitly says "directly format / one-click / don't ask") → no questions, auto-select the theme that best fits the subject or the default first entry, and explain the choice at delivery.
- User is not satisfied with any existing theme / wants a new style → follow the "Custom Theme Generation" process (see next section), generate and register the theme, then return to this step to select it.
- theme-index is empty → stop formatting and inform the user that they need to add a theme first (they can use "Custom Theme Generation").
Only after the user decides on a theme do you proceed to component matching within that theme (Steps 3 and 4: determine the article type → select a component combination based on that theme's recipe table).
2. Read Component Libraries (Two)
(1) Based on the theme's "Component Library File" column in theme-index, Read the theme-specific component library references/theme-{identifier}.md (includes entry cards, section titles, body text markers, signatures, and other theme-specific components).
(2) Simultaneously Read the shared common components library references/common-components.md——code blocks, images/GIFs, and small label titles are shared by all themes; just apply the current theme's primary color.
All subsequent generation is based solely on these two component libraries. HTML must always be taken from them, never written by hand.
3. Parse Markdown Structure
| Element | Recognition Rule |
|---|---|
| Article title | # Title or frontmatter title |
| Opening quote | The first > Quote block at the beginning of the article |
| Section title | ## Title |
| Subsection | ### Title |
| Bold / highlight / underline | **text** / ==text== / <u>text</u> or ++text++ |
| Quote paragraphs | > text that is not the opening |
| Image / GIF | ,  (GIFs are handled the same as images) |
| Code / command / prompt | ``` fenced code block ```, inline `code` |
| Separator / list | ---, *** / - item or 1. item |
| Table | Markdown table separated by ` |
After parsing the structure, determine the article type (take the dominant type, can be composite): tutorial/guidelines, checklist/tool roundup, opinion/in-depth analysis, interview/feature article, data review/report, life/emotional essay, case study. Determination criteria: many steps and commands → tutorial; many parallel items → checklist; many quotes and narrative → interview; many numbers and comparisons → data; many argumentative reasoning → opinion.
4. Select Component Combination via Recipe → Assemble HTML
First check the selected theme library's "Article Type → Component Combination Recipe" table, determine the core component combination and accent components for this article based on its type——don't randomly select components paragraph by paragraph from the library; the recipe ensures consistent formatting style across similar articles. For elements outside the recipe, supplement according to the theme library's mapping rules table.
Then assemble according to the theme library's "Complete Article Template Skeleton" section, replacing each Markdown element with the corresponding component:
- Skeleton order follows the theme library; different themes may have different skeletons, do not apply another theme's skeleton.
- Inline markings are matched to the corresponding components in the selected theme library by semantics (component IDs vary across libraries; always match by semantics, never by fixed IDs):
**bold**→ primary color bold;==highlight==→ solid-color light background highlight;<u>text</u>or++text++→ underline;~~text~~→ highlighter (solid-color light background);>quote→ quote highlight block. - Components from the shared common library:
``` code block ```→ 1a dark / 1b light code block, inline`code`→ 1c;→ 2a image (add alt component only if alt text is present),.gif→ 2b GIF; small titles/emphasis that need highlighting → 3a left-vertical-bar small title or 3b pill label, golden sentences → 3d, tip side note → 3e. Priority: first check the theme library's mapping rules table——if the theme has equivalent semantic components (e.g., its own golden sentence or tip block), use the theme library version to maintain consistency; if the theme library has no corresponding component, then use the shared library's 3x components and apply its color-swapping rules to match the theme color. - Only use components from the selected theme for one article; do not mix themes.
- Use "small label / left vertical bar" for emphasis and small titles, not dashed boxes: to highlight a small title or a block of content, use left vertical bar small title (3a), pill label (3b), or left vertical bar golden sentence/tip block (3d/3e); do not use a dashed border (
dashed) box around a title, which is heavy and distracting.
5. Validation Compliance (Mandatory)
After writing the generated HTML to the target file, you must run the validation script; only deliver when ERROR count is zero:
# Call using the absolute path of the skill's scripts directory; also pass the actual path of the generated HTML (the two directories are usually different)
<SKILL_ROOT>/scripts/validate_gzh_html.py <actual path to the generated .html>
It deterministically checks for platform-prohibited items and <span leaf> wrapping. If ERROR is reported, return to Step 4 to fix; half-width punctuation WARNINGs must also be fixed to 0 before delivery (this is the most common rework point in actual use).
Gradient background WARNINGs must be handled one by one: text highlights, quotes/data/guide card backgrounds should default to a pure color or rgba pure color within the theme; only keep the gradient if the user explicitly requests it, and when delivering, note that the darkmode-no-gradient popup may be triggered. Pure decorative gradients are also flagged; if retained, explain the risk.
6. Output
Output format: pure <section>…</section> body fragment, starting from the global container, do not wrap with <!DOCTYPE>/<html>/<head>/<body>——the WeChat editor only accepts body fragments; extra document shells are discarded or interfere with pasting.
- Clean body file: Save the HTML to the current working directory with the filename
{original filename}_formatted_{theme Chinese name}({English identifier}).html(English identifier = theme-index component library filename without thetheme-prefix and.mdsuffix). This file is used for validation and manual pasting as a fallback. - Preview page with a "Copy" button (allows one-click copying without manual select-all):
Produces<SKILL_ROOT>/scripts/wrap_preview.py <above clean body.html>{...}_preview.html——when opened in a browser, a "Copy to Official Account" button appears in the top-right corner; clicking it copies the rendered rich text to the clipboard (equivalent to Ctrl+A/Ctrl+C), which can then be pasted into the WeChat editor with Ctrl/⌘+V. The button and script are only in the preview shell, not inside the copied section, so the pasted content remains clean and compliant. - Inform the user: Open
{...}_preview.html→ click the top-right "Copy" button → paste into the WeChat editor; also provide the clean body file path as a fallback. Attach the validation script result (passed / remaining warnings).
Smart Processing During Generation (These are this skill's unique features and must be done)
- Automatic chapter numbering: Assign
01/02/03…based on the order of##; if the last chapter is a conclusion/summary type, use the conclusion numbering variant specified by the theme library (e.g.,∞); if the theme library does not specify, continue with numeric numbering. - English labels: Generate an English label from the Chinese chapter title (实测→TEST, 教程→TUTORIAL, 总结→SUMMARY, 思考→THOUGHTS…), used when the theme library has a corresponding slot.
- Keyword underlining in body text (core feature): For each body paragraph, actively find 1–3 most important phrases and mark them with the theme's underline CSS (see theme-index). Prioritize core opinions, conclusions, key data, proper nouns; phrases should be 4–15 characters; if a paragraph has no key points, it can be skipped. Even if the original text has no bold, you must actively add underlines—they are the most frequently used basic marker.
- Keyword highlighting in opening quote: Identify key words in the opening golden sentence and mark them with a highlight component.
- Table of contents extraction: Extract the first 3
##headings as guide/table-of-contents points (only if the theme library has a TOC component). - Opening quote card attribution: Based on the article's author or subject—if the article has a named author, write "—— Author Name"; if there is no clear author, use a short attribution related to the subject or omit entirely. Do not hardcode "Jiamu (甲木)" (the footer signature area also uses
{{author name}}placeholder, see item 7). - Footer author signature area (author fills in, only one at the end): Do not hardcode any person's name by default; use a placeholder for the user to replace with their own name.
- First sentence (Author introduction):
I am {{Author Name}}, {{one-sentence bio, e.g., passionate about sharing AI observations and insights}}——if the user provided a name or bio in the request/preferences, fill it in directly; if not, keep the{{Author Name}}/{{Bio}}placeholders and prompt the user to replace them at delivery. - Second sentence (Engagement prompt, generic and can remain as is):
If you found today's article valuable, feel free to **like, share, and forward**—see you in the next post - If the original text already has an author signature paragraph at the end (e.g., "I am XXX…") → keep the original attribution and do not replace it with the placeholder.
- First sentence (Author introduction):
- List conversion: Handle according to the theme library's mapping rules; if there is no dedicated list component, convert to indented body paragraphs.
- Chinese full-width punctuation: Use full-width punctuation throughout the body (,。!?:;""''()——…), do not use half-width
, . ! ? :or English straight quotes" '. Write curved quotes ""'' directly in the HTML, do not write straight quotes and replace them later——convert straight quotes from the original text on the spot. Exceptions: Code blocks, inline code, English proper nouns/URLs/code identifiers should keep their original form.
Visual Hierarchy (3 levels, universal across all themes)
| Level | Role | Frequency | Method |
|---|---|---|---|
| Anchor level | Strongest anchor: product name/step/CTA/core golden sentence | ≤ 5 per article | Primary color bold, dark background white text quote |
| Marker level | Keywords in body text, 1–3 per paragraph | High frequency | Underline marker |
| Container level | Quote blocks, concept tags, long sentence emphasis | As needed | Light background quote, highlighter, badge |
Platform Red Lines (Core, full check by validation script)
- Prohibited:
<style>/<script>/<div>,class/idattributes,position:fixed/absolute/sticky,float,@media/@keyframes,display:grid, CSS variables, external fonts/CSS. - Required: All styles must be inline
style; all text nodes must be wrapped in<span leaf="">text</span>(otherwise formatting is lost after pasting). - Allowed:
display:flex(limited),border-radius,box-shadow,<section>/<p>/<span>/<strong>/<img>/<h3>. - Gradient background compatibility: Gradients can render but may trigger the WeChat
darkmode-no-gradientcontent structure check; text and card backgrounds should default to solid colors, do not add gradients extra. For legacy components or custom themes that encounter this, follow Step 5.
Gotchas (Common pitfalls from real formatting)
- Missing
<span leaf>wrapping is the most common fatal error——styles are completely lost after pasting into WeChat. Rely on the validation script in Step 5 to catch this; do not skip it. - Underlines: implement per paragraph, 1–3 phrases each. Do not underline entire paragraphs (loses focus), and do not mark some paragraphs while missing others; key descriptions in list items should also be marked.
- Chapter numbering errors: strictly follow the order of
##, do not skip numbers; conclusion numbering variants are only for the last chapter, not for intermediate chapters. - Signature area: exactly one at the end: use fixed copy, do not put it in the middle or multiple places; if the original text already has an author signature / "like, share, and forward" paragraph at the end, recognize and merge it into this single signature area/CTA card, do not keep the original paragraph and also generate a new one.
- Fabricating image captions: only generate a caption component when
actually has caption text; do not fabricate a caption forwith an empty alt. - Images: responsive, not stretched:
<img>should always havemax-width:100%;height:auto;display:block;margin:0 auto——display at the image's natural size, centered, large images shrink to container width, small images keep their original size. Do not usewidth:100%(which stretches small images and makes them blurry); only usewidth:100%for layout elements like tables, cover cards, or flowcharts. - Mixing components across themes: only use components from the selected theme + the shared library; do not borrow components from other themes.
- Overusing the anchor level: use the strongest emphasis ≤ 5 times per article; too much bold everywhere means no emphasis at all.
- Missing original content: convert every paragraph and every image; do not add or remove substantive content from the original.
- Residual placeholder images: if signature area/CTA components have image placeholders (e.g.,
<img src="...URL for business card or guide image">), delete the entire line if there is no real image URL; do not leave placeholders in the output. - Table of contents: selected, not exhaustive: the introductory guide/TOC component displays a selection of 3 core highlights, not a complete chapter list; when there are more than 3 chapters, pick the 3 most important ones, do not force all or mislead the reader into thinking there are only 3 chapters.
- Do not use dashed boxes: use small labels or left vertical bars (shared library 3a–3e) for highlighting titles/emphasis; do not wrap a title in a
border:…dashedbox. Exception: If the theme library explicitly defines a dashed component (e.g., Mofu Green's quote-box quote box, oneliner-card highlight card), it is a stylistic feature of that theme and can be used normally according to the theme library's instructions. - Don't mix half-width punctuation: half-width commas, periods, and English straight quotes
"'in the body must all be changed to full-width; but half-width symbols inside code blocks and inline code should remain as is—do not "full-width-ify" code. - Code/Prompt must use code blocks: code, commands, and prompts in the article should use the shared library's code block components (1a/1b); do not put them into normal paragraphs or quote blocks, or indentation and monospacing will be lost.
- Code blocks should be compact, avoid large whitespace: use the shared library 1a/1b's "one
<p style="margin:0">per line" approach; never usewhite-space:pre——it will render the indentation before spans and line breaks in the HTML source as large left indentation + empty lines; use only full-width spacesfor indentation, and useline-height:1.6for line spacing. - Center pending media: placeholders like
【Insert...】, pending screen recordings/GIFs/videos/results images, use the shared library's 2c centered pending media placeholder block (light background with soft dashed border + centered icon and description), do not use left-aligned tip blocks.
Custom Theme Generation (Second Workflow)
When the user wants a new style beyond the built-in themes (saying "generate a new theme / custom style / create a component library based on this reference image", or is not satisfied with any existing theme), read references/theme-generator.md and strictly follow its workflow:
- Collect preferences: Topic description is required (or a reference image); name/ID/five colors/fonts/three types of TAG/radius/shadow can be left empty and will be auto-completed; ask everything at once, do not ask field by field.
- Generate the block library HTML: Execute the [Generation Prompt] at the end of theme-generator.md as-is, produce a complete block library of 45–75 Blocks, save to
assets/theme-previews/{theme-id}.html——all blocks arranged continuously on a single page; the user opens it in a browser to view the entire page at once to confirm the style, without confirming block by block. - Convert + Register: After the user confirms the style, convert to a standard
references/theme-{identifier}.md(must add<span leaf="">wrapping, remove preview IDs, complete the five sections, see details in theme-generator.md Step 3), register in theme-index.md, runcomponent_lint.pyuntil 0 ERROR. - After delivery, the new theme becomes a permanent selectable option on par with built-in themes for future formatting.
During the generation phase, the prompt rules take precedence; during conversion into the theme library phase, this file's "Platform Red Lines" and "New Theme Addition Specification" take precedence (when there is a conflict between the two, the latter takes precedence because the theme library directly determines the formatting output).
New Theme Addition Specification
New themes must be named references/theme-{English identifier}.md and must include:
- Design variables quick reference table (primary color/light background/dark text/title color/body color/separator color, etc.)
- Complete HTML for each component (inline styles +
<span leaf="">wrapping, adhering to the "Platform Red Lines" above) - Complete article template skeleton (component assembly order; if there is a TOC/navigation component, specify its position relative to the cover/intro)
- Article type → Component combination recipe table (core component combination + accent components for each article type; the recipe is key to stable formatting style)
- Markdown → Component mapping rules table
After adding, register one line in references/theme-index.md (theme name / primary color / applicable scenarios / component library file / body underline CSS), and run python3 scripts/component_lint.py . to confirm the component library has no anti-patterns (0 ERROR).
For trigger and theme selection regression test cases, see
references/eval-cases.md(maintained for regression checks, does not affect individual generation).
