mardora 1.2.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 (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/dist/chunk-3OCUX4OO.js +7690 -0
  4. package/dist/chunk-3OCUX4OO.js.map +1 -0
  5. package/dist/chunk-3ZOCCFDL.cjs +74 -0
  6. package/dist/chunk-3ZOCCFDL.cjs.map +1 -0
  7. package/dist/chunk-7JOEPNEV.cjs +7740 -0
  8. package/dist/chunk-7JOEPNEV.cjs.map +1 -0
  9. package/dist/chunk-BIKZQZ6W.js +33 -0
  10. package/dist/chunk-BIKZQZ6W.js.map +1 -0
  11. package/dist/chunk-EQJESPP2.js +234 -0
  12. package/dist/chunk-EQJESPP2.js.map +1 -0
  13. package/dist/chunk-G4SE26YY.js +70 -0
  14. package/dist/chunk-G4SE26YY.js.map +1 -0
  15. package/dist/chunk-KNDWF2DP.cjs +35 -0
  16. package/dist/chunk-KNDWF2DP.cjs.map +1 -0
  17. package/dist/chunk-MLBEBFHB.cjs +2971 -0
  18. package/dist/chunk-MLBEBFHB.cjs.map +1 -0
  19. package/dist/chunk-P7JFCYU3.js +905 -0
  20. package/dist/chunk-P7JFCYU3.js.map +1 -0
  21. package/dist/chunk-SWFUKJDO.cjs +243 -0
  22. package/dist/chunk-SWFUKJDO.cjs.map +1 -0
  23. package/dist/chunk-WFVCG4LD.cjs +926 -0
  24. package/dist/chunk-WFVCG4LD.cjs.map +1 -0
  25. package/dist/chunk-XL6WFGJT.js +2901 -0
  26. package/dist/chunk-XL6WFGJT.js.map +1 -0
  27. package/dist/editor/index.cjs +277 -0
  28. package/dist/editor/index.cjs.map +1 -0
  29. package/dist/editor/index.d.cts +186 -0
  30. package/dist/editor/index.d.ts +186 -0
  31. package/dist/editor/index.js +4 -0
  32. package/dist/editor/index.js.map +1 -0
  33. package/dist/index.cjs +405 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.cts +13 -0
  36. package/dist/index.d.ts +13 -0
  37. package/dist/index.js +8 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/lib/index.cjs +12 -0
  40. package/dist/lib/index.cjs.map +1 -0
  41. package/dist/lib/index.d.cts +16 -0
  42. package/dist/lib/index.d.ts +16 -0
  43. package/dist/lib/index.js +3 -0
  44. package/dist/lib/index.js.map +1 -0
  45. package/dist/mardora-DCwjomil.d.cts +640 -0
  46. package/dist/mardora-DCwjomil.d.ts +640 -0
  47. package/dist/plugins/index.cjs +104 -0
  48. package/dist/plugins/index.cjs.map +1 -0
  49. package/dist/plugins/index.d.cts +740 -0
  50. package/dist/plugins/index.d.ts +740 -0
  51. package/dist/plugins/index.js +7 -0
  52. package/dist/plugins/index.js.map +1 -0
  53. package/dist/preview/index.cjs +38 -0
  54. package/dist/preview/index.cjs.map +1 -0
  55. package/dist/preview/index.d.cts +101 -0
  56. package/dist/preview/index.d.ts +101 -0
  57. package/dist/preview/index.js +5 -0
  58. package/dist/preview/index.js.map +1 -0
  59. package/dist/types-NBsaxl4d.d.cts +71 -0
  60. package/dist/types-Pw2SWWAR.d.ts +71 -0
  61. package/package.json +92 -0
  62. package/src/editor/attachments/extension.ts +181 -0
  63. package/src/editor/attachments/format.ts +63 -0
  64. package/src/editor/attachments/index.ts +3 -0
  65. package/src/editor/attachments/types.ts +37 -0
  66. package/src/editor/heading-fold/config.ts +25 -0
  67. package/src/editor/heading-fold/extension.ts +268 -0
  68. package/src/editor/heading-fold/extract.ts +88 -0
  69. package/src/editor/heading-fold/index.ts +5 -0
  70. package/src/editor/heading-fold/theme.ts +85 -0
  71. package/src/editor/heading-fold/types.ts +24 -0
  72. package/src/editor/i18n.ts +13 -0
  73. package/src/editor/icons/index.ts +367 -0
  74. package/src/editor/index.ts +16 -0
  75. package/src/editor/mardora.ts +257 -0
  76. package/src/editor/media-lightbox-theme.ts +146 -0
  77. package/src/editor/media-lightbox.ts +125 -0
  78. package/src/editor/plugin.ts +294 -0
  79. package/src/editor/selection-toolbar/activation.ts +123 -0
  80. package/src/editor/selection-toolbar/commands.ts +279 -0
  81. package/src/editor/selection-toolbar/extension.ts +564 -0
  82. package/src/editor/selection-toolbar/i18n.ts +164 -0
  83. package/src/editor/selection-toolbar/index.ts +7 -0
  84. package/src/editor/selection-toolbar/menu.ts +252 -0
  85. package/src/editor/selection-toolbar/position.ts +43 -0
  86. package/src/editor/selection-toolbar/theme.ts +195 -0
  87. package/src/editor/selection-toolbar/types.ts +155 -0
  88. package/src/editor/slash/default-commands.ts +190 -0
  89. package/src/editor/slash/extension.ts +319 -0
  90. package/src/editor/slash/index.ts +7 -0
  91. package/src/editor/slash/insertions.ts +26 -0
  92. package/src/editor/slash/menu.ts +123 -0
  93. package/src/editor/slash/position.ts +61 -0
  94. package/src/editor/slash/query.ts +33 -0
  95. package/src/editor/slash/theme.ts +113 -0
  96. package/src/editor/slash/types.ts +40 -0
  97. package/src/editor/table-of-contents/extension.ts +202 -0
  98. package/src/editor/table-of-contents/extract.ts +53 -0
  99. package/src/editor/table-of-contents/index.ts +7 -0
  100. package/src/editor/table-of-contents/panel.ts +83 -0
  101. package/src/editor/table-of-contents/slug.ts +50 -0
  102. package/src/editor/table-of-contents/storage.ts +35 -0
  103. package/src/editor/table-of-contents/theme.ts +153 -0
  104. package/src/editor/table-of-contents/types.ts +44 -0
  105. package/src/editor/theme.ts +72 -0
  106. package/src/editor/utils.ts +176 -0
  107. package/src/editor/view-plugin.ts +189 -0
  108. package/src/index.ts +5 -0
  109. package/src/lib/index.ts +2 -0
  110. package/src/lib/input-handler.ts +47 -0
  111. package/src/plugins/code-plugin.theme.ts +545 -0
  112. package/src/plugins/code-plugin.ts +1892 -0
  113. package/src/plugins/emoji-plugin.ts +140 -0
  114. package/src/plugins/heading-plugin.ts +194 -0
  115. package/src/plugins/hr-plugin.ts +102 -0
  116. package/src/plugins/html-plugin.ts +353 -0
  117. package/src/plugins/image-plugin.ts +806 -0
  118. package/src/plugins/index.ts +71 -0
  119. package/src/plugins/inline-plugin.ts +311 -0
  120. package/src/plugins/link-plugin.ts +509 -0
  121. package/src/plugins/list-plugin.ts +492 -0
  122. package/src/plugins/math-plugin.ts +526 -0
  123. package/src/plugins/mermaid-plugin.ts +513 -0
  124. package/src/plugins/paragraph-plugin.ts +38 -0
  125. package/src/plugins/quote-plugin.ts +733 -0
  126. package/src/plugins/table-controls-theme.ts +126 -0
  127. package/src/plugins/table-controls.ts +423 -0
  128. package/src/plugins/table-model.ts +661 -0
  129. package/src/plugins/table-plugin.ts +2111 -0
  130. package/src/preview/context.ts +45 -0
  131. package/src/preview/css-generator.ts +64 -0
  132. package/src/preview/default-renderers.ts +29 -0
  133. package/src/preview/index.ts +29 -0
  134. package/src/preview/preview.ts +41 -0
  135. package/src/preview/renderer.ts +184 -0
  136. package/src/preview/syntax-theme.ts +112 -0
  137. package/src/preview/toc.ts +23 -0
  138. package/src/preview/types.ts +89 -0
@@ -0,0 +1,71 @@
1
+ // Re-export individual plugins
2
+ export { ParagraphPlugin } from "./paragraph-plugin";
3
+ export { HeadingPlugin } from "./heading-plugin";
4
+ export { InlinePlugin } from "./inline-plugin";
5
+ export { LinkPlugin } from "./link-plugin";
6
+ export { ListPlugin } from "./list-plugin";
7
+ export { TablePlugin } from "./table-plugin";
8
+ export { HTMLPlugin } from "./html-plugin";
9
+ export { ImagePlugin } from "./image-plugin";
10
+ export { MathPlugin } from "./math-plugin";
11
+ export { MermaidPlugin } from "./mermaid-plugin";
12
+ export {
13
+ bindCodeCopyButtons,
14
+ CodePlugin,
15
+ CODE_COPY_SUCCESS_ICON,
16
+ copyCodeTextToClipboard,
17
+ decodeCodeCopyPayload,
18
+ encodeCodeCopyPayload,
19
+ } from "./code-plugin";
20
+ export { QuotePlugin, resolveCalloutTitleInputTarget, resolveCalloutTypeChange } from "./quote-plugin";
21
+ export type { CalloutLabel, CalloutTitleInputTarget, CalloutTypeChange } from "./quote-plugin";
22
+ export { HRPlugin } from "./hr-plugin";
23
+ export { EmojiPlugin } from "./emoji-plugin";
24
+
25
+ // Plugin collections
26
+ import { MardoraPlugin } from "../editor/plugin";
27
+ import { ParagraphPlugin } from "./paragraph-plugin";
28
+ import { HeadingPlugin } from "./heading-plugin";
29
+ import { InlinePlugin } from "./inline-plugin";
30
+ import { LinkPlugin } from "./link-plugin";
31
+ import { ListPlugin } from "./list-plugin";
32
+ import { TablePlugin } from "./table-plugin";
33
+ import { HTMLPlugin } from "./html-plugin";
34
+ import { ImagePlugin } from "./image-plugin";
35
+ import { MathPlugin } from "./math-plugin";
36
+ import { MermaidPlugin } from "./mermaid-plugin";
37
+ import { CodePlugin } from "./code-plugin";
38
+ import { QuotePlugin } from "./quote-plugin";
39
+ import { HRPlugin } from "./hr-plugin";
40
+ import { EmojiPlugin } from "./emoji-plugin";
41
+
42
+ /**
43
+ * Default plugins
44
+ *
45
+ * This is the set of essential plugins
46
+ */
47
+ const essentialPlugins: MardoraPlugin[] = [
48
+ new ParagraphPlugin(),
49
+ new HeadingPlugin(),
50
+ new InlinePlugin(),
51
+ new LinkPlugin(),
52
+ new ListPlugin(),
53
+ new TablePlugin(),
54
+ new HTMLPlugin(),
55
+ new ImagePlugin(),
56
+ new MathPlugin(),
57
+ new MermaidPlugin(),
58
+ new CodePlugin(),
59
+ new QuotePlugin(),
60
+ new HRPlugin(),
61
+ new EmojiPlugin(),
62
+ ];
63
+
64
+ /**
65
+ * All plugins
66
+ *
67
+ * This is the set of all plugins available with mardora
68
+ */
69
+ const allPlugins: MardoraPlugin[] = [...essentialPlugins];
70
+
71
+ export { essentialPlugins, allPlugins };
@@ -0,0 +1,311 @@
1
+ import { Decoration, KeyBinding } from "@codemirror/view";
2
+ import { syntaxTree } from "@codemirror/language";
3
+ import { DecorationContext, DecorationPlugin } from "../editor/plugin";
4
+ import { createTheme } from "../editor";
5
+ import { SyntaxNode } from "@lezer/common";
6
+ import { toggleMarkdownStyle } from "../editor/utils";
7
+ import { tags } from "@lezer/highlight";
8
+ import type { MarkdownConfig, InlineParser } from "@lezer/markdown";
9
+ import { Extension } from "@codemirror/state";
10
+ import { createWrapSelectionInputHandler } from "../lib";
11
+
12
+ /**
13
+ * Node types for inline styling in markdown
14
+ */
15
+ const INLINE_TYPES = {
16
+ Emphasis: "emphasis",
17
+ StrongEmphasis: "strong",
18
+ Strikethrough: "strikethrough",
19
+ Subscript: "subscript",
20
+ Superscript: "superscript",
21
+ Highlight: "highlight",
22
+ } as const;
23
+
24
+ /**
25
+ * Mark decorations for inline content
26
+ */
27
+ const inlineMarkDecorations = {
28
+ emphasis: Decoration.mark({ class: "cm-mardora-emphasis" }),
29
+ strong: Decoration.mark({ class: "cm-mardora-strong" }),
30
+ strikethrough: Decoration.mark({ class: "cm-mardora-strikethrough" }),
31
+ subscript: Decoration.mark({ class: "cm-mardora-subscript" }),
32
+ superscript: Decoration.mark({ class: "cm-mardora-superscript" }),
33
+ highlight: Decoration.mark({ class: "cm-mardora-highlight" }),
34
+ // Markers (* _ ~~ ^ ~ ==)
35
+ "inline-mark": Decoration.replace({}),
36
+ };
37
+
38
+ // Character code for '='
39
+ const EQUALS = 61;
40
+
41
+ // Punctuation regex for flanking checks (matches Unicode punctuation)
42
+ // eslint-disable-next-line no-useless-escape
43
+ let Punctuation = /[!"#$%&'()*+,\-./:;<=>?@\[\\\]^_`{|}~\xA1\u2010-\u2027]/;
44
+ try {
45
+ Punctuation = new RegExp("[\\p{S}|\\p{P}]", "u");
46
+ } catch {
47
+ // Fallback regex is used above for environments without Unicode support
48
+ }
49
+
50
+ // Delimiter type for highlight markers — enables nested inline parsing
51
+ const HighlightDelim = { resolve: "Highlight", mark: "HighlightMark" };
52
+
53
+ /**
54
+ * Inline parser for highlight syntax: ==text==
55
+ * Uses addDelimiter (like Strikethrough) so nested inline styles work.
56
+ */
57
+ const highlightParser: InlineParser = {
58
+ name: "Highlight",
59
+ parse(cx, next, pos) {
60
+ // Must start with ==
61
+ if (next !== EQUALS || cx.char(pos + 1) !== EQUALS) return -1;
62
+ // Don't match === (or more)
63
+ if (cx.char(pos + 2) === EQUALS) return -1;
64
+
65
+ // Flanking checks (same logic as Strikethrough)
66
+ const before = cx.slice(pos - 1, pos);
67
+ const after = cx.slice(pos + 2, pos + 3);
68
+ const sBefore = /\s|^$/.test(before),
69
+ sAfter = /\s|^$/.test(after);
70
+ const pBefore = Punctuation.test(before),
71
+ pAfter = Punctuation.test(after);
72
+
73
+ return cx.addDelimiter(
74
+ HighlightDelim,
75
+ pos,
76
+ pos + 2,
77
+ !sAfter && (!pAfter || sBefore || pBefore),
78
+ !sBefore && (!pBefore || sAfter || pAfter)
79
+ );
80
+ },
81
+ };
82
+
83
+ /**
84
+ * InlinePlugin - Decorates inline markdown formatting
85
+ *
86
+ * Adds visual styling to inline elements:
87
+ * - Emphasis (italic) - *text* or _text_
88
+ * - Strong (bold) - **text** or __text__
89
+ * - Strikethrough - ~~text~~
90
+ * - Subscript - ~text~
91
+ * - Superscript - ^text^
92
+ * - Highlight - ==text==
93
+ *
94
+ * Hides formatting markers when cursor is not in the element
95
+ */
96
+ export class InlinePlugin extends DecorationPlugin {
97
+ readonly name = "inline";
98
+ readonly version = "1.0.0";
99
+ override decorationPriority = 20;
100
+ override readonly requiredNodes = [
101
+ "Emphasis",
102
+ "StrongEmphasis",
103
+ "Strikethrough",
104
+ "Subscript",
105
+ "Superscript",
106
+ "Highlight",
107
+ "EmphasisMark",
108
+ "StrikethroughMark",
109
+ "SubscriptMark",
110
+ "SuperscriptMark",
111
+ "HighlightMark",
112
+ "Escape",
113
+ ] as const;
114
+ marks: string[] = [];
115
+
116
+ constructor() {
117
+ super();
118
+
119
+ for (const mark of Object.keys(INLINE_TYPES)) {
120
+ this.marks.push(...this.getMarkerNames(mark));
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Plugin theme
126
+ */
127
+ override get theme() {
128
+ return theme;
129
+ }
130
+
131
+ /**
132
+ * Keyboard shortcuts for inline formatting
133
+ */
134
+ override getKeymap(): KeyBinding[] {
135
+ return [
136
+ {
137
+ key: "Mod-b",
138
+ run: toggleMarkdownStyle("**"),
139
+ preventDefault: true,
140
+ },
141
+ {
142
+ key: "Mod-i",
143
+ run: toggleMarkdownStyle("*"),
144
+ preventDefault: true,
145
+ },
146
+ {
147
+ key: "Mod-Shift-s",
148
+ run: toggleMarkdownStyle("~~"),
149
+ preventDefault: true,
150
+ },
151
+ {
152
+ key: "Mod-,",
153
+ run: toggleMarkdownStyle("~"),
154
+ preventDefault: true,
155
+ },
156
+ {
157
+ key: "Mod-.",
158
+ run: toggleMarkdownStyle("^"),
159
+ preventDefault: true,
160
+ },
161
+ {
162
+ key: "Mod-Shift-h",
163
+ run: toggleMarkdownStyle("=="),
164
+ preventDefault: true,
165
+ },
166
+ ];
167
+ }
168
+
169
+ /**
170
+ * Intercepts inline marker typing to wrap selected text.
171
+ *
172
+ * If user types inline markers while text is selected, wraps each selected
173
+ * range with the appropriate marker:
174
+ * - * _ ~ ^ -> marker + selected + marker
175
+ * - = -> ==selected==
176
+ */
177
+ override getExtensions(): Extension[] {
178
+ return [createWrapSelectionInputHandler({ "*": "*", _: "_", "~": "~", "^": "^", "=": "==" })];
179
+ }
180
+
181
+ /**
182
+ * Return markdown parser extensions for highlight syntax (==text==)
183
+ */
184
+ override getMarkdownConfig(): MarkdownConfig {
185
+ return {
186
+ defineNodes: [
187
+ { name: "Highlight", style: tags.emphasis },
188
+ { name: "HighlightMark", style: tags.processingInstruction },
189
+ ],
190
+ parseInline: [highlightParser],
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Build inline decorations by iterating the syntax tree
196
+ */
197
+ buildDecorations(ctx: DecorationContext): void {
198
+ const { view, decorations } = ctx;
199
+ const tree = syntaxTree(view.state);
200
+
201
+ tree.iterate({
202
+ enter: (node) => {
203
+ const { from, to, name } = node;
204
+
205
+ if (name === "Escape") {
206
+ decorations.push(inlineMarkDecorations["inline-mark"].range(from, Math.min(from + 1, to)));
207
+ return;
208
+ }
209
+
210
+ // Check if this is an inline type we handle
211
+ const inlineType = INLINE_TYPES[name as keyof typeof INLINE_TYPES];
212
+ if (!inlineType) {
213
+ return;
214
+ }
215
+
216
+ // Add mark decoration for the content
217
+ decorations.push(inlineMarkDecorations[inlineType].range(from, to));
218
+
219
+ // Only hide markers when cursor is not in the element
220
+ const cursorInNode = ctx.selectionOverlapsRange(from, to);
221
+ if (!cursorInNode) {
222
+ // Get the appropriate marker children based on type
223
+ const markerNames = this.getMarkerNames(name);
224
+ for (const markerName of markerNames) {
225
+ const marks = node.node.getChildren(markerName);
226
+ for (const mark of marks) {
227
+ decorations.push(inlineMarkDecorations["inline-mark"].range(mark.from, mark.to));
228
+ }
229
+ }
230
+ }
231
+ },
232
+ });
233
+ }
234
+
235
+ /**
236
+ * Get the marker node names for a given inline type
237
+ */
238
+ private getMarkerNames(nodeType: string): string[] {
239
+ switch (nodeType) {
240
+ case "Emphasis":
241
+ case "StrongEmphasis":
242
+ return ["EmphasisMark"];
243
+ case "Strikethrough":
244
+ return ["StrikethroughMark"];
245
+ case "Subscript":
246
+ return ["SubscriptMark"];
247
+ case "Superscript":
248
+ return ["SuperscriptMark"];
249
+ case "Highlight":
250
+ return ["HighlightMark"];
251
+ default:
252
+ return [];
253
+ }
254
+ }
255
+
256
+ override renderToHTML(node: SyntaxNode, children: string): string | null {
257
+ if (this.marks.includes(node.name)) {
258
+ return "";
259
+ }
260
+
261
+ const inlineType = INLINE_TYPES[node.name as keyof typeof INLINE_TYPES];
262
+ if (!inlineType) {
263
+ return null;
264
+ }
265
+ const className = inlineMarkDecorations[inlineType].spec.class as string;
266
+
267
+ return `<span class="${className}">${children}</span>`;
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Theme for inline styling
273
+ */
274
+ const theme = createTheme({
275
+ default: {
276
+ // Emphasis (italic)
277
+ ".cm-mardora-emphasis": {
278
+ fontStyle: "italic",
279
+ },
280
+
281
+ // Strong (bold)
282
+ ".cm-mardora-strong": {
283
+ fontWeight: "bold",
284
+ },
285
+
286
+ // Strikethrough
287
+ ".cm-mardora-strikethrough": {
288
+ textDecoration: "line-through",
289
+ opacity: "0.7",
290
+ },
291
+
292
+ // Subscript
293
+ ".cm-mardora-subscript": {
294
+ fontSize: "0.75em",
295
+ verticalAlign: "sub",
296
+ },
297
+
298
+ // Superscript
299
+ ".cm-mardora-superscript": {
300
+ fontSize: "0.75em",
301
+ verticalAlign: "super",
302
+ },
303
+
304
+ // Highlight
305
+ ".cm-mardora-highlight": {
306
+ backgroundColor: "rgba(255, 213, 0, 0.35)",
307
+ borderRadius: "2px",
308
+ padding: "1px 2px",
309
+ },
310
+ },
311
+ });