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