カテゴリー別アーカイブ: AH Formatter

【動画公開】FormatterClub 2021秋 ウェビナー

に開催した『FormatterClub 2021秋 ウェビナー』のアンテナハウス社員発表の録画を編集、分割し「アンテナハウスPDFチャンネル」にて動画を公開しました。

『AH Formatter20年の歩み』 ~FormatterClub 2021秋 ウェビナー ~

「PDFは当初ターゲットとしていなかった」「最初はActivXアプリだった」など、最近アンテナハウスやAH Formatterを知った方には驚きの内容もあったのではないでしょうか。

『XSL Formatter 拡張仕様使いこなしガイドの紹介』~FormatterClub 2021秋 ウェビナー~

『使いこなしガイド』の紹介です。ショウケースの紹介、『使いこなしガイド』を使って入力項目のある書類を作成するデモを行いました。

『AH Formatter V7.2 のご紹介』~FormatterClub 2021秋 ウェビナー ~

AH Formatter V7.2公開がウェビナー前日の16日だったため、非常にタイムリーな話題でした。
GUIのしおり表示やaxf:float-y="anchor"など、動画映えする機能が追加されています。機能のほかにも対応プラットフォームの拡大など、見逃せない内容を紹介しています。

FormatterClubについて

Formatter Club は、アンテナハウスの XML 自動組版ソフト『AH Formatter』を導入されているユーザーや関心を持っていただいている皆様と開発者とを繋ぎ、会員同士の交流、情報交換により『AH Formatter』の利用技術を向上させ、より皆様のお役に立てる製品としていくために役立てることを目的として発足いたしました。
『AH Formatter』とその関連技術(XSL、CSS、XML 多言語組版など)に関心のある方でしたらどなたも参加できます。参加費は無料です。
Formatter Club の活動には会員メーリングリストを情報交換のために利用し、会員専用の Web ページも提供いたします。また定例会を開催し、会員相互の親睦をはかります。定例会は、『AH Formatter』開発者から最新バージョンの紹介・デモ、活用事例紹介、組版技術の向上のための勉強会などを行います。

FormatterClubについて アンテナハウス株式会社


https://www.antenna.co.jp/AHF/formatterclub.html

関連記事




XSL-FO試行錯誤 スライドPDFをXSL-FOで組む

以前に、スライドをXSL-FOで作成した例をご紹介しました。
今回、明日9/17(金)17時よりオンライン開催される「FormatterClub2021」用のスライドを改めてXSL-FOで作成したのでご紹介します。

まずは明日の宣伝です。

FormatterClub2021ウェビナー

【どなたでも無料視聴可能】

日時
2021年9月17日(金)17:00~18:10
概要
今回のFormatterClubでは、キヤノンの吉田一様にFormatterでのマニュアル作成と自動組版の取り組みを発表していただく他、XSL拡張仕様のご説明、AH Formatterの今後をご紹介を致します。
内容紹介・お申込みページ
ウェビナー登録ページ

今回はPowerPointで下書きを作成した後、清書をXMLで行い、XSLTでXSL-FOに変換するという方法を取っています。以前のウェビナーではPowerpoint原稿をそのまま使ったのですが、見出しや各箇所の文字サイズといった、同じ内容の繰り返しが多い事柄に対し個別に変更を行っていくのはちょっと辟易してしまったためです。
Powerpoint文書もXMLの集合ではあるのですが、PresentationMLはとくにDrawingML色が強く、いってみればグラフィカルな配置に重点が置かれているため、「流し込んだら良い感じに自動配置してほしい」といった要求のための元テキストを得るのは恐らくWord以上に困難です。

XSLTのバージョンは3.0で動かしています。記事中に登場するFO、XSLTの動作について保証するものではありません。ご了承ください。

XML

次のようなXMLからXSL-FOを生成します。

<section xml:id="about"><title>概要</title>
   <div style="slide" layout="cover" />
 ...
   <div style="slide" layout="fig-desc">
   <description>
     <dl>
       <dlentry>
         <dt>書名</dt>
         <dd>AH XSL Formatter拡張仕様使いこなしガイド</dd>
       </dlentry>
       <dlentry>
         <dt>公開日</dt>
         <dd>2021年5月18日</dd>
       </dlentry>
       <dlentry>
         <dt>概要</dt>
         <dd>XSLをAH XSL Formatterが独自に拡張した仕様についてのガイド
           <list style="unordered">
            <li>複合的なショウケース</li>
            <li>「やりたいこと」から引ける逆引きリファレンス</li>
          </list>
        </dd>
      </dlentry>
     </dl>
   </description>
   <figure>
      <image href="./XSL-FO-Extensions.png"/>
   </figure>
 </div>
 <div style="slide" layout="plain">
 ...
 </div>
</section>
...

若干の制限を設けたブロックとしてdescriptionタグを用意していますが、概ねHTML5程度の表現力のXMLを用意しました。汎用タグdivで何でも表そうとすると、子や親の要素・属性に制限を設けることが難しいという欠点にぶつかります。

dlentryはdtとddの組を区切るのに使用しています。HTML5のようにdivでないのは上と同じ理由です。区切りを前提にすることによってXSLT上でのパースがかなり楽に行えます。

ulとol相当はlistのclassとして使い分けます。CommonMarkのDTDなどはこのように扱っていますね。

テーマ擬き

Powerpoint、あるいは多くのプレゼンテーション用ソフトには「テーマ」という、スタイル設定の集合があります。
Word文書などと同様、Powerpoint文書はレイアウト用と見た目用の構造が渾然一体となっているのでテーマ切り替えだけでは大抵万事上手くは行かず適宜調整することになります。とまれ、見た目上の違いが印象に大きな影響を与えるスライド文書では類似の機構があると便利です。

