テキスト→TeXのスクリプト

SRWで現在書いている『己の傷の下に恢復せよ』の分量が増えてきたので,TeXで組んでみるかなあと考えた.

最初,齋藤修三郎さんの「青空文庫を読もう!」コンテンツ内にあるスクリプトを流用できないかと思ったのだが,自分のテキストファイルが青空文庫に完全準拠していないのと,使用スタイルファイルが違うのと,段落の扱いが違う等々でうまくできなかったので,Rubyで簡単なのを作ってみることにした.

基本の構造は,入力ファイルを開き,出力ファイルを新しく作って開き,1行ずつ処理して最後はファイルを閉じておけばいいんだよね.

#!/usr/bin/ruby -Ks
ここでKsオプション付けておくか,コマンドラインでRuby呼び出すときにオプション付けるかしないと,日本語処理ができない.

(このへんにメソッドなどの定義や,変数の初期化など)

# ファイルの定義
inputtext_name = ARGV.shift #入力テキストファイル名
outputtex_name = inputtext_name.sub(/\.txt$/, ".tex") #出力TeXファイル名

inputfile = open(inputtext_name) #入力ファイル開く
outputfile = open(outputtex_name, "w") #出力ファイルを開く

while line = inputfile.gets#入力ファイルの行末まで繰り返し
  line.chop!#行末の改行は取り除いておく.

(このへんに処理を書く)

  outputfile.print line + "\n\n"#基本,1行1段落なので,最後は改行2回で書き出す
end

inputfile.close #入力ファイル閉じる
outputfile.close #出力ファイルを閉じる

「処理」のところに何をさせるか.

TeXだと,段落冒頭は自動でインデントなので,まずは,段落冒頭の全角空白を除去します.

  if line =~ /^ / #行頭の全角空白を除去
    line.sub!(/^ /, "")
  end

これだけでもTeXソースとしてはそこそこいける(物語文はラクだ)はずなので,コンパイルして様子を見てみる.

ありゃ.括弧が下がりすぎだ.そうか,会話文としての括弧はインデントして欲しくないけど,TeX側じゃそんな加減わからないから,他の段落冒頭と同じように下がっちゃうんだなあ.

そこで,冒頭の括弧の前に\noindentと書いて,下がらないようにしてみると……

ありゃ.今度は上がりすぎか.括弧の次の文字が1字インデントした文字と同じ高さになるといいんだけどなあ.それに,同じ指定のはずなのになぜかガタガタになっている.

調べてみたところ,見た目で隙間が同じぐらいになるように,TeXではグルーとかカーンとか呼ばれる仕組みがあって,この場合,それが悪さをするようです.

それで,TeXソースのプリアンブルの方で,

\def\「{\noindent\kern.5zw\inhibitglue「}

などとして,新しいコマンド「\「 」などを作り,冒頭の括弧ではそのコマンドの括弧を使うことにします.

