Hugo Markup 配置完全指南:从 Goldmark 到 AsciiDoc、reStructuredText 与代码高亮
【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo
导读
markup是 Hugo 站点构建中控制"内容如何被渲染为 HTML"的核心配置区块。本文以官方文档 docs/content/en/configuration/markup.md 为骨架,结合本仓库源码(markup/markup_config/config.go、markup/goldmark/goldmark_config/config.go、markup/asciidocext/asciidocext_config/config.go 等)逐项讲解默认 Markdown 处理器、Goldmark 扩展与解析器设置、AsciiDoc / reStructuredText 外部渲染器的接入方式、代码高亮与目录(TOC)配置。读完本文,你将能按需切换 Markdown 处理器、启用脚注 / LaTeX 数学 / 排版替换等扩展,并为 AsciiDoc 与 reStructuredText 配置语法高亮,所有配置均可在hugo.toml中直接落地。
默认处理器(Default handler)
Hugo 默认使用 [Goldmark][] 将 Markdown 渲染为 HTML,对应配置为:
[markup] defaultMarkdownHandler = 'goldmark'从源码看,该默认值定义在 markup/markup_config/config.go 的Default结构体中(DefaultMarkdownHandler: "goldmark"),并在 markup/markup.go 的NewConverterProvider中完成转换器注册与别名绑定:当某个转换器的名称与defaultMarkdownHandler匹配时,会额外注册markdown别名,确保markdown始终指向当前默认处理器。
以.md、.mdown或.markdown结尾的文件默认按 Markdown 处理,除非你在 front matter 中通过markup字段显式指定其他格式。
切换渲染器
可在项目配置中将defaultMarkdownHandler指定为以下任一值:
defaultMarkdownHandler | 渲染器 |
|---|---|
asciidocext | [AsciiDoc][] |
goldmark | [Goldmark][] |
org | [Emacs Org Mode][] |
pandoc | [Pandoc][] |
rst | [reStructuredText][] |
使用 AsciiDoc、Pandoc 或 reStructuredText 时,你必须先安装对应的外部渲染器(Asciidoctor、Pandoc、Docutils),并更新 security policy 以允许 Hugo 调用这些外部可执行文件——Hugo 通过 common/hexec 管理这类外部命令调用,默认安全策略下外部命令是被禁止的。
[!NOTE] 除非你确实需要某个替代 Markdown 处理器提供的独有能力,否则强烈建议保持默认设置。Goldmark 快速、维护良好、符合 [CommonMark][] 规范,并兼容 [GitHub Flavored Markdown][](GFM)。从源码也能印证:
asciidocext、rst、pandoc、org均依赖外部可执行文件(markup/markup.go 中它们与goldmark并列注册,但实现路径不同)。
Goldmark 渲染器
Goldmark 是 Hugo 内置的 Markdown 渲染引擎(Go 语言实现,仓库位于 markup/goldmark),其默认配置如下(完整默认值定义见 markup/goldmark/goldmark_config/config.go):
[markup.goldmark] duplicateResourceFiles = false [markup.goldmark.renderer] hardWraps = false unsafe = false xhtml = false [markup.goldmark.parser] attribute.block = false attribute.title = true autoHeadingID = true autoIDType = "github" autoDefinitionTermID = false wrapStandAloneImageWithinParagraph = true [markup.goldmark.extensions] cjk.enable = false cjk.eastAsianLineBreaks = false cjk.eastAsianLineBreaksStyle = "simple" cjk.escapedSpace = false definitionList = true footnote.enable = true footnote.enableAutoIDPrefix = false footnote.backlinkHTML = "↩︎" linkify = true linkifyProtocol = "https" strikethrough = true table = true taskList = true typographer.disable = false typographer.ellipsis = "…" typographer.leftAngleQuote = "«" typographer.rightAngleQuote = "»" typographer.leftDoubleQuote = "“" typographer.rightDoubleQuote = "”" typographer.leftSingleQuote = "‘" typographer.rightSingleQuote = "’" typographer.apostrophe = "’" typographer.enDash = "–" typographer.emDash = "—" [markup.goldmark.extensions.extras] delete.enable = false insert.enable = false mark.enable = false subscript.enable = false superscript.enable = false [markup.goldmark.extensions.passthrough] enable = false [markup.goldmark.renderHooks.image] enableDefault = false useEmbedded = "auto" [markup.goldmark.renderHooks.link] enableDefault = false useEmbedded = "auto"扩展(Extensions)
除 Extras 与 Passthrough 外,其余扩展默认均启用:
| 扩展 | 说明 | 默认启用 |
|---|---|---|
cjk | 中日韩文字排版支持 | ✔ |
definitionList | PHP Markdown Extra 定义列表 | ✔ |
extras | Hugo Goldmark Extensions 的 Extras 扩展(删除/插入/标记/上下标) | 否 |
footnote | PHP Markdown Extra 脚注 | ✔ |
linkify | GFM 自动链接 | ✔ |
passthrough | Hugo Goldmark Extensions 的 Passthrough 扩展(LaTeX 数学) | 否 |
strikethrough | GFM 删除线 | ✔ |
table | GFM 表格 | ✔ |
taskList | GFM 任务列表 | ✔ |
typographer | 排版替换(弯引号、破折号、省略号等) | ✔ |
注意cjk在配置默认值中Enable为false(markup/goldmark/goldmark_config/config.go),但按官方文档说明它在功能层面默认启用——若你的站点以中日韩文字为主,建议显式开启cjk.enable = true以获得更优的换行处理。
Extras:删除、插入、标记与上下标
Extras 扩展允许在 Markdown 中直接使用 HTML5 语义元素:
| 元素 | Markdown | 渲染结果 |
|---|---|---|
| 删除文本 | ~~foo~~ | <del>foo</del> |
| 插入文本 | ++bar++ | <ins>bar</ins> |
| 标记文本 | ==baz== | <mark>baz</mark> |
| 下标 | H~2~O | H<sub>2</sub>O |
| 上标 | 1^st^ | 1<sup>st</sup> |
冲突警告:由于~~同时是删除线与下标的语法,若启用 Extras 的下标功能,必须先禁用 Strikethrough 扩展:
[markup.goldmark.extensions] strikethrough = false [markup.goldmark.extensions.extras.subscript] enable = true禁用 Strikethrough 后若仍需"删除文本"效果,可启用 Extras 的 delete 功能:
[markup.goldmark.extensions] strikethrough = false [markup.goldmark.extensions.extras.delete] enable = true配置后,删除文本同样使用双波浪号包裹(~~foo~~),但由 Extras 扩展渲染为<del>元素而非 GFM 语义。
Footnote 脚注扩展
默认启用,可在 Markdown 中使用[^1]语法插入脚注。其配置项包括:
enable: (bool,新增于 0.151.0)是否启用脚注扩展,默认true。
backlinkHTML: (string,新增于 0.151.0)脚注末尾指向正文引用的返回链接 HTML,默认↩︎(↩ 返回箭头符号),与源码中BacklinkHTML: "↩︎"一致(markup/goldmark/goldmark_config/config.go)。
enableAutoIDPrefix: (bool,新增于 0.151.0)是否为脚注 ID 添加唯一前缀,防止多文档合并渲染时 ID 冲突。前缀对每个逻辑路径唯一,但在不同内容维度(如多语言)间不保证唯一,默认false。
需要说明的是,脚注配置在 0.151.0 中由布尔值升级为结构体,源码 markup/markup_config/config.go 的normalizeConfig会自动迁移旧配置:footnote = false会转换为footnote.enable = false,footnote = true则保持默认。
Passthrough:LaTeX 数学公式
启用 Passthrough 扩展即可在 Markdown 中使用 LaTeX 书写数学公式。配置示例:
[markup.goldmark.extensions.passthrough] enable = true [markup.goldmark.extensions.passthrough.delimiters] block = [['\[', '\]'], ['$$', '$$']] inline = [['\(', '\)'], ['$', '$']]完整的数学语法说明参见 mathematics in Markdown。从源码看,Passthrough 的Delimiters结构支持Inline与Block两组分隔符,每组元素为「开分隔符、闭分隔符」二元组(markup/goldmark/goldmark_config/config.go)。
Typographer 排版替换
Typographer 扩展将特定字符组合替换为 HTML 实体:
| Markdown | 替换为 | 说明 |
|---|---|---|
... | … | 水平省略号 |
' | ’ | 撇号 |
-- | – | 短破折号(en dash) |
--- | — | 长破折号(em dash) |
« | « | 左书名号 |
“ | “ | 左双引号 |
‘ | ‘ | 左单引号 |
» | » | 右书名号 |
” | ” | 右双引号 |
’ | ’ | 右单引号 |
所有替换值均可在配置中覆盖,例如:
[markup.goldmark.extensions.typographer] enDash = "–" emDash = "—"源码中的默认实体值见 markup/goldmark/goldmark_config/config.go。Typographer 在 0.112.0 中也由布尔值升级为结构体,旧配置typographer = false会自动迁移为typographer.disable = true(见 markup/markup_config/config.go)。
设置(Settings)
duplicateResourceFiles: (bool)多语言单主机项目中是否为每种语言复制共享页面资源,默认false。详见 multilingual page resources。
[!NOTE] 在多语言单主机项目中,将该参数设为
false会启用 Hugo 的 embedded link render hook 与 embedded image render hook,这也是多语言单主机项目的默认配置。
parser.wrapStandAloneImageWithinParagraph: (bool)渲染时是否将无相邻内容的独立图片包裹在p元素内。这是标准 Markdown 行为,默认true。若你使用 image render hook 将独立图片渲染为figure元素,应设为false。
parser.autoDefinitionTermID: (bool,新增于 0.144.0)是否自动为描述列表术语(dt元素)添加id属性。为true时,可通过Page对象的Fragments.Identifiers方法访问每个dt的id。默认false。源码在 markup/goldmark/goldmark_config/config.go 中做了联动约束:若AutoDefinitionTermID为true但DefinitionList扩展被禁用,则该设置自动失效。
parser.autoHeadingID: (bool)是否自动为h1–h6标题添加id属性,默认true。
parser.autoIDType: (string)自动生成id的策略,取值为github、github-ascii或blackfriday,默认github。常量定义见 markup/goldmark/goldmark_config/config.go。
github:生成与 GitHub 兼容的id;github-ascii:在重音规范化后丢弃所有非 ASCII 字符;blackfriday:生成与 Blackfriday 渲染器兼容的id。
该策略同样被urls.Anchorize函数使用。源码中AutoHeadingIDType已在 0.144.0 更名为AutoIDType,旧的AutoHeadingIDType配置会被自动迁移(markup/goldmark/goldmark_config/config.go)。
parser.attribute.block: (bool)是否启用块级元素 Markdown 属性,默认false。
parser.attribute.title: (bool)是否启用标题的 Markdown 属性,默认true。
renderHooks.image.enableDefault: (bool,已在 0.148.0 弃用)请改用renderHooks.image.useEmbedded。
renderHooks.image.useEmbedded: (string,新增于 0.148.0)何时使用 embedded image render hook,取值为auto、never、always或fallback,默认auto。
auto:仅在多语言单主机项目且禁用共享页面资源复制时使用内嵌图片渲染钩子;若项目、模块或主题定义了自定义图片渲染钩子,则优先使用自定义钩子。never:永不使用内嵌图片渲染钩子;有自定义钩子时使用自定义钩子。always:总是使用内嵌图片渲染钩子,即使存在自定义钩子。fallback:仅在不存在自定义图片渲染钩子时使用内嵌钩子。
renderHooks.link.enableDefault: (bool,已在 0.148.0 弃用)请改用renderHooks.link.useEmbedded。
renderHooks.link.useEmbedded: (string)何时使用 embedded link render hook,取值与默认值同上(auto/never/always/fallback,默认auto),各取值的语义与图片渲染钩子一致。useEmbedded常量在 markup/goldmark/goldmark_config/config.go 中定义。
renderer.hardWraps: (bool)是否将段落内的换行符替换为br元素,默认false。
renderer.unsafe: (bool)是否渲染 Markdown 中混写的原始 HTML,默认false。除非内容完全受你控制,否则开启是不安全的。对应源码字段 markup/goldmark/goldmark_config/config.go 中还有xhtml(输出 XHTML 而非 HTML5)选项。
AsciiDoc 渲染器
使用asciidocext时,Hugo 会调用外部的 Asciidoctor 可执行文件(在 Windows 上为asciidoctor.bat)。其默认配置见 markup/asciidocext/asciidocext_config/config.go,如下:
[markup.asciidocExt] attributes = {} backend = "html5" extensions = [] failureLevel = "fatal" noHeaderOrFooter = true preserveTOC = false safeMode = "unsafe" sectionNumbers = false trace = false verbose = false workingFolderCurrent = false设置
attributes: (map)键值对集合,每个键值对是一个文档属性。参见 Asciidoctor 的 [attributes][] 文档。
backend: (string)后端输出文件格式,默认html5。源码 markup/asciidocext/asciidocext_config/config.go 中允许的值包括html5、html5s、xhtml5、docbook5、docbook45与manpage。
extensions: ([]string)启用的扩展数组,例如asciidoctor-html5s、asciidoctor-bibtex或asciidoctor-diagram。
[!NOTE] 为降低安全风险,扩展名中不得包含正斜杠(
/)、反斜杠(\)或句点。受此限制,扩展必须位于 Ruby 的$LOAD_PATH中。
failureLevel: (string)触发非零退出码(构建失败)的最低日志级别,默认fatal。源码 markup/asciidocext/asciidocext_config/config.go 中允许fatal与warn两个级别。
noHeaderOrFooter: (bool)是否输出可嵌入文档——即排除页眉、页脚及文档正文之外的所有内容,默认true。
preserveTOC: (bool)是否保留 Asciidoctor 渲染的目录(TOC)。默认情况下,为兼容现有主题,Hugo 会移除 Asciidoctor 渲染的 TOC;如需渲染目录,请在模板中使用Page对象的TableOfContents方法,默认false。
safeMode: (string)安全模式级别,取值为unsafe、safe、server或secure,默认unsafe。允许值在源码 markup/asciidocext/asciidocext_config/config.go 中校验。
sectionNumbers: (bool)是否为每个章节标题编号,默认false。
trace: (bool)出错时是否包含回溯(backtrace)信息,默认false。
verbose: (bool)是否向 stderr 详细打印处理信息与配置文件检查结果,默认false。
workingFolderCurrent: (bool)是否将工作目录设置为与正在处理的 AsciiDoc 文件相同,从而允许 [includes][] 使用相对路径。渲染 [asciidoctor-diagram][] 图表时需设为true,默认false。
配置示例
[markup.asciidocExt] backend = 'html5s' extensions = ['asciidoctor-html5s','asciidoctor-diagram'] workingFolderCurrent = true [markup.asciidocExt.attributes] my-base-url = 'https://example.com/' my-attribute-name = 'my value'AsciiDoc 语法高亮
按以下步骤启用语法高亮:
步骤 1:在项目配置中设置source-highlighter属性,例如:
[markup.asciidocExt.attributes] source-highlighter = 'rouge'步骤 2:生成高亮器 CSS,例如:
rougify style monokai.sublime > assets/css/highlight.css步骤 3:在base模板中引入该 CSS 文件:
<head> {{ with resources.Get "css/highlight.css" }} <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} </head>步骤 4:在文档中书写待高亮代码:
[#hello,go] ---- package main import "fmt" func main() { fmt.Println("Hello, World!") } ----故障排查
运行hugo build --logLevel debug可查看 Hugo 对 Asciidoctor 可执行文件的调用细节:
INFO 2019/12/22 09:08:48 Rendering book-as-pdf.adoc with C:\Ruby26-x64\bin\asciidoctor.bat using asciidoc args [--no-header-footer -r asciidoctor-html5s -b html5s -r asciidoctor-diagram --base-dir D:\prototypes\hugo_asciidoc_ddd\docs -a outdir=D:\prototypes\hugo_asciidoc_ddd\build -] ...从日志可见,noHeaderOrFooter会映射为命令行参数--no-header-footer,extensions中的每一项映射为-r参数,backend映射为-b参数。需要留意的是,源码 markup/asciidocext/asciidocext_config/config.go 将outdir列为禁用属性(DisallowedAttributes),用户配置中不可覆盖它,因为 Hugo 需要控制输出目录。
reStructuredText 渲染器
使用rst时,Hugo 调用外部的 Docutils 可执行文件(rst2html系列命令)完成渲染。默认配置见 markup/rst/rst_config/config.go:
[markup.rst] syntaxHighlight = "long"设置
syntaxHighlight: (string)使用 Pygments 解析代码时的 token 名称集合,取值为long、short或none,默认long。源码 markup/rst/rst_config/config.go 的Init会对非法的取值直接报错:invalid value for syntaxHighlight: "..."。
reStructuredText 语法高亮
步骤 1:将syntaxHighlight设为short:
[markup.rst] syntaxHighlight = 'short'步骤 2:生成高亮器 CSS,例如:
pygmentize -S monokai -f html > assets/css/highlight.css步骤 3:在base模板中引入该 CSS 文件:
<head> {{ with resources.Get "css/highlight.css" }} <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} </head>步骤 4:在文档中书写待高亮代码:
.. code-block:: go package main import "fmt" func main() { fmt.Println("Hello, World!") }代码高亮(Highlight)
以下设置适用于 Markdown 围栏代码块、内嵌的highlightshortcode、transform.Highlight与transform.HighlightCodeBlock函数。默认配置见 markup/highlight/config.go:
[markup.highlight] anchorLineNos = false codeFences = true guessSyntax = false hl_Lines = '' hl_inline = false lineAnchors = '' lineNoStart = 1 lineNos = false lineNumbersInTable = true noClasses = true style = 'monokai' tabWidth = 4 wrapperClass = 'highlight'各选项说明
anchorLineNos: (bool)是否将每个行号渲染为 HTML 锚点元素,并把外围span的id设为行号。lineNos为false时无效。默认false。
codeFences: (bool)是否高亮围栏代码块,默认true。
guessSyntax: (bool)当LANG参数为空或对应语言没有词法分析器(lexer)时,是否自动检测语言;若检测失败则回退为纯文本。默认false。
[!NOTE] 语法高亮器内置约 300 种语言的 lexer,但其中只有 5 种实现了自动语言检测。
hl_Lines: (string)需要强调的行列表,空格分隔。例如强调第 2、3、4、7 行,设为2-4 7。该选项独立于lineNoStart。
hl_inline: (bool)是否不包裹容器直接渲染高亮代码,默认false。
lineAnchors: (string)行号渲染为 HTML 锚点时,追加到外围span的id前缀,用于页面包含多个代码块时保证id唯一。lineNos或anchorLineNos为false时无效。
lineNoStart: (int)首行显示的行号,lineNos为false时无效。默认1。
lineNos: (any)控制行号显示,默认false。
true:启用行号,由lineNumbersInTable控制呈现方式;false:禁用行号;inline:启用内联行号(同时将lineNumbersInTable置为false);table:启用基于表格的行号(同时将lineNumbersInTable置为true)。
lineNumbersInTable: (bool)是否将高亮代码渲染为两单元格的 HTML 表格:左单元格为行号,右单元格为代码。lineNos为false时无效。默认true。
noClasses: (bool)是否使用内联 CSS 样式而非外部 CSS 文件,默认true。若需使用外部 CSS 文件,设为false并用以下命令生成:
hugo gen chromastyles --style=github > assets/css/highlight.css部分样式提供独立的亮色 / 暗色配色。使用--mode标志为指定模式生成样式表,用--modeSelector标志将每个选择器限定在顶层模式类下(如.dark .chroma):
hugo gen chromastyles --style=monokai --mode=light > assets/css/highlight.css hugo gen chromastyles --style=monokai --mode=dark --modeSelector > assets/css/highlight-dark.css通过增删根元素上的dark类即可切换暗色模式。省略--mode时,Hugo 使用该样式的默认模式生成样式表。此外也可在模板内用css.ChromaStyles函数生成样式表。
style: (string)应用于高亮代码的 CSS 样式名,不区分大小写,默认monokai。可选样式参见 syntax highlighting styles。
tabWidth: (int)每个 tab 字符替换为的空格数,noClasses为false时无效。默认4。
wrapperClass: (string,新增于 0.140.2)高亮代码最外层元素的 class 名,默认highlight。
从实现看,markup/highlight/config.go 的toHTMLOptions会将上述配置转换为 Chroma 的 HTML 渲染选项,其中lineNos的字符串形式"inline"/"table"会映射为对应的表格开关;hl_Lines会被解析为行区间数组[2][4]int传给 Chroma 渲染强调行。此外该包还保留了 Pygments 时代的旧配置兼容:pygmentsStyle、pygmentsUseClasses、pygmentsCodeFences、pygmentsCodefencesGuessSyntax、pygmentsOptions等遗留键仍会被ApplyLegacyConfig自动迁移(markup/highlight/config.go)。
目录(Table of contents)
目录配置同时适用于 Goldmark 与 Asciidoctor,默认配置如下(对应源码 markup/tableofcontents/tableofcontents.go):
[markup.tableOfContents] endLevel = 3 ordered = false startLevel = 2startLevel: (int)级别小于该值的标题将被排除在目录外。例如要排除h1,将其设为2。默认2。
endLevel: (int)级别大于该值的标题将被排除在目录外。例如要排除h4、h5、h6,将其设为3。默认3。源码 markup/tableofcontents/tableofcontents.go 还支持-1,表示包含所有层级。
ordered: (bool)是否生成有序列表(<ol>)而非无序列表(<ul>),默认false。
在 markup/tableofcontents/tableofcontents.go 的tocBuilder中可以看到目录的完整渲染逻辑:writeNav输出<nav id="TableOfContents">容器,writeHeadings依据startLevel/stopLevel决定哪些层级进入列表,ordered决定输出ol还是ul,最终生成的Fragments数据结构同时供模板中的TableOfContents方法使用。
小结
markup配置区块覆盖了 Hugo 内容渲染的完整链路:defaultMarkdownHandler决定使用哪个渲染器;markup.goldmark控制内置 Goldmark 引擎的扩展、解析器与渲染行为;markup.asciidocExt、markup.rst分别对接 Asciidoctor 与 Docutils 两个外部渲染器;markup.highlight统一管理围栏代码块与 shortcode 的 Chroma 高亮;markup.tableOfContents则约束目录生成范围。绝大多数配置在 markup/markup_config/config.go 中被一次解码并注入转换器注册表(markup/markup.go),其中goldmark.parser.attribute、typographer、footnote等历史结构变更均有自动迁移逻辑,升级 Hugo 时无需手工改写旧配置。以本文的配置示例为起点,你可以为多语言站点、数学文档或 AsciiDoc 工作流构建贴合自身需求的渲染管线。
【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考