自定义 shortcode 实现代码块嵌套超链接

通过自定义 shortcode 实现在 Hugo 的 Markdown 中代码块能够嵌套超链接。

问题背景

在 Hugo 中, Markdown 的代码块内嵌套超链接时会遇到问题:渲染后的超链接无法正常生效。这是因为代码块会将所有内容视为纯文本,不会解析HTML标记。 代码块中的超链接不生效

常见解决方案及其局限性

使用普通文本或引用块

将代码块改为普通文本或引用块确实可以让超链接生效,但排版效果不理想,无法保持代码的格式化显示。 普通文本中的超链接

直接添加HTML链接标签

尝试在代码块中直接使用 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 样式

为了使自定义 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 解决方案具有以下优点:

  • 功能完整:同时保留代码块的格式化显示和超链接的功能
  • 灵活可控:通过自定义 shortcode ,我们可以完全控制渲染的方式和样式
  • 视觉一致:可以通过 CSS 调整使其与博客整体风格保持一致
  • 复用性强:在博客的任何地方都可以使用该 shortcode 实现相同效果
  • 兼容性好:适应不同的主题和显示环境,包括暗黑模式

扩展应用

除了目录树结构外,这种方法同样适用于任何需要在代码块中嵌入超链接的场景,如代码示例中包含参考文档链接、 API 调用示例等。

使用 Hugo 构建, 主题 StackJimmy 设计
本博客已稳定运行:, 共发表了10篇文章