4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめに

対象読者

  • Claris FileMaker ユーザ
  • FileMaker に興味がある人
  • CSS 組版に興味がある人
    • not CSS 組み版ガチ勢
  • 次の前置きを要参照

前置き

  • 以下のイベントへの参加記事です
  • Paged.js を本気で使い込むって主旨ではないので、CSS 組版ガチ勢向けの記事ではありません
  • FileMaker を使って CSS 組版を簡易的にやってみたらどうなるかという、ライト層向けです
  • 「Paged.js より Vivliostyle.js のほうがよくね?」という意見もあるのは承知の上ですが、環境構築不要で LiveServer を用意することなく CDN でより簡易的に使えるのが Paged.js なので、これを採用しました

what is CSS 組版?

  • 書籍用レイアウトを HTML + CSS ( + JavaScript ) で表現するもの

最終的に出来上がるモノ

  • 以下のような感じに印刷できる

image.png
image.png

  • 冊子制作にあたりページ単位でレコード管理もできる

image.png

環境

  • Windows 10 Pro
    • Windows のため WEB ビュアーは Microsoft Edge
  • Claris FileMaker 19.4.x / 19.5.1
  • Paged.js latest

準備

Paged.js

https://unpkg.com/pagedjs/dist/paged.polyfill.js

FileMaker

fmp12 ファイル作成

  • kumihan.fmp12 を作成

テーブル作成

  • ひとまず texts という名前で一つ作成

image.png

フィールド用意

  • id - 数字
  • input - テキスト
  • css - テキスト
  • g_for_webview - テキスト - グローバル

image.png

レイアウト用意

  • 作成したフィールドをペタペタと置いていく

image.png

  • input と css のフィールドを切り替えるためにスライドコントロール

image.png

  • WEB ビューアの中身は以下の通りにして、オプションも以下のようにしておく(使うかわからないけれど)
WEB ビューア
Let (
  [
    paged_js_path = $$paged_js_path;
    input = texts::input;
    css = texts::css;

    result = texts::g_for_webview;
    result = Substitute ( result ; "[[[paged_js_path]]]" ; paged_js_path );
    result = Substitute ( result ; "[[[input]]]" ; input );
    result = Substitute ( result ; "[[[css]]]" ; css )
  ];

  result
)
  • g_for_webview フィールドの中身は以下のように
g_for_webview
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="[[[paged_js_path]]]"></script>
<style>
[[[css]]]
</style>
</head>
<body>
<script>
window.PagedConfig = {
  before: () => {
    return new Promise(resolve, reject) {
      setTimeout(() => { resolve() }, 1000);
    }
  },
  after: (flow) => { console.log("after", flow) },
};
</script>
<div id="result">[[[input]]]</div>
</body>
</html>

image.png

スクリプト用意

  • 以下の二つ
    • open
    • set_global_var.paged_js_path
  • 先ほど取得しておいた Paged.js を CDN として読み込むリンクを格納しておく

image.png

image.png

スクリプトトリガ用意

  • レイアウトに対して設定

image.png

表示するためのテキストを用意

準備完了!

  • はい、ここまで来たら準備完了です

横書き表示

input フィールドへ入力

input
<h1>方丈記</h1>
<h2>鴨長明</h2>
<p>行く川のながれは絶えずして、しかも本の水にあらず。よどみに浮ぶうたかたは、かつ消えかつ結びて久しくとゞまることなし。……(後略)……</p>

css フィールドへ入力

css
.pagedjs_page {
  margin-top: 10mm;
  margin-right: 20mm;
  margin-bottom: 25mm;
  margin-left: 15mm;
}

.pagedjs_page .pagedjs_margin-bottom-left::after {
  content: string(title);
}

.pagedjs_page .pagedjs_margin-bottom-center::after {
  content: var(--pagedjs-string-title);
  text-transform: uppercase;
}

横書きの表示確認

  • ここまでくると、以下の画像のようになっているはずです

image.png

  • スクロールしてみると……
  • お、イイ感じじゃないですか?

image.png
image.png

Google Fonts から BIZ UDPGothic を適用

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=BIZ+UDPGothic&display=swap" rel="stylesheet">
  • もうめんどうになってきたので g_for_webview の中に直接書いてしまいましょう…… </head> の手前あたりに
  • さらに css フィールドの冒頭へ追記
css
html {
  font-family: 'BIZ UDPGothic', sans-serif;
}
  • しかし何か逆に読みづらいな……? 行間が詰まりすぎているのだな

image.png

  • 以下を css へ適用
css
html {
  font-family: 'BIZ UDPGothic', sans-serif;
  line-height: 200%;
}
  • これくらいで良い感じではなかろうか🤔

image.png
image.png

横書きで印刷の検証

  • WEB ビューアを右クリックするとこういうメニューが出てきますので、ここで 印刷 を選ぶことによって WEB ビューアの中身だけを印刷することができてしまいます。便利ねー

