topic/titleの処理 (1)

何をいまさらtopic/titleと思われるかもしれません.でも最近いろいろなスタイルシートを見ていて、意外と理解されていないのではないのかと気が付きました.topicがmapからtopicrefで参照されていたとすると、これからPDFを作ろうということでXSL-FOを生成する際、いろいろな箇所にこのtopic/titleは登場します.

1. 本文中のtopic/titleの配置される箇所
2. toc(目次.topicref/@toc="no"でなくて、そのtopicが目次に出すレベルの場合です.)
3. しおり(Bookmark)
4. xrefの参照先
5. related-linksの参照先

これらにはそれぞれ特徴があります.例えば次のようなtopicを考えてみます.

<?xml version="1.0"?>
<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">
<topic id="topic_e2k_dzf_kq">
    <title><ph keyref="PRODUCT" id="ph_r4h_k1c_mq"/>のエンジン諸元<ph><indexterm><keyword keyref="PRODUCT"/>のエンジン諸元</indexterm></ph></title>
    <body>
        <p>エンジン諸元一覧表</p>
    </body>
</topic>

"PRODUCT"というキーは次のようにマップで定義するものとします.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
<map>
 <title>Keydef map</title>
 <keydef keys="PRODUCT">
  <topicmeta>
   <keywords>
    <keyword>TYS125F</keyword>
   </keywords>
  </topicmeta>
 </keydef>
</map>

indextermはDITAでは本来このようなtitleの中にオーサリングするものではありません.本当はtopic/prolog/metadata/keywordsに入れるのが普通でしょう.でもtopicにindextermをかため打ちして入れるというのはついちょっと前までDocBookの世界で当たり前ののように行われてきたことです.DITAのtopicの文書モデルでも許されており、オーサリングされたら正常に処理できなければなりません.

次に各々の箇所での特徴を見てゆきたいと思います.

1. 本文中のtopic/titleの配置される箇所

ここではindextermを必ず処理しなければなりません.例えば次のようなFOを生成する必要があります.

<fo:wrapper index-key="TYS125Fのエンジン諸元"/>

あとph/@idの処理をどうするか?という問題があります.普通phは再利用コンテンツで使用され特別なレイアウトは行いません.また本来はxrefの参照先にも成り得ません.ですので@idを無視することもできるのですが、@idがオーサリングされているということは、それを尊重してFOに反映すべきと考え、次のようなFOを生成します.

<fo:block>
  <fo:inline id="unique_1_ph_r4h_k1c_mq">TYS125F</fo:inline>のエンジン諸元
</fo:block>

"unique_1"というのはDITA-OTが内部的にtopicに割り当てたidです.ここではtopicの@idとph/@idを"_"でつなげてユニークな値を生成しています.

実はindextermと@idの処理を行うのはここの場合のみです.

2. toc、4. xrefの参照先、5. related-linksの参照先としてtopic/titleを処理する場合は、決してindextermを処理してはなりませんし、FO中に上記のような@idを生成してはなりません.これらの場合は単なる参照先のラベルのようなもので、実体はあくまでtopic/titleが本文中に現れる箇所にあるからです.

更に、3. しおり(Bookmark)の場合、FOではfo:bookmark/fo:bookmark-titleに展開してやる必要がありますが、fo:bookmark-titleの下はテキストノードしか許されません.ですので、topic/titleはテキストモード(テキストのみを抽出するモード)で処理してやります.もちろんindextermは決してこのような箇所で処理してはなりませんし、テキストモードなのでXSL-FO中での@idの生成もあり得ません.このようにして作成した例は次のようになります."unique_1"は先に述べたように中間ファイル中でtopicにDITA-OTが割り当てた@idです.

<fo:bookmark starting-state="hide" internal-destination="unique_1">
  <fo:bookmark-title>1.1 TYS125Fのエンジン諸元</fo:bookmark-title>
</fo:bookmark>

以上がざっとした規則ですが、実際のPDFではヘッダーやフッターに、running-headerをつけたりすることもあるので、fo:markerも生成する機会があり、処理は更に複雑になります.もし上記のようなルールを守らずにスタイルシートを作るとindextermと@idの生成処理が錯綜してぐっちゃんぐっちゃんになります.topic/titleと言えど決してハンドリングは簡単ではありません.XSL-FOの生成要件として覚えておいていただいて損はないと思います.