これはSATySFi advent calendar 2021の11日目の記事です.昨日はmonaqaさんでした.明日はTakashi Suwaさんの予定です.
LaTeXにはページスタイルという機能があります.ヘッダとフッタを出力するためのもので,文書中での変更などができます.こんな感じのものがSATySFiでもあればよいかなと思い,PageStyleパッケージを作ってみました.あわせて必要なのでページ番号を管理するPageNumberパッケージも作りました.どちらも簡素な作りのものです.主にクラスファイル作成時に使うことを想定しているもので,ちょっと楽にするというのもありますが,違うパッケージでも基盤として同じだと便利だろうというのが目的です.
インストール
いつも通りSatyrographosを使いましょう.
> opam install satysfi-pagestyle satysfi-pagenumber
> satyrographos install
pagenumberについて
先にページ番号管理について説明します.通常文書にはページ数が打たれますが,これは文書開始からのページ数とは限りません.例えば前付けが終わったときにページ数がリセットされるということはよくあります.以下,文書開始時から一つずつ増えているページ数を「真のページ数」,実際に出力されるページ数を「見かけのページ数」と呼びます.
実際に出力されるのは見かけのページ数です.これは整数値ですが,この出力形式も多様です.多くはアラビア数字でしょうが,ローマ数字かもしれません.この出力に合わせた文字列を「ページ数文字列」と呼ぶことにします.これは実際に出力される文字列のことですが,与えられた見かけのページ数を文字列に変換する関数(int -> string型)を「ページ数文字列」と呼ぶこともあります.
PageNumberパッケージは,この見かけのページ数とページ数文字列を管理します.現在の見かけのページ数をnに変更するset-page-number n
と\set-page-number n
,およびページ数文字列をfuncに変更するset-page-number func
が提供されます.真のページ数から見かけのページ数とページ数文字列を得るにはget-page-number
およびget-page-string
を使います.詳しくはマニュアルをご覧ください.
クラスファイル側の使い方
ページスタイルの定義はシンプルです.
type page-style = (|
odd-header : context -> int -> int -> string -> block-boxes;
even-header : context -> int -> int -> string -> block-boxes;
odd-footer : context -> int -> int -> string -> block-boxes;
even-footer : context -> int -> int -> string -> block-boxes;
|)
どれも同じですが,pagestyle#odd-header ctx page1 page2 str
の形で呼び出され,出力するべきblock-boxesを返します.page1
は真のページ数,page2
は見かけのページ数,str
はページ数文字列です.現在のページスタイルはheader
およびfooter
で取得できます.どちらも同様で,header istwoside pbinfo
で呼び出します.istwoside
はbool型で,ページ数の偶奇に応じてヘッダとフッタを変更するかを指定します.LaTeXドキュメントクラスによくあるtwosideオプションに似ています.pbinfo
はpage-number
フィールドに真のページ数が入っているやつです.
以上のことから,典型的には次のように定義されたpagestyle
をpage-break
の第三引数(またはpage-break-multicolumn
の第六引数)に指定することになるでしょう.
let pagestyle pbinfo =
let (xh,yh) = ... in % header の位置を計算
let (xf,yf) = ... in % footer の位置を計算
(|
header-content = PageStyle.header true pbinfo;
header-origin = (xh,yh);
footer-content = PageStyle.footer true pbinfo;
footer-origin = (xf,yf);
|)
ページスタイルの指定
ページスタイルはset-page-style-inline
で指定します.引数はページスタイル一つです.これが返したinline-boxesが埋め込まれた場所でページスタイルが変更されます.ユーザ用命令\set-page-style(page-style)
もあります.
ページスタイルは上で述べたような関数ですから,SATySFiになれていれば簡単に定義をすることができます.一方,もうちょっと簡単に定義するためにpagestyle-scheme
という関数も用意されています.これはヘッダとフッタを「柱」と「ノンブル」という単位に分割して定義するものです.詳しくはマニュアルをご覧ください.なお,クラスファイルとしての作成には次のマークの理解が必要です.
マーク
ページスタイルは上で述べたような関数ですから,SATySFiになれていれば簡単に定義をすることができます.しかし,多くの場合には「ヘッダに現在の節の見出しを出力したい」ということになるでしょう.このための機構が「マーク」です.これは次のようなことを実現します.ページの適当な場所に「マーク」として節の見出しなどのデータを登録します.そして,SATySFiがページ分割を通じて文書を構築する際に,この登録したデータを参照することができます.この機能を使うことで,ヘッダに節の見出しを出力するということは次のように実現できます.
+section
にて与えられた見出しを「マーク」に登録.- ページスタイルの各関数で,このマークを参照する.
この機能を使うには@require: pagestyle/mark
します.全ての関数はMark
モジュールに配置されています.
登録できるマークは一つではありません.複数のマークは整数値で管理されています.n番目のマークの登録はset-mark
を使いset-mark n content
により行います.典型的には見出しタイプに整数値を割り当てておくことになるでしょう.let section-mark-index=0
のようにしておくと便利かもしれません.これを使うと,+section
は例えば次のような形の定義になります.
let-block ctx +section ?:label title inner =
% 整数値section-mark-indexをどっかで定義しておく.
let mark-b = Mark.set-mark section-mark-index title in
.... % +sectionの処理
let main-b = ... % +section本体のブロックボックス
% きちんとMark.set-mark の戻り値を埋め込んでおく.
mark-b ++ main-b
同一ページ内に複数のマークがあるということもありますので,マークを参照する際にはどのマークを取得するかを指定しなければなりません.Markモジュールでは,「ページ最初のマーク」と「ページ最後のマーク」を取得する命令が提供されています.(ほかのマークを取得する命令は用意されていません,よくある文書作成ではこの二つで十分と思います.)それぞれget-first-mark
とget-last-mark
です.どちらも使い方は同様で,get-first-mark index page
とします.これはindex番目(マークは複数作ることができ,おのおののマークは整数値で管理されるのでした)のpageページの最初のマークを取得する命令です.ページスタイルを独自に作るにはこれらの関数を使うことになるでしょう.pagestyle-scheme
内ではこれらの関数が使われています.
0 件のコメント:
コメントを投稿
コメントの追加にはサードパーティーCookieの許可が必要です