Extras
MarkdownViewer
BitMarkdownViewer is a native, SEO friendly Blazor component that parses Markdown into an AST and renders it straight to the Blazor render tree - no JavaScript interop, no third-party packages. Composable pipelines add exactly the flavors a document needs, from the GitHub set to front matter, containers, definition lists and mathematics; URLs are sanitized and untrusted input bounded by default; and the parsed tree, the rendering of any node, and the words the renderers write themselves are all yours to change.
Notes
To use this component, you need to install the Bit.BlazorUI.Extras nuget package, as described in the Optional steps of the Getting started page.
Parsing and rendering happen entirely in C# (no JavaScript interop), so the component renders real DOM and works the same while prerendering, on the server, and on the client.
Raw HTML in the source is rendered as text and every link and image URL is sanitized, so untrusted Markdown cannot inject active content.
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
Markdown parameter. With no Pipeline the component
understands the CommonMark core - headings, emphasis, links, images, lists, block quotes, code spans and
code blocks - and nothing else, which is the safest starting point for untrusted content.
Native Markdown in Blazor
Rendered entirely in C# with no JavaScript and no third-party packages.
- Real DOM output
- Safe by default
- Zero interop
GitHub flavored
Pipeline. The ready-made
BitMarkdownPipelines.GitHub adds the six GitHub flavors - pipe tables with per-column
alignment, ~~strikethrough~~, task lists, autolink literals that turn bare URLs and email
addresses into links, and the footnotes and alerts shown in the next two sections.
GitHub Flavored Markdown
Supports strikethrough and bare links like https://bitplatform.dev
Task list
- Parse Markdown in pure C#
- Render the real render tree
- Use any JavaScript
Table
| Feature | Basic | GitHub |
|---|---|---|
| Headings | ✔ | ✔ |
| Tables | ✔ | |
| Strikethrough | ✔ |
Alerts
[!NOTE], [!TIP], [!IMPORTANT],
[!WARNING] or [!CAUTION] renders as a titled callout. The kind is written out as
a heading rather than signalled by color alone, so it survives a screen reader and a monochrome print.
Add it on its own with UseAlerts(), or get it with the GitHub bundle.
Note
Useful information that users should know, even when skimming content.
Tip
Helpful advice for doing things better or more easily.
Important
Key information users need to know to achieve their goal.
Warning
Urgent info that needs immediate user attention to avoid problems.
Caution
Advises about risks or negative outcomes of certain actions.
A block quote without a marker is still an ordinary block quote.
Footnotes
[^label] reference and a [^label]: ... definition anywhere in the document
become a numbered footnote. Notes are numbered in the order they are first cited, gathered into one
section at the end, and every citation gets its own back-link. A reference with no definition stays plain
text and a definition nobody cites is dropped. Add it on its own with UseFootnotes(), or get it
with the GitHub bundle - which carries it because [^1]: ... is also a valid link reference
definition, so a pipeline with tables but without footnotes would quietly turn the note into a link.
References & entities
[label]: /url "title") declares a destination once and lets [text][label],
[text][] and [text] reuse it from anywhere in the document - before or after the
definition - keeping long documents readable; the definition line itself is not rendered. And
character references (©, ©, ©)
are decoded to the characters they name everywhere except inside code, where they stay literal.
Reference links
The bit platform site, the Blazor docs, and the same bit link again as a shortcut reference.
Character references are decoded too: © 2026 — © is the same
sign written as a number, and ✅ as hex. Inside code they stay literal:
©.
Emphasis extras
* / _ and GFM's ~~,
UseEmphasisExtras() adds the four marks technical writing keeps reaching for:
~subscript~, ^superscript^, ++inserted++ and
==highlighted==, rendered as real <sub>, <sup>,
<ins> and <mark> elements rather than styled spans. Subscript
shares the ~ character with strikethrough - one tilde is subscript, two are strikethrough -
so enabling it implies strikethrough and the two can be added in either order. A lone + or
= in ordinary prose is never mistaken for a delimiter: both need a run of two.
Water is H2O, the area of a circle is πr2, and 210 = 1024.
This release adds streaming and drops the old overload, so read the migration notes first.
Ordinary prose is left alone: 1 + 2 = 3, and a+b is not inserted text.
Typography
UseSmartyPants() turns the ASCII stand-ins authors type into the characters they mean:
straight quotes curl into typographic ones, -- and --- become en and em dashes,
... becomes an ellipsis and << / >> become guillemets.
Whether a quote opens or closes is read from what precedes it, which is also what gives
don't its apostrophe. Only text is rewritten - code spans, code blocks and URLs keep every
character exactly as it was written.
"Typography matters," she said -- and it's hard to disagree...
The 2024--2026 range uses an en dash; an aside uses an em dash --- like this one.
Code keeps every character: --- "not curled" ...
“Typography matters,” she said – and it’s hard to disagree…
The 2024–2026 range uses an en dash; an aside uses an em dash — like this one.
Code keeps every character: --- "not curled" ...
Front matter
.md file from a docs site or a static-site generator usually opens with a metadata
block fenced by --- (YAML) or +++ (TOML). Without
UseFrontMatter() that block is ordinary Markdown - a thematic break followed by a heading -
so the file renders with its metadata splashed across the top. The extension parses it into a
BitMarkdownFrontMatterNode that renders nothing and keeps the raw text. Reading that text
back needs the parsed document, which is what OnParsed hands you - it is raised with the
tree the renderer is about to walk, just before it does - and
BitMarkdownFrontMatterNode.Find(document) finds the node in it, for you to hand to
whichever serializer you already use.
title: Release notes date: 2026-09-09 tags: [blazor, markdown]
Release notes
The metadata above describes the file; it is not part of the document.
Release notes
The metadata above describes the file; it is not part of the document.
Containers
UseContainers() adds the ::: fence documentation sites are written with. The
word after the fence names the container and becomes its class, and anything after that word is its
title - so :::warning Read this first renders as a titled callout without the renderer
knowing that "warning" means anything. Containers nest, and the stylesheet already colours the names a
docs site reaches for (note, info, tip, success,
warning, caution, danger); any other name is a plain block you
style yourself. One name means more than a class: :::details renders a real
<details> with the title as its <summary>, which is the only way
to a collapsible section in a language that has no syntax for one.
Start here
Containers are fenced with three colons. The first word names the container.
Read this first
The rest of the line is the title, and the body is ordinary Markdown.
Containers nest, so an aside can sit inside one.
How the fence is read
The word after the fence names the container; the rest of the line is its title.
This one is a real <details>, so it opens and closes.
A name the stylesheet has no opinion about is a plain block you style yourself.
Definition lists
UseDefinitionLists() reads a term on its own line followed by
: its definition - the shape Pandoc and markdown-it use - into a real
<dl> of <dt> and <dd>. A term may carry several
definitions, and a definition indented under its own text may run to several paragraphs or hold a
nested list.
- Pipeline
- The immutable set of flavors a document is parsed with.
- Build it once and share it.
- AST
The tree of headings, paragraphs and inline runs the parser produces.
A definition indented under its own text may run to several paragraphs, or hold a list:
- one
- two
Abbreviations
UseAbbreviations() lets a document explain its jargon once. A
*[HTML]: HyperText Markup Language line declares the term and renders nothing; every
whole-word occurrence of it afterwards becomes an <abbr> carrying the expansion, so it
is a tooltip for a reader and a spoken expansion for a screen reader. Only text is rewritten -
HTMLElement keeps its own name and a term inside code stays literal - and where
two terms overlap the longer one wins.
The parser builds an AST and the renderer writes HTML from it, which is what keeps the output usable under a strict CSP.
Only whole words are expanded, so HTMLElement keeps its own name and HTML inside
code stays literal.
Mathematics
UseMathematics() reads $inline$ and $$display$$. Its first job is
protection: TeX is made of the underscores, asterisks and backslashes Markdown itself is made of, so
without it $a_1 + b_1$ loses its subscripts to emphasis. What survives is kept verbatim,
delimiters and all, in a span.math-inline or a .math-display. The viewer
typesets nothing itself, so with no typesetter on the page the TeX reads as the text it is - which is
what the first column shows. Typesetting is the page's choice: in the second, KaTeX renders each of
those elements once the viewer has drawn them, reading the class rather than the delimiters, since
KaTeX's auto-render does not take a single $ as one and the viewer has already told math
from money. Prices are safe: a $ followed by a space, or a closing one followed by a
digit, is never a delimiter.
Euler's identity, $e^{i\pi} + 1 = 0$, in one line.
Prices are left alone: this costs $5 and that one $10.
Euler's identity, $e^{i\pi} + 1 = 0$, in one line.
Prices are left alone: this costs $5 and that one $10.
Figures
UseFigures() turns a
paragraph holding nothing but a titled image into a <figure> with the title as its
<figcaption>. The caption comes from the title and never from the alt text: alt
describes the picture for someone who cannot see it, a caption is read by everyone, and using one text
for both would have a screen reader say the same sentence twice. An image with no title is left exactly
as it was.

