Renderer: align ordered list items on the widest marker of their list - #27
Open
rosekanari wants to merge 1 commit into
Open
Renderer: align ordered list items on the widest marker of their list#27rosekanari wants to merge 1 commit into
rosekanari wants to merge 1 commit into
Conversation
The hanging indent of an ordered item was the width of that item's own prefix. The body font is not monospaced, so "1. " and "10. " are 18.47 pt and 31.00 pt wide at a 21 pt body, and each item's text started at a different x — a 12.5 pt step, visible at a glance on any list that crosses ten items. `render` now pre-scans the joined lines and, for each contiguous run of ordered items at one indent level, computes the widest prefix; every item of the run hangs under it. The run is known before any rendering, so the widest prefix is too. `testWiderOrderedMarkerHangsFurther` keeps passing, and for the right reason: it renders "1. alpha" and "10. alpha" as two separate one-item documents, so each still hangs under its own — and only — marker. Its stated intent, "a wider marker has to hang further, or 10. would overlap its own text", is preserved: within a list, every item now hangs under the widest one. Adds `testOrderedItemsOfOneListShareTheirHangingIndent`, which fails on unpatched main and passes here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ordered list items each hang under their own marker, so their text starts at a different x. This aligns every item of a list on the widest marker of that list.
The problem
renderListItemcallsapplyListParagraphStyle(_:hangingUnder:)with that item’s own prefix, which delegates toapplyHangingIndent(_:indent:hangingUnder:):The body font is not monospaced, so prefixes of different items have different widths. Measured at a 21 pt body:
prefix | width | vs "1. " -- | -- | -- "1. " | 18.47 pt | — "9. " | 21.95 pt | +3.49 "10. " | 31.00 pt | +12.53 "100. " | 43.68 pt | +25.21A ten-item list is enough to see it: the text of item 10 starts 12.53 pt further right than that of item 1. Nothing overflows — no width is imposed — but nothing lines up either.
The change
renderpre-scans the joined lines and, for each contiguous run of ordered items at one indent level, computes the widest prefix; every item of the run hangs under it. The run is fully known before any item is rendered, so the widest prefix is too.renderLineandrenderListItemtake it as an optional parameter defaulting tonil, so unordered items, task items and every other caller are untouched.Two files, 69 insertions, 6 deletions.
Tests
testOrderedItemsOfOneListShareTheirHangingIndentis added. It renders a twelve-item list and asserts that all items share oneheadIndent. It fails on unpatched main and passes with this change. The full suite passes.testWiderOrderedMarkerHangsFurtherkeeps passing, and for the right reason: it renders"1. alpha"and"10. alpha"as two separate one-item documents, so each still hangs under its own — and only — marker. Its stated intent, “a wider marker has to hang further, or10.would overlap its own text”, is preserved: within a list, every item now hangs under the widest one, so the widest never overlaps its text.Notes
Verified against
28d86fd. Built and tested with:Written with Claude Code.
Happy to split, rename, or drop the added test if you would rather keep the suite as it is