今回は次のレイアウトを用意しました。

  • 「表紙用レイアウト」
  • 「大項目扉ページレイアウト」
  • 「通常ページレイアウト」
  • 「段組レイアウト」
  • 「画像とその説明用レイアウト」
  • 「大きめの画像表示レイアウト」

大きく異なるレイアウトについては異なるページマスターとして用意します。
通常ページ、段組、画像とその説明、大きめの画像表示レイアウトは同一のページマスターです。また、スライド全体の表紙と、大項目扉ページは同一のページマスターです。両者の違いは、fo:region-startfo:region-beforefo:region-afterの領域の有無、またそれを考慮したfo:region-bodyであるかです。

表紙系のページ

表紙以外のページ

(AH XSL Formatter拡張仕様ではページシーケンスの入れ子が行えるので「同じ項目内容の途中でスライドのレイアウトを切り換える」という要求を簡単に満たすことができます。この辺りも元のXML構造の設計に影響します。)

表紙系でないページでは、小項目のタイトルをfo:region-beforeに表示することにします。スライドではヘッダーとしての表示と見出しとしての表示を兼用してもあまり違和感がありませんね。また、大項目をfo:region-startに配置します。16:9のスライドの場合、画面の左端から右端までが4:3に比べ遠くなるため、タイトル領域として活用することにしました。こうすることで、大項目と小項目を両方表示したいとき、1つのヘッダーに大項目と小項目を両方表示するよりも、あまり文字を小さくせずにすみます。

段組レイアウトはAH XSL Formatter拡張仕様であるブロックコンテナへのcolumn-count指定で実装しました。

画像とその説明用のレイアウトはインラインコンテナを並べて実装しています。インラインコンテナは分離しないよう、念のためkeep-with-*などを指定します。幅指定を行わないと2つめのインラインコンテナが次の行へ送られてしまったり、高さ指定を合わせておかないとline-stacking-strategyによっては配置がガタガタしてしまいますから注意が必要です。

画像とその説明用のレイアウト
<fo:block>
 <xsl:attribute name="line-stacking-strategy">line-height</xsl:attribute> 
   <fo:inline-container width="48%"
     height="100%"
     keep-with-next.within-line="always">
     <fo:block>
        <xsl:apply-templates select="child::description"/>
     </fo:block>
   </fo:inline-container>
   <fo:inline-container width="50%" height="100%">
     <fo:block>
       <xsl:apply-templates select="child::figure"/>
     </fo:block>
   </fo:inline-container>
 </fo:block>

ほかの方法としては、「region-bodyを複数用意してflow-nameを切り換える」、「画像を左右へのフロートで配置する」といったものが考えられます。フロート配置は王道ですが、スライド用途の場合、AH XSL Formatter拡張でなければ思ったように(目的のスライド位置に)配置することはかなり難しいかもしれません。

箇条書き

スライドでは箇条書きが頻出する傾向があります。端的に内容を示し、口頭でのプレゼンに詳細内容を譲るためなど理由は考えられますが「様々な場所で登場する」ということに留意する必要があります。

XSL-FOのリスト構造はstart-indentとend-indentが肝要です。

ブロックのインデントは基本的には親の値を引き継いでいれば問題ありませんが、start-indentを指定したブロックの入れ子にリストブロックがあるケースなどでは、うっかり領域の端からの値にならないよう、inherited-property-value(*-indent)で親のインデントの値を取得してから自分のインデントを追加する必要があります。

<!-- 入れ子レベル$listLevelは計算済 -->
...
<xsl:attribute name="provisional-distance-between-starts">
 <xsl:value-of select="'inherited-property-value(start-indent) + 0.5em + ' || $listLevel || 'em'"/>
 </xsl:attribute>

fo:list-item-labelの内部はブロックなので、ラベルに使える記号の自由度は高いです。今回は入れ子レベルによるラベルの切り換えは行いませんでした。

定義箇条もリストブロックにしました。同じDL内のDTの文字列長を比較し、最長のものを基準にインデントを決定しています。あまりにDTが長ければ単純なブロックに切り換えます。今回は和欧混合文などは考慮しません。


<xsl:template match="dl">
 <xsl:variable name="dt-lens">
   <xsl:for-each select="child::dlentry/dt">
     <len>
        <xsl:sequence select="xs:double(string-length(./text()))"/>
     </len>
   </xsl:for-each>
 </xsl:variable>
 <xsl:variable name="max-length-dt" select="xs:integer(max($dt-lens/len/text()))"
   as="xs:integer"/>
 <xsl:choose>
   <xsl:when test="$max-length-dt &lt; 20">
     <fo:list-block
       provisional-distance-between-starts="inherited-property-value(start-indent) + {$max-length-dt}em + 2em"
       provisional-label-separation="1em">
        <xsl:for-each select="child::dlentry">
           <fo:list-item>
             <fo:list-item-label ...">
                <fo:block ...>
                   <xsl:apply-templates select=".//dt"/>
                </fo:block>
             </fo:list-item-label>
             <fo:list-item-body ...>
                <fo:block ...>
                   <xsl:apply-templates select=".//dd"/>
                </fo:block>
             </fo:list-item-body>
           </fo:list-item>
         </xsl:for-each>
     </fo:list-block>
   </xsl:when>
   <xsl:otherwise>
    ...
   </xsl:otherwise>
  </xsl:choose>
</xsl:template>

最長である「公開日」の長さを基準にインデントが決定されています。均等割り付けの指定は「:」を含んでしまっているので「概要」の後のスペースなどはちょっと微妙です。end方向に揃えるか、axf:text-autospaceで揃えるか、ブロックの横にフロートかブロックコンテナで「:」配置すればより良くなるでしょう。

