Add phpspecgen, improve HTML output.
authorMo McRoberts <mo.mcroberts@bbc.co.uk>
Mon, 09 Sep 2013 21:03:58 +0100
changeset 20 7eb74bbe9931
parent 19 9bb7b2b9b9da
child 21 c8b4f86a87ad
Add phpspecgen, improve HTML output.
2/Makefile
2/ODRL20.html
2/template.phtml
classes.php
phpspecgen.php
--- a/2/Makefile	Mon Sep 09 21:02:53 2013 +0100
+++ b/2/Makefile	Mon Sep 09 21:03:58 2013 +0100
@@ -4,7 +4,7 @@
 
 NSURI = http://www.w3.org/ns/odrl/2/
 
-ALL = ODRL20.rdf ODRL20.nt
+ALL = ODRL20.rdf ODRL20.nt ODRL20.html
 
 all: $(ALL)
 
--- a/2/ODRL20.html	Mon Sep 09 21:02:53 2013 +0100
+++ b/2/ODRL20.html	Mon Sep 09 21:03:58 2013 +0100
@@ -19,7 +19,7 @@
 </dl>
 <h2 id="sec-toc">Table of Contents</h2><ol class="toc"><li><a href="#sec-summary"><span class="secno">1</span> Summary of Terms</a></li><li><a href="#sec-classes"><span class="secno">2</span> Classes</a></li><li><a href="#sec-properties"><span class="secno">3</span> Properties</a></li><li><a href="#sec-concept-schemes"><span class="secno">4</span> Concept schemes</a></li><li><a href="#sec-concepts"><span class="secno">5</span> Concepts</a></li><li><a href="#sec-named-individuals"><span class="secno">6</span> Named individuals</a></li></ol><h2 id="sec-summary">Summary of Terms</h2>
 <p>This vocabulary defines 19 classes, 53 properties, 2 concept schemes, 60 concepts and 17 named individuals.</p>
