diff options
-rw-r--r-- | doc/reference.doxygen.in (renamed from Doxyfile) | 60 | ||||
-rwxr-xr-x | gendoc.py | 193 | ||||
-rw-r--r-- | lv2/lv2plug.in/ns/index.html.in | 4 | ||||
-rwxr-xr-x | lv2specgen/lv2specgen.py | 40 | ||||
-rw-r--r-- | wscript | 205 |
5 files changed, 255 insertions, 247 deletions
diff --git a/Doxyfile b/doc/reference.doxygen.in index 0776204..3e35029 100644 --- a/Doxyfile +++ b/doc/reference.doxygen.in @@ -31,14 +31,14 @@ PROJECT_NAME = LV2 # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = @LV2_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = ns/doc +OUTPUT_DIRECTORY = @LV2_DOC_DIR@ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output @@ -511,13 +511,13 @@ LAYOUT_FILE = # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. -QUIET = NO +QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. -WARNINGS = NO +WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will @@ -565,30 +565,30 @@ WARN_LOGFILE = # with spaces. INPUT = \ - ../doc/mainpage.dox \ - ns/ext/atom/atom-helpers.h \ - ns/ext/atom/atom.h \ - ns/ext/atom/forge.h \ - ns/ext/contexts/contexts.h \ - ns/ext/data-access/data-access.h \ - ns/ext/dynmanifest/dynmanifest.h \ - ns/ext/event/event-helpers.h \ - ns/ext/event/event.h \ - ns/ext/instance-access/instance-access.h \ - ns/ext/log/log.h \ - ns/ext/osc/osc-print.h \ - ns/ext/osc/osc.h \ - ns/ext/pui/pui.h \ - ns/ext/reference/reference.h \ - ns/ext/resize-port/resize-port.h \ - ns/ext/state/state.h \ - ns/ext/string-port/string-port.h \ - ns/ext/time/time.h \ - ns/ext/ui-resize/ui-resize.h \ - ns/ext/uri-map/uri-map.h \ - ns/ext/urid/urid.h \ - ns/extensions/ui/ui.h \ - ns/lv2core/lv2.h + @LV2_SRCDIR@/doc/mainpage.dox \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/atom/atom-helpers.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/atom/atom.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/atom/forge.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/contexts/contexts.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/data-access/data-access.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/event/event-helpers.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/event/event.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/instance-access/instance-access.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/log/log.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/osc/osc-print.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/osc/osc.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/pui/pui.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/reference/reference.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/resize-port/resize-port.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/state/state.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/string-port/string-port.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/time/time.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/ui-resize/ui-resize.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/uri-map/uri-map.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/ext/urid/urid.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/extensions/ui/ui.h \ + @LV2_SRCDIR@/lv2/lv2plug.in/ns/lv2core/lv2.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -814,7 +814,7 @@ HTML_FOOTER = # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = doxy-style.css +HTML_STYLESHEET = @LV2_SRCDIR@/doc/doxy-style.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to @@ -1315,7 +1315,7 @@ TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = tags +GENERATE_TAGFILE = build/tags # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes diff --git a/gendoc.py b/gendoc.py deleted file mode 100755 index cfa7b3b..0000000 --- a/gendoc.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env python - -import datetime -import glob -import os -import rdflib -import shutil -import subprocess -import sys - -sys.path.append("./lv2specgen") -import lv2specgen - -try: - shutil.rmtree('build', 'ns') -except: - pass - -# Copy bundles (less build files) to build directory -shutil.copytree('lv2/lv2plug.in/ns', 'build/ns', - ignore=shutil.ignore_patterns('.*', 'waf', 'wscript', '*.in')) - -try: - os.mkdir('build/aux') -except: - pass - -# Copy stylesheet to build directory -shutil.copy('lv2specgen/style.css', 'build/aux/style.css') - -URIPREFIX = 'http://lv2plug.in/ns/' -DOXPREFIX = 'ns/doc/html/' -SPECGENDIR = os.path.abspath('lv2specgen') -STYLEPATH = os.path.abspath('build/aux/style.css') -TAGFILE = os.path.abspath('build/tags') -BUILDDIR = os.path.abspath('build') - -doap = rdflib.Namespace('http://usefulinc.com/ns/doap#') -lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#') -owl = rdflib.Namespace('http://www.w3.org/2002/07/owl#') -rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') - -devnull = open(os.devnull, 'w') - -# Enter build directory -print("Entering directory `%s'\n" % os.path.abspath('build')) -oldcwd = os.getcwd() -os.chdir('build') - -# Generate code (headers) documentation -print('## Generating header documentation with doxygen ##') -shutil.copy('../doc/doxy-style.css', './doxy-style.css') -subprocess.call(['doxygen', '../Doxyfile'], stdout=devnull) - -def subst_file(template, output, dict): - i = open(template, 'r') - o = open(output, 'w') - for line in i: - for key in dict: - line = line.replace(key, dict[key]) - o.write(line) - i.close() - o.close() - -extensions = [] - -print('\n## Generating specification documentation with lv2specgen ##') - -for root, dirs, files in os.walk('ns'): - if '.svn' in dirs: - dirs.remove('.svn') - - if root in ['ns', 'ns/ext', 'ns/extensions']: - if 'doc' in dirs: - dirs.remove('doc') - continue - - abs_root = os.path.abspath(root) - outdir = root - bundle = root - b = os.path.basename(root) - - if not os.access(outdir + '/%s.ttl' % b, os.R_OK): - print('warning: extension %s has no %s.ttl file' % (root, root)) - continue - - print(' * %s' % outdir) - - try: - model = rdflib.ConjunctiveGraph() - for i in glob.glob('%s/*.ttl' % bundle): - model.parse(i, format='n3') - except: - e = sys.exc_info()[1] - print('error parsing %s: %s' % (bundle, str(e))) - continue - - # Get extension URI - ext_node = model.value(None, rdf.type, lv2.Specification) - if not ext_node: - continue - - ext = str(ext_node) - - # Get version - minor = 0 - micro = 0 - try: - minor = int(model.value(ext_node, lv2.minorVersion, None)) - micro = int(model.value(ext_node, lv2.microVersion, None)) - except Exception as e: - print("warning: %s: failed to find version for %s" % (bundle, ext)) - - # Get date - date = None - for r in model.triples([ext_node, doap.release, None]): - revision = model.value(r[2], doap.revision, None) - if revision == ("%d.%d" % (minor, micro)): - date = model.value(r[2], doap.created, None) - break - - # Verify that this date is the latest - for r in model.triples([ext_node, doap.release, None]): - revision = model.value(r[2], doap.revision, None) - this_date = model.value(r[2], doap.created, None) - if this_date > date: - print("warning: revision %d.%d (%s) is not the latest release" % ( - minor, micro, date)) - break - - # Get short description - shortdesc = model.value(ext_node, doap.shortdesc, None) - - specdoc = lv2specgen.specgen( - root + '/%s.ttl' % b, - SPECGENDIR, - os.path.relpath(os.path.join('ns', 'doc'), abs_root), - os.path.relpath(STYLEPATH, abs_root), - os.path.relpath(BUILDDIR, abs_root), - TAGFILE, - instances=True) - - lv2specgen.save(root + '/%s.html' % b, specdoc) - - # Name (comment is to act as a sort key) - row = '<tr><!-- %s --><td><a rel="rdfs:seeAlso" href="%s">%s</a></td>' % ( - b, os.path.relpath(root, 'ns'), b) - - # Description - if shortdesc: - row += '<td>' + str(shortdesc) + '</td>' - else: - row += '<td></td>' - - # Version - version_str = '%s.%s' % (minor, micro) - if minor == 0 or (micro % 2 != 0): - row += '<td><span style="color: red">' + version_str + '</span></td>' - else: - row += '<td>' + version_str + '</td>' - - # Date - row += '<td>%s</td>' % (str(date) if date else '') - - # Status - deprecated = model.value(ext_node, owl.deprecated, None) - if minor == 0: - row += '<td><span class="error">Experimental</span></td>' - elif deprecated and str(deprecated[2]) != "false": - row += '<td><span class="warning">Deprecated</span></td>' - elif micro % 2 == 0: - row += '<td><span class="success">Stable</span></td>' - - row += '</tr>' - extensions.append(row) - - subst_file('../doc/htaccess.in', outdir + '/.htaccess', - { '@NAME@': b, - '@BASE@': '/' + outdir }) - -index_rows = '' -extensions.sort() -for i in extensions: - index_rows += i + '\n' - -subst_file('../lv2/lv2plug.in/ns/index.html.in', 'ns/index.html', - { '@ROWS@': index_rows, - '@TIME@': datetime.datetime.utcnow().strftime('%F %H:%M UTC') }) - -print("\nLeaving directory `%s'" % os.getcwd()) -os.chdir(oldcwd) - -devnull.close() diff --git a/lv2/lv2plug.in/ns/index.html.in b/lv2/lv2plug.in/ns/index.html.in index 4863cb2..ab23f99 100644 --- a/lv2/lv2plug.in/ns/index.html.in +++ b/lv2/lv2plug.in/ns/index.html.in @@ -22,11 +22,11 @@ <th>Date</th> <th>Status</th> </tr> - @ROWS@ +@ROWS@ </table> </div> <div id="footer"> - <div>Generated on @TIME@ by gendoc.py</div> + <div>Generated at @TIME@</div> </div> </body> </html> diff --git a/lv2specgen/lv2specgen.py b/lv2specgen/lv2specgen.py index 6b4b7c6..c2d9067 100755 --- a/lv2specgen/lv2specgen.py +++ b/lv2specgen/lv2specgen.py @@ -974,7 +974,7 @@ def getInstances(model, classes, properties): instances.append(getSubject(i)) return instances -def load_tags(path, doc_base): +def load_tags(path, doc_base, doc_prefix): "Build a (symbol => URI) map from a Doxygen tag file." def getChildText(elt, tagname): @@ -985,12 +985,8 @@ def load_tags(path, doc_base): return '' def linkTo(sym, url): - #print "LINK: ", '<span><a href="%s/%s">%s</a></span>' % (doc_base, url, sym) return '<span><a href="%s/%s">%s</a></span>' % (doc_base, url, sym) - # FIXME: Parameterize - DOXPREFIX = 'ns/doc/html/' - tagdoc = xml.dom.minidom.parse(path) root = tagdoc.documentElement linkmap = {} @@ -1003,7 +999,7 @@ def load_tags(path, doc_base): name = getChildText(cn, 'name') filename = getChildText(cn, 'filename') - linkmap[name] = linkTo(name, DOXPREFIX + filename) + linkmap[name] = linkTo(name, doc_prefix + filename) prefix = '' if cn.getAttribute('kind') != 'file': @@ -1015,13 +1011,11 @@ def load_tags(path, doc_base): mafile = getChildText(m, 'anchorfile') manchor = getChildText(m, 'anchor') linkmap[mname] = linkTo( - mname, '%s%s#%s' % (DOXPREFIX, mafile, manchor)) + mname, '%s%s#%s' % (doc_prefix, mafile, manchor)) - #import pprint - #pprint.pprint(linkmap) return linkmap -def specgen(specloc, indir, docdir, style_uri, doc_base, tags, instances=False, mode="spec"): +def specgen(specloc, indir, docdir, style_uri, doc_base, doc_prefix, tags, instances=False, mode="spec"): """The meat and potatoes: Everything starts here.""" global spec_url @@ -1041,7 +1035,7 @@ def specgen(specloc, indir, docdir, style_uri, doc_base, tags, instances=False, template = f.read() # Load code documentation link map from tags file - linkmap = load_tags(tags, doc_base) + linkmap = load_tags(tags, doc_base, doc_prefix) m = rdflib.ConjunctiveGraph() manifest_path = os.path.join(os.path.dirname(specloc), 'manifest.ttl') @@ -1242,12 +1236,13 @@ def usage(): script = os.path.basename(sys.argv[0]) print("""Usage: %s ONTOLOGY INDIR STYLE OUTPUT BASE TAGS [FLAGS] - ONTOLOGY : Path to ontology file - INDIR : Input directory containing template.html and style.css - STYLE : Stylesheet URI - OUTPUT : HTML output path - BASE : Documentation output base URI - TAGS : Doxygen tags file + ONTOLOGY : Path to ontology file + INDIR : Input directory containing template.html and style.css + STYLE : Stylesheet URI + OUTPUT : HTML output path + DOCBASE : Documentation output base URI + DOCPREFIX : Documentation link prefix + TAGS : Doxygen tags file Optional flags: -i : Document class/property instances (disabled by default) @@ -1282,15 +1277,18 @@ if __name__ == "__main__": # Doxygen documentation directory doc_base = args[4] + # Documentation link prefix + doc_prefix = args[5] + # Doxygen tags file - doc_tags = args[5] + doc_tags = args[6] docdir = os.path.join(doc_base, 'ns', 'doc') # Flags instances = False - if len(args) > 5: - flags = args[5:] + if len(args) > 7: + flags = args[7:] i = 0 while i < len(flags): if flags[i] == '-i': @@ -1301,7 +1299,7 @@ if __name__ == "__main__": i += 1 try: - save(dest, specgen(specloc, indir, docdir, style_uri, doc_base, tags, instances=instances)) + save(dest, specgen(specloc, indir, docdir, style_uri, doc_base, doc_prefix, tags, instances=instances)) except: e = sys.exc_info()[1] print('error: ' + str(e)) @@ -42,7 +42,7 @@ def configure(conf): conf.env.append_unique('CFLAGS', '-std=c99') - subdirs = ['lv2/lv2plug.in/ns/lv2core'] + subdirs = ['lv2/lv2plug.in/ns/lv2core/'] subdirs += glob.glob('lv2/lv2plug.in/ns/ext/*/') subdirs += glob.glob('lv2/lv2plug.in/ns/extensions/*/') subdirs += glob.glob('plugins/*/') @@ -52,10 +52,213 @@ def configure(conf): conf.env['LV2_SUBDIRS'] = subdirs +# Rule for copying a file to the build directory +def copy(task): + shutil.copy(task.inputs[0].abspath(), task.outputs[0].abspath()) + +def chop_lv2_prefix(s): + if s.startswith('lv2/lv2plug.in/'): + return s[len('lv2/lv2plug.in/'):] + return s + +# Rule for calling lv2specgen on a spec bundle +def specgen(task): + import rdflib + doap = rdflib.Namespace('http://usefulinc.com/ns/doap#') + lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#') + owl = rdflib.Namespace('http://www.w3.org/2002/07/owl#') + rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') + + sys.path.append("./lv2specgen") + import lv2specgen + + spec = task.inputs[0] + path = os.path.dirname(spec.srcpath()) + indir = os.path.dirname(spec.abspath()) + outdir = os.path.abspath(os.path.join(out, chop_lv2_prefix(path))) + + bundle = str(outdir) + b = os.path.basename(outdir) + + if not os.access(spec.abspath(), os.R_OK): + print('warning: extension %s has no %s.ttl file' % (root, root)) + return + + try: + model = rdflib.ConjunctiveGraph() + for i in glob.glob('%s/*.ttl' % bundle): + model.parse(i, format='n3') + except: + e = sys.exc_info()[1] + print('error parsing %s: %s' % (bundle, str(e))) + return + + # Get extension URI + ext_node = model.value(None, rdf.type, lv2.Specification) + if not ext_node: + print('no extension found in %s' % bundle) + return + + ext = str(ext_node) + + # Get version + minor = 0 + micro = 0 + try: + minor = int(model.value(ext_node, lv2.minorVersion, None)) + micro = int(model.value(ext_node, lv2.microVersion, None)) + except Exception as e: + print("warning: %s: failed to find version for %s" % (bundle, ext)) + + # Get date + date = None + for r in model.triples([ext_node, doap.release, None]): + revision = model.value(r[2], doap.revision, None) + if revision == ("%d.%d" % (minor, micro)): + date = model.value(r[2], doap.created, None) + break + + # Verify that this date is the latest + for r in model.triples([ext_node, doap.release, None]): + revision = model.value(r[2], doap.revision, None) + this_date = model.value(r[2], doap.created, None) + if this_date > date: + print("warning: revision %d.%d (%s) is not the latest release" % ( + minor, micro, date)) + break + + # Get short description + shortdesc = model.value(ext_node, doap.shortdesc, None) + + SPECGENDIR = 'lv2specgen' + STYLEPATH = 'build/aux/style.css' + TAGFILE = 'build/tags' + + specdoc = lv2specgen.specgen( + spec.abspath(), + SPECGENDIR, + os.path.relpath('doc', bundle), + os.path.relpath(STYLEPATH, bundle), + os.path.abspath('build'), + 'doc/html/', + TAGFILE, + instances=True) + + lv2specgen.save(task.outputs[0].abspath(), specdoc) + + # Name (comment is to act as a sort key) + row = '<tr><!-- %s --><td><a rel="rdfs:seeAlso" href="%s">%s</a></td>' % ( + b, path[len('lv2/lv2plug.in/ns/'):], b) + + # Description + if shortdesc: + row += '<td>' + str(shortdesc) + '</td>' + else: + row += '<td></td>' + + # Version + version_str = '%s.%s' % (minor, micro) + if minor == 0 or (micro % 2 != 0): + row += '<td><span style="color: red">' + version_str + '</span></td>' + else: + row += '<td>' + version_str + '</td>' + + # Date + row += '<td>%s</td>' % (str(date) if date else '') + + # Status + deprecated = model.value(ext_node, owl.deprecated, None) + if minor == 0: + row += '<td><span class="error">Experimental</span></td>' + elif deprecated and str(deprecated[2]) != "false": + row += '<td><span class="warning">Deprecated</span></td>' + elif micro % 2 == 0: + row += '<td><span class="success">Stable</span></td>' + + row += '</tr>' + + index = open(os.path.join('build', 'index_rows', b), 'w') + index.write(row) + index.close() + +def subst_file(template, output, dict): + i = open(template, 'r') + o = open(output, 'w') + for line in i: + for key in dict: + line = line.replace(key, dict[key]) + o.write(line) + i.close() + o.close() + +# Task to build extension index +def build_index(task): + global index_lines + rows = [] + for f in task.inputs: + if not f.abspath().endswith('index.html.in'): + rowfile = open(f.abspath(), 'r') + rows += rowfile.readlines() + rowfile.close() + + subst_file(task.inputs[0].abspath(), task.outputs[0].abspath(), + { '@ROWS@': ''.join(rows), + '@TIME@': datetime.datetime.utcnow().strftime('%F %H:%M UTC') }) + def build(bld): for i in bld.env['LV2_SUBDIRS']: bld.recurse(i) + if bld.env['DOCS']: + # Build Doxygen documentation (and tags file) + autowaf.build_dox(bld, 'LV2', VERSION, top, out) + + # Copy stylesheet to build directory + obj = bld(rule = copy, + name = 'copy', + source = 'doc/style.css', + target = 'aux/style.css') + + index_files = [] + + # Generate .htaccess files (and directory skeleton) + for i in bld.env['LV2_SUBDIRS']: + if i.startswith('lv2/lv2plug.in'): + # Copy spec files to build dir + for f in bld.path.ant_glob(i + '*.*'): + obj = bld(rule = copy, + name = 'copy', + source = f, + target = chop_lv2_prefix(f.srcpath())) + + base = i[len('lv2/lv2plug.in'):] + name = os.path.basename(i[:len(i)-1]) + index_file = os.path.join('index_rows', name) + index_files += [index_file] + + # Generate .htaccess file + obj = bld(features = 'subst', + source = 'doc/htaccess.in', + target = os.path.join(base, '.htaccess'), + install_path = None, + NAME = name, + BASE = base) + + bld.add_group() + + # Call lv2specgen to generate spec docs + obj = bld(rule = specgen, + name = 'specgen', + source = os.path.join(i, name + '.ttl'), + target = ['%s%s.html' % (chop_lv2_prefix(i), name), + index_file]) + + # Build extension index + obj = bld(rule = build_index, + name = 'index', + source = ['lv2/lv2plug.in/ns/index.html.in'] + index_files, + target = 'ns/index.html') + def release(ctx): lv2 = rdflib.Namespace('http://lv2plug.in/ns/lv2core#') rdf = rdflib.Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') |