2019/11/01

Python3で静的サイトジェネレータを自作してみる

leopa

Python3で静的サイトジェネレータを作ってみました。その名は「leopa」
leopaはヒョウモントカゲモドキの英名leopard geckoから命名し、ヒョウモントカゲモドキの愛称「レオパ」として使われています。
leopaのリポジトリはこちら

現在のところまだまだ荒削りなものですが、マークダウンでドキュメントを作成し、HTMLファイルに変換する機能があります。おおまかな使い方の流れは以下のようになります。

$ python3
>>> import leopa  # 1
>>> # この時プロジェクト名をProjectクラスに渡さなければ
>>> # デフォルトのprojectが使われる
>>> p = leopa.Project()  # 2
>>> p.create()  # 2
>>> p.reload()  # 3
>>> p.publish()  # 4
  1. Python3のインタラクティブシェルを起動し、インポートする。作業は起動したまま行う。
  2. Projectクラスを作成し、createでプロジェクトのディレクトリが作成されます。設定ファイルもその中に作成されます。
  3. 設定ファイルで諸々設定します。この時docsにドキュメントの構成をYAML形式で書きますと、reloadすることで自動でマークダウンファイルがその構成通り(ディレクトリも)に作成されます。
  4. 各ドキュメントを書き終えたら、publishpublicディレクトリにHTMLファイルが作成されます。
といった感じの流れになっています。
いつもぶち当たる壁としましては、CSSに関する部分です。どのように各HTMLファイルに反映するか。
現在のところ、設定ファイルで外部CSSのURLを書くようにするか、各マークダウンファイルのメタデータの部分で、CSSファイルへのリンクを書くようにするか、など色々悩んでおります。
デザインの好みは人それぞれなので、なかなか万人向けに作るのは難しいものです。改めて静的サイトジェネレータの難しさ・凄さを感じています。

markdownライブラリでメタデータを扱う

Pythonのmarkdownライブラリでは、デフォルトではメタデータを扱うことができません。したがって、スイッチオンにしなければなりません。やり方は簡単で通常は以下のように使うところ

>>> import markdown
>>> mk = markdown.Markdown()
以下のようにします。

>>> mk = markdown.Markdown(extensions=['meta'])
これで例えば以下のようなメタデータを持つマークダウンファイル(test.mdとする)がある場合

title: My title
autho: me

# Heading

brahbrahbrah...
以下のような方法で扱うことができるようになります。

>>> import markdown
>>> mk = markdown.Markdown(extensions=['meta'])
>>> with open('test.md', 'rt', encoding='utf-8') as f:
...     text = f.read()
...     content = mk.convert(text)
...     metadata = mk.Meta
...
>>> print(metadata)
{'title': ['My title'], 'author': ['me']}
>>> print(content)
<h1>Heading</h1>
<p>brahbrahbrah...</p>
markdownライブラリでは、メタデータは、辞書として返ってきて、キーは文字列、バリューは文字列のリストとなっているようです。使えることがわかると、結構役立ち、今回の静的サイトジェネレータではありがたい機能となりました。