いものやま。

雑多な知識の寄せ集め

TeXで同人誌を作ってみた。(ページスタイル作成)

f:id:yamaimo0625:20190918075457j:plain

今日はページスタイルの作成について。
なお、 \TeX \LaTeXは区別せずに扱っている。

参考にしたのは以下:

LaTeX2ε辞典 増補改訂版

LaTeX2ε辞典 増補改訂版

余談だけど、 \TeXの入門書というと奥村先生の美文書作成入門が定番として挙げられるけど、個人的にはあまり好みでない・・・
持ってはいるし参考にもするけど。
とりあえず必要なことを網羅的にぶち込みましたというリファレンス的な感じが強くて(そのくせ載ってない内容もけっこう多い)、ユーザガイドとしてはちょっと。。。
かといって他にいいユーザガイドがあるかというと難しいところで、まぁつまりは \TeX \LaTeXの設計がもはや古すぎてアレだからキレイに説明するのが難しいんだろうなぁ・・・

そんな中でこの辞典は逆引きのリファレンスのように見えて割とユーザに親切で痒いところに手が届く感じに書いてくれてるのでいい。
もちろん最初にこの本を読んでもサッパリなので、なんとなく手なりで使えるようになった人がちゃんと \TeXを使っていくときに読むといいと思う。

Before / After

閑話休題

ページスタイルを作ることでどうなるのかをまずは示しておく。

作成前はこちら:

f:id:yamaimo0625:20190921115209p:plain f:id:yamaimo0625:20190921115222p:plain f:id:yamaimo0625:20190921115234p:plain

作成後はこちら:

f:id:yamaimo0625:20190921115248p:plain f:id:yamaimo0625:20190921115300p:plain f:id:yamaimo0625:20190921115312p:plain

以下が変わってることが分かると思う:

  • ヘッダの下線がなくなっている
  • ページ番号が縦線(|)で囲われている
  • 章タイトル、節タイトルがページの内側(ノド側)ではなく外側(小口側)に寄せられている

基本的には『数学ガール』をマネたものなんだけど、ページ番号を縦線で囲っているのがオリジナルと違くて、これは柱(章タイトルとか)との区別がつきにくいと思ったから。

ちなみに、他の本を見ると以下のようなデザインもあるみたい:

  • 柱を本文に揃えて、ページ番号はその外へ出す(この場合、ページ番号を枠で囲ったりすることが多いっぽい)
  • 柱を本文に揃えて、ページ番号はフッタで出す
  • ヘッダにはページ番号だけ出し、小口に縦書きで章タイトル/節タイトルを出す

どれも一長一短で、なかなか難しいところ。

ページスタイルの概要

まず、本文領域の上と下にそれぞれヘッダとフッタがある。
そして、ヘッダとフッタの出力をどうするのかを指定するのがページスタイル。

デフォルトで以下のようなページスタイルが用意されている:

ページスタイル 説明
empty ヘッダとフッタに何も出力しない
plain フッタにページ番号を出力する
heading 柱とページ番号をヘッダに出力する
myheading ページ番号とユーザの指定した柱を出力する

独自のヘッダとフッタを出力したい場合、ページスタイルを自分で作ってそのページスタイルを使うことを指定することになる。

ページスタイルを作る場合、以下のようにする:

  1. \ps@<ページスタイル名>を定義(もしくは再定義)して、その定義の中で
    1. 奇数ページのヘッダを出力する\@oddheadを再定義
    2. 偶数ページのヘッダを出力する\@evenheadを再定義
    3. 奇数ページのフッタを出力する\@oddfootを再定義
    4. 偶数ページのフッタを出力する\@evenheadを再定義

それぞれの再定義ではページ番号を出力する\thepageや奇数ページの柱を出力する\rightmark、偶数ページの柱を出力する\leftmarkを使うといい。

なお、柱の内容は\markboth{<left mark>}{<right mark>}などで登録する。
\chapter\sectionでは内部でこれを呼び出して柱の登録を行なっている。

ページスタイルの作成

以下のようにmycustomというページスタイルを作ってみた。
(もうちょい命名なんとかならなかったものか・・・)

\makeatletter

%%% 隠しノンブルのための仕込み

% 隠しノンブルを出力(印刷用で定義を上書きする)
\newcommand{\oddNombre}{\relax}  % 奇数ページ用
\newcommand{\evenNombre}{\relax} % 偶数ページ用

%%% ヘッダ・フッタの体裁カスタマイズ

