之前从 hexo 转成 hugo 的时候,顺便用了使用非常方便的 ox-hugo 这个轮子。当时贪图省力,就直接用 pandoc 将 markdown 文件批量转换成了 orgmode,但是所有的 metadata 全都没能转换,后期还是得一个一个改。虽然是一个重新审阅自己黑历史的方式,但是要改四百多篇确实还是太过费心费力了。事情一变得繁杂起来,我的拖延症就犯了,于是直到现在我还是只改好了十几篇。今天终于忍不住了,动手看起了 pandoc 文档。

Pandoc 可以自己设置 template,其中 orgmode 的 template 长这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$if(title)$
#+TITLE: $title$

$endif$
$if(author)$
#+AUTHOR: $for(author)$$author$$sep$; $endfor$
$endif$
$if(date)$
#+DATE: $date$

$endif$
$for(header-includes)$
$header-includes$

$endfor$
$for(include-before)$
$include-before$

$endfor$
$body$
$for(include-after)$

$include-after$
$endfor$

所以我重新写了一个 orgmode 的 template,这样可以按照 ox-hugo 的模板导出 org 文档。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
,*** $if(title)$$title$$endif$  :$for(categories)$@$categories$$sep$:$endfor$:$for(tags)$$tags$$sep$:$endfor$:
    :PROPERTIES:
    :EXPORT_FILE_NAME: $if(sourcefile)$$sourcefile$$endif$
    :EXPORT_DATE: $if(date)$$date$$endif$ +0800
    :EXPORT_HUGO_SLUG: $if(url)$$url$$endif$
    :EXPORT_HUGO_WEIGHT: $if(id)$-$id$$endif$
    :EXPORT_HUGO_CATEGORIES: $for(categories)$$categories$$sep$, $endfor$
    :END:

$body$

但是 pandoc 1.17.1 的更新中还赋予了 org writer 在每级标题下添加 :PROPERTIES: 抽屉和 CUSTOM_ID 的功能,这对我来说有些累赘。所以需要写一个 Lua filter来避免:

1
2
3
function Header (header)
  return pandoc.Header(header.level+3, header.content, pandoc.Attr())
end

本来还想使用 Lua filter 把之前导出的 markdown 文件中误识别的四级标题也处理掉,无奈实在看不明白 Pandoc 作者弄的Header.content 为什么是 list of inlines,sed 对中文支持又不好,只能手动替换了。

另外我还使用了几个extension

  • markdown去除了span和div标记
  • hard_line_breaks将hard_line_breaks改成\\\\
  • lists_without_preceding_blankline来避免列表不被识别

很奇怪的是所有中英交杂的文字中的英文间的空格都会被pandoc识别为换行,由于code之类并未被替换,所以一时我也想不到什么比较好的方法来恢复空格,这能先这样了。

1
pandoc -f markdown+lists_without_preceding_blankline+hard_line_breaks --template template.org --lua-filter=remove_custom_id.lua ./posts/*.md -o output.org

由于使用了 template 和 Lua filter,所以不能像上面这样简单地 bulk convert,在这儿我使用find指令批量转换并合并为一个org文档:

1
2
3
4
mkdir output
find . -name "*.md" -type f -exec sh -c 'pandoc -f markdown+lists_without_preceding_blankline+hard_line_breaks --template ./../template.org --lua-filter=./../remove_custom_id.lua "${0}" -o "./output/$(basename ${0%.md}.org)"' {} \;
cat ./output/*.org > all.org
rm -r output