kamidanaのreadmeの生成にkamidanaを使うことにした

github.com

kamidanaのreadmeの生成にkamidanaを使うことにした。便利で良かった。ちょっとしたセルフホスティング的な何か(意味的には違う)という感じになり面白かったのでちょっとだけ文章にしてみる。あとjinja2にけっこう便利な組み込みのフィルターが存在することに気づいていなかった(組み込みのフィルターはこのあたりに書いてある(実際はコードを覗いた方が早い))。

便利なfilter

個人的に便利だと思ったのはindentというフィルター。これとReSTの相性がとても良い。特に以下の様なフィルターを用意してindentと一緒に使うと便利だった。

import subprocess
from kamidana import as_filter


@as_filter
def read(filename):
    with open(filename) as rf:
        return rf.read()


@as_filter
def spawn(cmd, encoding="utf-8"):
    p = subprocess.run(
        cmd,
        shell=True,
        check=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )
    return p.stdout.decode(encoding)

ちょっとしたファイルの参照にread + indent

ちょっとしたコードをcode-blockでwrapして載せるのにはread + indentが便利。例えば以下の様なpythonのコードがあったとして

def hello():
    return "hello"

これをReST上に載せると以下のようになる。インデントが必要になるのが面倒くさい。

.. code-block:: python

  def hello():
      return "hello"

ここで先程のreadとindentのフィルターを使うと以下の様に書ける。

.. code-block:: python

{{"./hello.py"|read|indent(2, True)}}

先頭もインデントしてほしければ、第二引数にTrueを渡す。

コードの実行結果を載せるのにspawn + indent

何らかのリポジトリにコマンドの実行結果を載せたい場合はよくある。このときにもjinja2のindentが便利。例えばlsのコマンドの結果をsortした結果を載せたりしたい場合に以下の様に書く。

.. code-block:: bash

  $ ls -l | sort
  <ls -l | sortの結果をコピペ>

これを先程のspawnを利用して以下の様に書くことができる。with extensionsも有効にしておくと便利。

.. code-block:: bash

{% with cmd="ls -l | sort" %}
  $ {{cmd}}
  {{cmd|spawn|indent(2)}}
{% endwith %}

というよりもここまで書いてみて思ったのだけれど。jinja2が便利と言うよりはReSTを扱うのにインデントを強要されるのがだるく。このインデントの対応にjinja2のindentフィルターがとても便利ということだった。

そんなわけでkamidanaのreadmeを書くのにkamidanaを使った

そんなわけでkamidanaのreadmeを書くのにkamidanaを使った。Makefileでreadmeを呼ぶとreadmeが生成される。Makefileはこういう感じ。 (additionals.pyにspawn,readが定義されている)

readme:
  kamidana misc/readme.rst.jinja2 --additionals misc/additionals.py > README.rst

このコミット https://github.com/podhmo/kamidana/commit/45c8a5c29622354a30e74eeb62feb5eb8a75f25f