Teru Komaki's Blog (Temporary)

Hugoのシンタックスハイライトのメモ

Hugoのシンタックスハイライトは、デフォルトでは、インラインスタイル noClasses = true として展開されます。

Syntax highlighting | Hugo

以下のマークダウンがありまして。

 1```html {hl_lines=["4-5",8]}
 2<!doctype html>
 3<html lang="en">
 4<head>
 5  <meta charset="utf-8">
 6  <title>Example HTML5 Document</title>
 7</head>
 8<body>
 9  <p>昔、男、初冠して、平安の都にありけり。清涼殿の御幸を賜ひて、梅の枝折りておきければ、その枝にこめたる心をたれもいとはず。よしあし言ふべきやうもあらず。よしなしごとを聞こえくるめる御世のけしきにもおはせまさり、宮の御心地いとやすからず。</p>
10</body>
11</html>
12```

以下のように表示されます。

 1<!doctype html>
 2<html lang="en">
 3<head>
 4  <meta charset="utf-8">
 5  <title>Example HTML5 Document</title>
 6</head>
 7<body>
 8  <p>昔、男、初冠して、平安の都にありけり。清涼殿の御幸を賜ひて、梅の枝折りておきければ、その枝にこめたる心をたれもいとはず。よしあし言ふべきやうもあらず。よしなしごとを聞こえくるめる御世のけしきにもおはせまさり、宮の御心地いとやすからず。</p>
 9</body>
10</html>

出力されたHTMLを確認すると、以下のように、インラインスタイルとして展開されます。

 1<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"><code class="language-html" data-lang="html"><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1</span><span><span style="color:#75715e">&lt;!doctype html&gt;</span>
 2</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2</span><span>&lt;<span style="color:#f92672">html</span> <span style="color:#a6e22e">lang</span><span style="color:#f92672">=</span><span style="color:#e6db74">"en"</span>&gt;
 3</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3</span><span>&lt;<span style="color:#f92672">head</span>&gt;
 4</span></span><span style="display:flex; background-color:#3c3d38"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4</span><span>  &lt;<span style="color:#f92672">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">"utf-8"</span>&gt;
 5</span></span><span style="display:flex; background-color:#3c3d38"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5</span><span>  &lt;<span style="color:#f92672">title</span>&gt;Example HTML5 Document&lt;/<span style="color:#f92672">title</span>&gt;
 6</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6</span><span>&lt;/<span style="color:#f92672">head</span>&gt;
 7</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7</span><span>&lt;<span style="color:#f92672">body</span>&gt;
 8</span></span><span style="display:flex; background-color:#3c3d38"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8</span><span>  &lt;<span style="color:#f92672">p</span>&gt;昔、男、初冠して、平安の都にありけり。清涼殿の御幸を賜ひて、梅の枝折りておきければ、その枝にこめたる心をたれもいとはず。よしあし言ふべきやうもあらず。よしなしごとを聞こえくるめる御世のけしきにもおはせまさり、宮の御心地いとやすからず。&lt;/<span style="color:#f92672">p</span>&gt;
 9</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9</span><span>&lt;/<span style="color:#f92672">body</span>&gt;
10</span></span><span style="display:flex;"><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10</span><span>&lt;/<span style="color:#f92672">html</span>&gt;
11</span></span></code></pre></div>

インラインではなく、classを設定したい場合は hugo.toml を以下に設定します。

Configure markup | Hugo

以下は hugo.toml のデフォルト値です。

 1[markup]
 2[markup.highlight]
 3anchorLineNos = false
 4codeFences = true
 5guessSyntax = false
 6hl_Lines = ''
 7hl_inline = false
 8lineAnchors = ''
 9lineNoStart = 1
10lineNos = false
11lineNumbersInTable = true
12noClasses = true
13noHl = false
14style = 'monokai'
15tabWidth = 4

noClasses = false に変更すると、classが設定されます。

