自己顕示欲の開放治療所

erg, programming and something.

別名:Laughing and Grief 雑記

Latin and Greekは習ったこともない

真面目な記事の他、特定の方には不快と思われる事柄に関して言及を行うことがあります。ちょっと頑張りますが、Blog内で解決できなかった場合要望があれば別ページに技術記事は書き直します

Sphinx howtoとmanualのLaTeXでの設定を読む

sphinx-users.jp

SphinxConJP2019に参加してきました。sphinx/tex_inputsにある LaTeX{}のクラスについて掠ったのでメモ。

想定

LaTeX{}の事前理解度の想定は「大学のレポートで使わされたなあ」 とか程度。多分。

sphinxhowto.clsとsphinxmanual.cls

github.com

\LaTeX{}でのオプションにhowtoとmanualがある。 これで何が変わるかというと、tex_inputsデェレクトリにあるSphinx用クラスファイルのsphinxhowto.clsと sphinxmanual.clsからどちらを選択するがが決まる。

ところで、エンジンやクラスを選択可能なconf.pyのパラメータは別にある。

「articleとかもクラスなんじゃないの?」

これは正しい。Sphinx用のクラスはLaTeXにおける「拡張されたクラスファイル」で、 article.clsなどの設定をロードし、更に独自の要素を加えたものになる。

%
% sphinxhowto.cls for Sphinx (http://sphinx-doc.org/)
%

\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesClass{sphinxhowto}[2018/12/23 v2.0 Document class (Sphinx howto)]
...

LaTeX2eで処理されることを宣言し、次にクラスファイル名を宣言している。 ここでのクラスファイル名は\documentclass{<class>} で呼ばれる名前。

% 'oneside' option overriding the 'twoside' default
\newif\if@oneside
\DeclareOption{oneside}{\@onesidetrue}

@onesideというブール値を宣言し、 \documentclass[<options>]{<class>}のオプションでonesideがあったらこれをtrueにするのが 最初の部分。順が前後するが、このブール値は

% Default to two-side document
\if@oneside
% nothing to do (oneside is the default)
\else
\PassOptionsToClass{twoside}{\sphinxdocclass}
\fi

で使われている。

% Pass remaining document options to the parent class.
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{\sphinxdocclass}}
\ProcessOptions\relax

他にもオプションで入ってる値が何かしらあったら親クラス、ここでは\sphinxdocclassのクラスに渡してというのがこの部分。 \DeclareOption\ProcessOptionsの前に置かなくてはならないので((\ProcessOptionsのときに処理されるともいう)) \DeclareOptionをまとめて記述し\PrpcessOptionsで一段落ついた後 onesideに関するif処理がされる。 \PassOptionsToClassがオプション値を渡すところ。

\LoadClass{\sphinxdocclass} 

\sphinxdocclassにはconf.pyで設定したarticleなどが入る。 まあプログラミング言語におけるクラスの継承と大体同じ、いやわからんけど。

howtoで説明した。 onesideはページの偶奇でレイアウトが変わらず、twosideでは変わる。 manualではopenrightを強制する。openrightでは章の始まりが常に奇数ページになる。

他に標準で読みこまれるsphinx.styとsphinxmulticell.styがあるが、こちらはhowtoでもmanualでも共通するような設定が記載されている。multicellはそのうち解説、する、かなあ。

Sphinxクラスファイルの設定(LoadClass後)

項目 howto manual
セクショニングの階層 2 2
目次の階層 2 1
タイトル表示(sphinxmaketitle) "" ""
目次 "" ""
目次調整(sphinxtableofcontentshook) "" ""
参考文献 section chapter

基本的にはbookなどになるmanualでは改ページ命令が入ったりするのがそれぞれの 項目で異なる部分。

セクショニングの階層はどちらも2で、サブセクションまでは見出しに番号が表示されるということ。 基本クラスをロードするなら大抵共通になるし要るのか?

ここでの目次の階層(topdepth)の設定によって目次に反映される見出しレベルが決まる。 2だとサブセクションまで表示。

目次表示の部分、態々ページ番号表示をローマ字にするよう\pagenumberingされているが、 ナウいLaTeXのクラスでは\frontmatter\mainmatterでページ番号の書式が変えられる。 人がどれだけ古いクラスファイルを使うかは想定できないので、 書き換えて新しくするより、ナウいクラス用のカスタムクラスを作るべきかもしれない。

\tableofcontentshookなのだが、 Sphinxの需要の大部分であろうライブラリリファレンスでの 利用に耐え得るであろう値の決め打ちをしているので、 独自のドキュメントで目次出力が気に入らない場合はconf.pyの値調整ではなく LaTeX{}を書く操作が必要になる。

sphinxthebibliographysphinxhowto.clsでは \refnameがなかったら\bibnameを使うようにif文が入っている。これはクラスファイルによって 参考文献の見出し名が\refnameだったり\bibnameだったりするからで、これはむしろ 今までSphinxの恩恵を受けてきて急にLaTeX{}を生で書く必要がでてくるとひっかかるポイントかもしれない。

memoirクラスを設定しているときだけ定義しない命令、呼ばないパッケージがあるが、他のドキュメントクラスでもこういった例はあるはずで、これもっと上手い方法があるんじゃないかなあ。

SphinxによってreSTから変換されたマークアップは、ほとんどがsphinx<latex command>のように ラップされたものとなる。\LaTeX{}を生で書く人間が初めて 軽量マークアップ変換を改造しようとして戸惑うのはこういったところかもしれない。

「sphinxhowtoやsphinxmanualで基本的に問題ないが1つのマークアップだけ挙動を変えたい」

となったときsphinx.styを手で書きかえるのは嫌であれば、 ここらへんを\renewcommandで書き換えるのが恐らくなんだかんだ最小限の変更になるはず。

ちなみにmysphinx.styを作って sphinx.styを流用するようなスタイルファイルをお行儀よく作るときは \LoadPackage{sphinx} などのようにしておくと、自分で書く部分を簡単に切り分けられる (\usepackage{sphinx}\usepackage{mysphinx}に書きかえるようなことをする場合なので、 このケースはかなり問題対処がチグハグ)。

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mysphinx} % スタイルファイル名

\LoadPackage{sphinx}

\renewcommand{<書きかえる動作の名前>}{%

}
...