把 blog 从 Movable Type 迁移到了 Hugo
花了些时间把 blog 从 Movable Type 迁移到了 Hugo。
说起来 Movable Type 已经用了有十七年之久了,不过 Movable Type 商业化以后便基本没有更新了, 由于它是 Perl 写的,因此我也没什么动力去持续维护。
由于 Movable Type 自己就是一个输出模板的引擎,因此考虑使用它来直接输出一套 Markdown 的格式的文本应该就可以了。 不过,我发现没有什么特别好的 Perl HTML -> Markdown 逆向转换的现成的库,那么比较明显的办法便是仍然让它正常输出 HTML, 然后用自己的脚本来把 HTML 转换成 Markdown。
第一步是做一个叫 Markdown 的页面(Entries)模板。
---
title: "<mt:entryTitle encode_php="qq" replace="\$","$">"
date: <$MTEntryDate format_name="iso8601" utc="1" $>
lastmod : <$MTEntryModifiedDate format_name="iso8601" utc="1" $><mt:EntryIfTagged>
tags: [<mt:EntryTags glue=', '>"<$mt:TagName$>"</mt:EntryTags>]</mt:EntryIfTagged>
categories: [<mt:EntryCategories glue=', '>"<$mt:CategoryLabel$>"</mt:EntryCategories>]
aliases:
- <$mt:EntryPermalink replace="https://blog.delphij.net",""$>
- /archives/<$mt:EntryID pad="6">.html
---
<mt:MarkdownOptions>
<mt:If tag="EntryBody">
<$mt:EntryBody$>
</mt:If>
<mt:If tag="EntryMore">
<!--more-->
<$mt:EntryMore$>
</mt:If>
<mt:IfCommentsActive>
<hr>
<mt:Comments lastn="1000">
<mt:CommentsHeader><h4>Archived: <$mt:EntryCommentCount singular="1 Comment" plural="# Comments" none="No Comments"$></h4></mt:CommentsHeader>
<$mt:CommentAuthorIdentity$><b><mt:IfCommentParent><$mt:CommentAuthorLink$> replied to comment from <mt:CommentParent><$mt:CommentAuthor$></mt:CommentParent> | <$mt:CommentDate$><mt:Else><$mt:CommentAuthorLink$> | <$mt:CommentDate$></mt:IfCommentParent></b>
<$mt:CommentBody$>
</mt:Comments>
</mt:IfCommentsActive>
<mt:IfPingsActive>
<hr>
<h4>Archived: trackbacks</h4>
<mt:Pings>
<b><a href="<$mt:PingURL$>"><$mt:PingTitle$></a> from <$mt:PingBlogName$> on <a href="#ping-<$mt:PingID$>"><$mt:PingDate$></a></b>
<p><$mt:PingExcerpt$> <a href="<$mt:PingURL$>">Read More</a></p>
</mt:Pings>
</mt:IfPingsActive>
</mt:MarkdownOptions>
这里把目前的回应全部转换成了页面的一部分。这个也不算特别理想,但是因为还没想好把回应弄到什么里面去,加上大部分回应已经是很久以前的了,索性就先这么做吧。
接下来就是把 HTML 转化为 Markdown 了。我使用的是一个叫 html2markdown 的 Python 库,为了满足迁移的需要,我自己做了少量的修改。 脚本本身非常简单:
import html2markdown
import os
import sys
import html
def mdify(input_name):
if not input_name.endswith('.html.md'):
raise ValueError("Bad name: %s" % input_name)
lines = open(input_name).read().split('\n')
# Find out the second ---
location = [i for i,x in enumerate(lines) if x == '---'][1]
# Get the YAML
yaml = '\n'.join(lines[:location+1])
# Get the HTML
html_content = '\n'.join(lines[location+1:])
# markdownify
md = html.unescape(html2markdown.convert(html_content))
output_name = input_name[:-8] + '.md'
output_file = open(output_name, 'w')
output_file.write(yaml)
output_file.write('\n')
output_file.write(md)
output_file.close()
os.remove(input_name)
for file in sys.argv[1:]:
print("Processing: %s\n" % (file))
mdify(file)
最后直接用 find . -name '*.html.md' -type f -exec python3 ~/convert.py {} +
转换就可以了。
在迁移过程中,主要遇到了以下一些问题:
- 很多曾经存在的网站都已经没有了。这个问题没有太好的解决方法,只能有时间慢慢整理了。目前的想法是如果有 互联网档案馆 的副本,则尽量使用这些副本;如果没有的话,就只能这么算了。
- 一些原有的内部链接损坏。在某次 Movable Type 版本升级的过程中,一些旧的链接被破坏掉了, 这次迁移的过程中吸取了这一教训,一部分其他网站链接本blog的链接将会提供一个永久性转向。
- 原有的内部图片丢失。我之前使用 Gallery3 做了一个相册并在 blog 中使用了其中的内容,由于 Gallery3 在几年前停止维护,于是我也把 Gallery3 的服务停掉了。这次搬移的过程中发现了这些图片死链, 目前的做法是直接粗暴地改为静态图片,令其看上去大致上还可以看。
一些留待后续解决的问题: