# Sage，LaTeXと仲間たち

著者: Rob Beezer (2010-05-23)

SageとTeX派生の組版システムLaTeXは，緊密な相乗的協働関係にある． ここでは，最も基本的なものから始めて，かなり特殊かつ難解なものに至るまでの両者の多様な相互関係を概観する． (このチュートリアルを初めて読む場合は，この節は飛ばしてかまわない)

## 概観

SageはLaTeXを多種多様な形で利用している． 利用のメカニズムを理解する早道は，まず三種類の代表的な利用法のあらましを把握しておくことだろう．

1. Sageでは全オブジェクトに対してLaTeX形式の印字表現が可能になっている． Sageオブジェクト `foo` のLaTeX形式による印字表現を見たければ，SageノートブックまたはSageコマンド入力行で `latex(foo)` と実行する． 出力された文字列をTeXの数式モード( 例えば一対の `$` で囲まれた領域 )内で処理すると十分に使える `foo` の表現が得られるはずだ． これについては以下で実例を見る．

   同じ手順によってSageをLaTeX文書の作成に活用することができる． 目的のオブジェクトをSage上で作成あるいは計算しておいてから，そのオブジェクトを `latex()` 経由で表示した出力をLaTeX文書にカット/ペーストすればよい．

2. ノートブックインターフェイスは，webブラウザ上で数式を明瞭に表示するため MathJax を使用するよう設定されている． MathJaxはJavaScriptで書かれたオープンソースの数式表示エンジンで，現行のブラウザ全てで動作し，TeX形式で表現された数式の全てではないにしても,その大部分を表示することができる． その目的はTeXで表わされた短い数式を正確に表示することであって，複雑な表や文書構造の表現と管理を支援するものではない． ノートブックにおける見たところ自動的な数式のレンダリング表示は，数式オブジェクトの `latex()` 出力をMathJaxが動作可能なHTML形式に変換して得られたものである． MathJaxはそれ自身のスケーラブルフォントを利用しており，方程式などTeX形式で表現されたテキストを静的なインライン画像に変換する方法より優れているといえる．

3. Sageコマンドラインあるいはノートブック上でMathJaxでは処理しきれないほどLaTeXコードが複雑化してしまった場合は，システム上で公開運用されているLaTeXによって処理することもできる． Sageには，Sage自体をビルドして使用するために必要な物ほとんど全てが含まれているが，TeXはその例外となっている． 場合によっては，TeXシステムおよび関連の変換ユーティリティ群を別途インストールしなければ欲しい機能が完全には使えないこともあるかもしれない．

ここで `latex()` 関数の基本的な用法を試してみよう.

    sage: var('z')
    z
    sage: latex(z^12)
    z^{12}
    sage: latex(integrate(z^4, z))
    \frac{1}{5} \, z^{5}
    sage: latex('a string')
    \text{\texttt{a{ }string}}
    sage: latex(QQ)
    \Bold{Q}
    sage: latex(matrix(QQ, 2, 3, [[2,4,6],[-1,-1,-1]]))
    \left(\begin{array}{rrr}
    2 & 4 & 6 \\
    -1 & -1 & -1
    \end{array}\right)

ノートブック上ではMathJaxの基本機能は自動的に動作するが，ここでは `MathJax` クラスを使ってMathJaxの働きを少しばかり観察してみることにしよう． `MathJax` クラスの `eval` 関数はSageオブジェクトをLaTeX形式に変換し，さらにCSSの "math"クラスを呼び出すHTMLにラップしてMathJaxを起動する．

    sage: from sage.misc.latex import MathJax
    sage: mj = MathJax()
    sage: var('z')
    z
    sage: mj(z^12)
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}z^{12}</script></html>
    sage: mj(QQ)
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}</script></html>
    sage: mj(ZZ[x])
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z}[x]</script></html>
    sage: mj(integrate(z^4, z))
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\frac{1}{5} \, z^{5}</script></html>