枠内にテキストを収める

大項目の扉ページでは、見出しテキストを四角い枠内に収めることにしました。

スライドは本と比べ、ページごとの独立性が高くなることが多いでしょう。「1枚の中に必要なコンテンツを収めたい」というとき、フォントサイズや字間、伸縮などを最適なものから外しても1枚のスライド内に収めるため、オーバーフロー処理を記述します。

どうにかテキストを枠内に収めるにしても限界値はあります。より汎用的に使うのであれば、文字数制約や、枠自体のサイズを指定し直すような記述を追加することになるでしょう。


今回採用、実装しなかったものとしては「自由配置の吹き出し」や「画像の上から付ける下線」などがあります。グラフィカルな配置はスライドとしても重要な要素ですが、代用が可能なものでもあります。たとえば画像側で下処理を行っておけば、清書としては都度処理する必要はありません。
とはいえ、まったくそれらの処理ができないのも不便ではあります。
今後、このようにXMLからPDFスライドを作成する機会があれば、SVGやブロックコンテナをページ上の座標など簡単なパラメータで任意の場所に配置するような形態で実装するかもしれません。

関連記事



【動画公開】「DITAで本を書いてAH XSL Formatterで自動組版する」、FormatterClub2021ウェビナーのお知らせ

2021年8月10日に開催しました、ちょっと一息アンテナハウスウェビナー「DITAで本を書いてAH XSL Formatterで自動組版する」の録画を編集した動画が公開されています。

動画は1本10分程度の4本立てとなりました。

ご好評いただけましたようで、当日は予定時間をはみ出すくらいにご質問をいただきました。
「タグを気にせず書きたい」といった意見もございました。個人的には「タグを気にしながら書きたい」派でしたのでそういった方のための資料はあまり用意できていなかったのですが、そういった方面のアプローチも存在しますので、機会があればあらためてまとめたいと思います。

さて、この動画自体は少し前に公開されたのですが、何故今ブログ記事にしているかというと、次のイベントに関連するためです。

FormatterClub2021ウェビナー開催

日時
2021年9月17日(金)17:00~18:10
概要
今回のFormatterClubでは、キヤノンの吉田一様にFormatterでのマニュアル作成と自動組版の取り組みの発表の他、XSL拡張仕様のご説明、AH Formatterの今後をご紹介を致します。
内容紹介・お申込みページ
ウェビナー登録ページ【終了しました】

Formatter Club は、アンテナハウスの XML 自動組版ソフト『AH Formatter』を導入されているユーザーや関心を持っていただいている皆様と開発者とを繋ぎ、会員同士の交流、情報交換により『AH Formatter』の利用技術を向上させ、より皆様のお役に立てる製品としていくために役立てることを目的として発足いたしました。
『AH Formatter』とその関連技術(XSL、CSS、XML 多言語組版など)に関心のある方でしたらどなたも参加できます。参加費は無料です。
Formatter Club の活動には会員メーリングリストを情報交換のために利用し、会員専用の Web ページも提供いたします。また定例会を開催し、会員相互の親睦をはかります。定例会は、『AH Formatter』開発者から最新バージョンの紹介・デモ、活用事例紹介、組版技術の向上のための勉強会などを行います。

Formatter Club について | アンテナハウス株式会社

ということで、「XSL拡張仕様のご説明」として『使いこなしガイド』の紹介をさせていただく予定です。
今回のウェビナーはFormatter Club会員様以外でも参加が可能ですのでお気軽にご登録、ご視聴ください。

関連記事



XSL-FO試行錯誤 SVGでもっとグラフィカルなボーダーを

Antenna House Formatterではボーダーに指定可能な線種について大きく拡張されています。

しかし、それでもボーダーの意匠について自由自在とまでは行きません。
例えば「ロープで結ったような枠線を出したい」というときには、背景画像を置くことになるでしょう。ボーダーの扱いで(他の多くと同様に)難しいところは、ページ分割のときにどうするかです。
背景画像に固定枠の画像を指定したとき、段落の長さによって枠をずらすようなことはできませんね*。ページ分割時にbeforeとafter部分のボーダーを再表示する必要がなければ、段落の前後に画像を挟めば良いだけで、テーブルレイアウトにする必要はありません。

さて、XSL-FO試行錯誤シリーズ、以前の回でテーブルレイアウトを駆使してブロックがページ分割されるごとに特定の要素を出現させる方法を紹介しました。
つまり、テーブルレイアウトのヘッダとフッタにボーダーとなる画像を指定し、テーブルのボディのbeforeとafterの位置に表示させてやろうというのが今回の試みです。

やることは単純明快。ソースコードは単純とはいきませんが。
早速結果を見てみましょう。

可変長の段落に対応した装飾的なボーダー

今回のソースコードは(特に)色々無駄があります。見ながら一緒に突っこんでいただければ幸いです。

ソースコード
<fo:block-container>
  <fo:table table-omit-header-at-break="false" table-omit-footer-at-break="false">
    <fo:table-header>
      <fo:table-row>
        <fo:table-cell>
          <fo:block-container 
            absolute-position="absolute"
            top="-2cm" left="-2.6cm"
            width="100%" height="6cm"
            axf:background-content-height="scale-down-to-fit"
            background-image="url(./corner.svg)"
            axf:background-size="cover">
          </fo:block-container>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-header>
    <fo:table-footer >
      <fo:table-row>
        <fo:table-cell>
          <fo:block-container 
            width="100%" height="10cm">
            <fo:block-container
              absolute-position="absolute"
              top="-4cm" left="3cm"
              width="100%" height="10cm"
              axf:background-content-height="scale-down-to-fit"
              axf:transform="rotate(180)"
              background-image="url(./corner.svg)"
              axf:background-size="cover">
           </fo:block-container>
         </fo:block-container>
       </fo:table-cell>
     </fo:table-row>
   </fo:table-footer>
   <fo:table-body>
     <fo:table-row>
       <fo:table-cell>
         <fo:block space-before="4cm"
           space-before.conditionality="keep" start-indent="2cm" end-indent="2cm">
 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

