From 0caa2ba3f28d8627124de45ea397a5c6163952a9 Mon Sep 17 00:00:00 2001 From: Mikael Capelle Date: Wed, 9 May 2018 11:05:01 +0200 Subject: [PATCH] Fix issues. --- pyltk/__init__.py | 3 ++- pyltk/documentclass.py | 11 ++++++++--- pyltk/element.py | 33 ++++++++++++++++++++++++++------- pyltk/includegraphics.py | 3 ++- pyltk/pgfplots/axis.py | 2 +- pyltk/pgfplots/generic_plot.py | 13 +++++++++++-- pyltk/strelement.py | 2 +- pyltk/tabular.py | 27 ++++++++++++++++++++++----- 8 files changed, 73 insertions(+), 21 deletions(-) diff --git a/pyltk/__init__.py b/pyltk/__init__.py index c413072..3dfb0b3 100644 --- a/pyltk/__init__.py +++ b/pyltk/__init__.py @@ -3,6 +3,7 @@ # flake8: noqa from .documentclass import * +from .element import wrapper_element from .figure import figure from .formatter import formatter from .input_element import input_element @@ -11,5 +12,5 @@ from .makebox import makebox from .resizebox import resizebox from .subfloat import subfloat from .table import table, tabledf -from .tabular import tabular, tabulardf +from .tabular import tabular, tabulardf, multicolumn from .inlines import it, bf, mt diff --git a/pyltk/documentclass.py b/pyltk/documentclass.py index ff12231..e505a35 100644 --- a/pyltk/documentclass.py +++ b/pyltk/documentclass.py @@ -90,7 +90,8 @@ class documentclass(element): 'content': super().content() }) - def compile(self, outfile, infile='auto', outlog=None): + def compile(self, outfile, infile='auto', outlog=None, + compile_twice=False): """ Compile the given document into a PDF file. If infile is not None, and infile already exists, the document @@ -105,7 +106,8 @@ class documentclass(element): 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 + - outlog Output loging stream (default stdout). + - compile_twice Set to true to compile the document twice. """ outdir = os.path.dirname(outfile) @@ -155,7 +157,10 @@ class documentclass(element): call = ['pdflatex', '-halt-on-error', '-output-directory', output_aux_folder, '-jobname', outfile, infile] - if subprocess.call(call, stdout=outlog) == 0: + res = subprocess.call(call, stdout=outlog) + if compile_twice: + res = subprocess.call(call, stdout=outlog) + if res == 0: os.rename( os.path.join( output_aux_folder, outfile + '.pdf'), diff --git a/pyltk/element.py b/pyltk/element.py index 28ef7be..0b61fef 100644 --- a/pyltk/element.py +++ b/pyltk/element.py @@ -49,7 +49,7 @@ class element: self.options = kargs def add(self, childrens): - if not isinstance(childrens, Iterable): + if not isinstance(childrens, Iterable) or isinstance(childrens, str): childrens = [childrens] for child in childrens: if not self.raw: @@ -68,15 +68,31 @@ class element: def fmt(self): return formatter(self.templates) - def format_options(self, options): - if not options: - return '' + def format_options_dict(self, options): opts = [] # Note: Sorted to have a guaranteed output for k in sorted(options): - opts.append('{key} = {{{value}}}'.format(key=k, value=options[k])) + value = options[k] + + if value is True: + opts.append(k) + else: + if isinstance(value, dict): + value = self.format_options_dict(value) + elif isinstance(value, list) or isinstance(value, tuple): + value = ','.join(value) + else: + value = str(value).strip() + if value[0] == '{' and value[1] == '}': + value = value[1:-1] + opts.append('{key}={{{value}}}'.format(key=k, value=value)) + return ', '.join(opts) + + def format_options(self, options): + if not options: + return '' return self.fmt().format('options', { - 'content': ', '.join(opts) + 'content': self.format_options_dict(options) }) def format_label(self, label): @@ -97,11 +113,14 @@ class wrapper_element(element): escape_list = ['_', '#', '%'] - def __init__(self, data, parent): + def __init__(self, data, parent=None, autoescape=True): super().__init__(parent=parent) + self.autoescape = autoescape self.data = data def escape(self, s): + if not self.autoescape: + return s for e in self.escape_list: s = s.replace(e, '\\' + e) return s diff --git a/pyltk/includegraphics.py b/pyltk/includegraphics.py index fc017de..cb18701 100644 --- a/pyltk/includegraphics.py +++ b/pyltk/includegraphics.py @@ -7,7 +7,8 @@ class includegraphics(element): """ Class representing a latex includegrahics. """ templates = { - 'element': '\\includegraphics[{options}]{{{filename}}}' + 'options': '[{content}]', + 'element': '\\includegraphics{options}{{{filename}}}' } autolabel = False diff --git a/pyltk/pgfplots/axis.py b/pyltk/pgfplots/axis.py index 43216c9..a83da0c 100644 --- a/pyltk/pgfplots/axis.py +++ b/pyltk/pgfplots/axis.py @@ -15,7 +15,7 @@ class axis(element): \\end{{axis}}""" } - def __init__(self, *args, parent=None, legend=True, label=None, **kwargs): + def __init__(self, *args, parent=None, legend=None, label=None, **kwargs): super().__init__(parent, label=label) self.options = kwargs self.legend = legend diff --git a/pyltk/pgfplots/generic_plot.py b/pyltk/pgfplots/generic_plot.py index 96112d1..0787158 100644 --- a/pyltk/pgfplots/generic_plot.py +++ b/pyltk/pgfplots/generic_plot.py @@ -8,7 +8,8 @@ class generic_plot(element): templates = { 'options': '+[{content}]', - 'content': """\\addplot{options} {data};""" + 'content': """\\addplot{options} {data};{legend}""", + 'legend': """\\addlegendentry{{{content}}}""" } def __init__(self, legend, data, precision=6, label=None, options=[]): @@ -36,8 +37,16 @@ class generic_plot(element): def format_values(self, values): return [self.format_value(value) for value in values] + def format_legend(self, legend): + if not legend: + return '' + return self.fmt().format('legend', { + 'content': legend + }) + def content(self): return self.fmt().format('content', { 'data': self.format_data(self.data), - 'options': self.format_options(self.options) + 'options': self.format_options(self.options), + 'legend': self.format_legend(self.legend) }) diff --git a/pyltk/strelement.py b/pyltk/strelement.py index 9c6980c..b27db7f 100644 --- a/pyltk/strelement.py +++ b/pyltk/strelement.py @@ -3,7 +3,7 @@ from .element import element -def strelement(element): +class strelement(element): def __init__(self, content, parent=None): self.inner = content diff --git a/pyltk/tabular.py b/pyltk/tabular.py index 59437b7..cad5601 100644 --- a/pyltk/tabular.py +++ b/pyltk/tabular.py @@ -2,7 +2,7 @@ import itertools -from .element import element +from .element import element, wrapper_element try: import pandas as pd @@ -107,10 +107,27 @@ class tabular(element): }) -def multicolumn(n, s=''): - if n == 1: - return s - return '\\multicolumn{' + str(n) + '}{c}{' + s + '}' +class multicolumn(element): + """ Class representing a multicolumn element. """ + + templates = { + 'content': """\\multicolumn{{{ncolumns}}}{{{align}}}{{{content}}}""" + } + + def __init__(self, ncolumns, content='', alignment='c', **kargs): + super().__init__(**kargs) + self.ncolumns = ncolumns + self.inner = content + self.alignment = alignment + + def content(self): + if self.ncolumns == 1: + return self.inner + return self.fmt().format('content', { + 'ncolumns': self.ncolumns, + 'content': self.inner, + 'align': self.alignment + }) class tabulardf(tabular):