An image with no title stays an ordinary image:

Line breaks
UseSoftLineAsHardLine() makes every newline a break instead - the equivalent of the
breaks option in marked and markdown-it.
Roses are red Violets are blue Markdown reflows Unless you tell it not to
Roses are red
Violets are blue
Markdown reflows
Unless you tell it not to
Custom pipeline
BitMarkdownPipelineBuilder. A built pipeline is
immutable and thread-safe, so build it once (a field, or a singleton) and share it - passing a
newly-built pipeline on every render would re-parse the source every time.
Custom pipeline ✨
This viewer uses a pipeline composed with only the extensions we picked: pipe tables, strikethrough, task lists, emoji and auto identifiers. Autolinks were left out, so https://bitplatform.dev stays plain text.
Oldapproach replaced- Anything left to do?
Untrusted content
ImageRendering decides
which image sources may load: a remote image is fetched the moment it renders, so
 exfiltrates whatever the attacker encodes into
the URL without any interaction. SameOrigin (the default) blocks cross-origin images and
keeps the alt text; None blocks every image; All is for fully trusted sources.
Alongside it, StripBidiControlCharacters neutralizes "Trojan Source" (CVE-2021-42574)
spoofing, MaxLength caps how much source is parsed, and MaxNestingDepth is an
always-on guard against pathologically nested input.
Content from somewhere else
A same-origin image always loads:

