This content has moved - please find it at https://devblog.cyotek.com.

Although these pages remain accessible, some content may not display correctly in future as the new blog evolves.

Visit https://devblog.cyotek.com.

kbd Markdig Plugin

A basic demonstration showing the output

I try to keep my markdown documents plain, avoiding HTML where possible. The core cyotek.com website is mostly powered by markdown, with embedded HTML and arcane constructs with assorted regular expression processors. The new blog uses pure markdown and although currently still uses an arcane construct or two for compatibility, these are provided via Markdig extensions rather than regular expressions.

However, one area I still keep writing HTML is for kbd tags, mostly in the documentation for our products but also in some blog articles. I finally decided to write another extension library to handle this and made it available for download.

The structure of this extension follows the same approach as in my original article on writing custom Markdig extensions, so I won't describe the code here.

Getting the library

The easiest way of obtaining the library is via NuGet.

Install-Package Cyotek.Markdig.Keyboard

Using the library

When you build your Markdig pipeline, call UseKeyboard(). Any text wrapped in double angled brackets will be converted to kbd tags.

_markdownPipeline = new MarkdownPipelineBuilder()
  .UseAdvancedExtensions()
  .UseKeyboard()
  .Build();

Options

There is also a KeyboardOptions class you can use to control the output. Currently it allows you either to assign a CSS class to generated elements via the ClassName property, or specify a different HTML tag via the TagName property.

_markdownPipeline = new MarkdownPipelineBuilder()
  .UseAdvancedExtensions()
  .UseKeyboard(new KeyboardOptions
  {
    ClassName = "my-class",
    TagName = "code"
  })
  .Build();

Examples

This first example uses default options, which output kbd tags with no further processing.

var markdownPipeline = new MarkdownPipelineBuilder()
  .UseAdvancedExtensions()
  .UseKeyboard()
  .Build();

var output = Markdown.ToHtml(@"### File Menu

| Description | Shortcut Keys |
| ----------- | ------------- |
| New         | <<Ctrl+N>>    |
| Open        | <<Ctrl+O>>    |
| Save        | <<Ctrl+S>>    |
| Save As     |               |
| Export      |               |
| Exit        | <<Alt+F4>>    |
", markdownPipeline);
<h3 id="file-menu">File Menu</h3>
<table>
  <thead>
    <tr>
      <th>Description</th>
      <th>Shortcut Keys</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>New</td>
      <td><kbd>Ctrl+N</kbd></td>
    </tr>
    <tr>
      <td>Open</td>
      <td><kbd>Ctrl+O</kbd></td>
    </tr>
    <tr>
      <td>Save</td>
      <td><kbd>Ctrl+S</kbd></td>
    </tr>
    <tr>
      <td>Save As</td>
      <td></td>
    </tr>
    <tr>
      <td>Export</td>
      <td></td>
    </tr>
    <tr>
      <td>Exit</td>
      <td><kbd>Alt+F4</kbd></td>
    </tr>
  </tbody>
</table>

This second example uses custom options to change the output tag to code and apply a custom class.

var markdownPipeline = new MarkdownPipelineBuilder()
  .UseAdvancedExtensions()
  .UseKeyboard(new KeyboardOptions
  {
    ClassName = "keyboard",
    TagName = "code"
  })
  .Build();

var output = Markdown.ToHtml("Press <<Alt+F4>> to exit.", markdownPipeline);
<p>Press <code class="keyboard">Alt+F4</code> to exit.</p>

Requirements

.NET Framework 3.5 or later.

Pre-built binaries are available via a signed NuGet package containing the following targets.

  • .NET 4.8
  • .NET Standard 2.0
  • .NET Standard 2.1
  • .NET Core 2.1
  • .NET Core 3.1
  • .NET 5.0

Source

Source code is available from the GitHub repository.

Implementation Note

The main library and the test library projects are in the SDK style. However, the WinForms demo is in the classic csproj format - originally it was SDK using .NET 5, but the WinForms designer in .NET 5 is shockingly bad. I had numerous issues with it, ranging from the designer frequently unable to load, event handlers getting unbound, and functionality like inline editing of MenuStrip controls just don't work at all.

In the end I converted it back to classic .NET as it is completely unusable in its current state, in my view.

License

This source is licensed under the MIT license. See LICENSE.txt for the full text.

Related articles you may be interested in

About The Author

Gravatar

The founder of Cyotek, Richard enjoys creating new blog content for the site. Much more though, he likes to develop programs, and can often found writing reams of code. A long term gamer, he has aspirations in one day creating an epic video game. Until that time, he is mostly content with adding new bugs to WebCopy and the other Cyotek products.

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?

Styling with Markdown is supported