@stll/folio-core 0.15.4 → 0.15.5

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.
@@ -4,7 +4,7 @@ import { padDecimal } from "../../docx/numberingParser.js";
4
4
  import { setParagraphFrame } from "../../layout-engine/paragraphFrame.js";
5
5
  import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
6
6
  import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
7
- import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
7
+ import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectSymbolAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
8
8
  import { autospacingMatchesBase } from "../../prosemirror/autospacingBase.js";
9
9
  import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
10
10
  import { directionIsRtl } from "../../prosemirror/paragraphDirection.js";
@@ -13,6 +13,7 @@ import { NUMBER_FORMAT_VALUES } from "../../types/documentEnumValues.js";
13
13
  import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
14
14
  import { resolveThemeFont } from "../../utils/fontResolver.js";
15
15
  import { resolveShadingFill } from "../../utils/formatToStyle.js";
16
+ import { decodeOoxmlSymbolCharacter } from "../../utils/ooxmlSymbol.js";
16
17
  import { AUTO_PARAGRAPH_SPACING_PX, halfPointsToPixels, halfPointsToPoints, pointsToPixels } from "../../utils/units.js";
17
18
  import { getColumns } from "../sectionColumns.js";
18
19
  import { groupParagraphFrames } from "./paragraphFrames.js";
@@ -538,6 +539,22 @@ function paragraphToRuns(node, startPos, _options) {
538
539
  runs.push(run);
539
540
  return;
540
541
  }
