Index: /trunk/lv2/ext/port_groups/lv2_port_groups.ttl
===================================================================
--- /trunk/lv2/ext/port_groups/lv2_port_groups.ttl (revision 2112)
+++ /trunk/lv2/ext/port_groups/lv2_port_groups.ttl (revision 2118)
@@ -22,5 +22,5 @@
 # OTHER DEALINGS IN THE SOFTWARE.
 
-@prefix pg:   <http://lv2plug.in/ns/dev/port-groups#> .
+@prefix pg:   <http://lv2plug.in/ns/ext/port-groups#> .
 @prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
 @prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@@ -31,8 +31,8 @@
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
 
-<http://lv2plug.in/ns/dev/port-groups> a lv2:Specification ;
+<http://lv2plug.in/ns/ext/port-groups> a lv2:Specification ;
 	doap:license <http://usefulinc.com/doap/licenses/mit> ;
 	doap:name	"LV2 Port Groups" ;
-	rdfs:comment "Defines meaningful groupings of LV2 ports" ;
+	rdfs:comment "Defines semantic groupings of LV2 ports" ;
 	doap:maintainer [
 		a foaf:Person ;
Index: /trunk/lv2specgen/lv2specgen.py
===================================================================
--- /trunk/lv2specgen/lv2specgen.py (revision 2114)
+++ /trunk/lv2specgen/lv2specgen.py (revision 2118)
@@ -3,5 +3,4 @@
 #
 # lv2specgen, an LV2 extension specification page generator
-#
 # Copyright (c) 2009 Dave Robillard <dave@drobilla.net>
 #
@@ -80,9 +79,9 @@
           }
 
