@tanstack/markdown 0.0.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.
- package/README.md +36 -0
- package/dist/extensions/callouts.d.ts +4 -0
- package/dist/extensions/callouts.d.ts.map +1 -0
- package/dist/extensions/callouts.js +39 -0
- package/dist/extensions/comment-components.d.ts +14 -0
- package/dist/extensions/comment-components.d.ts.map +1 -0
- package/dist/extensions/comment-components.js +68 -0
- package/dist/extensions/docs.d.ts +8 -0
- package/dist/extensions/docs.d.ts.map +1 -0
- package/dist/extensions/docs.js +25 -0
- package/dist/extensions/framework.d.ts +3 -0
- package/dist/extensions/framework.d.ts.map +1 -0
- package/dist/extensions/framework.js +40 -0
- package/dist/extensions/headings.d.ts +7 -0
- package/dist/extensions/headings.d.ts.map +1 -0
- package/dist/extensions/headings.js +51 -0
- package/dist/extensions/shared.d.ts +12 -0
- package/dist/extensions/shared.d.ts.map +1 -0
- package/dist/extensions/shared.js +92 -0
- package/dist/extensions/tabs.d.ts +7 -0
- package/dist/extensions/tabs.d.ts.map +1 -0
- package/dist/extensions/tabs.js +145 -0
- package/dist/html.d.ts +6 -0
- package/dist/html.d.ts.map +1 -0
- package/dist/html.js +157 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/inline.d.ts +3 -0
- package/dist/inline.d.ts.map +1 -0
- package/dist/inline.js +227 -0
- package/dist/parser.d.ts +3 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +349 -0
- package/dist/react.d.ts +15 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +129 -0
- package/dist/types.d.ts +172 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +70 -0
- package/package.json +94 -0
package/dist/html.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { parseMarkdown } from './parser.js';
|
|
2
|
+
import { escapeAttr, escapeHtml } from './utils.js';
|
|
3
|
+
export function renderHtml(input, options = {}) {
|
|
4
|
+
const document = typeof input === 'string' ? parseMarkdown(input, options) : input;
|
|
5
|
+
return document.children.map(node => renderBlock(node, options)).join('\n');
|
|
6
|
+
}
|
|
7
|
+
export function renderBlock(node, options = {}) {
|
|
8
|
+
const extension = renderExtension(node, options);
|
|
9
|
+
if (extension !== undefined)
|
|
10
|
+
return extension;
|
|
11
|
+
switch (node.type) {
|
|
12
|
+
case 'heading': {
|
|
13
|
+
const id = node.id ? ` id="${escapeAttr(node.id)}"` : '';
|
|
14
|
+
const framework = node.framework ? ` data-framework="${escapeAttr(node.framework)}"` : '';
|
|
15
|
+
return `<h${node.depth}${id}${framework}>${renderInlines(node.children, options)}${renderHeadingAnchor(node.id, options)}</h${node.depth}>`;
|
|
16
|
+
}
|
|
17
|
+
case 'paragraph':
|
|
18
|
+
return `<p>${renderInlines(node.children, options)}</p>`;
|
|
19
|
+
case 'code':
|
|
20
|
+
return renderCodeBlock(node, options);
|
|
21
|
+
case 'list': {
|
|
22
|
+
const tag = node.ordered ? 'ol' : 'ul';
|
|
23
|
+
const start = node.ordered && node.start && node.start !== 1 ? ` start="${node.start}"` : '';
|
|
24
|
+
const items = node.items
|
|
25
|
+
.map(item => {
|
|
26
|
+
const task = item.checked === undefined
|
|
27
|
+
? ''
|
|
28
|
+
: `<input type="checkbox" disabled${item.checked ? ' checked' : ''}> `;
|
|
29
|
+
return `<li>${task}${item.children.map(child => renderBlock(child, options)).join('\n')}</li>`;
|
|
30
|
+
})
|
|
31
|
+
.join('\n');
|
|
32
|
+
return `<${tag}${start}>\n${items}\n</${tag}>`;
|
|
33
|
+
}
|
|
34
|
+
case 'blockquote':
|
|
35
|
+
return `<blockquote>\n${node.children.map(child => renderBlock(child, options)).join('\n')}\n</blockquote>`;
|
|
36
|
+
case 'table': {
|
|
37
|
+
const header = `<thead><tr>${node.header.map((cell, index) => renderTableCell('th', cell, node.align[index], options)).join('')}</tr></thead>`;
|
|
38
|
+
const body = `<tbody>${node.rows
|
|
39
|
+
.map(row => `<tr>${row.map((cell, index) => renderTableCell('td', cell, node.align[index], options)).join('')}</tr>`)
|
|
40
|
+
.join('')}</tbody>`;
|
|
41
|
+
return `<table>${header}${body}</table>`;
|
|
42
|
+
}
|
|
43
|
+
case 'thematicBreak':
|
|
44
|
+
return '<hr>';
|
|
45
|
+
case 'html':
|
|
46
|
+
return options.allowHtml ? node.value : escapeHtml(node.value);
|
|
47
|
+
case 'callout':
|
|
48
|
+
return renderCallout(node, options);
|
|
49
|
+
case 'component':
|
|
50
|
+
return renderComponent(node, options);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function renderInline(node, options = {}) {
|
|
54
|
+
const extension = renderExtension(node, options);
|
|
55
|
+
if (extension !== undefined)
|
|
56
|
+
return extension;
|
|
57
|
+
switch (node.type) {
|
|
58
|
+
case 'text':
|
|
59
|
+
return escapeHtml(node.value);
|
|
60
|
+
case 'inlineCode':
|
|
61
|
+
return `<code>${escapeHtml(node.value)}</code>`;
|
|
62
|
+
case 'strong':
|
|
63
|
+
return `<strong>${renderInlines(node.children, options)}</strong>`;
|
|
64
|
+
case 'emphasis':
|
|
65
|
+
return `<em>${renderInlines(node.children, options)}</em>`;
|
|
66
|
+
case 'strike':
|
|
67
|
+
return `<s>${renderInlines(node.children, options)}</s>`;
|
|
68
|
+
case 'link':
|
|
69
|
+
return `<a href="${escapeAttr(node.href)}"${node.title ? ` title="${escapeAttr(node.title)}"` : ''}>${renderInlines(node.children, options)}</a>`;
|
|
70
|
+
case 'image':
|
|
71
|
+
return `<img src="${escapeAttr(node.src)}" alt="${escapeAttr(node.alt)}"${node.title ? ` title="${escapeAttr(node.title)}"` : ''}>`;
|
|
72
|
+
case 'break':
|
|
73
|
+
return '<br>';
|
|
74
|
+
case 'inlineHtml':
|
|
75
|
+
return options.allowHtml ? node.value : escapeHtml(node.value);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function renderDocument(document, options = {}) {
|
|
79
|
+
return renderHtml(document, options);
|
|
80
|
+
}
|
|
81
|
+
function renderInlines(nodes, options) {
|
|
82
|
+
return nodes.map(node => renderInline(node, options)).join('');
|
|
83
|
+
}
|
|
84
|
+
function renderCodeBlock(node, options) {
|
|
85
|
+
const lang = node.lang ?? 'plaintext';
|
|
86
|
+
const codeAttrs = ` class="language-${escapeAttr(lang)}"`;
|
|
87
|
+
const preAttrs = [
|
|
88
|
+
'class="tm-code"',
|
|
89
|
+
`data-lang="${escapeAttr(lang)}"`,
|
|
90
|
+
node.title ? `data-code-title="${escapeAttr(node.title)}"` : '',
|
|
91
|
+
node.file ? `data-filename="${escapeAttr(node.file)}"` : '',
|
|
92
|
+
node.framework ? `data-framework="${escapeAttr(node.framework)}"` : '',
|
|
93
|
+
]
|
|
94
|
+
.filter(Boolean)
|
|
95
|
+
.join(' ');
|
|
96
|
+
const highlighter = options.highlighter;
|
|
97
|
+
const highlightOptions = {
|
|
98
|
+
...(node.highlightLines ? { highlightLines: node.highlightLines } : {}),
|
|
99
|
+
...(options.codeLineNumbers !== undefined ? { lineNumbers: options.codeLineNumbers } : {}),
|
|
100
|
+
};
|
|
101
|
+
const html = highlighter ? highlighter(node.value, lang, highlightOptions) : escapeHtml(node.value);
|
|
102
|
+
const pre = `<pre ${preAttrs}><code${codeAttrs}>${html}</code></pre>`;
|
|
103
|
+
if (!node.title)
|
|
104
|
+
return pre;
|
|
105
|
+
return `<figure class="tm-code-frame" data-lang="${escapeAttr(lang)}"><figcaption>${escapeHtml(node.title)}</figcaption>${pre}</figure>`;
|
|
106
|
+
}
|
|
107
|
+
function renderCallout(node, options) {
|
|
108
|
+
const kind = node.kind.toLowerCase();
|
|
109
|
+
const children = node.children.map(child => renderBlock(child, options)).join('\n');
|
|
110
|
+
return `<div class="markdown-alert markdown-alert-${escapeAttr(kind)}"><p class="markdown-alert-title">${escapeHtml(node.title)}</p><div class="markdown-alert-content">${children}</div></div>`;
|
|
111
|
+
}
|
|
112
|
+
function renderComponent(node, options) {
|
|
113
|
+
const tag = node.tagName ?? 'md-comment-component';
|
|
114
|
+
const attrs = renderComponentAttrs(node);
|
|
115
|
+
const children = node.children.map(child => renderBlock(child, options)).join('\n');
|
|
116
|
+
return `<${tag}${attrs}>${children}</${tag}>`;
|
|
117
|
+
}
|
|
118
|
+
function renderTableCell(tag, cell, align, options) {
|
|
119
|
+
const style = align ? ` style="text-align:${align}"` : '';
|
|
120
|
+
return `<${tag}${style}>${renderInlines(cell.children, options)}</${tag}>`;
|
|
121
|
+
}
|
|
122
|
+
function renderExtension(node, options) {
|
|
123
|
+
for (const extension of options.extensions ?? []) {
|
|
124
|
+
const rendered = extension.renderHtml?.(node, {
|
|
125
|
+
options,
|
|
126
|
+
renderBlock: block => renderBlock(block, options),
|
|
127
|
+
renderInline: inline => renderInline(inline, options),
|
|
128
|
+
});
|
|
129
|
+
if (rendered !== undefined)
|
|
130
|
+
return rendered;
|
|
131
|
+
}
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
function renderHeadingAnchor(id, options) {
|
|
135
|
+
if (!id || !options.headingAnchors)
|
|
136
|
+
return '';
|
|
137
|
+
const anchorOptions = typeof options.headingAnchors === 'object' ? options.headingAnchors : {};
|
|
138
|
+
const content = anchorOptions.content ?? '#';
|
|
139
|
+
const className = anchorOptions.className ?? 'anchor-heading anchor-heading-link';
|
|
140
|
+
const ariaHidden = anchorOptions.ariaHidden ?? true;
|
|
141
|
+
const tabIndex = anchorOptions.tabIndex ?? -1;
|
|
142
|
+
return `<a href="#${escapeAttr(id)}" aria-hidden="${ariaHidden}" class="${escapeAttr(className)}" tabindex="${tabIndex}">${escapeHtml(content)}</a>`;
|
|
143
|
+
}
|
|
144
|
+
function renderComponentAttrs(node) {
|
|
145
|
+
const props = {
|
|
146
|
+
...node.properties,
|
|
147
|
+
};
|
|
148
|
+
if (!node.tagName) {
|
|
149
|
+
props['data-component'] = node.name;
|
|
150
|
+
if (!props['data-attributes'])
|
|
151
|
+
props['data-attributes'] = JSON.stringify(node.attributes);
|
|
152
|
+
}
|
|
153
|
+
const entries = Object.entries(props);
|
|
154
|
+
if (!entries.length)
|
|
155
|
+
return '';
|
|
156
|
+
return ` ${entries.map(([key, value]) => `${key}="${escapeAttr(value)}"`).join(' ')}`;
|
|
157
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,mBAAmB,YAAY,CAAA"}
|
package/dist/index.js
ADDED
package/dist/inline.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG1D,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,UAAU,EAAE,CASnF"}
|
package/dist/inline.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { sanitizeUrl } from './utils.js';
|
|
2
|
+
export function parseInline(value, options = {}) {
|
|
3
|
+
const nodes = parseInlineRaw(value, options);
|
|
4
|
+
let result = mergeText(nodes);
|
|
5
|
+
for (const extension of options.extensions ?? []) {
|
|
6
|
+
result = extension.transformInline?.(result, { options }) ?? result;
|
|
7
|
+
}
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
function parseInlineRaw(value, options) {
|
|
11
|
+
const nodes = [];
|
|
12
|
+
let index = 0;
|
|
13
|
+
let text = '';
|
|
14
|
+
const pushText = () => {
|
|
15
|
+
if (text) {
|
|
16
|
+
nodes.push({ type: 'text', value: text });
|
|
17
|
+
text = '';
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
while (index < value.length) {
|
|
21
|
+
const char = value[index];
|
|
22
|
+
const next = value[index + 1];
|
|
23
|
+
if (char === '\\') {
|
|
24
|
+
if (next === '\n') {
|
|
25
|
+
pushText();
|
|
26
|
+
nodes.push({ type: 'break' });
|
|
27
|
+
index += 2;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (next && /[\\`*_[\]{}()#+\-.!|~>]/.test(next)) {
|
|
31
|
+
text += next;
|
|
32
|
+
index += 2;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (char === '`') {
|
|
37
|
+
const tickCount = countRun(value, index, '`');
|
|
38
|
+
const close = findClosingRun(value, index + tickCount, '`', tickCount);
|
|
39
|
+
if (close !== -1) {
|
|
40
|
+
pushText();
|
|
41
|
+
nodes.push({
|
|
42
|
+
type: 'inlineCode',
|
|
43
|
+
value: value.slice(index + tickCount, close).replace(/\s+/g, ' ').trim(),
|
|
44
|
+
});
|
|
45
|
+
index = close + tickCount;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (char === '!' && next === '[') {
|
|
50
|
+
const parsed = parseLinkish(value, index + 1, options);
|
|
51
|
+
if (parsed) {
|
|
52
|
+
pushText();
|
|
53
|
+
nodes.push({
|
|
54
|
+
type: 'image',
|
|
55
|
+
src: sanitizeUrl(parsed.href),
|
|
56
|
+
alt: textFromMarkdown(parsed.label),
|
|
57
|
+
...(parsed.title ? { title: parsed.title } : {}),
|
|
58
|
+
});
|
|
59
|
+
index = parsed.end;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (char === '[') {
|
|
64
|
+
const parsed = parseLinkish(value, index, options);
|
|
65
|
+
if (parsed) {
|
|
66
|
+
const href = sanitizeUrl(parsed.href);
|
|
67
|
+
pushText();
|
|
68
|
+
if (href) {
|
|
69
|
+
nodes.push({
|
|
70
|
+
type: 'link',
|
|
71
|
+
href,
|
|
72
|
+
...(parsed.title ? { title: parsed.title } : {}),
|
|
73
|
+
children: parseInlineRaw(parsed.label, options),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
nodes.push(...parseInlineRaw(parsed.label, options));
|
|
78
|
+
}
|
|
79
|
+
index = parsed.end;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if ((char === '*' && next === '*') || (char === '_' && next === '_')) {
|
|
84
|
+
const close = findDelimiter(value, index + 2, char + char);
|
|
85
|
+
if (close !== -1) {
|
|
86
|
+
pushText();
|
|
87
|
+
nodes.push({
|
|
88
|
+
type: 'strong',
|
|
89
|
+
children: parseInlineRaw(value.slice(index + 2, close), options),
|
|
90
|
+
});
|
|
91
|
+
index = close + 2;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
text += char + next;
|
|
95
|
+
index += 2;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (char === '~' && next === '~') {
|
|
99
|
+
const close = findDelimiter(value, index + 2, '~~');
|
|
100
|
+
if (close !== -1) {
|
|
101
|
+
pushText();
|
|
102
|
+
nodes.push({
|
|
103
|
+
type: 'strike',
|
|
104
|
+
children: parseInlineRaw(value.slice(index + 2, close), options),
|
|
105
|
+
});
|
|
106
|
+
index = close + 2;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
text += '~~';
|
|
110
|
+
index += 2;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (char === '*' || char === '_') {
|
|
114
|
+
const close = findDelimiter(value, index + 1, char);
|
|
115
|
+
if (close !== -1 && !isIntrawordUnderscore(value, index, close, char)) {
|
|
116
|
+
pushText();
|
|
117
|
+
nodes.push({
|
|
118
|
+
type: 'emphasis',
|
|
119
|
+
children: parseInlineRaw(value.slice(index + 1, close), options),
|
|
120
|
+
});
|
|
121
|
+
index = close + 1;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (char === '<' && options.allowHtml) {
|
|
126
|
+
const close = value.indexOf('>', index + 1);
|
|
127
|
+
if (close !== -1) {
|
|
128
|
+
pushText();
|
|
129
|
+
nodes.push({ type: 'inlineHtml', value: value.slice(index, close + 1) });
|
|
130
|
+
index = close + 1;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
text += char;
|
|
135
|
+
index++;
|
|
136
|
+
}
|
|
137
|
+
pushText();
|
|
138
|
+
return nodes;
|
|
139
|
+
}
|
|
140
|
+
function parseLinkish(value, open, options) {
|
|
141
|
+
const closeBracket = findBalanced(value, open, '[', ']');
|
|
142
|
+
if (closeBracket === -1 || value[closeBracket + 1] !== '(')
|
|
143
|
+
return undefined;
|
|
144
|
+
const closeParen = findBalanced(value, closeBracket + 1, '(', ')');
|
|
145
|
+
if (closeParen === -1)
|
|
146
|
+
return undefined;
|
|
147
|
+
const label = value.slice(open + 1, closeBracket);
|
|
148
|
+
const destination = value.slice(closeBracket + 2, closeParen).trim();
|
|
149
|
+
const parsed = parseDestination(destination);
|
|
150
|
+
if (!parsed.href)
|
|
151
|
+
return undefined;
|
|
152
|
+
return {
|
|
153
|
+
label,
|
|
154
|
+
href: parsed.href,
|
|
155
|
+
...(parsed.title ? { title: parsed.title } : {}),
|
|
156
|
+
end: closeParen + 1,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function parseDestination(value) {
|
|
160
|
+
const match = value.match(/^(\S+)(?:\s+["']([^"']*)["'])?$/);
|
|
161
|
+
if (!match)
|
|
162
|
+
return { href: value };
|
|
163
|
+
return {
|
|
164
|
+
href: match[1].replace(/^<|>$/g, ''),
|
|
165
|
+
...(match[2] ? { title: match[2] } : {}),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function findBalanced(value, openIndex, open, close) {
|
|
169
|
+
let depth = 0;
|
|
170
|
+
for (let index = openIndex; index < value.length; index++) {
|
|
171
|
+
if (value[index - 1] === '\\')
|
|
172
|
+
continue;
|
|
173
|
+
if (value[index] === open)
|
|
174
|
+
depth++;
|
|
175
|
+
if (value[index] === close) {
|
|
176
|
+
depth--;
|
|
177
|
+
if (depth === 0)
|
|
178
|
+
return index;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return -1;
|
|
182
|
+
}
|
|
183
|
+
function countRun(value, index, char) {
|
|
184
|
+
let count = 0;
|
|
185
|
+
while (value[index + count] === char)
|
|
186
|
+
count++;
|
|
187
|
+
return count;
|
|
188
|
+
}
|
|
189
|
+
function findClosingRun(value, start, char, count) {
|
|
190
|
+
for (let index = start; index < value.length; index++) {
|
|
191
|
+
if (value[index] !== char)
|
|
192
|
+
continue;
|
|
193
|
+
if (countRun(value, index, char) >= count)
|
|
194
|
+
return index;
|
|
195
|
+
}
|
|
196
|
+
return -1;
|
|
197
|
+
}
|
|
198
|
+
function findDelimiter(value, start, delimiter) {
|
|
199
|
+
for (let index = start; index < value.length; index++) {
|
|
200
|
+
if (value[index - 1] === '\\')
|
|
201
|
+
continue;
|
|
202
|
+
if (value.startsWith(delimiter, index))
|
|
203
|
+
return index;
|
|
204
|
+
}
|
|
205
|
+
return -1;
|
|
206
|
+
}
|
|
207
|
+
function isIntrawordUnderscore(value, open, close, delimiter) {
|
|
208
|
+
if (delimiter !== '_')
|
|
209
|
+
return false;
|
|
210
|
+
return /\w/.test(value[open - 1] ?? '') && /\w/.test(value[close + 1] ?? '');
|
|
211
|
+
}
|
|
212
|
+
function textFromMarkdown(value) {
|
|
213
|
+
return parseInlineRaw(value, {}).map(node => (node.type === 'text' || node.type === 'inlineCode' ? node.value : '')).join('');
|
|
214
|
+
}
|
|
215
|
+
function mergeText(nodes) {
|
|
216
|
+
const result = [];
|
|
217
|
+
for (const node of nodes) {
|
|
218
|
+
const previous = result.at(-1);
|
|
219
|
+
if (previous?.type === 'text' && node.type === 'text') {
|
|
220
|
+
previous.value += node.value;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
result.push(node);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAOV,gBAAgB,EAChB,YAAY,EAGb,MAAM,YAAY,CAAA;AAKnB,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,gBAAgB,CAuB5F"}
|