Skip to content

Commit 2ca8a40

Browse files
authored
Merge pull request #46 from AtomGraph/develop
Develop
2 parents cb817ef + ddf64e9 commit 2ca8a40

23 files changed

Lines changed: 508 additions & 342 deletions

File tree

.github/workflows/check-docs.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Check Docs
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
check-docs:
10+
name: Check documentation
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: RDF syntax check
18+
uses: AtomGraph/RDF-syntax-check@v1.0.5
19+
20+
- name: Check links
21+
run: ./check-links.sh

check-links.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
5+
EXIT_CODE=0
6+
7+
resolve_url() {
8+
python3 -c "
9+
import urllib.parse, sys
10+
base = 'http://x/' + sys.argv[1]
11+
result = urllib.parse.urljoin(base, sys.argv[2])
12+
print(result[len('http://x/'):])
13+
" "$1" "$2"
14+
}
15+
16+
while IFS= read -r -d '' ttl_file; do
17+
rel="${ttl_file#"$REPO_DIR"/}"
18+
url_path="${rel%.ttl}/"
19+
20+
while IFS= read -r url; do
21+
[[ "$url" =~ ^https?:// ]] && continue
22+
[[ "$url" =~ ^# ]] && continue
23+
[[ "$url" =~ (^|/)uploads/ ]] && continue
24+
[[ -z "$url" ]] && continue
25+
26+
path="${url%%#*}"
27+
[[ -z "$path" ]] && continue
28+
[[ "$path" =~ \.[a-zA-Z]+$ ]] && continue # skip links to files (e.g. .xsl)
29+
30+
resolved="$(resolve_url "$url_path" "$path")"
31+
target_file="$REPO_DIR/${resolved%/}.ttl"
32+
33+
if [[ ! -f "$target_file" ]]; then
34+
echo "BROKEN: $rel$url (resolves to ${resolved%/}.ttl)"
35+
EXIT_CODE=1
36+
fi
37+
done < <(grep -oE '(href|src|data)="[^"]*"' "$ttl_file" | sed 's/^[^"]*"//;s/"$//' || true)
38+
done < <(find "$REPO_DIR" -name "*.ttl" -print0)
39+
40+
exit "$EXIT_CODE"

demo/copenhagen/parking-facilities.ttl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
# Main container document
1010
<> a dh:Container ;
1111
dct:title "Parking facilities" ;
12-
rdf:_1 <#largest-parkings> ;
12+
rdf:_1 <#largest-parkings-block> ;
1313
rdf:_2 <#select-children> .
1414

15-
# Chart block
15+
# Chart block (wrapped in ldh:Object per ContentMode contract)
16+
<#largest-parkings-block> a ldh:Object ;
17+
rdf:value <#largest-parkings> .
18+
1619
<#largest-parkings> a ldh:ResultSetChart ;
1720
dct:title "Largest parking facilities" ;
1821
spin:query <#parking-by-spaces-query> ;

demo/copenhagen/root.ttl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
dct:description "Geospatial and other open data about cities, imported by transforming CSV files to RDF" ;
1717
rdf:_1 <#page-header> ;
1818
rdf:_2 <#city-intro> ;
19-
rdf:_3 <#facilities-overview> ;
19+
rdf:_3 <#facilities-overview-block> ;
2020
rdf:_4 <#main-library> ;
2121
rdf:_5 <#charts> ;
2222
rdf:_6 <#largest-parkings> ;
@@ -42,6 +42,9 @@
4242
This dataset includes libraries, schools, parking facilities, sports centers, playgrounds, and more.</p>
4343
</div>"""^^rdf:XMLLiteral .
4444

45+
<#facilities-overview-block> a ldh:Object ;
46+
rdf:value <#facilities-overview> .
47+
4548
<#facilities-overview> a ldh:ResultSetChart ;
4649
dct:title "Facilities by type" ;
4750
spin:query <#facilities-by-type-query> ;

demo/northwind-traders/admin/model/ns.ttl

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,34 @@ schema:PostalAddress a owl:Class ;
2727
rdfs:label "Postal address" ;
2828
rdfs:isDefinedBy : .
2929

30+
schema:ProductGroup a owl:Class ;
31+
rdfs:label "Product group" ;
32+
rdfs:isDefinedBy : .
33+
34+
schema:Corporation a owl:Class ;
35+
rdfs:label "Corporation" ;
36+
rdfs:isDefinedBy : .
37+
38+
schema:ContactPoint a owl:Class ;
39+
rdfs:label "Contact point" ;
40+
rdfs:isDefinedBy : .
41+
42+
schema:ParcelDelivery a owl:Class ;
43+
rdfs:label "Parcel delivery" ;
44+
rdfs:isDefinedBy : .
45+
46+
schema:OrderItem a owl:Class ;
47+
rdfs:label "Order item" ;
48+
rdfs:isDefinedBy : .
49+
50+
schema:Product a owl:Class ;
51+
rdfs:label "Product" ;
52+
rdfs:isDefinedBy : .
53+
54+
schema:Place a owl:Class ;
55+
rdfs:label "Place" ;
56+
rdfs:isDefinedBy : .
57+
3058
# properties
3159

3260
schema:broker a owl:ObjectProperty ;
@@ -47,6 +75,170 @@ schema:address a owl:ObjectProperty ;
4775
rdfs:range schema:PostalAddress ;
4876
rdfs:isDefinedBy : .
4977

78+
schema:contactPoint a owl:ObjectProperty ;
79+
rdfs:label "Contact point" ;
80+
rdfs:domain schema:Corporation ;
81+
rdfs:range schema:ContactPoint ;
82+
rdfs:isDefinedBy : .
83+
84+
schema:employee a owl:ObjectProperty ;
85+
rdfs:label "Employee" ;
86+
rdfs:domain schema:Corporation ;
87+
rdfs:range schema:Person ;
88+
rdfs:isDefinedBy : .
89+
90+
schema:customer a owl:ObjectProperty ;
91+
rdfs:label "Customer" ;
92+
rdfs:domain schema:Order ;
93+
rdfs:range schema:Corporation ;
94+
rdfs:isDefinedBy : .
95+
96+
schema:orderDelivery a owl:ObjectProperty ;
97+
rdfs:label "Order delivery" ;
98+
rdfs:domain schema:Order ;
99+
rdfs:range schema:ParcelDelivery ;
100+
rdfs:isDefinedBy : .
101+
102+
schema:deliveryAddress a owl:ObjectProperty ;
103+
rdfs:label "Delivery address" ;
104+
rdfs:domain schema:ParcelDelivery ;
105+
rdfs:range schema:PostalAddress ;
106+
rdfs:isDefinedBy : .
107+
108+
schema:provider a owl:ObjectProperty ;
109+
rdfs:label "Provider" ;
110+
rdfs:range schema:Corporation ;
111+
rdfs:isDefinedBy : .
112+
113+
schema:category a owl:ObjectProperty ;
114+
rdfs:label "Category" ;
115+
rdfs:domain schema:Product ;
116+
rdfs:range schema:ProductGroup ;
117+
rdfs:isDefinedBy : .
118+
119+
schema:containedInPlace a owl:ObjectProperty ;
120+
rdfs:label "Contained in place" ;
121+
rdfs:domain schema:City ;
122+
rdfs:range schema:Place ;
123+
rdfs:isDefinedBy : .
124+
125+
schema:sponsor a owl:ObjectProperty ;
126+
rdfs:label "Sponsor" ;
127+
rdfs:domain schema:Person ;
128+
rdfs:range schema:Person ;
129+
rdfs:isDefinedBy : .
130+
131+
schema:orderedItem a owl:ObjectProperty ;
132+
rdfs:label "Ordered item" ;
133+
rdfs:isDefinedBy : .
134+
135+
schema:name a owl:DatatypeProperty ;
136+
rdfs:label "Name" ;
137+
rdfs:isDefinedBy : .
138+
139+
schema:identifier a owl:DatatypeProperty ;
140+
rdfs:label "Identifier" ;
141+
rdfs:isDefinedBy : .
142+
143+
schema:description a owl:DatatypeProperty ;
144+
rdfs:label "Description" ;
145+
rdfs:isDefinedBy : .
146+
147+
schema:legalName a owl:DatatypeProperty ;
148+
rdfs:label "Legal name" ;
149+
rdfs:domain schema:Corporation ;
150+
rdfs:isDefinedBy : .
151+
152+
schema:telephone a owl:DatatypeProperty ;
153+
rdfs:label "Telephone" ;
154+
rdfs:isDefinedBy : .
155+
156+
schema:faxNumber a owl:DatatypeProperty ;
157+
rdfs:label "Fax number" ;
158+
rdfs:isDefinedBy : .
159+
160+
schema:jobTitle a owl:DatatypeProperty ;
161+
rdfs:label "Job title" ;
162+
rdfs:domain schema:Person ;
163+
rdfs:isDefinedBy : .
164+
165+
schema:addressCountry a owl:DatatypeProperty ;
166+
rdfs:label "Address country" ;
167+
rdfs:domain schema:PostalAddress ;
168+
rdfs:isDefinedBy : .
169+
170+
schema:addressLocality a owl:DatatypeProperty ;
171+
rdfs:label "Address locality" ;
172+
rdfs:domain schema:PostalAddress ;
173+
rdfs:isDefinedBy : .
174+
175+
schema:postalCode a owl:DatatypeProperty ;
176+
rdfs:label "Postal code" ;
177+
rdfs:domain schema:PostalAddress ;
178+
rdfs:isDefinedBy : .
179+
180+
schema:streetAddress a owl:DatatypeProperty ;
181+
rdfs:label "Street address" ;
182+
rdfs:domain schema:PostalAddress ;
183+
rdfs:isDefinedBy : .
184+
185+
schema:addressRegion a owl:DatatypeProperty ;
186+
rdfs:label "Address region" ;
187+
rdfs:domain schema:PostalAddress ;
188+
rdfs:isDefinedBy : .
189+
190+
schema:givenName a owl:DatatypeProperty ;
191+
rdfs:label "Given name" ;
192+
rdfs:domain schema:Person ;
193+
rdfs:isDefinedBy : .
194+
195+
schema:familyName a owl:DatatypeProperty ;
196+
rdfs:label "Family name" ;
197+
rdfs:domain schema:Person ;
198+
rdfs:isDefinedBy : .
199+
200+
schema:honorificPrefix a owl:DatatypeProperty ;
201+
rdfs:label "Honorific prefix" ;
202+
rdfs:domain schema:Person ;
203+
rdfs:isDefinedBy : .
204+
205+
schema:birthDate a owl:DatatypeProperty ;
206+
rdfs:label "Birth date" ;
207+
rdfs:domain schema:Person ;
208+
rdfs:isDefinedBy : .
209+
210+
schema:orderQuantity a owl:DatatypeProperty ;
211+
rdfs:label "Order quantity" ;
212+
rdfs:domain schema:OrderItem ;
213+
rdfs:isDefinedBy : .
214+
215+
schema:discount a owl:DatatypeProperty ;
216+
rdfs:label "Discount" ;
217+
rdfs:domain schema:OrderItem ;
218+
rdfs:isDefinedBy : .
219+
220+
schema:price a owl:DatatypeProperty ;
221+
rdfs:label "Price" ;
222+
rdfs:isDefinedBy : .
223+
224+
schema:orderDate a owl:DatatypeProperty ;
225+
rdfs:label "Order date" ;
226+
rdfs:domain schema:Order ;
227+
rdfs:isDefinedBy : .
228+
229+
schema:expectedArrivalUntil a owl:DatatypeProperty ;
230+
rdfs:label "Expected arrival until" ;
231+
rdfs:domain schema:ParcelDelivery ;
232+
rdfs:isDefinedBy : .
233+
234+
schema:url a owl:DatatypeProperty ;
235+
rdfs:label "URL" ;
236+
rdfs:isDefinedBy : .
237+
238+
schema:location a owl:ObjectProperty ;
239+
rdfs:label "Location" ;
240+
rdfs:isDefinedBy : .
241+
50242
# restrictions
51243

52244
[] a owl:Restriction ;

demo/northwind-traders/categories.ttl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<> a dh:Container ;
1111
dct:title "Categories" ;
1212
rdf:_1 <#category-intro> ;
13-
rdf:_2 <#category-revenue> ;
13+
rdf:_2 <#category-revenue-block> ;
1414
rdf:_3 <#category-distribution> ;
15-
rdf:_4 <#products-per-category> ;
15+
rdf:_4 <#products-per-category-block> ;
1616
rdf:_5 <#select-categories> .
1717

1818
# Intro XHTML
@@ -23,7 +23,10 @@
2323
Analyzing category-level metrics helps identify portfolio strengths, diversification opportunities, and inventory priorities.</p>
2424
</div>"""^^rdf:XMLLiteral .
2525

26-
# Category revenue chart
26+
# Category revenue chart (wrapped in ldh:Object per ContentMode contract)
27+
<#category-revenue-block> a ldh:Object ;
28+
rdf:value <#category-revenue> .
29+
2730
<#category-revenue> a ldh:ResultSetChart ;
2831
dct:title "Revenue by category" ;
2932
spin:query <#category-revenue-query> ;
@@ -62,7 +65,10 @@ ORDER BY DESC(?revenue)""" .
6265
Categories with more products may indicate core competencies or simply broader product lines.</p>
6366
</div>"""^^rdf:XMLLiteral .
6467

65-
# Products per category chart
68+
# Products per category chart (wrapped in ldh:Object per ContentMode contract)
69+
<#products-per-category-block> a ldh:Object ;
70+
rdf:value <#products-per-category> .
71+
6672
<#products-per-category> a ldh:ResultSetChart ;
6773
dct:title "Products per category" ;
6874
spin:query <#products-per-category-query> ;

demo/northwind-traders/customers.ttl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<> a dh:Container ;
1111
dct:title "Customers" ;
1212
rdf:_1 <#customers-intro> ;
13-
rdf:_2 <#top-customers> ;
13+
rdf:_2 <#top-customers-block> ;
1414
rdf:_3 <#geographic-distribution> ;
15-
rdf:_4 <#customers-by-country> ;
15+
rdf:_4 <#customers-by-country-block> ;
1616
rdf:_5 <#customer-insights> ;
1717
rdf:_6 <#select-customers> .
1818

@@ -24,7 +24,10 @@
2424
and market concentration helps prioritize account management and target growth strategies.</p>
2525
</div>"""^^rdf:XMLLiteral .
2626

27-
# Top customers chart
27+
# Top customers chart (wrapped in ldh:Object per ContentMode contract)
28+
<#top-customers-block> a ldh:Object ;
29+
rdf:value <#top-customers> .
30+
2831
<#top-customers> a ldh:ResultSetChart ;
2932
dct:title "Top 10 customers by revenue" ;
3033
spin:query <#top-customers-query> ;
@@ -61,7 +64,10 @@ LIMIT 10""" .
6164
Understanding geographic concentration helps guide expansion efforts and resource allocation.</p>
6265
</div>"""^^rdf:XMLLiteral .
6366

64-
# Customers by country chart
67+
# Customers by country chart (wrapped in ldh:Object per ContentMode contract)
68+
<#customers-by-country-block> a ldh:Object ;
69+
rdf:value <#customers-by-country> .
70+
6571
<#customers-by-country> a ldh:ResultSetChart ;
6672
dct:title "Customers by country" ;
6773
spin:query <#customers-by-country-query> ;

demo/northwind-traders/employees.ttl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<> a dh:Container ;
1111
dct:title "Employees" ;
1212
rdf:_1 <#employee-intro> ;
13-
rdf:_2 <#sales-by-employee> ;
13+
rdf:_2 <#sales-by-employee-block> ;
1414
rdf:_3 <#select-employees> .
1515

1616
# Intro XHTML
@@ -21,7 +21,10 @@
2121
contributions helps recognize top performers, identify coaching opportunities, and optimize territory assignments.</p>
2222
</div>"""^^rdf:XMLLiteral .
2323

24-
# Sales by employee chart
24+
# Sales by employee chart (wrapped in ldh:Object per ContentMode contract)
25+
<#sales-by-employee-block> a ldh:Object ;
26+
rdf:value <#sales-by-employee> .
27+
2528
<#sales-by-employee> a ldh:ResultSetChart ;
2629
dct:title "Sales by employee" ;
2730
spin:query <#sales-by-employee-query> ;

0 commit comments

Comments
 (0)