Skip to content

iOS: resolve paragraph chrome direction from TextKit instead of a separate first-strong scan #874

Description

@hryhoriiK97

Context

#829 adds WritingDirectionResolver, which re-implements Unicode bidi rules P2/P3 with a three-range table and stamps baseWritingDirection on every paragraph so that list markers, blockquote bars, checkbox hit-testing and the HTML export know the paragraph direction.

UIKit's header defines NSWritingDirectionNatural as "determines direction using the Unicode Bidi Algorithm rules P2 and P3", so TextKit already resolves every .natural paragraph with the same rules. The text was laid out correctly before #829; only the chrome and the HTML export were reading .natural as "app direction". As a result, text and chrome are now resolved by two different algorithms.

Where they disagree

Verified on the iPhone 16 simulator by laying out .natural paragraphs in MarkdownTextView and comparing NSTextLayoutManager.baseWritingDirection(at:) with WritingDirectionResolver.firstStrongDirection(of:):

Paragraph TextKit Resolver
Arabic RTL RTL
Latin LTR LTR
U+200F then digits RTL neutral, so LTR after fallback
Adlam letters RTL LTR
digits only LTR neutral
digits then Hebrew RTL RTL

A paragraph starting with U+200F (which people insert to force RTL) is not a letter, so the resolver skips it. Adlam sits outside the three ranges. In both cases the text flows one way and the marker sits on the other side, which is the bug #829 set out to fix.

Proposal

  • Leave paragraphs .natural and have the drawers (ParagraphMarkerDrawer, BlockquoteBorderDrawer) and the task-list hit test ask NSTextLayoutManager.baseWritingDirection(at:) for the resolved direction. They already have the layout manager, and the call returns RTL for both cases above.
  • Forced .leftToRight / .rightToLeft keep stamping the paragraph style as they do now.
  • The HTML generator has no layout, so it keeps a first-strong scan or emits dir="auto".

With that, .firstStrong and .natural collapse into one case, MarkdownWritingDirection mirrors NSWritingDirection one to one, and the Unicode range table goes away.

Raised in the review of #829: #829 (comment)

Activity

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

Metadata

Metadata

Assignees

Labels

library: iosTasks for ios enriched markdown

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions