我正在用 Jekyll 和用 Markdown 编写的 Github-Page 构建一个网站。我希望能够轻松地永久链接到标题,就像大多数在线文档所做的那样。
我想在单击标题时获取带有哈希值的 URL。在 Kramdown 或 Jekyll 的配置中是否有一种简单的方法可以实现这一点?
Markdown 页面
#### A regular header
A regular sentence.
理想的结果
<h4 id="a-regular-header"><a href="#a-regular-header">A regular header</a></h4>
<p>A regular sentence.</p>
您可以在每个标题的 Markdown 中手动执行此操作:
#### [A regular header](#a-regular-header)
A regular sentence.
缺点是维护成本。另一种选择是通过将其添加到所选页面的底部来在客户端创建链接:
<script>
var headings = document.querySelectorAll("h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]");
for (var i = 0; i < headings.length; i++) {
headings[i].innerHTML =
'<a href="#' + headings[i].id + '">' +
headings[i].innerText +
'</a>';
}
</script>
如果 JavaScript 依赖项不适合您的受众,您可以考虑使用插件、修改后的 Markdown 解析器或任务运行器(例如 gulp.js)在构建时执行此操作。如果您希望 GitHub Pages 构建您的页面,则不能使用这些替代方案,但您可以在本地构建并提交输出。
如果您想要一种无需 JavaScript 的 GitHub Pages 兼容方式来执行此操作,您可以使用 Liquid 获得 crazy creative,并仔细将渲染的 HTML 解析为字符串并按此操作。
或者您可以使用这个代码片段来实现这一点:https://github.com/allejo/jekyll-anchor-headings
您可以使用 Jekyll plugins 来覆盖标准行为。我把这个放进去
_plugins/header.rb
:
class Jekyll::MarkdownHeader < Jekyll::Converters::Markdown
def convert(content)
super.gsub(/<h(\d) id="(.*?)">/, '<h\1 id="\2"><a href="#\2">§</a>')
end
end
正则表达式将所有带有 ID 标签的标头替换为还添加链接的标头。在一般情况下,这不是一个万无一失的方法(例如
<h2 class="foo" id="x")
不起作用),但 Kramdown 输出相当可靠且一致,所以应该没问题。我用 Jekyll 3.8.4 和 Kramdown 1.17.0 添加了这个。
如果您想要/需要更强大的解决方案,那么您可以使用 HTML 解析器。应该不会那么难。
这样做的好处是客户端不需要 JavaScript。
或者如果您想链接实际标题而不是预先添加链接:
class Jekyll::MarkdownHeader < Jekyll::Converters::Markdown
def convert(content)
super.gsub(/<h(\d) id="(.*?)">(.*)<\/h(\d)>/, '<h\1 id="\2"><a href="#\2">\3</a></h\1>')
end
end
从生成器的角度来看,如果没有 Jekyll 插件,这是不可能的。由于您使用的是 GitHub Pages,这是不可能的,因为它们不支持自定义插件。
一个合理的解决方案是创建一个脚本,查找所有带有 ID 的标题并将它们转换为链接或附加链接图标。
header_links
选项,它生成一个空的 <a>
标签作为标题的第一个子项:
<h2 id="participate"><a href="#participate"></a>Participate</h2>
然后,您可以使用 CSS 将内容放入该链接中,并使其在适当的时间显示。一种选择如下,但您可能需要调整它:
[id]:hover > a:first-child::before {
content: "#"
display: inline-block;
margin-inline-start: -1em;
width: 1em;
}