Clean code with black and create setup.py.
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,4 @@ | ||||
| *~ | ||||
| **/__pycache__ | ||||
| **/.mypy_cache | ||||
| *.egg-info | ||||
|   | ||||
| @@ -17,26 +17,25 @@ class CompileResult(enum.Enum): | ||||
|  | ||||
| class documentclass(element): | ||||
|  | ||||
|     classname = 'standalone' | ||||
|     classname = "standalone" | ||||
|  | ||||
|     templates = { | ||||
|         'package': '\\usepackage{pkgoptions}{{{pkgname}}}', | ||||
|         'options': '[{content}]', | ||||
|         'def': '\\def\\{name}{nargs}{{{value}}}', | ||||
|         'content': """\\documentclass{options}{{{classname}}} | ||||
|         "package": "\\usepackage{pkgoptions}{{{pkgname}}}", | ||||
|         "options": "[{content}]", | ||||
|         "def": "\\def\\{name}{nargs}{{{value}}}", | ||||
|         "content": """\\documentclass{options}{{{classname}}} | ||||
| {packages} | ||||
| {preamble} | ||||
| \\begin{{document}} | ||||
| {content} | ||||
| \\end{{document}} | ||||
| """ | ||||
| """, | ||||
|     } | ||||
|  | ||||
|     output_aux_folder = '.pyltk' | ||||
|     auto_tex_folder_name = 'tex2pdf' | ||||
|     output_aux_folder = ".pyltk" | ||||
|     auto_tex_folder_name = "tex2pdf" | ||||
|  | ||||
|     def __init__(self, classname, childrens=[], options=[], | ||||
|                  packages=[], preamble=[]): | ||||
|     def __init__(self, classname, childrens=[], options=[], packages=[], preamble=[]): | ||||
|         super().__init__(parent=None, childrens=childrens) | ||||
|         self.options = options | ||||
|         self.classname = classname | ||||
| @@ -60,38 +59,44 @@ class documentclass(element): | ||||
|             self.preamble.append(value) | ||||
|  | ||||
|     def add_def(self, name, nargs, value): | ||||
|         self.preamble.append(self.fmt().format('def', { | ||||
|             'name': name, | ||||
|             'nargs': '#{}'.format(nargs) if nargs > 0 else '', | ||||
|             'value': value | ||||
|         })) | ||||
|         self.preamble.append( | ||||
|             self.fmt().format( | ||||
|                 "def", | ||||
|                 { | ||||
|                     "name": name, | ||||
|                     "nargs": "#{}".format(nargs) if nargs > 0 else "", | ||||
|                     "value": value, | ||||
|                 }, | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
|     def format_preamble(self, defs): | ||||
|         return '\n'.join(str(p) for p in self.preamble) | ||||
|         return "\n".join(str(p) for p in self.preamble) | ||||
|  | ||||
|     def format_packages(self, pkgs): | ||||
|         out = [] | ||||
|         for pkg in sorted(pkgs): | ||||
|             options = '' | ||||
|             options = "" | ||||
|             if pkgs[pkg] is not True: | ||||
|                 options = self.format_options(pkgs[pkg]) | ||||
|             out.append(self.fmt().format('package', { | ||||
|                 'pkgname': pkg, | ||||
|                 'pkgoptions': options | ||||
|             })) | ||||
|         return '\n'.join(out) | ||||
|             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() | ||||
|         }) | ||||
|         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='auto', outlog=None, | ||||
|                 compile_twice=False): | ||||
|     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 | ||||
| @@ -116,55 +121,62 @@ class documentclass(element): | ||||
|         res = CompileResult.ERROR | ||||
|  | ||||
|         output_aux_folder = os.path.join(outdir, self.output_aux_folder) | ||||
|         auto_tex_folder = os.path.join(output_aux_folder, | ||||
|                                        self.auto_tex_folder_name) | ||||
|         auto_tex_folder = os.path.join(output_aux_folder, self.auto_tex_folder_name) | ||||
|  | ||||
|         # Make aux directory | ||||
|         os.makedirs(output_aux_folder, exist_ok=True) | ||||
|  | ||||
|         # Remove extension if exists | ||||
|         if outfile.endswith('.pdf'): | ||||
|         if outfile.endswith(".pdf"): | ||||
|             outfile = outfile[:-4] | ||||
|  | ||||
|         to_delete = False | ||||
|  | ||||
|         if infile == 'auto': | ||||
|         if infile == "auto": | ||||
|             os.makedirs(auto_tex_folder, exist_ok=True) | ||||
|             infile = '{}/{}.tex'.format(auto_tex_folder, outfile) | ||||
|             infile = "{}/{}.tex".format(auto_tex_folder, outfile) | ||||
|  | ||||
|         if infile is None: | ||||
|             to_delete = True | ||||
|             infile = os.path.join(outdir, '.pyltk-{}.tex'.format(outfile)) | ||||
|             infile = os.path.join(outdir, ".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: | ||||
|             with open(infile, "r") as infd: | ||||
|                 old_content = infd.read() | ||||
|  | ||||
|             # Content has not changed | ||||
|             if old_content == new_content \ | ||||
|                 and os.path.exists(os.path.join(outdir, outfile) + '.pdf') \ | ||||
|                 and os.path.getctime(infile) <= \ | ||||
|                     os.path.getctime(os.path.join(outdir, outfile) + '.pdf'): | ||||
|             if ( | ||||
|                 old_content == new_content | ||||
|                 and os.path.exists(os.path.join(outdir, outfile) + ".pdf") | ||||
|                 and os.path.getctime(infile) | ||||
|                 <= os.path.getctime(os.path.join(outdir, outfile) + ".pdf") | ||||
|             ): | ||||
|                 to_create = False | ||||
|  | ||||
|         if to_create: | ||||
|             with open(infile, 'w') as infd: | ||||
|             with open(infile, "w") as infd: | ||||
|                 infd.write(self.content()) | ||||
|             call = ['pdflatex', '-halt-on-error', | ||||
|                     '-output-directory', output_aux_folder, | ||||
|                     '-jobname', outfile, infile] | ||||
|             call = [ | ||||
|                 "pdflatex", | ||||
|                 "-halt-on-error", | ||||
|                 "-output-directory", | ||||
|                 output_aux_folder, | ||||
|                 "-jobname", | ||||
|                 outfile, | ||||
|                 infile, | ||||
|             ] | ||||
|             res = subprocess.call(call, stdout=outlog) | ||||
|             if compile_twice: | ||||
|                 res = subprocess.call(call, stdout=outlog) | ||||
|             if res == 0: | ||||
|                 os.replace( | ||||
|                     os.path.join( | ||||
|                         output_aux_folder, outfile + '.pdf'), | ||||
|                     os.path.join(outdir, outfile + '.pdf')) | ||||
|                     os.path.join(output_aux_folder, outfile + ".pdf"), | ||||
|                     os.path.join(outdir, outfile + ".pdf"), | ||||
|                 ) | ||||
|                 res = CompileResult.SUCCESS | ||||
|             else: | ||||
|                 res = CompileResult.ERROR | ||||
|   | ||||
| @@ -18,7 +18,7 @@ class element: | ||||
|     are no subclasses of `element`. """ | ||||
|  | ||||
|     # Joiner for childrens | ||||
|     sep = '\n' | ||||
|     sep = "\n" | ||||
|  | ||||
|     # Automatically add label after element if present | ||||
|     autolabel = True | ||||
| @@ -26,8 +26,7 @@ class element: | ||||
|     # Do not wrap non-element in wrapper_element | ||||
|     raw = False | ||||
|  | ||||
|     def __init__(self, parent=None, childrens=[], label=None, | ||||
|                  raw=False, **kargs): | ||||
|     def __init__(self, parent=None, childrens=[], label=None, raw=False, **kargs): | ||||
|         """ Create a new element with given parameters. | ||||
|  | ||||
|         Parameters: | ||||
| @@ -80,25 +79,25 @@ class element: | ||||
|                 if isinstance(value, dict): | ||||
|                     value = self.format_options_dict(value) | ||||
|                 elif isinstance(value, list) or isinstance(value, tuple): | ||||
|                     value = ','.join(value) | ||||
|                     value = ",".join(value) | ||||
|                 else: | ||||
|                     value = str(value).strip() | ||||
|                     if value[0] == '{' and value[1] == '}': | ||||
|                     if value[0] == "{" and value[1] == "}": | ||||
|                         value = value[1:-1] | ||||
|                 opts.append('{key}={{{value}}}'.format(key=k, value=value)) | ||||
|         return ', '.join(opts) | ||||
|                 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': self.format_options_dict(options) | ||||
|         }) | ||||
|             return "" | ||||
|         return self.fmt().format( | ||||
|             "options", {"content": self.format_options_dict(options)} | ||||
|         ) | ||||
|  | ||||
|     def format_label(self, label): | ||||
|         if not label: | ||||
|             return '' | ||||
|         return '\\label{{{}}}'.format(label) | ||||
|             return "" | ||||
|         return "\\label{{{}}}".format(label) | ||||
|  | ||||
|     def __str__(self): | ||||
|         out = self.content().strip() | ||||
| @@ -111,7 +110,7 @@ class wrapper_element(element): | ||||
|  | ||||
|     """ Wrapper for standard python types working as latex elements. """ | ||||
|  | ||||
|     escape_list = ['_', '#', '%'] | ||||
|     escape_list = ["_", "#", "%"] | ||||
|  | ||||
|     def __init__(self, data, parent=None, autoescape=True): | ||||
|         super().__init__(parent=parent) | ||||
| @@ -122,7 +121,7 @@ class wrapper_element(element): | ||||
|         if not self.autoescape: | ||||
|             return s | ||||
|         for e in self.escape_list: | ||||
|             s = s.replace(e, '\\' + e) | ||||
|             s = s.replace(e, "\\" + e) | ||||
|         return s | ||||
|  | ||||
|     def content(self): | ||||
|   | ||||
| @@ -7,19 +7,25 @@ class figure(element): | ||||
|     """ Class representing a latex figure. """ | ||||
|  | ||||
|     templates = { | ||||
|         'caption': '\\caption{{{content}}}', | ||||
|         'content': """\\begin{{figure}}[{options}] | ||||
|         "caption": "\\caption{{{content}}}", | ||||
|         "content": """\\begin{{figure}}[{options}] | ||||
| {centered} | ||||
| {inner} | ||||
| {caption}{label} | ||||
| \\end{{figure}}""" | ||||
| \\end{{figure}}""", | ||||
|     } | ||||
|  | ||||
|     autolabel = False | ||||
|  | ||||
|     def __init__(self, childrens=None, parent=None, | ||||
|                  caption=None, options='!h', | ||||
|                  centered=True, label=None): | ||||
|     def __init__( | ||||
|         self, | ||||
|         childrens=None, | ||||
|         parent=None, | ||||
|         caption=None, | ||||
|         options="!h", | ||||
|         centered=True, | ||||
|         label=None, | ||||
|     ): | ||||
|         """ Create a figure with given options. | ||||
|  | ||||
|         Parameters: | ||||
| @@ -29,18 +35,21 @@ class figure(element): | ||||
|         super().__init__(parent, childrens, label=label) | ||||
|         self.options = options | ||||
|         self.caption = caption | ||||
|         self.centered = '' | ||||
|         self.centered = "" | ||||
|         if centered: | ||||
|             self.centered = '\\centering' | ||||
|             self.centered = "\\centering" | ||||
|  | ||||
|     def content(self): | ||||
|         caption = '' | ||||
|         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() | ||||
|         }) | ||||
|             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(), | ||||
|             }, | ||||
|         ) | ||||
|   | ||||
| @@ -7,8 +7,8 @@ class includegraphics(element): | ||||
|     """ Class representing a latex includegrahics. """ | ||||
|  | ||||
|     templates = { | ||||
|         'options': '[{content}]', | ||||
|         'element': '\\includegraphics{options}{{{filename}}}' | ||||
|         "options": "[{content}]", | ||||
|         "element": "\\includegraphics{options}{{{filename}}}", | ||||
|     } | ||||
|  | ||||
|     autolabel = False | ||||
| @@ -18,7 +18,7 @@ class includegraphics(element): | ||||
|         self.filename = filename | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('element', { | ||||
|             'filename': self.filename, | ||||
|             'options': self.format_options(self.options) | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "element", | ||||
|             {"filename": self.filename, "options": self.format_options(self.options)}, | ||||
|         ) | ||||
|   | ||||
| @@ -11,23 +11,19 @@ class inline_element(element): | ||||
|     def __init__(self, content, parent=None): | ||||
|         super().__init__(parent=parent) | ||||
|         self.value = content | ||||
|         self.templates = { | ||||
|             'wrapper': self.wrapper | ||||
|         } | ||||
|         self.templates = {"wrapper": self.wrapper} | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('wrapper', { | ||||
|             'value': self.value | ||||
|         }) | ||||
|         return self.fmt().format("wrapper", {"value": self.value}) | ||||
|  | ||||
|  | ||||
| class it(inline_element): | ||||
|     wrapper = '\\textit{{{value}}}' | ||||
|     wrapper = "\\textit{{{value}}}" | ||||
|  | ||||
|  | ||||
| class bf(inline_element): | ||||
|     wrapper = '\\textbf{{{value}}}' | ||||
|     wrapper = "\\textbf{{{value}}}" | ||||
|  | ||||
|  | ||||
| class mt(inline_element): | ||||
|     wrapper = '${value}$' | ||||
|     wrapper = "${value}$" | ||||
|   | ||||
| @@ -5,15 +5,11 @@ from .element import element | ||||
|  | ||||
| class input_element(element): | ||||
|  | ||||
|     templates = { | ||||
|         'element': '\\input{{{filename}}}' | ||||
|     } | ||||
|     templates = {"element": "\\input{{{filename}}}"} | ||||
|  | ||||
|     def __init__(self, filename, parent=None): | ||||
|         super().__init__(parent) | ||||
|         self.filename = filename.replace('.tex', '') | ||||
|         self.filename = filename.replace(".tex", "") | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('element', { | ||||
|             'filename': self.filename | ||||
|         }) | ||||
|         return self.fmt().format("element", {"filename": self.filename}) | ||||
|   | ||||
| @@ -6,10 +6,7 @@ from .element import element | ||||
|  | ||||
| class generic_element(element): | ||||
|  | ||||
|     templates = { | ||||
|         'element': '\\{name}{options}{attributes}', | ||||
|         'options': '[{content}]' | ||||
|     } | ||||
|     templates = {"element": "\\{name}{options}{attributes}", "options": "[{content}]"} | ||||
|  | ||||
|     autolabel = False | ||||
|  | ||||
| @@ -17,22 +14,23 @@ class generic_element(element): | ||||
|         super().__init__(parent, **kargs) | ||||
|         self.name = name | ||||
|         if not args: | ||||
|             self.attributes = '{}' | ||||
|             self.attributes = "{}" | ||||
|         else: | ||||
|             self.attributes = '' | ||||
|             self.attributes = "" | ||||
|             for arg in args: | ||||
|                 self.attributes += '{{{}}}'.format(arg) | ||||
|                 self.attributes += "{{{}}}".format(arg) | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('element', { | ||||
|             'name': self.name, | ||||
|             'attributes': self.attributes, | ||||
|             'options': self.format_options(self.options) | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "element", | ||||
|             { | ||||
|                 "name": self.name, | ||||
|                 "attributes": self.attributes, | ||||
|                 "options": self.format_options(self.options), | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class factory: | ||||
|  | ||||
|     def __getattr__(self, name): | ||||
|         return lambda *args, **kargs: \ | ||||
|           generic_element(name, *args, **kargs) | ||||
|         return lambda *args, **kargs: generic_element(name, *args, **kargs) | ||||
|   | ||||
| @@ -7,7 +7,7 @@ class makebox(element): | ||||
|     """ Class representing an unindented makebox. """ | ||||
|  | ||||
|     templates = { | ||||
|         'content': """{noindent}\\makebox[{width}]{{ | ||||
|         "content": """{noindent}\\makebox[{width}]{{ | ||||
| {inner} | ||||
| }}""" | ||||
|     } | ||||
| @@ -25,17 +25,20 @@ class makebox(element): | ||||
|  | ||||
|         self.width = width | ||||
|         if self.width is None: | ||||
|             self.width = '\\textwidth' | ||||
|         elif type(self.width) != 'str': | ||||
|             self.width = '{}\\textwidth'.format(self.width) | ||||
|             self.width = "\\textwidth" | ||||
|         elif type(self.width) != "str": | ||||
|             self.width = "{}\\textwidth".format(self.width) | ||||
|  | ||||
|         self.noindent = '' | ||||
|         self.noindent = "" | ||||
|         if self.noindent: | ||||
|             self.noindent = '\\noindent' | ||||
|             self.noindent = "\\noindent" | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('content', { | ||||
|             'inner': super().content(), | ||||
|             'width': self.width, | ||||
|             'noindent': self.noindent | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             { | ||||
|                 "inner": super().content(), | ||||
|                 "width": self.width, | ||||
|                 "noindent": self.noindent, | ||||
|             }, | ||||
|         ) | ||||
|   | ||||
| @@ -7,12 +7,12 @@ class axis(element): | ||||
|     """ Class representing an axis. """ | ||||
|  | ||||
|     templates = { | ||||
|         'options': '[{content}]', | ||||
|         'legends': '\\legend{{{content}}}', | ||||
|         'content': """\\begin{{axis}}{options} | ||||
|         "options": "[{content}]", | ||||
|         "legends": "\\legend{{{content}}}", | ||||
|         "content": """\\begin{{axis}}{options} | ||||
| {inner} | ||||
| {legend} | ||||
| \\end{{axis}}""" | ||||
| \\end{{axis}}""", | ||||
|     } | ||||
|  | ||||
|     def __init__(self, *args, parent=None, legend=None, label=None, **kwargs): | ||||
| @@ -23,17 +23,24 @@ class axis(element): | ||||
|             self.add(arg) | ||||
|  | ||||
|     def content(self): | ||||
|         leg = '' | ||||
|         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 | ||||
|         }) | ||||
|                 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, | ||||
|             }, | ||||
|         ) | ||||
|   | ||||
| @@ -4,13 +4,11 @@ from .generic_plot import generic_plot | ||||
|  | ||||
|  | ||||
| class coordinates_plot(generic_plot): | ||||
|  | ||||
|     def __init__(self, *args, **kargs): | ||||
|         super().__init__(*args, **kargs) | ||||
|  | ||||
|     def format_data(self, data): | ||||
|         pts = [] | ||||
|         for d in data: | ||||
|             pts.append('({}, {})'.format( | ||||
|                 *self.format_values(d))) | ||||
|         return 'coordinates {{{}}}'.format(''.join(pts)) | ||||
|             pts.append("({}, {})".format(*self.format_values(d))) | ||||
|         return "coordinates {{{}}}".format("".join(pts)) | ||||
|   | ||||
| @@ -4,10 +4,8 @@ from .generic_plot import generic_plot | ||||
|  | ||||
|  | ||||
| class errorbars_plot(generic_plot): | ||||
|  | ||||
|     def __init__(self, legend, data, precision=5, label=None, options=[]): | ||||
|         options = options + [ | ||||
|             'error bars/.cd', ('y dir', 'both'), ('y explicit')] | ||||
|         options = options + ["error bars/.cd", ("y dir", "both"), ("y explicit")] | ||||
|         super().__init__(legend, data, label=label, options=options) | ||||
|  | ||||
|     def format_data(self, data): | ||||
| @@ -19,7 +17,12 @@ class errorbars_plot(generic_plot): | ||||
|             except TypeError: | ||||
|                 p = d[2] | ||||
|                 n = p | ||||
|             rows.append('({x}, {y}) += (0, {p}) -= (0, {n})'.format( | ||||
|                 x=self.format_value(x), y=self.format_value(y), | ||||
|                 p=self.format_value(p), n=self.format_value(n))) | ||||
|         return 'coordinates {{{}}}'.format('\n'.join(rows)) | ||||
|             rows.append( | ||||
|                 "({x}, {y}) += (0, {p}) -= (0, {n})".format( | ||||
|                     x=self.format_value(x), | ||||
|                     y=self.format_value(y), | ||||
|                     p=self.format_value(p), | ||||
|                     n=self.format_value(n), | ||||
|                 ) | ||||
|             ) | ||||
|         return "coordinates {{{}}}".format("\n".join(rows)) | ||||
|   | ||||
| @@ -7,9 +7,9 @@ class generic_plot(element): | ||||
|     """ Class representing a pgfplots plot. """ | ||||
|  | ||||
|     templates = { | ||||
|         'options': '+[{content}]', | ||||
|         'content': """\\addplot{options} {data};{legend}""", | ||||
|         'legend': """\\addlegendentry{{{content}}}""" | ||||
|         "options": "+[{content}]", | ||||
|         "content": """\\addplot{options} {data};{legend}""", | ||||
|         "legend": """\\addlegendentry{{{content}}}""", | ||||
|     } | ||||
|  | ||||
|     def __init__(self, legend, data, precision=6, label=None, options=[]): | ||||
| @@ -21,32 +21,31 @@ class generic_plot(element): | ||||
|  | ||||
|     def format_options(self, options): | ||||
|         if not options: | ||||
|             return '' | ||||
|             return "" | ||||
|         opts = [] | ||||
|         for opt in options: | ||||
|             if type(opt) is not str: | ||||
|                 opt = '{}={}'.format(*opt) | ||||
|                 opt = "{}={}".format(*opt) | ||||
|             opts.append(str(opt)) | ||||
|         return self.fmt().format('options', { | ||||
|             'content': ', '.join(opts) | ||||
|         }) | ||||
|         return self.fmt().format("options", {"content": ", ".join(opts)}) | ||||
|  | ||||
|     def format_value(self, value): | ||||
|         return '{:.{prec}f}'.format(value, prec=self.precision) | ||||
|         return "{:.{prec}f}".format(value, prec=self.precision) | ||||
|  | ||||
|     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 | ||||
|         }) | ||||
|             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), | ||||
|             'legend': self.format_legend(self.legend) | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             { | ||||
|                 "data": self.format_data(self.data), | ||||
|                 "options": self.format_options(self.options), | ||||
|                 "legend": self.format_legend(self.legend), | ||||
|             }, | ||||
|         ) | ||||
|   | ||||
| @@ -7,12 +7,12 @@ class semilogyaxis(axis): | ||||
|     """ Class representing an axis. """ | ||||
|  | ||||
|     templates = { | ||||
|         'options': '[{content}]', | ||||
|         'legends': '\\legend{{{content}}}', | ||||
|         'content': """\\begin{{semilogyaxis}}{options} | ||||
|         "options": "[{content}]", | ||||
|         "legends": "\\legend{{{content}}}", | ||||
|         "content": """\\begin{{semilogyaxis}}{options} | ||||
| {inner} | ||||
| {legend} | ||||
| \\end{{semilogyaxis}}""" | ||||
| \\end{{semilogyaxis}}""", | ||||
|     } | ||||
|  | ||||
|     def __init__(self, *args, **kargs): | ||||
| @@ -23,12 +23,12 @@ class semilogxaxis(axis): | ||||
|     """ Class representing an axis. """ | ||||
|  | ||||
|     templates = { | ||||
|         'options': '[{content}]', | ||||
|         'legends': '\\legend{{{content}}}', | ||||
|         'content': """\\begin{{semilogxaxis}}{options} | ||||
|         "options": "[{content}]", | ||||
|         "legends": "\\legend{{{content}}}", | ||||
|         "content": """\\begin{{semilogxaxis}}{options} | ||||
| {inner} | ||||
| {legend} | ||||
| \\end{{semilogxaxis}}""" | ||||
| \\end{{semilogxaxis}}""", | ||||
|     } | ||||
|  | ||||
|     def __init__(self, *args, **kargs): | ||||
|   | ||||
| @@ -7,13 +7,12 @@ class resizebox(element): | ||||
|     """ Class representing a latex resizebox. """ | ||||
|  | ||||
|     templates = { | ||||
|         'content': """\\resizebox{{{width}}}{{{height}}}{{ | ||||
|         "content": """\\resizebox{{{width}}}{{{height}}}{{ | ||||
| {inner} | ||||
| }}""" | ||||
|     } | ||||
|  | ||||
|     def __init__(self, content=None, parent=None, | ||||
|                  width="\\linewidth", height="!"): | ||||
|     def __init__(self, content=None, parent=None, width="\\linewidth", height="!"): | ||||
|         """ Create a resizebox with given width and height. | ||||
|  | ||||
|         Parameters: | ||||
| @@ -28,12 +27,11 @@ class resizebox(element): | ||||
|         super().__init__(parent, content) | ||||
|         self.width = width | ||||
|         if type(width) is not str: | ||||
|             self.width = '{}\\linewidth'.format(width) | ||||
|             self.width = "{}\\linewidth".format(width) | ||||
|         self.height = height | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('content', { | ||||
|             'width': self.width, | ||||
|             'height': self.height, | ||||
|             'inner': super().content() | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             {"width": self.width, "height": self.height, "inner": super().content()}, | ||||
|         ) | ||||
|   | ||||
| @@ -4,7 +4,6 @@ from .element import element | ||||
|  | ||||
|  | ||||
| class strelement(element): | ||||
|  | ||||
|     def __init__(self, content, parent=None): | ||||
|         self.inner = content | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ class subfloat(element): | ||||
|     """ Class representing a latex subfloat. """ | ||||
|  | ||||
|     templates = { | ||||
|         'content': """\\subfloat[{caption}{label}]{{ | ||||
|         "content": """\\subfloat[{caption}{label}]{{ | ||||
| {inner} | ||||
| }}""" | ||||
|     } | ||||
| @@ -19,8 +19,11 @@ class subfloat(element): | ||||
|         self.caption = caption | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('content', { | ||||
|             'caption': self.caption, | ||||
|             'label': self.format_label(self.label), | ||||
|             'inner': super().content() | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             { | ||||
|                 "caption": self.caption, | ||||
|                 "label": self.format_label(self.label), | ||||
|                 "inner": super().content(), | ||||
|             }, | ||||
|         ) | ||||
|   | ||||
| @@ -8,19 +8,25 @@ class table(element): | ||||
|     """ Class representing a latex figure. """ | ||||
|  | ||||
|     templates = { | ||||
|         'caption': '\\caption{{{content}}}', | ||||
|         'content': """\\begin{{table}}[{options}] | ||||
|         "caption": "\\caption{{{content}}}", | ||||
|         "content": """\\begin{{table}}[{options}] | ||||
| {centered} | ||||
| {inner} | ||||
| {caption}{label} | ||||
| \\end{{table}}""" | ||||
| \\end{{table}}""", | ||||
|     } | ||||
|  | ||||
|     autolabel = False | ||||
|  | ||||
|     def __init__(self, childrens=None, parent=None, | ||||
|                  caption=None, options='!ht', | ||||
|                  centered=True, label=None): | ||||
|     def __init__( | ||||
|         self, | ||||
|         childrens=None, | ||||
|         parent=None, | ||||
|         caption=None, | ||||
|         options="!ht", | ||||
|         centered=True, | ||||
|         label=None, | ||||
|     ): | ||||
|         """ Create a table with given options. | ||||
|  | ||||
|         Parameters: | ||||
| @@ -30,25 +36,27 @@ class table(element): | ||||
|         super().__init__(parent, childrens, label=label) | ||||
|         self.options = options | ||||
|         self.caption = caption | ||||
|         self.centered = '' | ||||
|         self.centered = "" | ||||
|         if centered: | ||||
|             self.centered = '\\centering' | ||||
|             self.centered = "\\centering" | ||||
|  | ||||
|     def content(self): | ||||
|         caption = '' | ||||
|         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() | ||||
|         }) | ||||
|             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, multilevels=False, fmt=None, **kargs): | ||||
|         super().__init__(**kargs) | ||||
|         self.add(tabulardf(df, header, multilevels, fmt)) | ||||
|   | ||||
| @@ -14,8 +14,9 @@ class row_element(element): | ||||
|  | ||||
|     """ Class representing a row of a tabular element. """ | ||||
|  | ||||
|     def __init__(self, columns, parent, label=None, | ||||
|                  wrapper=False, endline=False, fmt=None): | ||||
|     def __init__( | ||||
|         self, columns, parent, label=None, wrapper=False, endline=False, fmt=None | ||||
|     ): | ||||
|         super().__init__(parent, columns, label=label, raw=(fmt is not None)) | ||||
|         self.wrapper = wrapper | ||||
|         self.endline = endline | ||||
| @@ -28,23 +29,22 @@ class row_element(element): | ||||
|         if self.__fmt: | ||||
|             row = map(self.__fmt, self.childrens) | ||||
|         if self.wrapper: | ||||
|             cw = 1/len(self.childrens) | ||||
|             cw = 1 / len(self.childrens) | ||||
|             wp = lambda c: self.wrapper(c, width=cw) | ||||
|             row = map(wp, row) | ||||
|         out = ' & '.join(map(str, row)) | ||||
|         out = " & ".join(map(str, row)) | ||||
|         if self.endline: | ||||
|             out += '\\\\' | ||||
|             out += "\\\\" | ||||
|         return out | ||||
|  | ||||
|  | ||||
| class hline_element(row_element): | ||||
|  | ||||
|     def __init__(self, command='hline', parent=None): | ||||
|     def __init__(self, command="hline", parent=None): | ||||
|         super().__init__([], parent) | ||||
|         self.command = command | ||||
|  | ||||
|     def content(self): | ||||
|         return '\\' + self.command | ||||
|         return "\\" + self.command | ||||
|  | ||||
|  | ||||
| # instance of hline element | ||||
| @@ -55,13 +55,20 @@ class tabular(element): | ||||
|     """ Class representing a latex tabular. """ | ||||
|  | ||||
|     templates = { | ||||
|         'content': """\\begin{{{name}}}{{{columns}}} | ||||
|         "content": """\\begin{{{name}}}{{{columns}}} | ||||
| {inner} | ||||
| \\end{{{name}}}""" | ||||
|     } | ||||
|  | ||||
|     def __init__(self, parent=None, rows=[], columns=None, | ||||
|                  autowrap=False, label=None, name='tabular'): | ||||
|     def __init__( | ||||
|         self, | ||||
|         parent=None, | ||||
|         rows=[], | ||||
|         columns=None, | ||||
|         autowrap=False, | ||||
|         label=None, | ||||
|         name="tabular", | ||||
|     ): | ||||
|         """ Create a tabular with given rows and column specification. | ||||
|  | ||||
|         Parameters: | ||||
| @@ -103,21 +110,18 @@ class tabular(element): | ||||
|             self.addrow(row, **kargs) | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('content', { | ||||
|             'name': self.name, | ||||
|             'columns': self.columns, | ||||
|             'inner': super().content() | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             {"name": self.name, "columns": self.columns, "inner": super().content()}, | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class multicolumn(element): | ||||
|     """ Class representing a multicolumn element. """ | ||||
|  | ||||
|     templates = { | ||||
|         'content': """\\multicolumn{{{ncolumns}}}{{{align}}}{{{content}}}""" | ||||
|     } | ||||
|     templates = {"content": """\\multicolumn{{{ncolumns}}}{{{align}}}{{{content}}}"""} | ||||
|  | ||||
|     def __init__(self, ncolumns, content='', alignment='c', **kargs): | ||||
|     def __init__(self, ncolumns, content="", alignment="c", **kargs): | ||||
|         super().__init__(**kargs) | ||||
|         self.ncolumns = ncolumns | ||||
|         self.inner = content | ||||
| @@ -126,15 +130,13 @@ class multicolumn(element): | ||||
|     def content(self): | ||||
|         if self.ncolumns == 1: | ||||
|             return self.inner | ||||
|         return self.fmt().format('content', { | ||||
|             'ncolumns': self.ncolumns, | ||||
|             'content': self.inner, | ||||
|             'align': self.alignment | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             {"ncolumns": self.ncolumns, "content": self.inner, "align": self.alignment}, | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class tabulardf(tabular): | ||||
|  | ||||
|     def __init__(self, df, header=None, multilevels=False, fmt=None, **kargs): | ||||
|         if header is None: | ||||
|             multilevels, header = self.create_header(df) | ||||
| @@ -145,7 +147,7 @@ class tabulardf(tabular): | ||||
|             ncols = len(header) | ||||
|             header = [header] | ||||
|  | ||||
|         kargs.setdefault('columns', 'r' * ncols) | ||||
|         kargs.setdefault("columns", "r" * ncols) | ||||
|         super().__init__(**kargs) | ||||
|         self.addrows(header) | ||||
|         self.addhline() | ||||
|   | ||||
| @@ -7,17 +7,17 @@ class tikzpicture(element): | ||||
|     """ Class representing a latex tikzfigure. """ | ||||
|  | ||||
|     templates = { | ||||
|         'options': '[{content}]', | ||||
|         'content': """\\begin{{tikzpicture}}{options} | ||||
|         "options": "[{content}]", | ||||
|         "content": """\\begin{{tikzpicture}}{options} | ||||
| {inner} | ||||
| \\end{{tikzpicture}}""" | ||||
| \\end{{tikzpicture}}""", | ||||
|     } | ||||
|  | ||||
|     def __init__(self, childrens=None, parent=None, label=None, **kargs): | ||||
|         super().__init__(parent, childrens, label=label, **kargs) | ||||
|  | ||||
|     def content(self): | ||||
|         return self.fmt().format('content', { | ||||
|             'inner': super().content(), | ||||
|             'options': self.format_options(self.options) | ||||
|         }) | ||||
|         return self.fmt().format( | ||||
|             "content", | ||||
|             {"inner": super().content(), "options": self.format_options(self.options)}, | ||||
|         ) | ||||
|   | ||||
							
								
								
									
										20
									
								
								setup.cfg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								setup.cfg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| [flake8] | ||||
| # Use black line length: | ||||
| max-line-length = 88 | ||||
| extend-ignore = | ||||
|     # See https://github.com/PyCQA/pycodestyle/issues/373 | ||||
|     E203, | ||||
|  | ||||
| [mypy] | ||||
| warn_return_any = True | ||||
| warn_unused_configs = True | ||||
| namespace_packages = True | ||||
|  | ||||
| [tox:tox] | ||||
| envlist = py36,py37,py38,py36-lint | ||||
|  | ||||
| [testenv] | ||||
| deps = | ||||
|     pytest | ||||
| commands = | ||||
|     pytest tests | ||||
							
								
								
									
										37
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| # -*- encoding: utf-8 -*- | ||||
|  | ||||
| from setuptools import setup, find_packages | ||||
|  | ||||
| dev_requires = [ | ||||
|     "black", | ||||
|     "flake8", | ||||
|     "flake8-black", | ||||
|     "mypy", | ||||
|     "pytest", | ||||
| ] | ||||
|  | ||||
| setup( | ||||
|     # Name of the package: | ||||
|     name="pyltk", | ||||
|     # Version of the package: | ||||
|     version="0.0.1", | ||||
|     # Find the package automatically (include everything): | ||||
|     packages=find_packages(), | ||||
|     # Author information: | ||||
|     author="Mikaël Capelle", | ||||
|     author_email="capelle.mikael@gmail.com", | ||||
|     # Description of the package: | ||||
|     description="Python library to generate and build LaTeX files", | ||||
|     include_package_data=True, | ||||
|     classifiers=[ | ||||
|         "Programming Language :: Python", | ||||
|         "Programming Language :: Python :: 3", | ||||
|         "Programming Language :: Python :: 3.6", | ||||
|         "Programming Language :: Python :: 3.7", | ||||
|     ], | ||||
|     # License: | ||||
|     license="MIT", | ||||
|     # Requirements: | ||||
|     install_requires=[], | ||||
|     extras_require={"dev": dev_requires}, | ||||
| ) | ||||
		Reference in New Issue
	
	Block a user