@aicayzer/inkkit 0.0.5 → 0.0.7

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 CHANGED
@@ -35,6 +35,8 @@ const snapshot = editor.snapshot(1)
35
35
 
36
36
  Markdown includes CommonMark, task lists, strikethrough, autolinks, GFM tables, editable footnotes and reference-style links, bounded callouts, highlights, author comments and offline Mermaid diagrams. Unsupported constructs remain literal Markdown. TXT mode treats all text literally. Images require a host adapter. RTF files remain outside the package scope.
37
37
 
38
+ Table controls include complete row/column movement and explicit stable text or numeric sorting. Ordinary spreadsheet paste preserves cell boundaries, replaces selected cells and grows supported tables. Hosts call these operations through the public facade; each is undoable.
39
+
38
40
  `await editor.printableSnapshot(1)` returns a complete printable HTML document, print styles and portable image bytes. It excludes author comments, includes folded content and reports unavailable assets or a changed document. Client apps own Print/PDF commands, dialogs and file generation.
39
41
 
40
42
  See [supported syntax](docs/supported-syntax.md), [the host API](docs/api.md), [preservation and clipboard behavior](docs/preservation.md), [development](docs/development.md), and [releases](docs/releasing.md).
@@ -42,3 +44,5 @@ See [supported syntax](docs/supported-syntax.md), [the host API](docs/api.md), [
42
44
  Delivery scope and release status are tracked in the [InkKit Project](https://github.com/users/aicayzer/projects/3) and [milestones](https://github.com/aicayzer/inkkit/milestones).
43
45
 
44
46
  MIT licensed. InkKit builds on the public PadPad and Memos editors; see [NOTICE](NOTICE).
47
+
48
+ Complete source/formatted editing, literal find/replace and replace-all, and current ordered headings/navigation are available through the public facade. Mode switching keeps document identity and history; unsupported or incomplete source and TXT remain saveable. Hosts own the editing controls and outline presentation. See the [API contracts](docs/api.md).
@@ -1,3 +1,4 @@
1
+ import type { EditorView } from '@milkdown/kit/prose/view';
1
2
  import type { Parent, RootContent } from 'mdast';
2
3
  interface Callout extends Parent {
3
4
  type: 'inkkitCallout';
@@ -17,6 +18,7 @@ declare module 'mdast' {
17
18
  inkkitCallout: Callout;
18
19
  }
19
20
  }
21
+ export declare function revealCalloutAncestors(view: EditorView, position: number): void;
20
22
  export declare const remarkCalloutsPlugin: import("@milkdown/kit/utils").$Remark<"inkkitCallouts", unknown>;
21
23
  export declare const calloutSchema: import("@milkdown/kit/utils").$Node;
22
24
  export declare const calloutView: import("@milkdown/kit/utils").$Prose;
package/dist/callouts.js CHANGED
@@ -3,6 +3,17 @@ import { remarkCtx } from '@milkdown/kit/core';
3
3
  import { Plugin, PluginKey } from '@milkdown/kit/prose/state';
4
4
  import { defaultHandlers } from 'mdast-util-to-markdown';
5
5
  const kinds = new Set(['NOTE', 'TIP', 'IMPORTANT', 'WARNING', 'CAUTION']);
6
+ export function revealCalloutAncestors(view, position) {
7
+ const node = view.domAtPos(position).node;
8
+ let element = node instanceof HTMLElement ? node : node.parentElement;
9
+ while (element && element !== view.dom) {
10
+ if (element.getAttribute('data-inkkit-folded') === 'true')
11
+ element
12
+ .querySelector(':scope > .inkkit-callout-header > [data-inkkit-callout-toggle]')
13
+ ?.click();
14
+ element = element.parentElement;
15
+ }
16
+ }
6
17
  function plainHeader(processor, source) {
7
18
  const node = processor.parse(source).children[0];
8
19
  return node?.type === 'paragraph' &&
package/dist/dialect.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { editorViewCtx, serializerCtx } from '@milkdown/kit/core';
2
- import { commonmark, hardbreakSchema, imageSchema, paragraphSchema, remarkInlineLinkPlugin, } from '@milkdown/kit/preset/commonmark';
2
+ import { commonmark, docSchema, hardbreakSchema, imageSchema, paragraphSchema, remarkInlineLinkPlugin, } from '@milkdown/kit/preset/commonmark';
3
3
  import { extendListItemSchemaForTask, strikethroughAttr, strikethroughInputRule, strikethroughKeymap, strikethroughSchema, toggleStrikethroughCommand, wrapInTaskListInputRule, tableSchema, tableHeaderRowSchema, tableHeaderSchema, tableRowSchema, tableCellSchema, tableEditingPlugin, tableKeymap, goToNextTableCellCommand, goToPrevTableCellCommand, insertTableCommand, addRowBeforeCommand, addRowAfterCommand, addColBeforeCommand, addColAfterCommand, selectRowCommand, selectColCommand, deleteSelectedCellsCommand, setAlignCommand, exitTable, } from '@milkdown/kit/preset/gfm';
4
- import { $remark } from '@milkdown/kit/utils';
4
+ import { $node, $remark } from '@milkdown/kit/utils';
5
5
  import { autolinkInputRule } from './autolink.js';
6
+ import { sourceAttribute } from './source.js';
7
+ import { normalizeTableAlignment, normalizeTableColumnAlignment, } from './table-alignment.js';
6
8
  import { preservingCodeBlocks, remarkCodeFences, fencedCodeHandler, } from './code-fences.js';
7
9
  import { literalBlock, createLiteralPreservation } from './literals.js';
8
10
  import { references, remarkReferencesPlugin } from './references.js';
@@ -86,6 +88,17 @@ function remarkDialect() {
86
88
  add('toMarkdownExtensions', gfmTaskListItemToMarkdown());
87
89
  add('toMarkdownExtensions', gfmAutolinkLiteralToMarkdown());
88
90
  add('toMarkdownExtensions', gfmTableToMarkdown());
91
+ add('toMarkdownExtensions', {
92
+ handlers: {
93
+ text(node, parent, state, info) {
94
+ const value = defaultHandlers.text(node, parent, state, info);
95
+ // GFM trims literal whitespace at cell edges on reopening.
96
+ return state.stack.includes('tableCell')
97
+ ? value.replace(/^[ \t]+|[ \t]+$/g, (spaces) => spaces.replaceAll(' ', '&#x20;').replaceAll('\t', '&#x9;'))
98
+ : value;
99
+ },
100
+ },
101
+ });
89
102
  add('toMarkdownExtensions', { handlers: { link, code: fencedCodeHandler } });
90
103
  }
91
104
  export const remarkDialectPlugin = $remark('remarkDialect', () => remarkDialect);
@@ -209,7 +222,7 @@ export const tables = [
209
222
  return false;
210
223
  return {
211
224
  ...attrs,
212
- alignment: dom.style.textAlign || dom.getAttribute('align') || null,
225
+ alignment: normalizeTableAlignment(dom),
213
226
  };
214
227
  },
215
228
  }
@@ -231,7 +244,7 @@ export const tables = [
231
244
  return false;
232
245
  return {
233
246
  ...attrs,
234
- alignment: dom.style.textAlign || dom.getAttribute('align') || null,
247
+ alignment: normalizeTableColumnAlignment(dom),
235
248
  };
236
249
  },
237
250
  }
@@ -262,6 +275,13 @@ export function createDialect(images) {
262
275
  // Protect unsupported inline HTML before the empty-line plugin consumes break nodes.
263
276
  createLiteralPreservation(images),
264
277
  commonmarkWithLiteralReferences,
278
+ $node('doc', () => ({
279
+ ...docSchema.schema,
280
+ attrs: {
281
+ ...docSchema.schema.attrs,
282
+ [sourceAttribute]: { default: null },
283
+ },
284
+ })),
265
285
  references,
266
286
  callouts,
267
287
  comments,
package/dist/editor.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { type TableCommand } from './tables.js';
1
+ import { type TableCommand, type TableOptions } from './tables.js';
2
2
  import { type DocumentInput, type DocumentSnapshot, type ImageAdapter, type ClipboardInput, type ClipboardOutput, type PrintableDocument } from './types.js';
3
+ import { type Heading } from './outline.js';
3
4
  export type Mark = 'bold' | 'italic' | 'strikethrough' | 'highlight' | 'code' | 'link';
4
5
  export type Block = {
5
6
  type: 'paragraph';
@@ -15,6 +16,7 @@ export type Block = {
15
16
  } | {
16
17
  type: 'taskList';
17
18
  };
19
+ export type EditingMode = 'source' | 'formatted';
18
20
  export interface CaretState {
19
21
  marks: Mark[];
20
22
  block: Block;
@@ -37,7 +39,6 @@ export declare class InkKitEditor {
37
39
  private readonly options;
38
40
  private editor;
39
41
  private lastMarkdown;
40
- private baseline;
41
42
  private documentId;
42
43
  private formatType;
43
44
  private revision;
@@ -45,6 +46,11 @@ export declare class InkKitEditor {
45
46
  private operationSequence;
46
47
  private plainComposing;
47
48
  private plainSearch;
49
+ private literalMatch?;
50
+ private beforePlainInput?;
51
+ private mode;
52
+ private sourcePreservations;
53
+ private outlineEpoch;
48
54
  private ready;
49
55
  private destroyed;
50
56
  private preservation?;
@@ -63,26 +69,39 @@ export declare class InkKitEditor {
63
69
  private context;
64
70
  private assertAlive;
65
71
  private assertCurrent;
66
- private plainSource;
72
+ private get literalSurface();
73
+ get editingMode(): EditingMode;
74
+ private currentText;
75
+ setEditingMode(mode: EditingMode, expectedGeneration?: number): boolean;
76
+ private updateSurface;
77
+ replaceSource(text: string, expectedGeneration?: number): boolean;
78
+ private applySource;
79
+ undo(expectedGeneration?: number): boolean;
80
+ redo(expectedGeneration?: number): boolean;
81
+ private replaceLiteralSelection;
67
82
  snapshot(expectedGeneration?: number): DocumentSnapshot;
68
83
  printableSnapshot(expectedGeneration?: number): Promise<PrintableDocument>;
69
84
  clipboardSnapshot(all?: boolean): Promise<ClipboardOutput>;
70
85
  paste(input: ClipboardInput): Promise<void>;
71
86
  setCommentsVisible(visible: boolean): void;
72
87
  pasteAsPlainText(text: string): void;
73
- table(command: TableCommand, options?: {
74
- rows?: number;
75
- columns?: number;
76
- }): boolean;
88
+ table(command: TableCommand, options?: TableOptions): boolean;
77
89
  destroy(): Promise<void>;
78
90
  private keymapPlugin;
91
+ private copySourceSelection;
79
92
  static mount(root: HTMLElement, events: EditorEvents, options?: {
80
93
  images?: ImageAdapter;
81
94
  }): Promise<InkKitEditor>;
82
95
  loadDocument(input: DocumentInput): void;
83
96
  reloadDocument(input: DocumentInput): void;
84
97
  private load;
85
- find(text: string): void;
98
+ find(text: string, expectedGeneration?: number): void;
99
+ replace(search: string, replacement: string, expectedGeneration?: number): boolean;
100
+ replaceAll(search: string, replacement: string, expectedGeneration?: number): number;
101
+ private replaceMatches;
102
+ private outlineContext;
103
+ headings(expectedGeneration?: number): readonly Heading[];
104
+ navigateHeading(heading: Heading): boolean;
86
105
  /** Buffered native typing follows the same input rules as direct typing. */
87
106
  insertText(text: string, generation: number): boolean;
88
107
  /** Let existing keymaps handle buffered editing commands before native fallback. */