Skip to content

styles set/edit/create --font never sets w:eastAsia, so CJK text keeps the theme font #6

Description

@xsvm

Summary

Any --font flag (docx styles set --font, docx edit --font, docx create --style-font, whatever calls applyRunFont) only writes w:ascii / w:hAnsi / w:cs on <w:rFonts>. It intentionally leaves w:eastAsia untouched — per the docstring on applyRunFont in src/core/ast/document/styles.tsx:

/** Point a `<w:rFonts>` at `fontName` for the Latin/ASCII script: set
 *  `w:ascii`/`w:hAnsi`/`w:cs` and DROP any `w:asciiTheme`/`w:hAnsiTheme`/
 *  `w:cstheme` reference (an explicit font must beat the theme). East-Asian /
 *  complex-script fallbacks (`w:eastAsia`) are left alone. Shared by
 *  `setDefaultFont`, `overrideStyleFonts`, and the `Fonts` lens's body/note walk. */
export function applyRunFont(rFonts: XmlNode, fontName: string): void {
	rFonts.setAttribute("w:ascii", fontName);
	rFonts.setAttribute("w:hAnsi", fontName);
	rFonts.setAttribute("w:cs", fontName);
	delete rFonts.attributes["w:asciiTheme"];
	delete rFonts.attributes["w:hAnsiTheme"];
	delete rFonts.attributes["w:cstheme"];
}

For a document whose visible text is Latin, this is invisible — nothing renders through w:eastAsia anyway. For a document whose visible text is Chinese/Japanese/Korean, it's the opposite: the change appears to do nothing, because CJK glyph shaping resolves through w:eastAsia (or its w:eastAsiaTheme fallback when no explicit w:eastAsia is set), never through w:ascii/w:hAnsi.

Repro

  1. docx create doc.docx --from - with a heading whose text is Chinese (e.g. # 标题). The built-in Heading 1 style ships with w:rFonts w:eastAsiaTheme="majorEastAsia" w:asciiTheme="majorHAnsi" ... (no explicit w:ascii/w:eastAsia).
  2. docx styles set doc.docx --at Heading1 --font SimSun
  3. Inspect the result: docx raw part get doc.docx --name word/styles.xml shows Heading1's <w:rFonts> now has explicit w:ascii="SimSun" w:hAnsi="SimSun" w:cs="SimSun", but w:eastAsiaTheme="majorEastAsia" is still there and there is no explicit w:eastAsia.
  4. Open in real Word (or render with a Word-faithful renderer): the Chinese heading text is still rendered in the theme's East Asian font (e.g. 等线/微软雅黑), not SimSun — even though docx styles --at Heading1 / a naive XML read makes it look like the font is "set". docx render's LibreOffice-based rasterizer did not reproduce this discrepancy for us, which made the bug easy to miss during verification — only inspecting the raw word/styles.xml XML surfaced it.

Impact

Any CJK-primary document (the majority of the visible content is Chinese/Japanese/Korean) gets zero visible effect from --font on headings/styles unless the user already knows to separately patch w:eastAsia via docx raw part edit. There's currently no CLI surface (no --font-east-asia/--cjk-font/similar) to set it directly — raw part edit string-replace is the only way today, which is fragile (unscoped match blast radius across word/styles.xml) and not discoverable.

Suggested fix

Add an explicit East-Asian-script font control alongside --font, e.g. --font-east-asia NAME (or --font-cjk), wired through the same RunFormat/applyRunFormatToRpr path --font already uses, applying to w:eastAsia and dropping w:eastAsiaTheme the same way applyRunFont does for the Latin attrs. Happy to open a PR — have a patch ready that:

  • extracts a parallel applyRunFontEastAsia(rFonts, fontName) next to applyRunFont
  • threads a new optional fontEastAsia field through RunFormat
  • adds --font-east-asia to the shared style/run-format flag parser used by styles set, styles create, and edit
  • updates README/CLAUDE.md docs and adds a CJK fixture + assertion to the existing font fidelity test

Found this while generating/patching Chinese-language .docx deliverables (software copyright registration materials) with docx-cli 0.21.0 (confirmed still present in 0.25.0 — no font-scope-related commits between the two in the changelog).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions