1#!/usr/local/bin/python
2
3"""
4This script converts a subset of SVG into an HTML imagemap
5
6Note *subset*.  It only handles <path> elements, for which it only pays
7attention to the M and L commands.  Futher, it only notices the "translate"
8transform.
9
10It was written to generate the examples in the documentation for maphilight,
11and thus is very squarely aimed at handling several SVG maps from wikipedia.
12It *assumes* that all the <path>s it will need are inside a <g>.  Any <path>
13outside of a <g> will be ignored.
14
15It takes several possible arguments, in the form:
16$ svn2imagemap.py FILENAME [x y [group1 group2 ... groupN]]
17
18FILENAME must be the name of an SVG file.  All other arguments are optional.
19
20x and y, if present, are the dimensions of the image you'll be creating from
21the SVG.  If not present, it assumes the values of the width and height
22attributes in the SVG file.
23
24group1 through groupN are group ids.  If only want particular groups used,
25enter their ids here and all others will be ignored.
26"""
27
28import os
29import re
30import sys
31import xml.dom.minidom
32
33import parse_path
34
35if len(sys.argv) == 1:
36    sys.exit("svn2imagemap.py FILENAME [x y [group1 group2 ... groupN]]")
37if not os.path.exists(sys.argv[1]):
38    sys.exit("Input file does not exist")
39x, y, groups = None, None, None
40if len(sys.argv) >= 3:
41    x = float(sys.argv[2])
42    y = float(sys.argv[3])
43    if len(sys.argv) > 3:
44        groups = sys.argv[4:]
45
46svg_file = xml.dom.minidom.parse(sys.argv[1])
47svg = svg_file.getElementsByTagName('svg')[0]
48
49raw_width = float(svg.getAttribute('width'))
50raw_height = float(svg.getAttribute('height'))
51width_ratio = x and (x / raw_width) or 1
52height_ratio = y and (y / raw_height) or 1
53
54if groups:
55    elements = [g for g in svg.getElementsByTagName('g') if (g.hasAttribute('id') and g.getAttribute('id') in groups)]
56    elements.extend([p for p in svg.getElementsByTagName('path') if (p.hasAttribute('id') and p.getAttribute('id') in groups)])
57else:
58    elements = svg.getElementsByTagName('g')
59
60parsed_groups = {}
61for e in elements:
62    paths = []
63    if e.nodeName == 'g':
64        for path in e.getElementsByTagName('path'):
65            points = parse_path.get_points(path.getAttribute('d'))
66            for pointset in points:
67                paths.append([path.getAttribute('id'), pointset])
68    else:
69        points = parse_path.get_points(e.getAttribute('d'))
70        for pointset in points:
71            paths.append([e.getAttribute('id'), pointset])
72    if e.hasAttribute('transform'):
73        print e.getAttribute('id'), e.getAttribute('transform')
74        for transform in re.findall(r'(\w+)\((-?\d+.?\d*),(-?\d+.?\d*)\)', e.getAttribute('transform')):
75            if transform[0] == 'translate':
76                x_shift = float(transform[1])
77                y_shift = float(transform[2])
78                for path in paths:
79                    path[1] = [(p[0] + x_shift, p[1] + y_shift) for p in path[1]]
80
81    parsed_groups[e.getAttribute('id')] = paths
82
83out = []
84for g in parsed_groups:
85    for path in parsed_groups[g]:
86        out.append('<area href="#" title="%s" shape="poly" coords="%s"></area>' %
87            (path[0], ', '.join([("%d,%d" % (p[0]*width_ratio, p[1]*height_ratio)) for p in path[1]])))
88
89outfile = open(sys.argv[1].replace('.svg', '.html'), 'w')
90outfile.write('\n'.join(out))