...
 
         </fo:block> 
       </fo:table-cell>
     </fo:table-row>
   </fo:table-body>
  </fo:table>
</fo:block-container>

思いつきのままに書いたのでもっとやりようがある気もします……。

corner.svgがボーダーとして用いる画像です。上のコードのように、わざわざaxf:transformで回転するよりも、もう1つフッタ位置用の画像を用意した方が早いでしょう。

ボーダー分、段落のbeforeにスペースを空けています。ボーダー画像を背景に指定しているブロックコンテナにabsolute-positionを設定しているためで、ブロックとfo:external-graphicでボーダー画像を配置した場合は不要です。SVGのサイズをきちんと把握して作成しておけば、もっとスッキリした指定になるでしょう。
background-sizeにcoverを指定していますが、coverである必要もないですね。左上の画像は高さの指定と合わず切れているので怒られかねません。

今回はbeforeとafterのボーダーに注目しました。ではstart、endのボーダーはどうすればいいのでしょうか? これは実はより単純で、背景に指定したボーダー用の画像をbackground-repeatでブロック進行方向に繰り返すことで、ある程度可変長の段落に対応できるようになります。ただ、ボーダー画像の端で上手く繰り返せるように段落の高さが背景画像の高さの整数倍になるようにする、beforeとafterのボーダー画像と破綻しないようにする、といった調整が必要になるでしょう。
beforeとafterについては背景画像ではなくfo:external-graphicやfo:internal-graphicでもあまり問題はないのですが、startとend方向は繰り返しの指定上背景画像への指定が良いのではないでしょうか。

* 後から検討したのですが、背景画像を指定した複数のブロックコンテナを入れ子で記述して描画位置を調整すればある程度可能そうです。結局ページ分割の問題にあたってしまいますが。

DITAで本を書いてAH XSL Formatterで自動組版する

日時
2021年8月10日(火)16:00~17:00
概要
2021年5月18日に公開/販売した『AH XSL Formatter 拡張仕様使いこなしガイド』の制作報告を通し、XML執筆からPDFを作る過程の知見をご紹介します。
DITAについてや、DITAでの書籍制作における実例の紹介や、DITAを扱うときの注意事項など、自動組版やXMLの使い方、DITAに興味がある方、Formatterユーザーさん、必見です!
内容紹介・お申込みページ
こくちーずプロからお申し込み:https://www.kokuchpro.com/event/20210810/
Zoomウェビナーへ直接お申込みいただく場合: ウェビナー登録ページ



XSL-FO試行錯誤 最初からハイフンのある語の制御

5月18日に『AH XSL Formatter拡張仕様使いこなしガイド』が公開・発売したことは
当日の記事で述べました。

『Antenna House XSL Formatter 拡張仕様使いこなしガイド』を公開・発売しました I Love Software2!

『XSL-FO 試行錯誤』連載ではこれまで密かに「AH XSL Formatterの拡張仕様はメインの対象にしない」という縛りでやってきたのですが、めでたく書籍が公開されましたので、これからは拡張仕様についても対象にしていきます。『AH XSL Formatter 拡張仕様使いこなしガイド』に載せられなかった話題について扱うかもしれません。たとえばAH XSL FormatterではCSS3にあるような装飾表現が可能であったりするのですが「CSS3を紹介したWebサイトを見れば良いのでは」となってボツにしたものがそこそこあります。

制作のXSL-FO以外の面についての話についても折を見て記事などで展開する予定です。気になった点などがあればコメントやSNSなどで言及していただければ反映できるかもしれません。

最初からハイフンのある語の制御

ということで、本記事の話題は見出しの通り。どういったものがあるかというと、コマンドラインのオプション引数(-optionとかですね)、XSL-FOの要素、プロパティ名など(border-top-styleなど)ですね。

そもそもこれらは行分割位置に来ないようにするのがおそらく理想的ですが、ページ数の制約などで妥協することもあるかもしれません。

もとからハイフンがある語は分割によるハイフンを追加しない

<fo:block ...
 hyphenate="true"
 axf:hyphenate-hyphenated-words="false">...
</fo:block>

サンプルFOのページのサンプルでもよく使われています。プロパティ名など、もともとハイフンを含む語にハイフンが追加されてしまうと、元からあったハイフンなのか、分割時に追加されたハイフンなのか分からなくなってしまうかもしれませんからね。

他の回避手段としては、ハイフネーションとして追加される記号を変更するという方法も考えられます。

ハイフンを含む特定の文字列を、分割可能でないハイフンに置き換える

(XSL-FOの標準仕様として、「行分割でハイフンが追加され得る単語で、分割前後の文字数によって分割位置を調整する」ことができるhyphenation-remain-character-counthyphenation-push-character-countがあります。)

さて、元からハイフン(-)を含む語があり、初期設定でこのハイフンの後では分割可能であるとします。しかし、この文字の後が1字のみのとき(「UTF-8」など)のとき、「8」だけ次の行にいくのはあまり望ましくないですね。

