Commentable HTML demo
This is a small playground. Try selecting some text below, right-click, and pick Add Comment. The comment appears in the sidebar on the right.
Try it
The commenting layer wraps a selection in a <mark> element and stores the character offsets within #commentRoot in localStorage. The HTML file itself records which comments the agent has already handled, so reloading the page automatically prunes anything marked done.
Clicking a highlighted span scrolls the sidebar to that comment. Clicking jump in a card scrolls the document to that highlight.
Callouts
Use cmh-callout with a variant class for boxed asides. They stay readable in both light and dark themes because they use the built-in theme variables, so never hardcode colors in report content.
cmh-callout-info.cmh-callout-success signals a good outcome.cmh-callout-warning draws a cautious eye.cmh-callout-danger and fully readable on its tinted background in either theme.Keyboard shortcuts
- Ctrl + Enter while typing in the composer saves the comment.
- Esc closes the composer or the context menu.
What ships in the clipboard
The Copy all button emits a Markdown bundle with quoted text, the user's note, the comment id, and a trailing HANDLED_IDS_JSON: [...] line for the agent. Comments are not auto-cleared on copy; they are pruned only when the agent marks ids handled in this HTML.
Code blocks (commentable by default)
Any <pre> or <pre><code> block that is not tagged cm-skip is selectable. Highlights survive line wraps, the sidebar preview keeps monospace formatting, and the Copy all bundle emits a fenced block so newlines and indentation paste back correctly. The language tag from class="language-XXX" on the inner <code> is propagated.
def reduce(items, fn, acc=None):
for x in items:
acc = fn(acc, x) if acc is not None else x
return acc
print(reduce([1, 2, 3, 4], lambda a, b: a + b))
Sortable tables
Every column of a table with a real <thead> gets up/down chevrons in its header. Click to sort ascending, again for descending, and a third time to restore the authored order. Numeric columns sort numerically, not lexicographically. Sorting reorders rows for display only; comment anchors are recomputed so they stay attached to their text.
| Service | Requests | p95 (ms) |
|---|---|---|
| gateway | 1200 | 85 |
| auth | 340 | 1020 |
| catalog | 9800 | 240 |
Kusto query blocks (Run in Azure Data Explorer deep link)
An embedded KQL query is rendered as a framed figure: a caption bar naming the target cluster/database, a Run in Azure Data Explorer deep link that opens the query pre-loaded in the Azure Data Explorer web UX, and the query itself with author-time syntax highlighting. The code stays a normal commentable <pre><code class="language-kusto"> block (select any part to comment); the caption and link are cm-skip chrome. Build the figure with tools/kql_highlight.py (which calls tools/kusto_link.py for the link).
StormEvents
| where StartTime between (datetime(2007-01-01) .. datetime(2007-12-31))
| where State == "TEXAS"
| summarize Events = count(), Damage = sum(DamageProperty) by State // group by state
| top 10 by Damage desc
Mermaid diagrams
If your document contains <pre class="mermaid"> blocks, the layer also lets you comment on individual diagram nodes. Hover any node, click Add Comment, and the comment is anchored to that node by its mermaid id rather than character offsets. The highlight is a coloured ring around the node and survives reload, copy, and Export as Portable.
Keep cm-skip on the <pre class="mermaid"> element. It tells the text-selection layer to ignore the source code; the mermaid layer attaches independently via the mermaid class.
flowchart LR
A([User]) --> B{Hover a node}
B --> C[Add Comment appears]
C --> D[Composer opens]
D --> E([Comment anchored to
diagramIndex + nodeKey])
Other diagram types work too. In a Gantt chart the task labels are commentable, anchored by the label text.
gantt
title Demo rollout
dateFormat YYYY-MM-DD
section Build
Design :done, des1, 2026-07-01, 3d
Implement :active, imp1, 2026-07-04, 5d
section Ship
Validate : val1, 2026-07-09, 2d
Release : rel1, 2026-07-11, 1d
Code review diffs (side-by-side or inline)
Drop a unified diff into a <pre class="cmh-diff"> block and the layer renders a colored code-review view. Use the Side-by-side view / Inline view button in the diff header to switch layouts; the preference is remembered for this document (all diffs in a document share one layout default). Hover any changed or context line and click Add Comment to attach a review comment. Diff comments are anchored to the diff line structurally (not by character offset), so they survive the layout toggle, reload, copy, and Export as Portable. Add data-diff-label to name the file.
@@ -1,5 +1,6 @@
def reduce(items, fn, acc=None):
- for x in items:
- acc = fn(acc, x) if acc is not None else x
+ for x in items:
+ acc = x if acc is None else fn(acc, x)
+ # None is now a valid seed value
return acc
print(reduce([1, 2, 3, 4], lambda a, b: a + b))
Images (commentable)
Any <img> inside the content is commentable. Hover an image (or focus it with the keyboard and press Enter) and click Add Comment to attach a note anchored to that image by its position and src. The highlight is a colored ring that survives reload, Copy all, and Export as Portable.
Charts (commentable)
A <canvas> chart inside a <figure class="chart"> is commentable just like an image, even though the render surface itself is cm-skip. Hover the chart and click Add Comment; the comment anchors to the chart by position and is labelled chart in the sidebar and the copied bundle.