refactor specfiles/scripts
[libfirm] / scripts / gen_docu.py
1 #!/usr/bin/env python
2 import sys
3 import docutils.core
4 import docutils.writers.html4css1
5 from datetime import datetime
6 from jinja2 import Environment, Template
7 from spec_util import isAbstract, load_spec
8
9 tags = None
10 linkbase = None
11
12 def format_doxygrouplink(string, link=None):
13         global tags
14         if link == None:
15                 link = string
16         if tags == None:
17                 return string
18         e = tags.xpath("//compound[name/text()='%s']" % link)
19         if len(e) == 0:
20                 return string
21         e = e[0]
22         anchorfile = e.xpath("filename/text()")
23         if len(anchorfile) == 0:
24                 return string
25         global linkbase
26         return "<a href=\"%s%s\">%s</a>" % (linkbase, anchorfile[0], string)
27
28 def format_doxylink(string, link=None):
29         global tags
30         if link == None:
31                 link = string
32         if tags == None:
33                 return string
34         e = tags.xpath("//member[name/text()='%s']" % link)
35         if len(e) == 0:
36                 return string
37         e = e[0]
38         anchorfile = e.xpath("anchorfile/text()")
39         anchor = e.xpath("anchor/text()")
40         if len(anchorfile) == 0 or len(anchor) == 0:
41                 return string
42         global linkbase
43         return "<a href=\"%s%s#%s\">%s</a>" % (linkbase, anchorfile[0], anchor[0], string)
44
45 def format_docutils(string):
46         writer = docutils.writers.html4css1.Writer()
47         document = docutils.core.publish_parts(string, writer=writer)['body']
48         return document
49
50 env = Environment()
51 env.filters['docutils'] = format_docutils
52 env.filters['doxylink'] = format_doxylink
53 env.filters['doxygrouplink'] = format_doxygrouplink
54
55 docu_template = env.from_string(
56 '''<html>
57         <head>
58                 <title>libFirm node specifications</title>
59                 <link rel='stylesheet' type='text/css' href='style.css'/>
60         </head>
61         <body>
62                 <div class="document">
63                 <div class="documentwrapper">
64                         <div class="bodywrapper"><div class="body">
65                                 <h1>Firm Node Types</h1>
66                                 {% for node in nodes %}
67                                 <div class="section" id="{{node.name}}">
68                                         <h3>{{node.name}}</h3>
69                                         {{node.doc|docutils}}
70                                         <h5>Inputs</h5>
71                                         <dl>
72                                         {% for input in node.ins %}
73                                                 <dt>{{input[0]}}</dt><dd>{{input[1]}}</dd>
74                                         {% endfor %}
75                                         {% if node.arity == "variable" %}
76                                                 <dt>...</dt><dd>additional inputs (oparity_variable)</dd>
77                                         {% elif node.arity == "dynamic" %}
78                                                 <dt>...</dt><dd>inputs dynamically mananged (oparity_dynamic)</dd>
79                                         {% endif %}
80                                         </dl>
81                                         {% if node.outs %}
82                                         <h5>Outputs</h5>
83                                         <dl>
84                                         {% for output in node.outs %}
85                                                 <dt>{{output[0]}}</dt><dd>{{output[1]}}</dd>
86                                         {% endfor %}
87                                         </dl>
88                                         {% endif %}
89                                         {% if node.attrs %}
90                                         <h5>Attributes</h5>
91                                         <dl>
92                                         {% for attr in node.attrs %}
93                                                 <dt>{{attr.name}}</dt><dd>{{attr.comment}} ({{attr.type}})</dd>
94                                         {% endfor %}
95                                         {% endif %}
96                                         </dl>
97                                         {% set comma = joiner(", ") %}
98                                         <h5>Flags</h5>
99                                         {% if node.flags.__len__() > 0 %}
100                                         {% for flag in node.flags -%}
101                                                 {{comma()}}{{flag|doxylink("irop_flag_" + flag)}}
102                                         {%- endfor %}
103                                         {% else %}
104                                         None
105                                         {% endif %}
106                                         <h5>{{"API"|doxygrouplink(node.name)}}</h5>
107                                         <hr/>
108                                 </div>
109                                 {% endfor %}
110                         </div></div>
111                 </div>
112                 <div class="sidebar">
113                         <div class="sidebarwrapper">
114                                 <h3>Table Of Contents</h3>
115                                 <ul>
116                                         <li><a href="#">Firm Node Types</a>
117                                         <ul>
118                                                 {% for node in nodes %}
119                                                 <li><a href="#{{node.name}}">{{node.name}}</a></li>
120                                                 {% endfor %}
121                                         </ul>
122                                         </li>
123                         </div>
124                 </div>
125                 </div>
126                 <div class="footer">
127                         Generated {{time}}
128                 </div>
129         </body>
130 </html>
131 ''')
132
133 #############################
134
135 def prepare_nodes(nodes):
136         real_nodes = []
137         for node in nodes:
138                 if isAbstract(node):
139                         continue
140                 real_nodes.append(node)
141
142         return real_nodes
143
144 def main(argv):
145         global tags
146         output = sys.stdout
147         specfile = argv[1]
148         if len(argv) > 2:
149                 output = open(argv[-1], "w")
150         if len(argv) > 4:
151                 tagfile = open(argv[-3], "r")
152                 global linkbase
153                 linkbase = argv[-2]
154                 if linkbase != "":
155                         linkbase += "/"
156                 try:
157                         from lxml import etree
158                         tags = etree.parse(tagfile)
159                 except:
160                         tags = None
161
162         spec = load_spec(specfile)
163         real_nodes = prepare_nodes(spec.nodes)
164         time = datetime.now().replace(microsecond=0).isoformat(' ')
165         output.write(docu_template.render(nodes=real_nodes, time=time))
166         if output != sys.stdout:
167                 output.close()
168
169 main(sys.argv)