tikz_builder.createTikzLib()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 13
rs 9.8
c 0
b 0
f 0
cc 1
nop 3
1
from SCons.Script import *
2
3
from xml.dom.minidom import parse as parseXml
4
5
6
def svg2pgf_shape(filename):
7
    '''
8
        Convert given SVG file to TiKZ code.
9
    '''
10
    xml = parseXml(filename)
11
    # determine size of the picture from SVG source
12
    svg = xml.getElementsByTagName('svg')[0]
13
    name = svg.attributes['id'].value
14
    height = int(svg.attributes['height'].value)
15
    width = int(svg.attributes['width'].value)
16
    # Define shape anchors, based on image size
17
    # We need double backslashes since the output is Python again
18
    # The SVG coordinate system is mirrored on the horizon axis, so we add a rotation command and a positional compensation
19
    result = '''
20
\\\\pgfdeclareshape{%(name)s}{
21
    \\\\anchor{center}{\pgfpoint{%(halfwidth)u}{%(halfheight)u}}
22
    \\\\anchor{north}{\pgfpoint{%(halfwidth)u}{%(height)u}}
23
    \\\\anchor{south}{\pgfpoint{%(halfwidth)u}{0}}
24
    \\\\anchor{west}{\pgfpoint{0}{%(halfheight)u}}
25
    \\\\anchor{east}{\pgfpoint{%(width)u}{%(halfheight)u}}
26
    \\\\foregroundpath{
27
        \\\\pgfsetlinewidth{1.4}
28
        \\\\pgftransformshift{\pgfpoint{%(width)u}{%(height)u}}
29
        \\\\pgftransformrotate{180}
30
        \\\\pgfsetfillcolor{white}
31
''' % {'name': name, 'height': height, 'halfheight': height / 2, 'width': width, 'halfwidth': width / 2}
32
    # add all SVG path
33
    pathCommands = xml.getElementsByTagName('path')
34
    for p in pathCommands:
35
        # The path may have styling. We ignore everything but dashing.
36
        if p.attributes.has_key('style'):
37
            if 'stroke-dasharray' in p.attributes['style'].value:
38
                # http://stuff.mit.edu/afs/athena/contrib/tex-contrib/beamer/pgf-1.01/doc/generic/pgf/version-for-tex4ht/en/pgfmanualse23.html
39
                result += "        \\\\pgfsetdash{{4.2}{1.4}}{0}\n"
40
        # Add the SVG path
41
        result += "        \\\\pgfpathsvg{%s}\n" % p.attributes['d'].value
42
    # add all SVG rectangle definitions
43
    # Add usepath after each rectangle, in order to get overlayed filled rects correctly generated
44
    rectCommands = xml.getElementsByTagName('rect')
45
    for r in rectCommands:
46
        rheight = float(r.attributes['height'].value)
47
        rwidth = float(r.attributes['width'].value)
48
        x = float(r.attributes['x'].value)
49
        y = float(r.attributes['y'].value)
50
        result += "        \\\\pgfrect{\pgfpoint{%f}{%f}}{\pgfpoint{%f}{%f}}\n\\\\pgfusepath{stroke, fill}\n" % (
51
            x, y, rwidth, rheight)
52
    # add all SVG circle definitions
53
    circleCommands = xml.getElementsByTagName('circle')
54
    for c in circleCommands:
55
        x = float(c.attributes['cx'].value)
56
        y = float(c.attributes['cy'].value)
57
        radius = float(c.attributes['r'].value)
58
        result += "        \\\\pgfcircle{\pgfpoint{%f}{%f}}{%f}\n\\\\pgfusepath{stroke, fill}\n" % (
59
            x, y, radius)
60
    # finalize TiKZ shape definition
61
    result += '        \\\\pgfusepath{stroke}\n}}'
62
    return result
63
64
65
def build_shape_lib_recursive(sources, covered=[]):
66
    '''
67
        Build static LaTex representation for our graphical symbols as TiKZ shapes.
68
        Some SVGs occur multiple times in subdirectories, so we track the already
69
        converted ones.
70
    '''
71
    result = ''
72
    for f in sources:
73
        try:
74
            result += svg2pgf_shape(str(f))
75
            print "Converting %s to TiKZ shape ..." % f
76
        except Exception, e:
77
            print "Error on parsing, ignoring %s ..." % f
78
            print e
79
    return result
80
81
82
def createTikzLib(target, source, env):
83
    '''Builds TiKZ shape library needed for Latex export / rendedering server.'''
84
    print "Generating TiKZ shape library ..."
85
    f = open(str(target[0]), "w")
86
    f.write("# Auto-generated, do not change !\n")
87
    f.write("tikz_shapes='''")
88
    f.write(
89
        "\n%% Start of shape library. This part remains the same for all graph exports.")
90
    f.write(build_shape_lib_recursive(source))
91
    f.write(
92
        "\n%% End of shape library. This part below is unique for all graph exports.\n")
93
    f.write("'''")
94
    f.close()
95
96
97
tikzbuilder = Builder(action=createTikzLib)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable Builder does not seem to be defined.
Loading history...
98