はじめに

この記事はGitHubのコードを埋め込むテストのためのものです。
コード埋め込みというと、通常はバッククォート3つで囲い、Markdownに直接記述します。もちろんこれでも表示する上では問題ないのですが、少しもやっとします。プログラミングでコードを書き、さらにブログを執筆する際にもまだコードを書かなければならない。DRY原則 を忠実に守るためにも一度書いたコードを繰り返したくはありません。そこで、GitHubのコードを自動的に取得し、埋め込む仕組みを作ってみました。
なお、この仕組みはnkmkさんhexo-tag-github-codeを参考にして作っています。コードを公開してくださり誠にありがとうございます。

様々な種類のコードをGitHubから持ってきてみる

Rustコードのサンプル

昔作った決定性有限オートマトンのRustによる実装を埋め込んでみます。話は逸れますが、Rustのパターンマッチングってものすごく便利ですよね。パターンマッチングのおかげで状態遷移図を何も考えずにそのまま転写するだけで実装できました。

オリジナルコード

1
{% ghcode https://github.com/Tsutomu-Ikeda/rust-dfa/blob/master/src/main.rs 23 36 %}

埋め込み結果

main.rs#L23-L36GitHubでみる
23
24
25
26
27
28
29
30
31
32
33
34
35
36
impl fmt::Display for States {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let printable = match *self {
States::S0 => "S0",
States::S1 => "S1",
States::S2 => "S2",
States::S3 => "S3",
States::S4 => "S4",
States::S5 => "S5",
States::S6 => "S6",
};
write!(f, "{}", printable)
}
}

match を含めてすべての予約語がしっかりとハイライトされています。ただ変数名などはハイライトされていません。highlight.js の特性上あまり重い処理はできなさそうなので、しょうがないのでしょうか…

Pythonコードのサンプル

オリジナルコード

1
{% ghcode https://github.com/selelab/admin/blob/master/api/accounting/models.py 14 30 %}

埋め込み結果

models.py#L14-L30GitHubでみる
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Project(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=50)
description = models.CharField(max_length=500)
accounting_type = models.CharField(max_length=10,
choices=ACCOUNTING_TYPES,
default='soft')
leader = models.ForeignKey(User,
on_delete=models.PROTECT,
null=True,
blank=True)
closed = models.BooleanField(default=False)
date_created = models.DateTimeField(default=utils.timezone.now, editable=False)
date_updated = models.DateTimeField(auto_now=True, editable=False)

class Meta:
ordering = ['-date_updated', '-date_created', 'id']

Pythonも変数名がハイライトされていません。しかし、文字列リテラルや数値リテラルはしっかりと認識されているようです。

.zshrc のサンプル

.zshrc は頻繁に更新するファイルで、行がずれる恐れがあるため、コミットIDを指定して埋め込みました。

オリジナルコード

1
{% ghcode https://github.com/Tsutomu-Ikeda/settings/blob/b487a295006849856deaa5ec646e1b7e23a5ea6f/unix/home/.zshrc 118 128 %}

埋め込み結果

.zshrc#L118-L128GitHubでみる
118
119
120
121
122
123
124
125
126
127
128
export PATH="/usr/local/opt/mysql-client/bin:$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$HOME/.cargo/bin:$PATH"
export WORDCHARS="*?_-.[]~=&;!#$%^(){}<>"

source $HOME/.zsh/greeting.zsh

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh && source $HOME/.zsh/p10k.zsh

if [ -e "${HOME}/.iterm2_shell_integration.zsh" ]; then
source "${HOME}/.iterm2_shell_integration.zsh"
fi

一見ちゃんとハイライトされているように見えて実はうまく行っていません。コメントは1行しかないはずなのにずっと続いていることになってしまっています。