Sai.MarkdownDocumentation 1.0.1

dotnet add package Sai.MarkdownDocumentation --version 1.0.1                
NuGet\Install-Package Sai.MarkdownDocumentation -Version 1.0.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Sai.MarkdownDocumentation" Version="1.0.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Sai.MarkdownDocumentation --version 1.0.1                
#r "nuget: Sai.MarkdownDocumentation, 1.0.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Sai.MarkdownDocumentation as a Cake Addin
#addin nuget:?package=Sai.MarkdownDocumentation&version=1.0.1

// Install Sai.MarkdownDocumentation as a Cake Tool
#tool nuget:?package=Sai.MarkdownDocumentation&version=1.0.1                

Markdown Documentation

Overview

Utility library for adding Markdown documentation to dotnet applications. Primarily designed for integration with aspnetcore applications.

Usage

Program.cs (assuming top level statements)

using Sai.MarkdownDocumentation;

// Add one or more folders containing "content" files. If no paths are defined "docs" is added automatically
builder.Services.AddMarkdownDocumentationReaderService("help");

Help.cshtml.cs

    public class HelpModel : PageModel
    {
        private readonly MarkdownDocumentationReaderService markdownDocumentationReaderService;
        public bool IncludesCodeBlocks { get; set; }
        public bool IncludesMermaidDiagrams { get; set; }
        public string HtmlToc { get; set; } = string.Empty;
        public string HtmlContent { get; set; } = string.Empty;

        public HelpModel(MarkdownDocumentationReaderService markdownDocumentationReaderService)
        {
            this.markdownDocumentationReaderService = markdownDocumentationReaderService;
        }

        // For the remainder of the URL to pass through as the content parameter,
        // this requires the following directive at the top of the cshtml page:
        // @page "/help/{*content}"
        public async Task<IActionResult> OnGet([FromRoute] string? content = null)
        {
            if (string.IsNullOrWhiteSpace(content))
                content = string.Empty;
            else
            {
                if (content.StartsWith("/"))
                    content = content.Substring(1);
                if (content.EndsWith("/"))
                    content = content.Substring(0, content.Length - 1);
            }

            var uri = $"help/{content}";

            HtmlToc = await markdownDocumentationReaderService.ReadTableOfContentsAsHtmlAsync("help", uri);

            var result = await markdownDocumentationReaderService.ReadMarkdownAsHtmlAsync(uri);
            if (result is not null)
            {
                HtmlContent = result.HtmlContent;
                IncludesCodeBlocks = result.IncludesCodeBlocks;
                IncludesMermaidDiagrams = result.IncludesMermaidDiagrams;
            }
            else
            {
                HtmlContent = "<p>Page not found</p>";
            }

            return Page();
        }
    }

Help.cshtml

@page "/help/{*content}"
@model MyApp.Pages.HelpModel
@{
    ViewData["Title"] = "Help";
    ViewData["Tab"] = "help";
}

@section Head
{
    <style>

        .page-container {
            display: grid; 
            grid-template-columns: 300px 1fr; 
            grid-template-rows: 1fr; 
            gap: 0px 10px; 
            grid-template-areas: 
            "toc content-wrapper";
            height: 100%;
        }

        .toc {
            grid-area: toc;
            border: 1px solid #ddd;
        }

        .toc > ul {
            overflow-y: scroll;
        }

        .toc ul {
            list-style-type: none;
            margin: 0;
            padding: 0;
            height: 100%
        }

        .toc-section {
            margin-bottom: 5px;
        }

        .toc > ul ul {
            padding-left: 20px; /* Child level indentation */
        }

        .toc li {
            color: var(--site-nav-side-text-color);
            list-style: none;
            margin: 5px;
        }

        .toc li > * {
            display: inline-block;
            padding: 5px 15px 5px 15px;
        }

        .toc li a, .toc li a:visited {
            color: var(--site-nav-side-text-color);
            text-decoration: none;
        }

        .toc li[aria-selected="true"] a {
            background-color: #f5f5f5;
            border-radius: 5px;
        }

        .toc li a:hover {
            text-decoration: underline;
        }

        .toc li.item-level-1 {
            font-weight: bold;
            margin-top: 15px;
        }

        .content-wrapper {
            grid-area: content-wrapper;
            border: 1px solid #ddd;
            padding: 20px;
            overflow-x: auto;
            overflow-y: scroll;
        }

        /* Match basic highlight.js formatting */
        pre code {         
            padding: 1em;
            display: block;
            background: #f6f6f6;
            color: #444;
        }

        .mermaid {
            min-height: 100px;
        }

        .content p > code {
            color: darkgoldenrod;
        }
       
    </style>

    @if (Model.IncludesCodeBlocks)
    {
        
        <link rel="stylesheet" href="~/styles/highlight/default.min.css" disabled>  
        <link rel="stylesheet" href="~/styles/highlight/rainbow.css" disabled>  
        <link rel="stylesheet" href="~/styles/highlight/stackoverflow-light.css">  
    }
}

<div class="page-container">
    <div class="toc">
        @Html.Raw(Model.HtmlToc)
    </div>
    <div class="content-wrapper">
        <div class="content">
            @Html.Raw(Model.HtmlContent)
        </div>
    </div>
</div>

@section Scripts 
{   
    <script type="module">

        var includesCodeBlocks = @Model.IncludesCodeBlocks.ToString().ToLower();
        if (includesCodeBlocks)
        {
            hljs.highlightAll();
        }

        var includesMermaidDiagrams = @Model.IncludesMermaidDiagrams.ToString().ToLower();
        if (includesMermaidDiagrams)
        {
            mermaid.initialize({startOnLoad:true});
        }

    </script>

    @if (Model.IncludesCodeBlocks)
    {
        
        <script src="~/scripts/highlight/highlight.min.js"></script>
        <script src="~/scripts/highlight/languages/powershell.min.js"></script>
        <script src="~/scripts/highlight/languages/dos.min.js"></script>
        <script src="~/scripts/highlight/languages/properties.min.js"></script>
    }

    @if (Model.IncludesMermaidDiagrams)
    {
        
        <script src="~/scripts/mermaid/mermaid.min.js"></script>
    }
}

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.1 222 9/2/2022
1.0.0 179 9/2/2022