アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

Paged.js を試す

October 23, 2020開発Paged.js

CSS 組版 Vivliostyle ユーザーと開発者の集い 2020 秋」で登壇することになった。テーマは「Paged.js について」。登壇スライド作成の一環として調査内容をブログにまとめる。

2020/11/3 追記

本記事の調査内容について Vivliostyle 村上さんが追試と考察を Gist へまとめている。随時、更新中。本記事に対する追補編と呼べる内容なので併せて一読を。

Paged.js とは?

Paged.js は Web ブラウザー上のコンテンツを CSS Paged Media Module (以下、Paged Media) に基づき組版をして印刷用のデータを生成するソフトウェア。オープン ソースとして pagedjs/pagedjs で開発されている。利用方法は以下。

どの方法でも最終的に HTML/CSS を組版することは共通であるため、本記事では取り回しのよい CLI を試す。

サンプル HTML/CSS

ゼロから Paged Media を網羅的に利用した HTML/CSS を作るのは大変なので、既存のサンプルを利用することにした。候補は以下。

Paged Media は Web 標準規格。そのため理想的には一方のサンプルが他方でも有効となるはず。これを前提として両サンプルを試す。なお村上さんと相談して以下は除外した。

  • 縦書き系

    • Vivliostyle サンプルの「ごん狐」など
    • Paged.js は未対応
  • 複数 HTML ファイル参照系

    • Vivliostyle サンプルの「Vivliostyle で本を作ろうシリーズ」など
    • この機能は Vivliostyle 独自拡張であるため
  • XML 系

    • print-css.rocks の lesson-two-column-with-author-box など
    • Vivliostyle と Paged.js が共に未対応
  • その他

    • Vivliostyle における wood_chrome
    • 昔の Chrome がハイフネーション未対応だったので wood に対し、これを無効にしたもの
    • 現在は対応されているので wood だけでよい

結果、

  • Vivliostyle: 9
  • print-css.rocks: 54

の合計 63 サンプルを検証対象とする。

CLI

Paged.js 公式ページの解説では CLI をグローバルにインストールしているが Node.js プロジェクトのローカルにしたほうが影響範囲が小さく管理もしやすい。よって以降は akabekobeko/examples-vivliostyle-pagedjs で試す。このプロジェクトでは Paged.js と Vivliostyle の CLI を利用して PDF 出力を実行するようにした。

検証対象とするサンプルはありがたいことに GitHub へ公開されている。そのため git submodule として参照するようにした。

npm-scripts としては以下のような感じ。命名は v: = Vivliostyle、p: = Paged.js でその後にサンプル種別 (Vivliostyle、print-css.rocks) と連番を振っている。

{
  "scripts": {
    "v:viv01": "vivliostyle build ./vivliostyle/samples/gon/index.html -o pdf/viv01.pdf",
    "p:viv01": "pagedjs-cli ./vivliostyle/samples/gon/index.html -o pdf/viv01.pdf"
  }
}

当初 PDF 出力だけでなくプレビューも定義していたのだが、村上さんと相談したところ最終出力である PDF をチェックすれば十分と判断した。PDF 出力は npm-run-all により一括実行も可能としてある。

比較検証

CLI で出力した PDF を対象に Vivliostyle と Paged.js を比較検証してゆく。検証にあたり成否判定の基準とする PDF は以下。

  • Vivliostyle

    • 本プロジェクトのコマンド実行により vivliostyle-cli が出力した PDF ファイル
    • Paged.js の基準になる
  • print-css.rocks

    • print-css-rocks/lessons/generated/**/*.pdf
    • ここには Lesson x Tool 単位の PDF が置かれている
    • Lessons の対応項目で OK とされたソフトウェアの PDF を基準とする
    • Vivliostyle と Page.js 両方の基準になる

以降へ実際に検証した結果をまとめた。リストにおける表記は V = Vivliostyle、P = Paged.js となる。

