@univerjs/docs-toc 1.0.0
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/LICENSE +176 -0
- package/README.md +41 -0
- package/lib/cjs/index.js +597 -0
- package/lib/es/index.js +583 -0
- package/lib/index.js +583 -0
- package/lib/types/commands/table-of-contents.command.d.ts +46 -0
- package/lib/types/config/config.d.ts +20 -0
- package/lib/types/index.d.ts +18 -0
- package/lib/types/plugin.d.ts +29 -0
- package/lib/umd/index.js +1 -0
- package/package.json +75 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
import { BooleanNumber, BuildTextUtils, CommandType, CustomRangeType, DependentOn, ICommandService, IConfigService, IUndoRedoService, IUniverInstanceService, Inject, Injector, JSONX, NamedStyleType, Plugin, SliceBodyType, TabStopAlignment, TabStopLeader, TextX, Tools, UniverInstanceType, cloneParagraphWithId, createParagraphId, generateRandomId, getBodySlice, getPlainText, getRichTextEditPath, merge } from "@univerjs/core";
|
|
2
|
+
import { DocSelectionManagerService, DocSkeletonManagerService, DocStateChangeManagerService, RichTextEditingMutation, UniverDocsPlugin } from "@univerjs/docs";
|
|
3
|
+
import { IRenderManagerService, UniverRenderEnginePlugin } from "@univerjs/engine-render";
|
|
4
|
+
import { filter, firstValueFrom, take, timeout } from "rxjs";
|
|
5
|
+
|
|
6
|
+
//#region src/commands/table-of-contents.command.ts
|
|
7
|
+
const FIELD_START = "";
|
|
8
|
+
const FIELD_END = "";
|
|
9
|
+
async function replaceBodyRange(accessor, doc, unitId, selection, body, historyAction, historyGroupId = generateRandomId()) {
|
|
10
|
+
const textX = new TextX();
|
|
11
|
+
textX.push(...BuildTextUtils.selection.delete([selection], doc.getBody(), 0, body));
|
|
12
|
+
const caretOffset = selection.startOffset + body.dataStream.length;
|
|
13
|
+
accessor.get(DocStateChangeManagerService).flushPendingChanges(unitId);
|
|
14
|
+
const group = accessor.get(IUndoRedoService).beginUndoRedoGroup(unitId, historyGroupId, "append");
|
|
15
|
+
try {
|
|
16
|
+
return Boolean(accessor.get(ICommandService).syncExecuteCommand(RichTextEditingMutation.id, {
|
|
17
|
+
unitId,
|
|
18
|
+
historyAction,
|
|
19
|
+
actions: JSONX.getInstance().editOp(textX.serialize(), getRichTextEditPath(doc)),
|
|
20
|
+
textRanges: [{
|
|
21
|
+
startOffset: caretOffset,
|
|
22
|
+
endOffset: caretOffset,
|
|
23
|
+
collapsed: true
|
|
24
|
+
}],
|
|
25
|
+
debounce: false,
|
|
26
|
+
trigger: historyAction
|
|
27
|
+
}));
|
|
28
|
+
} finally {
|
|
29
|
+
group.dispose();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const UpdateTableOfContentsCommand = {
|
|
33
|
+
id: "doc.command.update-table-of-contents",
|
|
34
|
+
type: CommandType.COMMAND,
|
|
35
|
+
handler: (accessor, params) => updateTableOfContents(accessor, params)
|
|
36
|
+
};
|
|
37
|
+
async function updateTableOfContents(accessor, params, historyGroupId = generateRandomId()) {
|
|
38
|
+
var _body$customRanges, _toc$properties, _render$getInjector;
|
|
39
|
+
const instanceService = accessor.get(IUniverInstanceService);
|
|
40
|
+
const doc = (params === null || params === void 0 ? void 0 : params.unitId) ? instanceService.getUnit(params.unitId, UniverInstanceType.UNIVER_DOC) : instanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
|
|
41
|
+
const body = doc === null || doc === void 0 ? void 0 : doc.getBody();
|
|
42
|
+
const selection = accessor.get(DocSelectionManagerService).getActiveTextRange();
|
|
43
|
+
const toc = (params === null || params === void 0 ? void 0 : params.rangeId) ? body === null || body === void 0 || (_body$customRanges = body.customRanges) === null || _body$customRanges === void 0 ? void 0 : _body$customRanges.find((range) => range.rangeId === params.rangeId && isTableOfContentsRange(range)) : findTableOfContentsAtOffset(body, selection === null || selection === void 0 ? void 0 : selection.startOffset);
|
|
44
|
+
const unitId = doc === null || doc === void 0 ? void 0 : doc.getUnitId();
|
|
45
|
+
if (!doc || !body || !toc || ((_toc$properties = toc.properties) === null || _toc$properties === void 0 ? void 0 : _toc$properties.locked) === BooleanNumber.TRUE || !unitId) return false;
|
|
46
|
+
const render = accessor.get(IRenderManagerService).getRenderUnitById(unitId);
|
|
47
|
+
const renderInjector = render === null || render === void 0 || (_render$getInjector = render.getInjector) === null || _render$getInjector === void 0 ? void 0 : _render$getInjector.call(render);
|
|
48
|
+
if (!render || !(renderInjector === null || renderInjector === void 0 ? void 0 : renderInjector.has(DocSkeletonManagerService))) return false;
|
|
49
|
+
const skeleton = render.with(DocSkeletonManagerService).getSkeleton();
|
|
50
|
+
if (!await waitForCompleteLayout(skeleton)) return false;
|
|
51
|
+
let updated = false;
|
|
52
|
+
for (let iteration = 0; iteration < 3; iteration += 1) {
|
|
53
|
+
var _currentBody$customRa, _currentToc$propertie, _skeleton$getLayoutPr;
|
|
54
|
+
const currentBody = doc.getBody();
|
|
55
|
+
const currentToc = currentBody === null || currentBody === void 0 || (_currentBody$customRa = currentBody.customRanges) === null || _currentBody$customRa === void 0 ? void 0 : _currentBody$customRa.find((range) => range.rangeId === toc.rangeId && isTableOfContentsRange(range));
|
|
56
|
+
if (!currentBody || !currentToc || ((_currentToc$propertie = currentToc.properties) === null || _currentToc$propertie === void 0 ? void 0 : _currentToc$propertie.locked) === BooleanNumber.TRUE) return false;
|
|
57
|
+
const resolvePageNumber = (offset) => {
|
|
58
|
+
var _skeleton$getSkeleton;
|
|
59
|
+
const pageIndex = skeleton.findBodyPageIndexByCharIndex(offset);
|
|
60
|
+
return (_skeleton$getSkeleton = skeleton.getSkeletonData()) === null || _skeleton$getSkeleton === void 0 || (_skeleton$getSkeleton = _skeleton$getSkeleton.pages[pageIndex]) === null || _skeleton$getSkeleton === void 0 ? void 0 : _skeleton$getSkeleton.pageNumber;
|
|
61
|
+
};
|
|
62
|
+
const replacement = (params === null || params === void 0 ? void 0 : params.mode) === "pageNumbersOnly" ? buildPageNumberOnlyTableOfContentsBody(currentBody, currentToc, resolvePageNumber) : buildTableOfContentsBody(currentBody, currentToc, resolvePageNumber);
|
|
63
|
+
if (!replacement) return false;
|
|
64
|
+
if ((params === null || params === void 0 ? void 0 : params.mode) === "pageNumbersOnly" && Tools.diffValue(getBodySlice(currentBody, currentToc.startIndex, currentToc.endIndex + 1, true, SliceBodyType.cut), replacement)) return true;
|
|
65
|
+
if (updated && currentBody.dataStream.slice(currentToc.startIndex, currentToc.endIndex + 1) === replacement.dataStream) return true;
|
|
66
|
+
const generation = ((_skeleton$getLayoutPr = skeleton.getLayoutProgress()) === null || _skeleton$getLayoutPr === void 0 ? void 0 : _skeleton$getLayoutPr.generation) ?? -1;
|
|
67
|
+
updated = await replaceBodyRange(accessor, doc, unitId, {
|
|
68
|
+
startOffset: currentToc.startIndex,
|
|
69
|
+
endOffset: currentToc.endIndex + 1,
|
|
70
|
+
collapsed: false
|
|
71
|
+
}, replacement, UpdateTableOfContentsCommand.id, historyGroupId);
|
|
72
|
+
if (!updated || iteration === 2) return updated;
|
|
73
|
+
if (!await waitForNextCompleteLayout(skeleton, generation)) return false;
|
|
74
|
+
}
|
|
75
|
+
return updated;
|
|
76
|
+
}
|
|
77
|
+
const DeleteTableOfContentsCommand = {
|
|
78
|
+
id: "doc.command.delete-table-of-contents",
|
|
79
|
+
type: CommandType.COMMAND,
|
|
80
|
+
async handler(accessor, params) {
|
|
81
|
+
var _body$customRanges2;
|
|
82
|
+
const instanceService = accessor.get(IUniverInstanceService);
|
|
83
|
+
const doc = (params === null || params === void 0 ? void 0 : params.unitId) ? instanceService.getUnit(params.unitId, UniverInstanceType.UNIVER_DOC) : instanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
|
|
84
|
+
const body = doc === null || doc === void 0 ? void 0 : doc.getBody();
|
|
85
|
+
const selection = accessor.get(DocSelectionManagerService).getActiveTextRange();
|
|
86
|
+
const toc = (params === null || params === void 0 ? void 0 : params.rangeId) ? body === null || body === void 0 || (_body$customRanges2 = body.customRanges) === null || _body$customRanges2 === void 0 ? void 0 : _body$customRanges2.find((range) => range.rangeId === params.rangeId && isTableOfContentsRange(range)) : findTableOfContentsAtOffset(body, selection === null || selection === void 0 ? void 0 : selection.startOffset);
|
|
87
|
+
const unitId = doc === null || doc === void 0 ? void 0 : doc.getUnitId();
|
|
88
|
+
if (!toc || !unitId) return false;
|
|
89
|
+
return replaceBodyRange(accessor, doc, unitId, {
|
|
90
|
+
startOffset: toc.startIndex,
|
|
91
|
+
endOffset: toc.endIndex + 1,
|
|
92
|
+
collapsed: false
|
|
93
|
+
}, { dataStream: "" }, DeleteTableOfContentsCommand.id);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const InsertTableOfContentsCommand = {
|
|
97
|
+
id: "doc.command.insert-table-of-contents",
|
|
98
|
+
type: CommandType.COMMAND,
|
|
99
|
+
async handler(accessor, params) {
|
|
100
|
+
var _render$getInjector2;
|
|
101
|
+
const instanceService = accessor.get(IUniverInstanceService);
|
|
102
|
+
const doc = (params === null || params === void 0 ? void 0 : params.unitId) ? instanceService.getUnit(params.unitId, UniverInstanceType.UNIVER_DOC) : instanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
|
|
103
|
+
const selection = accessor.get(DocSelectionManagerService).getActiveTextRange();
|
|
104
|
+
const body = doc === null || doc === void 0 ? void 0 : doc.getBody();
|
|
105
|
+
const unitId = doc === null || doc === void 0 ? void 0 : doc.getUnitId();
|
|
106
|
+
const render = unitId ? accessor.get(IRenderManagerService).getRenderUnitById(unitId) : void 0;
|
|
107
|
+
const renderInjector = render === null || render === void 0 || (_render$getInjector2 = render.getInjector) === null || _render$getInjector2 === void 0 ? void 0 : _render$getInjector2.call(render);
|
|
108
|
+
if (!doc || !body || !unitId || !selection || selection.segmentId || selection.startOffset !== selection.endOffset || findTableOfContentsAtOffset(body, selection.startOffset) || !render || !(renderInjector === null || renderInjector === void 0 ? void 0 : renderInjector.has(DocSkeletonManagerService))) return false;
|
|
109
|
+
const skeleton = render.with(DocSkeletonManagerService).getSkeleton();
|
|
110
|
+
if (!await waitForCompleteLayout(skeleton)) return false;
|
|
111
|
+
const levels = Math.min(9, Math.max(1, Math.trunc((params === null || params === void 0 ? void 0 : params.levels) ?? 3)));
|
|
112
|
+
const showPageNumbers = (params === null || params === void 0 ? void 0 : params.showPageNumbers) ?? true;
|
|
113
|
+
const rightAlignPageNumbers = showPageNumbers && ((params === null || params === void 0 ? void 0 : params.rightAlignPageNumbers) ?? true);
|
|
114
|
+
const tabLeader = (params === null || params === void 0 ? void 0 : params.tabLeader) ?? "dots";
|
|
115
|
+
const format = (params === null || params === void 0 ? void 0 : params.format) ?? "fromTemplate";
|
|
116
|
+
const rangeId = generateRandomId();
|
|
117
|
+
const toc = {
|
|
118
|
+
rangeId,
|
|
119
|
+
rangeType: CustomRangeType.FIELD,
|
|
120
|
+
startIndex: selection.startOffset,
|
|
121
|
+
endIndex: selection.startOffset,
|
|
122
|
+
wholeEntity: false,
|
|
123
|
+
properties: {
|
|
124
|
+
fieldType: "TOC",
|
|
125
|
+
instruction: buildTableOfContentsInstruction({
|
|
126
|
+
levels,
|
|
127
|
+
showPageNumbers,
|
|
128
|
+
rightAlignPageNumbers
|
|
129
|
+
}),
|
|
130
|
+
sourceKind: "complex",
|
|
131
|
+
showPageNumbers,
|
|
132
|
+
rightAlignPageNumbers,
|
|
133
|
+
tabLeader,
|
|
134
|
+
format,
|
|
135
|
+
title: params === null || params === void 0 ? void 0 : params.title
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const { pageSize, marginLeft = 0, marginRight = 0 } = doc.getDocumentStyle();
|
|
139
|
+
const replacement = buildTableOfContentsBody(body, toc, (offset) => {
|
|
140
|
+
var _skeleton$getSkeleton2;
|
|
141
|
+
const pageIndex = skeleton.findBodyPageIndexByCharIndex(offset);
|
|
142
|
+
return (_skeleton$getSkeleton2 = skeleton.getSkeletonData()) === null || _skeleton$getSkeleton2 === void 0 || (_skeleton$getSkeleton2 = _skeleton$getSkeleton2.pages[pageIndex]) === null || _skeleton$getSkeleton2 === void 0 ? void 0 : _skeleton$getSkeleton2.pageNumber;
|
|
143
|
+
}, generateRandomId, { tabStopOffset: Math.max(72, ((pageSize === null || pageSize === void 0 ? void 0 : pageSize.width) ?? 594.3) - marginLeft - marginRight) });
|
|
144
|
+
if (!replacement) return false;
|
|
145
|
+
const historyGroupId = generateRandomId();
|
|
146
|
+
if (!await replaceBodyRange(accessor, doc, unitId, {
|
|
147
|
+
startOffset: selection.startOffset,
|
|
148
|
+
endOffset: selection.startOffset,
|
|
149
|
+
collapsed: true
|
|
150
|
+
}, replacement, InsertTableOfContentsCommand.id, historyGroupId)) return false;
|
|
151
|
+
await updateTableOfContents(accessor, {
|
|
152
|
+
unitId,
|
|
153
|
+
rangeId,
|
|
154
|
+
mode: "entireTable"
|
|
155
|
+
}, historyGroupId);
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
function buildTableOfContentsInstruction(options = {}) {
|
|
160
|
+
const levels = Math.min(9, Math.max(1, Math.trunc(options.levels ?? 3)));
|
|
161
|
+
const showPageNumbers = options.showPageNumbers ?? true;
|
|
162
|
+
const rightAlignPageNumbers = showPageNumbers && (options.rightAlignPageNumbers ?? true);
|
|
163
|
+
return `TOC ${[
|
|
164
|
+
`\\o "1-${levels}"`,
|
|
165
|
+
"\\h",
|
|
166
|
+
"\\z",
|
|
167
|
+
"\\u",
|
|
168
|
+
...!showPageNumbers ? ["\\n"] : [],
|
|
169
|
+
...showPageNumbers && !rightAlignPageNumbers ? ["\\p \" \""] : []
|
|
170
|
+
].join(" ")}`;
|
|
171
|
+
}
|
|
172
|
+
function isTableOfContentsRange(range) {
|
|
173
|
+
var _range$properties;
|
|
174
|
+
return range.rangeType === CustomRangeType.FIELD && ((_range$properties = range.properties) === null || _range$properties === void 0 ? void 0 : _range$properties.fieldType) === "TOC";
|
|
175
|
+
}
|
|
176
|
+
function findTableOfContentsAtOffset(body, offset) {
|
|
177
|
+
var _body$customRanges3;
|
|
178
|
+
if (offset == null) return;
|
|
179
|
+
return body === null || body === void 0 || (_body$customRanges3 = body.customRanges) === null || _body$customRanges3 === void 0 ? void 0 : _body$customRanges3.filter((range) => isTableOfContentsRange(range) && range.startIndex <= offset && offset <= range.endIndex).sort((left, right) => left.endIndex - left.startIndex - (right.endIndex - right.startIndex))[0];
|
|
180
|
+
}
|
|
181
|
+
async function waitForCompleteLayout(skeleton) {
|
|
182
|
+
const progress = skeleton.getLayoutProgress();
|
|
183
|
+
if (progress == null || progress.complete) return true;
|
|
184
|
+
try {
|
|
185
|
+
await firstValueFrom(skeleton.layoutProgress$.pipe(filter((next) => next.complete), take(1), timeout({ first: 3e4 })));
|
|
186
|
+
return true;
|
|
187
|
+
} catch {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async function waitForNextCompleteLayout(skeleton, generation) {
|
|
192
|
+
try {
|
|
193
|
+
await firstValueFrom(skeleton.layoutProgress$.pipe(filter((next) => next.generation > generation && next.complete), take(1), timeout({ first: 3e4 })));
|
|
194
|
+
return true;
|
|
195
|
+
} catch {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function buildPageNumberOnlyTableOfContentsBody(body, toc, resolvePageNumber) {
|
|
200
|
+
var _toc$properties2, _result$customRanges, _result$customRanges2;
|
|
201
|
+
if (((_toc$properties2 = toc.properties) === null || _toc$properties2 === void 0 ? void 0 : _toc$properties2.locked) === BooleanNumber.TRUE) return null;
|
|
202
|
+
const result = Tools.deepClone(getBodySlice(body, toc.startIndex, toc.endIndex + 1, true, SliceBodyType.cut));
|
|
203
|
+
const pageFields = ((_result$customRanges = result.customRanges) === null || _result$customRanges === void 0 ? void 0 : _result$customRanges.filter((range) => {
|
|
204
|
+
var _range$properties2, _range$properties3;
|
|
205
|
+
return range.rangeType === CustomRangeType.FIELD && ((_range$properties2 = range.properties) === null || _range$properties2 === void 0 ? void 0 : _range$properties2.fieldType) === "PAGEREF" && ((_range$properties3 = range.properties) === null || _range$properties3 === void 0 ? void 0 : _range$properties3.locked) !== BooleanNumber.TRUE;
|
|
206
|
+
}).sort((left, right) => right.startIndex - left.startIndex)) ?? [];
|
|
207
|
+
for (const pageField of pageFields) {
|
|
208
|
+
var _body$customRanges4;
|
|
209
|
+
const originalField = (_body$customRanges4 = body.customRanges) === null || _body$customRanges4 === void 0 ? void 0 : _body$customRanges4.find((range) => range.rangeId === pageField.rangeId);
|
|
210
|
+
const targetOffset = originalField && resolvePageReferenceOffset(body, originalField);
|
|
211
|
+
const pageNumber = targetOffset == null ? void 0 : resolvePageNumber(targetOffset);
|
|
212
|
+
if (pageNumber == null) return null;
|
|
213
|
+
replaceFieldResult(result, pageField, String(pageNumber));
|
|
214
|
+
}
|
|
215
|
+
const outer = (_result$customRanges2 = result.customRanges) === null || _result$customRanges2 === void 0 ? void 0 : _result$customRanges2.find((range) => range.rangeId === toc.rangeId);
|
|
216
|
+
if (outer === null || outer === void 0 ? void 0 : outer.properties) outer.properties.cachedResult = getPlainText(result.dataStream.slice(1, -1)).replaceAll(FIELD_START, "").replaceAll(FIELD_END, "");
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
function resolvePageReferenceOffset(body, pageField) {
|
|
220
|
+
var _String$match, _pageField$properties, _body$customRanges6, _link$properties, _body$paragraphs;
|
|
221
|
+
const targetId = (_String$match = String(((_pageField$properties = pageField.properties) === null || _pageField$properties === void 0 ? void 0 : _pageField$properties.instruction) ?? "").match(/PAGEREF\s+"?([^"\s\\]+)"?/i)) === null || _String$match === void 0 ? void 0 : _String$match[1];
|
|
222
|
+
if (targetId) {
|
|
223
|
+
var _body$customRanges5;
|
|
224
|
+
const bookmark = (_body$customRanges5 = body.customRanges) === null || _body$customRanges5 === void 0 ? void 0 : _body$customRanges5.find((range) => {
|
|
225
|
+
var _range$properties4;
|
|
226
|
+
return range.rangeType === CustomRangeType.BOOKMARK && ((_range$properties4 = range.properties) === null || _range$properties4 === void 0 ? void 0 : _range$properties4.bookmarkId) === targetId;
|
|
227
|
+
});
|
|
228
|
+
if (bookmark) return bookmark.startIndex;
|
|
229
|
+
}
|
|
230
|
+
const link = (_body$customRanges6 = body.customRanges) === null || _body$customRanges6 === void 0 ? void 0 : _body$customRanges6.find((range) => range.rangeType === CustomRangeType.HYPERLINK && range.startIndex <= pageField.startIndex && pageField.endIndex <= range.endIndex);
|
|
231
|
+
const headingId = link === null || link === void 0 || (_link$properties = link.properties) === null || _link$properties === void 0 ? void 0 : _link$properties.headingId;
|
|
232
|
+
return (_body$paragraphs = body.paragraphs) === null || _body$paragraphs === void 0 || (_body$paragraphs = _body$paragraphs.find((paragraph) => {
|
|
233
|
+
var _paragraph$paragraphS;
|
|
234
|
+
return ((_paragraph$paragraphS = paragraph.paragraphStyle) === null || _paragraph$paragraphS === void 0 ? void 0 : _paragraph$paragraphS.headingId) === headingId;
|
|
235
|
+
})) === null || _body$paragraphs === void 0 ? void 0 : _body$paragraphs.startIndex;
|
|
236
|
+
}
|
|
237
|
+
function replaceFieldResult(body, field, value) {
|
|
238
|
+
var _body$paragraphs2, _body$customRanges7;
|
|
239
|
+
const start = field.startIndex + 1;
|
|
240
|
+
const end = field.endIndex;
|
|
241
|
+
if (field.properties) field.properties.cachedResult = value;
|
|
242
|
+
if (body.dataStream.slice(start, end) === value) return;
|
|
243
|
+
const delta = value.length - (end - start);
|
|
244
|
+
body.dataStream = `${body.dataStream.slice(0, start)}${value}${body.dataStream.slice(end)}`;
|
|
245
|
+
shiftRuns(body.textRuns, start, end, delta);
|
|
246
|
+
(_body$paragraphs2 = body.paragraphs) === null || _body$paragraphs2 === void 0 || _body$paragraphs2.forEach((paragraph) => {
|
|
247
|
+
if (paragraph.startIndex >= end) paragraph.startIndex += delta;
|
|
248
|
+
});
|
|
249
|
+
(_body$customRanges7 = body.customRanges) === null || _body$customRanges7 === void 0 || _body$customRanges7.forEach((range) => {
|
|
250
|
+
if (range.startIndex >= end) {
|
|
251
|
+
range.startIndex += delta;
|
|
252
|
+
range.endIndex += delta;
|
|
253
|
+
} else if (range.endIndex >= end) range.endIndex += delta;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
function shiftRuns(runs, start, end, delta) {
|
|
257
|
+
runs === null || runs === void 0 || runs.forEach((run) => {
|
|
258
|
+
if (run.st >= end) {
|
|
259
|
+
run.st += delta;
|
|
260
|
+
run.ed += delta;
|
|
261
|
+
} else if (run.ed > start) run.ed += delta;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function buildTableOfContentsBody(body, toc, resolvePageNumber, idFactory = generateRandomId, options) {
|
|
265
|
+
var _toc$properties3, _toc$properties4, _toc$properties5, _toc$properties6, _toc$properties7, _toc$properties8, _body$customRanges8, _body$paragraphs3, _toc$properties9;
|
|
266
|
+
if (((_toc$properties3 = toc.properties) === null || _toc$properties3 === void 0 ? void 0 : _toc$properties3.locked) === BooleanNumber.TRUE) return null;
|
|
267
|
+
const instruction = String(((_toc$properties4 = toc.properties) === null || _toc$properties4 === void 0 ? void 0 : _toc$properties4.instruction) ?? "");
|
|
268
|
+
if (/\\c\s+/i.test(instruction)) return null;
|
|
269
|
+
const [minLevel, maxLevel] = parseOutlineLevelRange(instruction);
|
|
270
|
+
const headings = collectHeadings(body, toc, minLevel, maxLevel);
|
|
271
|
+
if (headings.length === 0) return null;
|
|
272
|
+
const showPageNumbers = ((_toc$properties5 = toc.properties) === null || _toc$properties5 === void 0 ? void 0 : _toc$properties5.showPageNumbers) !== false && !/\\n(?:\s|$)/i.test(instruction);
|
|
273
|
+
const rightAlignPageNumbers = showPageNumbers && ((_toc$properties6 = toc.properties) === null || _toc$properties6 === void 0 ? void 0 : _toc$properties6.rightAlignPageNumbers) !== false && !/\\p\s+/i.test(instruction);
|
|
274
|
+
const tabLeader = normalizeTabLeader((_toc$properties7 = toc.properties) === null || _toc$properties7 === void 0 ? void 0 : _toc$properties7.tabLeader);
|
|
275
|
+
const format = normalizeFormat((_toc$properties8 = toc.properties) === null || _toc$properties8 === void 0 ? void 0 : _toc$properties8.format);
|
|
276
|
+
const oldParagraphs = ((_body$customRanges8 = body.customRanges) === null || _body$customRanges8 === void 0 ? void 0 : _body$customRanges8.some((range) => range.rangeId === toc.rangeId)) ?? false ? ((_body$paragraphs3 = body.paragraphs) === null || _body$paragraphs3 === void 0 ? void 0 : _body$paragraphs3.filter((paragraph) => paragraph.startIndex >= toc.startIndex && paragraph.startIndex <= toc.endIndex)) ?? [] : [];
|
|
277
|
+
const title = typeof ((_toc$properties9 = toc.properties) === null || _toc$properties9 === void 0 ? void 0 : _toc$properties9.title) === "string" ? toc.properties.title.trim() : getExistingTableOfContentsTitle(body, oldParagraphs);
|
|
278
|
+
const result = {
|
|
279
|
+
dataStream: FIELD_START,
|
|
280
|
+
paragraphs: [],
|
|
281
|
+
customRanges: []
|
|
282
|
+
};
|
|
283
|
+
const ranges = result.customRanges;
|
|
284
|
+
const oldTitleParagraph = oldParagraphs.find((paragraph) => {
|
|
285
|
+
var _paragraph$styleId;
|
|
286
|
+
return ((_paragraph$styleId = paragraph.styleId) === null || _paragraph$styleId === void 0 ? void 0 : _paragraph$styleId.toLowerCase()) === "tocheading";
|
|
287
|
+
});
|
|
288
|
+
const oldEntryParagraphs = oldParagraphs.filter((paragraph) => paragraph !== oldTitleParagraph);
|
|
289
|
+
const usedParagraphIds = /* @__PURE__ */ new Set();
|
|
290
|
+
let cachedResult = "";
|
|
291
|
+
if (title) {
|
|
292
|
+
result.dataStream += `${title}\r`;
|
|
293
|
+
cachedResult += `${title}\r`;
|
|
294
|
+
result.paragraphs.push(cloneParagraphWithId({
|
|
295
|
+
startIndex: result.dataStream.length - 1,
|
|
296
|
+
paragraphId: (oldTitleParagraph === null || oldTitleParagraph === void 0 ? void 0 : oldTitleParagraph.paragraphId) ?? "",
|
|
297
|
+
styleId: "TOCHeading"
|
|
298
|
+
}, usedParagraphIds));
|
|
299
|
+
}
|
|
300
|
+
for (const [index, heading] of headings.entries()) {
|
|
301
|
+
const pageNumber = showPageNumbers ? resolvePageNumber(heading.startOffset) : void 0;
|
|
302
|
+
if (showPageNumbers && pageNumber == null) return null;
|
|
303
|
+
const entryStart = result.dataStream.length;
|
|
304
|
+
const separator = showPageNumbers ? rightAlignPageNumbers ? " " : " " : "";
|
|
305
|
+
const visibleEntry = `${heading.text}${separator}${pageNumber ?? ""}`;
|
|
306
|
+
result.dataStream += `${heading.text}${separator}`;
|
|
307
|
+
const targetId = heading.bookmarkId ?? heading.headingId;
|
|
308
|
+
const link = {
|
|
309
|
+
startIndex: entryStart,
|
|
310
|
+
endIndex: result.dataStream.length - 1,
|
|
311
|
+
rangeId: idFactory(),
|
|
312
|
+
rangeType: CustomRangeType.HYPERLINK,
|
|
313
|
+
wholeEntity: false,
|
|
314
|
+
properties: {
|
|
315
|
+
...heading.bookmarkId ? { bookmarkId: targetId } : { headingId: targetId },
|
|
316
|
+
textStyleMode: "text"
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
ranges.push(link);
|
|
320
|
+
if (showPageNumbers) {
|
|
321
|
+
const pageFieldStart = result.dataStream.length;
|
|
322
|
+
result.dataStream += `${FIELD_START}${pageNumber}${FIELD_END}`;
|
|
323
|
+
const pageFieldEnd = result.dataStream.length - 1;
|
|
324
|
+
link.endIndex = pageFieldEnd;
|
|
325
|
+
ranges.push({
|
|
326
|
+
startIndex: pageFieldStart,
|
|
327
|
+
endIndex: pageFieldEnd,
|
|
328
|
+
rangeId: idFactory(),
|
|
329
|
+
rangeType: CustomRangeType.FIELD,
|
|
330
|
+
wholeEntity: false,
|
|
331
|
+
properties: {
|
|
332
|
+
fieldType: "PAGEREF",
|
|
333
|
+
instruction: `PAGEREF ${targetId} \\h`,
|
|
334
|
+
cachedResult: String(pageNumber),
|
|
335
|
+
sourceKind: "complex"
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
result.dataStream += "\r";
|
|
340
|
+
cachedResult += `${visibleEntry}\r`;
|
|
341
|
+
result.paragraphs.push(copyTocParagraph(oldEntryParagraphs, index, heading.level, result.dataStream.length - 1, usedParagraphIds, rightAlignPageNumbers ? options === null || options === void 0 ? void 0 : options.tabStopOffset : void 0, tabLeader, format));
|
|
342
|
+
}
|
|
343
|
+
result.dataStream += FIELD_END;
|
|
344
|
+
ranges.push({
|
|
345
|
+
startIndex: 0,
|
|
346
|
+
endIndex: result.dataStream.length - 1,
|
|
347
|
+
rangeId: toc.rangeId,
|
|
348
|
+
rangeType: CustomRangeType.FIELD,
|
|
349
|
+
wholeEntity: false,
|
|
350
|
+
properties: {
|
|
351
|
+
...Tools.deepClone(toc.properties ?? {}),
|
|
352
|
+
fieldType: "TOC",
|
|
353
|
+
instruction,
|
|
354
|
+
cachedResult
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
ranges.sort((left, right) => left.startIndex - right.startIndex || right.endIndex - left.endIndex);
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
function getExistingTableOfContentsTitle(body, paragraphs) {
|
|
361
|
+
const titleParagraph = paragraphs.find((paragraph) => {
|
|
362
|
+
var _paragraph$styleId2;
|
|
363
|
+
return ((_paragraph$styleId2 = paragraph.styleId) === null || _paragraph$styleId2 === void 0 ? void 0 : _paragraph$styleId2.toLowerCase()) === "tocheading";
|
|
364
|
+
});
|
|
365
|
+
if (!titleParagraph) return "";
|
|
366
|
+
const allParagraphs = [...body.paragraphs ?? []].sort((left, right) => left.startIndex - right.startIndex);
|
|
367
|
+
const index = allParagraphs.findIndex((paragraph) => paragraph === titleParagraph || paragraph.paragraphId === titleParagraph.paragraphId);
|
|
368
|
+
let start = index > 0 ? allParagraphs[index - 1].startIndex + 1 : 0;
|
|
369
|
+
while (body.dataStream[start] === FIELD_START || body.dataStream[start] === FIELD_END) start += 1;
|
|
370
|
+
return getPlainText(body.dataStream.slice(start, titleParagraph.startIndex)).trim();
|
|
371
|
+
}
|
|
372
|
+
function countTableOfContentsHeadings(body, levels = 3) {
|
|
373
|
+
if (!body) return 0;
|
|
374
|
+
return collectHeadings(body, void 0, 1, Math.min(9, Math.max(1, Math.trunc(levels)))).length;
|
|
375
|
+
}
|
|
376
|
+
function parseOutlineLevelRange(instruction) {
|
|
377
|
+
const match = instruction.match(/\\o\s+"(\d+)\s*-\s*(\d+)"/i);
|
|
378
|
+
const min = Math.max(1, Number((match === null || match === void 0 ? void 0 : match[1]) ?? 1));
|
|
379
|
+
return [min, Math.min(9, Math.max(min, Number((match === null || match === void 0 ? void 0 : match[2]) ?? 3)))];
|
|
380
|
+
}
|
|
381
|
+
function collectHeadings(body, toc, minLevel, maxLevel) {
|
|
382
|
+
const paragraphs = [...body.paragraphs ?? []].sort((left, right) => left.startIndex - right.startIndex);
|
|
383
|
+
let paragraphStart = 0;
|
|
384
|
+
return paragraphs.flatMap((paragraph) => {
|
|
385
|
+
var _paragraph$paragraphS2, _body$customRanges9, _bookmark$properties;
|
|
386
|
+
let startOffset = paragraphStart;
|
|
387
|
+
while (body.dataStream[startOffset] === FIELD_START || body.dataStream[startOffset] === FIELD_END) startOffset += 1;
|
|
388
|
+
paragraphStart = paragraph.startIndex + 1;
|
|
389
|
+
const level = getOutlineLevel(paragraph);
|
|
390
|
+
const headingId = (_paragraph$paragraphS2 = paragraph.paragraphStyle) === null || _paragraph$paragraphS2 === void 0 ? void 0 : _paragraph$paragraphS2.headingId;
|
|
391
|
+
if (!headingId || level == null || level < minLevel || level > maxLevel || toc && startOffset >= toc.startIndex && paragraph.startIndex <= toc.endIndex) return [];
|
|
392
|
+
const text = getPlainText(body.dataStream.slice(startOffset, paragraph.startIndex)).trim();
|
|
393
|
+
if (!text) return [];
|
|
394
|
+
const bookmark = (_body$customRanges9 = body.customRanges) === null || _body$customRanges9 === void 0 ? void 0 : _body$customRanges9.find((range) => {
|
|
395
|
+
var _range$properties5;
|
|
396
|
+
return range.rangeType === CustomRangeType.BOOKMARK && range.startIndex <= paragraph.startIndex && range.endIndex >= startOffset && ((_range$properties5 = range.properties) === null || _range$properties5 === void 0 ? void 0 : _range$properties5.bookmarkId);
|
|
397
|
+
});
|
|
398
|
+
return [{
|
|
399
|
+
bookmarkId: bookmark === null || bookmark === void 0 || (_bookmark$properties = bookmark.properties) === null || _bookmark$properties === void 0 ? void 0 : _bookmark$properties.bookmarkId,
|
|
400
|
+
headingId,
|
|
401
|
+
level,
|
|
402
|
+
paragraph,
|
|
403
|
+
startOffset,
|
|
404
|
+
text
|
|
405
|
+
}];
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
function getOutlineLevel(paragraph) {
|
|
409
|
+
var _paragraph$paragraphS3, _paragraph$paragraphS4;
|
|
410
|
+
const outlineLevel = (_paragraph$paragraphS3 = paragraph.paragraphStyle) === null || _paragraph$paragraphS3 === void 0 ? void 0 : _paragraph$paragraphS3.outlineLevel;
|
|
411
|
+
if (outlineLevel != null && outlineLevel >= 0 && outlineLevel <= 8) return outlineLevel + 1;
|
|
412
|
+
const namedStyle = (_paragraph$paragraphS4 = paragraph.paragraphStyle) === null || _paragraph$paragraphS4 === void 0 ? void 0 : _paragraph$paragraphS4.namedStyleType;
|
|
413
|
+
if (namedStyle != null && namedStyle >= NamedStyleType.HEADING_1 && namedStyle <= NamedStyleType.HEADING_5) return namedStyle - NamedStyleType.HEADING_1 + 1;
|
|
414
|
+
}
|
|
415
|
+
function copyTocParagraph(oldParagraphs, index, level, startIndex, usedParagraphIds, tabStopOffset, tabLeader = "dots", format = "fromTemplate") {
|
|
416
|
+
const source = oldParagraphs.find((paragraph) => {
|
|
417
|
+
var _paragraph$styleId3;
|
|
418
|
+
return ((_paragraph$styleId3 = paragraph.styleId) === null || _paragraph$styleId3 === void 0 || (_paragraph$styleId3 = _paragraph$styleId3.match(/TOC(\d+)/i)) === null || _paragraph$styleId3 === void 0 ? void 0 : _paragraph$styleId3[1]) === String(level);
|
|
419
|
+
}) ?? oldParagraphs[Math.min(index, oldParagraphs.length - 1)];
|
|
420
|
+
if (source) {
|
|
421
|
+
var _oldParagraphs$index;
|
|
422
|
+
return cloneParagraphWithId({
|
|
423
|
+
...source,
|
|
424
|
+
startIndex,
|
|
425
|
+
paragraphId: ((_oldParagraphs$index = oldParagraphs[index]) === null || _oldParagraphs$index === void 0 ? void 0 : _oldParagraphs$index.paragraphId) ?? ""
|
|
426
|
+
}, usedParagraphIds);
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
startIndex,
|
|
430
|
+
paragraphId: createParagraphId(usedParagraphIds),
|
|
431
|
+
styleId: `TOC${level}`,
|
|
432
|
+
paragraphStyle: {
|
|
433
|
+
indentStart: { v: Math.max(0, level - 1) * getFormatIndent(format) },
|
|
434
|
+
spaceBelow: format === "modern" ? { v: 4 } : format === "classic" ? { v: 2 } : void 0,
|
|
435
|
+
tabStops: tabStopOffset == null ? void 0 : [{
|
|
436
|
+
offset: tabStopOffset,
|
|
437
|
+
alignment: TabStopAlignment.END,
|
|
438
|
+
leader: getTabStopLeader(tabLeader)
|
|
439
|
+
}]
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function normalizeTabLeader(value) {
|
|
444
|
+
return value === "none" || value === "dashes" || value === "underline" ? value : "dots";
|
|
445
|
+
}
|
|
446
|
+
function getTabStopLeader(value) {
|
|
447
|
+
return {
|
|
448
|
+
none: TabStopLeader.NONE,
|
|
449
|
+
dots: TabStopLeader.DOT,
|
|
450
|
+
dashes: TabStopLeader.HYPHEN,
|
|
451
|
+
underline: TabStopLeader.UNDERSCORE
|
|
452
|
+
}[value];
|
|
453
|
+
}
|
|
454
|
+
function normalizeFormat(value) {
|
|
455
|
+
return value === "classic" || value === "modern" || value === "simple" ? value : "fromTemplate";
|
|
456
|
+
}
|
|
457
|
+
function getFormatIndent(format) {
|
|
458
|
+
return {
|
|
459
|
+
fromTemplate: 18,
|
|
460
|
+
classic: 14,
|
|
461
|
+
modern: 20,
|
|
462
|
+
simple: 12
|
|
463
|
+
}[format];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region package.json
|
|
468
|
+
var name = "@univerjs/docs-toc";
|
|
469
|
+
var version = "1.0.0";
|
|
470
|
+
|
|
471
|
+
//#endregion
|
|
472
|
+
//#region src/config/config.ts
|
|
473
|
+
/**
|
|
474
|
+
* Copyright 2023-present DreamNum Co., Ltd.
|
|
475
|
+
*
|
|
476
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
477
|
+
* you may not use this file except in compliance with the License.
|
|
478
|
+
* You may obtain a copy of the License at
|
|
479
|
+
*
|
|
480
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
481
|
+
*
|
|
482
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
483
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
484
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
485
|
+
* See the License for the specific language governing permissions and
|
|
486
|
+
* limitations under the License.
|
|
487
|
+
*/
|
|
488
|
+
const DOCS_TOC_PLUGIN_CONFIG_KEY = "docs-toc.config";
|
|
489
|
+
const configSymbol = Symbol(DOCS_TOC_PLUGIN_CONFIG_KEY);
|
|
490
|
+
const defaultPluginConfig = {};
|
|
491
|
+
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
|
|
494
|
+
function __decorateParam(paramIndex, decorator) {
|
|
495
|
+
return function(target, key) {
|
|
496
|
+
decorator(target, key, paramIndex);
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
|
|
502
|
+
function __decorate(decorators, target, key, desc) {
|
|
503
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
504
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
505
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
506
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
|
|
511
|
+
function _typeof(o) {
|
|
512
|
+
"@babel/helpers - typeof";
|
|
513
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
514
|
+
return typeof o;
|
|
515
|
+
} : function(o) {
|
|
516
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
517
|
+
}, _typeof(o);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
//#endregion
|
|
521
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
|
|
522
|
+
function toPrimitive(t, r) {
|
|
523
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
524
|
+
var e = t[Symbol.toPrimitive];
|
|
525
|
+
if (void 0 !== e) {
|
|
526
|
+
var i = e.call(t, r || "default");
|
|
527
|
+
if ("object" != _typeof(i)) return i;
|
|
528
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
529
|
+
}
|
|
530
|
+
return ("string" === r ? String : Number)(t);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
//#endregion
|
|
534
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
|
|
535
|
+
function toPropertyKey(t) {
|
|
536
|
+
var i = toPrimitive(t, "string");
|
|
537
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
//#endregion
|
|
541
|
+
//#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
|
|
542
|
+
function _defineProperty(e, r, t) {
|
|
543
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
544
|
+
value: t,
|
|
545
|
+
enumerable: !0,
|
|
546
|
+
configurable: !0,
|
|
547
|
+
writable: !0
|
|
548
|
+
}) : e[r] = t, e;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
//#endregion
|
|
552
|
+
//#region src/plugin.ts
|
|
553
|
+
let UniverDocsTocPlugin = class UniverDocsTocPlugin extends Plugin {
|
|
554
|
+
constructor(_config = defaultPluginConfig, _injector, _configService, _commandService) {
|
|
555
|
+
super();
|
|
556
|
+
this._config = _config;
|
|
557
|
+
this._injector = _injector;
|
|
558
|
+
this._configService = _configService;
|
|
559
|
+
this._commandService = _commandService;
|
|
560
|
+
const { ...rest } = merge({}, defaultPluginConfig, this._config);
|
|
561
|
+
this._configService.setConfig(DOCS_TOC_PLUGIN_CONFIG_KEY, rest);
|
|
562
|
+
}
|
|
563
|
+
onStarting() {
|
|
564
|
+
[
|
|
565
|
+
InsertTableOfContentsCommand,
|
|
566
|
+
UpdateTableOfContentsCommand,
|
|
567
|
+
DeleteTableOfContentsCommand
|
|
568
|
+
].forEach((command) => this.disposeWithMe(this._commandService.registerCommand(command)));
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
_defineProperty(UniverDocsTocPlugin, "pluginName", "DOCS_TOC_PLUGIN");
|
|
572
|
+
_defineProperty(UniverDocsTocPlugin, "packageName", name);
|
|
573
|
+
_defineProperty(UniverDocsTocPlugin, "version", version);
|
|
574
|
+
_defineProperty(UniverDocsTocPlugin, "type", UniverInstanceType.UNIVER_DOC);
|
|
575
|
+
UniverDocsTocPlugin = __decorate([
|
|
576
|
+
DependentOn(UniverDocsPlugin, UniverRenderEnginePlugin),
|
|
577
|
+
__decorateParam(1, Inject(Injector)),
|
|
578
|
+
__decorateParam(2, IConfigService),
|
|
579
|
+
__decorateParam(3, ICommandService)
|
|
580
|
+
], UniverDocsTocPlugin);
|
|
581
|
+
|
|
582
|
+
//#endregion
|
|
583
|
+
export { DeleteTableOfContentsCommand, InsertTableOfContentsCommand, UniverDocsTocPlugin, UpdateTableOfContentsCommand, buildPageNumberOnlyTableOfContentsBody, buildTableOfContentsBody, buildTableOfContentsInstruction, countTableOfContentsHeadings, findTableOfContentsAtOffset };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2023-present DreamNum Co., Ltd.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import type { ICommand, ICustomRange, IDocumentBody } from '@univerjs/core';
|
|
17
|
+
export interface IUpdateTableOfContentsCommandParams {
|
|
18
|
+
unitId?: string;
|
|
19
|
+
rangeId?: string;
|
|
20
|
+
mode?: 'pageNumbersOnly' | 'entireTable';
|
|
21
|
+
}
|
|
22
|
+
export interface IInsertTableOfContentsCommandParams {
|
|
23
|
+
unitId?: string;
|
|
24
|
+
levels?: number;
|
|
25
|
+
showPageNumbers?: boolean;
|
|
26
|
+
rightAlignPageNumbers?: boolean;
|
|
27
|
+
tabLeader?: TableOfContentsTabLeader;
|
|
28
|
+
format?: TableOfContentsFormat;
|
|
29
|
+
title?: string;
|
|
30
|
+
}
|
|
31
|
+
export type TableOfContentsTabLeader = 'none' | 'dots' | 'dashes' | 'underline';
|
|
32
|
+
export type TableOfContentsFormat = 'fromTemplate' | 'classic' | 'modern' | 'simple';
|
|
33
|
+
export interface IDeleteTableOfContentsCommandParams {
|
|
34
|
+
unitId?: string;
|
|
35
|
+
rangeId?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const UpdateTableOfContentsCommand: ICommand<IUpdateTableOfContentsCommandParams>;
|
|
38
|
+
export declare const DeleteTableOfContentsCommand: ICommand<IDeleteTableOfContentsCommandParams>;
|
|
39
|
+
export declare const InsertTableOfContentsCommand: ICommand<IInsertTableOfContentsCommandParams>;
|
|
40
|
+
export declare function buildTableOfContentsInstruction(options?: Pick<IInsertTableOfContentsCommandParams, 'levels' | 'showPageNumbers' | 'rightAlignPageNumbers'>): string;
|
|
41
|
+
export declare function findTableOfContentsAtOffset(body: IDocumentBody | null | undefined, offset: number | undefined): ICustomRange | undefined;
|
|
42
|
+
export declare function buildPageNumberOnlyTableOfContentsBody(body: IDocumentBody, toc: ICustomRange, resolvePageNumber: (offset: number) => number | undefined): IDocumentBody | null;
|
|
43
|
+
export declare function buildTableOfContentsBody(body: IDocumentBody, toc: ICustomRange, resolvePageNumber: (offset: number) => number | undefined, idFactory?: () => string, options?: {
|
|
44
|
+
tabStopOffset?: number;
|
|
45
|
+
}): IDocumentBody | null;
|
|
46
|
+
export declare function countTableOfContentsHeadings(body: IDocumentBody | null | undefined, levels?: number): number;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2023-present DreamNum Co., Ltd.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
export declare const DOCS_TOC_PLUGIN_CONFIG_KEY = "docs-toc.config";
|
|
17
|
+
export declare const configSymbol: unique symbol;
|
|
18
|
+
export interface IUniverDocsTocConfig {
|
|
19
|
+
}
|
|
20
|
+
export declare const defaultPluginConfig: IUniverDocsTocConfig;
|