「分割しないハイフン(NON BREAKING HYPHEN)」(U+2011)という文字があります。この文字でハイフンを置き換えてあげれば、ハイフンの前後で行分割は通常起こりません。
では、すべてのハイフンを置換しますか? それはそれで文字数の調整が狂ってしまいかねません。
また、元のファイルが500ファイル以上になっていたので、時間的に個別に置換するのはちょっと困難だとします。

今回は「特定の文字の組み合わせ(-*)でのみ、1字の次行送りが発生する」ことが分かっていたので、axf:text-replaceを使うことにしました。

axf:text-replace / CSS (-ah-)text-replace AH Formatter マニュアル


<xsl:attribute-set name="code">
<xsl:attribute name="axf:text-replace" select="'-&#x2217;' '&#x2011;&#x2217'"/>
</xsl:attribute-set>

指定に確認していない漏れがなければ上手く行っているはず。


この成果(書籍全体で適用されているか)は『AH XSL Formatter 拡張仕様使いこなしガイド』で確認してください!
(XMLファイルを処理するときにXSLTは経由したわけで、XSLT 2.0の正規表現などによる置換なども可能ですが、その辺りをあまり変更したくない、変更できない場合、ありますよね?)


『AH XSL Formatter 拡張仕様使いこなしガイド』



『Antenna House XSL Formatter 拡張仕様使いこなしガイド』を公開・発売しました

に『Antenna House XSL Formatter 拡張仕様使いこなしガイド』を公開しました。


Antenna House XSL Formatter 拡張仕様使いこなしガイド | AH Formatter XML関連出版物の紹介

また、弊社Webページで公開しているPDF版のほか、AmazonのPrint On Demand(POD)により印刷版をお買い求めいただけます。

Antenna House XSL Formatter 拡張仕様使いこなしガイド | Amazon

書籍の概要や目次についての詳細は紹介ページに掲載されていますが、この記事では少し短くまとめて紹介します。

本書は、W3C勧告のExtensible Stylesheet Language(XSL)1.1のFormatting Object(FO)から、アンテナハウスが独自に拡張した機能について解説しています。本書は次の4章構成です。

  1. 『ショウケース』
  2. 『Antenna House XSL Formatter 拡張仕様と応用例』
  3. 『PDF出力』
  4. 『その他の拡張』

『ショウケース』はAntenna House XSL Formatterを利用してどのようなレイアウトが可能であるのか、サンプルをどんと出してから、どのようにXSL-FOを記述しているかを項目に分けて説明しています。



『AH XSL Formatter 拡張仕様と応用例』では拡張仕様によって可能になる文書構造、利用例を逆引きで掲載しています。「行いたい表現」から対応する仕様を探す際などにお役に立てていただくことを想定しています。

『PDF出力』『その他の拡張』も拡張仕様の逆引き項目を主内容としますが、PDFに特化した機能は多岐に渡り、セクションでまとめるには大変な量となってしまうため、章として独立しています。『その他の拡張』は印刷やオプション設定など、文書内部とは関連の薄い項目をまとめています。

それぞれのトピックは、ほかのトピックへの言及は極力避け、目次、または最後に配置した仕様一覧へと頻繁にアクセスすることを想定した構成になっています。

さて、本書自体もAntenna House XSL Formatter V7.1改訂2版を用いて制作されています。
LwDITAで下書きを行い、DITAに変換し調整、修正を行った後、DITA-OTとPDF5-MLを基に拡張したプラグインでFOに変換、Antenna House XSL FormatterでAmazon PODの要求する仕様に沿ったPDFを出力、という工程です。この詳細についてはまたブログなどでまとめられればと思います。

Antenna House Formatterでは試用版をご用意しています。XSL-FOによる組版、そして本書で紹介しているような拡張を試用してみたい方はぜひお申込みください。
AH Formatter 評価版のお申し込み



【動画公開しました】1月26日火曜日のちょっと一息・アンテナハウスウェビナーは「PDF自動生成超入門 PDF自動生成へ挑戦する人のための始めの一歩」

アンテナハウスでは、昨年8月から第2、第4火曜日の16時から「ちょっと一息・アンテナハウスウェビナー」*と題する無償のZoomウェビナーを開催しています。

ちょっと時間の余裕があれば、お気軽にご参加いただけて有用な知識を持ち帰っていただける、肩が凝らないウェビナーを目指しています。

来週は、「PDF自動生成超入門 PDF自動生成へ挑戦する人のための始めの一歩」と題して、自動組版は初めてという人向けに、弊社が目指す自動組版のお話をさせていただきます。

自動組版にはDTPソフトを組版エンジンとして使う方式から、自動組版専用エンジンを使う方式までいろいろな方法がありますが、26日のウェビナーでは、自動組版専用エンジンであるAH Formatter**を使う方法についての簡単な説明を致します。


※画像をクリックすると「こくちーず」の本ウェビナーご案内ページに移動します。
終了しました。

本ウェビナーご視聴いただければ、今すぐでなくてもいずれは必ずお役に立つ情報を得られるでしょう。自動組版に少しでも関心をお持ちの方はぜひご参加ください。


2021年2月:追記ウェビナーの録画を編集した動画を公開しました。

なお、「ちょっと一息・アンテナハウスウェビナー」の過去開催分は録画を、YouTubeのアンテナハウスPDFチャンネルにて公開しています。
チャンネル登録をお願い致します。

Antenna House YouTube Channel

アンテナハウスPDFチャンネル


Antenna House XML Services
AH Formatter

MathMLで空欄付きの数式を表現する

センター、もとい、大学入学共通テストがおこなわれましたね。

数学や物理では数式に空欄が入った問題がおなじみです。「空欄アに入る数を答えよ」といったものですね。

ふと、「これをMathMLだけで組めるのだろうか」と思い、軽く調べてみました。
文字自体は<mtext>で良いとして、空欄であることを示すための枠線が必要です。

