DITA 1.3の見果てぬ夢(2)

次の問題はDITA 1.3で導入されたキースコープです.DITA 1.2ではキーが使用できるようになり、@keysでキーを定義し、@keyrefでテキストコンテンツを参照したり、@conkeyrefでキーを使って間接的にコンテンツを参照できました.しかし問題は@keysの定義はグローバルであったことです.一度定義したキーは文書全般にわたって同じ値を保持し変わることはありません.

これでは大変だという事でDITA 1.3ではスコープドキーが定義できるようになりました.雑に言えばマップで@keyscopeを記述すれば、それ以下の範囲でキーはローカルに定義/使用できるというものです.例えば次のような例はDITAコンソーシアムのプレゼンなどで幾度も出てきているはずです.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
<map>
 <title/>
 <topicref href="cKeyRef.dita" keyscope="SCOPE01">
  <keydef keys="PRODUCT">
   <topicmeta>
    <keywords>
     <keyword>TYS-125F</keyword>
    </keywords>
   </topicmeta>
  </keydef>
 </topicref>
 <topicref href="cKeyRef.dita" keyscope="SCOPE02">
  <keydef keys="PRODUCT">
   <topicmeta>
    <keywords>
     <keyword>TTR-125F</keyword>
    </keywords>
   </topicmeta>
  </keydef>
 </topicref>
</map>

ここではキースコープ"SCOPE01"、"SCOPE02"で同じ名前の"PRODUCT"というキーを定義しています.これを次のようにトピックで参照すれば別々の値が出るというものです.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="concept_vfd_lgw_yx">
 <title><ph keyref="PRODUCT"/> Specification</title>
</concept>

やってみれば事実次のように別々のキー値が参照されます.

イメージ 1

しかし、本当の実践例ではこんな簡単なことで片付くのだろうか?というのが私の思うところです.

あるお客様のサンプルデータを作っていたときに、別々のタスクでまったくと言って良いほど同じステップで構成されている例がありました.このような時、同じ内容を2つのタスクにオーサリングするでしょうか?再利用してやろうというのが誰しも思うところです.2つの違いは片方が全てのステップがあり、もう片方は1つだけステップがないものと簡単化して考えます.そうすれば、すべてのステップを記述した再利用用の(ライブラリもしくはコレクションと呼ぶ)タスクを用意して、それに@conkeyrefしてやれば良いでしょう.

ただ問題は、一ヶ所stepsectionがあり「~のときはステップNへ、そうでないときはステップMへ」とう記述があったことです.上記のステップの違いはこのステップセクションの前なので、ステップへのxrefで表し、当然NとMは2つのタスクで違ったステップ番号になります.

少し長いですが、マップから順に引用します.

[bookmap]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd">
<bookmap xml:lang="en-US">
    <booktitle>
        <mainbooktitle>Online Help</mainbooktitle>
    </booktitle>
    <frontmatter>
        <mapref href="mKeyDef.ditamap"/>
    </frontmatter>
    <chapter href="topics/cUsingOnlineHelp.dita" navtitle="How to use online-help"/>
    <chapter navtitle="Prepareing to use the software" href="topics/cPreparingToUseSoftware.dita">
        <topicgroup keyscope="SINGLE-PRINTER">
            <keydef keys="CONNECTING_PRINTERS" href="collection-topics/tWhenConnectingPrintersTemplate.dita"/>
            <topicref navtitle="Connecting a single printer" keys="REFERENCE-TOPIC" format="dita" href="topics/tWhenConnectingASinglePrinter.dita"/>
        </topicgroup>
        <topicgroup keyscope="MULTIPLE-PRINTER">
            <keydef keys="CONNECTING_PRINTERS" href="collection-topics/tWhenConnectingPrintersTemplate.dita"/>
            <topicref navtitle="Connecting multiple printer"  keys="REFERENCE-TOPIC" format="dita" href="topics/tWhenConnectingMultiplePrinters.dita"/>
        </topicgroup>
    </chapter>
</bookmap>

[tWhenConnectingPrintersTemplate.dita 再利用タスク]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
<task id="task_03" xml:lang="en-US">
    <title id="title_03"><uicontrol>Setting the environment</uicontrol></title>
    <taskbody>
        <steps id="steps_r2v_rg4_wx">
            <step id="step01">
                <cmd>Click <uicontrol>[PC]</uicontrol> icon.</cmd>
            </step>
            <step id="step02">
                <cmd>Click <uicontrol>[General]</uicontrol> tab.</cmd>
            </step>
            <step id="step03">
                <cmd>Click <uicontrol>[Multi Printer]</uicontrol> tab.</cmd>
            </step>
            <stepsection id="stepsection_01">To configure the settings of the color measurement instrument, go to step <xref keyref="REFERENCE-TOPIC/step-color" format="dita" type="step"/>. Otherwise, go to step <xref
                keyref="REFERENCE-TOPIC/step-other" format="dita" type="step"/>.</stepsection>
            <step id="step04">
                <cmd>Click the <uicontrol>[Color]</uicontrol> tab.</cmd>
            </step>
            <step id="step05">
                <cmd>Click <uicontrol>[OK}</uicontrol>.</cmd>
            </step>
            <step id="step06">
                <cmd>Terminate <term keyref="PRODUCT"/> and launch it again.</cmd>
            </step>
        </steps>
        <postreq id="postreq_03">
            <note>Postreq note contents</note>
        </postreq>
    </taskbody>
