md-to-rich 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +203 -0
  3. package/dist/chunk-5CRCBG3P.js +221 -0
  4. package/dist/chunk-5CRCBG3P.js.map +1 -0
  5. package/dist/chunk-DJVBCM6N.cjs +35 -0
  6. package/dist/chunk-DJVBCM6N.cjs.map +1 -0
  7. package/dist/chunk-JMKP2EMX.cjs +165 -0
  8. package/dist/chunk-JMKP2EMX.cjs.map +1 -0
  9. package/dist/chunk-NNRBDNG7.js +173 -0
  10. package/dist/chunk-NNRBDNG7.js.map +1 -0
  11. package/dist/chunk-PKBYGGAU.cjs +176 -0
  12. package/dist/chunk-PKBYGGAU.cjs.map +1 -0
  13. package/dist/chunk-U7TPKOGA.js +28 -0
  14. package/dist/chunk-U7TPKOGA.js.map +1 -0
  15. package/dist/chunk-WWNNSHI7.cjs +224 -0
  16. package/dist/chunk-WWNNSHI7.cjs.map +1 -0
  17. package/dist/chunk-ZYIRT2QF.js +162 -0
  18. package/dist/chunk-ZYIRT2QF.js.map +1 -0
  19. package/dist/index.cjs +39 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.d.cts +11 -0
  22. package/dist/index.d.ts +11 -0
  23. package/dist/index.js +6 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/serializers/ansi/index.cjs +17 -0
  26. package/dist/serializers/ansi/index.cjs.map +1 -0
  27. package/dist/serializers/ansi/index.d.cts +8 -0
  28. package/dist/serializers/ansi/index.d.ts +8 -0
  29. package/dist/serializers/ansi/index.js +4 -0
  30. package/dist/serializers/ansi/index.js.map +1 -0
  31. package/dist/serializers/doc-tree/index.cjs +17 -0
  32. package/dist/serializers/doc-tree/index.cjs.map +1 -0
  33. package/dist/serializers/doc-tree/index.d.cts +8 -0
  34. package/dist/serializers/doc-tree/index.d.ts +8 -0
  35. package/dist/serializers/doc-tree/index.js +4 -0
  36. package/dist/serializers/doc-tree/index.js.map +1 -0
  37. package/dist/serializers/html/index.cjs +17 -0
  38. package/dist/serializers/html/index.cjs.map +1 -0
  39. package/dist/serializers/html/index.d.cts +8 -0
  40. package/dist/serializers/html/index.d.ts +8 -0
  41. package/dist/serializers/html/index.js +4 -0
  42. package/dist/serializers/html/index.js.map +1 -0
  43. package/dist/types-Di2funKi.d.cts +136 -0
  44. package/dist/types-Di2funKi.d.ts +136 -0
  45. package/package.json +81 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jithin Sebastian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # md-to-rich
2
+
3
+ Convert Markdown to rich text output formats. TypeScript-first, tree-shakeable, ESM + CJS dual output.
4
+
5
+ **Built-in serializers:** HTML string · ANSI terminal string · Doc Tree (structured JSON)
6
+
7
+ **Extensible:** implement `Serializer<T>` to add any output format without touching this package.
8
+
9
+ ---
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ npm install md-to-rich
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ```typescript
22
+ import { toHtml, toAnsi, toDocTree } from 'md-to-rich'
23
+
24
+ toHtml('# Hello\n\n**bold**')
25
+ // → '<h1 id="hello">Hello</h1><p><strong>bold</strong></p>'
26
+
27
+ toAnsi('# Hello\n\n**bold**', { columns: 80 })
28
+ // → ANSI-escaped terminal string
29
+
30
+ toDocTree('# Hello')
31
+ // → { type: 'document', children: [{ type: 'heading', depth: 1, ... }] }
32
+ ```
33
+
34
+ ---
35
+
36
+ ## API
37
+
38
+ ### `toHtml(md, options?): string`
39
+
40
+ Converts Markdown to an HTML string.
41
+
42
+ ```typescript
43
+ import { toHtml } from 'md-to-rich'
44
+ // or sub-path:
45
+ import { toHtml } from 'md-to-rich/html'
46
+ ```
47
+
48
+ | Option | Type | Default | Description |
49
+ | --- | --- | --- | --- |
50
+ | `headingIds` | `boolean` | `true` | Add slug-based `id` attributes to headings (collision-safe) |
51
+ | `classNames` | `Partial<Record<HtmlElement, string>>` | `{}` | Custom CSS class per element |
52
+ | `renderImages` | `boolean` | `true` | Render `<img>` tags |
53
+ | `gfm` | `boolean` | `true` | Enable GitHub Flavored Markdown |
54
+ | `remarkPlugins` | `Plugin[]` | `[]` | Extra remark plugins |
55
+
56
+ ### `toAnsi(md, options?): string`
57
+
58
+ Converts Markdown to an ANSI-escaped terminal string.
59
+
60
+ ```typescript
61
+ import { toAnsi } from 'md-to-rich'
62
+ // or:
63
+ import { toAnsi } from 'md-to-rich/ansi'
64
+ ```
65
+
66
+ | Option | Type | Default | Description |
67
+ | --- | --- | --- | --- |
68
+ | `columns` | `number` | `process.stdout.columns ?? 80` | Terminal width for word-wrap and HR |
69
+ | `hyperlinks` | `boolean` | `false` | Emit OSC 8 hyperlink sequences |
70
+ | `theme` | `Partial<AnsiTheme>` | built-in | Override ANSI styles |
71
+ | `gfm` | `boolean` | `true` | Enable GFM |
72
+ | `remarkPlugins` | `Plugin[]` | `[]` | Extra remark plugins |
73
+
74
+ **Default theme** uses bold/underline for headings, italic, strikethrough, reverse-video for inline code, and box-drawing characters for tables and code blocks. No external chalk dependency — inline ANSI constants only.
75
+
76
+ ### `toDocTree(md, options?): DocDocument`
77
+
78
+ Converts Markdown to a structured `DocDocument` tree (plain JSON, no ANSI, no HTML).
79
+
80
+ ```typescript
81
+ import { toDocTree } from 'md-to-rich'
82
+ // or:
83
+ import { toDocTree } from 'md-to-rich/doc-tree'
84
+ ```
85
+
86
+ The tree is suitable for feeding into rich-text editors (ProseMirror, Slate, Quill, etc.) — see the adapter guide below.
87
+
88
+ ---
89
+
90
+ ### `serialize(md, serializer, options?): T`
91
+
92
+ Generic dispatch function — works with any `Serializer<T>` implementation.
93
+
94
+ ```typescript
95
+ import { serialize } from 'md-to-rich'
96
+ import type { Serializer } from 'md-to-rich'
97
+
98
+ const PlainText: Serializer<string> = {
99
+ serialize(ast) {
100
+ // ast is an MDAST Root node
101
+ return myCustomWalker(ast)
102
+ },
103
+ }
104
+
105
+ serialize('# Hello\n\nWorld', PlainText) // → 'Hello\nWorld'
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Building a Custom Serializer
111
+
112
+ Implement the `Serializer<TOutput, TOptions>` interface:
113
+
114
+ ```typescript
115
+ import type { Root } from 'mdast'
116
+ import { serialize } from 'md-to-rich'
117
+ import type { BaseOptions, Serializer } from 'md-to-rich'
118
+
119
+ interface MyOptions extends BaseOptions {
120
+ uppercase?: boolean
121
+ }
122
+
123
+ export const MySerializer: Serializer<string, MyOptions> = {
124
+ serialize(ast: Root, options: MyOptions): string {
125
+ // Walk the MDAST using your own logic, remark-stringify, unist-util-visit, etc.
126
+ const result = walkAst(ast)
127
+ return options.uppercase ? result.toUpperCase() : result
128
+ },
129
+ }
130
+
131
+ export function toMy(md: string, options?: MyOptions): string {
132
+ return serialize(md, MySerializer, options)
133
+ }
134
+ ```
135
+
136
+ The `Serializer` interface is the only contract. No inheritance, no registration — just pass your serializer to `serialize()`.
137
+
138
+ ---
139
+
140
+ ## Doc Tree Node Types
141
+
142
+ ```
143
+ DocDocument { type: 'document', children: DocBlockNode[] }
144
+ DocHeading { type: 'heading', depth: 1-6, children: DocInlineNode[] }
145
+ DocParagraph { type: 'paragraph', children: DocInlineNode[] }
146
+ DocBlockquote { type: 'blockquote', children: DocBlockNode[] }
147
+ DocCodeBlock { type: 'code', lang: string|null, value: string }
148
+ DocList { type: 'list', ordered: boolean, children: DocListItem[] }
149
+ DocListItem { type: 'listItem', checked: boolean|null, children: [...] }
150
+ DocTable { type: 'table', align: [...], children: DocTableRow[] }
151
+ DocTableRow { type: 'tableRow', isHeader: boolean, children: DocTableCell[] }
152
+ DocTableCell { type: 'tableCell', children: DocInlineNode[] }
153
+ DocHorizontalRule { type: 'thematicBreak' }
154
+
155
+ DocText { type: 'text', value: string, bold: boolean, italic: boolean, strikethrough: boolean }
156
+ DocInlineCode { type: 'inlineCode', value: string }
157
+ DocLink { type: 'link', url: string, title: string|null, children: DocInlineNode[] }
158
+ DocImage { type: 'image', url: string, alt: string|null, title: string|null }
159
+ DocBreak { type: 'break' }
160
+ ```
161
+
162
+ Nested `strong`/`emphasis`/`delete` marks are flattened into `DocText` boolean flags, making it straightforward to map into ProseMirror marks or Slate leaf properties.
163
+
164
+ ---
165
+
166
+ ## ProseMirror / Slate Adapter Guide
167
+
168
+ `toDocTree` outputs a plain JSON tree. Mapping to ProseMirror:
169
+
170
+ ```typescript
171
+ import { toDocTree } from 'md-to-rich'
172
+ import type { DocBlockNode, DocInlineNode } from 'md-to-rich'
173
+ import { schema } from 'prosemirror-schema-basic'
174
+
175
+ function blockToNode(node: DocBlockNode) {
176
+ if (node.type === 'paragraph') {
177
+ return schema.nodes.paragraph!.create(null, node.children.map(inlineToNode))
178
+ }
179
+ if (node.type === 'heading') {
180
+ return schema.nodes.heading!.create({ level: node.depth }, node.children.map(inlineToNode))
181
+ }
182
+ // ... other block types
183
+ }
184
+
185
+ function inlineToNode(node: DocInlineNode) {
186
+ if (node.type === 'text') {
187
+ const marks = []
188
+ if (node.bold) marks.push(schema.marks.strong!.create())
189
+ if (node.italic) marks.push(schema.marks.em!.create())
190
+ return schema.text(node.value, marks)
191
+ }
192
+ // ... other inline types
193
+ }
194
+
195
+ const doc = toDocTree(markdownString)
196
+ const pmDoc = schema.nodes.doc!.create(null, doc.children.map(blockToNode))
197
+ ```
198
+
199
+ ---
200
+
201
+ ## License
202
+
203
+ MIT
@@ -0,0 +1,221 @@
1
+ import { serialize } from './chunk-U7TPKOGA.js';
2
+
3
+ // src/serializers/ansi/theme.ts
4
+ var ESC = "\x1B[";
5
+ function style(open, close) {
6
+ const openCodes = Array.isArray(open) ? open : [open];
7
+ return {
8
+ open: `${ESC}${openCodes.join(";")}m`,
9
+ close: `${ESC}${close}m`
10
+ };
11
+ }
12
+ var defaultTheme = {
13
+ h1: style([1, 4, 35], 0),
14
+ // bold + underline + magenta
15
+ h2: style([1, 4, 36], 0),
16
+ // bold + underline + cyan
17
+ h3: style([1, 36], 0),
18
+ // bold + cyan
19
+ bold: style(1, 22),
20
+ italic: style(3, 23),
21
+ strikethrough: style(9, 29),
22
+ inlineCode: style([7, 33], 0),
23
+ // reverse + yellow
24
+ codeBlock: style(90, 39),
25
+ // dark grey
26
+ blockquote: style(90, 39),
27
+ // dark grey
28
+ link: style([4, 34], 0),
29
+ // underline + blue
30
+ listBullet: "\u2022",
31
+ hrChar: "\u2500"
32
+ };
33
+
34
+ // src/serializers/ansi/renderer.ts
35
+ var ANSI_RE = /\x1b\[[^m]*m|\x1b\][^\x07]*\x07/g;
36
+ function visibleWidth(s) {
37
+ return s.replace(ANSI_RE, "").length;
38
+ }
39
+ function wordWrap(text, columns, indent = "") {
40
+ const indentWidth = visibleWidth(indent);
41
+ const maxWidth = columns - indentWidth;
42
+ const words = text.split(/\s+/).filter(Boolean);
43
+ const lines = [];
44
+ let current = "";
45
+ for (const word of words) {
46
+ const candidate = current ? current + " " + word : word;
47
+ if (visibleWidth(candidate) > maxWidth && current) {
48
+ lines.push(current);
49
+ current = word;
50
+ } else {
51
+ current = candidate;
52
+ }
53
+ }
54
+ if (current) lines.push(current);
55
+ return lines.map((l) => indent + l).join("\n");
56
+ }
57
+ function renderToAnsi(ast, opts) {
58
+ const columns = opts.columns ?? (process.stdout.columns ?? 80);
59
+ const hyperlinks = opts.hyperlinks ?? false;
60
+ const theme = { ...defaultTheme, ...opts.theme ?? {} };
61
+ function applyStyle(s, text) {
62
+ return `${s.open}${text}${s.close}`;
63
+ }
64
+ function renderBlocks(nodes) {
65
+ return nodes.map((n) => renderBlock(n)).filter(Boolean).join("\n\n");
66
+ }
67
+ function renderBlock(node) {
68
+ switch (node.type) {
69
+ case "root":
70
+ return renderBlocks(node.children);
71
+ case "heading":
72
+ return renderHeading(node);
73
+ case "paragraph":
74
+ return renderParagraph(node);
75
+ case "blockquote":
76
+ return renderBlockquote(node);
77
+ case "code":
78
+ return renderCode(node);
79
+ case "list":
80
+ return renderList(node, 0);
81
+ case "table":
82
+ return renderTable(node);
83
+ case "thematicBreak":
84
+ return renderHr();
85
+ default:
86
+ return "";
87
+ }
88
+ }
89
+ function renderHeading(node) {
90
+ const text = renderInlines(node.children);
91
+ const styleKey = `h${node.depth}`;
92
+ const s = theme[styleKey] ?? theme.h3;
93
+ return applyStyle(s, text);
94
+ }
95
+ function renderParagraph(node) {
96
+ const text = renderInlines(node.children);
97
+ return wordWrap(text, columns);
98
+ }
99
+ function renderBlockquote(node) {
100
+ const inner = renderBlocks(node.children);
101
+ const prefix = applyStyle(theme.blockquote, "\u2502 ");
102
+ return inner.split("\n").map((line) => prefix + line).join("\n");
103
+ }
104
+ function renderCode(node) {
105
+ const lang = node.lang ? ` (${node.lang})` : "";
106
+ const header = applyStyle(theme.codeBlock, `\u250C\u2500 code${lang}`);
107
+ const lines = node.value.split("\n").map((l) => applyStyle(theme.codeBlock, `\u2502 ${l}`));
108
+ const footer = applyStyle(theme.codeBlock, "\u2514\u2500");
109
+ return [header, ...lines, footer].join("\n");
110
+ }
111
+ function renderList(node, depth) {
112
+ return node.children.map((li, i) => renderListItem(li, node, i + 1, depth)).join("\n");
113
+ }
114
+ function renderListItem(node, parent, index, depth) {
115
+ const indent = " ".repeat(depth);
116
+ const bullet = parent.ordered ? `${index}.` : applyStyle({ open: "", close: "" }, theme.listBullet);
117
+ const prefix = `${indent}${bullet} `;
118
+ const nestedLists = [];
119
+ const textParts = [];
120
+ for (const child of node.children) {
121
+ if (child.type === "list") {
122
+ nestedLists.push(child);
123
+ } else if (child.type === "paragraph") {
124
+ textParts.push(renderInlines(child.children));
125
+ }
126
+ }
127
+ const taskPrefix = node.checked !== null && node.checked !== void 0 ? node.checked ? "[x] " : "[ ] " : "";
128
+ const mainText = wordWrap(
129
+ taskPrefix + textParts.join(" "),
130
+ columns,
131
+ " ".repeat(visibleWidth(prefix))
132
+ ).replace(/^\s+/, "");
133
+ const nested = nestedLists.map((l) => renderList(l, depth + 1)).join("\n");
134
+ return prefix + mainText + (nested ? "\n" + nested : "");
135
+ }
136
+ function renderTable(node) {
137
+ const [headerRow, ...bodyRows] = node.children;
138
+ if (!headerRow) return "";
139
+ const allRows = [headerRow, ...bodyRows];
140
+ const widths = [];
141
+ for (const row of allRows) {
142
+ for (let i = 0; i < row.children.length; i++) {
143
+ const cell = row.children[i];
144
+ const w = cell ? visibleWidth(renderInlines(cell.children)) : 0;
145
+ widths[i] = Math.max(widths[i] ?? 0, w);
146
+ }
147
+ }
148
+ function renderRow(row, isHeader) {
149
+ const cells = row.children.map((cell, i) => {
150
+ const text = renderInlines(cell.children);
151
+ const pad = (widths[i] ?? 0) - visibleWidth(text);
152
+ const padded = text + " ".repeat(Math.max(0, pad));
153
+ return isHeader ? applyStyle(theme.bold, padded) : padded;
154
+ });
155
+ return "\u2502 " + cells.join(" \u2502 ") + " \u2502";
156
+ }
157
+ function separator(char) {
158
+ return "\u251C" + widths.map((w) => char.repeat((w ?? 0) + 2)).join("\u253C") + "\u2524";
159
+ }
160
+ const top = "\u250C" + widths.map((w) => "\u2500".repeat((w ?? 0) + 2)).join("\u252C") + "\u2510";
161
+ const bottom = "\u2514" + widths.map((w) => "\u2500".repeat((w ?? 0) + 2)).join("\u2534") + "\u2518";
162
+ const lines = [top, renderRow(headerRow, true), separator("\u2500")];
163
+ for (const row of bodyRows) {
164
+ lines.push(renderRow(row, false));
165
+ }
166
+ lines.push(bottom);
167
+ return lines.join("\n");
168
+ }
169
+ function renderHr(_node) {
170
+ return theme.hrChar.repeat(columns);
171
+ }
172
+ function renderInlines(nodes) {
173
+ return nodes.map(renderInline).join("");
174
+ }
175
+ function renderInline(node) {
176
+ switch (node.type) {
177
+ case "text":
178
+ return node.value;
179
+ case "inlineCode":
180
+ return applyStyle(theme.inlineCode, node.value);
181
+ case "strong":
182
+ return applyStyle(theme.bold, renderInlines(node.children));
183
+ case "emphasis":
184
+ return applyStyle(theme.italic, renderInlines(node.children));
185
+ case "delete":
186
+ return applyStyle(theme.strikethrough, renderInlines(node.children));
187
+ case "link": {
188
+ const l = node;
189
+ const label = renderInlines(l.children);
190
+ if (hyperlinks) {
191
+ const safeUrl = l.url.replace(/[\x00-\x1f\x7f]/g, "");
192
+ return `\x1B]8;;${safeUrl}\x07${applyStyle(theme.link, label)}\x1B]8;;\x07`;
193
+ }
194
+ return `${applyStyle(theme.link, label)} (${l.url})`;
195
+ }
196
+ case "image": {
197
+ const img = node;
198
+ return `[image: ${img.alt ?? img.url}]`;
199
+ }
200
+ case "break":
201
+ return "\n";
202
+ default:
203
+ return "";
204
+ }
205
+ }
206
+ return renderBlocks(ast.children);
207
+ }
208
+
209
+ // src/serializers/ansi/index.ts
210
+ var AnsiSerializer = {
211
+ serialize(ast, options) {
212
+ return renderToAnsi(ast, options);
213
+ }
214
+ };
215
+ function toAnsi(md, options) {
216
+ return serialize(md, AnsiSerializer, options);
217
+ }
218
+
219
+ export { AnsiSerializer, toAnsi };
220
+ //# sourceMappingURL=chunk-5CRCBG3P.js.map
221
+ //# sourceMappingURL=chunk-5CRCBG3P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/serializers/ansi/theme.ts","../src/serializers/ansi/renderer.ts","../src/serializers/ansi/index.ts"],"names":[],"mappings":"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","file":"chunk-5CRCBG3P.js","sourcesContent":["import type { AnsiTheme } from '../../types.js'\n\n// Raw ANSI escape helpers — no external dependency\nconst ESC = '\\x1b['\n\nfunction style(open: number | number[], close: number): { open: string; close: string } {\n const openCodes = Array.isArray(open) ? open : [open]\n return {\n open: `${ESC}${openCodes.join(';')}m`,\n close: `${ESC}${close}m`,\n }\n}\n\nexport const defaultTheme: AnsiTheme = {\n h1: style([1, 4, 35], 0), // bold + underline + magenta\n h2: style([1, 4, 36], 0), // bold + underline + cyan\n h3: style([1, 36], 0), // bold + cyan\n bold: style(1, 22),\n italic: style(3, 23),\n strikethrough: style(9, 29),\n inlineCode: style([7, 33], 0), // reverse + yellow\n codeBlock: style(90, 39), // dark grey\n blockquote: style(90, 39), // dark grey\n link: style([4, 34], 0), // underline + blue\n listBullet: '•',\n hrChar: '─',\n}\n","import type {\n Root, Content, PhrasingContent,\n Heading, Paragraph, Blockquote, Code, List, ListItem,\n Table, TableRow, ThematicBreak,\n Text, InlineCode, Strong, Emphasis, Delete, Link, Image, Break,\n} from 'mdast'\nimport type { AnsiOptions, AnsiStyle, AnsiTheme } from '../../types.js'\nimport { defaultTheme } from './theme.js'\n\n// ---------------------------------------------------------------------------\n// ANSI escape sequence width — strip sequences for width calc\n// ---------------------------------------------------------------------------\n\nconst ANSI_RE = /\\x1b\\[[^m]*m|\\x1b\\][^\\x07]*\\x07/g\n\nfunction visibleWidth(s: string): number {\n return s.replace(ANSI_RE, '').length\n}\n\n// ---------------------------------------------------------------------------\n// Word-wrap that respects invisible ANSI sequences\n// ---------------------------------------------------------------------------\n\nfunction wordWrap(text: string, columns: number, indent = ''): string {\n const indentWidth = visibleWidth(indent)\n const maxWidth = columns - indentWidth\n const words = text.split(/\\s+/).filter(Boolean)\n const lines: string[] = []\n let current = ''\n\n for (const word of words) {\n const candidate = current ? current + ' ' + word : word\n if (visibleWidth(candidate) > maxWidth && current) {\n lines.push(current)\n current = word\n } else {\n current = candidate\n }\n }\n if (current) lines.push(current)\n return lines.map((l) => indent + l).join('\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Renderer\n// ---------------------------------------------------------------------------\n\nexport function renderToAnsi(ast: Root, opts: AnsiOptions): string {\n const columns = opts.columns ?? (process.stdout.columns ?? 80)\n const hyperlinks = opts.hyperlinks ?? false\n const theme: AnsiTheme = { ...defaultTheme, ...(opts.theme ?? {}) }\n\n function applyStyle(s: AnsiStyle, text: string): string {\n return `${s.open}${text}${s.close}`\n }\n\n function renderBlocks(nodes: Content[]): string {\n return nodes.map((n) => renderBlock(n)).filter(Boolean).join('\\n\\n')\n }\n\n function renderBlock(node: Content | Root): string {\n switch (node.type) {\n case 'root':\n return renderBlocks((node as Root).children)\n case 'heading':\n return renderHeading(node as Heading)\n case 'paragraph':\n return renderParagraph(node as Paragraph)\n case 'blockquote':\n return renderBlockquote(node as Blockquote)\n case 'code':\n return renderCode(node as Code)\n case 'list':\n return renderList(node as List, 0)\n case 'table':\n return renderTable(node as Table)\n case 'thematicBreak':\n return renderHr(node as ThematicBreak)\n default:\n return ''\n }\n }\n\n function renderHeading(node: Heading): string {\n const text = renderInlines(node.children)\n const styleKey = (`h${node.depth}`) as keyof Pick<AnsiTheme, 'h1' | 'h2' | 'h3'>\n const s = (theme[styleKey] ?? theme.h3) as AnsiStyle\n return applyStyle(s, text)\n }\n\n function renderParagraph(node: Paragraph): string {\n const text = renderInlines(node.children)\n return wordWrap(text, columns)\n }\n\n function renderBlockquote(node: Blockquote): string {\n const inner = renderBlocks(node.children)\n const prefix = applyStyle(theme.blockquote, '│ ')\n return inner\n .split('\\n')\n .map((line) => prefix + line)\n .join('\\n')\n }\n\n function renderCode(node: Code): string {\n const lang = node.lang ? ` (${node.lang})` : ''\n const header = applyStyle(theme.codeBlock, `┌─ code${lang}`)\n const lines = node.value.split('\\n').map((l) => applyStyle(theme.codeBlock, `│ ${l}`))\n const footer = applyStyle(theme.codeBlock, '└─')\n return [header, ...lines, footer].join('\\n')\n }\n\n function renderList(node: List, depth: number): string {\n return node.children.map((li, i) => renderListItem(li, node, i + 1, depth)).join('\\n')\n }\n\n function renderListItem(node: ListItem, parent: List, index: number, depth: number): string {\n const indent = ' '.repeat(depth)\n const bullet = parent.ordered\n ? `${index}.`\n : applyStyle({ open: '', close: '' }, theme.listBullet)\n const prefix = `${indent}${bullet} `\n\n const nestedLists: List[] = []\n const textParts: string[] = []\n\n for (const child of node.children) {\n if (child.type === 'list') {\n nestedLists.push(child as List)\n } else if (child.type === 'paragraph') {\n textParts.push(renderInlines((child as Paragraph).children))\n }\n }\n\n const taskPrefix =\n node.checked !== null && node.checked !== undefined\n ? node.checked\n ? '[x] '\n : '[ ] '\n : ''\n\n const mainText = wordWrap(\n taskPrefix + textParts.join(' '),\n columns,\n ' '.repeat(visibleWidth(prefix)),\n ).replace(/^\\s+/, '')\n\n const nested = nestedLists.map((l) => renderList(l, depth + 1)).join('\\n')\n return prefix + mainText + (nested ? '\\n' + nested : '')\n }\n\n function renderTable(node: Table): string {\n const [headerRow, ...bodyRows] = node.children\n if (!headerRow) return ''\n\n const allRows: TableRow[] = [headerRow, ...bodyRows]\n // Compute column widths\n const widths: number[] = []\n for (const row of allRows) {\n for (let i = 0; i < row.children.length; i++) {\n const cell = row.children[i]\n const w = cell ? visibleWidth(renderInlines(cell.children as PhrasingContent[])) : 0\n widths[i] = Math.max(widths[i] ?? 0, w)\n }\n }\n\n function renderRow(row: TableRow, isHeader: boolean): string {\n const cells = row.children.map((cell, i) => {\n const text = renderInlines(cell.children as PhrasingContent[])\n const pad = (widths[i] ?? 0) - visibleWidth(text)\n const padded = text + ' '.repeat(Math.max(0, pad))\n return isHeader ? applyStyle(theme.bold, padded) : padded\n })\n return '│ ' + cells.join(' │ ') + ' │'\n }\n\n function separator(char: string): string {\n return '├' + widths.map((w) => char.repeat((w ?? 0) + 2)).join('┼') + '┤'\n }\n\n const top = '┌' + widths.map((w) => '─'.repeat((w ?? 0) + 2)).join('┬') + '┐'\n const bottom = '└' + widths.map((w) => '─'.repeat((w ?? 0) + 2)).join('┴') + '┘'\n const lines = [top, renderRow(headerRow, true), separator('─')]\n for (const row of bodyRows) {\n lines.push(renderRow(row, false))\n }\n lines.push(bottom)\n return lines.join('\\n')\n }\n\n function renderHr(_node: ThematicBreak): string {\n return theme.hrChar.repeat(columns)\n }\n\n function renderInlines(nodes: PhrasingContent[]): string {\n return nodes.map(renderInline).join('')\n }\n\n function renderInline(node: PhrasingContent): string {\n switch (node.type) {\n case 'text':\n return (node as Text).value\n case 'inlineCode':\n return applyStyle(theme.inlineCode, (node as InlineCode).value)\n case 'strong':\n return applyStyle(theme.bold, renderInlines((node as Strong).children))\n case 'emphasis':\n return applyStyle(theme.italic, renderInlines((node as Emphasis).children))\n case 'delete':\n return applyStyle(theme.strikethrough, renderInlines((node as Delete).children))\n case 'link': {\n const l = node as Link\n const label = renderInlines(l.children)\n if (hyperlinks) {\n // OSC 8 hyperlink — strip control chars to prevent sequence injection\n const safeUrl = l.url.replace(/[\\x00-\\x1f\\x7f]/g, '')\n return `\\x1b]8;;${safeUrl}\\x07${applyStyle(theme.link, label)}\\x1b]8;;\\x07`\n }\n return `${applyStyle(theme.link, label)} (${l.url})`\n }\n case 'image': {\n const img = node as Image\n return `[image: ${img.alt ?? img.url}]`\n }\n case 'break':\n return '\\n'\n default:\n return ''\n }\n }\n\n return renderBlocks(ast.children)\n}\n","import type { Root } from 'mdast'\nimport { serialize } from '../../serialize.js'\nimport type { AnsiOptions, Serializer } from '../../types.js'\nimport { renderToAnsi } from './renderer.js'\n\nexport const AnsiSerializer: Serializer<string, AnsiOptions> = {\n serialize(ast: Root, options: AnsiOptions): string {\n return renderToAnsi(ast, options)\n },\n}\n\nexport function toAnsi(md: string, options?: AnsiOptions): string {\n return serialize(md, AnsiSerializer, options)\n}\n\nexport type { AnsiOptions }\n"]}
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ var remarkGfm = require('remark-gfm');
4
+ var remarkParse = require('remark-parse');
5
+ var unified = require('unified');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
10
+ var remarkParse__default = /*#__PURE__*/_interopDefault(remarkParse);
11
+
12
+ // src/parser.ts
13
+ function parseMarkdown(md, opts = {}) {
14
+ const processor = unified.unified().use(remarkParse__default.default);
15
+ if (opts.gfm !== false) {
16
+ processor.use(remarkGfm__default.default);
17
+ }
18
+ if (opts.remarkPlugins) {
19
+ for (const plugin of opts.remarkPlugins) {
20
+ processor.use(plugin);
21
+ }
22
+ }
23
+ return processor.runSync(processor.parse(md));
24
+ }
25
+
26
+ // src/serialize.ts
27
+ function serialize(md, serializer, options) {
28
+ const opts = options ?? {};
29
+ const ast = parseMarkdown(md, opts);
30
+ return serializer.serialize(ast, opts);
31
+ }
32
+
33
+ exports.serialize = serialize;
34
+ //# sourceMappingURL=chunk-DJVBCM6N.cjs.map
35
+ //# sourceMappingURL=chunk-DJVBCM6N.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/parser.ts","../src/serialize.ts"],"names":["unified","remarkParse","remarkGfm"],"mappings":";;;;;;;;;;;;AAMO,SAAS,aAAA,CAAc,EAAA,EAAY,IAAA,GAAoB,EAAC,EAAS;AACtE,EAAA,MAAM,SAAA,GAAYA,eAAA,EAAQ,CAAE,GAAA,CAAIC,4BAAW,CAAA;AAE3C,EAAA,IAAI,IAAA,CAAK,QAAQ,KAAA,EAAO;AACtB,IAAA,SAAA,CAAU,IAAIC,0BAAS,CAAA;AAAA,EACzB;AAEA,EAAA,IAAI,KAAK,aAAA,EAAe;AACtB,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,aAAA,EAAe;AACvC,MAAA,SAAA,CAAU,IAAI,MAAM,CAAA;AAAA,IACtB;AAAA,EACF;AAGA,EAAA,OAAO,SAAA,CAAU,OAAA,CAAQ,SAAA,CAAU,KAAA,CAAM,EAAE,CAAC,CAAA;AAC9C;;;AClBO,SAAS,SAAA,CACd,EAAA,EACA,UAAA,EACA,OAAA,EACS;AACT,EAAA,MAAM,IAAA,GAAO,WAAY,EAAC;AAC1B,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,EAAA,EAAI,IAAI,CAAA;AAClC,EAAA,OAAO,UAAA,CAAW,SAAA,CAAU,GAAA,EAAK,IAAI,CAAA;AACvC","file":"chunk-DJVBCM6N.cjs","sourcesContent":["import remarkGfm from 'remark-gfm'\nimport remarkParse from 'remark-parse'\nimport { unified } from 'unified'\nimport type { Root } from 'mdast'\nimport type { BaseOptions } from './types.js'\n\nexport function parseMarkdown(md: string, opts: BaseOptions = {}): Root {\n const processor = unified().use(remarkParse)\n\n if (opts.gfm !== false) {\n processor.use(remarkGfm)\n }\n\n if (opts.remarkPlugins) {\n for (const plugin of opts.remarkPlugins) {\n processor.use(plugin)\n }\n }\n\n // parse() only tokenises; runSync() applies transformer plugins (e.g. user-supplied ones)\n return processor.runSync(processor.parse(md)) as Root\n}\n","import { parseMarkdown } from './parser.js'\nimport type { BaseOptions, Serializer } from './types.js'\n\nexport function serialize<TOutput, TOptions extends BaseOptions = BaseOptions>(\n md: string,\n serializer: Serializer<TOutput, TOptions>,\n options?: TOptions,\n): TOutput {\n const opts = options ?? ({} as TOptions)\n const ast = parseMarkdown(md, opts)\n return serializer.serialize(ast, opts)\n}\n"]}