Skip to content

Multi-column sections fill left-to-right in RTL sections: text starts in the left column instead of the right #3945

Description

@Nathaniel-260

Summary

In a section that carries <w:bidi/>, column fill order is still left-to-right. Paragraph 1 lands in the left column and overflow spills into the right one. Word starts an RTL section in the right column and flows right-to-left.

Column widths, gap and the text direction inside each column are all correct — only the column ordering axis is wrong. Export is clean (<w:cols> and <w:bidi/> round-trip intact), so this is a render-only defect.

Measured on superdoc@2.10.0 / @superdoc/docx-engine@0.9.0, Chrome 141, Windows 10.

Reproduction

A minimal document is enough — 24 numbered paragraphs so the content overflows column 1, and an RTL section:

<w:body>
  <!-- x24, numbered so the flow order is readable off the screen -->
  <w:p>
    <w:pPr><w:bidi/><w:jc w:val="both"/></w:pPr>
    <w:r><w:rPr><w:rtl/></w:rPr><w:t xml:space="preserve">פסקה מספר 1. …</w:t></w:r>
  </w:p>
  …
  <w:sectPr>
    <w:pgSz w:w="11906" w:h="16838"/>
    <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440"
             w:header="708" w:footer="708" w:gutter="0"/>
    <w:cols w:num="2" w:space="720" w:equalWidth="1"/>
    <w:bidi/>
    <w:docGrid w:linePitch="360"/>
  </w:sectPr>
</w:body>

Open it in SuperDoc and read the paragraph numbers.

Measured

Geometry is correct. A4 page at x=296 w=794, 1" margins, so a 602px content area:

x range width
column A 392 … 669 277px
column B 717 … 994 277px

277 + 48 + 277 = 602, and the 48px gap is exactly w:space="720". Nothing wrong there.

The order is wrong. Reading each rendered line's x and text:

y=290  x=392  "פסקה מספר 1. …"     ← left column holds paragraphs 1–19
y=290  x=717  "פסקה מספר 20. …"    ← right column holds the overflow, 20–24

Expected in Word for this section: paragraphs 1–19 in the right column (x≈717), overflow into the left one (x≈392).

Control — the direction is not being read at all

Same document, same w:cols, but English text and no w:bidi anywhere:

y=290  x=392  "Paragraph number 1. …"    ← left column holds paragraphs 1–14
y=290  x=717  "Paragraph number 15. …"   ← right column holds the overflow

Identical geometry, identical fill order. So the fill order is a fixed left-to-right, and the section direction is not consulted for columns at all — this is not an RTL mis-resolution, it is an axis that was never wired up.

Scope

  • Same result whether w:cols comes from the file or is applied at runtime via sections.setColumns({ count: 2, gap: 0.5, equalWidth: true }).
  • Text inside each column is correctly RTL — right-aligned, correct Hebrew shaping. Paragraph-level bidi works.
  • Round-trip is clean. Exported sectPr comes back as <w:cols w:num="2" w:space="720" w:equalWidth="1"/> <w:bidi/>, so no data is lost and the file still opens correctly in Word. The defect is display-only.
  • Presumably the same axis governs column separators (w:sep) and column-break targeting, though I did not measure those.

Where it looks like it lives

Your published types already describe the contract that is not being honoured.

layout-engine/contracts/src/direction-context.d.ts:

Direction context for a section. Used by section-level chrome only (page numbers, columns, gutters).
pageDirection: BaseDirection; — Section page direction; from w:sectPr/w:bidi.

But layout-engine/contracts/src/column-layout.d.ts resolves geometry on one axis only:

x and separatorX are CONTENT-RELATIVE (measured from the content-area left edge)

and no function in that API — getColumnGeometry, getColumnX, getColumnAtX, getColumnSeparatorPositions — takes a direction argument. So SectionDirectionContext.pageDirection appears to have no consumer on the column axis.

Note that getColumnAtX matters for more than paint: once ordering is direction-aware, hit-testing has to flip with it, or clicks will select the wrong column.

I would have opened a PR, but superdoc/dist/layout-engine ships 225 .d.ts files and zero .js — the implementation is in @superdoc/docx-engine, which is not in this repo. Hence an issue.

Context

Hebrew two-column layouts are common in the documents we handle (Torah literature — commentary set beside text), and today every one of them reads backwards on screen. Related: #3933 (Hebrew numbering), which you fixed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions