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,7 @@
1
+ export { CODE_COPY_SUCCESS_ICON, CodePlugin, EmojiPlugin, HRPlugin, HTMLPlugin, HeadingPlugin, ImagePlugin, InlinePlugin, LinkPlugin, ListPlugin, MathPlugin, MermaidPlugin, ParagraphPlugin, QuotePlugin, TablePlugin, allPlugins, bindCodeCopyButtons, copyCodeTextToClipboard, decodeCodeCopyPayload, encodeCodeCopyPayload, essentialPlugins, resolveCalloutTitleInputTarget, resolveCalloutTypeChange } from '../chunk-3OCUX4OO.js';
2
+ import '../chunk-XL6WFGJT.js';
3
+ import '../chunk-BIKZQZ6W.js';
4
+ import '../chunk-EQJESPP2.js';
5
+ import '../chunk-P7JFCYU3.js';
6
+ //# sourceMappingURL=index.js.map
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ var chunk3ZOCCFDL_cjs = require('../chunk-3ZOCCFDL.cjs');
4
+ var chunkSWFUKJDO_cjs = require('../chunk-SWFUKJDO.cjs');
5
+ require('../chunk-WFVCG4LD.cjs');
6
+
7
+
8
+
9
+ Object.defineProperty(exports, "extractPreviewTocFromMarkdown", {
10
+ enumerable: true,
11
+ get: function () { return chunk3ZOCCFDL_cjs.extractPreviewTocFromMarkdown; }
12
+ });
13
+ Object.defineProperty(exports, "generateCSS", {
14
+ enumerable: true,
15
+ get: function () { return chunk3ZOCCFDL_cjs.generateCSS; }
16
+ });
17
+ Object.defineProperty(exports, "preview", {
18
+ enumerable: true,
19
+ get: function () { return chunk3ZOCCFDL_cjs.preview; }
20
+ });
21
+ Object.defineProperty(exports, "PreviewRenderer", {
22
+ enumerable: true,
23
+ get: function () { return chunkSWFUKJDO_cjs.PreviewRenderer; }
24
+ });
25
+ Object.defineProperty(exports, "defaultRenderers", {
26
+ enumerable: true,
27
+ get: function () { return chunkSWFUKJDO_cjs.defaultRenderers; }
28
+ });
29
+ Object.defineProperty(exports, "escapeHtml", {
30
+ enumerable: true,
31
+ get: function () { return chunkSWFUKJDO_cjs.escapeHtml; }
32
+ });
33
+ Object.defineProperty(exports, "generateSyntaxThemeCSS", {
34
+ enumerable: true,
35
+ get: function () { return chunkSWFUKJDO_cjs.generateSyntaxThemeCSS; }
36
+ });
37
+ //# sourceMappingURL=index.cjs.map
38
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
@@ -0,0 +1,101 @@
1
+ import { P as PreviewConfig, G as GenerateCSSConfig, S as SyntaxThemeInput, a as NodeRendererMap } from '../types-NBsaxl4d.cjs';
2
+ export { N as NodeRenderer, b as PreviewContext } from '../types-NBsaxl4d.cjs';
3
+ import { MarkdownConfig } from '@lezer/markdown';
4
+ import { y as MardoraTocConfig, z as MardoraTocItem, q as MardoraPlugin, a3 as ThemeEnum } from '../mardora-DCwjomil.cjs';
5
+ import '@lezer/highlight';
6
+ import '@codemirror/state';
7
+ import '@codemirror/language';
8
+ import '@lezer/common';
9
+ import '@codemirror/view';
10
+ import 'style-mod';
11
+
12
+ /**
13
+ * Render markdown to semantic HTML
14
+ *
15
+ * @param markdown - Markdown string to render
16
+ * @param config - Preview configuration
17
+ * @returns HTML string
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { preview } from 'mardora/preview';
22
+ * import { HeadingPlugin, ListPlugin } from 'mardora/plugins';
23
+ *
24
+ * const html = preview('# Hello World', {
25
+ * plugins: [new HeadingPlugin(), new ListPlugin()],
26
+ * wrapperClass: 'mardora-preview',
27
+ * });
28
+ * ```
29
+ */
30
+ declare function preview(markdown: string, config?: PreviewConfig): Promise<string>;
31
+
32
+ /**
33
+ * Generate CSS for preview rendering
34
+ *
35
+ * @param config - CSS generation configuration
36
+ * @returns CSS string
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { generateCSS } from 'mardora/preview';
41
+ * import { HeadingPlugin, ListPlugin } from 'mardora/plugins';
42
+ *
43
+ * const css = generateCSS({
44
+ * plugins: [new HeadingPlugin(), new ListPlugin()],
45
+ * theme: ThemeEnum.AUTO,
46
+ * includeBase: true,
47
+ * });
48
+ * ```
49
+ */
50
+ declare function generateCSS(config?: GenerateCSSConfig): string;
51
+
52
+ /**
53
+ * Extract syntax highlight CSS from resolved CodeMirror HighlightStyle modules.
54
+ */
55
+ declare function generateSyntaxThemeCSS(syntaxTheme: SyntaxThemeInput | SyntaxThemeInput[] | undefined, _wrapperClass: string): string;
56
+
57
+ declare function extractPreviewTocFromMarkdown(doc: string, config?: MardoraTocConfig, markdownConfig?: MarkdownConfig[]): MardoraTocItem[];
58
+
59
+ /**
60
+ * Escape HTML special characters
61
+ */
62
+ declare function escapeHtml(text: string): string;
63
+ /**
64
+ * Default node renderers for all markdown node types
65
+ */
66
+ declare const defaultRenderers: NodeRendererMap;
67
+
68
+ /**
69
+ * Renderer class that walks the syntax tree and produces HTML
70
+ */
71
+ declare class PreviewRenderer {
72
+ private doc;
73
+ private theme;
74
+ private plugins;
75
+ private markdown;
76
+ private sanitizeHtml;
77
+ private syntaxTheme;
78
+ private renderers;
79
+ private ctx;
80
+ private nodeToPlugins;
81
+ constructor(doc: string, plugins: MardoraPlugin[] | undefined, markdown: MarkdownConfig[], theme?: ThemeEnum, sanitize?: boolean, syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[]);
82
+ /**
83
+ * Build a map from node names to plugins that handle them
84
+ */
85
+ private buildNodePluginMap;
86
+ /**
87
+ * Render the document to HTML
88
+ */
89
+ render(): Promise<string>;
90
+ /**
91
+ * Render a single node to HTML
92
+ */
93
+ private renderNode;
94
+ private renderNodeWithExtent;
95
+ /**
96
+ * Render all children of a node, including text between nodes
97
+ */
98
+ private renderChildren;
99
+ }
100
+
101
+ export { GenerateCSSConfig, NodeRendererMap, PreviewConfig, PreviewRenderer, SyntaxThemeInput, defaultRenderers, escapeHtml, extractPreviewTocFromMarkdown, generateCSS, generateSyntaxThemeCSS, preview };
@@ -0,0 +1,101 @@
1
+ import { P as PreviewConfig, G as GenerateCSSConfig, S as SyntaxThemeInput, a as NodeRendererMap } from '../types-Pw2SWWAR.js';
2
+ export { N as NodeRenderer, b as PreviewContext } from '../types-Pw2SWWAR.js';
3
+ import { MarkdownConfig } from '@lezer/markdown';
4
+ import { y as MardoraTocConfig, z as MardoraTocItem, q as MardoraPlugin, a3 as ThemeEnum } from '../mardora-DCwjomil.js';
5
+ import '@lezer/highlight';
6
+ import '@codemirror/state';
7
+ import '@codemirror/language';
8
+ import '@lezer/common';
9
+ import '@codemirror/view';
10
+ import 'style-mod';
11
+
12
+ /**
13
+ * Render markdown to semantic HTML
14
+ *
15
+ * @param markdown - Markdown string to render
16
+ * @param config - Preview configuration
17
+ * @returns HTML string
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { preview } from 'mardora/preview';
22
+ * import { HeadingPlugin, ListPlugin } from 'mardora/plugins';
23
+ *
24
+ * const html = preview('# Hello World', {
25
+ * plugins: [new HeadingPlugin(), new ListPlugin()],
26
+ * wrapperClass: 'mardora-preview',
27
+ * });
28
+ * ```
29
+ */
30
+ declare function preview(markdown: string, config?: PreviewConfig): Promise<string>;
31
+
32
+ /**
33
+ * Generate CSS for preview rendering
34
+ *
35
+ * @param config - CSS generation configuration
36
+ * @returns CSS string
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import { generateCSS } from 'mardora/preview';
41
+ * import { HeadingPlugin, ListPlugin } from 'mardora/plugins';
42
+ *
43
+ * const css = generateCSS({
44
+ * plugins: [new HeadingPlugin(), new ListPlugin()],
45
+ * theme: ThemeEnum.AUTO,
46
+ * includeBase: true,
47
+ * });
48
+ * ```
49
+ */
50
+ declare function generateCSS(config?: GenerateCSSConfig): string;
51
+
52
+ /**
53
+ * Extract syntax highlight CSS from resolved CodeMirror HighlightStyle modules.
54
+ */
55
+ declare function generateSyntaxThemeCSS(syntaxTheme: SyntaxThemeInput | SyntaxThemeInput[] | undefined, _wrapperClass: string): string;
56
+
57
+ declare function extractPreviewTocFromMarkdown(doc: string, config?: MardoraTocConfig, markdownConfig?: MarkdownConfig[]): MardoraTocItem[];
58
+
59
+ /**
60
+ * Escape HTML special characters
61
+ */
62
+ declare function escapeHtml(text: string): string;
63
+ /**
64
+ * Default node renderers for all markdown node types
65
+ */
66
+ declare const defaultRenderers: NodeRendererMap;
67
+
68
+ /**
69
+ * Renderer class that walks the syntax tree and produces HTML
70
+ */
71
+ declare class PreviewRenderer {
72
+ private doc;
73
+ private theme;
74
+ private plugins;
75
+ private markdown;
76
+ private sanitizeHtml;
77
+ private syntaxTheme;
78
+ private renderers;
79
+ private ctx;
80
+ private nodeToPlugins;
81
+ constructor(doc: string, plugins: MardoraPlugin[] | undefined, markdown: MarkdownConfig[], theme?: ThemeEnum, sanitize?: boolean, syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[]);
82
+ /**
83
+ * Build a map from node names to plugins that handle them
84
+ */
85
+ private buildNodePluginMap;
86
+ /**
87
+ * Render the document to HTML
88
+ */
89
+ render(): Promise<string>;
90
+ /**
91
+ * Render a single node to HTML
92
+ */
93
+ private renderNode;
94
+ private renderNodeWithExtent;
95
+ /**
96
+ * Render all children of a node, including text between nodes
97
+ */
98
+ private renderChildren;
99
+ }
100
+
101
+ export { GenerateCSSConfig, NodeRendererMap, PreviewConfig, PreviewRenderer, SyntaxThemeInput, defaultRenderers, escapeHtml, extractPreviewTocFromMarkdown, generateCSS, generateSyntaxThemeCSS, preview };
@@ -0,0 +1,5 @@
1
+ export { extractPreviewTocFromMarkdown, generateCSS, preview } from '../chunk-G4SE26YY.js';
2
+ export { PreviewRenderer, defaultRenderers, escapeHtml, generateSyntaxThemeCSS } from '../chunk-EQJESPP2.js';
3
+ import '../chunk-P7JFCYU3.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,71 @@
1
+ import * as _lezer_markdown from '@lezer/markdown';
2
+ import { q as MardoraPlugin, a3 as ThemeEnum } from './mardora-DCwjomil.cjs';
3
+ import * as _lezer_highlight from '@lezer/highlight';
4
+ import * as _codemirror_state from '@codemirror/state';
5
+ import * as _codemirror_language from '@codemirror/language';
6
+ import { SyntaxNode } from '@lezer/common';
7
+
8
+ type SyntaxThemeInput = _codemirror_language.HighlightStyle | _codemirror_state.Extension | readonly _codemirror_state.Extension[];
9
+ /**
10
+ * Context passed to plugin preview methods
11
+ */
12
+ interface PreviewContext {
13
+ /** Full document text */
14
+ readonly doc: string;
15
+ /** Current theme */
16
+ readonly theme: ThemeEnum;
17
+ /** Slice document text between positions */
18
+ sliceDoc(from: number, to: number): string;
19
+ /** Sanitize HTML content (for HTMLBlock/HTMLTag) */
20
+ sanitize(html: string): string;
21
+ /** Render children of a node to HTML */
22
+ renderChildren(node: SyntaxNode): Promise<string>;
23
+ /** Active syntax highlighters used for code rendering */
24
+ readonly syntaxHighlighters?: readonly _lezer_highlight.Highlighter[];
25
+ /** Return a stable heading id for TOC-aware heading renderers */
26
+ headingIdForNode?(node: SyntaxNode): string | null;
27
+ }
28
+ /**
29
+ * Configuration for the preview renderer
30
+ */
31
+ interface PreviewConfig {
32
+ /** Plugins to use for rendering */
33
+ plugins?: MardoraPlugin[];
34
+ /** Markdown extensions to use for rendering */
35
+ markdown?: _lezer_markdown.MarkdownConfig[];
36
+ /** CSS class for the wrapper element */
37
+ wrapperClass?: string;
38
+ /** HTML tag for the wrapper element */
39
+ wrapperTag?: "article" | "div" | "section";
40
+ /** Whether to sanitize HTML blocks (default: true) */
41
+ sanitize?: boolean;
42
+ /** Theme to use */
43
+ theme?: ThemeEnum;
44
+ /** CodeMirror syntax theme input used for static preview highlighting */
45
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
46
+ }
47
+ /**
48
+ * Result of CSS generation
49
+ */
50
+ interface GenerateCSSConfig {
51
+ /** Plugins to extract styles from */
52
+ plugins?: MardoraPlugin[];
53
+ /** Theme to use */
54
+ theme?: ThemeEnum;
55
+ /** Wrapper class for scoping (default: "mardora-preview") */
56
+ wrapperClass?: string;
57
+ /** Include base styles */
58
+ includeBase?: boolean;
59
+ /** CodeMirror syntax theme input used for static preview syntax highlighting */
60
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
61
+ }
62
+ /**
63
+ * Node renderer function type
64
+ */
65
+ type NodeRenderer = (node: SyntaxNode, children: string, ctx: PreviewContext) => string;
66
+ /**
67
+ * Map of node names to their renderers
68
+ */
69
+ type NodeRendererMap = Record<string, NodeRenderer>;
70
+
71
+ export type { GenerateCSSConfig as G, NodeRenderer as N, PreviewConfig as P, SyntaxThemeInput as S, NodeRendererMap as a, PreviewContext as b };
@@ -0,0 +1,71 @@
1
+ import * as _lezer_markdown from '@lezer/markdown';
2
+ import { q as MardoraPlugin, a3 as ThemeEnum } from './mardora-DCwjomil.js';
3
+ import * as _lezer_highlight from '@lezer/highlight';
4
+ import * as _codemirror_state from '@codemirror/state';
5
+ import * as _codemirror_language from '@codemirror/language';
6
+ import { SyntaxNode } from '@lezer/common';
7
+
8
+ type SyntaxThemeInput = _codemirror_language.HighlightStyle | _codemirror_state.Extension | readonly _codemirror_state.Extension[];
9
+ /**
10
+ * Context passed to plugin preview methods
11
+ */
12
+ interface PreviewContext {
13
+ /** Full document text */
14
+ readonly doc: string;
15
+ /** Current theme */
16
+ readonly theme: ThemeEnum;
17
+ /** Slice document text between positions */
18
+ sliceDoc(from: number, to: number): string;
19
+ /** Sanitize HTML content (for HTMLBlock/HTMLTag) */
20
+ sanitize(html: string): string;
21
+ /** Render children of a node to HTML */
22
+ renderChildren(node: SyntaxNode): Promise<string>;
23
+ /** Active syntax highlighters used for code rendering */
24
+ readonly syntaxHighlighters?: readonly _lezer_highlight.Highlighter[];
25
+ /** Return a stable heading id for TOC-aware heading renderers */
26
+ headingIdForNode?(node: SyntaxNode): string | null;
27
+ }
28
+ /**
29
+ * Configuration for the preview renderer
30
+ */
31
+ interface PreviewConfig {
32
+ /** Plugins to use for rendering */
33
+ plugins?: MardoraPlugin[];
34
+ /** Markdown extensions to use for rendering */
35
+ markdown?: _lezer_markdown.MarkdownConfig[];
36
+ /** CSS class for the wrapper element */
37
+ wrapperClass?: string;
38
+ /** HTML tag for the wrapper element */
39
+ wrapperTag?: "article" | "div" | "section";
40
+ /** Whether to sanitize HTML blocks (default: true) */
41
+ sanitize?: boolean;
42
+ /** Theme to use */
43
+ theme?: ThemeEnum;
44
+ /** CodeMirror syntax theme input used for static preview highlighting */
45
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
46
+ }
47
+ /**
48
+ * Result of CSS generation
49
+ */
50
+ interface GenerateCSSConfig {
51
+ /** Plugins to extract styles from */
52
+ plugins?: MardoraPlugin[];
53
+ /** Theme to use */
54
+ theme?: ThemeEnum;
55
+ /** Wrapper class for scoping (default: "mardora-preview") */
56
+ wrapperClass?: string;
57
+ /** Include base styles */
58
+ includeBase?: boolean;
59
+ /** CodeMirror syntax theme input used for static preview syntax highlighting */
60
+ syntaxTheme?: SyntaxThemeInput | SyntaxThemeInput[];
61
+ }
62
+ /**
63
+ * Node renderer function type
64
+ */
65
+ type NodeRenderer = (node: SyntaxNode, children: string, ctx: PreviewContext) => string;
66
+ /**
67
+ * Map of node names to their renderers
68
+ */
69
+ type NodeRendererMap = Record<string, NodeRenderer>;
70
+
71
+ export type { GenerateCSSConfig as G, NodeRenderer as N, PreviewConfig as P, SyntaxThemeInput as S, NodeRendererMap as a, PreviewContext as b };
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "mardora",
3
+ "version": "1.2.0",
4
+ "description": "Core library for Mardora",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Refinex-Space/mardora.git",
9
+ "directory": "packages/mardora"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "lint": "eslint src/",
19
+ "typecheck": "tsc --noEmit",
20
+ "test": "bun test tests"
21
+ },
22
+ "devDependencies": {
23
+ "@turbo/gen": "^2.7.6",
24
+ "@types/dompurify": "^3.2.0",
25
+ "@types/node": "^25.0.10",
26
+ "@workspace/eslint-config": "workspace:*",
27
+ "@workspace/typescript-config": "workspace:*",
28
+ "eslint": "^9.39.2",
29
+ "tsup": "^8.5.1",
30
+ "typescript": "^5.9.3"
31
+ },
32
+ "dependencies": {
33
+ "@codemirror/commands": "6.10.3",
34
+ "@codemirror/lang-markdown": "6.5.0",
35
+ "@codemirror/language": "6.12.3",
36
+ "@codemirror/language-data": "6.5.2",
37
+ "@codemirror/state": "6.6.0",
38
+ "@codemirror/view": "6.43.1",
39
+ "@lezer/common": "1.5.2",
40
+ "@lezer/highlight": "1.2.3",
41
+ "@lezer/markdown": "1.6.4",
42
+ "dompurify": "^3.3.1",
43
+ "katex": "^0.16.28",
44
+ "mermaid": "11.12.2",
45
+ "node-emoji": "^2.2.0",
46
+ "style-mod": "^4.1.3",
47
+ "zod": "^4.3.6"
48
+ },
49
+ "exports": {
50
+ ".": {
51
+ "types": "./dist/index.d.ts",
52
+ "import": "./dist/index.js",
53
+ "require": "./dist/index.cjs",
54
+ "default": "./dist/index.js"
55
+ },
56
+ "./editor": {
57
+ "types": "./dist/editor/index.d.ts",
58
+ "import": "./dist/editor/index.js",
59
+ "require": "./dist/editor/index.cjs",
60
+ "default": "./dist/editor/index.js"
61
+ },
62
+ "./plugins": {
63
+ "types": "./dist/plugins/index.d.ts",
64
+ "import": "./dist/plugins/index.js",
65
+ "require": "./dist/plugins/index.cjs",
66
+ "default": "./dist/plugins/index.js"
67
+ },
68
+ "./preview": {
69
+ "types": "./dist/preview/index.d.ts",
70
+ "import": "./dist/preview/index.js",
71
+ "require": "./dist/preview/index.cjs",
72
+ "default": "./dist/preview/index.js"
73
+ },
74
+ "./lib": {
75
+ "types": "./dist/lib/index.d.ts",
76
+ "import": "./dist/lib/index.js",
77
+ "require": "./dist/lib/index.cjs",
78
+ "default": "./dist/lib/index.js"
79
+ },
80
+ "./src": {
81
+ "types": "./src/index.ts",
82
+ "default": "./src/index.ts"
83
+ },
84
+ "./src/*": "./src/*"
85
+ },
86
+ "files": [
87
+ "dist",
88
+ "src",
89
+ "README.md",
90
+ "LICENSE"
91
+ ]
92
+ }
@@ -0,0 +1,181 @@
1
+ import { Extension } from "@codemirror/state";
2
+ import { EditorView } from "@codemirror/view";
3
+ import { createUploadMarker, detectAttachmentKind, formatAttachmentMarkdown, isAcceptedAttachment } from "./format";
4
+ import type {
5
+ MardoraAttachmentKind,
6
+ MardoraAttachmentsConfig,
7
+ MardoraAttachmentUploadSource,
8
+ MardoraAttachmentUploader,
9
+ } from "./types";
10
+
11
+ let uploadSequence = 0;
12
+
13
+ export type MardoraAttachmentEditorView = {
14
+ state: {
15
+ doc: {
16
+ length: number;
17
+ toString(): string;
18
+ lineAt(position: number): { from: number; to: number };
19
+ };
20
+ selection: {
21
+ main: { from: number; to: number };
22
+ };
23
+ };
24
+ dispatch(spec: {
25
+ changes?: { from: number; to?: number; insert?: string } | Array<{ from: number; to?: number; insert?: string }>;
26
+ selection?: { anchor: number };
27
+ scrollIntoView?: boolean;
28
+ }): void;
29
+ focus?(): void;
30
+ };
31
+
32
+ export type MardoraUploadAttachmentOptions = {
33
+ kind?: MardoraAttachmentKind;
34
+ source: MardoraAttachmentUploadSource;
35
+ range?: { from: number; to: number };
36
+ uploader: MardoraAttachmentUploader;
37
+ };
38
+
39
+ function nextUploadTaskId(): string {
40
+ uploadSequence += 1;
41
+ return `task-${Date.now()}-${uploadSequence}`;
42
+ }
43
+
44
+ function findMarkerRange(view: MardoraAttachmentEditorView, taskId: string): { from: number; to: number } | null {
45
+ const doc = view.state.doc.toString();
46
+ const marker = `mardora-upload://${taskId}`;
47
+ const markerIndex = doc.indexOf(marker);
48
+
49
+ if (markerIndex === -1) {
50
+ return null;
51
+ }
52
+
53
+ const line = view.state.doc.lineAt(markerIndex);
54
+ return { from: line.from, to: line.to };
55
+ }
56
+
57
+ export async function uploadAttachmentFile(
58
+ view: MardoraAttachmentEditorView,
59
+ file: File,
60
+ options: MardoraUploadAttachmentOptions
61
+ ): Promise<void> {
62
+ const kind = options.kind ?? detectAttachmentKind(file);
63
+ const range = options.range ?? {
64
+ from: view.state.selection.main.from,
65
+ to: view.state.selection.main.to,
66
+ };
67
+ const taskId = nextUploadTaskId();
68
+ const marker = createUploadMarker({ taskId, kind, name: file.name, state: "uploading" });
69
+
70
+ view.dispatch({
71
+ changes: { from: range.from, to: range.to, insert: marker },
72
+ selection: { anchor: range.from + marker.length },
73
+ scrollIntoView: true,
74
+ });
75
+
76
+ try {
77
+ const result = await options.uploader(file, {
78
+ kind,
79
+ source: options.source,
80
+ documentText: view.state.doc.toString(),
81
+ selection: { from: range.from, to: range.from + marker.length },
82
+ });
83
+ const markerRange = findMarkerRange(view, taskId);
84
+
85
+ if (!markerRange) {
86
+ return;
87
+ }
88
+
89
+ const output = formatAttachmentMarkdown(kind, {
90
+ ...result,
91
+ name: result.name ?? file.name,
92
+ mimeType: result.mimeType ?? file.type,
93
+ });
94
+
95
+ view.dispatch({
96
+ changes: { from: markerRange.from, to: markerRange.to, insert: output },
97
+ selection: { anchor: markerRange.from + output.length },
98
+ scrollIntoView: true,
99
+ });
100
+ } catch {
101
+ const markerRange = findMarkerRange(view, taskId);
102
+
103
+ if (!markerRange) {
104
+ return;
105
+ }
106
+
107
+ const failedMarker = createUploadMarker({ taskId, kind, name: file.name, state: "failed" });
108
+ view.dispatch({
109
+ changes: { from: markerRange.from, to: markerRange.to, insert: failedMarker },
110
+ selection: { anchor: markerRange.from + failedMarker.length },
111
+ scrollIntoView: true,
112
+ });
113
+ }
114
+ }
115
+
116
+ function getFilesFromEvent(event: ClipboardEvent | DragEvent): File[] {
117
+ const files =
118
+ event.type === "paste" ? (event as ClipboardEvent).clipboardData?.files : (event as DragEvent).dataTransfer?.files;
119
+ return files ? Array.from(files) : [];
120
+ }
121
+
122
+ function uploadFilesFromEvent(
123
+ view: EditorView,
124
+ event: ClipboardEvent | DragEvent,
125
+ source: MardoraAttachmentUploadSource,
126
+ config: Required<Pick<MardoraAttachmentsConfig, "uploader">> & MardoraAttachmentsConfig
127
+ ): boolean {
128
+ const files = getFilesFromEvent(event);
129
+ if (files.length === 0) {
130
+ return false;
131
+ }
132
+
133
+ event.preventDefault();
134
+
135
+ for (const file of files) {
136
+ const kind = detectAttachmentKind(file);
137
+ const acceptRules = config.accept?.[kind] ?? ["*/*"];
138
+
139
+ if (!isAcceptedAttachment(file, acceptRules)) {
140
+ continue;
141
+ }
142
+
143
+ void uploadAttachmentFile(view, file, {
144
+ kind,
145
+ source,
146
+ uploader: config.uploader,
147
+ });
148
+ }
149
+
150
+ return true;
151
+ }
152
+
153
+ export function attachments(config: MardoraAttachmentsConfig = {}): Extension[] {
154
+ if (config.enabled === false || !config.uploader) {
155
+ return [];
156
+ }
157
+
158
+ const normalizedConfig = {
159
+ enablePaste: true,
160
+ enableDrop: true,
161
+ ...config,
162
+ uploader: config.uploader,
163
+ };
164
+
165
+ return [
166
+ EditorView.domEventHandlers({
167
+ paste(event, view) {
168
+ if (!normalizedConfig.enablePaste) {
169
+ return false;
170
+ }
171
+ return uploadFilesFromEvent(view, event, "paste", normalizedConfig);
172
+ },
173
+ drop(event, view) {
174
+ if (!normalizedConfig.enableDrop) {
175
+ return false;
176
+ }
177
+ return uploadFilesFromEvent(view, event, "drop", normalizedConfig);
178
+ },
179
+ }),
180
+ ];
181
+ }