第17章 表

XSL-FO の表は次のような構造をしている。fo:table-and-captionとfo:tableは両方ともブロックレベルのFOであり、表サブツリーの最上位はどちらでも良い。

表の構造

図17・1 表の構造

表の構造概要をFOで簡単に表すと次のようになる。

<fo:table-and-caption>
  <fo:table>
    <fo:table-column/>
    <fo:table-column/>
    <fo:table-header>
      <fo:table-row>
        <fo:table-cell>
          <fo:block>........</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>........</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-header>
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell>
          <fo:block>........</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>........</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</fo:table-and-caption>

17–1 表とキャプション

fo:table-and-captionは表(本体)とキャプション(表の見出し)をグループにする。子供はオプションのfo:table-captionと必須のfo:tableである。fo:table-captionにはブロックレベルのFOを介してキャプションを記述する。caption-sideプロパティでキャプションの位置を設定する。

表17・1 caption-sideプロパティ
プロパティ値説明
beforeキャプションをブロック進行方向で表に対して前に置く。
afterキャプションをブロック進行方向で表に対して後に置く。
startキャプションをインライン進行方向で表に対して開始辺側に置く。
endキャプションをインライン進行方向で表に対して終了辺側に置く。
topキャプションを表に対して上に置く。
bottomキャプションを表に対して下に置く。
leftキャプションを表に対して左に置く。
rightキャプションを表に対して右に置く。

17–1–1 表の左右位置揃え

fo:table-and-captionのtext-alignプロパティは表全体の左右位置揃えを指定する。表本体とキャプションは一緒に位置が移動する。キャプションのみを位置揃えしたいときは、ブロックレベルのFOで位置揃えする。次は表とキャプションの配置の例である。最初の表はfo:table-and-captionに位置揃えの指定をしていないが、二つ目の表はfo:table-and-captionにcaption-side="after"とtext-align="center"を指定している。

<fo:table-and-caption border="0.2pt solid #CCCCCC" 
                      space-after="0.5em">
  <fo:table-caption>
    <fo:block>表の見出し</fo:block>
  </fo:table-caption>
  <fo:table width="10cm" table-layout="fixed">
    <fo:table-body>
      <fo:table-row>
	    <fo:table-cell border-style="solid" 
                       border-width="thin">
          <fo:block>Cell 1</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" 
                       border-width="thin">
          <fo:block>Cell 2</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</fo:table-and-caption>		
<fo:table-and-caption  caption-side="after"  
                       text-align="center" 
                       border="0.2pt solid #CCCCCC"  
                       space-after="0.5em">
  <fo:table-caption>
    <fo:block>表の見出し</fo:block>
  </fo:table-caption>
  <fo:table width="10cm" table-layout="fixed">					
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell border-style="solid" 
                       border-width="thin">
          <fo:block>Cell 1</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" 
                       border-width="thin">
          <fo:block>Cell 2</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</fo:table-and-caption>

組版結果は図17・2 表とキャプションの配置のようになり、最初の表は左寄せ、二つ目の表は中央揃えになる。fo:table-and-captionのtext-align="center"は表全体の配置のみでなく、表のセルの中のテキストの配置まで継承する。

表とキャプションの配置

図17・2 表とキャプションの配置

17–2 表の本体レイアウト

fo:table)は表形式の本体部分を組版するためのFOである。fo:tableの子供はfo:table-column(オプション)、fo:table-header(ヘッダー、オプション)とfo:table-footer(フッター、オプション)とfo:table-body(表のボディ、必須)である。fo:tableのレイアウトに特有のプロパティは次の四つである。

17–2–1 表の自動レイアウトと固定レイアウト

fo:tableのプロパティtable-layoutプロパティはXSL-FOプロセサが幅をどのように処理するかを指定する。