-<dl><dt>Classes</dt><dd><a href="#term-Asset">Asset</a> | <a href="#term-Party">Party</a> | <a href="#term-Scope">Scope</a> | <a href="#term-Policy">Policy</a> | <a href="#term-ConflictTerm">ConflictTerm</a> | <a href="#term-UndefinedTerm">UndefinedTerm</a> | <a href="#term-Rule">Rule</a> | <a href="#term-Permission">Permission</a> | <a href="#term-Prohibition">Prohibition</a> | <a href="#term-Duty">Duty</a> | <a href="#term-Action">Action</a> | <a href="#term-Constraint">Constraint</a> | <a href="#term-Operator">Operator</a> | <a href="#term-Agreement">Agreement</a> | <a href="#term-Offer">Offer</a> | <a href="#term-Privacy">Privacy</a> | <a href="#term-Request">Request</a> | <a href="#term-Set">Set</a> | <a href="#term-Ticket">Ticket</a></dd><dt>Properties</dt><dd><a href="#term-scope">scope</a> | <a href="#term-conflict">conflict</a> | <a href="#term-undefined">undefined</a> | <a href="#term-permission">permission</a> | <a href="#term-prohibition">prohibition</a> | <a href="#term-inheritAllowed">inheritAllowed</a> | <a href="#term-inheritFrom">inheritFrom</a> | <a href="#term-relation">relation</a> | <a href="#term-output">output</a> | <a href="#term-target">target</a> | <a href="#term-function">function</a> | <a href="#term-action">action</a> | <a href="#term-constraint">constraint</a> | <a href="#term-duty">duty</a> | <a href="#term-unit">unit</a> | <a href="#term-operator">operator</a> | <a href="#term-rightOperand">rightOperand</a> | <a href="#term-status">status</a> | <a href="#term-absolutePosition">absolutePosition</a> | <a href="#term-absoluteSize">absoluteSize</a> | <a href="#term-count">count</a> | <a href="#term-dateTime">dateTime</a> | <a href="#term-deliveryChannel">deliveryChannel</a> | <a href="#term-device">device</a> | <a href="#term-elapsedTime">elapsedTime</a> | <a href="#term-event">event</a> | <a href="#term-fileFormat">fileFormat</a> | <a href="#term-industry">industry</a> | <a href="#term-language">language</a> | <a href="#term-media">media</a> | <a href="#term-meteredTime">meteredTime</a> | <a href="#term-payAmount">payAmount</a> | <a href="#term-percentage">percentage</a> | <a href="#term-product">product</a> | <a href="#term-proximity">proximity</a> | <a href="#term-purpose">purpose</a> | <a href="#term-recipient">recipient</a> | <a href="#term-relativePosition">relativePosition</a> | <a href="#term-relativeSize">relativeSize</a> | <a href="#term-resolution">resolution</a> | <a href="#term-spatial">spatial</a> | <a href="#term-system">system</a> | <a href="#term-timedCount">timedCount</a> | <a href="#term-timeInterval">timeInterval</a> | <a href="#term-version">version</a> | <a href="#term-virtualLocation">virtualLocation</a> | <a href="#term-assignee">assignee</a> | <a href="#term-assigner">assigner</a> | <a href="#term-attributedParty">attributedParty</a> | <a href="#term-consentingParty">consentingParty</a> | <a href="#term-informedParty">informedParty</a> | <a href="#term-payeeParty">payeeParty</a> | <a href="#term-trackingParty">trackingParty</a></dd><dt>Concept schemes</dt><dd><a href="#term-actions">actions</a> | <a href="#term-scopes">scopes</a></dd><dt>Concepts</dt><dd><a href="#term-acceptTracking">acceptTracking</a> | <a href="#term-adHocShare">adHocShare</a> | <a href="#term-aggregate">aggregate</a> | <a href="#term-annotate">annotate</a> | <a href="#term-anonymize">anonymize</a> | <a href="#term-append">append</a> | <a href="#term-archive">archive</a> | <a href="#term-attachPolicy">attachPolicy</a> | <a href="#term-attachSource">attachSource</a> | <a href="#term-attribute">attribute</a> | <a href="#term-commercialize">commercialize</a> | <a href="#term-concurrentUse">concurrentUse</a> | <a href="#term-copy">copy</a> | <a href="#term-delete">delete</a> | <a href="#term-derive">derive</a> | <a href="#term-display">display</a> | <a href="#term-distribute">distribute</a> | <a href="#term-ensureExclusivity">ensureExclusivity</a> | <a href="#term-execute">execute</a> | <a href="#term-export">export</a> | <a href="#term-extract">extract</a> | <a href="#term-extractChar">extractChar</a> | <a href="#term-extractPage">extractPage</a> | <a href="#term-extractWord">extractWord</a> | <a href="#term-give">give</a> | <a href="#term-include">include</a> | <a href="#term-index">index</a> | <a href="#term-inform">inform</a> | <a href="#term-install">install</a> | <a href="#term-lease">lease</a> | <a href="#term-license">license</a> | <a href="#term-lend">lend</a> | <a href="#term-modify">modify</a> | <a href="#term-move">move</a> | <a href="#term-nextPolicy">nextPolicy</a> | <a href="#term-obtainConsent">obtainConsent</a> | <a href="#term-pay">pay</a> | <a href="#term-play">play</a> | <a href="#term-present">present</a> | <a href="#term-preview">preview</a> | <a href="#term-print">print</a> | <a href="#term-read">read</a> | <a href="#term-reproduce">reproduce</a> | <a href="#term-reviewPolicy">reviewPolicy</a> | <a href="#term-secondaryUse">secondaryUse</a> | <a href="#term-sell">sell</a> | <a href="#term-share">share</a> | <a href="#term-shareAlike">shareAlike</a> | <a href="#term-textToSpeech">textToSpeech</a> | <a href="#term-transform">transform</a> | <a href="#term-translate">translate</a> | <a href="#term-uninstall">uninstall</a> | <a href="#term-watermark">watermark</a> | <a href="#term-write">write</a> | <a href="#term-all">all</a> | <a href="#term-all2ndConnections">all2ndConnections</a> | <a href="#term-allConnections">allConnections</a> | <a href="#term-allGroups">allGroups</a> | <a href="#term-group">group</a> | <a href="#term-individual">individual</a></dd><dt>Named individuals</dt><dd><a href="#term-perm">perm</a> | <a href="#term-prohibit">prohibit</a> | <a href="#term-ignore">ignore</a> | <a href="#term-invalid">invalid</a> | <a href="#term-support">support</a> | <a href="#term-eq">eq</a> | <a href="#term-gt">gt</a> | <a href="#term-gteq">gteq</a> | <a href="#term-hasPart">hasPart</a> | <a href="#term-isA">isA</a> | <a href="#term-isAllOf">isAllOf</a> | <a href="#term-isAnyOf">isAnyOf</a> | <a href="#term-isNoneOf">isNoneOf</a> | <a href="#term-isPartOf">isPartOf</a> | <a href="#term-lt">lt</a> | <a href="#term-lteq">lteq</a> | <a href="#term-neq">neq</a></dd></dl><h2 id="sec-classes">Classes</h2>
+<dl><dt>Classes</dt><dd><a href="#term-Action">Action</a> | <a href="#term-Agreement">Agreement</a> | <a href="#term-Asset">Asset</a> | <a href="#term-ConflictTerm">ConflictTerm</a> | <a href="#term-Constraint">Constraint</a> | <a href="#term-Duty">Duty</a> | <a href="#term-Offer">Offer</a> | <a href="#term-Operator">Operator</a> | <a href="#term-Party">Party</a> | <a href="#term-Permission">Permission</a> | <a href="#term-Policy">Policy</a> | <a href="#term-Privacy">Privacy</a> | <a href="#term-Prohibition">Prohibition</a> | <a href="#term-Request">Request</a> | <a href="#term-Rule">Rule</a> | <a href="#term-Scope">Scope</a> | <a href="#term-Set">Set</a> | <a href="#term-Ticket">Ticket</a> | <a href="#term-UndefinedTerm">UndefinedTerm</a></dd><dt>Properties</dt><dd><a href="#term-absolutePosition">absolutePosition</a> | <a href="#term-absoluteSize">absoluteSize</a> | <a href="#term-action">action</a> | <a href="#term-assignee">assignee</a> | <a href="#term-assigner">assigner</a> | <a href="#term-attributedParty">attributedParty</a> | <a href="#term-conflict">conflict</a> | <a href="#term-consentingParty">consentingParty</a> | <a href="#term-constraint">constraint</a> | <a href="#term-count">count</a> | <a href="#term-dateTime">dateTime</a> | <a href="#term-deliveryChannel">deliveryChannel</a> | <a href="#term-device">device</a> | <a href="#term-duty">duty</a> | <a href="#term-elapsedTime">elapsedTime</a> | <a href="#term-event">event</a> | <a href="#term-fileFormat">fileFormat</a> | <a href="#term-function">function</a> | <a href="#term-industry">industry</a> | <a href="#term-informedParty">informedParty</a> | <a href="#term-inheritAllowed">inheritAllowed</a> | <a href="#term-inheritFrom">inheritFrom</a> | <a href="#term-language">language</a> | <a href="#term-media">media</a> | <a href="#term-meteredTime">meteredTime</a> | <a href="#term-operator">operator</a> | <a href="#term-output">output</a> | <a href="#term-payeeParty">payeeParty</a> | <a href="#term-payAmount">payAmount</a> | <a href="#term-percentage">percentage</a> | <a href="#term-permission">permission</a> | <a href="#term-product">product</a> | <a href="#term-prohibition">prohibition</a> | <a href="#term-proximity">proximity</a> | <a href="#term-purpose">purpose</a> | <a href="#term-recipient">recipient</a> | <a href="#term-relation">relation</a> | <a href="#term-relativePosition">relativePosition</a> | <a href="#term-relativeSize">relativeSize</a> | <a href="#term-resolution">resolution</a> | <a href="#term-rightOperand">rightOperand</a> | <a href="#term-scope">scope</a> | <a href="#term-spatial">spatial</a> | <a href="#term-status">status</a> | <a href="#term-system">system</a> | <a href="#term-target">target</a> | <a href="#term-timeInterval">timeInterval</a> | <a href="#term-timedCount">timedCount</a> | <a href="#term-trackingParty">trackingParty</a> | <a href="#term-undefined">undefined</a> | <a href="#term-unit">unit</a> | <a href="#term-version">version</a> | <a href="#term-virtualLocation">virtualLocation</a></dd><dt>Concept schemes</dt><dd><a href="#term-actions">actions</a> | <a href="#term-scopes">scopes</a></dd><dt>Concepts</dt><dd><a href="#term-acceptTracking">acceptTracking</a> | <a href="#term-adHocShare">adHocShare</a> | <a href="#term-aggregate">aggregate</a> | <a href="#term-all">all</a> | <a href="#term-allConnections">allConnections</a> | <a href="#term-allGroups">allGroups</a> | <a href="#term-all2ndConnections">all2ndConnections</a> | <a href="#term-annotate">annotate</a> | <a href="#term-anonymize">anonymize</a> | <a href="#term-append">append</a> | <a href="#term-archive">archive</a> | <a href="#term-attachPolicy">attachPolicy</a> | <a href="#term-attachSource">attachSource</a> | <a href="#term-attribute">attribute</a> | <a href="#term-commercialize">commercialize</a> | <a href="#term-concurrentUse">concurrentUse</a> | <a href="#term-copy">copy</a> | <a href="#term-delete">delete</a> | <a href="#term-derive">derive</a> | <a href="#term-display">display</a> | <a href="#term-distribute">distribute</a> | <a href="#term-ensureExclusivity">ensureExclusivity</a> | <a href="#term-execute">execute</a> | <a href="#term-export">export</a> | <a href="#term-extract">extract</a> | <a href="#term-extractChar">extractChar</a> | <a href="#term-extractPage">extractPage</a> | <a href="#term-extractWord">extractWord</a> | <a href="#term-give">give</a> | <a href="#term-group">group</a> | <a href="#term-include">include</a> | <a href="#term-index">index</a> | <a href="#term-individual">individual</a> | <a href="#term-inform">inform</a> | <a href="#term-install">install</a> | <a href="#term-lease">lease</a> | <a href="#term-lend">lend</a> | <a href="#term-license">license</a> | <a href="#term-modify">modify</a> | <a href="#term-move">move</a> | <a href="#term-nextPolicy">nextPolicy</a> | <a href="#term-obtainConsent">obtainConsent</a> | <a href="#term-pay">pay</a> | <a href="#term-play">play</a> | <a href="#term-present">present</a> | <a href="#term-preview">preview</a> | <a href="#term-print">print</a> | <a href="#term-read">read</a> | <a href="#term-reproduce">reproduce</a> | <a href="#term-reviewPolicy">reviewPolicy</a> | <a href="#term-secondaryUse">secondaryUse</a> | <a href="#term-sell">sell</a> | <a href="#term-share">share</a> | <a href="#term-shareAlike">shareAlike</a> | <a href="#term-textToSpeech">textToSpeech</a> | <a href="#term-transform">transform</a> | <a href="#term-translate">translate</a> | <a href="#term-uninstall">uninstall</a> | <a href="#term-watermark">watermark</a> | <a href="#term-write">write</a></dd><dt>Named individuals</dt><dd><a href="#term-eq">eq</a> | <a href="#term-gt">gt</a> | <a href="#term-gteq">gteq</a> | <a href="#term-hasPart">hasPart</a> | <a href="#term-ignore">ignore</a> | <a href="#term-invalid">invalid</a> | <a href="#term-isA">isA</a> | <a href="#term-isAllOf">isAllOf</a> | <a href="#term-isAnyOf">isAnyOf</a> | <a href="#term-isNoneOf">isNoneOf</a> | <a href="#term-isPartOf">isPartOf</a> | <a href="#term-lt">lt</a> | <a href="#term-lteq">lteq</a> | <a href="#term-neq">neq</a> | <a href="#term-perm">perm</a> | <a href="#term-prohibit">prohibit</a> | <a href="#term-support">support</a></dd></dl><h2 id="sec-classes">Classes</h2>
 <h3 id="term-Asset">Asset</h3
 <p>Asset is anything which can be subject to a policy. Asserting that something the target of a policy implies that it is an Asset.</p>
 <table>
