feat(input): parse and serialize lists (lists 3/5)#512
Conversation
Introduces BlockType.ANCHORED (Android) and ENRMBlockTypePersistsWhenEmpty (iOS) and routes the block store's adjust/normalize passes, the formatter's zero-length anchor stamping, and the views' orphan-anchor prune through them instead of heading-only checks. No behavior change — headings are the only anchored type until the list block type lands on top. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
UNORDERED_LIST_ITEM and ORDERED_LIST_ITEM with 0-based nesting depth in the range's level payload, joined to the anchored-type set. The store's list-metadata pass clamps depths to valid ancestry (an item nests at most one level under the previous adjacent item, so every state serializes) and computes each ordered item's 1-based ordinal from its position among adjacent same-depth, same-type siblings. One handler instance per type: Android renders via LeadingMarginSpans (bullet dot/ring/square by depth; right-aligned number for ordered) plus a LineHeightSpan for spacing; iOS reserves the indent column via the paragraph style and draws the glyph or number in the layout manager, with the ordinal stamped as a text attribute. listItemSpacing prop spaces items on both platforms. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Parsers map list items to their block type with depth derived from AST UL/OL nesting (never leading spaces); iOS tags MD_BLOCK_LI itself since md4c emits inner paragraphs only for loose lists, clipping each item to its own first line. Serializers emit "- " / computed "N. " via the handler's line prefix, indented a uniform three spaces per depth so ordered and bullet nesting round-trip in any combination; an empty item's line serializes bare — a marker-only line re-parses as a setext underline for the previous line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Note on ordered-list start numbers (future extension point): Both parsers in this PR normalize ordered lists to start at 1 — the store recomputes each item's ordinal from its adjacent same-depth siblings, so an imported Flagging it here because of react-native-streamdown: LLM output routinely contains continuation lists ( |
The list stack (per the review ask, now including ordered lists — the shared machinery made them cheap to add):
GitHub can't base a fork PR on another fork branch, so every PR targets
mainand the diff shown for PR N is cumulative — this PR's own change is its last commit (each stage is exactly one commit on the previous branch). We'll merge bottom-up; after each merge the next PR's diff collapses to just its own commit. Checkoutfeat/list-5-stateto test the full feature end-to-end.This PR (last commit)
Parsers map list items to their block type with depth derived from AST UL/OL nesting (never from counting leading spaces); iOS tags
MD_BLOCK_LIitself since md4c emits inner paragraphs only for loose lists, and clips each item's range to its own first line so nested items keep their own depth.Serializers emit
-/ computedN.via the handler's line prefix, indented a uniform three spaces per depth so ordered and bullet nesting round-trip in any combination. An empty item's line serializes bare: a marker-only line (-) re-parses as a setext-heading underline for the previous line. Ordered markers always use computed ordinals, so a pasted5.start value normalizes to1.— noted in the docs.Easy to verify with round-trips:
1. alpha\n 1. beta\n2. gamma↔ editor.🤖 Generated with Claude Code