@usejunior/docx-mcp 0.1.2 → 0.2.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/README.md +4 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/conformance/harness.js +7 -7
- package/dist/conformance/harness.js.map +1 -1
- package/dist/server.d.ts +5 -5
- package/dist/server.js +8 -8
- package/dist/server.js.map +1 -1
- package/dist/session/manager.d.ts +6 -6
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +6 -6
- package/dist/session/manager.js.map +1 -1
- package/dist/tool_catalog.d.ts +26 -20
- package/dist/tool_catalog.d.ts.map +1 -1
- package/dist/tool_catalog.js +18 -13
- package/dist/tool_catalog.js.map +1 -1
- package/dist/tools/clear_formatting.d.ts +14 -0
- package/dist/tools/clear_formatting.d.ts.map +1 -0
- package/dist/tools/clear_formatting.js +94 -0
- package/dist/tools/clear_formatting.js.map +1 -0
- package/dist/tools/get_session_status.js +3 -3
- package/dist/tools/get_session_status.js.map +1 -1
- package/dist/tools/insert_paragraph.d.ts +1 -0
- package/dist/tools/insert_paragraph.d.ts.map +1 -1
- package/dist/tools/insert_paragraph.js +61 -397
- package/dist/tools/insert_paragraph.js.map +1 -1
- package/dist/tools/open_document.js +5 -5
- package/dist/tools/open_document.js.map +1 -1
- package/dist/tools/replace_text.d.ts +9 -0
- package/dist/tools/replace_text.d.ts.map +1 -1
- package/dist/tools/replace_text.js +128 -516
- package/dist/tools/replace_text.js.map +1 -1
- package/dist/tools/{download.d.ts → save.d.ts} +4 -4
- package/dist/tools/save.d.ts.map +1 -0
- package/dist/tools/{download.js → save.js} +21 -20
- package/dist/tools/save.js.map +1 -0
- package/dist/tools/tag_parser.d.ts +28 -0
- package/dist/tools/tag_parser.d.ts.map +1 -0
- package/dist/tools/tag_parser.js +327 -0
- package/dist/tools/tag_parser.js.map +1 -0
- package/package.json +2 -2
- package/dist/tools/download.d.ts.map +0 -1
- package/dist/tools/download.js.map +0 -1
- package/dist/tools/duplicate_document.d.ts +0 -8
- package/dist/tools/duplicate_document.d.ts.map +0 -1
- package/dist/tools/duplicate_document.js +0 -90
- package/dist/tools/duplicate_document.js.map +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { ok, err } from './types.js';
|
|
2
|
+
import { resolveSessionForTool, mergeSessionResolutionMetadata } from './session_resolution.js';
|
|
3
|
+
import { OOXML, W } from '@usejunior/docx-core';
|
|
4
|
+
export async function clearFormatting(manager, params) {
|
|
5
|
+
try {
|
|
6
|
+
const resolved = await resolveSessionForTool(manager, params, { toolName: 'clear_formatting' });
|
|
7
|
+
if (!resolved.ok)
|
|
8
|
+
return resolved.response;
|
|
9
|
+
const { session, metadata } = resolved;
|
|
10
|
+
const { nodes } = session.doc.buildDocumentView({ includeSemanticTags: false });
|
|
11
|
+
const pids = params.paragraph_ids ?? nodes.map((n) => n.id);
|
|
12
|
+
let modifiedCount = 0;
|
|
13
|
+
for (const pid of pids) {
|
|
14
|
+
const pEl = session.doc.getParagraphElementById(pid);
|
|
15
|
+
if (!pEl)
|
|
16
|
+
continue;
|
|
17
|
+
const rElems = Array.from(pEl.getElementsByTagNameNS(OOXML.W_NS, W.r));
|
|
18
|
+
let pModified = false;
|
|
19
|
+
for (const r of rElems) {
|
|
20
|
+
const rPr = r.getElementsByTagNameNS(OOXML.W_NS, W.rPr).item(0);
|
|
21
|
+
if (!rPr)
|
|
22
|
+
continue;
|
|
23
|
+
if (params.clear_highlight) {
|
|
24
|
+
const highlights = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.highlight));
|
|
25
|
+
if (highlights.length > 0) {
|
|
26
|
+
for (const h of highlights)
|
|
27
|
+
h.parentNode?.removeChild(h);
|
|
28
|
+
pModified = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (params.clear_bold) {
|
|
32
|
+
const bolds = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.b));
|
|
33
|
+
if (bolds.length > 0) {
|
|
34
|
+
for (const b of bolds)
|
|
35
|
+
b.parentNode?.removeChild(b);
|
|
36
|
+
pModified = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (params.clear_italic) {
|
|
40
|
+
const italics = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.i));
|
|
41
|
+
if (italics.length > 0) {
|
|
42
|
+
for (const i of italics)
|
|
43
|
+
i.parentNode?.removeChild(i);
|
|
44
|
+
pModified = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (params.clear_underline) {
|
|
48
|
+
const underlines = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.u));
|
|
49
|
+
if (underlines.length > 0) {
|
|
50
|
+
for (const u of underlines)
|
|
51
|
+
u.parentNode?.removeChild(u);
|
|
52
|
+
pModified = true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (params.clear_color) {
|
|
56
|
+
const colors = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.color));
|
|
57
|
+
if (colors.length > 0) {
|
|
58
|
+
for (const c of colors)
|
|
59
|
+
c.parentNode?.removeChild(c);
|
|
60
|
+
pModified = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (params.clear_font) {
|
|
64
|
+
const fonts = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.rFonts));
|
|
65
|
+
const sizes = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.sz));
|
|
66
|
+
const csSizes = Array.from(rPr.getElementsByTagNameNS(OOXML.W_NS, W.szCs));
|
|
67
|
+
if (fonts.length > 0 || sizes.length > 0 || csSizes.length > 0) {
|
|
68
|
+
for (const f of fonts)
|
|
69
|
+
f.parentNode?.removeChild(f);
|
|
70
|
+
for (const s of sizes)
|
|
71
|
+
s.parentNode?.removeChild(s);
|
|
72
|
+
for (const s of csSizes)
|
|
73
|
+
s.parentNode?.removeChild(s);
|
|
74
|
+
pModified = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (pModified)
|
|
79
|
+
modifiedCount++;
|
|
80
|
+
}
|
|
81
|
+
if (modifiedCount > 0) {
|
|
82
|
+
manager.markEdited(session);
|
|
83
|
+
}
|
|
84
|
+
return ok(mergeSessionResolutionMetadata({
|
|
85
|
+
success: true,
|
|
86
|
+
session_id: session.sessionId,
|
|
87
|
+
paragraphs_modified: modifiedCount,
|
|
88
|
+
}, metadata));
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
return err('CLEAR_FORMATTING_ERROR', `Failed to clear formatting: ${e.message}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=clear_formatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear_formatting.js","sourceRoot":"","sources":["../../src/tools/clear_formatting.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,10 +14,10 @@ export async function getSessionStatus(manager, params) {
|
|
|
14
14
|
last_activity: session.lastAccessedAt.toISOString(),
|
|
15
15
|
edit_count: session.editCount,
|
|
16
16
|
edit_revision: session.editRevision,
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
cached_save_artifacts: session.saveCache.size,
|
|
18
|
+
save_defaults: {
|
|
19
19
|
default_variants: ['clean', 'redline'],
|
|
20
|
-
|
|
20
|
+
default_save_format: 'both',
|
|
21
21
|
supports_variant_override: true,
|
|
22
22
|
redownload_by_session_id: true,
|
|
23
23
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_session_status.js","sourceRoot":"","sources":["../../src/tools/get_session_status.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,EAAE,EAAqB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhG,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAuB,EACvB,MAAmD;IAEnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC;QAC3C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACvC,OAAO,EAAE,CAAC,8BAA8B,CAAC;YACvC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;YAC3C,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;YAC3C,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE;YACnD,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,aAAa,EAAE,OAAO,CAAC,YAAY;YACnC,
|
|
1
|
+
{"version":3,"file":"get_session_status.js","sourceRoot":"","sources":["../../src/tools/get_session_status.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,EAAE,EAAqB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,8BAA8B,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhG,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAuB,EACvB,MAAmD;IAEnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAClG,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC;QAC3C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACvC,OAAO,EAAE,CAAC,8BAA8B,CAAC;YACvC,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;YAC3C,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;YAC3C,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,WAAW,EAAE;YACnD,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,aAAa,EAAE,OAAO,CAAC,YAAY;YACnC,qBAAqB,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI;YAC7C,aAAa,EAAE;gBACb,gBAAgB,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;gBACtC,mBAAmB,EAAE,MAAM;gBAC3B,yBAAyB,EAAE,IAAI;gBAC/B,wBAAwB,EAAE,IAAI;aAC/B;YACD,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE;YACxC,aAAa,EAAE,OAAO,CAAC,kBAAkB;gBACvC,CAAC,CAAC;oBACE,WAAW,EAAE,OAAO,CAAC,kBAAkB,CAAC,UAAU;oBAClD,oBAAoB,EAAE,OAAO,CAAC,kBAAkB,CAAC,eAAe;oBAChE,mBAAmB,EAAE,OAAO,CAAC,kBAAkB,CAAC,oBAAoB;oBACpE,uBAAuB,EAAE,OAAO,CAAC,kBAAkB,CAAC,qBAAqB;oBACzE,qBAAqB,EAAE,KAAK;iBAC7B;gBACH,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,mBAAmB,EAAE,CAAC,EAAE,uBAAuB,EAAE,CAAC,EAAE,qBAAqB,EAAE,IAAI,EAAE;SACxG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChB,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC5B,OAAO,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insert_paragraph.d.ts","sourceRoot":"","sources":["../../src/tools/insert_paragraph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"insert_paragraph.d.ts","sourceRoot":"","sources":["../../src/tools/insert_paragraph.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAsGxD,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE;IACN,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB,EAAE,MAAM,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACA,OAAO,CAAC,YAAY,CAAC,CA6FvB"}
|
|
@@ -1,240 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getParagraphRuns, hasHyperlinkTags, stripHyperlinkTags, stripAllInlineTags, } from '@usejunior/docx-core';
|
|
2
2
|
import { errorMessage } from "../error_utils.js";
|
|
3
3
|
import { err, ok } from './types.js';
|
|
4
4
|
import { RESULT_PREVIEW_CHARS, previewText } from './preview.js';
|
|
5
5
|
import { mergeSessionResolutionMetadata, resolveSessionForTool } from './session_resolution.js';
|
|
6
|
-
|
|
7
|
-
const CLOSE_DEF = '</definition>';
|
|
8
|
-
const OPEN_HEADER = '<header>';
|
|
9
|
-
const CLOSE_HEADER = '</header>';
|
|
10
|
-
const OPEN_RUN_IN_HEADER = '<RunInHeader>';
|
|
11
|
-
const CLOSE_RUN_IN_HEADER = '</RunInHeader>';
|
|
12
|
-
const OPEN_HL = '<highlighting>';
|
|
13
|
-
const CLOSE_HL = '</highlighting>';
|
|
14
|
-
const OPEN_B = '<b>';
|
|
15
|
-
const CLOSE_B = '</b>';
|
|
16
|
-
const OPEN_I = '<i>';
|
|
17
|
-
const CLOSE_I = '</i>';
|
|
18
|
-
const OPEN_U = '<u>';
|
|
19
|
-
const CLOSE_U = '</u>';
|
|
20
|
-
function isTruthyEnv(value) {
|
|
21
|
-
if (!value)
|
|
22
|
-
return false;
|
|
23
|
-
const v = value.trim().toLowerCase();
|
|
24
|
-
return v === '1' || v === 'true' || v === 'yes' || v === 'on';
|
|
25
|
-
}
|
|
26
|
-
function useLegacyDefinitionTags() {
|
|
27
|
-
return isTruthyEnv(process.env.SAFE_DOCX_ENABLE_LEGACY_DEFINITION_TAGS);
|
|
28
|
-
}
|
|
29
|
-
function statesEqual(a, b) {
|
|
30
|
-
return (a.definition === b.definition
|
|
31
|
-
&& a.header === b.header
|
|
32
|
-
&& a.highlighting === b.highlighting
|
|
33
|
-
&& a.bold === b.bold
|
|
34
|
-
&& a.italic === b.italic
|
|
35
|
-
&& a.underline === b.underline);
|
|
36
|
-
}
|
|
37
|
-
function pushSegment(out, text, state) {
|
|
38
|
-
if (!text)
|
|
39
|
-
return;
|
|
40
|
-
const prev = out[out.length - 1];
|
|
41
|
-
if (prev && statesEqual(prev, state)) {
|
|
42
|
-
prev.text += text;
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
out.push({ text, ...state });
|
|
46
|
-
}
|
|
47
|
-
function splitTaggedText(text, opts) {
|
|
48
|
-
const counters = {
|
|
49
|
-
definition: 0,
|
|
50
|
-
header: 0,
|
|
51
|
-
highlighting: 0,
|
|
52
|
-
bold: 0,
|
|
53
|
-
italic: 0,
|
|
54
|
-
underline: 0,
|
|
55
|
-
};
|
|
56
|
-
const out = [];
|
|
57
|
-
let i = 0;
|
|
58
|
-
let buf = '';
|
|
59
|
-
const state = () => ({
|
|
60
|
-
definition: counters.definition > 0,
|
|
61
|
-
header: counters.header > 0,
|
|
62
|
-
highlighting: counters.highlighting > 0,
|
|
63
|
-
bold: counters.bold > 0,
|
|
64
|
-
italic: counters.italic > 0,
|
|
65
|
-
underline: counters.underline > 0,
|
|
66
|
-
});
|
|
67
|
-
const flush = () => {
|
|
68
|
-
pushSegment(out, buf, state());
|
|
69
|
-
buf = '';
|
|
70
|
-
};
|
|
71
|
-
const open = (key) => {
|
|
72
|
-
flush();
|
|
73
|
-
counters[key] += 1;
|
|
74
|
-
};
|
|
75
|
-
const close = (key, errCode) => {
|
|
76
|
-
flush();
|
|
77
|
-
if (counters[key] === 0)
|
|
78
|
-
throw new Error(errCode);
|
|
79
|
-
counters[key] -= 1;
|
|
80
|
-
};
|
|
81
|
-
while (i < text.length) {
|
|
82
|
-
if (opts.allowDefinitionTags && text.startsWith(OPEN_DEF, i)) {
|
|
83
|
-
open('definition');
|
|
84
|
-
i += OPEN_DEF.length;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
if (opts.allowDefinitionTags && text.startsWith(CLOSE_DEF, i)) {
|
|
88
|
-
close('definition', 'UNBALANCED_DEFINITION_TAGS');
|
|
89
|
-
i += CLOSE_DEF.length;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (text.startsWith(OPEN_HEADER, i)) {
|
|
93
|
-
open('header');
|
|
94
|
-
i += OPEN_HEADER.length;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
if (text.startsWith(CLOSE_HEADER, i)) {
|
|
98
|
-
close('header', 'UNBALANCED_HEADER_TAGS');
|
|
99
|
-
i += CLOSE_HEADER.length;
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (text.startsWith(OPEN_RUN_IN_HEADER, i)) {
|
|
103
|
-
open('header');
|
|
104
|
-
i += OPEN_RUN_IN_HEADER.length;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
if (text.startsWith(CLOSE_RUN_IN_HEADER, i)) {
|
|
108
|
-
close('header', 'UNBALANCED_HEADER_TAGS');
|
|
109
|
-
i += CLOSE_RUN_IN_HEADER.length;
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
if (text.startsWith(OPEN_HL, i)) {
|
|
113
|
-
open('highlighting');
|
|
114
|
-
i += OPEN_HL.length;
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
if (text.startsWith(CLOSE_HL, i)) {
|
|
118
|
-
close('highlighting', 'UNBALANCED_HIGHLIGHT_TAGS');
|
|
119
|
-
i += CLOSE_HL.length;
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (text.startsWith(OPEN_B, i)) {
|
|
123
|
-
open('bold');
|
|
124
|
-
i += OPEN_B.length;
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (text.startsWith(CLOSE_B, i)) {
|
|
128
|
-
close('bold', 'UNBALANCED_BOLD_TAGS');
|
|
129
|
-
i += CLOSE_B.length;
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
if (text.startsWith(OPEN_I, i)) {
|
|
133
|
-
open('italic');
|
|
134
|
-
i += OPEN_I.length;
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
if (text.startsWith(CLOSE_I, i)) {
|
|
138
|
-
close('italic', 'UNBALANCED_ITALIC_TAGS');
|
|
139
|
-
i += CLOSE_I.length;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
if (text.startsWith(OPEN_U, i)) {
|
|
143
|
-
open('underline');
|
|
144
|
-
i += OPEN_U.length;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (text.startsWith(CLOSE_U, i)) {
|
|
148
|
-
close('underline', 'UNBALANCED_UNDERLINE_TAGS');
|
|
149
|
-
i += CLOSE_U.length;
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
buf += text[i];
|
|
153
|
-
i += 1;
|
|
154
|
-
}
|
|
155
|
-
flush();
|
|
156
|
-
if (counters.definition > 0)
|
|
157
|
-
throw new Error('UNBALANCED_DEFINITION_TAGS');
|
|
158
|
-
if (counters.header > 0)
|
|
159
|
-
throw new Error('UNBALANCED_HEADER_TAGS');
|
|
160
|
-
if (counters.highlighting > 0)
|
|
161
|
-
throw new Error('UNBALANCED_HIGHLIGHT_TAGS');
|
|
162
|
-
if (counters.bold > 0)
|
|
163
|
-
throw new Error('UNBALANCED_BOLD_TAGS');
|
|
164
|
-
if (counters.italic > 0)
|
|
165
|
-
throw new Error('UNBALANCED_ITALIC_TAGS');
|
|
166
|
-
if (counters.underline > 0)
|
|
167
|
-
throw new Error('UNBALANCED_UNDERLINE_TAGS');
|
|
168
|
-
return out.length > 0 ? out : [{ text: '', ...state() }];
|
|
169
|
-
}
|
|
170
|
-
const QUOTE_CHARS = new Set([
|
|
171
|
-
'"',
|
|
172
|
-
"'",
|
|
173
|
-
'\u201c',
|
|
174
|
-
'\u201d',
|
|
175
|
-
'\u2018',
|
|
176
|
-
'\u2019',
|
|
177
|
-
'\u00ab',
|
|
178
|
-
'\u00bb',
|
|
179
|
-
'\u2039',
|
|
180
|
-
'\u203a',
|
|
181
|
-
]);
|
|
182
|
-
function isQuoteChar(ch) {
|
|
183
|
-
return QUOTE_CHARS.has(ch);
|
|
184
|
-
}
|
|
185
|
-
function stripOuterQuotes(term) {
|
|
186
|
-
let t = term;
|
|
187
|
-
while (t && isQuoteChar(t[0]))
|
|
188
|
-
t = t.slice(1);
|
|
189
|
-
while (t && isQuoteChar(t[t.length - 1]))
|
|
190
|
-
t = t.slice(0, -1);
|
|
191
|
-
return t;
|
|
192
|
-
}
|
|
193
|
-
function absorbSurroundingQuotes(segs) {
|
|
194
|
-
for (let i = 0; i < segs.length; i++) {
|
|
195
|
-
const seg = segs[i];
|
|
196
|
-
if (!seg.definition)
|
|
197
|
-
continue;
|
|
198
|
-
const prev = i > 0 ? segs[i - 1] : null;
|
|
199
|
-
if (prev && !prev.definition && prev.text && isQuoteChar(prev.text[prev.text.length - 1])) {
|
|
200
|
-
prev.text = prev.text.slice(0, -1);
|
|
201
|
-
}
|
|
202
|
-
const next = i + 1 < segs.length ? segs[i + 1] : null;
|
|
203
|
-
if (next && !next.definition && next.text && isQuoteChar(next.text[0])) {
|
|
204
|
-
next.text = next.text.slice(1);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
function segmentAddRunProps(seg) {
|
|
209
|
-
const add = {};
|
|
210
|
-
if (seg.bold)
|
|
211
|
-
add.bold = true;
|
|
212
|
-
if (seg.italic)
|
|
213
|
-
add.italic = true;
|
|
214
|
-
if (seg.underline)
|
|
215
|
-
add.underline = true;
|
|
216
|
-
if (seg.highlighting)
|
|
217
|
-
add.highlight = true;
|
|
218
|
-
return Object.keys(add).length > 0 ? add : undefined;
|
|
219
|
-
}
|
|
6
|
+
import { splitTaggedText, segmentAddRunProps, } from './tag_parser.js';
|
|
220
7
|
function mergeAddRunProps(a, b) {
|
|
221
|
-
const out = {};
|
|
222
|
-
if (
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
8
|
+
const out = { ...a };
|
|
9
|
+
if (b) {
|
|
10
|
+
if (b.bold !== undefined)
|
|
11
|
+
out.bold = b.bold;
|
|
12
|
+
if (b.italic !== undefined)
|
|
13
|
+
out.italic = b.italic;
|
|
14
|
+
if (b.underline !== undefined)
|
|
15
|
+
out.underline = b.underline;
|
|
16
|
+
if (b.highlight !== undefined)
|
|
17
|
+
out.highlight = b.highlight;
|
|
18
|
+
if (b.fontSize !== undefined)
|
|
19
|
+
out.fontSize = b.fontSize;
|
|
20
|
+
if (b.fontName !== undefined)
|
|
21
|
+
out.fontName = b.fontName;
|
|
22
|
+
if (b.color !== undefined)
|
|
23
|
+
out.color = b.color;
|
|
24
|
+
}
|
|
238
25
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
239
26
|
}
|
|
240
27
|
function chooseRunByOverlap(runs, start, end) {
|
|
@@ -253,36 +40,6 @@ function chooseRunByOverlap(runs, start, end) {
|
|
|
253
40
|
}
|
|
254
41
|
return bestRun;
|
|
255
42
|
}
|
|
256
|
-
function getWAttr(el, localName) {
|
|
257
|
-
return el.getAttributeNS(OOXML.W_NS, localName) ?? el.getAttribute(`w:${localName}`) ?? el.getAttribute(localName);
|
|
258
|
-
}
|
|
259
|
-
function extractDefinitionAddRunProps(run) {
|
|
260
|
-
if (!run)
|
|
261
|
-
return null;
|
|
262
|
-
const rPr = run.getElementsByTagNameNS(OOXML.W_NS, W.rPr).item(0);
|
|
263
|
-
if (!rPr)
|
|
264
|
-
return null;
|
|
265
|
-
const add = {};
|
|
266
|
-
const bEl = rPr.getElementsByTagNameNS(OOXML.W_NS, W.b).item(0);
|
|
267
|
-
if (bEl) {
|
|
268
|
-
const v = getWAttr(bEl, 'val');
|
|
269
|
-
if (v !== '0' && v !== 'false')
|
|
270
|
-
add.bold = true;
|
|
271
|
-
}
|
|
272
|
-
const iEl = rPr.getElementsByTagNameNS(OOXML.W_NS, W.i).item(0);
|
|
273
|
-
if (iEl) {
|
|
274
|
-
const v = getWAttr(iEl, 'val');
|
|
275
|
-
if (v !== '0' && v !== 'false')
|
|
276
|
-
add.italic = true;
|
|
277
|
-
}
|
|
278
|
-
const uEl = rPr.getElementsByTagNameNS(OOXML.W_NS, W.u).item(0);
|
|
279
|
-
if (uEl) {
|
|
280
|
-
const v = getWAttr(uEl, 'val');
|
|
281
|
-
if (!v || v !== 'none')
|
|
282
|
-
add.underline = v ?? true;
|
|
283
|
-
}
|
|
284
|
-
return Object.keys(add).length > 0 ? add : null;
|
|
285
|
-
}
|
|
286
43
|
function headerFormattingToAddRunProps(formatting) {
|
|
287
44
|
if (!formatting || typeof formatting !== 'object')
|
|
288
45
|
return null;
|
|
@@ -296,33 +53,6 @@ function headerFormattingToAddRunProps(formatting) {
|
|
|
296
53
|
add.underline = true;
|
|
297
54
|
return Object.keys(add).length > 0 ? add : null;
|
|
298
55
|
}
|
|
299
|
-
function findDefinitionRoleModelAddRunProps(session, anchorParagraphId) {
|
|
300
|
-
const { nodes } = session.doc.buildDocumentView({ includeSemanticTags: false });
|
|
301
|
-
const anchorIdx = nodes.findIndex((n) => n.id === anchorParagraphId);
|
|
302
|
-
if (anchorIdx < 0)
|
|
303
|
-
return null;
|
|
304
|
-
for (let delta = 0; delta < nodes.length; delta++) {
|
|
305
|
-
const candidates = [anchorIdx - delta, anchorIdx + delta];
|
|
306
|
-
for (const idx of candidates) {
|
|
307
|
-
if (idx < 0 || idx >= nodes.length)
|
|
308
|
-
continue;
|
|
309
|
-
const nid = nodes[idx].id;
|
|
310
|
-
const pEl = session.doc.getParagraphElementById(nid);
|
|
311
|
-
if (!pEl)
|
|
312
|
-
continue;
|
|
313
|
-
const text = session.doc.getParagraphTextById(nid) ?? '';
|
|
314
|
-
const span = findInlineDefinitionSpan(text);
|
|
315
|
-
if (!span)
|
|
316
|
-
continue;
|
|
317
|
-
const runs = getParagraphRuns(pEl);
|
|
318
|
-
const r = chooseRunByOverlap(runs, span.term_start, span.term_end);
|
|
319
|
-
const add = extractDefinitionAddRunProps(r);
|
|
320
|
-
if (add)
|
|
321
|
-
return add;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
return null;
|
|
325
|
-
}
|
|
326
56
|
function findHeaderRoleModelAddRunProps(session, anchorParagraphId) {
|
|
327
57
|
const { nodes } = session.doc.buildDocumentView({ includeSemanticTags: false });
|
|
328
58
|
const anchorIdx = nodes.findIndex((n) => n.id === anchorParagraphId);
|
|
@@ -341,90 +71,17 @@ function findHeaderRoleModelAddRunProps(session, anchorParagraphId) {
|
|
|
341
71
|
}
|
|
342
72
|
return null;
|
|
343
73
|
}
|
|
344
|
-
function
|
|
345
|
-
const chunks = [];
|
|
346
|
-
for (const seg of segments) {
|
|
347
|
-
if (!seg.text)
|
|
348
|
-
continue;
|
|
349
|
-
if (legacyDefinitionTags && seg.definition) {
|
|
350
|
-
const term = stripOuterQuotes(seg.text);
|
|
351
|
-
chunks.push(`"${term}"`);
|
|
352
|
-
}
|
|
353
|
-
else {
|
|
354
|
-
chunks.push(seg.text);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
return chunks.join('');
|
|
358
|
-
}
|
|
359
|
-
function buildReplacementPartsForInsert(segments, plainText, templateRun, legacyDefinitionTags, defAddProps, headerAddProps) {
|
|
74
|
+
function buildReplacementPartsForInsert(segments, templateRun, headerAddProps) {
|
|
360
75
|
const parts = [];
|
|
361
|
-
const hasTaggedDefinition = legacyDefinitionTags && segments.some((s) => s.definition);
|
|
362
|
-
const autoDefSpan = (!hasTaggedDefinition && defAddProps)
|
|
363
|
-
? findInlineDefinitionSpan(plainText)
|
|
364
|
-
: null;
|
|
365
|
-
let textOffset = 0;
|
|
366
76
|
for (const seg of segments) {
|
|
367
77
|
if (!seg.text)
|
|
368
78
|
continue;
|
|
369
79
|
const segAdd = mergeAddRunProps(segmentAddRunProps(seg), seg.header ? headerAddProps : null);
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
parts.push({
|
|
376
|
-
text: term,
|
|
377
|
-
templateRun: templateRun ?? undefined,
|
|
378
|
-
addRunProps: mergeAddRunProps(defAddProps, segAdd),
|
|
379
|
-
});
|
|
380
|
-
parts.push({ text: '"', templateRun: templateRun ?? undefined, addRunProps: segAdd });
|
|
381
|
-
textOffset += (`"${term}"`).length;
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
const segText = seg.text;
|
|
385
|
-
const segStart = textOffset;
|
|
386
|
-
const segEnd = segStart + segText.length;
|
|
387
|
-
textOffset = segEnd;
|
|
388
|
-
if (autoDefSpan
|
|
389
|
-
&& autoDefSpan.term_end > autoDefSpan.term_start
|
|
390
|
-
&& Math.min(segEnd, autoDefSpan.term_end) > Math.max(segStart, autoDefSpan.term_start)) {
|
|
391
|
-
const overlapStart = Math.max(segStart, autoDefSpan.term_start);
|
|
392
|
-
const overlapEnd = Math.min(segEnd, autoDefSpan.term_end);
|
|
393
|
-
const relStart = overlapStart - segStart;
|
|
394
|
-
const relEnd = overlapEnd - segStart;
|
|
395
|
-
const before = segText.slice(0, relStart);
|
|
396
|
-
const term = segText.slice(relStart, relEnd);
|
|
397
|
-
const after = segText.slice(relEnd);
|
|
398
|
-
if (before) {
|
|
399
|
-
parts.push({
|
|
400
|
-
text: before,
|
|
401
|
-
templateRun: templateRun ?? undefined,
|
|
402
|
-
addRunProps: segAdd,
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
if (term) {
|
|
406
|
-
parts.push({
|
|
407
|
-
text: term,
|
|
408
|
-
templateRun: templateRun ?? undefined,
|
|
409
|
-
addRunProps: mergeAddRunProps(segAdd, defAddProps),
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
-
if (after) {
|
|
413
|
-
parts.push({
|
|
414
|
-
text: after,
|
|
415
|
-
templateRun: templateRun ?? undefined,
|
|
416
|
-
addRunProps: segAdd,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
parts.push({
|
|
422
|
-
text: segText,
|
|
423
|
-
templateRun: templateRun ?? undefined,
|
|
424
|
-
addRunProps: segAdd,
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
}
|
|
80
|
+
parts.push({
|
|
81
|
+
text: seg.text,
|
|
82
|
+
templateRun: templateRun ?? undefined,
|
|
83
|
+
addRunProps: segAdd,
|
|
84
|
+
});
|
|
428
85
|
}
|
|
429
86
|
return parts.some((p) => !!p.addRunProps) ? parts : null;
|
|
430
87
|
}
|
|
@@ -436,36 +93,50 @@ export async function insertParagraph(manager, params) {
|
|
|
436
93
|
const { session, metadata } = resolved;
|
|
437
94
|
const positionUpper = (params.position ?? 'AFTER').toUpperCase();
|
|
438
95
|
if (positionUpper !== 'BEFORE' && positionUpper !== 'AFTER') {
|
|
439
|
-
return err('INVALID_POSITION', `Invalid position: ${params.position}. Must be 'BEFORE' or 'AFTER'
|
|
96
|
+
return err('INVALID_POSITION', `Invalid position: ${params.position}. Must be 'BEFORE' or 'AFTER'.`);
|
|
440
97
|
}
|
|
441
|
-
// Ensure anchor exists.
|
|
442
98
|
const anchorText = session.doc.getParagraphTextById(params.positional_anchor_node_id);
|
|
443
99
|
if (anchorText === null) {
|
|
444
|
-
return err('ANCHOR_NOT_FOUND', `Paragraph ID ${params.positional_anchor_node_id} not found in document
|
|
100
|
+
return err('ANCHOR_NOT_FOUND', `Paragraph ID ${params.positional_anchor_node_id} not found in document`);
|
|
101
|
+
}
|
|
102
|
+
let styleSourceId = params.style_source_id;
|
|
103
|
+
if (!styleSourceId && params.target_style) {
|
|
104
|
+
const { nodes } = session.doc.buildDocumentView({ includeSemanticTags: false });
|
|
105
|
+
const anchorIdx = nodes.findIndex((n) => n.id === params.positional_anchor_node_id);
|
|
106
|
+
if (anchorIdx >= 0) {
|
|
107
|
+
let bestDist = Infinity;
|
|
108
|
+
let bestId = null;
|
|
109
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
110
|
+
if (nodes[i].style === params.target_style) {
|
|
111
|
+
const dist = Math.abs(i - anchorIdx);
|
|
112
|
+
if (dist < bestDist) {
|
|
113
|
+
bestDist = dist;
|
|
114
|
+
bestId = nodes[i].id;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (bestId)
|
|
119
|
+
styleSourceId = bestId;
|
|
120
|
+
}
|
|
445
121
|
}
|
|
446
|
-
const legacyDefinitionTags = useLegacyDefinitionTags();
|
|
447
122
|
let inputText = params.new_string;
|
|
448
|
-
if (!legacyDefinitionTags && hasDefinitionTags(inputText))
|
|
449
|
-
inputText = stripDefinitionTags(inputText);
|
|
450
|
-
// Strip <a> tags — hyperlinks are read-only and cannot be created via insert_paragraph.
|
|
451
123
|
if (hasHyperlinkTags(inputText))
|
|
452
124
|
inputText = stripHyperlinkTags(inputText);
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
return
|
|
460
|
-
}
|
|
461
|
-
const plainParagraphs =
|
|
125
|
+
const paragraphInputs = inputText.replace(/\r\n/g, '\n').split(/\n{2,}/);
|
|
126
|
+
let parsedParagraphs;
|
|
127
|
+
try {
|
|
128
|
+
parsedParagraphs = paragraphInputs.map((p) => splitTaggedText(p));
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
return err(errorMessage(e), `Tag parse error in new_string: ${errorMessage(e)}`);
|
|
132
|
+
}
|
|
133
|
+
const plainParagraphs = paragraphInputs.map((p) => stripAllInlineTags(p));
|
|
462
134
|
const res = session.doc.insertParagraph({
|
|
463
135
|
positionalAnchorNodeId: params.positional_anchor_node_id,
|
|
464
136
|
relativePosition: positionUpper,
|
|
465
137
|
newText: plainParagraphs.join('\n\n'),
|
|
466
|
-
styleSourceId:
|
|
138
|
+
styleSourceId: styleSourceId,
|
|
467
139
|
});
|
|
468
|
-
const defAddProps = findDefinitionRoleModelAddRunProps(session, params.positional_anchor_node_id);
|
|
469
140
|
const needsHeaderRoleModel = parsedParagraphs.some((segs) => segs.some((s) => s.header));
|
|
470
141
|
const headerAddProps = needsHeaderRoleModel
|
|
471
142
|
? findHeaderRoleModelAddRunProps(session, params.positional_anchor_node_id)
|
|
@@ -478,17 +149,11 @@ export async function insertParagraph(manager, params) {
|
|
|
478
149
|
if (!pEl)
|
|
479
150
|
continue;
|
|
480
151
|
const runs = getParagraphRuns(pEl);
|
|
481
|
-
const templateRun = chooseRunByOverlap(runs, 0, Math.max(plainText.length, 1))
|
|
482
|
-
|
|
483
|
-
?? null;
|
|
484
|
-
const replacementParts = buildReplacementPartsForInsert(segs, plainText, templateRun, legacyDefinitionTags, defAddProps, headerAddProps);
|
|
152
|
+
const templateRun = chooseRunByOverlap(runs, 0, Math.max(plainText.length, 1)) ?? runs[0]?.r ?? null;
|
|
153
|
+
const replacementParts = buildReplacementPartsForInsert(segs, templateRun, headerAddProps);
|
|
485
154
|
if (!replacementParts || replacementParts.length === 0)
|
|
486
155
|
continue;
|
|
487
|
-
session.doc.replaceText({
|
|
488
|
-
targetParagraphId: newPid,
|
|
489
|
-
findText: plainText,
|
|
490
|
-
replaceText: replacementParts,
|
|
491
|
-
});
|
|
156
|
+
session.doc.replaceText({ targetParagraphId: newPid, findText: plainText, replaceText: replacementParts });
|
|
492
157
|
}
|
|
493
158
|
manager.markEdited(session);
|
|
494
159
|
const responseData = {
|
|
@@ -507,8 +172,7 @@ export async function insertParagraph(manager, params) {
|
|
|
507
172
|
return ok(mergeSessionResolutionMetadata(responseData, metadata));
|
|
508
173
|
}
|
|
509
174
|
catch (e) {
|
|
510
|
-
|
|
511
|
-
return err('INSERT_ERROR', `Failed to insert paragraph: ${msg}`, 'Use grep or read_file to find valid anchor paragraph IDs.');
|
|
175
|
+
return err('INSERT_ERROR', `Failed to insert paragraph: ${errorMessage(e)}`);
|
|
512
176
|
}
|
|
513
177
|
}
|
|
514
178
|
//# sourceMappingURL=insert_paragraph.js.map
|