@stll/folio-core 0.66.1 → 0.66.2
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.
- package/dist/ai-edits/apply.d.ts +13 -1
- package/dist/ai-edits/apply.js +533 -136
- package/dist/ai-edits/batch-claims.d.ts +26 -0
- package/dist/ai-edits/batch-claims.js +30 -5
- package/dist/ai-edits/headless.d.ts +6 -0
- package/dist/ai-edits/headless.js +25 -3
- package/dist/ai-edits/newListNumbering.d.ts +4 -1
- package/dist/ai-edits/newListNumbering.js +4 -2
- package/dist/ai-edits/types.d.ts +1 -1
- package/dist/document-operations.d.ts +13 -1
- package/dist/document-operations.js +11 -4
- package/dist/docx/listNumberingInstances.d.ts +6 -4
- package/dist/docx/listNumberingInstances.js +12 -11
- package/dist/docx/numberingIds.d.ts +10 -0
- package/dist/docx/numberingIds.js +5 -1
- package/dist/docx/paragraphParser.js +16 -3
- package/dist/docx/paragraphProperties.js +2 -1
- package/dist/docx/serializer/paragraphSerializer.js +86 -66
- package/dist/i18n/messages/ar.gen.js +1 -0
- package/dist/i18n/messages/catalogs.gen.d.ts +17 -0
- package/dist/i18n/messages/catalogs.gen.js +17 -0
- package/dist/i18n/messages/cs.gen.js +1 -0
- package/dist/i18n/messages/de.gen.js +1 -0
- package/dist/i18n/messages/en.gen.js +1 -0
- package/dist/i18n/messages/es.gen.js +1 -0
- package/dist/i18n/messages/et.gen.js +1 -0
- package/dist/i18n/messages/fr.gen.js +1 -0
- package/dist/i18n/messages/he.gen.js +1 -0
- package/dist/i18n/messages/hi.gen.js +1 -0
- package/dist/i18n/messages/hu.gen.js +1 -0
- package/dist/i18n/messages/lt.gen.js +1 -0
- package/dist/i18n/messages/lv.gen.js +1 -0
- package/dist/i18n/messages/messages.gen.d.ts +1 -0
- package/dist/i18n/messages/pl.gen.js +1 -0
- package/dist/i18n/messages/pt-BR.gen.js +1 -0
- package/dist/i18n/messages/sk.gen.js +1 -0
- package/dist/i18n/messages/tr.gen.js +1 -0
- package/dist/i18n/messages/zh-CN.gen.js +1 -0
- package/dist/internal/wholeStoryRevisionResolution.d.ts +1 -1
- package/dist/internal/wholeStoryRevisionResolution.js +24 -9
- package/dist/layout-bridge/convert/runMarkFormatting.js +1 -0
- package/dist/markdown/renderRuns.js +68 -12
- package/dist/prosemirror/commands/comments.js +2 -0
- package/dist/prosemirror/commands/resolveParagraphProperties.js +15 -2
- package/dist/prosemirror/conversion/fromProseDoc.js +55 -18
- package/dist/prosemirror/conversion/hyphenTextCarriers.d.ts +23 -1
- package/dist/prosemirror/conversion/hyphenTextCarriers.js +46 -1
- package/dist/prosemirror/conversion/toProseDoc.js +15 -9
- package/dist/prosemirror/extensions/StarterKit.js +1 -1
- package/dist/prosemirror/extensions/features/pasteCleanup.js +6 -0
- package/dist/prosemirror/extensions/features/pastedHtmlLists.js +2 -1
- package/dist/prosemirror/extensions/markRegistry.d.ts +3 -1
- package/dist/prosemirror/extensions/markRegistry.js +3 -0
- package/dist/prosemirror/extensions/marks/HyphenElementExtension.d.ts +6 -0
- package/dist/prosemirror/extensions/marks/HyphenElementExtension.js +54 -0
- package/dist/prosemirror/fieldRepresentation.js +2 -1
- package/dist/prosemirror/hyphenElementAttrs.d.ts +10 -0
- package/dist/prosemirror/hyphenElementAttrs.js +32 -0
- package/dist/prosemirror/keptRangeBoundaries.d.ts +2 -0
- package/dist/prosemirror/keptRangeBoundaries.js +1 -1
- package/dist/prosemirror/listNumbering.js +3 -2
- package/dist/prosemirror/paragraphIndentation.js +2 -1
- package/dist/prosemirror/paragraphPropertyCarry.d.ts +1 -14
- package/dist/prosemirror/paragraphPropertyCarry.js +4 -28
- package/dist/prosemirror/plugins/suggestionMode.js +19 -6
- package/dist/prosemirror/replacedAnnotations.d.ts +1 -0
- package/dist/prosemirror/replacedAnnotations.js +1 -0
- package/dist/prosemirror/sectionCarrier.d.ts +8 -0
- package/dist/prosemirror/sectionCarrier.js +29 -1
- package/dist/prosemirror/styles/paragraphStyleCascade.d.ts +10 -0
- package/dist/prosemirror/styles/paragraphStyleCascade.js +12 -2
- package/dist/prosemirror/tableRunIn.d.ts +24 -9
- package/dist/prosemirror/tableRunIn.js +107 -21
- package/dist/prosemirror/textInput.js +3 -1
- package/dist/prosemirror/validation.js +6 -0
- package/dist/utils/createDocument.js +11 -8
- package/dist/utils/formatToStyle.js +2 -2
- package/dist/utils/units.d.ts +5 -0
- package/dist/utils/units.js +6 -1
- package/package.json +3 -3
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { getProseParagraphPropertySourceToken, recreateProseNodeWithParagraphPropertySource } from "../docx/paragraphPropertySource.js";
|
|
2
2
|
import { expectParagraphAttrs } from "./attrs/index.js";
|
|
3
|
-
import { paragraphRemainsOf } from "./keptRangeBoundaries.js";
|
|
3
|
+
import { REVISION_MARK_NAMES, paragraphRemainsOf, revisionLayerRemovesContent } from "./keptRangeBoundaries.js";
|
|
4
4
|
import { rebaseParagraphRuns } from "./rebaseParagraphRunFormatting.js";
|
|
5
5
|
import { paragraphRunStyleContext } from "./runStyleFormatting.js";
|
|
6
|
+
import { trackedRevisionPathOf } from "./trackedRevisionPath.js";
|
|
6
7
|
import { paragraphContentOf } from "./zeroWidthAnchors.js";
|
|
7
8
|
import { Fragment, Slice } from "prosemirror-model";
|
|
8
|
-
import { ReplaceAroundStep, StepMap } from "prosemirror-transform";
|
|
9
|
+
import { ReplaceAroundStep, ReplaceStep, StepMap } from "prosemirror-transform";
|
|
9
10
|
import { paragraphMarkOutcome } from "@stll/docx-core/ops";
|
|
10
11
|
// src/prosemirror/tableRunIn.ts
|
|
11
12
|
/**
|
|
@@ -19,35 +20,53 @@ import { paragraphMarkOutcome } from "@stll/docx-core/ops";
|
|
|
19
20
|
*
|
|
20
21
|
* A paragraph with nothing left to carry is simply removed by the resolvers;
|
|
21
22
|
* one that ends a section keeps its place, as does one before a table whose
|
|
22
|
-
*
|
|
23
|
+
* first row or cell may not stay. Rejecting every change gives the document
|
|
24
|
+
* before back, so a deleted row stays for it. A table that resolving every
|
|
25
|
+
* change removes never stood in the way: the paragraph runs on into what follows
|
|
26
|
+
* that table.
|
|
23
27
|
*/
|
|
24
28
|
/**
|
|
25
29
|
* Whether the cell a paragraph's words would run into is itself pending: its
|
|
26
30
|
* row or the cell (through nested tables' first cells) is inserted, deleted
|
|
27
|
-
* or merged, so resolving may not keep it.
|
|
28
|
-
*
|
|
31
|
+
* or merged, so resolving may not keep it. A deletion is not pending for a
|
|
32
|
+
* rejection of every change. Pending rows or cells elsewhere in the table leave
|
|
33
|
+
* that cell where it is.
|
|
29
34
|
*/
|
|
30
|
-
const runInCellPending = (table) => {
|
|
35
|
+
const runInCellPending = (table, everyChange) => {
|
|
36
|
+
const deletionStays = everyChange === "reject";
|
|
31
37
|
let node = table;
|
|
32
38
|
while (node?.type.spec["tableRole"] === "table") {
|
|
33
39
|
const row = node.firstChild;
|
|
34
40
|
if (!row) return false;
|
|
35
|
-
if (row.attrs["trIns"] != null
|
|
41
|
+
if (row.attrs["trIns"] != null) return true;
|
|
42
|
+
if (row.attrs["trDel"] != null && !deletionStays) return true;
|
|
36
43
|
const cell = row.firstChild;
|
|
37
44
|
if (!cell) return false;
|
|
38
|
-
|
|
45
|
+
const marker = cell.attrs["cellMarker"];
|
|
46
|
+
if (marker != null && !(deletionStays && marker.kind === "del")) return true;
|
|
39
47
|
node = cell.firstChild;
|
|
40
48
|
}
|
|
41
49
|
return false;
|
|
42
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Whether resolving every change takes this row out with what it records. The
|
|
53
|
+
* table it stands in goes when all its rows do.
|
|
54
|
+
*/
|
|
55
|
+
const rowGoes = (row, mode) => row.attrs[mode === "accept" ? "trDel" : "trIns"] != null;
|
|
56
|
+
/** Whether resolving every change in `mode` removes the whole table. */
|
|
57
|
+
const tableGoes = (table, mode) => {
|
|
58
|
+
if (table.type.spec["tableRole"] !== "table" || table.childCount === 0) return false;
|
|
59
|
+
for (let index = 0; index < table.childCount; index++) if (!rowGoes(table.child(index), mode)) return false;
|
|
60
|
+
return true;
|
|
61
|
+
};
|
|
43
62
|
/** The first paragraph of a table's first cell, descending into nested tables. */
|
|
44
|
-
const runInTarget = (doc, tablePos) => {
|
|
63
|
+
const runInTarget = (doc, tablePos, everyChange) => {
|
|
45
64
|
let node = doc.nodeAt(tablePos);
|
|
46
65
|
let pos = tablePos;
|
|
47
66
|
const table = node;
|
|
48
67
|
const firstRow = table?.firstChild;
|
|
49
68
|
if (!table || table.type.spec["tableRole"] !== "table" || !firstRow) return null;
|
|
50
|
-
if (runInCellPending(table)) return null;
|
|
69
|
+
if (runInCellPending(table, everyChange)) return null;
|
|
51
70
|
while (node && node.type.name !== "paragraph") {
|
|
52
71
|
const child = node.firstChild;
|
|
53
72
|
if (!child || child.isInline) return null;
|
|
@@ -59,22 +78,22 @@ const runInTarget = (doc, tablePos) => {
|
|
|
59
78
|
node
|
|
60
79
|
} : null;
|
|
61
80
|
};
|
|
62
|
-
const paragraphAfterContentRemoval = (paragraph,
|
|
81
|
+
const paragraphAfterContentRemoval = (paragraph, everyChange) => everyChange ? paragraph.copy(Fragment.fromArray(paragraph.children.filter((child) => !child.marks.some((mark) => REVISION_MARK_NAMES.has(mark.type.name) && trackedRevisionPathOf(mark).some((layer) => revisionLayerRemovesContent(layer, everyChange)))))) : paragraph;
|
|
63
82
|
/**
|
|
64
83
|
* Run the paragraph at `paragraphPos` on into the table right after it.
|
|
65
84
|
* Returns where the paragraph that took its words now starts and the
|
|
66
85
|
* paragraph-property source it hands over, or null when it did not run in and
|
|
67
86
|
* the caller keeps its own handling.
|
|
68
87
|
*/
|
|
69
|
-
const runParagraphIntoTable = ({ tr, paragraphPos, styleResolver,
|
|
88
|
+
const runParagraphIntoTable = ({ tr, paragraphPos, styleResolver, everyChange }) => {
|
|
70
89
|
const paragraph = tr.doc.nodeAt(paragraphPos);
|
|
71
90
|
if (paragraph?.type.name !== "paragraph") return null;
|
|
72
91
|
if (expectParagraphAttrs(paragraph)._sectionProperties !== void 0) return null;
|
|
73
|
-
const left = paragraphAfterContentRemoval(paragraph,
|
|
92
|
+
const left = paragraphAfterContentRemoval(paragraph, everyChange);
|
|
74
93
|
const remains = paragraphRemainsOf(left);
|
|
75
94
|
if (!paragraphContentOf(left) && (remains.blocks.length > 0 || remains.comments.length === 0)) return null;
|
|
76
95
|
const tablePos = paragraphPos + paragraph.nodeSize;
|
|
77
|
-
const target = runInTarget(tr.doc, tablePos);
|
|
96
|
+
const target = runInTarget(tr.doc, tablePos, everyChange);
|
|
78
97
|
if (!target) return null;
|
|
79
98
|
const $target = tr.doc.resolve(target.pos + 1);
|
|
80
99
|
const containerDepth = tr.doc.resolve(paragraphPos).depth;
|
|
@@ -118,6 +137,36 @@ const markGoes = (paragraph, mode) => {
|
|
|
118
137
|
if (!mark) return false;
|
|
119
138
|
return (mark.kind === "ins" || mark.kind === "moveTo") !== (mode === "accept");
|
|
120
139
|
};
|
|
140
|
+
/** Whether resolving every change in `mode` leaves nothing of this paragraph. */
|
|
141
|
+
const paragraphGoes = (paragraph, mode) => {
|
|
142
|
+
if (paragraph.type.name !== "paragraph" || !markGoes(paragraph, mode) || expectParagraphAttrs(paragraph)._sectionProperties != null) return false;
|
|
143
|
+
const left = paragraphAfterContentRemoval(paragraph, mode);
|
|
144
|
+
if (paragraphContentOf(left)) return false;
|
|
145
|
+
const remains = paragraphRemainsOf(left);
|
|
146
|
+
return remains.blocks.length === 0 && remains.comments.length === 0 && remains.inline.length === 0;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Whether what stands right after a paragraph whose mark goes is itself removed
|
|
150
|
+
* by this resolution, so the paragraph runs on into what stands after that, as
|
|
151
|
+
* it would had the removed block never been there: a table it removes, or, when
|
|
152
|
+
* rejecting, an inserted paragraph it empties with a table after it. (Accepted,
|
|
153
|
+
* a deleted paragraph did stand there, and the join ended at it. Paragraphs join
|
|
154
|
+
* among themselves without help.)
|
|
155
|
+
*/
|
|
156
|
+
const paragraphBeforeRemovedBlock = ({ parent, index, mode }) => {
|
|
157
|
+
const paragraph = parent.child(index);
|
|
158
|
+
const next = parent.maybeChild(index + 1);
|
|
159
|
+
if (paragraph.type.name !== "paragraph" || !next || !markGoes(paragraph, mode)) return false;
|
|
160
|
+
if (tableGoes(next, mode)) return true;
|
|
161
|
+
if (mode !== "reject" || paragraphGoes(paragraph, mode)) return false;
|
|
162
|
+
let following = index + 1;
|
|
163
|
+
while (following < parent.childCount) {
|
|
164
|
+
const block = parent.child(following);
|
|
165
|
+
if (!paragraphGoes(block, mode)) break;
|
|
166
|
+
following += 1;
|
|
167
|
+
}
|
|
168
|
+
return following > index + 1 && parent.maybeChild(following)?.type.spec["tableRole"] === "table";
|
|
169
|
+
};
|
|
121
170
|
const runsIntoFollowingTable = ({ parent, index, mode }) => {
|
|
122
171
|
const paragraph = parent.child(index);
|
|
123
172
|
const next = parent.maybeChild(index + 1);
|
|
@@ -125,7 +174,6 @@ const runsIntoFollowingTable = ({ parent, index, mode }) => {
|
|
|
125
174
|
const remains = paragraphRemainsOf(paragraph);
|
|
126
175
|
const holdsContent = paragraphContentOf(paragraph);
|
|
127
176
|
const needsCommentHost = !holdsContent && remains.blocks.length === 0 && remains.comments.length > 0;
|
|
128
|
-
const removedMark = paragraph.type.schema.marks[mode === "accept" ? "deletion" : "insertion"];
|
|
129
177
|
let hasPrecedingCommentHost = false;
|
|
130
178
|
for (let previousIndex = needsCommentHost ? index - 1 : -1; previousIndex >= 0; previousIndex -= 1) {
|
|
131
179
|
const previous = parent.child(previousIndex);
|
|
@@ -134,7 +182,7 @@ const runsIntoFollowingTable = ({ parent, index, mode }) => {
|
|
|
134
182
|
hasPrecedingCommentHost = true;
|
|
135
183
|
break;
|
|
136
184
|
}
|
|
137
|
-
const retained = paragraphAfterContentRemoval(previous,
|
|
185
|
+
const retained = paragraphAfterContentRemoval(previous, mode);
|
|
138
186
|
if (paragraphContentOf(retained)) break;
|
|
139
187
|
if (paragraphRemainsOf(retained).blocks.length > 0) {
|
|
140
188
|
hasPrecedingCommentHost = true;
|
|
@@ -146,22 +194,60 @@ const runsIntoFollowingTable = ({ parent, index, mode }) => {
|
|
|
146
194
|
holdsContent,
|
|
147
195
|
markWasAdded: expectParagraphAttrs(paragraph).pPrMark?.kind === "ins" || expectParagraphAttrs(paragraph).pPrMark?.kind === "moveTo",
|
|
148
196
|
containerStillEndsWithParagraph: false,
|
|
149
|
-
followingTableCanReceiveRunIn: expectParagraphAttrs(paragraph)._sectionProperties === void 0 && !runInCellPending(next),
|
|
197
|
+
followingTableCanReceiveRunIn: expectParagraphAttrs(paragraph)._sectionProperties === void 0 && !runInCellPending(next, mode),
|
|
150
198
|
needsFollowingCommentHost: needsCommentHost && !hasPrecedingCommentHost
|
|
151
199
|
}).kind === "run-in";
|
|
152
200
|
};
|
|
153
201
|
/**
|
|
202
|
+
* Stand each block this resolution removes before the paragraph whose mark goes
|
|
203
|
+
* right before it, so that paragraph meets what it will run on into. The block
|
|
204
|
+
* is going, so where it goes from does not show; the paragraph's words keep
|
|
205
|
+
* mapping to themselves.
|
|
206
|
+
*/
|
|
207
|
+
const moveRemovedBlocksBeforeParagraphs = (tr, mode) => {
|
|
208
|
+
const maps = [];
|
|
209
|
+
for (;;) {
|
|
210
|
+
let move = null;
|
|
211
|
+
tr.doc.descendants((node, position, parent, index) => {
|
|
212
|
+
if (move !== null) return false;
|
|
213
|
+
if (node.type.name !== "paragraph") return !node.isTextblock;
|
|
214
|
+
const block = parent?.maybeChild(index + 1);
|
|
215
|
+
if (parent && block && paragraphBeforeRemovedBlock({
|
|
216
|
+
parent,
|
|
217
|
+
index,
|
|
218
|
+
mode
|
|
219
|
+
})) move = {
|
|
220
|
+
position,
|
|
221
|
+
paragraph: node,
|
|
222
|
+
block
|
|
223
|
+
};
|
|
224
|
+
return false;
|
|
225
|
+
});
|
|
226
|
+
if (move === null) return maps;
|
|
227
|
+
const { position, paragraph, block } = move;
|
|
228
|
+
const blockPosition = position + paragraph.nodeSize;
|
|
229
|
+
tr.step(new ReplaceStep(position, blockPosition + block.nodeSize, new Slice(Fragment.fromArray([block, paragraph]), 0, 0)));
|
|
230
|
+
maps.push(new StepMap([
|
|
231
|
+
position,
|
|
232
|
+
0,
|
|
233
|
+
block.nodeSize,
|
|
234
|
+
blockPosition,
|
|
235
|
+
block.nodeSize,
|
|
236
|
+
0
|
|
237
|
+
]));
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
154
241
|
* Before every change in a story is resolved: run each paragraph whose mark
|
|
155
242
|
* goes and that sits right before a table on into that table. Returns each
|
|
156
243
|
* paragraph that took words (its position after the step count given) and
|
|
157
244
|
* the paragraph-property sources handed over.
|
|
158
245
|
*/
|
|
159
246
|
const runParagraphsIntoTables = (tr, mode, styleResolver) => {
|
|
160
|
-
const removedMark = tr.doc.type.schema.marks[mode === "accept" ? "deletion" : "insertion"];
|
|
161
247
|
const tried = /* @__PURE__ */ new Set();
|
|
162
248
|
const targets = [];
|
|
163
249
|
const transfers = [];
|
|
164
|
-
const maps =
|
|
250
|
+
const maps = moveRemovedBlocksBeforeParagraphs(tr, mode);
|
|
165
251
|
for (;;) {
|
|
166
252
|
let candidate = null;
|
|
167
253
|
tr.doc.descendants((node, pos, parent, index) => {
|
|
@@ -183,7 +269,7 @@ const runParagraphsIntoTables = (tr, mode, styleResolver) => {
|
|
|
183
269
|
tr,
|
|
184
270
|
paragraphPos: candidate,
|
|
185
271
|
styleResolver,
|
|
186
|
-
|
|
272
|
+
everyChange: mode
|
|
187
273
|
});
|
|
188
274
|
if (ranIn !== null) {
|
|
189
275
|
targets.push({
|
|
@@ -196,4 +282,4 @@ const runParagraphsIntoTables = (tr, mode, styleResolver) => {
|
|
|
196
282
|
}
|
|
197
283
|
}
|
|
198
284
|
};
|
|
199
|
-
export { runInCellPending, runParagraphIntoTable, runParagraphsIntoTables, runsIntoFollowingTable };
|
|
285
|
+
export { paragraphBeforeRemovedBlock, runInCellPending, runParagraphIntoTable, runParagraphsIntoTables, runsIntoFollowingTable };
|
|
@@ -30,8 +30,10 @@ const dispatchEditorTextInput = (view, input) => {
|
|
|
30
30
|
});
|
|
31
31
|
const tr = view.state.tr;
|
|
32
32
|
if (formattingMarks !== void 0) tr.setStoredMarks(formattingMarks);
|
|
33
|
+
const typesOverSelection = !selection.empty && selection.from === from && selection.to === to;
|
|
34
|
+
if (typesOverSelection && !selection.$from.parent.inlineContent) return tr.insertText(text);
|
|
33
35
|
tr.insertText(text, from, to);
|
|
34
|
-
return
|
|
36
|
+
return typesOverSelection ? tr.setSelection(TextSelection.create(tr.doc, from + text.length)) : tr;
|
|
35
37
|
}
|
|
36
38
|
const start = Selection.atStart(view.state.doc);
|
|
37
39
|
const end = Selection.atEnd(view.state.doc);
|
|
@@ -3,7 +3,9 @@ import { readBlockCustomXmlAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAtt
|
|
|
3
3
|
import { readBookmarkBoundaryAttrs } from "./bookmarkBoundaryAttrs.js";
|
|
4
4
|
import { readCommentRangeBoundaryAttrs } from "./commentRangeBoundaryAttrs.js";
|
|
5
5
|
import { readCommentReferenceAttrs } from "./commentReferenceAttrs.js";
|
|
6
|
+
import { HYPHEN_ELEMENT_MARK_NAME } from "./conversion/hyphenTextCarriers.js";
|
|
6
7
|
import { fieldRequiresStructuredContent } from "./fieldRepresentation.js";
|
|
8
|
+
import { readHyphenElementMarkAttrs } from "./hyphenElementAttrs.js";
|
|
7
9
|
import { readMoveRangeBoundaryAttrs } from "./moveRangeBoundaryAttrs.js";
|
|
8
10
|
import { readRangeAnchorAttrs } from "./rangeAnchorAttrs.js";
|
|
9
11
|
import { isRunContentInlineNodeName } from "./runContentProjection.js";
|
|
@@ -15,6 +17,7 @@ import { readTextBoxAnchorAttrs } from "./textBoxAnchorAttrs.js";
|
|
|
15
17
|
const COMPLEX_FIELD_RESULT_MARK_NAMES = /* @__PURE__ */ new Set([
|
|
16
18
|
...RUN_FORMATTING_MARK_NAMES,
|
|
17
19
|
RUN_IDENTITY_MARK_NAME,
|
|
20
|
+
HYPHEN_ELEMENT_MARK_NAME,
|
|
18
21
|
"runPropertyChange",
|
|
19
22
|
"footnoteRef"
|
|
20
23
|
]);
|
|
@@ -352,6 +355,9 @@ const validateMark = (mark, markPath, issues) => {
|
|
|
352
355
|
case "textShadow":
|
|
353
356
|
case "textOutline":
|
|
354
357
|
case "rtl": return;
|
|
358
|
+
case "hyphenElement":
|
|
359
|
+
appendAttrIssues(markPath, readHyphenElementMarkAttrs(mark), issues);
|
|
360
|
+
return;
|
|
355
361
|
case "textEffect":
|
|
356
362
|
appendAttrIssues(markPath, readTextEffectMarkAttrs(mark), issues);
|
|
357
363
|
return;
|
|
@@ -5,6 +5,7 @@ import { formatParseWarnings } from "../docx/parseWarningMessage.js";
|
|
|
5
5
|
import { DEFAULT_TAB_STOP_TWIPS as DEFAULT_TAB_STOP_TWIPS$1 } from "../docx/settingsParser.js";
|
|
6
6
|
import { STYLE_SET_PART, normalizeDocumentStyleSet } from "../style-sets/styleSetNormalization.js";
|
|
7
7
|
import "../style-sets/types.js";
|
|
8
|
+
import { generateHexId } from "./hexId.js";
|
|
8
9
|
import { panic } from "better-result";
|
|
9
10
|
import { DOCX_CONFORMANCE_CLASSES } from "@stll/docx-core/model";
|
|
10
11
|
// src/utils/createDocument.ts
|
|
@@ -368,17 +369,19 @@ function createEmptyDocument(options = {}) {
|
|
|
368
369
|
if (options.marginLeft !== void 0) sectionProps.marginLeft = Math.round(options.marginLeft);
|
|
369
370
|
if (options.marginRight !== void 0) sectionProps.marginRight = Math.round(options.marginRight);
|
|
370
371
|
const initialText = options.initialText ?? "";
|
|
372
|
+
const run = {
|
|
373
|
+
type: "run",
|
|
374
|
+
content: initialText ? [{
|
|
375
|
+
type: "text",
|
|
376
|
+
text: initialText
|
|
377
|
+
}] : [],
|
|
378
|
+
formatting: {}
|
|
379
|
+
};
|
|
371
380
|
const documentBody = {
|
|
372
381
|
content: [{
|
|
373
382
|
type: "paragraph",
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
content: initialText ? [{
|
|
377
|
-
type: "text",
|
|
378
|
-
text: initialText
|
|
379
|
-
}] : [],
|
|
380
|
-
formatting: {}
|
|
381
|
-
}],
|
|
383
|
+
paraId: generateHexId(),
|
|
384
|
+
content: [run],
|
|
382
385
|
formatting: { styleId: styleSet?.initialParagraphStyleId ?? "Normal" }
|
|
383
386
|
}],
|
|
384
387
|
finalSectionProperties: sectionProps
|
|
@@ -6,7 +6,7 @@ import { resolveColor, resolveHighlightToCss, resolveShadingColor } from "./colo
|
|
|
6
6
|
import { resolveFontFamily, resolveThemeFont } from "./fontResolver.js";
|
|
7
7
|
import { getHorizontalScaleFactor, normalizeHorizontalScalePercent } from "./horizontalScale.js";
|
|
8
8
|
import { textFlowCss } from "./textDirectionFlow.js";
|
|
9
|
-
import { AUTO_PARAGRAPH_SPACING_PX, eighthsToPixels, formatPx, halfPointsToPixels, halfPointsToPoints, twipsToPixels } from "./units.js";
|
|
9
|
+
import { AUTO_PARAGRAPH_SPACING_PX, eighthsToPixels, formatPx, halfPointsToPixels, halfPointsToPoints, hangingFirstLineIndent, twipsToPixels } from "./units.js";
|
|
10
10
|
import { statesNoBorder } from "@stll/docx-core/model";
|
|
11
11
|
// src/utils/formatToStyle.ts
|
|
12
12
|
/**
|
|
@@ -119,7 +119,7 @@ function paragraphToStyle(formatting, theme) {
|
|
|
119
119
|
if (formatting.indentLeft !== void 0) style.marginLeft = formatPx(twipsToPixels(formatting.indentLeft));
|
|
120
120
|
if (formatting.indentRight !== void 0) style.marginRight = formatPx(twipsToPixels(formatting.indentRight));
|
|
121
121
|
if (formatting.indentFirstLine !== void 0) {
|
|
122
|
-
const textIndent = formatting.hangingIndent ?
|
|
122
|
+
const textIndent = formatting.hangingIndent ? hangingFirstLineIndent(formatting.indentFirstLine) : formatting.indentFirstLine;
|
|
123
123
|
style.textIndent = formatPx(twipsToPixels(textIndent));
|
|
124
124
|
}
|
|
125
125
|
if (formatting.borders) {
|
package/dist/utils/units.d.ts
CHANGED
|
@@ -22,6 +22,11 @@ export declare const PIXELS_PER_INCH: 96;
|
|
|
22
22
|
* twips conversion. See eigenpal/docx-editor#823.
|
|
23
23
|
*/
|
|
24
24
|
export declare const AUTO_PARAGRAPH_SPACING_PX: number;
|
|
25
|
+
/**
|
|
26
|
+
* The `indentFirstLine` a hanging indent of `magnitude` twips stores: negated,
|
|
27
|
+
* but never as `-0`, which compares unequal to the `0` a model holds elsewhere.
|
|
28
|
+
*/
|
|
29
|
+
export declare const hangingFirstLineIndent: (magnitude: number) => number;
|
|
25
30
|
/**
|
|
26
31
|
* Convert twips to pixels (at 96 DPI)
|
|
27
32
|
*
|
package/dist/utils/units.js
CHANGED
|
@@ -34,6 +34,11 @@ const PIXELS_PER_INCH = STANDARD_DPI;
|
|
|
34
34
|
*/
|
|
35
35
|
const AUTO_PARAGRAPH_SPACING_PX = pointsToPixels(14);
|
|
36
36
|
/**
|
|
37
|
+
* The `indentFirstLine` a hanging indent of `magnitude` twips stores: negated,
|
|
38
|
+
* but never as `-0`, which compares unequal to the `0` a model holds elsewhere.
|
|
39
|
+
*/
|
|
40
|
+
const hangingFirstLineIndent = (magnitude) => magnitude === 0 ? 0 : -Math.abs(magnitude);
|
|
41
|
+
/**
|
|
37
42
|
* Convert twips to pixels (at 96 DPI)
|
|
38
43
|
*
|
|
39
44
|
* 1 inch = 1440 twips = 96 pixels
|
|
@@ -146,4 +151,4 @@ function clamp(value, min, max) {
|
|
|
146
151
|
function formatPx(px) {
|
|
147
152
|
return `${roundPixels(px)}px`;
|
|
148
153
|
}
|
|
149
|
-
export { AUTO_PARAGRAPH_SPACING_PX, PIXELS_PER_INCH, TWIPS_PER_INCH, clamp, eighthsToPixels, emuToPixels, emuToStrokePixels, emuToTwips, formatPx, halfPointsToPixels, halfPointsToPoints, pixelsToEmu, pixelsToTwips, pointsToHalfPoints, pointsToPixels, roundPixels, twipsToEmu, twipsToPixels };
|
|
154
|
+
export { AUTO_PARAGRAPH_SPACING_PX, PIXELS_PER_INCH, TWIPS_PER_INCH, clamp, eighthsToPixels, emuToPixels, emuToStrokePixels, emuToTwips, formatPx, halfPointsToPixels, halfPointsToPoints, hangingFirstLineIndent, pixelsToEmu, pixelsToTwips, pointsToHalfPoints, pointsToPixels, roundPixels, twipsToEmu, twipsToPixels };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.66.
|
|
3
|
+
"version": "0.66.2",
|
|
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",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"perf": "bun scripts/profile-editor.ts"
|
|
174
174
|
},
|
|
175
175
|
"dependencies": {
|
|
176
|
-
"@stll/docx-core": "^0.
|
|
176
|
+
"@stll/docx-core": "^0.42.0",
|
|
177
177
|
"@stll/docx-utils": "^0.2.0",
|
|
178
178
|
"@stll/template-conditions": "^0.6.2",
|
|
179
179
|
"@stll/utf8-boundaries": "0.2.0",
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
"prosemirror-state": "^1.4.4",
|
|
199
199
|
"prosemirror-tables": "^1.8.5",
|
|
200
200
|
"prosemirror-transform": "^1.12.4",
|
|
201
|
-
"prosemirror-view": "^1.42.
|
|
201
|
+
"prosemirror-view": "^1.42.8",
|
|
202
202
|
"y-prosemirror": "^1.3.7",
|
|
203
203
|
"y-protocols": "^1.0.6",
|
|
204
204
|
"yjs": "^13.6.33"
|