@@ -44,6 +44,7 @@
 <tr><th>Label:</th> <td>Scope</td></tr>
 <tr><th>Status:</th> <td>testing</td></tr>
 <tr><th>Parent class:</th> <td><a href="http://www.w3.org/2004/02/skos/core#Concept">skos:Concept</a></td></tr>
+<tr><th>Instances:</th> <td><a href="#term-all">all</a>, <a href="#term-all2ndConnections">all2ndConnections</a>, <a href="#term-allConnections">allConnections</a>, <a href="#term-allGroups">allGroups</a>, <a href="#term-group">group</a>, <a href="#term-individual">individual</a></td></tr>
 </table>
 </div>
 <h3 id="term-Policy">Policy</h3
@@ -63,6 +64,7 @@
   <tr><th>URI:</th> <td><a href="http://www.w3.org/ns/odrl/2/ConflictTerm">http://www.w3.org/ns/odrl/2/ConflictTerm</a></td></tr>
 <tr><th>Label:</th> <td>Conflict term</td></tr>
 <tr><th>Status:</th> <td>testing</td></tr>
+<tr><th>Instances:</th> <td><a href="#term-perm">perm</a>, <a href="#term-prohibit">prohibit</a>, <a href="#term-invalid">invalid</a></td></tr>
 </table>
 </div>
 <h3 id="term-UndefinedTerm">UndefinedTerm</h3
