物語文のテキストファイルから縦書きPDFを作るためにTeXソースに変換するRubyスクリプトを以前作った.
縦書きにするので,!や?がたくさん重なるときは必ず偶数である(まあ,あんまりたくさん繋がる文章は滅多に書かないのだが).
それで,こないだ変換処理をかけていて失敗していることに気づいた.
以前書いていたRubyのソースはこうだ.
if line =~ /[?!][?!]/ #?!のつながりは,半角にして並べる
line.gsub!(/([?!])([?!])([^、-◯])/){"\\rensuji{" +to_single($1)+to_single($2)+"}\\quad "+$3} #次の文字との間に1文字空白
line.gsub!(/([?!])([?!])([、-◯])/){"\\rensuji{" +to_single($1)+to_single($2)+"}"+$3} #次の文字が記号の時は空白を入れない
end
「!」や「?」の後ろの文字まで検索対象にしていたのは,次の文字が普通の文字だったときは空白を開け,そうでなければ空白を開けない処理にするためだった.が,長文の変換を書けた結果,いくつか残ってしまう「!!」や「??」がある.
しばらくにらめっこしていて,これだと文末や,カギ括弧の前にはヒットしないことにやっと気がついた.
それで,処理を変えて,まずは全て半角にしてrensuji処理をし,その後に次の文字が普通の文字の所は全角空白を入れることにした.
if line =~ /[?!][?!]/ #?!のつながりは,半角にして並べる
line.gsub!(/(?|!)(?|!)/){"\\rensuji{" +to_single($1)+to_single($2)+"}"} #まず全てrensuji処理する
line.gsub!(/(rensuji\{.*\})([^、-◯|\\rensuji])/){$1+"\\quad "+$2} #次の文字が普通の文字の場合,rensujiの後に1文字空白
end
こんな感じ.
ちなみに,to_singleは,これより前で定義しており,!や?を半角にするメソッドなんだけど,trメソッドで書けなかったのがずっと疑問だった.それで,今回,調べてみたら,trはそのままだと日本語処理できないから,jcodeやnkfを読み込んで拡張しなければいけないのだと分かった.さらに,Rubyは1.9からjcodeは無くなっちゃったみたい.
なので,
require 'nkf'
def to_single(s)
s = NKF::nkf("-s", s.tr("!?","!?"))
return s
end
にしたら,うまくいった!
あと,TeX的にエスケープしなければならない&が文中に出てきたので,以下のコードを追加.
if line =~ /&/ #記号のエスケープ
line.gsub!(/&/, "\\\\&")
end
あんまり物語文に半角の記号が出てくることは少ないんだけど,ちょっと英文を書いた部分があったので.\を4つ重ねなければいけないのがミソ.この記号も&だけじゃなく増えそうだなあとは思う.