Simplified → Traditional (zh-hans → zh-hant)
Convert one Simplified-Chinese article into Traditional Chinese, and keep the pair in sync.
Approval gate — read before anything else
- Never convert or write without explicit user approval. This skill converts on demand only; it does not run automatically and does not pick articles on its own.
- Wait for the user to name the article. If they don't, do nothing but ask which one.
- Before writing, confirm the plan: the source file, the exact output path, and whether an existing
-zh-hant.mdshould be overwritten. Never overwrite silently. - Scope: future articles only. In this repo a bare
docs/<YYMMDD-slug>.mdis the English article and the legacy-chn.mdfiles are the existing Simplified-Chinese articles — neither is a source here unless the user explicitly orders it.
Conventions
- Filenames. Simplified article =
docs/<YYMMDD-slug>-zh-hans.md; Traditional twin =docs/<YYMMDD-slug>-zh-hant.md. (In ai-thoughts a bare.mdis English and the legacy-chn.mdfiles are out of scope.) - Source of truth = the Simplified file. The Traditional file is derived from it.
- Traditional variant. OpenCC
s2twp(Taiwan, phrase-aware) — the best default for these literary articles. - Cross-link. Exactly one line, directly under the H1 and above the infographic; Chinese label; a permanent absolute URL on the
j3ffyangaccount:- In the Simplified file:
> 繁体版:[<simplified title>](https://github.com/j3ffyang/ai-thoughts/blob/main/docs/<slug>-zh-hant.md) - In the Traditional file:
> 簡體版:[<traditional title>](https://github.com/j3ffyang/ai-thoughts/blob/main/docs/<slug>-zh-hans.md) - The label is written in the file's own script (Simplified file →
繁体版; Traditional file →簡體版) so neither file mixes scripts.
- In the Simplified file:
- Infographic stays Simplified and is shared by both files (same
../imgs/...path). The README lists the Simplified article only.
Procedure
- Wait for the user to name the article, then locate
docs/<YYMMDD-slug>-zh-hans.md(in this repo the source must be-zh-hans.md— a bare.mdis English). - Confirm the plan: source path, output path (
-zh-hant.md), and overwrite permission if the output already exists. - If an existing
-zh-hant.mdis present, stop and ask before overwriting — unless the user asked to update it. - Run the sync script:
It (a) injects/updates the Simplified file'spython3 .opencode/skills/simplified-to-traditional/scripts/sync_tra.py docs/<slug>-zh-hans.md繁體版cross-link, (b) converts the body withopencc -c s2twp, (c) injects the Traditional file's简体版cross-link, and (d) writesdocs/<slug>-zh-hant.md. - Review the generated Traditional against the Simplified, and clear the script's lint. OpenCC can pick the wrong form for a 一简对多繁 character (see "OpenCC pitfalls" below) and can rewrite characters inside a quote.
sync_tra.pyprints a⚠ … ambiguous form(s) to verifylist after every run — check each against the cited edition (or the intended meaning) and pin any genuine fix inOVERRIDES. Surface anything else suspicious to the user; do not silently hand-fix — a hand-edit is drift and will fail the next--check. - Verify the pair is in sync:
Exit 0 = in sync; exit 1 lists what is stale.python3 .opencode/skills/simplified-to-traditional/scripts/sync_tra.py docs/<slug>-zh-hans.md --check - Report: source, output, and any review notes.
Keeping the two in sync
- After editing the Simplified article, re-run the sync to refresh its Traditional twin.
--checkregenerates the Traditional in memory and diffs it against the file (ignoring the cross-link lines); non-zero exit means out of sync.- Do not treat the Traditional file as an editable primary. Edit the Simplified and re-sync. If a term is genuinely mis-converted by OpenCC, tell the user and decide together, then pin it as a
(from, to)pair inscripts/sync_tra.py→OVERRIDES— it is applied after OpenCC on every re-sync, so it survives (a hand-edit would not).
OpenCC pitfalls (一简对多繁)
opencc -c s2twp is deterministic but context-blind: when one Simplified character maps to several Traditional ones, it can pick the wrong one for a rare, literary, or technical term. Two failure modes:
- Ambiguous characters. e.g.
云(说)→雲(cloud);干→乾(dry)/幹(do). Rare terms err most.sync_tra.pyprints a lint of every risky form(雲 幹 髮 複 …)after each run — verify each against the cited edition and pin a fix inOVERRIDESif wrong. - Register normalization.
s2twpmay rewrite characters its Taiwan dictionary prefers(e.g.哄→鬨,背→揹). Acceptable in running prose, but wrong inside a verbatim quote taken from another edition.
Quotes must match the cited edition
Never delegate quoted primary text to a converter. For every verbatim quote, compare its Traditional characters with the edition named in the article's 引用来源; where s2twp differs, pin the (from, to) pair in OVERRIDES. Quoted text is otherwise frozen — do not change its characters or punctuation.
Pinning fixes (OVERRIDES)
OVERRIDES in sync_tra.py is applied to the converted Traditional text after OpenCC, in order, on every re-sync. Add a pair only when OpenCC is genuinely wrong for this corpus; keep the list small and specific. Never hand-edit -zh-hant.md — a hand-edit is drift and fails --check.
Verification checklist
- Traditional file exists at
docs/<slug>-zh-hant.md. - Both files carry the correct cross-link line directly under the H1 (Chinese label,
j3ffyangURL, pointing at the other file). -
sync_tra.py <source> --checkexits 0. - The script's ambiguous-form lint was reviewed; genuine miscodings pinned in
OVERRIDES(never hand-edited), and quotes verified against the cited edition. - The infographic reference points at the shared (Simplified) image; no broken
../imgs/. - The Simplified file's body is otherwise unchanged (only the cross-link line added).
- Nothing committed (commit only on explicit approval).
Error handling
- Source not found: list
docs/*-zh-hans.mdand ask which to use; do not substitute a bare (English) or-chn.mdfile. - Output already exists: stop and ask before overwriting.
openccmissing or wrong dict: report and stop; do not guess a conversion.- Ambiguous source name (neither
-zh-hans.mdnor an explicitly ordered-chn.md): ask.
