2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
5 # Copyright (C) 2005 Holger Hans Peter Freyther
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to deal
10 # in the Software without restriction, including without limitation the rights
11 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 # copies of the Software, and to permit persons to whom the Software is
13 # furnished to do so, subject to the following conditions:
15 # The above copyright notice and this permission notice shall be included in all
16 # copies or substantial portions of the Software.
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 # SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
24 # THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 import optparse, os, sys
31 sys.path.append(os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
34 from string import split, join
40 Simple class to help to generate some sort of HTML files. It is
41 quite inferior solution compared to docbook, gtkdoc, doxygen but it
43 We've a global introduction site (index.html) and then one site for
44 the list of keys (alphabetical sorted) and one for the list of groups,
45 one site for each key with links to the relations and groups.
54 def replace(self, text, *pairs):
56 From pydoc... almost identical at least
60 text = join(split(text, a), b)
63 def escape(self, text):
65 Escape string to be conform HTML
67 return self.replace(text,
71 def createNavigator(self):
75 return """<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
77 <td><a accesskey="g" href="index.html">Home</a></td>
78 <td><a accesskey="n" href="groups.html">Groups</a></td>
79 <td><a accesskey="u" href="keys.html">Keys</a></td>
83 def relatedKeys(self, item):
85 Create HTML to link to foreign keys
87 txt = "<p><b>See also:</b><br>"
88 for it in item.related():
89 txt += """<a href="key%s.html">%s</a>, """ % (it, it)
93 def groups(self,item):
95 Create HTML to link to related groups
97 txt = "<p><b>Seel also:</b><br>"
98 for group in item.groups():
99 txt += """<a href="group%s.html">%s</a>, """ % (group,group)
104 def createKeySite(self,item):
106 Create a site for a key. It contains the header/navigator, a heading,
107 the description, links to related keys and to the groups.
110 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
111 <html><head><title>Key %s</title></head>
112 <link rel="stylesheet" href="style.css" type="text/css">
113 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
115 <h2><span class="refentrytitle">%s</span></h2>
117 <div class="refsynopsisdiv">
119 <pre class="synopsis">
124 <div class="refsynopsisdiv">
125 <h2>Related Keys</h2>
126 <pre class="synopsis">
131 <div class="refsynopsisdiv">
133 <pre class="synopsis">
140 """ % (item.name(), self.createNavigator(), item.name(),
141 self.escape(item.description()), self.relatedKeys(item), self.groups(item))
143 def createGroupsSite(self, doc):
145 Create the Group Overview site
149 for group in doc.groups():
150 groups += """<a href="group%s.html">%s</a><br>""" % (group, group)
152 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
153 <html><head><title>Group overview</title></head>
154 <link rel="stylesheet" href="style.css" type="text/css">
155 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
157 <h2>Available Groups</h2>
160 """ % (self.createNavigator(), groups)
162 def createIndex(self):
164 Create the index file
167 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
168 <html><head><title>Bitbake Documentation</title></head>
169 <link rel="stylesheet" href="style.css" type="text/css">
170 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
172 <h2>Documentation Entrance</h2>
173 <a href="groups.html">All available groups</a><br>
174 <a href="keys.html">All available keys</a><br>
176 """ % self.createNavigator()
178 def createKeysSite(self, doc):
180 Create Overview of all avilable keys
183 for key in doc.doc_keys():
184 keys += """<a href="key%s.html">%s</a><br>""" % (key, key)
186 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
187 <html><head><title>Key overview</title></head>
188 <link rel="stylesheet" href="style.css" type="text/css">
189 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
191 <h2>Available Keys</h2>
194 """ % (self.createNavigator(), keys)
196 def createGroupSite(self,gr, items):
198 Create a site for a group:
199 Group the name of the group, items contain the name of the keys
204 groups += """<a href="group%s.html">%s</a><br>""" % (group.name(), group.name())
206 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
207 <html><head><title>Group %s</title></head>
208 <link rel="stylesheet" href="style.css" type="text/css">
209 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
211 <div class="refsynopsisdiv">
212 <h2>Keys in Group %s</h2>
213 <pre class="synopsis">
218 """ % (gr, self.createNavigator(), gr, groups)
226 return """.synopsis, .classsynopsis
229 border: solid 1px #aaaaaa;
235 border: solid 1px #aaaaff;
243 .variablelist td:first-child
250 border: solid 1px #ffaaaa;
252 margin-bottom: 0.5em;
258 .navigation a:visited
275 div.gallery-float img
285 text-decoration: none;
289 text-decoration: underline;
296 class DocumentationItem:
298 A class to hold information about a configuration
299 item. It contains the key name, description, a list of related names,
300 and the group this item is contained in.
315 def description(self):
321 def setName(self, name):
324 def setDescription(self, desc):
327 def addGroup(self, group):
328 self._groups.append(group)
330 def addRelation(self,relation):
331 self._related.append(relation)
336 Holds the documentation... with mappings from key to items...
343 def insert_doc_item(self, item):
345 Insert the Doc Item into the internal list
348 self.__keys[item.name()] = item
350 for group in item.groups():
351 if not group in self.__groups:
352 self.__groups[group] = []
353 self.__groups[group].append(item)
356 def doc_item(self, key):
358 Return the DocumentationInstance describing the key
361 return self.__keys[key]
367 Return the documented KEYS (names)
369 return self.__keys.keys()
373 Return the names of available groups
375 return self.__groups.keys()
377 def group_content(self,group_name):
379 Return a list of keys/names that are in a specefic
380 group or the empty list
383 return self.__groups[group_name]
388 def parse_cmdline(args):
390 Parse the CMD line and return the result as a n-tuple
393 parser = optparse.OptionParser( version = "Bitbake Documentation Tool Core version %s, %%prog version %s" % (bb.__version__,__version__))
394 usage = """%prog [options]
396 Create a set of html pages (documentation) for a bitbake.conf....
399 # Add the needed options
400 parser.add_option( "-c", "--config", help = "Use the specified configuration file as source",
401 action = "store", dest = "config", default = os.path.join("conf", "documentation.conf") )
403 parser.add_option( "-o", "--output", help = "Output directory for html files",
404 action = "store", dest = "output", default = "html/" )
406 parser.add_option( "-D", "--debug", help = "Increase the debug level",
407 action = "count", dest = "debug", default = 0 )
409 parser.add_option( "-v","--verbose", help = "output more chit-char to the terminal",
410 action = "store_true", dest = "verbose", default = False )
412 options, args = parser.parse_args( sys.argv )
415 bb.debug_level = options.debug
417 return options.config, options.output
424 (config_file,output_dir) = parse_cmdline( sys.argv )
426 # right to let us load the file now
428 documentation = bb.parse.handle( config_file, bb.data.init() )
430 bb.fatal( "Unable to open %s" % config_file )
431 except bb.parse.ParseError:
432 bb.fatal( "Unable to parse %s" % config_file )
435 # Assuming we've the file loaded now, we will initialize the 'tree'
436 doc = Documentation()
443 for key in bb.data.keys(documentation):
444 data = bb.data.getVarFlag(key, "doc", documentation)
448 # The Documentation now starts
449 doc_ins = DocumentationItem()
453 tokens = data.split(' ')
457 token = token.strip(',')
459 if not state == state_see and token == "@see":
462 elif not state == state_group and token == "@group":
466 if state == state_begin:
467 string += " %s" % token
468 elif state == state_see:
469 doc_ins.addRelation(token)
470 elif state == state_group:
471 doc_ins.addGroup(token)
473 # set the description
474 doc_ins.setDescription(string)
475 doc.insert_doc_item(doc_ins)
477 # let us create the HTML now...
478 bb.mkdirhier(output_dir)
481 # Let us create the sites now. We do it in the following order
482 # Start with the index.html. It will point to sites explaining all
484 html_slave = HTMLFormatter()
486 f = file('style.css', 'w')
487 print >> f, html_slave.createCSS()
489 f = file('index.html', 'w')
490 print >> f, html_slave.createIndex()
492 f = file('groups.html', 'w')
493 print >> f, html_slave.createGroupsSite(doc)
495 f = file('keys.html', 'w')
496 print >> f, html_slave.createKeysSite(doc)
498 # now for each group create the site
499 for group in doc.groups():
500 f = file('group%s.html' % group, 'w')
501 print >> f, html_slave.createGroupSite(group, doc.group_content(group))
504 for key in doc.doc_keys():
505 f = file('key%s.html' % doc.doc_item(key).name(), 'w')
506 print >> f, html_slave.createKeySite(doc.doc_item(key))
509 if __name__ == "__main__":