ochre-sdk 1.0.15 → 1.0.17

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.
@@ -1,4 +1,5 @@
1
1
  //#region src/parsers/mdx.d.ts
2
2
  declare function serializeMDXText(value: string): string;
3
+ declare function serializeMDXContent(value: string): string;
3
4
  //#endregion
4
- export { serializeMDXText };
5
+ export { serializeMDXContent, serializeMDXText };
@@ -1,9 +1,22 @@
1
1
  //#region src/parsers/mdx.ts
2
2
  const MDX_LITERAL_EXPRESSION_REGEX = /[!#*<>[\]_`{|}~]/;
3
3
  const MDX_LITERAL_BLOCK_REGEX = /(?:^|\n)[\t ]*(?:import|export|[+>-]|\d+[).])(?:[\t ]|$)/;
4
+ const MDX_MULTIPLE_SPACES_REGEX = / {2,}/g;
5
+ const MDX_INLINE_BOUNDARY_PATTERN = "(?:Annotation|ExternalLink|InlineImage|InternalLink|TooltipSpan|em|strong|u)";
6
+ const MDX_INLINE_BOUNDARY_SPACES_REGEX = new RegExp(String.raw`(\}|<\/${MDX_INLINE_BOUNDARY_PATTERN}>|\/>)([\t ]+)(?=\{|<\/?${MDX_INLINE_BOUNDARY_PATTERN}\b)`, "g");
7
+ const MDX_INLINE_BOUNDARY_REGEX = new RegExp(String.raw`(?:\}[\t ]*|<\/${MDX_INLINE_BOUNDARY_PATTERN}>|\/>)(?=\{|<\/?${MDX_INLINE_BOUNDARY_PATTERN}\b)`);
8
+ function preserveMultipleSpaces(value) {
9
+ return value.replaceAll(MDX_MULTIPLE_SPACES_REGEX, (spaces) => `${spaces.slice(0, 1)}${"\xA0".repeat(spaces.length - 1)}`);
10
+ }
4
11
  function serializeMDXText(value) {
5
- if (value === "" || !MDX_LITERAL_EXPRESSION_REGEX.test(value) && !MDX_LITERAL_BLOCK_REGEX.test(value)) return value;
6
- return `{${JSON.stringify(value)}}`;
12
+ const displaySafeValue = preserveMultipleSpaces(value);
13
+ if (displaySafeValue === "" || !(displaySafeValue !== value) && !MDX_LITERAL_EXPRESSION_REGEX.test(displaySafeValue) && !MDX_LITERAL_BLOCK_REGEX.test(displaySafeValue)) return displaySafeValue;
14
+ return `{${JSON.stringify(displaySafeValue)}}`;
15
+ }
16
+ function serializeMDXContent(value) {
17
+ const content = value.replaceAll(MDX_INLINE_BOUNDARY_SPACES_REGEX, (_, previousBoundary, spaces) => `${previousBoundary}{${JSON.stringify(preserveMultipleSpaces(spaces))}}`);
18
+ if (!MDX_INLINE_BOUNDARY_REGEX.test(content)) return content;
19
+ return content.endsWith("\n") ? `<>\n${content}</>` : `<>\n${content}\n</>`;
7
20
  }
8
21
  //#endregion
9
- export { serializeMDXText };
22
+ export { serializeMDXContent, serializeMDXText };
@@ -1,5 +1,5 @@
1
1
  import { TEXT_ANNOTATION_UUID } from "../constants.mjs";
2
- import { serializeMDXText } from "./mdx.mjs";
2
+ import { serializeMDXContent, serializeMDXText } from "./mdx.mjs";
3
3
  import { MultilingualString } from "./multilingual.mjs";
4
4
  import { renderOptionsSchema } from "../schemas.mjs";
5
5
  import { getXMLSourceIndex } from "../xml/metadata.mjs";
@@ -63,6 +63,12 @@ function applyMDXRenderElements(contentString, options) {
63
63
  }
64
64
  return result;
65
65
  }
