@pubid/pubid 0.1.3 → 0.1.5

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.
Files changed (185) hide show
  1. package/artifact/corpus.json.gz +0 -0
  2. package/dist/conformance/cli.js +5 -1
  3. package/dist/flavors/amca/grammar.d.ts +4 -0
  4. package/dist/flavors/amca/grammar.js +87 -0
  5. package/dist/flavors/amca/index.d.ts +4 -0
  6. package/dist/flavors/amca/index.js +76 -0
  7. package/dist/flavors/amca/model.d.ts +29 -0
  8. package/dist/flavors/amca/model.js +146 -0
  9. package/dist/flavors/ansi/index.d.ts +24 -0
  10. package/dist/flavors/ansi/index.js +147 -0
  11. package/dist/flavors/api/grammar.d.ts +4 -0
  12. package/dist/flavors/api/grammar.js +79 -0
  13. package/dist/flavors/api/index.d.ts +4 -0
  14. package/dist/flavors/api/index.js +71 -0
  15. package/dist/flavors/api/model.d.ts +27 -0
  16. package/dist/flavors/api/model.js +114 -0
  17. package/dist/flavors/ashrae/grammar.d.ts +2 -0
  18. package/dist/flavors/ashrae/grammar.js +667 -0
  19. package/dist/flavors/ashrae/index.d.ts +4 -0
  20. package/dist/flavors/ashrae/index.js +306 -0
  21. package/dist/flavors/ashrae/model.d.ts +87 -0
  22. package/dist/flavors/ashrae/model.js +335 -0
  23. package/dist/flavors/ashrae/preprocessor.d.ts +7 -0
  24. package/dist/flavors/ashrae/preprocessor.js +44 -0
  25. package/dist/flavors/asme/grammar.d.ts +2 -0
  26. package/dist/flavors/asme/grammar.js +200 -0
  27. package/dist/flavors/asme/index.d.ts +4 -0
  28. package/dist/flavors/asme/index.js +138 -0
  29. package/dist/flavors/asme/model.d.ts +34 -0
  30. package/dist/flavors/asme/model.js +123 -0
  31. package/dist/flavors/astm/grammar.d.ts +2 -0
  32. package/dist/flavors/astm/grammar.js +110 -0
  33. package/dist/flavors/astm/index.d.ts +2 -0
  34. package/dist/flavors/astm/index.js +127 -0
  35. package/dist/flavors/astm/model.d.ts +42 -0
  36. package/dist/flavors/astm/model.js +263 -0
  37. package/dist/flavors/bipm/index.d.ts +30 -0
  38. package/dist/flavors/bipm/index.js +434 -0
  39. package/dist/flavors/bsi/grammar.d.ts +4 -0
  40. package/dist/flavors/bsi/grammar.js +535 -0
  41. package/dist/flavors/bsi/index.d.ts +4 -0
  42. package/dist/flavors/bsi/index.js +941 -0
  43. package/dist/flavors/bsi/model.d.ts +127 -0
  44. package/dist/flavors/bsi/model.js +863 -0
  45. package/dist/flavors/calconnect/index.d.ts +21 -0
  46. package/dist/flavors/calconnect/index.js +113 -0
  47. package/dist/flavors/cen_cenelec/grammar.d.ts +4 -0
  48. package/dist/flavors/cen_cenelec/grammar.js +107 -0
  49. package/dist/flavors/cen_cenelec/index.d.ts +5 -0
  50. package/dist/flavors/cen_cenelec/index.js +263 -0
  51. package/dist/flavors/cen_cenelec/model.d.ts +45 -0
  52. package/dist/flavors/cen_cenelec/model.js +490 -0
  53. package/dist/flavors/cie/grammar.d.ts +5 -0
  54. package/dist/flavors/cie/grammar.js +127 -0
  55. package/dist/flavors/cie/index.d.ts +2 -0
  56. package/dist/flavors/cie/index.js +311 -0
  57. package/dist/flavors/cie/model.d.ts +122 -0
  58. package/dist/flavors/cie/model.js +464 -0
  59. package/dist/flavors/csa/grammar.d.ts +6 -0
  60. package/dist/flavors/csa/grammar.js +239 -0
  61. package/dist/flavors/csa/index.d.ts +2 -0
  62. package/dist/flavors/csa/index.js +634 -0
  63. package/dist/flavors/csa/model.d.ts +33 -0
  64. package/dist/flavors/csa/model.js +505 -0
  65. package/dist/flavors/doi/index.d.ts +13 -0
  66. package/dist/flavors/doi/index.js +65 -0
  67. package/dist/flavors/easc/index.d.ts +4 -0
  68. package/dist/flavors/easc/index.js +107 -0
  69. package/dist/flavors/ecma/index.d.ts +4 -0
  70. package/dist/flavors/ecma/index.js +117 -0
  71. package/dist/flavors/etsi/index.d.ts +14 -0
  72. package/dist/flavors/etsi/index.js +307 -0
  73. package/dist/flavors/evs/grammar.d.ts +2 -0
  74. package/dist/flavors/evs/grammar.js +22 -0
  75. package/dist/flavors/evs/index.d.ts +2 -0
  76. package/dist/flavors/evs/index.js +24 -0
  77. package/dist/flavors/evs/model.d.ts +19 -0
  78. package/dist/flavors/evs/model.js +36 -0
  79. package/dist/flavors/gb/index.d.ts +31 -0
  80. package/dist/flavors/gb/index.js +159 -0
  81. package/dist/flavors/gost/grammar.d.ts +2 -0
  82. package/dist/flavors/gost/grammar.js +46 -0
  83. package/dist/flavors/gost/index.d.ts +2 -0
  84. package/dist/flavors/gost/index.js +165 -0
  85. package/dist/flavors/gost/model.d.ts +61 -0
  86. package/dist/flavors/gost/model.js +147 -0
  87. package/dist/flavors/gost/prefix_routes.d.ts +15 -0
  88. package/dist/flavors/gost/prefix_routes.js +192 -0
  89. package/dist/flavors/iala/index.d.ts +32 -0
  90. package/dist/flavors/iala/index.js +300 -0
  91. package/dist/flavors/iana/index.d.ts +19 -0
  92. package/dist/flavors/iana/index.js +71 -0
  93. package/dist/flavors/idf/grammar.d.ts +2 -0
  94. package/dist/flavors/idf/grammar.js +71 -0
  95. package/dist/flavors/idf/index.d.ts +2 -0
  96. package/dist/flavors/idf/index.js +100 -0
  97. package/dist/flavors/idf/model.d.ts +54 -0
  98. package/dist/flavors/idf/model.js +359 -0
  99. package/dist/flavors/iec/grammar.d.ts +3 -0
  100. package/dist/flavors/iec/grammar.js +187 -0
  101. package/dist/flavors/iec/index.d.ts +4 -0
  102. package/dist/flavors/iec/index.js +507 -0
  103. package/dist/flavors/iec/model.d.ts +54 -0
  104. package/dist/flavors/iec/model.js +437 -0
  105. package/dist/flavors/ieee/grammar.d.ts +2 -0
  106. package/dist/flavors/ieee/grammar.js +697 -0
  107. package/dist/flavors/ieee/index.d.ts +3 -0
  108. package/dist/flavors/ieee/index.js +1258 -0
  109. package/dist/flavors/ieee/model.d.ts +144 -0
  110. package/dist/flavors/ieee/model.js +1237 -0
  111. package/dist/flavors/ieee/preprocessor.d.ts +8 -0
  112. package/dist/flavors/ieee/preprocessor.js +410 -0
  113. package/dist/flavors/ieee/update_codes.d.ts +8 -0
  114. package/dist/flavors/ieee/update_codes.js +197 -0
  115. package/dist/flavors/ietf/index.d.ts +30 -0
  116. package/dist/flavors/ietf/index.js +151 -0
  117. package/dist/flavors/iho/index.d.ts +4 -0
  118. package/dist/flavors/iho/index.js +126 -0
  119. package/dist/flavors/index.d.ts +9 -0
  120. package/dist/flavors/index.js +136 -0
  121. package/dist/flavors/isbn/index.d.ts +13 -0
  122. package/dist/flavors/isbn/index.js +97 -0
  123. package/dist/flavors/iso/grammar.d.ts +2 -0
  124. package/dist/flavors/iso/grammar.js +207 -0
  125. package/dist/flavors/iso/index.d.ts +2 -0
  126. package/dist/flavors/iso/index.js +343 -0
  127. package/dist/flavors/iso/model.d.ts +159 -0
  128. package/dist/flavors/iso/model.js +802 -0
  129. package/dist/flavors/iso/stages.generated.d.ts +13 -0
  130. package/dist/flavors/iso/stages.generated.js +391 -0
  131. package/dist/flavors/itu/grammar.d.ts +4 -0
  132. package/dist/flavors/itu/grammar.js +205 -0
  133. package/dist/flavors/itu/index.d.ts +2 -0
  134. package/dist/flavors/itu/index.js +224 -0
  135. package/dist/flavors/itu/model.d.ts +184 -0
  136. package/dist/flavors/itu/model.js +599 -0
  137. package/dist/flavors/jcgm/index.d.ts +7 -0
  138. package/dist/flavors/jcgm/index.js +300 -0
  139. package/dist/flavors/jis/index.d.ts +4 -0
  140. package/dist/flavors/jis/index.js +267 -0
  141. package/dist/flavors/nist/grammar.d.ts +2 -0
  142. package/dist/flavors/nist/grammar.js +287 -0
  143. package/dist/flavors/nist/index.d.ts +2 -0
  144. package/dist/flavors/nist/index.js +1244 -0
  145. package/dist/flavors/nist/model.d.ts +155 -0
  146. package/dist/flavors/nist/model.js +823 -0
  147. package/dist/flavors/nist/preprocessor.d.ts +11 -0
  148. package/dist/flavors/nist/preprocessor.js +281 -0
  149. package/dist/flavors/oasis/index.d.ts +23 -0
  150. package/dist/flavors/oasis/index.js +110 -0
  151. package/dist/flavors/ogc/index.d.ts +20 -0
  152. package/dist/flavors/ogc/index.js +75 -0
  153. package/dist/flavors/oiml/grammar.d.ts +2 -0
  154. package/dist/flavors/oiml/grammar.js +206 -0
  155. package/dist/flavors/oiml/implementation.d.ts +9 -0
  156. package/dist/flavors/oiml/implementation.js +45 -0
  157. package/dist/flavors/oiml/model.d.ts +23 -0
  158. package/dist/flavors/oiml/model.js +592 -0
  159. package/dist/flavors/omg/index.d.ts +14 -0
  160. package/dist/flavors/omg/index.js +73 -0
  161. package/dist/flavors/plateau/index.d.ts +4 -0
  162. package/dist/flavors/plateau/index.js +97 -0
  163. package/dist/flavors/tgpp/index.d.ts +4 -0
  164. package/dist/flavors/tgpp/index.js +122 -0
  165. package/dist/flavors/un/index.d.ts +13 -0
  166. package/dist/flavors/un/index.js +90 -0
  167. package/dist/flavors/w3c/index.d.ts +14 -0
  168. package/dist/flavors/w3c/index.js +148 -0
  169. package/dist/flavors/xsf/index.d.ts +18 -0
  170. package/dist/flavors/xsf/index.js +65 -0
  171. package/dist/grammar/engine.d.ts +78 -0
  172. package/dist/grammar/engine.js +351 -0
  173. package/dist/index.d.ts +1 -0
  174. package/dist/index.js +3 -0
  175. package/dist/model/attribute.d.ts +54 -0
  176. package/dist/model/attribute.js +53 -0
  177. package/dist/model/builder.d.ts +39 -0
  178. package/dist/model/builder.js +124 -0
  179. package/dist/model/component.d.ts +70 -0
  180. package/dist/model/component.js +170 -0
  181. package/dist/model/identifier.d.ts +84 -0
  182. package/dist/model/identifier.js +270 -0
  183. package/dist/model/urn-generator.d.ts +27 -0
  184. package/dist/model/urn-generator.js +91 -0
  185. package/package.json +1 -1
