Update documentclass.
This commit is contained in:
@@ -3,20 +3,41 @@
|
||||
from collections import Iterable
|
||||
from .element import element
|
||||
|
||||
import enum
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
class change_directory:
|
||||
|
||||
"""Context manager for changing the current working directory"""
|
||||
|
||||
def __init__(self, newPath):
|
||||
self.newPath = os.path.expanduser(newPath)
|
||||
|
||||
def __enter__(self):
|
||||
self.savedPath = os.getcwd()
|
||||
os.chdir(self.newPath)
|
||||
|
||||
def __exit__(self, etype, value, traceback):
|
||||
os.chdir(self.savedPath)
|
||||
|
||||
|
||||
class CompileResult(enum.Enum):
|
||||
|
||||
ALREADY_EXISTS = 1
|
||||
SUCCESS = 2
|
||||
ERROR = 3
|
||||
|
||||
|
||||
class documentclass(element):
|
||||
|
||||
packages = {}
|
||||
preamble = []
|
||||
options = []
|
||||
classname = 'standalone'
|
||||
|
||||
templates = {
|
||||
'package': '\\usepackage{pkgoptions}{{{pkgname}}}',
|
||||
'options': '[{content}]',
|
||||
'def': '\\def\\{name}#{nargs}{{{value}}}',
|
||||
'def': '\\def\\{name}{nargs}{{{value}}}',
|
||||
'content': """\\documentclass{options}{{{classname}}}
|
||||
{packages}
|
||||
{preamble}
|
||||
@@ -26,11 +47,18 @@ class documentclass(element):
|
||||
"""
|
||||
}
|
||||
|
||||
def __init__(self, classname, childrens=[], options=[], packages=[]):
|
||||
output_aux_folder = '.pyltk'
|
||||
auto_tex_folder = '{}/tex2pdf'.format(output_aux_folder)
|
||||
|
||||
def __init__(self, classname, childrens=[], options=[],
|
||||
packages=[], preamble=[]):
|
||||
super().__init__(parent=None, childrens=childrens)
|
||||
self.options = options
|
||||
self.classname = classname
|
||||
self.packages = {}
|
||||
self.add_packages(packages)
|
||||
self.preamble = []
|
||||
self.add2preamble(preamble)
|
||||
|
||||
def add_packages(self, packages):
|
||||
if type(packages) is str:
|
||||
@@ -49,19 +77,19 @@ class documentclass(element):
|
||||
def add_def(self, name, nargs, value):
|
||||
self.preamble.append(self.fmt().format('def', {
|
||||
'name': name,
|
||||
'nargs': nargs,
|
||||
'nargs': '#{}'.format(nargs) if nargs > 0 else '',
|
||||
'value': value
|
||||
}))
|
||||
|
||||
def format_preamble(self, defs):
|
||||
return '\n'.join(self.preamble)
|
||||
return '\n'.join(str(p) for p in self.preamble)
|
||||
|
||||
def format_packages(self, pkgs):
|
||||
out = []
|
||||
for pkg, opts in self.packages.items():
|
||||
for pkg in sorted(pkgs):
|
||||
options = ''
|
||||
if opts is not True:
|
||||
options = self.format_options(opts)
|
||||
if pkgs[pkg] is not True:
|
||||
options = self.format_options(pkgs[pkg])
|
||||
out.append(self.fmt().format('package', {
|
||||
'pkgname': pkg,
|
||||
'pkgoptions': options
|
||||
@@ -77,12 +105,78 @@ class documentclass(element):
|
||||
'content': super().content()
|
||||
})
|
||||
|
||||
def compile(self, outfile, infile=None, outlog=None):
|
||||
if infile is None:
|
||||
infile = '/tmp/pyltk-{}.tex'.format(id(self))
|
||||
def compile(self, outfile, infile='auto', outlog=None):
|
||||
""" Compile the given document into a PDF file.
|
||||
|
||||
with open(infile, 'w') as infd:
|
||||
infd.write(self.content())
|
||||
If infile is not None, and infile already exists, the document
|
||||
will only be compiled if the content of infile is different
|
||||
from this document or if infile is newer than the output
|
||||
document.
|
||||
|
||||
call = ['pdflatex', '-halt-on-error', '-jobname', outfile, infile]
|
||||
subprocess.call(call, stdout=outlog)
|
||||
Parameters:
|
||||
- outfile Name of the output file (pdf extension may
|
||||
be omitted).
|
||||
- infile Name of the file to which latex code must be
|
||||
written. If None, a temporary file will be created
|
||||
and then erased. If 'auto', file will be saved in
|
||||
an automatic folder for future use.
|
||||
- outlog
|
||||
"""
|
||||
|
||||
outdir = os.path.dirname(outfile)
|
||||
outfile = os.path.basename(outfile)
|
||||
|
||||
res = CompileResult.ERROR
|
||||
|
||||
with change_directory(outdir):
|
||||
|
||||
os.makedirs(self.output_aux_folder, exist_ok=True)
|
||||
|
||||
if outfile.endswith('.pdf'):
|
||||
outfile = outfile[:-4]
|
||||
|
||||
to_delete = False
|
||||
|
||||
if infile == 'auto':
|
||||
os.makedirs(self.auto_tex_folder, exist_ok=True)
|
||||
infile = '{}/{}.tex'.format(self.auto_tex_folder, outfile)
|
||||
|
||||
if infile is None:
|
||||
to_delete = True
|
||||
infile = '.pyltk-{}.tex'.format(outfile)
|
||||
|
||||
to_create = True
|
||||
new_content = self.content()
|
||||
|
||||
# If the input file already exists...
|
||||
if os.path.exists(infile):
|
||||
with open(infile, 'r') as infd:
|
||||
old_content = infd.read()
|
||||
|
||||
# Content has not changed
|
||||
if old_content == new_content \
|
||||
and os.path.exists('{}.pdf'.format(outfile)) \
|
||||
and os.path.getctime(infile) <= \
|
||||
os.path.getctime('{}.pdf'.format(outfile)):
|
||||
to_create = False
|
||||
|
||||
if to_create:
|
||||
with open(infile, 'w') as infd:
|
||||
infd.write(self.content())
|
||||
call = ['pdflatex', '-halt-on-error',
|
||||
'-output-directory', self.output_aux_folder,
|
||||
'-jobname', outfile, infile]
|
||||
if subprocess.call(call, stdout=outlog) == 0:
|
||||
os.rename('{}/{}.pdf'.format(
|
||||
self.output_aux_folder, outfile),
|
||||
'{}.pdf'.format(outfile))
|
||||
res = CompileResult.SUCCESS
|
||||
else:
|
||||
res = CompileResult.ERROR
|
||||
else:
|
||||
res = CompileResult.ALREADY_EXISTS
|
||||
|
||||
if to_delete:
|
||||
os.remove(infile)
|
||||
|
||||
return res
|
||||
|
||||
Reference in New Issue
Block a user