Skip to content

組み込み以外の言語で帳票を出す

エンジンにコンパイル済みで入っている言語は、ja-JPen-US の二つだけです。 残りはファイルです。 packs/locale/ に置かれた YAML を一つ読ませると、その言語の帳票PDFが出ます。 エンジンのビルドは変わりません。

この設計にした理由は単純で、レンダリングしない言語のデータをバイナリに入れたくないからです。 台湾向けの請求書しか出さない環境に、ヒンディー語の月名を持たせても仕方がありません。 組み込みの二つを残しているのは、ファイルを何も置かなくても動くようにするためです。

ロケールパックが決めるもの

一つのパックが持っているのは、その言語の帳票で読み手が目にする値です。

  • 通貨:既定の通貨コード、記号、言語ごとの通貨名、記号を数字のどちら側に置くか
  • 日付d MMM y のような書式と、月名、曜日名
  • 数値:桁区切りと小数点の記号、桁のまとめ方
  • 単位:「3 รายการ」の「รายการ」のような、数量に添える語
  • フォント:その言語のグリフを持つフォントパックと、ラテン文字を補うフォールバック

テンプレート側には言語が書かれていません。 defaults.locale に書くのはタグ一つで、値の見た目はパックが決めます。 ギャラリーのレシートは、同じ座標と同じ組み方で六つのロケールぶん置いてあります。 違うのはロケールのタグと、その言語で書かれたラベルだけです。

置き方

テンプレートに一行足します。

yaml
defaults:
  locale: zh-TW
  currency: TWD

あとはパックのファイルをエンジンに見つけさせるだけです。 コマンドラインなら --locale-dir を渡すか、$SHOJIKU_LOCALE_DIR を設定します。 どちらも無ければ ./packs/locale を見ます。

bash
shojiku render --templates templates.yml --params params.json \
  --locale-dir ./packs/locale --output out.pdf

ブラウザや Workers のように読めるファイルが無い環境では、パックの中身を文字列で渡します。 setLocale(tag, text) がその入口です。

タグに対応するパックも組み込みも無いときは、エンジンは代わりに別の言語を使ったりしません。 組み込みのタグ一覧と探したディレクトリを添えたエラーになります。

出荷しているパック

ロケール通貨日付フォント
zh-TWTWDy年M月d日Noto Sans TC
zh-CNCNYy年M月d日Noto Sans SC
hi-ININRd MMM yNoto Sans Devanagari + Noto Sans
fil-PHPHPMMM d, yNoto Sans
th-THTHBd MMM yNoto Sans Thai + Noto Sans

フォントも同じ考え方で、パックが名前で参照するだけです。 デーヴァナーガリーとタイ文字の書体はその文字しか持たないので、ラテン文字は noto-sans から補います。 フィリピン語はラテン文字なので、自前のフォントを持ちません。

言語によって組版そのものが変わるところ

パックはデータなので、足しても組版は変わりません。 それでも三つの言語には、エンジン側に専用の処理があります。

中国語の禁則:閉じ括弧や句読点が行頭に来てしまうとき、前の行の最後の文字を次の行へ送り、その文字を行頭にします。 日本語と同じ文字クラスを共有していて、lineBreak で強さを選べます。

インドの桁区切り₹1,23,45,678 のように、右から三桁、そのあとは二桁ずつ区切ります。 区切りの幅はパックが持つ数値なので、エンジンのアルゴリズムは言語を知りません。

タイ語の分かち書きと仏暦:タイ語は単語のあいだに空白を置きません。 折り返す場所は単語分割器が決めます(詳細)。 日付は仏暦で入り、2026 年は 2569 年になります。 西暦で出したいときは日付の書式に gregorian を指定します。

新しい言語を足す

ロケールを一つ増やすのに、エンジンのコードは触りません。 scripts/gen-locale-builtins.pyPACK_CONFIG に一項目書いて、スクリプトを流すとパックができます。 値の出どころは CLDR です。 必要なフォントパックが無い場合は、それを別に用意する必要があります。

訳文について

このページを書いた人間は、タイ語と中国語のどちらも読めません。 数値や書式は CLDR のデータをそのまま出していますが、 語の選び方や、その言語の帳票として自然かどうかまでは確かめられていません。 おかしなところを見つけたら Issue で教えてください。