はてなブログの記事を Next.js 製ブログにインポート
旧ブログ の記事の移行が終わりました。
Rust のパーサコンビネータ nom の使いかたに慣れるため JSON parser を作ったりと寄り道が激しかったです。
はてなブログから記事をエクスポートすると Movable Type で書かれた txt ファイルをダウンロードできます。
これを変換して markdown で書いているこのサイトでインポートできるようにしたい。
Movable Type のフォーマット にちゃんと対応するのは大変なので必要なところだけ対応した。
movable_type_to_markdown
作った移行ツールがこちら https://github.com/wat-aro/movable_type_to_markdown
使ったことがなかったので clap や anyhow を使ってみた。
to_markdown といいつつ、実際は Movable Type ファイルに入っていた html のまま。
最初は html からマークダウンにしようかと考えていたけれどコードブロックの pre
タグがめんどくさすぎて断念。
cargo run MOVABLE_TYPE_FILE OUTPUT_DIRECTORY
で OUTPUT_DIRECTORY に変換した markdown ファイルを出力できます。
作りはシンプルに パースして記事用のオブジェクトを作成してファイル作成。
はまりどころ 1
Movable Type の複数行フィールド・セクションは -----\n
によって区切られている。
本文で -----------\n
などが使われている箇所があったためパースできなくなってしまった。
セパレータは行頭から開始される場合に限るため \n-----\n
で判定することでなんとかなった
はまりどころ 2
コードブロック以外はそのままの html でそれなりに表示されているのでそれでよしとした。
ただコードブロックはいかんともしがたく。
これはこちらのサイト側で対応。
はてなブログのコードブロックの pre
タグ直下に code
タグを入れて children をラップすると、ハイライトされないが改行はきちんと反映されることがわかった。
ただし、markdown で書いたコードブロックを使っているため、pre
タグのクラス名に code
が含まれている場合にはてなブログのコードブロックだと判定するようにした。
このサイトは unified
を使ってマークダウンから html に変換している。
以下の plugin を追加することでコードブロックを表示できるようにした。
export const rehypeHatenaCodeBlock: Plugin = () => {
return (tree, file) => {
visit(tree, 'element', (node: Element) => {
if (
node.tagName == 'pre' &&
node.properties?.className &&
Array.isArray(node.properties.className) &&
node.properties.className.includes('code')
) {
const children = node.children;
const code = {
type: 'element',
tagName: 'code',
properties: {},
children: children,
} as ElementContent;
node.children = [code];
}
return true;
});
};
};
今後の展望
今は全件表示されているため、次はページネーションを導入するぞい。