glossarist 0.3.5 → 0.3.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glossarist",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
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",
package/src/index.d.ts CHANGED
@@ -35,8 +35,9 @@ export { conceptUuid, localizedConceptUuid, uuidV5 } from './uuid';
35
35
  export { ReferenceResolver, Reference, referenceResolver } from './reference-resolver';
36
36
 
37
37
  export type MentionParseResult = {
38
- kind: 'cite-ref' | 'numeric' | 'unresolved';
38
+ kind: 'cite-ref' | 'urn-ref' | 'numeric' | 'designation' | 'unresolved';
39
39
  key?: string;
40
+ uri?: string;
40
41
  label?: string | null;
41
42
  id?: string;
42
43
  raw: string;
@@ -2,29 +2,26 @@
2
2
  * Mention parser for {{...}} inline references in concept text.
3
3
  *
4
4
  * Pure function: takes a raw mention body (the text inside
5
- * {{...}}) and returns a structured MentionParseResult. The
6
- * extractor (in src/reference-resolver.js) consumes the
7
- * structured form to emit Reference objects.
5
+ * {{...}}) and returns a structured MentionParseResult.
8
6
  *
9
- * Two outcomes in v8:
10
- * - 'cite-ref': the mention is {{cite:<key>}} or
11
- * {{cite:<key>,<label>}}. The extractor looks the key up in
12
- * the current concept's sources list.
13
- * - 'numeric': the mention is a bare dotted or dashed id
14
- * like {{3.1.1.1}} or {{103-01-02}}. Resolves to a
15
- * same-dataset concept.
16
- * - 'unresolved': the mention did not match a recognized
17
- * form. The extractor silently drops it.
7
+ * Convention: the ID always comes first, the display (render) text
8
+ * always comes last. Every comma-separated form follows this:
18
9
  *
19
- * The full v6 form-aware parser (URI schemes, short-ids,
20
- * quoting) is aspirational; v8 only supports the two forms
21
- * above plus a catch-all unresolved case.
10
+ * {{cite:key}} cite-key (source id)
11
+ * {{cite:key, render term}} cite-key + render term
12
+ * {{urn:...}} URN reference
13
+ * {{urn:..., render term}} URN + render term
14
+ * {{numeric_id}} local concept ID
15
+ * {{numeric_id, render term}} local concept ID + render term
16
+ * {{designation}} designation matching
17
+ * {{designation, render term}} designation + render term
22
18
  *
23
19
  * @typedef {Object} MentionParseResult
24
- * @property {'cite-ref' | 'numeric' | 'unresolved'} kind
20
+ * @property {'cite-ref' | 'urn-ref' | 'numeric' | 'designation' | 'unresolved'} kind
25
21
  * @property {string} [key] — for 'cite-ref': the local key
26
- * @property {string} [label] — for 'cite-ref': the inline label
27
- * @property {string} [id] for 'numeric': the bare id
22
+ * @property {string} [uri] — for 'urn-ref': the URN
23
+ * @property {string} [label] render text (always last)
24
+ * @property {string} [id] — for 'numeric' / 'designation': the id
28
25
  * @property {string} raw — the original mention body
29
26
  */
30
27
 
@@ -42,12 +39,7 @@ const NUMERIC_RE = /^\d+(?:[.-]\d+)+$/;
42
39
  export function parseMention(raw) {
43
40
  const body = raw.trim();
44
41
 
45
- // 1. cite:<key> form, with optional ,<label> after the key.
46
- // The key must not contain a comma (the comma is the
47
- // label separator). Labels can be quoted (CSV-style) to
48
- // contain commas; if not quoted, the label is the text
49
- // up to the next comma or the end of the mention. The
50
- // label may be empty.
42
+ // 1. cite:<key>[,render] explicit citation reference.
51
43
  const citeMatch = body.match(/^cite:([^,}]+)(?:,(.*))?$/);
52
44
  if (citeMatch) {
53
45
  const label = citeMatch[2] !== undefined ? unquoteLabel(citeMatch[2].trim()) : null;
@@ -59,20 +51,38 @@ export function parseMention(raw) {
59
51
  };
60
52
  }
61
53
 
62
- // 2. Bare numeric id: same-dataset concept id.
63
- if (NUMERIC_RE.test(body)) {
54
+ // 2. urn:...[,render] URN reference.
55
+ const urnMatch = body.match(/^(urn:[^,}]+)(?:,(.*))?$/);
56
+ if (urnMatch) {
57
+ const label = urnMatch[2] !== undefined ? unquoteLabel(urnMatch[2].trim()) : null;
64
58
  return {
65
- kind: 'numeric',
66
- id: body,
59
+ kind: 'urn-ref',
60
+ uri: urnMatch[1].trim(),
61
+ label,
67
62
  raw: body,
68
63
  };
69
64
  }
70
65
 
71
- // 3. Anything else is unresolved at the parse layer.
72
- return {
73
- kind: 'unresolved',
74
- raw: body,
75
- };
66
+ // 3. Comma-separated form: {{id, render}}.
67
+ // ID always comes first, render text always comes last.
68
+ const commaIdx = body.indexOf(',');
69
+ if (commaIdx !== -1) {
70
+ const id = body.slice(0, commaIdx).trim();
71
+ const label = unquoteLabel(body.slice(commaIdx + 1).trim());
72
+
73
+ if (NUMERIC_RE.test(id)) {
74
+ return { kind: 'numeric', id, label, raw: body };
75
+ }
76
+ return { kind: 'designation', id, label, raw: body };
77
+ }
78
+
79
+ // 4. Bare numeric id.
80
+ if (NUMERIC_RE.test(body)) {
81
+ return { kind: 'numeric', id: body, label: null, raw: body };
82
+ }
83
+
84
+ // 5. Anything else is unresolved at the parse layer.
85
+ return { kind: 'unresolved', raw: body };
76
86
  }
77
87
 
78
88
  /**
@@ -150,12 +150,23 @@ export class ReferenceResolver {
150
150
  case 'cite-ref':
151
151
  refs.push(this._resolveCiteRef(parsed, source, concept));
152
152
  break;
153
+ case 'urn-ref':
154
+ refs.push(new Reference('concept', parsed.label ?? parsed.uri, 'embedded', source, {
155
+ uri: parsed.uri,
156
+ resolution: null,
157
+ }));
158
+ break;
153
159
  case 'numeric':
154
- refs.push(new Reference('concept', parsed.id, 'embedded', source));
160
+ refs.push(new Reference('concept', parsed.label ?? parsed.id, 'embedded', source, {
161
+ lookupKey: { id: parsed.id },
162
+ }));
163
+ break;
164
+ case 'designation':
165
+ refs.push(new Reference('concept', parsed.label ?? parsed.id, 'embedded', source, {
166
+ lookupKey: { designation: parsed.id },
167
+ }));
155
168
  break;
156
169
  case 'unresolved':
157
- // Silently dropped. The mention is either non-reference
158
- // text (e.g. math, code) or a form we don't support.
159
170
  break;
160
171
  }
161
172
  }