glossarist 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,11 +8,15 @@
8
8
  @prefix gloss: <https://www.glossarist.org/ontologies/> .
9
9
  @prefix sh: <http://www.w3.org/ns/shacl#> .
10
10
  @prefix skos: <http://www.w3.org/2004/02/skos/core#> .
11
- @prefix xl: <http://www.w3.org/2008/05/skos-xl#> .
11
+ @prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
12
12
  @prefix dcterms: <http://purl.org/dc/terms/> .
13
13
  @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
14
14
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
15
15
  @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
16
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
17
+ @prefix prov: <http://www.w3.org/ns/prov#> .
18
+ @prefix foaf: <http://xmlns.com/foaf/0.1/> .
19
+ @prefix dcat: <http://www.w3.org/ns/dcat#> .
16
20
 
17
21
  # ══════════════════════════════════════════════════════════════════════════
18
22
  # Concept shapes
@@ -175,9 +179,9 @@ gloss:ConceptCollectionShape a sh:NodeShape ;
175
179
 
176
180
  gloss:DesignationShape a sh:NodeShape ;
177
181
  sh:targetClass gloss:Designation ;
178
- sh:class xl:Label ;
182
+ sh:class skosxl:Label ;
179
183
  sh:property [
180
- sh:path xl:literalForm ;
184
+ sh:path skosxl:literalForm ;
181
185
  sh:minCount 1 ;
182
186
  sh:maxCount 1 ;
183
187
  ] ;
@@ -430,6 +434,108 @@ gloss:NonVerbalRepresentationShape a sh:NodeShape ;
430
434
  sh:class gloss:ConceptSource ;
431
435
  ] .
432
436
 
437
+ # === K1: Non-verbal entity shapes ===
438
+ # Class declarations (NonVerbalEntity, Figure, Table, Formula, SharedNonVerbalEntity)
439
+ # live in glossarist.ttl — this file contains validation shapes only.
440
+
441
+ gloss:FigureShape a sh:NodeShape ;
442
+ sh:targetClass gloss:Figure ;
443
+ sh:property [
444
+ sh:path gloss:image ;
445
+ sh:datatype xsd:anyURI ;
446
+ sh:minCount 1 ;
447
+ ] ;
448
+ sh:property [
449
+ sh:path gloss:caption ;
450
+ sh:datatype xsd:string ;
451
+ sh:maxCount 1 ;
452
+ ] ;
453
+ sh:property [
454
+ sh:path dcterms:description ;
455
+ sh:datatype xsd:string ;
456
+ sh:maxCount 1 ;
457
+ ] .
458
+
459
+ gloss:TableShape a sh:NodeShape ;
460
+ sh:targetClass gloss:Table ;
461
+ sh:property [
462
+ sh:path gloss:content ;
463
+ sh:datatype xsd:string ;
464
+ sh:minCount 1 ;
465
+ ] ;
466
+ sh:property [
467
+ sh:path gloss:caption ;
468
+ sh:datatype xsd:string ;
469
+ sh:maxCount 1 ;
470
+ ] ;
471
+ sh:property [
472
+ sh:path dcterms:title ;
473
+ sh:datatype xsd:string ;
474
+ sh:maxCount 1 ;
475
+ ] .
476
+
477
+ gloss:FormulaShape a sh:NodeShape ;
478
+ sh:targetClass gloss:Formula ;
479
+ sh:property [
480
+ sh:path gloss:expression ;
481
+ sh:datatype xsd:string ;
482
+ sh:minCount 1 ;
483
+ ] ;
484
+ sh:property [
485
+ sh:path gloss:latexForm ;
486
+ sh:datatype xsd:string ;
487
+ sh:maxCount 1 ;
488
+ ] ;
489
+ sh:property [
490
+ sh:path dcterms:description ;
491
+ sh:datatype xsd:string ;
492
+ sh:maxCount 1 ;
493
+ ] .
494
+
495
+ # === K2: Image binary references ===
496
+
497
+ gloss:ImageShape a sh:NodeShape ;
498
+ sh:targetClass foaf:Image ;
499
+ sh:property [
500
+ sh:path dcterms:format ;
501
+ sh:datatype xsd:string ;
502
+ sh:minCount 1 ;
503
+ ] ;
504
+ sh:property [
505
+ sh:path dcterms:language ;
506
+ sh:datatype xsd:string ;
507
+ sh:maxCount 1 ;
508
+ ] ;
509
+ sh:property [
510
+ sh:path dcat:byteSize ;
511
+ sh:datatype xsd:integer ;
512
+ sh:maxCount 1 ;
513
+ ] .
514
+
515
+ # === K4: NonVerbalRepresentation (concept-level NVR) ===
516
+ # Class declaration lives in glossarist.ttl as gloss:NonVerbalRepresentation.
517
+
518
+ gloss:NonVerbalRepresentationShape a sh:NodeShape ;
519
+ sh:targetClass gloss:NonVerbalRepresentation ;
520
+ sh:property [
521
+ sh:path skosxl:prefLabel ;
522
+ sh:minCount 1 ;
523
+ ] ;
524
+ sh:property [
525
+ sh:path gloss:image ;
526
+ sh:datatype xsd:anyURI ;
527
+ sh:maxCount 1 ;
528
+ ] ;
529
+ sh:property [
530
+ sh:path dcterms:description ;
531
+ sh:maxCount 1 ;
532
+ ] ;
533
+ sh:property [
534
+ sh:path prov:wasDerivedFrom ;
535
+ sh:class prov:Entity ;
536
+ sh:maxCount 1 ;
537
+ ] .
538
+
433
539
  gloss:ReferenceShape a sh:NodeShape ;
