diff --git a/pylatex/document.py b/pylatex/document.py index 47d4c73f..85386e03 100644 --- a/pylatex/document.py +++ b/pylatex/document.py @@ -295,7 +295,7 @@ def generate_pdf(self, filepath=None, *, clean=True, clean_tex=True, else: # Notify user that none of the compilers worked. - raise(CompilerError( + raise (CompilerError( 'No LaTex compiler was found\n' 'Either specify a LaTex compiler ' 'or make sure you have latexmk or pdfLaTex installed.' diff --git a/pylatex/package.py b/pylatex/package.py index 040bed53..008f7e75 100644 --- a/pylatex/package.py +++ b/pylatex/package.py @@ -30,3 +30,4 @@ def __init__(self, name, options=None): """ super().__init__(arguments=name, options=options) + diff --git a/pylatex/quantities.py b/pylatex/quantities.py index d6e60c8a..e15e3b13 100644 --- a/pylatex/quantities.py +++ b/pylatex/quantities.py @@ -24,6 +24,7 @@ 'Celsius': 'celsius', 'revolutions_per_minute': 'rpm', 'v': 'volt', + 'arcdegree': 'degree' } @@ -46,7 +47,7 @@ def _dimensionality_to_siunitx(dim): # Split unitname into prefix and actual name if possible if unit.name.startswith(prefix): substring += '\\' + prefix - name = unit.name[len(prefix)] + name = unit.name[len(prefix):] break else: # Otherwise simply use the full name @@ -141,3 +142,12 @@ def _format(val): self.arguments._escape = False # dash in e.g. \num{3 +- 2} if self.options is not None: self.options._escape = False # siunitx uses dashes in kwargs + + def __str__(self): + return self.dumps() + + def __add__(self, other): + return str(self) + other + + def __radd__(self, other): + return other + str(self) diff --git a/pylatex/tikz.py b/pylatex/tikz.py index 98add4be..1fbe49e4 100644 --- a/pylatex/tikz.py +++ b/pylatex/tikz.py @@ -12,6 +12,10 @@ import math +class TikZLibrary(Package): + _latex_name = "usetikzlibrary" + + class TikZOptions(Options): """Options class, do not escape.""" @@ -27,13 +31,15 @@ class TikZ(Environment): """Basic TikZ container class.""" _latex_name = 'tikzpicture' - packages = [Package('tikz')] + packages = [Package('tikz'), TikZLibrary('positioning'),Package('pgfplots'), Command('pgfplotsset', 'compat=newest')] class Axis(Environment): """PGFPlots axis container class, this contains plots.""" - packages = [Package('pgfplots'), Command('pgfplotsset', 'compat=newest')] + packages = [Package('pgfplots'), + Command('pgfplotsset', 'compat=newest'), + Command('usepgfplotslibrary','groupplots')] def __init__(self, options=None, *, data=None): """ @@ -200,8 +206,9 @@ class TikZNode(TikZObject): """A class that represents a TiKZ node.""" _possible_anchors = ['north', 'south', 'east', 'west'] + _counter = 0 - def __init__(self, handle=None, options=None, at=None, text=None): + def __init__(self, handle=None, options=None, at=None, text=None, positioning=None): """ Args ---- @@ -215,9 +222,13 @@ def __init__(self, handle=None, options=None, at=None, text=None): Body text of the node """ super(TikZNode, self).__init__(options=options) - + if not handle: + handle = f'Node{TikZNode._counter}' + TikZNode._counter += 1 self.handle = handle + self._positioning = positioning + if isinstance(at, (TikZCoordinate, type(None))): self._node_position = at else: @@ -230,8 +241,7 @@ def __init__(self, handle=None, options=None, at=None, text=None): def dumps(self): """Return string representation of the node.""" - ret_str = [] - ret_str.append(Command('node', options=self.options).dumps()) + ret_str = [Command('node', options=self.options).dumps()] if self.handle is not None: ret_str.append('({})'.format(self.handle)) @@ -239,6 +249,9 @@ def dumps(self): if self._node_position is not None: ret_str.append('at {}'.format(str(self._node_position))) + if self._positioning is not None: + ret_str.append(f'[{self._positioning[1]} = of {self._positioning[0].handle}]') + if self._node_text is not None: ret_str.append('{{{text}}};'.format(text=self._node_text)) else: @@ -550,7 +563,7 @@ def dumps(self): self.error_bar): # ie: "(x,y) +- (e_x,e_y)" string += '(' + str(x) + ',' + str(y) + \ - ') +- (' + str(e_x) + ',' + str(e_y) + ')%\n' + ') +- (' + str(e_x) + ',' + str(e_y) + ')%\n' string += '};%\n%\n' diff --git a/pylatex/utils.py b/pylatex/utils.py index ed517b04..b2c3cc1e 100644 --- a/pylatex/utils.py +++ b/pylatex/utils.py @@ -36,30 +36,6 @@ def _is_iterable(element): return hasattr(element, '__iter__') and not isinstance(element, str) -class NoEscape(str): - """ - A simple string class that is not escaped. - - When a `.NoEscape` string is added to another `.NoEscape` string it will - produce a `.NoEscape` string. If it is added to normal string it will - produce a normal string. - - Args - ---- - string: str - The content of the `NoEscape` string. - """ - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, self) - - def __add__(self, right): - s = super().__add__(right) - if isinstance(right, NoEscape): - return NoEscape(s) - return s - - def escape_latex(s): r"""Escape characters that are special in latex. @@ -95,6 +71,30 @@ def escape_latex(s): return NoEscape(''.join(_latex_special_chars.get(c, c) for c in str(s))) +class NoEscape(str): + """ + A simple string class that is not escaped. + + When a `.NoEscape` string is added to another `.NoEscape` string it will + produce a `.NoEscape` string. If it is added to normal string it will + produce a normal string. + + Args + ---- + string: str + The content of the `NoEscape` string. + """ + + def __repr__(self): + return '%s(%s)' % (self.__class__.__name__, self) + + def __add__(self, right): + s = super().__add__(right) + if isinstance(right, NoEscape): + return NoEscape(s) + return s + + def fix_filename(path): r"""Fix filenames for use in LaTeX.