@rtif-sdk/web 1.0.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.
Files changed (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/block-drag-handler.d.ts +189 -0
  4. package/dist/block-drag-handler.d.ts.map +1 -0
  5. package/dist/block-drag-handler.js +745 -0
  6. package/dist/block-drag-handler.js.map +1 -0
  7. package/dist/block-renderer.d.ts +402 -0
  8. package/dist/block-renderer.d.ts.map +1 -0
  9. package/dist/block-renderer.js +424 -0
  10. package/dist/block-renderer.js.map +1 -0
  11. package/dist/clipboard.d.ts +178 -0
  12. package/dist/clipboard.d.ts.map +1 -0
  13. package/dist/clipboard.js +432 -0
  14. package/dist/clipboard.js.map +1 -0
  15. package/dist/command-bus.d.ts +113 -0
  16. package/dist/command-bus.d.ts.map +1 -0
  17. package/dist/command-bus.js +70 -0
  18. package/dist/command-bus.js.map +1 -0
  19. package/dist/composition.d.ts +220 -0
  20. package/dist/composition.d.ts.map +1 -0
  21. package/dist/composition.js +271 -0
  22. package/dist/composition.js.map +1 -0
  23. package/dist/content-extraction.d.ts +69 -0
  24. package/dist/content-extraction.d.ts.map +1 -0
  25. package/dist/content-extraction.js +228 -0
  26. package/dist/content-extraction.js.map +1 -0
  27. package/dist/content-handler-file.d.ts +40 -0
  28. package/dist/content-handler-file.d.ts.map +1 -0
  29. package/dist/content-handler-file.js +91 -0
  30. package/dist/content-handler-file.js.map +1 -0
  31. package/dist/content-handler-image.d.ts +82 -0
  32. package/dist/content-handler-image.d.ts.map +1 -0
  33. package/dist/content-handler-image.js +120 -0
  34. package/dist/content-handler-image.js.map +1 -0
  35. package/dist/content-handler-url.d.ts +129 -0
  36. package/dist/content-handler-url.d.ts.map +1 -0
  37. package/dist/content-handler-url.js +244 -0
  38. package/dist/content-handler-url.js.map +1 -0
  39. package/dist/content-handlers.d.ts +67 -0
  40. package/dist/content-handlers.d.ts.map +1 -0
  41. package/dist/content-handlers.js +263 -0
  42. package/dist/content-handlers.js.map +1 -0
  43. package/dist/content-pipeline.d.ts +383 -0
  44. package/dist/content-pipeline.d.ts.map +1 -0
  45. package/dist/content-pipeline.js +232 -0
  46. package/dist/content-pipeline.js.map +1 -0
  47. package/dist/cursor-nav.d.ts +149 -0
  48. package/dist/cursor-nav.d.ts.map +1 -0
  49. package/dist/cursor-nav.js +230 -0
  50. package/dist/cursor-nav.js.map +1 -0
  51. package/dist/cursor-rect.d.ts +65 -0
  52. package/dist/cursor-rect.d.ts.map +1 -0
  53. package/dist/cursor-rect.js +98 -0
  54. package/dist/cursor-rect.js.map +1 -0
  55. package/dist/drop-indicator.d.ts +108 -0
  56. package/dist/drop-indicator.d.ts.map +1 -0
  57. package/dist/drop-indicator.js +236 -0
  58. package/dist/drop-indicator.js.map +1 -0
  59. package/dist/editor.d.ts +41 -0
  60. package/dist/editor.d.ts.map +1 -0
  61. package/dist/editor.js +710 -0
  62. package/dist/editor.js.map +1 -0
  63. package/dist/floating-toolbar.d.ts +93 -0
  64. package/dist/floating-toolbar.d.ts.map +1 -0
  65. package/dist/floating-toolbar.js +159 -0
  66. package/dist/floating-toolbar.js.map +1 -0
  67. package/dist/index.d.ts +62 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +119 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/input-bridge.d.ts +273 -0
  72. package/dist/input-bridge.d.ts.map +1 -0
  73. package/dist/input-bridge.js +884 -0
  74. package/dist/input-bridge.js.map +1 -0
  75. package/dist/link-popover.d.ts +38 -0
  76. package/dist/link-popover.d.ts.map +1 -0
  77. package/dist/link-popover.js +278 -0
  78. package/dist/link-popover.js.map +1 -0
  79. package/dist/mark-renderer.d.ts +275 -0
  80. package/dist/mark-renderer.d.ts.map +1 -0
  81. package/dist/mark-renderer.js +210 -0
  82. package/dist/mark-renderer.js.map +1 -0
  83. package/dist/perf.d.ts +145 -0
  84. package/dist/perf.d.ts.map +1 -0
  85. package/dist/perf.js +260 -0
  86. package/dist/perf.js.map +1 -0
  87. package/dist/plugin-kit.d.ts +265 -0
  88. package/dist/plugin-kit.d.ts.map +1 -0
  89. package/dist/plugin-kit.js +234 -0
  90. package/dist/plugin-kit.js.map +1 -0
  91. package/dist/plugins/alignment-plugin.d.ts +68 -0
  92. package/dist/plugins/alignment-plugin.d.ts.map +1 -0
  93. package/dist/plugins/alignment-plugin.js +98 -0
  94. package/dist/plugins/alignment-plugin.js.map +1 -0
  95. package/dist/plugins/block-utils.d.ts +113 -0
  96. package/dist/plugins/block-utils.d.ts.map +1 -0
  97. package/dist/plugins/block-utils.js +191 -0
  98. package/dist/plugins/block-utils.js.map +1 -0
  99. package/dist/plugins/blockquote-plugin.d.ts +39 -0
  100. package/dist/plugins/blockquote-plugin.d.ts.map +1 -0
  101. package/dist/plugins/blockquote-plugin.js +88 -0
  102. package/dist/plugins/blockquote-plugin.js.map +1 -0
  103. package/dist/plugins/bold-plugin.d.ts +37 -0
  104. package/dist/plugins/bold-plugin.d.ts.map +1 -0
  105. package/dist/plugins/bold-plugin.js +48 -0
  106. package/dist/plugins/bold-plugin.js.map +1 -0
  107. package/dist/plugins/callout-plugin.d.ts +100 -0
  108. package/dist/plugins/callout-plugin.d.ts.map +1 -0
  109. package/dist/plugins/callout-plugin.js +200 -0
  110. package/dist/plugins/callout-plugin.js.map +1 -0
  111. package/dist/plugins/code-block-plugin.d.ts +62 -0
  112. package/dist/plugins/code-block-plugin.d.ts.map +1 -0
  113. package/dist/plugins/code-block-plugin.js +176 -0
  114. package/dist/plugins/code-block-plugin.js.map +1 -0
  115. package/dist/plugins/code-plugin.d.ts +37 -0
  116. package/dist/plugins/code-plugin.d.ts.map +1 -0
  117. package/dist/plugins/code-plugin.js +48 -0
  118. package/dist/plugins/code-plugin.js.map +1 -0
  119. package/dist/plugins/embed-plugin.d.ts +90 -0
  120. package/dist/plugins/embed-plugin.d.ts.map +1 -0
  121. package/dist/plugins/embed-plugin.js +147 -0
  122. package/dist/plugins/embed-plugin.js.map +1 -0
  123. package/dist/plugins/font-family-plugin.d.ts +58 -0
  124. package/dist/plugins/font-family-plugin.d.ts.map +1 -0
  125. package/dist/plugins/font-family-plugin.js +57 -0
  126. package/dist/plugins/font-family-plugin.js.map +1 -0
  127. package/dist/plugins/font-size-plugin.d.ts +57 -0
  128. package/dist/plugins/font-size-plugin.d.ts.map +1 -0
  129. package/dist/plugins/font-size-plugin.js +56 -0
  130. package/dist/plugins/font-size-plugin.js.map +1 -0
  131. package/dist/plugins/heading-plugin.d.ts +52 -0
  132. package/dist/plugins/heading-plugin.d.ts.map +1 -0
  133. package/dist/plugins/heading-plugin.js +114 -0
  134. package/dist/plugins/heading-plugin.js.map +1 -0
  135. package/dist/plugins/hr-plugin.d.ts +33 -0
  136. package/dist/plugins/hr-plugin.d.ts.map +1 -0
  137. package/dist/plugins/hr-plugin.js +75 -0
  138. package/dist/plugins/hr-plugin.js.map +1 -0
  139. package/dist/plugins/image-plugin.d.ts +115 -0
  140. package/dist/plugins/image-plugin.d.ts.map +1 -0
  141. package/dist/plugins/image-plugin.js +199 -0
  142. package/dist/plugins/image-plugin.js.map +1 -0
  143. package/dist/plugins/indent-plugin.d.ts +62 -0
  144. package/dist/plugins/indent-plugin.d.ts.map +1 -0
  145. package/dist/plugins/indent-plugin.js +128 -0
  146. package/dist/plugins/indent-plugin.js.map +1 -0
  147. package/dist/plugins/index.d.ts +45 -0
  148. package/dist/plugins/index.d.ts.map +1 -0
  149. package/dist/plugins/index.js +42 -0
  150. package/dist/plugins/index.js.map +1 -0
  151. package/dist/plugins/italic-plugin.d.ts +37 -0
  152. package/dist/plugins/italic-plugin.d.ts.map +1 -0
  153. package/dist/plugins/italic-plugin.js +48 -0
  154. package/dist/plugins/italic-plugin.js.map +1 -0
  155. package/dist/plugins/link-plugin.d.ts +129 -0
  156. package/dist/plugins/link-plugin.d.ts.map +1 -0
  157. package/dist/plugins/link-plugin.js +212 -0
  158. package/dist/plugins/link-plugin.js.map +1 -0
  159. package/dist/plugins/list-plugin.d.ts +53 -0
  160. package/dist/plugins/list-plugin.d.ts.map +1 -0
  161. package/dist/plugins/list-plugin.js +309 -0
  162. package/dist/plugins/list-plugin.js.map +1 -0
  163. package/dist/plugins/mark-utils.d.ts +173 -0
  164. package/dist/plugins/mark-utils.d.ts.map +1 -0
  165. package/dist/plugins/mark-utils.js +425 -0
  166. package/dist/plugins/mark-utils.js.map +1 -0
  167. package/dist/plugins/mention-plugin.d.ts +191 -0
  168. package/dist/plugins/mention-plugin.d.ts.map +1 -0
  169. package/dist/plugins/mention-plugin.js +295 -0
  170. package/dist/plugins/mention-plugin.js.map +1 -0
  171. package/dist/plugins/strikethrough-plugin.d.ts +37 -0
  172. package/dist/plugins/strikethrough-plugin.d.ts.map +1 -0
  173. package/dist/plugins/strikethrough-plugin.js +48 -0
  174. package/dist/plugins/strikethrough-plugin.js.map +1 -0
  175. package/dist/plugins/text-color-plugin.d.ts +57 -0
  176. package/dist/plugins/text-color-plugin.d.ts.map +1 -0
  177. package/dist/plugins/text-color-plugin.js +56 -0
  178. package/dist/plugins/text-color-plugin.js.map +1 -0
  179. package/dist/plugins/underline-plugin.d.ts +37 -0
  180. package/dist/plugins/underline-plugin.d.ts.map +1 -0
  181. package/dist/plugins/underline-plugin.js +48 -0
  182. package/dist/plugins/underline-plugin.js.map +1 -0
  183. package/dist/presets.d.ts +95 -0
  184. package/dist/presets.d.ts.map +1 -0
  185. package/dist/presets.js +159 -0
  186. package/dist/presets.js.map +1 -0
  187. package/dist/renderer.d.ts +125 -0
  188. package/dist/renderer.d.ts.map +1 -0
  189. package/dist/renderer.js +415 -0
  190. package/dist/renderer.js.map +1 -0
  191. package/dist/scroll-to-cursor.d.ts +25 -0
  192. package/dist/scroll-to-cursor.d.ts.map +1 -0
  193. package/dist/scroll-to-cursor.js +59 -0
  194. package/dist/scroll-to-cursor.js.map +1 -0
  195. package/dist/selection-sync.d.ts +159 -0
  196. package/dist/selection-sync.d.ts.map +1 -0
  197. package/dist/selection-sync.js +527 -0
  198. package/dist/selection-sync.js.map +1 -0
  199. package/dist/shortcut-handler.d.ts +98 -0
  200. package/dist/shortcut-handler.d.ts.map +1 -0
  201. package/dist/shortcut-handler.js +155 -0
  202. package/dist/shortcut-handler.js.map +1 -0
  203. package/dist/toolbar.d.ts +103 -0
  204. package/dist/toolbar.d.ts.map +1 -0
  205. package/dist/toolbar.js +134 -0
  206. package/dist/toolbar.js.map +1 -0
  207. package/dist/trigger-manager.d.ts +205 -0
  208. package/dist/trigger-manager.d.ts.map +1 -0
  209. package/dist/trigger-manager.js +466 -0
  210. package/dist/trigger-manager.js.map +1 -0
  211. package/dist/types.d.ts +216 -0
  212. package/dist/types.d.ts.map +1 -0
  213. package/dist/types.js +2 -0
  214. package/dist/types.js.map +1 -0
  215. package/package.json +30 -0
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Embed block type plugin — registers the `embed` block type and
3
+ * `insertEmbed` / `removeEmbed` commands for embedding external content
4
+ * (YouTube, Twitter/X, Vimeo, etc.) as atomic, non-editable blocks.
5
+ *
6
+ * Embed blocks are atomic — they carry no meaningful text content.
7
+ * Their visual representation is determined by the block renderer layer
8
+ * (iframe, provider-specific HTML, etc.) based on the `url` and
9
+ * `embedType` attributes.
10
+ *
11
+ * @module
12
+ */
13
+ import { blockTextLength } from '@rtif-sdk/core';
14
+ import { getBlockAtCursor, getBlockStartOffset } from './block-utils.js';
15
+ /**
16
+ * Command name constants for the embed plugin.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * engine.exec(EmbedCommands.INSERT, { url: 'https://youtube.com/...' });
21
+ * engine.exec(EmbedCommands.REMOVE, { blockId: 'b3' });
22
+ * ```
23
+ */
24
+ export const EmbedCommands = {
25
+ INSERT: 'insertEmbed',
26
+ REMOVE: 'removeEmbed',
27
+ };
28
+ /**
29
+ * Create the embed block type plugin.
30
+ *
31
+ * Registers:
32
+ * - Block type: `embed` (attrs must include `url` as a non-empty string)
33
+ * - Command: `insertEmbed` — inserts a new embed block after the current block
34
+ * - Command: `removeEmbed` — reverts an embed block to plain text, clearing embed attrs
35
+ *
36
+ * @returns A plugin instance ready for `engine.use()`
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const engine = createEngine(initialDoc);
41
+ * engine.use(embedPlugin());
42
+ *
43
+ * // Insert a YouTube embed after the current block
44
+ * engine.exec(EmbedCommands.INSERT, {
45
+ * url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
46
+ * type: 'video',
47
+ * });
48
+ *
49
+ * // Remove the embed, reverting to a plain text block
50
+ * engine.exec(EmbedCommands.REMOVE, { blockId: 'b2' });
51
+ * ```
52
+ */
53
+ export function embedPlugin() {
54
+ return {
55
+ id: 'block-embed',
56
+ init(ctx) {
57
+ // ---------------------------------------------------------------
58
+ // Block type registration
59
+ // ---------------------------------------------------------------
60
+ ctx.registerBlockType('embed', {
61
+ validate: (attrs) => {
62
+ return typeof attrs.url === 'string' && attrs.url.length > 0;
63
+ },
64
+ });
65
+ // ---------------------------------------------------------------
66
+ // insertEmbed command
67
+ // ---------------------------------------------------------------
68
+ ctx.registerCommand(EmbedCommands.INSERT, {
69
+ /**
70
+ * Insert a new embed block after the block at the cursor.
71
+ *
72
+ * Implementation:
73
+ * 1. Get the current block and compute its end offset.
74
+ * 2. `split_block` at the end offset to create a new empty block.
75
+ * 3. `set_block_type` on the new block to `'embed'`.
76
+ * 4. `set_block_attrs` on the new block with `{ url, embedType }`.
77
+ *
78
+ * @param engine - The editor engine instance
79
+ * @param payload - {@link InsertEmbedPayload} with `url` and optional `type`
80
+ */
81
+ execute(engine, payload) {
82
+ const p = payload;
83
+ if (!p || typeof p.url !== 'string' || p.url.length === 0)
84
+ return;
85
+ const block = getBlockAtCursor(engine);
86
+ const blockStart = getBlockStartOffset(engine.state.doc, block.id);
87
+ const blockLen = blockTextLength(block);
88
+ const splitOffset = blockStart + blockLen;
89
+ const newBlockId = `${block.id}_embed`;
90
+ const embedType = p.type ?? 'generic';
91
+ const ops = [
92
+ { type: 'split_block', offset: splitOffset, newBlockId },
93
+ { type: 'set_block_type', blockId: newBlockId, blockType: 'embed' },
94
+ {
95
+ type: 'set_block_attrs',
96
+ blockId: newBlockId,
97
+ attrs: { url: p.url, embedType },
98
+ },
99
+ ];
100
+ engine.dispatch(ops);
101
+ },
102
+ canExecute(_engine) {
103
+ return true;
104
+ },
105
+ });
106
+ // ---------------------------------------------------------------
107
+ // removeEmbed command
108
+ // ---------------------------------------------------------------
109
+ ctx.registerCommand(EmbedCommands.REMOVE, {
110
+ /**
111
+ * Remove an embed block, reverting it to a plain text block.
112
+ *
113
+ * Sets the block's type to `'text'` and clears the embed-specific
114
+ * attrs (`url` and `embedType`).
115
+ *
116
+ * @param engine - The editor engine instance
117
+ * @param payload - {@link RemoveEmbedPayload} with `blockId`
118
+ */
119
+ execute(engine, payload) {
120
+ const p = payload;
121
+ if (!p || typeof p.blockId !== 'string')
122
+ return;
123
+ const block = engine.state.doc.blocks.find((b) => b.id === p.blockId);
124
+ if (!block || block.type !== 'embed')
125
+ return;
126
+ const ops = [
127
+ { type: 'set_block_type', blockId: p.blockId, blockType: 'text' },
128
+ {
129
+ type: 'set_block_attrs',
130
+ blockId: p.blockId,
131
+ attrs: { url: null, embedType: null },
132
+ },
133
+ ];
134
+ engine.dispatch(ops);
135
+ },
136
+ canExecute(engine, payload) {
137
+ const p = payload;
138
+ if (!p || typeof p.blockId !== 'string')
139
+ return false;
140
+ const block = engine.state.doc.blocks.find((b) => b.id === p.blockId);
141
+ return block !== undefined && block.type === 'embed';
142
+ },
143
+ });
144
+ },
145
+ };
146
+ }
147
+ //# sourceMappingURL=embed-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed-plugin.js","sourceRoot":"","sources":["../../src/plugins/embed-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEzE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;CACb,CAAC;AA0CX;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,IAAI,CAAC,GAAG;YACN,kEAAkE;YAClE,0BAA0B;YAC1B,kEAAkE;YAElE,GAAG,CAAC,iBAAiB,CAAC,OAAO,EAAE;gBAC7B,QAAQ,EAAE,CAAC,KAA8B,EAAW,EAAE;oBACpD,OAAO,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC/D,CAAC;aACF,CAAC,CAAC;YAEH,kEAAkE;YAClE,sBAAsB;YACtB,kEAAkE;YAElE,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,MAAM,EAAE;gBACxC;;;;;;;;;;;mBAWG;gBACH,OAAO,CAAC,MAAqB,EAAE,OAAiB;oBAC9C,MAAM,CAAC,GAAG,OAAyC,CAAC;oBACpD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;wBAAE,OAAO;oBAElE,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;oBACvC,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;oBACnE,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;oBACxC,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;oBAE1C,MAAM,UAAU,GAAG,GAAG,KAAK,CAAC,EAAE,QAAQ,CAAC;oBACvC,MAAM,SAAS,GAAc,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;oBAEjD,MAAM,GAAG,GAAgB;wBACvB,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE;wBACxD,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE;wBACnE;4BACE,IAAI,EAAE,iBAAiB;4BACvB,OAAO,EAAE,UAAU;4BACnB,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE;yBACjC;qBACF,CAAC;oBAEF,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAED,UAAU,CAAC,OAAsB;oBAC/B,OAAO,IAAI,CAAC;gBACd,CAAC;aACF,CAAC,CAAC;YAEH,kEAAkE;YAClE,sBAAsB;YACtB,kEAAkE;YAElE,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,MAAM,EAAE;gBACxC;;;;;;;;mBAQG;gBACH,OAAO,CAAC,MAAqB,EAAE,OAAiB;oBAC9C,MAAM,CAAC,GAAG,OAAyC,CAAC;oBACpD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;wBAAE,OAAO;oBAEhD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAC1B,CAAC;oBACF,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;wBAAE,OAAO;oBAE7C,MAAM,GAAG,GAAgB;wBACvB,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;wBACjE;4BACE,IAAI,EAAE,iBAAiB;4BACvB,OAAO,EAAE,CAAC,CAAC,OAAO;4BAClB,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;yBACtC;qBACF,CAAC;oBAEF,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAED,UAAU,CAAC,MAAqB,EAAE,OAAiB;oBACjD,MAAM,CAAC,GAAG,OAAyC,CAAC;oBACpD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;wBAAE,OAAO,KAAK,CAAC;oBAEtD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAC1B,CAAC;oBACF,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;gBACvD,CAAC;aACF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Font family mark plugin — registers the `fontFamily` mark type,
3
+ * `setFontFamily` and `removeFontFamily` commands.
4
+ *
5
+ * This is a parameterized mark plugin: the mark value is a non-empty string
6
+ * representing a CSS font-family value (e.g., `"Arial"`, `"monospace"`,
7
+ * `"'Courier New', monospace"`).
8
+ *
9
+ * @module
10
+ */
11
+ import type { Plugin } from '@rtif-sdk/engine';
12
+ /**
13
+ * Command name constants for the font family plugin.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
18
+ * engine.exec(FontFamilyCommands.REMOVE);
19
+ * ```
20
+ */
21
+ export declare const FontFamilyCommands: {
22
+ readonly SET: "setFontFamily";
23
+ readonly REMOVE: "removeFontFamily";
24
+ };
25
+ /**
26
+ * Payload for the `setFontFamily` command.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * engine.exec('setFontFamily', { family: 'Arial' });
31
+ * ```
32
+ */
33
+ export interface SetFontFamilyPayload {
34
+ /** The CSS font-family value to apply */
35
+ readonly family: string;
36
+ }
37
+ /**
38
+ * Create the font family mark plugin.
39
+ *
40
+ * Registers:
41
+ * - Mark type: `fontFamily` (value must be a non-empty string)
42
+ * - Command: `setFontFamily` — apply font family to selection or set pending mark
43
+ * - Command: `removeFontFamily` — remove font family from selection or set pending mark null
44
+ *
45
+ * No keyboard shortcuts are registered.
46
+ *
47
+ * @returns A plugin instance ready for `engine.use()`
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const engine = createEngine(initialDoc);
52
+ * engine.use(fontFamilyPlugin());
53
+ * engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
54
+ * engine.exec(FontFamilyCommands.REMOVE);
55
+ * ```
56
+ */
57
+ export declare function fontFamilyPlugin(): Plugin;
58
+ //# sourceMappingURL=font-family-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-family-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/font-family-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Font family mark plugin — registers the `fontFamily` mark type,
3
+ * `setFontFamily` and `removeFontFamily` commands.
4
+ *
5
+ * This is a parameterized mark plugin: the mark value is a non-empty string
6
+ * representing a CSS font-family value (e.g., `"Arial"`, `"monospace"`,
7
+ * `"'Courier New', monospace"`).
8
+ *
9
+ * @module
10
+ */
11
+ import { createSetMarkCommand, createRemoveMarkCommand } from './mark-utils.js';
12
+ /**
13
+ * Command name constants for the font family plugin.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
18
+ * engine.exec(FontFamilyCommands.REMOVE);
19
+ * ```
20
+ */
21
+ export const FontFamilyCommands = {
22
+ SET: 'setFontFamily',
23
+ REMOVE: 'removeFontFamily',
24
+ };
25
+ /**
26
+ * Create the font family mark plugin.
27
+ *
28
+ * Registers:
29
+ * - Mark type: `fontFamily` (value must be a non-empty string)
30
+ * - Command: `setFontFamily` — apply font family to selection or set pending mark
31
+ * - Command: `removeFontFamily` — remove font family from selection or set pending mark null
32
+ *
33
+ * No keyboard shortcuts are registered.
34
+ *
35
+ * @returns A plugin instance ready for `engine.use()`
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const engine = createEngine(initialDoc);
40
+ * engine.use(fontFamilyPlugin());
41
+ * engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
42
+ * engine.exec(FontFamilyCommands.REMOVE);
43
+ * ```
44
+ */
45
+ export function fontFamilyPlugin() {
46
+ return {
47
+ id: 'mark-fontFamily',
48
+ init(ctx) {
49
+ ctx.registerMarkType('fontFamily', {
50
+ validate: (value) => typeof value === 'string' && value.length > 0,
51
+ });
52
+ ctx.registerCommand(FontFamilyCommands.SET, createSetMarkCommand('fontFamily', (p) => p.family));
53
+ ctx.registerCommand(FontFamilyCommands.REMOVE, createRemoveMarkCommand('fontFamily'));
54
+ },
55
+ };
56
+ }
57
+ //# sourceMappingURL=font-family-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-family-plugin.js","sourceRoot":"","sources":["../../src/plugins/font-family-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,GAAG,EAAE,eAAe;IACpB,MAAM,EAAE,kBAAkB;CAClB,CAAC;AAeX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,EAAE,EAAE,iBAAiB;QACrB,IAAI,CAAC,GAAG;YACN,GAAG,CAAC,gBAAgB,CAAC,YAAY,EAAE;gBACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;aACnE,CAAC,CAAC;YAEH,GAAG,CAAC,eAAe,CACjB,kBAAkB,CAAC,GAAG,EACtB,oBAAoB,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAE,CAA0B,CAAC,MAAM,CAAC,CAC9E,CAAC;YAEF,GAAG,CAAC,eAAe,CAAC,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC,CAAC;QACxF,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Font size mark plugin — registers the `fontSize` mark type,
3
+ * `setFontSize` and `removeFontSize` commands.
4
+ *
5
+ * This is a parameterized mark plugin: the mark value is a positive number
6
+ * representing the font size (unit is consumer-defined, typically px or pt).
7
+ *
8
+ * @module
9
+ */
10
+ import type { Plugin } from '@rtif-sdk/engine';
11
+ /**
12
+ * Command name constants for the font size plugin.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * engine.exec(FontSizeCommands.SET, { size: 24 });
17
+ * engine.exec(FontSizeCommands.REMOVE);
18
+ * ```
19
+ */
20
+ export declare const FontSizeCommands: {
21
+ readonly SET: "setFontSize";
22
+ readonly REMOVE: "removeFontSize";
23
+ };
24
+ /**
25
+ * Payload for the `setFontSize` command.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * engine.exec('setFontSize', { size: 16 });
30
+ * ```
31
+ */
32
+ export interface SetFontSizePayload {
33
+ /** The font size value (must be a positive number) */
34
+ readonly size: number;
35
+ }
36
+ /**
37
+ * Create the font size mark plugin.
38
+ *
39
+ * Registers:
40
+ * - Mark type: `fontSize` (value must be a positive number)
41
+ * - Command: `setFontSize` — apply font size to selection or set pending mark
42
+ * - Command: `removeFontSize` — remove font size from selection or set pending mark null
43
+ *
44
+ * No keyboard shortcuts are registered.
45
+ *
46
+ * @returns A plugin instance ready for `engine.use()`
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const engine = createEngine(initialDoc);
51
+ * engine.use(fontSizePlugin());
52
+ * engine.exec(FontSizeCommands.SET, { size: 24 });
53
+ * engine.exec(FontSizeCommands.REMOVE);
54
+ * ```
55
+ */
56
+ export declare function fontSizePlugin(): Plugin;
57
+ //# sourceMappingURL=font-size-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-size-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/font-size-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAgBvC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Font size mark plugin — registers the `fontSize` mark type,
3
+ * `setFontSize` and `removeFontSize` commands.
4
+ *
5
+ * This is a parameterized mark plugin: the mark value is a positive number
6
+ * representing the font size (unit is consumer-defined, typically px or pt).
7
+ *
8
+ * @module
9
+ */
10
+ import { createSetMarkCommand, createRemoveMarkCommand } from './mark-utils.js';
11
+ /**
12
+ * Command name constants for the font size plugin.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * engine.exec(FontSizeCommands.SET, { size: 24 });
17
+ * engine.exec(FontSizeCommands.REMOVE);
18
+ * ```
19
+ */
20
+ export const FontSizeCommands = {
21
+ SET: 'setFontSize',
22
+ REMOVE: 'removeFontSize',
23
+ };
24
+ /**
25
+ * Create the font size mark plugin.
26
+ *
27
+ * Registers:
28
+ * - Mark type: `fontSize` (value must be a positive number)
29
+ * - Command: `setFontSize` — apply font size to selection or set pending mark
30
+ * - Command: `removeFontSize` — remove font size from selection or set pending mark null
31
+ *
32
+ * No keyboard shortcuts are registered.
33
+ *
34
+ * @returns A plugin instance ready for `engine.use()`
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * const engine = createEngine(initialDoc);
39
+ * engine.use(fontSizePlugin());
40
+ * engine.exec(FontSizeCommands.SET, { size: 24 });
41
+ * engine.exec(FontSizeCommands.REMOVE);
42
+ * ```
43
+ */
44
+ export function fontSizePlugin() {
45
+ return {
46
+ id: 'mark-fontSize',
47
+ init(ctx) {
48
+ ctx.registerMarkType('fontSize', {
49
+ validate: (value) => typeof value === 'number' && value > 0,
50
+ });
51
+ ctx.registerCommand(FontSizeCommands.SET, createSetMarkCommand('fontSize', (p) => p.size));
52
+ ctx.registerCommand(FontSizeCommands.REMOVE, createRemoveMarkCommand('fontSize'));
53
+ },
54
+ };
55
+ }
56
+ //# sourceMappingURL=font-size-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-size-plugin.js","sourceRoot":"","sources":["../../src/plugins/font-size-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,aAAa;IAClB,MAAM,EAAE,gBAAgB;CAChB,CAAC;AAeX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,EAAE,EAAE,eAAe;QACnB,IAAI,CAAC,GAAG;YACN,GAAG,CAAC,gBAAgB,CAAC,UAAU,EAAE;gBAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC;aAC5D,CAAC,CAAC;YAEH,GAAG,CAAC,eAAe,CACjB,gBAAgB,CAAC,GAAG,EACpB,oBAAoB,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAE,CAAwB,CAAC,IAAI,CAAC,CACxE,CAAC;YAEF,GAAG,CAAC,eAAe,CAAC,gBAAgB,CAAC,MAAM,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Heading block type plugin — registers the `heading` block type, `toggleHeading`
3
+ * command, input rules for `# ` through `###### `, and Cmd/Ctrl+Alt+1/2/3 shortcuts.
4
+ *
5
+ * @module
6
+ */
7
+ import type { Plugin } from '@rtif-sdk/engine';
8
+ /**
9
+ * Command name constants for the heading plugin.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * engine.exec(HeadingCommands.TOGGLE, { level: 2 });
14
+ * ```
15
+ */
16
+ export declare const HeadingCommands: {
17
+ readonly TOGGLE: "toggleHeading";
18
+ };
19
+ /**
20
+ * Payload for the `toggleHeading` command.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * engine.exec('toggleHeading', { level: 2 });
25
+ * ```
26
+ */
27
+ export interface ToggleHeadingPayload {
28
+ /** Heading level (1-6) */
29
+ readonly level: number;
30
+ }
31
+ /**
32
+ * Create the heading block type plugin.
33
+ *
34
+ * Registers:
35
+ * - Block type: `heading` (attrs must have `level` between 1 and 6)
36
+ * - Command: `toggleHeading` — toggle between heading at a given level and plain text
37
+ * - Input rules: `# ` through `###### ` at block start converts to heading
38
+ * - Shortcuts: Cmd/Ctrl+Alt+1/2/3 for heading levels 1-3
39
+ *
40
+ * @returns A plugin instance ready for `engine.use()`
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const engine = createEngine(initialDoc);
45
+ * engine.use(headingPlugin());
46
+ *
47
+ * // Toggle heading level 2 on the block at cursor
48
+ * engine.exec(HeadingCommands.TOGGLE, { level: 2 });
49
+ * ```
50
+ */
51
+ export declare function headingPlugin(): Plugin;
52
+ //# sourceMappingURL=heading-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heading-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/heading-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAG9D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;CAElB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,IAAI,MAAM,CA2FtC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Heading block type plugin — registers the `heading` block type, `toggleHeading`
3
+ * command, input rules for `# ` through `###### `, and Cmd/Ctrl+Alt+1/2/3 shortcuts.
4
+ *
5
+ * @module
6
+ */
7
+ import { getBlockStartOffset, getBlockAtCursor, isBlockType, setBlockType } from './block-utils.js';
8
+ /**
9
+ * Command name constants for the heading plugin.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * engine.exec(HeadingCommands.TOGGLE, { level: 2 });
14
+ * ```
15
+ */
16
+ export const HeadingCommands = {
17
+ TOGGLE: 'toggleHeading',
18
+ };
19
+ /**
20
+ * Create the heading block type plugin.
21
+ *
22
+ * Registers:
23
+ * - Block type: `heading` (attrs must have `level` between 1 and 6)
24
+ * - Command: `toggleHeading` — toggle between heading at a given level and plain text
25
+ * - Input rules: `# ` through `###### ` at block start converts to heading
26
+ * - Shortcuts: Cmd/Ctrl+Alt+1/2/3 for heading levels 1-3
27
+ *
28
+ * @returns A plugin instance ready for `engine.use()`
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const engine = createEngine(initialDoc);
33
+ * engine.use(headingPlugin());
34
+ *
35
+ * // Toggle heading level 2 on the block at cursor
36
+ * engine.exec(HeadingCommands.TOGGLE, { level: 2 });
37
+ * ```
38
+ */
39
+ export function headingPlugin() {
40
+ return {
41
+ id: 'block-heading',
42
+ init(ctx) {
43
+ // ---------------------------------------------------------------
44
+ // Block type registration
45
+ // ---------------------------------------------------------------
46
+ ctx.registerBlockType('heading', {
47
+ defaultAttrs: { level: 1 },
48
+ validate: (attrs) => {
49
+ return (typeof attrs.level === 'number' &&
50
+ attrs.level >= 1 &&
51
+ attrs.level <= 6);
52
+ },
53
+ });
54
+ // ---------------------------------------------------------------
55
+ // toggleHeading command
56
+ // ---------------------------------------------------------------
57
+ ctx.registerCommand(HeadingCommands.TOGGLE, {
58
+ execute(engine, payload) {
59
+ const p = payload;
60
+ if (!p || typeof p.level !== 'number')
61
+ return;
62
+ const block = getBlockAtCursor(engine);
63
+ if (isBlockType(engine, 'heading', { level: p.level })) {
64
+ // Already a heading at this level — revert to plain text
65
+ engine.dispatch([
66
+ { type: 'set_block_type', blockId: block.id, blockType: 'text' },
67
+ { type: 'set_block_attrs', blockId: block.id, attrs: { level: null } },
68
+ ]);
69
+ }
70
+ else {
71
+ // Set to heading with the requested level
72
+ setBlockType(engine, block.id, 'heading', { level: p.level });
73
+ }
74
+ },
75
+ canExecute(_engine) {
76
+ return true;
77
+ },
78
+ isActive(engine, payload) {
79
+ const p = payload;
80
+ if (!p || typeof p.level !== 'number')
81
+ return false;
82
+ return isBlockType(engine, 'heading', { level: p.level });
83
+ },
84
+ });
85
+ // ---------------------------------------------------------------
86
+ // Input rules: # through ###### followed by space
87
+ // ---------------------------------------------------------------
88
+ for (let level = 1; level <= 6; level++) {
89
+ const hashes = '#'.repeat(level);
90
+ const pattern = new RegExp(`^${hashes} $`);
91
+ ctx.registerInputRule({
92
+ pattern,
93
+ exclusive: true,
94
+ handler(engine, match, blockId) {
95
+ const blockStart = getBlockStartOffset(engine.state.doc, blockId);
96
+ const prefixLength = match[0].length;
97
+ engine.dispatch([
98
+ { type: 'delete_text', offset: blockStart, count: prefixLength },
99
+ { type: 'set_block_type', blockId, blockType: 'heading' },
100
+ { type: 'set_block_attrs', blockId, attrs: { level } },
101
+ ]);
102
+ },
103
+ });
104
+ }
105
+ // ---------------------------------------------------------------
106
+ // Keyboard shortcuts: Cmd/Ctrl+Alt+1/2/3
107
+ // ---------------------------------------------------------------
108
+ for (let level = 1; level <= 3; level++) {
109
+ ctx.registerShortcut({ key: String(level), mod: true, alt: true }, HeadingCommands.TOGGLE, { level });
110
+ }
111
+ },
112
+ };
113
+ }
114
+ //# sourceMappingURL=heading-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heading-plugin.js","sourceRoot":"","sources":["../../src/plugins/heading-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Horizontal rule block type plugin — registers the `hr` block type and
3
+ * an input rule for `---` at the start of an empty block.
4
+ *
5
+ * The HR plugin does not register any commands — horizontal rules are
6
+ * created exclusively via the input rule or programmatic operation dispatch.
7
+ *
8
+ * @module
9
+ */
10
+ import type { Plugin } from '@rtif-sdk/engine';
11
+ /**
12
+ * Create the horizontal rule block type plugin.
13
+ *
14
+ * Registers:
15
+ * - Block type: `hr` (no default attrs)
16
+ * - Input rule: `---` at the start of an empty block converts to an HR
17
+ * and inserts a new empty text block below it
18
+ *
19
+ * @returns A plugin instance ready for `engine.use()`
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const engine = createEngine(initialDoc);
24
+ * engine.use(hrPlugin());
25
+ *
26
+ * // Type "---" then the input rule fires:
27
+ * // 1. Deletes the "---" text
28
+ * // 2. Sets block type to 'hr'
29
+ * // 3. Splits block to create a new empty text block below
30
+ * ```
31
+ */
32
+ export declare function hrPlugin(): Plugin;
33
+ //# sourceMappingURL=hr-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hr-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/hr-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAI9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CA+CjC"}