from xml.dom.minidom import parse import re import subprocess as sp source = "./ink-bug.svg" tmp_svg = "./tmp4738233729506.svg" output_path = "./output/" special_name_re = re.compile("\s*\$exp\s*:\s*(.+)") def generate_svg (filename, node): b = """ image/svg+xml """ e = """ """ f = open(filename, "w") f.write(b + node.toxml() + e) return f.close() def find_figure_node (nodes): return next(node for node in nodes if not(node.nodeName in ["text", "#text"])) class InkComm: def __init__(self): "Open unbuffered pipe to Inkscape shell in text mode" self.p = sp.Popen(['inkscape', '--shell'], bufsize=0, universal_newlines=True, stdin=sp.PIPE, stdout=sp.PIPE) self.read() def read(self): "Read from open Inkscape shell till '>' occur" rv = '' while True: r = self.p.stdout.read(1) if r == '>': break rv += r return rv def write(self, words_of_wisdom): "Write data and newline char" return self.p.stdin.write(words_of_wisdom + '\n') def close(self): "Guess what this method does" stdout, stderr = self.p.communicate('quit\n') return self.p.returncode, stdout, stderr def get_svg_geometry (self, svgfile): "Returns list contains [x, y, width, height] of svg" self.write("-S " + svgfile) s = self.read().splitlines()[0] return map(float,s.split(',')[1:]) def export_svg_area_in_png (self, svg, pngout, svgarea, width=None, height=None): com = svg com += " --export-png={0}".format(pngout) com += " --export-area-snap" com += " --export-area={0}".format(':'.join(map(str,svgarea))) com += " --export-background='#ffffff'" if height: com += " --export-height={0}".format(height) if width: com += " --export-width={0}".format(width) self.write(com) self.read() return(pngout) fig_table = {"star-01":{'y':590}, "star-02":{'y':368}, "star-03":{'y':210}, "star-04":{'y':0}, "star-05":{'y':-212}, "star-06":{'y':-445}, "star-07":{'y':-664}, "star-08":{'y':-865}, "star-09":{'y':-1110}, "star-10":{'y':-1325}, } def expand_area (x,y,w,h): rd = .3 dx = w*rd x1 = x - dx x2 = x + w + dx y1 = y y2 = y + 1.5*h return x1,y1,x2,y2 ink_proc = InkComm() def test_raster(svg, yopts, of): x, y, w, h = ink_proc.get_svg_geometry(tmp_svg) real_y = yopts['y'] # real_y = 886.154 - y print "{:s} {:f} {:f}".format(of, y, real_y) real_h = yopts.get('h') or h ink_proc.export_svg_area_in_png(svg, of, expand_area(x, real_y, w, real_h), width = 150) def gen_rfiles (xmlfile): xml = parse(xmlfile) text_elements = xml.getElementsByTagName("text") for text_element in text_elements: x = text_element.firstChild if x.hasChildNodes(): t = x.firstChild.nodeValue m = special_name_re.match(t) if m: nam = m.group(1).strip() yopts = fig_table.get(nam) if yopts: figure = find_figure_node(text_element.parentNode.childNodes) generate_svg(tmp_svg, figure) test_raster(tmp_svg, yopts, output_path + nam + '.png') gen_rfiles(source) ink_proc.close()