Skip to content

Updating source

Use a document session when highlighting the same source after edits. Unlike a one-shot call, a document retains its source and syntax trees so later edits can be parsed incrementally. It shares compiled queries with the highlighter.

The usual sequence is to create a document, update its source, highlight it, and render the result. Keep the document across edits. Each result is a snapshot that can be rendered independently.

For unrelated snippets, the one-shot functions in the quickstarts are usually simpler.

Create and update a document

JavaScript

Dispose the document when finished. Result objects do not need disposal.

JavaScript
import {
  createDocument,
  RenderHtmlConfig,
  RenderHtmlStyle,
} from "@comfit/node";

const document = createDocument({ language: "rust", source: "fn main() {}" });
try {
  document.update("fn main() { let answer = 42; }");
  const result = document.highlight();

  const config = new RenderHtmlConfig();
  config.style = RenderHtmlStyle.Inline;
  const darkHtml = result.renderHtml("catppina-dark", config);
  const lightHtml = result.renderHtml("catppina-light", config);
} finally {
  document.dispose();
}

Each example updates the source once, then renders the same result with two themes. The second render does not parse or highlight the source again.

Know what is reused

Parsing, highlighting, and rendering reuse different work:

OperationWork performed
Update the sourceDerive a UTF-8-safe edit and incrementally reparse the root and compatible embedded-language trees. Unchanged source is a no-op.
Highlight after an editRun highlighting queries on the updated trees.
Change the rainbow optionInvalidate cached highlighting and rerun queries on the next highlight.
Change only the emphasized linesReuse cached highlighting.
Render a result with another themeReuse the result without parsing or running queries.

Embedded-language layers update from parent to child. Compatible layers reuse their trees. New layers and edits at injection boundaries require fresh parsing.

Incremental parsing does not make query execution incremental.

Keep snapshots and languages separate

Results own their source and captures, so later edits or document disposal do not invalidate a snapshot. Documents also remain usable after the original Rust or browser highlighter is released.

A document snapshots the registry's loaded languages at creation. Create another document to change the root language or use a different set of grammars.

Bracket depths are collected during highlighting. Rendering cannot add depths if collection was disabled.

Release browser resources

Browser documents and results hold WASM resources. After creating a browser highlighter, use this cleanup pattern:

TypeScript
const document = highlighter.createDocument({
  language: "rust",
  source: "fn main() {}",
});

try {
  const result = document.highlight();
  try {
    const html = result.renderHtml();
    const lines = result.lines;
  } finally {
    result.dispose();
  }
} finally {
  document.dispose();
}

Keep documents across edits, but dispose each result when you no longer need to render it. Access browser result.lines before disposing the result. Once exported, those lines remain usable after disposal.