日別アーカイブ: 2021年3月16日

XSL-FO試行錯誤 fo:flow-map 概要編

今回はflow-mapについてです。今回の記事は「概要編」としてflow-mapとはどんなものなのか紹介します。

region-bodyは複数記述可能

<fo:region-body><fo:simple-page-master>に複数記述可能です。region-body同士は重なり得るので、適切に配置します。<fo:flow>@flow-nameで利用するregion-bodyを指定します。

region-bodyを複数使う例

<fo:layout-master-set>
  <fo:simple-page-master master-name="main"
     size="JIS-B5 portrait" margin="10mm">
     <fo:region-body region-name="en" margin-right="182mm div 2 - 5mm"/>
     <fo:region-body region-name="jp" margin-left="182mm div 2 - 5mm"/>
   </fo:simple-page-master>
 </fo:layout-master-set>
 <fo:page-sequence master-reference="main">
   <fo:flow xml:lang="ja" flow-name="jp" >
     <fo:block ...>日本語</fo:block>
     ...
   </fo:flow>
   <fo:flow xml:lang="en" flow-name="en">
     <fo:block ...>English</fo:block>
     ...
   </fo:flow>
</fo:page-sequence>

region-bodyを複数使う例

たとえば、翻訳文を併記したいけれどテキストの長さが元の文と異なってしまうときなどにも対応可能ですね。表組や段組で左右の文の位置が揃うよう並べるよりも構造がすっきりしているのではないでしょうか。表組の解除や段抜きなどはないため、図版だけページ中央に表示したいなどの要求があるとややこしくなりますが。

flow-mapについて

本記事の本題はflow-mapです。名前の通りflowのマッピングを行える機能です。簡易な理解ではページシーケンスマスタでのページシーケンスとページマスタの関係を、flowとregionに置き換えたものとなります。ページシーケンスマスタのように条件よる参照分岐はできません。

XSL-FOの基礎 | 第4章 ページレイアウトの切り替え

JIS X 4179『拡張可能なスタイルシート言語(XSL) 1.1』で紹介されているflow-mapの使い方は3パターンほどです。簡単な例としては次のような形があります。

  1. 別々のregionであるregionA、regionBに対し、同じflowを流し込む
  2. 1つのregionに対し、別々のflowであるflow1、flow2を流し込む
  3. regionA、regionBにflow1、flow2を流し込む

この中でもっとも使い方として分かりやすいのは「regionA、regionBに対し同じflowを流し込む」という形でしょう。

flow-mapで2つのregionを1つのflowに対応させる
<fo:layout-master-set>
  <fo:simple-page-master master-name="complex"
     size="JIS-B5 portrait" margin="10mm">
     <fo:region-body region-name="regionA"
       margin-top="1cm" margin-bottom="130mm"
       margin-right="182mm div 2 - 5mm"/>
     <fo:region-body region-name="regionB"
       margin-top="180mm" 
       margin-left="182mm div 2 - 5mm"/>
   </fo:simple-page-master>
  ...
  <fo:flow-map flow-map-name="flowmap">
   <fo:flow-assignment>
     <fo:flow-source-list>
       <fo:flow-name-specifier flow-name-reference="flow-merged"/>
     </fo:flow-source-list>
   <fo:flow-target-list>
     <fo:region-name-specifier
       region-name-reference="regionA" />
     <fo:region-name-specifier 
       region-name-reference="regionB"/>
   </fo:flow-target-list>
   </fo:flow-assignment>
 </fo:flow-map>
<fo:layout-master-set>
<fo:page-sequence master-reference="complex"
  flow-map-reference="flowmap">
  <fo:flow flow-name="flow-merged"/>
    <fo:block>...
    <fo:block>
  &t;/fo:flow>
</fo:page-sequence>

flow-mapで2つのregionを1つのflowに対応させる

<fo:flow-map>@flow-map-nameを指定し、<fo:page-sequence>でそのflow-mapを参照するようにします。
流し込まれるソースのflowの@flow-nameと同じ値を<fo:flow-source-list>の子、 <fo:flow-name-specifier>@flow-name-referenceに、流し込み先のregionを<fo:flow-target-list>の子、<fo:region-name-specifier@region-name-referenceに指定します。今回はregion2つに対してflow1つを割り当てました。

<fo:page-sequence>@flow-map-referenceで参照するflow-mapを指定する必要があります。
複数flow-mapを用意すれば、同じflow-nameのflowに対し、flow-mapの参照を変更することで別のregionに流し込むことも可能です。

さらに細かいregionとflow-mapを利用することで、次のようなレイアウトも可能です*

沢山のregionをflow-mapで割り当てる

試行錯誤であるところはここからで、このregionはマッピングされているとはいえそれぞれ独立です。たとえばフォントサイズを大きくするとテキストの位置がずれ、次の行のテキストと重なるかもしれません。

一部のフォントサイズを変更した結果テキストが重なった