Skip to content

Commit 05d186b

Browse files
committed
feat: add support for raw MDX block parsing and serialization in XML content handling
1 parent 45ee9e9 commit 05d186b

1 file changed

Lines changed: 83 additions & 4 deletions

File tree

src/parsers/string.ts

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ const ENTRY_PAGE_TOKEN = "entry-page";
6262
const VARIANT_TOKEN = "variant";
6363
const HEADING_LEVEL_TOKEN = "heading-level";
6464

65+
const RAW_MDX_BLOCK_DELIMITER = "```***```";
66+
const RAW_MDX_BLOCK_PLACEHOLDER_PREFIX = "\0raw-mdx-block:";
67+
const RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX = "\0";
68+
6569
const MDX_QUOTED_ATTRIBUTE_ESCAPE_REGEX = /[\n\r"]/;
6670
const MDX_RENDER_ELEMENTS = {
6771
bold: "strong",
@@ -593,7 +597,11 @@ function hasRichTextEnvelope(item: XMLRichTextItem): boolean {
593597
function parseXMLStringItem<V extends ReadonlyArray<string>>(
594598
item: XMLRichTextItem,
595599
contentItem: XMLContent["content"][number],
596-
options: { languages: V; rendering: TextRendering },
600+
options: {
601+
languages: V;
602+
rendering: TextRendering;
603+
rawMDXBlocks?: Array<string>;
604+
},
597605
): string {
598606
const hasTextContent = item.payload != null || item.string != null;
599607
if (!hasTextContent && getXMLRichTextLinks(item).length === 0) {
@@ -639,13 +647,75 @@ function parseXMLStringItem<V extends ReadonlyArray<string>>(
639647
function parseNestedStringItems<V extends ReadonlyArray<string>>(
640648
items: ReadonlyArray<XMLRichTextItem>,
641649
contentItem: XMLContent["content"][number],
642-
options: { languages: V; rendering: TextRendering },
650+
options: {
651+
languages: V;
652+
rendering: TextRendering;
653+
rawMDXBlocks?: Array<string>;
654+
},
643655
): string {
644656
let result = "";
645-
for (const item of items) {
657+
let rawMDXBlockStartIndex: number | null = null;
658+
for (const [index, item] of items.entries()) {
659+
if (
660+
item.payload === RAW_MDX_BLOCK_DELIMITER &&
661+
item.rend == null &&
662+
item.links == null &&
663+
item.properties == null &&
664+
item.annotation == null &&
665+
item.string == null
666+
) {
667+
if (rawMDXBlockStartIndex == null) {
668+
rawMDXBlockStartIndex = index;
669+
continue;
670+
}
671+
672+
let rawMDXBlock = "";
673+
for (
674+
let rawIndex = rawMDXBlockStartIndex + 1;
675+
rawIndex < index;
676+
rawIndex += 1
677+
) {
678+
const rawItem = items[rawIndex];
679+
if (rawItem != null) {
680+
rawMDXBlock += parseXMLStringItem(rawItem, contentItem, {
681+
languages: options.languages,
682+
rendering: "plain",
683+
});
684+
}
685+
}
686+
687+
if (item.whitespace?.split(" ").includes("newline") === true) {
688+
rawMDXBlock += "\n";
689+
}
690+
691+
if (options.rendering === "rich" && options.rawMDXBlocks != null) {
692+
const placeholder = `${RAW_MDX_BLOCK_PLACEHOLDER_PREFIX}${options.rawMDXBlocks.length}${RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX}`;
693+
options.rawMDXBlocks.push(rawMDXBlock);
694+
result += placeholder;
695+
} else {
696+
result += rawMDXBlock;
697+
}
698+
699+
rawMDXBlockStartIndex = null;
700+
continue;
701+
}
702+
703+
if (rawMDXBlockStartIndex != null) {
704+
continue;
705+
}
706+
646707
result += parseXMLStringItem(item, contentItem, options);
647708
}
648709

710+
if (rawMDXBlockStartIndex != null) {
711+
for (let index = rawMDXBlockStartIndex; index < items.length; index += 1) {
712+
const item = items[index];
713+
if (item != null) {
714+
result += parseXMLStringItem(item, contentItem, options);
715+
}
716+
}
717+
}
718+
649719
return result;
650720
}
651721

@@ -951,17 +1021,26 @@ function parseXMLContentItem<V extends ReadonlyArray<string>>(
9511021
contentItem: XMLContent["content"][number],
9521022
options: { languages: V },
9531023
): MultilingualStringText {
1024+
const rawMDXBlocks: Array<string> = [];
9541025
const richText = parseNestedStringItems(contentItem.string, contentItem, {
9551026
...options,
9561027
rendering: "rich",
1028+
rawMDXBlocks,
9571029
});
1030+
let serializedRichText = serializeMDXContent(richText);
1031+
for (const [index, rawMDXBlock] of rawMDXBlocks.entries()) {
1032+
serializedRichText = serializedRichText.replaceAll(
1033+
`${RAW_MDX_BLOCK_PLACEHOLDER_PREFIX}${index}${RAW_MDX_BLOCK_PLACEHOLDER_SUFFIX}`,
1034+
rawMDXBlock,
1035+
);
1036+
}
9581037

9591038
return {
9601039
text: parseNestedStringItems(contentItem.string, contentItem, {
9611040
...options,
9621041
rendering: "plain",
9631042
}),
964-
richText: serializeMDXContent(richText),
1043+
richText: serializedRichText,
9651044
};
9661045
}
9671046

0 commit comments

Comments
 (0)