@@ -0,0 +1,138 @@
1
+ import { parseGrammar } from "../../grammar/engine.js";
2
+ import { asmeGrammar } from "./grammar.js";
3
+ import { AsmeIdentifier } from "./model.js";
4
+ /**
5
+ * Port of lib/pubid/asme/builder.rb — joint publishers, BPVC code
6
+ * assembly, and the flat attribute assignments.
7
+ */
8
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
9
+ const strv = (v) => {
10
+ if (v === undefined || v === null)
11
+ return undefined;
12
+ if (Array.isArray(v)) {
13
+ const flat = v.flat(10);
14
+ const joined = flat.map(String).join("");
15
+ return joined.length > 0 ? joined : undefined;
16
+ }
17
+ const s = String(v).trim();
18
+ return s.length > 0 ? s : undefined;
19
+ };
20
+ function flatten(data) {
21
+ return Array.isArray(data) ? Object.assign({}, ...data) : data;
22
+ }
23
+ function buildCode(parsed) {
24
+ const designator = parsed["designator"];
25
+ if (isObj(designator)) {
26
+ const bpvc = designator["bpvc_code"];
27
+ if (isObj(bpvc)) {
28
+ if (bpvc["special"] !== undefined)
29
+ return "BPVC COMPLETE CODE BIND";
30
+ const subdivision = isObj(bpvc["subdivision"]) ? bpvc["subdivision"] : undefined;
31
+ if (subdivision !== undefined && subdivision["ssc_code"] !== undefined) {
32
+ // BPVC.SSC.XI.II.V.IX pattern. The sections sit under
33
+ // `ssc_code`; a bare "BPVC.SSC." parses with no inner capture,
34
+ // so `ssc_code` is the matched string.
35
+ const sscCode = subdivision["ssc_code"];
36
+ const sections = isObj(sscCode) ? sscCode["ssc_sections"] : undefined;
37
+ const sectionsStr = Array.isArray(sections)
38
+ ? sections.flat(10).map(String).join(".")
39
+ : String(sections ?? "");
40
+ return sectionsStr === "" ? "BPVC.SSC." : `BPVC.SSC.${sectionsStr}`;
41
+ }
42
+ if (subdivision !== undefined && subdivision["case_code"] !== undefined) {
43
+ const cc = strv(subdivision["case_code"]) ?? "";
44
+ const caseSub = strv(subdivision["case_sub"]);
45
+ return caseSub !== undefined && caseSub !== ""
46
+ ? `BPVC.CC.${cc}.${caseSub}`
47
+ : `BPVC.CC.${cc}`;
48
+ }
49
+ if (bpvc["case_code"] !== undefined) {
50
+ return `BPVC-CC-${strv(bpvc["case_code"])}`;
51
+ }
52
+ if (subdivision !== undefined) {
53
+ const parts = [strv(subdivision["section"]), strv(subdivision["subsection"]), strv(subdivision["sub_subsection"])]
54
+ .filter((p) => p !== undefined && p !== "");
55
+ const langSuffix = strv(subdivision["lang_suffix"]);
56
+ let result = `BPVC.${parts.join(".")}`;
57
+ if (langSuffix !== undefined)
58
+ result += `_${langSuffix}`;
59
+ return result;
60
+ }
61
+ return "BPVC";
62
+ }
63
+ }
64
+ let designatorStr = isObj(designator) ? strv(designator["designator"]) : strv(designator);
65
+ designatorStr ??= "";
66
+ // Normalize "V V" to "V&V".
67
+ if (designatorStr === "V V")
68
+ designatorStr = "V&V";
69
+ const number = strv(parsed["number"]) ?? "";
70
+ return `${designatorStr}${number}`;
71
+ }
72
+ export function buildAsmeIdentifier(tree) {
73
+ const parsed = flatten(tree);
74
+ const self = {};
75
+ if (parsed["joint_publisher"] !== undefined) {
76
+ const joint = strv(parsed["joint_publisher"]);
77
+ self["joint_publisher"] = joint;
78
+ self["publisher"] = joint;
79
+ }
80
+ else if (parsed["first_publisher"] !== undefined) {
81
+ self["first_publisher"] = strv(parsed["first_publisher"]);
82
+ self["first_code"] = strv(parsed["first_code"]);
83
+ self["second_publisher"] = strv(parsed["second_publisher"]);
84
+ self["publisher"] = `${strv(parsed["first_publisher"])}/${strv(parsed["second_publisher"])}`;
85
+ }
86
+ else {
87
+ self["publisher"] = "ASME";
88
+ }
89
+ if (parsed["designator"] !== undefined) {
90
+ self["number"] = buildCode(parsed);
91
+ }
92
+ else if (parsed["number"] !== undefined) {
93
+ self["number"] = strv(parsed["number"]);
94
+ }
95
+ if (parsed["ptc_suffix"] !== undefined)
96
+ self["ptc_suffix"] = strv(parsed["ptc_suffix"]);
97
+ if (parsed["year"] !== undefined)
98
+ self["year"] = strv(parsed["year"]);
99
+ if (parsed["draft_year"] !== undefined)
100
+ self["draft_year"] = strv(parsed["draft_year"]);
101
+ if (parsed["reaffirmation"] !== undefined) {
102
+ const raw = parsed["reaffirmation"];
103
+ const reaffirmation = isObj(raw) ? strv(raw["year"]) : strv(raw);
104
+ self["reaffirmation"] = `R${reaffirmation}`;
105
+ }
106
+ if (parsed["language"] !== undefined) {
107
+ self["language"] = strv(parsed["language"]);
108
+ }
109
+ else if (parsed["lang_suffix"] !== undefined) {
110
+ self["language"] = strv(parsed["lang_suffix"]);
111
+ }
112
+ if (parsed["csa_number"] !== undefined)
113
+ self["csa_number"] = strv(parsed["csa_number"]);
114
+ if (parsed["handbook"] !== undefined)
115
+ self["handbook"] = true;
116
+ if (parsed["revision_note"] !== undefined) {
117
+ self["revision_note"] = `[${strv(parsed["revision_note"])}]`;
118
+ }
119
+ if (parsed["ref_standard"] !== undefined) {
120
+ const ref = strv(parsed["ref_standard"]) ?? "";
121
+ const m = /^(Proposed revision|Revision) of (.+)$/.exec(ref);
122
+ if (m !== null) {
123
+ self["parenthetical_revision"] = `(${m[1]} of ${m[2]})`;
124
+ }
125
+ else {
126
+ self["parenthetical_revision"] = `(Revision of ${ref})`;
127
+ }
128
+ }
129
+ return new AsmeIdentifier(self);
130
+ }
131
+ export function asmeGrammarImplementation() {
132
+ return {
133
+ parse(input) {
134
+ const tree = parseGrammar(asmeGrammar, input);
135
+ return buildAsmeIdentifier(tree);
136
+ },
137
+ };
138
+ }
@@ -0,0 +1,34 @@
1
+ import { BaseIdentifier } from "../../model/identifier.js";
2
+ import { type FieldMapping } from "../../model/attribute.js";
3
+ import { BaseUrnGenerator } from "../../model/urn-generator.js";
4
+ /**
5
+ * Port of lib/pubid/asme: the single Standard class (the whole printed
6
+ * code as `number`), the renderer and the URN generator.
7
+ */
8
+ declare class AsmeUrnGenerator extends BaseUrnGenerator<AsmeIdentifier> {
9
+ generate(): string;
10
+ private specialType;
11
+ }
12
+ export declare class AsmeIdentifier extends BaseIdentifier {
13
+ static polymorphicName: string;
14
+ static urnGenerator: typeof AsmeUrnGenerator;
15
+ static attributes: import("../../model/attribute.js").AttributeTable;
16
+ static mappings: FieldMapping[];
17
+ readonly publisher: string | undefined;
18
+ readonly number: string | undefined;
19
+ readonly year: string | undefined;
20
+ readonly reaffirmation: string | undefined;
21
+ readonly language: string | undefined;
22
+ readonly csa_number: string | undefined;
23
+ readonly draft_year: string | undefined;
24
+ readonly revision_note: string | undefined;
25
+ readonly parenthetical_revision: string | undefined;
26
+ readonly handbook: boolean | undefined;
27
+ readonly ptc_suffix: string | undefined;
28
+ readonly joint_publisher: string | undefined;
29
+ readonly first_publisher: string | undefined;
30
+ readonly first_code: string | undefined;
31
+ readonly second_publisher: string | undefined;
32
+ render(): string;
33
+ }
34
+ export {};
@@ -0,0 +1,123 @@
1
+ import { BaseIdentifier, registerType } from "../../model/identifier.js";
2
+ import { keyValue, extendAttributes } from "../../model/attribute.js";
3
+ import { BaseUrnGenerator } from "../../model/urn-generator.js";
4
+ /**
5
+ * Port of lib/pubid/asme: the single Standard class (the whole printed
6
+ * code as `number`), the renderer and the URN generator.
7
+ */
8
+ class AsmeUrnGenerator extends BaseUrnGenerator {
9
+ generate() {
10
+ const id = this.identifier;
11
+ const parts = ["urn", "asme"];
12
+ const specialType = this.specialType(id);
13
+ if (specialType !== undefined)
14
+ parts.push(specialType);
15
+ parts.push(id.publisher !== undefined ? id.publisher.toLowerCase() : "asme");
16
+ if (id.number !== undefined)
17
+ parts.push(id.number);
18
+ if (id.draft_year !== undefined)
19
+ parts.push(id.draft_year);
20
+ else if (id.year !== undefined)
21
+ parts.push(id.year);
22
+ if (specialType !== "ptc" && id.ptc_suffix !== undefined) {
23
+ parts.push(`ptc-suffix.${id.ptc_suffix}`);
24
+ }
25
+ if (specialType !== "csa" && id.csa_number !== undefined) {
26
+ parts.push(`csa.${id.csa_number}`);
27
+ }
28
+ if (id.first_publisher !== undefined) {
29
+ parts.push(`pub1.${id.first_publisher.toLowerCase()}`);
30
+ }
31
+ if (id.first_code !== undefined)
32
+ parts.push(`code1.${id.first_code}`);
33
+ if (id.second_publisher !== undefined) {
34
+ parts.push(`pub2.${id.second_publisher.toLowerCase()}`);
35
+ }
36
+ if (id.joint_publisher !== undefined) {
37
+ parts.push(`joint.${id.joint_publisher.toLowerCase()}`);
38
+ }
39
+ if (id.language !== undefined)
40
+ parts.push(id.language.toLowerCase());
41
+ if (id.reaffirmation !== undefined)
42
+ parts.push(`reaff.${id.reaffirmation}`);
43
+ if (id.revision_note !== undefined)
44
+ parts.push(`revnote.${id.revision_note}`);
45
+ if (id.parenthetical_revision !== undefined) {
46
+ parts.push(`prev.${id.parenthetical_revision}`);
47
+ }
48
+ return parts.join(":");
49
+ }
50
+ specialType(id) {
51
+ if (id.handbook === true)
52
+ return "handbook";
53
+ if (id.ptc_suffix !== undefined)
54
+ return "ptc";
55
+ if (id.csa_number !== undefined)
56
+ return "csa";
57
+ return undefined;
58
+ }
59
+ }
60
+ export class AsmeIdentifier extends BaseIdentifier {
61
+ static polymorphicName = "pubid:asme:standard";
62
+ static urnGenerator = AsmeUrnGenerator;
63
+ static attributes = extendAttributes(BaseIdentifier, {
64
+ publisher: { type: "string" },
65
+ number: { type: "string" },
66
+ year: { type: "string" },
67
+ reaffirmation: { type: "string" },
68
+ language: { type: "string" },
69
+ csa_number: { type: "string" },
70
+ draft_year: { type: "string" },
71
+ revision_note: { type: "string" },
72
+ parenthetical_revision: { type: "string" },
73
+ handbook: { type: "boolean", default: false },
74
+ ptc_suffix: { type: "string" },
75
+ joint_publisher: { type: "string" },
76
+ first_publisher: { type: "string" },
77
+ first_code: { type: "string" },
78
+ second_publisher: { type: "string" },
79
+ });
80
+ static mappings = keyValue({ wire: "publisher", to: "publisher" }, { wire: "number", to: "number" }, { wire: "year", to: "year" }, { wire: "reaffirmation", to: "reaffirmation" }, { wire: "language", to: "language" }, { wire: "csa_number", to: "csa_number" }, { wire: "draft_year", to: "draft_year" }, { wire: "revision_note", to: "revision_note" }, { wire: "parenthetical_revision", to: "parenthetical_revision" }, { wire: "handbook", to: "handbook" }, { wire: "ptc_suffix", to: "ptc_suffix" }, { wire: "joint_publisher", to: "joint_publisher" }, { wire: "first_publisher", to: "first_publisher" }, { wire: "first_code", to: "first_code" }, { wire: "second_publisher", to: "second_publisher" });
81
+ render() {
82
+ const parts = [];
83
+ if (this.first_publisher !== undefined && this.first_code !== undefined) {
84
+ parts.push(this.first_publisher, this.first_code);
85
+ if (this.second_publisher !== undefined)
86
+ parts.push(`/${this.second_publisher}`);
87
+ if (this.number !== undefined && this.number !== "")
88
+ parts.push(this.number);
89
+ }
90
+ else if (this.joint_publisher !== undefined) {
91
+ parts.push(this.joint_publisher);
92
+ if (this.number !== undefined && this.number !== "")
93
+ parts.push(this.number);
94
+ }
95
+ else {
96
+ if (this.publisher !== undefined)
97
+ parts.push(this.publisher);
98
+ if (this.number !== undefined)
99
+ parts.push(this.number);
100
+ }
101
+ let result = parts.join(" ");
102
+ if (this.ptc_suffix !== undefined)
103
+ result += ` ${this.ptc_suffix}`;
104
+ if (this.csa_number !== undefined)
105
+ result += `/CSA ${this.csa_number}`;
106
+ if (this.handbook === true)
107
+ result += " Handbook";
108
+ if (this.draft_year !== undefined)
109
+ result += `-${this.draft_year}`;
110
+ else if (this.year !== undefined)
111
+ result += `-${this.year}`;
112
+ if (this.parenthetical_revision !== undefined)
113
+ result += ` ${this.parenthetical_revision}`;
114
+ if (this.language !== undefined)
115
+ result += ` (${this.language})`;
116
+ if (this.reaffirmation !== undefined)
117
+ result += ` (${this.reaffirmation})`;
118
+ if (this.revision_note !== undefined)
119
+ result += ` ${this.revision_note}`;
120
+ return result.replaceAll(/[–—]/g, "-");
121
+ }
122
+ }
123
+ registerType(AsmeIdentifier);
@@ -0,0 +1,2 @@
1
+ import { Grammar } from "../../grammar/engine.js";
2
+ export declare const astmGrammar: Grammar;
@@ -0,0 +1,110 @@
1
+ import { match, ref, str } from "../../grammar/engine.js";
2
+ /**
3
+ * Port of lib/pubid/astm/parser.rb — 1:1. The identifier alternation
4
+ * order is load-bearing (research_report first, standard last).
5
+ */
6
+ function buildRules() {
7
+ const rules = {};
8
+ const rule = (name, build) => {
9
+ rules[name] = build();
10
+ };
11
+ const space = str(" ");
12
+ const dash = str("-");
13
+ const slash = str("/");
14
+ const colon = str(":");
15
+ const digit = match("[0-9]");
16
+ const digits = digit.repeat(1, Infinity);
17
+ const letter = match("[A-Z]");
18
+ const letters = letter.repeat(1, Infinity);
19
+ const publisher = () => str("ASTM").as("publisher").then(space.maybe());
20
+ rule("standard_letter", () => match("[A-G]").as("letter"));
21
+ rule("year_2digit", () => digit.repeat(2, 2).as("year"));
22
+ rule("reapproval", () => str("(").then(digit.repeat(4, 4).as("reapproval")).then(str(")")));
23
+ rule("comment", () => space.maybe().then(str("#")).then(match("[^#]").repeat(0, Infinity)));
24
+ rule("edition", () => str("e").then(digits.as("edition_number"))
25
+ .or(str("9TH")).or(str("8TH")).or(str("7TH")).or(str("6TH"))
26
+ .or(str("5TH")).or(str("4TH")).or(str("3RD")).or(str("2ND"))
27
+ .or(str("1ST"))
28
+ .as("edition"));
29
+ rule("sub_year", () => match("[a-c]").as("sub_year"));
30
+ rule("format_suffix", () => dash.then(str("EB").as("format_suffix")));
31
+ rule("format_suffix_no_dash", () => str("EB").as("format_suffix"));
32
+ rule("supplement", () => dash.then(str("SUP").as("supplement")).then(dash));
33
+ rule("research_report", () => publisher().maybe()
34
+ .then(str("RR").as("type"))
35
+ .then(colon)
36
+ .then(letter.then(digit.repeat(2, 2)).as("committee"))
37
+ .then(dash)
38
+ .then(digits.as("number")));
39
+ rule("manual", () => publisher().maybe()
40
+ .then(str("MNL").as("type"))
41
+ .then(str("TP").as("tp_designation").maybe())
42
+ .then(digits.as("number"))
43
+ .then(dash.then(ref(rules, "edition")).maybe())
44
+ .then(ref(rules, "supplement").then(ref(rules, "format_suffix_no_dash").maybe())
45
+ .or(ref(rules, "format_suffix").maybe())));
46
+ rule("monograph", () => publisher().maybe()
47
+ .then(str("MONO").as("type"))
48
+ .then(digits.as("number"))
49
+ .then(dash.then(ref(rules, "edition")).maybe())
50
+ .then(ref(rules, "format_suffix").maybe()));
51
+ rule("data_series_suffix", () => match("[A-Z]").as("suffix"));
52
+ rule("data_series_subseries_with_dash", () => dash.then(str("S")).then(digits.as("subseries")));
53
+ rule("data_series_subseries_no_dash", () => digits.as("subseries"));
54
+ rule("data_series_code", () => digits.as("number").then(str("HOL").as("hol_suffix")
55
+ .or(ref(rules, "data_series_suffix")
56
+ .then(
57
+ // A letter suffix may carry its subseries with the dash
58
+ // spelled out too ("DS55S-S1"), not only glued ("DS55S1").
59
+ ref(rules, "data_series_subseries_no_dash")
60
+ .or(ref(rules, "data_series_subseries_with_dash"))
61
+ .maybe()))
62
+ .or(ref(rules, "data_series_subseries_with_dash"))
63
+ .maybe()));
64
+ rule("data_series", () => publisher().maybe()
65
+ .then(str("DS").as("type"))
66
+ .then(ref(rules, "data_series_code"))
67
+ .then(ref(rules, "format_suffix").maybe()));
68
+ rule("work_in_progress", () => publisher().maybe()
69
+ .then(str("WK").as("type"))
70
+ .then(digits.as("number")));
71
+ rule("adjunct", () => publisher().maybe()
72
+ .then(str("ADJ").as("type"))
73
+ .then(letter.then(digits).or(letters).or(digits).as("designation"))
74
+ .then(dash.then(str("EA")).maybe().as("ea_suffix"))
75
+ .then(str("DVD").maybe().as("dvd_suffix")));
76
+ rule("technical_report_iso_astm", () => str("ISO/ASTMTR").as("type")
77
+ .then(digits.as("number"))
78
+ .then(ref(rules, "format_suffix").maybe())
79
+ .then(ref(rules, "comment").maybe()));
80
+ rule("technical_report_simple", () => publisher().maybe()
81
+ .then(str("TR").as("type"))
82
+ .then(digits.as("number"))
83
+ .then(ref(rules, "format_suffix").maybe())
84
+ .then(ref(rules, "comment").maybe()));
85
+ rule("technical_report", () => ref(rules, "technical_report_iso_astm").or(ref(rules, "technical_report_simple")));
86
+ rule("dual_unit", () => slash.then(ref(rules, "standard_letter")).then(digits).then(str("M").as("dual_m")));
87
+ rule("standard_code_with_letter", () => ref(rules, "standard_letter").then(digits.as("number")).then(ref(rules, "dual_unit").maybe()));
88
+ rule("standard_code_digit_only", () => digits.as("number"));
89
+ rule("standard", () => publisher().maybe()
90
+ .then(ref(rules, "standard_code_with_letter").or(ref(rules, "standard_code_digit_only")))
91
+ .then(dash.then(ref(rules, "year_2digit"))
92
+ .then(ref(rules, "sub_year").maybe())
93
+ .then(ref(rules, "reapproval").maybe())
94
+ .then(ref(rules, "edition").maybe())
95
+ .maybe())
96
+ .then(ref(rules, "comment").maybe()));
97
+ rule("identifier", () => ref(rules, "research_report")
98
+ .or(ref(rules, "technical_report"))
99
+ .or(ref(rules, "manual"))
100
+ .or(ref(rules, "monograph"))
101
+ .or(ref(rules, "data_series"))
102
+ .or(ref(rules, "work_in_progress"))
103
+ .or(ref(rules, "adjunct"))
104
+ .or(ref(rules, "standard")));
105
+ return rules;
106
+ }
107
+ export const astmGrammar = {
108
+ rules: buildRules(),
109
+ root: "identifier",
110
+ };
@@ -0,0 +1,2 @@
1
+ import type { FlavorImplementation } from "../../conformance/implementation.js";
2
+ export declare function astmGrammarImplementation(): FlavorImplementation;
@@ -0,0 +1,127 @@
1
+ import { parseGrammar } from "../../grammar/engine.js";
2
+ import { astmGrammar } from "./grammar.js";
3
+ import { AdjunctClass, DataSeriesClass, IsoDualPublishedClass, ManualClass, MonographClass, ResearchReportClass, StandardClass, TechnicalReportClass, WorkInProgressClass, } from "./model.js";
4
+ /**
5
+ * Port of lib/pubid/astm/builder.rb — the parse-tree → identifier
6
+ * pipeline (class routing by type/number, code-column assembly,
7
+ * type-specific attributes, 2-digit year conversion).
8
+ */
9
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
10
+ const str = (v) => {
11
+ if (v === undefined || v === null)
12
+ return undefined;
13
+ const s = String(v);
14
+ return s.length > 0 ? s : undefined;
15
+ };
16
+ function convertYear(yearStr) {
17
+ if (yearStr.length === 4)
18
+ return yearStr;
19
+ const yearInt = Number.parseInt(yearStr, 10);
20
+ return yearInt <= 24 ? `20${yearStr}` : `19${yearStr}`;
21
+ }
22
+ function determineClass(d) {
23
+ const type = str(d["type"]);
24
+ if ((type === undefined || type === "") && d["number"] !== undefined && d["letter"] === undefined) {
25
+ const numberStr = str(d["number"]) ?? "";
26
+ if (numberStr.startsWith("5"))
27
+ return IsoDualPublishedClass;
28
+ return StandardClass;
29
+ }
30
+ switch (type) {
31
+ case "RR": return ResearchReportClass;
32
+ case "MNL": return ManualClass;
33
+ case "MONO": return MonographClass;
34
+ case "DS": return DataSeriesClass;
35
+ case "WK": return WorkInProgressClass;
36
+ case "ADJ": return AdjunctClass;
37
+ case "TR":
38
+ case "ISO/ASTMTR":
39
+ return TechnicalReportClass;
40
+ default: return StandardClass;
41
+ }
42
+ }
43
+ class AstmBuilder {
44
+ build(tree) {
45
+ const d = Array.isArray(tree) ? Object.assign({}, ...tree) : tree;
46
+ const klass = determineClass(d);
47
+ const self = {};
48
+ if (d["letter"] !== undefined || d["number"] !== undefined) {
49
+ const letter = d["letter"] !== undefined &&
50
+ !(str(d["type"]) === "TR" && (str(d["publisher"]) ?? "").startsWith("ISO/ASTM"))
51
+ ? str(d["letter"])
52
+ : undefined;
53
+ self["letter"] = letter;
54
+ self["number"] = str(d["number"]);
55
+ self["suffix"] = str(d["suffix"]);
56
+ self["subseries"] = str(d["subseries"]);
57
+ self["dual_m"] = d["dual_m"] !== undefined;
58
+ }
59
+ if (str(d["type"]) === "ISO/ASTMTR") {
60
+ self["publisher"] = "ISO/ASTM";
61
+ }
62
+ else {
63
+ self["publisher"] = str(d["publisher"]) ?? "ASTM";
64
+ }
65
+ if (d["year"] !== undefined) {
66
+ self["year"] = convertYear(str(d["year"]) ?? "");
67
+ }
68
+ if (d["format_suffix"] !== undefined) {
69
+ self["format_suffix"] = `-${str(d["format_suffix"])}`;
70
+ }
71
+ this.buildTypeSpecific(self, klass, d);
72
+ return new klass(self);
73
+ }
74
+ buildTypeSpecific(self, klass, d) {
75
+ if (klass === ResearchReportClass && d["committee"] !== undefined) {
76
+ self["committee"] = str(d["committee"]);
77
+ }
78
+ if (klass === ManualClass) {
79
+ if (d["edition"] !== undefined)
80
+ self["edition"] = str(d["edition"]);
81
+ if (d["supplement"] !== undefined)
82
+ self["supplement"] = true;
83
+ if (d["tp_designation"] !== undefined)
84
+ self["tp_designation"] = str(d["tp_designation"]);
85
+ }
86
+ if (klass === MonographClass && d["edition"] !== undefined) {
87
+ self["edition"] = str(d["edition"]);
88
+ }
89
+ if (klass === DataSeriesClass && d["hol_suffix"] !== undefined) {
90
+ self["hol_suffix"] = true;
91
+ }
92
+ if (klass === AdjunctClass) {
93
+ if (d["designation"] !== undefined)
94
+ self["number"] = str(d["designation"]);
95
+ if (d["ea_suffix"] !== undefined && d["ea_suffix"] !== null)
96
+ self["ea_suffix"] = true;
97
+ if (d["dvd_suffix"] !== undefined && d["dvd_suffix"] !== null)
98
+ self["dvd_suffix"] = true;
99
+ }
100
+ if (klass === StandardClass || klass === IsoDualPublishedClass) {
101
+ if (d["sub_year"] !== undefined)
102
+ self["sub_year"] = str(d["sub_year"]);
103
+ if (d["reapproval"] !== undefined)
104
+ self["reapproval"] = str(d["reapproval"]);
105
+ const editionData = d["edition"];
106
+ if (editionData !== undefined) {
107
+ if (isObj(editionData)) {
108
+ const editionNumber = str(editionData["edition_number"]);
109
+ if (editionNumber !== undefined)
110
+ self["edition"] = editionNumber;
111
+ }
112
+ else {
113
+ self["edition"] = str(editionData);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ export function astmGrammarImplementation() {
120
+ const builder = new AstmBuilder();
121
+ return {
122
+ parse(input) {
123
+ const tree = parseGrammar(astmGrammar, input);
124
+ return builder.build(tree);
125
+ },
126
+ };
127
+ }
@@ -0,0 +1,42 @@
1
+ import { BaseIdentifier } from "../../model/identifier.js";
2
+ import type { IdentifierStatic } from "../../model/identifier.js";
3
+ import { type AttributeTable, type FieldMapping } from "../../model/attribute.js";
4
+ /**
5
+ * Port of lib/pubid/astm: the CodeNumber split columns (letter/number/
6
+ * suffix/subseries/dual_m) on every concrete class, the renderer family
7
+ * and the URN generator. Adjunct stores its designation directly in
8
+ * `number`.
9
+ */
10
+ export declare class AstmCode {
11
+ readonly letter: string | undefined;
12
+ readonly number: string | undefined;
13
+ readonly suffix: string | undefined;
14
+ readonly subseries: string | undefined;
15
+ readonly dualM: boolean;
16
+ constructor(attrs: Record<string, unknown>);
17
+ render(): string;
18
+ }
19
+ export declare abstract class AstmIdentifier extends BaseIdentifier {
20
+ static attributes: AttributeTable;
21
+ static mappings: FieldMapping[];
22
+ readonly number: string | undefined;
23
+ readonly letter: string | undefined;
24
+ readonly suffix: string | undefined;
25
+ readonly subseries: string | undefined;
26
+ readonly dual_m: boolean | undefined;
27
+ readonly publisher: string;
28
+ readonly year: string | undefined;
29
+ readonly format_suffix: string | undefined;
30
+ readonly type: string | undefined;
31
+ code(): AstmCode | undefined;
32
+ toUrn(): string;
33
+ }
34
+ export declare const StandardClass: IdentifierStatic;
35
+ export declare const IsoDualPublishedClass: IdentifierStatic;
36
+ export declare const ResearchReportClass: IdentifierStatic;
37
+ export declare const DataSeriesClass: IdentifierStatic;
38
+ export declare const TechnicalReportClass: IdentifierStatic;
39
+ export declare const MonographClass: IdentifierStatic;
40
+ export declare const AdjunctClass: IdentifierStatic;
41
+ export declare const WorkInProgressClass: IdentifierStatic;
42
+ export declare const ManualClass: IdentifierStatic;