markdown-to-html-dom
v0.1.1
Published
Synchronize streaming Markdown to HTML DOM
Downloads
242
Maintainers
Readme
Synchronize streaming Markdown to HTML DOM
markdown-to-html-dom is a minimal browser-focused streaming Markdown renderer, which lets you append Markdown text in chunks and render it incrementally into a target DOM element. This is useful for chat UIs, live logs, and any interface where content arrives over time.
Features
- Incremental rendering to HTML
- Keeps finalized blocks stable while rebuilding only the trailing active block
- Supports common Markdown plus GFM features (tables, task lists, strike-through) via micromark and micromark-extension-gfm
- Small API surface:
push,flush,set,clear, callbacks when elements are created.
Refer to the demo page and the corresponding source code for a full example.
Installation
npm install markdown-to-html-domQuick Start
import { MarkdownHTMLConverter } from "markdown-to-html-dom";
const root = document.getElementById("output");
const converter = new MarkdownHTMLConverter(root);
converter.push("# Demo");
converter.push("\n");
converter.push("This paragraph arrives");
converter.push(" in pieces.\n\n");
converter.push("- item one\n");
converter.push("- item two\n");
// Finalize trailing content when the stream ends.
converter.flush();API
new MarkdownHTMLConverter(rootNode: HTMLElement)
Creates an incremental Markdown renderer bound to an HTML target element.
The element rootNode receives rendered HTML.
Throws TypeError if rootNode is not an HTMLElement.
push(markdownChunk: string): void
Appends a Markdown chunk and re-renders incrementally.
Empty chunks are ignored. Re-render affects only active nodes, finalized nodes are not impacted.
flush(): void
Finalizes any pending trailing block.
Use this when no more chunks are expected (for example, end of stream) so the last active block becomes finalized.
set(markdownText: string): void
Replaces the current output with a full Markdown document.
Renders the provided text as a complete replacement. Clears pending state.
clear(): void
Clears all rendered output and pending state.
onAnchorCreated(callback: (link: HTMLAnchorElement) => void): void
Registers a callback that runs for each newly created anchor element.
Invoked whenever rendered output includes one or more <a href="..."> elements. Useful for setting link behavior (for example target or rel attributes). May be invoked multiple times when active element is cleared and re-populated.
onCodeBlockCreated(callback: (codeBlock: HTMLPreElement) => void): void
Registers a callback that runs for each newly created fenced code block container.
Invoked whenever rendered output includes one or more <pre> code block elements. Useful for syntax highlighting or post-processing rendered code blocks. May be invoked multiple times when active element is cleared and re-populated.
Samples
Nested lists
1. Item 1
2. Item 2
- Sub-item 2.1
- Sub-item 2.2
Paragraph
> Blockquote
> across linesList item contents are wrapped in <p> depending on whether block-level elements are present. This behavior is inherited from micromark.
<ol>
<li>Item 1</li>
<li>Item 2
<ul>
<li>
<p>Sub-item 2.1</p>
</li>
<li>
<p>Sub-item 2.2</p>
<p>Paragraph</p>
<blockquote>
<p>Blockquote across lines</p>
</blockquote>
</li>
</ul>
</li>
</ol>Fenced code blocks
~~~python
# Python example
def greet(name):
return f"Hello, {name}!"
print(greet("World"))
~~~
~~~javascript
// JavaScript example
function greet(name) {
return \`Hello, \${name}!\`;
}
console.log(greet("World"));
~~~<pre> elements for fenced code blocks are wrapped in a <div> to allow styling of overflow and borders without affecting the layout.
<div class="code">
<pre><code class="language-python"># Python example
def greet(name):
return f"Hello, {name}!"
print(greet("World"))
</code></pre>
</div>
<div>
<pre><code class="language-javascript">// JavaScript example
function greet(name) {
return \`Hello, \${name}!\`;
}
console.log(greet("World"));
</code></pre>
</div>CSS class hints
In order to help styling, the CSS classes code and table are applied to <div> elements that wrap <pre> and <table> elements, respectively. <ul> elements that represent task lists have the CSS class tasklist.
Active Block Marker
While content is still incomplete, the current trailing block is marked with the attribute data-active. This can be used for styling or UI affordances while streaming.
Usage Notes
This package is browser-oriented and expects DOM globals (document, HTMLElement).
Output is rendered as HTML. If Markdown input is untrusted, validate/sanitize according to your application security requirements.