Vivliostyle サンプル

  1. 高瀬舟 (ルビ) - 固定サイズ

    • V: OK
    • P: NG、ルビ表示 OK。ページ処理無効。後続ページであろうテキストが重なって表示される。
  2. 高瀬舟 - 固定サイズ

    • V: OK
    • P: NG、ページ処理無効。後続ページであろうテキストが重なって表示される。
  3. Alice's Adventures in Wonderland

    • V: OK
    • P: NG、左ノンブル表示無効、リスト連番無効、first-letter 無効など。コンテンツの区切り?に十字の記号が表示されるのは独自拡張?
  4. White Fang

    • V: OK
    • P: NG、左ノンブル表示無効、リスト連番無効、first-letter 無効など。コンテンツの区切り?に十字の記号が表示されるのは独自拡張?
  5. The Adventures of Sherlock Holmes

    • V: OK
    • P: NG、PDF 出力不能。詳しくはこちらを参照のこと。
  6. 高瀬舟 (ルビ) - 可変サイズ

    • V: OK
    • P: NG、ページ処理無効。後続ページであろうテキストが重なって表示される。
  7. 高瀬舟 (ルビ) - 可変サイズ

    • V: OK
    • P: NG、ページ処理無効。後続ページであろうテキストが重なって表示される。
  8. Wood Engraving

    • V: OK
    • P: OK
  9. 宇宙論入門

    • V: OK
    • P: NG、ページ処理無効。「高瀬舟」などと異なり後続ページのテキストは出現せず重ならない。

成否の数を表へまとめる。

Software OK NG
Vivliostyle 9 0
Paged.js 1 8

print-css.rocks サンプル

  1. antennahouse-autofit-text

    • V: NG、"Box with text overflow" だけ OK、それ以外は青枠に収まらずはみ出る。
    • P: NG、同上。
  2. antennahouse-multicol-with-sidenotes

    • V: NG、赤い傍注が上部に表示、他の傍注は本文へ重なる。テーブルに本文テキストが回り込む。
    • P: NG、赤い傍注は正常表示、他の傍注は消える。テーブルに本文テキストが回り込む。
  3. archive-pdf

    • V: NG、画像が表示されない。
    • P: NG、同上。
  4. background-repeated

    • V: OK
    • P: NG、スケーリングとマージンが効かずページ全体に画像が広がる
  5. basic

    • V: OK
    • P: OK
  6. blank-pages

    • V: NG、ブランク ページは処理できているが他のソフトウェアのように青ではなく真っ白になる
    • P: OK
  7. border-model

    • V: OK
    • P: NG、p2 のボーダーが正方形ではなく縦へかなり延びた長方形になる
  8. box-styling

    • V: OK
    • P: OK
  9. center-vertical

    • V: OK
    • P: OK
  10. chapter-numbering

    • V: OK
    • P: OK、ネスト表示を対象としているためか Lessons で OK とされているが Paged.js だけ数字が 1 開始ではなく 2 となっているのは気になる。
  11. chart-js

    • V: NG、チャート表示されず真っ白になる。
    • P: NG、同上。
  12. cmyk

    • V: OK、Lessons 上で OK とされる Paged.js 相当の表示になっているため OK とした。しかし Paged.js と共に他サンプルで表示されている冒頭テキストの背景と枠線がない点が気になる。
    • P: OK
  13. complex-css

    • V: OK
    • P: OK
  14. cross-references

    • V: OK
    • P: NG、目次の Chapter が対応する I 〜 IV ではなく全て 0。
  15. css-gradients

    • V: OK
    • P: OK
  16. css-transformations

    • V: OK
    • P: OK
  17. css-transformations2

    • V: OK
    • P: OK、Lessons 上で OK だが図形 (これは適切) 以外の余計な線や背景色のはみ出しから NG に見える。
  18. css-transformations3

    • V: OK
    • P: OK
  19. css-zindex

    • V: OK
    • P: OK
  20. css-zindex-2

    • V: OK
    • P: OK、Lessons 上で OK だが全サンプル中 Antennahouse と PDFreactor だけ #1 #3 の前面で他は背面となるのが気になる。
  21. flotr2-js

    • V: NG、真っ白。JavaScript 処理が必要なので Paged.js と同様に対応していない?
    • P: NG、ただし真っ白にはならずチャートの数字だけは表示される。
  22. fonts

    • V: OK
    • P: OK
  23. fonts-emoji

    • V: OK
    • P: OK
  24. footnotes

    • V: NG、脚注の数字を処理できておらず文中はすべて 0 表記、脚注テキストには数字が割り当てられない。
    • P: NG、PDF 出力処理が終わらない。詳しくはこちらを参照のこと。
  25. footnotes-multi-columns

    • V: NG、マルチカラムになっているが脚注の数字を処理できていない。
    • P: NG、マルチカラムになっているが脚注を処理できず、そのテキストが本文にそのまま表示される。
  26. hyphenation

    • V: OK、行末にきた "welches" を "wel-" と "ches" にして行送りをするなど、対応していると判断した。
    • P: NG、Lessons の指摘どおり単語のハイフネーションが効いていない。
  27. hyphenation-long-words

    • V: OK
    • P: NG
  28. image-multi-columns

    • V: OK
    • P: OK
  29. image-scaling

    • V: OK
    • P: OK
  30. images

    • V: OK、ただし PDF 参照は未サポート。
    • P: OK、同上。
  31. ligatures

    • V: OK
    • P: OK
  32. mathml-native

    • V: NG、数式として表示されず通常のテキストになる。
    • P: NG、PDF 出力処理が終わらない。詳しくはこちらを参照のこと。
  33. mathml-torture-test

    • V: NG、"As rendered by your browser" が全て失敗 (Chromium の問題?)。
    • P: NG、同上。
  34. metadata-pdfua

    • V: OK、Lessons で Paged.js が本機能を未サポートとして OK なので Vivliostyle も同様と判断した。
    • P: OK、同上。
  35. multi-columns

    • V: OK
    • P: OK
  36. multiple-backgrounds

    • V: OK
    • P: OK
  37. named-pages

    • V: NG、p2 が独立したページにならず landscape 表示もされない、p3 が出力されない。
    • P: NG、p2 が landscape 表示されない、Lessons に指摘された空白の p4 は出力されなかった (修正された?)。
  38. page-areas

    • V: OK
    • P: OK、Lessons に指摘された空白の p2 は出力されなかった (修正された?)。
  39. page-numbers

    • V: OK
    • P: OK、Lessons ではページ番号が表示されず NG だが正常表示されている (修正された?)。
  40. pagination

    • V: OK
    • P: OK
  41. pdf-bookmarks

    • V: NG、Lessons で NG とされている Paged.js と同様の出力だが「見本と全く見分けがつかない = print-css.rocks の評価を踏襲」ということで NG とした。
    • P: NG、同上。
  42. pdf-links

    • V: OK
    • P: OK
  43. pdfreactor-autofit-text

    • V: NG、"Auto fit by adjusting the font-size using Javascript" でテキストが青枠に収まらずはみ出る。
    • P: NG、同上。
  44. pdfreactor-mathjax

    • V: NG、数式として表示されない。
    • P: NG、同上。
  45. pdfreactor-multicol-with-dual-sidenotes

    • V: NG、傍注が本文に重なって表示される。
    • P: NG、同上。
  46. pdfreactor-multicol-with-sidenotes

    • V: NG、p1 傍注が上部へ表示される、テーブルが隣のカラムにはみ出る。p2 正常。p3 傍注が表示されない。
    • P: NG、p1 傍注正常、テーブルが隣のカラムにはみ出る。p2 正常。p3 傍注が表示されない。
  47. positioning

    • V: OK
    • P: OK
  48. prince-multicol-with-dual-sidenotes

    • V: OK、リポジトリー上に存在するが Lessons ページは見当たらず。名前から Prince 固有機能と思われるので OK (明示的な未サポート) とする。
    • P: OK、同上。
  49. prince-table-tricks

    • V: OK、Prince 固有機能と思われるので OK (明示的な未サポート) とする。
    • P: OK、同上。
  50. right-to-left

    • V: OK
    • P: OK
  51. running-elements

    • V: NG
    • P: NG
  52. tables

    • V: OK
    • P: NG。p2 ヘッダーだけ。p3 ヘッダーすら表示されず。p4 ヘッダー表示されずフッターがテーブルから離れて表示。p5 出力されず。
  53. texts-rotated-360-degrees

    • V: OK
    • P: OK
  54. typography

    • V: OK
    • P: OK

成否の数を表へまとめる。

Software OK NG
Vivliostyle 37 17
Paged.js 32 22

考察

Vivliostyle サンプルで Paged.js が正常表示できたのは Wood Engraving のみであった。print-css.rocks のページネーション系は正常に処理できているため、原因がサンプルか Paged.js が対応しきれていない機能によるものなのか気になる。

print-css.rocks サンプルは Paged.js だけ OK なものは blank-pages だけであった。逆に Vivliostyle だけ OK なものは結構ある。当初 print-css.rocks の検証対象となるだけあって Paged.js のほうが OK で上回ると予想していたため意外だった。

Vivlostyle (vivliostyle-cli)、Paged.js (pagedjs-cli) は共に puppeteer 経由で Chromium を利用しているため、その対応状況に依存する数式などは同様に NG となっていた。puppeteer-core だと処理対象に Firefox も指定可能なので数式に関してはそちらにすることで、よりよい結果を得られるかもしれない。

print-css.rock の Lessons で Paged.js が NG となっていた問題の一部は修正されているようだ。村上さんの調査で根本原因を特定した問題もあるので後ほど本家の Issue として報告する予定。

その他、気になった点。

  • 公式 Web サイト

    • 技術情報が非常に充実している How to use Paged.js
    • Paged Media の機能を個別詳細に解説している点が特にすばらしい
    • Polyfill かくあるべし、という感じ
  • 周辺ツール

    • 単体 JavaScript、npm、CLI
    • 最近の Vivliostyle も拡充を進めている部分なので参考になる
    • vivliostyle/themesvivliostyle/create-book などは Vivliostyle が先行していると思う
    • 公式ではないようだが VS Code 拡張は訴求力ありそう、環境構築の面倒さを回避できるしプレビューもありがたい
  • サンプル不足

    • 機能単位のサンプル コードはあるが、文書としての公式サンプルはなさそう
    • Vivliostyle でいう vivliostyle/vivliostyle_doc 的なものがほしい
  • pagedjs-cli のプレビュー

    • Chromium へ表示するだけで Vivliostyle Viewer のようなパラメーター変更機能などは提供されない
    • プレビュー実行すると初回描画が崩れて Web ブラウザーのリロードが必要なことがある
    • CLI パラメーターが -d, --debug であり、開発者の DevTools 用途を想定しているようだ
    • Vivliostyle のプレビューや Web ブラウザー向け表示の良さを再認識した

まとめ

CSS 組版技術として Vivliostyle のよき競合だと感じた。サンプル検証結果も拮抗している。print-css.rocks のような第三者の比較検証に選ばれている点で認知度も高そう。Vivliostyle も CLI など周辺ツールが充実してきたので、こうした方面への訴求をするのはどうだろうか?

競合といっても Paged.js とは共存共栄してゆきたい。Vivliostyle で本を作ろう Vol.2 への寄稿でも触れたが、組版も含む View (外観) を定義する技術として Web 標準の普及を願っている。その仲間として Paged.js を歓迎したい。

Copyright © 2009 - 2020 akabeko.me All Rights Reserved.