This is the 2D companion to the 3D Bidi Reordering Lab, computed independently rather than a flattened render of the 3D scene. It keeps the same real Unicode Bidirectional Algorithm (UBA, UAX #9) mechanism — the rule that lets a phone show "Save مرحبا 42 World" with the Arabic word flowing right-to-left while the English words and digits still read left-to-right, in one line — but derives embedding levels straight from UAX #9 rules I1/I2 for a single level run (no explicit embedding codes here, so the whole sequence is one run at the paragraph's base level b):
base level b = 0 (paragraph is LTR) or 1 (paragraph is RTL)
L (Latin word) → nearest level of the SAME direction as b (b, or b+1 if b is odd)
R (Arabic/Hebrew) → nearest level of the OPPOSITE direction (b+1, or b if b is odd)
EN (digit run) → rule I1/I2: in an even run, EN goes up TWO levels (b+2);
in an odd run, EN goes up ONE level (b+1) — numbers always
end up on an EVEN level so they still render left-to-right,
even nested inside an RTL run.
Storage order never changes — a screen reader and the underlying string always see the tokens in logical (typed) order, top row here. What changes is the display order, computed by rule L2:
L2: from the highest level down to the lowest ODD level present,
reverse every maximal run of tokens whose level >= that level.
Run it by hand on "Save(0) مرحبا(1) 42(2) World(0)": max level 2, lowest odd level 1.
At level 2 → reverse the single-token run [42] (no visible change, length 1).
At level 1 → reverse the run [مرحبا, 42] → [42, مرحبا]. Final visual order:
Save, 42, مرحبا, World — the number stays LTR but sits before the Arabic word it followed in storage.
- Block height = embedding level (taller = deeper nesting).
- Curved threads connect each token's fixed storage slot (top row) to its computed screen slot (bottom row) — a straight bundle of threads means no reordering happened; crossing threads mean an RTL run flipped.
- Drag to pan, scroll/pinch to zoom the diagram — useful once you build a long sequence.
- This exact rule is why every localized mobile app needs RTL-aware layout mirroring, not just translated strings.