borderのようなattributeを持つ要素を探してみると、<mtable>が該当しました。
frame="solid"のようにして枠線が付けられます。枠で囲った「ア」を描画してみました。
セルや行、列単位で枠線を引くのであればcolumnlinesなど細かいattributeを指定しますが、今はもっとも外側の枠線だけて十分ですね。

<mtable frame="solid"><mtr><mtd><mtext>ア</mtext></mtd></mtr></mtable>

数式中に記述し、AH Formatterで出力してみます。

<mtable>による空欄付きの数式

 

根号の中に空欄が表示されています。<mtable>widthを指定できるので、幅を明示的に指定しました。

<mtable>は数ベクトルや行列を表現するために用いるのが主用途であることを考えると、電子的に配布を考える場合は別途注釈や内容のMathMLを記述した方が良いかもしれません。ともあれ、空欄付きの数式を表示してみました。

より簡潔な方法もありました。<menclose>です。

<menclose>による空欄付きの数式

こちらは「ア」の前後のパディングに、とりあえず<mspace>を使用しています。

ふと思いたち書いてみた方法なので、あるいはもっと適した方法があるのかもしれません。

なお、本記事で記述した方法を推奨したり保証するものではありません。


参考文献

Mathematical Markup Language (MathML) Version 3.0 2nd Edition

MathML 数式組版入門



XSL-FOでスライドを作成してみる

先日社内でプレゼンの機会がありました。プレゼンといえばスライドですね。プレゼンには身振り手振りやデモなどもありますが、制作期間や発表時間といった制限時間、不測の事態や資料の提出などを考えるとスライドは安定性が違います。欲をいえばプレゼン時にスクリーンに出す資料と頒布する資料は対応を取りつつ情報量を変えたいなどもありますが、こういったものはリソースとの戦いですね。

スライドといえばMicrosoft PowerPoint、macOSであればKeynoteもあります。
これらのソフトを立ち上げスライドのファイルを読み込みいざオンラインプレゼン、オンライン会議ツールを立ち上げ……あ、画面が固まった。なんてことも。GUIによるプレゼンテーション作成ソフトと、オンライン会議ツールを同時起動しているゆえに負荷がそこそこ高いからでしょうか。
他の手段として、HTML+CSS+JavaScriptスライドというのもあります。Webブラウザがあれば動くということで、まあ悪くありません。クラウドのオフィスツールではGUIでこれらを作ることもできます。外部サービスでは会社で採用していないと使える機会が限られるのが難点でしょうか。

これらのスライドを、PDFに別で保存することがあります。PDFであれば、会議の進行役に念のため予備を渡しておいて「表示環境がない」ということもそうありません。先に挙げたようなオフィスツールでPDF出力をしてもよいし、作り方にもよりますがHTMLスライドもWebブラウザなどからPDFとして出力できます。

今回なぜか発表本番2、3日前にXSL-FOを直接書いてスライドをPDF出力していました。せっかくなのでそのときのFOを一部ご紹介します。

スライドを作成するとき、コンテンツはスライドのコンテンツとして都度作成しなければなりません。構成や情報量は、発表時間やオーディエンス、発表環境などによって、練り直さなければならないためです。「スライドの一部を書き換えて何度も利用する」というのはよくあるかもしれませんが、媒体の方向性としては一品ものと捉えてもよいでしょう。1からスライドを作るのにXSL-FOを直接書くというのは個人的におススメできないことはあらかじめお伝えしておきます。

テキスト内容などは変更しています。また動作などについて保証するものではありません。使用したのはAntenna House XSL Formatter V7.0 MR5となります。

ページレイアウトと背景


<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:axf="http://www.antennahouse.com/names/XSL/Extensions"
font-size="28pt"
line-height="1.8"
font-family="sans-serif"
color="white">
<fo:layout-master-set>
   <fo:simple-page-master master-name="slide"
    background-image="linear-gradient(to left, rgba(0,0,0, .7) 0%,rgba(0,0,0, .9) 100%) )"
    page-width="1920px" page-height="1080px"
    margin="0"
>
    <fo:region-before extent="2cm" />
    <fo:region-after region-name="footer" extent="2cm"/>
    <fo:region-body region-name="body" margin="2cm 3cm" />
  </fo:simple-page-master>
</fo:layout-master-set>

ページサイズは幅1920px、高さ1080pxのFHDサイズにしました。これはPDF出力時に物理的なサイズに変換されます。
ルートでフォントサイズ、行の高さ、フォントファミリ―を指定しています。文字色も指定していますが、背景の色と関連するのでルートよりも後で指定する方が望ましいかもしれません。その背景は単純ページマスターで指定しています。線形グラデーションで灰色の度合いを変化させています。rgbaで透過色を指定をしているのは当初この下に背景画像を置こうとしていたからです。実際に追加するのであれば、linear-gradientの後に指定します。

ヘッダーとフッターの領域を2cmずつ用意し、本文区画は上下2cm、左右3㎝のマージンをとっています。

タイトルページ

タイトルページ
 <fo:page-sequence master-reference="slide">
  <fo:flow flow-name="body">
   <fo:block-container id="title" 
    <fo:wrapper font-size="92pt" line-height="2"  text-align="center">    
     <fo:block margin-top="2cm" >
       なんかものすごい<fo:block />プレゼン</fo:block>
    </fo:wrapper>
      <fo:block-container space-before="3cm" 
            text-align="end">
        <fo:block>2020-11-30</fo:block>
        <fo:block>アンテナ太郎</fo:block>     
        </fo:block-container>
    </fo:block-container>
  </fo:flow>
