How OfficeCLI Implements Word i18n and RTL Support with Per-Script Font Slots
OfficeCLI handles Word internationalization by cascading RTL direction markers through paragraphs and runs while maintaining separate font slots for Latin, East Asian, and Complex Script text via dedicated keys like font.cs.
The iOfficeAI/OfficeCLI repository provides a dedicated internationalization module for Word documents that bridges OpenXML complexity with a simple CLI interface. Located in WordHandler.I18n.cs, this module manages bidirectional text layout and multi-script typography without affecting PowerPoint or Excel handlers. Understanding how these features work enables precise control over documents containing Arabic, Hebrew, Japanese, or mixed-script content.
The RTL Cascade: Handling Right-to-Left Text Direction
When a paragraph requires right-to-left layout, OfficeCLI must inject three specific OpenXML elements to ensure proper rendering across different Word processors. The ApplyDirectionCascade method in src/officecli/Handlers/Word/WordHandler.I18n.cs (lines 33‑44) orchestrates this process.
The method adds:
<w:bidi/>on the paragraph properties<w:rtl/>on the paragraph-mark run<w:rtl/>on every individual run within the paragraph
This cascade ensures that both the paragraph container and its textual content inherit the correct directionality. The dispatcher in WordHandler.Set.cs detects paragraph-level keys such as direction or bidi and routes them to this cascade function. Header and footer sections receive identical treatment through the same code path.
Complex Script Formatting and Per-Script Font Slots
Word stores distinct formatting attributes for complex scripts (Arabic, Hebrew, Japanese, Korean) separate from Latin text. OfficeCLI exposes these through canonical keys: font.cs, size.cs, bold.cs, and italic.cs, alongside font.latin and font.ea (East Asian).
Reading Complex Script Values
The ReadComplexScriptRunFormatting method in WordHandler.I18n.cs (lines 50‑95) extracts values from OpenXML elements including <w:rFonts cs="…">, <w:szCs>, <w:bCs>, and <w:iCs>. It merges these into the format dictionary using the canonical key names, allowing subsequent commands to inspect the current complex script state.
Writing Per-Script Fonts
When updating a run, ApplyRunFormatting (defined in WordHandler.Helpers.RunFormat.cs) writes the <w:rFonts> element with separate attributes for each script type: ascii and hAnsi for Latin, eastAsia for East Asian, and cs for complex script. The dispatcher in WordHandler.Set.cs (lines 753‑754) treats font.cs and its aliases as run-level properties, ensuring they pass through to the formatting routine.
Header and Footer i18n Support
Headers and footers participate fully in the internationalization pipeline. Inside SetHeaderFooter (WordHandler.Set.cs, lines 86‑88), the code checks for direction or bidi properties after applying paragraph-level formatting and invokes ApplyDirectionCascade when needed. The same block handles per-script font keys (lines 47‑58), ensuring that font.cs updates propagate to every run and the paragraph-mark run within headers and footers.
Practical Usage Examples
Set a paragraph to right-to-left, automatically applying the RTL cascade to all nested runs:
officecli set /body/p[3] --prop direction=rtl
Assign a complex-script font to a specific run while preserving other font slots:
officecli set /body/p[2]/r[1] --prop font.cs=MSゴシック
Combine RTL direction with per-script formatting in a document header:
officecli set /header[1] \
--prop direction=rtl \
--prop font.cs=Arabic\ Typesetting \
--prop size=12pt
Query the complex-script font currently applied to a run:
officecli get /body/p[2]/r[1] --prop font.cs
New runs inherit existing per-script font slots automatically when created, as implemented in WordHandler.Add.Text.cs (lines 348‑362), ensuring consistent typography when appending text to existing paragraphs.
Summary
- RTL directionality requires three OpenXML elements (
<w:bidi/>and dual<w:rtl/>tags) that OfficeCLI injects viaApplyDirectionCascadeinWordHandler.I18n.cs. - Per-script font slots (
font.latin,font.ea,font.cs) map to OpenXMLrFontsattributes and are managed throughApplyRunFormattingwith read-back support viaReadComplexScriptRunFormatting. - Headers and footers receive the same i18n treatment as body paragraphs, including RTL cascades and complex script formatting.
- Complex script properties use the
.cssuffix (e.g.,size.cs,bold.cs) to distinguish them from Latin formatting in the CLI interface.
Frequently Asked Questions
What OpenXML elements does OfficeCLI add for RTL support?
OfficeCLI adds <w:bidi/> to the paragraph properties and <w:rtl/> to both the paragraph-mark run and every individual run within the paragraph. The ApplyDirectionCascade method in WordHandler.I18n.cs manages these insertions to ensure consistent right-to-left rendering.
How do I set a different font for Arabic text versus English text in the same document?
Use the per-script font slots: specify --prop font.latin=Calibri for English text and --prop font.cs=Arabic Typesetting for Arabic text. OfficeCLI writes these to separate rFonts attributes (ascii/hAnsi versus cs) within the same run, allowing Word to render each script with its appropriate typeface.
Does RTL support apply to headers and footers automatically?
Yes. When you set direction=rtl on a header or footer path, the SetHeaderFooter method in WordHandler.Set.cs detects this property and calls ApplyDirectionCascade, ensuring the entire section—including all runs and paragraph marks—receives the correct bidirectional markers.
Where does OfficeCLI store complex script formatting values when reading a document?
The ReadComplexScriptRunFormatting method extracts values from elements like <w:szCs>, <w:bCs>, and <w:rFonts cs="…"> and stores them under canonical keys (size.cs, bold.cs, font.cs) in the format dictionary. This allows the get command to return complex script properties using the same key names used for writing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →