A streaming markdown renderer turns partially-received markdown into valid HTML at every step of a stream. When a language model streams an answer, you hold a growing prefix like **Bold te — a normal markdown parser renders that as a literal **Bold te because the closing marker has not arrived, so the reader watches raw asterisks flicker until the token finishes. This renderer instead treats an open marker as if it will close, so **Bold te reads as bold text the instant it arrives.
Implement streamingMarkdownStateMachine(md), returning an HTML string. Support a small subset and, crucially, close anything left open at the end of the input:
**text** becomes <strong>text</strong>; an unclosed **text still renders as <strong>text</strong>.<code>text</code>, and unclosed renders closed. Inside inline code, ** is literal.<pre><code>code</code></pre>. An unclosed fence renders the code so far. Inside a fence, everything is literal.<, >, and & in text is escaped, so the HTML is safe to inject.function streamingMarkdownStateMachine(md: string): string;
streamingMarkdownStateMachine('**Bold** and `code`');
// '<strong>Bold</strong> and <code>code</code>'
streamingMarkdownStateMachine('**half'); // '<strong>half</strong>' (closed at end)
streamingMarkdownStateMachine('```js\nx = 1\n```');
// '<pre><code>x = 1</code></pre>' (the js info string is dropped)
** is literal text, not formatting.<, >, and & everywhere, including inside code blocks.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.