S97SP.Prism.Blazor
1.0.3
See the version list below for details.
dotnet add package S97SP.Prism.Blazor --version 1.0.3
NuGet\Install-Package S97SP.Prism.Blazor -Version 1.0.3
<PackageReference Include="S97SP.Prism.Blazor" Version="1.0.3" />
<PackageVersion Include="S97SP.Prism.Blazor" Version="1.0.3" />
<PackageReference Include="S97SP.Prism.Blazor" />
paket add S97SP.Prism.Blazor --version 1.0.3
#r "nuget: S97SP.Prism.Blazor, 1.0.3"
#:package S97SP.Prism.Blazor@1.0.3
#addin nuget:?package=S97SP.Prism.Blazor&version=1.0.3
#tool nuget:?package=S97SP.Prism.Blazor&version=1.0.3
Prism.Blazor
Prism.Blazor is a lightweight, extensible, and Blazor-native component for client-side syntax highlighting. It leverages regular expressions to tokenize code and applies CSS classes or inline styles for theming, bringing Prism.js-like capabilities directly into the .NET Blazor ecosystem without JavaScript interop for the core highlighting logic.
Table of Contents
- Why Prism.Blazor?
- Features
- Getting Started
- Usage
- Styling the Output
- Advanced Customization
- Building from Source
- Contributing
- License
- Acknowledgements
Why Prism.Blazor?
- Blazor Native: Pure .NET and Blazor implementation. No JavaScript interop for the core highlighting engine means a smaller deployment size (if you're avoiding JS elsewhere) and a development experience that stays within the C#/Razor paradigm.
- Lightweight: Designed to be lean and efficient for Blazor WebAssembly and Blazor Server applications.
- Extensible: Easily define new language syntaxes or extend existing ones using C#.
- Control & Simplicity: Offers a straightforward approach to syntax highlighting for developers already comfortable with .NET.
Features
- Client-Side Highlighting: Processes and renders highlighted code directly in the browser.
- Regex-Based Tokenization: Uses regular expressions for flexible and powerful language parsing.
- CSS Theming: Prioritizes CSS classes for styling, allowing for easy customization and theme creation. Inline styles are also supported.
- Preset Languages: Includes a growing set of common language definitions out-of-the-box.
- Configurable Messages: Customize loading and error messages displayed by the component.
- Asynchronous Processing: Highlighting is performed asynchronously to prevent UI blocking.
Getting Started
Installation
Prism.Blazor is distributed as a NuGet package. You can install it using the .NET CLI or the NuGet Package Manager in Visual Studio.
.NET CLI:
dotnet add package Prism.Blazor
Package Manager Console:
Install-Package Prism.Blazor
Importing
To make the CodeHighlighter component and its related types easily accessible in your Razor files, add the following using statements to your project's _Imports.razor file:
// File: _Imports.razor
@using Prism.Blazor
@using Prism.Blazor.PresetDefinitions
Usage
Basic Highlighting
The core of Prism.Blazor is the CodeHighlighter component. To use it, provide your code Content and a LanguageDefinition.
@page "/code-example"
<h3>C# Code Highlighting</h3>
<CodeHighlighter Content="@csharpCode"
LanguageDefinition="@(new CSharpLanguageDefinition())" />
@code {
private string csharpCode = """
// Example C# Code
public class Greeter
{
public string? Name { get; set; }
public void SayHello()
{
Console.WriteLine($"Hello, {Name ?? "World"}!");
}
}
""";
}
Component Parameters
The CodeHighlighter component accepts the following parameters:
Content(string?): The code string to be highlighted.LanguageDefinition(ILanguageDefinition?): An instance of a language definition (e.g.,new CSharpLanguageDefinition()).LoadingMessage(string, default: "Processing code..."): Text displayed while highlighting is in progress.ErrorMessage(string, default: "Error highlighting code."): Text displayed if an error occurs during highlighting.
Available Language Definitions
Prism.Blazor comes with several preset language definitions:
CSharpLanguageDefinitionCssLanguageDefinitionJavaScriptLanguageDefinitionJsxLanguageDefinitionRazorLanguageDefinitionSqlLanguageDefinitionTypeScriptLanguageDefinitionTsxLanguageDefinitionXmlLanguageDefinitionPlainTextLanguageDefinition: Renders the input text HTML-encoded without applying any syntax highlighting. Useful for displaying plain text snippets safely.
Styling the Output
HTML Structure
The CodeHighlighter component renders the highlighted code within the following HTML structure:
<pre class="code-highlighter-pre">
<code class="code-highlighter-code language-{name}">
<span class="{tokenCssClass}" style="{tokenInlineStyle}">...</span>
</code>
</pre>
- The
language-{name}class on the<code>element is derived from theNameproperty of yourILanguageDefinition(e.g.,language-csharp). - Each recognized token is wrapped in a
<span>.
Styling with CSS Classes
This is the recommended approach for styling. Each TokenRule in a language definition can specify a CssClass. This class will be applied to the <span> elements wrapping the matched tokens.
Define your styles: Add CSS rules to your application's stylesheet (e.g.,
app.cssor a component-specific CSS file). TheCodeHighlighter.razor.cssfile included in the library provides base styles for the<pre>and<code>elements. You'll need to add styles for the tokens themselves./* Base styles (from CodeHighlighter.razor.css or your global styles) */ .code-highlighter-pre { background-color: #2d2d2d; /* Example: Dark background */ color: #cccccc; /* Example: Light default text */ padding: 1em; overflow-x: auto; border-radius: 0.3em; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 0.9em; line-height: 1.5; border: 1px solid #444; } .code-highlighter-code { white-space: pre; } .code-highlighter-loading { padding: 1em; font-style: italic; color: #888; } /* Token-specific styles (you define these based on your language definitions) */ /* For CSharpLanguageDefinition examples: */ .code-highlighter-code .keyword { color: #569cd6; font-weight: bold; } .code-highlighter-code .type { color: #4ec9b0; } .code-highlighter-code .string { color: #ce9178; } .code-highlighter-code .comment { color: #6a9955; font-style: italic; } .code-highlighter-code .number { color: #b5cea8; } .code-highlighter-code .preprocessor { color: #bbb529; } .code-highlighter-code .punctuation { color: #d4d4d4; } .code-highlighter-code .identifier.method { color: #ffc66d; } /* For CSSLanguageDefinition examples: */ .code-highlighter-code.language-css .property-name { color: #9cdcfe; } .code-highlighter-code.language-css .keyword.value { color: #569cd6; } .code-highlighter-code.language-css .selector.id { color: #569cd6; } .code-highlighter-code.language-css .selector.class { color: #4ec9b0; } /* Add more rules for other languages and token types */Note: The
CssClassprovided inTokenRule(e.g.,"keyword","comment") is directly used. The examples above assume you're using simple class names. If yourTokenRulespecifiescssClass: "token my-custom-keyword", then your CSS selector would be.code-highlighter-code .token.my-custom-keyword. The preset definitions generally use simple class names like "keyword", "string", etc.Ensure styles are loaded: Make sure your Blazor application loads these CSS files.
Using Inline Styles
Alternatively, a TokenRule can specify an InlineStyle string (e.g., "color: #569cd6; font-weight: bold;"). This style will be directly applied to the style attribute of the <span> element. This approach is less flexible for theming and generally not recommended over CSS classes.
Advanced Customization
Creating Custom Language Definitions
To highlight a language not included in the presets, or to modify existing behavior, implement the ILanguageDefinition interface:
Create a class that implements
ILanguageDefinition:// File: MyLangDefinition.cs using Prism.Blazor; using System.Collections.Generic; using System.Text.RegularExpressions; public class MyLangDefinition : ILanguageDefinition { public string Name => "MyLang"; // Used for the CSS class `language-mylang` // Define styles or CSS class names private const string SpecialKeywordClass = "mylang-special-keyword"; private const string OperatorStyle = "color: #FF8C00;"; // DarkOrange // Define token rules private static readonly List<TokenRule> Rules = [ // Rule: Match "BEGIN" or "END" as special keywords // Priority 10, uses a CSS class new TokenRule(@"\b(BEGIN|END)\b", 10, SpecialKeywordClass, null), // Rule: Match "=>" or "->" as operators // Priority 5, uses an inline style new TokenRule(@"(=>|->)", 5, null, OperatorStyle), // Add more rules for comments, strings, numbers, etc. ]; public IEnumerable<TokenRule> GetRules() => Rules; }Use your custom definition:
<CodeHighlighter Content="@myCustomLangCode" LanguageDefinition="@(new MyLangDefinition())" /> @code { private string myCustomLangCode = "BEGIN some process => result END"; }Remember to add CSS for
.mylang-special-keywordif you use CSS classes.
Understanding TokenRule Logic
The heart of the highlighting process lies in TokenRule objects and how they are processed. Each TokenRule defines:
Regex: ASystem.Text.RegularExpressions.Regexobject for matching a token. TheRegexOptions.Compiledflag is automatically added.Priority(int): A number indicating the rule's importance. Higher numbers mean higher priority.CssClass(string?): CSS class(es) to apply if this rule matches.InlineStyle(string?): Inline style string to apply if this rule matches.
Matching and Conflict Resolution:
When highlighting text, Prism.Blazor performs the following steps:
- Collect All Matches: It iterates through all
TokenRules in the language definition and finds all possible matches in the input string. - Sort Matches: All found matches are then sorted according to these criteria, in order:
- Start Index (Ascending): Matches occurring earlier in the text come first.
- Priority (Descending): If multiple matches start at the same index, the one from a
TokenRulewith a higherPriorityvalue is preferred. - Match Length (Descending): If start index and priority are also equal, the longer match is preferred.
- Select Non-Overlapping Matches: The component iterates through the sorted list of potential matches. It selects the first valid match and then discards any subsequent potential matches that overlap with the already selected one. It then continues this process from the end of the last selected match.
This mechanism ensures that more specific rules (e.g., a keyword "string") can take precedence over more general rules (e.g., a general identifier) if they have higher priority or produce a longer match at the same position.
Building from Source
If you wish to build the library from source:
- Clone the repository:
git clone https://github.com/lorenzodimauro97/Prism.Blazor.git cd Prism.Blazor - Build the solution:
The compiled library (dotnet build Prism.Blazor.sln -c Release.dll) will be in thePrism.Blazor/bin/Release/directory.
Contributing
Contributions are highly welcome! Whether it's bug reports, feature requests, documentation improvements, or new language definitions, please feel free to:
- Open an Issue: Discuss the change you wish to make or report a bug.
- Fork the Repository: Create your own copy.
- Create a Feature Branch: (
git checkout -b feature/AmazingFeature) - Commit your Changes: (
git commit -m 'Add some AmazingFeature') - Push to the Branch: (
git push origin feature/AmazingFeature) - Open a Pull Request: Target the
mainbranch of the original repository.
Please ensure your code adheres to the existing style and best practices.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Acknowledgements
- Inspired by the original Prism.js library.
- Color palettes for preset languages are inspired by themes from popular code editors like Visual Studio Code and Rider.
| 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
- Microsoft.AspNetCore.Components.Web (>= 9.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Initial release of Prism.Blazor.