1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
# Python module Pweave
# Matti Pastell 2010-2013
# http://mpastell.com/pweave
from __future__ import print_function, division, unicode_literals, absolute_import
import inspect
from . import readers
from .pweb import *
from .formatters import *
from .readers import *
from .processors import *
from .config import *
import copy
__version__ = '0.25'
def weave(file, doctype=None, informat=None, shell="python", shell_path=None, plot=True,
docmode=False, cache=False,
figdir='figures', cachedir='cache',
figformat=None, returnglobals=True, listformats=False,
output=None):
"""
Processes a Pweave document and writes output to a file
:param file: ``string`` input file
:param doctype: ``string`` output document format: call with listformats true to get list of supported formats.
:param informat: ``string`` input format: "noweb", "markdown", "notebook" or "script"
:param shell: ``string`` shell used to run code: "python", "ipython", "matlab" or "octave"
:param shell_path: ``string`` Set the path of shell to run code, only affects "epython" shell
:param plot: ``bool`` use matplotlib
:param docmode: ``bool`` use documentation mode, chunk code and results will be loaded from cache and inline code will be hidden
:param cache: ``bool`` Cache results to disk for documentation mode
:param figdir: ``string`` directory path for figures
:param cachedir: ``string`` directory path for cached results used in documentation mode
:param figformat: ``string`` format for saved figures (e.g. '.png'), if None then the default for each format is used
:param returnglobals: ``bool`` if True the namespace of the executed document is added to callers global dictionary. Then it is possible to work interactively with the data while writing the document. IronPython needs to be started with -X:Frames or this won't work.
:param listformats: ``bool`` List available formats and exit
:param output: ``string`` output file
"""
if listformats:
PwebFormats.listformats()
return
assert file != "" is not None, "No input specified"
doc = Pweb(file, shell=shell, output=output, figdir=figdir)
if doctype == None:
doc.detect_format()
else:
doc.setformat(doctype)
if informat == None:
doc.detect_reader()
else:
doc.setreader(informat)
rcParams["usematplotlib"] = plot
#rcParams["figdir"] = figdir
rcParams["cachedir"] = cachedir
doc.documentationmode = docmode
rcParams["storeresults"] = cache
if shell_path is not None:
rcParams["shell_path"] = shell_path
if figformat is not None:
doc.updateformat({'figfmt': figformat, 'savedformats': [figformat]})
# Returning globals
try:
doc.weave(shell)
if returnglobals:
# Get the calling scope and return results to its globals
#this way you can modify the weaved variables from repl
_returnglobals()
except Exception as inst:
# Return varibles used this far if there is an exception
if returnglobals:
_returnglobals()
raise
def _returnglobals():
"""Inspect stack to get the scope of the terminal/script calling pweave function"""
if hasattr(sys, '_getframe'):
caller = inspect.stack()[2][0]
caller.f_globals.update(PwebProcessorGlobals.globals)
if not hasattr(sys, '_getframe'):
print('%s\n%s\n' % ("Can't return globals", "Start Ironpython with ipy -X:Frames if you wan't this to work"))
def tangle(file):
"""Tangles a noweb file i.e. extracts code from code chunks to a .py file
:param file: ``string`` the pweave document containing the code
"""
doc = Pweb(file)
doc.tangle()
def publish(file, doc_format="html", theme = "skeleton", latex_engine = "pdflatex"):
"""Publish python script and results to html or pdf, expects that doc
chunks are written in markdown.
":param file: ``string`` input file"
":param format: ``string`` output format "html" of "pdf", pdf output
requires pandoc and pdflatex in your path.
:param: ``string`` latex_engine the command for running latex. Defaults to "pdflatex".
"""
if doc_format == "html":
pformat = "md2html"
elif doc_format == "pdf":
pformat = "pandoc2latex"
else:
print("Unknown format, exiting")
return
doc = Pweb(file)
doc.setformat(pformat, theme = theme)
doc.setreader(readers.PwebScriptReader)
doc.parse()
doc.run()
doc.format()
doc.write(action="Published")
if doc_format == "pdf":
try:
latex = Popen([latex_engine, doc.sink], stdin=PIPE, stdout=PIPE)
print("Running " + latex_engine + "...")
except:
print("Can't find " + latex_engine + ", no pdf produced!")
return
x = latex.communicate()[0].decode('utf-8')
print("\n".join(x.splitlines()[-2:]))
def spin(file):
"""Convert input file from script format to noweb format, similar to Knitr's spin."""
doc = readers.PwebConvert(file)
def convert(file, informat="noweb", outformat="script", pandoc_args=None,
listformats=False):
"""Convert input file from script to noweb or vice versa
:param file: ``string`` input file
:param informat: ``string`` input format noweb, script or notebook
:param outformat: ``string`` input format noweb or script
:param pandoc_args: ``string`` arguments passed to pandoc to convert doc chunks.
e.g. to convert from markdown to latex use: `"-f markdown -t latex"` .
Note that each doc chunk is converted separately so you can't use pandocs -s option.
:param listformats: ``bool`` List available formats and exit
"""
if listformats:
readers.PwebConverters.listformats()
return
Converter = readers.PwebConverters.formats[outformat]['class']
# pandoc_args = None skips the call to pandoc
doc = Converter(file, informat, outformat, pandoc_args)
doc.convert()
doc.write()
def listformats():
"""List output formats"""
PwebFormats.listformats()
|