Passed
Push — master ( ab513a...1713a6 )
by Peter
05:21 queued 03:17
created

tikz_builder.svg2pgf_shape()   B

Complexity

Conditions 6

Size

Total Lines 55
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 29
nop 1
dl 0
loc 55
rs 7.8834
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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