Qiitaっぽいlistingのcaption
こんにちは、びしょ〜じょです。(後略)
Qiitaっぽくlistingにcaptionを差し込むものがJekyllにも欲しくなった。 とりあえず以下のようなシンタックスを考える。
Markdownのcode block内にMarkdownのcode blockを書く方法がわからん
``\`lang:caption
......
``\`
markdown to HTML converterをグニャッと行くのは面倒なので、これをひとまず次のように変換する。
<span class="listing-name">caption</span>
``\`lang
......
``\`
これなら簡単にできる。
listing_name1.rb
def listing_name content
in_listing = false
acc = ""
content.each_line{|txt|
if l = txt.match(/^\s*```\s*([^:]*)\s*:?\s*(.*)$/)
if not in_listing
in_listing = true
acc += "<span class=\"listing-name\">#{l[2]}</span>\n\n```#{l[1]}".chomp + "\n"
else
in_listing = false
acc += "```\n"
end
else
acc += txt
end
}
acc
end
module Jekyll
module Converters
class Markdown < Converter
priority :low
alias plain_convert convert
def convert(content)
plain_convert(listing_name content)
end
end
end
end
これにより以下のような感じになる。
これ
<p><span class="listing-name">caption</span></p>
<div class="highlight">
<pre>
......
</pre>
</div>
これで以下のような感じになってほしい。
これんなってほしい
<div class="highlight">
<span class="listing-name">caption</span> <!-- 中に入っとる -->
<pre>
......
</pre>
</div>
Jekyllではメソッドをいくつかのタイミングでフックすることができる。
Using hooks, your plugin can exercise fine-grained control over various aspects of the build process. If your plugin defines any hooks, Jekyll will call them at pre-defined points.
が~~~しかし、markdownから生成されたHTMLをさらに操作する方法がよくわからなかった。 ので筋肉やっていき
listing_name.rb
require'nokogiri'
def listing_name content
......
end
def listing_name_into_div content
html = Nokogiri::HTML content
pspans = html.xpath('//div[@class="highlight"]/preceding-sibling::p[span[@class="listing-name"]]')
divs = html.xpath('//p[span[@class="listing-name"]]/following-sibling::div[@class="highlight"]')
pspans.each_with_index{|pspan, idx|
span = pspan.remove.xpath('span').remove
divs[idx].children.first.add_previous_sibling(span)
}
# キャプションが空のときは消す
html.xpath('//span[@class="listing-name" and string-length(text()) = 0]').remove
html.xpath('/html/body/*').to_s
end
module Jekyll
module Converters
class Markdown < Converter
# priority :lowest
# lowerstにするとなんかぶち壊れたのでヤバい、適宜ほかをhigherにしていって
alias plain_convert convert
def convert(content)
# すぐにヤバくなりそう
listing_name_into_div(plain_convert(listing_name content))
end
end
end
end
バイトのおかげでXPathに少し詳しくなりました。webはやめよう。
『劇場版 魔法科高校の劣等生 星を呼ぶ少女』舞台挨拶LV付きを観に行った。 何故か徹夜で行ってしまったので爆睡するかと思ったが、大音量に手の混んだ魔法エフェクト、そしていつもと変わらない!! お兄様クオリティーで大変面白かったので終始笑いながら観た。 どんな敵が出ても最終的に被害0でお兄様大勝利なのでアンパンマン並に安心して観られますね。