</fo:page-sequence>

タイトルページではヘッダーとフッターを表示しないよう、その後のページとページシーケンスを分けていますが、参照しているページマスターは同じです。ページマスターを分けるほど複雑な構成は必要なかったためこのようにしています。
タイトルは中央揃え、名前や日時はendに揃えています。よりこだわるなら名前や日時のブロック自体は右側に置いた上で、ブロックの内側では左揃えといった置き方もできます。

ヘッダーとフッター

ヘッダーに社のロゴ、フッターにスライドのページ番号を表示することにします。

ヘッダーとフッター、箇条書き

<fo:page-sequence master-reference="slide" initial-page-number="2">
<fo:static-content flow-name="header" >
    <fo:block-container><fo:block text-align="end">
      <fo:external-graphic src="url(https://www.antenna.co.jp/img/ah_headerlogo.svg)" width="8cm" height="1lh"/>
  </fo:block>  
  </fo:block-container>
</fo:static-content>
  <fo:static-content flow-name="footer">
      <fo:block-container>
          <fo:block 
           text-align="end" space-before="1cm" end-indent="2cm">
           <fo:inline font-family="serif"> p-<fo:page-number font-variant="oldstyle-nums"/> </fo:inline>
          </fo:block>
      </fo:block-container>
  </fo:static-content>
...
<fo:page-sequence>

ヘッダーのロゴの高さを行の高さにしました。このスライドでは使用していませんが、スライドの見出しをマーカーで参照し、ヘッダーで表示することを想定したサイズ指定です。SVGのロゴ画像なのでサイズ変更が容易で助かりました。

本文がサンセリフなのに対し、フッターのページ番号はセリフにすることで本文と区別できるようにしています。ついでにページ番号の数字はオールドスタイルにしてみました。ページ番号の前に接頭辞をつけるにはページシーケンスでfo:folio-prefixをつける方法がありますが、
ページ番号参照のときに「p-4」のように表示させたいわけではないので、通常のテキストとして配置しています。

initial-page-number=”auto”では前のページ番号を引き継ぐので、上で記述されているページの開始番号のように指定しなくとも問題ありません。

箇条書き

スライドでは定番の箇条書き表現。GUIのプレゼンテーションツールやHTMLとXSL-FOでかなり書き心地が異なります。

<fo:block-container break-before="page">
    <fo:wrapper font-size="62pt" font-weight="bold">
        <fo:block>
       XSL-FOの関連仕様
        </fo:block>
    </fo:wrapper>
    <fo:list-block provisional-distance-between-starts="0.5em"
    provisional-label-separation="0em"
    >
        <fo:list-item>
            <fo:list-item-label end-indent="label-end()">
          <fo:block xml:lang="en">•</fo:block>
            </fo:list-item-label>
            <fo:list-item-body start-indent="body-start()">
                <fo:block>Extensible Markup Language
          </fo:block>  
          </fo:list-item-body>
        </fo:list-item>
        <fo:list-item>
            <fo:list-item-label end-indent="label-end()">
          <fo:block>•</fo:block>
            </fo:list-item-label>
            <fo:list-item-body start-indent="body-start()">
               <fo:block>XMLNamespace</fo:block>
          </fo:list-item-body>
        </fo:list-item>
        <fo:list-item>
            <fo:list-item-label end-indent="label-end()">
          <fo:block>•</fo:block>
            </fo:list-item-label>
            <fo:list-item-body start-indent="body-start()">
           <fo:block>XML Transformations</fo:block>
          </fo:list-item-body>
        </fo:list-item>
        </fo:list-block>
    <fo:block>
    </fo:block>
</fo:block-container>

1つの箇条書き項目を表すために記述がリストブロック、リストアイテム、リストアイテムラベル、リストアイテムボディの要素と、ラベルとボディ間の間隔を指定する必要があります。入れ子のリストブロックや長さがバラバラのリストアイテムなどがあるとき真価を発揮する箇条書き用の構造ですが、これくらいの内容であれば項目ごとにブロックで記述した方が簡単です。

ソースコードを複数段表示する

ソースコード

スライドはスクリーンなどの都合もあり幅の方を長くとることが大半であると思います。これは改行で整えられた行数の多いコードを表示するのにあまり向きません。ブロックコンテナ―に段組を指定し、スライド1枚に詰め込めるソースコードを増やしてみました。

<fo:block-container break-before="page" column-count="2"
border="0.3pt solid white" 
axf:column-gap="2em" axf:column-fill="auto"
>
  <fo:block  border-bottom="0.3pt dashed white">XSL</fo:block>
  <fo:block
font-size="24pt"
line-height="1.2"
axf:line-number="show"
axf:line-number-color="white"
axf:line-number-font-size="20pt"
axf:line-number-offset="10pt"
axf:line-number-font-style="italic"
margin="2pt"
white-space-collapse="false" white-space-treatment="preserve"
linefeed-treatment="preserve"
xml:space="preserve" font-family="monospace">
..</fo:block>
</fo:block-container>

ということでXSL-FOで直接作成したスライドとその記述の一部を紹介しました。今回のように直接書くのはやはりおススメできませんが、他のXML文書などからスライドを用意するのであればなかなか悪くないのでは、と感じました。

xsl-foの基礎第2版


fo:bookmarkというマークアップから考えるしおり

『岩波国語辞典第八版』*1によれば、「しおり(しをり)」には2つの意味があります。

1. 本の読みかけのところに挟んで目印とするもの 2. 初めての人などにわかりよく説明した本。手引き

岩波国語辞典第八版

「目次」は次のように記されています。

(書物の)内容の題目を、書かれている順に並べて記したもの

岩波国語辞典第八版

