# OfficeCLI i18n and RTL Support in Word Documents: A Technical Deep Dive

> Explore OfficeCLI's advanced i18n and RTL support for Word documents. Discover its unique multi-layered property cascade operating independently of Microsoft Word for robust internationalization.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: deep-dive
- Published: 2026-08-06

---

**OfficeCLI provides built-in, first-class internationalization (i18n) and right-to-left (RTL) language support for Word documents through a multi-layered property cascade that operates independently of Microsoft Word.**

OfficeCLI enables AI agents and automation scripts to create, modify, and query Word documents in any language or script. Unlike simple wrappers around COM objects, the iOfficeAI/OfficeCLI repository implements native RTL handling directly within its core engine, ensuring reliable document generation for Arabic, Hebrew, CJK, and other complex scripts.

## How OfficeCLI Implements i18n and RTL Support

The architecture follows a **three-layer model** (Read → DOM → Raw XML) with RTL logic integrated at the DOM layer. This ensures that both high-level `view` commands and low-level `raw-set` operations see consistent direction information across the entire document tree.

### Document-Wide Defaults

Global RTL settings and language tags are stored in the document's default properties. In [`WordHandler.Set.DocDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.DocDefaults.cs), the engine reads and writes `<w:bidi>` elements within the `docDefaults` section, handling properties such as `docdefaults.rtl` and `docdefaults.direction`.

When you create a document with a locale flag, the CLI automatically sets these defaults. For example, using `--locale ar-SA` triggers the logic at line 116 in [`WordHandler.Set.DocDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.DocDefaults.cs) to enable RTL document-wide and insert the appropriate BCP-47 language tag.

### Style and Paragraph-Level Cascade

Direction inheritance flows from document defaults through sections, tables, and styles down to individual paragraphs. The `ResolveEffectiveParagraphStyleProperties` method in [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs) (lines 885-938) merges `<w:bidi>` values from style paragraph properties, table cells, section defaults, and numbering levels.

This method emits both `effective.direction` and `effective.rtl` for downstream consumers, ensuring that any element inheriting from a style receives the correct text direction. The [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs) file (lines 98-106) specifically lifts `<w:bidi>` attributes from style definitions into an effective run-level `RightToLeftText` flag.

### Run-Level Property Resolution

Individual runs may explicitly set RTL via `<w:rtl>` elements or inherit direction from their parent paragraph. The `ResolveEffectiveRunPropertiesCore` method in [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs) (lines 77-88) merges run properties, table-style runs, and paragraph bidi attributes into a single `RightToLeftText` object.

The method records provenance information in `effective.rtl`, allowing you to trace whether a run's direction was set explicitly, inherited from a style, or derived from document defaults.

### Selector and Query Support

The CLI exposes RTL state through selectors for querying and filtering. In [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs) (lines 207-214), the `rtl` key maps to the run's `RightToLeftText` value, enabling queries such as `paragraph[rtl=true]` or `run[rtl=true]`.

The `set` command accepts multiple value formats for RTL properties, including `rtl`, `righttoleft`, `true`, or `1`, parsed through [`WordHandler.Set.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.cs).

## Language Tags and Per-Script Font Slots

OfficeCLI respects OpenXML's complex script handling through dedicated font slots and language attributes:

* **Per-script font slots**: `font.eastAsia` for CJK scripts, [`font.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/font.cs) for complex scripts (Arabic/Hebrew), `font.hAnsi` for high ANSI, and `font.ascii` for basic Latin.
* **BCP-47 language tags**: Exposed as `lang.latin`, `lang.ea` (East Asian), and [`lang.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/lang.cs) (complex script).
* **RTL-specific layout features**: Including `rtlGutter`, `pgBorders`, and locale-aware page numbering.

The `MergeRunProperties` method in [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs) (lines 93-106) handles the inheritance and merging rules for these per-slot properties, ensuring that mixed-script documents render correctly.

## Practical Code Examples

### Create an RTL Document Automatically

```bash
officecli create report.docx --locale ar-SA

```