表17・2 table-layoutプロパティ
プロパティ値説明
auto(初期値)表の自動レイアウトを指定する。
fixedinline-progression-dimensionまたは横組ではwidth(縦組ではheight)に、長さまたは比率が指定されていて、table-layout="fixed"ならば、表の固定レイアウトを指定する(これ以外では自動レイアウトとなる)。

表の自動レイアウトはXSL-FOプロセサが表のセルの内容から自動的に列幅を計算して設定する。自動レイアウトのアルゴリズムはXSL-FOプロセサに依存する。表の自動レイアウトは一般的に組版処理の時間がかかる。

表の固定レイアウトではすべてのカラムについて、後述のfo:table-columnでカラム幅(列幅)を指定しなければならない(XSL-FO仕様書ではCSS2.1の表の固定レイアウトを参照している。CSS2.1では、column要素があればそれを優先し、次に表の1行目のfo:table-cellの幅が指定されていればそれをカラム幅とする。それ以外のカラムの幅は均等配分する。)

17–3 表のカラム幅指定

fo:table-columnは補助的なオブジェクトである。同じカラム(表の列)とスパンをもつセルに、次のプロパティを使って、カラム幅やカラムの枠線の優先度などを設定する。

17–3–1 カラム位置と幅の指定

プロパティcolumn-numberでカラムの順番、プロパティcolumn-widthでカラム幅を指定する。

表17・3 column-numberプロパティ
プロパティ値説明
<number>自然数。もし正でない数や自然数でない数が指定されたら、1以上の近い自然数にする。
表17・4 column-widthプロパティ
プロパティ値説明
<length>長さ
<percentage>表の幅に対するパーセント。

表の固定レイアウトではcolumn-widthプロパティにプロパティ値関数proportional-column-width()を使える。XSL-FOプロセサは、最初にカラム幅が指定された列の合計列幅を計算し、表全体の幅から組版済みの合計列幅を引いた残りを、proportional-column-width()の指定値で案分する。次の例は五つのカラムをもつ表にカラム幅を設定した。

<fo:table-column column-number="1" 
                 column-width="20pt" />
<fo:table-column column-number="2" 
                 column-width="24pt" />
<fo:table-column column-number="3" 
                 column-width="6em" />
<fo:table-column column-number="4" 
                 column-width="proportional-column-width(4)" />
<fo:table-column column-number="5" 
                 column-width="proportional-column-width(2)" />

上の例のカラム幅は次のようになる。4番目と5番目の列の幅は2:1となる。

i01-image40.png

図17・3 カラム幅の例

17–3–2 カラムの繰り返しと跨り

プロパティnumber-columns-repeatedはカラムの繰り返し回数を指定する。プロパティnumber-columns-repeatedの次のcolumn-numberは、前のcolumn-numberとnumber-columns-repeatedの合計に1を加えた数とする。

表17・5 number-columns-repeatedプロパティ
プロパティ値説明
<number>自然数。初期値は1。もし正でない数や自然数でない数が指定されたら、1以上の近い自然数にする。

number-columns-spannedはカラムのスパン(カラムを跨る数)を指定する。fo:table-columnとfo:table-cellに指定できる。

表17・6 number-columns-spannedプロパティ
プロパティ値説明
<number>自然数。もし正でない数や自然数でない数が指定されたら、1以上の近い自然数にする。

17–4 表のヘッダーとフッター

fo:table-header(ヘッダー)とfo:table-footerフッターはオプションであり、表の見出し行として使うfo:table-rowまたはfo:table-cellを包含する。プロパティtable-omit-header-at-breakプロパティtable-omit-footer-at-breakは、表がページや段を跨った場合、ヘッダーとフッターを各ページ・段で省くかどうかを指定する。

表17・7 table-omit-header-at-breakオプション
プロパティ値説明
trueヘッダーを省く。
false(初期値)ヘッダーを省かない(繰り返す)。

次の例はfo:tableにtable-omit-header-at-breakを指定していない。

