Skip to content

Add optional per-paragraph direction from assembled spans - #148

Open
st0ck wants to merge 5 commits into
foresightmobile:mainfrom
st0ck:pr/paragraph-direction
Open

st0ck wants to merge 5 commits into
foresightmobile:mainfrom
st0ck:pr/paragraph-direction

Conversation

@st0ck

@st0ck st0ck commented Sep 6, 2026

Copy link
Copy Markdown

Problem and proposal

Related to #65. A single inherited Directionality cannot give English and RTL prose paragraphs independent base directions. This draft adds optional paragraphDirectionBuilder: TextDirection? Function(InlineSpan) to Markdown/MarkdownBody and the builder. It receives the renderer's assembled spans; a non-null result supplies Directionality around the existing paragraph widgets. Null/omitted keeps the existing tree and behavior. No automatic language detection, new dependency or renderer framework.

The hook covers ordinary prose and tight/loose list/blockquote paragraphs, in selectable and non-selectable modes. Formatting and link recognizers remain attached to the same rendered spans. Images/custom widgets are not inspected or rebuilt; their surrounding text segments share paragraph direction. Headings, fenced code, table cells and list markers are excluded. README documents the application-supplied direction policy.

Related work: #147 exposes a general block-widget wrapper for anchors. This proposal is narrower and provides assembled span input rather than AST text or widget-tree inspection. Happy to align the API shape with that work; this draft does not duplicate its wrapper or change its branch. This supplies an opt-in building block for #65, not a claim to implement all automatic RTL behavior.

Callback updates

Changing paragraphDirectionBuilder on an existing Markdown/MarkdownBody triggers the existing reparse path. The callback participates in didUpdateWidget's current invalidation condition; no new cache or key workaround.

Local validation

  • Focused paragraph/link/context-menu/selection lane: 168 passed, 3 pre-existing upstream skips.
  • Includes 64 paragraph tests: both paragraph orders/UI directions, nested blocks, inherited/null behavior, span identity, formatting, real link taps in both selection modes, excluded blocks, image-separated text and physical start alignment.
  • Eight same-mounted-widget cases hold data/style/key/environment and State identity stable while adding/switching/removing the callback or replacing it with one returning null. Actual RenderParagraph/RenderEditable directions and exactly one link dispatch after each update are asserted. All eight failed on stale direction before the lifecycle correction.
  • Focused analyzers: no issues. Formatting and whitespace checked.

Test SDK: Flutter 3.41.9 / Dart 3.11.5. Fresh upstream's dev-only mockito ^5.7.0 cannot resolve against that SDK's pinned meta1.17.0, so local tests used an uncommitted pubspec_overrides.yaml with mockito5.6.4. No override, lockfile, SDK or dependency changes are included in this PR. No full CI claim.

@st0ck
st0ck marked this pull request as ready for review September 6, 2026 16:38
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.

1 participant