feat(input): block-editing pipeline foundation#460
Conversation
Add the generic block-editing abstractions for the input component, mirroring the inline-style pipeline (StyleType→FormattingStore→StyleHandler →InputFormatter→serializer/parser). No concrete block type is registered yet, so behavior is unchanged (plain paragraphs, inline styles intact); a later change plugs a heading handler in without touching the orchestrator. - ENRMInputBlockType enum + block paragraph attribute keys - ENRMBlockRange model (type + range + generic level payload) - ENRMBlockHandler protocol: paragraph attributes, markdown line prefix, md4c block matching — sufficient for headings and list items - ENRMBlockStore: generic line-scoped block range store with edit adjustment - InputFormatter: block-handler registry (empty) + applyBlockRanges - Serializer: block-aware overload; asserts the line-count invariant instead of silently dropping blocks - Parser: real md4c enter_block/leave_block via a kSupportedBlocks table (paragraph-only today), replacing the no-op TODO - Orchestrator: wires a block store through apply/edit/import/export, inert until a handler is registered Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhuNE6PjRGjroxobhdd72q
Android mirror of the iOS block-editing foundation: the generic block abstractions for the input component, paralleling the inline-style pipeline (StyleType→FormattingStore→StyleHandler→InputFormatter→serializer/parser). No concrete block type is registered, so behavior is unchanged; a later change plugs a heading handler in without touching the orchestrator. - BlockType enum (PARAGRAPH default) + BlockRange model (type/start/end/level) - BlockHandler interface: createSpans, spanClasses, markdownLinePrefix, matchesNodeType — sufficient for headings and list items - BlockStore: generic line-scoped block range store with edit adjustment (reuses FormattingStore's edit-overlap logic) - InputFormatter: block-handler registry (empty) + applyBlockFormatting - MarkdownSerializer: block-aware overload; asserts the line-count invariant instead of silently dropping blocks - InputParser: ParseResult.blockRanges from the shared AST (paragraph-only today; the C++ parser is unchanged so readonly rendering is unaffected) - Orchestrator + event emitter: wire a block store through apply/edit/ import/export, inert until a handler is registered Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhuNE6PjRGjroxobhdd72q
|
To show how this foundation is meant to be used, here's the first handler (headings, H1–H6) plugging into it as a reference PR, stacked on this branch so the diff is only the heading delta: It demonstrates the intended extension pattern — a new block type is added by implementing the |
|
@hryhoriiK97 - base pipeline ready for review. See wildseansy#1 for how it's used for headings, and wildseansy#2 for the headings fully integrated into the test app |
hryhoriiK97
left a comment
There was a problem hiding this comment.
@wildseansy thanks for the PR! I'll try to take a look this week if possible. We have a lot on our plate right now, so I can't make any promises.
What
First PR in the block-editing series requested in #455 (closed in favor of this rebuild). This adds the generic block-editing pipeline foundation for the editable input, mirroring the existing inline-style pipeline (
StyleType → FormattingStore → StyleHandler → InputFormatter → serializer/parser). No concrete block type is registered yet — with no handler the editor behaves exactly as today (plain paragraphs, all inline styles unaffected). A follow-up PR plugs the first handler (headings, H1–H6) in without touching the orchestrator.Abstractions (both platforms)
ENRMInputStyleType/StyleTypeENRMInputBlockType/BlockType(Paragraph default)ENRMStyleHandler/StyleHandlerENRMBlockHandler/BlockHandler— paragraph attributes, markdown line prefix, parser-block matchingENRMFormattingStore/FormattingStoreENRMBlockStore/BlockStore— generic, line-scoped block ranges +adjustForEditapplyBlockRangesenter_block/leave_block(replaces the no-op TODO); Android: block ranges from the shared AST (C++ untouched)Notes addressing the #455 review
bolddid for inline.enter_block/leave_block(the existing TODO is removed), not a post-pass.MarkdownASTNodethe readonly renderer already emits —MD4CParser.cppis unchanged, so readonly parsing is unaffected.Testing
Both platforms build green (example app, iOS sim + Android emulator). Behavior is inert (byte-for-byte unchanged) with no block handler registered.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EhuNE6PjRGjroxobhdd72q