以前からやろうとして出来なかったことに多言語組版があります。一つのスタイルシートで、いくつもの言語を扱えるようにするという多言語組版ではなくて、一つのドキュメント中に複数の言語のパートが存在して、それを一つのスタイルシートでちゃんとハンドリングできるようにするというものです。例えば簡単なものでは以下のようなtopicがあります。
<!DOCTYPE topic
<topic id="topic_30_1">
<title>CJK test</title>
<body>
<p>We say "Hello" in English.</p>
<p>We say "<ph xml:lang="ja-JP">こんにちは!</ph>" in Japanese.</p>
<p>We say "<ph xml:lang="zh-CN">?好!</ph>" in Chinese.</p>
<p>We say "<ph xml:lang="ko-KR">안녕하세요!</ph>" in Korean.</p>
</body>
</topic>
これはphタグレベルでxml:langを指定して言語を切り替えられるようにしたいという意図です。でももしかしたらそんなのもう標準のDITA-OTのPDFプラグインで出来てるじゃん!?といわれる方もいらっしゃるかもしれません。確かにそのとおりで、私に言わせれば「不完全」ながらもPDFプラグインはこのtopicをちゃんとフォーマットできるXSL-FOに落としてくれます。以下のような感じになります。
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:opentopic-i18n="http://www.idiominc.com/opentopic/i18n"
font-size="10pt"
writing-mode="lr"
xml:lang="en-US"
line-height-shift-adjustment="disregard-shifts"
font-family="Times New Roman, Times, Arial Unicode MS, Tahoma, Batang">
このようにFOの先頭でfont-family="Times New Roman, Times, Arial Unicode MS, Tahoma, Batang"と一発でやってしまいます。これで英語はTimes New RomanかTimes、日本語・中国語はArial Unicode MS、韓国語はBatangでというつもりなのでしょう。そしてtopicの実際の箇所は、
<fo:block space-after="0.6em" space-before="0.6em" text-indent="0em">We say "Hello" in English.</fo:block>
<fo:block space-after="0.6em" space-before="0.6em" text-indent="0em">We say "<fo:inline border-left-width="0pt" border-right-width="0pt">こんにちは!</fo:inline>" in Japanese.</fo:block>
<fo:block space-after="0.6em" space-before="0.6em" text-indent="0em">We say "<fo:inline border-left-width="0pt" border-right-width="0pt">?好!</fo:inline>" in Chinese.</fo:block>
<fo:block space-after="0.6em" space-before="0.6em" text-indent="0em">We say "<fo:inline border-left-width="0pt" border-right-width="0pt">안녕하세요!</fo:inline>" in Korean.</fo:block>
となっています。つまり完全にFormatterまかせです。で実際の表示は以下のようになります。
確かに表示できていますが、日本語、中国語、韓国語も全部Arial Unicode MSが使われていて、とうてい見る気がしません。font-familyにはオールマイティのArial Unicode MSが先に指定されているので、いくらBatangがあっても韓国語には使われないのです。
私はDITA-OT標準のPDFプラグインにはまったく興味はないのでトレースしていませんでした。昔はXSL-FOのテキストノードの文字コードからフォントをマッピングするというとんでもないことをやっていましたが、今はそこまではやらずfo:rootに各言語に必要なフォントをまとめて指定してしまうという方法になっているようです。
一見しておわかりになると思いますが、この方法ではCJKのフォントを使い分けることができません。これは致命的です。
では土曜日に徹夜して作った私のスタイルシートの出力したXSL-FOをご覧ください。まだ未完成なので少し余計な属性が入っているのでそこは削除しました。
<fo:block font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
space-before="1.5122em - 3.8673mm">We say "Hello" in English.</fo:block>
<fo:block font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
space-before="1.5122em - 3.8673mm">We say "<fo:inline font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
font-family="MS Mincho"
color="black"
xml:lang="ja-JP">こんにちは!</fo:inline>" in Japanese.</fo:block>
<fo:block font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
space-before="1.5122em - 3.8673mm">We say "<fo:inline font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
font-family="SimSun"
color="black"
xml:lang="zh-CN">?好!</fo:inline>" in Chinese.</fo:block>
<fo:block font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
space-before="1.5122em - 3.8673mm">We say "<fo:inline font-size="inherited-property-value(font-size)"
line-height="inherited-property-value(line-height)"
font-family="Batang"
color="black"
xml:lang="ko-KR">안녕하세요!</fo:inline>" in Korean.</fo:block>
結果のPDFは以下のようになります。
違いは一目瞭然で、fo:inline単位(元のph単位)に、xml:lang属性によりfont-familyを日本語は"MS Mincho"、中国語(簡体字)は"SimSun"、韓国語は"Batang"と切り替えていることです。これにより日本語、中国語(簡体字)、中国語(繁体字)、韓国語であっても言語により、フォントの切り替えが可能になります。
実はこのアイディアは2012年にやらねばならないと考えたのでした。でも忙しくてほとんどほったらかしにしていて、出張の帰りの電車の中などでちょくちょくコーディングしていたのが関の山でした。今回思い切ってコーディング/デバッグして意図するFOが出てくれました。まだアイディアをそのままコードにしてみただけなので、荒削りですが、それでもできることがわかってうれしく思っています。
世の中に役立つものならなんとか使っていただけるよう、今後コードを磨いてゆきたいと考えています。
(なおYahoo!ブログでは中国語の「イ尓」(ni)の文字が?に化けてしまうようです。ご了承ください。)