Skip to content

Add RTL/BiDi support for Arabic, Hebrew, and other RTL scripts#923

Open
Tirador1 wants to merge 1 commit intocharmbracelet:masterfrom
Tirador1:fix/rtl-bidi-support
Open

Add RTL/BiDi support for Arabic, Hebrew, and other RTL scripts#923
Tirador1 wants to merge 1 commit intocharmbracelet:masterfrom
Tirador1:fix/rtl-bidi-support

Conversation

@Tirador1
Copy link
Copy Markdown

@Tirador1 Tirador1 commented Apr 8, 2026

Summary

Fixes #725.

  • Adds a post-render Unicode BiDi reordering pass that correctly displays Arabic, Hebrew, Syriac, and other RTL scripts in terminals that don't implement BiDi (e.g., Windows Terminal)
  • Reverses characters within RTL runs and mirrors bracket pairs, while preserving LTR text (English, code) unchanged
  • Zero overhead for pure-LTR content via fast-path containsRTL check
  • No new dependencies — uses golang.org/x/text/unicode/bidi which is already a transitive dependency

Before

Arabic text appears with reversed characters and wrong word order:

ترامس ماش    (should be: شام سمارت)

After

Arabic text displays correctly when read right-to-left:

شام سمارت    ✓

Changes

File Description
bidi.go New — ANSI-aware BiDi reordering: strips escape codes, applies Unicode BiDi algorithm per line, reverses RTL runs with bracket mirroring, reconstructs styled output
main.go 1 line — calls bidiReorder(out) after glamour renders

Test plan

  • Pure Arabic headings and paragraphs render correctly
  • Mixed Arabic/English text preserves LTR segments in correct position
  • Pure English markdown is completely unaffected (byte-identical)
  • Code blocks remain LTR
  • ANSI styling (colors, bold, italic) preserved across reordering
  • Unit tests pass for pure RTL, mixed LTR/RTL, and edge cases

Fixes charmbracelet#725.

Terminals like Windows Terminal render text strictly left-to-right
without applying the Unicode BiDi algorithm. This causes Arabic and
other RTL text to appear with reversed characters and wrong word order.

This adds a post-render BiDi reordering pass that:
- Strips ANSI escape codes, applies the Unicode BiDi algorithm
  (golang.org/x/text/unicode/bidi) per line, then reconstructs
  the styled output with correct visual ordering
- Reverses characters within RTL runs and mirrors bracket pairs
- Preserves LTR runs (English, code) unchanged
- Has zero overhead for pure-LTR content (fast-path check)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Tirador1 Tirador1 requested a review from a team as a code owner April 8, 2026 23:03
@Tirador1 Tirador1 requested review from andreynering and meowgorithm and removed request for a team April 8, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RTL text is not presented properly (reveresed and left-aligned)

1 participant