ochre-sdk 1.0.40 → 1.0.41

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.
@@ -16,8 +16,10 @@ const RAW_MDX_BLOCK_DELIMITER = "``md``";
16
16
  const RAW_MDX_BLOCK_PLACEHOLDER_PREFIX = "\0raw-mdx-block:";
17
17
  const RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX = "\0";
18
18
  const RICH_LINE_BREAK = "<br />\n";
19
- const RICH_PARAGRAPH_BREAK = "\n\n";
20
19
  const MDX_QUOTED_ATTRIBUTE_ESCAPE_REGEX = /[\n\r"]/;
20
+ const MDX_NEWLINE_RUN_REGEX = /\n{3,}/g;
21
+ const MDX_SIMPLE_INLINE_TAG_REGEX = /<\/?(?:em|strong|u)>/g;
22
+ const MDX_MARKDOWN_LIST_LINE_REGEX = /^\s*(?:[*+-]|\d+[).])\s+/;
21
23
  const MDX_RENDER_ELEMENTS = {
22
24
  bold: "strong",
23
25
  italic: "em",
@@ -26,6 +28,47 @@ const MDX_RENDER_ELEMENTS = {
26
28
  function hasNewlineWhitespace(value) {
27
29
  return value?.split(" ").includes("newline") === true;
28
30
  }
31
+ function hasNoRichTextPayload(item) {
32
+ return (item.payload == null || item.payload === "") && item.rend == null && item.links == null && item.properties == null && item.annotation == null && item.string == null;
33
+ }
34
+ function isRawMDXBlockDelimiter(item, index) {
35
+ return item.payload === RAW_MDX_BLOCK_DELIMITER && (index === 0 || hasNewlineWhitespace(item.whitespace)) && item.rend == null && item.links == null && item.properties == null && item.annotation == null && item.string == null;
36
+ }
37
+ function normalizeMDXNewlineRuns(value) {
38
+ return value.replaceAll(MDX_NEWLINE_RUN_REGEX, "\n\n");
39
+ }
40
+ function isMarkdownListLine(value) {
41
+ return MDX_MARKDOWN_LIST_LINE_REGEX.test(value);
42
+ }
43
+ function isStandaloneFormattedLine(value) {
44
+ const trimmedValue = value.trim();
45
+ if (trimmedValue === "" || isMarkdownListLine(trimmedValue)) return false;
46
+ const unwrappedValue = trimmedValue.replaceAll(MDX_SIMPLE_INLINE_TAG_REGEX, "").trim();
47
+ return unwrappedValue !== trimmedValue && unwrappedValue !== "";
48
+ }
49
+ function pushBlankLine(lines) {
50
+ if (lines.length > 0 && lines.at(-1) !== "") lines.push("");
51
+ }
52
+ function getLastNonBlankLine(lines) {
53
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
54
+ const line = lines[index];
55
+ if (line != null && line.trim() !== "") return line;
56
+ }
57
+ return null;
58
+ }
59
+ function normalizeRawMDXBlock(value) {
60
+ const sourceLines = normalizeMDXNewlineRuns(value).split("\n");
61
+ const normalizedLines = [];
62
+ for (const [index, line] of sourceLines.entries()) {
63
+ const nextLine = sourceLines[index + 1];
64
+ const shouldStartOwnParagraph = isStandaloneFormattedLine(line);
65
+ const lastNonBlankLine = getLastNonBlankLine(normalizedLines);
66
+ if (shouldStartOwnParagraph || isMarkdownListLine(line) && (lastNonBlankLine == null || !isMarkdownListLine(lastNonBlankLine))) pushBlankLine(normalizedLines);
67
+ normalizedLines.push(line);
68
+ if (shouldStartOwnParagraph && nextLine != null && nextLine.trim() !== "" && !isMarkdownListLine(nextLine)) pushBlankLine(normalizedLines);
69
+ }
70
+ return normalizeMDXNewlineRuns(normalizedLines.join("\n"));
71
+ }
29
72
  function isXMLRichTextLink(value) {
30
73
  return typeof value === "object" && value != null;
31
74
  }
@@ -74,7 +117,7 @@ function applyMDXRenderElements(contentString, options) {
74
117
  function applyNewlineWhitespace(contentString, whitespace, rendering) {
75
118
  if (whitespace == null) return contentString;
76
119
  if (!hasNewlineWhitespace(whitespace)) return contentString;
77
- if (contentString === "" && rendering !== "plain") return RICH_PARAGRAPH_BREAK;
120
+ if (contentString === "") return rendering === "rich" ? RICH_LINE_BREAK : "\n";
78
121
  if (rendering === "rich") return contentString.trim() === "***" ? `${contentString}\n` : `${RICH_LINE_BREAK}${contentString}`;
79
122
  return `\n${contentString}`;
80
123
  }
@@ -263,7 +306,7 @@ function parseNestedStringItems(items, contentItem, options) {
263
306
  let result = "";
264
307
  let rawMDXBlockStartIndex = null;
265
308
  for (const [index, item] of items.entries()) {
266
- if (item.payload === RAW_MDX_BLOCK_DELIMITER && (index === 0 || hasNewlineWhitespace(item.whitespace)) && item.rend == null && item.links == null && item.properties == null && item.annotation == null && item.string == null) {
309
+ if (isRawMDXBlockDelimiter(item, index)) {
267
310
  if (rawMDXBlockStartIndex == null) {
268
311
  rawMDXBlockStartIndex = index;
269
312
  continue;
@@ -279,6 +322,7 @@ function parseNestedStringItems(items, contentItem, options) {
279
322
  });
280
323
  }
281
324
  if (rawMDXBlock !== "" && !rawMDXBlock.endsWith("\n") && hasNewlineWhitespace(item.whitespace)) rawMDXBlock += "\n";
325
+ rawMDXBlock = normalizeRawMDXBlock(rawMDXBlock);
282
326
  if (options.rendering === "rich" && options.rawMDXBlocks != null) {
283
327
  const placeholder = `${RAW_MDX_BLOCK_PLACEHOLDER_PREFIX}${options.rawMDXBlocks.length}${RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX}`;
284
328
  options.rawMDXBlocks.push(rawMDXBlock);
@@ -288,6 +332,11 @@ function parseNestedStringItems(items, contentItem, options) {
288
332
  continue;
289
333
  }
290
334
  if (rawMDXBlockStartIndex != null) continue;
335
+ const nextItem = items[index + 1];
336
+ if (options.rendering === "rich" && hasNoRichTextPayload(item) && hasNewlineWhitespace(item.whitespace) && nextItem != null && isRawMDXBlockDelimiter(nextItem, index + 1)) {
337
+ result += "\n";
338
+ continue;
339
+ }
291
340
  const parsedItem = parseXMLStringItem(item, contentItem, options);
292
341
  result += options.rendering === "rich" && result.endsWith("\n") && parsedItem.startsWith(RICH_LINE_BREAK) ? parsedItem.slice(6) : parsedItem;
293
342
  }
@@ -468,6 +517,7 @@ function parseXMLContentItem(contentItem, options) {
468
517
  rawMDXBlocks
469
518
  }));
470
519
  for (const [index, rawMDXBlock] of rawMDXBlocks.entries()) serializedRichText = serializedRichText.replaceAll(`${RAW_MDX_BLOCK_PLACEHOLDER_PREFIX}${index}${RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX}`, rawMDXBlock);
520
+ serializedRichText = normalizeMDXNewlineRuns(serializedRichText);
471
521
  return {
472
522
  text: parseNestedStringItems(contentItem.string, contentItem, {
473
523
  ...options,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.40",
3
+ "version": "1.0.41",
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",