问题背景
在 Hugo 中, Markdown 的代码块内嵌套超链接时会遇到问题:渲染后的超链接无法正常生效。这是因为代码块会将所有内容视为纯文本,不会解析HTML标记。
常见解决方案及其局限性
使用普通文本或引用块
将代码块改为普通文本或引用块确实可以让超链接生效,但排版效果不理想,无法保持代码的格式化显示。
直接添加HTML链接标签
尝试在代码块中直接使用 HTML 的超链接标签,但结果显示 HTML 标签并未被渲染,仍然被当作纯文本处理。
即使在 hugo.yaml
中已启用 unsafe: true
(允许 Markdown 中的 HTML 内容),代码块中的 HTML 代码 <a href="...">详细资料</a>
仍被视为纯文本。这是因为代码块的特性决定了其中所有内容都被视为纯文本,不会被 Hugo 的 Markdown 处理器解析。
创建自定义 shortcode 解决方案
通过创建自定义 shortcode ,我们可以解决这个问题。下面是具体实现步骤:
创建基础 shortcode 文件
在 layouts\shortcodes\link-in-code.html
路径创建文件(如不存在则创建),并添加以下代码:
1<!-- 目录树shortcode,可以在代码块中使用HTML链接 -->
2<div class="link-in-code">
3 <pre><code>{{ .Inner | safeHTML }}</code></pre>
4</div>
5
6<style>
7 .link-in-code pre {
8 background-color: var(--code-background-color, #f8f8f8);
9 padding: 1rem;
10 border-radius: 8px;
11 overflow-x: auto;
12 font-family: monospace;
13 }
14
15 .link-in-code a {
16 text-decoration: none;
17 color: #0366d6;
18 }
19
20 .link-in-code a:hover {
21 text-decoration: underline;
22 }
23</style>
将 Markdown 代码块替换为该 shortcode 后,虽然实现了超链接功能,但样式与原代码块有差异:
渲染结果:
优化 shortcode 样式
为了使自定义 shortcode 的样式更接近博客原有代码块样式,我们需要进一步修改 link-in-code.html
:
1<!-- 目录树shortcode,可以在代码块中使用HTML链接 -->
2<div class="article-content">
3 <div class="highlight link-in-code-custom">
4 <pre tabindex="0"><code>{{ .Inner | safeHTML }}</code></pre>
5 </div>
6</div>
7
8<style>
9 .link-in-code-custom {
10 max-width: 105% !important;
11 background-color: var(--pre-background-color);
12 padding: var(--card-padding);
13 position: relative;
14 border-radius: 20px;
15 margin-left: -10px !important;
16 margin-right: -15px !important;
17 box-shadow: var(--shadow-l1) !important;
18 }
19
20 .link-in-code-custom pre {
21 margin: 0;
22 padding: 0;
23 width: auto;
24 background-color: transparent;
25 font-family: monospace;
26 max-height: none;
27 overflow-x: auto;
28 }
29
30 [data-scheme="light"] .article-content .link-in-code-custom {
31 background-color: #FAFAFA;
32 }
33
34 [data-scheme="light"] .link-in-code-custom code {
35 color: inherit;
36 background-color: transparent;
37 }
38
39 .link-in-code-custom a {
40 text-decoration: none;
41 color: #0366d6;
42 background-color: transparent;
43 }
44
45 .link-in-code-custom a:hover {
46 text-decoration: underline;
47 }
48
49 .chroma .link-in-code-custom {
50 color: #ff6f00;
51 background-color: #FAFAFA;
52 }
53
54 @media (prefers-color-scheme: dark) {
55 .link-in-code-custom a {
56 color: #58a6ff;
57 }
58 }
59</style>
优化后的 shortcode 渲染效果与原代码块样式对比:
虽然仍有细微差异,但通过进一步调整 CSS 可以实现更加一致的视觉效果。
使用方法
在需要在代码块中嵌入超链接的地方,使用如下格式替代普通代码块:
优势总结
这种自定义 shortcode 解决方案具有以下优点:
- 功能完整:同时保留代码块的格式化显示和超链接的功能
- 灵活可控:通过自定义 shortcode ,我们可以完全控制渲染的方式和样式
- 视觉一致:可以通过 CSS 调整使其与博客整体风格保持一致
- 复用性强:在博客的任何地方都可以使用该 shortcode 实现相同效果
- 兼容性好:适应不同的主题和显示环境,包括暗黑模式
扩展应用
除了目录树结构外,这种方法同样适用于任何需要在代码块中嵌入超链接的场景,如代码示例中包含参考文档链接、 API 调用示例等。