@owomark/core 0.1.0 → 0.1.2

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.
@@ -0,0 +1,32 @@
1
+ // src/clipboard/paste.ts
2
+ function getBlockquotePrefixAtPos(text, pos) {
3
+ let lineStart = pos;
4
+ while (lineStart > 0 && text[lineStart - 1] !== "\n") lineStart--;
5
+ let lineEnd = pos;
6
+ while (lineEnd < text.length && text[lineEnd] !== "\n") lineEnd++;
7
+ const line = text.slice(lineStart, lineEnd);
8
+ const match = line.match(/^((?:\s*>\s?)+)/);
9
+ if (!match) return "";
10
+ const rawPrefix = match[1];
11
+ return /\s$/.test(rawPrefix) ? rawPrefix : rawPrefix + " ";
12
+ }
13
+ function applyBlockquotePrefix(cleaned, prefix) {
14
+ if (!prefix) return cleaned;
15
+ return cleaned.replace(/\n/g, "\n" + prefix);
16
+ }
17
+ function normalizeMarkdownPaste(raw, tabSize = 2) {
18
+ let text = raw;
19
+ text = text.replace(/\r\n/g, "\n");
20
+ text = text.replace(/\r/g, "\n");
21
+ text = text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
22
+ text = text.replace(/[\u200B\u200C\u200D\uFEFF]/g, "");
23
+ const spaces = " ".repeat(tabSize);
24
+ text = text.replace(/\t/g, spaces);
25
+ return text;
26
+ }
27
+
28
+ export {
29
+ getBlockquotePrefixAtPos,
30
+ applyBlockquotePrefix,
31
+ normalizeMarkdownPaste
32
+ };
@@ -0,0 +1,85 @@
1
+ // src/commands/word-boundary.ts
2
+ var hasIntlSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl;
3
+ function findWordBoundariesBackward(text, pos) {
4
+ if (pos <= 0) return 0;
5
+ if (hasIntlSegmenter) {
6
+ const segmenter = new Intl.Segmenter(void 0, { granularity: "word" });
7
+ const before2 = text.slice(0, pos);
8
+ const segments = [...segmenter.segment(before2)];
9
+ let idx = segments.length - 1;
10
+ while (idx >= 0 && !segments[idx].isWordLike && segments[idx].segment.trim() === "") {
11
+ idx--;
12
+ }
13
+ if (idx < 0) return 0;
14
+ return segments[idx].index;
15
+ }
16
+ const before = text.slice(0, pos);
17
+ const trimmed = before.replace(/\s+$/, "");
18
+ if (trimmed.length === 0) return 0;
19
+ const match = trimmed.match(/(?:.*\b)(\S+)$/);
20
+ return match ? trimmed.length - match[1].length : 0;
21
+ }
22
+ function findWordBoundaryForward(text, pos) {
23
+ if (pos >= text.length) return text.length;
24
+ if (hasIntlSegmenter) {
25
+ const segmenter = new Intl.Segmenter(void 0, { granularity: "word" });
26
+ const after2 = text.slice(pos);
27
+ const segments = [...segmenter.segment(after2)];
28
+ if (segments.length === 0) return pos;
29
+ let consumed = 0;
30
+ let idx = 0;
31
+ consumed += segments[idx].segment.length;
32
+ const wasWordLike = segments[idx].isWordLike;
33
+ idx++;
34
+ if (wasWordLike) {
35
+ while (idx < segments.length && !segments[idx].isWordLike && segments[idx].segment.trim() === "") {
36
+ consumed += segments[idx].segment.length;
37
+ idx++;
38
+ }
39
+ }
40
+ return pos + consumed;
41
+ }
42
+ const after = text.slice(pos);
43
+ const match = after.match(/^\S+\s*/);
44
+ return match ? pos + match[0].length : text.length;
45
+ }
46
+ function deleteWordBackward(text, pos) {
47
+ if (pos <= 0) return { newText: text, newPos: pos };
48
+ const boundary = findWordBoundariesBackward(text, pos);
49
+ return {
50
+ newText: text.slice(0, boundary) + text.slice(pos),
51
+ newPos: boundary
52
+ };
53
+ }
54
+ function deleteWordForward(text, pos) {
55
+ if (pos >= text.length) return { newText: text, newPos: pos };
56
+ const boundary = findWordBoundaryForward(text, pos);
57
+ return {
58
+ newText: text.slice(0, pos) + text.slice(boundary),
59
+ newPos: pos
60
+ };
61
+ }
62
+ function deleteToLineStart(text, pos) {
63
+ if (pos <= 0) return { newText: text, newPos: 0 };
64
+ const lineStart = text.lastIndexOf("\n", pos - 1) + 1;
65
+ return {
66
+ newText: text.slice(0, lineStart) + text.slice(pos),
67
+ newPos: lineStart
68
+ };
69
+ }
70
+ function deleteToLineEnd(text, pos) {
71
+ if (pos >= text.length) return { newText: text, newPos: pos };
72
+ let lineEnd = text.indexOf("\n", pos);
73
+ if (lineEnd === -1) lineEnd = text.length;
74
+ return {
75
+ newText: text.slice(0, pos) + text.slice(lineEnd),
76
+ newPos: pos
77
+ };
78
+ }
79
+
80
+ export {
81
+ deleteWordBackward,
82
+ deleteWordForward,
83
+ deleteToLineStart,
84
+ deleteToLineEnd
85
+ };
@@ -1,3 +1,15 @@
1
+ import {
2
+ applyBlockquotePrefix,
3
+ getBlockquotePrefixAtPos,
4
+ normalizeMarkdownPaste
5
+ } from "./chunk-BGXCXQZP.js";
6
+ import {
7
+ deleteToLineEnd,
8
+ deleteToLineStart,
9
+ deleteWordBackward,
10
+ deleteWordForward
11
+ } from "./chunk-MPIWZLI3.js";
12
+
1
13
  // src/parser/inline-tokens.ts
