Re: SphinxのLaTeXのフォーマットをいじる

卒論とか修論TeX で書いていた割には、TeX マクロが苦手な @tk0miya です。
先輩から秘伝のタレ的?なスタイルファイルを頂いたのでそれで済ませてました。

Sphinx で PDF 出力するときは TeX を介して出力することが多いのですが、
未だに TeX マクロをちゃんと理解していないのでまったくいじらず、素のままで使っていました。

そんな折、
SphinxのLaTeXのフォーマットをいじる という記事を見かけました。

この記事では Sphinx 本体や付属のマクロをいじっているのですが、Sphinx は設定でアプローチできるようになっているので、
同じことを conf.py の記述だけで実現してみようと思います。

用紙サイズを a4 に変更する

latex_elements['papersize'] 経由で変更できます。

latex_elements = {
    'papersize': 'a4paper',
}

latex_paper_size という変数もあるので、こっちで指定してもよいみたい。こっちは page と size のあいだにアンダースコアが入る。
その場合は paper を付けずに指定する模様。

latex_paper_size = 'a4'

article クラスを利用する

latex_documents の末尾の要素を書き換えます。デフォルトでは report 系を意味する 'howto' が指定されています。

latex_documents = [
  ('index', 'test.tex', u'test Documentation',
   u'test', 'howto'),
]

行間を狭くする

BEGIN_DOC の内容はいじれませんが、マクロの差し替えをするだけであれば latex_elements['preamble'] を使います。

latex_elements = {
    'preamble': '''
\\renewcommand{\\baselinestretch}{0.8}
'''
}

default_elements を書き換える

conf.py の latex_elements を設定しておくと、上書きされます。
記事と同じ内容に揃えるのであればこうすると良いみたい。

latex_elements = {
    'papersize': 'a4paper',
    'fontpkg': '',
    'fncychap': '',
}

ちなみに、fncychap は language = 'ja' の設定をしていると、自動的に空になるようです。

TeX のドキュメントクラスに jsarticle, jsbook を使いたい

これは LaTeX 経由での PDF 出力の設定でもお馴染みですね。latex_docclass を定義します。
普段は jsbook しか設定していませんが、ちゃんと jsarticle も使えるようにしておきます。

latex_docclass = {
    'howto': 'jsarticle',
    'manual': 'jsbook',
}

ページ番号を表示する

これもプリアンブル部に定義すると良いので、latex_elements['preamble'] に書き加えます。

latex_elements = {
    'preamble': '''
\\pagestyle{plain}
\\thispagestyle{plain}
'''
}

ここでは \thispagestyle{empty} を無効にするために、再度 \thispagestyle を呼んでページスタイルを上書きしています。

ページ番号の深さを変更する

これもやっぱりプリアンブル部です。

latex_elements = {
    'preamble': '''
\\setcounter{secnumdepth}{3}
'''
}

タイトルを変更する

ちょっと量が多いので悩んだのですが、これもプリアンブル部に突っ込みます。
TeX のエラーで悩まされたので \makeatletter, \makeatother で囲んで調整しています。

latex_elements = {
    'preamble': '''
\\makeatletter
\\renewcommand{\maketitle}{
  \\ifsphinxpdfoutput
    \\begingroup
      \\def\\\\{, }
      \\def\\and{and }
      \\pdfinfo{
        /Author (\\@author)
        /Title (\\@title)
      }
    \\endgroup
  \\fi
  \\begin{center}
    \\sphinxlogo%
    {\\Large \\@title} \\par
  \\end{center}
  \\begin{flushright}
    \\@date \\hspace{3zw} \\@author \\par
    \\py@authoraddress \\par
  \\end{flushright}
  \\@thanks
  \\setcounter{footnote}{0}
  \\let\\thanks\\relax\\let\\maketitle\\relax
}
\\makeatother
'''
}

目次を変更する

これもやっぱりプリアンブル部。

latex_elements = {
    'preamble': '''
\\let\\pyOldTableofcontents=\\tableofcontents
\\renewcommand{\\tableofcontents}{
  \\begingroup
  \\parskip = 0mm
  \\pyOldTableofcontents
  \\endgroup
  \\vspace{12pt}
}
'''
}

元の定義だと \py@OldTableofcontents って変数名なんだけど、なぜかエラーになったので @ を取ってしまいました。
原因がよく分からないけど、動いたので深追いせず。

まとめ

プリアンブル部をいじりまくってるので、最終的にどうなったのかを貼っつけて終わりにします。

language = 'ja'

latex_elements = {
    'papersize': 'a4paper',
    'fontpkg': '',
    'fncychap': '',
    'preamble': '''
\\renewcommand{\\baselinestretch}{0.8}
\\pagestyle{plain}
\\thispagestyle{plain}
\\setcounter{secnumdepth}{3}

\\makeatletter
\\renewcommand{\maketitle}{
  \\ifsphinxpdfoutput
    \\begingroup
      \\def\\\\{, }
      \\def\\and{and }
      \\pdfinfo{
        /Author (\\@author)
        /Title (\\@title)
      }
    \\endgroup
  \\fi
  \\begin{center}
    \\sphinxlogo%
    {\\Large \\@title} \\par
  \\end{center}
  \\begin{flushright}
    \\@date \\hspace{3zw} \\@author \\par
    \\py@authoraddress \\par
  \\end{flushright}
  \\@thanks
  \\setcounter{footnote}{0}
  \\let\\thanks\\relax\\let\\maketitle\\relax
}
\\makeatother

\\let\\pyOldTableofcontents=\\tableofcontents
\\renewcommand{\\tableofcontents}{
  \\begingroup
  \\parskip = 0mm
  \\pyOldTableofcontents
  \\endgroup
  \\vspace{12pt}
}
''',
}

latex_docclass = {
    'howto': 'jsarticle',
    'manual': 'jsbook',
}

latex_documents = [
  ('index', 'test.tex', u'test Documentation',
   u'test', 'howto'),
]

勉強になりました。