From: W. Trevor King <wking@drexel.edu> Date: Wed, 22 Feb 2012 20:48:27 +0000 (-0500) Subject: Add Maple post with mw2txt.py script. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=1f0bb05;p=mw2txt.git Add Maple post with mw2txt.py script. --- diff --git a/posts/Maple.mdwn b/posts/Maple.mdwn new file mode 100644 index 0000000..50b3f01 --- /dev/null +++ b/posts/Maple.mdwn @@ -0,0 +1,28 @@ +Some of the classes I TA use [Maple][]. (Caveat: I prefer [[Python]], +as a more general language. Use [[SymPy]] or [Sage][] if you need +symbolic processing.) Anyhow, I get Maple worksheets to grade. +[[SSH]]ing into the department computer lab to fire up `xmaple` is a +pain, so I wrote [[mw2txt.py]] to extract the Maple commands from the +worksheet. It benefits from the fact that worksheets are fairly clean +XML. Graphs and equations are more difficult, since they have +complicated layout and are stored as encoded blobs. Other than that, +things work pretty well. Here's the output from my [[example.mw]] +example worksheet, picking out the math-mode sections (in red) and +unprocessed blocks (in yellow) from the comments (uncolored). + +<pre><code>$ mw2txt.py --color example.mw +Hi there +<span style="color: red">> restart; +> interface(prettyprint=0): +> 1;#</span> one <span style="color: red">+</span> plus <span style="color: red">2</span> two <span style="color: red">;</span> +1 +<span style="color: red">> 3 + 4;</span> bold +7 +<span style="color: yellow">Equation</span> +</code></pre> + +[Maple]: http://www.maplesoft.com/products/maple/ +[Sage]: http://www.sagemath.org/ + +[[!tag tags/code]] +[[!tag tags/python]] diff --git a/posts/Maple/example.mw b/posts/Maple/example.mw new file mode 100644 index 0000000..57278d8 --- /dev/null +++ b/posts/Maple/example.mw @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Worksheet> +<Version major="15" minor="0"/> +<Label-Scheme value="2" prefix=""/> +<View-Properties presentation="true"></View-Properties> +<MapleNet-Properties elisiondigitsbefore="100" labelling="true" indentamount="4" elisiontermsthreshold="10000" ansi="false" errorbreak="1" useclientjvm="true" echo="1" imaginaryunit="I" labelwidth="20" contextmenusize="automatic" plotdriver="opengl" elisiondigitsafter="100" plotoutput="terminal" helpbrowser="standard" rtablesize="10" elisiontermsbefore="100" elisiondigitsthreshold="10000" typesetting="standard" plotdevice="inline" verboseproc="1" showassumed="1" errorcursor="false" longdelim="true" plotoptions="" quiet="false" elisiontermsafter="100" screenwidth="79" preplot="" prettyprint="3" displayprecision="-1" screenpixelheight="480" warnlevel="3" screenheight="25" latexwidth="6.0" postplot="" prompt="> " ShowLabels="true"/> +<Styles><Font name="Ordered List 1" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Annotation Text" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Ordered List 2" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Ordered List 3" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Ordered List 4" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Ordered List 5" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Author" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Annotation Title" background="[255,255,255]" bold="true" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="18" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Warning" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[0,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Caption Reference" background="[255,255,255]" bold="true" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Maple Input Placeholder" background="[255,255,255]" bold="true" executable="true" family="Courier New" foreground="[200,0,200]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="true"/> +<Font name="Maple Plot" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Code" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[255,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Line Printed Output" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[0,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Text Output" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[0,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Diagnostic" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[40,120,40]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="2D Inert Output" background="[255,255,255]" bold="false" executable="true" family="Times New Roman" foreground="[144,144,144]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Normal" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Hyperlink" background="[255,255,255]" bold="false" executable="false" family="Times New Roma" foreground="[0,128,128]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="true" placeholder="false"/> +<Font name="Maple Output" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Dash Item" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="2D Math" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Maple Input" background="[255,255,255]" bold="true" executable="true" family="Courier New" foreground="[255,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="2D Output" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="2D Input" background="[255,255,255]" bold="false" executable="true" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="HyperlinkError" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[255,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="true" placeholder="false"/> +<Font name="Header and Footer" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="10" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Error" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[255,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Title" background="[255,255,255]" bold="true" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="18" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Heading 1" background="[255,255,255]" bold="true" executable="false" family="Times New Roma" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="18" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Text" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Bullet Item" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Heading 4" background="[255,255,255]" bold="false" executable="false" family="Times New Roma" foreground="[0,0,0]" italic="true" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Equation Label" background="[255,255,255]" bold="true" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Heading 3" background="[255,255,255]" bold="true" executable="false" family="Times New Roma" foreground="[0,0,0]" italic="true" opaque="false" readonly="false" size="14" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="Heading 2" background="[255,255,255]" bold="true" executable="false" family="Times New Roma" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="16" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="HyperlinkWarning" background="[255,255,255]" bold="false" executable="false" family="Courier New" foreground="[0,0,255]" italic="false" opaque="false" readonly="true" size="12" subscript="false" superscript="false" underline="true" placeholder="false"/> +<Font name="Dictionary Hyperlink" background="[255,255,255]" bold="false" executable="false" family="Times New Roma" foreground="[147,0,15]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="true" placeholder="false"/> +<Font name="Caption Text" background="[255,255,255]" bold="true" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Font name="List Item" background="[255,255,255]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" opaque="false" readonly="false" size="12" subscript="false" superscript="false" underline="false" placeholder="false"/> +<Layout name="Ordered List 1" alignment="left" bullet="numeric" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="-1" bulletsuffix=""/> +<Layout name="Ordered List 2" alignment="left" bullet="alphabetic" firstindent="0" leftmargin="36" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="-1" bulletsuffix=""/> +<Layout name="Ordered List 3" alignment="left" bullet="roman" firstindent="0" leftmargin="72" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="-1" bulletsuffix=""/> +<Layout name="Ordered List 4" alignment="left" bullet="ALPHABETIC" firstindent="0" leftmargin="108" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="-1" bulletsuffix=""/> +<Layout name="Ordered List 5" alignment="left" bullet="ROMAN" firstindent="0" leftmargin="144" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="-1" bulletsuffix=""/> +<Layout name="Author" alignment="centred" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="8" spacebelow="8" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Warning" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Annotation Title" alignment="centred" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="12" spacebelow="12" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Maple Plot" alignment="centred" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Line Printed Output" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="any" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Text Output" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="newline" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Diagnostic" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="any" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Normal" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Maple Output" alignment="centred" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.3" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Dash Item" alignment="left" bullet="dash" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="HyperlinkError" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Error" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Title" alignment="centred" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="12" spacebelow="12" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Heading 1" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="8" spacebelow="4" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Bullet Item" alignment="left" bullet="dot" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Heading 4" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Heading 3" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="Heading 2" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="8" spacebelow="2" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="HyperlinkWarning" alignment="left" bullet="none" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="0" spacebelow="0" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Layout name="List Item" alignment="left" bullet="indent" firstindent="0" leftmargin="0" rightmargin="0" linespacing="0.0" spaceabove="3" spacebelow="3" linebreak="space" pagebreak-before="false" initial="0" bulletsuffix=""/> +<Pencil-style name="Pencil 5" pen-color="[255,0,0]" pen-height="5.0" pen-width="5.0" pen-opacity="1.0"/> +<Pencil-style name="Pencil 4" pen-color="[0,0,255]" pen-height="3.0" pen-width="3.0" pen-opacity="1.0"/> +<Pencil-style name="Pencil 3" pen-color="[0,0,0]" pen-height="3.0" pen-width="3.0" pen-opacity="1.0"/> +<Pencil-style name="Pencil 2" pen-color="[0,0,255]" pen-height="1.0" pen-width="1.0" pen-opacity="1.0"/> +<Pencil-style name="Pencil 1" pen-color="[0,0,0]" pen-height="1.0" pen-width="1.0" pen-opacity="1.0"/> +<Highlighter-style name="Highlighter 2" pen-color="[255,204,0]" pen-height="14.0" pen-width="14.0" pen-opacity="0.8"/> +<Highlighter-style name="Highlighter 1" pen-color="[255,153,255]" pen-height="12.0" pen-width="8.0" pen-opacity="0.8"/> +<Highlighter-style name="Highlighter 4" pen-color="[0,255,255]" pen-height="32.0" pen-width="32.0" pen-opacity="0.8"/> +<Highlighter-style name="Highlighter 3" pen-color="[51,255,0]" pen-height="24.0" pen-width="24.0" pen-opacity="0.8"/> +<Highlighter-style name="Highlighter 5" pen-color="[255,255,0]" pen-height="48.0" pen-width="48.0" pen-opacity="0.8"/> +</Styles> +<Task-table> + <Task-category name="<default>"> + </Task-category> +</Task-table> +<Task> +</Task><Presentation-Block> +<Group view="presentation" hide-input="false" hide-output="true" inline-output="false" labelreference="L1" drawlabel="true"> +<Input> +<Text-field style="Text" layout="Normal" alignment="centred">Hi there</Text-field> +</Input> +</Group></Presentation-Block><Presentation-Block> +<Group view="presentation" hide-input="false" hide-output="true" inline-output="false" labelreference="L2" drawlabel="true"> +<Input> +<Text-field style="Text" layout="Normal"></Text-field> +</Input> +</Group> +<Group view="code" labelreference="L6" drawlabel="true"> +<Input> +<Text-field prompt="> " style="Maple Input" layout="Normal">restart;</Text-field> +</Input> +</Group> +<Group view="code" labelreference="L7" drawlabel="true"> +<Input> +<Text-field prompt="> " style="Maple Input" layout="Normal">interface(prettyprint=0):</Text-field> +</Input> +</Group> +<Group view="code" labelreference="L3" drawlabel="true"> +<Input> +<Text-field prompt="> " style="Maple Input" layout="Normal">1;# <Font style="Text">one </Font><Font executable="false">+ </Font><Font style="Text">plus </Font><Font executable="false">2 </Font><Font style="Text">two</Font><Font executable="false"> ;</Font></Text-field> +</Input> +<Output> +<Text-field style="Line Printed Output" layout="Line Printed Output">1</Text-field> +</Output> +</Group> +<Group view="code" labelreference="L5" drawlabel="true"> +<Input> +<Text-field prompt="> " style="Maple Input" layout="Normal">3 + <Font italic="true">4</Font>;<Font bold="true" style="Text"> bold</Font></Text-field> +</Input> +<Output> +<Text-field style="Line Printed Output" layout="Line Printed Output">7</Text-field> +</Output> +</Group></Presentation-Block><Presentation-Block> +<Group view="presentation" hide-input="false" hide-output="true" inline-output="false" labelreference="L4" drawlabel="true"> +<Input> +<Text-field style="Text" layout="Normal"><Equation executable="false" style="2D Math" input-equation="" display="LUklbXJvd0c2Iy9JK21vZHVsZW5hbWVHNiJJLFR5cGVzZXR0aW5nR0koX3N5c2xpYkdGJzYkLUkjbWlHRiQ2I1EhRicvJSxtYXRodmFyaWFudEdRJ25vcm1hbEYn">JSFH</Equation></Text-field> +</Input> +</Group></Presentation-Block> +</Worksheet> \ No newline at end of file diff --git a/posts/Maple/mw2txt.py b/posts/Maple/mw2txt.py new file mode 100755 index 0000000..c19c3fe --- /dev/null +++ b/posts/Maple/mw2txt.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +# +# Copyright (C) 2011-2012 W. Trevor King <wking@drexel.edu> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/>. + +"""View Maple worksheets (.mw) from the command line (without X). + +./mw2txt.py -c input.mw | less +./mw2txt.py -m input.mw | /opt/maple15/bin/maple | less +""" + +import sys as _sys + +import lxml.etree as _lxml_etree + +try: + from pygments.console import colorize as _colorize +except ImportError, e: + _sys.stderr.write(str(e) + '\n') + def _write_color(string, color=None, stream=None): + if stream is None: + stream = _sys.stdout + stream.write(string) +else: + def _write_color(string, color=None, stream=None): + if color is None: + color = 'reset' + if stream is None: + stream = _sys.stdout + stream.write(_colorize(color_key=color, text=string)) + + +__version__ = '0.1' + + +class Writer (object): + def __init__(self, color=None, stream=None, use_color=False): + self.color = color + self.stream = stream + self.use_color = use_color + self.last_char = None + + def __call__(self, text, color=None): + if not self.use_color: + color = None + elif color is None: + color = self.color + if text == '\n' and self.last_char == '\n': + return # don't add lots of blank lines + _write_color(string=text, color=color, stream=self.stream) + self.last_char = text[-1] + + +def mw2txt(path, writer, filter_math=False): + xml = _lxml_etree.parse(path) + pruned_iteration( + root=xml.getroot(), + match=lambda node: node.tag == 'Text-field', + match_action=lambda node: top_text_node2txt( + node=node, writer=writer, filter_math=filter_math), + match_tail=lambda node:writer(text='\n')) + +def top_text_node2txt(node, writer, filter_math=False): + if filter_math: + match_action = None + else: + match_action = lambda node: other_in_text_node2txt( + node=node, writer=writer) + pruned_iteration( + root=node, + match=lambda node: node.tag not in ['Text-field', 'Font', 'Hyperlink'], + match_action=match_action, + other_action=lambda node: text_node2txt( + node=node, writer=writer, filter_math=filter_math), + match_tail=lambda node:tail_node2txt( + node=node, writer=writer, filter_math=filter_math), + other_tail=lambda node:tail_node2txt( + node=node, writer=writer, filter_math=filter_math)) + +def other_in_text_node2txt(node, writer): + if node.tag in ['Drawing-Root']: + # ignore missing content + pass + elif node.tag in ['Equation', 'Image', 'Plot']: + # warn about missing content + writer(text=node.tag, color='yellow') + else: + # warn about wierd tag + writer(text=node.tag, color='magenta') + +def text_node2txt(node, writer, filter_math=False): + if node.tag not in ['Text-field', 'Font', 'Hyperlink'] and not filter_math: + # warn about wierd tag + writer(text=node.tag, color='magenta') + write_text( + node=node, text=node.text, writer=writer, filter_math=filter_math) + +def tail_node2txt(node, writer, filter_math=False): + if node.tag != 'Text-field': + write_text( + node=node.getparent(), text=node.tail, writer=writer, + filter_math=filter_math) + +def write_text(node, text, writer, filter_math=False): + if not text: + return + style = node_style(node) + if filter_math: + if style == 'Maple Input': + writer(text=text) + return + prompt = node.get('prompt', None) + if prompt: + t = '\n'.join(prompt+line for line in text.splitlines()) + if text.endswith('\n'): + t += '\n' # '\n'.join('a\nb\n'.splitlines()) == 'a\nb' + if writer.last_char not in [None, '\n']: + t = t[len(prompt):] # no initial prompt + text = t + if style == 'Maple Input': + color = 'red' + else: + color = None + writer(text=text, color=color) + +def node_style(node): + p = node + while p is not None: + style = p.get('style', None) + if style: + return style + p = p.getparent() + return None + +def pruned_iteration(root, match, match_action=None, match_tail=None, + other_action=None, other_tail=None, debug=False): + if debug: + _write_color('start pruned iteration from %s\n' % root, color='blue') + line = [None] + stack = [root] + while len(stack) > 0: + node = stack.pop(0) + p = node.getparent() + while line[-1] != p: + n = line.pop() + if n is None: + break + _pruned_iteration_handle_tail( + node=n, match=match, match_tail=match_tail, + other_tail=other_tail, debug=debug) + line.append(node) + if debug: + color_node(node, color='cyan') + if match(node): + if match_action: + match_action(node) + else: + if other_action: + other_action(node) + stack = list(node.getchildren()) + stack + while len(line) > 0: + n = line.pop() + if n is None: + break + _pruned_iteration_handle_tail( + node=n, match=match, match_tail=match_tail, other_tail=other_tail, + debug=debug) + if debug: + _write_color('end pruned iteration from %s\n' % root, color='blue') + +def _pruned_iteration_handle_tail(node, match, match_tail, other_tail, + debug=False): + if debug: + color_node(node, color='magenta', tail=True) + if match(node): + if match_tail: + match_tail(node) + else: + if other_tail: + other_tail(node) + +def node_depth(node): + depth = 0 + p = node.getparent() + while p is not None: + depth += 1 + p = p.getparent() + return depth + +def color_node(node, color=None, tail=False): + depth = node_depth(node) + string = ' '*depth + node.tag + if tail: + string += ' tail' + _write_color(string + '\n', color) + + +if __name__ == '__main__': + from optparse import OptionParser as _OptionParser + + # don't wrap epilog paragraphs + class OptionParser (_OptionParser): + def format_epilog(self, formatter): + return self.epilog + + parser = OptionParser( + usage='%prog [options] input.mw', epilog='\n'+__doc__) + parser.add_option( + '-c', '--color', dest='color', action='store_true', + help='Use ANSI escape sequences to color output') + parser.add_option( + '-m', '--maple', dest='maple', action='store_true', + help='output text suitable for piping into `maple`') + + options,args = parser.parse_args() + path = args[0] + + filter_math = options.maple + writer = Writer(use_color=options.color) + if options.maple: + if options.color: + raise ValueError("maple doesn't understand ANSI color") + mw2txt(path=path, writer=writer, filter_math=filter_math)