Skip to content

Fix RTL/LTR text overflow in overlay transcript#24

Open
Abdulrhman-92 wants to merge 1 commit into
dbachelder:mainfrom
Abdulrhman-92:feature/bidi-rendering
Open

Fix RTL/LTR text overflow in overlay transcript#24
Abdulrhman-92 wants to merge 1 commit into
dbachelder:mainfrom
Abdulrhman-92:feature/bidi-rendering

Conversation

@Abdulrhman-92

Copy link
Copy Markdown

Summary

Fixes the bug where mixed RTL (Arabic, Hebrew, Persian) and LTR (English,
code) text would overflow the BTW overlay frame boundaries because the
existing wrapping logic used wrapTextWithAnsi() which is byte-width based
and doesn't handle Unicode UAX #9 bidirectional rules.

Closes #23.

Changes

extensions/btw.ts

  • wrapTranscript() now uses bidiWrapText() for lines containing RTL
    characters. Pure-LTR lines continue to use wrapTextWithAnsi() for
    zero-overhead performance.
  • fitRenderedLine() uses bidiVisibleWidth() and bidiTruncate() for
    accurate width measurement and bidi-safe truncation.
  • Added containsBidi() helper method for fast RTL detection.

lib/bidi-wrap.ts (new, 480 lines)

A self-contained bidi text processing module ported from the Python
format.py helper in the bidi-text-formatting skill:

  • wrapWithIsolates(text) — wraps each RTL/LTR run with U+2068/U+2069
  • splitRuns(text) — classifies text into directional runs
  • bidiWrapText(text, width) — width-aware wrapping preserving ANSI
  • bidiTruncate(text, width, ellipsis?) — width-aware truncation
  • bidiVisibleWidth(text) — display width ignoring markers/ANSI
  • isRtlChar(ch) / isBidiContent(text) — classification helpers
  • detectDirection(text) / normalizeBidi(text) — utility helpers

tests/bidi-wrap.test.ts (new, 25 tests)

Visual regression tests covering:

  • Pure Arabic wrapping (short, long, edge cases)
  • Pure English wrapping (regression test)
  • Mixed RTL/LTR wrapping (the bug we fix)
  • Code identifier preservation (cpp_str, snake_case, camelCase)
  • Multi-paragraph content
  • Boundary conditions (empty, single char, width=1, exact fit)

tsconfig.json + package.json

  • include updated to lib/**/*.ts
  • files updated to include lib/

CHANGELOG.md (new)

Documents the fix with detailed technical breakdown.

README.md

  • Adds 'bidi-correct rendering' feature to the feature list

Test Results

Test Files  2 passed (2)
     Tests  81 passed (81)

All 56 existing tests continue to pass + 25 new visual regression tests.

Performance Impact

  • Pure-LTR lines: zero overhead (continues to use wrapTextWithAnsi)
  • Bidi lines: containsBidi() is O(n) but typically returns false
    quickly; only the small fraction of lines with RTL content take
    the bidi path

Compatibility

  • No breaking changes
  • No new runtime dependencies
  • Module is self-contained (no external imports beyond pi-tui types)
  • Backward compatible with all existing usage patterns

Testing Locally

git clone https://github.com/Abdulrhman-92/pi-btw.git
cd pi-btw
git checkout feature/bidi-rendering
npm install
npm test

Screenshots

Before fix: text overflows the frame, code identifiers may appear reversed.
After fix: text wraps within the frame, code identifiers preserved.

(Screenshots available in the issue #23 description.)

Mixed bidirectional content (e.g., 'cpp_str المعكوس') would exceed the
overlay frame boundaries because the previous wrapping logic didn't
account for Unicode UAX dbachelder#9 bidi rules.

Changes:
- extensions/btw.ts:
  - wrapTranscript() uses bidiWrapText for bidi content (fast path
    for pure LTR)
  - fitRenderedLine() uses bidiVisibleWidth + bidiTruncate for
    accurate width measurement and safe truncation
  - Added containsBidi() helper for fast RTL detection

- lib/bidi-wrap.ts (new):
  - Core bidi module with wrapWithIsolates, splitRuns, bidiWrapText,
    bidiTruncate, bidiVisibleWidth, isRtlChar, isBidiContent,
    detectDirection, normalizeBidi

- tests/bidi-wrap.test.ts (new):
  - 25 visual regression tests covering pure Arabic, pure English,
    mixed RTL/LTR, code identifiers, multi-paragraph, edge cases

- CHANGELOG.md (new):
  - Documented the fix

- README.md:
  - Added bidi-correct rendering feature

- tsconfig.json, package.json:
  - Include lib/ directory in build and distribution

All 81 tests pass (56 existing + 25 new).
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.

Bug: RTL/LTR mixed text overflows the overlay frame in transcript

2 participants