% mycustomページスタイルを作成
\newcommand{\printpage}[1]{$|$\hbox to 3em{\hss\textbf{#1}\hss}$|$}
\newcommand{\ps@mycustom}{%
    \renewcommand{\@oddfoot}{\oddNombre}%
    \renewcommand{\@evenfoot}{\evenNombre}%
    \renewcommand{\@oddhead}{\hfil\rightmark\hspace{2em}\printpage{\thepage}}%
    \renewcommand{\@evenhead}{\printpage{\thepage}\hspace{2em}\leftmark\hfil}%
    \let\@mkboth\markboth
    \def\chaptermark##1{\markboth{%
        \ifnum \c@secnumdepth >\m@ne
            \if@mainmatter
                \if@omit@number\else
                    \@chapapp\thechapter\@chappos\hskip1\jsZw
                \fi
            \fi
        \fi
        ##1}{}}%
    \def\sectionmark##1{\markright{%
        \ifnum \c@secnumdepth >\z@ \bxjs@label@sect{section}\hskip1\jsZw\fi
        ##1}}%
    }
\pagestyle{mycustom}

\makeatother

最初に隠しノンブルを出すための仕込みを用意している。
\relaxなので何もしないんだけど、印刷用の場合はあとでこれを再定義することで隠しノンブルを出力できるようになる。

そしてページ番号を|で囲って出力するためのマクロを用意している。
ページの桁数によって幅が変わるとイヤだったので、3em分の箱を作ってその中で中央寄せになるようにしてる。

あとはそれぞれの命令を再定義していて、フッタでは隠しノンブルの出力を行い、ヘッダでは柱とページ番号を出力するようにしている。

そのあと\chaptermark\sectionmarkを定義しているのは、オリジナル(bxjsbook.cls)からコピペしてきたもの。
コードを確認すると、\chapter\sectionはそこから\chaptermark\sectionmarkを呼び出し、その中で\markbothを呼び出すことで柱の登録を行なっている。
そしてこの\chaptermark\sectionmarkの命令を用意してるのは\ps@headingsなどのページスタイルの定義となっていた。
なので、自分でページスタイルを作る場合もこれらの命令を用意しておかないと柱がちゃんと出力されないっぽい。

それと最後に\pagestyle{mycustom}としてページスタイルを自分が作ったmycustomに変えておくのを忘れずに。

章初めのページスタイルの修正

これで大丈夫かなと思いきや、章初めのページは特別なページスタイルが使われるみたいだった。

\newcommand{\chapter}{%
  ...
  \plainifnotempty
  ...
  }

\def\plainifnotempty{%
  \ifx \@oddhead \@empty
    \ifx \@oddfoot \@empty
    \else
      \thispagestyle{plainfoot}%
    \fi
  \else
    \thispagestyle{plainhead}%
  \fi}

なので、そのページスタイル(plainhead)も再定義しておかないとダメだった。

plainheadのオリジナル(bxjsbook.cls)の定義は以下:

\def\ps@plainhead{%
  \let\@mkboth\@gobbletwo
  \let\@oddfoot\@empty
  \let\@evenfoot\@empty
  \def\@evenhead{%
    \if@mparswitch \hss \fi
    \hbox to \fullwidth{\textbf{\thepage}\hfil}%
    \if@mparswitch\else \hss \fi}%
  \def\@oddhead{%
    \hbox to \fullwidth{\hfil\textbf{\thepage}}\hss}}

これをmycustomページスタイルに合わせて再定義:

\makeatletter

% 章の最初のページ用のスタイルを上書き
\renewcommand{\ps@plainhead}{%
    \renewcommand{\@oddfoot}{\oddNombre}%
    \renewcommand{\@evenfoot}{\evenNombre}%
    \renewcommand{\@oddhead}{\hfil\printpage{\thepage}}%
    \renewcommand{\@evenhead}{\printpage{\thepage}\hfil}%
    \let\@mkboth\markboth
    \def\chaptermark##1{\markboth{%
        \ifnum \c@secnumdepth >\m@ne
            \if@mainmatter
                \if@omit@number\else
                    \@chapapp\thechapter\@chappos\hskip1\jsZw
                \fi
            \fi
        \fi
        ##1}{}}%
    \def\sectionmark##1{\markright{%
        \ifnum \c@secnumdepth >\z@ \bxjs@label@sect{section}\hskip1\jsZw\fi
        ##1}}%
    }

\makeatother

ただし柱は出力しないようにしている。
(これはplainheadに合わせたもの;節が始まってないから出力すべき内容もない)

emptyページスタイルの修正

普通はemptyページスタイルを修正する必要はないんだけど、隠しノンブルをフッタを使って入れるようにするので、その仕込みが必要。
(白紙ページにも隠しノンブルは出力した方がいい)

オリジナル(latex.ltx)は以下のようになっていた:

\def\ps@empty{%
  \let\@mkboth\@gobbletwo\let\@oddhead\@empty\let\@oddfoot\@empty
  \let\@evenhead\@empty\let\@evenfoot\@empty}

これを以下のように修正した:

\makeatletter

% 空白ページのスタイルを上書き
\renewcommand{\ps@empty}{%
    \let\@mkboth\@gobbletwo\let\@oddhead\@empty\let\@evenhead\@empty
    \renewcommand{\@oddfoot}{\oddNombre}%
    \renewcommand{\@evenfoot}{\evenNombre}}

\makeatother

これでページスタイルの作成は完了。

それにしても、このコピペして修正っていうの、ホントなんとかならないものか・・・
CSSのように変更がある部分だけ上書きで修正するみたいな仕組みが欲しい。
あと、そもそもオリジナルのソースを調べてみないと変更できないっていうのをやめて欲しい・・・

今日はここまで!