myrole-docx-editor 0.2.0 → 0.3.1
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/assistant-mcp.mjs +192 -0
- package/dist/chunks/{sdk-BM5tI24s.js → sdk-Bi8qAaV_.js} +8543 -8045
- package/dist/chunks/sdk-Bi8qAaV_.js.map +1 -0
- package/dist/chunks/{vars-blockly-BQPk_GUT.js → vars-blockly-BVG2ZfAW.js} +2 -2
- package/dist/chunks/{vars-blockly-BQPk_GUT.js.map → vars-blockly-BVG2ZfAW.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/react.js +1 -1
- package/dist/types/packages/docx-editor/src/assistant.d.ts +26 -0
- package/dist/types/packages/docx-editor/src/commands.d.ts +1 -1
- package/dist/types/packages/docx-editor/src/editor.d.ts +13 -2
- package/dist/types/packages/docx-editor/src/html.d.ts +3 -2
- package/dist/types/packages/docx-editor/src/index.d.ts +1 -0
- package/dist/types/packages/docx-editor/src/sdk.d.ts +5 -0
- package/dist/types/packages/docx-editor/src/vars-complete.d.ts +3 -3
- package/dist/types/packages/docx-editor/src/vars-library.d.ts +14 -0
- package/dist/types/packages/docx-editor/src/vars-panel.d.ts +2 -0
- package/dist/types/packages/docx-model/src/editor.d.ts +2 -0
- package/dist/types/packages/docx-render/src/index.d.ts +1 -1
- package/dist/types/packages/docx-render/src/render-api.d.ts +2 -1
- package/dist/types/packages/docx-render/src/types.d.ts +16 -0
- package/dist/types/packages/docx-tags/src/grammar.d.ts +1 -0
- package/package.json +11 -6
- package/dist/chunks/sdk-BM5tI24s.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as s from "blockly";
|
|
2
|
-
import { k as p, T as u, m, n as f, o as g, q as h } from "./sdk-
|
|
2
|
+
import { k as p, T as u, m, n as f, o as g, q as h } from "./sdk-Bi8qAaV_.js";
|
|
3
3
|
let r = !1;
|
|
4
4
|
function b(o, n, i) {
|
|
5
5
|
r || (p(), r = !0), o.replaceChildren();
|
|
@@ -39,4 +39,4 @@ function b(o, n, i) {
|
|
|
39
39
|
export {
|
|
40
40
|
b as mountBlockly
|
|
41
41
|
};
|
|
42
|
-
//# sourceMappingURL=vars-blockly-
|
|
42
|
+
//# sourceMappingURL=vars-blockly-BVG2ZfAW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vars-blockly-
|
|
1
|
+
{"version":3,"file":"vars-blockly-BVG2ZfAW.js","sources":["../../src/vars-blockly.ts"],"sourcesContent":["import * as Blockly from 'blockly'\nimport {\n decorate, defineBlocks, fieldLibrary, setFields, THEME, TOOLBOX,\n type BlockJson,\n} from '@myrole/docx-vars'\nimport type { Tag } from '@myrole/docx-tags'\n\n/**\n * Le mode Blockly, chargé à la demande.\n *\n * Le canvas ne se replie pas — c'est ce qui a fait choisir le rendu DOM par\n * défaut — mais il sait ce que le DOM ne fait pas encore aussi bien :\n * restructurer librement une expression au glisser-déposer, avec sa poubelle,\n * son annulation et ses connexions typées.\n *\n * Il vit dans son propre module pour ne peser que si on l'ouvre : un\n * mégaoctet et demi qu'un utilisateur qui ne bascule jamais ne télécharge pas.\n */\n\nlet defined = false\n\nexport interface BlocklyView {\n load(tree: BlockJson): void\n read(): BlockJson | null\n resize(): void\n dispose(): void\n}\n\nexport function mountBlockly(\n holder: HTMLElement, onChange: () => void, tags: () => Tag[],\n): BlocklyView {\n if (!defined) { defineBlocks(); defined = true }\n holder.replaceChildren()\n const host = document.createElement('div')\n host.className = 'vp-canvas-host'\n holder.append(host)\n\n const ws = Blockly.inject(host, {\n // La boîte à outils : sans elle, on peut lire une expression et la\n // rebrancher, mais pas y AJOUTER quoi que ce soit — c'est la moitié de ce\n // qu'on vient chercher dans un canvas de blocs.\n toolbox: TOOLBOX,\n theme: THEME,\n renderer: 'geras',\n trashcan: true,\n sounds: false,\n grid: { spacing: 20, length: 1, colour: '#e8e9ed', snap: false },\n zoom: { controls: true, wheel: true, startScale: 0.95, minScale: 0.3, maxScale: 2 },\n move: { scrollbars: true, drag: true, wheel: true },\n })\n ws.addChangeListener((e) => { if (!e.isUiEvent) onChange() })\n\n return {\n load(tree) {\n // `setFields` alimente le sélecteur du bloc « champ » : sans lui, un clic\n // sur un champ n'ouvre rien.\n const groups = fieldLibrary(tags())\n setFields(groups.flatMap((g) => g.fields.map((f) => ({ path: f.path, label: f.label }))))\n Blockly.serialization.workspaces.load({ blocks: { languageVersion: 0, blocks: [tree] } }, ws)\n decorate(ws)\n Blockly.svgResize(ws)\n },\n read() {\n const state = Blockly.serialization.workspaces.save(ws) as {\n blocks?: { blocks?: BlockJson[] }\n }\n return state?.blocks?.blocks?.[0] ?? null\n },\n resize() { Blockly.svgResize(ws) },\n dispose() { ws.dispose() },\n }\n}\n"],"names":["defined","mountBlockly","holder","onChange","tags","defineBlocks","host","ws","Blockly","TOOLBOX","THEME","e","tree","groups","fieldLibrary","setFields","g","f","decorate"],"mappings":";;AAmBA,IAAIA,IAAU;AASP,SAASC,EACdC,GAAqBC,GAAsBC,GAC9B;AACb,EAAKJ,MAAWK,EAAA,GAAgBL,IAAU,KAC1CE,EAAO,gBAAA;AACP,QAAMI,IAAO,SAAS,cAAc,KAAK;AACzC,EAAAA,EAAK,YAAY,kBACjBJ,EAAO,OAAOI,CAAI;AAElB,QAAMC,IAAKC,EAAQ,OAAOF,GAAM;AAAA;AAAA;AAAA;AAAA,IAI9B,SAASG;AAAA,IACT,OAAOC;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM,EAAE,SAAS,IAAI,QAAQ,GAAG,QAAQ,WAAW,MAAM,GAAA;AAAA,IACzD,MAAM,EAAE,UAAU,IAAM,OAAO,IAAM,YAAY,MAAM,UAAU,KAAK,UAAU,EAAA;AAAA,IAChF,MAAM,EAAE,YAAY,IAAM,MAAM,IAAM,OAAO,GAAA;AAAA,EAAK,CACnD;AACD,SAAAH,EAAG,kBAAkB,CAACI,MAAM;AAAE,IAAKA,EAAE,aAAWR,EAAA;AAAA,EAAW,CAAC,GAErD;AAAA,IACL,KAAKS,GAAM;AAGT,YAAMC,IAASC,EAAaV,GAAM;AAClC,MAAAW,EAAUF,EAAO,QAAQ,CAACG,MAAMA,EAAE,OAAO,IAAI,CAACC,OAAO,EAAE,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAA,EAAQ,CAAC,CAAC,GACxFT,EAAQ,cAAc,WAAW,KAAK,EAAE,QAAQ,EAAE,iBAAiB,GAAG,QAAQ,CAACI,CAAI,EAAA,EAAE,GAAKL,CAAE,GAC5FW,EAASX,CAAE,GACXC,EAAQ,UAAUD,CAAE;AAAA,IACtB;AAAA,IACA,OAAO;AAIL,aAHcC,EAAQ,cAAc,WAAW,KAAKD,CAAE,GAGxC,QAAQ,SAAS,CAAC,KAAK;AAAA,IACvC;AAAA,IACA,SAAS;AAAE,MAAAC,EAAQ,UAAUD,CAAE;AAAA,IAAE;AAAA,IACjC,UAAU;AAAE,MAAAA,EAAG,QAAA;AAAA,IAAU;AAAA,EAAA;AAE7B;"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as f, r as m, e as w, f as p, p as u, l as y, a as g, b as h, c as x } from "./chunks/sdk-
|
|
2
|
-
import { d as R, g as b, h as U, j, s as A } from "./chunks/sdk-
|
|
1
|
+
import { i as f, r as m, e as w, f as p, p as u, l as y, a as g, b as h, c as x } from "./chunks/sdk-Bi8qAaV_.js";
|
|
2
|
+
import { d as R, g as b, h as U, j, s as A } from "./chunks/sdk-Bi8qAaV_.js";
|
|
3
3
|
async function P(a, o, r = {}) {
|
|
4
4
|
const i = performance.now(), [c] = await Promise.all([
|
|
5
5
|
typeof a == "string" ? fetch(a).then((e) => e.ok ? e.arrayBuffer() : Promise.reject(new Error(`${e.status} ${a}`))) : Promise.resolve(a),
|
package/dist/react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as h } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as v, useRef as o, useEffect as a } from "react";
|
|
3
|
-
import { d as y } from "./chunks/sdk-
|
|
3
|
+
import { d as y } from "./chunks/sdk-Bi8qAaV_.js";
|
|
4
4
|
const s = v(function({ src: u, className: b, style: S, onReady: g, ...e }, f) {
|
|
5
5
|
const l = o(null), c = o(null), n = o(e);
|
|
6
6
|
n.current = e;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DocxEditorHandle } from './sdk';
|
|
2
|
+
/**
|
|
3
|
+
* The editor as the tool provider of a LOCAL MCP server.
|
|
4
|
+
*
|
|
5
|
+
* The tools run here, on the document open in this tab; `scripts/assistant-mcp.ts`
|
|
6
|
+
* only relays them between the MCP client (Claude Code) and the tab. Exactly one
|
|
7
|
+
* tab is connected at a time: the one where the user last pressed « Assistant ».
|
|
8
|
+
* The model never chooses which editor it drives, and it never sees a URL, a
|
|
9
|
+
* token or the package — only paragraph text, addressed by index.
|
|
10
|
+
*
|
|
11
|
+
* ponytail: body paragraphs only; headers, footers and notes when someone needs them.
|
|
12
|
+
*/
|
|
13
|
+
export interface AssistantTool {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
inputSchema: Record<string, unknown>;
|
|
17
|
+
readOnly: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface AssistantOptions {
|
|
20
|
+
/** the relay started by `scripts/assistant-mcp.ts` */
|
|
21
|
+
url?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare const ASSISTANT_TOOLS: AssistantTool[];
|
|
24
|
+
export declare function runTool(handle: DocxEditorHandle, name: string, args: Record<string, unknown>): unknown;
|
|
25
|
+
/** The « Assistant » button of the status bar, and the connection it opens. */
|
|
26
|
+
export declare function mountAssistant(status: HTMLElement, handle: DocxEditorHandle, options?: AssistantOptions): () => void;
|
|
@@ -11,7 +11,7 @@ import type { Command } from './editor';
|
|
|
11
11
|
*/
|
|
12
12
|
export declare const FONTS: string[];
|
|
13
13
|
export declare const SIZES: number[];
|
|
14
|
-
/**
|
|
14
|
+
/** Alignment uses the same optical grid as the other ribbon actions. */
|
|
15
15
|
export declare function alignIcon(align: string): SVGElement;
|
|
16
16
|
/**
|
|
17
17
|
* Insere une variable au curseur, choisie dans la bibliotheque du document.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CellPatch, type MarginPatch, type DocViews, type DocxDocument, type DocPos, type EditContext, type PageSetup, type PageSetupPatch, type ParaPatch, type RunPatch } from '../../docx-model/src/index';
|
|
2
|
-
import { type ImageRect, type LineTrace, type MarkRect, type ResumeState, type SelRect, type TableRect } from '../../docx-render/src/index';
|
|
2
|
+
import { type ImageRect, type LineTrace, type MarkRect, type ResumeState, type SelRect, type TableRect, type CellRect } from '../../docx-render/src/index';
|
|
3
3
|
export interface EditorHooks {
|
|
4
4
|
/** appelé après chaque composition, avec ce qu'il faut pour la barre d'outils */
|
|
5
5
|
onContext?(ctx: EditContext | null, hasSelection: boolean): void;
|
|
@@ -19,6 +19,7 @@ export interface ComposeOut {
|
|
|
19
19
|
* peindre : c'est l'hôte qui vient poser dedans. Voir extensions.md.
|
|
20
20
|
*/
|
|
21
21
|
mark(r: MarkRect): void;
|
|
22
|
+
cell(r: CellRect): void;
|
|
22
23
|
}
|
|
23
24
|
/** Ce que l'hôte fournit : comment composer le document, et où. */
|
|
24
25
|
export interface EditorSetup {
|
|
@@ -117,6 +118,15 @@ export declare function createEditor(setup: EditorSetup): {
|
|
|
117
118
|
width: number;
|
|
118
119
|
height: number;
|
|
119
120
|
}[];
|
|
121
|
+
cellRects: () => {
|
|
122
|
+
para: number;
|
|
123
|
+
page: number;
|
|
124
|
+
x: number;
|
|
125
|
+
y: number;
|
|
126
|
+
width: number;
|
|
127
|
+
height: number;
|
|
128
|
+
}[];
|
|
129
|
+
selectedCells: () => number[];
|
|
120
130
|
/** Objet sélectionné — une image ou un tableau pris comme un tout, ou `null`. */
|
|
121
131
|
selectedObject: () => {
|
|
122
132
|
kind: "image";
|
|
@@ -178,11 +188,12 @@ export declare function createEditor(setup: EditorSetup): {
|
|
|
178
188
|
setListLevel(level: number): void;
|
|
179
189
|
restartList(start?: number): boolean;
|
|
180
190
|
setList(ordered: boolean | null): void;
|
|
191
|
+
clearTableBorders(): boolean;
|
|
181
192
|
formatCell(patch: CellPatch): boolean;
|
|
182
193
|
mergeNextCell(): boolean;
|
|
183
194
|
replaceAll(query: string, replacement: string, matchCase?: boolean): number;
|
|
184
195
|
/** Insère du texte au curseur, ou remplace la sélection. */
|
|
185
|
-
insert: (text: string) => void;
|
|
196
|
+
insert: (text: string, patch?: RunPatch) => void;
|
|
186
197
|
deleteSelection: () => void;
|
|
187
198
|
deleteObject: () => void;
|
|
188
199
|
splitAtCaret: () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PastedBlock } from '../../docx-model/src/index';
|
|
1
|
+
import type { PastedBlock, PastedRun, RunPatch } from '../../docx-model/src/index';
|
|
2
2
|
/** Décode une URI `data:` en octets, ou rend `null` si ce n'en est pas une. */
|
|
3
3
|
export declare function dataUri(src: string): {
|
|
4
4
|
data: Uint8Array;
|
|
@@ -10,4 +10,5 @@ export declare function dataUri(src: string): {
|
|
|
10
10
|
* Les espaces sont normalisées comme le ferait un navigateur — le HTML de Word
|
|
11
11
|
* est plein de retours à la ligne et d'indentation qui ne sont pas du texte.
|
|
12
12
|
*/
|
|
13
|
-
export declare function htmlToBlocks(html: string): PastedBlock[];
|
|
13
|
+
export declare function htmlToBlocks(html: string, baseStyle?: RunPatch): PastedBlock[];
|
|
14
|
+
export declare function runsToHtml(paragraphs: PastedRun[][]): string;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export { createDocxEditor } from './sdk';
|
|
11
11
|
export type { DocxEditorHandle, DocxEditorOptions, DocxEditorUiOptions, DocxEditorEvent, ChromeMode, Theme } from './sdk';
|
|
12
12
|
export type { FeedbackReport, FeedbackContext, FeedbackOptions } from './feedback';
|
|
13
|
+
export type { AssistantOptions } from './assistant';
|
|
13
14
|
export { renderDocx } from './embed';
|
|
14
15
|
export type { Rendered } from './embed';
|
|
15
16
|
export { installFonts, defaultFontsUrl } from './fonts';
|
|
@@ -21,6 +21,7 @@ import { type CommentRange } from './comments';
|
|
|
21
21
|
import { type Panel, type DocxEditorUiOptions } from './ui/shell';
|
|
22
22
|
import { type Draft } from './drafts';
|
|
23
23
|
import { type FeedbackOptions } from './feedback';
|
|
24
|
+
import { type AssistantOptions } from './assistant';
|
|
24
25
|
export type ChromeMode = 'full' | 'viewer' | 'none';
|
|
25
26
|
export type Theme = 'light' | 'dark' | 'system';
|
|
26
27
|
export type { DocxEditorUiOptions } from './ui/shell';
|
|
@@ -64,10 +65,14 @@ export interface DocxEditorOptions {
|
|
|
64
65
|
panel?: Panel | null;
|
|
65
66
|
/** the fields and snippets the application offers, beyond what the document already uses */
|
|
66
67
|
library?: LibraryExtras;
|
|
68
|
+
/** Optional host loader, called once per editor; the host owns the route and authentication. */
|
|
69
|
+
loadLibrary?: () => Promise<unknown>;
|
|
67
70
|
/** show Word's comments as marks on the text (default true) */
|
|
68
71
|
comments?: boolean;
|
|
69
72
|
/** Opt-in feedback button: true exports JSON; onSubmit routes the report to the host. */
|
|
70
73
|
feedback?: boolean | FeedbackOptions;
|
|
74
|
+
/** Opt-in « Assistant » button: lends this tab's document to the local MCP relay (`scripts/assistant-mcp.ts`). */
|
|
75
|
+
assistant?: boolean | AssistantOptions;
|
|
71
76
|
}
|
|
72
77
|
export interface DocxEditorHandle {
|
|
73
78
|
load(src: ArrayBuffer | Uint8Array | Blob | string, options?: {
|
|
@@ -8,8 +8,7 @@ import type { Tag } from '../../docx-tags/src/index';
|
|
|
8
8
|
*
|
|
9
9
|
* - **dans un tag ouvert** (`{{` ou `{%` sans fermeture avant le curseur) :
|
|
10
10
|
* champs et fonctions, c'est-à-dire ce qui a le droit d'y figurer ;
|
|
11
|
-
* - **après un `/` en début de mot** :
|
|
12
|
-
* depuis que Notion en a fait une convention.
|
|
11
|
+
* - **après un `/` en début de mot** : champs, fonctions et extraits.
|
|
13
12
|
*
|
|
14
13
|
* Le clavier passe AVANT l'éditeur : la capture est posée sur le champ de
|
|
15
14
|
* frappe, et les flèches, Entrée, Tab et Échap ne redescendent pas jusqu'à lui
|
|
@@ -30,7 +29,7 @@ export interface CompleteHost {
|
|
|
30
29
|
off: number;
|
|
31
30
|
} | null;
|
|
32
31
|
/** Remplace une plage du paragraphe courant par ce texte. */
|
|
33
|
-
replace(para: number, from: number, to: number, text: string): void;
|
|
32
|
+
replace(para: number, from: number, to: number, text: string, caretOffset?: number): void;
|
|
34
33
|
/** Where to hang the list; by default under the page's caret. */
|
|
35
34
|
anchor?(): DOMRect | undefined;
|
|
36
35
|
}
|
|
@@ -51,6 +50,7 @@ interface Context {
|
|
|
51
50
|
kinds: LibEntry['kind'][];
|
|
52
51
|
/** ce qu'on insère : le code entier, ou seulement l'expression */
|
|
53
52
|
as: 'code' | 'expr';
|
|
53
|
+
padded?: boolean;
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Lit le contexte de frappe autour du curseur.
|
|
@@ -23,13 +23,23 @@ export interface LibEntry {
|
|
|
23
23
|
/** Ce qu'on met dans une expression, sans les accolades. */
|
|
24
24
|
expr: string;
|
|
25
25
|
desc?: string;
|
|
26
|
+
/** Example rendered value, such as RODET; informational metadata, separate from inserted code. */
|
|
27
|
+
output?: string;
|
|
28
|
+
tags?: string[];
|
|
29
|
+
deprecated?: boolean;
|
|
26
30
|
}
|
|
27
31
|
/** A field the host declares — what the matrix MAY use, beyond what it already does. */
|
|
28
32
|
export interface LibraryField {
|
|
29
33
|
/** `salarie.nom` */
|
|
30
34
|
path: string;
|
|
35
|
+
/** Exact insertion text supplied by the variable catalog. */
|
|
36
|
+
copy?: string;
|
|
37
|
+
tags?: string[];
|
|
38
|
+
deprecated?: boolean;
|
|
31
39
|
label?: string;
|
|
32
40
|
desc?: string;
|
|
41
|
+
/** Example rendered value, such as RODET; informational metadata, separate from inserted code. */
|
|
42
|
+
output?: string;
|
|
33
43
|
}
|
|
34
44
|
/** A snippet the host declares — a whole block, ready to paste. */
|
|
35
45
|
export interface LibrarySnippet {
|
|
@@ -38,6 +48,8 @@ export interface LibrarySnippet {
|
|
|
38
48
|
code: string;
|
|
39
49
|
category?: string;
|
|
40
50
|
desc?: string;
|
|
51
|
+
/** Example rendered value, such as RODET; informational metadata, separate from inserted code. */
|
|
52
|
+
output?: string;
|
|
41
53
|
}
|
|
42
54
|
export interface LibraryExtras {
|
|
43
55
|
fields?: LibraryField[];
|
|
@@ -45,6 +57,8 @@ export interface LibraryExtras {
|
|
|
45
57
|
/** keep the built-in snippets next to the host's (default true) */
|
|
46
58
|
builtinSnippets?: boolean;
|
|
47
59
|
}
|
|
60
|
+
/** Validate host-loaded JSON before replacing any existing catalog entries. */
|
|
61
|
+
export declare function parseLibrary(data: unknown): LibraryExtras;
|
|
48
62
|
/** Each editor supplies its own library. */
|
|
49
63
|
export declare function libraryEntries(tags: Tag[], extras?: LibraryExtras): LibEntry[];
|
|
50
64
|
/** Filtre sans accent ni casse — on cherche « majore », on trouve « Majoré ». */
|
|
@@ -35,6 +35,8 @@ export interface VarsPanel {
|
|
|
35
35
|
show(tag: Tag | null): void;
|
|
36
36
|
/** Ouvre la bibliothèque, sans tag. */
|
|
37
37
|
library(): void;
|
|
38
|
+
/** Refresh catalog data without opening the panel or replacing the tag being edited. */
|
|
39
|
+
refreshLibrary(): void;
|
|
38
40
|
current(): Tag | null;
|
|
39
41
|
open(): boolean;
|
|
40
42
|
destroy(): void;
|
|
@@ -294,6 +294,8 @@ export interface CellPatch {
|
|
|
294
294
|
borderPt?: number;
|
|
295
295
|
borderColor?: string;
|
|
296
296
|
}
|
|
297
|
+
/** Explicit nil borders suppress style inheritance; nested tables keep their own grid. */
|
|
298
|
+
export declare function clearTableBorders(doc: DocxDocument, para: number): boolean;
|
|
297
299
|
export declare function formatCell(doc: DocxDocument, para: number, patch: CellPatch): boolean;
|
|
298
300
|
/** Merge with the next cell without dropping its paragraphs. Vertical merges are protected. */
|
|
299
301
|
export declare function mergeNextCell(doc: DocxDocument, para: number): boolean;
|
|
@@ -2,7 +2,7 @@ export { render } from './renderer';
|
|
|
2
2
|
export { PT_PX } from './types';
|
|
3
3
|
export { decodeImage, preloadImages } from './images';
|
|
4
4
|
export type { RenderInput, RenderOptions, ResumeState } from './render-api';
|
|
5
|
-
export type { BreakTrace, ImageMap, ImageRect, LineTrace, MarkRect, PlacedTextBox, RowTrace, RuleTrace, SectionParts, TableRect, } from './types';
|
|
5
|
+
export type { BreakTrace, ImageMap, ImageRect, LineTrace, MarkRect, PlacedTextBox, RowTrace, RuleTrace, SectionParts, TableRect, CellRect, } from './types';
|
|
6
6
|
export { caretAt, editableLines, hitTest, ordered, paraRange, samePos, selectionRects, verticalStep, } from './hit';
|
|
7
7
|
export type { CaretRect, DocPos, HitMode, SelRect } from './hit';
|
|
8
8
|
export { buildRenderInput, footnoteContent, partParagraphs, styleParagraphs } from './document';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BodyBlock, ListInfo, PageSetup, StyledParagraph, TableInfo } from '../../docx-model/src/index';
|
|
2
2
|
import type { SideWrap } from './floating';
|
|
3
|
-
import type { BreakTrace, Footnotes, ImageMap, ImageRect, LineTrace, MarkRect, PlacedTextBox, RowTrace, RuleTrace, SectionParts, TableRect } from './types';
|
|
3
|
+
import type { BreakTrace, Footnotes, ImageMap, ImageRect, LineTrace, MarkRect, PlacedTextBox, RowTrace, RuleTrace, SectionParts, TableRect, CellRect } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Public input of the document compositor.
|
|
6
6
|
*
|
|
@@ -39,6 +39,7 @@ export interface RenderOptions {
|
|
|
39
39
|
onLine?(line: LineTrace): void;
|
|
40
40
|
onImage?(rect: ImageRect): void;
|
|
41
41
|
onTable?(rect: TableRect): void;
|
|
42
|
+
onCell?(rect: CellRect): void;
|
|
42
43
|
/** Include empty lines in traces (needed by the editor, not the bench). */
|
|
43
44
|
traceEmpty?: boolean;
|
|
44
45
|
onRule?(rule: RuleTrace): void;
|
|
@@ -136,6 +136,7 @@ export interface DrawCtx {
|
|
|
136
136
|
onLine?(line: LineTrace): void;
|
|
137
137
|
/** publie le rectangle de chaque image dessinée — la souris n'a que ça */
|
|
138
138
|
onImage?(rect: ImageRect): void;
|
|
139
|
+
onCell?(rect: CellRect): void;
|
|
139
140
|
/** Internal content tracking, independent of public traces and bitmap decoding.
|
|
140
141
|
* Wire only into real body/cell paint contexts, never speculative probes. */
|
|
141
142
|
onContent?(page: number): void;
|
|
@@ -353,6 +354,12 @@ export interface Footnotes {
|
|
|
353
354
|
}>;
|
|
354
355
|
}
|
|
355
356
|
export interface LineTrace {
|
|
357
|
+
/** Editing bounds include whitespace omitted from the ink trace. */
|
|
358
|
+
caretRange?: {
|
|
359
|
+
from: number;
|
|
360
|
+
to: number;
|
|
361
|
+
endX: number;
|
|
362
|
+
};
|
|
356
363
|
/**
|
|
357
364
|
* Index du BLOC dont vient cette ligne.
|
|
358
365
|
*
|
|
@@ -479,6 +486,15 @@ export interface TableRect {
|
|
|
479
486
|
width: number;
|
|
480
487
|
height: number;
|
|
481
488
|
}
|
|
489
|
+
/** A cell fragment on one page, addressed by its first body paragraph. */
|
|
490
|
+
export interface CellRect {
|
|
491
|
+
para: number;
|
|
492
|
+
page: number;
|
|
493
|
+
x: number;
|
|
494
|
+
y: number;
|
|
495
|
+
width: number;
|
|
496
|
+
height: number;
|
|
497
|
+
}
|
|
482
498
|
/** Rectangle dessiné pour un run marqué, en px CSS relatifs à sa page. */
|
|
483
499
|
export interface MarkRect {
|
|
484
500
|
mark: string;
|
|
@@ -18,6 +18,7 @@ export declare const DIRECTIVES: {
|
|
|
18
18
|
readonly 'inline-section': "open";
|
|
19
19
|
readonly 'style-section': "open";
|
|
20
20
|
readonly 'else-section': "middle";
|
|
21
|
+
readonly 'else-if-section': "middle";
|
|
21
22
|
readonly 'end-section': "close";
|
|
22
23
|
readonly 'table-start': "open";
|
|
23
24
|
readonly 'table-end': "close";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myrole-docx-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Word-faithful .docx editor and renderer on canvas — the MyRole engine as an embeddable SDK, with a React component.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -46,20 +46,25 @@
|
|
|
46
46
|
"react-dom": "^19.2.8",
|
|
47
47
|
"vite": "^6.4.3",
|
|
48
48
|
"@myrole/docx-model": "0.0.0",
|
|
49
|
-
"@myrole/docx-
|
|
50
|
-
"@myrole/fonts": "0.1.0",
|
|
49
|
+
"@myrole/docx-tags": "0.0.0",
|
|
51
50
|
"@myrole/docx-render": "0.0.0",
|
|
52
|
-
"@myrole/
|
|
51
|
+
"@myrole/fonts": "0.1.0",
|
|
52
|
+
"@myrole/docx-vars": "0.0.0"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"fonts": "node scripts/pack-fonts.mjs",
|
|
59
|
-
"build": "node scripts/pack-fonts.mjs && vite build && node scripts/types.mjs",
|
|
60
|
-
"
|
|
59
|
+
"build": "node scripts/pack-fonts.mjs && vite build && vite build --config vite.assistant.config.ts && node scripts/types.mjs",
|
|
60
|
+
"watch": "vite build --watch",
|
|
61
|
+
"check": "node scripts/pack-fonts.mjs && tsc -p tsconfig.json && tsx scripts/locking.test.ts && tsx scripts/assistant-mcp.test.ts",
|
|
62
|
+
"assistant": "tsx scripts/assistant-mcp.ts",
|
|
61
63
|
"types": "node scripts/types.mjs"
|
|
62
64
|
},
|
|
65
|
+
"bin": {
|
|
66
|
+
"myrole-docx-assistant": "./dist/assistant-mcp.mjs"
|
|
67
|
+
},
|
|
63
68
|
"typesVersions": {
|
|
64
69
|
"*": {
|
|
65
70
|
"react": [
|