434
540
  sh:targetClass gloss:Reference ;
435
541
  sh:or (
@@ -696,6 +802,11 @@ gloss:SectionShape a sh:NodeShape ;
696
802
  sh:path gloss:hasChildSection ;
697
803
  sh:class gloss:Section ;
698
804
  ] ;
805
+ sh:property [
806
+ sh:path gloss:hasParentSection ;
807
+ sh:class gloss:Section ;
808
+ sh:maxCount 1 ;
809
+ ] ;
699
810
  sh:property [
700
811
  sh:path gloss:sectionOrdering ;
701
812
  sh:class skos:Concept ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glossarist",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "JavaScript SDK for Glossarist GCR packages — read, write, validate, and manage terminology concepts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -34,6 +34,10 @@ export class Figure extends SharedNonVerbalEntity {
34
34
  this._subfigures = null;
35
35
  }
36
36
 
37
+ rdfClass() {
38
+ return 'Figure';
39
+ }
40
+
37
41
  get images() {
38
42
  return this._lazy('_images', '_rawImages',
39
43
  i => i instanceof FigureImage ? i : new FigureImage(i));
@@ -8,6 +8,10 @@ export class Formula extends SharedNonVerbalEntity {
8
8
  this.notation = data.notation ?? null;
9
9
  }
10
10
 
11
+ rdfClass() {
12
+ return 'Formula';
13
+ }
14
+
11
15
  toJSON() {
12
16
  const obj = super.toJSON();
13
17
  if (this.expression != null) obj.expression = this.expression;
@@ -11,6 +11,10 @@ export class NonVerbRep extends NonVerbalEntity {
11
11
  this._images = null;
12
12
  }
13
13
 
14
+ rdfClass() {
15
+ return 'NonVerbalRepresentation';
16
+ }
17
+
14
18
  get images() {
15
19
  return this._lazy('_images', '_rawImages',
16
20
  i => i instanceof FigureImage ? i : new FigureImage(i));
@@ -16,6 +16,13 @@ export class NonVerbalEntity extends RegistrableModel {
16
16
  s => s instanceof ConceptSource ? s : new ConceptSource(s));
17
17
  }
18
18
 
19
+ // Ontology class local-name. Subtypes override to return their specific
20
+ // class (Figure/Table/Formula). Used by the RDF emitter so a new subtype
21
+ // registers without editing the emitter (OCP).
22
+ rdfClass() {
23
+ return 'NonVerbalEntity';
24
+ }
25
+
19
26
  findById(_targetId) {
20
27
  return null;
21
28
  }
@@ -8,6 +8,10 @@ export class Table extends SharedNonVerbalEntity {
8
8
  this.format = data.format ?? null;
9
9
  }
10
10
 
11
+ rdfClass() {
12
+ return 'Table';
13
+ }
14
+
11
15
  toJSON() {
12
16
  const obj = super.toJSON();
13
17
  if (this.content != null) obj.content = this.content;
@@ -2,12 +2,31 @@
2
2
  //
3
3
  // URI shape: `<uriBase>/<registerId>/concept/<conceptId>`.
4
4
  // Localized concepts: `<uriBase>/<registerId>/concept/<conceptId>/<lang>`.
5
+ // Figure/Table/Formula references: `<uriBase>/<registerId>/<kind>/<entityId>`.
5
6
  import { PRED } from './predicates.js';
6
7
  import { WELL_KNOWN } from './prefixes.js';
7
8
  import { localizedConceptToQuads } from './gloss-localized-concept.js';
8
9
  import { conceptSourceToQuads } from './gloss-source.js';
9
10
  import { namedNode, literal, quad } from './terms.js';
10
11
 
12
+ // Kind tag → URI segment. Each NonVerbalReference subtype has a
13
+ // predictable URL path so the same entity is reachable from any
14
+ // concept that references it.
15
+ const NVR_KIND_SEGMENT = {
16
+ FigureReference: 'figure',
17
+ TableReference: 'table',
18
+ FormulaReference: 'formula',
19
+ };
20
+
21
+ // Builds the URI for a NonVerbalReference target entity. Returns null
22
+ // when the reference has no entityId (e.g., inline display-only refs).
23
+ function nonVerbalReferenceUri(ref, options) {
24
+ const kind = NVR_KIND_SEGMENT[ref.constructor.name];
25
+ if (!kind || !ref.entityId) return null;
26
+ const base = String(options.uriBase ?? '').replace(/\/+$/, '');
27
+ return `${base}/${options.registerId}/${kind}/${ref.entityId}`;
28
+ }
29
+
11
30
  export function conceptUri(concept, { registerId, uriBase }) {
12
31
  const id = String(concept.id ?? concept.termid ?? '');
13
32
  const base = String(uriBase ?? '').replace(/\/+$/, '');
@@ -27,6 +46,16 @@ export function* conceptToQuads(concept, options) {
27
46
  yield quad(s, namedNode(PRED.gloss.hasStatus), namedNode(`${PRED.gloss.$ns}status/${concept.status}`));
28
47
  }
29
48
 
49
+ // NonVerbal references — emit the link quad only. The actual
50
+ // Figure/Table/Formula entity quads are emitted by `nonVerbalEntityToQuads`
51
+ // when the dataset's NVR collection is iterated.
52
+ for (const ref of [...(concept.figures ?? []), ...(concept.tables ?? []), ...(concept.formulas ?? [])]) {
53
+ const targetUri = nonVerbalReferenceUri(ref, options);
54
+ if (targetUri) {
55
+ yield quad(s, namedNode(PRED.gloss.hasNonVerbalRep), namedNode(targetUri));
56
+ }
57
+ }
58
+
30
59
  for (const lang of concept.languages) {
31
60
  const lc = concept.localization(lang);
32
61
  if (!lc) continue;
@@ -10,6 +10,7 @@ import { WELL_KNOWN } from './prefixes.js';
10
10
  import { designationToQuads, skosLabelPredicate } from './gloss-designation.js';
11
11
  import { detailedDefinitionToQuads } from './gloss-detailed-definition.js';
12
12
  import { conceptSourceToQuads } from './gloss-source.js';
13
+ import { nonVerbalRepToQuads } from './gloss-non-verbal-rep.js';
13
14
  import { namedNode, literal, quad } from './terms.js';
14
15
  const DCTERMS_LANGUAGE = `${PREFIXES.dcterms}language`;
15
16
 
@@ -55,6 +56,12 @@ export function* localizedConceptToQuads(localizedConcept, { parentUri, language
55
56
  yield* definitionsToQuads(localizedConcept.examples, { subjectUri, language, role: 'hasExample' });
56
57
  yield* definitionsToQuads(localizedConcept.annotations, { subjectUri, language, role: 'hasAnnotation' });
57
58
 
59
+ let nvrIndex = 0;
60
+ for (const nvr of localizedConcept.nonVerbalRep ?? []) {
61
+ yield* nonVerbalRepToQuads(nvr, { parentUri: subjectUri, index: nvrIndex, language });
62
+ nvrIndex += 1;
63
+ }
64
+
58
65
  let srcIndex = 0;
59
66
  for (const source of localizedConcept.sources ?? []) {
60
67
  yield* conceptSourceToQuads(source, { subjectUri, index: srcIndex });
@@ -0,0 +1,191 @@
1
+ // NonVerbal entity → RDF quads. Mirrors the v3.1.0 concept-model
2
+ // NonVerbal class hierarchy. Two distinct shapes:
3
+ //
4
+ // 1. Legacy `gloss:NonVerbalRepresentation` (NonVerbRep) — a child of
5
+ // LocalizedConcept with a positional bnode subject. Carries
6
+ // `representationType`, `representationRef`, `representationText`.
7
+ //
8
+ // 2. Dataset-level `gloss:Figure` / `gloss:Table` / `gloss:Formula`
9
+ // (SharedNonVerbalEntity subtypes) — first-class resources with
10
+ // their own URIs. Carries caption, description, altText, sources,
11
+ // plus subtype-specific fields (Figure: images + subfigures;
12
+ // Table: content + format; Formula: expression + notation +
13
+ // latexForm).
14
+ //
15
+ // The dispatch on the entity's `rdfClass()` follows the same OCP
16
+ // pattern as Designation — a new subtype registers without editing
17
+ // this emitter.
18
+ import { PRED, PREFIXES } from './predicates.js';
19
+ import { WELL_KNOWN } from './prefixes.js';
20
+ import { deterministicBnode } from './deterministic-id.js';
21
+ import { namedNode, literal, quad } from './terms.js';
22
+ import { conceptSourceToQuads } from './gloss-source.js';
23
+
24
+ const DCTERMS_DESCRIPTION = `${PREFIXES.dcterms}description`;
25
+ const DCTERMS_FORMAT = `${PREFIXES.dcterms}format`;
26
+ const XSD_STRING = `${PREFIXES.xsd}string`;
27
+
28
+ // ── Legacy NonVerbRep (concept-local, positional) ──────────────────────
29
+
30
+ // Emits a `gloss:NonVerbalRepresentation` blank node linked from the
31
+ // parent localized concept via `gloss:hasNonVerbalRep`. Mirrors the
32
+ // Ruby `Rdf::GlossNonVerbalRep` shape: type/ref/text plus sources.
33
+ export function* nonVerbalRepToQuads(nvr, { parentUri, index, language = null }) {
34
+ const subject = deterministicBnode(parentUri, 'nvr', index);
35
+
36
+ yield quad(namedNode(parentUri), namedNode(PRED.gloss.hasNonVerbalRep), namedNode(subject));
37
+ yield quad(namedNode(subject), namedNode(WELL_KNOWN.rdfType), namedNode(`${PRED.gloss.$ns}${nvr.rdfClass()}`));
38
+
39
+ if (nvr.type) {
40
+ yield quad(namedNode(subject), namedNode(PRED.gloss.representationType), literal(nvr.type, XSD_STRING));
41
+ }
42
+ for (const image of nvr.images ?? []) {
43
+ if (image.src) {
44
+ yield quad(namedNode(subject), namedNode(PRED.gloss.image), literal(image.src, XSD_STRING));
45
+ }
46
+ }
47
+ if (nvr.caption) {
48
+ yield quad(namedNode(subject), namedNode(PRED.gloss.caption), literal(nvr.caption, language));
49
+ }
50
+ if (nvr.description) {
51
+ yield quad(namedNode(subject), namedNode(DCTERMS_DESCRIPTION), literal(nvr.description, language));
52
+ }
53
+ if (nvr.alt) {
54
+ yield quad(namedNode(subject), namedNode(PRED.gloss.altText), literal(nvr.alt, language));
55
+ }
56
+
57
+ let srcIndex = 0;
58
+ for (const source of nvr.sources ?? []) {
59
+ yield* conceptSourceToQuads(source, { subjectUri: subject, index: srcIndex });
60
+ srcIndex += 1;
61
+ }
62
+ }
63
+
64
+ // ── Dataset-level Figure / Table / Formula ────────────────────────────
65
+
66
+ // URI scheme: `<uriBase>/<registerId>/<kind>/<id>` where `kind` is the
67
+ // entity's rdfClass() lowercased (figure/table/formula). Stable across
68
+ // runs and consumers.
69
+ export function nonVerbalEntityUri(entity, { registerId, uriBase }) {
70
+ const id = String(entity.id ?? entity.identifier ?? '');
71
+ const kind = String(entity.rdfClass() ?? 'NonVerbalEntity').toLowerCase();
72
+ const base = String(uriBase ?? '').replace(/\/+$/, '');
73
+ return `${base}/${registerId}/${kind}/${id}`;
74
+ }
75
+
76
+ // Emits a dataset-level NonVerbalEntity (Figure/Table/Formula) as a
77
+ // first-class resource. Calls into subtype-specific emitters via the
78
+ // entity's class identity — OCP: a new subtype adds a branch in
79
+ // `subtypeQuadsFor` without changing the public entry point.
80
+ export function* nonVerbalEntityToQuads(entity, options) {
81
+ const subjectUri = nonVerbalEntityUri(entity, options);
82
+ const s = namedNode(subjectUri);
83
+
84
+ yield quad(s, namedNode(WELL_KNOWN.rdfType), namedNode(`${PRED.gloss.$ns}${entity.rdfClass()}`));
85
+
86
+ if (entity.caption) {
87
+ yield quad(s, namedNode(PRED.gloss.caption), literal(entity.caption, null));
88
+ }
89
+ if (entity.description) {
90
+ yield quad(s, namedNode(DCTERMS_DESCRIPTION), literal(entity.description, null));
91
+ }
92
+ if (entity.alt) {
93
+ yield quad(s, namedNode(PRED.gloss.altText), literal(entity.alt, null));
94
+ }
95
+
96
+ yield* subtypeQuadsFor(entity, s, options);
97
+
98
+ let srcIndex = 0;
99
+ for (const source of entity.sources ?? []) {
100
+ yield* conceptSourceToQuads(source, { subjectUri, index: srcIndex });
101
+ srcIndex += 1;
102
+ }
103
+ }
104
+
105
+ // Dispatch table: maps the entity's rdfClass() local name to a
106
+ // subtype-specific quad generator. Adding a new subtype = adding a
107
+ // branch here + an rdfClass() override on the model class.
108
+ function* subtypeQuadsFor(entity, s, options) {
109
+ switch (entity.rdfClass()) {
110
+ case 'Figure': yield* figureQuads(entity, s, options); break;
111
+ case 'Table': yield* tableQuads(entity, s); break;
112
+ case 'Formula': yield* formulaQuads(entity, s); break;
113
+ // NonVerbalEntity base or unknown — no subtype-specific quads.
114
+ }
115
+ }
116
+
117
+ function* figureQuads(figure, s, options) {
118
+ let imgIndex = 0;
119
+ for (const image of figure.images ?? []) {
120
+ const imgSubject = deterministicBnode(s.value, 'image', imgIndex);
121
+ yield quad(s, namedNode(PRED.gloss.image), namedNode(imgSubject));
122
+ yield quad(namedNode(imgSubject), namedNode(WELL_KNOWN.rdfType), namedNode(PRED.gloss.FigureImage));
123
+ if (image.src) {
124
+ yield quad(namedNode(imgSubject), namedNode(PRED.gloss.src), literal(image.src, XSD_STRING));
125
+ }
126
+ if (image.format) {
127
+ yield quad(namedNode(imgSubject), namedNode(DCTERMS_FORMAT), literal(image.format, XSD_STRING));
128
+ }
129
+ if (image.role) {
130
+ yield quad(namedNode(imgSubject), namedNode(PRED.gloss.role), literal(image.role, XSD_STRING));
131
+ }
132
+ imgIndex += 1;
133
+ }
134
+
135
+ let subIndex = 0;
136
+ for (const sub of figure.subfigures ?? []) {
137
+ const subSubject = deterministicBnode(s.value, 'subfig', subIndex);
138
+ yield quad(s, namedNode(PRED.gloss.hasSubfigure), namedNode(subSubject));
139
+ // Subfigures recurse as their own Figure bnodes — same shape,
140
+ // different subject. We inline the base + subtype quads so the
141
+ // subfigure's images also resolve.
142
+ yield* subfigureQuads(sub, subSubject, options);
143
+ subIndex += 1;
144
+ }
145
+ }
146
+
147
+ // Sub-figure emitter — mirrors `nonVerbalEntityToQuads` but with a
148
+ // pre-assigned bnode subject (subfigures don't get their own URI).
149
+ function* subfigureQuads(figure, subjectUri, _options) {
150
+ const s = namedNode(subjectUri);
151
+ yield quad(s, namedNode(WELL_KNOWN.rdfType), namedNode(`${PRED.gloss.$ns}${figure.rdfClass()}`));
152
+
153
+ if (figure.caption) {
154
+ yield quad(s, namedNode(PRED.gloss.caption), literal(figure.caption, null));
155
+ }
156
+ if (figure.description) {
157
+ yield quad(s, namedNode(DCTERMS_DESCRIPTION), literal(figure.description, null));
158
+ }
159
+ if (figure.alt) {
160
+ yield quad(s, namedNode(PRED.gloss.altText), literal(figure.alt, null));
161
+ }
162
+
163
+ let imgIndex = 0;
164
+ for (const image of figure.images ?? []) {
165
+ const imgSubject = deterministicBnode(s.value, 'image', imgIndex);
166
+ yield quad(s, namedNode(PRED.gloss.image), namedNode(imgSubject));
167
+ yield quad(namedNode(imgSubject), namedNode(WELL_KNOWN.rdfType), namedNode(PRED.gloss.FigureImage));
168
+ if (image.src) {
169
+ yield quad(namedNode(imgSubject), namedNode(PRED.gloss.src), literal(image.src, XSD_STRING));
170
+ }
171
+ imgIndex += 1;
172
+ }
173
+ }
174
+
175
+ function* tableQuads(table, s) {
176
+ if (table.content) {
177
+ yield quad(s, namedNode(PRED.gloss.content), literal(table.content, null));
178
+ }
179
+ if (table.format) {
180
+ yield quad(s, namedNode(PRED.gloss.format), literal(table.format, XSD_STRING));
181
+ }
182
+ }
183
+
184
+ function* formulaQuads(formula, s) {
185
+ if (formula.expression) {
186
+ yield quad(s, namedNode(PRED.gloss.expression), literal(formula.expression, null));
187
+ }
188
+ if (formula.notation) {
189
+ yield quad(s, namedNode(PRED.gloss.latexForm), literal(formula.notation, XSD_STRING));
190
+ }
191
+ }
@@ -10,6 +10,7 @@ import type { LocalizedConcept } from '../models/index';
10
10
  import type { Designation } from '../models/index';
11
11
  import type { DetailedDefinition } from '../models/index';
12
12
  import type { ConceptSource } from '../models/index';
13
+ import type { NonVerbRep, Figure, Table, Formula } from '../models/index';
13
14
 
14
15
  export { PRED, PREFIXES } from './predicates';
15
16
  export type PredicateMap = typeof PRED;
@@ -76,6 +77,26 @@ export interface ConceptSourceEmitOptions {
76
77
 
77
78
  export declare function conceptSourceToQuads(source: ConceptSource, options: ConceptSourceEmitOptions): Generator<Quad, void, unknown>;
78
79
 
80
+ // ── Non-verbal representation emitters ─────────────────────────────────
81
+
82
+ export interface NonVerbalRepEmitOptions {
83
+ parentUri: string;
84
+ index: number;
85
+ language?: string | null;
86
+ }
87
+
88
+ export declare function nonVerbalRepToQuads(nvr: NonVerbRep, options: NonVerbalRepEmitOptions): Generator<Quad, void, unknown>;
89
+
90
+ export interface NonVerbalEntityEmitOptions {
91
+ registerId: string;
92
+ uriBase?: string;
93
+ }
94
+
95
+ export type NonVerbalEntity = Figure | Table | Formula;
96
+
97
+ export declare function nonVerbalEntityUri(entity: NonVerbalEntity, options: NonVerbalEntityEmitOptions): string;
98
+ export declare function nonVerbalEntityToQuads(entity: NonVerbalEntity, options: NonVerbalEntityEmitOptions): Generator<Quad, void, unknown>;
99
+
79
100
  export declare function collectQuads(quadsIterable: Iterable<Quad>): Quad[];
80
101
 
81
102
  export interface WriteTurtleOptions {
@@ -102,6 +123,7 @@ export interface ValidationReport {
102
123
  }>;
103
124
  }
104
125
 
105
- export declare function loadShapes(): Promise<Dataset>;
106
- export declare function validateShacl(dataDataset: Dataset, options?: { shapes?: Dataset }): Promise<ValidationReport>;
126
+ export declare function loadShapes(options?: { shapesPath?: string }): Promise<Dataset>;
127
+ export declare function validateShacl(dataDataset: Dataset, options?: { shapes?: Dataset; shapesPath?: string }): Promise<ValidationReport>;
128
+ export declare function clearShapesCache(): void;
107
129
  export declare function quadsToDataset(quads: Iterable<Quad>): Dataset;
package/src/rdf/index.js CHANGED
@@ -17,6 +17,11 @@ export {
17
17
  } from './gloss-designation.js';
18
18
  export { detailedDefinitionToQuads } from './gloss-detailed-definition.js';
19
19
  export { conceptSourceToQuads } from './gloss-source.js';
20
+ export {
21
+ nonVerbalRepToQuads,
22
+ nonVerbalEntityToQuads,
23
+ nonVerbalEntityUri,
24
+ } from './gloss-non-verbal-rep.js';
20
25
  export {
21
26
  collectQuads,
22
27
  writeTurtle,
@@ -24,4 +29,4 @@ export {
24
29
  writeJsonld,
25
30
  sortQuads,
26
31
  } from './document-writer.js';
27
- export { validateShacl, loadShapes, quadsToDataset } from './shacl.js';
32
+ export { validateShacl, loadShapes, clearShapesCache, quadsToDataset } from './shacl.js';
@@ -26,6 +26,12 @@ export declare const PRED = {
26
26
  "DesignationRelationship": "https://www.glossarist.org/ontologies/DesignationRelationship",
27
27
  "ConceptDate": "https://www.glossarist.org/ontologies/ConceptDate",
28
28
  "NonVerbalRepresentation": "https://www.glossarist.org/ontologies/NonVerbalRepresentation",
29
+ "NonVerbalEntity": "https://www.glossarist.org/ontologies/NonVerbalEntity",
30
+ "SharedNonVerbalEntity": "https://www.glossarist.org/ontologies/SharedNonVerbalEntity",
31
+ "Figure": "https://www.glossarist.org/ontologies/Figure",
32
+ "Table": "https://www.glossarist.org/ontologies/Table",
33
+ "Formula": "https://www.glossarist.org/ontologies/Formula",
34
+ "FigureImage": "https://www.glossarist.org/ontologies/FigureImage",
29
35
  "CustomLocality": "https://www.glossarist.org/ontologies/CustomLocality",
30
36
  "Locality": "https://www.glossarist.org/ontologies/Locality",
31
37
  "DatasetRegister": "https://www.glossarist.org/ontologies/DatasetRegister",
@@ -69,6 +75,16 @@ export declare const PRED = {
69
75
  "isTruncation": "https://www.glossarist.org/ontologies/isTruncation",
70
76
  "text": "https://www.glossarist.org/ontologies/text",
71
77
  "image": "https://www.glossarist.org/ontologies/image",
78
+ "caption": "https://www.glossarist.org/ontologies/caption",
79
+ "altText": "https://www.glossarist.org/ontologies/altText",
80
+ "description": "https://www.glossarist.org/ontologies/description",
81
+ "expression": "https://www.glossarist.org/ontologies/expression",
82
+ "latexForm": "https://www.glossarist.org/ontologies/latexForm",
83
+ "content": "https://www.glossarist.org/ontologies/content",
84
+ "hasSubfigure": "https://www.glossarist.org/ontologies/hasSubfigure",
85
+ "src": "https://www.glossarist.org/ontologies/src",
86
+ "format": "https://www.glossarist.org/ontologies/format",
87
+ "role": "https://www.glossarist.org/ontologies/role",
72
88
  "pronunciationContent": "https://www.glossarist.org/ontologies/pronunciationContent",
73
89
  "pronunciationLanguage": "https://www.glossarist.org/ontologies/pronunciationLanguage",
74
90
  "pronunciationScript": "https://www.glossarist.org/ontologies/pronunciationScript",
@@ -268,6 +284,12 @@ export type Predicate =
268
284
  | "https://www.glossarist.org/ontologies/DesignationRelationship"
269
285
  | "https://www.glossarist.org/ontologies/ConceptDate"
270
286
  | "https://www.glossarist.org/ontologies/NonVerbalRepresentation"
287
+ | "https://www.glossarist.org/ontologies/NonVerbalEntity"
288
+ | "https://www.glossarist.org/ontologies/SharedNonVerbalEntity"
289
+ | "https://www.glossarist.org/ontologies/Figure"
290
+ | "https://www.glossarist.org/ontologies/Table"
291
+ | "https://www.glossarist.org/ontologies/Formula"
292
+ | "https://www.glossarist.org/ontologies/FigureImage"
271
293
  | "https://www.glossarist.org/ontologies/CustomLocality"
272
294
  | "https://www.glossarist.org/ontologies/Locality"
273
295
  | "https://www.glossarist.org/ontologies/DatasetRegister"
@@ -311,6 +333,16 @@ export type Predicate =
311
333
  | "https://www.glossarist.org/ontologies/isTruncation"
312
334
  | "https://www.glossarist.org/ontologies/text"
313
335
  | "https://www.glossarist.org/ontologies/image"
336
+ | "https://www.glossarist.org/ontologies/caption"
337
+ | "https://www.glossarist.org/ontologies/altText"
338
+ | "https://www.glossarist.org/ontologies/description"
339
+ | "https://www.glossarist.org/ontologies/expression"
340
+ | "https://www.glossarist.org/ontologies/latexForm"
341
+ | "https://www.glossarist.org/ontologies/content"
342
+ | "https://www.glossarist.org/ontologies/hasSubfigure"
343
+ | "https://www.glossarist.org/ontologies/src"
344
+ | "https://www.glossarist.org/ontologies/format"
345
+ | "https://www.glossarist.org/ontologies/role"
314
346
  | "https://www.glossarist.org/ontologies/pronunciationContent"
315
347
  | "https://www.glossarist.org/ontologies/pronunciationLanguage"
316
348
  | "https://www.glossarist.org/ontologies/pronunciationScript"
@@ -26,6 +26,12 @@ export const PRED = {
26
26
  "DesignationRelationship": "https://www.glossarist.org/ontologies/DesignationRelationship",
27
27
  "ConceptDate": "https://www.glossarist.org/ontologies/ConceptDate",
28
28
  "NonVerbalRepresentation": "https://www.glossarist.org/ontologies/NonVerbalRepresentation",
29
+ "NonVerbalEntity": "https://www.glossarist.org/ontologies/NonVerbalEntity",
30
+ "SharedNonVerbalEntity": "https://www.glossarist.org/ontologies/SharedNonVerbalEntity",
31
+ "Figure": "https://www.glossarist.org/ontologies/Figure",
32
+ "Table": "https://www.glossarist.org/ontologies/Table",
33
+ "Formula": "https://www.glossarist.org/ontologies/Formula",
34
+ "FigureImage": "https://www.glossarist.org/ontologies/FigureImage",
29
35
  "CustomLocality": "https://www.glossarist.org/ontologies/CustomLocality",
30
36
  "Locality": "https://www.glossarist.org/ontologies/Locality",
31
37
  "DatasetRegister": "https://www.glossarist.org/ontologies/DatasetRegister",
@@ -69,6 +75,16 @@ export const PRED = {
69
75
  "isTruncation": "https://www.glossarist.org/ontologies/isTruncation",
70
76
  "text": "https://www.glossarist.org/ontologies/text",
71
77
  "image": "https://www.glossarist.org/ontologies/image",
78
+ "caption": "https://www.glossarist.org/ontologies/caption",
79
+ "altText": "https://www.glossarist.org/ontologies/altText",
80
+ "description": "https://www.glossarist.org/ontologies/description",
81
+ "expression": "https://www.glossarist.org/ontologies/expression",
82
+ "latexForm": "https://www.glossarist.org/ontologies/latexForm",
83
+ "content": "https://www.glossarist.org/ontologies/content",
84
+ "hasSubfigure": "https://www.glossarist.org/ontologies/hasSubfigure",
85
+ "src": "https://www.glossarist.org/ontologies/src",
86
+ "format": "https://www.glossarist.org/ontologies/format",
87
+ "role": "https://www.glossarist.org/ontologies/role",
72
88
  "pronunciationContent": "https://www.glossarist.org/ontologies/pronunciationContent",
73
89
  "pronunciationLanguage": "https://www.glossarist.org/ontologies/pronunciationLanguage",
74
90
  "pronunciationScript": "https://www.glossarist.org/ontologies/pronunciationScript",
package/src/rdf/shacl.js CHANGED
@@ -91,8 +91,9 @@ export function quadsToDataset(quads) {
91
91
  return ds;
92
92
  }
93
93
 
94
- // Test-only: clears the shapes cache. Exported so tests can verify
95
- // independent caching per path without reaching into module internals.
96
- export function __clearShapesCacheForTests() {
94
+ // Clears the in-memory shapes cache. Exposed as part of the public API
95
+ // so callers (including tests) can force a fresh load when the
96
+ // underlying shapes file changes during a process's lifetime.
97
+ export function clearShapesCache() {
97
98
  SHAPES_CACHE.clear();
98
99
  }