17 |
|
|
18 |
import os.path |
import os.path |
19 |
import docutils.parsers.rst.directives, docutils.nodes, docutils.core |
import docutils.parsers.rst.directives, docutils.nodes, docutils.core |
20 |
import umltool |
import umltool, mputils |
21 |
|
|
22 |
umltool.settings['tmpdir'] = 'doc/uml' |
def __rst_init__(): |
23 |
|
""" |
24 |
#Environmental variable MPINPUTS should be relative to tmpdir, |
Initializes Docutils Directives. |
25 |
#or be an absolute path. |
""" |
26 |
os.putenv("MPINPUTS", "../../metacode") |
uml_directive.arguments = (1, 0, 0) |
27 |
|
uml_directive.options = {} |
28 |
#TEXFMOUTPUT should change the output directory of metapost, but it didn't |
uml_directive.content = 1 |
29 |
#seem to do that. Instead of this, metapost is currently run in tmpdir. |
|
30 |
#os.putenv("TEXMFOUTPUT", umltool.settings['tmpdir']) |
docutils.parsers.rst.directives._directives['uml'] = uml_directive |
31 |
|
|
32 |
|
uml_refer_directive.arguments = (1, 0, 0) |
33 |
|
uml_refer_directive.options = {} |
34 |
|
uml_refer_directive.content = 0 |
35 |
|
|
36 |
|
docutils.parsers.rst.directives._directives['uml-refer'] = uml_refer_directive |
37 |
|
|
38 |
def uml_directive(name, arguments, options, content, lineno, |
def uml_directive(name, arguments, options, content, lineno, |
39 |
content_offset, block_text, state, state_machine): |
content_offset, block_text, state, state_machine): |
40 |
""" |
""" |
44 |
reST document tree. |
reST document tree. |
45 |
""" |
""" |
46 |
attributes = {'name': arguments[0]} |
attributes = {'name': arguments[0]} |
47 |
|
uml_node = docutils.nodes.comment('', 'UML:'+attributes['name']) |
48 |
if content: |
if content: |
|
uml_node = docutils.nodes.comment('', 'UML:'+attributes['name']) |
|
49 |
|
|
50 |
#splits content into uml and mp parts |
#splits content into uml and mp parts |
51 |
files = ['', ''] |
files = ['', ''] |
60 |
temp += line + "\n" |
temp += line + "\n" |
61 |
files[current] = temp |
files[current] = temp |
62 |
|
|
63 |
# XXX fatal error if diagram with the same name already exists |
# XXX fatal error should be made if diagram with the same name |
64 |
# Anyway, this needs more thinking. This check should be global, |
# already exists Anyway, this needs more thinking. |
65 |
|
# This check should be global, |
66 |
# but following asserts would need to make clean tmpdir before |
# but following asserts would need to make clean tmpdir before |
67 |
# every remake... |
# every remake... |
68 |
# assert not os.path.isfile(umltool.settings['tmpdir']+"/"\ |
|
|
# +attributes['name']+".gen.uml"), "file "\ |
|
|
# +attributes['name']+".gen.uml already exists" |
|
|
# assert not os.path.isfile(umltool.settings['tmpdir']+"/"\ |
|
|
# +attributes['name']+".uml") |
|
|
|
|
69 |
#writes uml and mp sourcefiles and converts them into png and html |
#writes uml and mp sourcefiles and converts them into png and html |
70 |
uml = open(umltool.settings['tmpdir']+"/"+attributes['name']+".gen.uml", "w") |
|
71 |
mp = open(umltool.settings['tmpdir']+"/"+attributes['name']+".gen.mp", "w") |
uml = open(mputils._slashify(mputils.settings['tmpdir'])\ |
72 |
|
+attributes['name']+".gen.uml", "w") |
73 |
uml.write(files[0]) |
uml.write(files[0]) |
|
mp.write(files[1]) |
|
74 |
uml.close() |
uml.close() |
75 |
|
|
76 |
|
mp = open(mputils._slashify(mputils.settings['tmpdir'])\ |
77 |
|
+attributes['name']+".gen.mp", "w") |
78 |
|
mp.write(files[1]) |
79 |
mp.close() |
mp.close() |
80 |
|
|
81 |
return [uml_node] |
add_refer_context(attributes['name'], 1) |
82 |
|
|
83 |
uml_directive.arguments = (1, 0, 0) |
return [uml_node] |
|
uml_directive.options = {} |
|
|
uml_directive.content = 1 |
|
84 |
|
|
|
docutils.parsers.rst.directives._directives['uml'] = uml_directive |
|
85 |
|
|
86 |
|
def add_refer_context(name, top = 0): |
87 |
|
if umltool.settings.has_key('context'): |
88 |
|
if (os.path.isfile(mputils._slashify(mputils.settings['tmpdir'])\ |
89 |
|
+name+".gen.refers")): |
90 |
|
old_refers = open(mputils._slashify(mputils.settings['tmpdir'])\ |
91 |
|
+name+".gen.refers", "r").read() |
92 |
|
if old_refers.find(umltool.settings['context']) == -1: |
93 |
|
if top: |
94 |
|
refers = open(mputils._slashify(mputils.settings['tmpdir'])\ |
95 |
|
+name+".gen.refers", "w") |
96 |
|
refers.write(umltool.settings['context']+"\n"+old_refers) |
97 |
|
refers.close() |
98 |
|
else: |
99 |
|
refers = open(mputils._slashify(mputils.settings['tmpdir'])\ |
100 |
|
+name+".gen.refers", "a") |
101 |
|
refers.write(umltool.settings['context']+"\n") |
102 |
|
refers.close() |
103 |
|
else: |
104 |
|
refers = open(mputils._slashify(mputils.settings['tmpdir'])\ |
105 |
|
+name+".gen.refers", "a") |
106 |
|
refers.write(umltool.settings['context']+"\n") |
107 |
|
refers.close() |
108 |
|
|
109 |
def uml_refer_directive(name, arguments, options, content, lineno, |
def uml_refer_directive(name, arguments, options, content, lineno, |
110 |
content_offset, block_text, state, state_machine): |
content_offset, block_text, state, state_machine): |
111 |
""" |
""" |
112 |
Adds a comment node "<!-- UML: foo -->" into reST document tree. |
Adds a comment node "<!-- UML: foo -->" into reST document tree. |
113 |
Excepts that diagram foo exists or is later generated from some |
Excepts that diagram foo exists or is later generated from some |
115 |
""" |
""" |
116 |
attributes = {'name': arguments[0]} |
attributes = {'name': arguments[0]} |
117 |
uml_node = docutils.nodes.comment('', 'UML:'+attributes['name']) |
uml_node = docutils.nodes.comment('', 'UML:'+attributes['name']) |
118 |
|
add_refer_context(attributes['name']) |
|
return [uml_node] |
|
|
|
|
|
uml_refer_directive.arguments = (1, 0, 0) |
|
|
uml_refer_directive.options = {} |
|
|
uml_refer_directive.content = 0 |
|
119 |
|
|
120 |
docutils.parsers.rst.directives._directives['uml-refer'] = uml_refer_directive |
return [uml_node] |
121 |
|
|
122 |
def create_diagram(diagram_orig, diagram_dest="", scale=1.0): |
def create_diagram(diagram_orig, diagram_dest="", scale=1.0): |
123 |
return (umltool.run(diagram_orig, diagram_dest, scale)) |
return (umltool.run(diagram_orig, diagram_dest, scale)) |
124 |
|
|
125 |
def embed_diagram(path): |
def embed_diagrams(path): |
126 |
if not umltool.settings.has_key('to_root'): |
umltool.set_transition_paths(path) |
|
umltool.set_to_root(path) |
|
127 |
|
|
128 |
#the second pass - adds uml into html |
#the second pass - adds uml into html |
129 |
if path.endswith(".rst"): path = path[0:len(path)-4] |
if path.endswith(".rst"): path = path[0:len(path)-4] |
137 |
|
|
138 |
#This should work also with non-generated UML-diagrams. Checks first |
#This should work also with non-generated UML-diagrams. Checks first |
139 |
#for generated and then if non-generated diagram exists. |
#for generated and then if non-generated diagram exists. |
140 |
if (os.path.isfile(umltool.settings['tmpdir']+"/"+name+".gen.uml")): |
if (os.path.isfile(mputils._slashify(mputils.settings['tmpdir'])\ |
141 |
|
+name+".gen.uml")): |
142 |
prefix = name + ".gen" |
prefix = name + ".gen" |
143 |
else: prefix = name |
else: prefix = name |
|
assert (os.path.isfile(umltool.settings['tmpdir']+"/"+prefix+".uml")\ |
|
|
and os.path.isfile(umltool.settings['tmpdir']+"/"+prefix+".mp")),\ |
|
|
"file "+ prefix+".uml or "+prefix+".mp not found" |
|
144 |
print "Embedding %s into %s" % (prefix, path) |
print "Embedding %s into %s" % (prefix, path) |
145 |
|
|
146 |
implicit_targets = create_diagram(prefix) |
context_name = name+"_"+path.replace("/","_") |
147 |
|
if context_name.endswith(".gen"): |
148 |
|
context_name = context_name[0:len(context_name)-4] |
149 |
|
implicit_targets = create_diagram(prefix, context_name, 1.0) |
150 |
for target in implicit_targets: |
for target in implicit_targets: |
151 |
embed_implicit(path, name, target) |
embed_implicit(path, name, target) |
152 |
|
|
|
assert (os.path.isfile(umltool.settings['tmpdir']+"/"+name+".gen.html")\ |
|
|
and os.path.isfile(umltool.settings['tmpdir']+"/"+name+".gen.png")),\ |
|
|
"file "+name+".gen.html or "+name+".gen.png not found" |
|
|
|
|
153 |
#Cut&Pastes imagemap into html |
#Cut&Pastes imagemap into html |
154 |
imgmap = open(umltool.settings['tmpdir']+"/"+name+".gen.html").read() |
imgmap = open(mputils.settings['tmpdir']+"/"+context_name+".gen.html").read() |
155 |
out.write("<map id=\""+name+"\" name=\""+name+"\">\n") |
out.write("<map id=\""+name+"\" name=\""+name+"\">\n") |
156 |
out.write(imgmap[imgmap.find('>',imgmap.find('<map'))+1:\ |
out.write(imgmap[imgmap.find('>',imgmap.find('<map'))+1:\ |
157 |
imgmap.find('</map>')]) |
imgmap.find('</map>')]) |
158 |
out.write("</map>\n") |
out.write("</map>\n") |
159 |
out.write("<img src=\""+umltool.settings['to_tmpdir']+"/"+name+".gen.png"\ |
|
160 |
+"\" usemap=\"#"+name+"\" alt=\""+name+"\" />") |
out.write("<div class=\"uml-explicit\">\n") |
161 |
|
if (os.path.isfile(mputils._slashify(mputils.settings['tmpdir'])\ |
162 |
|
+name+".gen.refers")): |
163 |
|
refers = open(mputils._slashify(mputils.settings['tmpdir'])\ |
164 |
|
+name+".gen.refers").readlines() |
165 |
|
out.write("<strong>"+name+"</strong>: \n") |
166 |
|
for refer in refers: |
167 |
|
out.write("[<a href=\""\ |
168 |
|
+mputils.transition_path(path, refer.replace(".rst", ".gen.html")).replace("\n","")\ |
169 |
|
+"#"+name+"\">"+refer.split("/")[-1].split(".")[0]+"</a>]\n") |
170 |
|
out.write("<br/>\n") |
171 |
|
out.write("<a id=\""+name+"\"></a>\n") |
172 |
|
out.write("<img src=\""+mputils._slashify(mputils.settings['to_tmpdir'])\ |
173 |
|
+context_name+".gen.png"\ |
174 |
|
+"\" usemap=\"#"+name+"\" alt=\""+name+"\" />\n") |
175 |
|
out.write("</div>\n") |
176 |
html = html[html.find("-->", insert)+3:len(html)] |
html = html[html.find("-->", insert)+3:len(html)] |
177 |
insert = html.find("<!-- UML:") |
insert = html.find("<!-- UML:") |
178 |
out.write(html) |
out.write(html) |
193 |
if slash != -1: |
if slash != -1: |
194 |
path = (oldpath[0:slash+1] + path).replace("//", "/") |
path = (oldpath[0:slash+1] + path).replace("//", "/") |
195 |
|
|
196 |
tmp = umltool.settings.copy() |
umltool_backup = umltool.settings.copy() |
197 |
umltool.set_to_root(path) |
mputils_backup = mputils.settings.copy() |
198 |
|
|
199 |
|
umltool.set_transition_paths(path) |
200 |
slash = oldpath.rfind("/") |
slash = oldpath.rfind("/") |
201 |
if slash != -1: |
if slash != -1: |
202 |
umltool.settings['to_context'] = umltool.merge_paths(path, oldpath[0:slash]) |
umltool.settings['to_context'] = mputils.transition_path(path, oldpath[0:slash]) |
203 |
else: umltool.settings['to_context'] = umltool.merge_paths(path, oldpath) |
else: umltool.settings['to_context'] = mputils.transition_path(path, oldpath) |
204 |
|
|
205 |
#the second pass - adds uml into html |
#the second pass - adds uml into html |
206 |
if path.endswith(".rst"): path = path[0:len(path)-4] |
if path.endswith(".rst"): path = path[0:len(path)-4] |
217 |
|
|
218 |
#This should work also with non-generated UML-diagrams. Checks first |
#This should work also with non-generated UML-diagrams. Checks first |
219 |
#for generated and then if non-generated diagram exists. |
#for generated and then if non-generated diagram exists. |
220 |
if (os.path.isfile(umltool.settings['tmpdir']+"/"+name+".gen.uml")): |
if (os.path.isfile(mputils._slashify(mputils.settings['tmpdir'])\ |
221 |
|
+name+".gen.uml")): |
222 |
old_prefix = name + ".gen" |
old_prefix = name + ".gen" |
223 |
else: old_prefix = name |
else: old_prefix = name |
224 |
|
|
225 |
print "Embedding %s into %s" % (name, path) |
print "Embedding %s into %s" % (name, path) |
226 |
|
|
227 |
new_prefix = name+"_"+path.replace("/","_") |
context_name = name+"_"+path.replace("/","_") |
228 |
if new_prefix.endswith(".gen"): |
if context_name.endswith(".gen"): |
229 |
new_prefix = new_prefix[0:len(new_prefix)-4] |
context_name = context_name[0:len(context_name)-4] |
230 |
create_diagram(old_prefix, new_prefix, 0.5) |
create_diagram(old_prefix, context_name, 0.5) |
231 |
|
|
232 |
#Cut&Pastes imagemap into html |
#Cut&Pastes imagemap into html |
233 |
imgmap = open(umltool.settings['tmpdir']+"/"+new_prefix+".gen.html").read() |
imgmap = open(mputils._slashify(mputils.settings['tmpdir'])\ |
234 |
|
+context_name+".gen.html").read() |
235 |
out.write("<map id=\""+name+"\" name=\""+name+"\">\n") |
out.write("<map id=\""+name+"\" name=\""+name+"\">\n") |
236 |
out.write(imgmap[imgmap.find('>',imgmap.find('<map'))+1:\ |
out.write(imgmap[imgmap.find('>',imgmap.find('<map'))+1:\ |
237 |
imgmap.find('</map>')]) |
imgmap.find('</map>')]) |
238 |
out.write("</map>\n") |
out.write("</map>\n") |
239 |
|
out.write("<div class=\"uml-implicit\">\n") |
240 |
|
if (os.path.isfile(mputils._slashify(mputils.settings['tmpdir'])\ |
241 |
|
+name+".gen.refers")): |
242 |
|
refers = open(mputils._slashify(mputils.settings['tmpdir'])\ |
243 |
|
+name+".gen.refers").readlines() |
244 |
|
out.write("<small><strong>"+name+"</strong>: \n") |
245 |
|
for refer in refers: |
246 |
|
out.write("[<a href=\""\ |
247 |
|
+mputils.transition_path(path, refer.replace(".rst", ".gen.html")).replace("\n","")\ |
248 |
|
+"#"+name+"\">"+refer.split("/")[-1].split(".")[0]+"</a>]\n") |
249 |
|
out.write("</small><br/>\n") |
250 |
|
|
251 |
|
out.write("<a id=\""+name+"\"></a>\n") |
252 |
out.write("<img "\ |
out.write("<img "\ |
253 |
+"src=\""+umltool.settings['to_tmpdir']+"/"\ |
+"src=\""+mputils._slashify(mputils.settings['to_tmpdir'])\ |
254 |
+new_prefix+".gen.png"\ |
+context_name+".gen.png"\ |
255 |
+"\" usemap=\"#"+name+"\" alt=\""+name+"\" />") |
+"\" usemap=\"#"+name+"\" alt=\""+name+"\" />\n") |
256 |
|
out.write("</div>\n") |
257 |
|
|
258 |
html = html[insert+5:len(html)] |
html = html[insert+5:len(html)] |
259 |
out.write(html) |
out.write(html) |
260 |
out.close() |
out.close() |
261 |
|
|
262 |
umltool.settings = tmp |
umltool.settings = umltool_backup |
263 |
|
mputils.settings = mputils_backup |