This command writes the appropriate BCP-47 tag and sets `docDefaults.rtl=true` automatically through the document defaults handler.

### Set Paragraph Direction Manually

```bash
officecli set report.docx '/body/p[1]' --prop direction=rtl

```

This updates `<w:pPr><w:bidi/>` on the target paragraph. The effective run-level RTL flag is emitted for all child runs through the cascade logic in [`StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/StyleList.cs).

### Verify Effective Direction on a Run

```bash
officecli get report.docx '/body/p[1]/r[1]' --json

```

Expected output:

```json
{
  "tag": "run",
  "path": "/body/p[1]/r[1]",
  "attributes": {
    "text": "مرحبا",
    "effective.rtl": true,
    "effective.direction": "rtl"
  }
}

```

### Query All RTL Runs in a Document

```bash
officecli query report.docx "run[rtl=true]" --json

```

This returns every run whose effective RTL flag is true, regardless of whether the direction originated from a style, section, table, or direct formatting.

### Apply Per-Script Font Slots

```bash
officecli set report.docx '/body/p[2]/r[1]' \
  --prop font.eastAsia=宋体 \
  --prop font.cs=Times New Roman \
  --prop font.ascii=Calibri

```

The merge respects the per-slot inheritance rules implemented in `MergeRunProperties`.

## Summary

* **OfficeCLI implements native i18n and RTL support** through [`WordHandler.Set.DocDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.DocDefaults.cs) and [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs), not through external Word automation.
* **Direction cascades** from docDefaults → section → table → style → paragraph → run, tracked via `effective.rtl` and `effective.direction` properties.
* **Selectors and commands** support RTL queries using `rtl=true` and accept multiple value formats (`rtl`, `righttoleft`, `1`) for setting direction.
* **Per-script font handling** uses dedicated slots (`eastAsia`, `cs`, `hAnsi`, `ascii`) with BCP-47 language tags exposed as `lang.latin`, `lang.ea`, and [`lang.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/lang.cs).
* **Provenance tracking** in `ResolveEffectiveRunPropertiesCore` allows tracing whether RTL state came from explicit formatting, styles, or document defaults.

## Frequently Asked Questions

### How does OfficeCLI handle mixed-direction documents containing both LTR and RTL text?

OfficeCLI resolves effective direction at the run level using `ResolveEffectiveRunPropertiesCore` in [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs). Each run maintains its own `RightToLeftText` property, allowing individual Arabic or Hebrew runs to display RTL within English paragraphs, or vice versa. The selector `run[rtl=true]` filters for specifically RTL content regardless of the surrounding paragraph direction.

### Can OfficeCLI set document-wide RTL defaults without modifying every paragraph?

Yes. Use the `create` command with `--locale` (e.g., `ar-SA` or `he-IL`) or manually set `docdefaults.rtl=true` via the `set` command targeting document defaults. In [`WordHandler.Set.DocDefaults.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Set.DocDefaults.cs), this writes the `<w:bidi>` element to the document's `docDefaults` section, causing all content to inherit RTL direction unless explicitly overridden at the paragraph or run level.

### What BCP-47 language tags does OfficeCLI support for font selection?

OfficeCLI supports the full range of BCP-47 tags exposed through OpenXML's language properties: `lang.latin` for Western scripts, `lang.ea` (East Asian) for CJK languages, and [`lang.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/lang.cs) (complex script) for Arabic, Hebrew, Thai, and similar scripts. These map to corresponding font slots (`font.ascii`, `font.eastAsia`, [`font.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/font.cs)) that are merged according to the rules in `MergeRunProperties` within [`WordHandler.StyleList.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.StyleList.cs).

### How do I query only the paragraphs that contain RTL text in a large document?

Use the `query` command with the RTL selector: `officecli query document.docx "paragraph[rtl=true]" --json`. This leverages the selector logic in [`WordHandler.Selector.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.Selector.cs) (lines 207-214), which evaluates the effective RTL flag computed through the style cascade. This flags paragraphs where the resolved direction is RTL, regardless of whether it was set via direct formatting, style inheritance, or document defaults.