## 基本的な使い方

上で概観したように，SageのLaTeX支援機能を利用する最も基本的な方法は `latex()` 関数を使って数学オブジェクトのLaTeX形式による印字表現を生成することである． 生成されたLaTeX表現は別仕立てのLaTeX文書に貼り付けて利用すればよい． この方法はノートブックでもSageコマンドラインでも同じように通用する．

もう一つの手軽な方法に `view()` コマンドの使用がある． Sageコマンドラインで `view(foo)` を実行すると `foo` のLaTeX表現が得られるから，これをLaTeX文書に取り込んで使っているシステムにインストールされたTeXで処理する． TeXの出力を適切なビューワーで表示して出来上がりである． 使用するTeXのバージョンや，それに応じた出力とビューワーは選択することができる( LaTeX処理のカスタマイズ 節を参照)．

ノートブック上では, `view(foo)` コマンドはMathJaxがワークシート上でLaTeX表現を正しくレンダリングできるよう適切なHTMLとCSSの組を生成する． ユーザーの目に映るのはSageデフォルトのASCII文字出力ではなく，きれいにフォーマットされた数式出力ということになる． ただしSageの数学オブジェクト全てがMathJaxで表示可能なLaTeX表現をもつとは限らない． 表示できない場合にはMathJaxではなくシステム上のTeXを使って処理し，出力をワークシートに表示可能な画像へ変換することができる． これに必要な一連の処理をどうやってコントロールするかについては LaTeXコード生成のカスタマイズ 節で解説する．

ノートブックにはTeXを利用するための機能があと二つある． 一つはワークシートの最初のセルのすぐ上に並ぶ四つのドロップダウンボックスの右にある "Typeset"ボタンである． これをチェックしておくと，以降はセルの評価結果はMathJaxで処理されて印刷品質で表示される． ただし，この機能は遡及的に作用するわけではなく，事前に評価済みのセルについては評価し直してやる必要がある． つまるところ "Typeset"ボタンにチェックを入れるのは，以降のセル評価出力を `view()` コマンドでラップして表示することを意味することになる．

ノートブックのTeX支援機能の二つ目は，ワークシートの注釈にTeX形式が利用可能な点である． ワークシート上でセルの間にカーソルが移動すると青色のバーが現れるから，そこで `<shift-click>` するとTinyMCEというちょっとしたワードプロセッサが起動する． これを使えばテキスト入力を行ない，かつWSIWYGエディタ経由でHTMLとCSSを作成して書式付けすることができる． つまりワークシート内で書式付きテキストを作成し注釈として付加することが可能なわけだ． 一方，ダラー記号(`$`)あるいはダラー記号2つ(`$$`)の間に挟まれた文字列はMathJaxによってインラインあるいはディスプレイ数式として解釈される．

## LaTeXコード生成のカスタマイズ

`latex()` コマンドによるLaTeXコードの生成をカスタマイズする方法は何通りも用意されている． ノートブックでもSageコマンドラインでも，すでに `latex` という名前のオブジェクトが定義済みで， `latex.` (ピリオド `.` に 注意)と入力して `[Tab]` キーを押せばメソッドの一覧を表示することができる．

ここでは `latex.matrix_delimiters` メソッドに注目してみよう． このメソッドを使えば，行列を囲む記号を大丸かっこ，角かっこ，中かっこ，縦棒などに変更することができる． 何か形式上の制限があるわけではないから，好きなように組み合わせてかまわない． LaTeXで使われるバックスラッシュには，Pythonの文字列内でエスケープするためもう1個のバックスラッシュを付ける必要があることに注意．

    sage: A = matrix(ZZ, 2, 2, range(4))
    sage: latex(A)
    \left(\begin{array}{rr}
    0 & 1 \\
    2 & 3
    \end{array}\right)
    sage: latex.matrix_delimiters(left='[', right=']')
    sage: latex(A)
    \left[\begin{array}{rr}
    0 & 1 \\
    2 & 3
    \end{array}\right]
    sage: latex.matrix_delimiters(left='\\{', right='\\}')
    sage: latex(A)
    \left\{\begin{array}{rr}
    0 & 1 \\
    2 & 3
    \end{array}\right\}