<fo:table width="6cm" 
           table-layout="fixed">
  <fo:table-column column-number="1" 
                   column-width="30%"/>
  <fo:table-column column-number="2" 
                   column-width="70%"/>
  <fo:table-header>
    <fo:table-row background-color="#CCCCCC">
      <fo:table-cell border="0.3pt solid black">
        <fo:block>ヘッダー1</fo:block>
      </fo:table-cell>
      <fo:table-cell border="0.3pt solid black">
        <fo:block>ヘッダー2</fo:block>
      </fo:table-cell>
    </fo:table-row>
  </fo:table-header>
  <fo:table-body>
    <fo:table-row>
      <fo:table-cell border="0.3pt solid black">
        <fo:block>ボディ行1セル1 </fo:block>
      </fo:table-cell>
      <fo:table-cell border="0.3pt solid black">
        <fo:block>ボディ行1セル2 </fo:block>
      </fo:table-cell>
    </fo:table-row>
    <fo:table-row>
      <fo:table-cell border="0.3pt solid black">
        <fo:block>ボディ行2セル1 </fo:block>
      </fo:table-cell>
      <fo:table-cell border="0.3pt solid black">
        <fo:block>ボディ行2セル2 </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </fo:table-body>
</fo:table>

組版結果は図17・4 表のヘッダーの繰り返しのようになり、表の途中で改段されるときヘッダーを繰り返す。

images/table-omit-header.png

図17・4 表のヘッダーの繰り返し

fo:tableにtable-omit-header-at-break="true"を指定する(他は変更なし)。

<fo:table table-omit-header-at-break="true" 
          width="6cm" 
          table-layout="fixed">
    …略…

組版結果は図17・5 表のヘッダーの繰り返しを省略のようになり、表の途中で改段されたとき、ヘッダーは省略される。

images/table-omit-header-true.png

図17・5 表のヘッダーの繰り返しを省略

17–4–1 表のライティングモード

fo:tableにwriting-modeを指定すると表の行と列の進行方向が変わる。さらに子孫のFOに継承するので表のセル中のライティングモードも変わる。次の例では fo:tableにwriting-mode="tb-rl"を指定している。

<fo:table-and-caption padding="0.5em" 
                      caption-side="after"  
                      border="0.2pt solid #CCCCCC"  
                      text-align="center" >
  <fo:table-caption>
    <fo:block> writing-mode="tb-rl" table-layout="fixed" inline-progression-dimension="4cm" for fo:table</fo:block>
  </fo:table-caption>
  <fo:table writing-mode="tb-rl" 
            inline-progression-dimension="4cm" 
            table-layout="fixed">
    <fo:table-column column-number="1" 
                     column-width="30%"/>
    <fo:table-column column-number="2" 
                     column-width="70%"/>
    <fo:table-header>
      <fo:table-row background-color="#CCCCCC">
        <fo:table-cell border="0.3pt solid black">
          <fo:block>ヘッダー1</fo:block>
        </fo:table-cell>	
        <fo:table-cell border="0.3pt solid black">
          <fo:block>ヘッダー2</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-header>					
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell border="0.3pt solid black">
          <fo:block>ボディ1</fo:block>
        </fo:table-cell>
        <fo:table-cell border="0.3pt solid black">
          <fo:block>ボディ2</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</fo:table-and-caption>	

images/table-writing-mode.png

図17・6 縦組の表

17–5 表のボディ

fo:table-bodyは表のボディを包含し、fo:table-row(表の行、オプション)とfo:table-cell(表のセル、必須)を子供として持つ。

17–6 表の行

fo:table-rowは、表のセルを行にグループ化するために使う。fo:table-rowの子供はfo:table-cellである。

17–7 表のセル

fo:table-cellは表のセルのデータを配置するエリアを生成する。fo:table-cellの生成するエリアは参照エリアである。表のセルの内容はブロックレベルのFOであり、表セルに直接文字を配置できない。

17–7–1 表のセルの跨り