542
+ if (child.type.name === "symbol") {
543
+ const attrs = expectSymbolAttrs(child);
544
+ const text = decodeOoxmlSymbolCharacter(attrs.char);
545
+ if (text === null) return;
546
+ const formatting = extractRunFormatting(child.marks, theme);
547
+ if (inTocParagraph) stripTocHyperlinkStyle(formatting);
548
+ runs.push({
549
+ kind: "text",
550
+ text,
551
+ ...mergeRunFormatting(paraDefaults, formatting),
552
+ fontFamily: attrs.font,
553
+ pmStart: childPos,
554
+ pmEnd: childPos + child.nodeSize
555
+ });
556
+ return;
557
+ }
541
558
  if (child.type.name === "hardBreak") {
542
559
  runs.push({
543
560
  kind: "lineBreak",
@@ -1,3 +1,4 @@
1
+ import { decodeOoxmlSymbolCharacter } from "../utils/ooxmlSymbol.js";
1
2
  import { wrapComment, wrapDeletion, wrapInsertion, wrapMoveFrom, wrapMoveTo } from "./annotations.js";
2
3
  import { escapeAltText, escapeInline, escapeLinkUrl } from "./escape.js";
3
4
  import { registerImage } from "./images.js";
@@ -68,7 +69,7 @@ function renderRunContent(ctx, pkg, content, paraId) {
68
69
  else out += " \n";
69
70
  break;
70
71
  case "symbol":
71
- out += escapeInline(item.char);
72
+ out += escapeInline(decodeOoxmlSymbolCharacter(item.char) ?? item.char);
72
73
  break;
73
74
  case "softHyphen": break;
74
75
  case "noBreakHyphen":
@@ -1,3 +1,4 @@
1
+ import { decodeOoxmlSymbolCharacter } from "../utils/ooxmlSymbol.js";
1
2
  import { escapeTableCell } from "./escape.js";
2
3
  import { registerImage } from "./images.js";
3
4
  import { pushWarning } from "./internals.js";
@@ -172,7 +173,7 @@ function renderHtmlRun(ctx, pkg, run, paraId) {
172
173
  text += "<br>";
173
174
  break;
174
175
  case "symbol":
175
- text += escapeHtml(item.char);
176
+ text += escapeHtml(decodeOoxmlSymbolCharacter(item.char) ?? item.char);
176
177
  break;
177
178
  case "noBreakHyphen":
178
179
  text += "&#8209;";
@@ -1,5 +1,5 @@
1
1
  import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, LanguageAttrs, RunFormattingOverrideAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "../schema/marks.js";
2
- import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "../schema/nodes.js";
2
+ import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "../schema/nodes.js";
3
3
  import "../schema/index.js";
4
4
  import { Mark, Node } from "prosemirror-model";
5
5
  //#region src/prosemirror/attrs/index.d.ts
@@ -20,6 +20,8 @@ declare const readHardBreakAttrs: (node: Node) => ReadProseMirrorAttrsResult<Har
20
20
  declare const expectHardBreakAttrs: (node: Node) => HardBreakAttrs;
21
21
  declare const readTabAttrs: (node: Node) => ReadProseMirrorAttrsResult<TabAttrs>;
22
22
  declare const expectTabAttrs: (node: Node) => TabAttrs;
23
+ declare const readSymbolAttrs: (node: Node) => ReadProseMirrorAttrsResult<SymbolAttrs>;
24
+ declare const expectSymbolAttrs: (node: Node) => SymbolAttrs;
23
25
  declare const readTableAttrs: (node: Node) => ReadProseMirrorAttrsResult<TableAttrs>;
24
26
  declare const expectTableAttrs: (node: Node) => TableAttrs;
25
27
  declare const readTableRowAttrs: (node: Node) => ReadProseMirrorAttrsResult<TableRowAttrs>;
@@ -83,4 +85,4 @@ declare const mergeTableAttrs: (node: Node, patch: NodeAttrPatch<TableAttrs>) =>
83
85
  declare const mergeTableRowAttrs: (node: Node, patch: NodeAttrPatch<TableRowAttrs>) => TableRowAttrs;
84
86
  declare const mergeTableCellAttrs: (node: Node, patch: NodeAttrPatch<TableCellAttrs>) => TableCellAttrs;
85
87
  //#endregion
86
- export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
88
+ export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
@@ -2,6 +2,7 @@ import { FIELD_TYPE_VALUES, HIGHLIGHT_COLOR_VALUES, IMAGE_HORIZONTAL_ALIGNMENT_V
2
2
  import { isParagraphDirection } from "../paragraphDirection.js";
3
3
  import { TRACKED_CHANGE_PROVENANCE_VALUES } from "../schema/marks.js";
4
4
  import { panic } from "better-result";
5
+ import { isOoxmlSymbolCharacter } from "@stll/docx-core/model";
5
6
  //#region src/prosemirror/attrs/index.ts
6
7
  const SECTION_BREAK_TYPES = [
7
8
  "nextPage",
@@ -120,6 +121,7 @@ const SECTION_VERTICAL_ALIGNMENTS = [
120
121
  const paragraphAttrsCache = /* @__PURE__ */ new WeakMap();
121
122
  const hardBreakAttrsCache = /* @__PURE__ */ new WeakMap();
122
123
  const tabAttrsCache = /* @__PURE__ */ new WeakMap();
124
+ const symbolAttrsCache = /* @__PURE__ */ new WeakMap();
123
125
  const tableAttrsCache = /* @__PURE__ */ new WeakMap();
124
126
  const tableRowAttrsCache = /* @__PURE__ */ new WeakMap();
125
127
  const tableCellAttrsCache = /* @__PURE__ */ new WeakMap();
@@ -248,6 +250,23 @@ const readTabAttrs = (node) => {
248
250
  return attrsResult(attrs, issues);
249
251
  };
250
252
  const expectTabAttrs = (node) => expectCachedNodeAttrs(node, tabAttrsCache, readTabAttrs, "tab attrs");
253
+ const readSymbolAttrs = (node) => {
254
+ const attrs = attrsRecord(node.attrs);
255
+ const issues = [];
256
+ expectNodeType(node, "symbol", issues);
257
+ requiredString(attrs, "font", "symbol.attrs.font", issues);
258
+ requiredString(attrs, "char", "symbol.attrs.char", issues);
259
+ if (typeof attrs["font"] === "string" && attrs["font"].trim() === "") issues.push({
260
+ path: "symbol.attrs.font",
261
+ message: "Expected a non-empty font name."
262
+ });
263
+ if (typeof attrs["char"] === "string" && !isOoxmlSymbolCharacter(attrs["char"])) issues.push({
264
+ path: "symbol.attrs.char",
265
+ message: "Expected exactly four hexadecimal digits."
266
+ });
267
+ return attrsResult(attrs, issues);
268
+ };
269
+ const expectSymbolAttrs = (node) => expectCachedNodeAttrs(node, symbolAttrsCache, readSymbolAttrs, "symbol attrs");
251
270
  const readTableAttrs = (node) => {
252
271
  const attrs = attrsRecord(node.attrs);
253
272
  const issues = [];
@@ -1426,4 +1445,4 @@ const optionalEmptyHyperlinkArray = (value, issues) => {
1426
1445
  }
1427
1446
  };
1428
1447
  //#endregion
1429
- export { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
1448
+ export { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
@@ -2,7 +2,7 @@ import { numPrEqual } from "../../docx/numberingParser.js";
2
2
  import { ShapeOutlineStyleSchema, narrowEnum } from "../../docx/parserEnums.js";
3
3
  import { OUTLINE_STYLE_CSS_ALIASES } from "../../types/documentEnumValues.js";
4
4
  import { pixelsToEmu } from "../../utils/units.js";
5
- import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
5
+ import { expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunPropertyChangeMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectSymbolAttrs, expectTabAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../attrs/index.js";
6
6
  import { autospacingMatchesBase, hasAutospacingBaseSide } from "../autospacingBase.js";
7
7
  import { directionToBidi } from "../paragraphDirection.js";
8
8
  import { RUN_FORMATTING_MARK_NAMES } from "../runFormattingMarkNames.js";
@@ -795,6 +795,9 @@ function extractParagraphContent(paragraph, _documentCounts, emptyHyperlinks, te
795
795
  currentRun = createRunFromText(node.text || "", node.marks);
796
796
  currentMarksKey = marksKey;
797
797
  }
798
+ } else if (node.type.name === "symbol") {
799
+ flushCurrentInline();
800
+ content.push(createSymbolRun(node, node.marks));
798
801
  } else if (node.type.name === "hardBreak") {
799
802
  flushCurrentInline();
800
803
  content.push(createBreakRun(readHardBreakType(node)));
@@ -867,6 +870,7 @@ function createTrackedChangeRun(node, marks) {
867
870
  restoreRunPropertyChanges(run, marks);
868
871
  return run;
869
872
  }
873
+ if (node.type.name === "symbol") return createSymbolRun(node, marks);
870
874
  if (node.type.name === "hardBreak") return createBreakRun(readHardBreakType(node));
871
875
  if (node.type.name === "image") return createImageRun(node);
872
876
  if (node.type.name === "shape") return createShapeRun(node);
@@ -974,6 +978,10 @@ function addNodeToHyperlink(hyperlink, node) {
974
978
  hyperlink.children.push(run);
975
979
  return;
976
980
  }
981
+ if (node.type.name === "symbol") {
982
+ hyperlink.children.push(createSymbolRun(node, nonLinkMarks));
983
+ return;
984
+ }
977
985
  if (node.type.name === "hardBreak") {
978
986
  hyperlink.children.push(createBreakRun(readHardBreakType(node), nonLinkMarks));
979
987
  return;
@@ -1026,6 +1034,21 @@ function createRunFromText(text, marks) {
1026
1034
  restoreRunPropertyChanges(run, marks);
1027
1035
  return run;
1028
1036
  }
1037
+ function createSymbolRun(node, marks) {
1038
+ const { font, char } = expectSymbolAttrs(node);
1039
+ const run = {
1040
+ type: "run",
1041
+ content: [{
1042
+ type: "symbol",
1043
+ font,
1044
+ char
1045
+ }]
1046
+ };
1047
+ const formatting = getRunFormattingFromMarks(marks);
1048
+ if (formatting) run.formatting = formatting;
1049
+ restoreRunPropertyChanges(run, marks);
1050
+ return run;
1051
+ }
1029
1052
  function restoreRunPropertyChanges(run, marks) {
1030
1053
  const changeMark = marks.find((mark) => mark.type.name === "runPropertyChange");
1031
1054
  if (!changeMark) return;
@@ -268,7 +268,7 @@ function convertTrackedChange(change, markType, getInheritedRunFormatting, style
268
268
  });
269
269
  }
270
270
  function canCarryTrackedRunMark(node, markType) {
271
- return node.isText || node.isInline && node.type.allowsMarkType(markType) && (node.type.name === "image" || node.type.name === "shape" || node.type.name === "hardBreak" || node.type.name === "tab" || node.type.name === "textBoxAnchor");
271
+ return node.isText || node.isInline && node.type.allowsMarkType(markType) && (node.type.name === "image" || node.type.name === "shape" || node.type.name === "hardBreak" || node.type.name === "tab" || node.type.name === "symbol" || node.type.name === "textBoxAnchor");
272
272
  }
273
273
  /**
274
274
  * Convert ParagraphFormatting to ProseMirror paragraph attrs
@@ -1078,7 +1078,10 @@ function convertRunContent(content, marks, formatting, textBoxAnchors) {
1078
1078
  case "instrText": return [];
1079
1079
  case "noBreakHyphen": return [schema.text("‑", marks)];
1080
1080
  case "softHyphen": return [schema.text("­", marks)];
1081
- case "symbol": return content.char ? [schema.text(content.char, marks)] : [];
1081
+ case "symbol": return [schema.node("symbol", {
1082
+ font: content.font,
1083
+ char: content.char
1084
+ }).mark(marks)];
1082
1085
  }
1083
1086
  }
1084
1087
  function withHyperlinkBoundaryMarks(node, marks) {
@@ -52,6 +52,7 @@ import { PageBreakExtension } from "./nodes/PageBreakExtension.js";
52
52
  import { RenderedPageBreakExtension } from "./nodes/RenderedPageBreakExtension.js";
53
53
  import { SdtExtension } from "./nodes/SdtExtension.js";
54
54
  import { ShapeExtension } from "./nodes/ShapeExtension.js";
55
+ import { SymbolExtension } from "./nodes/SymbolExtension.js";
55
56
  import { TabExtension } from "./nodes/TabExtension.js";
56
57
  import { createTableExtensions } from "./nodes/TableExtension.js";
57
58
  import { TextBoxAnchorExtension } from "./nodes/TextBoxAnchorExtension.js";
@@ -106,6 +107,7 @@ function createStarterKit(options = {}) {
106
107
  add("runPropertyChange", RunPropertyChangeExtension());
107
108
  add("hardBreak", HardBreakExtension());
108
109
  add("tab", TabExtension());
110
+ add("symbol", SymbolExtension());
109
111
  add("image", ImageExtension());
110
112
  add("textBox", TextBoxExtension());
111
113
  add("textBoxAnchor", TextBoxAnchorExtension());
@@ -0,0 +1,5 @@
1
+ import { NodeExtension } from "../types.js";
2
+ //#region src/prosemirror/extensions/nodes/SymbolExtension.d.ts
3
+ declare const SymbolExtension: (options?: Partial<Record<string, unknown>> | undefined) => NodeExtension;
4
+ //#endregion
5
+ export { SymbolExtension };
@@ -0,0 +1,49 @@
1
+ import { decodeOoxmlSymbolCharacter } from "../../../utils/ooxmlSymbol.js";
2
+ import { expectSymbolAttrs } from "../../attrs/index.js";
3
+ import { createNodeExtension } from "../create.js";
4
+ import { isOoxmlSymbolCharacter } from "@stll/docx-core/model";
5
+ //#region src/prosemirror/extensions/nodes/SymbolExtension.ts
6
+ const escapeCssString = (value) => value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"").replaceAll("\n", "\\a ").replaceAll("\r", "\\d ").replaceAll("\f", "\\c ");
7
+ const SymbolExtension = createNodeExtension({
8
+ name: "symbol",
9
+ schemaNodeName: "symbol",
10
+ nodeSpec: {
11
+ inline: true,
12
+ group: "inline",
13
+ atom: true,
14
+ marks: "_",
15
+ attrs: {
16
+ font: {},
17
+ char: {}
18
+ },
19
+ selectable: false,
20
+ parseDOM: [{
21
+ tag: "span[data-docx-symbol-char][data-docx-symbol-font]",
22
+ getAttrs(node) {
23
+ if (!(node instanceof HTMLElement)) return false;
24
+ const font = node.dataset["docxSymbolFont"];
25
+ const char = node.dataset["docxSymbolChar"];
26
+ if (!font || font.trim() === "" || !char || !isOoxmlSymbolCharacter(char)) return false;
27
+ return {
28
+ font,
29
+ char
30
+ };
31
+ }
32
+ }],
33
+ toDOM(node) {
34
+ const { font, char } = expectSymbolAttrs(node);
35
+ const decoded = decodeOoxmlSymbolCharacter(char);
36
+ return [
37
+ "span",
38
+ {
39
+ "data-docx-symbol-char": char,
40
+ "data-docx-symbol-font": font,
41
+ style: `font-family: "${escapeCssString(font)}";`
42
+ },
43
+ decoded ?? "�"
44
+ ];
45
+ }
46
+ }
47
+ });
48
+ //#endregion
49
+ export { SymbolExtension };
@@ -1,4 +1,6 @@
1
1
  import { findAllMatches } from "../utils/findReplace.js";
2
+ import { decodeOoxmlSymbolCharacter } from "../utils/ooxmlSymbol.js";
3
+ import { expectSymbolAttrs } from "./attrs/index.js";
2
4
  //#region src/prosemirror/findReplaceSelection.ts
3
5
  function resolveFindMatchRange(doc, match) {
4
6
  let resolved = null;
@@ -105,7 +107,7 @@ function resolveTextRangeInParagraph({ paragraph, paragraphPos, startOffset, end
105
107
  }
106
108
  function getSearchTextTokenLength(node) {
107
109
  if (node.isText) return node.text?.length ?? 0;
108
- if (node.type.name === "tab" || node.type.name === "hardBreak") return 1;
110
+ if (node.type.name === "tab" || node.type.name === "hardBreak" || node.type.name === "symbol") return 1;
109
111
  return 0;
110
112
  }
111
113
  function getSearchableParagraphText(paragraph) {
@@ -123,6 +125,10 @@ function getSearchableParagraphText(paragraph) {
123
125
  text += "\n";
124
126
  return false;
125
127
  }
128
+ if (node.type.name === "symbol") {
129
+ text += decodeOoxmlSymbolCharacter(expectSymbolAttrs(node).char) ?? "";
130
+ return false;
131
+ }
126
132
  return true;
127
133
  });
128
134
  return text;
@@ -1,6 +1,6 @@
1
1
  import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, LanguageAttrs, RunFormattingOverrideAttrs, RunPropertyChangeMarkAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "./marks.js";
2
2
  import { ExtensionManager } from "../extensions/ExtensionManager.js";
3
- import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "./nodes.js";
3
+ import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "./nodes.js";
4
4
  //#region src/prosemirror/schema/index.d.ts
5
5
  declare const singletonManager: ExtensionManager;
6
6
  declare const schema: import("prosemirror-model").Schema<any, any>;
@@ -11,4 +11,4 @@ type DocxSchema = typeof schema;
11
11
  type DocxNode = ReturnType<typeof schema.node>;
12
12
  type DocxMark = ReturnType<typeof schema.mark>;
13
13
  //#endregion
14
- export { type BlockSdtAttrs, type CharacterSpacingAttrs, type CharacterStyleAttrs, type CommentAttrs, DocxMark, DocxNode, DocxSchema, type EmphasisMarkAttrs, type FieldAttrs, type FontFamilyAttrs, type FontSizeAttrs, type FootnoteRefAttrs, type HardBreakAttrs, type HighlightAttrs, type HyperlinkAttrs, type ImageAttrs, type ImagePositionAttrs, type LanguageAttrs, type MathAttrs, type ParagraphAttrs, type RunFormattingOverrideAttrs, type RunPropertyChangeMarkAttrs, type RunShadingAttrs, type SdtAttrs, type ShapeAttrs, type StrikeAttrs, type TabAttrs, type TableAttrs, type TableCellAttrs, type TableRowAttrs, type TextBoxAttrs, type TextColorAttrs, type TextEffectAttrs, type TrackedChangeMarkAttrs, type UnderlineAttrs, schema, singletonManager };
14
+ export { type BlockSdtAttrs, type CharacterSpacingAttrs, type CharacterStyleAttrs, type CommentAttrs, DocxMark, DocxNode, DocxSchema, type EmphasisMarkAttrs, type FieldAttrs, type FontFamilyAttrs, type FontSizeAttrs, type FootnoteRefAttrs, type HardBreakAttrs, type HighlightAttrs, type HyperlinkAttrs, type ImageAttrs, type ImagePositionAttrs, type LanguageAttrs, type MathAttrs, type ParagraphAttrs, type RunFormattingOverrideAttrs, type RunPropertyChangeMarkAttrs, type RunShadingAttrs, type SdtAttrs, type ShapeAttrs, type StrikeAttrs, type SymbolAttrs, type TabAttrs, type TableAttrs, type TableCellAttrs, type TableRowAttrs, type TextBoxAttrs, type TextColorAttrs, type TextEffectAttrs, type TrackedChangeMarkAttrs, type UnderlineAttrs, schema, singletonManager };
@@ -11,6 +11,10 @@ type HardBreakAttrs = {
11
11
  type TabAttrs = {
12
12
  positional?: document_d_exports.PositionalTab;
13
13
  };
14
+ type SymbolAttrs = {
15
+ font: string;
16
+ char: string;
17
+ };
14
18
  /**
15
19
  * Paragraph node attributes - maps to ParagraphFormatting
16
20
  */
@@ -684,4 +688,4 @@ type TableCellAttrs = {
684
688
  _docxVMergeContinuationCells?: document_d_exports.TableCell[];
685
689
  };
686
690
  //#endregion
687
- export { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs };
691
+ export { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs };
@@ -1,4 +1,4 @@
1
- import { readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs } from "./attrs/index.js";
1
+ import { readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunPropertyChangeMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readSymbolAttrs, readTabAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs } from "./attrs/index.js";
2
2
  import { readTextBoxAnchorAttrs } from "./textBoxAnchorAttrs.js";
3
3
  //#region src/prosemirror/validation.ts
4
4
  var ProseMirrorDocumentValidationError = class extends Error {
@@ -53,6 +53,9 @@ const validateNodeAttrs = (node, path, issues) => {
53
53
  case "tab":
54
54
  appendAttrIssues(path, readTabAttrs(node), issues);
55
55
  return;
56
+ case "symbol":
57
+ appendAttrIssues(path, readSymbolAttrs(node), issues);
58
+ return;
56
59
  case "hardBreak":
57
60
  appendAttrIssues(path, readHardBreakAttrs(node), issues);
58
61
  return;
@@ -0,0 +1,4 @@
1
+ //#region src/utils/ooxmlSymbol.d.ts
2
+ declare const decodeOoxmlSymbolCharacter: (value: string) => string | null;
3
+ //#endregion
4
+ export { decodeOoxmlSymbolCharacter };
@@ -0,0 +1,5 @@
1
+ import { isOoxmlSymbolCharacter } from "@stll/docx-core/model";
2
+ //#region src/utils/ooxmlSymbol.ts
3
+ const decodeOoxmlSymbolCharacter = (value) => isOoxmlSymbolCharacter(value) ? String.fromCodePoint(Number.parseInt(value, 16)) : null;
4
+ //#endregion
5
+ export { decodeOoxmlSymbolCharacter };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/folio-core",
3
- "version": "0.15.4",
3
+ "version": "0.15.5",
4
4
  "description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
5
5
  "keywords": [
6
6
  "document-model",
@@ -107,7 +107,7 @@
107
107
  "perf": "bun scripts/profile-editor.ts"
108
108
  },
109
109
  "dependencies": {
110
- "@stll/docx-core": "^0.7.0",
110
+ "@stll/docx-core": "^0.8.0",
111
111
  "@stll/docx-utils": "^0.1.0",
112
112
  "@stll/template-conditions": "^0.1.0",
113
113
  "better-result": "2.10.0",