66
+ function applyNewlineWhitespace(contentString, whitespace, rendering) {
67
+ if (whitespace == null) return contentString;
68
+ if (!whitespace.split(" ").includes("newline")) return contentString;
69
+ if (rendering === "rich") return contentString.trim() === "***" ? `${contentString}\n` : `<br />\n${contentString}`;
70
+ return `\n${contentString}`;
71
+ }
66
72
  /**
67
73
  * Parses XML string into a formatted string with rendering options
68
74
  *
@@ -76,7 +82,7 @@ function applyMDXRenderElements(contentString, options) {
76
82
  function parseXMLStringVariant(string, options) {
77
83
  let returnString = parseXMLStringPayload(string, options);
78
84
  if (string.rend != null) returnString = parseRenderOptions(returnString, string.rend, options.rendering);
79
- return returnString;
85
+ return applyNewlineWhitespace(returnString, string.whitespace, options.rendering);
80
86
  }
81
87
  function parseXMLStringPayload(string, options) {
82
88
  const payload = string.payload ?? "";
@@ -232,17 +238,17 @@ function hasRichTextEnvelope(item) {
232
238
  return item.properties?.property[0] != null || getXMLRichTextLinks(item).length > 0;
233
239
  }
234
240
  function parseXMLStringItem(item, contentItem, options) {
235
- if (!(item.payload != null || item.string != null) && getXMLRichTextLinks(item).length === 0) return "";
241
+ if (!(item.payload != null || item.string != null) && getXMLRichTextLinks(item).length === 0) return applyNewlineWhitespace("", item.whitespace, options.rendering);
236
242
  if (hasRichTextEnvelope(item)) {
237
243
  let linkString = item.payload != null ? parseXMLStringPayload(item, { rendering: options.rendering }) : parseNestedStringItems(item.string ?? [], contentItem, { ...options });
238
244
  if (item.rend != null) linkString = parseRenderOptions(linkString, item.rend, options.rendering);
239
- if (options.rendering === "plain") return linkString;
245
+ if (options.rendering === "plain") return applyNewlineWhitespace(linkString, item.whitespace, options.rendering);
240
246
  return renderRichTextItem(item, linkString, contentItem, options);
241
247
  }
242
248
  if (item.payload != null) return parseXMLStringVariant(item, { rendering: options.rendering });
243
249
  let result = parseNestedStringItems(item.string ?? [], contentItem, options);
244
250
  if (item.rend != null) result = parseRenderOptions(result, item.rend, options.rendering);
245
- return result;
251
+ return applyNewlineWhitespace(result, item.whitespace, options.rendering);
246
252
  }
247
253
  function parseNestedStringItems(items, contentItem, options) {
248
254
  let result = "";
@@ -292,7 +298,7 @@ function renderRichTextItem(item, linkString, contentItem, options) {
292
298
  const { languages, rendering } = options;
293
299
  const annotationMetadata = extractAnnotationMetadata(item, { language: contentItem.lang });
294
300
  const links = getXMLRichTextLinks(item);
295
- if (links.length === 0) return wrapWithTextStyling(linkString, annotationMetadata.textStyling);
301
+ if (links.length === 0) return applyNewlineWhitespace(wrapWithTextStyling(linkString, annotationMetadata.textStyling), item.whitespace, rendering);
296
302
  let result = "";
297
303
  for (const link of links) {
298
304
  const linkContent = link.identification != null ? "content" in link.identification.label ? parseXMLContent(link.identification.label, { languages }) : MultilingualString.create(contentItem.lang, parseXMLString(link.identification.label), languages) : MultilingualString.create(contentItem.lang, "", languages);
@@ -379,7 +385,7 @@ function renderRichTextItem(item, linkString, contentItem, options) {
379
385
  result += component;
380
386
  }
381
387
  }
382
- return result;
388
+ return applyNewlineWhitespace(result, item.whitespace, rendering);
383
389
  }
384
390
  /**
385
391
  * Parses rich text content into a formatted string with links and annotations
@@ -413,15 +419,16 @@ function parseXMLContent(item, options) {
413
419
  return MultilingualString.empty(languages, { aliases });
414
420
  }
415
421
  function parseXMLContentItem(contentItem, options) {
422
+ const richText = parseNestedStringItems(contentItem.string, contentItem, {
423
+ ...options,
424
+ rendering: "rich"
425
+ });
416
426
  return {
417
427
  text: parseNestedStringItems(contentItem.string, contentItem, {
418
428
  ...options,
419
429
  rendering: "plain"
420
430
  }),
421
- richText: parseNestedStringItems(contentItem.string, contentItem, {
422
- ...options,
423
- rendering: "rich"
424
- })
431
+ richText: serializeMDXContent(richText)
425
432
  };
426
433
  }
427
434
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Node.js library for working with OCHRE (Online Cultural and Historical Research Environment) data",