image.png

  • オプションのところに ヘッダーとフッター チェックがついていると、今のところ邪魔なので消しておきましょうか

image.png

  • しかし……あれ?

image.png

  • なぜか偶数ページが空白になるのである🤔🤔🤔

image.png

  • こういう場合は十中八九 margin 系の CSS のせいなので、css フィールドから html の定義以外を全て削除(つまり公式ドキュメントから引っ張ってきた css を削除)
  • すると、WEB ビューアの見た目的には左寄りになったように見えてしまうけれど、印刷プレビューでは正しく改ページされるようになった。ということで、これでヨシ

image.png

image.png

横書き出力完了!

  • これでめでたく、横書きでの出力は完了できるようになりました🎉
  • ここまでは順調ですが、鬼門は次からですね……

縦書き表示

css フィールドへ入力

  • Paged.js は縦書き言語圏を想定していないので、さてどうなるか
  • css フィールドに以下のように入力します
css
html {
  font-family: 'BIZ UDPGothic', sans-serif;
  line-height: 200%;
  text-orientation: upright;
  writing-mode: vertical-rl;
}
  • お? 一見良さそうに見えますが……

image.png

  • 見事に崩れましたね、はい
  • 分かりますでしょうか、これ、上の段落のほうでは左端あたりがきれてしまっていたり……下の段落のほうでは、そもそもこれ以上下スクロールできなくなっていたり……

image.png

改ページ処理を入れてみる

  • css に以下の class を作ってみます
css
.page-break {
  break-before: page;
}
  • 改行したいところを、いったん </p> で切って、あらたに <p class="page-break"> を入れてみると……
    • なお改ページ処理は <span class="page-break"> でも可

image.png

  • お! 左にスクロールできるようにもなって、正しく改ページできている! 良い感じ!

image.png

  • 印刷プレビューで見てみると、ちょっと 1 ページ目が左端に寄りすぎていますね
  • そして、合計 2 ページって……しっかり改ページ処理を入れていかないと、印刷用に認識されないのですね🤔

image.png

  • これを解消するには、印刷サイズを 90 に縮小すると良い感じにおさまるようになります。とりあえず運用でカバーみたいな感じ……

image.png

  • さらに css に調整を入れる。明示的に A4 サイズを指定し、 p タグ内の height を長めに
css
@page {
  size: A4;
}

p {
  height: 150%;
}
  • 結果……そこそこイイ感じ?

image.png

image.png

image.png

Google Fonts から BIZ UDGothic を適用

  • 色んなことが気になってきますね。縦書きだとやはり、下端が揃っていないと気持ち悪い……
  • なのでプロポーショナルでないフォントに変更します
  • 単に 'BIZ UDPGothic' から一文字 P を削って 'BIZ UDGothic' にすればヨシ
css
html {
  font-family: 'BIZ UDGothic', sans-serif;
  line-height: 200%;
  text-orientation: upright;
  writing-mode: vertical-rl;
}
  • これによって揃ってきた

image.png

  • しかしこれ……改行処理入れていくのツライね?
  • 単一のテキストフィールドで運用するには限界があるのでは

image.png

  • ……ということで、次にページ管理をおこなうためのテーブルを作ります

テーブル拡張による管理機能の向上

pages テーブル作成と books テーブルへの改名

  • 1 ページ = 1 レコードとなるような pages テーブルを作成
  • ついでに先ほどのテーブル名を books へ改名しておく

image.png

pages テーブルへフィールド作成

  • id - 数字
  • book_id - 数字
  • page - 数字
  • head - テキスト
    • h1 タグなどが挿入される場合に使用
  • text - テキスト
  • c_word_count - 計算 - 数字
    • 改行する目安をはかるために
  • c_output - 計算 - テキスト
    • page-break class を付与した p タグで挟んで返すために
      • ただし 1 ページ目は page-break しない
    • head テキストが存在する場合はあわあせて出力

image.png

c_word_count
WordCount ( text )
c_output
If (
  not IsEmpty ( head );
    head & ¶
) & 

If (
  Exact ( page ; 1 );
    "<p>" & text & "</p>";
    "<p class=\"page-break\">" & text & "</p>"
) &

リレーション作成

  • book_id をキーにして双方向へ移動できるように

image.png

  • books から pages に対しては page の値に基づく昇順ソートを指定

image.png

books テーブルのフィールド変更

  • テキストフィールドだった inputc_input 計算フィールドへ変更
c_input
List (
  books⇔pages◎book_id::c_output
)

pages テーブル用レイアウト

  • ひとまずサッサッと置いておく

image.png

pages テーブルへレコード作成

1 ページ目

image.png

2 ページ目

image.png

3 ページ目

image.png

表示確認

  • だいたい 1 ページあたりを 400 文字以内におさめていくと、この設定であれば良い感じになる

image.png

image.png
image.png
image.png

