# Specgen code adapted to be independent of a particular vocabulary (e.g., FOAF) __all__ = [ 'main' ] import sys, time, re, urllib, getopt import RDF foaf = RDF.NS("http://xmlns.com/foaf/0.1/") dc = RDF.NS('http://purl.org/dc/elements/1.1/') 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#') xfoaf = RDF.NS('http://www.foafrealm.org/xfoaf/0.1/') mont = RDF.NS('http://www.marcont.org/ontology/marcont.owl#') # add your namespaces here classranges = {} classdomains = {} termdir = './doc' # namespace for which the spec is being generated. # spec_url = "http://xmlns.com/foaf/0.1/" # spec_pre = "foaf" spec_url = "http://rdfs.org/sioc/ns#" spec_pre = "sioc" spec_ns = RDF.NS(spec_url) ns_list = { "http://xmlns.com/foaf/0.1/" : "foaf", 'http://purl.org/dc/elements/1.1/' : "dc", 'http://purl.org/dc/terms/' : "dcterms", 'http://usefulinc.com/ns/doap#' : 'doap', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' : "rdf", 'http://www.w3.org/2000/01/rdf-schema#' : "rdfs", 'http://www.w3.org/2002/07/owl#' : "owl", 'http://www.w3.org/2001/XMLSchema#' : 'xsd', 'http://www.w3.org/2003/06/sw-vocab-status/ns#' : "status", 'http://purl.org/rss/1.0/modules/content/' : "content", 'http://rdfs.org/sioc/ns#' : "sioc" } def niceName( uri = None ): if uri is None: return regexp = re.compile( "^(.*[/#])([^/#]+)$" ) rez = regexp.search( uri ) pref = rez.group(1) return ns_list.get(pref, pref) + ":" + rez.group(2) def setTermDir(directory): global termdir termdir = directory def termlink(string): """FOAF specific: function which replaces foaf:* with a link to the term in the document.""" return re.sub(r"" + spec_pre + r":(\w+)", r"""""" + spec_pre + r""":\1""", string) def return_name(m, urinode): "Trims the FOAF namespace out of a term to give a name to the term." return str(urinode.uri).replace(spec_url, "") def get_rdfs(m, urinode): "Returns label and comment given an RDF.Node with a URI in it" comment = '' label = '' l = m.find_statements(RDF.Statement(urinode, rdfs.label, None)) if l.current(): label = l.current().object.literal_value['string'] c = m.find_statements(RDF.Statement(urinode, rdfs.comment, None)) if c.current(): comment = c.current().object.literal_value['string'] return label, comment def get_status(m, urinode): "Returns the status text for a term." status = '' s = m.find_statements(RDF.Statement(urinode, vs.term_status, None)) if s.current(): return s.current().object.literal_value['string'] def htmlDocInfo( t ): """Opens a file based on the term name (t) and termdir directory (global). Reads in the file, and returns a linkified version of it.""" doc = "" try: f = open("%s/%s.en" % (termdir, t), "r") doc = f.read() doc = termlink(doc) except: return "" # "

No detailed documentation for this term.