@@ -71,6 +73,7 @@
   <tr><th>URI:</th> <td><a href="http://www.w3.org/ns/odrl/2/UndefinedTerm">http://www.w3.org/ns/odrl/2/UndefinedTerm</a></td></tr>
 <tr><th>Label:</th> <td>Undefined values</td></tr>
 <tr><th>Status:</th> <td>testing</td></tr>
+<tr><th>Instances:</th> <td><a href="#term-ignore">ignore</a>, <a href="#term-invalid">invalid</a>, <a href="#term-support">support</a></td></tr>
 </table>
 </div>
 <h3 id="term-Rule">Rule</h3
@@ -122,6 +125,7 @@
 <tr><th>Status:</th> <td>testing</td></tr>
 <tr><th>Parent class:</th> <td><a href="http://www.w3.org/2004/02/skos/core#Concept">skos:Concept</a></td></tr>
 <tr><th>Properties:</th> <td><a href="#term-relation">relation</a>, <a href="#term-output">output</a>, <a href="#term-target">target</a></td></tr>
+<tr><th>Instances:</th> <td><a href="#term-acceptTracking">acceptTracking</a>, <a href="#term-adHocShare">adHocShare</a>, <a href="#term-aggregate">aggregate</a>, <a href="#term-annotate">annotate</a>, <a href="#term-anonymize">anonymize</a>, <a href="#term-append">append</a>, <a href="#term-archive">archive</a>, <a href="#term-attachPolicy">attachPolicy</a>, <a href="#term-attachSource">attachSource</a>, <a href="#term-attribute">attribute</a>, <a href="#term-commercialize">commercialize</a>, <a href="#term-concurrentUse">concurrentUse</a>, <a href="#term-copy">copy</a>, <a href="#term-delete">delete</a>, <a href="#term-derive">derive</a>, <a href="#term-display">display</a>, <a href="#term-distribute">distribute</a>, <a href="#term-ensureExclusivity">ensureExclusivity</a>, <a href="#term-execute">execute</a>, <a href="#term-export">export</a>, <a href="#term-extract">extract</a>, <a href="#term-extractChar">extractChar</a>, <a href="#term-extractPage">extractPage</a>, <a href="#term-extractWord">extractWord</a>, <a href="#term-give">give</a>, <a href="#term-include">include</a>, <a href="#term-index">index</a>, <a href="#term-inform">inform</a>, <a href="#term-install">install</a>, <a href="#term-lease">lease</a>, <a href="#term-license">license</a>, <a href="#term-lend">lend</a>, <a href="#term-modify">modify</a>, <a href="#term-move">move</a>, <a href="#term-nextPolicy">nextPolicy</a>, <a href="#term-obtainConsent">obtainConsent</a>, <a href="#term-pay">pay</a>, <a href="#term-play">play</a>, <a href="#term-present">present</a>, <a href="#term-preview">preview</a>, <a href="#term-print">print</a>, <a href="#term-read">read</a>, <a href="#term-reproduce">reproduce</a>, <a href="#term-reviewPolicy">reviewPolicy</a>, <a href="#term-secondaryUse">secondaryUse</a>, <a href="#term-sell">sell</a>, <a href="#term-share">share</a>, <a href="#term-shareAlike">shareAlike</a>, <a href="#term-textToSpeech">textToSpeech</a>, <a href="#term-transform">transform</a>, <a href="#term-translate">translate</a>, <a href="#term-uninstall">uninstall</a>, <a href="#term-watermark">watermark</a>, <a href="#term-write">write</a></td></tr>
 </table>
 </div>
 <h3 id="term-Constraint">Constraint</h3