2
14
  function overlaps(segs, start, end) {
3
15
  return segs.some((s) => start < s.end && end > s.start);
@@ -5,6 +17,31 @@ function overlaps(segs, start, end) {
5
17
  function tok(type, text, start) {
6
18
  return { type, text, start, end: start + text.length };
7
19
  }
20
+ function isEscaped(raw, index) {
21
+ let backslashCount = 0;
22
+ for (let cursor = index - 1; cursor >= 0 && raw[cursor] === "\\"; cursor--) {
23
+ backslashCount += 1;
24
+ }
25
+ return backslashCount % 2 === 1;
26
+ }
27
+ function findInlineMathRanges(raw) {
28
+ const ranges = [];
29
+ for (let start = 0; start < raw.length; start++) {
30
+ if (raw[start] !== "$" || isEscaped(raw, start)) continue;
31
+ if (raw[start + 1] === "$") {
32
+ start += 1;
33
+ continue;
34
+ }
35
+ for (let end = start + 1; end < raw.length; end++) {
36
+ if (raw[end] !== "$" || isEscaped(raw, end)) continue;
37
+ if (raw[end - 1] === "$" || raw[end + 1] === "$") continue;
38
+ ranges.push({ start, end: end + 1 });
39
+ start = end;
40
+ break;
41
+ }
42
+ }
43
+ return ranges;
44
+ }
8
45
  function tokenizeInline(raw, baseOffset = 0) {
9
46
  if (!raw) return [{ type: "text", text: "", start: baseOffset, end: baseOffset }];
10
47
  const segs = [];
@@ -68,6 +105,21 @@ function tokenizeInline(raw, baseOffset = 0) {
68
105
  });
69
106
  }
70
107
  }
