Markdown view
A text's Markdown, nol-markdown-view, drawn as the kit's message draws its text blocks, for an app that lays out its own message from the kit's parts. The app adds provideMarkdown once; without it, and until the parser has loaded, the text shows as it was written, plain, with its Markdown marks.
The text is parsed as CommonMark with tables, strikethrough, autolinks and read-only task lists, with raw HTML left as text, and drawn as elements, never as HTML: an image is drawn by the app's template, or else shows its alt text, and only http, https and mailto addresses and those with a scheme the app names in MarkdownViewComponent.linkSchemes become links, which a click, a middle click or Enter hands to the app through MarkdownViewComponent.linkActivate and never follow; a link to a file's path is a link only when the app turns on MarkdownViewComponent.fileLinks, and shows its text plain otherwise, and a link to a file: URL on this machine is a link to its path only then, and shows as written otherwise. Nesting deeper than 24 elements, 8 lists or 8 quotes is drawn at the deepest level, and text past 200,000 characters is shown plain. Code, a code block or fenced in the text, shows in the kit's code block at its whole height on its own; inside the kit's message it shows up to 32rem high, then scrolls inside. The view takes the message text size, the text color and the message line height, 1.6, on its own as inside the kit's message.
Unless MarkdownViewComponent.math is off, math between \( and \) or $ and $ is drawn in its line, and between \[ and \] or $$ and $$ centered on a line of its own, scrolling sideways when wider than the view, by KaTeX in the text color. A single $ opens only before a character that isn't a space and closes only after one, never before a digit, so a price such as $5 and $10 stays text; math in inline code or a code block stays text. A formula KaTeX can't read, one still being written while the text streams, and every formula until KaTeX has loaded show their source as written, delimiters included. KaTeX takes no command that links, loads or sets attributes, and bounds the size and macro expansion a formula asks for.
An ng-template nolMessageImage, MessageImageDirective from @noldova/ui.components.angular, inside the view draws each image in its text, with the context { src, alt, title } (IMessageImageContext; title is null when the image has none). The template's content sits where the image was, inline in a paragraph, list item, table cell or quote, in an inline block no wider than the block it sits in, whose children are no wider than the inline block. A view with no template of its own uses the template of the message or view it sits in. Without a template an image shows its alt text. The kit draws nothing for an image and never fetches its src, which is any address the text wrote, percent-encoded, for the app to check. A streamed text keeps the content the template drew while it grows, and an image in inline code or a code block stays text.
Examples
Loading…
States
Loading…
API
Selector nol-markdown-view
Import from @noldova/ui.components.angular/markdown
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
text | string | Required | The Markdown text to draw. |
streaming | boolean | false | Whether the text is still streaming in; false when not bound. While it streams, the text that arrives shows a little at a time, by whole characters, in bursts about 50 milliseconds apart, every third frame at 60 Hz, closing the gap with what has arrived by about two thirds every quarter of a second and by at least 40 characters a second. Once it ends, the rest shows every frame, closing the gap the same way every 60 milliseconds. Under reduced motion the text shows as it arrives, and a view drawn while its text streams shows the text it already has at once, unless it is |
entering | boolean | false | Whether the view is new in a reply that is streaming, such as a reply's first text or the text after a tool call; false when not bound. A view drawn streaming and entering reveals the text it starts with from nothing, a little at a time, rather than showing it at once. A message sets it for each text block that arrives after the message is first drawn. |
paced | boolean | false | Whether text still being revealed when |
mentions | readonly MentionCandidate[] | [] | The people and agents whose mentions the view marks, the mention field's candidates; none when not bound. Each A link to |
mentionNames | boolean | true | Whether the view marks each |
fileLinks | boolean | false | Whether a link to a file's path is a link; false when not bound, and then such a link shows its text plain. A file link starts with the file badge for its path, without a |
linkSchemes | MarkdownLinkSchemes | MarkdownLinkSchemes.none | The link schemes of the app's own that the view makes links of; |
folderLinks | ReadonlySet<string> | new Set() | The paths of the view's file links that are folders, in the form |
references | ILinkReferenceSource | null | The app's reader of links to items on code hosts; null, the default, keeps every link plain. The view asks it about each link once, by its address and text, and draws a link it knows as the item's chip, a |
shellRuns | boolean | false | Whether the view's code blocks tagged as a shell, as the code block's |
shellRunStates | ReadonlyMap<number, ShellRunState> | new Map() | What became of each shell block's latest Run, keyed by its index, as |
shellRunOutputs | ReadonlySet<number> | new Set() | The code blocks, by index, under which the view draws the app's |
math | boolean | true | Whether the view draws math; true when not bound. When it's off, |
Outputs
| Name | Type | Description |
|---|---|---|
linkActivate | string | Emits the address of the link the person chooses; the app decides what opens. |
linkOpen | LinkOpenEvent | Emits each link the person opens, a link in the text, a reference's chip or a link in its card, beside the address |
linkMenu | LinkMenuEvent | Emits each link the person asks the menu of, by a right-click or the menu key, with its address and the event, whose default the view leaves to the app: one that shows its own menu cancels it in its handler, before it returns. A link to a file emits none. |
fileActivate | string | Emits the target of the file link the person chooses with a click, a middle click or Enter, while |
filePathsChange | readonly string[] | Emits the paths of the file links the view shows, in the form |
shellRun | ShellRun | Emits the code, language and index of the block whose Run the person chooses while |
Accessibility
| Key | Action |
|---|---|
| Tab | Moves the focus to each link in the text, in reading order, and into a code block's actions, which are one Tab stop. |
| Enter | Hands the focused link to its owner through linkActivate; the view never follows it. |
The text is drawn as elements, never as HTML: paragraphs, lists, quotes and tables keep their own roles, and a heading is a paragraph with the heading role and its level.
A task item's mark is an image named Done or Not done, before its text.
A link is a link with its address, which a click, a middle click or Enter hands to the owner, and a right-click or the menu key asks the owner for its menu; a mention is text in the mention color, not a link.
A code block is the kit's code block, with its toolbar named Code block actions.
The view itself adds no role and takes no focus.
Specification
Loading…