</task>

[tWhenConnectingASinglePrinter.dita 再利用元:conkeyrefしているだけです]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
<task id="task_lbb_mc4_wx" xml:lang="en-US">
    <title>Connecting a single printer</title>
    <task id="task_e3q_mg4_wx">
        <title conkeyref="CONNECTING_PRINTERS/title_03"/>
        <taskbody>
            <steps>
                <step conkeyref="CONNECTING_PRINTERS/step01" id="step01">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step02" id="step02">
                    <cmd/>
                </step>
                <stepsection conkeyref="CONNECTING_PRINTERS/stepsection_01"/> 
                <step conkeyref="CONNECTING_PRINTERS/step04" id="step-color">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step05" id="step-other">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step06" id="step06">
                    <cmd/>
                </step>
            </steps>
            <postreq conkeyref="CONNECTING_PRINTERS/postreq_03"/>
        </taskbody>
    </task>
</task>

[tWhenConnectingMultiplePrinters.dita]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
<task id="task_ops_1q4_wx" xml:lang="en-US">
    <title>Connecting multiple printers</title>
    <task id="task_w4d_yjq_wx">
        <title conkeyref="CONNECTING_PRINTERS/title_03"/>
        <taskbody>
            <steps id="steps_x4d_yjq_wx">
                <step conkeyref="CONNECTING_PRINTERS/step01" id="step01">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step02" id="step02">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step03" id="step03">
                    <cmd/>
                </step>
                <stepsection conkeyref="CONNECTING_PRINTERS/stepsection_01"/> 
                <step conkeyref="CONNECTING_PRINTERS/step04" id="step-color">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step05" id="step-other">
                    <cmd/>
                </step>
                <step conkeyref="CONNECTING_PRINTERS/step06" id="step06">
                    <cmd/>
                </step>
            </steps>
            <postreq conkeyref="CONNECTING_PRINTERS/postreq_03" id="postreq_y4d_yjq_wx"/>
        </taskbody>
    </task>
</task>

tWhenConnectingASinglePrinter.ditaとtWhenConnectingMultiplePrinters.ditaの違いは簡単に言えば再利用タスクのtWhenConnectingPrintersTemplate.ditaのid="step03"のステップを参照しているか否かだけかの違いです.

ところが、これをXHTMLで出力するとまったくまともな表示になりません.問題はステップセクションの箇所です.この箇所は、自分をconkeyrefしているタスクのステップをREFERENCE-TOPICというキーを使って参照しているのですが、そこで生成されるxref/@hrefはボロボロです.結果としてtWhenConnectingASinglePrinter.ditaは次のような表示になります.

イメージ 2

この部分のHTMLを見ると

<p class="li stepsection">To configure the settings of the color measurement instrument, go to step <a class="xref" href="../collection-topics/../topics/tWhenConnectingMultiplePrinters.html#task_ops_1q4_wx__step-color">Connecting a single printer</a>. Otherwise, go to step <a class="xref" href="../collection-topics/../topics/tWhenConnectingMultiplePrinters.html#task_ops_1q4_wx__step-other">Connecting a single printer</a>.</p>

と@hrefがぐちゃぐちゃです.本当は"To configure the settings of the color measurement instrument, go to step 3. Otherwise, go to step 4."と出てくれないと困ります.

念のためにtempフォルダのtWhenConnectingPrintersTemplate.ditaを見ると次のようになっています.(簡単のため余計な属性は除いてあります)

<stepsection id="stepsection_01" class="- topic/li task/stepsection ">To configure the settings of the color measurement instrument, go to step <xref keyref="REFERENCE-TOPIC/step-color" format="dita" type="step" class="- topic/xref " href="../topics/tWhenConnectingMultiplePrinters.dita#task_ops_1q4_wx/step-color"><?ditaot usertext?>Connecting a single printer</xref>. Otherwise, go to step <xref keyref="REFERENCE-TOPIC/step-other" format="dita" type="step" class="- topic/xref " href="../topics/tWhenConnectingMultiplePrinters.dita#task_ops_1q4_wx/step-other"><?ditaot usertext?>Connecting a single printer</xref>.</stepsection>

すでに@hrefの値がtWhenConnectingMultiplePrinters.ditaの値に確定してしまっています.これではキースコープを定義し、REFERENCE-TOPICというキーに別々のタスクを割り当ててもなんの意味もありません.

これはDITA-OTのissueに出してありますが、少なくともDITA 1.3でスコープドキーを導入し、同じキー名が異なるキースコープで定義可能ならば、キーの評価はスタティックに行うのではなく、キースコープによりダイナミックに行わないと意味がまったくありません.

現在のDITA-OTはまったくそのような要請に無頓着な気がします.以下のスナップは今年Eliot Kimberさんが行ったDITA 1.3の紹介スライドの一部ですが、キースコープによりxrefの結果も変わるであろうことを述べています."Different results for cross references" でも実態はそうではありません.

イメージ 3

しかし、これを実装するとなると、@conkeyrefや@keyrefを持つトピックは、それがどのキースコープで参照されるかが決まらないとそのコンテンツや参照先を確定できないことになります.実装は大変でしょう.しかしDITA 1.3では盛られているにもかかわらず実装が追い付いていない2番目の例になるのではないでしょうか?

(ちなみにissueはGitHubに出したばかりで意見がついていません.この話、もしかしたら私の勘違いが含まれているかもしれません.)