さらに一歩先へ

段落で字下げ

  • まずは p タグについて csstext-indent を定義しましょう
css
p {
  height: 150%;
  text-indent: 1em;
}

image.png

  • 任意のところで段落下げたいというニーズもありますね。今、ページ単位で p タグを割り当てるようにしているので、ページ単位の制御は div タグにするというのが手っ取り早いでしょうか。以下で出力される p タグを div にする……しかしそうすると、必ず手で p タグを入れなくてはならなくなってメンドクサイ……🤔
c_output
If (
  not IsEmpty ( head );
    head & ¶
) & 

If (
  Exact ( page ; 1 );
    "<p>" & text & "</p>";
    "<p class=\"page-break\">" & text & "</p>"
) & ¶
  • そこで FileMaker の改行タグを br span タグに置き換えてしまいましょう。cssline-break という class も追加
css
.line-break {
  display: inline-block;
  text-indent: 1em;
}
Let ( 
  [
    head = head;
    text = text;
    text = Substitute ( text ; ¶ ; "<br><span class=\"line-break\">" )
  ];


  If (
    not IsEmpty ( head );
      head & ¶
  ) & 

  If (
    Exact ( page ; 1 );
      "<p>" & text & "</p>";
      "<p class=\"page-break\">" & text & "</p>"
  ) & ¶
)

image.png

  • 上記のようにテキストフィールド内で改行した箇所で、以下のように字下げされるようになった。これでヨシ

image.png

ルビつけたい

  • まあ日本語ですからね、つけたいですよね……ただ Paged.js はネイティヴに対応されてはいないのですよね……
  • とりあえずつけるだけなら html ストレートで ruby タグを使うやり方で対応は可能
<ruby><rt>たま</rt></ruby>しきの都の中に

image.png

image.png

  • ちょっと書き方が煩雑なのでもう少し簡単に書けるようにしたい気もする(良いアイディア募集中)
    • 横書きであれば以下記事のような書き方も可能であったけれど、縦書きだと position: absolute; がうまくハマってくれない

ページ番号を挿入したい

  • バグでページ番号が正しくカウントできないっていう issue が……🤔
  • この時点でいやダメじゃんって感じになるかもしれないけれど、グッと堪えて……
  • 横書きならページ番号出力できるのだけれど、縦書きだと表示されないという罠に遭遇中。たとえば css@page の定義中に以下を追加しておくと、正しくページ番号が表示される
css
@page {
  size: A4;

  @bottom-center {
    content: counter(page);
  }
}

image.png

  • しかし縦書きだと表示されない……

image.png

  • bottom ではなくて top にするとどうなるか? と思って試してみると、表示されるように
    • しかし @top-center とかに指定しても効いてくれないのだなあ。今後の課題……
    • 本気でやるならページめくりにあわせて左右に寄せ直ししていかないといけないですし(中央寄せという逃げ方もなくはない)
css
@page {
  size: A4;

  @top {
    content: counter(page);
  }
}

image.png

以上!

  • ひとまずこれで、最低限の FileMaker を用いた CSS 組版プレビューシステムができたかなと思います!

おまけ

books ⇔ pages の行き来

books

  • books 側には pages テーブルを一覧できるようにポータルを設置してあげるのがよいでしょう

image.png

  • ポータル内のページ番号を押すと pages テーブルの関連レコードが開かれるように

image.png

pages

  • pages 側には books レイアウトへ移動するためのボタンを置いておきます

image.png

他の手法について

  • たとえば books から pages を開く時に新しいウインドウでカード的に開かせるというのも一つの手でしょう。そのあたりはお好みで

おわりに

想定されうる反論

いや、この程度のことは組版とは呼べなくね?

  • ガチ実装までしている時間はなかったので、よかったらプルリクエスト送ってください!

何か後半、 JS あんまり関係なくね?

  • Paged.js を使うという時点で JS の上に成り立っているのです!

GitHub 公開リポジトリ

感想

  • たぶん FileMaker + JS + WEB ビューア というと、鉄板なのがチャートやグラフ系のヴィジュアライズなので、それ以外の路線で面白いネタなんかないかなーと思って逆張りしてみた感じですが、いかがでしたでしょう?
  • Paged.js は日本語縦書きと相性悪いっていう参考記事もあったので、真っ向勝負するとなると苦労しそうですが、こんな感じで FileMaker と組み合わせることによって、割とそれなりにイケる感じのつくりにできてしまうのでは? と思いましたり。FileMaker の汎用性スゲーなって話ですよ
  • 電子書籍出版……まで考えなくても、まあ社内ドキュメントくらいなら余裕でいけるんじゃないでしょうか
  • 横書きなら FileMaker のレイアウト機能オンリーで WEB ビューア使わずに組版できる気もするけれど、縦書きはさすがにキツイだろうから WEB ビューア使った方がまだ良いと思います

参考記事

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?