You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Hakyll/Pandoc中为标题添加自链接?

给Hakyll博客标题添加自链接的实现方案

方法一:启用Pandoc章节Div+CSS样式

  • 修改站点配置文件:在site.hs中启用Pandoc的writerSectionDivs选项,让每个标题对应带ID的容器:
import Hakyll
import Text.Pandoc.Options

main :: IO ()
main = hakyll $ do
    -- 保留原有路由和规则
    match "posts/*" $ do
        route $ setExtension "html"
        compile $ pandocCompilerWith defaultHakyllReaderOptions customWriterOpts
            >>= loadAndApplyTemplate "templates/post.html" postCtx
            >>= loadAndApplyTemplate "templates/default.html" postCtx
            >>= relativizeUrls

customWriterOpts :: WriterOptions
customWriterOpts = defaultHakyllWriterOptions
    { writerSectionDivs = True
    }
  • 添加CSS样式:在全局CSS文件中加入以下代码,实现hover时显示锚点链接:
h1, h2, h3, h4, h5, h6 {
    position: relative;
    padding-left: 1.2em;
}

.header-anchor {
    position: absolute;
    left: 0;
    opacity: 0;
    transition: opacity 0.2s;
    text-decoration: none;
    color: #999;
}

h1:hover .header-anchor,
h2:hover .header-anchor,
h3:hover .header-anchor,
h4:hover .header-anchor,
h5:hover .header-anchor,
h6:hover .header-anchor {
    opacity: 1;
}

.header-anchor::before {
    content: "#";
}

方法二:使用Pandoc过滤器直接注入链接

如果需要更灵活的控制,可编写Pandoc过滤器给每个标题添加自链接:

  • 编写过滤器函数:在site.hs中添加以下代码:
import Hakyll
import Text.Pandoc
import Text.Pandoc.Walk

-- 给标题添加自链接
addHeaderAnchors :: Pandoc -> Pandoc
addHeaderAnchors = walk transformHeader
  where
    transformHeader :: Block -> Block
    transformHeader header@(Header _ (id', _, _) _)
        | not (null id') =
            let anchor = Link ("header-anchor", [], []) [Str "#"] ("#" <> id', "")
                newContent = anchor : headerContent header
            in setHeaderContent newContent header
    transformHeader x = x

-- 辅助函数:获取和设置标题内容
headerContent :: Block -> [Inline]
headerContent (Header _ _ content) = content
headerContent _ = []

setHeaderContent :: [Inline] -> Block -> Block
setHeaderContent content (Header level attr _) = Header level attr content
setHeaderContent _ x = x
  • 应用过滤器到编译流程:修改文章编译规则,加载过滤器:
match "posts/*" $ do
    route $ setExtension "html"
    compile $ pandocCompilerWithTransform
        defaultHakyllReaderOptions
        defaultHakyllWriterOptions
        addHeaderAnchors
        >>= loadAndApplyTemplate "templates/post.html" postCtx
        >>= loadAndApplyTemplate "templates/default.html" postCtx
        >>= relativizeUrls

两种方法都能实现:访客将鼠标悬停在标题上时,会显示#样式的锚点链接,点击即可直接获取该章节的锚点URL,无需查看页面源代码。

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:33:25