" return doc def owlVersionInfo(m): v = m.find_statements(RDF.Statement(None, owl.versionInfo, None)) if v.current(): return v.current().object.literal_value['string'] else: return "" def rdfsPropertyInfo(term,m): """Generate HTML for properties: Domain, range, status.""" doc = "" range = "" domain = "" # Find subPropertyOf information o = m.find_statements( RDF.Statement(term, rdfs.subPropertyOf, None) ) if o.current(): doc += "\tsub-property-of:" rlist = '' for st in o: k = str( st.object.uri ) if (spec_url in k): k = """%s""" % (k.replace(spec_url, ""), niceName(k)) else: k = """%s""" % (k, niceName(k)) rlist += "%s " % k doc += "\n\t%s\n" % rlist # domain and range stuff (properties only) d = m.find_statements(RDF.Statement(term, rdfs.domain, None)) if d.current(): domain = d.current().object.uri domain = str(domain) else: domain = "" r = m.find_statements(RDF.Statement(term, rdfs.range, None)) if r.current(): range = r.current().object.uri range = str(range) if domain: # NOTE can add a warning of multiple rdfs domains / ranges if (spec_url in domain): domain = """%s""" % (domain.replace(spec_url, ""), niceName(domain)) else: domain = """%s""" % (domain, niceName(domain)) doc += "\tDomain:\n\t%s\n" % domain if range: if (spec_url in range): range = """%s""" % (range.replace(spec_url, ""), niceName(range)) else: range = """%s""" % (range, niceName(range)) doc += "\tRange:\n\t%s\n" % range return doc def rdfsClassInfo(term,m): """Generate rdfs-type information for Classes: ranges, and domains.""" global classranges global classdomains doc = "" # Find subClassOf information o = m.find_statements( RDF.Statement(term, rdfs.subClassOf, None) ) if o.current(): doc += "\tsub-class-of:" rlist = '' for st in o: k = str( st.object.uri ) if (spec_url in k): k = """%s""" % (k.replace(spec_url, ""), niceName(k)) else: k = """%s""" % (k, niceName(k)) rlist += "%s " % k doc += "\n\t%s\n" % rlist # Find out about properties which have rdfs:range of t r = classranges.get(str(term.uri), "") if r: rlist = '' for k in r: if (spec_url in k): k = """%s""" % (k.replace(spec_url, ""), niceName(k)) else: k = """%s""" % (k, niceName(k)) rlist += "%s " % k doc += "in-range-of:"+rlist+"" # Find out about properties which have rdfs:domain of t d = classdomains.get(str(term.uri), "") if d: dlist = '' for k in d: if (spec_url in k): k = """%s""" % (k.replace(spec_url, ""), niceName(k)) else: k = """%s""" % (k, niceName(k)) dlist += "%s " % k doc += "in-domain-of:"+dlist+"" return doc def owlInfo(term,m): """Returns an extra information that is defined about a term (an RDF.Node()) using OWL.""" res = '' # Inverse properties ( owl:inverseOf ) o = m.find_statements( RDF.Statement(term, owl.inverseOf, None) ) if o.current(): res += "\tInverse:" rlist = '' for st in o: k = str( st.object.uri ) if (spec_url in k): k = """%s""" % (k.replace(spec_url, ""), niceName(k)) else: k = """%s""" % (k, niceName(k)) rlist += "%s " % k res += "\n\t%s\n" % rlist # Datatype Property ( owl.DatatypeProperty ) o = m.find_statements( RDF.Statement(term, rdf.type, owl.DatatypeProperty) ) if o.current(): res += "\tOWL Type:\n\tDatatypeProperty\n" # Object Property ( owl.ObjectProperty ) o = m.find_statements( RDF.Statement(term, rdf.type, owl.ObjectProperty) ) if o.current(): res += "\tOWL Type:\n\tObjectProperty\n" # IFPs ( owl.InverseFunctionalProperty ) o = m.find_statements( RDF.Statement(term, rdf.type, owl.InverseFunctionalProperty) ) if o.current(): res += "\tOWL Type:\n\tInverseFunctionalProperty (uniquely identifying property)\n" # Symmertic Property ( owl.SymmetricProperty ) o = m.find_statements( RDF.Statement(term, rdf.type, owl.SymmetricProperty) ) if o.current(): res += "\tOWL Type:\n\tSymmetricProperty\n" return res def docTerms(category, list, m): """A wrapper class for listing all the terms in a specific class (either Properties, or Classes. Category is 'Property' or 'Class', list is a list of term names (strings), return value is a chunk of HTML.""" doc = "" nspre = spec_pre for t in list: term = spec_ns[t] doc += """
\n

%s: %s:%s

\n""" % (t, category, nspre, t) label, comment = get_rdfs(m, term) status = get_status(m, term) doc += "

%s - %s

" % (label, comment) # doc += """\n\t\n""" % status doc += """
\n""" doc += owlInfo(term,m) if category=='Property': doc += rdfsPropertyInfo(term,m) if category=='Class': doc += rdfsClassInfo(term,m) doc += "
\n" doc += htmlDocInfo(t) doc += "

[back to top]

\n\n" doc += "\n
\n
\n\n" return doc def buildazlist(classlist, proplist): """Builds the A-Z list of terms. Args are a list of classes (strings) and a list of props (strings)""" azlist = """
""" azlist = """%s\n

Classes: |""" % azlist classlist.sort() for c in classlist: azlist = """%s %s | """ % (azlist, c.replace(" ", ""), c) azlist = """%s\n

""" % azlist azlist = """%s\n

Properties: |""" % azlist proplist.sort() for p in proplist: azlist = """%s %s | """ % (azlist, p.replace(" ", ""), p) azlist = """%s\n

""" % azlist azlist = """%s\n
""" % azlist return azlist def build_simple_list(classlist, proplist): """Builds a simple