Skip to content

Instantly share code, notes, and snippets.

@chris-morgan
Created December 13, 2011 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chris-morgan/1471691 to your computer and use it in GitHub Desktop.
Save chris-morgan/1471691 to your computer and use it in GitHub Desktop.
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
Copy link

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
Copy link
Author

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

@nikitakit
Copy link

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
Copy link

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
Copy link
Author

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

@nikitakit
Copy link

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