プロパティnumber-columns-spanned表17・6 number-columns-spannedプロパティ参照)は表のセルのプロパティとして指定すると、そのセルがカラムを跨る数を指定できる。また、プロパティnumber-rows-spannedはそのセルが行を跨る数を指定できる。

表17・9 number-rows-spannedプロパティ
プロパティ値説明
<number>自然数。もし正でない数や自然数でない数が指定されたら、1以上の近い自然数にする。

17–7–2 表のセルから行を構成

fo:table-rowがなく、fo:table-cellを子供としてもつ場合は、表の行の開始セルにstarts-row="true"プロパティstarts-row]]、表の行の終わりのセルにends-row="true"プロパティends-row]]を指定して、行毎にグループ化する。

表17・10 starts-rowプロパティ
プロパティ値説明
true当該セルから行を開始する。
false(初期値)当該セルで行を開始しない。
表17・11 ends-row
プロパティ値説明
true当該セルで行を終了する。
false(初期値)当該セルで行を終了しない。

17–7–3 ブロック方向位置合わせの設定例

表のセルにはブロック方向位置合わせ(display-align)を設定できる。

<fo:table width="12cm" 
          table-layout="fixed">
  <fo:table-column column-number="1" 
                   column-width="25%">
  </fo:table-column>
  <fo:table-column column-number="2" 
                   column-width="40%">
  </fo:table-column>
  <fo:table-column column-number="3" 
                   column-width="72pt">
  </fo:table-column>
  <fo:table-body>
    <fo:table-row height="60pt">
      <fo:table-cell column-number="1" 
                     display-align="before" 
                     border-style="solid" 
                     border-width="thin">
        <fo:block>Cell 1</fo:block>
      </fo:table-cell>
      <fo:table-cell column-number="2"
                     display-align="center" 
                     text-align="center" 
                     border-style="solid" 
                     border-width="thin">
      <fo:block>Cell 2</fo:block>
      </fo:table-cell>
      <fo:table-cell column-number="3" 
                     display-align="after" 
                     text-align="end" 
                     border-style="solid" 
                     border-width="thin">
      <fo:block>Cell 3</fo:block>
      </fo:table-cell>
    </fo:table-row>
  </fo:table-body>
</fo:table>

組版結果を図17・7 表のセル(display-align)に示す。cell1の幅は表の幅(12cm)の25%で3cmとなる。

i01-image38.png

図17・7 表のセル(display-align)

17–7–4 相対方向位置合わせ

プロパティrelative-alignプロパティによって、セル内のFOを相対的に位置合わせできる。relative-alignはdisplay-align(auto以外)が指定されていると無視される。

表17・12 relative-align(表のセル)
プロパティ値説明
before各行のすべてのセルについて、最初の子供のエリアの内容領域の前方辺は行のグリッドから同じ距離に配置される。さらに、最低一つのセルでは配置矩形の前方辺と表のセルの内容領域の前方辺が一致しなければならない。
baseline各行を構成するすべてのセルの最初の子供エリアは、最初の行のfo:table-rowに指定されている支配ベースラインが行のグリッドから同じ位置になる。さらに、セルの最初の子供エリアのうち一つは配置矩形の前方辺が、表のセルの内容領域の前方辺と一致しなければならない。つまり、該当するすべてのセルで、最初の行のベースラインはブロック進行方向で最小の距離に合わせて配置されるということである。

17–8 表の罫線

表の罫線はborder-*-style、border-*-width、border-*-colorプロパティ(ボーダープロパティ)を使って指定する。*には、before、after、start、end、top、bottom、left、rightで四辺を指定する。ボーダープロパティは、fo:table-and-caption、fo:table、fo:table-caption、fo:table-cellには制限なく適用される。fo:table-column、fo:table-header、fo:table-footer、fo:table-body、fo:table-rowには、次に説明するborder-collapseの値が"collapse"または"collapse-with-precedence"のときだけ適用される。

17–8–1 隣合う罫線を一本にするか

表はfo:tableのborder-collapseによって表の中で隣合わせのカラム(列)・行・セルの罫線を一本に統合するか別にするかを指定する。

