demo · v148

Range Marker Highlighter

Wrap text in <?start name="X">...<?end> processing-instruction markers. The page detects each matching pair after parsing and highlights the enclosed range in real time. Same pattern Declarative Partial Updates uses to denote streaming holes.

About this demo: The HTML on the left is parsed with DOMParser. We walk the result, find each ProcessingInstruction whose target is start or end, pair them up, and wrap the nodes between each pair with a <span data-range-name="...">. The CSS rules for those spans (blue, rose, emerald, amber) make each named range visible without ever rendering the PIs themselves.

preset documents

input

bio ad status note

rendered

Ranges detected: 0

what's happening

After parsing, we collect every ProcessingInstruction node whose target is start or end. start PIs carry a name="X" attribute; the next end closes the most recent open named range. We then traverse the DOM and wrap everything between each matched pair in a span tagged with the range name, which CSS uses to apply a coloured highlight.

const doc = new DOMParser().parseFromString(input, "text/html");
const stack = [];
const ranges = [];
const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ALL);
let node;
while ((node = walker.nextNode())) {
  if (node.nodeType !== Node.PROCESSING_INSTRUCTION_NODE) continue;
  if (node.target === "start") {
    const m = node.data.match(/name="([^"]+)"/);
    stack.push({ name: m?.[1] ?? "range", start: node });
  } else if (node.target === "end" && stack.length) {
    const open = stack.pop();
    ranges.push({ name: open.name, start: open.start, end: node });
  }
}
// Wrap each pair in a span — see the live demo for the exact walk.

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