ochre-sdk 1.0.78 → 1.1.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/README.md +31 -3
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/categories.d.mts +249 -0
- package/dist/categories.mjs +259 -0
- package/dist/constants.d.mts +14 -0
- package/dist/constants.mjs +18 -1
- package/dist/errors.d.mts +23 -0
- package/dist/{utilities.mjs → errors.mjs} +33 -84
- package/dist/fetchers/gallery.mjs +15 -51
- package/dist/fetchers/item-children.mjs +20 -66
- package/dist/fetchers/item-links.mjs +26 -79
- package/dist/fetchers/item-ocr-data.d.mts +2 -2
- package/dist/fetchers/item-ocr-data.mjs +11 -15
- package/dist/fetchers/item.d.mts +0 -15
- package/dist/fetchers/item.mjs +20 -72
- package/dist/fetchers/request.d.mts +70 -0
- package/dist/fetchers/request.mjs +100 -0
- package/dist/fetchers/set/items.mjs +27 -73
- package/dist/fetchers/set/property-values.d.mts +2 -3
- package/dist/fetchers/set/property-values.mjs +96 -130
- package/dist/fetchers/website-metadata.mjs +35 -57
- package/dist/fetchers/website.d.mts +2 -3
- package/dist/fetchers/website.mjs +22 -31
- package/dist/getters.d.mts +78 -148
- package/dist/getters.mjs +127 -208
- package/dist/helpers.d.mts +0 -4
- package/dist/helpers.mjs +19 -6
- package/dist/index.d.mts +8 -6
- package/dist/index.mjs +6 -4
- package/dist/ocr.d.mts +37 -0
- package/dist/ocr.mjs +52 -0
- package/dist/parsers/helpers.d.mts +21 -1
- package/dist/parsers/helpers.mjs +26 -6
- package/dist/parsers/index.d.mts +0 -8
- package/dist/parsers/index.mjs +118 -259
- package/dist/parsers/languages.d.mts +72 -0
- package/dist/parsers/languages.mjs +132 -0
- package/dist/parsers/multilingual.d.mts +49 -74
- package/dist/parsers/multilingual.mjs +88 -189
- package/dist/parsers/property-token.d.mts +34 -0
- package/dist/parsers/property-token.mjs +29 -0
- package/dist/parsers/string.d.mts +19 -0
- package/dist/parsers/string.mjs +45 -25
- package/dist/parsers/website/bounds.d.mts +10 -0
- package/dist/parsers/website/bounds.mjs +28 -0
- package/dist/parsers/website/components.d.mts +91 -0
- package/dist/parsers/website/components.mjs +681 -0
- package/dist/parsers/website/index.d.mts +0 -7
- package/dist/parsers/website/index.mjs +92 -1153
- package/dist/parsers/website/links.d.mts +36 -0
- package/dist/parsers/website/links.mjs +58 -0
- package/dist/parsers/website/messages.d.mts +24 -0
- package/dist/parsers/website/messages.mjs +31 -0
- package/dist/parsers/website/options.d.mts +6 -0
- package/dist/parsers/website/options.mjs +114 -0
- package/dist/parsers/website/properties.d.mts +12 -0
- package/dist/parsers/website/properties.mjs +158 -0
- package/dist/parsers/website/reader.d.mts +54 -4
- package/dist/parsers/website/reader.mjs +65 -20
- package/dist/parsers/website/slug.d.mts +64 -0
- package/dist/parsers/website/slug.mjs +82 -0
- package/dist/parsers/website/styles.d.mts +28 -0
- package/dist/parsers/website/styles.mjs +103 -0
- package/dist/parsers/website/walk.d.mts +68 -0
- package/dist/parsers/website/walk.mjs +116 -0
- package/dist/query.d.mts +66 -18
- package/dist/query.mjs +202 -48
- package/dist/reflection.d.mts +64 -0
- package/dist/reflection.mjs +79 -0
- package/dist/schemas.d.mts +7 -0
- package/dist/schemas.mjs +12 -3
- package/dist/types/index.d.mts +1 -31
- package/dist/types/utilities.d.mts +9 -0
- package/dist/types/utilities.mjs +1 -0
- package/dist/types/website.d.mts +49 -58
- package/dist/xml/metadata.d.mts +16 -0
- package/dist/xml/metadata.mjs +32 -11
- package/dist/xml/schemas.d.mts +5970 -3
- package/dist/xml/schemas.mjs +43 -45
- package/dist/xml/types.d.mts +13 -30
- package/dist/xquery.d.mts +46 -0
- package/dist/xquery.mjs +66 -0
- package/package.json +3 -3
- package/dist/utilities.d.mts +0 -54
package/dist/getters.mjs
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
import { deepEqual } from "fast-equals";
|
|
2
2
|
//#region src/getters.ts
|
|
3
|
+
/**
|
|
4
|
+
* The variable label that asks a filter to match against every property
|
|
5
|
+
*/
|
|
6
|
+
const ALL_FIELDS_VARIABLE_LABEL = "all-fields";
|
|
3
7
|
const DEFAULT_OPTIONS = {
|
|
4
8
|
includeNestedProperties: false,
|
|
5
9
|
limitToLeafPropertyValues: true
|
|
6
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Normalize an OCHRE property variable label for comparison
|
|
13
|
+
*
|
|
14
|
+
* OCHRE varies the casing and the word separator of a property label, so every
|
|
15
|
+
* comparison against a label goes through here. This is the only rule in the
|
|
16
|
+
* SDK for deciding whether a label names a given property.
|
|
17
|
+
* @param value - The label to normalize
|
|
18
|
+
* @returns The normalized label
|
|
19
|
+
*/
|
|
20
|
+
function normalizePropertyVariableLabel(value) {
|
|
21
|
+
return value.trim().toLocaleLowerCase("en-US").replaceAll(/[\s_]+/g, "-");
|
|
22
|
+
}
|
|
7
23
|
function withDefaultOptions(options) {
|
|
8
24
|
return {
|
|
9
25
|
includeNestedProperties: options.includeNestedProperties ?? false,
|
|
10
26
|
limitToLeafPropertyValues: options.limitToLeafPropertyValues ?? true
|
|
11
27
|
};
|
|
12
28
|
}
|
|
13
|
-
function findPropertyByVariableUuid(properties, variableUuid) {
|
|
14
|
-
for (const property of properties) if (property.variable.uuid === variableUuid) return property;
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
function findPropertyByVariableLabel(properties, variableLabel) {
|
|
18
|
-
for (const property of properties) if (getPropertyVariableLabel(property) === variableLabel) return property;
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
29
|
function getPropertyVariableLabel(property) {
|
|
22
30
|
return typeof property.variable.label === "string" ? property.variable.label : property.variable.label.getText();
|
|
23
31
|
}
|
|
@@ -34,42 +42,63 @@ function hasEqualPropertyValueContents(property, valueContents) {
|
|
|
34
42
|
for (const [index, value] of property.values.entries()) if (!deepEqual(value.content, valueContents[index])) return false;
|
|
35
43
|
return true;
|
|
36
44
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Compile a selector into a predicate over one property
|
|
47
|
+
*
|
|
48
|
+
* The label is normalized once here rather than once per candidate property.
|
|
49
|
+
*/
|
|
50
|
+
function createPropertyPredicate(selector) {
|
|
51
|
+
if ("uuid" in selector) {
|
|
52
|
+
const { uuid } = selector;
|
|
53
|
+
return (property) => property.variable.uuid === uuid;
|
|
54
|
+
}
|
|
55
|
+
const normalizedLabel = normalizePropertyVariableLabel(selector.label);
|
|
56
|
+
const hasMatchingLabel = (property) => normalizePropertyVariableLabel(getPropertyVariableLabel(property)) === normalizedLabel;
|
|
57
|
+
if ("values" in selector) {
|
|
58
|
+
const { values } = selector;
|
|
59
|
+
return (property) => hasMatchingLabel(property) && deepEqual(property.values, values);
|
|
60
|
+
}
|
|
61
|
+
if ("valueContents" in selector) {
|
|
62
|
+
const { valueContents } = selector;
|
|
63
|
+
return (property) => hasMatchingLabel(property) && hasEqualPropertyValueContents(property, valueContents);
|
|
64
|
+
}
|
|
65
|
+
if ("value" in selector) {
|
|
66
|
+
const { value } = selector;
|
|
67
|
+
return (property) => hasMatchingLabel(property) && hasPropertyValue(property, value);
|
|
68
|
+
}
|
|
69
|
+
if ("valueContent" in selector) {
|
|
70
|
+
const { valueContent } = selector;
|
|
71
|
+
return (property) => hasMatchingLabel(property) && hasPropertyValueContent(property, valueContent);
|
|
72
|
+
}
|
|
73
|
+
return hasMatchingLabel;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Find the first property matching a predicate, descending when asked to
|
|
77
|
+
*
|
|
78
|
+
* Every property at one level is tested before descending, so a match on the
|
|
79
|
+
* item's own properties always wins over one on a nested property.
|
|
80
|
+
*/
|
|
81
|
+
function findProperty(properties, isMatch, shouldIncludeNestedProperties) {
|
|
82
|
+
for (const property of properties) if (isMatch(property)) return property;
|
|
83
|
+
if (!shouldIncludeNestedProperties) return null;
|
|
41
84
|
for (const property of properties) {
|
|
42
85
|
if (!("properties" in property)) continue;
|
|
43
|
-
const
|
|
44
|
-
if (
|
|
45
|
-
const transformedResult = transformNestedResult != null ? transformNestedResult(nestedResult) : nestedResult;
|
|
46
|
-
if (transformedResult !== null) return transformedResult;
|
|
86
|
+
const nestedProperty = findProperty(property.properties, isMatch, true);
|
|
87
|
+
if (nestedProperty !== null) return nestedProperty;
|
|
47
88
|
}
|
|
48
89
|
return null;
|
|
49
90
|
}
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
function clonePropertyValues(values) {
|
|
56
|
-
return Array.from(values, (value) => ({ ...value }));
|
|
57
|
-
}
|
|
58
|
-
function getNormalizedProperty(property, shouldLimitToLeafPropertyValues, transformValues) {
|
|
59
|
-
if (!shouldLimitToLeafPropertyValues) return property;
|
|
60
|
-
const values = getLeafPropertyValues(property.values);
|
|
61
|
-
return {
|
|
62
|
-
...property,
|
|
63
|
-
values: transformValues != null ? transformValues(values) : values
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function getFirstPropertyValueResult(values, shouldLimitToLeafPropertyValues) {
|
|
67
|
-
if (shouldLimitToLeafPropertyValues) return getLeafPropertyValues(values)[0] ?? null;
|
|
68
|
-
return values[0] ?? null;
|
|
91
|
+
function getLeafPropertyValues(propertyValues) {
|
|
92
|
+
const leafPropertyValues = [];
|
|
93
|
+
for (const value of propertyValues) if (value.hierarchy.isLeaf) leafPropertyValues.push(value);
|
|
94
|
+
return leafPropertyValues;
|
|
69
95
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Project a property's values, copying so callers cannot mutate the source
|
|
98
|
+
*/
|
|
99
|
+
function projectPropertyValues(values, shouldLimitToLeafPropertyValues) {
|
|
100
|
+
const projectedValues = shouldLimitToLeafPropertyValues ? getLeafPropertyValues(values) : values;
|
|
101
|
+
return Array.from(projectedValues, (value) => ({ ...value }));
|
|
73
102
|
}
|
|
74
103
|
function visitProperties(properties, shouldIncludeNestedProperties, visit) {
|
|
75
104
|
for (const property of properties) {
|
|
@@ -77,227 +106,117 @@ function visitProperties(properties, shouldIncludeNestedProperties, visit) {
|
|
|
77
106
|
if (shouldIncludeNestedProperties && "properties" in property) visitProperties(property.properties, shouldIncludeNestedProperties, visit);
|
|
78
107
|
}
|
|
79
108
|
}
|
|
80
|
-
function getPropertyByVariableUuid(properties, variableUuid, options = DEFAULT_OPTIONS) {
|
|
81
|
-
const { includeNestedProperties } = withDefaultOptions(options);
|
|
82
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => findPropertyByVariableUuid(currentProperties, variableUuid));
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Retrieves all values for a property with the given variable UUID.
|
|
86
|
-
*
|
|
87
|
-
* @param properties - Array of properties to search through
|
|
88
|
-
* @param variableUuid - The property variable UUID to search for
|
|
89
|
-
* @param options - Search options, including whether to include nested properties
|
|
90
|
-
* @returns Array of property values, or null if property not found
|
|
91
|
-
*/
|
|
92
|
-
function getPropertyValuesByVariableUuid(properties, variableUuid, options = DEFAULT_OPTIONS) {
|
|
93
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
94
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
95
|
-
const property = findPropertyByVariableUuid(currentProperties, variableUuid);
|
|
96
|
-
if (property == null) return null;
|
|
97
|
-
return getPropertyValuesResult(property.values, limitToLeafPropertyValues, true);
|
|
98
|
-
}, (nestedResult) => getPropertyValuesResult(nestedResult, limitToLeafPropertyValues, true));
|
|
99
|
-
}
|
|
100
109
|
/**
|
|
101
|
-
*
|
|
110
|
+
* Find the property a selector names
|
|
102
111
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* @
|
|
106
|
-
* @
|
|
112
|
+
* The property is returned exactly as it was found, so its `values` are
|
|
113
|
+
* whatever the item carries and `limitToLeafPropertyValues` does not apply.
|
|
114
|
+
* Use {@link getPropertyValues} when leaf filtering matters.
|
|
115
|
+
* @param properties - The properties to search
|
|
116
|
+
* @param selector - Which property to look for
|
|
117
|
+
* @param options - Search options
|
|
118
|
+
* @param options.includeNestedProperties - Whether to descend into nested properties
|
|
119
|
+
* @returns The matching property, or null when there is none
|
|
107
120
|
*/
|
|
108
|
-
function
|
|
109
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
110
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
111
|
-
const property = findPropertyByVariableUuid(currentProperties, variableUuid);
|
|
112
|
-
if (property == null) return null;
|
|
113
|
-
return Array.from(getPropertyValuesResult(property.values, limitToLeafPropertyValues, false), (value) => value.content);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Gets the first value of a property with the given variable UUID.
|
|
118
|
-
*
|
|
119
|
-
* @param properties - Array of properties to search through
|
|
120
|
-
* @param variableUuid - The property variable UUID to search for
|
|
121
|
-
* @param options - Search options, including whether to include nested properties
|
|
122
|
-
* @returns The first property value, or null if property not found
|
|
123
|
-
*/
|
|
124
|
-
function getPropertyValueByVariableUuid(properties, variableUuid, options = DEFAULT_OPTIONS) {
|
|
125
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
126
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
127
|
-
const values = getPropertyValuesByVariableUuid(currentProperties, variableUuid, {
|
|
128
|
-
includeNestedProperties: false,
|
|
129
|
-
limitToLeafPropertyValues
|
|
130
|
-
});
|
|
131
|
-
if (values === null || values.length === 0) return null;
|
|
132
|
-
return getFirstPropertyValueResult(values, limitToLeafPropertyValues);
|
|
133
|
-
}, (nestedResult) => getFirstPropertyValueResult([nestedResult], limitToLeafPropertyValues));
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Gets the first value content of a property with the given variable UUID.
|
|
137
|
-
*
|
|
138
|
-
* @param properties - Array of properties to search through
|
|
139
|
-
* @param variableUuid - The property variable UUID to search for
|
|
140
|
-
* @param options - Search options, including whether to include nested properties
|
|
141
|
-
* @returns The first property value content, or null if property not found
|
|
142
|
-
*/
|
|
143
|
-
function getPropertyValueContentByVariableUuid(properties, variableUuid, options = DEFAULT_OPTIONS) {
|
|
144
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
145
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
146
|
-
const values = getPropertyValuesByVariableUuid(currentProperties, variableUuid, {
|
|
147
|
-
includeNestedProperties: false,
|
|
148
|
-
limitToLeafPropertyValues
|
|
149
|
-
});
|
|
150
|
-
if (values === null || values.length === 0) return null;
|
|
151
|
-
return getFirstPropertyValueContentResult(values, limitToLeafPropertyValues);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
function getPropertyByVariableLabel(properties, variableLabel, options = DEFAULT_OPTIONS) {
|
|
121
|
+
function getProperty(properties, selector, options = DEFAULT_OPTIONS) {
|
|
155
122
|
const { includeNestedProperties } = withDefaultOptions(options);
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
function getPropertyByVariableLabelAndValues(properties, variableLabel, values, options = DEFAULT_OPTIONS) {
|
|
159
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
160
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
161
|
-
for (const property of currentProperties) if (getPropertyVariableLabel(property) === variableLabel && deepEqual(property.values, values)) return getNormalizedProperty(property, limitToLeafPropertyValues);
|
|
162
|
-
return null;
|
|
163
|
-
}, (nestedResult) => getNormalizedProperty(nestedResult, limitToLeafPropertyValues));
|
|
164
|
-
}
|
|
165
|
-
function getPropertyByVariableLabelAndValueContents(properties, variableLabel, valueContents, options = DEFAULT_OPTIONS) {
|
|
166
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
167
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
168
|
-
for (const property of currentProperties) if (getPropertyVariableLabel(property) === variableLabel && hasEqualPropertyValueContents(property, valueContents)) return getNormalizedProperty(property, limitToLeafPropertyValues, clonePropertyValues);
|
|
169
|
-
return null;
|
|
170
|
-
}, (nestedResult) => getNormalizedProperty(nestedResult, limitToLeafPropertyValues));
|
|
171
|
-
}
|
|
172
|
-
function getPropertyByVariableLabelAndValue(properties, variableLabel, value, options = DEFAULT_OPTIONS) {
|
|
173
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
174
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
175
|
-
for (const property of currentProperties) if (getPropertyVariableLabel(property) === variableLabel && hasPropertyValue(property, value)) return getNormalizedProperty(property, limitToLeafPropertyValues);
|
|
176
|
-
return null;
|
|
177
|
-
}, (nestedResult) => getNormalizedProperty(nestedResult, limitToLeafPropertyValues));
|
|
178
|
-
}
|
|
179
|
-
function getPropertyByVariableLabelAndValueContent(properties, variableLabel, valueContent, options = DEFAULT_OPTIONS) {
|
|
180
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
181
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
182
|
-
for (const property of currentProperties) if (getPropertyVariableLabel(property) === variableLabel && hasPropertyValueContent(property, valueContent)) return getNormalizedProperty(property, limitToLeafPropertyValues);
|
|
183
|
-
return null;
|
|
184
|
-
}, (nestedResult) => getNormalizedProperty(nestedResult, limitToLeafPropertyValues));
|
|
123
|
+
return findProperty(properties, createPropertyPredicate(selector), includeNestedProperties);
|
|
185
124
|
}
|
|
186
125
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* @param
|
|
190
|
-
* @param
|
|
191
|
-
* @param options -
|
|
192
|
-
* @
|
|
126
|
+
* Read every value of the property a selector names
|
|
127
|
+
* @param properties - The properties to search
|
|
128
|
+
* @param selector - Which property to look for
|
|
129
|
+
* @param options - Search options
|
|
130
|
+
* @param options.includeNestedProperties - Whether to descend into nested properties
|
|
131
|
+
* @param options.limitToLeafPropertyValues - Whether to keep only leaf values
|
|
132
|
+
* @returns The values, or null when no property matched
|
|
193
133
|
*/
|
|
194
|
-
function
|
|
134
|
+
function getPropertyValues(properties, selector, options = DEFAULT_OPTIONS) {
|
|
195
135
|
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (property == null) return null;
|
|
199
|
-
return getPropertyValuesResult(property.values, limitToLeafPropertyValues, false);
|
|
200
|
-
}, (nestedResult) => getPropertyValuesResult(nestedResult, limitToLeafPropertyValues, false));
|
|
136
|
+
const property = findProperty(properties, createPropertyPredicate(selector), includeNestedProperties);
|
|
137
|
+
return property == null ? null : projectPropertyValues(property.values, limitToLeafPropertyValues);
|
|
201
138
|
}
|
|
202
139
|
/**
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* @param
|
|
206
|
-
* @param
|
|
207
|
-
* @param options -
|
|
208
|
-
* @
|
|
140
|
+
* Read the first value of the property a selector names
|
|
141
|
+
* @param properties - The properties to search
|
|
142
|
+
* @param selector - Which property to look for
|
|
143
|
+
* @param options - Search options
|
|
144
|
+
* @param options.includeNestedProperties - Whether to descend into nested properties
|
|
145
|
+
* @param options.limitToLeafPropertyValues - Whether to keep only leaf values
|
|
146
|
+
* @returns The first value, or null when no property matched or it has none
|
|
209
147
|
*/
|
|
210
|
-
function
|
|
211
|
-
|
|
212
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
213
|
-
const values = getPropertyValuesByVariableLabel(currentProperties, variableLabel, {
|
|
214
|
-
includeNestedProperties: false,
|
|
215
|
-
limitToLeafPropertyValues
|
|
216
|
-
});
|
|
217
|
-
if (values === null || values.length === 0) return null;
|
|
218
|
-
return getFirstPropertyValueResult(values, limitToLeafPropertyValues);
|
|
219
|
-
}, (nestedResult) => getFirstPropertyValueResult([nestedResult], limitToLeafPropertyValues));
|
|
148
|
+
function getPropertyValue(properties, selector, options = DEFAULT_OPTIONS) {
|
|
149
|
+
return getPropertyValues(properties, selector, options)?.[0] ?? null;
|
|
220
150
|
}
|
|
221
151
|
/**
|
|
222
|
-
* Gets
|
|
152
|
+
* Gets all unique properties from an array of properties.
|
|
223
153
|
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* @param
|
|
227
|
-
* @
|
|
154
|
+
* Properties are returned exactly as they were found, deduplicated by variable
|
|
155
|
+
* UUID, keeping the first occurrence.
|
|
156
|
+
* @param properties - Array of properties to get unique properties from
|
|
157
|
+
* @param options - Search options
|
|
158
|
+
* @param options.includeNestedProperties - Whether to descend into nested properties
|
|
159
|
+
* @returns Array of unique properties
|
|
228
160
|
*/
|
|
229
|
-
function getPropertyValueContentByVariableLabel(properties, variableLabel, options = DEFAULT_OPTIONS) {
|
|
230
|
-
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
231
|
-
return searchPropertyResult(properties, { includeNestedProperties }, (currentProperties) => {
|
|
232
|
-
const values = getPropertyValuesByVariableLabel(currentProperties, variableLabel, {
|
|
233
|
-
includeNestedProperties: false,
|
|
234
|
-
limitToLeafPropertyValues
|
|
235
|
-
});
|
|
236
|
-
if (values === null || values.length === 0) return null;
|
|
237
|
-
return getFirstPropertyValueContentResult(values, limitToLeafPropertyValues);
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
161
|
function getUniqueProperties(properties, options = DEFAULT_OPTIONS) {
|
|
241
|
-
const { includeNestedProperties
|
|
162
|
+
const { includeNestedProperties } = withDefaultOptions(options);
|
|
242
163
|
const uniqueProperties = [];
|
|
164
|
+
const seenVariableUuids = /* @__PURE__ */ new Set();
|
|
243
165
|
visitProperties(properties, includeNestedProperties, (property) => {
|
|
244
|
-
|
|
166
|
+
if (seenVariableUuids.has(property.variable.uuid)) return;
|
|
167
|
+
seenVariableUuids.add(property.variable.uuid);
|
|
245
168
|
uniqueProperties.push(property);
|
|
246
169
|
});
|
|
247
|
-
if (limitToLeafPropertyValues) return Array.from(uniqueProperties, (property) => getNormalizedProperty(property, limitToLeafPropertyValues));
|
|
248
170
|
return uniqueProperties;
|
|
249
171
|
}
|
|
250
172
|
/**
|
|
251
173
|
* Gets all unique property variable labels from an array of properties.
|
|
252
|
-
*
|
|
253
174
|
* @param properties - Array of properties to get unique property variable labels from
|
|
254
|
-
* @param options - Search options
|
|
175
|
+
* @param options - Search options
|
|
176
|
+
* @param options.includeNestedProperties - Whether to descend into nested properties
|
|
255
177
|
* @returns Array of unique property variable labels
|
|
256
178
|
*/
|
|
257
179
|
function getUniquePropertyVariableLabels(properties, options = DEFAULT_OPTIONS) {
|
|
258
180
|
const { includeNestedProperties } = withDefaultOptions(options);
|
|
259
181
|
const uniquePropertyVariableLabels = [];
|
|
182
|
+
const seenLabels = /* @__PURE__ */ new Set();
|
|
260
183
|
visitProperties(properties, includeNestedProperties, (property) => {
|
|
261
184
|
const variableLabel = getPropertyVariableLabel(property);
|
|
262
|
-
if (
|
|
185
|
+
if (seenLabels.has(variableLabel)) return;
|
|
186
|
+
seenLabels.add(variableLabel);
|
|
263
187
|
uniquePropertyVariableLabels.push(variableLabel);
|
|
264
188
|
});
|
|
265
189
|
return uniquePropertyVariableLabels;
|
|
266
190
|
}
|
|
267
|
-
/**
|
|
268
|
-
* Get the leaf property values from an array of property values.
|
|
269
|
-
*
|
|
270
|
-
* @param propertyValues - The array of property values to get the leaf property values from
|
|
271
|
-
* @returns The array of leaf property values
|
|
272
|
-
*/
|
|
273
|
-
function getLeafPropertyValues(propertyValues) {
|
|
274
|
-
const leafPropertyValues = [];
|
|
275
|
-
for (const value of propertyValues) if (value.hierarchy.isLeaf) leafPropertyValues.push(value);
|
|
276
|
-
return leafPropertyValues;
|
|
277
|
-
}
|
|
278
191
|
function isContentMatchingFilter(content, filterContent) {
|
|
279
192
|
if (typeof content === "string") return typeof filterContent === "string" && content.toLocaleLowerCase("en-US").includes(filterContent.toLocaleLowerCase("en-US"));
|
|
280
193
|
if (typeof content === "number") return typeof filterContent === "number" && content === filterContent;
|
|
281
194
|
return typeof filterContent === "boolean" && content === filterContent;
|
|
282
195
|
}
|
|
283
196
|
/**
|
|
284
|
-
*
|
|
197
|
+
* Whether a property matches a variable label and value content criterion.
|
|
285
198
|
*
|
|
286
|
-
*
|
|
199
|
+
* Matching is client-side and deliberately loose: string contents match on a
|
|
200
|
+
* case-insensitive substring, numbers and booleans on equality. A
|
|
201
|
+
* `variableLabel` of "all fields" matches against every property.
|
|
202
|
+
* @param property - The property to test
|
|
287
203
|
* @param filter - Filter criteria containing variable label and value to match
|
|
288
204
|
* @param filter.variableLabel - The variable label to filter by
|
|
289
205
|
* @param filter.value - The value to filter by
|
|
290
|
-
* @param options - Search options
|
|
206
|
+
* @param options - Search options
|
|
207
|
+
* @param options.includeNestedProperties - Whether to descend into nested properties
|
|
208
|
+
* @param options.limitToLeafPropertyValues - Whether to test only leaf values
|
|
291
209
|
* @returns True if the property matches the filter criteria, false otherwise
|
|
292
210
|
*/
|
|
293
|
-
function
|
|
211
|
+
function isPropertyMatchingFilter(property, filter, options = DEFAULT_OPTIONS) {
|
|
294
212
|
const { includeNestedProperties, limitToLeafPropertyValues } = withDefaultOptions(options);
|
|
295
|
-
|
|
296
|
-
|
|
213
|
+
const normalizedFilterLabel = normalizePropertyVariableLabel(filter.variableLabel);
|
|
214
|
+
if (normalizedFilterLabel === ALL_FIELDS_VARIABLE_LABEL || normalizePropertyVariableLabel(getPropertyVariableLabel(property)) === normalizedFilterLabel) {
|
|
215
|
+
const values = limitToLeafPropertyValues ? getLeafPropertyValues(property.values) : property.values;
|
|
297
216
|
for (const value of values) if (isContentMatchingFilter(value.content, filter.value.content)) return true;
|
|
298
217
|
}
|
|
299
218
|
if (includeNestedProperties && "properties" in property) {
|
|
300
|
-
for (const nestedProperty of property.properties) if (
|
|
219
|
+
for (const nestedProperty of property.properties) if (isPropertyMatchingFilter(nestedProperty, filter, {
|
|
301
220
|
includeNestedProperties: true,
|
|
302
221
|
limitToLeafPropertyValues
|
|
303
222
|
})) return true;
|
|
@@ -305,4 +224,4 @@ function filterProperties(property, filter, options = DEFAULT_OPTIONS) {
|
|
|
305
224
|
return false;
|
|
306
225
|
}
|
|
307
226
|
//#endregion
|
|
308
|
-
export {
|
|
227
|
+
export { getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
|
package/dist/helpers.d.mts
CHANGED
|
@@ -3,10 +3,6 @@ import { ContainedItemCategory, Item, ItemCategory, ItemPayloadKind, LanguageCod
|
|
|
3
3
|
type FlattenedItem<U, T extends LanguageCodes> = Omit<U, "properties"> & {
|
|
4
4
|
properties: Array<SetItemProperty<T>>;
|
|
5
5
|
};
|
|
6
|
-
/**
|
|
7
|
-
* The default page size to use for fetching paginated items
|
|
8
|
-
*/
|
|
9
|
-
export declare const DEFAULT_PAGE_SIZE = 48;
|
|
10
6
|
/**
|
|
11
7
|
* Flatten the properties of an item
|
|
12
8
|
* @param item - The item whose properties to flatten
|
package/dist/helpers.mjs
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { flattenProperties } from "./utilities.mjs";
|
|
2
1
|
//#region src/helpers.ts
|
|
3
2
|
/**
|
|
4
|
-
* The default page size to use for fetching paginated items
|
|
5
|
-
*/
|
|
6
|
-
const DEFAULT_PAGE_SIZE = 48;
|
|
7
|
-
/**
|
|
8
3
|
* Flatten the properties of an item
|
|
9
4
|
* @param item - The item whose properties to flatten
|
|
10
5
|
* @returns The item with the properties flattened
|
|
@@ -29,5 +24,23 @@ function flattenItemProperties(item) {
|
|
|
29
24
|
properties: flattenProperties(allProperties)
|
|
30
25
|
};
|
|
31
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Flatten a properties array
|
|
29
|
+
* @param properties - The properties to flatten
|
|
30
|
+
* @returns The flattened properties
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
function flattenProperties(properties) {
|
|
34
|
+
const result = [];
|
|
35
|
+
for (const property of properties) {
|
|
36
|
+
result.push({
|
|
37
|
+
variable: property.variable,
|
|
38
|
+
values: property.values,
|
|
39
|
+
comment: property.comment
|
|
40
|
+
});
|
|
41
|
+
if ("properties" in property) result.push(...flattenProperties(property.properties));
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
32
45
|
//#endregion
|
|
33
|
-
export {
|
|
46
|
+
export { flattenItemProperties };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { MultilingualOptions, MultilingualString, MultilingualStringEntries, MultilingualStringEntry, MultilingualStringInput, MultilingualStringJSON, MultilingualStringObject, MultilingualStringText } from "./parsers/multilingual.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { ContextTree, ContextTreeFilterLevel, ContextTreeFilterVariant, ContextTreeLevel, ContextTreeLevelItem, ProtectedWebsite, ResponsiveStyles, Scope, Style, StylesheetItem, WebAccordionItem, WebBlock, WebBlockByLayout, WebBlockItem, WebBlockLayout, WebElement, WebElementComponent, WebElementComponentName, WebElementComponentOf, WebElementOf, WebIiifViewer, WebImage, WebLoadingVariant, WebOptions, WebSectionDisplay, WebSectionVariant, WebSidebar, WebTitle, Webpage, Website, WebsiteMetadata, WebsitePrivacy, WebsitePropertyQuery, WebsitePropertyQueryNode, WebsiteSegment, WebsiteType } from "./types/website.mjs";
|
|
3
|
+
import { BaseItem, BaseItemLink, BelongsTo, Bibliography, BibliographyEntryInfo, BibliographyItemLink, BibliographySourceDocument, Concept, ConceptItemLink, ContainedItemCategory, ContainedItemCategoryFromOption, ContainedItemCategoryOption, Context, ContextItem, ContextItemCategory, ContextNode, Coordinates, CoordinatesSource, DictionaryUnitItemLink, Event, Gallery, Heading, HeadingItemCategory, Identification, Image, ImageMap, ImageMapArea, Interpretation, Item, ItemCategory, ItemCategoryFromOption, ItemCategoryOption, ItemCategoryWithEmbeddedItems, ItemContainerCategory, ItemLink, ItemLinkCategory, ItemLinks, ItemPayloadKind, ItemWithoutEmbeddedItems, LanguageCodes, License, Metadata, Note, Observation, OcrString, Period, PeriodItemLink, Person, PersonItemLink, Property, PropertyLike, PropertyRelation, PropertyValue, PropertyValueContent, PropertyValueDataType, PropertyValueItemLink, PropertyValueQueryItem, PropertyVariable, PropertyVariableItemLink, Query, QueryGroup, QueryLeaf, QueryablePropertyValueDataType, Resource, ResourceItemLink, Section, Set, SetAttributeValueQueryItem, SetBibliography, SetConcept, SetItem, SetItemCategory, SetItemLink, SetItemProperty, SetItemSimplifiedProperty, SetItemsSort, SetItemsSortDirection, SetPeriod, SetResource, SetSpatialUnit, SetTree, SimplifiedProperty, SpatialUnit, SpatialUnitItemLink, Text, TextItemLink, Tree, TreeItemCategory, TreeItemLink } from "./types/index.mjs";
|
|
4
|
+
import { DEFAULT_PAGE_SIZE } from "./constants.mjs";
|
|
4
5
|
import { fetchGallery } from "./fetchers/gallery.mjs";
|
|
5
6
|
import { fetchItemChildren } from "./fetchers/item-children.mjs";
|
|
6
7
|
import { fetchItemLinks } from "./fetchers/item-links.mjs";
|
|
7
8
|
import { fetchItemOcrData } from "./fetchers/item-ocr-data.mjs";
|
|
8
|
-
import {
|
|
9
|
+
import { fetchItem } from "./fetchers/item.mjs";
|
|
9
10
|
import { fetchSetItems } from "./fetchers/set/items.mjs";
|
|
10
11
|
import { fetchSetPropertyValues } from "./fetchers/set/property-values.mjs";
|
|
11
12
|
import { fetchWebsiteMetadata } from "./fetchers/website-metadata.mjs";
|
|
12
13
|
import { fetchWebsite } from "./fetchers/website.mjs";
|
|
13
|
-
import { PropertyOptions,
|
|
14
|
-
import {
|
|
15
|
-
|
|
14
|
+
import { PropertyOptions, PropertySelector, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
|
|
15
|
+
import { flattenItemProperties } from "./helpers.mjs";
|
|
16
|
+
import { defineLanguages } from "./parsers/languages.mjs";
|
|
17
|
+
export { type BaseItem, type BaseItemLink, type BelongsTo, type Bibliography, type BibliographyEntryInfo, type BibliographyItemLink, type BibliographySourceDocument, type Concept, type ConceptItemLink, type ContainedItemCategory, type ContainedItemCategoryFromOption, type ContainedItemCategoryOption, type Context, type ContextItem, type ContextItemCategory, type ContextNode, type ContextTree, type ContextTreeFilterLevel, type ContextTreeFilterVariant, type ContextTreeLevel, type ContextTreeLevelItem, type Coordinates, type CoordinatesSource, DEFAULT_PAGE_SIZE, type DictionaryUnitItemLink, type Event, type Gallery, type Heading, type HeadingItemCategory, type Identification, type Image, type ImageMap, type ImageMapArea, type Interpretation, type Item, type ItemCategory, type ItemCategoryFromOption, type ItemCategoryOption, type ItemCategoryWithEmbeddedItems, type ItemContainerCategory, type ItemLink, type ItemLinkCategory, type ItemLinks, type ItemPayloadKind, type ItemWithoutEmbeddedItems, type LanguageCodes, type License, type Metadata, type MultilingualOptions, MultilingualString, type MultilingualStringEntries, type MultilingualStringEntry, type MultilingualStringInput, type MultilingualStringJSON, type MultilingualStringObject, type MultilingualStringText, type Note, type Observation, type OcrString, type Period, type PeriodItemLink, type Person, type PersonItemLink, type Property, type PropertyLike, type PropertyOptions, type PropertyRelation, type PropertySelector, type PropertyValue, type PropertyValueContent, type PropertyValueDataType, type PropertyValueItemLink, type PropertyValueQueryItem, type PropertyVariable, type PropertyVariableItemLink, type ProtectedWebsite, type Query, type QueryGroup, type QueryLeaf, type QueryablePropertyValueDataType, type Resource, type ResourceItemLink, type ResponsiveStyles, type Scope, type Section, type Set, type SetAttributeValueQueryItem, type SetBibliography, type SetConcept, type SetItem, type SetItemCategory, type SetItemLink, type SetItemProperty, type SetItemSimplifiedProperty, type SetItemsSort, type SetItemsSortDirection, type SetPeriod, type SetResource, type SetSpatialUnit, type SetTree, type SimplifiedProperty, type SpatialUnit, type SpatialUnitItemLink, type Style, type StylesheetItem, type Text, type TextItemLink, type Tree, type TreeItemCategory, type TreeItemLink, type WebAccordionItem, type WebBlock, type WebBlockByLayout, type WebBlockItem, type WebBlockLayout, type WebElement, type WebElementComponent, type WebElementComponentName, type WebElementComponentOf, type WebElementOf, type WebIiifViewer, type WebImage, type WebLoadingVariant, type WebOptions, type WebSectionDisplay, type WebSectionVariant, type WebSidebar, type WebTitle, type Webpage, type Website, type WebsiteMetadata, type WebsitePrivacy, type WebsitePropertyQuery, type WebsitePropertyQueryNode, type WebsiteSegment, type WebsiteType, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { DEFAULT_PAGE_SIZE } from "./constants.mjs";
|
|
2
|
+
import { getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel } from "./getters.mjs";
|
|
3
|
+
import { flattenItemProperties } from "./helpers.mjs";
|
|
3
4
|
import { MultilingualString } from "./parsers/multilingual.mjs";
|
|
5
|
+
import { defineLanguages } from "./parsers/languages.mjs";
|
|
4
6
|
import { fetchGallery } from "./fetchers/gallery.mjs";
|
|
5
7
|
import { fetchItemChildren } from "./fetchers/item-children.mjs";
|
|
6
8
|
import { fetchItemLinks } from "./fetchers/item-links.mjs";
|
|
7
9
|
import { fetchItemOcrData } from "./fetchers/item-ocr-data.mjs";
|
|
8
|
-
import {
|
|
10
|
+
import { fetchItem } from "./fetchers/item.mjs";
|
|
9
11
|
import { fetchSetItems } from "./fetchers/set/items.mjs";
|
|
10
12
|
import { fetchSetPropertyValues } from "./fetchers/set/property-values.mjs";
|
|
11
13
|
import { fetchWebsiteMetadata } from "./fetchers/website-metadata.mjs";
|
|
12
14
|
import { fetchWebsite } from "./fetchers/website.mjs";
|
|
13
|
-
export { DEFAULT_PAGE_SIZE, MultilingualString, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata,
|
|
15
|
+
export { DEFAULT_PAGE_SIZE, MultilingualString, defineLanguages, fetchGallery, fetchItem, fetchItemChildren, fetchItemLinks, fetchItemOcrData, fetchSetItems, fetchSetPropertyValues, fetchWebsite, fetchWebsiteMetadata, flattenItemProperties, getProperty, getPropertyValue, getPropertyValues, getUniqueProperties, getUniquePropertyVariableLabels, isPropertyMatchingFilter, normalizePropertyVariableLabel };
|
package/dist/ocr.d.mts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/ocr.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The name of the element wrapping an OCR layer inside an OCHRE document
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare const OCR_LAYER_ELEMENT_NAME = "ocr";
|
|
7
|
+
/**
|
|
8
|
+
* The attribute an OCR word element holds its word in
|
|
9
|
+
*
|
|
10
|
+
* The word is in the attribute rather than in the element's text content.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare const OCR_WORD_CONTENT_ATTRIBUTE = "CONTENT";
|
|
14
|
+
/**
|
|
15
|
+
* An XQuery sequence of every QName an OCR word element can carry
|
|
16
|
+
*
|
|
17
|
+
* Use with the `cts:element-*` query constructors, which need concrete QNames
|
|
18
|
+
* and cannot match on a case-folded local name the way {@link buildOcrWordPath}
|
|
19
|
+
* does. This has to stay in agreement with that path: a word element the
|
|
20
|
+
* narrowing misses is a document the search silently drops.
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export declare const OCR_WORD_QNAMES: string;
|
|
24
|
+
/**
|
|
25
|
+
* Build an XQuery path selecting every OCR word element beneath a node
|
|
26
|
+
*
|
|
27
|
+
* Matches the layer and the word elements on a case-folded `local-name()`
|
|
28
|
+
* rather than a name test, because a name test silently matches nothing when
|
|
29
|
+
* OCHRE varies the casing or serves the elements in a namespace. Word elements
|
|
30
|
+
* are selected at any depth, because the hierarchy between the layer and its
|
|
31
|
+
* words is irregular and is not parsed.
|
|
32
|
+
* @param rootExpression - The XQuery expression to select from
|
|
33
|
+
* @returns The XQuery path
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildOcrWordPath(rootExpression: string): string;
|
|
37
|
+
//#endregion
|
package/dist/ocr.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { stringLiteral } from "./xquery.mjs";
|
|
2
|
+
//#region src/ocr.ts
|
|
3
|
+
const ALTO_NAMESPACE = "http://www.loc.gov/standards/alto/ns-v2#";
|
|
4
|
+
/**
|
|
5
|
+
* The local names OCHRE serves OCR word elements under
|
|
6
|
+
*
|
|
7
|
+
* OCHRE varies the casing, and serves the elements both in the ALTO namespace
|
|
8
|
+
* and in no namespace at all. Every selector over the layer has to accept all
|
|
9
|
+
* of them: an `xs:QName("String")` narrowing matches 2 of the 18,446 documents
|
|
10
|
+
* carrying an OCR layer, while the ALTO-namespaced `String` matches 14,650.
|
|
11
|
+
*/
|
|
12
|
+
const OCR_WORD_LOCAL_NAMES = ["String", "string"];
|
|
13
|
+
const OCR_WORD_CASE_FOLDED_LOCAL_NAME = "string";
|
|
14
|
+
/**
|
|
15
|
+
* The name of the element wrapping an OCR layer inside an OCHRE document
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
const OCR_LAYER_ELEMENT_NAME = "ocr";
|
|
19
|
+
/**
|
|
20
|
+
* The attribute an OCR word element holds its word in
|
|
21
|
+
*
|
|
22
|
+
* The word is in the attribute rather than in the element's text content.
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
const OCR_WORD_CONTENT_ATTRIBUTE = "CONTENT";
|
|
26
|
+
/**
|
|
27
|
+
* An XQuery sequence of every QName an OCR word element can carry
|
|
28
|
+
*
|
|
29
|
+
* Use with the `cts:element-*` query constructors, which need concrete QNames
|
|
30
|
+
* and cannot match on a case-folded local name the way {@link buildOcrWordPath}
|
|
31
|
+
* does. This has to stay in agreement with that path: a word element the
|
|
32
|
+
* narrowing misses is a document the search silently drops.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
const OCR_WORD_QNAMES = `(${[...OCR_WORD_LOCAL_NAMES.map((localName) => `fn:QName(${stringLiteral(ALTO_NAMESPACE)}, ${stringLiteral(localName)})`), ...OCR_WORD_LOCAL_NAMES.map((localName) => `xs:QName(${stringLiteral(localName)})`)].join(", ")})`;
|
|
36
|
+
/**
|
|
37
|
+
* Build an XQuery path selecting every OCR word element beneath a node
|
|
38
|
+
*
|
|
39
|
+
* Matches the layer and the word elements on a case-folded `local-name()`
|
|
40
|
+
* rather than a name test, because a name test silently matches nothing when
|
|
41
|
+
* OCHRE varies the casing or serves the elements in a namespace. Word elements
|
|
42
|
+
* are selected at any depth, because the hierarchy between the layer and its
|
|
43
|
+
* words is irregular and is not parsed.
|
|
44
|
+
* @param rootExpression - The XQuery expression to select from
|
|
45
|
+
* @returns The XQuery path
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
function buildOcrWordPath(rootExpression) {
|
|
49
|
+
return `${rootExpression}//*[lower-case(local-name(.)) = ${stringLiteral("ocr")}]//*[lower-case(local-name(.)) = ${stringLiteral(OCR_WORD_CASE_FOLDED_LOCAL_NAME)}][@${OCR_WORD_CONTENT_ATTRIBUTE}]`;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { OCR_LAYER_ELEMENT_NAME, OCR_WORD_CONTENT_ATTRIBUTE, OCR_WORD_QNAMES, buildOcrWordPath };
|