glossarist 0.3.5 → 0.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glossarist",
3
- "version": "0.3.5",
3
+ "version": "0.3.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",
package/src/index.d.ts CHANGED
@@ -35,7 +35,7 @@ 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' | 'numeric' | 'designation' | 'unresolved';
39
39
  key?: string;
40
40
  label?: string | null;
41
41
  id?: string;
@@ -2,29 +2,21 @@
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
+ * {{id}} bare ID
11
+ * {{id, display text}} ID + display text
12
+ * {{cite:key}} cite-key (source id)
13
+ * {{cite:key, display text}} cite-key + display text
22
14
  *
23
15
  * @typedef {Object} MentionParseResult
24
- * @property {'cite-ref' | 'numeric' | 'unresolved'} kind
16
+ * @property {'cite-ref' | 'numeric' | 'designation' | 'unresolved'} kind
25
17
  * @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
18
+ * @property {string} [label] — display text (always last)
19
+ * @property {string} [id] — for 'numeric' / 'designation': the id
28
20
  * @property {string} raw — the original mention body
29
21
  */
30
22
 
@@ -42,12 +34,8 @@ const NUMERIC_RE = /^\d+(?:[.-]\d+)+$/;
42
34
  export function parseMention(raw) {
43
35
  const body = raw.trim();
44
36
 
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.
37
+ // 1. cite:<key>[,display] explicit citation reference.
38
+ // Key is the source id; display text is optional.
51
39
  const citeMatch = body.match(/^cite:([^,}]+)(?:,(.*))?$/);
52
40
  if (citeMatch) {
53
41
  const label = citeMatch[2] !== undefined ? unquoteLabel(citeMatch[2].trim()) : null;
@@ -59,20 +47,26 @@ export function parseMention(raw) {
59
47
  };
60
48
  }
61
49
 
62
- // 2. Bare numeric id: same-dataset concept id.
50
+ // 2. Comma-separated form: {{id, display}}.
51
+ // ID always comes first, display text always comes last.
52
+ const commaIdx = body.indexOf(',');
53
+ if (commaIdx !== -1) {
54
+ const id = body.slice(0, commaIdx).trim();
55
+ const label = unquoteLabel(body.slice(commaIdx + 1).trim());
56
+
57
+ if (NUMERIC_RE.test(id)) {
58
+ return { kind: 'numeric', id, label, raw: body };
59
+ }
60
+ return { kind: 'designation', id, label, raw: body };
61
+ }
62
+
63
+ // 3. Bare numeric id.
63
64
  if (NUMERIC_RE.test(body)) {
64
- return {
65
- kind: 'numeric',
66
- id: body,
67
- raw: body,
68
- };
65
+ return { kind: 'numeric', id: body, label: null, raw: body };
69
66
  }
70
67
 
71
- // 3. Anything else is unresolved at the parse layer.
72
- return {
73
- kind: 'unresolved',
74
- raw: body,
75
- };
68
+ // 4. Anything else is unresolved at the parse layer.
69
+ return { kind: 'unresolved', raw: body };
76
70
  }
77
71
 
78
72
  /**
@@ -151,11 +151,16 @@ export class ReferenceResolver {
151
151
  refs.push(this._resolveCiteRef(parsed, source, concept));
152
152
  break;
153
153
  case 'numeric':
154
- refs.push(new Reference('concept', parsed.id, 'embedded', source));
154
+ refs.push(new Reference('concept', parsed.label ?? parsed.id, 'embedded', source, {
155
+ lookupKey: { id: parsed.id },
156
+ }));
157
+ break;
158
+ case 'designation':
159
+ refs.push(new Reference('concept', parsed.label ?? parsed.id, 'embedded', source, {
160
+ lookupKey: { designation: parsed.id },
161
+ }));
155
162
  break;
156
163
  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
164
  break;
160
165
  }
161
166
  }