この前Octopressをアップデート
して、
Jekyllがバージョン2になったり色々変更があったんですが、
過去のcodeblock
関連の所が表示がおかしくなっていたので
それを修正したのと、
エラーにならない予期しない動作を防げる様に
色々ポストの変換前のMarkdownファイルをチェックする様にした話。
見つかった問題
codeblock
で書いてる次の様な部分:
次のコード:
{% codeblock %}
test
{% endcodeblock %}
が、ページ上で
次のコード:<div class=’bogus-wrapper’>
<div class=”highlight”><table><tr><td class=”gutter”><pre class=”line-numbers”>1 </pre></td><td class=’code’><pre>test code</pre></td></tr></table></div>
みたいにHTMLのソースがそのまま表示されていました。
問題はcodeblock
のすぐ上の行が空白行ではないことです。
以前も、MarkdownのパーサーをKramdownへ変更
を行った際にインデントでのコード表示や
引用(>
)の部分の前に空白行が無いときちんと表示されない問題が出ましたが、
KramdownかJekyllのアップデートでcodeblock
の前もきちんと空けないといけなくなった模様
1。
いずれにしろ、この辺の書き方で1行空けても他のパーサーでも問題ないわけで、 今後も空けて問題になることは無いと思うので空ける様に。
ただ、結構沢山該当箇所があって、調べるついでに Rakeタスクで自動的にチェックできる様な物も作りました。
チェック用タスク
Rakefileに以下の様な関数2つとタスクを1つ加えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
ok_failed_stop(condition)
はOctopressのpublic/_deployディレクトリの変更 でも書いた、引数がtruならただOKと表示してそうでなければそこでraise
するだけの関数。grep_check
はsoruce
内のファイルを見て、word
の周りをチェックする関数。grep_option
には対象となるファイルとかそれ以降の処理を入れます。opt
では0
で上下、1
で上だけ、2
で下だけチェックする様にします。task :check, :opt do |t, args|
がメインのタスク。- 引数が
new
の場合は#{source_dir}/#{posts_dir}/
内にあるファイルだけを対象に、 それ以外の場合は#{source_dir}
内にある全てのMarkdownファイルを対象にします。- 古い記事を
#{source_dir}/#{posts_dir}/y_2014
等年ごとのディレクトリに 退避するようにしてるのでnew
が有効です。 - Octopress(Jekyll)では
#{posts_dir}
以下にサブディレクトリがあっても再帰的に ポストのファイルを探して#{posts_dir}
直下にあるファイルと同等の 扱いで変換してくれます。
- 古い記事を
grep_option
では該当行の前後を見て、空白やraw
の行が無いことを見る処理。raw
を使ってcodeblock
内の1行目に書くことがあるので。
- 普段チェックするのは
codeblock
と- - -
、それに加えて Octopressのpublic/_deployディレクトリの変更 でもやった禁止ワードチェック。- MarkdownのパーサーをKramdownへ変更
のところには
<hr>
も空けないとだめ、と書いてますが今試した所大丈夫なので チェックから外してあります。 >
(引用)については下側は空けないと>
を付けないでも引き続き引用になります。 のでそうやって書いてあるところもあったのですが分かりやすいように 2行目以降にも>
を付けるように変更しておきました。 ただ、>
という文字は、diff
で使われて、codeblock
内の 途中に現れる事もあって、それをきっちり回避するのが面倒だったので、 普段はコメントアウトしておいて、必要なら外してチェックして 問題がありそうなところを探す、というふうにしました。#
については、章のタイトル部分でこれも上側を空けないと行けないわけですが、 これをコメントとして扱うプログラム言語が多いので それらがかなり多くヒットしてしまってこのままでは使い物にならないので、 普段はコメントアウト。- 上に上げた
codbelock
の次のコード:
の例もcodeblock
で書くと これによってエラーが出てしまいますが、通常、例でも避けた方が良いと思うので、 上の例では字下げブロックでエラーを回避しています。。
- MarkdownのパーサーをKramdownへ変更
のところには
- 引数が
これを毎回rake generate
する時に呼ぶように、
1 2 3 4 5 6 7 8 9 |
|
と、generate
のタスクの中でjekyll
を実行する前に入れておきます。
前に作ったgenerate_only
2
の方にも同様に入れておきます
3。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
その他覚書
putsの最後の改行
puts
は通常最後に改行が入るが、最後に\n
を入れるとそれは無視される。
(puts
自体が改行を1つ出すので、\n
無しの場合と同じように次の行に移るだけ。)
ので、
puts "\nChecking \"#{word}\"...\n\n"
となってる部分は下に一行空ける、になる様にしているだけです。
(最後の\n
がダミーみたいな物)
Pygmentsのキャッシュ
色々いじってる最中に
$ rake generate_only
## Test build for source/_posts/2014-07-25-blog-octopress.md
## Stashing other posts
## Generating Site with Jekyll
identical source/stylesheets/screen.css
Configuration file: /octopress/_config.yml
Source: source
Destination: ~/tmp/octopress/public
Generating...
Liquid Exception: Tag '{% ' was not properly terminated with regexp: /\%\}/ in _posts/2014-07-25-blog-octopress.md.tmp/#excerpt
jekyll 2.1.0 | Error: Tag '{% ' was not properly terminated with regexp: /\%\}/
## Restoring stashed posts
$
みたいなエラーが出て、以後、2014-07-25-blog-octopress.md の内容をすべて消しても同じエラーが出て止まらなくなりました。
同じファイルを違う名前にして試してみると通る状態。
これはPygments
のキャッシュが残っていてそれがうまく処理できなかった様で、
rake clean
4で/octopress/.pygments-cache
ディレクトリの中身を掃除したら
同じ名前の空ファイルで大丈夫になりました。
この時の問題は上のRakefile内のコードの記述で、
これらにはraw
5
が必要でした。
rake generate(jekyll build)時に使われるファイル
rake generate
の際には#{source_dir}/#{posts_dir}/
以下のファイルが使われるわけですが、
どうもファイルの拡張子とかは全く関係がなさそう。
使われるファイルは
- 日付フォーマットで始まる:
yyyy-mm-dd
-name.md - 最低1ワードはファイル名がある: yyyy-mm-dd
-name
.md - 拡張子がある: yyyy-md-dd-name
.md
を満たすもの(かつ、中身のyamlブロックでpublishedがfalse
出ないもの)
になる模様。
拡張子がmd
だろうとmarkdown
だろうと関係ないし
(Rakefileの中で設定してるのはrake new_post
時に作るファイル名のためだけ)、
txt
とかでも使われます。
さらに、1つ以上なら.
はいくつもあって良いみたいで
2014-07-25-test.md.tmp等、最後に余計な物を付けても使われます。
なので、一時的に今のファイルを.tmp
ファイルとして退避させて、
みたいな事をやろうにも、中でpublished: false
にしておかないと
使われてしまいます。
さらに、Rakefile内のisolate
というタスクでは
移動させないファイルをチェックするのにinclude
を使っているので、
この様な.tmp
付きのファイルは残ってしまいます。
これだとgenerate_only
とか使ってもこの問題を回避できません。
include
を使っておけば同じ名前の一部を持つファイル群、みたいな指定の仕方も
出来るわけですが、実際にはそんな使い方しないのでend_with
に変えておきます。
1 2 3 4 5 6 7 8 9 10 |
|
テーマ
上の変更したRakefile等は下のテーマの中にも入っています。