从Jekyll迁移到Hexo
上周,我将博客从jekyll平台迁移到hexo下。
缘起
不为什么。本来不想换,奈何不能成功在ubuntu 14.10上用rvm成功编译=ruby 2.1+=,连续几次过热自动关机后,就默默装上了基于node的hexo。
迁移记录
对jekyll,日志源文件都在=posts/=目录下。而hexo则在=sources/posts/=下。两者支持的都是带metadata的markdown文件。(当然,我还有一些用textile标记的文件。)简单来说,只要把相应的markdown文件迁移到hexo对应的位置就行。
但在迁移碰到了几个问题:
- 修正permalink
- 语法高亮部分修改
- 特殊字符escape
- textile文件
与jekyll之前配置一致的url结构和文件命名方式
以前,我用jeykll时,每个文件名字如下:
2012-11-19-this-is-a-post.md
对应的url为
http://reverland.org/2012/11/19/this-is-a-post/
或者可以是
http://reverland.org/2012/11/19/this-is-a-post http://reverland.org/2012/11/19/this-is-a-post/index.html
首先,要把hexo也改成这样的,在=config.yml=中:
new_post_name: :year-:month-:day-:title.md # File name of new posts permalink: :category/:year/:month/:day/:title/
但,还是有问题,具体可以参照我提的issue,hexo如果看你的文件名是这样:
2014-06-12-.md
会生成这样的url
2015/11/13/2014-06-12.html
显然这不是我们想要的。
我们通过将=nodemodules/hexo-util/lib/permalink.js=第28行由
return '(.+?)';
更改为
return '(.*?)';
可以实现以前的jekyll风格。
如果你现在用的是hexo版本=3.1.0=,如果文件是:
可能会遇到生成这种url链接:
http://reverland.org/2014/06/12//index.html http://reverland.org/2014/06/12//
在github中hexo已经不会有这个问题了,可以参见 hexo/helper/url\for的
return path.replace(/\/{2,}/g, '/');
来进行修改,如果你用的不是git版本的hexo。
我之后还碰到个问题,hexo中的分类是大小写敏感的,jekyll也是,但jekyll在url中会统一变成小写而hexo则不会,这竟然造成了我迁移后的一些链接失效。修正方法也很简单,通过=sed=将所有大写的=category=项都替换成对应的小写版本。
sed -i 's/^category: Life/category: life/g' source/_posts/*.md # 我只有Life分类莫名写成了大写
这样,确保了和jekyll之前所有链接一致,然而,发现还是有disqus的评论消失了,检查链接并没有差异,暂时不知为什么。如果有谁能指教下请告诉我。
语法高亮修改
jekyll中,除了我用四个空格作为编码块区域缩进设定,还广泛使用了jekyll所特有的记法进行代码高亮。
{% highlight python %} def sum(a, b): return a + b; {% endhighlight %} {% highlight cl%} (cdr, (add, 1, 1)) {% endhighlight %}
另外,我的每个文件里还有些jekyll特定命令来加入统计和评论什么的。这是当年从Skydark那里画虎不成留下的各种dirty hack的结果。
{% include JB/setup %}
可以这样转换掉
sed -i 's/{%[[:space:]]highlight[[:space:]]\(.*\)[[:space:]]*%\}/```\1/g' source/_posts/*.md # 注意有空格和没空格 sed -i 's/{%[[:space:]]endhighlight[[:space:]]%\}/```/g' source/_posts/*.md sed -i 's/{%[[:space:]]include JB\/setup[[:space:]]%\}//g source/_posts/*.md'
特殊字符escape
接着有些特殊的文件会解析报错,因为hexo用nunjunks来渲染,如果文本中有={{ }}=或者={% %}=会出错。我发现如果是缩进四格的代码标记或者```会出错,但如果用另一种标记法 `````则没关系。
实在不行,我们可以用html实体编码。
<code>abc</code>
textile文件
我试着用pandoc转换了下,发现几个问题:
- 会将metadata错误地转换
- 莫名的在行或特殊符号后面加反斜杠
- 不能很好处理jekyll的代码高亮标记法
我写了些脚本辅助手工更改为markdown格式。话说这些sed代码还都是之前尝试往pelican上迁移时写的辅助脚本,虽然从来没有迁移到pelican平台上。
# 删除和转换jeykll特定标记 sed -i 's/{%[[:space:]]include JB\/setup[[:space:]]%\}//g' source/_posts/*.textile sed -i 's/{%[[:space:]]highlight[[:space:]]\(.*\)[[:space:]]*%\}/```\1/g' source/_posts/*.textile sed -i 's/{%[[:space:]]endhighlight[[:space:]]%\}/```/g' source/_posts/*.textile # textile标记到markdown的转换 # 列表 sed -i 's/^* /- /g' source/_posts/*.textile sed -i 's/^# /- /g' source/_posts/*.textile # 标题 sed -i 's/^h1./#/g' source/_posts/*.textile sed -i 's/^h2./##/g' source/_posts/*.textile sed -i 's/^h3./###/g' source/_posts/*.textile sed -i 's/^h4./####/g' source/_posts/*.textile sed -i 's/^h5./#####/g' source/_posts/*.textile # 脚注 sed -i 's/^fn\([[:digit:]]\)\./[\^\1]:/g' source/*.textile sed -i 's/\[\([[:digit:]]*\)\]/[\^\1]/g' source/*.textile # 默认的markdown解析并不支持脚注 # 如果需要,参考这里替换默认markdown解析,https://github.com/celsomiranda/hexo-renderer-markdown-it # 可惜这个引擎中,```块就不能正常解析{{ }}这种东西了 # 不知道那个pandoc后端的怎样。 # 链接 sed -i 's/"\([^"]*\)"\([h|\/].*\)/[\1](\2)/g' source/*.textile sed -i 's/"\([^"]*\)"\([^h\/].*\)/[\1][\2]/g' source/*.textile # 最后把后缀改了,hexo不会处理后缀是textile的文件 for file in source/_posts/*.textile; do cp $file source/_posts/`basename $file .textile`.md done
当然,最好脚本辅助,手工确认。
另外,有这么个东西hexo render pandoc来替换hexo的渲染引擎,就能顺便支持textile。值得一试和研究,也许里头就用到对文档元数据或者跳过指定行数的转换吧。没有细看。话说,还看到[@CodeFalling](http://codefalling.com/2015/11/15/new-version-of-hexo-renderer-org/)使用emacs来做org渲染后端,hexo的灵活性可见一斑。
feed
默认的hexo竟然不像jekyll一样有feed生成支持!不过有hexo-generator-feed这个插件来实现。具体参照文档就好。
添加友情链接、分类页、标签页
根据根据Next主题的文档来就好。