Markdown¶
Note: The markdown component is currently experimental and may undergo changes in future releases.
The markdown component renders Markdown content as Angular components. Use its options to configure extensions, code highlighting, and custom rendering behavior. Options can be shared between multiple component instances.
Usage¶
Create the options once and pass the same instance to each si-markdown component that needs the configuration. The component supports GitHub Flavored Markdown by default, including tables, task lists, strikethrough, and autolinked URLs.
import { Component, signal } from '@angular/core';
import { makeSiMarkdownOptions, SiMarkdownComponent } from '@siemens/element-ng/markdown';
import { siMarkdownMathKaTeX } from '@siemens/element-ng/markdown/extensions/katex';
import { siMarkdownMermaid } from '@siemens/element-ng/markdown/extensions/mermaid';
import { siMarkdownHighlightJs } from '@siemens/element-ng/markdown/hightlighter/highlightjs';
import remarkGemoji from 'remark-gemoji';
@Component({
imports: [SiMarkdownComponent],
template: ` <si-markdown [markdown]="markdown()" [options]="markdownOptions" /> `
})
export class MarkdownExampleComponent {
protected readonly markdown = signal('# Release notes');
protected readonly markdownOptions = makeSiMarkdownOptions()
.setCodeHighlighter(siMarkdownHighlightJs({ autoDetectLanguage: true }))
.installExtension(siMarkdownMathKaTeX())
.installExtension(siMarkdownMermaid())
.installUnifiedPlugin(remarkGemoji);
}
Extensions¶
The following rendering support is included in every Markdown component:
| Rendering support | Purpose |
|---|---|
| GitHub Flavored Markdown | Parses tables, task lists, strikethrough, and autolinked URLs. |
| Inline HTML | Renders sanitized inline HTML. |
| Code blocks | Renders fenced code blocks without syntax highlighting. |
Optional integrations are configured through SiMarkdownOptions:
| Integration | Configuration | Purpose |
|---|---|---|
| KaTeX | .installExtension(siMarkdownMathKaTeX()) | Parses and renders inline and block LaTeX math expressions. It accepts optional remark-math parser and KaTeX rendering options. |
| Mermaid | .installExtension(siMarkdownMermaid()) | Renders fenced code blocks declared as mermaid as diagrams. It accepts optional Mermaid configuration. |
| Highlight.js | .setCodeHighlighter(siMarkdownHighlightJs()) | Adds syntax highlighting to fenced code blocks. It accepts Highlight.js options, including automatic language detection. |
| Gemojis | .installUnifiedPlugin(remarkGemoji) | Converts emoji shortcodes such as :rocket: to emoji. |
You can also add a compatible unified or remark plugin with .installUnifiedPlugin(plugin, options). This is useful for syntax that is not covered by the Element integrations, such as emoji shortcodes.
Bundle size: KaTeX, Mermaid, Highlight.js, and additional
unifiedplugins increase the application bundle size. Import and configure only the integrations your Markdown content requires.
Custom extension¶
An extension can install unified plugin(s) and associate the AST node types produced by that plugin with Angular renderer components. The KaTeX integration is an example: remark-math parses Markdown math into math and inlineMath nodes, which are then rendered by the same component.
import { type KatexOptions } from 'katex';
import remarkMath, { type Options as RemarkMathOptions } from 'remark-math';
import { type SiMarkdownExtension } from '@siemens/element-ng/markdown';
import { MarkdownKatexComponent } from './markdown-katex.component';
export const markdownKaTeX = (
parseOptions?: RemarkMathOptions,
katexOptions?: KatexOptions
): SiMarkdownExtension => ({
plugins: [{ plugin: remarkMath, options: parseOptions }],
types: [
{ type: 'math', component: MarkdownKatexComponent, options: katexOptions },
{ type: 'inlineMath', component: MarkdownKatexComponent, options: katexOptions }
]
});
The renderer implements SiMarkdownExtensionComponent. Element supplies the parsed node, its parent, and the options provided in the extension definition as signal inputs.
import { Component, computed, inject, input } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { type KatexOptions, renderToString } from 'katex';
import { type Literal, type Node, type Parent } from 'mdast';
import { type SiMarkdownExtensionComponent } from '@siemens/element-ng/markdown';
@Component({
selector: 'app-markdown-katex',
template: '',
host: {
'[innerHTML]': 'html()'
}
})
export class MarkdownKatexComponent implements SiMarkdownExtensionComponent {
private readonly sanitizer = inject(DomSanitizer);
readonly node = input.required<Node>();
readonly parent = input.required<Parent>();
readonly options = input<KatexOptions>();
protected readonly html = computed(() => {
const expression = (this.node() as Literal).value;
return this.sanitizer.bypassSecurityTrustHtml(
renderToString(expression, {
...this.options(),
displayMode: this.node().type === 'math'
})
);
});
}
Register the extension with the component options:
protected readonly markdownOptions = makeSiMarkdownOptions().installExtension(markdownKaTeX());
Code¶
SiMarkdownComponent API Documentation¶
si-markdownComponent to display markdown text
This component is built using concepts from ngx-remark, namely using Angular templates to render the AST produced by remark .
Unlike ngx-remark , it features a configuration based approach of extensibility so that multiple instances of the component can be used with the same configuration, e.g. inside a chat component w/o repeating templates.
Input Properties¶
| Name | Type | Default | Description |
|---|---|---|---|
| debug ¶ | boolean | false | Debug mode. When true, unknown node types will be displayed along with the node as JSON. |
| markdown ¶ | string | '' | The markdown text to transform and display |
| options ¶ | SiMarkdownOptions | Options to control rendering. Can be shared across multiple instances. |
Types Documentation¶
| Options for the markdown renderer. This holds all configuration and allows installing extensions. A number of extensions are already ready to use and shipped with Element. Example: | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||
| |||||||||||||||||||||
|
| AST node type handler | ||||
|---|---|---|---|---|
|
| Combination of unified plugin with options | |||
|---|---|---|---|
|
| A combination of a component and options passed to it during run-time | |||
|---|---|---|---|
|
| Interface an extension component must implement | ||||
|---|---|---|---|---|
|
| Interface a code highlighter component must implement | |||||
|---|---|---|---|---|---|
|
Processor import imported from unified |
|---|
import imported from @types/mdast |
|---|
| Extended root with references |
|---|
| An extension to the si-markdown component | ||||
|---|---|---|---|---|
|
import imported from @types/mdast |
|---|
import imported from @types/mdast |
|---|
Plugin import imported from unified |
|---|
Transformer import imported from unified |
|---|
Preset import imported from unified |
|---|
PluggableList import imported from unified |
|---|
import imported from @types/mdast |
|---|
| Extra node for collecting all footnotes | |||||
|---|---|---|---|---|---|
|
import imported from @types/mdast |
|---|
import imported from @types/mdast |
|---|
import imported from @types/unist |
|---|
import imported from @types/mdast |
|---|
Except where otherwise noted, content on this site is licensed under MIT License.