表17・13 border-collapseプロパティ
プロパティ値説明
collapse(初期値)隣合う罫線を一本にする方法を選択する。
collapse-with-precedence隣合う罫線が衝突したときの優先度指定付きで隣合う罫線を一本にする方法を選択する。
separate隣合う罫線を分離する方法を選択する。

border-collapse="separate"のとき、border-separationプロパティにより、間隔を指定する。

表17・14 border-separationプロパティ
プロパティ値説明
<length-bp-ip-direction>行の進行方向(表のブロック進行方向)とカラムの進行方向(表の行内進行方向)の両方について長さを指定する。初期値は両方0ptである。

次の例は、表の罫線を分離し、隣合う罫線の間隔を3ptに設定している。なお、2行目のセルにはパディングを指定してセル内でのテキストの配置を変更している。

<fo:table-and-caption border-style="solid">
  <fo:table table-layout="fixed" 
            width="100%" 
            border-collapse="separate"
            border-separation.block-progression-direction="3pt" 
            border-separation.inline-progression-direction="3pt">
    <fo:table-body>
      <fo:table-row border-style="dotted" 
                    border-width="thin">
        <fo:table-cell border-style="solid" 
                       border-width="thin">
          <fo:block>1</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="dotted" 
                       border-width="thin">
          <fo:block>2</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="dashed" 
                       border-width="thin">
            <fo:block>3</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="inset" 
                       border-width="thin">
          <fo:block>4</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="outset" 
                       border-width="thin">
          <fo:block>5</fo:block>
        </fo:table-cell>
      </fo:table-row>
      <fo:table-row >
        <fo:table-cell border-style="solid" 
                       border-width="thin" 
                       padding="5pt">
          <fo:block background-color="#EEEEEE">2-1</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" 
                       border-width="thin" 
                       padding="5mm">
          <fo:block background-color="#EEEEEE">2-2</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" 
                       border-width="thin" 
                       padding="3em">
          <fo:block background-color="#EEEEEE">2-3</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" 
                       border-width="thin" 
                       padding="1cm">
          <fo:block background-color="#EEEEEE">2-4</fo:block>
        </fo:table-cell>
        <fo:table-cell border-style="solid" 
                       border-width="thin">
          <fo:block background-color="#EEEEEE">2-5</fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</fo:table-and-caption>

組版結果を図17・8 表の罫線の例に示す。

i01-image39.png

図17・8 表の罫線の例

17–8–2 罫線の優先度

border-before-precedence、border-after-precedence、border-start-precedence、border-end-precedenceは、表のFO(fo:table-and-captionとfo:table-captionの二つを除く)の各辺に、罫線の優先度を設定する。border-collapse="collapse-with-precedence"のとき、隣合う罫線のうち優先度の高い方を採用する。

表17・15 border-before-precedence、border-after-precedence、border-start-precedence、border-end-precedenceプロパティ
プロパティ値説明
forceあらゆる数字よりも優先度が高い。
<integer>自然数。数字が大きいほど優先度が高い。初期値は、fo:table: 6、fo:table-cell: 5、fo:table-column: 4、fo:table-row: 3、fo:table-body: 2、fo:table-header: 1、fo:table-footer: 0である。

17–8–3 空のセル周囲の罫線

empty-cellsプロパティは、fo:table-cellに指定し、空のセルの周囲の罫線を表示するかしないかを指定する。

表17・16 empty-cellsプロパティ
プロパティ値説明
show(初期値)表示する。
hide隠す。

17–9 一般プロパティの表への適用

表はブロックFOに適用できる様々なプロパティを設定できる。次に主なものを示す。

17–10 表のヘッダー・フッターの動的設定

