Per-evidence-item export: click Export → Copy as Markdown / Copy as HTML writes a portable citation card to the clipboard. Cmd/Ctrl+Shift+C exports the active evidence as Markdown. - ADR-0007 locks the Markdown + HTML output formats. - New shared types: CitationCard, openContextUrl(), resolveSourceLabel(). - Engine renderers under src/engine/rendering/: renderCitationCardMarkdown, renderCitationCardHtml — snapshot-tested, escape-safe, BEM classes for HTML. - src/work/useExportEvidence.ts wires engine + renderers + clipboard. - EvidenceSidebar gains an Export popover per row + auto-dismissing toast. - E2E test (tests/integration/citation-card-export-e2e.dom.test.tsx) walks PRD scenario steps 10-11 and asserts the clipboard payload. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4.3 KiB
ADR-0007 — Citation card output format (Markdown and HTML)
- Status: accepted
- Date: 2026-05-25
- Workplan: CE-WP-0004-T02 (Markdown renderer) and CE-WP-0004-T03 (HTML renderer)
- Spec refs:
wiki/ArchitectureOverview.md§4.7, §14.1, §14.2, §14.3
Context
The MVP scenario ends with a user exporting an evidence item as a portable citation card. Two formats ship in CE-WP-0004:
- Markdown — copied to the clipboard for pasting into notes, emails, GitHub issues, and so on. Renders well as plain text and as rendered Markdown.
- HTML — copied for pasting into rich-text editors and web pages.
A third format, the <citation-card> Web Component from
ArchitectureOverview.md §14.2, is out of scope here and lands in a later
workplan. Its visual presentation should be equivalent to the HTML form
but is not constrained to be byte-identical.
The two formats need a written contract so that:
- UI components (T04 sidebar export, future web embeds) can rely on the exact output structure.
- Snapshot tests fail loudly if the format drifts.
- Consumers that style the HTML form know which elements and classes are stable.
Decision
Markdown format (CE-WP-0004-T02)
> {quote}
— *{sourceLabel}* · [Open source]({openContextUrl})
{commentary}
Rules:
- Each
{quote}line is rendered with the leading>blockquote marker, preserving line breaks in the source quote. A single-line quote is one blockquote line; a multi-line quote becomes multiple>-prefixed lines. - A blank line follows the blockquote.
- The attribution line uses an em dash (
—, U+2014) followed by a single space, the italicised source label, a middle dot (·, U+00B7) with surrounding spaces, and the[Open source]({openContextUrl})link. - The middle dot + link segment is omitted entirely when no
openContextUrlis provided (which is unusual but possible for evidence items without an annotation). - A blank line follows the attribution.
- The optional
{commentary}paragraph is rendered as-is. When absent the trailing blank line and commentary paragraph are both omitted. - The output ends with a single trailing newline.
Reserved Markdown characters inside the quote are not escaped — the
intent is to reproduce the source text verbatim. The blockquote prefix
already neutralises the most dangerous reflow problems. The
{sourceLabel} is escaped to defuse */_ only; the link target is
URL-encoded by openContextUrl().
HTML format (CE-WP-0004-T003)
A single <aside class="citation-card"> root element with this stable
structure:
<aside class="citation-card">
<blockquote class="citation-card__quote">{escaped quote}</blockquote>
<p class="citation-card__attribution">
<cite class="citation-card__source">{escaped source label}</cite>
<a class="citation-card__link" href="{open context url}">Open source</a>
</p>
<div class="citation-card__commentary">{escaped commentary}</div>
</aside>
Rules:
- All user-supplied text is HTML-escaped (
&,<,>,",'). - Inline styles are not emitted. Host pages provide the CSS.
- The
<a>and the attribution·separator are omitted when noopenContextUrlis provided. - The
<div class="citation-card__commentary">is omitted when no commentary is provided. - Commentary is treated as plain text — no Markdown or raw HTML passthrough. A future workplan can introduce a sanitiser if rich commentary is required.
- The output ends with a single trailing newline.
Class-name contract
The four BEM-style class names — citation-card, citation-card__quote,
citation-card__attribution, citation-card__source,
citation-card__link, citation-card__commentary — are part of the
public contract. They must not be renamed without an ADR superseding
this one.
Consequences
- Snapshot tests in
src/engine/rendering/*.test.tslock these formats. Intentional changes require updating both the snapshots and this ADR. - The Web Component planned for §14.2 will reuse the HTML structure inside its shadow DOM, so the class names also become the customisation surface for downstream stylesheets.
- The
openContextUrlshape fromwiki/ArchitectureOverview.md§14.3 is now consumed by two renderers; changing the URL scheme requires regenerating snapshots and announcing via a new ADR.