108
+ for (const range of findInlineMathRanges(raw)) {
109
+ if (!overlaps(segs, range.start, range.end)) {
110
+ const innerStart = range.start + 1;
111
+ const innerEnd = range.end - 1;
112
+ segs.push({
113
+ start: range.start,
114
+ end: range.end,
115
+ tokens: [
116
+ tok("math-marker", "$", baseOffset + range.start),
117
+ tok("math-text", raw.slice(innerStart, innerEnd), baseOffset + innerStart),
118
+ tok("math-marker", "$", baseOffset + innerEnd)
119
+ ]
120
+ });
121
+ }
122
+ }
71
123
  for (const m of raw.matchAll(/\*\*(.+?)\*\*/g)) {
72
124
  const s = m.index;
73
125
  if (!overlaps(segs, s, s + m[0].length)) {
@@ -1338,112 +1390,6 @@ function toggleWrap(params, wrapper) {
1338
1390
  return { handled: true, value: newText, selectionStart: newCursor, selectionEnd: newCursor };
1339
1391
  }
1340
1392
 
1341
- // src/commands/word-boundary.ts
1342
- var hasIntlSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl;
1343
- function findWordBoundariesBackward(text, pos) {
1344
- if (pos <= 0) return 0;
1345
- if (hasIntlSegmenter) {
1346
- const segmenter = new Intl.Segmenter(void 0, { granularity: "word" });
1347
- const before2 = text.slice(0, pos);
1348
- const segments = [...segmenter.segment(before2)];
1349
- let idx = segments.length - 1;
1350
- while (idx >= 0 && !segments[idx].isWordLike && segments[idx].segment.trim() === "") {
1351
- idx--;
1352
- }
1353
- if (idx < 0) return 0;
1354
- return segments[idx].index;
1355
- }
1356
- const before = text.slice(0, pos);
1357
- const trimmed = before.replace(/\s+$/, "");
1358
- if (trimmed.length === 0) return 0;
1359
- const match = trimmed.match(/(?:.*\b)(\S+)$/);
1360
- return match ? trimmed.length - match[1].length : 0;
1361
- }
1362
- function findWordBoundaryForward(text, pos) {
1363
- if (pos >= text.length) return text.length;
1364
- if (hasIntlSegmenter) {
1365
- const segmenter = new Intl.Segmenter(void 0, { granularity: "word" });
1366
- const after2 = text.slice(pos);
1367
- const segments = [...segmenter.segment(after2)];
1368
- if (segments.length === 0) return pos;
1369
- let consumed = 0;
1370
- let idx = 0;
1371
- consumed += segments[idx].segment.length;
1372
- const wasWordLike = segments[idx].isWordLike;
1373
- idx++;
1374
- if (wasWordLike) {
1375
- while (idx < segments.length && !segments[idx].isWordLike && segments[idx].segment.trim() === "") {
1376
- consumed += segments[idx].segment.length;
1377
- idx++;
1378
- }
1379
- }
1380
- return pos + consumed;
1381
- }
1382
- const after = text.slice(pos);
1383
- const match = after.match(/^\S+\s*/);
1384
- return match ? pos + match[0].length : text.length;
1385
- }
1386
- function deleteWordBackward(text, pos) {
1387
- if (pos <= 0) return { newText: text, newPos: pos };
1388
- const boundary = findWordBoundariesBackward(text, pos);
1389
- return {
1390
- newText: text.slice(0, boundary) + text.slice(pos),
1391
- newPos: boundary
1392
- };
1393
- }
1394
- function deleteWordForward(text, pos) {
1395
- if (pos >= text.length) return { newText: text, newPos: pos };
1396
- const boundary = findWordBoundaryForward(text, pos);
1397
- return {
1398
- newText: text.slice(0, pos) + text.slice(boundary),
1399
- newPos: pos
1400
- };
1401
- }
1402
- function deleteToLineStart(text, pos) {
1403
- if (pos <= 0) return { newText: text, newPos: 0 };
1404
- const lineStart = text.lastIndexOf("\n", pos - 1) + 1;
1405
- return {
1406
- newText: text.slice(0, lineStart) + text.slice(pos),
1407
- newPos: lineStart
1408
- };
1409
- }
1410
- function deleteToLineEnd(text, pos) {
1411
- if (pos >= text.length) return { newText: text, newPos: pos };
1412
- let lineEnd = text.indexOf("\n", pos);
1413
- if (lineEnd === -1) lineEnd = text.length;
1414
- return {
1415
- newText: text.slice(0, pos) + text.slice(lineEnd),
1416
- newPos: pos
1417
- };
1418
- }
1419
-
1420
- // src/clipboard/paste.ts
1421
- function getBlockquotePrefixAtPos(text, pos) {
1422
- let lineStart = pos;
1423
- while (lineStart > 0 && text[lineStart - 1] !== "\n") lineStart--;
1424
- let lineEnd = pos;
1425
- while (lineEnd < text.length && text[lineEnd] !== "\n") lineEnd++;
1426
- const line = text.slice(lineStart, lineEnd);
1427
- const match = line.match(/^((?:\s*>\s?)+)/);
1428
- if (!match) return "";
1429
- const rawPrefix = match[1];
1430
- return /\s$/.test(rawPrefix) ? rawPrefix : rawPrefix + " ";
1431
- }
1432
- function applyBlockquotePrefix(cleaned, prefix) {
1433
- if (!prefix) return cleaned;
1434
- return cleaned.replace(/\n/g, "\n" + prefix);
1435
- }
1436
- function normalizeMarkdownPaste(raw, tabSize = 2) {
1437
- let text = raw;
1438
- text = text.replace(/\r\n/g, "\n");
1439
- text = text.replace(/\r/g, "\n");
1440
- text = text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
1441
- text = text.replace(/[\u200B\u200C\u200D\uFEFF]/g, "");
1442
- const spaces = " ".repeat(tabSize);
1443
- text = text.replace(/\t/g, spaces);
1444
- return text;
1445
- }
1446
-
1447
1393
  // src/commands/slash/registry.ts
1448
1394
  function createCommandRegistry() {
1449
1395
  const commands = /* @__PURE__ */ new Map();
@@ -3052,6 +2998,7 @@ var TOKEN_TO_CLASS = {
3052
2998
  "code-block-text": "owo-syntax-code-block",
3053
2999
  "strikethrough-marker": "owo-syntax-marker",
3054
3000
  "strikethrough": "owo-syntax-strikethrough",
3001
+ "math-marker": "owo-syntax-marker",
3055
3002
  "math-text": "owo-syntax-math",
3056
3003
  "hr": "owo-syntax-hr",
3057
3004
  "html": "owo-syntax-html"
@@ -3232,11 +3179,6 @@ export {
3232
3179
  insertTable,
3233
3180
  insertImage,
3234
3181
  insertSideAnnotation,
3235
- deleteWordBackward,
3236
- deleteWordForward,
3237
- deleteToLineStart,
3238
- deleteToLineEnd,
3239
- normalizeMarkdownPaste,
3240
3182
  createCommandRegistry,
3241
3183
  resolveBlockContextType,
3242
3184
  createOwoMarkCore,
@@ -68,7 +68,7 @@ type CompositionState = {
68
68
  active: boolean;
69
69
  range: VirtualSelection | null;
70
70
  };
71
- type InlineTokenType = 'text' | 'strong-marker' | 'strong' | 'emphasis-marker' | 'emphasis' | 'code-marker' | 'code' | 'link-bracket' | 'link-text' | 'link-url' | 'image-marker' | 'image-alt' | 'image-url' | 'heading-marker' | 'list-marker' | 'blockquote-marker' | 'fence-marker' | 'fence-lang' | 'code-block-text' | 'strikethrough-marker' | 'strikethrough' | 'math-text' | 'hr' | 'html';
71
+ type InlineTokenType = 'text' | 'strong-marker' | 'strong' | 'emphasis-marker' | 'emphasis' | 'code-marker' | 'code' | 'link-bracket' | 'link-text' | 'link-url' | 'image-marker' | 'image-alt' | 'image-url' | 'heading-marker' | 'list-marker' | 'blockquote-marker' | 'fence-marker' | 'fence-lang' | 'code-block-text' | 'strikethrough-marker' | 'strikethrough' | 'math-marker' | 'math-text' | 'hr' | 'html';
72
72
  type InlineToken = {
73
73
  type: InlineTokenType;
74
74
  text: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { B as BlockNode, a as BlockContextType, O as OwoMarkSelection, C as CoreStateSnapshot, S as SlashState, b as CommandRegistry, c as OwoMarkDocument, D as DirtyRange, P as PreviewBlockKind, d as PreviewBlock, e as BlockTransform, f as OwoMarkSharedStateController, I as InlineToken, g as InlineTokenType } from './dom-adapter-IZEW91gZ.js';
2
- export { h as BeforeInputIntent, i as BlockContext, j as BlockContextListener, k as BlockInsertType, l as BlockType, m as CommandContext, n as CommandDefinition, o as CompositionState, p as CoreApplyAction, q as CoreApplyResult, r as CoreSelectionSnapshot, s as CreateOwoMarkCoreOptions, t as Decorator, u as DecoratorType, v as DocumentChangeCallback, w as DomAdapterInstance, H as HeadingLevel, x as HistoryEntry, y as IndentMode, z as IndentResult, J as JsonPrimitive, A as JsonValue, K as KeyDownIntent, L as Leaf, E as OwoMarkCommands, F as OwoMarkCore, G as OwoMarkEditorInstance, M as OwoMarkEditorLike, N as OwoMarkSharedState, Q as OwoMarkSharedStateStore, R as PasteIntent, T as PreviewDirtyReason, U as SlashStateListener, V as SlashTriggerInfo, W as VirtualPosition, X as VirtualSelection, Y as applyMarkdownIndent, Z as createOwoMarkCore, _ as getBlockIndexForPosition, $ as isVirtualSelectionCollapsed, a0 as linearToVirtual, a1 as linearToVirtualPosition, a2 as resolveIndentSize, a3 as virtualPositionToLinear, a4 as virtualPositionsEqual, a5 as virtualToLinear } from './dom-adapter-IZEW91gZ.js';
1
+ import { B as BlockNode, a as BlockContextType, O as OwoMarkSelection, C as CoreStateSnapshot, S as SlashState, b as CommandRegistry, c as OwoMarkDocument, D as DirtyRange, P as PreviewBlockKind, d as PreviewBlock, e as BlockTransform, f as OwoMarkSharedStateController, I as InlineToken, g as InlineTokenType } from './dom-adapter-BwEilZtY.js';
2
+ export { h as BeforeInputIntent, i as BlockContext, j as BlockContextListener, k as BlockInsertType, l as BlockType, m as CommandContext, n as CommandDefinition, o as CompositionState, p as CoreApplyAction, q as CoreApplyResult, r as CoreSelectionSnapshot, s as CreateOwoMarkCoreOptions, t as Decorator, u as DecoratorType, v as DocumentChangeCallback, w as DomAdapterInstance, H as HeadingLevel, x as HistoryEntry, y as IndentMode, z as IndentResult, J as JsonPrimitive, A as JsonValue, K as KeyDownIntent, L as Leaf, E as OwoMarkCommands, F as OwoMarkCore, G as OwoMarkEditorInstance, M as OwoMarkEditorLike, N as OwoMarkSharedState, Q as OwoMarkSharedStateStore, R as PasteIntent, T as PreviewDirtyReason, U as SlashStateListener, V as SlashTriggerInfo, W as VirtualPosition, X as VirtualSelection, Y as applyMarkdownIndent, Z as createOwoMarkCore, _ as getBlockIndexForPosition, $ as isVirtualSelectionCollapsed, a0 as linearToVirtual, a1 as linearToVirtualPosition, a2 as resolveIndentSize, a3 as virtualPositionToLinear, a4 as virtualPositionsEqual, a5 as virtualToLinear } from './dom-adapter-BwEilZtY.js';
3
+ export { WordBoundaryResult, deleteToLineEnd, deleteToLineStart, deleteWordBackward, deleteWordForward } from './internal/commands/word-boundary.js';
4
+ export { normalizeMarkdownPaste } from './internal/clipboard/paste.js';
3
5
  export { enableMapSet, produce } from 'immer';
4
6
 
5
7
  /**
@@ -265,15 +267,6 @@ declare function insertSideAnnotation(params: {
265
267
  type?: string;
266
268
  }): CommandResult;
267
269
 
268
- type WordBoundaryResult = {
269
- newText: string;
270
- newPos: number;
271
- };
272
- declare function deleteWordBackward(text: string, pos: number): WordBoundaryResult;
273
- declare function deleteWordForward(text: string, pos: number): WordBoundaryResult;
274
- declare function deleteToLineStart(text: string, pos: number): WordBoundaryResult;
275
- declare function deleteToLineEnd(text: string, pos: number): WordBoundaryResult;
276
-
277
270
  /**
278
271
  * Block transform: extract image dimensions from Markdown image syntax.
279
272
  *
@@ -297,8 +290,6 @@ type ImageSizeSyntax = 'obsidian' | 'pandoc' | 'mou' | 'none';
297
290
  */
298
291
  declare function createImageSizeTransform(syntax?: ImageSizeSyntax): BlockTransform;
299
292
 
300
- declare function normalizeMarkdownPaste(raw: string, tabSize?: number): string;
301
-
302
293
  /**
303
294
  * Incremental DOM patch: only re-render dirty blocks.
304
295
  */
@@ -361,4 +352,4 @@ declare function buildVirtualRows(blocks: readonly BlockNode[], heightCache: Map
361
352
  /** Compute the visible range given scroll state. */
362
353
  declare function computeVisibleRange(rows: VirtualRow[], scrollTop: number, viewportHeight: number, overscan?: number): VisibleRange;
363
354
 
364
- export { BLOCK_TYPE_TO_CLASS, BQ_STEP, BlockContextType, type BlockIdGenerator, BlockNode, BlockTransform, CommandRegistry, type CommandResult, type CoreEventHub, type CoreSlashStateListener, CoreStateSnapshot, type CreateSharedStateOptions, DirtyRange, type ImageSizeSyntax, InlineToken, InlineTokenType, NOT_HANDLED, OwoMarkDocument, OwoMarkSelection, OwoMarkSharedStateController, PreviewBlock, PreviewBlockKind, SlashState, TOKEN_TO_CLASS, type VirtualRow, type VisibleRange, type WordBoundaryResult, buildBlockquoteBarsBoxShadow, buildVirtualRows, computePreviewDirtyRange, computeVisibleRange, createBlockElement, createBlockIdGenerator, createCommandRegistry, createImageSizeTransform, createSharedStateStore, deleteToLineEnd, deleteToLineStart, deleteWordBackward, deleteWordForward, deriveBlockId, deriveRenderKey, detectAndRenderDirty, domRangeToOffset, estimateEditorBlockHeight, expandDirtyRange, expandWithContext, fullRender, getBlockAtOffset, getBlockById, getBlockIndexById, getBlockStartOffset, handleCharInput, handleMarkdownEnter, handleSmartBackspace, handleSmartDelete, insertCodeFence, insertImage, insertLink, insertMathBlock, insertSideAnnotation, insertTable, invalidateBlockCache, normalizeMarkdownPaste, offsetToDomRange, parseMarkdownToDocument, patchDirtyBlocks, projectToPreviewBlocks, readSelection, reconcileBlocks, resetBlockIdCounter, resolveBlockContextType, restoreSelection, serializeDocument, toggleBold, toggleItalic, tokenizeBlock, tokenizeInline, updateBlockElement };
355
+ export { BLOCK_TYPE_TO_CLASS, BQ_STEP, BlockContextType, type BlockIdGenerator, BlockNode, BlockTransform, CommandRegistry, type CommandResult, type CoreEventHub, type CoreSlashStateListener, CoreStateSnapshot, type CreateSharedStateOptions, DirtyRange, type ImageSizeSyntax, InlineToken, InlineTokenType, NOT_HANDLED, OwoMarkDocument, OwoMarkSelection, OwoMarkSharedStateController, PreviewBlock, PreviewBlockKind, SlashState, TOKEN_TO_CLASS, type VirtualRow, type VisibleRange, buildBlockquoteBarsBoxShadow, buildVirtualRows, computePreviewDirtyRange, computeVisibleRange, createBlockElement, createBlockIdGenerator, createCommandRegistry, createImageSizeTransform, createSharedStateStore, deriveBlockId, deriveRenderKey, detectAndRenderDirty, domRangeToOffset, estimateEditorBlockHeight, expandDirtyRange, expandWithContext, fullRender, getBlockAtOffset, getBlockById, getBlockIndexById, getBlockStartOffset, handleCharInput, handleMarkdownEnter, handleSmartBackspace, handleSmartDelete, insertCodeFence, insertImage, insertLink, insertMathBlock, insertSideAnnotation, insertTable, invalidateBlockCache, offsetToDomRange, parseMarkdownToDocument, patchDirtyBlocks, projectToPreviewBlocks, readSelection, reconcileBlocks, resetBlockIdCounter, resolveBlockContextType, restoreSelection, serializeDocument, toggleBold, toggleItalic, tokenizeBlock, tokenizeInline, updateBlockElement };
package/dist/index.js CHANGED
@@ -11,10 +11,6 @@ import {
11
11
  createBlockIdGenerator,
12
12
  createCommandRegistry,
13
13
  createOwoMarkCore,
14
- deleteToLineEnd,
15
- deleteToLineStart,
16
- deleteWordBackward,
17
- deleteWordForward,
18
14
  detectAndRenderDirty,
19
15
  domRangeToOffset,
20
16
  expandDirtyRange,
@@ -39,7 +35,6 @@ import {
39
35
  isVirtualSelectionCollapsed,
40
36
  linearToVirtual,
41
37
  linearToVirtualPosition,
42
- normalizeMarkdownPaste,
43
38
  offsetToDomRange,
44
39
  parseMarkdownToDocument,
45
40
  patchDirtyBlocks,
@@ -58,7 +53,16 @@ import {
58
53
  virtualPositionToLinear,
59
54
  virtualPositionsEqual,
60
55
  virtualToLinear
61
- } from "./chunk-RYTHPR7H.js";
56
+ } from "./chunk-RINTEGPG.js";
57
+ import {
58
+ normalizeMarkdownPaste
59
+ } from "./chunk-BGXCXQZP.js";
60
+ import {
61
+ deleteToLineEnd,
62
+ deleteToLineStart,
63
+ deleteWordBackward,
64
+ deleteWordForward
65
+ } from "./chunk-MPIWZLI3.js";
62
66
 
63
67
  // src/preview/block-id.ts
64
68
  function deriveBlockId(startLine, endLine) {
@@ -177,6 +181,11 @@ function projectToPreviewBlocks(doc, themeKey, transforms) {
177
181
  i = sideChain.endIndex + 1;
178
182
  continue;
179
183
  }
184
+ if (isBlankParagraph(block)) {
185
+ currentLine += blockLines;
186
+ i++;
187
+ continue;
188
+ }
180
189
  if (isGroupableType(block.type)) {
181
190
  const groupType = block.type;
182
191
  const groupRawParts = [block.raw];
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Paste normalization and blockquote-aware insertion.
3
+ * Migrated from admin-editor-writing-assists.ts — pure functions.
4
+ */
5
+ /**
6
+ * Extract the blockquote prefix (e.g. "> ", ">> ") from the line at `pos`.
7
+ * Returns only blockquote markers — list markers are excluded so that
8
+ * pasted content may contain its own list structure.
9
+ */
10
+ declare function getBlockquotePrefixAtPos(text: string, pos: number): string;
11
+ /**
12
+ * Prepend a blockquote prefix to every newline in the pasted content,
13
+ * so multi-line pastes stay inside the blockquote.
14
+ */
15
+ declare function applyBlockquotePrefix(cleaned: string, prefix: string): string;
16
+ declare function normalizeMarkdownPaste(raw: string, tabSize?: number): string;
17
+
18
+ export { applyBlockquotePrefix, getBlockquotePrefixAtPos, normalizeMarkdownPaste };
@@ -0,0 +1,10 @@
1
+ import {
2
+ applyBlockquotePrefix,
3
+ getBlockquotePrefixAtPos,
4
+ normalizeMarkdownPaste
5
+ } from "../../chunk-BGXCXQZP.js";
6
+ export {
7
+ applyBlockquotePrefix,
8
+ getBlockquotePrefixAtPos,
9
+ normalizeMarkdownPaste
10
+ };
@@ -0,0 +1,10 @@
1
+ type WordBoundaryResult = {
2
+ newText: string;
3
+ newPos: number;
4
+ };
5
+ declare function deleteWordBackward(text: string, pos: number): WordBoundaryResult;
6
+ declare function deleteWordForward(text: string, pos: number): WordBoundaryResult;
7
+ declare function deleteToLineStart(text: string, pos: number): WordBoundaryResult;
8
+ declare function deleteToLineEnd(text: string, pos: number): WordBoundaryResult;
9
+
10
+ export { type WordBoundaryResult, deleteToLineEnd, deleteToLineStart, deleteWordBackward, deleteWordForward };
@@ -0,0 +1,12 @@
1
+ import {
2
+ deleteToLineEnd,
3
+ deleteToLineStart,
4
+ deleteWordBackward,
5
+ deleteWordForward
6
+ } from "../../chunk-MPIWZLI3.js";
7
+ export {
8
+ deleteToLineEnd,
9
+ deleteToLineStart,
10
+ deleteWordBackward,
11
+ deleteWordForward
12
+ };
@@ -1 +1 @@
1
- export { v as DocumentChangeCallback, w as DomAdapterInstance, a6 as createDomAdapter } from '../dom-adapter-IZEW91gZ.js';
1
+ export { v as DocumentChangeCallback, w as DomAdapterInstance, a6 as createDomAdapter } from '../dom-adapter-BwEilZtY.js';
@@ -4,9 +4,11 @@ import {
4
4
  fullRender,
5
5
  readSelection,
6
6
  restoreSelection
7
- } from "../chunk-RYTHPR7H.js";
7
+ } from "../chunk-RINTEGPG.js";
8
+ import "../chunk-BGXCXQZP.js";
9
+ import "../chunk-MPIWZLI3.js";
8
10
 
9
- // src/adapter/dom-adapter.ts
11
+ // src/internal/dom-adapter.ts
10
12
  function createDomAdapter() {
11
13
  const core = createOwoMarkCore();
12
14
  let root = null;
package/package.json CHANGED
@@ -1,20 +1,12 @@
1
1
  {
2
2
  "name": "@owomark/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Framework-agnostic core engine for the OwoMark editor.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "license": "MIT",
10
- "repository": {
11
- "type": "git",
12
- "url": "https://github.com/kzhoa/qblog.git",
13
- "directory": "owomark/packages/owomark-core"
14
- },
15
- "bugs": {
16
- "url": "https://github.com/kzhoa/qblog/issues"
17
- },
18
10
  "keywords": [
19
11
  "markdown",
20
12
  "editor",
@@ -29,8 +21,16 @@
29
21
  "import": "./dist/index.js"
30
22
  },
31
23
  "./internal/dom-adapter": {
32
- "types": "./dist/adapter/dom-adapter.d.ts",
33
- "import": "./dist/adapter/dom-adapter.js"
24
+ "types": "./dist/internal/dom-adapter.d.ts",
25
+ "import": "./dist/internal/dom-adapter.js"
26
+ },
27
+ "./internal/clipboard/paste": {
28
+ "types": "./dist/internal/clipboard/paste.d.ts",
29
+ "import": "./dist/internal/clipboard/paste.js"
30
+ },
31
+ "./internal/commands/word-boundary": {
32
+ "types": "./dist/internal/commands/word-boundary.d.ts",
33
+ "import": "./dist/internal/commands/word-boundary.js"
34
34
  }
35
35
  },
36
36
  "files": [