fo:markerマーカー)とfo:retrieve-table-marker(表マーカー取り出し)を使って、表のヘッダーとフッターの内容を組版時に変更できる。マーカーとして表の行までの小計や「続きへ」といった文字列を用意しておき、表の途中で改ページ・改段するときにヘッダーやフッターに表示する用途などに使う(マーカーについては15–1 取り出したい内容の設定を参照)。組版された結果できるエリアにマーカーが付随する。

17–10–1 表マーカー取り出し

表マーカー取り出しは、あらかじめ用意したマーカーの内容を組版時に取り出し、取り出したマーカーの内容(子供)と置き換わる。表マーカー取り出しは、fo:table-header、fo:table-footerの子孫として、あるいはfo:tableの子供としてfo:table-header、fo:table-footerが許される位置に置くことができる。表マーカー取り出しは、取り出したマーカーの子供に入れ替わって組版されるので、マーカーの内容がその位置で構造上に妥当になるように用意しておく必要がある。

retrieve-class-nameプロパティで取り出したいマーカーの種類を限定する。また、retrieve-boundary-within-tableで範囲エリア集合の作り方を指定する。

一つのfo:table(表)を組版した結果として2段組で2ページに跨る表を例にとって、範囲エリア集合の作り方について説明する。表を組版した結果として表が分割されたとき、分割された部分をtable-fragment(表の部分)という。範囲エリア集合の作り方は、table(表全体)、表の部分、page(ページ)の三通りである。表マーカー取り出しを行う場所は分割時に作られるヘッダーまたはフッターである。図ではH1/F1~H4/F4で示す。H1/F1~H4/F4に配置される表マーカー取り出しが、取り出しの主体となり、取り出された結果、そこにマーカーの内容によるエリアが作られる。

images/table-marker--epub--.png

図17・9 表マーカーの範囲

範囲エリア集合の中で、表マーカー取り出しで取り出したマーカーの内容が生成するエリアを含むものを、主範囲エリアという。

表17・17 主範囲エリア
取り出す範囲H1/F1H2/F2H3/F3H4/F4
tableA1A2A3A4
table-fragmentA1A2A3A4
pageA1A2A3A4

ヘッダーH1~H4、フッターF1~F4の位置で、範囲エリア集合の作り方によって、主範囲エリアと先行する範囲エリアの集合は表のようになる。

表17・18 先行する範囲エリア
取り出す範囲H1/F1H2/F2H3/F3H4/F4
tableA1A1、A2A1、A2、A3A1、A2、A3、A4
table-fragmentA1A2A3A4
pageA1A1、A2A3A3、A4

H1/F1~H4/F4の位置の表マーカー取り出しは、マーカーの種類と範囲エリア集合の作り方の二つのプロパティでマーカーを限定し、その中からretrieve-position-within-tableプロパティで優先されるエリアを選択して、そこについているマーカーの内容を取り出す。

17–10–2 取り出すエリアの優先順位

retrieve-position-within-tableはマーカーの内容を取り出す対象として、優先するエリアを設定する。

表17・19 retrieve-position-within-tableプロパティ
プロパティ値説明
first-starting
(初期値)
主範囲エリアに含まれる開始エリアであり、エリアツリーで先行するエリアを優先する。
first-including-carryover主範囲エリアの子孫であり、エリアツリーで先行するエリアを優先する。
last-starting範囲エリアの子孫であり、開始エリアであり、エリアツリーで後行するエリアを優先する。
last-ending範囲エリアの子孫であり、終了エリアであり、エリアツリーで後行するエリアを優先する。

17–10–3 取り出すエリア範囲の集合

retrieve-boundary-within-tableプロパティでマーカーの内容を取り出す対象エリア範囲の集合を設定する。

表17・20 retrieve-boundary-within-tableプロパティ
プロパティ値説明
table(初期値)取り出し対象エリア範囲の集合を、主範囲エリアとそれに先行する範囲エリアに限定する。
table-fragment取り出し対象エリア範囲の集合を、主範囲エリアに限定する。
page取り出し対象エリア範囲の集合を、主範囲エリアおよびそれと同一ページ内で先行する範囲エリアに限定する。