quill-clausula 0.1.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 ADDED
@@ -0,0 +1,133 @@
1
+ # quill-clausula
2
+
3
+ Brazilian legal document formatting module for [Quill 2](https://quilljs.com) — auto-numbered **Cláusulas**, **Parágrafos**, **Incisos**, and **Alíneas**, plus contract **Partes** (CONTRATANTE/CONTRATADO), **OBJETO**, signature blocks, and per-clause Lock / Agree / Disagree workflow.
4
+
5
+ Also ships:
6
+
7
+ - **Markdown import** (`importMarkdown`) — AI-generated legal Markdown → Delta with live clause numbering
8
+ - **Markdown/HTML export** (`exportMarkdown` / `exportHTML`) — numbering labels materialized; MD is pandoc-friendly for DOCX pipelines
9
+ - **Ghost Cut** — non-destructive Ctrl+X ([Textualize's idea](https://ishmael.textualize.io/blog/ghost-cut/)): the selection fades instead of being deleted; Ctrl+V moves it atomically (single undo); Esc cancels
10
+ - **Clause organizer** — floating drag handle to reorder whole clause blocks (parent + children)
11
+ - **Word-style spacing** — `lineheight` and `spacing` (space-after) block formats
12
+ - Table export support (Quill 2's table module → pipe tables in MD, `<table>` in HTML)
13
+
14
+ ## Installation
15
+
16
+ ```sh
17
+ npm install quill-clausula quill
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```js
23
+ import Quill from 'quill';
24
+ import { register } from 'quill-clausula';
25
+ import 'quill-clausula/dist/quill-clausula.css';
26
+ import 'quill/dist/quill.snow.css';
27
+
28
+ register();
29
+
30
+ const quill = new Quill('#editor', {
31
+ theme: 'snow',
32
+ modules: {
33
+ toolbar: {
34
+ container: [
35
+ [
36
+ { clausula: ['clausula', 'subclausula', 'paragrafo', 'inciso', 'alinea', false] },
37
+ { parte: ['contratante', 'contratado', false] },
38
+ ],
39
+ ['objeto', 'assinatura'],
40
+ ['bold', 'italic', 'underline'],
41
+ ],
42
+ },
43
+ clausula: {
44
+ clausulaFormat: 'extenso', // CLÁUSULA PRIMEIRA —
45
+ paragrafoFormat: 'extenso', // Parágrafo Primeiro. / Parágrafo Único.
46
+ incisoFormat: 'roman', // I —, II —
47
+ alineaFormat: 'letter-parenthesis', // a), b)
48
+ currentUser: 'user1',
49
+ users: ['user1', 'user2'],
50
+ },
51
+ },
52
+ });
53
+ ```
54
+
55
+ ## Autofill
56
+
57
+ Type a trigger word at the start of a line followed by Space:
58
+
59
+ | Trigger | Result |
60
+ |---|---|
61
+ | `cl`, `clausula` | Cláusula |
62
+ | `sub`, `subclausula` | Sub-cláusula |
63
+ | `par`, `paragrafo`, `§` | Parágrafo |
64
+ | `inc`, `inciso` | Inciso |
65
+ | `al`, `alinea` | Alínea |
66
+ | `contratante`, `contratado` | Parte (with template) |
67
+ | `objeto` | Objeto |
68
+
69
+ Tab / Shift+Tab promote and demote clause levels.
70
+
71
+ ## Numbering formats
72
+
73
+ - `clausulaFormat`: `extenso`, `numeric`, `numeric-padded`, `ordinal`, `abbreviation`, `regular`, `regular-padded`
74
+ - `subclausulaFormat`: `dotted` (1.1), `dotted-padded`, `numeric`, `extenso`
75
+ - `paragrafoFormat`: `extenso`, `uppercase`, `numeric`, `symbol` (§1º) — a single parágrafo renders as *Parágrafo Único*
76
+ - `incisoFormat`: `roman`, `roman-lower`
77
+ - `alineaFormat`: `letter-parenthesis`, `letter`
78
+
79
+ Change `module.options` at runtime and call `module.renumber()` to reformat.
80
+
81
+ ## Import / Export
82
+
83
+ ```js
84
+ import { importMarkdown, exportMarkdown, exportHTML } from 'quill-clausula';
85
+
86
+ // AI-generated legal Markdown -> Delta with clausula attributes
87
+ quill.setContents(importMarkdown(aiMarkdown));
88
+
89
+ // Delta -> pandoc-friendly Markdown / clean HTML (numbering materialized)
90
+ const module = quill.getModule('clausula');
91
+ const md = module.exportMarkdown(); // pipe into `pandoc -o contrato.docx`
92
+ const html = module.exportHTML(); // print / PDF / read-only display
93
+ ```
94
+
95
+ `importMarkdown` recognizes the patterns LLMs produce for Brazilian legal
96
+ documents (`## CLÁUSULA PRIMEIRA — ...`, `1.1`, `§1º`, `Parágrafo Único.`,
97
+ `I —`, `a)`, `CONTRATANTE:`, `OBJETO:`) and STRIPS the numbering labels — the
98
+ module re-materializes them, so numbering never goes stale in the editor.
99
+
100
+ ## Persistence
101
+
102
+ Save and restore documents with **deltas only** (`quill.getContents()` / `quill.setContents()`).
103
+
104
+ > **Warning:** numbering labels ("CLÁUSULA PRIMEIRA — ", "1.1", "§1º") are presentation-only UI nodes. `quill.getSemanticHTML()` omits them, and saving `root.innerHTML` duplicates them on reload. For print/PDF HTML with numbering use `exportHTML()`; for DOCX use `exportMarkdown()` + pandoc.
105
+
106
+ ## Editing UX
107
+
108
+ - **Ghost Cut**: Ctrl+X fades the selection (nothing is deleted, clipboard untouched, no undo entry); Ctrl+V moves it to the cursor as ONE undoable operation; Esc cancels. Full-line cuts carry the line format, so cutting a cláusula never leaves an orphaned number. Traditional cut = Ctrl+C + Backspace.
109
+ - **Clause organizer**: hover a cláusula and a ⋮⋮ handle appears on the left; drag it to move the whole block (cláusula + children) — numbering follows.
110
+ - **Tab / Shift+Tab** promote and demote clause levels; `destroy()` detaches everything for SPA unmounting.
111
+
112
+ ## Options
113
+
114
+ | Option | Default | Description |
115
+ |---|---|---|
116
+ | `currentUser` | — | User id recording agree/disagree votes |
117
+ | `users` | — | All users that must agree before Sign enables |
118
+ | `showActions` | `true` | Per-clause Lock/Agree/Disagree/Conversation buttons |
119
+ | `showFloatingBar` | `true` | Global action bar (Agree All, Lock All, Sign…) |
120
+ | `showDragHandle` | `true` | Floating drag handle to reorder clause blocks |
121
+ | `onJudge` / `onShare` / `onSign` / `onConversation` | — | Callbacks for the corresponding buttons |
122
+
123
+ ## Development
124
+
125
+ ```sh
126
+ npm run dev # demo at localhost:5173
127
+ npm test # vitest
128
+ npm run build # dist/ (esm + cjs + css + types)
129
+ ```
130
+
131
+ ## License
132
+
133
+ MIT
@@ -0,0 +1,2 @@
1
+ export declare function createActionButtons(doc: Document): HTMLDivElement;
2
+ export declare function syncButtonState(actionsContainer: HTMLElement, domNode: HTMLElement, currentUser: string | undefined, users: string[] | undefined, children?: HTMLElement[]): void;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Clause organizer — a floating drag handle (⋮⋮) that appears to the left of
3
+ * the cláusula under the mouse. Dragging it moves the WHOLE clause block
4
+ * (parent cláusula + its children) to another position; a drop indicator
5
+ * line shows the target boundary while dragging.
6
+ *
7
+ * The handle is an overlay on `quill.container` (never inside the editable
8
+ * DOM), so Quill's document model is untouched until the actual move, which
9
+ * the module performs as a single atomic delta.
10
+ */
11
+ export interface DragBlock {
12
+ /** Clausula item blots: parent first, then its children */
13
+ items: any[];
14
+ }
15
+ export interface DragOrganizerCallbacks {
16
+ getBlocks: () => DragBlock[];
17
+ /** Move block `sourceIndex` to sit at boundary `targetBoundary` (0..blocks.length) */
18
+ moveBlock: (sourceIndex: number, targetBoundary: number) => void;
19
+ }
20
+ export declare class DragOrganizer {
21
+ private quill;
22
+ private callbacks;
23
+ private container;
24
+ private handle;
25
+ private indicator;
26
+ private hoveredBlockIndex;
27
+ private hoveredParentEl;
28
+ private hideTimer;
29
+ private dragging;
30
+ private dropBoundary;
31
+ private blockRects;
32
+ private onMouseMove;
33
+ private onMouseLeave;
34
+ private onPointerDown;
35
+ private onPointerMove;
36
+ private onPointerUp;
37
+ constructor(quill: any, callbacks: DragOrganizerCallbacks);
38
+ private hideHandle;
39
+ /** Hide with a grace period so the mouse can travel to the handle. */
40
+ private scheduleHide;
41
+ private cancelHide;
42
+ /**
43
+ * While a block is hovered, the strip from the handle to the block's
44
+ * right edge (with vertical slack) counts as "still hovering" — without
45
+ * it the handle vanishes as soon as the mouse leaves the text on its
46
+ * way to grab it.
47
+ */
48
+ private isInReachCorridor;
49
+ private trackHover;
50
+ private startDrag;
51
+ private trackDrag;
52
+ private endDrag;
53
+ destroy(): void;
54
+ }
@@ -0,0 +1,19 @@
1
+ export interface FloatingBarCallbacks {
2
+ onUndo?: () => void;
3
+ onAgreeAll?: () => void;
4
+ onDisagreeAll?: () => void;
5
+ onLockAll?: () => void;
6
+ onJudge?: () => void;
7
+ onShare?: () => void;
8
+ onSign?: () => void;
9
+ }
10
+ export declare function createFloatingBar(doc: Document, callbacks: FloatingBarCallbacks): HTMLDivElement;
11
+ /**
12
+ * Creates the undo warning modal overlay.
13
+ */
14
+ export declare function createUndoModal(doc: Document, onConfirm: () => void, onCancel: () => void): HTMLDivElement;
15
+ /**
16
+ * Check if all clausula items (leaf-level, non-parent) have all users agreed.
17
+ * Returns true only when every leaf item has `agreed[user] === true` for every user.
18
+ */
19
+ export declare function isContractFullyAgreed(allItems: HTMLElement[], users: string[]): boolean;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Ghost Cut — a non-destructive cut, after Textualize's "ghost cut" idea
3
+ * (https://ishmael.textualize.io/blog/ghost-cut/):
4
+ *
5
+ * - **Ctrl+X / Cmd+X (or menu Cut)**: nothing is deleted and nothing touches
6
+ * the clipboard. The selection just fades — it becomes "ghost" content.
7
+ * No undo entry is created.
8
+ * - **Ctrl+V / Cmd+V**: the ghost content is moved to the cursor in ONE
9
+ * atomic delta — a single undo restores everything.
10
+ * - **Escape**: the ghost returns to normal, nothing changed.
11
+ * - A traditional destructive cut is still available as Ctrl+C + Backspace.
12
+ *
13
+ * When the selection covers whole line(s), the range is extended to include
14
+ * the trailing newline so line formats (clausula, parte, objeto) travel with
15
+ * the move — cutting a cláusula never leaves an orphaned numbered line
16
+ * behind.
17
+ */
18
+ interface GhostRange {
19
+ index: number;
20
+ length: number;
21
+ }
22
+ /** Scans a delta for the contiguous extent of `ghost` formatted content. */
23
+ export declare function findGhostRange(delta: {
24
+ ops: any[];
25
+ }): GhostRange | null;
26
+ export declare class GhostCut {
27
+ private quill;
28
+ private isRangeLocked;
29
+ constructor(quill: any, options: {
30
+ isRangeLocked: (index: number, length: number) => boolean;
31
+ });
32
+ get active(): boolean;
33
+ private findRange;
34
+ /**
35
+ * Expands a selection to include the trailing newline when it covers the
36
+ * entire text of its line(s), so line formats move together.
37
+ */
38
+ private expandToLineBoundary;
39
+ /** Handles a `cut` DOM event. Returns true when the event was consumed. */
40
+ handleCut(event: ClipboardEvent): boolean;
41
+ /**
42
+ * Lines fully covered by the ghost range get a line-level class so their
43
+ * UI labels ("CLÁUSULA SEGUNDA — ", "2.1", "Parágrafo Primeiro.") fade
44
+ * together with the content — the label is presentation DOM, not text,
45
+ * so the inline ghost format alone cannot reach it.
46
+ */
47
+ private markGhostLines;
48
+ private clearGhostLines;
49
+ /** Handles a `paste` DOM event. Returns true when the event was consumed. */
50
+ handlePaste(event: ClipboardEvent): boolean;
51
+ /** Cancels an active ghost (Escape). Returns true when one was cleared. */
52
+ cancel(): boolean;
53
+ destroy(): void;
54
+ }
55
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Builds the op list for an atomic "move" delta: remove `length` characters
3
+ * at `start` and re-insert them (as `sliceOps`) at `target`, where `target`
4
+ * is a position in the PRE-move document. The result applies as a single
5
+ * updateContents call — one history entry, fully undoable.
6
+ */
7
+ export declare function buildMoveOps(start: number, length: number, target: number, sliceOps: Array<Record<string, unknown>>): Array<Record<string, unknown>>;
@@ -0,0 +1,5 @@
1
+ import type { AssinaturaConfig, SignatureLine } from '../types.js';
2
+ /**
3
+ * Renders the signature block HTML from extracted names + config.
4
+ */
5
+ export declare function renderAssinatura(lines: SignatureLine[], config: AssinaturaConfig): string;
@@ -0,0 +1,12 @@
1
+ import type { SignatureLine } from '../types.js';
2
+ interface ParteBlotLike {
3
+ domNode: HTMLElement;
4
+ }
5
+ /**
6
+ * Extracts signature lines from parte blots.
7
+ *
8
+ * For each parte, the "name" is the text content before the first comma.
9
+ * If no comma is found, the entire text content is used.
10
+ */
11
+ export declare function extractSignatureLines(parteItems: ParteBlotLike[]): SignatureLine[];
12
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { ClausulaType } from './types.js';
2
+ /**
3
+ * Extra triggers for non-clausula formats (parte, objeto).
4
+ * Returns { format, value } for applying to the line.
5
+ */
6
+ export interface ExtraTriggerResult {
7
+ format: string;
8
+ value: string;
9
+ }
10
+ /**
11
+ * The full regex that matches any trigger word at the start of a line.
12
+ * Used as the `prefix` in the keyboard binding.
13
+ */
14
+ export declare const AUTOFILL_PREFIX: RegExp;
15
+ /**
16
+ * Given a matched prefix string, return the corresponding clausula type.
17
+ */
18
+ export declare function matchTrigger(prefix: string): ClausulaType | null;
19
+ /**
20
+ * Given a matched prefix string, return a non-clausula format trigger if matched.
21
+ */
22
+ export declare function matchExtraTrigger(prefix: string): ExtraTriggerResult | null;
@@ -0,0 +1,11 @@
1
+ import type { AssinaturaConfig } from '../types.js';
2
+ declare const BlockEmbed: any;
3
+ declare class AssinaturaEmbed extends BlockEmbed {
4
+ static blotName: string;
5
+ static tagName: "DIV";
6
+ static className: string;
7
+ static create(value: AssinaturaConfig | string): HTMLElement;
8
+ static value(domNode: HTMLElement): AssinaturaConfig;
9
+ static formats(domNode: HTMLElement): undefined;
10
+ }
11
+ export default AssinaturaEmbed;
@@ -0,0 +1,4 @@
1
+ declare const Container: any;
2
+ declare class ClausulaContainer extends Container {
3
+ }
4
+ export default ClausulaContainer;
@@ -0,0 +1,15 @@
1
+ import type { ClausulaType } from '../types.js';
2
+ declare const Block: any;
3
+ declare class ClausulaItem extends Block {
4
+ static blotName: string;
5
+ static tagName: "DIV";
6
+ static className: string;
7
+ actionsNode: HTMLElement | null;
8
+ static create(value: ClausulaType): HTMLElement;
9
+ static formats(domNode: HTMLElement): string | undefined;
10
+ static register(): void;
11
+ constructor(scroll: any, domNode: HTMLElement);
12
+ format(name: string, value: string): void;
13
+ update(mutations: MutationRecord[], context: Record<string, any>): void;
14
+ }
15
+ export default ClausulaItem;
@@ -0,0 +1,4 @@
1
+ declare const Container: any;
2
+ declare class ObjetoContainer extends Container {
3
+ }
4
+ export default ObjetoContainer;
@@ -0,0 +1,12 @@
1
+ declare const Block: any;
2
+ declare class ObjetoItem extends Block {
3
+ static blotName: string;
4
+ static tagName: "DIV";
5
+ static className: string;
6
+ static create(value: string): HTMLElement;
7
+ static formats(domNode: HTMLElement): "true" | undefined;
8
+ static register(): void;
9
+ constructor(scroll: any, domNode: HTMLElement);
10
+ format(name: string, value: string): void;
11
+ }
12
+ export default ObjetoItem;
@@ -0,0 +1,4 @@
1
+ declare const Container: any;
2
+ declare class ParteContainer extends Container {
3
+ }
4
+ export default ParteContainer;
@@ -0,0 +1,13 @@
1
+ import type { ParteType } from '../types.js';
2
+ declare const Block: any;
3
+ declare class ParteItem extends Block {
4
+ static blotName: string;
5
+ static tagName: "DIV";
6
+ static className: string;
7
+ static create(value: ParteType): HTMLElement;
8
+ static formats(domNode: HTMLElement): string | undefined;
9
+ static register(): void;
10
+ constructor(scroll: any, domNode: HTMLElement);
11
+ format(name: string, value: string): void;
12
+ }
13
+ export default ParteItem;
@@ -0,0 +1,64 @@
1
+ import type { AssinaturaConfig, ClausulaModuleOptions, ClausulaType, ParteType } from '../types.js';
2
+ /**
3
+ * Delta-based document export.
4
+ *
5
+ * The delta is the single source of truth for persistence; numbering labels
6
+ * ("CLÁUSULA PRIMEIRA — ", "1.1", "§1º") exist only as presentation-side UI
7
+ * nodes and are NOT part of the delta. These exporters re-materialize the
8
+ * labels from the delta's line attributes, producing output that carries the
9
+ * full legal numbering:
10
+ *
11
+ * - `exportMarkdown` → pandoc-friendly Markdown (e.g. for DOCX conversion)
12
+ * - `exportHTML` → clean, class-annotated HTML (print / PDF / preview)
13
+ */
14
+ interface DeltaOp {
15
+ insert?: string | Record<string, unknown>;
16
+ attributes?: Record<string, any>;
17
+ }
18
+ export interface DeltaLike {
19
+ ops: DeltaOp[];
20
+ }
21
+ export interface ExportSegment {
22
+ text: string;
23
+ bold?: boolean;
24
+ italic?: boolean;
25
+ underline?: boolean;
26
+ }
27
+ export interface ExportLine {
28
+ kind: 'clausula' | 'parte' | 'objeto' | 'assinatura' | 'table-cell' | 'text';
29
+ /** Row identifier when kind is 'table-cell' (cells of the same row share it) */
30
+ tableRow?: string;
31
+ clausulaType?: ClausulaType;
32
+ parteType?: ParteType;
33
+ /** Materialized numbering/prefix label ('' when not applicable) */
34
+ label: string;
35
+ /** Plain text content of the line */
36
+ text: string;
37
+ segments: ExportSegment[];
38
+ locked?: boolean;
39
+ agreed?: Record<string, boolean>;
40
+ assinatura?: AssinaturaConfig;
41
+ /** Word-style spacing (CSS values), when set on the line */
42
+ lineHeight?: string;
43
+ spacingAfter?: string;
44
+ }
45
+ /**
46
+ * Parses a delta into a flat list of logical lines with materialized
47
+ * numbering labels. This is the shared document model both exporters use.
48
+ */
49
+ export declare function parseDeltaToLines(delta: DeltaLike, options: ClausulaModuleOptions): ExportLine[];
50
+ /**
51
+ * Exports a delta as pandoc-friendly Markdown with all numbering labels
52
+ * materialized. Cláusulas become `##` headings (mapping to Heading 2 in
53
+ * DOCX); every other label is emitted as literal bold text so pandoc/word
54
+ * processors never renumber the legal structure.
55
+ */
56
+ export declare function exportMarkdown(delta: DeltaLike, options: ClausulaModuleOptions): string;
57
+ /**
58
+ * Exports a delta as clean, self-describing HTML with all numbering labels
59
+ * materialized — suitable for print, PDF generation, or read-only display
60
+ * outside the editor. (Unlike `quill.getSemanticHTML()`, which omits the
61
+ * labels, and `quill.root.innerHTML`, which duplicates them on reload.)
62
+ */
63
+ export declare function exportHTML(delta: DeltaLike, options: ClausulaModuleOptions): string;
64
+ export {};
@@ -0,0 +1,9 @@
1
+ declare const Attributor: any;
2
+ declare class AgreedAttributor extends Attributor {
3
+ constructor(attrName: string, keyName: string, options?: Record<string, unknown>);
4
+ add(node: HTMLElement, value: Record<string, boolean> | string): boolean;
5
+ remove(node: HTMLElement): void;
6
+ value(node: HTMLElement): Record<string, boolean> | undefined;
7
+ }
8
+ declare const Agreed: AgreedAttributor;
9
+ export default Agreed;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Transient inline format used by Ghost Cut: text marked `ghost` is the
3
+ * faded, inert content awaiting a paste-to-move. It is applied and removed
4
+ * with SILENT source (no history entries) and never survives an export.
5
+ */
6
+ declare const GhostAttribute: any;
7
+ export default GhostAttribute;
@@ -0,0 +1,2 @@
1
+ declare const LockedAttribute: any;
2
+ export default LockedAttribute;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Word-style spacing controls, stored in the delta as line attributes:
3
+ *
4
+ * - `lineheight`: line spacing within the paragraph (Word's "entre linhas")
5
+ * - `spacing`: space after the paragraph (Word's "depois do parágrafo")
6
+ *
7
+ * Both are plain CSS style attributors, so they survive copy/paste and
8
+ * export naturally as inline styles.
9
+ */
10
+ export declare const LINE_HEIGHTS: readonly ["1", "1.15", "1.5", "2", "2.5", "3"];
11
+ export declare const PARAGRAPH_SPACINGS: readonly ["0em", "0.5em", "1em", "1.5em", "2em"];
12
+ export declare const LineHeightAttribute: any;
13
+ export declare const ParagraphSpacingAttribute: any;
@@ -0,0 +1,37 @@
1
+ import type { DeltaLike } from '../export/exporter.js';
2
+ /**
3
+ * Markdown → Quill Delta importer.
4
+ *
5
+ * Converts AI-generated Brazilian legal documents (Markdown) into a Delta
6
+ * whose lines carry quill-clausula attributes (`clausula`, `parte`,
7
+ * `objeto`), with numbering labels STRIPPED — the module re-materializes
8
+ * them dynamically, so imported numbers never go stale when clauses are
9
+ * added, removed, or reordered in the editor.
10
+ *
11
+ * Recognized patterns (tolerant to the typical LLM output variance):
12
+ *
13
+ * ## CLÁUSULA PRIMEIRA — DO OBJETO → clausula (text: "DO OBJETO")
14
+ * CLÁUSULA 2ª - DO PREÇO → clausula
15
+ * **1.1** texto / 1.1 texto / 1.1. texto → subclausula
16
+ * §1º texto / § 2º. texto → paragrafo
17
+ * Parágrafo Único. texto / **Parágrafo Primeiro.** texto → paragrafo
18
+ * I — texto / IV - texto → inciso
19
+ * a) texto / b) texto → alinea
20
+ * CONTRATANTE: texto / **CONTRATADA:** texto → parte
21
+ * OBJETO: texto → objeto
22
+ *
23
+ * Inline `**bold**`, `*italic*` and `_italic_` are converted to Quill
24
+ * attributes. YAML frontmatter is dropped.
25
+ */
26
+ interface InsertOp {
27
+ insert: string;
28
+ attributes?: Record<string, unknown>;
29
+ }
30
+ /** Minimal inline Markdown parser: **bold**, *italic*, _italic_. */
31
+ export declare function parseInline(text: string): InsertOp[];
32
+ /**
33
+ * Converts legal-document Markdown into a Quill Delta with quill-clausula
34
+ * line attributes. Feed the result to `quill.setContents(...)`.
35
+ */
36
+ export declare function importMarkdown(markdown: string): DeltaLike;
37
+ export {};
@@ -0,0 +1,32 @@
1
+ import ClausulaModule from './module.js';
2
+ import ClausulaItem from './blots/clausula-item.js';
3
+ import ClausulaContainer from './blots/clausula-container.js';
4
+ import ParteItem from './blots/parte-item.js';
5
+ import ParteContainer from './blots/parte-container.js';
6
+ import ObjetoItem from './blots/objeto-item.js';
7
+ import ObjetoContainer from './blots/objeto-container.js';
8
+ import AssinaturaEmbed from './blots/assinatura-embed.js';
9
+ import LockedAttribute from './formats/locked.js';
10
+ import AgreedAttribute from './formats/agreed.js';
11
+ import GhostAttribute from './formats/ghost.js';
12
+ import { LineHeightAttribute, ParagraphSpacingAttribute } from './formats/spacing.js';
13
+ export declare function register(): void;
14
+ export { createActionButtons, syncButtonState } from './actions/action-buttons.js';
15
+ export { createFloatingBar, createUndoModal, isContractFullyAgreed } from './actions/floating-bar.js';
16
+ export { ClausulaModule, ClausulaItem, ClausulaContainer, ParteItem, ParteContainer, ObjetoItem, ObjetoContainer, AssinaturaEmbed, LockedAttribute, AgreedAttribute, GhostAttribute, LineHeightAttribute, ParagraphSpacingAttribute, };
17
+ export { LINE_HEIGHTS, PARAGRAPH_SPACINGS } from './formats/spacing.js';
18
+ export type { ClausulaType, ClausulaFormat, SubclausulaFormat, ParagrafoFormat, IncisoFormat, AlineaFormat, ClausulaModuleOptions, ClausulaIndex, ConversationContext, ParteType, ParteIndex, AssinaturaConfig, SignatureLine, } from './types.js';
19
+ export { toExtenso, toExtensoUpper } from './numbering/extenso.js';
20
+ export { toRoman, toRomanLower } from './numbering/roman.js';
21
+ export { computeIndices, computeIndicesFromTypes } from './numbering/counter.js';
22
+ export { formatLabel } from './numbering/formatter.js';
23
+ export { computeParteIndices, computeParteIndicesFromTypes, formatParteLabel } from './partes/partes-counter.js';
24
+ export { extractSignatureLines } from './assinatura/assinatura-sync.js';
25
+ export { renderAssinatura } from './assinatura/assinatura-renderer.js';
26
+ export { matchTrigger, matchExtraTrigger, AUTOFILL_PREFIX } from './autofill.js';
27
+ export { exportMarkdown, exportHTML, parseDeltaToLines } from './export/exporter.js';
28
+ export type { ExportLine, ExportSegment, DeltaLike } from './export/exporter.js';
29
+ export { importMarkdown, parseInline } from './import/markdown-importer.js';
30
+ export { GhostCut, findGhostRange } from './actions/ghost-cut.js';
31
+ export { DragOrganizer } from './actions/drag-organizer.js';
32
+ export { buildMoveOps } from './actions/move-delta.js';