@valkyrianlabs/payload-markdown 1.3.1

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 (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +222 -0
  3. package/dist/blocks/MarkdownBlock/Component.d.ts +2 -0
  4. package/dist/blocks/MarkdownBlock/Component.js +13 -0
  5. package/dist/blocks/MarkdownBlock/Component.js.map +1 -0
  6. package/dist/blocks/MarkdownBlock/config.d.ts +2 -0
  7. package/dist/blocks/MarkdownBlock/config.js +20 -0
  8. package/dist/blocks/MarkdownBlock/config.js.map +1 -0
  9. package/dist/blocks/MarkdownBlock/types.d.js +3 -0
  10. package/dist/blocks/MarkdownBlock/types.d.js.map +1 -0
  11. package/dist/components/MarkdownRenderer/Component.client.d.ts +5 -0
  12. package/dist/components/MarkdownRenderer/Component.client.js +163 -0
  13. package/dist/components/MarkdownRenderer/Component.client.js.map +1 -0
  14. package/dist/components/MarkdownRenderer/Component.d.ts +3 -0
  15. package/dist/components/MarkdownRenderer/Component.js +87 -0
  16. package/dist/components/MarkdownRenderer/Component.js.map +1 -0
  17. package/dist/components/MarkdownRenderer/index.css +69 -0
  18. package/dist/components/MarkdownRenderer/index.module.css +45 -0
  19. package/dist/components/MarkdownRenderer/index.module.scss +43 -0
  20. package/dist/components/MarkdownRenderer/index.scss +83 -0
  21. package/dist/components/MarkdownRenderer/types.d.js +5 -0
  22. package/dist/components/MarkdownRenderer/types.d.js.map +1 -0
  23. package/dist/core/codeConfig.d.ts +6 -0
  24. package/dist/core/codeConfig.js +45 -0
  25. package/dist/core/codeConfig.js.map +1 -0
  26. package/dist/core/codeToHtml.d.ts +5 -0
  27. package/dist/core/codeToHtml.js +180 -0
  28. package/dist/core/codeToHtml.js.map +1 -0
  29. package/dist/core/plugins/rehypeApplyLayoutClasses.d.ts +4 -0
  30. package/dist/core/plugins/rehypeApplyLayoutClasses.js +72 -0
  31. package/dist/core/plugins/rehypeApplyLayoutClasses.js.map +1 -0
  32. package/dist/core/plugins/rehypeStripAuthoredInlineStyles.d.ts +3 -0
  33. package/dist/core/plugins/rehypeStripAuthoredInlineStyles.js +17 -0
  34. package/dist/core/plugins/rehypeStripAuthoredInlineStyles.js.map +1 -0
  35. package/dist/core/plugins/remarkCompileLayouts.d.ts +3 -0
  36. package/dist/core/plugins/remarkCompileLayouts.js +169 -0
  37. package/dist/core/plugins/remarkCompileLayouts.js.map +1 -0
  38. package/dist/core/plugins/remarkHeadingAnchorsAndToc.d.ts +3 -0
  39. package/dist/core/plugins/remarkHeadingAnchorsAndToc.js +68 -0
  40. package/dist/core/plugins/remarkHeadingAnchorsAndToc.js.map +1 -0
  41. package/dist/core/plugins/remarkLayoutDirectives.d.ts +3 -0
  42. package/dist/core/plugins/remarkLayoutDirectives.js +26 -0
  43. package/dist/core/plugins/remarkLayoutDirectives.js.map +1 -0
  44. package/dist/core/plugins/remarkLayoutSentinels.d.ts +3 -0
  45. package/dist/core/plugins/remarkLayoutSentinels.js +184 -0
  46. package/dist/core/plugins/remarkLayoutSentinels.js.map +1 -0
  47. package/dist/core/plugins/remarkLiftLayoutDirectives.d.ts +3 -0
  48. package/dist/core/plugins/remarkLiftLayoutDirectives.js +93 -0
  49. package/dist/core/plugins/remarkLiftLayoutDirectives.js.map +1 -0
  50. package/dist/core/plugins/remarkNormalizeLayoutSyntax.d.ts +3 -0
  51. package/dist/core/plugins/remarkValidateDirectiveThemes.d.ts +4 -0
  52. package/dist/core/plugins/remarkValidateDirectiveThemes.js +28 -0
  53. package/dist/core/plugins/remarkValidateDirectiveThemes.js.map +1 -0
  54. package/dist/core/renderMarkdown.d.ts +2 -0
  55. package/dist/core/renderMarkdown.js +270 -0
  56. package/dist/core/renderMarkdown.js.map +1 -0
  57. package/dist/core/types.d.js +7 -0
  58. package/dist/core/types.d.js.map +1 -0
  59. package/dist/core/types.d.ts +238 -0
  60. package/dist/core/types.js +5 -0
  61. package/dist/core/types.js.map +1 -0
  62. package/dist/directives/attributes.d.ts +14 -0
  63. package/dist/directives/attributes.js +121 -0
  64. package/dist/directives/attributes.js.map +1 -0
  65. package/dist/directives/definitions/callout.d.ts +6 -0
  66. package/dist/directives/definitions/callout.js +107 -0
  67. package/dist/directives/definitions/callout.js.map +1 -0
  68. package/dist/directives/definitions/card.d.ts +4 -0
  69. package/dist/directives/definitions/card.js +120 -0
  70. package/dist/directives/definitions/card.js.map +1 -0
  71. package/dist/directives/definitions/cards.d.ts +7 -0
  72. package/dist/directives/definitions/cards.js +72 -0
  73. package/dist/directives/definitions/cards.js.map +1 -0
  74. package/dist/directives/definitions/cell.d.ts +4 -0
  75. package/dist/directives/definitions/cell.js +44 -0
  76. package/dist/directives/definitions/cell.js.map +1 -0
  77. package/dist/directives/definitions/columns.d.ts +4 -0
  78. package/dist/directives/definitions/columns.js +89 -0
  79. package/dist/directives/definitions/columns.js.map +1 -0
  80. package/dist/directives/definitions/details.d.ts +2 -0
  81. package/dist/directives/definitions/details.js +76 -0
  82. package/dist/directives/definitions/details.js.map +1 -0
  83. package/dist/directives/definitions/section.d.ts +2 -0
  84. package/dist/directives/definitions/section.js +32 -0
  85. package/dist/directives/definitions/section.js.map +1 -0
  86. package/dist/directives/definitions/steps.d.ts +2 -0
  87. package/dist/directives/definitions/steps.js +242 -0
  88. package/dist/directives/definitions/steps.js.map +1 -0
  89. package/dist/directives/definitions/tab.d.ts +8 -0
  90. package/dist/directives/definitions/tab.js +59 -0
  91. package/dist/directives/definitions/tab.js.map +1 -0
  92. package/dist/directives/definitions/tabs.d.ts +2 -0
  93. package/dist/directives/definitions/tabs.js +197 -0
  94. package/dist/directives/definitions/tabs.js.map +1 -0
  95. package/dist/directives/definitions/toc.d.ts +7 -0
  96. package/dist/directives/definitions/toc.js +59 -0
  97. package/dist/directives/definitions/toc.js.map +1 -0
  98. package/dist/directives/diagnostics.d.ts +8 -0
  99. package/dist/directives/diagnostics.js +167 -0
  100. package/dist/directives/diagnostics.js.map +1 -0
  101. package/dist/directives/headingAnchors.d.ts +9 -0
  102. package/dist/directives/headingAnchors.js +54 -0
  103. package/dist/directives/headingAnchors.js.map +1 -0
  104. package/dist/directives/index.d.ts +5 -0
  105. package/dist/directives/index.js +6 -0
  106. package/dist/directives/index.js.map +1 -0
  107. package/dist/directives/registry.d.ts +20 -0
  108. package/dist/directives/registry.js +152 -0
  109. package/dist/directives/registry.js.map +1 -0
  110. package/dist/directives/renderData.d.ts +3 -0
  111. package/dist/directives/renderData.js +11 -0
  112. package/dist/directives/renderData.js.map +1 -0
  113. package/dist/directives/themes.d.ts +25 -0
  114. package/dist/directives/themes.js +274 -0
  115. package/dist/directives/themes.js.map +1 -0
  116. package/dist/directives/types.d.ts +72 -0
  117. package/dist/directives/types.js +3 -0
  118. package/dist/directives/types.js.map +1 -0
  119. package/dist/editor/MarkdownCodeMirror/Component.client.d.ts +8 -0
  120. package/dist/editor/MarkdownCodeMirror/Component.client.js +78 -0
  121. package/dist/editor/MarkdownCodeMirror/Component.client.js.map +1 -0
  122. package/dist/editor/MarkdownCodeMirror/Component.d.ts +9 -0
  123. package/dist/editor/MarkdownCodeMirror/Component.js +10 -0
  124. package/dist/editor/MarkdownCodeMirror/Component.js.map +1 -0
  125. package/dist/editor/MarkdownCodeMirror.d.ts +8 -0
  126. package/dist/editor/MarkdownCodeMirror.js +74 -0
  127. package/dist/editor/MarkdownCodeMirror.js.map +1 -0
  128. package/dist/editor/MarkdownEditor.d.ts +10 -0
  129. package/dist/editor/MarkdownEditor.js +22 -0
  130. package/dist/editor/MarkdownEditor.js.map +1 -0
  131. package/dist/editor/directives/completions.d.ts +5 -0
  132. package/dist/editor/directives/completions.js +93 -0
  133. package/dist/editor/directives/completions.js.map +1 -0
  134. package/dist/editor/directives/diagnostics.d.ts +1 -0
  135. package/dist/editor/directives/diagnostics.js +12 -0
  136. package/dist/editor/directives/diagnostics.js.map +1 -0
  137. package/dist/editor/themes/payload.d.ts +27 -0
  138. package/dist/editor/themes/payload.js +269 -0
  139. package/dist/editor/themes/payload.js.map +1 -0
  140. package/dist/editor/themes/support/highlighters.d.ts +20 -0
  141. package/dist/editor/themes/support/highlighters.js +1141 -0
  142. package/dist/editor/themes/support/highlighters.js.map +1 -0
  143. package/dist/editor/themes/support/lang.d.ts +40 -0
  144. package/dist/editor/themes/support/lang.js +201 -0
  145. package/dist/editor/themes/support/lang.js.map +1 -0
  146. package/dist/exports/advanced.d.ts +3 -0
  147. package/dist/exports/advanced.js +5 -0
  148. package/dist/exports/advanced.js.map +1 -0
  149. package/dist/exports/client.d.ts +1 -0
  150. package/dist/exports/client.js +2 -0
  151. package/dist/exports/client.js.map +1 -0
  152. package/dist/exports/server.d.ts +3 -0
  153. package/dist/exports/server.js +5 -0
  154. package/dist/exports/server.js.map +1 -0
  155. package/dist/field/BlocksParams/config.d.ts +7 -0
  156. package/dist/field/BlocksParams/config.js +149 -0
  157. package/dist/field/BlocksParams/config.js.map +1 -0
  158. package/dist/field/CodeBlock/config.d.ts +7 -0
  159. package/dist/field/CodeBlock/config.js +321 -0
  160. package/dist/field/CodeBlock/config.js.map +1 -0
  161. package/dist/field/CodeBlockConfig/config.d.ts +7 -0
  162. package/dist/field/CodeBlockConfig/config.js +306 -0
  163. package/dist/field/CodeBlockConfig/config.js.map +1 -0
  164. package/dist/field/CodeBlockParams/config.d.ts +7 -0
  165. package/dist/field/CodeBlockParams/config.js +321 -0
  166. package/dist/field/CodeBlockParams/config.js.map +1 -0
  167. package/dist/field/Config/config.d.ts +7 -0
  168. package/dist/field/Config/config.js +149 -0
  169. package/dist/field/Config/config.js.map +1 -0
  170. package/dist/field/MarkdownField/Component.d.ts +2 -0
  171. package/dist/field/MarkdownField/Component.js +42 -0
  172. package/dist/field/MarkdownField/Component.js.map +1 -0
  173. package/dist/field/MarkdownField/config.d.ts +3 -0
  174. package/dist/field/MarkdownField/config.js +20 -0
  175. package/dist/field/MarkdownField/config.js.map +1 -0
  176. package/dist/field/Tailwind/config.d.ts +9 -0
  177. package/dist/field/Tailwind/config.js +13 -0
  178. package/dist/field/Tailwind/config.js.map +1 -0
  179. package/dist/field/TailwindField/config.d.ts +9 -0
  180. package/dist/field/TailwindField/config.js +13 -0
  181. package/dist/field/TailwindField/config.js.map +1 -0
  182. package/dist/index.d.ts +10 -0
  183. package/dist/index.js +91 -0
  184. package/dist/index.js.map +1 -0
  185. package/dist/runtime/index.d.ts +36 -0
  186. package/dist/runtime/index.js +124 -0
  187. package/dist/runtime/index.js.map +1 -0
  188. package/dist/styles/directiveSurface.d.ts +11 -0
  189. package/dist/styles/directiveSurface.js +38 -0
  190. package/dist/styles/directiveSurface.js.map +1 -0
  191. package/dist/types/core.d.ts +285 -0
  192. package/dist/types/core.js +5 -0
  193. package/dist/types/core.js.map +1 -0
  194. package/dist/types/layoutToken.d.ts +1 -0
  195. package/dist/types/layoutToken.js +3 -0
  196. package/dist/types/layoutToken.js.map +1 -0
  197. package/dist/types/mdast.d.js +5 -0
  198. package/dist/types/mdast.d.js.map +1 -0
  199. package/dist/types.d.js +3 -0
  200. package/dist/types.d.js.map +1 -0
  201. package/dist/types.d.ts +80 -0
  202. package/dist/types.js +3 -0
  203. package/dist/types.js.map +1 -0
  204. package/package.json +181 -0
@@ -0,0 +1,69 @@
1
+ pre.shiki.md-code-enhanced {
2
+ background: #18191c;
3
+ padding: 0;
4
+ overflow-x: auto;
5
+ position: relative;
6
+ border: 1px solid rgba(255, 255, 255, 0.06);
7
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
8
+ }
9
+ pre.shiki.md-code-enhanced code span.md-line {
10
+ display: block;
11
+ position: relative;
12
+ white-space: pre;
13
+ }
14
+ pre.shiki.md-code-enhanced code span.md-line.md-line-no-numbers {
15
+ padding-left: 0.75rem;
16
+ }
17
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-1 {
18
+ padding-left: 2rem;
19
+ }
20
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-1 .md-line-number {
21
+ width: 1.25rem;
22
+ }
23
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-2 {
24
+ padding-left: 2.5rem;
25
+ }
26
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-2 .md-line-number {
27
+ width: 1.75rem;
28
+ }
29
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-3 {
30
+ padding-left: 3rem;
31
+ }
32
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-3 .md-line-number {
33
+ width: 2.25rem;
34
+ }
35
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-4 {
36
+ padding-left: 3.5rem;
37
+ }
38
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-4 .md-line-number {
39
+ width: 2.75rem;
40
+ }
41
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-5 {
42
+ padding-left: 4rem;
43
+ }
44
+ pre.shiki.md-code-enhanced code span.md-line.md-line-digits-5 .md-line-number {
45
+ width: 3.25rem;
46
+ }
47
+ pre.shiki.md-code-enhanced code span.md-line .md-line-number {
48
+ position: absolute;
49
+ left: 0;
50
+ top: 0;
51
+ text-align: right;
52
+ color: #7c8596;
53
+ opacity: 0.8;
54
+ user-select: none;
55
+ pointer-events: none;
56
+ font-variant-numeric: tabular-nums;
57
+ font-feature-settings: "tnum";
58
+ line-height: inherit;
59
+ }
60
+ pre.shiki.md-code-enhanced code span.md-line .md-empty-line {
61
+ display: inline-block;
62
+ min-height: 1em;
63
+ line-height: inherit;
64
+ visibility: hidden;
65
+ user-select: none;
66
+ pointer-events: none;
67
+ }
68
+
69
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1,45 @@
1
+ .md-code-pre {
2
+ background: #18191c;
3
+ padding: 0;
4
+ overflow-x: auto;
5
+ position: relative;
6
+ border: 1px solid rgba(255, 255, 255, 0.06);
7
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
8
+ }
9
+
10
+ .md-code-block {
11
+ display: block;
12
+ padding: 0;
13
+ margin: 0;
14
+ }
15
+
16
+ .md-line {
17
+ display: block;
18
+ position: relative;
19
+ white-space: pre;
20
+ }
21
+
22
+ .md-line-number {
23
+ position: absolute;
24
+ left: 0;
25
+ top: 0;
26
+ text-align: right;
27
+ color: #7c8596;
28
+ opacity: 0.8;
29
+ user-select: none;
30
+ pointer-events: none;
31
+ font-variant-numeric: tabular-nums;
32
+ font-feature-settings: "tnum";
33
+ line-height: inherit;
34
+ }
35
+
36
+ .md-empty-line {
37
+ display: inline-block;
38
+ min-height: 1em;
39
+ line-height: inherit;
40
+ visibility: hidden;
41
+ user-select: none;
42
+ pointer-events: none;
43
+ }
44
+
45
+ /*# sourceMappingURL=index.module.css.map */
@@ -0,0 +1,43 @@
1
+ .md-code-pre {
2
+ background: #18191c;
3
+ padding: 0;
4
+ overflow-x: auto;
5
+ position: relative;
6
+ border: 1px solid rgba(255, 255, 255, 0.06);
7
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
8
+ }
9
+
10
+ .md-code-block {
11
+ display: block;
12
+ padding: 0;
13
+ margin: 0;
14
+ }
15
+
16
+ .md-line {
17
+ display: block;
18
+ position: relative;
19
+ white-space: pre;
20
+ }
21
+
22
+ .md-line-number {
23
+ position: absolute;
24
+ left: 0;
25
+ top: 0;
26
+ text-align: right;
27
+ color: #7c8596;
28
+ opacity: 0.8;
29
+ user-select: none;
30
+ pointer-events: none;
31
+ font-variant-numeric: tabular-nums;
32
+ font-feature-settings: "tnum";
33
+ line-height: inherit;
34
+ }
35
+
36
+ .md-empty-line {
37
+ display: inline-block;
38
+ min-height: 1em;
39
+ line-height: inherit;
40
+ visibility: hidden;
41
+ user-select: none;
42
+ pointer-events: none;
43
+ }
@@ -0,0 +1,83 @@
1
+ pre.shiki.md-code-enhanced {
2
+ background: #18191c;
3
+ padding: 0;
4
+ overflow-x: auto;
5
+ position: relative;
6
+ border: 1px solid rgba(255, 255, 255, 0.06);
7
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
8
+
9
+ code {
10
+ span.md-line {
11
+ display: block;
12
+ position: relative;
13
+ white-space: pre;
14
+
15
+ &.md-line-no-numbers {
16
+ padding-left: .75rem;
17
+ }
18
+
19
+ &.md-line-digits-1 {
20
+ padding-left: 2rem;
21
+
22
+ .md-line-number {
23
+ width: 1.25rem;
24
+ }
25
+ }
26
+
27
+ &.md-line-digits-2 {
28
+ padding-left: 2.5rem;
29
+
30
+ .md-line-number {
31
+ width: 1.75rem;
32
+ }
33
+ }
34
+
35
+ &.md-line-digits-3 {
36
+ padding-left: 3rem;
37
+
38
+ .md-line-number {
39
+ width: 2.25rem;
40
+ }
41
+ }
42
+
43
+ &.md-line-digits-4 {
44
+ padding-left: 3.5rem;
45
+
46
+ .md-line-number {
47
+ width: 2.75rem;
48
+ }
49
+ }
50
+
51
+ &.md-line-digits-5 {
52
+ padding-left: 4rem;
53
+
54
+ .md-line-number {
55
+ width: 3.25rem;
56
+ }
57
+ }
58
+
59
+ .md-line-number {
60
+ position: absolute;
61
+ left: 0;
62
+ top: 0;
63
+ text-align: right;
64
+ color: #7c8596;
65
+ opacity: 0.8;
66
+ user-select: none;
67
+ pointer-events: none;
68
+ font-variant-numeric: tabular-nums;
69
+ font-feature-settings: "tnum";
70
+ line-height: inherit;
71
+ }
72
+
73
+ .md-empty-line {
74
+ display: inline-block;
75
+ min-height: 1em;
76
+ line-height: inherit;
77
+ visibility: hidden;
78
+ user-select: none;
79
+ pointer-events: none;
80
+ }
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Props for the main markdown renderer component.
3
+ */ export { };
4
+
5
+ //# sourceMappingURL=types.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/MarkdownRenderer/types.d.ts"],"sourcesContent":["import type React, { JSX, ReactNode } from 'react'\n\n/**\n * Options that control how fenced code blocks are rendered inside markdown content.\n *\n * By default, code blocks use the plugin's enhanced rendering mode:\n * - `highlightLines` defaults to `false`\n * - `lineNumbers` defaults to `true`\n * - `prettyCodeBlocks` defaults to `true`\n * - `theme` defaults to `'github-dark'`\n *\n * These options are passed through the markdown rendering pipeline and primarily\n * affect Shiki-rendered code fences.\n */\nexport type RenderMarkdownOptions = {\n /**\n * Whether to preserve Shiki-provided per-line background highlighting.\n *\n * Defaults to `false`.\n *\n * When disabled, background styles are stripped from highlighted lines and token\n * spans so code blocks integrate more cleanly with the surrounding site design.\n */\n highlightLines?: boolean\n\n /**\n * Whether to show line numbers for fenced code blocks.\n *\n * Defaults to `true`.\n */\n lineNumbers?: boolean\n\n /**\n * Whether to apply the plugin's enhanced code block formatting.\n *\n * Defaults to `true`.\n *\n * When enabled, the renderer normalizes Shiki output for better integration with\n * markdown prose styling. This includes adjustments such as background removal,\n * spacing cleanup, line layout normalization, and other structural fixes needed\n * for features like line numbers and consistent empty-line rendering.\n *\n * Set this to `false` if you want to preserve raw Shiki block styling as much as\n * possible.\n */\n prettyCodeBlocks?: boolean\n\n /**\n * The Shiki theme to use for syntax highlighting.\n *\n * Defaults to `'github-dark'`.\n *\n * Note that this plugin is optimized around themes that still look good when block\n * backgrounds are removed or reduced. Some light themes may require additional\n * customization to maintain good contrast and readability.\n */\n theme?: string\n}\n\n/**\n * The result of compiling markdown into sanitized HTML.\n */\nexport type RenderMarkdownResult = {\n /**\n * The rendered HTML output.\n */\n html: string\n\n /**\n * Non-fatal warnings produced during rendering.\n */\n warnings: string[]\n}\n\n/**\n * Shared base props for markdown renderer components.\n */\nexport type BaseMarkdownRendererProps = {\n /**\n * The HTML tag used for the rendered markdown container.\n *\n * Defaults to `'article'`.\n */\n as?: keyof JSX.IntrinsicElements\n\n /**\n * Additional classes applied to the rendered markdown element itself.\n */\n className?: string\n\n /**\n * Content rendered when the markdown input is empty or missing.\n */\n emptyFallback?: React.ReactNode\n\n /**\n * Content rendered when markdown compilation fails and a fallback is desired.\n */\n errorFallback?: React.ReactNode\n\n /**\n * The markdown source string to render.\n */\n markdown?: null | string\n\n /**\n * Options that control fenced code block rendering.\n */\n options?: RenderMarkdownOptions\n\n /**\n * Additional classes applied to the outer wrapper element.\n */\n wrapperClassName?: string\n}\n\n/**\n * Preset visual styles for rendered markdown content.\n */\nexport type MarkdownVariant = 'blog' | 'compact' | 'docs' | 'unstyled'\n\n/**\n * Preset typography sizes for rendered markdown content.\n */\nexport type MarkdownSize = 'lg' | 'md' | 'sm'\n\n/**\n * Props for the main markdown renderer component.\n */\nexport type MarkdownRendererProps = {\n /**\n * Whether to center the rendered markdown container within its wrapper.\n *\n * Defaults to `true`.\n */\n centered?: boolean\n\n /**\n * Additional classes applied to the rendered markdown element itself.\n */\n className?: string\n\n /**\n * Whether to apply horizontal gutter padding to the outer wrapper.\n *\n * Defaults to `false`.\n */\n enableGutter?: boolean\n\n /**\n * Whether fenced code blocks should extend beyond the normal content width\n * on larger screens.\n *\n * Defaults to `false`.\n */\n fullBleedCode?: boolean\n\n /**\n * Optional content rendered above the markdown body.\n */\n lead?: ReactNode\n\n /**\n * Whether heading colors should be slightly muted.\n *\n * Defaults to `false`.\n */\n mutedHeadings?: boolean\n\n /**\n * Typography size preset for the rendered markdown.\n *\n * Defaults to `'lg'`.\n */\n size?: MarkdownSize\n\n /**\n * Visual style preset for the rendered markdown.\n *\n * Defaults to `'blog'`.\n */\n variant?: MarkdownVariant\n\n /**\n * Additional classes applied to the outer wrapper element.\n */\n wrapperClassName?: string\n} & Omit<BaseMarkdownRendererProps, 'className' | 'wrapperClassName'>\n"],"names":[],"mappings":"AA8HA;;CAEC,GACD,WA0DqE"}
@@ -0,0 +1,6 @@
1
+ import type { MarkdownCodeConfig, MarkdownRenderConfig, RenderMarkdownOptions } from '../types/core.js';
2
+ export declare function resolveCodeConfigFromLegacy(config?: MarkdownRenderConfig): MarkdownCodeConfig | undefined;
3
+ export declare function mergeMarkdownCodeConfigs(...configs: Array<MarkdownCodeConfig | undefined>): MarkdownCodeConfig | undefined;
4
+ export declare function mergeCodeConfigFromRenderConfigs(...configs: Array<MarkdownRenderConfig | undefined>): MarkdownCodeConfig | undefined;
5
+ export declare function resolveRenderMarkdownOptions(config?: MarkdownRenderConfig): RenderMarkdownOptions;
6
+ export declare function resolveFullBleedCode(config: MarkdownRenderConfig): boolean | undefined;
@@ -0,0 +1,45 @@
1
+ export function resolveCodeConfigFromLegacy(config) {
2
+ if (!config) return undefined;
3
+ const legacy = {};
4
+ if (config.options?.langs) legacy.langs = config.options.langs;
5
+ if (config.options?.lineNumbers !== undefined) legacy.lineNumbers = config.options.lineNumbers;
6
+ if (config.options?.theme) legacy.shikiTheme = config.options.theme;
7
+ if (config.options?.enhancedCodeBlocks !== undefined) legacy.enhanced = config.options.enhancedCodeBlocks;
8
+ if (config.fullBleedCode !== undefined) legacy.fullBleed = config.fullBleedCode;
9
+ return Object.keys(legacy).length > 0 ? legacy : undefined;
10
+ }
11
+ export function mergeMarkdownCodeConfigs(...configs) {
12
+ const merged = {};
13
+ for (const config of configs){
14
+ if (!config) continue;
15
+ if (config.enhanced !== undefined) merged.enhanced = config.enhanced;
16
+ if (config.fullBleed !== undefined) merged.fullBleed = config.fullBleed;
17
+ if (config.langs !== undefined) merged.langs = config.langs;
18
+ if (config.lineNumbers !== undefined) merged.lineNumbers = config.lineNumbers;
19
+ if (config.shikiTheme !== undefined) merged.shikiTheme = config.shikiTheme;
20
+ }
21
+ return Object.keys(merged).length > 0 ? merged : undefined;
22
+ }
23
+ export function mergeCodeConfigFromRenderConfigs(...configs) {
24
+ const ordered = [];
25
+ for (const config of configs){
26
+ if (!config) continue;
27
+ ordered.push(resolveCodeConfigFromLegacy(config), config.code);
28
+ }
29
+ return mergeMarkdownCodeConfigs(...ordered);
30
+ }
31
+ export function resolveRenderMarkdownOptions(config = {}) {
32
+ const code = mergeMarkdownCodeConfigs(resolveCodeConfigFromLegacy(config), config.code);
33
+ return {
34
+ ...config.options ?? {},
35
+ enhancedCodeBlocks: code?.enhanced ?? config.options?.enhancedCodeBlocks,
36
+ langs: code?.langs ?? config.options?.langs,
37
+ lineNumbers: code?.lineNumbers ?? config.options?.lineNumbers,
38
+ theme: code?.shikiTheme ?? config.options?.theme
39
+ };
40
+ }
41
+ export function resolveFullBleedCode(config) {
42
+ return config.code?.fullBleed ?? config.fullBleedCode;
43
+ }
44
+
45
+ //# sourceMappingURL=codeConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/codeConfig.ts"],"sourcesContent":["import type { MarkdownCodeConfig, MarkdownRenderConfig, RenderMarkdownOptions } from '../types/core.js'\n\nexport function resolveCodeConfigFromLegacy(config?: MarkdownRenderConfig): MarkdownCodeConfig | undefined {\n if (!config) return undefined\n\n const legacy: MarkdownCodeConfig = {}\n\n if (config.options?.langs) legacy.langs = config.options.langs\n if (config.options?.lineNumbers !== undefined) legacy.lineNumbers = config.options.lineNumbers\n if (config.options?.theme) legacy.shikiTheme = config.options.theme\n if (config.options?.enhancedCodeBlocks !== undefined)\n legacy.enhanced = config.options.enhancedCodeBlocks\n if (config.fullBleedCode !== undefined) legacy.fullBleed = config.fullBleedCode\n\n return Object.keys(legacy).length > 0 ? legacy : undefined\n}\n\nexport function mergeMarkdownCodeConfigs(\n ...configs: Array<MarkdownCodeConfig | undefined>\n): MarkdownCodeConfig | undefined {\n const merged: MarkdownCodeConfig = {}\n\n for (const config of configs) {\n if (!config) continue\n\n if (config.enhanced !== undefined) merged.enhanced = config.enhanced\n if (config.fullBleed !== undefined) merged.fullBleed = config.fullBleed\n if (config.langs !== undefined) merged.langs = config.langs\n if (config.lineNumbers !== undefined) merged.lineNumbers = config.lineNumbers\n if (config.shikiTheme !== undefined) merged.shikiTheme = config.shikiTheme\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined\n}\n\nexport function mergeCodeConfigFromRenderConfigs(\n ...configs: Array<MarkdownRenderConfig | undefined>\n): MarkdownCodeConfig | undefined {\n const ordered: Array<MarkdownCodeConfig | undefined> = []\n\n for (const config of configs) {\n if (!config) continue\n\n ordered.push(resolveCodeConfigFromLegacy(config), config.code)\n }\n\n return mergeMarkdownCodeConfigs(...ordered)\n}\n\nexport function resolveRenderMarkdownOptions(\n config: MarkdownRenderConfig = {},\n): RenderMarkdownOptions {\n const code = mergeMarkdownCodeConfigs(resolveCodeConfigFromLegacy(config), config.code)\n\n return {\n ...(config.options ?? {}),\n enhancedCodeBlocks: code?.enhanced ?? config.options?.enhancedCodeBlocks,\n langs: code?.langs ?? config.options?.langs,\n lineNumbers: code?.lineNumbers ?? config.options?.lineNumbers,\n theme: code?.shikiTheme ?? config.options?.theme,\n }\n}\n\nexport function resolveFullBleedCode(config: MarkdownRenderConfig): boolean | undefined {\n return config.code?.fullBleed ?? config.fullBleedCode\n}\n"],"names":["resolveCodeConfigFromLegacy","config","undefined","legacy","options","langs","lineNumbers","theme","shikiTheme","enhancedCodeBlocks","enhanced","fullBleedCode","fullBleed","Object","keys","length","mergeMarkdownCodeConfigs","configs","merged","mergeCodeConfigFromRenderConfigs","ordered","push","code","resolveRenderMarkdownOptions","resolveFullBleedCode"],"mappings":"AAEA,OAAO,SAASA,4BAA4BC,MAA6B;IACvE,IAAI,CAACA,QAAQ,OAAOC;IAEpB,MAAMC,SAA6B,CAAC;IAEpC,IAAIF,OAAOG,OAAO,EAAEC,OAAOF,OAAOE,KAAK,GAAGJ,OAAOG,OAAO,CAACC,KAAK;IAC9D,IAAIJ,OAAOG,OAAO,EAAEE,gBAAgBJ,WAAWC,OAAOG,WAAW,GAAGL,OAAOG,OAAO,CAACE,WAAW;IAC9F,IAAIL,OAAOG,OAAO,EAAEG,OAAOJ,OAAOK,UAAU,GAAGP,OAAOG,OAAO,CAACG,KAAK;IACnE,IAAIN,OAAOG,OAAO,EAAEK,uBAAuBP,WACzCC,OAAOO,QAAQ,GAAGT,OAAOG,OAAO,CAACK,kBAAkB;IACrD,IAAIR,OAAOU,aAAa,KAAKT,WAAWC,OAAOS,SAAS,GAAGX,OAAOU,aAAa;IAE/E,OAAOE,OAAOC,IAAI,CAACX,QAAQY,MAAM,GAAG,IAAIZ,SAASD;AACnD;AAEA,OAAO,SAASc,yBACd,GAAGC,OAA8C;IAEjD,MAAMC,SAA6B,CAAC;IAEpC,KAAK,MAAMjB,UAAUgB,QAAS;QAC5B,IAAI,CAAChB,QAAQ;QAEb,IAAIA,OAAOS,QAAQ,KAAKR,WAAWgB,OAAOR,QAAQ,GAAGT,OAAOS,QAAQ;QACpE,IAAIT,OAAOW,SAAS,KAAKV,WAAWgB,OAAON,SAAS,GAAGX,OAAOW,SAAS;QACvE,IAAIX,OAAOI,KAAK,KAAKH,WAAWgB,OAAOb,KAAK,GAAGJ,OAAOI,KAAK;QAC3D,IAAIJ,OAAOK,WAAW,KAAKJ,WAAWgB,OAAOZ,WAAW,GAAGL,OAAOK,WAAW;QAC7E,IAAIL,OAAOO,UAAU,KAAKN,WAAWgB,OAAOV,UAAU,GAAGP,OAAOO,UAAU;IAC5E;IAEA,OAAOK,OAAOC,IAAI,CAACI,QAAQH,MAAM,GAAG,IAAIG,SAAShB;AACnD;AAEA,OAAO,SAASiB,iCACd,GAAGF,OAAgD;IAEnD,MAAMG,UAAiD,EAAE;IAEzD,KAAK,MAAMnB,UAAUgB,QAAS;QAC5B,IAAI,CAAChB,QAAQ;QAEbmB,QAAQC,IAAI,CAACrB,4BAA4BC,SAASA,OAAOqB,IAAI;IAC/D;IAEA,OAAON,4BAA4BI;AACrC;AAEA,OAAO,SAASG,6BACdtB,SAA+B,CAAC,CAAC;IAEjC,MAAMqB,OAAON,yBAAyBhB,4BAA4BC,SAASA,OAAOqB,IAAI;IAEtF,OAAO;QACL,GAAIrB,OAAOG,OAAO,IAAI,CAAC,CAAC;QACxBK,oBAAoBa,MAAMZ,YAAYT,OAAOG,OAAO,EAAEK;QACtDJ,OAAOiB,MAAMjB,SAASJ,OAAOG,OAAO,EAAEC;QACtCC,aAAagB,MAAMhB,eAAeL,OAAOG,OAAO,EAAEE;QAClDC,OAAOe,MAAMd,cAAcP,OAAOG,OAAO,EAAEG;IAC7C;AACF;AAEA,OAAO,SAASiB,qBAAqBvB,MAA4B;IAC/D,OAAOA,OAAOqB,IAAI,EAAEV,aAAaX,OAAOU,aAAa;AACvD"}
@@ -0,0 +1,5 @@
1
+ import type { CodeBlockOptions } from '../types/core.js';
2
+ export declare const DEFAULT_CODE_LANG = "text";
3
+ export declare const DEFAULT_CODE_THEME = "github-dark";
4
+ export declare const DEFAULT_CODE_LANGS: readonly string[];
5
+ export declare function codeToHtml(code: string, options?: CodeBlockOptions): Promise<string>;
@@ -0,0 +1,180 @@
1
+ import { createHighlighter } from 'shiki';
2
+ export const DEFAULT_CODE_LANG = 'text';
3
+ export const DEFAULT_CODE_THEME = 'github-dark';
4
+ export const DEFAULT_CODE_LANGS = [
5
+ 'cpp',
6
+ 'java',
7
+ 'js',
8
+ 'ts',
9
+ 'jsx',
10
+ 'tsx',
11
+ 'json',
12
+ 'python',
13
+ 'rust',
14
+ 'html',
15
+ 'css',
16
+ 'yaml',
17
+ 'sql'
18
+ ];
19
+ const highlighterCache = new Map();
20
+ function getHighlighterCacheKey(theme, langs) {
21
+ return `${theme}::${[
22
+ ...langs
23
+ ].sort().join(',')}`;
24
+ }
25
+ function getHighlighter(theme, langs) {
26
+ const cacheKey = getHighlighterCacheKey(theme, langs);
27
+ const existing = highlighterCache.get(cacheKey);
28
+ if (existing) return existing;
29
+ const created = createHighlighter({
30
+ langs: [
31
+ ...langs
32
+ ],
33
+ themes: [
34
+ theme
35
+ ]
36
+ });
37
+ highlighterCache.set(cacheKey, created);
38
+ return created;
39
+ }
40
+ function countLines(code) {
41
+ return code.length === 0 ? 1 : code.split('\n').length;
42
+ }
43
+ function resolveCodeBlockOptions(options) {
44
+ const enhancedCodeBlocks = options.enhancedCodeBlocks ?? true;
45
+ return {
46
+ ...options,
47
+ enhancedCodeBlocks,
48
+ lineNumbers: enhancedCodeBlocks ? options.lineNumbers ?? true : false
49
+ };
50
+ }
51
+ function isText(node) {
52
+ return node.type === 'text';
53
+ }
54
+ function isElement(node) {
55
+ return node.type === 'element';
56
+ }
57
+ function isEmptyText(node) {
58
+ return node.value === '';
59
+ }
60
+ function isVisuallyEmptyLine(node) {
61
+ if (node.children.length === 0) return true;
62
+ return node.children.every((child)=>{
63
+ if (isText(child)) return isEmptyText(child);
64
+ if (isElement(child)) {
65
+ if (child.children.length === 0) return true;
66
+ return child.children.every((grandchild)=>{
67
+ if (isText(grandchild)) return isEmptyText(grandchild);
68
+ return false;
69
+ });
70
+ }
71
+ return false;
72
+ });
73
+ }
74
+ function mergeClassNames(existing, additions) {
75
+ const current = typeof existing === 'string' ? existing.split(/\s+/).filter(Boolean) : Array.isArray(existing) ? existing.filter((v)=>typeof v === 'string' && v.trim().length > 0) : [];
76
+ return [
77
+ ...new Set([
78
+ ...additions,
79
+ ...current
80
+ ])
81
+ ];
82
+ }
83
+ function setMergedClassNames(node, additions) {
84
+ const merged = mergeClassNames(node.properties.className ?? node.properties.class, additions);
85
+ node.properties.className = merged;
86
+ node.properties.class = merged.join(' ');
87
+ }
88
+ function makeClassElement(className, text) {
89
+ return {
90
+ type: 'element',
91
+ children: [
92
+ {
93
+ type: 'text',
94
+ value: text
95
+ }
96
+ ],
97
+ properties: {
98
+ class: className,
99
+ className: [
100
+ className
101
+ ]
102
+ },
103
+ tagName: 'span'
104
+ };
105
+ }
106
+ /**
107
+ * Builds the Shiki transformer pipeline used to normalize and enhance
108
+ * rendered fenced code blocks.
109
+ */ function buildTransformers({ enhancedCodeBlocks, lineNumbers }, totalLines) {
110
+ const transformers = [];
111
+ const useEnhanced = enhancedCodeBlocks;
112
+ const digits = Math.max(1, String(totalLines).length);
113
+ transformers.push({
114
+ pre (node) {
115
+ if (!useEnhanced) return;
116
+ setMergedClassNames(node, [
117
+ 'md-code-enhanced'
118
+ ]);
119
+ },
120
+ code (node) {
121
+ if (!useEnhanced) return;
122
+ if (node.children) {
123
+ node.children = node.children.filter((child)=>{
124
+ if (child.type !== 'text') return true;
125
+ // Shiki inserts raw newline separator text nodes between rendered line spans.
126
+ // Those create fake blank rows once line display is class-driven.
127
+ return !/^\r?\n$/.test(child.value);
128
+ });
129
+ }
130
+ },
131
+ line (node, line) {
132
+ if (!useEnhanced && !lineNumbers) return;
133
+ const isEmptyLine = isVisuallyEmptyLine(node);
134
+ if (lineNumbers) setMergedClassNames(node, [
135
+ 'md-line',
136
+ `md-line-digits-${digits}`
137
+ ]);
138
+ else if (useEnhanced) setMergedClassNames(node, [
139
+ 'md-line',
140
+ 'md-line-no-numbers'
141
+ ]);
142
+ if (lineNumbers) node.children.unshift(makeClassElement('md-line-number', String(line)));
143
+ if (isEmptyLine) {
144
+ const lineNumberNode = lineNumbers ? node.children[0] : null;
145
+ node.children = [
146
+ ...lineNumberNode ? [
147
+ lineNumberNode
148
+ ] : [],
149
+ makeClassElement('md-empty-line', '\u00A0')
150
+ ];
151
+ }
152
+ }
153
+ });
154
+ return transformers;
155
+ }
156
+ export async function codeToHtml(code, options = {}) {
157
+ const resolvedOptions = resolveCodeBlockOptions(options);
158
+ const lang = resolvedOptions.lang?.trim() || DEFAULT_CODE_LANG;
159
+ const langs = resolvedOptions.langs ?? DEFAULT_CODE_LANGS;
160
+ const theme = resolvedOptions.theme?.trim() || DEFAULT_CODE_THEME;
161
+ const highlighter = await getHighlighter(theme, langs);
162
+ const normalizedCode = code.replace(/\n+$/, '');
163
+ const totalLines = countLines(normalizedCode);
164
+ const transformers = buildTransformers(resolvedOptions, totalLines);
165
+ try {
166
+ return highlighter.codeToHtml(normalizedCode, {
167
+ lang,
168
+ theme,
169
+ transformers
170
+ });
171
+ } catch {
172
+ return highlighter.codeToHtml(normalizedCode, {
173
+ lang: DEFAULT_CODE_LANG,
174
+ theme,
175
+ transformers
176
+ });
177
+ }
178
+ }
179
+
180
+ //# sourceMappingURL=codeToHtml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/codeToHtml.ts"],"sourcesContent":["import type { Element, ElementContent, Text } from 'hast'\n\nimport { createHighlighter, type ShikiTransformer } from 'shiki'\n\nimport type { CodeBlockOptions } from '../types/core.js'\n\nexport const DEFAULT_CODE_LANG = 'text'\nexport const DEFAULT_CODE_THEME = 'github-dark'\nexport const DEFAULT_CODE_LANGS: readonly string[] = [\n 'cpp',\n 'java',\n 'js',\n 'ts',\n 'jsx',\n 'tsx',\n 'json',\n 'python',\n 'rust',\n 'html',\n 'css',\n 'yaml',\n 'sql',\n]\n\nconst highlighterCache = new Map<string, ReturnType<typeof createHighlighter>>()\n\nfunction getHighlighterCacheKey(theme: string, langs: readonly string[]) {\n return `${theme}::${[...langs].sort().join(',')}`\n}\n\nfunction getHighlighter(theme: string, langs: readonly string[]) {\n const cacheKey = getHighlighterCacheKey(theme, langs)\n const existing = highlighterCache.get(cacheKey)\n if (existing) return existing\n\n const created = createHighlighter({\n langs: [...langs],\n themes: [theme],\n })\n\n highlighterCache.set(cacheKey, created)\n return created\n}\n\nfunction countLines(code: string): number {\n return code.length === 0 ? 1 : code.split('\\n').length\n}\n\nfunction resolveCodeBlockOptions(\n options: CodeBlockOptions,\n): CodeBlockOptions & Required<Pick<CodeBlockOptions, 'enhancedCodeBlocks' | 'lineNumbers'>> {\n const enhancedCodeBlocks = options.enhancedCodeBlocks ?? true\n\n return {\n ...options,\n enhancedCodeBlocks,\n lineNumbers: enhancedCodeBlocks ? (options.lineNumbers ?? true) : false,\n }\n}\n\nfunction isText(node: ElementContent): node is Text {\n return node.type === 'text'\n}\n\nfunction isElement(node: ElementContent): node is Element {\n return node.type === 'element'\n}\n\nfunction isEmptyText(node: Text): boolean {\n return node.value === ''\n}\n\nfunction isVisuallyEmptyLine(node: Element): boolean {\n if (node.children.length === 0) return true\n\n return node.children.every((child) => {\n if (isText(child)) return isEmptyText(child)\n\n if (isElement(child)) {\n if (child.children.length === 0) return true\n\n return child.children.every((grandchild) => {\n if (isText(grandchild)) return isEmptyText(grandchild)\n return false\n })\n }\n\n return false\n })\n}\n\nfunction mergeClassNames(existing: unknown, additions: string[]): string[] {\n const current =\n typeof existing === 'string'\n ? existing.split(/\\s+/).filter(Boolean)\n : Array.isArray(existing)\n ? existing.filter((v): v is string => typeof v === 'string' && v.trim().length > 0)\n : []\n\n return [...new Set([...additions, ...current])]\n}\n\nfunction setMergedClassNames(node: { properties: Record<string, unknown> }, additions: string[]) {\n const merged = mergeClassNames(node.properties.className ?? node.properties.class, additions)\n\n node.properties.className = merged\n node.properties.class = merged.join(' ')\n}\n\nfunction makeClassElement(className: string, text: string): Element {\n return {\n type: 'element',\n children: [{ type: 'text', value: text }],\n properties: {\n class: className,\n className: [className],\n },\n tagName: 'span',\n }\n}\n\n/**\n * Builds the Shiki transformer pipeline used to normalize and enhance\n * rendered fenced code blocks.\n */\nfunction buildTransformers(\n {\n enhancedCodeBlocks,\n lineNumbers,\n }: Required<Pick<CodeBlockOptions, 'enhancedCodeBlocks' | 'lineNumbers'>>,\n totalLines: number,\n): ShikiTransformer[] {\n const transformers: ShikiTransformer[] = []\n const useEnhanced = enhancedCodeBlocks\n const digits = Math.max(1, String(totalLines).length)\n\n transformers.push({\n pre(node) {\n if (!useEnhanced) return\n setMergedClassNames(node, ['md-code-enhanced'])\n },\n\n code(node) {\n if (!useEnhanced) return\n\n if (node.children) {\n node.children = node.children.filter((child) => {\n if (child.type !== 'text') return true\n\n // Shiki inserts raw newline separator text nodes between rendered line spans.\n // Those create fake blank rows once line display is class-driven.\n return !/^\\r?\\n$/.test(child.value)\n })\n }\n },\n\n line(node, line) {\n if (!useEnhanced && !lineNumbers) return\n\n const isEmptyLine = isVisuallyEmptyLine(node)\n\n if (lineNumbers) setMergedClassNames(node, ['md-line', `md-line-digits-${digits}`])\n else if (useEnhanced) setMergedClassNames(node, ['md-line', 'md-line-no-numbers'])\n\n if (lineNumbers) node.children.unshift(makeClassElement('md-line-number', String(line)))\n\n if (isEmptyLine) {\n const lineNumberNode = lineNumbers ? node.children[0] : null\n\n node.children = [\n ...(lineNumberNode ? [lineNumberNode] : []),\n makeClassElement('md-empty-line', '\\u00A0'),\n ]\n }\n },\n })\n\n return transformers\n}\n\nexport async function codeToHtml(code: string, options: CodeBlockOptions = {}) {\n const resolvedOptions = resolveCodeBlockOptions(options)\n\n const lang = resolvedOptions.lang?.trim() || DEFAULT_CODE_LANG\n const langs = resolvedOptions.langs ?? DEFAULT_CODE_LANGS\n const theme = resolvedOptions.theme?.trim() || DEFAULT_CODE_THEME\n\n const highlighter = await getHighlighter(theme, langs)\n const normalizedCode = code.replace(/\\n+$/, '')\n const totalLines = countLines(normalizedCode)\n const transformers = buildTransformers(resolvedOptions, totalLines)\n\n try {\n return highlighter.codeToHtml(normalizedCode, {\n lang,\n theme,\n transformers,\n })\n } catch {\n return highlighter.codeToHtml(normalizedCode, {\n lang: DEFAULT_CODE_LANG,\n theme,\n transformers,\n })\n }\n}\n"],"names":["createHighlighter","DEFAULT_CODE_LANG","DEFAULT_CODE_THEME","DEFAULT_CODE_LANGS","highlighterCache","Map","getHighlighterCacheKey","theme","langs","sort","join","getHighlighter","cacheKey","existing","get","created","themes","set","countLines","code","length","split","resolveCodeBlockOptions","options","enhancedCodeBlocks","lineNumbers","isText","node","type","isElement","isEmptyText","value","isVisuallyEmptyLine","children","every","child","grandchild","mergeClassNames","additions","current","filter","Boolean","Array","isArray","v","trim","Set","setMergedClassNames","merged","properties","className","class","makeClassElement","text","tagName","buildTransformers","totalLines","transformers","useEnhanced","digits","Math","max","String","push","pre","test","line","isEmptyLine","unshift","lineNumberNode","codeToHtml","resolvedOptions","lang","highlighter","normalizedCode","replace"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Root } from 'hast';
2
+ import type { Plugin } from 'unified';
3
+ import type { MarkdownRenderConfig } from '../../types/core.js';
4
+ export declare const rehypeApplyLayoutClasses: Plugin<[MarkdownRenderConfig?], Root>;
@@ -0,0 +1,72 @@
1
+ import { visit } from 'unist-util-visit';
2
+ import { layoutDirectiveRegistry } from '../../directives/registry.js';
3
+ function compactClassNames(...values) {
4
+ return values.flatMap((value)=>value?.split(/\s+/).filter(Boolean) ?? []);
5
+ }
6
+ function mergeClassNames(...values) {
7
+ const tokens = compactClassNames(...values);
8
+ const seen = new Set();
9
+ const out = [];
10
+ for(let i = tokens.length - 1; i >= 0; --i){
11
+ const token = tokens[i];
12
+ if (seen.has(token)) continue;
13
+ seen.add(token);
14
+ out.push(token);
15
+ }
16
+ return out.reverse();
17
+ }
18
+ function isElement(node) {
19
+ return Boolean(node && typeof node === 'object' && 'type' in node && node.type === 'element');
20
+ }
21
+ function isCellBoundary(node) {
22
+ return isElement(node) && [
23
+ 'h2',
24
+ 'h3',
25
+ 'h4'
26
+ ].includes(node.tagName);
27
+ }
28
+ function wrapAsCell(children, columnClassName, cellTheme) {
29
+ return {
30
+ type: 'element',
31
+ children,
32
+ properties: {
33
+ className: mergeClassNames(cellTheme?.hookClassName ?? 'flex flex-col w-full gap-2 [&>h2]:text-2xl [&>h2]:my-4 [&>h3]:text-xl [&>h3]:my-3 [&>h4]:text-lg [&>h4]:my-2', cellTheme?.modifierClassName, cellTheme?.classes, columnClassName),
34
+ dataTheme: cellTheme?.name,
35
+ dataVlLayout: 'cell'
36
+ },
37
+ tagName: 'div'
38
+ };
39
+ }
40
+ function groupChildrenIntoCells(children, columnClassName, cellTheme) {
41
+ const groups = [];
42
+ let current = [];
43
+ for (const child of children){
44
+ if (isCellBoundary(child) && current.length > 0) {
45
+ groups.push(current);
46
+ current = [
47
+ child
48
+ ];
49
+ continue;
50
+ }
51
+ current.push(child);
52
+ }
53
+ if (current.length > 0) groups.push(current);
54
+ return groups.map((group)=>wrapAsCell(group, columnClassName, cellTheme));
55
+ }
56
+ export const rehypeApplyLayoutClasses = (config = {})=>{
57
+ return (tree)=>{
58
+ visit(tree, 'element', (node)=>{
59
+ if (!isElement(node)) return;
60
+ const marker = node.properties?.dataVlLayout;
61
+ if (typeof marker !== 'string') return;
62
+ const definition = layoutDirectiveRegistry.get(marker);
63
+ if (!definition?.applyHast) return;
64
+ definition.applyHast(node, config, {
65
+ groupChildrenIntoCells,
66
+ mergeClassNames
67
+ });
68
+ });
69
+ };
70
+ };
71
+
72
+ //# sourceMappingURL=rehypeApplyLayoutClasses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/plugins/rehypeApplyLayoutClasses.ts"],"sourcesContent":["import type { Element, ElementContent, Root } from 'hast'\nimport type { Plugin } from 'unified'\n\nimport { visit } from 'unist-util-visit'\n\nimport type { ResolvedDirectiveTheme } from '../../directives/themes.js'\nimport type { MarkdownRenderConfig } from '../../types/core.js'\n\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\n\nfunction compactClassNames(...values: Array<string | undefined>): string[] {\n return values.flatMap((value) => value?.split(/\\s+/).filter(Boolean) ?? [])\n}\n\nfunction mergeClassNames(...values: Array<string | undefined>): string[] {\n const tokens = compactClassNames(...values)\n const seen = new Set<string>()\n const out: string[] = []\n\n for (let i = tokens.length - 1; i >= 0; --i) {\n const token = tokens[i]\n if (seen.has(token)) continue\n seen.add(token)\n out.push(token)\n }\n\n return out.reverse()\n}\n\nfunction isElement(node: unknown): node is Element {\n return Boolean(\n node && typeof node === 'object' && 'type' in node && (node as Element).type === 'element',\n )\n}\n\nfunction isCellBoundary(node: ElementContent): boolean {\n return isElement(node) && ['h2', 'h3', 'h4'].includes(node.tagName)\n}\n\nfunction wrapAsCell(\n children: ElementContent[],\n columnClassName?: string,\n cellTheme?: ResolvedDirectiveTheme,\n): Element {\n return {\n type: 'element',\n children,\n properties: {\n className: mergeClassNames(\n cellTheme?.hookClassName ??\n 'flex flex-col w-full gap-2 [&>h2]:text-2xl [&>h2]:my-4 [&>h3]:text-xl [&>h3]:my-3 [&>h4]:text-lg [&>h4]:my-2',\n cellTheme?.modifierClassName,\n cellTheme?.classes,\n columnClassName,\n ),\n dataTheme: cellTheme?.name,\n dataVlLayout: 'cell',\n },\n tagName: 'div',\n }\n}\n\nfunction groupChildrenIntoCells(\n children: ElementContent[],\n columnClassName?: string,\n cellTheme?: ResolvedDirectiveTheme,\n): ElementContent[] {\n const groups: ElementContent[][] = []\n let current: ElementContent[] = []\n\n for (const child of children) {\n if (isCellBoundary(child) && current.length > 0) {\n groups.push(current)\n current = [child]\n continue\n }\n\n current.push(child)\n }\n\n if (current.length > 0) groups.push(current)\n\n return groups.map((group) => wrapAsCell(group, columnClassName, cellTheme))\n}\n\nexport const rehypeApplyLayoutClasses: Plugin<[MarkdownRenderConfig?], Root> = (\n config: MarkdownRenderConfig = {},\n) => {\n return (tree: Root) => {\n visit(tree, 'element', (node) => {\n if (!isElement(node)) return\n\n const marker = node.properties?.dataVlLayout\n if (typeof marker !== 'string') return\n\n const definition = layoutDirectiveRegistry.get(marker)\n if (!definition?.applyHast) return\n\n definition.applyHast(node, config, {\n groupChildrenIntoCells,\n mergeClassNames,\n })\n })\n }\n}\n"],"names":["visit","layoutDirectiveRegistry","compactClassNames","values","flatMap","value","split","filter","Boolean","mergeClassNames","tokens","seen","Set","out","i","length","token","has","add","push","reverse","isElement","node","type","isCellBoundary","includes","tagName","wrapAsCell","children","columnClassName","cellTheme","properties","className","hookClassName","modifierClassName","classes","dataTheme","name","dataVlLayout","groupChildrenIntoCells","groups","current","child","map","group","rehypeApplyLayoutClasses","config","tree","marker","definition","get","applyHast"],"mappings":"AAGA,SAASA,KAAK,QAAQ,mBAAkB;AAKxC,SAASC,uBAAuB,QAAQ,+BAA8B;AAEtE,SAASC,kBAAkB,GAAGC,MAAiC;IAC7D,OAAOA,OAAOC,OAAO,CAAC,CAACC,QAAUA,OAAOC,MAAM,OAAOC,OAAOC,YAAY,EAAE;AAC5E;AAEA,SAASC,gBAAgB,GAAGN,MAAiC;IAC3D,MAAMO,SAASR,qBAAqBC;IACpC,MAAMQ,OAAO,IAAIC;IACjB,MAAMC,MAAgB,EAAE;IAExB,IAAK,IAAIC,IAAIJ,OAAOK,MAAM,GAAG,GAAGD,KAAK,GAAG,EAAEA,EAAG;QAC3C,MAAME,QAAQN,MAAM,CAACI,EAAE;QACvB,IAAIH,KAAKM,GAAG,CAACD,QAAQ;QACrBL,KAAKO,GAAG,CAACF;QACTH,IAAIM,IAAI,CAACH;IACX;IAEA,OAAOH,IAAIO,OAAO;AACpB;AAEA,SAASC,UAAUC,IAAa;IAC9B,OAAOd,QACLc,QAAQ,OAAOA,SAAS,YAAY,UAAUA,QAAQ,AAACA,KAAiBC,IAAI,KAAK;AAErF;AAEA,SAASC,eAAeF,IAAoB;IAC1C,OAAOD,UAAUC,SAAS;QAAC;QAAM;QAAM;KAAK,CAACG,QAAQ,CAACH,KAAKI,OAAO;AACpE;AAEA,SAASC,WACPC,QAA0B,EAC1BC,eAAwB,EACxBC,SAAkC;IAElC,OAAO;QACLP,MAAM;QACNK;QACAG,YAAY;YACVC,WAAWvB,gBACTqB,WAAWG,iBACT,gHACFH,WAAWI,mBACXJ,WAAWK,SACXN;YAEFO,WAAWN,WAAWO;YACtBC,cAAc;QAChB;QACAZ,SAAS;IACX;AACF;AAEA,SAASa,uBACPX,QAA0B,EAC1BC,eAAwB,EACxBC,SAAkC;IAElC,MAAMU,SAA6B,EAAE;IACrC,IAAIC,UAA4B,EAAE;IAElC,KAAK,MAAMC,SAASd,SAAU;QAC5B,IAAIJ,eAAekB,UAAUD,QAAQ1B,MAAM,GAAG,GAAG;YAC/CyB,OAAOrB,IAAI,CAACsB;YACZA,UAAU;gBAACC;aAAM;YACjB;QACF;QAEAD,QAAQtB,IAAI,CAACuB;IACf;IAEA,IAAID,QAAQ1B,MAAM,GAAG,GAAGyB,OAAOrB,IAAI,CAACsB;IAEpC,OAAOD,OAAOG,GAAG,CAAC,CAACC,QAAUjB,WAAWiB,OAAOf,iBAAiBC;AAClE;AAEA,OAAO,MAAMe,2BAAkE,CAC7EC,SAA+B,CAAC,CAAC;IAEjC,OAAO,CAACC;QACN/C,MAAM+C,MAAM,WAAW,CAACzB;YACtB,IAAI,CAACD,UAAUC,OAAO;YAEtB,MAAM0B,SAAS1B,KAAKS,UAAU,EAAEO;YAChC,IAAI,OAAOU,WAAW,UAAU;YAEhC,MAAMC,aAAahD,wBAAwBiD,GAAG,CAACF;YAC/C,IAAI,CAACC,YAAYE,WAAW;YAE5BF,WAAWE,SAAS,CAAC7B,MAAMwB,QAAQ;gBACjCP;gBACA9B;YACF;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Root } from 'hast';
2
+ import type { Plugin } from 'unified';
3
+ export declare const rehypeStripAuthoredInlineStyles: Plugin<[], Root>;
@@ -0,0 +1,17 @@
1
+ import { visit } from 'unist-util-visit';
2
+ function isElement(node) {
3
+ return Boolean(node && typeof node === 'object' && 'type' in node && node.type === 'element');
4
+ }
5
+ const ALLOW_STYLE_ON_AUTHORED_TAGS = new Set([]);
6
+ export const rehypeStripAuthoredInlineStyles = ()=>{
7
+ return (tree)=>{
8
+ visit(tree, 'element', (node)=>{
9
+ if (!isElement(node)) return;
10
+ if (!node.properties?.style) return;
11
+ if (ALLOW_STYLE_ON_AUTHORED_TAGS.has(node.tagName)) return;
12
+ delete node.properties.style;
13
+ });
14
+ };
15
+ };
16
+
17
+ //# sourceMappingURL=rehypeStripAuthoredInlineStyles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/plugins/rehypeStripAuthoredInlineStyles.ts"],"sourcesContent":["import type { Element, Root } from 'hast'\nimport type { Plugin } from 'unified'\n\nimport { visit } from 'unist-util-visit'\n\nfunction isElement(node: unknown): node is Element {\n return Boolean(\n node && typeof node === 'object' && 'type' in node && (node as Element).type === 'element',\n )\n}\n\nconst ALLOW_STYLE_ON_AUTHORED_TAGS = new Set<string>([])\n\nexport const rehypeStripAuthoredInlineStyles: Plugin<[], Root> = () => {\n return (tree) => {\n visit(tree, 'element', (node) => {\n if (!isElement(node)) return\n if (!node.properties?.style) return\n if (ALLOW_STYLE_ON_AUTHORED_TAGS.has(node.tagName)) return\n\n delete node.properties.style\n })\n }\n}\n"],"names":["visit","isElement","node","Boolean","type","ALLOW_STYLE_ON_AUTHORED_TAGS","Set","rehypeStripAuthoredInlineStyles","tree","properties","style","has","tagName"],"mappings":"AAGA,SAASA,KAAK,QAAQ,mBAAkB;AAExC,SAASC,UAAUC,IAAa;IAC9B,OAAOC,QACLD,QAAQ,OAAOA,SAAS,YAAY,UAAUA,QAAQ,AAACA,KAAiBE,IAAI,KAAK;AAErF;AAEA,MAAMC,+BAA+B,IAAIC,IAAY,EAAE;AAEvD,OAAO,MAAMC,kCAAoD;IAC/D,OAAO,CAACC;QACNR,MAAMQ,MAAM,WAAW,CAACN;YACtB,IAAI,CAACD,UAAUC,OAAO;YACtB,IAAI,CAACA,KAAKO,UAAU,EAAEC,OAAO;YAC7B,IAAIL,6BAA6BM,GAAG,CAACT,KAAKU,OAAO,GAAG;YAEpD,OAAOV,KAAKO,UAAU,CAACC,KAAK;QAC9B;IACF;AACF,EAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Root } from 'mdast';
2
+ import type { Plugin } from 'unified';
3
+ export declare const remarkCompileLayouts: Plugin<[], Root>;