A cross-origin one only loads under All:
Unsafe URLs never survive the sanitizer, whatever the policy:
a javascript link and .
Raw <b>HTML</b> and <script>alert(1)</script> are rendered as text.
Table of contents
OnParsed hands over is good for more than reading one node out of:
Document exposes the same tree afterwards, and either way it is the whole document.
Walking it with
BitMarkdownAstHelper.Descendants is how you read structure out of a document without parsing
it twice - here, the headings and the slugs the UseAutoIdentifiers() extension gave them,
turned into a navigation rail. BitMarkdownAstHelper.ToPlainText reads the other half out of
the same tree: what the document says with none of the markup it says it with, which is the text a
search index, an excerpt or a meta description is built from.
Release notes
9.4.0
Added
Footnotes, alerts and reference links.
Fixed
Truncation no longer splits a surrogate pair.
9.3.0
Added
The whole native parser.
Heading anchors
UseAutoIdentifiers(anchorLinks: true) adds the permalink a documentation site is expected
to have: every heading keeps its generated id and gains a # link back to itself, so a
reader can copy a link straight to a section. The glyph is hidden from assistive technology and the link
is named after its heading instead, so it is announced as "Permalink to Installation" rather than as a
punctuation mark; it stays invisible until the heading is hovered or the link itself is focused.
A heading may also name its own id by ending with {#the-id}, which is worth doing wherever a
generated slug would change with the wording - every link already pointing at that section breaks the
moment it does. The marker names the heading and is not part of what it says, so it never reaches the
rendered text.
Inline
<p> that
takes a line of its own. Setting Inline renders the root as a span and drops
the paragraph wrappers, letting a short piece of Markdown sit inside a sentence, a table cell or a
label. Blocks that are not paragraphs still render as themselves, so nothing is silently lost - and
because a span may not legally hold a list or a table, a document that turns out to hold
one keeps its div and is laid out inline by the stylesheet instead.
Span<T> - read whyTemplates
CodeBlockTemplate is where a syntax highlighter, a copy button or a diagram renderer goes -
it is handed the block, so it can read the language off Info and the source off
Content. ImageTemplate is for a lightbox or a placeholder, and
LinkTemplate for routing an in-app destination through the router. Every safeguard has
already run when a template does: the URL is sanitized, and an image the
ImageRendering policy blocked arrives with an empty Url. Anything else is
still open to a BitMarkdownNodeRenderer of your own on the pipeline.
Every code block below is drawn by the template, not by the viewer:
var pipeline = new BitMarkdownPipelineBuilder().UseGitHubFlavored().Build();dotnet add package Bit.BlazorUI.ExtrasAnd every link, like the bit platform , gets its own chrome.
Interactive task lists
OnTaskChanged is what makes them live: the boxes become enabled, and ticking one reports
its index, its new state, and the source rewritten to match - so storing the change is one
assignment. The viewer never edits Markdown behind your back; the state stays the one you
own. The rewrite counts the same markers the renderer drew, skipping any inside code blocks, and
BitMarkdownTaskList.Toggle is the same helper if you would rather call it yourself.
Release checklist
- Write the parser
- Write the renderer
- Write the docs
- Ship it
Nested items count too:
- Polish
- Icons
- Copy
Link policy
rel="noopener noreferrer", and
a link within the site opens in place. UseLinkOptions() changes that policy: keep
everything in the same tab, which is what a viewer embedded in an app usually wants, or mark
user-written links nofollow ugc - the two words that stop a comment box from becoming a
link farm and tell a search engine the site did not write them.
A link a reader wrote to somewhere else
opens in the same tab and is marked nofollow ugc.
A link to another page here is untouched, and so is one to a section of this page.
Rewriting URLs
UseBaseUrl() resolves the relative ones against an
address you choose and leaves absolute destinations and in-page fragments alone;
UseUrlRewriter() is the general form, for pointing images at a CDN or stripping tracking
parameters. Whatever a rewriter returns is sanitized again on the way out, so it cannot reintroduce an
unsafe destination - and returning null drops the destination while keeping the text.

The image above is written with a relative path, the way a README in a repository writes one. An absolute link is left alone.

The image above is written with a relative path, the way a README in a repository writes one. An absolute link is left alone.
Localization
UseTexts() replaces them. They belong to the pipeline
because a rendered document has no other place to learn what language it is in - so the same
BitMarkdownTexts travels with the flavors, and the numbered ones take their number
through {0}.
Playground
Basic (CommonMark only),
GitHub (plus the GitHub flavors) and Advanced (plus emoji and heading ids). Re-parsing only happens when an input that affects the output actually changes.
BitMarkdownViewer
A native Blazor Markdown viewer written in pure C# - no JavaScript,
no innerHTML, and no external dependencies zero external dependencies.
Why it exists
Most Blazor Markdown components wrap a JavaScript library and marshal strings across the interop boundary. This one parses Markdown into an AST and renders it straight to the Blazor render tree, so the output is real DOM.
Feature highlights
- Headings (ATX
#and Setext) - Bold, italic, bold italic, and
strikethrough - H2O, x2, inserted and highlighted (the emphasis extras)
inline codeand fenced code blocks- Links and images
- Ordered and unordered lists, including nesting:
- First item
- Second item
- nested bullet
- another one
- Third item
- GitHub-style task lists:
- Parse blocks
- Parse inlines
- Conquer the world
Code
Inline: var viewer = new BitMarkdownViewer();
public static BitMarkdownDocumentNode Parse(string? markdown)
{
var document = new BitMarkdownDocumentNode();
if (string.IsNullOrEmpty(markdown))
return document;
return document;
}Alerts
Tip
Switch the Flavor above to Basic and watch this become an ordinary block quote.
Blockquotes
"Any sufficiently advanced technology is indistinguishable from magic."
- Arthur C. Clarke
Tables
| Feature | Supported | Notes |
|---|---|---|
| Headings | Yes | Levels 1-6 |
| Tables | Yes | With column alignment |
| Task lists | Yes | GitHub flavoured |
| Raw HTML | No | Escaped for safety |
Links and notes
Reference links keep the prose clean1: see the bit platform site.
Safety
Link and image URLs are sanitized, so javascript: URIs are stripped and raw
HTML in the source is rendered as text rather than executed.
Plugins (try the Flavor switch above)
With the Advanced flavor you also get emoji and autolinks:
- Emoji shortcodes: 🚀 ✨ 🎉 🔥 👍
- Bare URLs become links: https://learn.microsoft.com
- Email autolinks: [email protected]
- Character references: © 2026 — decoded everywhere but in
code
Switch to Basic to see the same source rendered as plain CommonMark.
Made with C# and the Blazor render tree.
The destination is declared once, at the bottom, instead of interrupting the sentence. ↩︎
Style & Class
Style and Class to style the wrapper the document is rendered into. Because
the output is real DOM, the elements inside it are styled with ordinary CSS descendant rules - no
::ng-deep-style escape hatch and no innerHTML blob to work around.
A styled viewer, set apart with an inline Style.
A classy viewer
Every code span and heading inside it is restyled from the page's own stylesheet.
RTL
Dir="BitDir.Rtl" to render a right-to-left document. The stylesheet is written with
logical properties throughout, so block-quote bars, list indentation and table alignment all flip with
the direction instead of staying pinned to the left.
نمایشگر مارکداون
متن درشت و مورب در کنار کد درونخطی.
Note
نوار رنگی این کادر با جهت متن جابهجا میشود.
- مورد اول
- مورد دوم
- مورد تودرتو
| ستون | مقدار |
|---|---|
| یک | ۱ |
| دو | ۲ |
API
Every parameter, public member, sub-class and enum this component exposes.
BitMarkdownViewer parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| Markdown | string? | null | The Markdown string value to render as html elements. |
| Pipeline | BitMarkdownPipeline? | null | The processing pipeline (flavor set). Defaults to the basic CommonMark core with no extensions. Use one of the ready-made pipelines on BitMarkdownPipelines (Basic, GitHub, Advanced) or build a custom one with BitMarkdownPipelineBuilder. |
| ImageRendering | BitMarkdownViewerImageRendering | BitMarkdownViewerImageRendering.SameOrigin | Controls whether remote images are allowed to load, guarding against silent data-exfiltration via auto-fetched image URLs (for example ). Defaults to the safe SameOrigin policy; set it to All to load every remote image when the source is fully trusted, or None for the strictest policy. |
| Inline | bool | false | Renders the document as inline content: the root element becomes a span and each top-level paragraph contributes its inline content directly, without the <p> that would otherwise force a line of its own. Use it where a short piece of Markdown has to sit inside a sentence, a table cell or a label. Blocks that are not paragraphs (lists, tables, headings) still render as themselves. |
| MaxNestingDepth | int | 100 | The maximum block/inline nesting depth allowed while parsing. Content nested deeper than this is rendered as plain text instead of being parsed further. An always-on safeguard against denial-of-service via pathologically nested input (e.g. thousands of nested blockquotes) that would otherwise overflow the stack. Values <= 0 fall back to the default. Legitimate documents never approach this limit. |
| MaxLength | int | 0 | When greater than zero, the Markdown source is truncated to this many characters before parsing, bounding the work done on untrusted input. The cut never splits a surrogate pair. Defaults to 0 (no limit). |
| OnParsed | EventCallback<BitMarkdownDocumentNode> | Called after the Markdown source has been parsed, with the document that is about to be rendered. The tree is the same one the renderer walks, so a handler can read it - to build a table of contents from the headings, for example - or rewrite it before it reaches the DOM. | |
| CodeBlockTemplate | RenderFragment<BitMarkdownCodeBlockNode>? | null | Renders every fenced or indented code block, instead of the <pre><code> the viewer would otherwise draw. This is where a syntax highlighter, a copy button or a diagram renderer goes: the template is given the block, so it can read the language off Info and the source off Content. |
| ImageTemplate | RenderFragment<BitMarkdownImageNode>? | null | Renders every image, instead of the <img> the viewer would otherwise draw - for a lightbox, a placeholder while it loads, or a component that serves a modern format. The ImageRendering policy has already been applied, so a blocked image reaches the template with an empty Url. |
| LinkTemplate | RenderFragment<BitMarkdownLinkNode>? | null | Renders every link, instead of the <a> the viewer would otherwise draw - to route an in-app destination through the router, or to decorate an external one. The destination has already been sanitized. A link's own content is not rendered for you; read BitMarkdownInlineHelpers.PlainText(context.Children) for its text. |
| OnTaskChanged | EventCallback<BitMarkdownViewerTaskChangedEventArgs> | Called when a reader ticks or unticks a task-list checkbox, with the source rewritten to match. Setting it is what makes the checkboxes interactive at all: with no handler they stay the read-only boxes GitHub renders. The viewer does not change Markdown itself - it hands you the new source and leaves storing it to you. Requires the task-list flavor. | |
| StripBidiControlCharacters | bool | false | When true, Unicode bidirectional control characters are stripped from the source before parsing, neutralizing 'Trojan Source' (CVE-2021-42574) spoofing where text is made to display in a different order than it is encoded. Recommended for untrusted or AI-generated Markdown. Zero-width joiners used by emoji and complex scripts are never removed. |
BitMarkdownViewer public members
| Name | Type | Default value | Description |
|---|---|---|---|
| Document | BitMarkdownDocumentNode | The most recently parsed document. Useful for reading structure out of the source (headings, links, images) without parsing it a second time. |
BitComponentBase parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AriaLabel | string? | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | string? | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | BitDir? | null | Gets or sets the text directionality for the component's content. |
| ForceAnimation | bool | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | Dictionary<string, object> | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. |
| Id | string? | null | Gets or sets the unique identifier for the component's root element. |
| IsEnabled | bool | true | Gets or sets a value indicating whether the component is enabled and can respond to user interaction. |
| Style | string? | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | string? | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | BitVisibility | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
BitComponentBase public members
| Name | Type | Default value | Description |
|---|---|---|---|
| UniqueId | Guid | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | ElementReference | Gets the reference to the root HTML element associated with this component. |
BitMarkdownPipelines properties
The ready-made, cached pipelines. Each is built once and shared, so passing one costs nothing per render.
| Name | Type | Default value | Description |
|---|---|---|---|
| Basic | static BitMarkdownPipeline | The basic CommonMark core only: headings, emphasis, links, images, lists, block quotes, code, link reference definitions and character references. | |
| GitHub | static BitMarkdownPipeline | The GitHub flavors: pipe tables, strikethrough, task lists, autolink literals, footnotes and alerts, on top of the core. | |
| Advanced | static BitMarkdownPipeline | The GitHub flavors plus front matter, the emphasis extras, containers, definition lists, abbreviations, figures, :shortcode: emoji and automatic heading ids. |
BitMarkdownPipelineBuilder properties
Composes a pipeline from the flavors you want. A freshly created builder holds only the CommonMark core; each Use... call adds one extension, and Build() produces the immutable pipeline. The same extension is only applied once.
| Name | Type | Default value | Description |
|---|---|---|---|
| UsePipeTables | BitMarkdownPipelineBuilder UsePipeTables() | Adds GitHub-style pipe tables with per-column alignment. | |
| UseStrikethrough | BitMarkdownPipelineBuilder UseStrikethrough() | Adds ~~strikethrough~~. | |
| UseTaskLists | BitMarkdownPipelineBuilder UseTaskLists() | Adds GitHub task lists (- [ ] / - [x]). | |
| UseAutoLinks | BitMarkdownPipelineBuilder UseAutoLinks() | Adds autolink literals, so bare URLs and email addresses become links. | |
| UseEmojis | BitMarkdownPipelineBuilder UseEmojis() | Adds :shortcode: emoji replacement, using the built-in map. | |
| UseEmojis | BitMarkdownPipelineBuilder UseEmojis(IReadOnlyDictionary<string, string> overrides) | Adds :shortcode: emoji replacement, extending the built-in map with per-pipeline overrides. An override replaces the built-in shortcode of the same name. | |
| UseAutoIdentifiers | BitMarkdownPipelineBuilder UseAutoIdentifiers() | Gives every heading a unique, URL-friendly id slug so it can be deep-linked. | |
| UseEmphasisExtras | BitMarkdownPipelineBuilder UseEmphasisExtras() | Adds the emphasis flavors beyond * , _ and ~~ : ~subscript~, ^superscript^, ++inserted++ and ==highlighted==, rendered as <sub>, <sup>, <ins> and <mark>. Implies strikethrough, because subscript shares the ~ character with it. | |
| UseContainers | BitMarkdownPipelineBuilder UseContainers() | Adds custom containers: ':::name optional title' ... ':::' renders as a div classed after the name, which is how documentation sites write admonitions and layout blocks. Containers nest, and the name 'details' renders a real <details> with the title as its <summary>. | |
| UseDefinitionLists | BitMarkdownPipelineBuilder UseDefinitionLists() | Adds definition lists: a term on its own line followed by ': its definition' renders as a real <dl> of <dt> and <dd>. | |
| UseAbbreviations | BitMarkdownPipelineBuilder UseAbbreviations() | Adds abbreviations: '*[HTML]: HyperText Markup Language' declares a term once and every whole-word occurrence of it becomes an <abbr> carrying the expansion. | |
| UseMathematics | BitMarkdownPipelineBuilder UseMathematics() | Adds mathematics: $inline$ and $$display$$ are kept verbatim - safe from Markdown's own emphasis and escape rules - and marked as span.math-inline / div.math-display for a client-side typesetter such as KaTeX or MathJax. | |
| UseFigures | BitMarkdownPipelineBuilder UseFigures() | Adds figures: an image alone in a paragraph and written with a title renders as a <figure> with that title as its <figcaption>. | |
| UseFrontMatter | BitMarkdownPipelineBuilder UseFrontMatter() | Adds YAML (---) and TOML (+++) front matter, so a metadata block at the top of the document is parsed into a BitMarkdownFrontMatterNode that renders nothing instead of showing up as a thematic break and a heading. | |
| UseSmartyPants | BitMarkdownPipelineBuilder UseSmartyPants() | Adds typographic replacement: curly quotes, en and em dashes, ellipses and guillemets. Code spans, code blocks and URLs keep every character as written. | |
| UseAutoIdentifiers | BitMarkdownPipelineBuilder UseAutoIdentifiers(bool anchorLinks) | Gives every heading a unique, URL-friendly id slug so it can be deep-linked, and - when anchorLinks is true - appends a permalink to each heading. A heading may also name its own id by ending with {#the-id}, which is removed from the rendered text. | |
| UseFootnotes | BitMarkdownPipelineBuilder UseFootnotes() | Adds GitHub-style footnotes: a [^label] reference plus a [^label]: definition. Included in the GitHub bundle, because a footnote definition is also a valid link reference definition. | |
| UseAlerts | BitMarkdownPipelineBuilder UseAlerts() | Adds GitHub alerts: > [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING] and > [!CAUTION] block quotes render as titled callouts. | |
| UseTexts | BitMarkdownPipelineBuilder UseTexts(BitMarkdownTexts texts) | Sets the words the renderers write themselves - alert titles, footnote back-links, the accessible names of the regions and controls the markup adds - so a rendered document can be in a language other than English. | |
| UseUrlRewriter | BitMarkdownPipelineBuilder UseUrlRewriter(Func<BitMarkdownUrlRewriteContext, string?> rewrite) | Rewrites every link and image destination through a function of your own. The result is sanitized again on the way out, so a rewriter can never reintroduce an unsafe destination; returning null drops the destination and keeps the text. | |
| UseBaseUrl | BitMarkdownPipelineBuilder UseBaseUrl(string baseUrl) | Resolves every relative link and image destination against baseUrl - what a README needs before it can be rendered anywhere but the repository it came from. Absolute destinations and in-page fragments are left alone. | |
| UseLinkOptions | BitMarkdownPipelineBuilder UseLinkOptions(BitMarkdownLinkTarget externalTarget, string? externalRel, BitMarkdownLinkTarget internalTarget, string? internalRel) | Chooses the target and rel a rendered link carries, replacing the defaults (external links open in a new tab with 'noopener noreferrer'). Pass 'noopener noreferrer nofollow ugc' for links a site's own readers wrote. | |
| UseSoftLineAsHardLine | BitMarkdownPipelineBuilder UseSoftLineAsHardLine() | Renders every single newline as a line break, the way a chat or comment box does. | |
| UseGitHubFlavored | BitMarkdownPipelineBuilder UseGitHubFlavored() | Adds the full GitHub bundle: pipe tables, strikethrough, task lists, autolinks, footnotes and alerts. | |
| UseAdvanced | BitMarkdownPipelineBuilder UseAdvanced() | Adds the GitHub flavors plus front matter, the emphasis extras, containers, definition lists, abbreviations, figures, emoji and auto-identifiers. | |
| Use | BitMarkdownPipelineBuilder Use(IBitMarkdownExtension extension) | Adds a custom extension. An extension registers block parsers, inline parsers, delimiter processors, AST processors and/or renderers; everything it registers must be stateless, since a built pipeline is shared across concurrent parses. | |
| Build | BitMarkdownPipeline Build() | Builds the immutable, reusable pipeline. |
BitMarkdownPipeline properties
An immutable, reusable Markdown processing configuration produced by a BitMarkdownPipelineBuilder. Pipelines are thread-safe and should be cached and shared rather than rebuilt per render.
| Name | Type | Default value | Description |
|---|---|---|---|
| Parse | BitMarkdownDocumentNode Parse(string? markdown) | Parses Markdown source into an AST, applying all AST processors. | |
| CreateRenderer | BitMarkdownRenderer CreateRenderer() | Creates a renderer bound to this pipeline's node renderers. |
BitMarkdownDocumentNode properties
The root of a parsed Markdown document. Inherits from BitMarkdownNode.
| Name | Type | Default value | Description |
|---|---|---|---|
| Children | List<BitMarkdownNode> | [] | The top-level child nodes of the document. |
| ChildNodes | IList<BitMarkdownNode> | The node's single child collection (returns Children). |
BitMarkdownNode properties
The abstract base type for every node produced by the parser. Nodes expose their mutable child collections so that AST processors (plugins) can traverse and rewrite the tree generically, even for node types they did not define. BitMarkdownAstHelper.Descendants(node) walks the whole tree iteratively, so even pathologically nested documents cannot overflow the stack.
| Name | Type | Default value | Description |
|---|---|---|---|
| ChildNodes | virtual IList<BitMarkdownNode>? | null | The node's single child collection, if it has exactly one. Container nodes override this; leaf nodes return null. |
| ChildLists | virtual IEnumerable<IList<BitMarkdownNode>> | All mutable child collections owned by this node. Defaults to the single ChildNodes collection; nodes with several (e.g. a table's cells) override this to expose each one. |
BitMarkdownFrontMatterNode properties
The metadata block a document may open with, fenced by --- (YAML) or +++ (TOML). It describes the file rather than belonging to it, so it renders nothing and is read back off the AST. Requires the front matter flavor; without it a leading --- is ordinary Markdown.
| Name | Type | Default value | Description |
|---|---|---|---|
| Fence | string | --- | The fence that opened the block, either --- or +++. |
| Text | string | The raw text between the fences, with the line endings normalized to . Hand it to whichever serializer you already use. | |
| IsToml | bool | false | True when the block was fenced with +++, i.e. TOML rather than YAML. |
| Find | static BitMarkdownFrontMatterNode? Find(BitMarkdownDocumentNode document) | Returns the document's front matter block, or null when it has none. |
BitMarkdownViewerTaskChangedEventArgs properties
What the viewer reports when a reader ticks or unticks a task-list checkbox.
| Name | Type | Default value | Description |
|---|---|---|---|
| Index | int | 0 | The checkbox's position in the document, counted from 0 in reading order. |
| Checked | bool | false | Its new state. |
| Markdown | string | The source with that one marker rewritten, ready to be stored. Produced by BitMarkdownTaskList.Toggle, which counts the same markers the viewer drew and skips any inside code blocks. |
BitMarkdownUrlRewriteContext properties
What a URL rewriter is told about the destination it is being asked to rewrite.
| Name | Type | Default value | Description |
|---|---|---|---|
| Url | string | The sanitized destination, exactly as it would otherwise be rendered. | |
| IsImage | bool | false | True for an image source, false for a link destination. |
| IsRelative | bool | false | True when the URL has no scheme and does not begin with '//'. An in-page fragment (#section) is not relative in this sense, since resolving it elsewhere would break every heading link in the document. |
BitMarkdownTexts properties
The words the renderers write into a document themselves, rather than taking them from the source. All strings default to English. The numbered ones take their number through {0}; FootnoteBackReferenceOccurrence takes the footnote's number and the citation's through {0} and {1}.
| Name | Type | Default value | Description |
|---|---|---|---|
| AlertNote | string | Note | The title of a > [!NOTE] alert. |
| AlertTip | string | Tip | The title of a > [!TIP] alert. |
| AlertImportant | string | Important | The title of a > [!IMPORTANT] alert. |
| AlertWarning | string | Warning | The title of a > [!WARNING] alert. |
| AlertCaution | string | Caution | The title of a > [!CAUTION] alert. |
| Footnotes | string | Footnotes | The accessible name of the footnotes section. |
| FootnoteBackReference | string | Back to reference {0} | The accessible name of a footnote's back-link, given the footnote's number. |
| FootnoteBackReferenceOccurrence | string | Back to reference {0}-{1} | The accessible name of one of several back-links on the same footnote, given the footnote's number and the citation's. |
| Table | string | Table | The accessible name of the scrollable region a table sits in. |
| PermalinkTo | string | Permalink to {0} | The accessible name of a heading's permalink, given the heading's text. |
| PermalinkToSection | string | Permalink to this section | The accessible name of a permalink whose heading has no text of its own. |
| Task | string | Task {0} | The accessible name of an interactive task-list checkbox, given its number. |
BitMarkdownAstHelper properties
Helpers for reading and rewriting a parsed document. Every walk here is iterative, so even a pathologically nested document cannot overflow the stack.
| Name | Type | Default value | Description |
|---|---|---|---|
| Descendants | static IEnumerable<BitMarkdownNode> Descendants(BitMarkdownNode node) | Enumerates every node in the tree, in document order, excluding the root. | |
| VisitChildLists | static void VisitChildLists(BitMarkdownNode node, Action<IList<BitMarkdownNode>> action) | Invokes the action for every child collection in the tree, depth-first. The action may add, remove or replace entries in place, which is how an AST processor rewrites the tree. | |
| ToPlainText | static string ToPlainText(BitMarkdownNode node) | Renders the subtree as plain text: what the document says, with none of the markup it says it with and none of the link destinations. Blocks are separated by a blank line. This is the text a search index, an excerpt or a meta description is built from. |
BitMarkdownRenderer properties
Walks an AST and dispatches each node to a matching node renderer. Renderers are probed in reverse registration order, so the last renderer registered for a node type wins, allowing pipeline extensions to override the core renderers.
| Name | Type | Default value | Description |
|---|---|---|---|
| WriteNodes | void WriteNodes(RenderTreeBuilder builder, IEnumerable<BitMarkdownNode> nodes) | Renders a sequence of nodes. | |
| WriteNode | void WriteNode(RenderTreeBuilder builder, BitMarkdownNode node) | Renders a single node using the matching renderer (last registered wins). |
BitMarkdownViewerImageRendering enum
| Name | Value | Description |
|---|---|---|
| All | 0 | All images are rendered and loaded automatically, including remote ones. Suitable only when the Markdown source is fully trusted. |
| SameOrigin | 1 | Only same-origin images (relative paths, anchors, same-document references and embedded data: images) are loaded. Cross-origin images (http:, https: and protocol-relative //) are blocked. The recommended mode for untrusted or AI-generated Markdown. |
| None | 2 | No image is allowed to load; every image source is stripped and only the alt text remains. The strictest option. |
BitMarkdownLinkTarget enum
| Name | Value | Description |
|---|---|---|
| Self | 0 | No target at all: the link opens in the same browsing context. |
| Blank | 1 | Opens in a new tab or window (_blank). |
| Parent | 2 | Opens in the parent browsing context (_parent). |
| Top | 3 | Opens in the topmost browsing context (_top). |
BitMarkdownAlertKind enum
| Name | Value | Description |
|---|---|---|
| Note | 0 | Useful information the reader should notice even when skimming. |
| Tip | 1 | Optional advice for doing something better. |
| Important | 2 | Key information the reader needs to succeed. |
| Warning | 3 | Urgent information that needs immediate attention to avoid a problem. |
| Caution | 4 | Advice about the risks or negative outcomes of an action. |
BitVisibility enum
| Name | Value | Description |
|---|---|---|
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
BitDir enum
| Name | Value | Description |
|---|---|---|
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.