@stll/folio-core 0.47.2 → 0.47.3

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.
@@ -128,8 +128,10 @@ function parseParagraphProperties(pPr, theme) {
128
128
  if (stated !== void 0) formatting.numPr = stated;
129
129
  const numberingChange = findChild(child, "w", "numberingChange");
130
130
  if (numberingChange) formatting.numberingChangeXml = captureVerbatimXml(numberingChange);
131
+ const numberingInsertion = findChild(child, "w", "ins");
132
+ if (numberingInsertion) formatting.numberingInsertionXml = captureVerbatimXml(numberingInsertion);
131
133
  const statedLevel = parseNumericAttribute(findChild(child, "w", "ilvl"), "w", "val");
132
- return stated !== void 0 || numberingChange !== null || statedLevel === -1;
134
+ return stated !== void 0 || numberingChange !== null || numberingInsertion !== null || statedLevel === -1;
133
135
  }),
134
136
  suppressLineNumbers: toggle("suppressLineNumbers", "suppressLineNumbers"),
135
137
  pBdr: once("pBdr", (child) => {
@@ -29,10 +29,10 @@ const RESERVED_PARAGRAPH_PROPERTY_CHILDREN = /* @__PURE__ */ new Set(["pPrChange
29
29
  /**
30
30
  * Revision records a captured `w:pPr` may not carry into a replay.
31
31
  *
32
- * `w:numberingChange` is not among them: the model holds it
33
- * (`ParagraphFormatting.numberingChangeXml`) and the serializer writes it
34
- * back, so both paths keep it. Refusing the capture used to force a rebuild
35
- * that could not write it, which turned a replay gate into a lost revision.
32
+ * The revision records inside `w:numPr` are not among them: the model holds
33
+ * `w:numberingChange` and `w:ins`, and the serializer writes both back, so both
34
+ * paths keep them. Refusing the capture used to force a rebuild that could not
35
+ * write the records, which turned a replay gate into a lost revision.
36
36
  */
37
37
  const RESERVED_PARAGRAPH_CAPTURE_CHILDREN = /* @__PURE__ */ new Set([
38
38
  ...RESERVED_PARAGRAPH_PROPERTY_CHILDREN,
@@ -1,7 +1,7 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
2
  import { ParagraphNumberingOverride } from "@stll/docx-core/model";
3
3
  //#region src/internal/paragraphFormattingSerialization.d.ts
4
- type ClassifiedParagraphFormattingField = "alignment" | "bidi" | "kinsoku" | "overflowPunctuation" | "spaceBefore" | "spaceAfter" | "lineSpacing" | "lineSpacingRule" | "snapToGrid" | "beforeAutospacing" | "afterAutospacing" | "spacingExplicit" | "spacingPreservedAttributes" | "indentLeft" | "indentRight" | "indentFirstLine" | "hangingIndent" | "indentPreservedAttributes" | "borders" | "shading" | "tabs" | "keepNext" | "keepLines" | "widowControl" | "pageBreakBefore" | "contextualSpacing" | "numPr" | "numPrFromStyle" | "numberingChangeXml" | "outlineLevel" | "styleId" | "frame" | "suppressLineNumbers" | "suppressAutoHyphens" | "runProperties" | "runInWithNext" | "preserved";
4
+ type ClassifiedParagraphFormattingField = "alignment" | "bidi" | "kinsoku" | "overflowPunctuation" | "spaceBefore" | "spaceAfter" | "lineSpacing" | "lineSpacingRule" | "snapToGrid" | "beforeAutospacing" | "afterAutospacing" | "spacingExplicit" | "spacingPreservedAttributes" | "indentLeft" | "indentRight" | "indentFirstLine" | "hangingIndent" | "indentPreservedAttributes" | "borders" | "shading" | "tabs" | "keepNext" | "keepLines" | "widowControl" | "pageBreakBefore" | "contextualSpacing" | "numPr" | "numPrFromStyle" | "numberingChangeXml" | "numberingInsertionXml" | "outlineLevel" | "styleId" | "frame" | "suppressLineNumbers" | "suppressAutoHyphens" | "runProperties" | "runInWithNext" | "preserved";
5
5
  type ExhaustiveParagraphFormatting = document_d_exports.ExhaustiveFields<document_d_exports.ParagraphFormatting, ClassifiedParagraphFormattingField>;
6
6
  /**
7
7
  * Whether resolved numbering still belongs to the paragraph's style tier.
@@ -72,32 +72,30 @@ const serializeIndentation = (formatting) => {
72
72
  const written = serializePreservedAttributes(attrs, formatting.indentPreservedAttributes);
73
73
  return written.length === 0 ? "" : `<w:ind ${written.join(" ")}/>`;
74
74
  };
75
- /**
76
- * `w:numPr`, with the tracked record of the numbering it replaced.
77
- *
78
- * `w:numberingChange` is the revision a reviewer's numbering change left
79
- * behind. It is history: nothing in the model derives it, and a rebuilt
80
- * `w:numPr` that drops it discards the revision silently. It is written even
81
- * when the paragraph's own numbering reference is gone, because a change
82
- * record with nothing left to describe is still a record — the schema declares
83
- * it last in `CT_NumPr`, after `w:ilvl` and `w:numId`.
84
- */
85
- const serializeNumbering = (numPr, numberingChangeXml) => {
75
+ const serializeNumbering = ({ numPr, numberingChangeXml, numberingInsertionXml }) => {
86
76
  const slots = numPr === void 0 ? {} : paragraphNumberingSlots(numPr);
87
77
  const parts = [];
88
78
  if (slots.ilvl !== void 0) parts.push(`<w:ilvl w:val="${intAttr(slots.ilvl)}"/>`);
89
79
  if (slots.numId !== void 0) parts.push(`<w:numId w:val="${intAttr(slots.numId)}"/>`);
90
80
  const change = replayableNumberingChangeXml(numberingChangeXml);
91
81
  if (change !== null) parts.push(change);
82
+ const insertion = replayableNumberingInsertionXml(numberingInsertionXml);
83
+ if (insertion !== null) parts.push(insertion);
92
84
  return parts.length === 0 ? "" : `<w:numPr>${parts.join("")}</w:numPr>`;
93
85
  };
94
86
  const NUMBERING_CHANGE_ROOT_NAME = /* @__PURE__ */ new Set(["numberingChange"]);
87
+ const NUMBERING_INSERTION_ROOT_NAME = /* @__PURE__ */ new Set(["ins"]);
95
88
  const WORDPROCESSINGML_NAMESPACE = /* @__PURE__ */ new Set([NAMESPACES.w]);
96
89
  const replayableNumberingChangeXml = (numberingChangeXml) => sanitizeCapturedXmlElement(numberingChangeXml, {
97
90
  allowedLocalNames: NUMBERING_CHANGE_ROOT_NAME,
98
91
  allowedNamespaceUris: WORDPROCESSINGML_NAMESPACE,
99
92
  inheritedNamespaceScope: OOXML_NAMESPACE_SCOPE
100
93
  });
94
+ const replayableNumberingInsertionXml = (numberingInsertionXml) => sanitizeCapturedXmlElement(numberingInsertionXml, {
95
+ allowedLocalNames: NUMBERING_INSERTION_ROOT_NAME,
96
+ allowedNamespaceUris: WORDPROCESSINGML_NAMESPACE,
97
+ inheritedNamespaceScope: OOXML_NAMESPACE_SCOPE
98
+ });
101
99
  const serializeFrameProperties = (frame) => {
102
100
  if (!frame) return "";
103
101
  const { dropCap, lines, width, height, hSpace, vSpace, hAnchor, vAnchor, x, y, xAlign, yAlign, wrap, preservedAttributes } = frame;
@@ -152,7 +150,7 @@ const paragraphMarkPropertiesInner = (runProperties, runInWithNext) => {
152
150
  */
153
151
  const modelParagraphFormattingEmission = (input) => {
154
152
  if (!input) return {};
155
- const { alignment, bidi, kinsoku, overflowPunctuation, spaceBefore, spaceAfter, lineSpacing, lineSpacingRule, snapToGrid, beforeAutospacing, afterAutospacing, spacingExplicit, spacingPreservedAttributes, indentLeft, indentRight, indentFirstLine, hangingIndent, indentPreservedAttributes, borders, shading, tabs, keepNext, keepLines, widowControl, pageBreakBefore, contextualSpacing, numPr, numPrFromStyle, numberingChangeXml, outlineLevel, styleId, frame, suppressLineNumbers, suppressAutoHyphens, runProperties, runInWithNext, preserved } = input;
153
+ const { alignment, bidi, kinsoku, overflowPunctuation, spaceBefore, spaceAfter, lineSpacing, lineSpacingRule, snapToGrid, beforeAutospacing, afterAutospacing, spacingExplicit, spacingPreservedAttributes, indentLeft, indentRight, indentFirstLine, hangingIndent, indentPreservedAttributes, borders, shading, tabs, keepNext, keepLines, widowControl, pageBreakBefore, contextualSpacing, numPr, numPrFromStyle, numberingChangeXml, numberingInsertionXml, outlineLevel, styleId, frame, suppressLineNumbers, suppressAutoHyphens, runProperties, runInWithNext, preserved } = input;
156
154
  modelSpacingProvenance(spacingExplicit);
157
155
  const propertiesXml = serializeSequenceChildren({
158
156
  container: "paragraph-properties",
@@ -164,7 +162,15 @@ const modelParagraphFormattingEmission = (input) => {
164
162
  ["pageBreakBefore", serializeOnOffElement(pageBreakBefore, "pageBreakBefore")],
165
163
  ["framePr", serializeFrameProperties(frame)],
166
164
  ["widowControl", serializeOnOffElement(widowControl, "widowControl")],
167
- ["numPr", isStyleSourcedParagraphNumbering(numPr, numPrFromStyle) ? serializeNumbering(void 0, numberingChangeXml) : serializeNumbering(numPr, numberingChangeXml)],
165
+ ["numPr", isStyleSourcedParagraphNumbering(numPr, numPrFromStyle) ? serializeNumbering({
166
+ numPr: void 0,
167
+ numberingChangeXml,
168
+ numberingInsertionXml
169
+ }) : serializeNumbering({
170
+ numPr,
171
+ numberingChangeXml,
172
+ numberingInsertionXml
173
+ })],
168
174
  ["suppressLineNumbers", serializeOnOffElement(suppressLineNumbers, "suppressLineNumbers")],
169
175
  ["pBdr", serializeParagraphBorders(borders)],
170
176
  ["shd", serializeShading(shading)],
@@ -2124,6 +2124,7 @@ const validateParagraphFormatting = (value, path, issues) => {
2124
2124
  optionalOneOf(value, "lineSpacingRule", `${path}.lineSpacingRule`, issues, LINE_SPACING_RULE_VALUES);
2125
2125
  optionalString(value, "styleId", `${path}.styleId`, issues);
2126
2126
  optionalString(value, "numberingChangeXml", `${path}.numberingChangeXml`, issues);
2127
+ optionalString(value, "numberingInsertionXml", `${path}.numberingInsertionXml`, issues);
2127
2128
  optionalOneOf(value, "listNumFmt", `${path}.listNumFmt`, issues, COUNTER_FORMAT_VALUES);
2128
2129
  optionalString(value, "listMarker", `${path}.listMarker`, issues);
2129
2130
  optionalString(value, "listMarkerTemplate", `${path}.listMarkerTemplate`, issues);
@@ -129,6 +129,9 @@ declare const PARAGRAPH_FORMATTING_WRITE_BACK: {
129
129
  readonly numberingChangeXml: {
130
130
  readonly kind: "original-only";
131
131
  };
132
+ readonly numberingInsertionXml: {
133
+ readonly kind: "original-only";
134
+ };
132
135
  readonly outlineLevel: {
133
136
  readonly kind: "style-resolved-attr";
134
137
  readonly attr: "outlineLevel";
@@ -78,6 +78,7 @@ const PARAGRAPH_FORMATTING_WRITE_BACK = {
78
78
  numPr: { kind: "direct-provenance" },
79
79
  numPrFromStyle: { kind: "derived" },
80
80
  numberingChangeXml: { kind: "original-only" },
81
+ numberingInsertionXml: { kind: "original-only" },
81
82
  outlineLevel: {
82
83
  kind: "style-resolved-attr",
83
84
  attr: "outlineLevel"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/folio-core",
3
- "version": "0.47.2",
3
+ "version": "0.47.3",
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",
@@ -128,7 +128,7 @@
128
128
  "perf": "bun scripts/profile-editor.ts"
129
129
  },
130
130
  "dependencies": {
131
- "@stll/docx-core": "^0.25.1",
131
+ "@stll/docx-core": "^0.25.2",
132
132
  "@stll/docx-utils": "^0.1.0",
133
133
  "@stll/template-conditions": ">=0.4.0 <1.0.0",
134
134
  "better-result": "3.0.1",