`latex.vector_delimiters` メソッドも同様の機能をもつ．

(整数，有理数，実数など)標準的な環や体をどんな書体で表示するかは `latex.blackboard_bold` メソッドによって制御することができる． デフォルトではボールド体で表示されるが，手書きの場合にやるように黒板ボールド体(重ね打ち体)を使うこともできる． それにはSageのビルトインマクロ `\Bold{}` を再定義してやればよい．

    sage: latex(QQ)
    \Bold{Q}
    sage: from sage.misc.latex import MathJax
    sage: mj=MathJax()
    sage: mj(QQ)
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Q}</script></html>
    sage: latex.blackboard_bold(True)
    sage: mj(QQ)
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbb{#1}}\Bold{Q}</script></html>
    sage: latex.blackboard_bold(False)

新しいマクロやパッケージなどを追加して，TeXの高い拡張性を利用することができる． まず，ノートブックでMathJaxが短いTeXコードを解釈する際に使われる，自分用のマクロを追加してみよう．

    sage: latex.extra_macros()
    ''
    sage: latex.add_macro("\\newcommand{\\foo}{bar}")
    sage: latex.extra_macros()
    '\\newcommand{\\foo}{bar}'
    sage: var('x y')
    (x, y)
    sage: latex(x+y)
    x + y
    sage: from sage.misc.latex import MathJax
    sage: mj=MathJax()
    sage: mj(x+y)
    <html><script type="math/tex; mode=display">\newcommand{\Bold}[1]{\mathbf{#1}}\newcommand{\foo}{bar}x + y</script></html>

以上のようなやり方で追加したマクロは，MathJaxでは対応しきれない大規模な処理が発生してシステム上のTeXが呼ばれるような場合にも使われる． 自立したLaTeX文書のプリアンブルを定義する `latex_extra_preamble` コマンドの使い方は以下で具体例を示す． これまで通りPython文字列中ではバックスラッシュが二重になっていることに注意．

    sage: latex.extra_macros('')
    sage: latex.extra_preamble('')
    sage: from sage.misc.latex import latex_extra_preamble
    sage: print(latex_extra_preamble())
    \newcommand{\ZZ}{\Bold{Z}}
    ...
    \newcommand{\Bold}[1]{\mathbf{#1}}
    sage: latex.add_macro("\\newcommand{\\foo}{bar}")
    sage: print(latex_extra_preamble())
    \newcommand{\ZZ}{\Bold{Z}}
    ...
    \newcommand{\Bold}[1]{\mathbf{#1}}
    \newcommand{\foo}{bar}

長く複雑なLaTeX表現を処理するために，LaTeXファイルのプリアンブルでパッケージ類を付加してやることができる． `latex.add_to_preamble` コマンドを使えば好きなものをプリアンブルに取り込めるし， `latex.add_package_to_preamble_if_available` コマンドはプリアンブルへの取り込みを実行する前に，指定したパッケージが利用可能かどうかをチェックしてくれる．

以下の例ではプリアンブルでgeometryパッケージを取り込み，ページ上でTeXに割り当てる領域(実質的にはマージン)サイズを指定している． 例によってPython文字列のバックスラッシュは二重になっていることに注意．

    sage: from sage.misc.latex import latex_extra_preamble
    sage: latex.extra_macros('')
    sage: latex.extra_preamble('')
    sage: latex.add_to_preamble('\\usepackage{geometry}')
    sage: latex.add_to_preamble('\\geometry{letterpaper,total={8in,10in}}')
    sage: latex.extra_preamble()
    '\\usepackage{geometry}\\geometry{letterpaper,total={8in,10in}}'
    sage: print(latex_extra_preamble())
    \usepackage{geometry}\geometry{letterpaper,total={8in,10in}}
    \newcommand{\ZZ}{\Bold{Z}}
    ...
    \newcommand{\Bold}[1]{\mathbf{#1}}

あるパッケージの存在確認をした上で取り込みを実行することもできる． 例として，ここでは存在しないはずのパッケージのプリアンブルへの取り込みを試みてみよう．

    sage: latex.extra_preamble('')
    sage: latex.extra_preamble()
    ''
    sage: latex.add_to_preamble('\\usepackage{foo-bar-unchecked}')
    sage: latex.extra_preamble()
    '\\usepackage{foo-bar-unchecked}'
    sage: latex.add_package_to_preamble_if_available('foo-bar-checked')
    sage: latex.extra_preamble()
    '\\usepackage{foo-bar-unchecked}'

## LaTeX処理のカスタマイズ

システムで公開運用されているTeXシステムから好みの種類を指定して，出力形式を変更することも可能だ． さらに，ノートブックがMathJax(簡易TeX表現用)とTeXシステム(複雑なLaTeX表現用)を使い分ける仕方を制御することができる．

`latex.engine()` コマンドを使えば，複雑なLaTeX表現に遭遇した場合，システム上で運用されているTeXの実行形式 `latex`, `pdflatex` または `xelatex` の内どれを使って処理するかを指定することができる． `view()` がsageコマンドラインから発行されると，実行形式 `latex` が選択されるから，出力はdviファイルとなりsageにおける表示にも(xdviのような)dviビューワーが使われる． これに対し，TeX実行形式として `pdflatex` が設定された状態でsageコマンドラインから `view()` を呼ぶと，出力はPDFファイルとなってSageが表示に使用するのはシステム上のPDF表示ユーティリティ(acrobat，okular, evinceなど)となる．

ノートブックでは，簡単なTeX表現だからMathJaxで処理できるのか，あるいは複雑なLaTeX表現のためシステム上のTeXを援用すべきなのか，判断の手掛りを与えてやる必要がある． 手掛りとするのは文字列リストで，リストに含まれる文字列が処理対象のLaTeX表現に含まれていたらノートブックはMathJaxを飛ばしてlatex(もしくは `latex.engine()` コマンドで指定された実行形式)による処理を開始する． このリストは `latex.add_to_mathjax_avoid_list` および `latex.mathjax_avoid_list` コマンドによって指定される．

    sage: latex.mathjax_avoid_list([])
    sage: latex.mathjax_avoid_list()
    []
    sage: latex.mathjax_avoid_list(['foo', 'bar'])
    sage: latex.mathjax_avoid_list()
    ['foo', 'bar']
    sage: latex.add_to_mathjax_avoid_list('tikzpicture')
    sage: latex.mathjax_avoid_list()
    ['foo', 'bar', 'tikzpicture']
    sage: latex.mathjax_avoid_list([])
    sage: latex.mathjax_avoid_list()
    []

ノートブック上で `view()` コマンド，あるいは "Typeset"ボタンがチェックされた状態でLaTeX表式が生成されたが， `latex.mathjax_avoid_list` によってシステム上のLaTeXが別途必要とされたとしよう． すると，そのLaTeX表式は(`latex.engine()` で設定した)指定のTeX実行形式によって処理される． しかし，Sageは(コマンドライン上のように)外部ビューワーを起動して表示する代わりに，結果をセル出力としてきっちりトリミングした1個の画像に変換してからワークシートに挿入する．

変換が実際にどう実行されるかについては，いくつもの要因が影響している． しかし大勢は，TeX実行形式として何が指定されているか，そして利用可能な変換ユーティリティは何かによって決まるようだ． `dvips`, `ps2pdf`, `dvipng` そして `ImageMagick` に含まれる `convert` の四種の優秀な変換ユーティリティがあれば，あらゆる状況に対処できるだろう． 目標はワークシートに挿入して表示可能なPNGファイルを生成することで，LaTeX表式からdvi形式へのLaTeXエンジンによる変換が成功していれば，dvipngが変換を仕上げてくれる． LaTeX表式とLaTeXエンジンの生成するdvi形式にdvipngが扱えないspecial命令が入っている場合には，dvipsでポストスクリプトファイルへ変換する． ポストスクリプトあるいは `pdflatex` エンジンによって出力されたPDFファイルは `convert` ユーティリティによってPNG形式へ変換される． ここで紹介した二つの変換ユーティリティは `have_dvipng()` と `have_convert()` ルーチンを使って存在を確認することができる．

必要な変換プログラムがインストールされていれば変換は自動的に行われる． ない場合は，何が不足していて，どこからダウンロードすればよいかを告げるエラーメッセージが表示される．

どうすれば複雑なLaTeX表式を処理できるのか，その具体例として次節(具体例： tkz-graphによる連結グラフの作成)ではLaTeXの `tkz-graph` パッケージを使って高品位の連結グラフを作成する方法を解説する． 他にも例が見たければ，パッケージ化済みのテストケースが用意されている． 利用するには， 以下で見るように `sage.misc.latex.LatexExamples` クラスのインスタンスである `sage.misc.latex.latex_examples` オブジェクトをインポートしなければならない． 現在，このクラスには可換図，組合せ論グラフと結び目理論，およびpstricks関連の例題が含まれており，各々がxy, tkz-graph, xypic, pstricksパッケージの使用例になっている． インポートを終えたら， `latex_examples` をタブ補完してパッケージに含まれる実例を表示してみよう． 例題各々で適正な表示に必要なパッケージや手続きが解説されている． (プリアンブルやlatexエンジン類が全て上手く設定されていても)実際に例題を表示するには `view()` を使わなくてはならない．

    sage: from sage.misc.latex import latex_examples
    sage: latex_examples.diagram()
    LaTeX example for testing display of a commutative diagram produced
    by xypic.
    <BLANKLINE>
    To use, try to view this object -- it won't work.  Now try
    'latex.add_to_preamble("\\usepackage[matrix,arrow,curve,cmtip]{xy}")',
    and try viewing again -- it should work in the command line but not
    from the notebook.  In the notebook, run
    'latex.add_to_mathjax_avoid_list("xymatrix")' and try again -- you
    should get a picture (a part of the diagram arising from a filtered
    chain complex).

## 具体例： tkz-graphによる連結グラフの作成

`tkz-graph` パッケージを使って高品位の連結グラフ(以降はたんに「グラフ」と呼ぶ)を作成することができる． このパッケージは `pgf` ライブラリの `tikz` フロントエンド上に構築されている． したがってその全構成要素がシステム運用中のTeXで利用可能でなければならないが，TeXシステムによっては必要なパッケージが全て最新になっているとは限らない． 満足すべき結果を得るには，必要なパッケージの最新版をユーザのtexmf配下にインストールする必要が生ずるかもしれない． 個人または公開利用のためのTeXのインストールや管理運用についてはこのチュートリアルの範囲を越えるが，必要な情報は簡単に見つかるはずだ． 必要なファイル類は TeXシステムの完全な運用 節に挙げられている．

まずは土台とするLaTeX文書のプリアンブルで必要なパッケージが付加されることを確認しておこう． グラフ画像はdviファイルを経由すると正しく生成されないので，latexエンジンとしては `pdflatex` プログラムを指定するのが一番だ． すると，Sageコマンドライン上で `view(graphs.CompleteGraph(4))` の実行が可能になり，完結したグラフ \(K_4\) の適切なPDF画像が生成されるはずだ．

ノートブックでも同様の動作を再現するには，グラフを表わすLaTeXコードのMathJaxによる処理を `mathjax avoid list` を使って抑止する必要がある． グラフは `tikzpicture` 環境で取り込まれるから，文字列 `tikzpicture` を `mathjax avoid list` に入れておくとよい． そうしてからワークシートで `view(graphs.CompleteGraph(4))` を実行するとpdflatexがPDFファイルを生成し，ついで `convert` ユーティリティが抽出したPNG画像がワークシートの出力セルに挿入されることになる． ノートブック上でグラフをLaTeXにグラフを処理させるために必要なコマンド操作を以下に示す．

    sage: from sage.graphs.graph_latex import setup_latex_preamble
    sage: setup_latex_preamble()
    sage: latex.extra_preamble() # random - システムで運用されているTeXに依存
    '\\usepackage{tikz}\n\\usepackage{tkz-graph}\n\\usepackage{tkz-berge}\n'
    sage: latex.engine('pdflatex')
    sage: latex.add_to_mathjax_avoid_list('tikzpicture')
    sage: latex.mathjax_avoid_list()
    ['tikz', 'tikzpicture']

ここまで設定してから `view(graphs.CompleteGraph(4))` のようなコマンドを実行すると， `tkz-graph` で表現されたグラフが `pdflatex` で処理されてノートブックに挿入される． LaTeXに `tkz-graph` 経由でグラフを描画させる際には多くのオプションが影響するが，詳細はこの節の範囲を越えている． 興味があればレファレンスマニュアル "LaTeX Options for Graphs"の解説を見てほしい．

## TeXシステムの完全な運用

TeXをSageに統合して運用する際，高度な機能の多くはシステムに独立してインストールされたTeXがないと利用できない． Linux系システムではTeXliveを基にした基本TeXパッケージを採用しているディストリビューションが多く，OSXではTeXshop，WindowsではMikTeXなどが使われている． `convert` ユーティリティは ImageMagick パッケージ(簡単にダウンロード可能)に含まれているし， `dvipng`, `ps2pdf` と `dvips` の三つのプログラムはTeXパッケージに同梱されているはずだ． また `dvipng` は http://sourceforge.net/projects/dvipng/ から， `ps2pdf` は Ghostscript の一部として入手することもできる．

連結グラフの作画には，PGFライブラリの新しいバージョンに加えて `tkz-graph.sty` と `tkz-arith.sty` が必要で，さらに `tkz-berge.sty` も必要になるかもしれない． tkz関係のファイルは全て Altermundus site から入手することができる．

## 外部プログラム

TeXとSageのさらなる統合運用に役立つプログラムが三つある． その一番目がsagetexで，このTeXマクロ集を使えばLaTeX文書からSage上の多様なオブジェクトに対する演算や組み込みコマンド `latex()` によるフォーマットなどを実行することができる． LaTeX文書のコンパイル処理過程で，Sageの演算やLaTeXによるフォーマット支援などの全ての機能も自動的に実行されるのである． sagetexを使えば，例えば数学試験作成において，問題の計算そのものをSageに実行させて対応する解答を正確に維持管理することなどが可能になる． 詳細は SageTeXを使う 節を参照してほしい．

tex2swsはLaTeX文書にSageコードを組込むための環境を定義している． これをしかるべきツールで処理すると，MathJaxで適切に表示される本文と入力セル経由で動作するSageコードが組込まれたSageワークシートが出来上がる． tex2sws環境を使えばLaTeXで教科書や記事をSageコードのブロックを含んだ形で執筆することができるが，これを変換すると数式混じりの本文は美しく整形され，かつSageコード部分が機能するSageワークシートになるわけである． 現在も開発進行中で，詳細は tex2sws @ BitBucket を見てほしい．

これとは逆に，sws2texはSageワークシートをLaTeX形式に変換してLaTeX関連ツールによる処理を可能にする． 現在も開発中で，詳細は sws2tex @ BitBucket を見てほしい．