DITA-OTでソースコードを書くならcoderefが便利

DITAでソースコードを書くときはcodeblock要素を使います。

(HTML5では引用ブロックやcodeblock(pre/code)もfigureの子孫として記述する方法がよく見られます。個人的な感覚として、英語だとキャプションに「figure 1」のようにしてソースコードが記載されていても違和感はないのですが、日本語で「図1」となっているところにソースコードが記載されていると違和感があります。)

さて、codeblockの中をどう書くかについて、方針はおおむね次の2つです。

  • 直接書く。XMLの<や>は
    • &lt;のようにして書く
    • xml-mentionドメインのタグを使って書く
  • coderefを使う

今回は記事タイトルにもあるように、coderefを使う方法が便利という話です。

DITA-OTではcodeblockでの処理について、仕様から拡張しています。記事タイトルが「DITAでcodeblockを書くときは~」ではないのはDITAの仕様ではないからです。なお、記事を作成する際に試行した環境はDITA-OT 3.7.1となります。

Extended codeblock processing DITA-OT

拡張内容は幾つかあるのですが、先に述べた通り、今回紹介するのはcoderefについてです。

codeblockにはテキストをそのまま記述することもできますが、XMLタグ、というか<などがきっちり処理されてしまうため、XMLやHTMLをソースコードとして例示するのは結構大変です。そこでcoderefです。

coderefは外部ソースコードを(主にテキストとして)参照し、結果を展開してほしい場合に使うタグです。@hrefで参照する先を指定します。XMLを参照する場合、@format=”xml”を付けましょう。

coderefの第一の利点は<をエスケープしなくて済む点です。これについてはDITA仕様のうちです。

coderefを使ったコードブロック
<codeblock xml:space="preserve"><coderef href="hoge.xml" /></codeblock>

ただ、実際のXMLファイルというのは結構行数が嵩みます。「coderefで参照する用にコード片を別ファイルに保存して……」というのはメインテナンス性からするとあまり歓迎できません。そこでDITA-OTの機能によって行数を制限します。

coderefの拡張記法は#から続くフラグメントによるものです。これに対応していない、DITA-OT以外のDITA処理系で使われても、ファイルの全行が出力されるだけで済みます。……結構大変なので、keyrefで切り出して切り換え可能にしておくのが良いかもしれませんね。

行数の記法はドキュメントにある通り、#line-range(<start>,<stop>)またはRFC 5147の記法で#line=<start><end>のようにして開始行、終了行を指定します。

このままで十分便利ですが、「元のソースコードを弄ったらトピックファイルで指定している行位置も変更しなくてはいけないのだろうか」と疑問を持たれたことでしょう。それはあまりメインテナンス性が良くありませんね。ということで、任意文字列を行位置の識別子にする方法が提供されています。
#token=<start-text>,<end-text>を指定すると、ソースコード中のstart-textがある行の次行からend-textがある行の前行までが範囲として取り出されます。想定としてはコメントアウトした行にstart-text、end-textを書いておく形のようなので、あまりトリッキーなことはしない方が良いでしょう。ほかにも幾つかの機能がDITA-OTのページで紹介されていますが、プラグインや処理系依存の機能もあるようなので都度確かめて使うと良いでしょう。

coderefのstart,end用文字列を追加したXML
<!-- example1start -->
<fo:block><fo:inline>Title</fo:inline></fo:block>
!-- example1end -->

ほか、coderefというcodeblockの中で更に別のタグを使うことのメリットは、@hrefで参照した箇所と、直接書く箇所をcodeblockの中で行える点です。

coderefを使ったコードブロック

<codeblock xml:space="preserve"><coderef href="hoge.xml#line-range(1,5)" />
... <!-- 直接書いた部分 -->
<coderef href="hoge.xml#line-range(10,15)" /></codeblock>

1-5行目、「…」を書いて10-15行目、なんて表示も可能になります。

そんなcoderef、DITA 2.0で若干の変更が入ることが現在のドラフトで言及されています。といってもエンドユーザがトピックを記述する上ではそう変化はなく、主に仕様上の立ち位置がより整理されるということのようです。