HTMLでのルビ付けプログラム

ブログの更新が滞っていて、「PDF教材をHTMLに変換する」という記事を書いてから、もう一年近くになります。

その時はプログラムの内容を殆ど何も書かなかったので、
今回はPythonで書いたプログラムの内容と、
それを機に、同じことをTypescript(Javascript)、GO、C++で書いてみたので、これらの言語の比較・感想を書いてみます。

最初に、ルビ付けプログラムの基本的考え方をみます。

簡単にいえば、辞書を用意しておいて、文書の中で当該漢字が出てくれば、その漢字をルビづけのHTML文字列で置き換えればいいのです。

文字列がコンピュータの中でどのように扱われているかは結構複雑で難しい問題ですが、
現在のプログラミング言語では、低レベルの仕組みを熟知していなくても、プログラミングできるようになっています。

文書の中で特定の文字を探し出し、他の文字と置換する関数(仕組み)は、大抵は2種類用意されています。

一つは文章の中に、示された文字列が完全に一致する文字列が含まれているかどうを探すいわば原始的探索で、もう一つはもっと複雑な質問に答える正規表現というものです。

正規表現のお馴染みのものはワイルドカードで、たとえば文書ファイルをみつけるために「*」を使って、「*.txt」と書いて拡張子が[txt]の文書にマッチするものをすべて探し出します。

昔私がPerlを頻繁に使用していたのは、Perlの正規表現がとても強くまた使いやすかったからです。

現在プログラミング言語としてのPerlは人気がなくなりましたが、最近のプログラミング言語は皆Perlを見習って、正規表現の充実を図っています。

今回の作業は、しかし、正規表現を使うまでもないと思います。

さて、具体的な話に進みましょう。

まず、漢字とかなを一対にした、(プログラム用語でいえば)連想記憶・辞書を準備します。

たとえば、

学:まな(ぶ)
学校:がっこう

のようなものです。

今回、教科書(実際は副読本)の一章を単位で処理していきます。

文書の中に、辞書で用意した漢字が出てくれば、すべて該当するHTML文で置換するという単純な方法では、
不具合が起こることは容易に推測できます。

そもそも教科書に出てくるすべての漢字(この場合「学」と「学校」)にかなを振るわけではありません。
章の初めの幾つかにルビを振り、あとはルビをつけません(そのルールは分かりません)。

ですから、出てくるすべての漢字にルビを振るアルゴリズムではよくないのです。

もう一つ問題は、「学校」には「がっこう」だけルビを付けなければいけないのであり、
学校に「まな」(ぶ)と「がっこう」の二つのルビを付けてはいけません。

この解決策として、やってはいけない文脈を与えることにしました。
すなわち、「学」の情報に、「まな」(ぶ)のルビをつけてはいけない文脈として「学校」や「学童」をリストアップしておきます。

これで、「学校」や「学童」に「『まな』(ぶ)」という余計なルビを振らなくなりますが、
その制限以外の「出てくる『学』にすべてカナをふる」のを防ぐことができません。

次に導入したのは、何番目の出現にルビを付けるのかを教える仕組みです。

章毎に考えれば、その漢字の何番目の出現にルビをふるかを調べるのは、難しいことではありません。
今回、印刷教本が手元になかったのですが、デジタルファイルに落とした文章でも、
何番目の漢字にルビを振るかは割と簡単に調べることができます。

ですから、「学」にルビを振るべき出現位置(番目)のリスト(何番と何番と何番と…のように)を与えれば、
置換場所は確定できます。(ルビ付けに位置情報を与えれば、文脈での制限は不要だと思います。)

以下に「道」と「橋」のフリガナ(RubyDict)と避けなければいかない制限(Options)の、
Json形式で書いた例を示します。

“RubyDict” : {“道”: “どう”, “橋”: “きょう”},
“Options” : {“道”: [[17], [“道で”, “この道”, “ある道”, “道を”]],
“橋”: [[1], [“鉄橋”, “橋を”]] }

このプログラムは簡単で、辞書をJson形式のファイルで用意し、プログラムそのものはPythonで200行強でした。

ルビ付けしたHTMLから、逆にルビを取り去って、元の文書に返るかどうかのプログラムも書いてみました。
こちらは100行強でした。

追。

PythonにはWeb関連のプラグインが沢山あって、ルビ付け作業は簡単にできたと思いますが、元に戻るプログラムで見ると、余計なことを色々やっているようで、結局使わないことにしました。
確か、BeautifulSoupだったと思います。

error: コピーできません !!