[Python][LaTeX] Sympyの計算結果をLaTeXで出力する

はじめに

Sympyで記号計算した結果をTeXで出力したいと思い、モジュールを書いた。Sympyには記号計算結果をTeX形式に直してくれる機能があるので、それを利用し、Python

数値計算TeXコード生成 → コンパイルplatex+dvipdfmx)

の三つを順に行う。

モジュールのソースコード

以下にlatexfile.pyモジュールの中身を示す。

"""
    latexfile.py
"""
import os
import subprocess
import textwrap


class LatexFile:
    PROLOGUE = textwrap.dedent('''\
        \\documentclass[{}pt,dvipdfmx,a4paper]{{jsarticle}}
        \\usepackage{{amsmath}}
        \\usepackage{{tgpagella, euler}}
        \\begin{{document}}\
    ''')

    def __init__(self, fname, title=None, point=10):
        self.title = title
        self.text = []
        self.fname = fname
        self.point = point
        if title is None:
            self.title = ''
        else:
            self.title = '\\title{{{}}} \n\\date{{}} \n\\maketitle'.format(title)
    
    def add_text(self, text):
        self.text.append(text)

    def add_eq(self, equation):
        self.text.append('\\begin{align*}\n' + equation + '\n\\end{align*}')
    
    def add_eqs(self, eqs, leftalign=True):
        if leftalign is True:
            self.text.append('\\begin{align*}\n' + '& ' + '\\\\ \n& '.join(eqs) + '\n\\end{align*}')
        else:
            self.text.append('\\begin{align*}\n' + '\\\\ \n'.join(eqs) + '\n\\end{align*}')

    def output(self):
        res = '\n'.join([
            self.PROLOGUE.format(self.point),
            self.title,
            '\n'.join(self.text),
            '\\end{document}'
        ])
        return res

    def compile(self, remove=True):
        with open(self.fname + '.tex', mode='wt') as fout:
            fout.write(self.output())
        command1 = 'platex {}.tex'.format(self.fname)
        print(command1.split(' '))
        subprocess.run(command1.split(' '))
        command2 = "dvipdfmx {}".format(self.fname)
        subprocess.run(command2.split(' '))
        if remove is True:
            rmv_list = [self.fname + x for x in ('.aux', '.log', '.dvi')]
            for rmv_fname in rmv_list:
                os.remove(rmv_fname)

使い方

使い方はこんな感じ。

"""
    test.py
"""
import sympy as sym

from latexfile import LatexFile


def main():
    tex = LatexFile('calc_result', title='Calculation result', point=9)
    tex.add_eq('1 + 1 = ' + sym.latex(1 + 1))
    tex.add_eqs([
        '1 + 2 = ' + sym.latex(1 + 2),
        '1 + 3 = ' + sym.latex(1 + 3)
    ])
    tex.compile()


if __name__ == '__main__':
    main()

1. オブジェクトの作成

はじめにLatexFileコンストラクタでオブジェクトを作る。

LatexFile(filename, title=None, point=10)

コンストラクタにはファイル名を指定する必要がある。オプションとして文書のタイトルや文字のポイント数を指定できる。

2. 数式の追加

作成したLatexFileオブジェクトに、式やテキストを追加していく。次の三つのメソッドが利用可能。

add_eq(str)

式を一つ追加する。

add_eqs([str, str, ...], leftalign=False)

式を複数本まとめて追加する。デフォルトでは式は中央揃えだが、leftalignオプションをTrueに指定すれば左寄せにできる。

add_text(str)

テキストを追加する。

3. コンパイル

最後にコンパイルすれば完了。

compile(remove=True)

コンパイルしてPDFを出力する。デフォルトではremoveオプションがTrueになっていて、コンパイル後にaux, log, dviファイルを削除する設定になっている。