Statiqがmarkdownから生成するhtmlのカスタマイズ

Published on
Updated on

はじめに

Statiqがmarkdownから生成するhtmlの任意のタグにクラスを追加する方法の備忘録

方法

Bootstrapperにおいて、Statiq.WebでWebサイトを生成するメソッドであるCreateWeb()では、markdownに関わるModuleのRenderMarkdownTemplates内で設定している。 そのため、ConfigureTemplates()を通じて、予め設定されたModuleを上書きすることで好みの設定を反映することができる。 Statiqでは、markdownを生成するためにmarkdigを使っているようなので、markdownの設定を追加するにはIMarkdownExtensionを継承したクラスをRendermarkdown.UseExtension<TExtension>()に渡す必要がある。

今回は、<img>タグをレスポンシブ対応と、<table>タグにクラスを追加するために、markdigのBootstrapExtensionを設定に追加する。

public static async Task<int> Main(string[] args) =>
    await Bootstrapper.Factory
        .CreateWeb(args)
        .ConfigureTemplates(templates =>
        {
            // 新しい設定のModuleを作成
            // デフォルトはUseExtensionsのみ
            var markdownModule = new RenderMarkdown()
                .UseExtensions()
                .UseExtension<BootstrapExtension>() // bootstrap
                .UseExtension<PrismJsExtension>(); // オリジナル
            if (templates.ContainsKey(MediaTypes.Markdown)) 
                templates[MediaTypes.Markdown].Module = markdownModule; // 既にあるならば書き換え
            else 
                templates.Add(MediaTypes.Markdown,
                    new Template(ContentType.Content, Phase.Process, markdownModule)); // 無ければ追加
        })
        .RunAsync();

また、prism.jsのコードブロックに行数を表示するクラスのline-numberを追加するために、新しくPrismJsExtension.csを作成し、BootstrapExtensionに倣い、MarkdownObjectCodeBlockであればline-numbersをクラスに追加するメソッドのPipelineOnDocumentProcessed()markdigの生成パイプラインにデリゲートを追加する。

// PrismJsExtension.cs
using Markdig;
using Markdig.Renderers;
using Markdig.Renderers.Html;
using Markdig.Syntax;

namespace Blog.Extensions
{
    public class PrismJsExtension : IMarkdownExtension
    {
        public void Setup(MarkdownPipelineBuilder pipeline)
        {
            pipeline.DocumentProcessed -= PipelineOnDocumentProcessed;
            pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
        }

        public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer)
        {
        }

        private static void PipelineOnDocumentProcessed(MarkdownDocument document)
        {
            foreach (var node in document.Descendants())
            {
                if (node is CodeBlock)
                {
                    node.GetAttributes().AddClass("line-numbers"); // 行数表示のクラスを追加
                }
            }
        }
    }
}

以上の2つの設定を追加してビルドすることで、bootstrapによる<img>タグのレスポンシブ対応、<table>タグのレイアウト、prism.jsの言語を指定したコードブロックに行数が表示されるようになる。

まとめ

StatiqのBootstrapperにてConfigureTemplates()からテンプレートのmarkdownに関わるModuleを書き換えることで、markdownからhtmlを生成する設定を変更することができ、RenderMarkdown.UseExtension<TExtension>()IMarkdownExtensionを継承したクラスを設定することで、htmlタグのクラス等を変更することができる。