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)
Context
#829 adds
WritingDirectionResolver, which re-implements Unicode bidi rules P2/P3 with a three-range table and stampsbaseWritingDirectionon every paragraph so that list markers, blockquote bars, checkbox hit-testing and the HTML export know the paragraph direction.UIKit's header defines
NSWritingDirectionNaturalas "determines direction using the Unicode Bidi Algorithm rules P2 and P3", so TextKit already resolves every.naturalparagraph with the same rules. The text was laid out correctly before #829; only the chrome and the HTML export were reading.naturalas "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
.naturalparagraphs inMarkdownTextViewand comparingNSTextLayoutManager.baseWritingDirection(at:)withWritingDirectionResolver.firstStrongDirection(of:):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
.naturaland have the drawers (ParagraphMarkerDrawer,BlockquoteBorderDrawer) and the task-list hit test askNSTextLayoutManager.baseWritingDirection(at:)for the resolved direction. They already have the layout manager, and the call returns RTL for both cases above..leftToRight/.rightToLeftkeep stamping the paragraph style as they do now.dir="auto".With that,
.firstStrongand.naturalcollapse into one case,MarkdownWritingDirectionmirrorsNSWritingDirectionone to one, and the Unicode range table goes away.Raised in the review of #829: #829 (comment)