mdx_circuit.py 2.62 KB
Newer Older
1 2 3 4 5
#!/usr/bin/env python
'''
Image Circuit Extension for Python-Markdown
======================================

6 7 8 9 10 11 12 13 14 15

Any single line beginning with circuit-schematic: and followed by data (which should be json data, but this
is not enforced at this level) will be displayed as a circuit schematic. This is simply an input element with
the value set to the data. It is left to javascript on the page to render that input as a circuit schematic.

ex:
circuit-schematic:[["r",[128,48,0],{"r":"1","_json_":0},["2","1"]],["view",0,0,2,null,null,null,null,null,null,null],["dc",{"0":0,"1":1,"I(_3)":-1}]]

(This is a schematic with a single one-ohm resistor. Note that this data is not meant to be user-editable.)

16
'''
17 18
import markdown
import re
19

20
from django.utils.html import escape
21

22 23 24 25 26 27
try:
    # Markdown 2.1.0 changed from 2.0.3. We try importing the new version first,
    # but import the 2.0.3 version if it fails
    from markdown.util import etree
except:
    from markdown import etree
28

29

30 31
class CircuitExtension(markdown.Extension):
    def __init__(self, configs):
32
        for key, value in configs:
33
            self.setConfig(key, value)
34

35 36 37 38 39
    def extendMarkdown(self, md, md_globals):
        ## Because Markdown treats contigous lines as one block of text, it is hard to match
        ## a regex that must occupy the whole line (like the circuit regex). This is why we have
        ## a preprocessor that inspects the lines and replaces the matched lines with text that is
        ## easier to match
40 41
        md.preprocessors.add('circuit', CircuitPreprocessor(md), "_begin")

42
        pattern = CircuitLink(r'processed-schematic:(?P<data>.*?)processed-schematic-end')
43 44
        pattern.md = md
        pattern.ext = self
45 46 47 48 49
        md.inlinePatterns.add('circuit', pattern, "<reference")


class CircuitPreprocessor(markdown.preprocessors.Preprocessor):
    preRegex = re.compile(r'^circuit-schematic:(?P<data>.*)$')
50

51
    def run(self, lines):
52 53 54
        def convertLine(line):
            m = self.preRegex.match(line)
            if m:
55
                return 'processed-schematic:{0}processed-schematic-end'.format(m.group('data'))
56 57
            else:
                return line
58 59

        return [convertLine(line) for line in lines]
60

61 62 63

class CircuitLink(markdown.inlinepatterns.Pattern):
    def handleMatch(self, m):
64
        data = m.group('data')
65
        data = escape(data)
66
        return etree.fromstring("<div align='center'><input type='hidden' parts='' value='" + data + "' analyses='' class='schematic ctrls' width='640' height='480'/></div>")
67 68


69 70
def makeExtension(configs=None):
    to_return = CircuitExtension(configs=configs)
71
    print "circuit returning ", to_return
72
    return to_return