BlakePlugin.DocsRenderer
1.0.15
dotnet add package BlakePlugin.DocsRenderer --version 1.0.15
NuGet\Install-Package BlakePlugin.DocsRenderer -Version 1.0.15
<PackageReference Include="BlakePlugin.DocsRenderer" Version="1.0.15" />
<PackageVersion Include="BlakePlugin.DocsRenderer" Version="1.0.15" />
<PackageReference Include="BlakePlugin.DocsRenderer" />
paket add BlakePlugin.DocsRenderer --version 1.0.15
#r "nuget: BlakePlugin.DocsRenderer, 1.0.15"
#:package BlakePlugin.DocsRenderer@1.0.15
#addin nuget:?package=BlakePlugin.DocsRenderer&version=1.0.15
#tool nuget:?package=BlakePlugin.DocsRenderer&version=1.0.15
BlakePlugin.DocsRenderer
A plugin for Blake that adds scrollspy, TOC navigation, and enhanced code syntax highlighting to your documentation sites.
Architecture Overview
BlakePlugin.DocsRenderer consists of two main components that work together to enhance your Blake static site:
Blake Plugin (IBlakePlugin
Implementation)
The core plugin that extends Blake's Markdown processing pipeline with two key extensions:
- Document Sectioning: Automatically splits documentation pages into sections based on headings, generating structured table of contents data and enabling in-page navigation with scrollspy functionality.
- Enhanced Prism.js Code Rendering: Replaces the default code block rendering with a feature-rich Prism.js implementation that supports line highlighting, diff visualization, line numbers, copy buttons, and 100+ programming languages.
Razor Components
Ready-to-use Blazor components that consume the data generated by the plugin:
- SiteToc: Site-wide table of contents navigation component
- PageToc: In-page table of contents with scrollspy highlighting and optional quick links
- PageTocMobile: Mobile-optimized version of PageToc with collapsible sections
You can use the Blake plugin independently without the Razor components by consuming the generated section data and building your own navigation components. The plugin injects a List<Section> _sections
variable into each page's @code
block that you can use in custom implementations.
Features
Document Navigation
- In-page navigation with scrollspy functionality
- Automatic document sectioning based on headings
- Site-wide table of contents generation
- Mobile-responsive navigation components
Enhanced Code Blocks
- 100+ programming languages supported via Prism.js
- Line highlighting - highlight specific lines or ranges using
marked
parameter - Diff visualization - show added/removed lines using
added
andremoved
parameters - Line numbers - automatic line numbering for better code reference
- Copy button - one-click code copying functionality
- Range support - specify multiple line ranges (e.g.,
1-5,10,15-20
)
Razor Components
- PageToc - In-page table of contents with QuickLinks support (desktop)
- PageTocMobile - Mobile-optimized collapsible version (no QuickLinks)
- SiteToc - Site-wide navigation component
- Customizable styling - Bootstrap-based with override capabilities
How it works
The Blake plugin integrates into Blake's Markdown processing pipeline using two custom Markdig extensions:
Document Sectioning Extension: Processes headings (
#
,##
,###
, etc.) to automatically create a hierarchical section structure. This data is serialized and injected into each page's@code
block as aList<Section> _sections
variable.Prism Extension: Replaces the default code block renderer with an enhanced version that:
- Supports 100+ programming languages
- Processes code block arguments for advanced features (line highlighting, diffing, etc.)
- Generates Prism.js-compatible HTML with appropriate CSS classes and data attributes
- Handles Razor code blocks specially to avoid compilation issues with
@
symbols
The included JavaScript (plugin.js
) provides scrollspy functionality that automatically highlights the current section in navigation components as users scroll through the page.
Installation
Add the package:
dotnet add package BlakePlugin.DocsRenderer
Import the necessary styles and scripts in your
index.html
, and initialise the DocsRenderer:<link rel="stylesheet" href="_content/BlakePlugin.DocsRenderer/lib/css/plugin.css" /> <script src="_content/BlakePlugin.DocsRenderer/lib/js/prism.js"></script> <script src="_content/BlakePlugin.DocsRenderer/lib/js/plugin.js"></script>
You will need to initialise the DocsRenderer plugin in order to use the components. The best place to do this is in your Blake template (i.e. template.razor
):
@inject IJSRuntime js
// ...
@code {
protected override async Task OnAfterRenderAsync(bool isFirstRender)
{
await base.OnAfterRenderAsync(isFirstRender);
if (isFirstRender)
{
await js.InvokeVoidAsync("initializeDocsPlugin");
}
}
}
This ensures that the plugin is ready to use when your pages are rendered. The initializeDocsPlugin
function is defined in the plugin.js
file included with the package.
Usage
Razor Setup
Once the plugin is installed, you can use the built-in Razor components to render both the site-wide and in-page table of contents.
Make sure to import the relevant namespaces at the top of your .razor
file:
@using BlakePlugin.DocsRenderer // Required for Section, note this is automatically added to generated pages
@using BlakePlugin.DocsRenderer.Components // Required for SiteToc and PageToc components
@using BlakePlugin.DocsRenderer.Utils // Required for TocNode and TocUtils
Content Setup
You don't need to do anything special to your Markdown files; the plugin will automatically process them. However, you should ensure that your documentation pages are structured with headings (e.g., #
, ##
, ###
) to enable sectioning and TOC generation.
Additionally, you can specify pageOrder: <order>
in your front matter to control the order of pages in the TOC. But you don't have to do this; the plugin will automatically order pages based on their filenames if pageOrder
is not specified.
Note: It actually sorts using the default directory sort order. This is usually alphabetically by filename, but it can be affected by the filesystem or other factors. If you need a specific order, use the
pageOrder
front matter field.
Razor Components
The plugin provides three main Razor components:
PageToc Component
Displays an in-page table of contents with scrollspy navigation:
<PageToc Sections="@_sections" QuickLinks="@myQuickLinks" />
Parameters:
Sections
(required):List<Section>
- The sections generated by the pluginQuickLinks
(optional):Dictionary<string, string>
- Additional links to display
Default QuickLinks:
QuickLinks = new Dictionary<string, string>
{
{ "GitHub Repository", "#" },
{ "Report Issue", "#" },
{ "Contribute", "#" },
{ "Changelog", "#" }
};
PageTocMobile Component
Mobile-optimized version with collapsible sections (no QuickLinks support):
<PageTocMobile Sections="@_sections" />
SiteToc Component
Site-wide navigation component:
<SiteToc Pages="@contentIndex" />
Using Components in Your Template
You can now use the components in your Razor pages or components, or template.razor
files:
@using BlakePlugin.DocsRenderer.Components
<div class="container-fluid">
<div class="row">
<div class="col-lg-3">
<SiteToc Pages="@contentIndex" />
</div>
<div class="col-lg-7">
</div>
<div class="col-lg-2">
<PageToc Sections="@_sections" />
<PageTocMobile Sections="@_sections" />
</div>
</div>
</div>
Generating TOC and Section Data
In your @code
block, you’ll typically initialise the site-wide table of contents like this:
@code {
private List<TocNode> contentIndex = TocUtils.BuildSiteTocNodes(GeneratedContentIndex.GetPages());
// This list of sections is automatically generated by the plugin
private List<Section> _sections = [
new Section { Text = "Introduction", Id = "introduction", Children = [ // ...] },
new Section { Text = "Getting Started", Id = "getting-started", Children = [] /*Empty in this case*/ },
// ...
];
}
The _sections
list is automatically injected by the plugin into the generated Razor page at build time, so you don't need to maintain it manually unless you’re testing or debugging. (Note the comments were added just for this example, they are not present in the actual code.)
Enhanced Code Blocks
The plugin provides powerful code syntax highlighting with advanced features through its custom Prism.js integration.
Supported Languages
Over 100 programming languages are supported, including popular ones like:
- Web:
html
,css
,javascript
,typescript
,jsx
,tsx
- .NET:
csharp
,fsharp
,vbnet
,razor
- Backend:
python
,java
,go
,rust
,cpp
,c
- DevOps:
bash
,powershell
,docker
,yaml
,json
- And many more:
sql
,markdown
,xml
,php
,ruby
,swift
,kotlin
, etc.
Line Highlighting
Highlight specific lines or ranges using the marked
parameter:
```csharp marked=2,5-7
public class Example
{
public string Name { get; set; } // This line is highlighted
public int Age { get; set; }
public void Method1() { // These lines are highlighted
Console.WriteLine("Hello"); // These lines are highlighted
} // These lines are highlighted
public void Method2() {
Console.WriteLine("World");
}
}
```
Diff Visualization
Show code changes using added
and removed
parameters:
```csharp added=2-3 removed=5-6
public class Example
{
+ public string FirstName { get; set; } // Added lines
+ public string LastName { get; set; } // Added lines
public int Age { get; set; }
- public string OldName { get; set; } // Removed lines
- public string OldAge { get; set; } // Removed lines
}
```
Range Syntax
All parameters support flexible range syntax:
- Single lines:
marked=3
- Ranges:
marked=2-5
- Multiple ranges:
marked=1-3,7,10-12
- Combined:
added=2-4 removed=6-8 marked=10
Additional Features
The plugin enables several additional Prism.js features by default:
- Line numbers: Automatic line numbering for better code reference
- Copy button: One-click copying of code blocks
- Language detection: Automatic file extension mapping
- Responsive design: Mobile-optimized code block display
Example with All Features
```typescript marked=3,8-10 added=12-14 removed=16-18
interface User {
id: number;
name: string; // Highlighted line
email: string;
}
class UserService {
private users: User[] = []; // Highlighted
private cache: Map<number, User> = new Map(); // Highlighted
private logger: Logger; // Highlighted
+ // New caching implementation
+ getCachedUser(id: number): User | undefined {
+ return this.cache.get(id);
+ }
- // Old implementation
- getUser(id: number): User {
- return this.users.find(u => u.id === id);
- }
}
```
Using the Plugin Without Razor Components
If you prefer to build your own navigation components, you can use the plugin's core functionality without the provided Razor components. The plugin will still:
- Generate section data: The
List<Section> _sections
variable is injected into every page - Process enhanced code blocks: All Prism.js enhancements will work
- Enable scrollspy: The JavaScript functionality is available
You can then build custom components that consume the _sections
data:
@foreach (var section in _sections)
{
<div class="my-custom-toc-item">
<a href="@($"#{section.Id}")">@section.Text</a>
@if (section.Children.Any())
{
<ul class="my-custom-subsections">
@foreach (var child in section.Children)
{
<li><a href="@($"#{child.Id}")">@child.Text</a></li>
}
</ul>
}
</div>
}
The plugin's JavaScript will still provide scrollspy functionality regardless of your component structure, as long as you use the generated Id
values in your anchor links.
Customisation
The provided Razor components use Bootstrap for styling, which was chosen because it's included by default in the Blazor WASM template. If you're not using Bootstrap or want different styling, you have several options:
Override styles: The components use specific CSS classes, so you can override the styles in your own CSS files without affecting functionality.
Copy and modify components: The included components are straightforward - you can copy the razor component code from this repository and replace the Bootstrap classes with your own styling framework or custom CSS.
Build custom components: Use the generated
_sections
data to create completely custom navigation components that fit your design requirements.
While the behaviour of the plugin is mostly fixed, you can use the generated data to drive your own components. Be careful of simply excluding the CSS include as it also has styling for code blocks and other elements that the plugin uses.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Blake.BuildTools (>= 1.0.22)
- Blazicons.Bootstrap (>= 2.3.40)
- Microsoft.AspNetCore.Components.Web (>= 9.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.0.15 | 112 | 9/4/2025 |
1.0.14 | 130 | 9/3/2025 |
1.0.13 | 138 | 8/10/2025 |
1.0.12 | 77 | 8/10/2025 |
1.0.11 | 110 | 8/9/2025 |
1.0.10 | 133 | 8/9/2025 |
1.0.9 | 213 | 8/7/2025 |
1.0.8 | 205 | 8/6/2025 |
1.0.7 | 206 | 8/6/2025 |
1.0.6 | 220 | 8/5/2025 |
1.0.5 | 216 | 8/5/2025 |
1.0.4 | 72 | 8/3/2025 |
1.0.0 | 42 | 8/2/2025 |
0.0.1-preview2 | 167 | 7/26/2025 |
0.0.1-preview1 | 412 | 7/25/2025 |