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
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License version 2 as
9 # published by the Free Software Foundation.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 import optparse, os, sys
23 sys.path.append(os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
26 from string import split, join
32 Simple class to help to generate some sort of HTML files. It is
33 quite inferior solution compared to docbook, gtkdoc, doxygen but it
35 We've a global introduction site (index.html) and then one site for
36 the list of keys (alphabetical sorted) and one for the list of groups,
37 one site for each key with links to the relations and groups.
46 def replace(self, text, *pairs):
48 From pydoc... almost identical at least
52 text = join(split(text, a), b)
55 def escape(self, text):
57 Escape string to be conform HTML
59 return self.replace(text,
63 def createNavigator(self):
67 return """<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2">
69 <td><a accesskey="g" href="index.html">Home</a></td>
70 <td><a accesskey="n" href="all_groups.html">Groups</a></td>
71 <td><a accesskey="u" href="all_keys.html">Keys</a></td>
75 def relatedKeys(self, item):
77 Create HTML to link to foreign keys
80 if len(item.related()) == 0:
83 txt = "<p><b>See also:</b><br>"
85 for it in item.related():
86 txts.append("""<a href="key%(it)s.html">%(it)s</a>""" % vars() )
88 return txt + ",".join(txts)
90 def groups(self,item):
92 Create HTML to link to related groups
95 if len(item.groups()) == 0:
99 txt = "<p><b>See also:</b><br>"
101 for group in item.groups():
102 txts.append( """<a href="group%s.html">%s</a> """ % (group,group) )
104 return txt + ",".join(txts)
107 def createKeySite(self,item):
109 Create a site for a key. It contains the header/navigator, a heading,
110 the description, links to related keys and to the groups.
113 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
114 <html><head><title>Key %s</title></head>
115 <link rel="stylesheet" href="style.css" type="text/css">
116 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
118 <h2><span class="refentrytitle">%s</span></h2>
120 <div class="refsynopsisdiv">
127 <div class="refsynopsisdiv">
128 <h2>Related Keys</h2>
134 <div class="refsynopsisdiv">
143 """ % (item.name(), self.createNavigator(), item.name(),
144 self.escape(item.description()), self.relatedKeys(item), self.groups(item))
146 def createGroupsSite(self, doc):
148 Create the Group Overview site
152 sorted_groups = doc.groups()
154 for group in sorted_groups:
155 groups += """<a href="group%s.html">%s</a><br>""" % (group, group)
157 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
158 <html><head><title>Group overview</title></head>
159 <link rel="stylesheet" href="style.css" type="text/css">
160 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
162 <h2>Available Groups</h2>
165 """ % (self.createNavigator(), groups)
167 def createIndex(self):
169 Create the index file
172 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
173 <html><head><title>Bitbake Documentation</title></head>
174 <link rel="stylesheet" href="style.css" type="text/css">
175 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
177 <h2>Documentation Entrance</h2>
178 <a href="all_groups.html">All available groups</a><br>
179 <a href="all_keys.html">All available keys</a><br>
181 """ % self.createNavigator()
183 def createKeysSite(self, doc):
185 Create Overview of all avilable keys
188 sorted_keys = doc.doc_keys()
190 for key in sorted_keys:
191 keys += """<a href="key%s.html">%s</a><br>""" % (key, key)
193 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
194 <html><head><title>Key overview</title></head>
195 <link rel="stylesheet" href="style.css" type="text/css">
196 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
198 <h2>Available Keys</h2>
201 """ % (self.createNavigator(), keys)
203 def createGroupSite(self, gr, items, _description = None):
205 Create a site for a group:
206 Group the name of the group, items contain the name of the keys
212 # create a section with the group descriptions
214 description += "<h2 Description of Grozp %s</h2>" % gr
215 description += _description
217 items.sort(lambda x,y:cmp(x.name(),y.name()))
219 groups += """<a href="key%s.html">%s</a><br>""" % (group.name(), group.name())
221 return """<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
222 <html><head><title>Group %s</title></head>
223 <link rel="stylesheet" href="style.css" type="text/css">
224 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
227 <div class="refsynopsisdiv">
228 <h2>Keys in Group %s</h2>
229 <pre class="synopsis">
234 """ % (gr, self.createNavigator(), description, gr, groups)
242 return """.synopsis, .classsynopsis
245 border: solid 1px #aaaaaa;
251 border: solid 1px #aaaaff;
259 .variablelist td:first-child
266 border: solid 1px #ffaaaa;
268 margin-bottom: 0.5em;
274 .navigation a:visited
291 div.gallery-float img
301 text-decoration: none;
305 text-decoration: underline;
312 class DocumentationItem:
314 A class to hold information about a configuration
315 item. It contains the key name, description, a list of related names,
316 and the group this item is contained in.
331 def description(self):
337 def setName(self, name):
340 def setDescription(self, desc):
343 def addGroup(self, group):
344 self._groups.append(group)
346 def addRelation(self,relation):
347 self._related.append(relation)
356 Holds the documentation... with mappings from key to items...
363 def insert_doc_item(self, item):
365 Insert the Doc Item into the internal list
369 self.__keys[item.name()] = item
371 for group in item.groups():
372 if not group in self.__groups:
373 self.__groups[group] = []
374 self.__groups[group].append(item)
375 self.__groups[group].sort()
378 def doc_item(self, key):
380 Return the DocumentationInstance describing the key
383 return self.__keys[key]
389 Return the documented KEYS (names)
391 return self.__keys.keys()
395 Return the names of available groups
397 return self.__groups.keys()
399 def group_content(self,group_name):
401 Return a list of keys/names that are in a specefic
402 group or the empty list
405 return self.__groups[group_name]
410 def parse_cmdline(args):
412 Parse the CMD line and return the result as a n-tuple
415 parser = optparse.OptionParser( version = "Bitbake Documentation Tool Core version %s, %%prog version %s" % (bb.__version__,__version__))
416 usage = """%prog [options]
418 Create a set of html pages (documentation) for a bitbake.conf....
421 # Add the needed options
422 parser.add_option( "-c", "--config", help = "Use the specified configuration file as source",
423 action = "store", dest = "config", default = os.path.join("conf", "documentation.conf") )
425 parser.add_option( "-o", "--output", help = "Output directory for html files",
426 action = "store", dest = "output", default = "html/" )
428 parser.add_option( "-D", "--debug", help = "Increase the debug level",
429 action = "count", dest = "debug", default = 0 )
431 parser.add_option( "-v","--verbose", help = "output more chit-char to the terminal",
432 action = "store_true", dest = "verbose", default = False )
434 options, args = parser.parse_args( sys.argv )
437 bb.msg.set_debug_level(options.debug)
439 return options.config, options.output
446 (config_file,output_dir) = parse_cmdline( sys.argv )
448 # right to let us load the file now
450 documentation = bb.parse.handle( config_file, bb.data.init() )
452 bb.fatal( "Unable to open %s" % config_file )
453 except bb.parse.ParseError:
454 bb.fatal( "Unable to parse %s" % config_file )
457 # Assuming we've the file loaded now, we will initialize the 'tree'
458 doc = Documentation()
465 for key in bb.data.keys(documentation):
466 data = bb.data.getVarFlag(key, "doc", documentation)
470 # The Documentation now starts
471 doc_ins = DocumentationItem()
475 tokens = data.split(' ')
479 token = token.strip(',')
481 if not state == state_see and token == "@see":
484 elif not state == state_group and token == "@group":
488 if state == state_begin:
489 string += " %s" % token
490 elif state == state_see:
491 doc_ins.addRelation(token)
492 elif state == state_group:
493 doc_ins.addGroup(token)
495 # set the description
496 doc_ins.setDescription(string)
497 doc.insert_doc_item(doc_ins)
499 # let us create the HTML now
500 bb.mkdirhier(output_dir)
503 # Let us create the sites now. We do it in the following order
504 # Start with the index.html. It will point to sites explaining all
506 html_slave = HTMLFormatter()
508 f = file('style.css', 'w')
509 print >> f, html_slave.createCSS()
511 f = file('index.html', 'w')
512 print >> f, html_slave.createIndex()
514 f = file('all_groups.html', 'w')
515 print >> f, html_slave.createGroupsSite(doc)
517 f = file('all_keys.html', 'w')
518 print >> f, html_slave.createKeysSite(doc)
520 # now for each group create the site
521 for group in doc.groups():
522 f = file('group%s.html' % group, 'w')
523 print >> f, html_slave.createGroupSite(group, doc.group_content(group))
526 for key in doc.doc_keys():
527 f = file('key%s.html' % doc.doc_item(key).name(), 'w')
528 print >> f, html_slave.createKeySite(doc.doc_item(key))
531 if __name__ == "__main__":