11lineNumbersInTable = true
12noClasses = false
13noHl = false
 1<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="cp">&lt;!doctype html&gt;</span>
 2</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="p">&lt;</span><span class="nt">html</span> <span class="na">lang</span><span class="o">=</span><span class="s">"en"</span><span class="p">&gt;</span>
 3</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
 4</span></span><span class="line hl"><span class="ln"> 4</span><span class="cl">  <span class="p">&lt;</span><span class="nt">meta</span> <span class="na">charset</span><span class="o">=</span><span class="s">"utf-8"</span><span class="p">&gt;</span>
 5</span></span><span class="line hl"><span class="ln"> 5</span><span class="cl">  <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Example HTML5 Document<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
 6</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
 7</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
 8</span></span><span class="line hl"><span class="ln"> 8</span><span class="cl">  <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>昔、男、初冠して、平安の都にありけり。清涼殿の御幸を賜ひて、梅の枝折りておきければ、その枝にこめたる心をたれもいとはず。よしあし言ふべきやうもあらず。よしなしごとを聞こえくるめる御世のけしきにもおはせまさり、宮の御心地いとやすからず。<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
 9</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
10</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
11</span></span></code></pre></div>

設定のあとに、以下のコマンドでcssが生成できます。

1$ hugo gen chromastyles --style=monokai > syntax.css
 1/* syntax.css */
 2
 3/* Background */ .bg { color:#f8f8f2;background-color:#272822; }
 4/* PreWrapper */ .chroma { color:#f8f8f2;background-color:#272822; }
 5/* Other */ .chroma .x {  }
 6/* Error */ .chroma .err { color:#960050;background-color:#1e0010 }
 7/* CodeLine */ .chroma .cl {  }
 8/* LineLink */ .chroma .lnlinks { outline:none;text-decoration:none;color:inherit }
 9/* LineTableTD */ .chroma .lntd { vertical-align:top;padding:0;margin:0;border:0; }
10/* LineTable */ .chroma .lntable { border-spacing:0;padding:0;margin:0;border:0; }
11/* LineHighlight */ .chroma .hl { background-color:#3c3d38 }
12/* LineNumbersTable */ .chroma .lnt { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f }
13/* LineNumbers */ .chroma .ln { white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f }
14/* Line */ .chroma .line { display:flex; }
15/* Keyword */ .chroma .k { color:#66d9ef }
16/* KeywordConstant */ .chroma .kc { color:#66d9ef }
17/* KeywordDeclaration */ .chroma .kd { color:#66d9ef }
18/* KeywordNamespace */ .chroma .kn { color:#f92672 }
19/* KeywordPseudo */ .chroma .kp { color:#66d9ef }
20/* KeywordReserved */ .chroma .kr { color:#66d9ef }
21/* KeywordType */ .chroma .kt { color:#66d9ef }
22/* Name */ .chroma .n {  }
23/* NameAttribute */ .chroma .na { color:#a6e22e }
24/* NameBuiltin */ .chroma .nb {  }
25/* NameBuiltinPseudo */ .chroma .bp {  }
26/* NameClass */ .chroma .nc { color:#a6e22e }
27/* NameConstant */ .chroma .no { color:#66d9ef }
28/* NameDecorator */ .chroma .nd { color:#a6e22e }
29/* NameEntity */ .chroma .ni {  }
30/* NameException */ .chroma .ne { color:#a6e22e }
31/* NameFunction */ .chroma .nf { color:#a6e22e }
32/* NameFunctionMagic */ .chroma .fm {  }
33/* NameLabel */ .chroma .nl {  }
34/* NameNamespace */ .chroma .nn {  }
35/* NameOther */ .chroma .nx { color:#a6e22e }
36/* NameProperty */ .chroma .py {  }
37/* NameTag */ .chroma .nt { color:#f92672 }
38/* NameVariable */ .chroma .nv {  }
39/* NameVariableClass */ .chroma .vc {  }
40/* NameVariableGlobal */ .chroma .vg {  }
41/* NameVariableInstance */ .chroma .vi {  }
42/* NameVariableMagic */ .chroma .vm {  }
43/* Literal */ .chroma .l { color:#ae81ff }
44/* LiteralDate */ .chroma .ld { color:#e6db74 }
45/* LiteralString */ .chroma .s { color:#e6db74 }
46/* LiteralStringAffix */ .chroma .sa { color:#e6db74 }
47/* LiteralStringBacktick */ .chroma .sb { color:#e6db74 }
48/* LiteralStringChar */ .chroma .sc { color:#e6db74 }
49/* LiteralStringDelimiter */ .chroma .dl { color:#e6db74 }
50/* LiteralStringDoc */ .chroma .sd { color:#e6db74 }
51/* LiteralStringDouble */ .chroma .s2 { color:#e6db74 }
52/* LiteralStringEscape */ .chroma .se { color:#ae81ff }
53/* LiteralStringHeredoc */ .chroma .sh { color:#e6db74 }
54/* LiteralStringInterpol */ .chroma .si { color:#e6db74 }
55/* LiteralStringOther */ .chroma .sx { color:#e6db74 }
56/* LiteralStringRegex */ .chroma .sr { color:#e6db74 }
57/* LiteralStringSingle */ .chroma .s1 { color:#e6db74 }
58/* LiteralStringSymbol */ .chroma .ss { color:#e6db74 }
59/* LiteralNumber */ .chroma .m { color:#ae81ff }
60/* LiteralNumberBin */ .chroma .mb { color:#ae81ff }
61/* LiteralNumberFloat */ .chroma .mf { color:#ae81ff }
62/* LiteralNumberHex */ .chroma .mh { color:#ae81ff }
63/* LiteralNumberInteger */ .chroma .mi { color:#ae81ff }
64/* LiteralNumberIntegerLong */ .chroma .il { color:#ae81ff }
65/* LiteralNumberOct */ .chroma .mo { color:#ae81ff }
66/* Operator */ .chroma .o { color:#f92672 }
67/* OperatorWord */ .chroma .ow { color:#f92672 }
68/* Punctuation */ .chroma .p {  }
69/* Comment */ .chroma .c { color:#75715e }
70/* CommentHashbang */ .chroma .ch { color:#75715e }
71/* CommentMultiline */ .chroma .cm { color:#75715e }
72/* CommentSingle */ .chroma .c1 { color:#75715e }
73/* CommentSpecial */ .chroma .cs { color:#75715e }
74/* CommentPreproc */ .chroma .cp { color:#75715e }
75/* CommentPreprocFile */ .chroma .cpf { color:#75715e }
76/* Generic */ .chroma .g {  }
77/* GenericDeleted */ .chroma .gd { color:#f92672 }
78/* GenericEmph */ .chroma .ge { font-style:italic }
79/* GenericError */ .chroma .gr {  }
80/* GenericHeading */ .chroma .gh {  }
81/* GenericInserted */ .chroma .gi { color:#a6e22e }
82/* GenericOutput */ .chroma .go {  }
83/* GenericPrompt */ .chroma .gp {  }
84/* GenericStrong */ .chroma .gs { font-weight:bold }
85/* GenericSubheading */ .chroma .gu { color:#75715e }
86/* GenericTraceback */ .chroma .gt {  }
87/* GenericUnderline */ .chroma .gl {  }
88/* TextWhitespace */ .chroma .w {  }

以下のようなHTMLで、cssを読み込みます。

 1// /my_blog/themes/my_theme/layouts/partials/head/css_highlight.html
 2
 3{{- with resources.Get "css/syntax.css" -}}
 4    {{- if eq hugo.Environment "development" -}}
 5        <link rel="stylesheet" href="{{ .RelPermalink }}">
 6    {{- else -}}
 7        {{- with . | minify | fingerprint -}}
 8            <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
 9        {{- end -}}
10    {{- end -}}
11{{- end -}}