タイトルなど、見た目が大切な部分で、ブラウザによって語句を無理やり改行させられると、美観を損ね、また、可読性も落ちてしまいます。

そこで、CaboChaを利用して、文節ごとに改行できるように、 <wbr>を挿入し、きれいに表示できるようにするフィルタを作成しました。 きれいな改行をしたい要素にwhite-space: nowrap;を加え、日本語の改行を抑止し、 以下のようにJekyllタグを組み込むと、文節ごとに設定された<wbr>でしか改行されなくなるため、改行がきれいになります。 手動で<br>を差し込む手間がなくなり、なおかつ横方向のはみ出し防止の確実性が増します。たぶん。

最初はMeCabを使おうとしたのですが、形態素で区切るのではなく文節で区切りたかったので、CaboChaを利用しました。 CaboChaを利用すると、1チャンクごとに文節で区切れます。そして、チャンクごとの係り受けを解析してくれます(が、今回使うのは文節だけです)。

{{ "だってその人は、ただの工事現場の看板なのよ!?" | wbr }}

{{ page.title | wbr }}

<span>だってその人は、</span><wbr><span>ただの</span><wbr><span>工事現場の</span><wbr><span>看板なのよ!?</span>

<span>日本語を</span><wbr><span>文節ごとに</span><wbr><span>改行する</span><wbr><span>ための</span><wbr><span>Jekyllフィルタを</span><wbr><span>作った</span>

以下がフィルターのソースコードです。適当に_pluginsに投入してLiquid::Template.register_filterしてご利用ください。 あっ、利用するためにはCaboChaのインストールが必要です。ガンバッテクダサイ。

require "CaboCha"

def wbr(input)
  result = "<span>"
  begin
    cabocha = CaboCha::Parser.new
    #tree = cabocha.parse("だってその人は、ただの工事現場の看板なのよ!?")
    tree = cabocha.parse(input)

    (0..(tree.chunk_size - 1)).map do |c|
      chunk = tree.chunk(c)
      prev = ""
      (0..chunk.token_size-1).map do |t|
        index = chunk.token_pos + t
        token = tree.token(index).surface.force_encoding("utf-8")
        dontspace = prev == "ps" && token == "1"
        result += " " if !dontspace && result != "" && prev.match(/^[a-zA-Z0-9]+$/) && token.match(/^[a-zA-Z0-9]+$/)
        result += token
        prev = token
      end
      result += "</span><wbr><span>" if c != tree.chunk_size - 1
    end
    result += "</span>"
  rescue
    result = input
  end
  result
end

<span>で文節を囲ってから<wbr>を間に挟み込んでいるのは、FirefoxとChrome系の見た目を合わせるためです。 詳細は下記の参考サイト様が詳しいです。


日本語は禁則処理さえ守れば、どの位置で改行してもいいフリーダムな言語ですが、読みやすい改行位置はやはり存在するので、 きれいに読める改行を意識したいところではあります。

この先
生きのこることができるか!?

この先生
きのこることができるか!?

極端な例

Pythonで同じものを書いて、Pandocフィルターに食わせてタイトル以外の<h1>以下にも適用できるようにしたい気もします。 とすると、このRubyで書かれたフィルターはいらない子になっちゃうわけですが……。