-rdf = RDF.NS('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
+rdf  = RDF.NS('http://www.w3.org/1999/02/22-rdf-syntax-ns#')
 rdfs = RDF.NS('http://www.w3.org/2000/01/rdf-schema#')
-owl = RDF.NS('http://www.w3.org/2002/07/owl#')
-vs = RDF.NS('http://www.w3.org/2003/06/sw-vocab-status/ns#')
-lv2 = RDF.NS('http://lv2plug.in/ns/lv2core#')
+owl  = RDF.NS('http://www.w3.org/2002/07/owl#')
+vs   = RDF.NS('http://www.w3.org/2003/06/sw-vocab-status/ns#')
+lv2  = RDF.NS('http://lv2plug.in/ns/lv2core#')
 doap = RDF.NS('http://usefulinc.com/ns/doap#')
 foaf = RDF.NS('http://xmlns.com/foaf/0.1/')
@@ -177,5 +176,5 @@
             k = getTermLink(str(st.object.uri), term, rdfs.subPropertyOf)
             rlist += "<dd>%s</dd>" % k
-        doc += "<dt>sub-property-of:</dt> %s" % rlist
+        doc += "<dt>Sub-property of</dt> %s" % rlist
 
     #domain stuff
@@ -193,5 +192,5 @@
                 domainsdoc += "<dd>%s</dd>" % getTermLink(str(d.object.uri), term, rdfs.domain)
     if (len(domainsdoc)>0):
-        doc += "<dt>Domain:</dt> %s" % domainsdoc
+        doc += "<dt>Domain</dt> %s" % domainsdoc
 
     #range stuff
@@ -209,5 +208,5 @@
                 rangesdoc += "<dd>%s</dd>" % getTermLink(str(r.object.uri), term, rdfs.range)
     if (len(rangesdoc)>0):
-        doc += "<dt>Range:</dt> %s" % rangesdoc
+        doc += "<dt>Range</dt> %s" % rangesdoc
 
     return doc
@@ -259,14 +258,7 @@
     doc = ""
 
-    #patch to control incoming strings (FIXME, why??? drop it!)
-    try:
-        term.uri
-    except:
-        term = RDF.Node(RDF.Uri(term))
-
     # Find subClassOf information
     o = m.find_statements( RDF.Statement(term, rdfs.subClassOf, None) )
     if o.current():
-        doc += "<dt>sub-class-of:</dt>"
         superclasses = []
         for st in o:
@@ -275,6 +267,8 @@
                 if (not uri in superclasses):
                     superclasses.append(uri)
-        for superclass in superclasses:
-            doc += "<dd>%s</dd>" % getTermLink(superclass)
+        if len(superclasses) > 0:
+            doc += "<dt>Sub-class of</dt>"
+            for superclass in superclasses:
+                doc += "<dd>%s</dd>" % getTermLink(superclass)
 
     # Find out about properties which have rdfs:domain of t
@@ -284,5 +278,5 @@
         for k in d:
             dlist += "<dd>%s</dd>" % getTermLink(k)
-        doc += "<dt>in-domain-of:</dt>" + dlist
+        doc += "<dt>In domain of</dt>" + dlist
 
     # Find out about properties which have rdfs:range of t
@@ -292,7 +286,35 @@
         for k in r:
             rlist += "<dd>%s</dd>" % getTermLink(k)
-        doc += "<dt>in-range-of:</dt>" + rlist
+        doc += "<dt>In range of</dt>" + rlist
 
     return doc
+
+
+def isSpecial(pred):
+    """Return True if the predicate is "special" and shouldn't be emitted generically"""
+    return pred == rdf.type or pred == rdfs.range or pred == rdfs.domain or pred == rdfs.label or pred == rdfs.comment
+
+
+def extraInfo(term,m):
+    """Generate information about misc. properties of a term"""
+    doc = ""
+    properties = m.find_statements(RDF.Statement(term, None, None))
+    #if properties:
+    #    doc += '<dl>\n'
+    last_pred = ''
+    for p in properties:
+        if isSpecial(p.predicate) or p.object.is_blank():
+            continue
+        if p.predicate != last_pred:
+            doc += '<dt>%s</dt>\n' % niceName(str(p.predicate.uri))
+        if p.object.is_resource():
+            doc += '<dd>%s</dd>\n' % getTermLink(str(p.object.uri), term, p.predicate)
+        elif p.object.is_literal():
+            doc += '<dd>%s</dd>\n' % str(p.object)
+        last_pred = p.predicate
+    #if properties:
+    #    doc += '</dl>\n'
+    return doc
+
 
 def rdfsInstanceInfo(term,m):
@@ -302,9 +324,11 @@
     t = m.find_statements( RDF.Statement(RDF.Node(RDF.Uri(term)), rdf.type, None) )
     if t.current():
-        doc += "<dt>RDF Type:</dt>"
+        doc += "<dt>Type</dt>"
     while t.current():
         doc += "<dd>%s</dd>" % getTermLink(str(t.current().object.uri), RDF.Node(RDF.Uri(term)), rdf.type)
         t.next()
 
+    doc += extraInfo(RDF.Node(RDF.Uri(term)), m)
+
     return doc
 
@@ -326,25 +350,25 @@
     o = m.find_statements( RDF.Statement(term, rdf.type, owl.DatatypeProperty) )
     if o.current():
-        res += "<dt>OWL Type:</dt><dd>DatatypeProperty</dd>\n"
+        res += "<dt>OWL Type</dt><dd>DatatypeProperty</dd>\n"
 
     # Object Property ( owl.ObjectProperty )
     o = m.find_statements( RDF.Statement(term, rdf.type, owl.ObjectProperty) )
     if o.current():
-        res += "<dt>OWL Type:</dt><dd>ObjectProperty</dd>\n"
+        res += "<dt>OWL Type</dt><dd>ObjectProperty</dd>\n"
 
     # Annotation Property ( owl.AnnotationProperty )
     o = m.find_statements( RDF.Statement(term, rdf.type, owl.AnnotationProperty) )
     if o.current():
-        res += "<dt>OWL Type:</dt><dd>AnnotationProperty</dd>\n"
+        res += "<dt>OWL Type</dt><dd>AnnotationProperty</dd>\n"
 
     # IFPs ( owl.InverseFunctionalProperty )
     o = m.find_statements( RDF.Statement(term, rdf.type, owl.InverseFunctionalProperty) )
     if o.current():
-        res += "<dt>OWL Type:</dt><dd>InverseFunctionalProperty (uniquely identifying property)</dd>\n"
+        res += "<dt>OWL Type</dt><dd>InverseFunctionalProperty (uniquely identifying property)</dd>\n"
 
     # Symmertic Property ( owl.SymmetricProperty )
     o = m.find_statements( RDF.Statement(term, rdf.type, owl.SymmetricProperty) )
     if o.current():
-        res += "<dt>OWL Type:</dt><dd>SymmetricProperty</dd>\n"
+        res += "<dt>OWL Type</dt><dd>SymmetricProperty</dd>\n"
 
     return res
@@ -378,9 +402,10 @@
             term_uri = term
         
-        doc += """<div class="specterm" id="term_%s" about="%s">\n<h3>%s: <a href="%s">%s</a></h3>\n""" % (t, term_uri, category, term_uri, curie)
+        doc += """<div class="specterm" id="term_%s" about="%s">\n<h3>%s <a href="%s">%s</a></h3>\n""" % (t, term_uri, category, term_uri, curie)
 
         label, comment = get_rdfs(m, term)    
         status = get_status(m, term)
-        doc += "<p><em>%s</em></p>" % label
+        if label!='':
+            doc += "<span property=\"rdfs:label\" class=\"subtitle\">%s</span>" % label
         if comment!='':
 			doc += "<p property=\"rdfs:comment\">%s</p>" % comment
@@ -393,8 +418,11 @@
         if category=='Instance':
             terminfo += rdfsInstanceInfo(term,m)
+        
+        terminfo += extraInfo(term,m)
+        
         if (len(terminfo)>0): #to prevent empty list (bug #882)
             doc += "\n<dl>%s</dl>\n" % terminfo
+        
         doc += htmlDocInfo(t)
-        doc += "<p style=\"float: right; font-size: small;\">[<a href=\"#sec-glance\">back to top</a>]</p>\n\n"
         doc += "\n\n</div>\n\n"
     
@@ -416,13 +444,13 @@
 
 
-def buildazlist(classlist, proplist, instalist=None):
+def buildIndex(classlist, proplist, instalist=None):
     """
     Builds the A-Z list of terms. Args are a list of classes (strings) and 
     a list of props (strings)
     """
-    azlist = '<div style="padding: 1em; border: dotted; background-color: #ddd;">'
+    azlist = '<dl class="index">'
 
     if (len(classlist)>0):
-        azlist += "<p>Classes: "
+        azlist += "<dt>Classes</dt><dd>"
         classlist.sort()
         for c in classlist:
@@ -430,8 +458,8 @@
                 c = c.split(spec_ns_str[-1])[1]
             azlist = """%s <a href="#term_%s">%s</a>, """ % (azlist, c, c)
-        azlist = """%s\n</p>""" % azlist
+        azlist = """%s</dd>\n""" % azlist
 
     if (len(proplist)>0):
-        azlist += "<p>Properties: "
+        azlist += "<dt>Properties</dt><dd>"
         proplist.sort()
         for p in proplist:
@@ -439,43 +467,15 @@
                 p = p.split(spec_ns_str[-1])[1]
             azlist = """%s <a href="#term_%s">%s</a>, """ % (azlist, p, p)
-        azlist = """%s\n</p>""" % azlist
+        azlist = """%s</dd>\n""" % azlist
 
     if (instalist!=None and len(instalist)>0):
-        azlist += "<p>Instances: "
+        azlist += "<dt>Instances</dt><dd>"
         for i in instalist:
             p = getShortName(i)
             anchor = getAnchor(i)
             azlist = """%s <a href="#term_%s">%s</a>, """ % (azlist, anchor, p)
-        azlist = """%s\n</p>""" % azlist
-
-    azlist = """%s\n</div>""" % azlist
-    return azlist
-
-
-def build_simple_list(classlist, proplist, instalist=None):
-    """
-    Builds a simple <ul> A-Z list of terms. Args are a list of classes (strings) and 
-    a list of props (strings)
-    """
-
-    azlist = """<div style="padding: 5px; border: dotted; background-color: #ddd;">"""
-    azlist = """%s\n<p>Classes:""" % azlist
-    azlist += """\n<ul>"""
-
-    classlist.sort()
-    for c in classlist:
-        azlist += """\n  <li><a href="#term_%s">%s</a></li>""" % (c.replace(" ", ""), c)
-    azlist = """%s\n</ul></p>""" % azlist
-
-    azlist = """%s\n<p>Properties:""" % azlist
-    azlist += """\n<ul>"""
-    proplist.sort()
-    for p in proplist:
-        azlist += """\n  <li><a href="#term_%s">%s</a></li>""" % (p.replace(" ", ""), p)
-    azlist = """%s\n</ul></p>""" % azlist
-
-    #FIXME: instances
-
-    azlist = """%s\n</div>""" % azlist
+        azlist = """%s</dd>\n""" % azlist
+
+    azlist = """%s\n</dl>""" % azlist
     return azlist
 
@@ -528,4 +528,5 @@
     return classlist, proplist
 
+
 def specProperty(m, subject, predicate):
     "Return the rdfs:comment of the spec."
@@ -534,4 +535,5 @@
             return str(c.object)
     return ''
+
 
 def specAuthors(m, subject):
@@ -542,4 +544,5 @@
             ret += '<div class="author" property="dc:creator">' + j.object.literal_value['string'] + '</div>\n'
     return ret
+
 
 def getInstances(model, classes, properties):
@@ -599,10 +602,5 @@
         instalist.sort(lambda x, y: cmp(getShortName(x).lower(), getShortName(y).lower()))
     
-    if mode == "spec":
-        # Build HTML list of terms.
-        azlist = buildazlist(classlist, proplist, instalist)
-    elif mode == "list":
-        # Build simple <ul> list of terms.
-        azlist = build_simple_list(classlist, proplist, instalist)
+    azlist = buildIndex(classlist, proplist, instalist)
 
     # Generate Term HTML
@@ -623,10 +621,6 @@
     template = re.sub(r"\$VersionInfo\$", owlVersionInfo(m).encode("utf-8"), template) 
     
-    # NOTE: This works with the assumtpion that all "%" in the template are escaped to "%%" and it
-    #       contains the same number of "%s" as the number of parameters in % ( ...parameters here... )
-    template = template % (azlist, termlist.encode("utf-8"));    
-    template += ("<!-- generated from %s by %s at %s -->" %
-        (os.path.basename(specloc), os.path.basename(sys.argv[0]), time.strftime('%X %x %Z')))
-
+    template = template.replace('@INDEX@', azlist)
+    template = template.replace('@REFERENCE@', termlist.encode("utf-8"))
     template = template.replace('@NAME@', specProperty(m, spec_url, doap.name))
     template = template.replace('@URI@', spec_url)
@@ -638,4 +632,7 @@
     template = template.replace('@AUTHORS@', specAuthors(m, spec_url))
     
+    template += ("<!-- generated from %s by %s at %s -->" %
+        (os.path.basename(specloc), os.path.basename(sys.argv[0]), time.strftime('%X %x %Z')))
+    
     return template
 
@@ -648,5 +645,5 @@
         f.close()
     except Exception, e:
-        print "Error writting in file \"" + path + "\": " + str(e)
+        print "Error writing to file \"" + path + "\": " + str(e)
 
 
@@ -695,4 +692,5 @@
 """ % (script, script)
     sys.exit(-1)
+
 
 if __name__ == "__main__":
Index: /trunk/lv2specgen/template.html
===================================================================
--- /trunk/lv2specgen/template.html (revision 2114)
+++ /trunk/lv2specgen/template.html (revision 2118)
@@ -13,4 +13,58 @@
     <meta name="generator" content="lv2specgen" />
     <!--<link rel="stylesheet" type="text/css" href="./style.css" />-->
+    <style type="text/css">
+        
+/* BEGIN STYLE */
+
+body {
+    color: black;
+    background: white;
+}
+
+:link    { color: #00C; background: transparent }
+:visited { color: #609; background: transparent }
+a:active { color: #C00; background: transparent }
+
+h1, h2, h3, h4, h5, h6 { text-align: left; background-color: #eee; padding: 0.25ex }
+h2, h3, h4, h5, h6 { margin-top: 2.5ex; }
+h1, h2, h3 { color: #005A9C; }
+
+.subtitle { margin: 0; padding: 0; font-style: italic }
+.index { padding: 1ex; border: dotted gray 2px; background-color: #eee; }
+
+dl { padding: 0; margin: 0 }
+dt { padding-top: 1ex; font-weight: bold }
+
+hr {
+    color: silver;
+    background-color: silver;
+    height: 1px;
+    border: 0;
+    margin-top: 3ex;
+    margin-bottom: 3ex
+}
+
+div.head { margin-bottom: 1em }
+div.head h1 { margin-top: 2em; clear: both }
+div.head table { margin-left: 2em; margin-top: 2em }
+
+pre { margin-left: 2em }
+/*
+p {
+  margin-top: 0.6em;
+  margin-bottom: 0.6em;
+}
+*/
+
+@media aural {  
+    h1, h2, h3 { stress: 20; richness: 90 }
+    p.copyright { volume: x-soft; speech-rate: x-fast }
+    dt { pause-before: 20% }
+    pre { speak-punctuation: code } 
+}
+
+/* END STYLE */
+
+  </style>
   </head>
   <body>
@@ -30,10 +84,11 @@
   <hr />
   <h2 id="abstract">Abstract</h2>
-  <p>This specification defines the "@NAME@" extension (with URI
-  <a href="@URI@">@URI@</a>) to the
-  <a href="http://lv2plug.in/ns/lv2core">LV2</a> specification.</p>
+  <p>@COMMENT@</p>
+
   <h2 id="status">About this Document</h2>
-  <p>This document is an <a href="http://validator.w3.org/check/referer?outline=1&amp;verbose=1"
-    title="Valid XHTML 1.0 Strict">XHTML+RDFa</a>
+  <p>This document describes &ldquo;@NAME@&rdquo; (<a href="@URI@">@URI@</a>), an extension to
+  <a href="http://lv2plug.in/ns/lv2core">LV2</a>.</p>
+  <p>This is an <a href="http://validator.w3.org/check/referer?outline=1&amp;verbose=1"
+    title="Valid XHTML+RDFa">XHTML+RDFa</a>
   page automatically generated from <a href="./@FILENAME@">@FILENAME@</a> by
   <a href="http://drobilla.net/software/lv2specgen">lv2specgen</a>.
@@ -45,12 +100,8 @@
 
   <p>Comments are welcome, please direct discussion to <a href="mailto:@MAIL@">@MAIL@</a>.</p>
-  <h2 id="contents">Table of Contents</h2>
+  <h2 id="contents">Contents</h2>
   <ol id="toc">
-    <li><a href="#desc">Description</a></li>
     <li><a href="#sec-glance">Index</a></li>
-    <li><a href="#reference">Reference</a></li>
-  </ol>
-  <h3>Appendices</h3>
-  <ol id="appendix">
+    <li><a href="#reference">Documentation</a></li>
     <li><a href="#references">References</a></li>
   </ol>
@@ -58,24 +109,18 @@
   
   <!-- ===================================================================== -->
-  <h2 id="desc">1 Description</h2>
-  <p>@COMMENT@</p>
-  
-  <!-- ===================================================================== -->
-  <h2 id="sec-glance">2. Index</h2>
-  <p>An alphabetical index of @NAME@ terms, by class (concepts) and by property
-  (relationships, attributes), are given below. All the terms are hyperlinked
-  to their detailed description for quick reference.</p>
+  <h2 id="sec-glance">1. Index</h2>
   <!-- The following is the script-generated index -->
-  %s 
+  @INDEX@ 
   <!-- End of the generated index -->
   
   <!-- ===================================================================== -->
-  <h2 id="reference">3. Reference</h2>
+  <h2 id="reference">2. Reference</h2>
   <!-- The following is the script-generated class/property/instance reference -->
-  %s 
+  @REFERENCE@
   <!-- End of the generated reference -->
 
   <!-- ===================================================================== -->
-  <h2 id="references">A References</h2>
+  <hr />
+  <h2 id="references">3. References</h2>
   <dl>
     <dt class="label" id="ref-rfc2119">IETF RFC 2119</dt>
