XSL入門 2 スタイルシート指定のパゥワー

5 min読了の目安(約4800字TECH技術記事

XSL Advent Calendar 2020 22日目の記事です。

前回、かなり限定されたCommonMarkのASTとXSLTファイルを用意して放っておきました。
アレを処理してみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xml:lang="ja-JP"
font-size="14pt"
line-height="1.6"
font-family="Noto Serif CJK Jp"
font-weight="normal"
>
  <fo:layout-master-set>
    <fo:simple-page-master master-name="main"
     page-width="182mm" page-height="257mm">
        <fo:region-body region-name="xsl-region-body"
         margin-top="15mm"
         margin-bottom="20mm"
         margin-left="15mm"
         margin-right="15mm" />
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="main">
    <fo:flow flow-name="xsl-region-body">
<fo:block>XSL入門</fo:block><fo:block>入門用の文章。<fo:inline>入門</fo:inline>って何かは知らないけれど。</fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>

多分こんな感じのができるハズ。じゃあ、これをFOPに通してみましょう。

はい。見出しと段落が分かれていることが辛うじて読み取れる程度ですね。CommonMarkで用いたマークアップが見る影もない。Windowsのメモ帳で印刷指定だけでも出力できるんじゃないか[1]? これはブロックとインラインという構造の変換だけを行った結果です。XSL-FOはフォーマッティング用の語彙なんですから、もっと色々使ってあげましょう。強調を太字で表現したり、見出しはデッカくしたりします。

……の前に、設定ファイルにフォント設定を追加しましょう。NotoSerifCJKJpのボールド体、NotoSansCJKJpの標準書体を指定しました。

<!-- fop.xconf -->
...
  <renderers>
    <renderer mime="application/pdf">
    ...

      <fonts>
      	  <font embed-url="file:\C:\Windows\Fonts\NotoSerifCJKjp-Regular.otf">
            <font-triplet name="Noto Serif CJK Jp" weight="normal" style="normal"/>
          </font>
     
      	  <font embed-url="file:\C:\Windows\Fonts\NotoSerifCJKjp-Bold.otf">
            <font-triplet name="Noto Serif CJK Jp" weight="bold" style="normal"/>
          </font>
     
      	  <font embed-url="file:\C:\Windows\Fonts\NotoSansCJKjp-Regular.otf">
            <font-triplet name="Noto Sans CJK Jp" weight="normal" style="normal"/>
          </font>
    </renderer>
</renderers>

気をとりなおし、XSLTを書き換えます。

    <xsl:template match="/">
        <fo:root
	  font-size="14pt" 
	  font-family="'Noto Serif CJK Jp'"
	  line-height="1.6"
	  xml:lang="ja-JP">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="main"
                    page-width="182mm" page-height="257mm">
                    <fo:region-body
                        margin-top="10mm"
                        margin-botom="10mm"
                        margin-left="10mm"
                        margin-right="10mm"
                    />
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="main">
                <fo:flow flow-name="xsl-region-body">           
                    <xsl:apply-templates />
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
    
    <xsl:template match="document">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="heading">
    <fo:block font-size="x-large" font-family="'Noto Sans CJK Jp'">
        <xsl:apply-templates />
        </fo:block>
    </xsl:template>

    <xsl:template match="paragraph">
    <fo:block text-indent="1em">
        <xsl:apply-templates />
        </fo:block>
    </xsl:template>

    <xsl:template match="strong">
    <fo:inline font-weight="bold">
        <xsl:apply-templates />
        </fo:inline>
    </xsl:template>

    <xsl:template match="*">
        <xsl:apply-templates />
    </xsl:template>
<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
font-family="'Noto Serif CJK Jp'"
font-size="14pt"
line-height="1.6">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="main"
        page-width="182mm" page-height="257mm">
         <fo:region-body
	   margin-top="10mm" margin-bottom="10mm"
	   margin-left="10mm" margin-right="10mm"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="main">
      <fo:flow flow-name="xsl-region-body">
         <fo:block font-size="x-large" font-family="Noto Sans CJK Jp">
    XSL入門
  </fo:block>
         <fo:block text-indent="1em">
    入門用の文章。
    <fo:inline font-weight="bold">
      入門
    </fo:inline>
    って何かは知らないけれど。
  </fo:block>
      </fo:flow>
   </fo:page-sequence>
</fo:root>

ででどん!

ようやくスタイルシートっぽいことしました。

さて、先にフォントを設定ファイルに登録しました。大概のスタイルについては、指定されたものが存在しないまたは指定が不正な値であるときに既定値にフォールバックします。FOPやRenderXだとフォールバックのデフォルトが欧文のみを想定しているため、「指定を失敗してもとりあえず最低限のものが表示される」までの設定がビギナー向けでないですね。

さて、上のXSLTを見てどう思いましたか? 「段落の字下げ変更や強調をboldからもっと太くするときに毎回このXSLTの該当箇所を書き換えるのか」なんて具体的な不満を持ってくれましたか?

とりあえず入門2はここまでで。

脚注
  1. 勿論そうでもないし、メモ帳などの印刷だって用途によっては悪くない。 ↩︎