しおりについて、1の意味では、読み手側が設定するものという印象が強いですね。ちなみに岩波国語辞典だとブックマークはWebブラウザのブックマーク(お気に入り)機能についての言及となっています。

さて、XML組版の仕様であるXSL1.1仕様にはしおりを作成するための機能fo:bookmarkfo:bookmark-titlefo:bookmark-treeが存在します。1.1の仕様に1.0との差異が記載されているのですぐにわかりますが、実は1.0のときには存在しなかった機能です*2

『XSL-FOの基礎 第2版』*3にしおりのFOについての解説があります。また、Antenna House XSL Formatterの*4サンプルFOのページ*5からしおりの設定されたPDFを確認できます。

<fo:layout-master-set>
    …略…
  </fo:layout-master-set>
  <fo:bookmark-tree>
    <fo:bookmark internal-destination="MARK001">
      <fo:bookmark-title font-weight="bold">
    目次</fo:bookmark-title>
    </fo:bookmark>
    <fo:bookmark internal-destination="MARK002"
                 starting-state="hide">
      <fo:bookmark-title>第1章</fo:bookmark-title>
      <fo:bookmark internal-destination="MARK003">
        <fo:bookmark-title>1.1</fo:bookmark-title>
      </fo:bookmark>
     ...
     </fo:bookmark-tree>
     ...
    <fo:page-sequence ...>
      <fo:block font-size="2em" font-weight="bold" space-after="5mm" id="MARK001">Bookmark sample-1</fo:block>
        <fo:block font-size="1.5em" font-weight="bold" id="MARK002">Lorem Ipsum</fo:block>
          <fo:block space-before="4mm" margin-left="2em" line-height="1.4">
         <fo:block keep-with-next="always" font-weight="bold" id="MARK003">Lorem ipsum dolor sit amet</fo:block>
            <fo:block>...</fo:block>
        </fo:block>
...
</fo:page-sequence>

ごく簡単に説明すると、fo:rootの子としてしおりのツリーを用意し、その子として、目的のIDやURLなどをプロパティの値に持つしおりfo:bookmarkとしおりの項目名fo:bookmark-titleを記述します。上の例ではfo:blockにそのIDが記述されていますね。ツリー構造ですので、階層も表現できます。

PDFなど、ページドメディアへの出力を意識したマークアップであるXSL-FOの機能として用意されていることから分かる通り、これは文書コンテンツ提供側が用意するしおりです。
XSL-FOは(中間形式にせよ)ページドメディアとしてかなり明示的なマークアップを求めますから「fo:bookmark*」は「この箇所をしおりとする」というはっきりとした意思表示となります。
文書コンテンツ作成者がコンテンツ頒布時に「この部分は読みかけ」というしおりを作ることは稀なことと捉えて良いでしょう。そして、fo:bookmark-titleというマークアップ名から分かる通り、しおりの項目名は長い段落などを記述する箇所でもありません。

目次項目は当然その項の内容を反映しまとめたものになりますから、しおりは多くの場合目次項目と同じ箇所でマークアップされ、対応したPDFビューアーでは「しおりを表示」といった機能でページ表示とは独立して表示できます。
特に数百、数千ページのPDF文書を頻繁に読む機会のある方は頷かれるのではないかと思いますが、紙の文書ではそれこそ「しおり」を挟んで分厚いページの束をまとめてむんずと掴んで目次に戻ったりできますが、PDFビューアー上で毎回目次ページへ戻って目次項目を確認するというのはそこそこ時間がかかります。

個人的には、しおりの重要な点として「ページ外の要素」であることが大きいのではないか、と考えています。目次で「2.3 詳細 200ページ」、文章中に「299ページに詳細」、索引ページに「fo:bookmark…300p」といったページ参照があるのはそれはそれで重要ですが、「本文を読みながら文書(あるいは文書外)の他の箇所への目印へすぐにアクセスできる」機能がしおりといえるのではないでしょうか。そして、XSLでは文書コンテンツ提供側がそれを提供することになります。

ところで、XSL-FOとXSL-FOプロセッサーによる処理ではPDFの作成時にしおりをマークアップすることになるので、すでにPDFとなっているものにしおりを付与することは範囲外です。Antenna House Formatterでは「PDFを画像のように埋め込む」といったことができるので、多少トリッキーな方法で後からしおりを付与することもできなくはありません。しかし専用のソフトウェアがあればもっと分かりやすく、そして効率的にしおりを付与できます。

antenna house webinar pdf bookmark

隔週で火曜に開催している「ちょっと一息 アンテナハウスウェビナー」、11月10日(火)16時からは「そもそも、PDFのしおりとはなにか ~目次と何が違うのか。どう作って活用するか~ 」というテーマでお送りします。この記事を書いているのが担当者でないため、発表内容の詳細はわかりません。しおりってなんなんでしょうね……。この謎を明かすためにも明日のウェビナーは必見です。

参考文献・資料

  1. *1 『岩波国語辞典第八版』(岩波書店, 2019年11月22日第1刷発行, ISBN 978-4-00-080048-8)
  2. *2 https://www.w3.org/TR/xsl11/#change10
  3. *3 https://www.antenna.co.jp/AHF/ahf_publication/data/xsl-fo-v2/201603282131.html『XSL-FO の基礎 第2版 – XML を組版するためのレイアウト仕様』(アンテナハウス株式会社, 2017年3月, ISBN 978-4-900552-48-7)
  4. *4 Antenna House Formatter
  5. *5 https://www.antenna.co.jp/AHF/ahf_samples/sample-fo.html#pdf


Pages: 1 2 3 4 5 6 7 8 9 10 ... 24 25 26 Next