Markdown
Assistant prose, typeset — headings, emphasis, lists, quotes, tables, links, and fenced code, streaming gracefully.
FlowMarkdown typesets what the assistant says. Assistant text parts
render through it by default — a thread wired yesterday shows rich
replies today, and markdown: false on FlowThread or FlowMessage
opts a literal-text host back out. User bubbles and system notices always
render plain: what the user typed is a transcription, not prose to
typeset.
The parser is built in — no dependency, synchronous, and written for the dialect assistants actually emit. Deliberately deferred syntax (images, task lists, footnotes, inline HTML, setext headings) renders as the literal text it is.
The document
Section titled “The document”Headings sit on the existing type ramp, inline code takes the mono face
on a rounded chip of the faint wash — painted under the glyphs, so a
wrapped chip keeps only its outer corners rounded and the streaming
reveal runs straight through it — quotes step down to the secondary ink
behind the hairline bar, and fenced code renders through
FlowCodeBlock — highlighting, header, and copy intent included:
FlowMarkdown( text: reply, isStreaming: generating, onLinkTap: (href) => openInBrowser(href), onCodeCopy: copyPart, codeCopyTooltip: 'Copy code',)Streaming
Section titled “Streaming”Streaming is data, as everywhere: rebuild with a longer text and the
trailing paragraph reveals with the same per-character fade plain text
gets, while fences, tables and rules render whole. The parser tolerates
input that ends mid-construct — unclosed emphasis stays literal until its
closer arrives (and restyles without re-fading), a half-typed link shows
its label and hides the URL, an unterminated fence is a code block still
in progress, and a table only appears once its delimiter row lands:
Tables
Section titled “Tables”Column alignment comes from the delimiter row; a table wider than its column scrolls horizontally inside the message rather than wrapping the page:
Links report intent: the label styles in the accent ink with an
underline, and tapping hands the host the href — the package never
launches URLs. With no onLinkTap wired, links render as plain prose
rather than a styled-but-dead affordance. In a thread the callback
carries the message too: onLinkTap: (message, href) => ....
Bare URLs autolink with GFM’s rules: https://, http:// and www.
(handed to the host with https:// prepended), trailing punctuation
trimmed, a closing parenthesis kept when the URL’s parens balance, and
emails deliberately left literal. Mid-stream, a URL still being typed
links early and its href grows with the text — links are inert while
the reveal runs, so nothing mis-taps.
Fenced code and copy
Section titled “Fenced code and copy”Every fence synthesizes a FlowCodePart, so copy flows through the same
contract code parts use — one onCodeCopy handler and one
copiedCodePart confirmation serve both. While a fence is still
streaming its copy affordance stays hidden, exactly like a streaming
FlowCodePart.
Restyling
Section titled “Restyling”FlowMarkdownStyle overrides the document’s per-element styling without
touching the global tokens: h1Style through h6Style (merged over each
level’s role), linkColor, inlineCodeStyle and codeChipColor (the
face and the painted chip), quoteColor and quoteBarColor,
tableHeaderStyle, tableCellStyle, tableBorderColor and
tableDividerColor, and ruleColor. Install one on
FlowTheme.markdownStyle for every markdown surface — assistant turns in
a thread included; the widget’s markdownStyle wins field by field.
Fences restyle through FlowCodeBlockStyle.
Key API
Section titled “Key API”text— the markdown source received so far.isStreaming— animates the trailing text block; tolerant parsing either way.style— merged overbodyLarge+onSurface; headings keep their scale but follow this style’s color.onLinkTap,onCodeCopy,copiedCodePart,codeCopyTooltip— intent out, host-localized strings in.- On
FlowThread/FlowMessage:markdown(default true) gates the assistant-text rendering;onLinkTapthreads through with the message-arity shape on the thread.
Selection is built into FlowThread: prose, tables and fences all join
the thread’s selection, and a copy keeps a line break between paragraphs.
A FlowMarkdown on its own selects inside a host SelectionArea, the way
a plain Text does; list markers stay out of it, as in a browser.