Files
brain-of-reese/.agents/phases/todo/138_markdown_blockquotes/01_blockquote_pass.md
T
ducoterra 0db6ab5df0
Build and Push Containers / build-and-push-app (push) Successful in 2m37s
Build and Push Containers / build-and-push-db (push) Successful in 12s
chore(agent): phase roadmap from TODO.md — 3 phases (138–140)
2026-09-30 09:35:07 -04:00

2.4 KiB

Task 01 — The blockquote pass in the shared renderer

Phase: 138_markdown_blockquotes · Source: TODO.md:3 — "Markdown formatted ">" quotes aren't rendering" Story: n/a

Objective

renderMarkdown turns runs of >-prefixed lines into <blockquote class="md-quote"> elements — after the escape + inline step, before the paragraph pass — with fences and tables keeping their precedence and non-quote input byte-identical.

Work

  1. frontend/assets/markdown.js — new pass between the step-2 text = inline(escapeHtml(text)) and the step-3 paragraph .map(...): split the text on \n; group the maximal run of consecutive lines matching ^\s*&gt;+ ? (the escaped quote marker); strip the &gt; run + one optional space from each member (nested >>/>>> collapses to one level — ASSUMPTION A1); join members with <br>; emit <blockquote class="md-quote">…</blockquote>. A blank line terminates the group.
  2. frontend/assets/markdown.js — extend the step-3 block-element guard from /^<(h\d|ul|ol|pre|li)/ to /^<(h\d|ul|ol|pre|li|blockquote)/ so the paragraph pass leaves the block alone (no <p> wrap).
  3. frontend/assets/markdown.js — update the module docstring: pass order is now fences → tables → escape+inline → blockquotes → paragraphs → restore; document the group rule (blank line terminates; nested collapses) and the documented limit (a list/heading line INSIDE a quote renders as plain text — the inline chain ran first; inline code/strong/em work).
  • ASSUMPTION: a > inside a code fence is already protected by the step-1 placeholder (no handling needed); a > in a table cell is escaped inside the <td> markup and restored in step 4 — both are pinned in task 03's behavior checks.

Testing & Quality

  • Unit: covered by task 03's file (the source pin + the node behavior listed there) — the frontend house pattern is one unit file per feature.
  • Coverage: n/a (frontend) — the suite + the pins are the gate.

Completion Criteria

  • node repro: renderMarkdown("> a\n> b") → <blockquote class="md-quote">a<br>b</blockquote>; renderMarkdown("> quoted") no longer emits a literal &gt;
  • a non-quote input (plain paragraph, list, table, fence) renders byte-identical to the pre-task renderer
  • uv run pytest green (the renderer-dependent unit suites unedited); uv run ruff check . clean