というわけで,テキスト→TeXのスクリプト側の処理では,

  if line =~ /^[「(〈]/ #行頭の括弧の処理
    line.sub!(/(^[「(〈])/){"\\"+$1} #\「等はTeX側で定義.
  end

です.

うまくいったみたい.

2008.7.6訂正:二重カギ括弧も見つけたので,正規表現のところを/^[「(〈]/と追加.見つけるたびに追加していくことになるんだろうなあ.

おつぎは,!や?が続いたときの処理.基本的に3つ以上つなげて書くことは無いので,2つ並んでいたときに半角にして縦に並べることにする.

  if line =~ /[?!][?!]/ #?!のつながりは,半角にして並べる
    line.gsub!(/([?!])([?!])/){"\\rensuji{" +to_single($1)+to_single($2)+"}"}
  end

to_singleのところは全角→半角処理で,コレより前に def to_single(s)
  if s == "!"
    s = "!"
  end
  if s == "?"
    s = "?"
  end
  return s
end
と定義しています.本当はtrでいけるんじゃないかと思ったんだけど,何故かうまくいかなかった.ちなみに,コンパイルしてみたら,文中の「!」や「?」の後は自動で空白が入るんだけど,\rensujiの後は入らないので,揃えるよう努力するかどうか思案中.

冒頭の――や……の処理.なぜかwundenで多用するようになったんですが,冒頭の――は,インデントして欲しくないので,\noindentをかます.

  if line =~ /^[―…]/ #冒頭の――や……がインデントしないようにする.
    line.sub!(/(^[―…])/){"\\noindent"+$1}
  end

倍角ダッシュ(――:全角の「―」が2つ)の処理は,最初,エムダッシュに変換するつもりだったので,「\---(半角の「-」3つ)」にしようと思っていたのですが,『LaTeX2ε美文書作成入門』に詳解されていたのを見つけたので,プリアンブルで \def\――{―\kern-.5zw―\kern-.5zw―} と定義することとし,変換は,\――(全角の「―」2つ)にしています.

  if line =~ /――/ #倍角ダッシュの処理
    line.gsub!(/――/, "\\――") #\――はTeX側で定義.
  end

冒頭処理と順序を逆にするとおかしくなるので,注意注意.

さて,難関のルビ処理ですが,漢字にカタカナルビのみならず,漢字に漢字ふってたり,カタカナに漢字ふってたり,果ては記号にカタカナふってたりと盛りだくさんなことをしているので,訳が分からなくなり,結局,上述の「青空文庫を読もう!」からもらってきたaozora.rbからルビ処理の定義の部分をもらってぺたぺたと貼りました.

ただし,私は藤田眞作氏のfurikana.sty(入手場所 http://homepage3.nifty.com/xymtex/fujitas2/texlatex/を使用し,オプションは,「0 親文字とルビの長いほうにあわせて均等割」を指定することにしているので,\\kana[0]{\1}{\2}に変更しています.

傍点の処理もぺたぺたしてもよかったのですが,別に難しいことはしていないし,難しい文字も使っていない(はず)ので,   if line =~ /[#「(.+?)」に傍点]/ #傍点の処理
    line.gsub!(/(.+?)[#「(\1)」に傍点]/, '\\bou{\1}')
  end
にしておきました.

ここからはあんまり汎用性のない話で.

引用のドイツ語に出てくるアクセント記号類を,私はHTMLの実態参照で書いています.それの変換.

  if line =~ /&.uml;/ #ウムラウト
    line.gsub!(/&(.)uml;/){'\\"{'+$1+'}'}
  end
  if line =~ /ß/ #エスツェット
    line.gsub!(/ß/, "\\ss ")
  end
  if line =~ /&.circ;/ #^
    line.gsub!(/&(.)circ;/){'\\^{'+$1+'}'}
  end
  if line =~ /&.ring;/ #リング
    line.gsub!(/&(.)ring;/){'\\r{'+$1+'}'}
  end

高地ドイツ語で書かれているものからも引っ張ったら,現代ドイツ語ではまず使わないような記号も必要になってしまった.最初,エスツェットの後に空白を入れるのを忘れて,エラーが出ました.そらそーやわなあ.他のは括弧くくりがあるけど,コレはないからどこまでがコマンドか分からんもんなあ.

それから,私は空行3つで場面展開というか「節」を作っているので,それの変換をば.まずは,空行数えるためのカウンターを作って,それが3まで行ったら\section*{}を挿入してカウンターを戻しています.

#カウンターやフラグ
section_c = 0

  if line =~ /^$/ #空行だったら
    section_c += 1#カウンターに+1
    if section_c == 3#カウンターが3になったら処理する.
      outputfile.print "\\section*{}\n"
      section_c = 0#カウンター戻す
    end
    next#次の行の処理に飛ぶ
  end

この後は,wunden用の特殊処理で,まったく汎用性がない.

まず,字下げですが,1字下げしか使っておらず,1字下げは引用のところでしか使っていないので,\quote環境に変更.

  if line == "[#ここから1字下げ]"
    line = "\\begin{quote}"
  end
  if line == "[#ここで字下げ終わり]"
    line = "\\end{quote}"
  end

最初quotation環境にしていたんだけど,詩の引用が多いので冒頭に字下げが起きない方がいいかと思って変えました.

字下げのところ,引用元は右揃えにしたかったので,これまた変更.

  if line=~ /^Aus \".+/ #引用元の右揃え(独文)
    line.sub!(/^Aus \"(.+)/){'\\begin{flushright}'+"\n"+'Aus "'+$1+"\n"+'\\end{flushright}'}
  end
  if line=~ /.+』より$/ #引用元の右揃え(和文)
    line.sub!(/(.+)』より$/){'\\begin{flushright}'+"\n"+$1+"』より\n"+'\\end{flushright}'}
  end

後は,冒頭の「第●章」の処理です.

  if line=~ /^第.章/
    line.sub!(/^(第.章)/){"\\chapter{"+$1+"}"}
  end

デフォルトのままだとこうすると,「第一章 第一章」になってしまうのですが,使うスタイルの方で章番号が出ない指定にします.

2008.7.5 訂正:正規表現を「第.章」とすると,章が2桁に行ったときに該当しなくなるので,「第.*章」にそれぞれ変更.

さて,これでテキスト→TeXは終わりで,今度はTeXファイルの方の用意です.

プリアンブルとここまでで作った章ごとのTeXソース(wunden00.tex,wunden01.tex...)を読み込むwunden.texを準備します.

\documentclass[b6paper]{tbook}
\usepackage{furikana}%藤田眞作さんのfurikana.styを利用

\usepackage[B6]{bunko} %トニイさんのbunko.styを利用
\bookname{己の傷の下に恢復せよ}%bunko.styで使う必須の指定.これが奇数頁のヘッダに出る.
\章番号無%bunko.styで使うオプション.章番号が自動で出なくなる.
%倍角ダッシュの定義(フォントに関係なく繋がるようになる)
\def\――{―\kern-.5zw―\kern-.5zw―}
%冒頭の括弧の定義.そのままにしておくとガタガタになるので,
%カーン指定・グルー禁止で,ちょうど括弧の次の文字が1字下がりになるように調整
\def\「{\noindent\kern.5zw\inhibitglue「}
\def\({\noindent\kern.5zw\inhibitglue(}
\def\〈{\noindent\kern.5zw\inhibitglue〈}
%dvipdfmxでPDF化する際に右綴じにする指定.dvi化で止める場合はコメントアウト
\AtBeginDvi{\special{pdf:docview <</ViewerPreferences <</Direction /R2L>> >>}}
\title{己の傷の\kana{下}{もと}に恢復せよ\\Ersteh unter deinen Wunden}
\author{淙穂鶫箜}
\date{}

\begin{document}
\maketitle
\tableofcontents

\input{wunden00}
\input{wunden01}
以下,ファイル読み込み.

\end{document}

tbookには本来b6paperという指定は無いと思うのですが,bunko.styでb6で組むように指定したときに,tbookのオプションにサイズを書いておかないと,余白いっぱいのDVIファイル(これはdviout側で変えられるけど)とPDFファイル(これはAcrobat Readerだと変えられない)ができあがるので,書いておきました.

トニイさんのbunko.styは,昔々niftyのftexフォーラムからもらってきた物なんだけど,「フォーラム@nifty」さえ無くなった現在,どこにも無いようなので,ここに置いておきます.

→トニイさん作「B6判・文庫本(A6判)スタイル」bunko10.lzh[11KB]

こうやって試作してみたPDFファイル.プロローグのみ[28KB]

以下,そのうち手を付けたいこと.

日時: 2008年6月 9日 | PC/Web > Ruby |

コメントを投稿

(空欄でもかまいません)

(メールアドレスは管理人に通知されますが,Web上には表示されません)

Powered by Movable Type