@@ -141,6 +145,7 @@
 <tr><th>Label:</th> <td>Operator</td></tr>
 <tr><th>Status:</th> <td>testing</td></tr>
 <tr><th>Parent class:</th> <td><a href="http://www.w3.org/2002/07/owl#Thing">owl:Thing</a></td></tr>
+<tr><th>Instances:</th> <td><a href="#term-eq">eq</a>, <a href="#term-gt">gt</a>, <a href="#term-gteq">gteq</a>, <a href="#term-hasPart">hasPart</a>, <a href="#term-isA">isA</a>, <a href="#term-isAllOf">isAllOf</a>, <a href="#term-isAnyOf">isAnyOf</a>, <a href="#term-isNoneOf">isNoneOf</a>, <a href="#term-isPartOf">isPartOf</a>, <a href="#term-lt">lt</a>, <a href="#term-lteq">lteq</a>, <a href="#term-neq">neq</a></td></tr>
 </table>
 </div>
 <h3 id="term-Agreement">Agreement</h3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2/template.phtml	Mon Sep 09 21:03:58 2013 +0100
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title><?php echo htmlspecialchars($vocab->label()); ?></title>
+	<link rel="stylesheet" type="text/css" href="http://www.w3.org/StyleSheets/TR/w3c-unofficial">
+	<link rel="stylesheet" type="text/css" href="local.css">
+</head>
+<body>
+    <div class="container">
+
+<?php
+
+print $vocab->htmlHeader();
+echo '<h2 id="sec-toc">Table of Contents</h2>';
+echo '<ol class="toc">';
+echo '<li><a href="#sec-summary"><span class="secno">1</span> Summary of Terms</a></li>';
+echo '<li><a href="#sec-classes"><span class="secno">2</span> Classes</a></li>';
+echo '<li><a href="#sec-properties"><span class="secno">3</span> Properties</a></li>';
+echo '<li><a href="#sec-concept-schemes"><span class="secno">4</span> Concept schemes</a></li>';
+echo '<li><a href="#sec-concepts"><span class="secno">5</span> Concepts</a></li>';
+echo '<li><a href="#sec-named-individuals"><span class="secno">6</span> Named individuals</a></li>';
+echo '</ol>';
+
+print $vocab->htmlSummaryOfTerms();
+print $vocab->htmlTerms('Phpspecgen_Class', 'Classes');
+print $vocab->htmlTerms('Phpspecgen_Property', 'Properties');
+print $vocab->htmlTerms('Phpspecgen_ConceptScheme', 'Concept schemes');
+print $vocab->htmlTerms('Phpspecgen_Concept', 'Concepts');
+print $vocab->htmlTerms('Phpspecgen_Individual', 'Named individuals');
+
+?>
+    </div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes.php	Mon Sep 09 21:03:58 2013 +0100
@@ -0,0 +1,331 @@
+<?php
+
+    class Phpspecgen_Term extends EasyRdf_Resource
+    {
+        public function termLink() {
+            $name = htmlspecialchars($this->localName());
+            return "<a href=\"#term-$name\">$name</a>";
+        }
+
+        public function propertyList($property, $skip = null) {
+            $items = array();
+			if(!is_array($skip))
+			{
+				$skip = array();
+			}
+            foreach ($this->all($property) as $value) {
+				if(in_array(strval($value), $skip))
+				{
+					continue;
+				}
+                if ($value instanceof Phpspecgen_Term) {
+                    array_push($items, $value->termLink());
+                } else if ($value instanceof EasyRdf_Resource) {
+                    array_push($items, $value->htmlLink($value->shorten()));
+                } else {
+                    array_push($items, strval($value));
+                }
+            }
+            return $items;
+        }
+
+        public function propertyRow($title, $property, $skip = null) {
+            $items = $this->propertyList($property, $skip);
+            if (count($items) > 0) {
+                return "<tr><th>$title:</th> <td>".implode(', ', $items)."</td></tr>\n";
+            } else {
+                return '';
+            }
+        }
+    }
+
+    class Phpspecgen_Class extends Phpspecgen_Term
+    {
+        public function termType() {
+            return 'Class';
+        }
+
+        public function inheritedProperties() {
+            $properties = array();
+            foreach ($this->allParents() as $parent) {
+                foreach($parent->all('^rdfs:domain') as $property) {
+                    if ($property instanceof Phpspecgen_Term) {
+                        array_push($properties, $property->termLink());
+                    }
+                }
+            }
+            return $properties;
+        }
+
+        protected function allParents($depth=0) {
+            $parents = array();
+            foreach ($this->all('rdfs:subClassOf') as $parent) {
+                if (!$parent instanceof Phpspecgen_Class)
+                    continue;
+                array_push($parents, $parent);
+                if ($depth < 10)
+                    $parents = array_merge($parents, $parent->allParents($depth));
+            }
+            return $parents;
+        }
+    }
+
+    class Phpspecgen_Property extends Phpspecgen_Term
+    {
+        public function termType() {
+            return 'Property';
+        }
+    }
+
+    class Phpspecgen_ConceptScheme extends Phpspecgen_Term
+    {
+        public function termType() {
+            return 'Concept scheme';
+        }
+    }
+
+    class Phpspecgen_Individual extends Phpspecgen_Term
+    {
+        public function termType() {
+            return 'Named individual';
+        }
+    }
+
+    class Phpspecgen_Concept extends Phpspecgen_Term
+    {
+        public function termType() {
+            return 'Concept';
+        }
+    }
+
+    class Phpspecgen_Vocab extends EasyRdf_Resource
+    {
+        protected function propertyDefinition($title, $property) {
+            $values = $this->all($property);
+            if (count($values) < 1)
+                return '';
+
+            $html = array();
+            foreach($values as $value) {
+                if ($value instanceof EasyRdf_Literal) {
+                    array_push($html, htmlspecialchars($value));
+                } else if ($value->get('foaf:homepage')) {
+                    array_push($html, $value->get('foaf:homepage')->htmlLink( $value->label() ));
+                } else {
+                    if ($value->isBnode()) {
+                        array_push($html, htmlspecialchars($value->label()) );
+                    } else {
+                        array_push($html, $value->htmlLink($value->label()) );
+                    }
+                }
+            }
+
+            return "<dt>$title</dt><dd>".implode(', ', array_unique($html))."</dd>\n";
+        }
+
+        public function htmlHeader() {
+            $html = "<h1>".htmlspecialchars($this->label())."</h1>\n";
+            $html .= "<em>".htmlspecialchars($this->get('dc:description|dc11:description|rdfs:comment'))."</em>\n";
+
+            $html .= "<dl>\n";
+            $html .= "<dt>Latest Version</dt><dd>".$this->htmlLink()."</dd>\n";
+            $html .= $this->propertyDefinition('Created', 'dc:created|dc11:created');
+            $html .= $this->propertyDefinition('Date', 'dc:date|dc11:date');
+            $html .= $this->propertyDefinition('Revision', 'owl:versionInfo');
+            $html .= $this->propertyDefinition('Authors', 'foaf:maker|dc:creator|dc11:creator');
+            $html .= $this->propertyDefinition('Contributors', 'dc:contributor|dc11:contributor');
+            $html .= "</dl>\n";
+            return $html;
+        }
+
+        public function htmlSummaryOfTerms() {
+            $html = "<h2 id=\"sec-summary\">Summary of Terms</h2>\n";
+			$classes = array();
+            $classCount = 0;
+			$props = array();
+            $propertyCount = 0;
+			$schemes = array();
+			$schemeCount = 0;
+			$concepts = array();
+			$conceptCount = 0;
+			$individuals = array();
+			$individualCount = 0;
+            foreach($this->all("^rdfs:isDefinedBy") as $term) {				
+				if(method_exists($term, 'label'))
+				{
+					$k = strval($term->label());
+				}
+				else
+				{
+					$k = strval($term->localName());
+				}
+                if ($term instanceof Phpspecgen_Class)
+				{
+					$classes[$k] = $term->termLink();
+                    $classCount++;
+				}
+                else if ($term instanceof Phpspecgen_Property)
+				{
+					$props[$k] = $term->termLink();
+                    $propertyCount++;
+				}
+				else if ($term instanceof Phpspecgen_ConceptScheme)
+				{
+					$schemes[$k] = $term->termLink();
+					$schemeCount++;
+				}
+				else if ($term instanceof Phpspecgen_Concept)
+				{
+					$concepts[$k] = $term->termLink();
+					$conceptCount++;
+				}
+				else if ($term instanceof Phpspecgen_Individual)
+				{
+					$individuals[$k] = $term->termLink();
+					$individualCount++;
+				}
+            }
+			ksort($classes);
+			ksort($props);
+			ksort($schemes);
+			ksort($concepts);
+			ksort($individuals);
+            $html .= "<p>This vocabulary defines ";
+			$counts = array();
+			if($classCount > 0)
+			{
+				$counts[] = ($classCount == 1 ? 'one class' : ($classCount . ' classes'));
+			}
+			if($propertyCount > 0)
+			{
+				$counts[] = ($propertyCount == 1 ? 'one property' : ($propertyCount . ' properties'));
+			}
+			if($schemeCount > 0)
+			{
+				$counts[] = ($schemeCount == 1 ? 'one concept scheme' : ($schemeCount . ' concept schemes'));
+			}
+			if($conceptCount > 0)
+			{
+				$counts[] = ($conceptCount == 1 ? 'one concept' : ($conceptCount . ' concepts'));
+			}
+			if($individualCount > 0)
+			{
+				$counts[] = ($individualCount == 1 ? 'one named individual' : ($individualCount . ' named individuals'));
+			}
+			$sub = array_slice($counts, 0, -1);
+			if(count($counts) > 1)
+			{
+				$last = ' and ' . array_pop($counts);
+			}
+			else
+			{
+				$last = '';
+			}
+			$html .= implode(', ', $sub) . $last . '.'; 
+            $html .= "</p>\n";
+
+			$html .= '<dl>';
+			if($classCount)
+			{
+				$html .= '<dt>Classes</dt>';
+				$html .= '<dd>' . implode(' | ', $classes) . '</dd>';
+			}
+			if($propertyCount)
+			{
+				$html .= '<dt>Properties</dt>';
+				$html .= '<dd>' . implode(' | ', $props) . '</dd>';
+			}
+			if($schemeCount)
+			{
+				$html .= '<dt>Concept schemes</dt>';
+				$html .= '<dd>' . implode(' | ', $schemes) . '</dd>';
+			}
+			if($conceptCount)
+			{
+				$html .= '<dt>Concepts</dt>';
+				$html .= '<dd>' . implode(' | ', $concepts) . '</dd>';
+			}
+			if($individualCount)
+			{
+				$html .= '<dt>Named individuals</dt>';
+				$html .= '<dd>' . implode(' | ', $individuals) . '</dd>';
+			}
+			$html .= '</dl>';
+/*
+            $html .= "<table>\n";
+            $html .= "<tr><th>Term Name</th><th>Type</th><th>Definition</th></tr>\n";
+            foreach($this->all("^rdfs:isDefinedBy") as $term) {
+                if ($term instanceof Phpspecgen_Term) {
+                    $html .= "<tr>";
+                    $html .= "<td>".$term->termLink()."</td>";
+                    $html .= "<td>".$term->termType()."</td>";
+                    $html .= "<td>".$term->getLiteral('rdfs:comment|rdfs:label')."</td>";
+                    $html .= "</tr>\n";
+                }
+            }
+            $html .= "</table>\n";
+*/
+            return $html;
+        }
+
+        public function htmlTerms($type, $title) {
+            $html = '';
+            $id = strtolower(str_replace(' ','-',$title));
+            $html .= "<h2 id=\"sec-$id\">$title</h2>\n";
+            foreach($this->all("^rdfs:isDefinedBy") as $term) {
+                if (!$term instanceof $type)
+                    continue;
+
+                $name = htmlspecialchars($term->localName());
+                $html .= "<h3 id=\"term-$name\">$name</h3\n";
+                $html .= "<p>".htmlspecialchars($term->get('rdfs:comment'))."</p>\n";
+                $html .= "<table>\n";
+                $html .= "  <tr><th>URI:</th> <td>".$term->htmlLink()."</td></tr>\n";
+                $html .= $term->propertyRow("Label", "rdfs:label");
+                $html .= $term->propertyRow("Status", "vs:term_status");
+                $html .= $term->propertyRow("Subclasses", "^rdfs:subClassOf");
+                $html .= $term->propertyRow("Subproperties", "^rdfs:subPropertyOf");
+                $html .= $term->propertyRow("Parent class", "rdfs:subClassOf");
+                $html .= $term->propertyRow("Parent property", "rdfs:subPropertyOf");
+                $html .= $term->propertyRow("Properties", "^rdfs:domain");
+                if ($term instanceof Phpspecgen_Class) {
+                    $properties = $term->inheritedProperties();
+                    if (count($properties) > 0)
+                        $html .= "  <tr><th>Inherited Properties:</th> ".
+                                 "<td>".join(', ', $properties)."</td></tr>\n";
+                }
+                $html .= $term->propertyRow("Range", "rdfs:range");
+                $html .= $term->propertyRow("Domain", "rdfs:domain");
+				$html .= $term->propertyRow('Instances', '^rdf:type');
+                $html .= $term->propertyRow("See Also", "rdfs:seeAlso");
+				if($term instanceof Phpspecgen_Individual || $term instanceof Phpspecgen_Concept)
+				{
+					$html .= $term->propertyRow('Class', 'rdf:type', array('http://www.w3.org/2004/02/skos/core#Concept', 'http://www.w3.org/2002/07/owl#NamedIndividual'));
+				}
+				$html .= $term->propertyRow('Concepts', 'skos:hasTopConcept');
+				$html .= $term->propertyRow('Concept scheme', '^skos:hasTopConcept');
+                $html .= "</table>\n";
+                $html .= "</div>\n";
+            }
+            return $html;
+        }
+
+    }
+
+    # Extra namespaces we use
+    EasyRdf_Namespace::set('vann', 'http://purl.org/vocab/vann/');
+    EasyRdf_Namespace::set('vs', 'http://www.w3.org/2003/06/sw-vocab-status/ns#');
+
+    ## Add mappings
+    EasyRdf_TypeMapper::set('owl:Ontology', 'Phpspecgen_Vocab');
+    EasyRdf_TypeMapper::set('owl:Class', 'Phpspecgen_Class');
+    EasyRdf_TypeMapper::set('rdfs:Class', 'Phpspecgen_Class');
+    EasyRdf_TypeMapper::set('owl:Property', 'Phpspecgen_Property');
+    EasyRdf_TypeMapper::set('owl:DatatypeProperty', 'Phpspecgen_Property');
+    EasyRdf_TypeMapper::set('owl:ObjectProperty', 'Phpspecgen_Property');
+    EasyRdf_TypeMapper::set('owl:InverseFunctionalProperty', 'Phpspecgen_Property');
+    EasyRdf_TypeMapper::set('owl:FunctionalProperty', 'Phpspecgen_Property');
+    EasyRdf_TypeMapper::set('rdf:Property', 'Phpspecgen_Property');
+    EasyRdf_TypeMapper::set('skos:ConceptScheme', 'Phpspecgen_ConceptScheme');
+    EasyRdf_TypeMapper::set('skos:Concept', 'Phpspecgen_Concept');
+    EasyRdf_TypeMapper::set('owl:NamedIndividual', 'Phpspecgen_Individual');
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phpspecgen.php	Mon Sep 09 21:03:58 2013 +0100
@@ -0,0 +1,44 @@
+<?php
+
+/*
+
+Adapted from yvesr's phpspecgen:
+
+https://github.com/motools/musicontology.com/blob/master/docs/phpspecgen.php
+
+which is derived from njh's:
+
+https://github.com/njh/phpspecgen
+
+*/
+
+require_once(dirname(__FILE__) . '/easyrdf/lib/EasyRdf.php');
+require_once(dirname(__FILE__) . '/classes.php');
+
+$err = fopen('php://stderr', 'w');
+if(count($argv) != 3)
+{
+	fprintf($err, "Usage: %s FILE.ttl URI\n", $argv[0]);
+	exit(1);
+}
+
+# Extra namespaces we use
+EasyRdf_Namespace::set('odrl', 'http://www.w3.org/ns/odrl/2/');
+
+$uri = $argv[2];
+$graph = new EasyRdf_Graph($uri);
+$graph->parseFile($argv[1], 'turtle', $uri);
+$vocab = $graph->get('owl:Ontology', '^rdf:type');
+if (!isset($vocab))
+{
+	fprint($err, "%s: No OWL ontologies defined at that URL.\n", $argv[0]);
+	exit(1);
+}
+if(!file_exists('template.phtml'))
+{
+	fprintf($err, "%s: cannot find template.phtml in the current directory\n", $argv[0]);
+	exit(1);
+}
+
+require('./template.phtml');
+