tDiaryの日記を静的サイトジェネレータで表示したい (1)
最近は日記の更新頻度がすっかり減った。とはいえ、過去の日記は自分のためにも見返せるようにしておきたい。そこで、そろそろtDiaryで書いてきた日記を、tDiaryがなくても表示できるようにしておこう。
考えることはいろいろある。
- 日記をどのように表示するか
- 日記データの取り出し方
日記をどのように表示するか
tDiaryが生成したHTMLファイルをそのままWebサーバでホスティングすることもできるが、今後のことを考えて静的サイトジェネレータ (SSG) を使うことにする。静的サイトジェネレータには、Hugo, Jekyll, Gatsby, Next.jsなどがある。それぞれ一通り触ってみたところ、すぐに動かすなら Hugo、細かくカスタマイズしたいなら Next.js が良さそうだった。まずは日記データを取り出せるところから確かめたいので、すぐに動かせるHugoを使ってみる。
日記データを取り出す
tDiaryは複数の記法(スタイル)に対応している。この日記は最近ではMarkdown (GFMスタイル)を使っていて、以前はHiki形式 (Wikiスタイル) を使っていた。
1つ目は、Markdown形式でSSGツールに読み込ませる方法。これはHiki形式の日記をMarkdownに変換するのが大変そう。それから、インラインプラグインを使っている箇所は何らかの手段で変換しないといけない。
2つ目は、tDiaryが出力したHTML形式をSSGツールに読み込ませる方法。日記のスタイル(Markdown, Hiki)に依存せず読み込めることがメリット。
tDiaryには、生成したHTMLファイルをファイルで保存する squeeze.rb というプラグインがある。これを改造し、SSGツール (Hugo) での読み込みに必要なFrontMatter付きのHTMLを出力できるようにした。
- 日単位ではなくセクション単位でHTMLを生成する
- FrontMatterにtDiaryのタグ情報を記載
squeeze.rbの改造箇所
module ::TDiary
class YATDiarySqueeze
def execute
dest = @dest
diary = @diary
suffix = @suffix
template = File.read("hugo.rhtml")
Dir.mkdir(dest, 0755) unless File.directory?(dest)
section_index = 0
diary.each_section do |section|
section_index += 1
load_plugins
filename = format("#{diary.date.strftime('%Y%m%d')}p%02d#{suffix}", section_index)
begin
html = @plugin.eval_src(ERB.new(section.body_to_html || section.subtitle).src)
rescue => e
STDERR.puts "plugin error at #{filename}"
STDERR.puts e
html = section.body_to_html
end
props = {}
props["title"] = section.stripped_subtitle
props["date"] = diary.date
props["url"] = URI.parse(@conf.base_url + filename).path
props["lastmod"] = diary.last_modified
props["draft"] = ! diary.visible?
props["tags"] = section.categories unless section.categories.empty?
props["categories"] = "#{diary.date.year}/#{diary.date.month}"
props["summary"] = @conf.shorten(remove_tag(html), 100)
props["aliases"] = [ URI.parse(@conf.base_url + @plugin.anchor(diary.date.strftime('%Y%m%d'))).path ]
r = ERB.new(template).result(binding)
# binding.irb
File::open("#{dest}/#{filename}", 'w') {|f| f.write(r) }
end
diary.date.strftime('%Y%m%d')
end
def remove_tag( str )
str.gsub( /<[^"'<>]*(?:"[^"]*"[^"'<>]*|'[^']*'[^"'<>]*)*(?:>|(?=<)|$)/, '' )
end
end
end
hugo.rhtml
<%= props.to_yaml %>
---
<%= html %>
tDiaryを設置してあるルートディレクトリでこのツールを動かす。
bundle exec ruby squeeze.rb -x .html -s html
FrontMatter付きのHTMLを生成できた。
---
title: tDiaryのプレビュー画面を横並びで表示
date: 2016-05-07 00:00:00.000000000 +09:00
url: "/diary/20160507p01.html"
lastmod: 2016-05-08 06:32:03.000000000 +09:00
draft: false
tags:
- tDiary
categories:
- '201605'
summary: tDiaryのプレビュー画面をリアルタイムで更新するpreviewプラグインを、横並びでいい感じに表示できるようにした。これでまた、日記が書きやすくなったよ。 以前は縦に並んでいたので、更新する..
aliases:
- "/diary/20160507.html"
---
<p>tDiaryのプレビュー画面をリアルタイムで更新するpreviewプラグインを、<a href="https://github.com/tdiary/tdiary-contrib/pull/157">横並びでいい感じに表示できるようにした</a>。これでまた、日記が書きやすくなったよ。</p>
(以下略)
出力したHTMLファイルをhugoに取り込むと、ほぼカスタマイズなしでいい感じに表示された。タグもちゃんと引き継がれている。
セクションごとにHTMLファイルを分けるようにしたので、次はURLをどうするかを考えないとな。