From 91e62921c8f6d17fb3a1b701c0b5f99cfeadd408 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 14 Jul 2014 22:39:29 +0000 Subject: pythontex (14jul14) git-svn-id: svn://tug.org/texlive/trunk@34605 c570f23f-e606-0410-a88d-b1316a301751 --- .../scripts/pythontex/pythontex_utils.py | 92 +++++++++++++++++++--- 1 file changed, 83 insertions(+), 9 deletions(-) (limited to 'Master/texmf-dist/scripts/pythontex/pythontex_utils.py') diff --git a/Master/texmf-dist/scripts/pythontex/pythontex_utils.py b/Master/texmf-dist/scripts/pythontex/pythontex_utils.py index 75d3115a395..2731e7ab765 100755 --- a/Master/texmf-dist/scripts/pythontex/pythontex_utils.py +++ b/Master/texmf-dist/scripts/pythontex/pythontex_utils.py @@ -6,7 +6,7 @@ The utilities class provides variables and methods for the individual Python scripts created and executed by PythonTeX. An instance of the class named "pytex" is automatically created in each individual script. -Copyright (c) 2012-2013, Geoffrey M. Poore +Copyright (c) 2012-2014, Geoffrey M. Poore All rights reserved. Licensed under the BSD 3-Clause License: http://www.opensource.org/licenses/BSD-3-Clause @@ -17,6 +17,8 @@ Licensed under the BSD 3-Clause License: # Imports import sys import warnings +if sys.version_info.major == 2: + import io # Most imports are only needed for SymPy; these are brought in via # "lazy import." Importing unicode_literals here shouldn't ever be necessary @@ -40,14 +42,14 @@ class PythonTeXUtils(object): String variables for keeping track of TeX information. Most are actually needed; the rest are included for completeness. - * input_family - * input_session - * input_restart - * input_command - * input_context - * input_args - * input_instance - * input_line + * family + * session + * restart + * command + * context + * args + * instance + * line Future file handle for output that is saved via macros * macrofile @@ -62,6 +64,63 @@ class PythonTeXUtils(object): ''' self.set_formatter(fmtr) + # We need a function that will process the raw `context` into a + # dictionary with attributes + _context_raw = None + class _DictWithAttr(dict): + pass + def set_context(self, expr): + ''' + Convert the string `{context}` into a dict with attributes + ''' + if not expr or expr == self._context_raw: + pass + else: + self._context_raw = expr + self.context = self._DictWithAttr() + k_and_v = [map(lambda x: x.strip(), kv.split('=')) for kv in expr.split(',')] + for k, v in k_and_v: + if v.startswith('!!int '): + v = int(float(v[6:])) + elif v.startswith('!!float '): + v = float(v[8:]) + elif v.startswith('!!str '): + v = v[6:] + self.context[k] = v + setattr(self.context, k, v) + + # A primary use for contextual information is to pass dimensions from the + # TeX side to the Python side. To make that as convenient as possible, + # we need some length conversion functions. + # Conversion reference: http://tex.stackexchange.com/questions/41370/what-are-the-possible-dimensions-sizes-units-latex-understands + def pt_to_in(self, expr): + ''' + Convert points to inches. Accepts numbers, strings of digits, and + strings of digits that end with `pt`. + ''' + try: + ans = expr/72.27 + except: + if expr.endswith('pt'): + expr = expr[:-2] + ans = float(expr)/72.27 + return ans + def pt_to_cm(self, expr): + ''' + Convert points to centimeters. + ''' + return self.pt_to_in(expr)*2.54 + def pt_to_mm(self, expr): + ''' + Convert points to millimeters. + ''' + return self.pt_to_in(expr)*25.4 + def pt_to_bp(self, expr): + ''' + Convert points to big (DTP or PostScript) points. + ''' + return self.pt_to_in(expr)*72 + # We need a context-aware interface to SymPy's latex printer. The # appearance of typeset math should depend on where it appears in a @@ -366,6 +425,21 @@ class PythonTeXUtils(object): for creation in self._created: print(creation) + # A custom version of `open()` is useful for automatically tracking files + # opened for reading as dependencies and tracking files opened for + # writing as created files. + def open(self, name, mode='r', *args, **kwargs): + if mode in ('r', 'rt', 'rb'): + self.add_dependencies(name) + elif mode in ('w', 'wt', 'wb'): + self.add_created(name) + else: + warnings.warn('Unsupported mode {0} for file tracking'.format(mode)) + if sys.version_info.major == 2 and (len(args) > 1 or 'encoding' in kwargs): + return io.open(name, mode, *args, **kwargs) + else: + return open(name, mode, *args, **kwargs) + def cleanup(self): self._save_dependencies() self._save_created() -- cgit v1.2.3