昨日書いた泉鏡花『貧民倶樂部』の記事において,鏡花テクスト引用のために大量のルビをマークアップしなければならなかった。HTML で <ruby>
このツールは,標準入力から UTF-8 テキストを読み,此(これ)のように,漢字 + ( + 読み + )のように書いた文字列に対して,マークアップを行う。デフォルトでは HTML タグを付加する。-l オプションを指定すると LaTeX 形式で整形する。対象テキストの括弧は全角でないといけない。そういう融通の利かないところがある。開括弧より前のテキストを後ろから逆方向に走査し,漢字以外が出現するまで漢字をスタックにプッシュし,あとでこのスタックからポップして得られる文字列(先入れ後出しにより文字の順番が戻る)を親文字と判定する。「漢字」は Unicode CJK 統合漢字に属するかを \p{InCJKUnifiedIdeographs} 正規表現文字クラスで判断している。Perl コードは以下の通り。
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 65 66 67 68 69 70 71 72 73 | #!/usr/bin/perl -w # -*- coding: utf-8; mode: cperl; -*- # # convertruby: ルビ・マークアップ # - ベタのテキストを <ruby> or \ruby シーケンスに整形する # - 例: 此(これ) ["(", ")" は全角括弧] # -> <ruby><rb>此</rb><rp>(</rp><rt>これ</rt><rp>)</rp></ruby> (default) # -> \ruby{此}{これ} (with -l option) # - usage: convertruby [-l] < stdin # -l: for LaTeX; default: for HTML # use strict; use utf8; use Getopt::Std; use File::Basename; binmode (STDOUT, ":utf8" ); # コマンドライン・オプション処理 my %opts = ( 'l' => 0); Getopt::Std::getopts( 'l' , \ %opts ) || die "Usage: " . basename( $0 ) . " [-l] \< (stdin)\n -l: for LaTeX; default: for HTML\n" ; # 行毎の主処理 while (<STDIN>) { my $line = $_ ; utf8::decode( $line ); utf8::decode( $_ ); my ( $yomi , $leftt , $rightt ); # 「(読み)」を含まない行はそのまま出力 unless ( $_ =~ /([^)]*)/gi) { print $line ; next ; } # 「(読み)」を走査し,これがある限りその前後を切り出す while ( $line =~ /([^)]*)/gi) { $yomi = $&; $leftt = $`; $rightt = $'; # 「(読み)」から括弧を外す $yomi =~ s|[()]||g; # 対象漢字部を後方から走査し,漢字スタックに push する my @kstack = (); my $k ; my @istack = split (//, $leftt ); # 「読み」の左側テキストの文字配列 while (( @istack ) && (( $k = pop ( @istack )) =~ /\p{InCJKUnifiedIdeographs}/g)) { push ( @kstack , $k ); $k = "" ; } # 最後に pop した非漢字を左側テキスト配列スタックに戻しておく push ( @istack , $k ) if ( $k ); # 漢字スタックから漢字部文字列を pop で復元 my $kanji = "" ; while ( @kstack ) { $kanji .= pop ( @kstack ); } # 抽出した漢字部よりも前の文字列を出力 if ( @istack ) { print $_ for @istack ; } # ruby マークアップ部分を出力 if ( $kanji ) { if ( $opts { 'l' }) { # LaTeX (with -l option) print '\ruby{' . $kanji . '}{' . $yomi . '}' ; } else { # HTML (default) print '<ruby><rb>' . $kanji . '</rb><rp>(</rp><rt>' . $yomi . '</rt><rp>)</rp></ruby>' ; } } else { # 「漢字(読み)」のパターンでないものはそのまま出力 print "($yomi)" ; } # 走査対象文字列に右側テキスト(残り)文字列を格納して,繰り返し $line = $rightt ; } # 残り文字列を出力 print $rightt if ( $rightt ); } |
GNU Emacs からは,以下を .emacs に追加すれば,利用できるようになる。ここでは convertruby は /usr/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ;; convertruby for HTML ( defun convert-ruby-html (start end) "Convert text to ruby HTML sequence." (interactive "r" ) (call-process-region start end "/usr/local/bin/convertruby" t ( list t nil ) nil "" ) ) ;; convertruby for LaTeX ( defun convert-ruby-latex (start end) "Convert text to ruby HTML sequence." (interactive "r" ) (call-process-region start end "/usr/local/bin/convertruby" t ( list t nil ) nil "-l" ) ) |
泉鏡花『貧民倶樂部』の引用に際しては,新字・新仮名遣いで引用文を作成し(図 1),自作のソフトで旧字・旧仮名遣いに変換し,次に,ルビを付けたい漢字に「(よみ)」を付加し(図 2),最後に Emacs 上で convertruby を実行して <ruby> タグをマークアップした(図 3)。ただし,図 3-1 は HTML 整形の,図 3-2 は LaTeX 整形の結果例である。



