[XSL-FO試行錯誤]索引のページ番号表示で一部を太字にする

索引語に続くページ番号表示。「3,6,11-15,100,…」のように並んでいても、「どこがその語を説明している箇所なのか」は分かりません。そのようなときに、索引表現ではとくに重要・説明的である箇所のページ番号についてスタイルを変えて表現することがあります。これを実現するFOについて考えてみましょう。


「ある箇所について特別な処理をしたい」というとき、必要なのは次の情報です。

  • 「ある箇所」と他を区別するルール
  • 特別な処理を実現するFO

今回の場合、「通常の索引と、重要な1箇所の索引が区別できること」については元のXMLとXSLT処理の書き方によって
大きく異なると思われますので、それらを最終的に落とし込むFOについて検討します。

索引用FOの機能

索引用のFOの基本は、@index-keyによって指定されるキーと、そのキーを表示するための<fo:index-citation-reference>です。

索引 XSL-FOの基礎 第2版

これらのFOでは、該当するキーを含むページ番号について、FOプロセッサが列挙し表示を調整するという処理を行います。
つまり、FOプロセッサというユーザの手を離れた段階で処理されるので、「索引用のFOで一部のページ番号だけを太字にしたい」という要求を実現するには、このFOでは上手くいかなさそうだということを意味します。


索引用FOでは「2ページだけを太字にする」処理は難しい

索引にリンクを付けたい場合はfo:index-citation-list/@page-number-treatment="link"で表示されたページ番号にリンクが付与されます。

汎用のページ番号参照

あるページの参照だけであれば、fo:page-number-citaionに該当箇所のidを指定すれば実現できます。これを利用することにします。
制限として、数ページにわたるページ番号参照には対応できません。

汎用的なリンク用のFOであるfo:basic-linkでは、internal-destinationにidを指定することで内部リンクを付与できます。

よって、id情報があれば、該当の番号のページへジャンプするリンクが付与されたページ番号参照が実現できます。

最終的な方針とFO

重要な箇所の索引をspとします。通常の索引のときは、fo:wrapper/@index-keyを挿入する通常の索引用の属性を、spの索引のときはfo:wrapper/@idを本文に挿入します。このとき、spの前後でindex-keyの値は変えておきます。

本文のFOを通常の索引とspとで切り換える
<fo:block><fo:wrapper index-key="あんてなはうす1"/>アンテナハウスは、Data Usability Companyです。</fo:block>
<!-- spの索引語 -->
<fo:block ...><fo:wrapper id="antenna"/>アンテナハウスは、日本のソフトウェア企業で、XML自動組版ソフトウェアAntenna House Formatterや、PDFに関連した製品を開発・販売しています。</fo:block>
<fo:block ...><fo:wrapper index-key="あんてなはうす2"/></fo:block>
<fo:block ...><fo:wrapper index-key="あんてなはうす2"/></fo:block>

索引ページのFO
<fo:block ... space-after="2rem" font-size="72pt">索引</fo:block>
  <fo:block background-color="black" color="white">あ</fo:block>
  <fo:block text-align-last="justify" text-align="justify">アンテナハウス<fo:leader leader-pattern="dots" leader-alignment="center"/><!--
--><fo:index-page-citation-list merge-sequential-page-numbers="merge"
	merge-pages-across-index-key-references="merge" 
	merge-ranges-across-index-key-references="merge">
	<fo:index-page-citation-list-separator>,</fo:index-page-citation-list-separator>
	<fo:index-page-citation-range-separator>-</fo:index-page-citation-range-separator>
	<fo:index-key-reference ref-index-key="あんてなはうす1" page-number-treatment="link" />
</fo:index-page-citation-list><!--spの索引--><fo:inline>,<fo:inline font-weight="bolder"><fo:basic-link
 internal-destination="antenna"><fo:page-number-citation ref-id="antenna"/></fo:basic-link></fo:inline>,</fo:inline><fo:index-page-citation-list
  merge-sequential-page-numbers="merge"
  merge-pages-across-index-key-references="merge" 
  merge-ranges-across-index-key-references="merge">
	<fo:index-page-citation-list-separator>,
	<fo:index-page-citation-range-separator>-
	<fo:index-key-reference ref-index-key="あんてなはうす2"  page-number-treatment="link"/>
</fo:index-page-citation-list>
</fo:block>

fo:index-page-citation-listは複数のfo:index-page-referenceを持てますが、今回は特別扱いするfo:inlineを挟みたいため、一旦終了して特別処理の箇所の後に別のfo:index-page-citation-listを開始しています。

これをFormatterで組版し、冒頭に上げた画像の索引が作成できました。

補足

実作業で厄介なのはXSLTでの処理時に@index-keyを持たないspを、索引リスト作成時にどのようにして取得するかでしょうか。また、spである索引が登場する場合としない場合、sp前後に同じ語の索引が登場しない場合の「,」表示の分岐など、索引FOが吸収していた面倒な分岐も自前で用意する必要があるでしょう。

索引ウェビナーの宣伝

索引について、もう少し全般的な紹介をするウェビナーを2023年9月19,26日(火)16時に行います。今回の記事は応用実装よりでニッチ度が高いものでしたが、まだまだ話題がありますので、どうぞご検討ください。