Using Markdown Extensions
MyLittleContentEngine uses Markdig for Markdown processing, which is a powerful and extensible Markdown parser for .NET. It supports a wide range of Markdown features and extensions, making it suitable for various content needs.
MyLittleContentEngine supports several Markdown extensions to enhance your content. These extensions provide additional
formatting options and features that aren't part of standard Markdig. These extensions merely generate HTML, so you'll
still need to style them with CSS to match your site's design. However, MyLittleContentEngine.MonorailCss
provides some
default values.
Default Markdig Pipeline
The default Markdig pipeline used by MyLittleContentEngine includes the following extensions:
public Func<IServiceProvider, MarkdownPipeline> MarkdownPipelineBuilder { get; init; } = serviceProvider =>
{
var syntaxHighlighter = serviceProvider.GetService<ISyntaxHighlightingService>();
var roslynHighlighterOptions = serviceProvider.GetService<CodeHighlighterOptions>();
var builder = new MarkdownPipelineBuilder()
.UseAutoIdentifiers(AutoIdentifierOptions.GitHub) // This sets up GitHub-style header IDs
.UseAlertBlocks()
.UseAbbreviations()
.UseCitations()
.UseCustomContainers()
.UseDefinitionLists()
.UseEmphasisExtras()
.UseFigures()
.UseFooters()
.UseFootnotes()
.UseGridTables()
.UseMathematics()
.UseMediaLinks()
.UsePipeTables()
.UseListExtras()
.UseTaskLists()
.UseAutoLinks()
.UseGenericAttributes()
.UseDiagrams()
.UseCustomAlertBlocks()
.UseCustomContainers()
.UseSyntaxHighlighting(syntaxHighlighter, roslynHighlighterOptions?.CodeHighlightRenderOptionsFactory)
.UseTabbedCodeBlocks(roslynHighlighterOptions?.TabbedCodeBlockRenderOptionsFactory)
.UseYamlFrontMatter();
// If the service provider has a component registry, enable Mdazor support
if (serviceProvider.GetService<IComponentRegistry>() != null)
builder = builder.UseMdazor(serviceProvider);
return builder.Build();
};
UseAutoIdentifiers(AutoIdentifierOptions.GitHub)
is critical for generating IDs for headers, which is necessary for
linking to specific sections of the content within the sidebar navigation.
Code Highlighting
MyLittleContentEngine will try to highlight code blocks based on the language specified in the opening code block server-side.
The following rules are followed:
- If Roslyn is connected and the code block is C# or VB.NET, then Roslyn's Microsoft.CodeAnalysis.Classification.Classifier will be used to highlight the code block. This ensures the latest language features are highlighted correctly.
- If the code block is bash or shell, a built-in highlighter will be used to highlight commands and their options.
- If the code block language is supported by TextMateSharp's Grammar package, then TextMateSharp will be used to highlight the code block. Current Grammars
- If those rules aren't met, then the code block will be rendered with the language set on the code block. Within the
MyLittleContentEngine.UI
scripts.js
file, ahighlightCode
function will be used to highlight the code block using Highlight.JS. This library will only be loaded if the code block isn't highlighted by the previous rules. This ensures that the page doesn't load unnecessary JavaScript.
See Syntax Highlighting System Architecture for more details.
Code Tabs
You can create tabbed content sections using the tabs
attribute on a code block. This allows you to organize content
into multiple tabs.
Place the tabs=true
attribute on the opening code block, and the subsequent code blocks will be treated as tab
content.
You can also specify titles for each tab by using the title
attribute.
```html tabs=true
<p>My Content</p>
```
```xml title="My XML Data"
<data>My Data</data>
```
This will render as:
<p>My Content</p>
<data>My Data</data>
Code blocks will be highlighted according to the rules mentioned above.
Code Transformations
MyLittleContentEngine supports Shiki-style code transformations that allow you to highlight specific lines, show differences, create focus effects, and add error/warning indicators to your code blocks. These transformations use special comment notations that are automatically processed and removed from the rendered output.
Line Highlighting
You can highlight specific lines in your code blocks by adding // [!code highlight]
or // [!code hl]
comments:
```javascript
function calculateSum(numbers) {
let total = 0; // [!code highlight]
for (const num of numbers) {
total += num;
}
return total; // [!code hl] return the total
}
```
This will render as:
function calculateSum(numbers) {
let total = 0
for (const num of numbers) {
total += num;
}
return total; // return the total
}
Diff Notation
Show additions and deletions in your code using // [!code ++]
for additions and // [!code --]
for deletions:
```javascript
function greetUser(name) {
console.log("Hello " + name); // [!code --]
console.log(`Hello ${name}!`); // [!code ++]
}
```
This will render as:
function greetUser(name) {
console.log("Hello " + name)
console.log(`Hello ${name}!`)
}
Error and Warning Indicators
Mark lines that contain errors or warnings using // [!code error]
and // [!code warning]
:
```javascript
function divide(a, b) {
if (b = 0) { // [!code error]
console.warn("Division by zero detected"); // [!code warning]
return null;
}
return a / b;
}
```
this will render as:
function divide(a, b) {
if (b = 0) {
console.warn("Division by zero detected")
return null;
}
return a / b;
}
Focus and Blur
Draw attention to specific lines by using // [!code focus]
. This will highlight the focused lines and dim all other lines:
```csharp
public async Task<User> GetUserAsync(int id)
{
return await _repository.FindByIdAsync(id); // [!code focus]
}
```
This will render as:
returnawait _repository.FindByIdAsync(id);
Word Highlighting
Highlight specific words or tokens within your code using // [!code word:wordToHighlight]
. You can also add tooltips with additional information using the pipe syntax:
```javascript
function processData(input) {
const result = transform(input); // [!code word:transform]
return result;
}
```
This will render as:
function processData(input) {
const result = transform(input)
return result;
}
Word Highlighting with Tooltips
Add helpful explanations using the pipe syntax // [!code word:word|explanation]
:
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IRepository, Repository>(); // [!code word:AddScoped|Registers service with scoped lifetime]
services.AddTransient<IValidator, Validator>();
}
```
This will render as:
public void ConfigureServices(IServiceCollection services)
{
services.<IRepository, Repository>();
services.AddTransient<IValidator, Validator>();
}
Tip
Note
Enhanced Alerts
The Markdig AlertBlock has been tweaked to play nicer with Monorail and Tailwind styling.
Note
> [!NOTE]
> Highlights information that users should take into account, even when skimming.
Note
Tip
> [!TIP]
> Optional information to help a user be more successful.
Tip
Important
> [!IMPORTANT]
> Crucial information necessary for users to succeed.
Important
Warning
> [!WARNING]
> Critical content demanding immediate user attention due to potential risks.
Warning
Caution
> [!CAUTION]
> Negative potential consequences of an action.
Caution
Mermaid Diagrams
MyLittleContentEngine supports Mermaid diagrams. If you are using MyLittleContentEngine.UI
, then
the scripts.js
file will automatically load the Mermaid library and render the diagrams with your current theme.
sequenceDiagram
participant Model
participant KV_Cache
Model->>Model: Process token 1
Model->>KV_Cache: Store K1, V1
Model->>Model: Process token 2
Model->>KV_Cache: Store K2, V2
LV->>KV_Cache: Retrieve K1–K2, V1–V2
Model->>Model: Generate token 3 using cache
Blazor within Markdown
Simple blazor components can be used within Markdown content, using the Mdazor library.
Mdazor is a custom Markdig extension that:
- Parses component tags - Recognizes
content syntax in your Markdown - Uses Blazor's HtmlRenderer - Actually renders real Blazor components server-side
- Handles nested content - Markdown inside components gets processed recursively
Steps Component
It includes a builtin Steps component that can be used to create a step-by-step guide.
To register the component, you need to add the following to your Program.cs
:
builder.Services.AddMdazor()
.AddMdazorComponent<Step>()
.AddMdazorComponent<Steps>();
Then you can use the component in your Markdown content like this:
## Here is some content that needs steps.
To do the action, follow these steps:
<Steps>
<Step stepNumber="1">
**The First Thing to Do**
This is the first step in the process.
It can contain any Markdown content, including **bold text**, *italic text*, and even code blocks.
```csharp
var i = 2+2;
```
</Step>
<Step stepNumber="2">
**The Second Thing to Do**
This is the second step in the process. For these two steps, the code is using
bold tags, but you can use Headers instead, and the links will still appear
in the sidebar.
</Step>
</Steps>
This will render as:
- 1
The First Thing to Do
This is the first step in the process.
It can contain any Markdown content, including bold text, italic text, and even code blocks.
var i = 2+2;
- 2
The Second Thing to Do
This is the second step in the process. For these two steps, the code is using bold tags, but you can use Headers instead, and the links will still appear in the sidebar.
Badges
- Note
- Success
- Tip
- Caution
- Danger
- New
- New and improved
- New, improved, and bigger
Card Components
MyLittleContentEngine.UI includes a set of card components that work together to create attractive content layouts. These components integrate seamlessly with Mdazor to provide flexible grid-based content organization.
To register the card components, add the following to your Program.cs
:
builder.Services.AddMdazor()
.AddMdazorComponent<CardGrid>()
.AddMdazorComponent<Card>()
.AddMdazorComponent<LinkCard>();
CardGrid Component
The CardGrid
component creates a responsive grid container for organizing cards. It automatically adjusts the number of columns based on screen size.
Parameters:
Columns
(string, default: "2") - Number of columns for the grid on larger screensChildContent
(RenderFragment) - The card content to display in the grid
Card Component
The Card
component creates a styled content card with optional icon and title.
Parameters:
Title
(string, optional) - The card title displayed prominently at the topColor
(string, default: "primary") - Color theme for the card stylingIcon
(RenderFragment, optional) - Icon content displayed next to the titleChildContent
(RenderFragment) - The main card content
LinkCard Component
The LinkCard
component extends the Card component by wrapping it in a clickable link.
Parameters:
Title
(string, optional) - The card title displayed prominently at the topHref
(string, optional) - The URL the card should link toColor
(string, default: "primary") - Color theme for the card stylingIcon
(RenderFragment, optional) - Icon content displayed next to the titleChildContent
(RenderFragment) - The main card content
Usage Example
Here's how to create a grid of link cards for navigation:
<CardGrid>
<LinkCard Title="Creating First Site" href="xref:docs.getting-started.creating-first-site">
<Icon>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="2em" height="2em" stroke="currentColor">
<path d="M8 4.5V3M16 4.5V3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
<path d="M8 11C8 9.58579 8 8.87868 8.43934 8.43934C8.87868 8 9.58579 8 11 8H13C14.4142 8 15.1213 8 15.5607 8.43934C16 8.87868 16 9.58579 16 11V13C16 14.4142 16 15.1213 15.5607 15.5607C15.1213 16 14.4142 16 13 16H11C9.58579 16 8.87868 16 8.43934 15.5607C8 15.1213 8 14.4142 8 13V11Z" stroke="currentColor" stroke-width="1.5"></path>
</svg>
</Icon>
Build a complete content site from scratch using MyLittleContentEngine
</LinkCard>
<LinkCard Title="Connecting to Roslyn" href="xref:docs.getting-started.connecting-to-roslyn" Color="secondary">
<Icon>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="2em" height="2em">
<path d="M4.51255 19.4866C7.02498 21.8794 10.016 20.9223 11.2124 19.9532" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path>
</svg>
</Icon>
Integrate Roslyn for enhanced code highlighting and documentation
</LinkCard>
</CardGrid>
You can also use the Card
component without links for static content displays:
<CardGrid Columns="3">
<Card Title="Feature One" Color="tertiary-one">
This card describes an important feature of your application.
</Card>
<Card Title="Feature Two" Color="tertiary-two">
Another key feature with different color styling.
</Card>
<Card Title="Feature Three" Color="yellow">
A card without an icon, showing just title and content.
</Card>
</CardGrid>
Feature One
This card describes an important feature of your application.
Feature Two
Another key feature with different color styling.
Feature Three
A card without an icon, showing just title and content.
Color Options
Both Card
and LinkCard
support color theming through the Color
parameter. The available colors depend on your CSS framework configuration, but common options include:
primary
(default) - Primary brand coloraccent
- Accent colorneutral
- Neutral gray tonestertiary-one
,tertiary-two
, etc. - Additional custom colors defined in your CSS
Responsive Behavior
The CardGrid
component automatically adjusts its layout:
- Mobile devices: Single column layout
- Tablets and larger: Uses the specified
Columns
value (default: 2)
This ensures your card layouts look great across all device sizes without requiring additional configuration.