Skip to content

[Feature]: Unify Story overlay with shared markdown parser/renderer #222

@forketyfork

Description

@forketyfork

Status Quo

The Story overlay (src/ui/story_parser.zig + src/ui/components/story_overlay.zig) uses a custom parser that only understands fenced code blocks (story-diff and plain), heading-level bold, and prose anchors (**[N]** / <!--ref:N-->). Prose text is rendered as plain unstyled text with word-wrapping — no inline bold, italic, strikethrough, code spans, links, lists, blockquotes, or tables.

Meanwhile, the Reader mode (src/ui/components/reader_overlay.zig) uses a full markdown pipeline: markdown_parser.zig parses CommonMark blocks and inline styles into DisplayBlock[], then markdown_renderer.zig wraps them into styled RenderLine[] with runs. Reader mode renders these runs with per-style fonts, colors, strikethrough decorations, clickable links, and Cmd+F search.

These two parsers were built independently. The story format is effectively markdown with extensions (story-diff fenced blocks, anchor markers, code block metadata comments). The current architecture duplicates markdown concerns rather than extending the shared parser.

Objectives

Story files should render with the same rich markdown formatting that Reader mode provides — inline styles, headings, lists, blockquotes, tables, clickable links, and in-overlay search — while preserving story-specific features (story-diff blocks with +/- coloring, anchor badges, bezier arrows between prose and code). The underlying architecture should use a single markdown parsing/rendering pipeline with story-specific extensions, eliminating the duplicated parser.

User Flow

Trigger: An architect story <file> notification arrives, or a story file is opened.

  1. Story overlay opens as today.
  2. Prose sections render with full markdown formatting: bold, italic, strikethrough, code, links, headings with sizing, lists, blockquotes, tables.
  3. story-diff and plain code fenced blocks render as before (diff coloring, anchor badges, bezier arrows).
  4. User can Cmd+F to search within the story content.
  5. User can click links to open them in the browser.

Result: Story overlay has full Reader-mode formatting/interaction fidelity, plus its existing story-specific features.

Scope

In scope:

  • Extend markdown_parser.zig to support story-specific extensions (story-diff fenced blocks with metadata comments, anchor markers in prose **[N]**, code ref comments <!--ref:N-->)
  • Refactor story_overlay.zig to use the shared markdown_parser + markdown_renderer pipeline instead of story_parser.zig
  • Render inline markdown styles (bold, italic, strikethrough, code, link) in story prose
  • Render markdown block types (headings, lists, blockquotes, tables, horizontal rules) in story prose
  • Add clickable link support to story overlay
  • Add Cmd+F search to story overlay
  • Preserve all existing story-specific rendering: diff line coloring, diff headers, anchor badges, bezier arrows
  • Remove story_parser.zig once migration is complete

Out of scope:

  • Changes to Reader mode behavior or rendering
  • New story-specific markdown extensions beyond what exists today
  • Story file editing or two-way sync
  • Prompt separator detection in story files (Reader-specific feature)

Implementation Plan

Affected Modules

  • src/ui/components/markdown_parser.zig: Extend with story-specific block kinds and anchor/ref parsing
  • src/ui/components/markdown_renderer.zig: Add render line kinds for story-diff blocks and anchor metadata
  • src/ui/components/story_overlay.zig: Rewrite rendering pipeline to consume RenderLine[] instead of DisplayRow[]; add search and link click handling
  • src/ui/story_parser.zig: Delete after migration
  • docs/ARCHITECTURE.md: Update module boundary table

Tasks

  1. Extend markdown_parser.zig with story-specific block kinds — add story_diff_header, story_diff_line, story_code_line to BlockKind; add CodeLineKind and CodeBlockMeta fields to DisplayBlock; teach the fence parser to recognize story-diff info strings and parse <!--{...}--> metadata JSON and <!--ref:N--> line annotations; teach inline span parsing to recognize **[N]** prose anchors as a new InlineStyle (or a span annotation) — src/ui/components/markdown_parser.zig
  2. Extend markdown_renderer.zig with story line kinds — add story_diff_header, story_diff_line, story_code_line to LineKind; carry through anchor and diff metadata from blocks to render lines — src/ui/components/markdown_renderer.zig
  3. Refactor story_overlay.zig rendering to consume RenderLine[] — replace the story_parser.parse() call with markdown_parser.parse() + markdown_renderer.buildLines(); adapt the texture-building and rendering loops to iterate over RenderLine runs with per-style font selection (bold, italic, code) and colors, matching Reader mode's rendering approach — src/ui/components/story_overlay.zig
  4. Preserve story-specific rendering features — ensure diff line coloring (+/- lines), diff header rendering, anchor badge placement, and bezier arrow drawing still work with the new RenderLine-based pipeline — src/ui/components/story_overlay.zig
  5. Add clickable link support — track link hit regions from RenderRun hrefs, handle click events to open URLs via os/open.zig, render link underlines and hover cursor changes — src/ui/components/story_overlay.zig
  6. Add Cmd+F search — port the search bar and match-highlighting logic from reader_overlay.zig (or extract into a shared search helper) — src/ui/components/story_overlay.zig
  7. Delete src/ui/story_parser.zig and remove all references
  8. Ensure existing Reader mode tests still pass; add tests for story-specific extensions in markdown_parser.zig (story-diff parsing, anchor extraction, code ref stripping)
  9. Update docs/ARCHITECTURE.md — update module boundary table to reflect the unified parser and removal of story_parser.zig

New Dependencies

None

Acceptance Criteria

  • Story prose renders inline markdown: bold, italic, strikethrough, code, links
  • Story prose renders block-level markdown: headings (with sizing), lists, blockquotes, tables
  • Story-diff blocks render with +/- coloring and diff headers as before
  • Anchor badges and bezier arrows work as before
  • Links in story prose are clickable (opens browser)
  • Cmd+F search works within story overlay
  • story_parser.zig is deleted; only markdown_parser.zig + markdown_renderer.zig are used
  • Existing Reader mode behavior is unchanged
  • All existing tests pass; new tests cover story-specific markdown extensions
  • docs/ARCHITECTURE.md updated
  • zig build, zig build test, just lint pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions