Vivliostyle
CSS組版ってなに?
そもそも組版とはなんでしょう。一言でいえば文字・
また、意外に思われるかもしれませんが、Vivliostyle以外にもCSS組版のアプリケーションはたくさんあります
上記にないVivliostyleの魅力は、縦書きを始めとする日本語組版に強いこと、そしてオープンソースであることです。
Vivliostyleの特徴と基本的な仕組み
Vivliostyleのアプリケーションは層状に積み重なったライブラリ/
図を見ると、2つの層に分かれていることが分かります。上層にあってブラウザーとともにHTMLとCSSを処理し、ページに組み立てるのが、組版エンジンであるVivliostyle.
この後ご紹介する2つのアプリケーションでも、最上位にVivliostyle.
前述したVivliostyle Viewerはそのままに、その下に新たな層が2つ追加されています
Vivliostyle CLIは以下のような機能をもっていますが、それらは丸括弧内のVivliostyleプロダクトの機能を利用しています。
- MarkdownをHTMLに変換する
(VFM) - スタイルを切り替える
(Themes) - 複数の原稿から本の形にまとめる
- HTMLとCSSを処理し、ページに組み立てる
(Vivliostyle. js) - CSS組版の結果をプレビューする
(Vivliostyle Viewer) - PDFとEPUBを出力する
このことから、Vivliostyle CLIにおいて、Vivliostyleの各プロダクトが1つに統合されているとも言えるでしょう。では最後に、Vivliostyle Pubをみてみましょう
Vivliostyle CLIはそのままに、下に1つ新たな層が追加されています。この層の実体はクラウドです。つまりVivliostyle Pubとは、Vivliostyle CLIをクラウド上にそのままデプロイし、ユーザー管理その他必要な機構を加えてWebアプリとして動作させたものなのです。
ここでもう一度、組版エンジンであるVivliostyle.
結果として、Vivliostyleは日進月歩の勢いですすむブラウザのCSS対応を、そのまま自分のものにできるという訳です。ただし、これについてはブラウザが変わると組版結果も変わりかねないデメリットがあることも忘れてはいけません。
実際に使ってみよう
Vivliostyle CLIを使って実際にCSS組版にチャレンジしてみましょう。前提としてNode.
では、ターミナルでサンプルファイルのあるディレクトリに移動した上で、Vivliostyle CLIをインストールしましょう。
% npm install -g @vivliostyle/cli
この記事のために青空文庫からサンプルを作ってみました。以下からローカルにクローンしてください。
% git clone https://github.com/MurakamiShinyu/shokubutsu_ichinichi.git % cd shokubutsu_ichinichi
うまくいったら、さっそくCSS組版でプレビューしてみましょう。
% vivliostyle preview shokubutsu_ichinichi.md
自動的にChromiumが起動して、下記のような画面が表示されれば成功です
画面中央右端の
ページをめくったところでウィンドウを横長に広げてみてください。下記のような見開き表示になります
最後にPDFファイルを出力してみましょう。ウィンドウを閉じてプレビューを終了させてから、以下のように入力してください。
% vivliostyle build shokubutsu_ichinichi.md -o shokubutsu_ichinichi.pdf
今いるディレクトリに、下記のようなPDFファイルが生成されているはずです
なお、Vivliostyle CLIは前述したようにEPUBが出力可能です。これについても本連載の中でご紹介していくつもりです。
Markdownファイルの中身
では、サンプルデータを詳しく見ていきましょう。まずは肝心の本文ファイル、shokubutsu_
冒頭1行から8行まで、---
で上下を囲んだ部分がフロントマター。
---
title: 植物一日一題
author: 牧野富太郎
lang: ja
link:
- rel: stylesheet
href: css/style.css
---
この部分はそのままHTMLではhead
要素に変換されます。では、実際にどのようなHTMLファイルに変換されるか見てみましょう。まず以下のコマンドでVFMをインストールします。
% npm install -g @vivliostyle/vfm
インストールが成功したら、以下のコマンドで、MarkdownファイルをHTMLファイルに変換します。
% vfm ./shokubutsu_ichinichi.md > shokubutsu_ichinichi.html
生成されたshokubutsu_
<html lang="ja">
<head>
<meta charset="utf-8">
<title>植物一日一題</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="牧野富太郎">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
フロントマターで記述されていたtitle:
、author:
、lang:
などのプロパティが、どのように変換されたか確認できます。とくに注目していただきたいのは、スタイルシートの読み込みもフロントマターのlink
でおこなっていることです。この方法以外にもvivliostyle.
でスタイルシートを指定する方法がありますが、この記事では分かりやすさを優先してフロントマターで指定しています。なお、今回は使用していませんが、一部のプロパティは<body>
の属性に変換されます。その他フロントマターの詳細は公式ドキュメントを参照してください。
さて、他にもVFMでお伝えすべきことはたくさんあるのですが、文字量の関係であと1つだけ、改行ルールについて書いておきましょう。shokubutsu_
の、たとえば142-146行目を見てください。段落と段落の間に空行が入っています。これがHTMLではどのように変換されたか、先ほどのshokubutsu_
を見てみましょう。
<p> 昔といっても文化五年(1808)の徳川時代に<ruby>小野蘭山<rt>おのらんざん</rt></ruby>という本草学者がいて、ジャガタライモを馬鈴薯であるといいはじめてから以来、今日にいたるまでほとんど誰もこれを否定する者がなく、ジャガタライモは馬鈴薯、馬鈴薯はジャガタライモだとしてこれを口にし、また書物や雑誌などに書き、これをそう肯定しているのが常識となっているが、それは大きな間違いであって、馬鈴薯はけっしてジャガタライモではないぞと今日大声で疾呼し喝破したのは私であったが、しかし蘭山がジャガタライモを馬鈴薯だといった後五年しての文化十年(1813)に<ruby>大槻玄沢<rt>おおつきげんたく</rt></ruby>は、この蘭山の考えている馬鈴薯をジャガタライモの漢名とするの説を疑い、これを<ruby>栗本丹洲<rt>くりもとたんしゅう</rt></ruby>に質問したが丹洲もまたその説を疑ったということが<ruby>白井光太郎<rt>しらいみつたろう</rt></ruby>博士の『改訂増補日本博物学年表』に出ている。</p>
<p> 元来馬鈴薯というものは中国の福建省中の一地方に産する一植物の名で、それが『<ruby>松溪県志<rt>しょうけいけんし</rt></ruby>』(松溪県は福建省地方の地名)と題する書物に僅かに載っているが、それがどんな植物であるのかは中国人でさえもこれを知らず、またかろうじての右の県志のほか、ありとあらゆる中国の文献には敢て一つもこれが出ていない。すなわち得体の分らぬ一辺境の中国土産の品で、中国人でさえも一向に知らないオブスキュアの植物である。</p>
<p> しかるにジャガタライモは元来外国産、すなわち南アメリカのアンデス地方の原産のもので、四三三年前の西暦一五六五年に初めて欧州に入り、後ち欧州から東洋に持ち来たされ、ついに我が日本におけると同様に中国にも入りこんだものである。この事実からみても、それが元来の中国植物である馬鈴薯ではあり得ない理屈ではないか。そして中国人はこの外来植物に対して適切な新命名の洋芋(洋とは海外から来た渡り者を意味する)あるいは荷蘭薯(オランダイモの意)などと称えていて、けっしてこれを馬鈴薯などと間違った名では呼んでいない。その間違いを敢てしているものはひとり日本人だけである。これはちょうど馬を指して鹿だといい、人を指して猿だといっているようなものであるから、この馬鈴薯をジャガイモと呼ぶことは躊躇なく早速に廃すべく、したがって馬鈴薯の名は即刻放遂すべきものだ。</p>
お分かりでしょうか。一般にMarkdownでは、改行2つでHTMLのp
要素の区切りになります。改行が1つだけp
要素、つまり段落ではなくなってしまいます[2]。
CSS組版のエッセンス、スタイルシート
スタイルシートを見ていく前に、CSS組版で使われるCSS仕様について確認しておきましょう。
- CSS Paged Media Module Level 3
- ページメディア用 CSS 基本仕様。ページ余白、ページサイズと向き、ページヘッダー/
フッター、ページ番号など
- ページメディア用 CSS 基本仕様。ページ余白、ページサイズと向き、ページヘッダー/
- CSS Generated Content for Paged Media Module
- ページメディア用の生成コンテンツ仕様。柱
(ページヘッダーに表示する章タイトルなど)、脚注、クロスリファレンス (ページ番号参照) など
- ページメディア用の生成コンテンツ仕様。柱
- CSS Page Floats
- ページフロート仕様。図版などを本のページの上部や下部に配置する
実際にリンク先を読むと分かりますが、これらはすべて勧告前のドラフトです。だからでしょうか、ブラウザーでは実装されていません。こうしてVivliostyleのようなプロダクトが生まれる余地ができたのですが、同時に現在のCSS組版の残念な状況も表しています。もっとユーザーを広げて、これらの仕様を勧告にまで改訂していくことが望まれます。
ではスタイルシートに移りましょう。前述した以下のコマンドで、再度プレビューを立ち上げてください。
% vivliostyle preview shokubutsu_ichinichi.md
その上でサンプルのスタイルシート、css
フォルダの中にあるstyle.
を開きましょう。:root
セレクタで定義された中の6行目に、以下のようなコメントアウトされた記述があります。
:root {
/* writing-mode: vertical-rl; */
/* ... */
}
writing-mode
は、CSS Writing Modes Level 3で規定された書字方向を指定するプロパティです。ここでは:root
セレクタで定義されたことにより、コンテンツ全体に効力が及ぶので
ただし、コメントアウトで無効化されたことで、現在は初期値のhorizontal-tb
、つまり横書きでプレビューされています。では、このコメントアウトを外して保存してみましょう。自動的にChromiumがリロードされて、縦組に変わりました
この他にもスタイルシートを上から下まで1つずつ説明していきたいのですが、文字量の関係でそうもいきません。最後にあと1つだけ、となるとやはりCSS組版の基本であるページネーションの指定をご説明します。ずっと後ろの方、266行-297行目を見てください。
@page {
size: A4;
margin: 25mm;
}
@page :left { /* 左ページ */
@top-left {
content: string(title); /* 柱:タイトル */
writing-mode: horizontal-tb;
font-size: 0.8rem;
}
@bottom-left {
content: counter(page); /* ぺージ番号 */
writing-mode: horizontal-tb;
font-size: 0.8rem;
}
}
@page :right { /* 右ページ */
@top-right {
content: string(chapter-title); /* 柱:章タイトル */
writing-mode: horizontal-tb;
font-size: 0.8rem;
}
@bottom-right {
content: counter(page); /* ぺージ番号 */
writing-mode: horizontal-tb;
font-size: 0.8rem;
}
}
最初の@page
は左と右ページの共通指定、2番目の@page :left
は左ページだけ、3番目の@page :right
は右ページだけの指定です。たとえば最初の@page
では判型とページの余白サイズを設定していますが、これは左右ページ共通の指定です。margin: 25mm
だと、左右ページの天地左右すべてのマージンが25ミリになる訳です@page
ルールについては、前述 “CSS Paged Media Module Level 3” の4.
2番目の@page :left
では柱としてタイトルが、3番目の@page :right
では章タイトルが別々に指定されています。ここでは異なる箇所で定義されている変数title
とchapter-title
を取得しています。それが下記の箇所、337行-343行です。
h1 {
string-set: title content();
}
h2 {
string-set: chapter-title content();
}
上記のようにtitle
としてh1
chapter-title
としてh2
content: string(…)
で、柱として取得し、規定のスタイルで配置するよう指定されている訳です。
柱というのは書籍特有のナビゲーションの1つです。そこでは決まった文字列や番号を、ページごとに特定の場所に配置することで、読者に今読んでいる場所をナビゲートしているのですが、こうした昔からの仕組みが巧みに仕様化されていて、それをスタイルシートで利用していることが分かると思います。より詳細は前述 “CSS Generated Content for Paged Media Module” の1.
同様に、@page :left
の子要素である@bottom-left
において、また@page :right
の子要素である@bottom-right
において、それぞれ取得するノンブルcounter(page)
として指定されています。
また、ここで記述されている@top-left
、@top-right
、あるいは@bottom-left
や@bottom-right
というのは、@top-left
は@top-right
は@bottom-left
は@bottom-right
は
まだまだCSS組版特有のCSS機能をご紹介すべきなのですが、連載初回のミッションは概説です。くどくなる前に切り上げることにしましょう。積み残した分は、この連載の後の方で再登場させていただく予定ですので、そちらで補えればと思います。スタイルシートでのコメントや、READMEになるべく説明を入れておきましたので、それらを手がかりにしてください。分からないことがあれば、私達のSlackにjoinして#q-and-aチャンネルで質問してください。大歓迎です!