Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Quick dm2svg port from perl to python (even less warranty than the perl version as it's not untested)
#!/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

This comment has been minimized.

Copy link

commented Dec 13, 2011

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'

@chris-morgan

This comment has been minimized.

Copy link
Owner Author

commented Dec 13, 2011

@nikitakit: whoops, replace all the occurrences of push with append.

@nikitakit

This comment has been minimized.

Copy link

commented Dec 13, 2011

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

@nikitakit

This comment has been minimized.

Copy link

commented Dec 13, 2011

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,)

@chris-morgan

This comment has been minimized.

Copy link
Owner Author

commented Dec 13, 2011

@nikitakit: yep, that's what I just came up with... all fixed now.

@nikitakit

This comment has been minimized.

Copy link

commented Dec 13, 2011

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.