使用 Pandoc 将 markdown 链接转换为 html

Convert markdown links to html with Pandoc

在我的新项目中,我有多个相互 linked 的降价文件。 这些 link 指的是原始 .md 文件。

示例: 文件 README.md

...
1. [Development documentation](Development.md)
1. [User documentation](Usage.md)
...

如果我用 Pandoc 转换这些文件,例如html 文件,所有 link 仍然指向原始 .md 文件。我正在寻找的是一种也可以转换 link 类型的方法,这意味着输出文件应该引用输出文件类型,例如 HTML、PDF、TeX 等。有没有办法使用 Pandoc 转换内部 link 类型?

我用它来转换文件:

pandoc -f markdown -t html5 input.md -o output.html

您可以创建一个过滤器来检查每个 link 元素,如果 url 以 .md 结尾,则将其替换为 .html

示例 Python,使用 panflute 包:

import panflute as pf

def action(elem, doc):
    if isinstance(elem, pf.Link) and elem.url.endswith('.md'):
        elem.url = elem.url[:-3] + '.html'
        return elem

if __name__ == '__main__':
    pf.run_filter(action)

假设您要通过网络服务器为您提供 html 页面,将所有 *.md url 解析为 *.html 相对简单,而不是通过 pandoc 重写它们,例如使用 NGinx:

location ~ \.md$ {
  if (!-f $request_filename) {
    rewrite ^(.*)\.md$  permanent;
  }
}

location / {
  try_files /$uri /$uri.html;
}

或者,您可以使用 sed 将所有 md 链接替换为 html (取自 here):

Change all internal file urls from pointing to *.md links and instead point to the local *.html file

  1. recursively run this sed command (programatically replace FILENAME)

    sed -n -i.bak '/href="\./s/\.md/\.html/' FILENAME.html
    
  2. alternatively, run the following command instead (programatically replace FILENAME)

    sed -e '/href="\./s/\.md/\.html/' FILENAME.html > FILENAME.html.tmp && mv FILENAME.html.tmp FILENAME.html`
    

我遇到了类似的问题,所以我做了这个:https://github.com/MatrixManAtYrService/md_htmldoc

它在目录中找到所有 .md 文件,然后创建一个单独的目录,其中所有 markdown 已转换为 html。

它修复了超链接(感谢@Sergio_Correia的回答)。

它还会收集所有本地文件引用,以便图像链接等仍然有效

built-in Lua filters 示例:

# links-to-html.lua
function Link(el)
  el.target = string.gsub(el.target, "%.md", ".html")
  return el
end

然后:

pandoc -f markdown -t html5 input.md -o output.html --lua-filter=links-to-html.lua

对于使用 Makefile 驱动转换的任何人,这里有一个 Makefile 片段,它提供了将 .md 转换为 .html 并调整了 link 的规则:

SHELL=/bin/bash

%.html: %.md
    ( set -eu -o pipefail ; \
    pandoc -i $< -t html | \
    sed -E 's/<a href="([^"]*).md/<a href=".html/g' > $@.tmp && mv -vf $@.tmp $@ ; )

如果当前目录中存在 test.mdmake test.html 会这样做。

该规则还注意在转换真正成功之前不要破坏现有的 HTML 文件(无论什么原因)。

对 Sergio Correia 的回答稍作修改 也可以捕获文档中的锚链接。请注意,在极少数情况下,这可能会使链接出现乱码...

import panflute as pf

def action(elem, doc):
    if isinstance(elem, pf.Link):
        if elem.url.endswith('.md'):
            elem.url = elem.url[:-3] + '.html'
            return elem
        elif elem.url.find('.md#'):
            elem.url = elem.url.replace('.md#', '.html#')
            return elem

if __name__ == '__main__':
    pf.run_filter(action)