直通元素渲染钩子
概述
Hugo 使用 Goldmark 将 Markdown 渲染为 HTML。Goldmark 支持自定义扩展来扩展其核心功能。直通 扩展捕获并保留原始 Markdown 在 delimited 文本片段中,包括分隔符本身。这些被称为 直通元素。
根据您选择的分隔符,Hugo 会将直通元素分类为 块级 或 内联。考虑这个人为的例子:
这是一个
\[块级\]
直通元素,带有开始和结束块级分隔符。
这是一个 \(内联\) 直通元素,带有开始和结束内联分隔符。更新您的站点配置以启用直通扩展并为每种直通元素类型定义开始和结束分隔符,block 或 inline。例如:
markup:
goldmark:
extensions:
passthrough:
delimiters:
block:
- - '\['
- '\]'
- - $$
- $$
inline:
- - '\('
- '\)'
enable: true
[markup]
[markup.goldmark]
[markup.goldmark.extensions]
[markup.goldmark.extensions.passthrough]
enable = true
[markup.goldmark.extensions.passthrough.delimiters]
block = [['\[', '\]'], ['$$', '$$']]
inline = [['\(', '\)']]
{
"markup": {
"goldmark": {
"extensions": {
"passthrough": {
"delimiters": {
"block": [
[
"\\[",
"\\]"
],
[
"$$",
"$$"
]
],
"inline": [
[
"\\(",
"\\)"
]
]
},
"enable": true
}
}
}
}
}
在上面的示例中有两组 block 分隔符。您可以在 Markdown 中使用其中任意一组。
直通扩展通常与 MathJax 或 KaTeX 显示引擎结合使用,以渲染用 LaTeX 标记语言编写的 数学表达式。
要启用直通元素的自定义渲染,请创建直通元素渲染钩子。
上下文
直通元素_渲染钩子_ 模板接收以下 上下文:
- Attributes
- (
map) Markdown 属性,如果您的站点配置如下则可用:markup: goldmark: parser: attribute: block: true[markup] [markup.goldmark] [markup.goldmark.parser] [markup.goldmark.parser.attribute] block = true{ "markup": { "goldmark": { "parser": { "attribute": { "block": true } } } } }Hugo 为 块级 直通元素填充
Attributes映射。Markdown 属性不适用于 内联 元素。 - Inner
- (
string) 直通元素的内联内容,不包括分隔符。 - Ordinal
- (
int) 页面上直通元素的从零开始的序号。 - Page
- (
page) 对当前页面的引用。 - PageInner
- (
page) 对通过RenderShortcodes方法嵌套的页面的引用。详见。 - Position
- (
string) 直通元素在页面内容中的位置。 - Type
- (
string) 直通元素类型,block或inline。
示例
与其使用 MathJax 或 KaTeX 进行客户端 JavaScript 渲染数学标记,不如创建一个调用 transform.ToMath 函数的直通元素渲染钩子。
{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }}
{{- with try (transform.ToMath .Inner $opts) }}
{{- with .Err }}
{{- errorf "无法使用 transform.ToMath 函数将数学标记渲染为 HTML。KaTeX 显示引擎抛出以下错误:%s:参见 %s。" . $.Position }}
{{- else }}
{{- .Value }}
{{- $.Page.Store.Set "hasMath" true }}
{{- end }}
{{- end -}}然后,在您的基础模板中,在 head 元素内有条件地包含 KaTeX CSS:
<head>
{{ $noop := .WordCount }}
{{ if .Page.Store.Get "hasMath" }}
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/katex.min.css"
integrity="sha384-WcoG4HRXMzYzfCgiyfrySxx90XSl2rxY5mnVY5TwtWE6KLrArNKn0T/mOgNL0Mmi"
crossorigin="anonymous"
>
{{ end }}
</head>在上面,请注意使用 noop 语句来强制在 Store.Get 方法检查 hasMath 值之前进行内容渲染。
虽然您可以使用一个带有条件逻辑的模板(如上所示),但您也可以为每种 Type 的直通元素创建单独的模板:
layouts/
└── _markup/
├── render-passthrough-block.html
└── render-passthrough-inline.htmlPageInner 详情
PageInner 的主要用途是相对于包含的 Page 解析链接和 页面资源。例如,创建一个 “include” 短代码,从多个内容文件组合页面,同时保留脚注和目录的全局上下文:
{{ with .Get 0 }}
{{ with $.Page.GetPage . }}
{{- .RenderShortcodes }}
{{ else }}
{{ errorf "短代码 %q 无法找到 %q。参见 %s" $.Name . $.Position }}
{{ end }}
{{ else }}
{{ errorf "短代码 %q 需要一个位置参数来指示要包含的文件的逻辑路径。参见 %s" .Name .Position }}
{{ end }}然后在您的 Markdown 中调用短代码:
{{% include "/posts/post-2" %}}在渲染 /posts/post-2 时触发的任何渲染钩子将获得:
- 调用
Page时获得/posts/post-1 - 调用
PageInner时获得/posts/post-2
如果不相关,PageInner 会回退到 Page 的值,并且始终返回一个值。
PageInner 方法仅与调用 RenderShortcodes 方法的短代码相关,并且您必须使用 Markdown 表示法 调用短代码。
作为实际示例,Hugo 的嵌入式链接和图像渲染钩子使用 PageInner 方法来解析 Markdown 链接和图像目标。请参阅各自的源代码: