Skip to content

Instantly share code, notes, and snippets.

@dunhamsteve
Last active December 15, 2015 14:29
Show Gist options
  • Save dunhamsteve/5274411 to your computer and use it in GitHub Desktop.
Save dunhamsteve/5274411 to your computer and use it in GitHub Desktop.
A little utility to convert a textual description of classes to a UML diagram (in dot format).
#!/usr/bin/python
# This code is public domain, share and enjoy.
import sys, re
rEdge = re.compile(r'(\w+)\s+([\w.*]*)\s*(--|->|<-|<->)\s*([\w.*]*)\s+(\w+)\s*')
rName = re.compile(r'\w+')
arrows = {
'--': ('none','none'),
'<-': ('open', 'none'),
'->': ('none', 'open'),
'<->': ('open', 'open')
}
def format(props):
rval = '['
for k,v in props.items():
rval += "%s=\"%s\" " % (k,v)
rval += ']'
return rval
def emit(current,fields):
if current:
label = ""
for field in fields:
label += field+"\l"
label = "{%s|%s}" % (current, label)
print current, format({'label': label})
if len(sys.argv) < 2:
print sys.argv[0], "converts simple-uml to dot graphs"
print "syntax:"
print """
Foo -> Bar
Bar * -- 1 Baz
Baz -- Fred
Baz --* Foo
Fred -> 1 Joe
Joe
- name : String
- potato : boolean
Fred
- name : String
- children : int
"""
sys.exit(1)
print "Graph G {\n node [ shape=\"record\" label=\"{\\N}\"]\n"
current = None
fields = []
for line in open(sys.argv[1]):
if line.startswith("#"):
continue
line = line.strip()
m = rEdge.match(line)
if m:
(left, leftLabel, arrow, rightLabel, right) = m.groups()
(arrowtail,arrowhead) = arrows[arrow]
props = {'arrowhead':arrowhead,'arrowtail':arrowtail}
if leftLabel:
props['taillabel'] = leftLabel
if rightLabel:
props['headlabel'] = rightLabel
print "%s -- %s %s\n" % (left, right, format(props))
continue
m = rName.match(line)
if m:
emit(current,fields)
current = m.group(0)
fields = []
continue
if line.startswith("- "):
fields.append(line)
emit(current,fields)
print "}\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment