pro-editor-schema 1.4.1 → 1.6.0

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/dist/index.mjs CHANGED
@@ -17,6 +17,7 @@ var FIGURE_PLACEMENT_ATTRIBUTE = "data-figure-placement";
17
17
  var LAYOUT_CELL_WIDTH_ATTRIBUTE = "data-cell-width";
18
18
  var LAYOUT_TABLE_ORIENTATION_ATTRIBUTE = "data-table-orientation";
19
19
  var LAYOUT_TABLE_PLACEMENT_ATTRIBUTE = "data-table-placement";
20
+ var VALIDATION_IGNORED_ATTRIBUTE = "data-validation-ignored";
20
21
  var LAYOUT_ATTRIBUTES = [
21
22
  ALIGNMENT_ATTRIBUTE,
22
23
  LEFT_INDENT_ATTRIBUTE,
@@ -146,7 +147,7 @@ var EMPHASIS_SCHEMA = createSchema({
146
147
  ...TRACK_CHANGES_ATTRS,
147
148
  {
148
149
  name: "role",
149
- values: ["lowercase", "uppercase", "initialcaps"],
150
+ values: ["lowercase", "uppercase", "initialcaps", "Non breaking space"],
150
151
  defaultValue: "lowercase"
151
152
  }
152
153
  ],
@@ -646,6 +647,27 @@ var POEM_TAG = "POEM";
646
647
  var BIBLIOMIXED_TAG = "BIBLIOMIXED";
647
648
  var REFERENCE_BIBLIOGRAPHY_TAG = "BIBLIOGRAPHY";
648
649
  var BIBLIODIV_TAG = "BIBLIODIV";
650
+ var BIBLIOMSET_TAG = "BIBLIOMSET";
651
+ var EDITOR_TAG = "EDITOR";
652
+ var OTHERCREDIT_TAG = "OTHERCREDIT";
653
+ var TRANSLATOR_TAG = "TRANSLATOR";
654
+ var COLLAB_TAG = "COLLAB";
655
+ var PUBDATE_TAG = "PUBDATE";
656
+ var DATE_TAG = "DATE";
657
+ var PUBLISHERNAME_TAG = "PUBLISHERNAME";
658
+ var ADDRESS_TAG = "ADDRESS";
659
+ var CITY_TAG = "CITY";
660
+ var VOLUMENUM_TAG = "VOLUMENUM";
661
+ var ISSUENUM_TAG = "ISSUENUM";
662
+ var PAGENUMS_TAG = "PAGENUMS";
663
+ var PAGENUM_TAG = "PAGENUM";
664
+ var EDITION_TAG = "EDITION";
665
+ var PUB_ID_TAG = "PUB-ID";
666
+ var BIBLIOID_TAG = "BIBLIOID";
667
+ var BIBLIOMISC_TAG = "BIBLIOMISC";
668
+ var CONFGROUP_TAG = "CONFGROUP";
669
+ var CONFTITLE_TAG = "CONFTITLE";
670
+ var CONFDATES_TAG = "CONFDATES";
649
671
  var MATHPHRASE_TAG = "MATHPHRASE";
650
672
  var MATH_TAG = "MATH";
651
673
  var MERROR_TAG = "MERROR";
@@ -866,7 +888,8 @@ var EQUATION_SCHEMA = createSchema({
866
888
  ],
867
889
  allowedChildrenCodes: [
868
890
  { code: "mathphrase", required: true },
869
- { code: "caption1", required: false }
891
+ { code: "caption1", required: false },
892
+ { code: "tag", required: false }
870
893
  ]
871
894
  });
872
895
 
@@ -1791,6 +1814,82 @@ var TABLE_SCHEMA = createSchema({
1791
1814
  ]
1792
1815
  });
1793
1816
 
1817
+ // src/schema/elementSchemas/elements/heading.ts
1818
+ var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
1819
+ var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
1820
+ var HEADING_SCHEMA = createSchema({
1821
+ code: "heading",
1822
+ kind: "element",
1823
+ tag: SECTION_TAG,
1824
+ matchesElement: (element) => {
1825
+ const role = element.getAttribute("role");
1826
+ if (!role) return false;
1827
+ return HEADING_ROLES.includes(role);
1828
+ },
1829
+ requiredAttributes: [
1830
+ ...ID_ATTRS,
1831
+ "xmlid",
1832
+ {
1833
+ name: "role",
1834
+ values: HEADING_ROLES,
1835
+ defaultValue: "H1"
1836
+ }
1837
+ ],
1838
+ optionalAttributes: [...TRACK_CHANGES_ATTRS],
1839
+ defaultChildCode: "para",
1840
+ allowedChildrenCodes: [
1841
+ { code: "title1", required: false },
1842
+ { code: "label1", required: false },
1843
+ { code: "para", required: false },
1844
+ { code: "subtitle1", required: false },
1845
+ { code: "sidebar", required: false },
1846
+ { code: "epigraph", required: false },
1847
+ { code: "blockquote", required: false },
1848
+ { code: "ul", required: false },
1849
+ { code: "ol", required: false },
1850
+ { code: "poem", required: false },
1851
+ { code: "dialogue", required: false },
1852
+ { code: "appendix", required: false },
1853
+ { code: "table1", required: false },
1854
+ { code: "figure1", required: false },
1855
+ { code: "heading", required: false },
1856
+ { code: "footnoteSection", required: false },
1857
+ { code: "info1", required: false },
1858
+ { code: "equation", required: false }
1859
+ ]
1860
+ });
1861
+
1862
+ // src/schema/elementSchemas/elements/box.ts
1863
+ var BOX_LEVEL = ["box1", "box2", "box3", "box4", "box5"];
1864
+ var BOX_SCHEMA = createSchema({
1865
+ code: "sidebar",
1866
+ kind: "element",
1867
+ tag: SIDEBAR_TAG,
1868
+ requiredAttributes: [
1869
+ ...ID_ATTRS,
1870
+ {
1871
+ name: "status",
1872
+ values: BOX_LEVEL,
1873
+ defaultValue: "box1"
1874
+ }
1875
+ ],
1876
+ optionalAttributes: [
1877
+ ...TRACK_CHANGES_ATTRS,
1878
+ "xmlid",
1879
+ {
1880
+ name: "role",
1881
+ values: ["add-element", "change-para-box"],
1882
+ defaultValue: "add-element"
1883
+ }
1884
+ ],
1885
+ defaultChildCode: "para",
1886
+ allowedChildrenCodes: [
1887
+ { code: "para", required: false },
1888
+ { code: "title1", required: false },
1889
+ { code: "sidebar", required: false }
1890
+ ]
1891
+ });
1892
+
1794
1893
  // src/schema/elementSchemas/elements/title.ts
1795
1894
  var TITLE_SCHEMA = createSchema({
1796
1895
  code: "title1",
@@ -1808,7 +1907,7 @@ var TITLE_SCHEMA = createSchema({
1808
1907
  },
1809
1908
  {
1810
1909
  name: "title",
1811
- values: ["H1", "H2", "H3", "H4", "H5", "H6", "foot_note"],
1910
+ values: [...HEADING_LEVEL, ...BOX_LEVEL, "foot_note"],
1812
1911
  defaultValue: "H1"
1813
1912
  }
1814
1913
  ],
@@ -1886,36 +1985,8 @@ var BLOCKQUOTE_SCHEMA = createSchema({
1886
1985
  { code: "ul", required: false },
1887
1986
  { code: "ol", required: false },
1888
1987
  { code: "sidebar", required: false },
1889
- { code: "source1", required: false }
1890
- ]
1891
- });
1892
-
1893
- // src/schema/elementSchemas/elements/box.ts
1894
- var BOX_SCHEMA = createSchema({
1895
- code: "sidebar",
1896
- kind: "element",
1897
- tag: SIDEBAR_TAG,
1898
- requiredAttributes: [
1899
- ...ID_ATTRS,
1900
- {
1901
- name: "status",
1902
- values: ["box1", "box2", "box3", "box4", "box5"],
1903
- defaultValue: "box1"
1904
- }
1905
- ],
1906
- optionalAttributes: [
1907
- ...TRACK_CHANGES_ATTRS,
1908
- "xmlid",
1909
- {
1910
- name: "role",
1911
- values: ["add-element", "change-para-box"],
1912
- defaultValue: "add-element"
1913
- }
1914
- ],
1915
- defaultChildCode: "para",
1916
- allowedChildrenCodes: [
1917
- { code: "para", required: false },
1918
- { code: "title1", required: false }
1988
+ { code: "source1", required: false },
1989
+ { code: "tag", required: false }
1919
1990
  ]
1920
1991
  });
1921
1992
 
@@ -1972,7 +2043,10 @@ var EPIGRAPH_SCHEMA = createSchema({
1972
2043
  }
1973
2044
  ],
1974
2045
  defaultChildCode: "para",
1975
- allowedChildrenCodes: [{ code: "para", required: false }]
2046
+ allowedChildrenCodes: [
2047
+ { code: "para", required: false },
2048
+ { code: "tag", required: false }
2049
+ ]
1976
2050
  });
1977
2051
 
1978
2052
  // src/schema/elementSchemas/elements/footnoteSection.ts
@@ -2002,51 +2076,6 @@ var FOOTNOTE_SECTION_SCHEMA = createSchema({
2002
2076
  ]
2003
2077
  });
2004
2078
 
2005
- // src/schema/elementSchemas/elements/heading.ts
2006
- var HEADING_LEVEL = ["H0", "H1", "H2", "H3", "H4", "H5", "H6"];
2007
- var HEADING_ROLES = [...HEADING_LEVEL, "vignette_group"];
2008
- var HEADING_SCHEMA = createSchema({
2009
- code: "heading",
2010
- kind: "element",
2011
- tag: SECTION_TAG,
2012
- matchesElement: (element) => {
2013
- const role = element.getAttribute("role");
2014
- if (!role) return false;
2015
- return HEADING_ROLES.includes(role);
2016
- },
2017
- requiredAttributes: [
2018
- ...ID_ATTRS,
2019
- "xmlid",
2020
- {
2021
- name: "role",
2022
- values: HEADING_ROLES,
2023
- defaultValue: "H1"
2024
- }
2025
- ],
2026
- optionalAttributes: [...TRACK_CHANGES_ATTRS],
2027
- defaultChildCode: "para",
2028
- allowedChildrenCodes: [
2029
- { code: "title1", required: false },
2030
- { code: "label1", required: false },
2031
- { code: "para", required: false },
2032
- { code: "subtitle1", required: false },
2033
- { code: "sidebar", required: false },
2034
- { code: "epigraph", required: false },
2035
- { code: "blockquote", required: false },
2036
- { code: "ul", required: false },
2037
- { code: "ol", required: false },
2038
- { code: "poem", required: false },
2039
- { code: "dialogue", required: false },
2040
- { code: "appendix", required: false },
2041
- { code: "table1", required: false },
2042
- { code: "figure1", required: false },
2043
- { code: "heading", required: false },
2044
- { code: "footnoteSection", required: false },
2045
- { code: "info1", required: false },
2046
- { code: "equation", required: false }
2047
- ]
2048
- });
2049
-
2050
2079
  // src/schema/elementSchemas/elements/info.ts
2051
2080
  var INFO_SCHEMA = createSchema({
2052
2081
  code: "info1",
@@ -2091,28 +2120,6 @@ var MATHPHRASE_SCHEMA = createSchema({
2091
2120
  allowedChildrenCodes: [{ code: MATH_SCHEMA.code, required: true }]
2092
2121
  });
2093
2122
 
2094
- // src/schema/elementSchemas/elements/reference/bibliodiv.ts
2095
- var BIBLIODIV_SCHEMA = createSchema({
2096
- code: "bibliodiv",
2097
- kind: "element",
2098
- tag: BIBLIODIV_TAG,
2099
- requiredAttributes: [
2100
- ...ID_ATTRS,
2101
- {
2102
- name: "role",
2103
- values: ["H1", "H2", "H3", "H4", "H5", "H6"],
2104
- defaultValue: "H1"
2105
- }
2106
- ],
2107
- optionalAttributes: [],
2108
- allowedChildrenCodes: [
2109
- { code: "bibliodiv", required: false },
2110
- { code: "referenceBibliomixed", required: false },
2111
- { code: "para", required: false },
2112
- { code: "title1", required: false }
2113
- ]
2114
- });
2115
-
2116
2123
  // src/schema/elementSchemas/elements/reference/bibliography.ts
2117
2124
  var REFERENCE_BIBLIOGRAPHY_SCHEMA = createSchema({
2118
2125
  code: "referenceBibliography",
@@ -2141,6 +2148,31 @@ var REFERENCE_BIBLIOGRAPHY_SCHEMA = createSchema({
2141
2148
  ]
2142
2149
  });
2143
2150
 
2151
+ // src/schema/shared/allowedReferenceChildren.ts
2152
+ var REFERENCE_PART_CODES_ALLOWED_CHILDREN = [
2153
+ { code: "author", required: false },
2154
+ { code: "editor", required: false },
2155
+ { code: "othercredit", required: false },
2156
+ { code: "translator", required: false },
2157
+ { code: "collab", required: false },
2158
+ { code: "title1", required: false },
2159
+ { code: "pubdate", required: false },
2160
+ { code: "date", required: false },
2161
+ { code: "publishername", required: false },
2162
+ { code: "orgname", required: false },
2163
+ { code: "address", required: false },
2164
+ { code: "volumenum", required: false },
2165
+ { code: "issuenum", required: false },
2166
+ { code: "pagenums", required: false },
2167
+ { code: "pagenum", required: false },
2168
+ { code: "edition", required: false },
2169
+ { code: "link", required: false },
2170
+ { code: "pubId", required: false },
2171
+ { code: "biblioid", required: false },
2172
+ { code: "bibliomisc", required: false },
2173
+ { code: "confgroup", required: false }
2174
+ ];
2175
+
2144
2176
  // src/schema/elementSchemas/elements/reference/bibliomixed.ts
2145
2177
  var BIBLIOMIXED_SCHEMA = createSchema({
2146
2178
  code: "referenceBibliomixed",
@@ -2152,82 +2184,390 @@ var BIBLIOMIXED_SCHEMA = createSchema({
2152
2184
  TRACK_CHANGES_ATTR_DATA_USERID,
2153
2185
  TRACK_CHANGES_ATTR_DATA_DATE
2154
2186
  ],
2155
- allowedChildrenCodes: []
2187
+ allowedChildrenCodes: [
2188
+ { code: "bibliomset", required: false },
2189
+ ...REFERENCE_PART_CODES_ALLOWED_CHILDREN,
2190
+ ...ATOM_CODES_ALLOWED_CHILDREN
2191
+ ]
2156
2192
  });
2157
2193
 
2158
- // src/schema/elementSchemas/elements/index.ts
2159
- var ELEMENT_SCHEMAS = {
2160
- bibliodiv: BIBLIODIV_SCHEMA,
2161
- referenceBibliography: REFERENCE_BIBLIOGRAPHY_SCHEMA,
2162
- referenceBibliomixed: BIBLIOMIXED_SCHEMA,
2163
- para: PARA_SCHEMA,
2164
- title1: TITLE_SCHEMA,
2165
- footnote: FOOTNOTE_SCHEMA,
2166
- footnoteno: FOOTNOTE_NUMBER_SCHEMA,
2167
- olink: OLINK_SCHEMA,
2168
- firstname: FIRSTNAME_SCHEMA,
2169
- surname: SURNAME_SCHEMA,
2170
- honorific: HONORIFIC_SCHEMA,
2171
- orgname: ORGNAME_SCHEMA,
2172
- email: EMAIL_SCHEMA,
2173
- org: ORG_SCHEMA,
2174
- degrees: DEGREES_SCHEMA,
2175
- dialogue: DIALOGUE_SCHEMA,
2176
- line: LINE_SCHEMA,
2177
- linegroup: LINE_GROUP_SCHEMA,
2178
- speaker: SPEAKER_SCHEMA,
2179
- equation: EQUATION_SCHEMA,
2180
- math: MATH_SCHEMA,
2181
- mathphrase: MATHPHRASE_SCHEMA,
2182
- merror: MERROR_SCHEMA,
2183
- mfrac: MFRAC_SCHEMA,
2184
- mi: MI_SCHEMA,
2185
- mmultiscripts: MMULTISCRIPTS_SCHEMA,
2186
- mn: MN_SCHEMA,
2187
- mo: MO_SCHEMA,
2188
- mover: MOVER_SCHEMA,
2189
- mpadded: MPADDED_SCHEMA,
2190
- mphantom: MPHANTOM_SCHEMA,
2191
- mprescripts: MPRESCRIPTS_SCHEMA,
2192
- mroot: MROOT_SCHEMA,
2193
- mrow: MROW_SCHEMA,
2194
- ms: MS_SCHEMA,
2195
- mspace: MSPACE_SCHEMA,
2196
- msqrt: MSQRT_SCHEMA,
2197
- mstyle: MSTYLE_SCHEMA,
2198
- msub: MSUB_SCHEMA,
2199
- msubsup: MSUBSUP_SCHEMA,
2200
- msup: MSUP_SCHEMA,
2201
- mtable: MTABLE_SCHEMA,
2202
- mtd: MTD_SCHEMA,
2203
- mtext: MTEXT_SCHEMA,
2204
- mtr: MTR_SCHEMA,
2205
- munder: MUNDER_SCHEMA,
2206
- munderover: MUNDEROVER_SCHEMA,
2207
- img: IMG_SCHEMA,
2208
- alttext: ALTTEXT_SCHEMA,
2209
- imageobject: IMAGEOBJECT_SCHEMA,
2210
- mediaobject: MEDIAOBJECT_SCHEMA,
2211
- caption1: CAPTION_SCHEMA,
2212
- figsource: FIGSOURCE_SCHEMA,
2213
- fignote: FIGNOTE_SCHEMA,
2214
- figure1: FIGURE_SCHEMA,
2215
- informalfigure: INFORMALFIGURE_SCHEMA,
2216
- keywordset: KEYWORDSET_SCHEMA,
2217
- keyword: KEYWORD_SCHEMA,
2218
- punc: PUNC_SCHEMA,
2219
- label1: LABEL_SCHEMA,
2220
- li: LI_SCHEMA,
2221
- ol: OL_SCHEMA,
2222
- ul: UL_SCHEMA,
2223
- token: TOKEN_SCHEMA,
2224
- tag: TAG_SCHEMA,
2225
- lrh: LRH_SCHEMA,
2226
- rrh: RRH_SCHEMA,
2227
- source1: SOURCE_SCHEMA,
2228
- subtitle1: SUBTITLE_SCHEMA,
2229
- table1: TABLE_SCHEMA,
2230
- tgroup: TGROUP_SCHEMA,
2194
+ // src/schema/elementSchemas/elements/reference/bibliodiv.ts
2195
+ var BIBLIODIV_SCHEMA = createSchema({
2196
+ code: "bibliodiv",
2197
+ kind: "element",
2198
+ tag: BIBLIODIV_TAG,
2199
+ requiredAttributes: [
2200
+ ...ID_ATTRS,
2201
+ "role"
2202
+ ],
2203
+ optionalAttributes: [],
2204
+ allowedChildrenCodes: [
2205
+ { code: "bibliodiv", required: false },
2206
+ { code: "referenceBibliomixed", required: false },
2207
+ { code: "para", required: false },
2208
+ { code: "title1", required: false }
2209
+ ]
2210
+ });
2211
+
2212
+ // src/schema/elementSchemas/elements/reference/bibliomset.ts
2213
+ var CONTAINER_BIBLIOMSET_RELATIONS = ["book", "journal"];
2214
+ var PART_BIBLIOMSET_RELATION = "part";
2215
+ var BIBLIOMSET_SCHEMA = createSchema({
2216
+ code: "bibliomset",
2217
+ kind: "element",
2218
+ tag: BIBLIOMSET_TAG,
2219
+ requiredAttributes: [
2220
+ {
2221
+ name: "relation",
2222
+ values: [
2223
+ PART_BIBLIOMSET_RELATION,
2224
+ "article",
2225
+ ...CONTAINER_BIBLIOMSET_RELATIONS
2226
+ ],
2227
+ defaultValue: PART_BIBLIOMSET_RELATION
2228
+ }
2229
+ ],
2230
+ optionalAttributes: [...ID_ATTRS],
2231
+ allowedChildrenCodes: [
2232
+ ...REFERENCE_PART_CODES_ALLOWED_CHILDREN,
2233
+ ...ATOM_CODES_ALLOWED_CHILDREN
2234
+ ]
2235
+ });
2236
+
2237
+ // src/schema/elementSchemas/elements/reference/editor.ts
2238
+ var EDITOR_SCHEMA = createSchema({
2239
+ code: "editor",
2240
+ kind: "element",
2241
+ tag: EDITOR_TAG,
2242
+ requiredAttributes: [],
2243
+ optionalAttributes: [...ID_ATTRS],
2244
+ allowedChildrenCodes: [
2245
+ { code: "personname", required: false },
2246
+ { code: "orgname", required: false },
2247
+ ...ATOM_CODES_ALLOWED_CHILDREN
2248
+ ]
2249
+ });
2250
+
2251
+ // src/schema/elementSchemas/elements/reference/othercredit.ts
2252
+ var OTHERCREDIT_SCHEMA = createSchema({
2253
+ code: "othercredit",
2254
+ kind: "element",
2255
+ tag: OTHERCREDIT_TAG,
2256
+ requiredAttributes: [],
2257
+ optionalAttributes: [...ID_ATTRS, "class", "otherclass"],
2258
+ allowedChildrenCodes: [
2259
+ { code: "personname", required: false },
2260
+ { code: "orgname", required: false },
2261
+ ...ATOM_CODES_ALLOWED_CHILDREN
2262
+ ]
2263
+ });
2264
+
2265
+ // src/schema/elementSchemas/elements/reference/translator.ts
2266
+ var TRANSLATOR_SCHEMA = createSchema({
2267
+ code: "translator",
2268
+ kind: "element",
2269
+ tag: TRANSLATOR_TAG,
2270
+ requiredAttributes: [],
2271
+ optionalAttributes: [...ID_ATTRS],
2272
+ allowedChildrenCodes: [
2273
+ { code: "personname", required: false },
2274
+ { code: "orgname", required: false },
2275
+ ...ATOM_CODES_ALLOWED_CHILDREN
2276
+ ]
2277
+ });
2278
+
2279
+ // src/schema/elementSchemas/elements/reference/collab.ts
2280
+ var COLLAB_SCHEMA = createSchema({
2281
+ code: "collab",
2282
+ kind: "element",
2283
+ tag: COLLAB_TAG,
2284
+ requiredAttributes: [],
2285
+ optionalAttributes: [...ID_ATTRS],
2286
+ allowedChildrenCodes: [
2287
+ { code: "orgname", required: false },
2288
+ { code: "personname", required: false },
2289
+ ...ATOM_CODES_ALLOWED_CHILDREN
2290
+ ]
2291
+ });
2292
+
2293
+ // src/schema/elementSchemas/elements/reference/pubdate.ts
2294
+ var PUBDATE_SCHEMA = createSchema({
2295
+ code: "pubdate",
2296
+ kind: "element",
2297
+ tag: PUBDATE_TAG,
2298
+ requiredAttributes: [],
2299
+ optionalAttributes: [...ID_ATTRS],
2300
+ allowedChildrenCodes: [
2301
+ ...ATOM_CODES_ALLOWED_CHILDREN
2302
+ ]
2303
+ });
2304
+
2305
+ // src/schema/elementSchemas/elements/reference/date.ts
2306
+ var ACCESSED_DATE_ROLE = "accessed";
2307
+ var DATE_SCHEMA = createSchema({
2308
+ code: "date",
2309
+ kind: "element",
2310
+ tag: DATE_TAG,
2311
+ requiredAttributes: [],
2312
+ optionalAttributes: [...ID_ATTRS, "role"],
2313
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2314
+ });
2315
+
2316
+ // src/schema/elementSchemas/elements/reference/publishername.ts
2317
+ var PUBLISHERNAME_SCHEMA = createSchema({
2318
+ code: "publishername",
2319
+ kind: "element",
2320
+ tag: PUBLISHERNAME_TAG,
2321
+ requiredAttributes: [],
2322
+ optionalAttributes: [...ID_ATTRS],
2323
+ allowedChildrenCodes: [
2324
+ ...ATOM_CODES_ALLOWED_CHILDREN
2325
+ ]
2326
+ });
2327
+
2328
+ // src/schema/elementSchemas/elements/reference/address.ts
2329
+ var ADDRESS_SCHEMA = createSchema({
2330
+ code: "address",
2331
+ kind: "element",
2332
+ tag: ADDRESS_TAG,
2333
+ requiredAttributes: [],
2334
+ optionalAttributes: [...ID_ATTRS],
2335
+ allowedChildrenCodes: [
2336
+ { code: "city", required: false },
2337
+ ...ATOM_CODES_ALLOWED_CHILDREN
2338
+ ]
2339
+ });
2340
+
2341
+ // src/schema/elementSchemas/elements/reference/city.ts
2342
+ var CITY_SCHEMA = createSchema({
2343
+ code: "city",
2344
+ kind: "element",
2345
+ tag: CITY_TAG,
2346
+ requiredAttributes: [],
2347
+ optionalAttributes: [...ID_ATTRS],
2348
+ allowedChildrenCodes: [
2349
+ ...ATOM_CODES_ALLOWED_CHILDREN
2350
+ ]
2351
+ });
2352
+
2353
+ // src/schema/elementSchemas/elements/reference/volumenum.ts
2354
+ var VOLUMENUM_SCHEMA = createSchema({
2355
+ code: "volumenum",
2356
+ kind: "element",
2357
+ tag: VOLUMENUM_TAG,
2358
+ requiredAttributes: [],
2359
+ optionalAttributes: [...ID_ATTRS],
2360
+ allowedChildrenCodes: [
2361
+ ...ATOM_CODES_ALLOWED_CHILDREN
2362
+ ]
2363
+ });
2364
+
2365
+ // src/schema/elementSchemas/elements/reference/issuenum.ts
2366
+ var ISSUENUM_SCHEMA = createSchema({
2367
+ code: "issuenum",
2368
+ kind: "element",
2369
+ tag: ISSUENUM_TAG,
2370
+ requiredAttributes: [],
2371
+ optionalAttributes: [...ID_ATTRS],
2372
+ allowedChildrenCodes: [
2373
+ ...ATOM_CODES_ALLOWED_CHILDREN
2374
+ ]
2375
+ });
2376
+
2377
+ // src/schema/elementSchemas/elements/reference/pagenums.ts
2378
+ var PAGENUMS_SCHEMA = createSchema({
2379
+ code: "pagenums",
2380
+ kind: "element",
2381
+ tag: PAGENUMS_TAG,
2382
+ requiredAttributes: [],
2383
+ optionalAttributes: [...ID_ATTRS],
2384
+ allowedChildrenCodes: [
2385
+ ...ATOM_CODES_ALLOWED_CHILDREN
2386
+ ]
2387
+ });
2388
+
2389
+ // src/schema/elementSchemas/elements/reference/pagenum.ts
2390
+ var PAGENUM_SCHEMA = createSchema({
2391
+ code: "pagenum",
2392
+ kind: "element",
2393
+ tag: PAGENUM_TAG,
2394
+ requiredAttributes: [],
2395
+ optionalAttributes: [...ID_ATTRS],
2396
+ allowedChildrenCodes: [
2397
+ ...ATOM_CODES_ALLOWED_CHILDREN
2398
+ ]
2399
+ });
2400
+
2401
+ // src/schema/elementSchemas/elements/reference/edition.ts
2402
+ var EDITION_SCHEMA = createSchema({
2403
+ code: "edition",
2404
+ kind: "element",
2405
+ tag: EDITION_TAG,
2406
+ requiredAttributes: [],
2407
+ optionalAttributes: [...ID_ATTRS],
2408
+ allowedChildrenCodes: [
2409
+ ...ATOM_CODES_ALLOWED_CHILDREN
2410
+ ]
2411
+ });
2412
+
2413
+ // src/schema/elementSchemas/elements/reference/pubId.ts
2414
+ var PUB_ID_SCHEMA = createSchema({
2415
+ code: "pubId",
2416
+ kind: "element",
2417
+ tag: PUB_ID_TAG,
2418
+ requiredAttributes: [],
2419
+ optionalAttributes: [...ID_ATTRS, "pub-id-type", "assigning-authority"],
2420
+ allowedChildrenCodes: [
2421
+ ...ATOM_CODES_ALLOWED_CHILDREN
2422
+ ]
2423
+ });
2424
+
2425
+ // src/schema/helpers/matchesSchemaTag.ts
2426
+ var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
2427
+
2428
+ // src/schema/elementSchemas/elements/reference/biblioid.ts
2429
+ var PUBMED_ID_BIBLIOID_CLASS = "other";
2430
+ var PUBMED_ID_BIBLIOID_OTHERCLASS = "pmid";
2431
+ var BIBLIOID_SCHEMA = createSchema({
2432
+ code: "biblioid",
2433
+ kind: "element",
2434
+ tag: BIBLIOID_TAG,
2435
+ requiredAttributes: [],
2436
+ optionalAttributes: [...ID_ATTRS, "class", "otherclass"],
2437
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2438
+ });
2439
+ var isPubMedIdBiblioid = (element) => matchesSchemaTag(element, BIBLIOID_TAG) && element.classList.contains(PUBMED_ID_BIBLIOID_CLASS) && element.getAttribute("otherclass") === PUBMED_ID_BIBLIOID_OTHERCLASS;
2440
+
2441
+ // src/schema/elementSchemas/elements/reference/bibliomisc.ts
2442
+ var LEGAL_REFERENCE_BIBLIOMISC_ROLE = "legalRef";
2443
+ var BIBLIOMISC_SCHEMA = createSchema({
2444
+ code: "bibliomisc",
2445
+ kind: "element",
2446
+ tag: BIBLIOMISC_TAG,
2447
+ requiredAttributes: [],
2448
+ optionalAttributes: [...ID_ATTRS, "role"],
2449
+ allowedChildrenCodes: [...ATOM_CODES_ALLOWED_CHILDREN]
2450
+ });
2451
+
2452
+ // src/schema/elementSchemas/elements/reference/confgroup.ts
2453
+ var CONFGROUP_SCHEMA = createSchema({
2454
+ code: "confgroup",
2455
+ kind: "element",
2456
+ tag: CONFGROUP_TAG,
2457
+ requiredAttributes: [],
2458
+ optionalAttributes: [...ID_ATTRS],
2459
+ allowedChildrenCodes: [
2460
+ { code: "conftitle", required: false },
2461
+ { code: "address", required: false },
2462
+ ...ATOM_CODES_ALLOWED_CHILDREN
2463
+ ]
2464
+ });
2465
+
2466
+ // src/schema/elementSchemas/elements/reference/conftitle.ts
2467
+ var CONFTITLE_SCHEMA = createSchema({
2468
+ code: "conftitle",
2469
+ kind: "element",
2470
+ tag: CONFTITLE_TAG,
2471
+ requiredAttributes: [],
2472
+ optionalAttributes: [...ID_ATTRS],
2473
+ allowedChildrenCodes: [
2474
+ ...ATOM_CODES_ALLOWED_CHILDREN
2475
+ ]
2476
+ });
2477
+
2478
+ // src/schema/elementSchemas/elements/index.ts
2479
+ var ELEMENT_SCHEMAS = {
2480
+ bibliodiv: BIBLIODIV_SCHEMA,
2481
+ referenceBibliography: REFERENCE_BIBLIOGRAPHY_SCHEMA,
2482
+ referenceBibliomixed: BIBLIOMIXED_SCHEMA,
2483
+ bibliomset: BIBLIOMSET_SCHEMA,
2484
+ editor: EDITOR_SCHEMA,
2485
+ othercredit: OTHERCREDIT_SCHEMA,
2486
+ translator: TRANSLATOR_SCHEMA,
2487
+ collab: COLLAB_SCHEMA,
2488
+ pubdate: PUBDATE_SCHEMA,
2489
+ date: DATE_SCHEMA,
2490
+ publishername: PUBLISHERNAME_SCHEMA,
2491
+ address: ADDRESS_SCHEMA,
2492
+ city: CITY_SCHEMA,
2493
+ volumenum: VOLUMENUM_SCHEMA,
2494
+ issuenum: ISSUENUM_SCHEMA,
2495
+ pagenums: PAGENUMS_SCHEMA,
2496
+ pagenum: PAGENUM_SCHEMA,
2497
+ edition: EDITION_SCHEMA,
2498
+ pubId: PUB_ID_SCHEMA,
2499
+ biblioid: BIBLIOID_SCHEMA,
2500
+ bibliomisc: BIBLIOMISC_SCHEMA,
2501
+ confgroup: CONFGROUP_SCHEMA,
2502
+ conftitle: CONFTITLE_SCHEMA,
2503
+ para: PARA_SCHEMA,
2504
+ title1: TITLE_SCHEMA,
2505
+ footnote: FOOTNOTE_SCHEMA,
2506
+ footnoteno: FOOTNOTE_NUMBER_SCHEMA,
2507
+ olink: OLINK_SCHEMA,
2508
+ firstname: FIRSTNAME_SCHEMA,
2509
+ surname: SURNAME_SCHEMA,
2510
+ honorific: HONORIFIC_SCHEMA,
2511
+ orgname: ORGNAME_SCHEMA,
2512
+ email: EMAIL_SCHEMA,
2513
+ org: ORG_SCHEMA,
2514
+ degrees: DEGREES_SCHEMA,
2515
+ dialogue: DIALOGUE_SCHEMA,
2516
+ line: LINE_SCHEMA,
2517
+ linegroup: LINE_GROUP_SCHEMA,
2518
+ speaker: SPEAKER_SCHEMA,
2519
+ equation: EQUATION_SCHEMA,
2520
+ math: MATH_SCHEMA,
2521
+ mathphrase: MATHPHRASE_SCHEMA,
2522
+ merror: MERROR_SCHEMA,
2523
+ mfrac: MFRAC_SCHEMA,
2524
+ mi: MI_SCHEMA,
2525
+ mmultiscripts: MMULTISCRIPTS_SCHEMA,
2526
+ mn: MN_SCHEMA,
2527
+ mo: MO_SCHEMA,
2528
+ mover: MOVER_SCHEMA,
2529
+ mpadded: MPADDED_SCHEMA,
2530
+ mphantom: MPHANTOM_SCHEMA,
2531
+ mprescripts: MPRESCRIPTS_SCHEMA,
2532
+ mroot: MROOT_SCHEMA,
2533
+ mrow: MROW_SCHEMA,
2534
+ ms: MS_SCHEMA,
2535
+ mspace: MSPACE_SCHEMA,
2536
+ msqrt: MSQRT_SCHEMA,
2537
+ mstyle: MSTYLE_SCHEMA,
2538
+ msub: MSUB_SCHEMA,
2539
+ msubsup: MSUBSUP_SCHEMA,
2540
+ msup: MSUP_SCHEMA,
2541
+ mtable: MTABLE_SCHEMA,
2542
+ mtd: MTD_SCHEMA,
2543
+ mtext: MTEXT_SCHEMA,
2544
+ mtr: MTR_SCHEMA,
2545
+ munder: MUNDER_SCHEMA,
2546
+ munderover: MUNDEROVER_SCHEMA,
2547
+ img: IMG_SCHEMA,
2548
+ alttext: ALTTEXT_SCHEMA,
2549
+ imageobject: IMAGEOBJECT_SCHEMA,
2550
+ mediaobject: MEDIAOBJECT_SCHEMA,
2551
+ caption1: CAPTION_SCHEMA,
2552
+ figsource: FIGSOURCE_SCHEMA,
2553
+ fignote: FIGNOTE_SCHEMA,
2554
+ figure1: FIGURE_SCHEMA,
2555
+ informalfigure: INFORMALFIGURE_SCHEMA,
2556
+ keywordset: KEYWORDSET_SCHEMA,
2557
+ keyword: KEYWORD_SCHEMA,
2558
+ punc: PUNC_SCHEMA,
2559
+ label1: LABEL_SCHEMA,
2560
+ li: LI_SCHEMA,
2561
+ ol: OL_SCHEMA,
2562
+ ul: UL_SCHEMA,
2563
+ token: TOKEN_SCHEMA,
2564
+ tag: TAG_SCHEMA,
2565
+ lrh: LRH_SCHEMA,
2566
+ rrh: RRH_SCHEMA,
2567
+ source1: SOURCE_SCHEMA,
2568
+ subtitle1: SUBTITLE_SCHEMA,
2569
+ table1: TABLE_SCHEMA,
2570
+ tgroup: TGROUP_SCHEMA,
2231
2571
  table: HTML_TABLE_SCHEMA,
2232
2572
  thead: THEAD_SCHEMA,
2233
2573
  tbody: TBODY_SCHEMA,
@@ -2299,7 +2639,10 @@ var INLINEEQUATION_SCHEMA = createSchema({
2299
2639
  defaultValue: "added"
2300
2640
  }
2301
2641
  ],
2302
- allowedChildrenCodes: [{ code: "mathphrase", required: true }]
2642
+ allowedChildrenCodes: [
2643
+ { code: "mathphrase", required: true },
2644
+ { code: "tag", required: false }
2645
+ ]
2303
2646
  });
2304
2647
 
2305
2648
  // src/schema/elementSchemas/inlineElements/link.ts
@@ -2386,9 +2729,6 @@ var findAttributeDefinitionByName = (definitions, name) => {
2386
2729
  // src/schema/helpers/findSchemaByCode.ts
2387
2730
  var findSchemaByCode = (code) => SCHEMAS[code];
2388
2731
 
2389
- // src/schema/helpers/matchesSchemaTag.ts
2390
- var matchesSchemaTag = (element, tag) => element.tagName.toUpperCase() === tag.toUpperCase();
2391
-
2392
2732
  // src/schema/helpers/findSchemaByElement.ts
2393
2733
  var findSchemaByElement = (element) => {
2394
2734
  const schema = Object.values(SCHEMAS).find(
@@ -2403,12 +2743,402 @@ var isAttributeRestricted = (attr) => typeof attr !== "string";
2403
2743
  // src/schema/helpers/isTrackChangesSchema.ts
2404
2744
  var isTrackChangesSchema = (schema) => schema.code === "insertion" || schema.code === "deletion" || schema.code === "lineGroupRemoval";
2405
2745
 
2746
+ // src/schema/referenceSchemas/referenceTypeSchemas.ts
2747
+ var LINK_FIELDS = ["doi", "url"];
2748
+ var OTHER_MATERIAL_FIELDS = [
2749
+ "author",
2750
+ "editor",
2751
+ "title",
2752
+ "year",
2753
+ "containerTitle",
2754
+ "publisherPlace",
2755
+ "publisher",
2756
+ "volume",
2757
+ "issue",
2758
+ "pages",
2759
+ "accessDate",
2760
+ "genre",
2761
+ "eventTitle",
2762
+ "eventPlace",
2763
+ "documentNumber",
2764
+ "pubmedId",
2765
+ ...LINK_FIELDS
2766
+ ];
2767
+ var REFERENCE_TYPE_SCHEMAS = {
2768
+ monograph: {
2769
+ code: "monograph",
2770
+ label: "Book",
2771
+ legacyRoles: ["book"],
2772
+ allowedFields: [
2773
+ "author",
2774
+ "editor",
2775
+ "title",
2776
+ "year",
2777
+ "volume",
2778
+ "publisherPlace",
2779
+ "publisher",
2780
+ ...LINK_FIELDS
2781
+ ],
2782
+ requiredFields: ["title", "creators"],
2783
+ fieldLabels: { title: "Book title" }
2784
+ },
2785
+ serial: {
2786
+ code: "serial",
2787
+ label: "Journal issue",
2788
+ legacyRoles: [],
2789
+ allowedFields: ["title", "year", "volume", "issue", ...LINK_FIELDS],
2790
+ requiredFields: ["title"]
2791
+ },
2792
+ contribution: {
2793
+ code: "contribution",
2794
+ label: "Contributed book",
2795
+ legacyRoles: ["chapter"],
2796
+ allowedFields: [
2797
+ "author",
2798
+ "editor",
2799
+ "title",
2800
+ "year",
2801
+ "containerTitle",
2802
+ "publisherPlace",
2803
+ "publisher",
2804
+ "pages",
2805
+ ...LINK_FIELDS
2806
+ ],
2807
+ requiredFields: ["title", "containerTitle", "creators"],
2808
+ bibliomsetRelations: ["part", "book"],
2809
+ fieldLabels: { title: "Chapter title", containerTitle: "Book title" }
2810
+ },
2811
+ article: {
2812
+ code: "article",
2813
+ label: "Journal article",
2814
+ legacyRoles: ["journal", "article-journal"],
2815
+ allowedFields: [
2816
+ "author",
2817
+ "editor",
2818
+ "title",
2819
+ "year",
2820
+ "containerTitle",
2821
+ "volume",
2822
+ "issue",
2823
+ "pages",
2824
+ "genre",
2825
+ "publisher",
2826
+ "publisherPlace",
2827
+ "pubmedId",
2828
+ "accessDate",
2829
+ ...LINK_FIELDS
2830
+ ],
2831
+ requiredFields: ["title", "containerTitle"],
2832
+ bibliomsetRelations: ["article", "journal"],
2833
+ fieldLabels: { title: "Article title", containerTitle: "Journal title" }
2834
+ },
2835
+ message: {
2836
+ code: "message",
2837
+ label: "Email message",
2838
+ legacyRoles: [],
2839
+ allowedFields: ["author", "title", "year", ...LINK_FIELDS],
2840
+ requiredFields: ["title"]
2841
+ },
2842
+ website: {
2843
+ code: "website",
2844
+ label: "Website",
2845
+ legacyRoles: [],
2846
+ allowedFields: ["author", "title", "year", "accessDate", ...LINK_FIELDS],
2847
+ requiredFields: ["title"]
2848
+ },
2849
+ unpublished: {
2850
+ code: "unpublished",
2851
+ label: "Unpublished material",
2852
+ legacyRoles: [],
2853
+ allowedFields: [
2854
+ "author",
2855
+ "title",
2856
+ "year",
2857
+ "publisher",
2858
+ "genre",
2859
+ "eventTitle",
2860
+ "eventPlace",
2861
+ ...LINK_FIELDS
2862
+ ],
2863
+ requiredFields: ["title"],
2864
+ replacedElements: [
2865
+ { tag: "pubdate", replacement: "date" },
2866
+ { tag: "publishername", replacement: "orgname" }
2867
+ ]
2868
+ },
2869
+ case: {
2870
+ code: "case",
2871
+ label: "Case",
2872
+ legacyRoles: [],
2873
+ allowedFields: ["title", "year", "documentNumber", ...LINK_FIELDS],
2874
+ requiredFields: ["title"]
2875
+ },
2876
+ legislation: {
2877
+ code: "legislation",
2878
+ label: "Legislation",
2879
+ legacyRoles: [],
2880
+ allowedFields: [
2881
+ "title",
2882
+ "year",
2883
+ "documentNumber",
2884
+ "publisherPlace",
2885
+ ...LINK_FIELDS
2886
+ ],
2887
+ requiredFields: ["title"]
2888
+ },
2889
+ other: {
2890
+ code: "other",
2891
+ label: "Other material",
2892
+ legacyRoles: [],
2893
+ allowedFields: OTHER_MATERIAL_FIELDS,
2894
+ requiredFields: ["title"]
2895
+ },
2896
+ recording: {
2897
+ code: "recording",
2898
+ label: "Recording",
2899
+ legacyRoles: [],
2900
+ allowedFields: ["author", "title", "year", ...LINK_FIELDS],
2901
+ requiredFields: ["title", "year"],
2902
+ replacedElements: [{ tag: "author", replacement: "othercredit" }]
2903
+ },
2904
+ film: {
2905
+ code: "film",
2906
+ label: "Film",
2907
+ legacyRoles: [],
2908
+ allowedFields: ["title", "year", ...LINK_FIELDS],
2909
+ requiredFields: ["title"]
2910
+ }
2911
+ };
2912
+
2913
+ // src/schema/helpers/findReferenceTypeSchemaByElement.ts
2914
+ var findReferenceTypeSchemaByElement = (reference) => {
2915
+ const role = reference.getAttribute("role")?.trim().toLowerCase() ?? "";
2916
+ const schemas = Object.values(REFERENCE_TYPE_SCHEMAS);
2917
+ return schemas.find(
2918
+ (schema) => schema.code === role || schema.legacyRoles.includes(role)
2919
+ );
2920
+ };
2921
+
2922
+ // src/helpers/isDeletedElement.ts
2923
+ var isDeletedElement = (element) => {
2924
+ return !!closestElementBySchema({
2925
+ element,
2926
+ code: "deletion"
2927
+ });
2928
+ };
2929
+
2930
+ // src/helpers/closestElementBySchema.ts
2931
+ var closestElementBySchema = ({
2932
+ element,
2933
+ code,
2934
+ ignoreDeletedElements = false
2935
+ }) => {
2936
+ const schema = findSchemaByCode(code);
2937
+ if (!schema) return;
2938
+ const closestElement = element.closest(
2939
+ schema.tag.toLowerCase()
2940
+ );
2941
+ if (!closestElement) return;
2942
+ if (schema.matchesElement && !schema.matchesElement(closestElement)) {
2943
+ return;
2944
+ }
2945
+ if (ignoreDeletedElements && isDeletedElement(closestElement)) {
2946
+ return closestElementBySchema({
2947
+ element: closestElement,
2948
+ code,
2949
+ ignoreDeletedElements
2950
+ });
2951
+ }
2952
+ return closestElement;
2953
+ };
2954
+
2955
+ // src/helpers/isInTrackedDeletion.ts
2956
+ var isInTrackedDeletion = (element) => !!element.closest("span.del");
2957
+
2958
+ // src/helpers/hasLiveUri.ts
2959
+ var hasLiveUri = (link) => Array.from(link.querySelectorAll("uri")).some(
2960
+ (uri) => !isInTrackedDeletion(uri)
2961
+ );
2962
+
2963
+ // src/schema/helpers/findReferenceFieldByElement.ts
2964
+ var isContainerTitle = (title) => {
2965
+ const relation = closestElementBySchema({
2966
+ element: title,
2967
+ code: "bibliomset"
2968
+ })?.getAttribute("relation");
2969
+ return CONTAINER_BIBLIOMSET_RELATIONS.some(
2970
+ (containerRelation) => containerRelation === relation
2971
+ );
2972
+ };
2973
+ var isUnpublishedReference = (element) => {
2974
+ const reference = closestElementBySchema({
2975
+ element,
2976
+ code: "referenceBibliomixed"
2977
+ });
2978
+ return !!reference && findReferenceTypeSchemaByElement(reference)?.code === "unpublished";
2979
+ };
2980
+ var hasAcceptedChild = (element, tag) => Array.from(element.querySelectorAll(tag.toLowerCase())).some(
2981
+ (child) => !isInTrackedDeletion(child)
2982
+ );
2983
+ var isConferenceDates = (confgroup) => hasAcceptedChild(confgroup, CONFDATES_TAG) && !hasAcceptedChild(confgroup, CONFTITLE_TAG);
2984
+ var findReferenceFieldByElement = (element) => {
2985
+ switch (findSchemaByElement(element)?.code) {
2986
+ case "author":
2987
+ case "othercredit":
2988
+ return "author";
2989
+ case "editor":
2990
+ return "editor";
2991
+ case "title1":
2992
+ return isContainerTitle(element) ? "containerTitle" : "title";
2993
+ case "pubdate":
2994
+ return "year";
2995
+ case "date":
2996
+ return element.getAttribute("role") === ACCESSED_DATE_ROLE ? "accessDate" : "year";
2997
+ case "publishername":
2998
+ case "orgname":
2999
+ return "publisher";
3000
+ case "address":
3001
+ return isUnpublishedReference(element) ? "eventPlace" : "publisherPlace";
3002
+ case "volumenum":
3003
+ return "volume";
3004
+ case "issuenum":
3005
+ return "issue";
3006
+ case "pagenums":
3007
+ return "pages";
3008
+ case "link":
3009
+ if (element.hasAttribute(LINKEND_ATTRIBUTE)) return void 0;
3010
+ return hasLiveUri(element) ? "url" : "doi";
3011
+ case "bibliomisc":
3012
+ return element.getAttribute("role") === LEGAL_REFERENCE_BIBLIOMISC_ROLE ? "documentNumber" : "genre";
3013
+ case "confgroup":
3014
+ return isConferenceDates(element) ? "year" : "eventTitle";
3015
+ case "biblioid":
3016
+ return isPubMedIdBiblioid(element) ? "pubmedId" : void 0;
3017
+ default:
3018
+ return void 0;
3019
+ }
3020
+ };
3021
+
3022
+ // src/schema/referenceSchemas/referenceFieldSchemas.ts
3023
+ var REFERENCE_FIELD_SCHEMAS = {
3024
+ author: {
3025
+ code: "author",
3026
+ label: "Author",
3027
+ elementCodes: ["author", "othercredit"]
3028
+ },
3029
+ editor: {
3030
+ code: "editor",
3031
+ label: "Editor",
3032
+ elementCodes: ["editor"]
3033
+ },
3034
+ title: {
3035
+ code: "title",
3036
+ label: "Title",
3037
+ elementCodes: ["title1"]
3038
+ },
3039
+ year: {
3040
+ code: "year",
3041
+ label: "Date",
3042
+ elementCodes: ["pubdate", "date", "confgroup"]
3043
+ },
3044
+ containerTitle: {
3045
+ code: "containerTitle",
3046
+ label: "Container title",
3047
+ elementCodes: ["title1"]
3048
+ },
3049
+ publisherPlace: {
3050
+ code: "publisherPlace",
3051
+ label: "Publisher place",
3052
+ elementCodes: ["address"]
3053
+ },
3054
+ publisher: {
3055
+ code: "publisher",
3056
+ label: "Publisher or institution",
3057
+ elementCodes: ["publishername", "orgname"]
3058
+ },
3059
+ volume: {
3060
+ code: "volume",
3061
+ label: "Volume",
3062
+ elementCodes: ["volumenum"]
3063
+ },
3064
+ issue: {
3065
+ code: "issue",
3066
+ label: "Issue",
3067
+ elementCodes: ["issuenum"]
3068
+ },
3069
+ pages: {
3070
+ code: "pages",
3071
+ label: "Pages",
3072
+ elementCodes: ["pagenums"]
3073
+ },
3074
+ doi: {
3075
+ code: "doi",
3076
+ label: "DOI",
3077
+ elementCodes: ["link"]
3078
+ },
3079
+ url: {
3080
+ code: "url",
3081
+ label: "URL",
3082
+ elementCodes: ["link"]
3083
+ },
3084
+ accessDate: {
3085
+ code: "accessDate",
3086
+ label: "Access date",
3087
+ elementCodes: ["date"]
3088
+ },
3089
+ genre: {
3090
+ code: "genre",
3091
+ label: "Description",
3092
+ elementCodes: ["bibliomisc"]
3093
+ },
3094
+ eventTitle: {
3095
+ code: "eventTitle",
3096
+ label: "Conference title",
3097
+ elementCodes: ["confgroup"]
3098
+ },
3099
+ eventPlace: {
3100
+ code: "eventPlace",
3101
+ label: "Conference place",
3102
+ elementCodes: ["address"]
3103
+ },
3104
+ documentNumber: {
3105
+ code: "documentNumber",
3106
+ label: "Legal reference",
3107
+ elementCodes: ["bibliomisc"]
3108
+ },
3109
+ pubmedId: {
3110
+ code: "pubmedId",
3111
+ label: "PubMed ID",
3112
+ elementCodes: ["biblioid"]
3113
+ }
3114
+ };
3115
+
2406
3116
  // src/schema/shared/labelElements.ts
2407
3117
  var ElementLabel = {
2408
3118
  mark: "Mark",
2409
3119
  referenceBibliomixed: "Reference Bibliomixed",
2410
3120
  referenceBibliography: "Reference Bibliography",
2411
3121
  bibliodiv: "Bibliodiv",
3122
+ bibliomset: "Reference Block",
3123
+ editor: "Editor",
3124
+ othercredit: "Other Credit",
3125
+ translator: "Translator",
3126
+ collab: "Collaborator",
3127
+ pubdate: "Publication Date",
3128
+ date: "Date",
3129
+ publishername: "Publisher Name",
3130
+ address: "Address",
3131
+ city: "City",
3132
+ volumenum: "Volume Number",
3133
+ issuenum: "Issue Number",
3134
+ pagenums: "Page Numbers",
3135
+ pagenum: "Page Number",
3136
+ edition: "Edition",
3137
+ pubId: "Publication ID",
3138
+ biblioid: "Bibliographic ID",
3139
+ bibliomisc: "Reference Miscellany",
3140
+ confgroup: "Conference",
3141
+ conftitle: "Conference Title",
2412
3142
  indexterm: "Indexterm",
2413
3143
  primary: "Primary",
2414
3144
  secondary: "Secondary",
@@ -2556,39 +3286,7 @@ var IGNORED_VALIDATION_ELEMENT_SELECTORS = [
2556
3286
  "referenceBibliomixed"
2557
3287
  ];
2558
3288
  var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.includes(code);
2559
-
2560
- // src/helpers/closestElementBySchema.ts
2561
- var closestElementBySchema = ({
2562
- element,
2563
- code,
2564
- ignoreDeletedElements = false
2565
- }) => {
2566
- const schema = findSchemaByCode(code);
2567
- if (!schema) return;
2568
- const closestElement = element.closest(
2569
- schema.tag.toLowerCase()
2570
- );
2571
- if (!closestElement) return;
2572
- if (schema.matchesElement && !schema.matchesElement(closestElement)) {
2573
- return;
2574
- }
2575
- if (ignoreDeletedElements && isDeletedElement(closestElement)) {
2576
- return closestElementBySchema({
2577
- element: closestElement,
2578
- code,
2579
- ignoreDeletedElements
2580
- });
2581
- }
2582
- return closestElement;
2583
- };
2584
-
2585
- // src/helpers/isDeletedElement.ts
2586
- var isDeletedElement = (element) => {
2587
- return !!closestElementBySchema({
2588
- element,
2589
- code: "deletion"
2590
- });
2591
- };
3289
+ var isIgnoredValidationByAttribute = (element) => element.getAttribute(VALIDATION_IGNORED_ATTRIBUTE) === "true";
2592
3290
 
2593
3291
  // src/validation/utils/getElementsSelector.ts
2594
3292
  var getElementsSelector = ({
@@ -2626,12 +3324,14 @@ var generateValidationIssueId = () => {
2626
3324
  };
2627
3325
 
2628
3326
  // src/validation/helpers/addValidationIssue.ts
2629
- var createValidationIssue = (issue) => ({
3327
+ var createValidationIssue = (element, issue) => ({
3328
+ ...issue,
2630
3329
  id: generateValidationIssueId(),
2631
- ...issue
3330
+ store: element ? getStore(element) : issue.store,
3331
+ ignored: element ? isIgnoredValidationByAttribute(element) : false
2632
3332
  });
2633
- var addValidationIssue = (errors, issue) => {
2634
- errors.push(createValidationIssue(issue));
3333
+ var addValidationIssue = (errors, element, issue) => {
3334
+ errors.push(createValidationIssue(element, issue));
2635
3335
  };
2636
3336
 
2637
3337
  // src/validation/validateFootnotes.ts
@@ -2650,8 +3350,7 @@ var validateFootnoteNumber = (footnoteElement) => {
2650
3350
  FOOTNOTE_NUMBER_SCHEMA.tag
2651
3351
  );
2652
3352
  if (!footnoteNumber) {
2653
- addValidationIssue(errors, {
2654
- store: getStore(footnoteElement),
3353
+ addValidationIssue(errors, footnoteElement, {
2655
3354
  title: "Footnote number missing",
2656
3355
  kind: "missing",
2657
3356
  description: "The footnote number is missing. Please add it to the footnote.",
@@ -2682,8 +3381,7 @@ var validateConsecutiveFootnotes = (root) => {
2682
3381
  );
2683
3382
  if (!footnoteNumberElement) {
2684
3383
  errors.push(
2685
- createValidationIssue({
2686
- store: getStore(footnote),
3384
+ createValidationIssue(footnote, {
2687
3385
  title: "Footnote number missing",
2688
3386
  kind: "missing",
2689
3387
  description: "The footnote number is missing. Please add it to the footnote.",
@@ -2696,8 +3394,7 @@ var validateConsecutiveFootnotes = (root) => {
2696
3394
  continue;
2697
3395
  }
2698
3396
  errors.push(
2699
- createValidationIssue({
2700
- store: getStore(footnote),
3397
+ createValidationIssue(footnote, {
2701
3398
  title: "Non-consecutive footnote numbers",
2702
3399
  kind: "missing",
2703
3400
  description: `Footnote numbers must be consecutive, footnote number (${label}) expected to be (${expectedNumber}). Please reorder the footnotes.`,
@@ -2728,8 +3425,7 @@ var validateConsecutiveFootnoteCues = (root) => {
2728
3425
  continue;
2729
3426
  }
2730
3427
  errors.push(
2731
- createValidationIssue({
2732
- store: getStore(footnoteLink),
3428
+ createValidationIssue(footnoteLink, {
2733
3429
  title: "Non-consecutive footnote cues",
2734
3430
  kind: "missing",
2735
3431
  description: "Footnote cues must be consecutive. Please reorder the footnote cues.",
@@ -2773,8 +3469,7 @@ var validateLinkend = (linkElement, elementsToLink) => {
2773
3469
  );
2774
3470
  if (isLinkFootnoteCue) {
2775
3471
  return [
2776
- createValidationIssue({
2777
- store: getStore(linkElement),
3472
+ createValidationIssue(linkElement, {
2778
3473
  title: "Unlinked footnote cue",
2779
3474
  kind: "unlinked",
2780
3475
  description: "This footnote cue is not referenced to any footnote in this chapter. Please link it again manually.",
@@ -2795,8 +3490,7 @@ var validateLinkend = (linkElement, elementsToLink) => {
2795
3490
  }
2796
3491
  const isBlocker = LINK_BLOCKER_ROLES.includes(role.toLowerCase());
2797
3492
  return [
2798
- createValidationIssue({
2799
- store: getStore(linkElement),
3493
+ createValidationIssue(linkElement, {
2800
3494
  title: "Unlinked element",
2801
3495
  kind: "unlinked",
2802
3496
  description: "This link is not referenced to any element in the current chapter or any other chapter. Please link it again manually.",
@@ -2856,8 +3550,7 @@ var validateAttributes = (element, schema) => {
2856
3550
  continue;
2857
3551
  }
2858
3552
  if (!definition.values.includes(value)) {
2859
- addValidationIssue(errors, {
2860
- store: getStore(element),
3553
+ addValidationIssue(errors, element, {
2861
3554
  title: `Invalid attribute value "${value}" in element ${element.tagName}`,
2862
3555
  level: "warning",
2863
3556
  kind: "forbidden",
@@ -2872,8 +3565,7 @@ var validateAttributes = (element, schema) => {
2872
3565
  var validateElementAgainstSchema = (element, schema) => {
2873
3566
  const errors = [];
2874
3567
  if (!matchesSchemaTag(element, schema.tag)) {
2875
- addValidationIssue(errors, {
2876
- store: getStore(element),
3568
+ addValidationIssue(errors, element, {
2877
3569
  title: `Expected ${schema.tag}, got ${element.tagName}`,
2878
3570
  level: "warning",
2879
3571
  kind: "forbidden",
@@ -2903,8 +3595,7 @@ var validateRequiredChildren = (element, schema, childElements) => {
2903
3595
  `Please provide at least one ${elementLabel} in this ${parentLabel}.`,
2904
3596
  extraInstruction
2905
3597
  ].filter(Boolean).join(" ");
2906
- addValidationIssue(errors, {
2907
- store: getStore(element),
3598
+ addValidationIssue(errors, element, {
2908
3599
  title: `${elementLabel} missing`,
2909
3600
  level: "warning",
2910
3601
  kind: "missing",
@@ -2938,8 +3629,7 @@ var validateChildren = (element, schema) => {
2938
3629
  for (const child of childElements) {
2939
3630
  const childSchema = findSchemaByElement(child);
2940
3631
  if (!childSchema) {
2941
- addValidationIssue(errors, {
2942
- store: getStore(child),
3632
+ addValidationIssue(errors, child, {
2943
3633
  title: `No schema found for child element ${child.tagName}`,
2944
3634
  level: "warning",
2945
3635
  kind: "missing",
@@ -2951,8 +3641,7 @@ var validateChildren = (element, schema) => {
2951
3641
  (candidate) => candidate.code === childSchema.code
2952
3642
  );
2953
3643
  if (!allowedChild) {
2954
- addValidationIssue(errors, {
2955
- store: getStore(child),
3644
+ addValidationIssue(errors, child, {
2956
3645
  title: `Forbidden child element ${child.tagName}`,
2957
3646
  level: "warning",
2958
3647
  kind: "forbidden",
@@ -3002,8 +3691,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3002
3691
  if (isFootnote(element)) {
3003
3692
  const label = extractFootnoteNumber(element);
3004
3693
  return [
3005
- createValidationIssue({
3006
- store: getStore(element),
3694
+ createValidationIssue(element, {
3007
3695
  title: "Uncited footnote",
3008
3696
  kind: "uncited",
3009
3697
  description: `The footnote ${label} is not cited to any footnote cue in this chapter. Please reference it in the chapter.`,
@@ -3013,8 +3701,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3013
3701
  }
3014
3702
  if (isReference(element)) {
3015
3703
  return [
3016
- createValidationIssue({
3017
- store: getStore(element),
3704
+ createValidationIssue(element, {
3018
3705
  title: "Uncited reference",
3019
3706
  kind: "uncited",
3020
3707
  description: "This reference is not cited in this chapter or any other chapter. Please add a link to this reference or delete it.",
@@ -3024,8 +3711,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3024
3711
  }
3025
3712
  if (isTable(element)) {
3026
3713
  return [
3027
- createValidationIssue({
3028
- store: getStore(element),
3714
+ createValidationIssue(element, {
3029
3715
  title: "Uncited table",
3030
3716
  kind: "uncited",
3031
3717
  description: "This table is not cited in this chapter or any other chapter. Please add a link to this table or delete it.",
@@ -3035,8 +3721,7 @@ var validateElementToLinkTo = (element, linkElements) => {
3035
3721
  }
3036
3722
  if (isFigure(element)) {
3037
3723
  return [
3038
- createValidationIssue({
3039
- store: getStore(element),
3724
+ createValidationIssue(element, {
3040
3725
  title: "Uncited figure",
3041
3726
  kind: "uncited",
3042
3727
  description: "This figure is not cited in this chapter or any other chapter. Please add a link to this figure or delete it.",
@@ -3052,6 +3737,7 @@ import Mark from "mark.js";
3052
3737
  var EDGE_PUNCTUATION = `:;.,\\-\u2013\u2014\u2012_(){}[\\]!'"+=\xAB\xBB\u2039\u203A\u201C\u201D\u2018\u2019<>`;
3053
3738
  var WEB_URI_PATTERN = `(?:(?:https?):\\/\\/|www\\.)(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}(?::\\d{1,5})?(?:\\/(?:[^\\s]*[^\\s${EDGE_PUNCTUATION}])?)?`;
3054
3739
  var WEB_URI_IN_TEXT_REGEX = new RegExp(WEB_URI_PATTERN, "gi");
3740
+ var POSSIBLE_WEBLINK_CLASS = "possible-weblink";
3055
3741
  var POSSIBLE_WEBLINK_EXCLUDE_SELECTORS = [
3056
3742
  "tag",
3057
3743
  "tag *",
@@ -3063,40 +3749,98 @@ var POSSIBLE_WEBLINK_EXCLUDE_SELECTORS = [
3063
3749
  "query *",
3064
3750
  "comment",
3065
3751
  "comment *",
3752
+ `.${POSSIBLE_WEBLINK_CLASS}`,
3753
+ `.${POSSIBLE_WEBLINK_CLASS} *`,
3066
3754
  ...IGNORED_ELEMENT_SELECTORS
3067
3755
  ];
3068
- var collectPossibleWebLinks = (content) => {
3069
- const clone = content.cloneNode(true);
3070
- const possibleWebLinks = /* @__PURE__ */ new Set();
3071
- const instance = new Mark(clone);
3756
+ var getPossibleWeblinks = (root) => {
3757
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3758
+ const allWeblinkMatches = Array.from(
3759
+ root.getElementsByClassName(POSSIBLE_WEBLINK_CLASS)
3760
+ );
3761
+ for (const weblinkMatch of allWeblinkMatches) {
3762
+ const storeId = weblinkMatch.getAttribute(STORE_ATTRIBUTE);
3763
+ if (!storeId || possibleWeblinks.has(storeId)) continue;
3764
+ const elements = allWeblinkMatches.filter(
3765
+ (element) => element.getAttribute(STORE_ATTRIBUTE) === storeId
3766
+ );
3767
+ const weblink = elements.map((element) => element.textContent).join("");
3768
+ possibleWeblinks.set(storeId, {
3769
+ weblink,
3770
+ elements
3771
+ });
3772
+ }
3773
+ return possibleWeblinks;
3774
+ };
3775
+ var getWeblinkMatchId = (matchIndex) => `weblink-match-${matchIndex}`;
3776
+ var createWeblinkMatchTracker = () => {
3777
+ const matchedText = [];
3778
+ const matchedElements = [];
3779
+ const possibleWeblinks = /* @__PURE__ */ new Map();
3780
+ let matchIndex = 0;
3781
+ let currentMatchId = getWeblinkMatchId(matchIndex);
3782
+ const resetMatch = () => {
3783
+ matchIndex += 1;
3784
+ currentMatchId = getWeblinkMatchId(matchIndex);
3785
+ matchedText.length = 0;
3786
+ matchedElements.length = 0;
3787
+ };
3788
+ const composeWeblink = (element, url) => {
3789
+ element.setAttribute(STORE_ATTRIBUTE, currentMatchId);
3790
+ matchedText.push(element.textContent);
3791
+ matchedElements.push(element);
3792
+ if (matchedText.join("") !== url) return;
3793
+ possibleWeblinks.set(currentMatchId, {
3794
+ weblink: matchedText.join(""),
3795
+ elements: [...matchedElements]
3796
+ });
3797
+ resetMatch();
3798
+ };
3799
+ return { composeWeblink, possibleWeblinks };
3800
+ };
3801
+ var markPossibleWeblinks = (editor) => {
3802
+ const instance = new Mark(editor);
3803
+ const { composeWeblink, possibleWeblinks } = createWeblinkMatchTracker();
3804
+ let possibleWebLink = "";
3072
3805
  instance.markRegExp(WEB_URI_IN_TEXT_REGEX, {
3806
+ className: POSSIBLE_WEBLINK_CLASS,
3073
3807
  acrossElements: false,
3074
3808
  exclude: POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
3075
3809
  filter: (_textNode, term) => {
3076
- possibleWebLinks.add(term);
3810
+ possibleWebLink = term;
3077
3811
  return true;
3078
- }
3812
+ },
3813
+ each: (element) => composeWeblink(element, possibleWebLink)
3079
3814
  });
3080
- return possibleWebLinks;
3815
+ return possibleWeblinks;
3081
3816
  };
3082
3817
  var validatePossibleWeblinks = (root) => {
3083
- const errors = [];
3084
- const possibleWebLinks = collectPossibleWebLinks(root);
3085
- for (const possibleWebLink of possibleWebLinks) {
3086
- errors.push(
3087
- createValidationIssue({
3088
- store: possibleWebLink,
3818
+ const issues = [];
3819
+ const cloneRoot = root.cloneNode(true);
3820
+ clearWeblinkMatches(cloneRoot);
3821
+ const possibleWeblinks = markPossibleWeblinks(cloneRoot);
3822
+ for (const [storeId, { elements }] of Array.from(possibleWeblinks)) {
3823
+ issues.push(
3824
+ createValidationIssue(null, {
3825
+ store: storeId,
3089
3826
  title: "Possible web link",
3090
3827
  kind: "possible-url",
3091
3828
  description: "This looks like a URL. Would you like to add weblink tags?",
3092
- level: "warning"
3829
+ level: "info",
3830
+ elements
3093
3831
  })
3094
3832
  );
3095
3833
  }
3096
- return errors;
3834
+ return issues;
3835
+ };
3836
+ var clearWeblinkMatches = (editor) => {
3837
+ const instance = new Mark(editor);
3838
+ instance.unmark({
3839
+ className: POSSIBLE_WEBLINK_CLASS
3840
+ });
3097
3841
  };
3098
3842
 
3099
- // src/validation/validateHeadingHierarchy.ts
3843
+ // src/validation/validateHierarchy.ts
3100
3844
  var shouldSuppressWarning = (element) => {
3101
3845
  const closestBox = closestElementBySchema({
3102
3846
  element,
@@ -3105,46 +3849,66 @@ var shouldSuppressWarning = (element) => {
3105
3849
  });
3106
3850
  return !!closestBox;
3107
3851
  };
3108
- var getHierarchyLevel = (element) => {
3109
- const role = element.getAttribute("role");
3852
+ var isHeading = (elementHierarchy) => {
3853
+ return elementHierarchy === "heading";
3854
+ };
3855
+ var getValidLevels = (elementHierarchy) => {
3856
+ return isHeading(elementHierarchy) ? HEADING_LEVEL : BOX_LEVEL;
3857
+ };
3858
+ var getAttributeName2 = (elementHierarchy) => {
3859
+ return isHeading(elementHierarchy) ? "role" : "status";
3860
+ };
3861
+ var getElementSchemaCode = (elementHierarchy) => {
3862
+ return isHeading(elementHierarchy) ? HEADING_SCHEMA.code : BOX_SCHEMA.code;
3863
+ };
3864
+ var getHierarchyLevel = (element, elementHierarchy) => {
3865
+ const role = element.getAttribute(getAttributeName2(elementHierarchy));
3110
3866
  if (!role) return void 0;
3111
- const validHeadingLevel = HEADING_LEVEL.indexOf(role);
3112
- if (validHeadingLevel === -1) return void 0;
3113
- return validHeadingLevel;
3867
+ const index = getValidLevels(elementHierarchy).indexOf(role);
3868
+ if (index === -1) return void 0;
3869
+ return isHeading(elementHierarchy) ? index : index + 1;
3114
3870
  };
3115
- var validateHeadingHierarchy = (element) => {
3871
+ var validateHierarchy = (element, elementHierarchy) => {
3116
3872
  const errors = [];
3117
3873
  if (isDeletedElement(element)) {
3118
3874
  return errors;
3119
3875
  }
3120
- if (shouldSuppressWarning(element)) {
3876
+ if (shouldSuppressWarning(element) && isHeading(elementHierarchy)) {
3121
3877
  return errors;
3122
3878
  }
3123
- const level = getHierarchyLevel(element);
3879
+ const level = getHierarchyLevel(element, elementHierarchy);
3124
3880
  if (level === void 0) {
3125
3881
  return errors;
3126
3882
  }
3127
3883
  if (!element.parentElement) {
3128
3884
  return errors;
3129
3885
  }
3130
- const parentHeading = closestElementBySchema({
3886
+ const parentElement = closestElementBySchema({
3131
3887
  element: element.parentElement,
3132
- code: HEADING_SCHEMA.code,
3888
+ code: getElementSchemaCode(elementHierarchy),
3133
3889
  ignoreDeletedElements: true
3134
3890
  });
3135
- if (!parentHeading) {
3891
+ if (!parentElement) {
3136
3892
  if (level > 1) {
3137
- addValidationIssue(errors, {
3138
- store: getStore(element),
3139
- title: "Missing heading H1",
3140
- kind: "missing",
3141
- description: `H${level} is not under an H1. Please check the heading hierarchy.`,
3142
- level: "warning"
3143
- });
3893
+ if (isHeading(elementHierarchy)) {
3894
+ addValidationIssue(errors, element, {
3895
+ title: "Missing heading H1",
3896
+ kind: "missing",
3897
+ description: `H${level} is not under an H1. Please check the heading hierarchy.`,
3898
+ level: "warning"
3899
+ });
3900
+ } else {
3901
+ addValidationIssue(errors, element, {
3902
+ title: "Missing box level 1",
3903
+ kind: "missing",
3904
+ description: `Box level ${level} is not under a box level. Please check the box hierarchy.`,
3905
+ level: "warning"
3906
+ });
3907
+ }
3144
3908
  }
3145
3909
  return errors;
3146
3910
  }
3147
- const parentLevel = getHierarchyLevel(parentHeading);
3911
+ const parentLevel = getHierarchyLevel(parentElement, elementHierarchy);
3148
3912
  if (parentLevel === void 0) {
3149
3913
  return errors;
3150
3914
  }
@@ -3152,13 +3916,21 @@ var validateHeadingHierarchy = (element) => {
3152
3916
  if (level === expectedLevel) {
3153
3917
  return errors;
3154
3918
  }
3155
- addValidationIssue(errors, {
3156
- store: getStore(element),
3157
- title: "Invalid heading hierarchy",
3158
- kind: "forbidden",
3159
- description: `H${level} cannot follow H${parentLevel} directly. Please check the heading hierarchy.`,
3160
- level: "warning"
3161
- });
3919
+ if (isHeading(elementHierarchy)) {
3920
+ addValidationIssue(errors, element, {
3921
+ title: "Invalid heading hierarchy",
3922
+ kind: "forbidden",
3923
+ description: `H${level} cannot follow H${parentLevel} directly. Please check the heading hierarchy.`,
3924
+ level: "warning"
3925
+ });
3926
+ } else {
3927
+ addValidationIssue(errors, element, {
3928
+ title: "Invalid box hierarchy",
3929
+ kind: "forbidden",
3930
+ description: `Box level ${level} cannot follow box level ${parentLevel} directly. Please check the box hierarchy.`,
3931
+ level: "warning"
3932
+ });
3933
+ }
3162
3934
  return errors;
3163
3935
  };
3164
3936
 
@@ -3175,8 +3947,7 @@ var validateOlink = (element) => {
3175
3947
  if (isEmpty || isValidOrcid) {
3176
3948
  return errors;
3177
3949
  }
3178
- addValidationIssue(errors, {
3179
- store: getStore(element.parentElement ?? element),
3950
+ addValidationIssue(errors, element, {
3180
3951
  title: "Invalid ORCID",
3181
3952
  kind: "forbidden",
3182
3953
  description: "The ORCiD is not the correct format. Please check it and adjust.",
@@ -3185,6 +3956,338 @@ var validateOlink = (element) => {
3185
3956
  return errors;
3186
3957
  };
3187
3958
 
3959
+ // src/helpers/getReferenceFieldElements.ts
3960
+ var REFERENCE_PART_SELECTOR = REFERENCE_PART_CODES_ALLOWED_CHILDREN.map(
3961
+ ({ code }) => findSchemaByCode(code).tag.toLowerCase()
3962
+ ).join(", ");
3963
+ var REFERENCE_PART_OWNER_SELECTOR = `${REFERENCE_PART_SELECTOR}, ${URI_SCHEMA.tag.toLowerCase()}`;
3964
+ var getReferenceParts = (reference) => Array.from(
3965
+ reference.querySelectorAll(REFERENCE_PART_SELECTOR)
3966
+ ).filter((element) => {
3967
+ if (isInTrackedDeletion(element)) return false;
3968
+ const owner = element.parentElement?.closest(REFERENCE_PART_OWNER_SELECTOR);
3969
+ return !owner || !reference.contains(owner);
3970
+ });
3971
+ var getReferenceFieldElements = (reference) => getReferenceParts(reference).flatMap((element) => {
3972
+ const field = findReferenceFieldByElement(element);
3973
+ return field ? [{ field, element }] : [];
3974
+ });
3975
+
3976
+ // src/validation/validateReferenceMarkup.ts
3977
+ var PERSONNAME_ORDER_ROLES = ["first-last", "last-first"];
3978
+ var ARTIST_OTHERCLASS = "artist";
3979
+ var NOT_PERMITTED_ELEMENTS = [
3980
+ { tag: BIBLIOID_TAG.toLowerCase() },
3981
+ { tag: "publisher" },
3982
+ { tag: AUTHORGROUP_TAG.toLowerCase() }
3983
+ ];
3984
+ var BIBLIOMSET = BIBLIOMSET_TAG.toLowerCase();
3985
+ var PERSONNAME = PERSONNAME_TAG.toLowerCase();
3986
+ var CONFGROUP = CONFGROUP_TAG.toLowerCase();
3987
+ var LINK = LINK_TAG.toLowerCase();
3988
+ var URI = URI_SCHEMA.tag.toLowerCase();
3989
+ var NAME_PARTS = [SURNAME_TAG, FIRSTNAME_TAG, HONORIFIC_TAG].map((tag) => tag.toLowerCase()).join(", ");
3990
+ var CONFERENCE_FIELDS_AND_DELETIONS = [
3991
+ CONFTITLE_TAG,
3992
+ CONFDATES_TAG,
3993
+ ADDRESS_TAG
3994
+ ].map((tag) => tag.toLowerCase()).concat("span.del").join(", ");
3995
+ var LOOSE_MARKUP = [
3996
+ BIBLIOMSET,
3997
+ PERSONNAME,
3998
+ URI,
3999
+ NAME_PARTS,
4000
+ CONFDATES_TAG.toLowerCase()
4001
+ ].concat(NOT_PERMITTED_ELEMENTS.map(({ tag }) => tag)).join(", ");
4002
+ var hasValue = (element, attribute) => !!element.getAttribute(attribute)?.trim();
4003
+ var hasUntaggedConferenceText = (element) => Array.from(element.childNodes).some((child) => {
4004
+ if (child.nodeType === Node.TEXT_NODE) return !!child.textContent?.trim();
4005
+ return child instanceof Element && !child.matches(CONFERENCE_FIELDS_AND_DELETIONS) && hasUntaggedConferenceText(child);
4006
+ });
4007
+ var isExternalLink = (link) => !hasValue(link, LINKEND_ATTRIBUTE);
4008
+ var DOI_URL = /^https?:\/\/(?:dx\.)?doi\.org\//i;
4009
+ var pointsAtDoiOrg = (link) => DOI_URL.test(link.getAttribute(LINK_ATTRIBUTE)?.trim() ?? "");
4010
+ var hasNameOrder = (personname) => {
4011
+ const order = personname.getAttribute("role")?.replace(/\s+/g, "");
4012
+ return PERSONNAME_ORDER_ROLES.some((role) => role === order);
4013
+ };
4014
+ var hasLooseReferenceMarkup = (reference) => Array.from(reference.querySelectorAll(LOOSE_MARKUP)).some(
4015
+ (element) => !isInTrackedDeletion(element)
4016
+ );
4017
+ var validateReferenceMarkup = (reference, typeSchema) => {
4018
+ const select = (selector) => Array.from(reference.querySelectorAll(selector)).filter(
4019
+ (element) => !isInTrackedDeletion(element)
4020
+ );
4021
+ const relations = typeSchema.bibliomsetRelations ?? [];
4022
+ const sets = select(BIBLIOMSET);
4023
+ const misrelatedSets = sets.filter(
4024
+ (set) => !relations.some((relation) => relation === set.getAttribute("relation"))
4025
+ );
4026
+ const hasEverySet = relations.every(
4027
+ (relation) => sets.some((set) => set.getAttribute("relation") === relation)
4028
+ );
4029
+ const rules = {
4030
+ missing_id: hasValue(reference, XMLID_ATTRIBUTE) ? [] : [reference],
4031
+ bibliomset_relation: misrelatedSets,
4032
+ bibliomset_missing: hasEverySet || misrelatedSets.length > 0 ? [] : [reference],
4033
+ bibliomset_repeated: sets.filter(
4034
+ (set, index) => sets.slice(0, index).some(
4035
+ (earlier) => earlier.getAttribute("relation") === set.getAttribute("relation")
4036
+ )
4037
+ ),
4038
+ bibliomset_title: sets.filter(
4039
+ (set) => !Array.from(set.querySelectorAll(TITLE_TAG.toLowerCase())).some(
4040
+ (title) => !isInTrackedDeletion(title)
4041
+ )
4042
+ ),
4043
+ bibliomset_nested: sets.filter(
4044
+ (set) => !!set.parentElement?.closest(BIBLIOMSET)
4045
+ ),
4046
+ part_editor: select(EDITOR_TAG.toLowerCase()).filter(
4047
+ (editor) => editor.closest(BIBLIOMSET)?.getAttribute("relation") === PART_BIBLIOMSET_RELATION
4048
+ ),
4049
+ personname_role: select(PERSONNAME).filter(
4050
+ (personname) => !hasNameOrder(personname)
4051
+ ),
4052
+ name_outside_personname: select(NAME_PARTS).filter(
4053
+ (part) => !part.closest(PERSONNAME)
4054
+ ),
4055
+ othercredit_artist: typeSchema.code === "recording" ? select(OTHERCREDIT_TAG.toLowerCase()).filter(
4056
+ (credit) => credit.getAttribute("otherclass") !== ARTIST_OTHERCLASS
4057
+ ) : [],
4058
+ link_without_target: select(LINK).filter(
4059
+ (link) => isExternalLink(link) && !hasValue(link, LINK_ATTRIBUTE)
4060
+ ),
4061
+ doi_inside_uri: select(LINK).filter(
4062
+ (link) => isExternalLink(link) && hasLiveUri(link) && pointsAtDoiOrg(link)
4063
+ ),
4064
+ doi_outside_doi_org: select(LINK).filter(
4065
+ (link) => isExternalLink(link) && hasValue(link, LINK_ATTRIBUTE) && !hasLiveUri(link) && !pointsAtDoiOrg(link)
4066
+ ),
4067
+ uri_outside_link: select(URI).filter(
4068
+ (uri) => !uri.closest(LINK) && !uri.closest(REFERENCE_PART_SELECTOR)
4069
+ ),
4070
+ confgroup_text: select(CONFGROUP).filter(hasUntaggedConferenceText),
4071
+ confdates_outside_confgroup: select(CONFDATES_TAG.toLowerCase()).filter(
4072
+ (dates) => !dates.closest(CONFGROUP)
4073
+ )
4074
+ };
4075
+ const wrongElements = [
4076
+ ...typeSchema.replacedElements ?? [],
4077
+ ...NOT_PERMITTED_ELEMENTS
4078
+ ].map(
4079
+ ({ tag, replacement }) => ({
4080
+ code: "wrong_element",
4081
+ tag,
4082
+ replacement,
4083
+ elements: select(tag).filter((element) => !isPubMedIdBiblioid(element))
4084
+ })
4085
+ );
4086
+ const markup = Object.entries(rules).map(
4087
+ ([rule, elements]) => ({
4088
+ code: "markup",
4089
+ rule,
4090
+ elements
4091
+ })
4092
+ );
4093
+ return [...wrongElements, ...markup].filter(
4094
+ ({ elements }) => elements.length > 0
4095
+ );
4096
+ };
4097
+
4098
+ // src/validation/validateReferenceStructure.ts
4099
+ var validateReferenceStructure = (reference) => {
4100
+ const typeSchema = findReferenceTypeSchemaByElement(reference);
4101
+ if (!typeSchema) return [{ code: "unknown_type" }];
4102
+ const issues = [];
4103
+ const present = /* @__PURE__ */ new Set();
4104
+ for (const { field } of getReferenceFieldElements(reference)) {
4105
+ if (!present.has(field) && !typeSchema.allowedFields.includes(field)) {
4106
+ issues.push({ code: "not_allowed", field });
4107
+ }
4108
+ present.add(field);
4109
+ }
4110
+ for (const field of typeSchema.requiredFields) {
4111
+ const isSatisfied = field === "creators" ? present.has("author") || present.has("editor") : present.has(field);
4112
+ if (!isSatisfied) issues.push({ code: "missing", field });
4113
+ }
4114
+ return [...issues, ...validateReferenceMarkup(reference, typeSchema)];
4115
+ };
4116
+ var isSameMarkupIssue = (candidate, issue) => candidate.code === "markup" && issue.code === "markup" && candidate.rule === issue.rule || candidate.code === "wrong_element" && issue.code === "wrong_element" && candidate.tag === issue.tag;
4117
+ var getReferenceStructureIssueElements = (reference, issue) => {
4118
+ if (issue.code === "not_allowed") {
4119
+ return getReferenceFieldElements(reference).filter(({ field }) => field === issue.field).map(({ element }) => element);
4120
+ }
4121
+ if (issue.code !== "markup" && issue.code !== "wrong_element") return [];
4122
+ const found = validateReferenceStructure(reference).find(
4123
+ (candidate) => isSameMarkupIssue(candidate, issue)
4124
+ );
4125
+ return (found?.elements ?? []).filter((element) => element !== reference);
4126
+ };
4127
+
4128
+ // src/validation/validateReference.ts
4129
+ var getFieldLabel = (field, typeSchema) => {
4130
+ if (field === "creators") {
4131
+ return typeSchema.allowedFields.includes("editor") ? "Author or editor" : "Author";
4132
+ }
4133
+ return typeSchema.fieldLabels?.[field] ?? REFERENCE_FIELD_SCHEMAS[field].label;
4134
+ };
4135
+ var getBibliomsetRelationCopy = (typeSchema) => {
4136
+ const relations = typeSchema.bibliomsetRelations ?? [];
4137
+ return relations.length > 0 ? `${typeSchema.label} references use bibliomset with the relation ${relations.join(" and ")}. Please correct the relation.` : `${typeSchema.label} references do not use bibliomset. Please remove it and keep its contents.`;
4138
+ };
4139
+ var getMarkupCopy = (rule, typeSchema) => {
4140
+ switch (rule) {
4141
+ case "missing_id":
4142
+ return {
4143
+ title: "Reference ID missing",
4144
+ kind: "missing",
4145
+ description: "Every reference needs an xml:id. Please add one."
4146
+ };
4147
+ case "bibliomset_relation":
4148
+ return {
4149
+ title: "Wrong bibliomset for this reference type",
4150
+ kind: "forbidden",
4151
+ description: getBibliomsetRelationCopy(typeSchema)
4152
+ };
4153
+ case "bibliomset_missing":
4154
+ return {
4155
+ title: "Bibliomset missing",
4156
+ kind: "missing",
4157
+ description: `${typeSchema.label} references need one bibliomset with the relation ${(typeSchema.bibliomsetRelations ?? []).join(" and one with ")}. Please wrap the details in them.`
4158
+ };
4159
+ case "bibliomset_repeated":
4160
+ return {
4161
+ title: "Bibliomset repeated",
4162
+ kind: "forbidden",
4163
+ description: "A reference holds one bibliomset of each relation. Please move the details of the repeated bibliomset into the first one."
4164
+ };
4165
+ case "bibliomset_title":
4166
+ return {
4167
+ title: "Bibliomset without a title",
4168
+ kind: "missing",
4169
+ description: "Every bibliomset must contain a title. Please move its title into it or remove the bibliomset."
4170
+ };
4171
+ case "bibliomset_nested":
4172
+ return {
4173
+ title: "Bibliomset inside another bibliomset",
4174
+ kind: "forbidden",
4175
+ description: "A bibliomset cannot sit inside another bibliomset. Please move it out so the two sit side by side."
4176
+ };
4177
+ case "part_editor":
4178
+ return {
4179
+ title: "Editor tagged in the chapter part",
4180
+ kind: "forbidden",
4181
+ description: "The part bibliomset holds the chapter and its author. Please tag the name as an author or move the editor to the book bibliomset."
4182
+ };
4183
+ case "personname_role":
4184
+ return {
4185
+ title: "Name order not set",
4186
+ kind: "missing",
4187
+ description: `Every personname needs a role of ${PERSONNAME_ORDER_ROLES.join(" or ")}. Please set the name order.`
4188
+ };
4189
+ case "name_outside_personname":
4190
+ return {
4191
+ title: "Name not wrapped in personname",
4192
+ kind: "forbidden",
4193
+ description: "A surname, firstname or honorific must sit inside a personname. Please wrap the name parts."
4194
+ };
4195
+ case "othercredit_artist":
4196
+ return {
4197
+ title: "Artist credit not marked",
4198
+ kind: "missing",
4199
+ description: `The othercredit of a recording needs otherclass="${ARTIST_OTHERCLASS}". Please set it.`
4200
+ };
4201
+ case "link_without_target":
4202
+ return {
4203
+ title: "Link incomplete",
4204
+ kind: "missing",
4205
+ description: "A link needs an xlink:href. Please complete the link."
4206
+ };
4207
+ case "doi_outside_doi_org":
4208
+ return {
4209
+ title: "DOI not pointing at doi.org",
4210
+ kind: "forbidden",
4211
+ description: "A DOI link must point at a https://doi.org/ address. Please fix its xlink:href, or tag the address as a URL with a uri inside the link."
4212
+ };
4213
+ case "doi_inside_uri":
4214
+ return {
4215
+ title: "DOI tagged as a URL",
4216
+ kind: "forbidden",
4217
+ description: "A DOI link holds the DOI directly, without a uri inside it. Please remove the uri."
4218
+ };
4219
+ case "uri_outside_link":
4220
+ return {
4221
+ title: "URL not wrapped in a link",
4222
+ kind: "forbidden",
4223
+ description: "A uri must sit inside a link that carries the xlink:href. Please wrap it in a link."
4224
+ };
4225
+ case "confgroup_text":
4226
+ return {
4227
+ title: "Text directly inside confgroup",
4228
+ kind: "forbidden",
4229
+ description: "A confgroup cannot hold text directly. Please tag the text as conftitle or confdates."
4230
+ };
4231
+ case "confdates_outside_confgroup":
4232
+ return {
4233
+ title: "Conference dates outside confgroup",
4234
+ kind: "forbidden",
4235
+ description: "Conference dates must sit inside a confgroup. Please wrap them in one."
4236
+ };
4237
+ }
4238
+ };
4239
+ var getIssueCopy = (issue, typeSchema) => {
4240
+ if (issue.code === "unknown_type" || !typeSchema) {
4241
+ return {
4242
+ title: "Reference type not set",
4243
+ kind: "missing",
4244
+ description: "This reference has no recognised type, so its structure cannot be checked. Please set its reference type."
4245
+ };
4246
+ }
4247
+ const typeLabel = typeSchema.label.toLowerCase();
4248
+ if (issue.code === "markup") return getMarkupCopy(issue.rule, typeSchema);
4249
+ if (issue.code === "wrong_element") {
4250
+ return {
4251
+ title: `${issue.tag} not allowed`,
4252
+ kind: "forbidden",
4253
+ description: issue.replacement ? `${issue.tag} is not used by ${typeLabel} references. Please use ${issue.replacement} instead.` : `${issue.tag} is not used by ${typeLabel} references. Please remove it and keep its contents.`
4254
+ };
4255
+ }
4256
+ const fieldLabel = getFieldLabel(issue.field, typeSchema);
4257
+ switch (issue.code) {
4258
+ case "missing":
4259
+ return {
4260
+ title: `${fieldLabel} missing`,
4261
+ kind: "missing",
4262
+ description: `Please tag the ${fieldLabel.toLowerCase()} in this ${typeLabel} reference.`
4263
+ };
4264
+ case "not_allowed":
4265
+ return {
4266
+ title: `${fieldLabel} not allowed`,
4267
+ kind: "forbidden",
4268
+ description: `${fieldLabel} is not used by ${typeLabel} references. Please untag or delete it.`
4269
+ };
4270
+ }
4271
+ };
4272
+ var validateReference = (reference) => {
4273
+ if (isDeletedElement(reference)) return [];
4274
+ const isBibliographyEntry = !!closestElementBySchema({
4275
+ element: reference,
4276
+ code: "referenceBibliography"
4277
+ });
4278
+ if (!isBibliographyEntry) return [];
4279
+ const isTagged = getReferenceParts(reference).length > 0 || hasLooseReferenceMarkup(reference);
4280
+ if (!isTagged) return [];
4281
+ const typeSchema = findReferenceTypeSchemaByElement(reference);
4282
+ return validateReferenceStructure(reference).map(
4283
+ (issue) => createValidationIssue(reference, {
4284
+ level: "warning",
4285
+ elements: getReferenceStructureIssueElements(reference, issue),
4286
+ ...getIssueCopy(issue, typeSchema)
4287
+ })
4288
+ );
4289
+ };
4290
+
3188
4291
  // src/validation/validateXml.ts
3189
4292
  var validateElement = (element, root, elementsToLink, linkElements, schemasToValidateAgainst) => {
3190
4293
  if (isIgnoredElement(element)) {
@@ -3194,13 +4297,18 @@ var validateElement = (element, root, elementsToLink, linkElements, schemasToVal
3194
4297
  const schema = findSchemaByElement(element);
3195
4298
  if (schema) {
3196
4299
  if (schemasToValidateAgainst.includes(schema.code)) {
3197
- errors.push(...validateElementAgainstSchema(element, schema));
4300
+ errors.push(
4301
+ ...schema.code === BIBLIOMIXED_SCHEMA.code ? validateReference(element) : validateElementAgainstSchema(element, schema)
4302
+ );
3198
4303
  }
3199
4304
  if (schema.tag === FOOTNOTE_SCHEMA.tag) {
3200
4305
  errors.push(...validateFootnoteNumber(element));
3201
4306
  }
3202
4307
  if (schema.code === HEADING_SCHEMA.code) {
3203
- errors.push(...validateHeadingHierarchy(element));
4308
+ errors.push(...validateHierarchy(element, "heading"));
4309
+ }
4310
+ if (schema.code === BOX_SCHEMA.code) {
4311
+ errors.push(...validateHierarchy(element, "box"));
3204
4312
  }
3205
4313
  if (schema.code === OLINK_SCHEMA.code) {
3206
4314
  errors.push(...validateOlink(element));
@@ -3341,6 +4449,13 @@ export {
3341
4449
  LAYOUT_USER_ATTRIBUTE,
3342
4450
  LEFT_INDENT_ATTRIBUTE,
3343
4451
  LINKEND_ATTRIBUTE,
4452
+ LINK_BLOCKER_ROLES,
4453
+ LINK_TO_CROSS_CHECK,
4454
+ POSSIBLE_WEBLINK_CLASS,
4455
+ POSSIBLE_WEBLINK_EXCLUDE_SELECTORS,
4456
+ REFERENCE_FIELD_SCHEMAS,
4457
+ REFERENCE_PART_SELECTOR,
4458
+ REFERENCE_TYPE_SCHEMAS,
3344
4459
  RIGHT_INDENT_ATTRIBUTE,
3345
4460
  SCHEMAS,
3346
4461
  SPACE_ABOVE_ATTRIBUTE,
@@ -3353,22 +4468,45 @@ export {
3353
4468
  TRACK_CHANGES_ATTR_DATA_TIME,
3354
4469
  TRACK_CHANGES_ATTR_DATA_USERID,
3355
4470
  TRACK_CHANGES_ATTR_DATA_USERNAME,
4471
+ VALIDATION_IGNORED_ATTRIBUTE,
3356
4472
  XMLID_ATTRIBUTE,
4473
+ clearWeblinkMatches,
3357
4474
  closestElementBySchema,
3358
4475
  createElement,
4476
+ extractFootnoteNumber,
3359
4477
  findAttributeDefinitionByName,
4478
+ findElementLinkedTo,
4479
+ findReferenceFieldByElement,
4480
+ findReferenceTypeSchemaByElement,
3360
4481
  findSchemaByCode,
3361
4482
  findSchemaByElement,
3362
4483
  getAdjacentElement,
3363
4484
  getAttributeName,
4485
+ getEffectiveChildElements,
3364
4486
  getElementLinks,
4487
+ getPossibleWeblinks,
4488
+ getReferenceFieldElements,
4489
+ getReferenceParts,
4490
+ getReferenceStructureIssueElements,
3365
4491
  getStore,
3366
4492
  isAttributeRestricted,
3367
4493
  isDeletedElement,
3368
4494
  isIgnoredAttribute,
3369
4495
  isIgnoredElement,
3370
4496
  isTrackChangesSchema,
4497
+ markPossibleWeblinks,
3371
4498
  queryAllElementsBySchema,
3372
4499
  queryElementBySchema,
4500
+ validateAttributes,
4501
+ validateConsecutiveFootnoteCues,
4502
+ validateConsecutiveFootnotes,
4503
+ validateElementAgainstSchema,
4504
+ validateElementToLinkTo,
4505
+ validateFootnoteNumber,
4506
+ validateHierarchy,
4507
+ validateLinkend,
4508
+ validateOlink,
4509
+ validatePossibleWeblinks,
4510
+ validateReferenceStructure,
3373
4511
  validateXml
3374
4512
  };