diff --git a/pyltk/__init__.py b/pyltk/__init__.py index 3a0772e..a9ec609 100644 --- a/pyltk/__init__.py +++ b/pyltk/__init__.py @@ -2,9 +2,13 @@ # flake8: noqa +from .documentclass import * from .figure import figure from .formatter import formatter +from .input_element import input_element from .makebox import makebox from .resizebox import resizebox from .subfloat import subfloat +from .table import table, tabledf from .tabular import tabular +from .inlines import it, bf, mt diff --git a/pyltk/documentclass.py b/pyltk/documentclass.py new file mode 100644 index 0000000..bc45900 --- /dev/null +++ b/pyltk/documentclass.py @@ -0,0 +1,88 @@ +# -*- encoding: utf-8 -*- + +from collections import Iterable +from .element import element + +import subprocess + + +class documentclass(element): + + packages = {} + preamble = [] + options = [] + classname = 'standalone' + + templates = { + 'package': '\\usepackage{pkgoptions}{{{pkgname}}}', + 'options': '[{content}]', + 'def': '\\def\\{name}#{nargs}{{{value}}}', + 'content': """\\documentclass{options}{{{classname}}} +{packages} +{preamble} +\\begin{{document}} +{content} +\\end{{document}} +""" + } + + def __init__(self, classname, childrens=[], options=[], packages=[]): + super().__init__(parent=None, childrens=childrens) + self.options = options + self.classname = classname + self.add_packages(packages) + + def add_packages(self, packages): + if type(packages) is str: + self.packages[packages] = True + elif type(packages) is dict: + self.packages.update(packages) + else: + self.packages.update({p: True for p in packages}) + + def add2preamble(self, value): + if isinstance(value, Iterable): + self.preamble.extend(value) + else: + self.preamble.append(value) + + def add_def(self, name, nargs, value): + self.preamble.append(self.fmt().format('def', { + 'name': name, + 'nargs': nargs, + 'value': value + })) + + def format_preamble(self, defs): + return '\n'.join(self.preamble) + + def format_packages(self, pkgs): + out = [] + for pkg, opts in self.packages.items(): + options = '' + if opts is not True: + options = self.format_options(opts) + out.append(self.fmt().format('package', { + 'pkgname': pkg, + 'pkgoptions': options + })) + return '\n'.join(out) + + def content(self): + return self.fmt().format('content', { + 'options': self.format_options(self.options), + 'packages': self.format_packages(self.packages), + 'preamble': self.format_preamble(self.preamble), + 'classname': self.classname, + 'content': super().content() + }) + + def compile(self, outfile, infile=None, outlog=None): + if infile is None: + infile = '/tmp/pyltk-{}.tex'.format(id(self)) + + with open(infile, 'w') as infd: + infd.write(self.content()) + + call = ['pdflatex', '-halt-on-error', '-jobname', outfile, infile] + subprocess.call(call, stdout=outlog) diff --git a/pyltk/element.py b/pyltk/element.py new file mode 100644 index 0000000..053080d --- /dev/null +++ b/pyltk/element.py @@ -0,0 +1,85 @@ +# -*- encoding: utf-8 -*- + +from .formatter import formatter + +from collections import Iterable + + +class element: + + """ Class representing a latex element. """ + + # Joiner for childrens + sep = '\n' + + # Automatically add label after element if present + autolabel = True + + def __init__(self, parent=None, childrens=[], label=None): + self.parent = parent + if childrens is None: + childrens = [] + if not isinstance(childrens, Iterable): + childrens = [childrens] + self.childrens = [] + self.add(childrens) + self.label = label + + def add(self, childrens): + if not isinstance(childrens, Iterable): + childrens = [childrens] + for child in childrens: + if not isinstance(child, element): + child = wrapper_element(child, self) + try: + child.parent.remove(child) + except: + pass + child.parent = self + self.childrens.append(child) + + def content(self): + return self.sep.join(map(str, self.childrens)) + + def fmt(self): + return formatter(self.templates) + + def format_options(self, options): + if not options: + return '' + opts = [] + for k, v in options.items(): + opts.append('{key} = {{{value}}}'.format(key=k, value=v)) + return self.fmt().format('options', { + 'content': ', '.join(opts) + }) + + def format_label(self, label): + if not label: + return '' + return '\\label{{{}}}'.format(label) + + def __str__(self): + out = self.content().strip() + if self.autolabel: + out += self.format_label(self.label) + return out + + +class wrapper_element(element): + + """ Wrapper for standard python types working as latex elements. """ + + escape_list = ['_', '#', '%'] + + def __init__(self, data, parent): + super().__init__(parent=parent) + self.data = data + + def escape(self, s): + for e in self.escape_list: + s = s.replace(e, '\\' + e) + return s + + def content(self): + return self.escape(str(self.data)) diff --git a/pyltk/figure.py b/pyltk/figure.py index 1bc3761..809f1ff 100644 --- a/pyltk/figure.py +++ b/pyltk/figure.py @@ -1,34 +1,46 @@ # -*- encoding: utf-8 -*- -from .formatter import formatter +from .element import element -class figure: +class figure(element): """ Class representing a latex figure. """ - fmt = formatter({ + templates = { + 'caption': '\\caption{{{content}}}', 'content': """\\begin{{figure}}[{options}] {centered} {inner} +{caption}{label} \\end{{figure}}""" - }) + } - def __init__(self, inner, options='!h', centered=True): + autolabel = False + + def __init__(self, childrens=None, parent=None, + caption=None, options='!h', + centered=True, label=None): """ Create a figure with given options. Parameters: - options Options for the figure. - centered Set to true to add a centering command. """ - self.inner = inner + super().__init__(parent, childrens, label=label) self.options = options + self.caption = caption self.centered = '' if centered: self.centered = '\\centering' - def __str__(self): - return self.fmt.format('content', { + def content(self): + caption = '' + if self.caption: + caption = self.fmt().format('caption', {'content': self.caption}) + return self.fmt().format('content', { 'options': self.options, 'centered': self.centered, - 'inner': self.inner + 'caption': caption, + 'label': self.format_label(self.label), + 'inner': super().content() }) diff --git a/pyltk/inlines.py b/pyltk/inlines.py new file mode 100644 index 0000000..e825c27 --- /dev/null +++ b/pyltk/inlines.py @@ -0,0 +1,33 @@ +# -*- encoding: utf-8 -*- + +from .element import element + + +class inline_element(element): + + """ Class representing simple latex inline elements such as bf, + it, math. """ + + def __init__(self, content, parent=None): + super().__init__(parent=parent) + self.value = content + self.templates = { + 'wrapper': self.wrapper + } + + def content(self): + return self.fmt().format('wrapper', { + 'value': self.value + }) + + +class it(inline_element): + wrapper = '\\textit{{{value}}}' + + +class bf(inline_element): + wrapper = '\\textbf{{{value}}}' + + +class mt(inline_element): + wrapper = '${value}$' diff --git a/pyltk/input_element.py b/pyltk/input_element.py new file mode 100644 index 0000000..bba4d8b --- /dev/null +++ b/pyltk/input_element.py @@ -0,0 +1,19 @@ +# -*- encoding: utf-8 -*- + +from .element import element + + +class input_element(element): + + templates = { + 'element': '\\input{{{filename}}}' + } + + def __init__(self, filename, parent=None): + super().__init__(parent) + self.filename = filename.replace('.tex', '') + + def content(self): + return self.fmt().format('element', { + 'filename': self.filename + }) diff --git a/pyltk/makebox.py b/pyltk/makebox.py index 7301c4e..bbdaf38 100644 --- a/pyltk/makebox.py +++ b/pyltk/makebox.py @@ -1,18 +1,18 @@ # -*- encoding: utf-8 -*- -from .formatter import formatter +from .element import element -class makebox: +class makebox(element): """ Class representing an unindented makebox. """ - fmt = formatter({ + templates = { 'content': """{noindent}\\makebox[{width}]{{ {inner} }}""" - }) + } - def __init__(self, inner, width=None, noindent=True): + def __init__(self, content=None, parent=None, width=None, noindent=True): """ Create a new makebox with given width. Parameters: @@ -21,7 +21,7 @@ class makebox: \\textwidth. - noindent Add a \\noindent command before the box. """ - self.inner = inner + super().__init__(parent, content) self.width = width if self.width is None: @@ -33,9 +33,9 @@ class makebox: if self.noindent: self.noindent = '\\noindent' - def __str__(self): - return self.fmt.format('content', { - 'inner': self.inner, + def content(self): + return self.fmt().format('content', { + 'inner': super().content(), 'width': self.width, 'noindent': self.noindent }) diff --git a/pyltk/pgfplots/__init__.py b/pyltk/pgfplots/__init__.py new file mode 100644 index 0000000..96d9397 --- /dev/null +++ b/pyltk/pgfplots/__init__.py @@ -0,0 +1,7 @@ +# -*- encoding: utf-8 -*- + +# flake8: noqa + +from .axis import axis +from .semilogaxis import * +from .plots import * diff --git a/pyltk/pgfplots/axis.py b/pyltk/pgfplots/axis.py new file mode 100644 index 0000000..d9019bf --- /dev/null +++ b/pyltk/pgfplots/axis.py @@ -0,0 +1,39 @@ +# -*- encoding: utf-8 -*- + +from ..element import element + + +class axis(element): + """ Class representing an axis. """ + + templates = { + 'options': '[{content}]', + 'legends': '\\legend{{{content}}}', + 'content': """\\begin{{axis}}{options} +{inner} +{legend} +\\end{{axis}}""" + } + + def __init__(self, *args, parent=None, legend=True, label=None, **kargs): + super().__init__(parent, label=label) + self.options = kargs + self.legend = legend + for arg in args: + self.add(arg) + + def content(self): + leg = '' + if self.legend: + if type(self.legend) is str: + leg = self.legend + else: + leg = self.fmt().format('legends', { + 'content': ', '.join('{{{}}}'.format(p.legend) + for p in self.childrens) + }) + return self.fmt().format('content', { + 'options': self.format_options(self.options), + 'inner': super().content(), + 'legend': leg + }) diff --git a/pyltk/tikz/coordinates_plot.py b/pyltk/pgfplots/coordinates_plot.py similarity index 100% rename from pyltk/tikz/coordinates_plot.py rename to pyltk/pgfplots/coordinates_plot.py diff --git a/pyltk/tikz/errorbars_plot.py b/pyltk/pgfplots/errorbars_plot.py similarity index 81% rename from pyltk/tikz/errorbars_plot.py rename to pyltk/pgfplots/errorbars_plot.py index bd319a3..0af311e 100644 --- a/pyltk/tikz/errorbars_plot.py +++ b/pyltk/pgfplots/errorbars_plot.py @@ -5,10 +5,10 @@ from .generic_plot import generic_plot class errorbars_plot(generic_plot): - def __init__(self, legend, data, options=[]): + def __init__(self, legend, data, label=None, options=[]): options = options + [ 'error bars/.cd', ('y dir', 'both'), ('y explicit')] - super().__init__(legend, data, options) + super().__init__(legend, data, label=label, options=options) def format_data(self, data): rows = [] diff --git a/pyltk/tikz/generic_plot.py b/pyltk/pgfplots/generic_plot.py similarity index 69% rename from pyltk/tikz/generic_plot.py rename to pyltk/pgfplots/generic_plot.py index a41d733..6b3af16 100644 --- a/pyltk/tikz/generic_plot.py +++ b/pyltk/pgfplots/generic_plot.py @@ -1,17 +1,18 @@ # -*- encoding: utf-8 -*- -from ..formatter import formatter +from ..element import element -class generic_plot: +class generic_plot(element): """ Class representing a pgfplots plot. """ - fmt = formatter({ + templates = { 'options': '+[{content}]', 'content': """\\addplot{options} {data};""" - }) + } - def __init__(self, legend, data, options=[]): + def __init__(self, legend, data, label=None, options=[]): + super().__init__(label=label) self.legend = legend self.data = data self.options = options @@ -24,12 +25,12 @@ class generic_plot: if type(opt) is not str: opt = '{}={}'.format(*opt) opts.append(str(opt)) - return self.fmt.format('options', { + return self.fmt().format('options', { 'content': ', '.join(opts) }) - def __str__(self): - return self.fmt.format('content', { + def content(self): + return self.fmt().format('content', { 'data': self.format_data(self.data), 'options': self.format_options(self.options) }) diff --git a/pyltk/tikz/plots.py b/pyltk/pgfplots/plots.py similarity index 100% rename from pyltk/tikz/plots.py rename to pyltk/pgfplots/plots.py diff --git a/pyltk/pgfplots/semilogaxis.py b/pyltk/pgfplots/semilogaxis.py new file mode 100644 index 0000000..b415f0d --- /dev/null +++ b/pyltk/pgfplots/semilogaxis.py @@ -0,0 +1,35 @@ +# -*- encoding: utf-8 -*- + +from .axis import axis + + +class semilogyaxis(axis): + """ Class representing an axis. """ + + templates = { + 'options': '[{content}]', + 'legends': '\\legend{{{content}}}', + 'content': """\\begin{{semilogyaxis}}{options} +{inner} +{legend} +\\end{{semilogyaxis}}""" + } + + def __init__(self, *args, **kargs): + super().__init__(*args, **kargs) + + +class semilogxaxis(axis): + """ Class representing an axis. """ + + templates = { + 'options': '[{content}]', + 'legends': '\\legend{{{content}}}', + 'content': """\\begin{{semilogxaxis}}{options} +{inner} +{legend} +\\end{{semilogxaxis}}""" + } + + def __init__(self, *args, **kargs): + super().__init__(*args, **kargs) diff --git a/pyltk/resizebox.py b/pyltk/resizebox.py index 1af95f1..7d0b5fb 100644 --- a/pyltk/resizebox.py +++ b/pyltk/resizebox.py @@ -1,18 +1,19 @@ # -*- encoding: utf-8 -*- -from .formatter import formatter +from .element import element -class resizebox: +class resizebox(element): """ Class representing a latex resizebox. """ - fmt = formatter({ + templates = { 'content': """\\resizebox{{{width}}}{{{height}}}{{ {inner} }}""" - }) + } - def __init__(self, inner, width, height="!"): + def __init__(self, content=None, parent=None, + width="\\linewidth", height="!"): """ Create a resizebox with given width and height. Parameters: @@ -24,15 +25,15 @@ class resizebox: - str Use as it is (e.g. "0.5\\linewidth", "!"). - others Use as a percentage of linewidth (e.g. 0.5). """ - self.inner = inner + super().__init__(parent, content) self.width = width - if type(width) != 'str': + if type(width) is not str: self.width = '{}\\linewidth'.format(width) self.height = height - def __str__(self): - return self.fmt.format('content', { + def content(self): + return self.fmt().format('content', { 'width': self.width, 'height': self.height, - 'inner': self.inner + 'inner': super().content() }) diff --git a/pyltk/strelement.py b/pyltk/strelement.py new file mode 100644 index 0000000..9c6980c --- /dev/null +++ b/pyltk/strelement.py @@ -0,0 +1,12 @@ +# -*- encoding: utf-8 -*- + +from .element import element + + +def strelement(element): + + def __init__(self, content, parent=None): + self.inner = content + + def __str__(self): + return str(self.inner) diff --git a/pyltk/subfloat.py b/pyltk/subfloat.py index 3f60d42..a602688 100644 --- a/pyltk/subfloat.py +++ b/pyltk/subfloat.py @@ -1,23 +1,23 @@ # -*- encoding: utf-8 -*- -from .formatter import formatter +from .element import element -class subfloat: +class subfloat(element): """ Class representing a latex subfloat. """ - fmt = formatter({ + templates = { 'content': """\\subfloat[{caption}]{{ {inner} }}""" - }) + } - def __init__(self, inner, caption): + def __init__(self, caption, parent=None, childrens=None, label=None): + super().__init__(parent, childrens, label=label) self.caption = caption - self.inner = inner - def __str__(self): - return self.fmt.format('content', { + def content(self): + return self.fmt().format('content', { 'caption': self.caption, - 'inner': self.inner + 'inner': super().content() }) diff --git a/pyltk/table.py b/pyltk/table.py new file mode 100644 index 0000000..72af98e --- /dev/null +++ b/pyltk/table.py @@ -0,0 +1,60 @@ +# -*- encoding: utf-8 -*- + +from .element import element +from .tabular import tabular + + +class table(element): + """ Class representing a latex figure. """ + + templates = { + 'caption': '\\caption{{{content}}}', + 'content': """\\begin{{table}}[{options}] +{centered} +{inner} +{caption}{label} +\\end{{table}}""" + } + + autolabel = False + + def __init__(self, childrens=None, parent=None, + caption=None, options='!ht', + centered=True, label=None): + """ Create a table with given options. + + Parameters: + - options Options for the table. + - centered Set to true to add a centering command. + """ + super().__init__(parent, childrens, label=label) + self.options = options + self.caption = caption + self.centered = '' + if centered: + self.centered = '\\centering' + + def content(self): + caption = '' + if self.caption: + caption = self.fmt().format('caption', {'content': self.caption}) + return self.fmt().format('content', { + 'options': self.options, + 'centered': self.centered, + 'caption': caption, + 'label': self.format_label(self.label), + 'inner': super().content() + }) + + +class tabledf(table): + + def __init__(self, df, header=None, **kargs): + super().__init__(**kargs) + if header is None: + header = df.columns + tab = tabular(columns='r' * len(header)) + tab.addrow(header) + tab.addhline() + tab.addrows(df.as_matrix()) + self.add(tab) diff --git a/pyltk/tabular.py b/pyltk/tabular.py index 0d0e60b..21ff551 100644 --- a/pyltk/tabular.py +++ b/pyltk/tabular.py @@ -1,53 +1,94 @@ # -*- encoding: utf-8 -*- -from .formatter import formatter +from .element import element -class tabular: +class row_element(element): + + """ Class representing a row of a tabular element. """ + + def __init__(self, columns, parent, label=None, + wrapper=False, endline=False): + super().__init__(parent, columns, label=label) + self.wrapper = wrapper + self.endline = endline + + def content(self): + wp = str + if self.wrapper: + cw = 1/len(self.childrens) + wp = lambda c: str(self.wrapper(c, width=cw)) + out = ' & '.join(map(wp, self.childrens)) + if self.endline: + out += '\\\\' + return out + + +class hline_element(row_element): + + def __init__(self, parent=None): + super().__init__([], parent) + + def content(self): + return '\\hline' + +# instance of hline element +hline = hline_element() + + +class tabular(element): """ Class representing a latex tabular. """ - fmt = formatter({ + templates = { 'content': """\\begin{{tabular}}{{{columns}}} {inner} \\end{{tabular}}""" - }) + } - def __init__(self, rows, columns=None): + def __init__(self, parent=None, rows=[], columns=None, + autowrap=False, label=None): """ Create a tabular with given rows and column specification. Parameters: - rows Rows for the tabular (list of list or list of string). - - columns String representing columns. - - If `rows` is a str, an empty tabular is created and `rows` is used - instead of `columns` for the columns specification. + - columns String representing columns options. """ - if type(rows) == str: - columns = rows - rows = [] + super().__init__(parent, label=label) self.columns = columns - self.rows = [] + self.autowrap = autowrap for row in rows: self.addrow(row) - def addrow(self, row): + def addhline(self): + """ Add a hline to the current tabular element. """ + self.addrow(hline_element(self), False) + + def addrow(self, row, wrap=None): """ Add a row to the tabular. Parameters: - row Array or string (array will be joined with ' & '). + - wrap Can contains a wrapper element (typically a resizebox) for + the cell of the row. """ - if type(row) != 'str': - row = ' & '.join(map(str, row)) - self.rows.append(row) + if not isinstance(row, row_element): + row = row_element(row, parent=self) + if wrap is None: + wrap = self.autowrap + row.wrapper = wrap + if self.childrens: + last = self.childrens[-1] + if isinstance(last, row_element): + last.endline = True + self.add(row) def addrows(self, rows): """ Add multiple rows to the tabular (see addrow). """ for row in rows: self.addrow(row) - def __str__(self): - inner = '\\\\\n'.join(self.rows) - return self.fmt.format('content', { + def content(self): + return self.fmt().format('content', { 'columns': self.columns, - 'inner': inner + 'inner': super().content() }) diff --git a/pyltk/tikz/__init__.py b/pyltk/tikz/__init__.py index 7fc2d40..2a933b2 100644 --- a/pyltk/tikz/__init__.py +++ b/pyltk/tikz/__init__.py @@ -2,5 +2,4 @@ # flake8: noqa -from .plots import * from .tikzpicture import tikzpicture diff --git a/pyltk/tikz/axis.py b/pyltk/tikz/axis.py deleted file mode 100644 index ff8dcd0..0000000 --- a/pyltk/tikz/axis.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- encoding: utf-8 -*- - -from ..formatter import formatter - - -class axis: - """ Class representing an axis. """ - - fmt = formatter({ - 'options': '[{content}]', - 'legends': '\\legend{{{content}}}', - 'content': """\\begin{{axis}}{options} -{inner} -{legend} -\\end{{axis}}""" - }) - - def __init__(self, *args, **kargs): - self.options = kargs - self.plots = [] - for arg in args: - self.addplot(arg) - - def addplot(self, pl): - self.plots.append(pl) - - def format_options(self, options): - if not options: - return '' - opts = [] - for k, v in options.items(): - opts.append('{key} = {{{value}}}'.format(key=k, value=v)) - return self.fmt.format('options', { - 'content': ', '.join(opts) - }) - - def __str__(self): - return self.fmt.format('content', { - 'options': self.format_options(self.options), - 'inner': '\n'.join(map(str, self.plots)), - 'legend': self.fmt.format('legends', { - 'content': ', '.join('{{{}}}'.format(p.legend) - for p in self.plots) - }) - }) diff --git a/pyltk/tikz/tikzpicture.py b/pyltk/tikz/tikzpicture.py index 9e7ee8e..5067d9b 100644 --- a/pyltk/tikz/tikzpicture.py +++ b/pyltk/tikz/tikzpicture.py @@ -1,29 +1,21 @@ # -*- encoding: utf-8 -from ..formatter import formatter - -from .axis import axis +from ..element import element -class tikzpicture: +class tikzpicture(element): """ Class representing a latex tikzfigure. """ - fmt = formatter({ + templates = { 'content': """\\begin{{tikzpicture}} {inner} \\end{{tikzpicture}}""" - }) + } - def __init__(self, axis=[]): - self.axis = [] + def __init__(self, childrens=None, parent=None, label=None): + super().__init__(parent, childrens, label=label) - def addaxis(self, *args, **kargs): - ax = args[0] - if not isinstance(ax, axis): - ax = axis(*args, **kargs) - self.axis.append(ax) - - def __str__(self): - return self.fmt.format('content', { - 'inner': '\n'.join(map(str, self.axis)) + def content(self): + return self.fmt().format('content', { + 'inner': super().content() }) diff --git a/tests/test_basic.py b/tests/test_basic.py index c3b6aa9..672ab9f 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1,18 +1,21 @@ # -*- encoding: utf-8 -*- +import os import sys sys.path += ['..'] from pyltk import subfloat, tabular, resizebox, makebox, figure -from pyltk.tikz import tikzpicture, errorbars_plot, coordinates_plot +from pyltk.tikz import tikzpicture +from pyltk.pgfplots import axis, errorbars_plot, coordinates_plot if __name__ == "__main__": + data = [[1.00000000e+00, 4.57213083e+00], [2.00000000e+00, - 1.16046200e+01], - [ 4.00000000e+00, + 1.16046200e+01], + [4.00000000e+00, 2.71873880e+01], [ 5.00000000e+00, 3.36039380e+01], @@ -21,30 +24,57 @@ if __name__ == "__main__": [ 2.00000000e+01, 1.50422028e+02]] - tk = tikzpicture() - tk.addaxis(coordinates_plot('test', data), - xlabel='', ylabel='Computation Time [s]') + tk1 = tikzpicture() + tk1.add(axis(coordinates_plot('test', data), + xlabel='', ylabel='Computation Time [s]')) tk2 = tikzpicture() - tk2.addaxis(errorbars_plot('test 2', [ + tk2.add(axis(errorbars_plot('test 2', [ [0, 5, (2, 3)], [1, 8, (4, 5)] - ])) + ]))) tk3 = tikzpicture() - tk3.addaxis(errorbars_plot('test 2', [ + tk3.add(axis(errorbars_plot('test 2', [ [0, 5, 3], [4, 8, 4] - ])) + ]))) - s1 = subfloat(tk, 'Caption 1') - s2 = subfloat(tk2, 'Caption 2') - s3 = subfloat(tk3, 'Caption 3') - s4 = subfloat('', 'Caption 4') + tk4 = tikzpicture() + tk4.add(axis(coordinates_plot('test', []))) - tab = tabular([ - [resizebox(s1, 0.5), resizebox(s2, 0.5)], - [resizebox(s3, 0.5), resizebox(s4, 0.5)] - ], columns='cc') + s1 = subfloat('Caption 1', childrens=tk1) + s2 = subfloat('Caption 2', childrens=tk2) + s3 = subfloat('Caption 3', childrens=tk3) + s4 = subfloat('Caption 4', childrens=tk4) - print(figure(makebox(tab), '!h')) + tab = tabular(rows=[ + [s1, s2], + [s3, s4] + ], columns='cc', autowrap=resizebox) + + f = figure(makebox(tab), '!h') + print(f) # f.childrens[0].childrens[0].childrens) + + wrap = """\\documentclass{{article}} +\\usepackage{{amsmath,amsfonts,amssymb}} +\\usepackage{{tabularx}} +\\usepackage{{multirow}} +\\usepackage{{stmaryrd}} +\\usepackage{{hhline}} +\\usepackage{{caption}} +\\usepackage{{tikz}} +\\usetikzlibrary{{arrows}} +\\usetikzlibrary{{positioning}} +\\usepackage{{subfig}} +\\usepackage{{pgfplots}} + +\\begin{{document}} +{content} +\\end{{document}}""".format(content=f) + + with open('/tmp/test.tex', 'w') as fd: + fd.write(wrap) + + os.system('pdflatex /tmp/test.tex') + os.system('evince test.pdf')