-
-
Save chris-morgan/1471691 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
import struct | |
def process_file(filename): | |
try: | |
f = open(filename, 'rb') | |
except IOError as e: | |
print >> sys.stderr, 'Unable to open %s: %s' % (filename, e) | |
return | |
with f: | |
height = emit_header(f) | |
layer = 'layer1' | |
timestamp = 0 | |
svg_element = '<g inkscape:groupmode="layer" id="%s">' % layer | |
while True: | |
tag = f.read(1) | |
if tag == '': | |
break | |
if ord(tag) > 128: | |
if tag == '\x90': | |
# Emit the current element and close the last layer | |
emit_element(svg_element) | |
emit_element('</g>') | |
# Start a new layer | |
layer = 'layer%d' % (ord(f.read(1)) + 1) | |
timestamp = 0 | |
svg_element = '<g inkscape:groupmode="layer" id="%s">' % layer | |
elif tag == '\x88': | |
# Read the timestamp next | |
timestamp += ord(f.read(1)) * 20 | |
else: | |
# Emit the current svg element | |
emit_element(svg_element) | |
coords = [] | |
# Pen down | |
while True: | |
coords.append(read_point(f, height)) | |
if ord(f.read(1)) >= 128: | |
break | |
f.seek(-1, 1) # It wasn't the magic value, don't miss it | |
# Pen up | |
coords.append(read_point(f, height)) | |
points = ' '.join(','.join(map(str, e)) for e in coords) | |
svg_element = '<polyline points="%s" dm:timestamp="%s" />' % (points, timestamp) | |
else: | |
print >> sys.stderr, 'Unsupported tag: %s\n' % tag | |
# Emit the footer to finish it off | |
print '\n</svg>\n' | |
def read_point(f, ymax): | |
x1, x2, y1, y2 = map(ord, f.read(4)) | |
x = x1 | x2 << 7 | |
y = y1 | y2 << 7 | |
return x, ymax - y | |
def emit_header(f): | |
id, version, width, height, page_type = struct.unpack('<32sBHHBxx', f.read(40)) | |
print ''' | |
<svg viewBox="0 0 %(width)s %(height)s" fill="none" stroke="black" stroke-width="10" stroke-linecap="round" stroke-linejoin="round" | |
xmlns="http://www.w3.org/2000/svg" | |
xmlns:svg="http://www.w3.org/2000/svg" | |
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |
xmlns:dm="http://github.com/nikitakit/DM2SVG"> | |
<metadata> | |
<dm:page | |
id="%(id)s" | |
version="%(version)s" | |
width="%(width)s" | |
height="%(height)s" | |
page_type="%(page_type)s"> | |
</dm:page> | |
</metadata> | |
<rect width="%(width)s" height="%(height)s" fill="aliceblue"/> | |
''' % locals() | |
return height | |
def emit_element(message): | |
if message: | |
print '%s\n' % message | |
if __name__ == '__main__': | |
import sys | |
if len(sys.argv) == 2: | |
process_file(sys.argv[1]) | |
else: | |
print >>sys.stderr, 'Usage: %s <dhw-file>' % sys.argv[0] |
@nikitakit: whoops, replace all the occurrences of push
with append
.
Traceback (most recent call last):
File "dm2svg.py", line 104, in
process_file(sys.argv[1])
File "dm2svg.py", line 53, in process_file
points = ' '.join(','.join(e) for e in coords)
File "dm2svg.py", line 53, in
points = ' '.join(','.join(e) for e in coords)
TypeError: sequence item 0: expected string, int found
Replacing e with str(e) doesn't help much, I get something like
points=(,2,1,7,9,,, ,7,8,9,3,) (,2,1,8,0,,, ,7,8,9,6,) (,2,1,8,2,,, ,7,8,9,9,) (,2,1,8,5,,, ,7,9,0,2,) (,2,1,8,9,,, ,7,9,0,4,) (,2,1,9,1,,, ,7,9,0,7,) (,2,1,9,5,,, ,7,9,1,2,) (,2,1,9,9,,, ,7,9,1,8,) (,2,2,0,4,,, ,7,9,2,5,) (,2,2,0,9,,, ,7,9,3,5,) (,2,2,1,4,,, ,7,9,4,5,) (,2,2,1,8,,, ,7,9,5,6,) (,2,2,2,1,,, ,7,9,7,0,) (,2,2,2,2,,, ,7,9,8,3,) (,2,2,2,4,,, ,7,9,9,4,) (,2,2,2,4,,, ,8,0,0,3,) (,2,2,2,2,,, ,8,0,1,1,) (,2,2,2,0,,, ,8,0,1,9,) (,2,2,1,8,,, ,8,0,2,7,) (,2,2,1,4,,, ,8,0,3,5,) (,2,2,1,1,,, ,8,0,4,3,) (,2,2,0,7,,, ,8,0,4,9,) (,2,2,0,5,,, ,8,0,5,2,) (,2,2,0,3,,, ,8,0,5,6,) (,2,2,0,1,,, ,8,0,5,9,) (,2,1,7,9,,, ,8,0,5,8,)
@nikitakit: yep, that's what I just came up with... all fixed now.
Looks good! Thank you! I'll comment if problems show up with any of my other files, though I think at this point I should be able to fix any problems myself.
Traceback (most recent call last):
File "dm2svg.py", line 104, in
process_file(sys.argv[1])
File "dm2svg.py", line 46, in process_file
coords.push(read_point(f, height))
AttributeError: 'list' object has no attribute 'push'