@valkyrianlabs/payload-markdown 1.3.4 → 1.4.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.
- package/README.md +63 -14
- package/dist/components/MarkdownRenderer/index.css +150 -0
- package/dist/components/MarkdownRenderer/index.scss +158 -0
- package/dist/core/plugins/rehypeResolveIcons.d.ts +4 -0
- package/dist/core/plugins/rehypeResolveIcons.js +27 -0
- package/dist/core/plugins/rehypeResolveIcons.js.map +1 -0
- package/dist/core/plugins/remarkButtonDirectives.d.ts +4 -0
- package/dist/core/plugins/remarkButtonDirectives.js +237 -0
- package/dist/core/plugins/remarkButtonDirectives.js.map +1 -0
- package/dist/core/plugins/remarkCompileLayouts.js +6 -5
- package/dist/core/plugins/remarkCompileLayouts.js.map +1 -1
- package/dist/core/plugins/remarkLayoutDirectives.js +17 -7
- package/dist/core/plugins/remarkLayoutDirectives.js.map +1 -1
- package/dist/core/plugins/remarkLiftLayoutDirectives.js +42 -4
- package/dist/core/plugins/remarkLiftLayoutDirectives.js.map +1 -1
- package/dist/core/renderMarkdown.js +27 -2
- package/dist/core/renderMarkdown.js.map +1 -1
- package/dist/directives/attributeDiagnostics.d.ts +2 -0
- package/dist/directives/attributeDiagnostics.js +35 -0
- package/dist/directives/attributeDiagnostics.js.map +1 -0
- package/dist/directives/attributes.d.ts +8 -0
- package/dist/directives/attributes.js +56 -5
- package/dist/directives/attributes.js.map +1 -1
- package/dist/directives/buttonSyntax.d.ts +7 -0
- package/dist/directives/buttonSyntax.js +26 -0
- package/dist/directives/buttonSyntax.js.map +1 -0
- package/dist/directives/closeLabels.d.ts +8 -0
- package/dist/directives/closeLabels.js +76 -0
- package/dist/directives/closeLabels.js.map +1 -0
- package/dist/directives/definitions/button.d.ts +15 -0
- package/dist/directives/definitions/button.js +96 -0
- package/dist/directives/definitions/button.js.map +1 -0
- package/dist/directives/definitions/buttons.d.ts +8 -0
- package/dist/directives/definitions/buttons.js +82 -0
- package/dist/directives/definitions/buttons.js.map +1 -0
- package/dist/directives/definitions/callout.js +20 -9
- package/dist/directives/definitions/callout.js.map +1 -1
- package/dist/directives/definitions/card.d.ts +4 -0
- package/dist/directives/definitions/card.js +90 -9
- package/dist/directives/definitions/card.js.map +1 -1
- package/dist/directives/definitions/cards.d.ts +4 -0
- package/dist/directives/definitions/cards.js +119 -4
- package/dist/directives/definitions/cards.js.map +1 -1
- package/dist/directives/definitions/details.js +4 -3
- package/dist/directives/definitions/details.js.map +1 -1
- package/dist/directives/definitions/tab.d.ts +1 -0
- package/dist/directives/definitions/tab.js +10 -3
- package/dist/directives/definitions/tab.js.map +1 -1
- package/dist/directives/definitions/tabs.js +3 -3
- package/dist/directives/definitions/tabs.js.map +1 -1
- package/dist/directives/definitions/toc.js +4 -3
- package/dist/directives/definitions/toc.js.map +1 -1
- package/dist/directives/diagnostics.js +97 -7
- package/dist/directives/diagnostics.js.map +1 -1
- package/dist/directives/iconPlaceholder.d.ts +12 -0
- package/dist/directives/iconPlaceholder.js +19 -0
- package/dist/directives/iconPlaceholder.js.map +1 -0
- package/dist/directives/labels.d.ts +3 -0
- package/dist/directives/labels.js +12 -0
- package/dist/directives/labels.js.map +1 -0
- package/dist/directives/registry.d.ts +1 -1
- package/dist/directives/registry.js +46 -6
- package/dist/directives/registry.js.map +1 -1
- package/dist/directives/renderData.d.ts +2 -2
- package/dist/directives/renderData.js.map +1 -1
- package/dist/directives/types.d.ts +6 -4
- package/dist/directives/types.js.map +1 -1
- package/dist/editor/MarkdownCodeMirror/Component.client.js +2 -0
- package/dist/editor/MarkdownCodeMirror/Component.client.js.map +1 -1
- package/dist/editor/directives/closeLabels.d.ts +2 -0
- package/dist/editor/directives/closeLabels.js +75 -0
- package/dist/editor/directives/closeLabels.js.map +1 -0
- package/dist/editor/directives/completions.js +49 -7
- package/dist/editor/directives/completions.js.map +1 -1
- package/dist/editor/themes/payload.js +197 -9
- package/dist/editor/themes/payload.js.map +1 -1
- package/dist/exports/advanced.d.ts +1 -0
- package/dist/exports/advanced.js +1 -0
- package/dist/exports/advanced.js.map +1 -1
- package/dist/icons/generateRegistry.d.ts +8 -0
- package/dist/icons/generateRegistry.js +36 -0
- package/dist/icons/generateRegistry.js.map +1 -0
- package/dist/icons/refs.d.ts +10 -0
- package/dist/icons/refs.js +42 -0
- package/dist/icons/refs.js.map +1 -0
- package/dist/icons/resolve.d.ts +9 -0
- package/dist/icons/resolve.js +95 -0
- package/dist/icons/resolve.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +8 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/types/core.d.ts +9 -0
- package/dist/types/core.js.map +1 -1
- package/dist/types/mdast.d.js.map +1 -1
- package/dist/types.d.ts +5 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { hasUnclosedDirectiveAttributeBlock } from '../../directives/attributes.js';
|
|
2
|
+
import { parseButtonDirectiveLine } from '../../directives/buttonSyntax.js';
|
|
3
|
+
import { DEFAULT_BUTTON_ICON_POSITION, DEFAULT_BUTTON_SIZE, DEFAULT_BUTTON_VARIANT, isButtonIconPosition, isButtonSize, isButtonVariant } from '../../directives/definitions/button.js';
|
|
4
|
+
import { layoutDirectiveRegistry } from '../../directives/registry.js';
|
|
5
|
+
import { normalizePayloadMarkdownIconRef } from '../../icons/refs.js';
|
|
6
|
+
function isParagraph(node) {
|
|
7
|
+
return node.type === 'paragraph';
|
|
8
|
+
}
|
|
9
|
+
function isText(node) {
|
|
10
|
+
return node.type === 'text';
|
|
11
|
+
}
|
|
12
|
+
function makeText(value) {
|
|
13
|
+
return {
|
|
14
|
+
type: 'text',
|
|
15
|
+
value
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function splitParagraphLines(node) {
|
|
19
|
+
const lines = [
|
|
20
|
+
[]
|
|
21
|
+
];
|
|
22
|
+
const currentLine = ()=>lines[lines.length - 1];
|
|
23
|
+
for (const child of node.children){
|
|
24
|
+
if (!isText(child)) {
|
|
25
|
+
currentLine().push(child);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const parts = child.value.split(/\r?\n/);
|
|
29
|
+
for(let index = 0; index < parts.length; ++index){
|
|
30
|
+
if (index > 0) lines.push([]);
|
|
31
|
+
if (parts[index]) currentLine().push(makeText(parts[index]));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return lines;
|
|
35
|
+
}
|
|
36
|
+
function collectExpandedDirectiveText(lines, startIndex) {
|
|
37
|
+
const firstText = getTextOnlyLine(lines[startIndex]);
|
|
38
|
+
if (!firstText) return null;
|
|
39
|
+
if (!hasUnclosedDirectiveAttributeBlock(firstText)) return {
|
|
40
|
+
endIndex: startIndex,
|
|
41
|
+
text: firstText
|
|
42
|
+
};
|
|
43
|
+
let text = firstText;
|
|
44
|
+
for(let index = startIndex + 1; index < lines.length; ++index){
|
|
45
|
+
const nextText = getTextOnlyLine(lines[index]);
|
|
46
|
+
if (nextText === null) break;
|
|
47
|
+
if (nextText.trim().startsWith('::')) break;
|
|
48
|
+
text += `\n${nextText}`;
|
|
49
|
+
if (!hasUnclosedDirectiveAttributeBlock(text)) return {
|
|
50
|
+
endIndex: index,
|
|
51
|
+
text
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
endIndex: startIndex,
|
|
56
|
+
text: firstText
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function phrasingToText(node) {
|
|
60
|
+
if (node.type === 'text') return node.value;
|
|
61
|
+
if (node.type === 'inlineCode') return node.value;
|
|
62
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
63
|
+
const values = node.children.map((child)=>phrasingToText(child));
|
|
64
|
+
return values.every((value)=>typeof value === 'string') ? values.join('') : null;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
function getTextOnlyLine(children) {
|
|
69
|
+
const values = children.map((child)=>phrasingToText(child));
|
|
70
|
+
if (!values.every((value)=>typeof value === 'string')) return null;
|
|
71
|
+
return values.join('');
|
|
72
|
+
}
|
|
73
|
+
function appendParagraphLine(lines, children) {
|
|
74
|
+
if (lines.length > 0) lines.push([
|
|
75
|
+
makeText('\n'),
|
|
76
|
+
...children
|
|
77
|
+
]);
|
|
78
|
+
else lines.push(children);
|
|
79
|
+
}
|
|
80
|
+
function flattenParagraphLines(lines) {
|
|
81
|
+
return lines.flat();
|
|
82
|
+
}
|
|
83
|
+
function getAttribute(attributes, name) {
|
|
84
|
+
const value = attributes[name];
|
|
85
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
86
|
+
}
|
|
87
|
+
function getBooleanAttribute(attributes, name) {
|
|
88
|
+
const value = attributes[name];
|
|
89
|
+
if (value === true) return true;
|
|
90
|
+
if (typeof value !== 'string') return false;
|
|
91
|
+
return value === 'true';
|
|
92
|
+
}
|
|
93
|
+
function getLeafDirectiveName(text) {
|
|
94
|
+
const trimmed = text.trim();
|
|
95
|
+
if (trimmed.startsWith(':::')) return undefined;
|
|
96
|
+
const match = trimmed.match(/^::([\w-]+)(?:$|[\s[{])/);
|
|
97
|
+
return match?.[1];
|
|
98
|
+
}
|
|
99
|
+
function makeIconPlaceholder(icon, iconPosition) {
|
|
100
|
+
const normalized = normalizePayloadMarkdownIconRef(icon);
|
|
101
|
+
const iconKey = normalized.icon?.key ?? icon;
|
|
102
|
+
return {
|
|
103
|
+
type: 'element',
|
|
104
|
+
children: [],
|
|
105
|
+
properties: {
|
|
106
|
+
ariaHidden: 'true',
|
|
107
|
+
className: [
|
|
108
|
+
'pmd-button__icon',
|
|
109
|
+
`pmd-button__icon--${iconPosition}`
|
|
110
|
+
],
|
|
111
|
+
dataPmdIcon: iconKey,
|
|
112
|
+
dataPmdIconRef: icon,
|
|
113
|
+
focusable: 'false'
|
|
114
|
+
},
|
|
115
|
+
tagName: 'span'
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function makeButtonDirective(line, file, _config) {
|
|
119
|
+
const parsed = parseButtonDirectiveLine(line);
|
|
120
|
+
if (!parsed) return undefined;
|
|
121
|
+
const definition = layoutDirectiveRegistry.get('button');
|
|
122
|
+
const attributes = parsed.attributes;
|
|
123
|
+
const label = parsed.label.trim();
|
|
124
|
+
const href = getAttribute(attributes, 'href');
|
|
125
|
+
const variant = isButtonVariant(attributes.variant) ? attributes.variant : DEFAULT_BUTTON_VARIANT;
|
|
126
|
+
const size = isButtonSize(attributes.size) ? attributes.size : DEFAULT_BUTTON_SIZE;
|
|
127
|
+
const iconPosition = isButtonIconPosition(attributes.iconPosition) ? attributes.iconPosition : DEFAULT_BUTTON_ICON_POSITION;
|
|
128
|
+
const icon = getAttribute(attributes, 'icon');
|
|
129
|
+
const ariaLabel = getAttribute(attributes, 'ariaLabel');
|
|
130
|
+
const newTab = getBooleanAttribute(attributes, 'newTab');
|
|
131
|
+
for (const warning of parsed.warnings)file.message(warning);
|
|
132
|
+
for (const warning of definition?.validateAttributes?.({
|
|
133
|
+
name: 'button',
|
|
134
|
+
attributes
|
|
135
|
+
}) ?? [])file.message(warning);
|
|
136
|
+
if (icon) {
|
|
137
|
+
const normalized = normalizePayloadMarkdownIconRef(icon);
|
|
138
|
+
if (normalized.warning) file.message(normalized.warning);
|
|
139
|
+
}
|
|
140
|
+
if (!label && !ariaLabel) file.message('Icon-only button requires an ariaLabel attribute.');
|
|
141
|
+
const hChildren = [
|
|
142
|
+
...icon && iconPosition === 'left' ? [
|
|
143
|
+
makeIconPlaceholder(icon, iconPosition)
|
|
144
|
+
] : [],
|
|
145
|
+
...label ? [
|
|
146
|
+
{
|
|
147
|
+
type: 'text',
|
|
148
|
+
value: label
|
|
149
|
+
}
|
|
150
|
+
] : [],
|
|
151
|
+
...icon && iconPosition === 'right' ? [
|
|
152
|
+
makeIconPlaceholder(icon, iconPosition)
|
|
153
|
+
] : []
|
|
154
|
+
];
|
|
155
|
+
return {
|
|
156
|
+
name: 'button',
|
|
157
|
+
type: 'leafDirective',
|
|
158
|
+
attributes: Object.fromEntries(Object.entries(attributes).map(([key, value])=>[
|
|
159
|
+
key,
|
|
160
|
+
String(value)
|
|
161
|
+
])),
|
|
162
|
+
children: label ? [
|
|
163
|
+
{
|
|
164
|
+
type: 'text',
|
|
165
|
+
value: label
|
|
166
|
+
}
|
|
167
|
+
] : [],
|
|
168
|
+
data: {
|
|
169
|
+
hChildren,
|
|
170
|
+
hName: 'a',
|
|
171
|
+
hProperties: {
|
|
172
|
+
...ariaLabel ? {
|
|
173
|
+
ariaLabel
|
|
174
|
+
} : {},
|
|
175
|
+
className: [
|
|
176
|
+
'pmd-button',
|
|
177
|
+
`pmd-button--${variant}`,
|
|
178
|
+
`pmd-button--${size}`
|
|
179
|
+
],
|
|
180
|
+
dataButton: '',
|
|
181
|
+
dataDirective: 'button',
|
|
182
|
+
dataIconPosition: icon ? iconPosition : undefined,
|
|
183
|
+
dataSize: size,
|
|
184
|
+
dataVariant: variant,
|
|
185
|
+
href,
|
|
186
|
+
...newTab ? {
|
|
187
|
+
rel: 'noopener noreferrer',
|
|
188
|
+
target: '_blank'
|
|
189
|
+
} : {}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function splitParagraphButtonDirectives(node, file, config) {
|
|
195
|
+
const out = [];
|
|
196
|
+
let paragraphLines = [];
|
|
197
|
+
const flushParagraph = ()=>{
|
|
198
|
+
const children = flattenParagraphLines(paragraphLines);
|
|
199
|
+
if (children.length > 0) out.push({
|
|
200
|
+
type: 'paragraph',
|
|
201
|
+
children
|
|
202
|
+
});
|
|
203
|
+
paragraphLines = [];
|
|
204
|
+
};
|
|
205
|
+
const lines = splitParagraphLines(node);
|
|
206
|
+
for(let index = 0; index < lines.length; ++index){
|
|
207
|
+
const lineChildren = lines[index];
|
|
208
|
+
const text = getTextOnlyLine(lineChildren);
|
|
209
|
+
const expanded = text ? collectExpandedDirectiveText(lines, index) : null;
|
|
210
|
+
const button = expanded ? makeButtonDirective(expanded.text, file, config) : undefined;
|
|
211
|
+
if (!button) {
|
|
212
|
+
const leafName = text ? getLeafDirectiveName(text) : undefined;
|
|
213
|
+
if (leafName && leafName !== 'button') file.message(`Unknown directive "${leafName}".`);
|
|
214
|
+
appendParagraphLine(paragraphLines, lineChildren);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
flushParagraph();
|
|
218
|
+
out.push(button);
|
|
219
|
+
index = expanded?.endIndex ?? index;
|
|
220
|
+
}
|
|
221
|
+
flushParagraph();
|
|
222
|
+
return out.length > 0 ? out : [
|
|
223
|
+
node
|
|
224
|
+
];
|
|
225
|
+
}
|
|
226
|
+
export const remarkButtonDirectives = (config = {})=>{
|
|
227
|
+
return (tree, file)=>{
|
|
228
|
+
tree.children = tree.children.flatMap((node)=>{
|
|
229
|
+
if (!isParagraph(node)) return [
|
|
230
|
+
node
|
|
231
|
+
];
|
|
232
|
+
return splitParagraphButtonDirectives(node, file, config);
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
//# sourceMappingURL=remarkButtonDirectives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/plugins/remarkButtonDirectives.ts"],"sourcesContent":["import type { Paragraph, PhrasingContent, Root, RootContent, Text } from 'mdast'\nimport type { LeafDirective } from 'mdast-util-directive'\nimport type { Plugin } from 'unified'\n\nimport type { MarkdownRenderConfig } from '../../types/core.js'\n\nimport { hasUnclosedDirectiveAttributeBlock } from '../../directives/attributes.js'\nimport { parseButtonDirectiveLine } from '../../directives/buttonSyntax.js'\nimport {\n DEFAULT_BUTTON_ICON_POSITION,\n DEFAULT_BUTTON_SIZE,\n DEFAULT_BUTTON_VARIANT,\n isButtonIconPosition,\n isButtonSize,\n isButtonVariant,\n} from '../../directives/definitions/button.js'\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\nimport { normalizePayloadMarkdownIconRef } from '../../icons/refs.js'\n\ntype MessageFile = {\n message: (reason: string) => unknown\n}\n\nfunction isParagraph(node: RootContent): node is Paragraph {\n return node.type === 'paragraph'\n}\n\nfunction isText(node: Paragraph['children'][number]): node is Text {\n return node.type === 'text'\n}\n\nfunction makeText(value: string): Text {\n return {\n type: 'text',\n value,\n }\n}\n\nfunction splitParagraphLines(node: Paragraph): PhrasingContent[][] {\n const lines: PhrasingContent[][] = [[]]\n const currentLine = () => lines[lines.length - 1]\n\n for (const child of node.children) {\n if (!isText(child)) {\n currentLine().push(child)\n continue\n }\n\n const parts = child.value.split(/\\r?\\n/)\n\n for (let index = 0; index < parts.length; ++index) {\n if (index > 0) lines.push([])\n if (parts[index]) currentLine().push(makeText(parts[index]))\n }\n }\n\n return lines\n}\n\nfunction collectExpandedDirectiveText(\n lines: PhrasingContent[][],\n startIndex: number,\n): { endIndex: number; text: string } | null {\n const firstText = getTextOnlyLine(lines[startIndex])\n\n if (!firstText) return null\n if (!hasUnclosedDirectiveAttributeBlock(firstText))\n return {\n endIndex: startIndex,\n text: firstText,\n }\n\n let text = firstText\n\n for (let index = startIndex + 1; index < lines.length; ++index) {\n const nextText = getTextOnlyLine(lines[index])\n\n if (nextText === null) break\n if (nextText.trim().startsWith('::')) break\n\n text += `\\n${nextText}`\n\n if (!hasUnclosedDirectiveAttributeBlock(text))\n return {\n endIndex: index,\n text,\n }\n }\n\n return {\n endIndex: startIndex,\n text: firstText,\n }\n}\n\nfunction phrasingToText(node: PhrasingContent): null | string {\n if (node.type === 'text') return node.value\n if (node.type === 'inlineCode') return node.value\n if ('children' in node && Array.isArray(node.children)) {\n const values = node.children.map((child) => phrasingToText(child))\n\n return values.every((value): value is string => typeof value === 'string')\n ? values.join('')\n : null\n }\n\n return null\n}\n\nfunction getTextOnlyLine(children: PhrasingContent[]): null | string {\n const values = children.map((child) => phrasingToText(child))\n\n if (!values.every((value): value is string => typeof value === 'string')) return null\n\n return values.join('')\n}\n\nfunction appendParagraphLine(lines: PhrasingContent[][], children: PhrasingContent[]) {\n if (lines.length > 0) lines.push([makeText('\\n'), ...children])\n else lines.push(children)\n}\n\nfunction flattenParagraphLines(lines: PhrasingContent[][]): PhrasingContent[] {\n return lines.flat()\n}\n\nfunction getAttribute(attributes: Record<string, boolean | string>, name: string): string | undefined {\n const value = attributes[name]\n\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction getBooleanAttribute(attributes: Record<string, boolean | string>, name: string): boolean {\n const value = attributes[name]\n\n if (value === true) return true\n if (typeof value !== 'string') return false\n\n return value === 'true'\n}\n\nfunction getLeafDirectiveName(text: string): string | undefined {\n const trimmed = text.trim()\n if (trimmed.startsWith(':::')) return undefined\n\n const match = trimmed.match(/^::([\\w-]+)(?:$|[\\s[{])/)\n\n return match?.[1]\n}\n\nfunction makeIconPlaceholder(icon: string, iconPosition: 'left' | 'right') {\n const normalized = normalizePayloadMarkdownIconRef(icon)\n const iconKey = normalized.icon?.key ?? icon\n\n return {\n type: 'element' as const,\n children: [],\n properties: {\n ariaHidden: 'true',\n className: [\n 'pmd-button__icon',\n `pmd-button__icon--${iconPosition}`,\n ],\n dataPmdIcon: iconKey,\n dataPmdIconRef: icon,\n focusable: 'false',\n },\n tagName: 'span',\n }\n}\n\nfunction makeButtonDirective(\n line: string,\n file: MessageFile,\n _config: MarkdownRenderConfig,\n): LeafDirective | undefined {\n const parsed = parseButtonDirectiveLine(line)\n if (!parsed) return undefined\n\n const definition = layoutDirectiveRegistry.get('button')\n const attributes = parsed.attributes\n const label = parsed.label.trim()\n const href = getAttribute(attributes, 'href')\n const variant = isButtonVariant(attributes.variant) ? attributes.variant : DEFAULT_BUTTON_VARIANT\n const size = isButtonSize(attributes.size) ? attributes.size : DEFAULT_BUTTON_SIZE\n const iconPosition = isButtonIconPosition(attributes.iconPosition)\n ? attributes.iconPosition\n : DEFAULT_BUTTON_ICON_POSITION\n const icon = getAttribute(attributes, 'icon')\n const ariaLabel = getAttribute(attributes, 'ariaLabel')\n const newTab = getBooleanAttribute(attributes, 'newTab')\n\n for (const warning of parsed.warnings) file.message(warning)\n for (const warning of definition?.validateAttributes?.({ name: 'button', attributes }) ?? [])\n file.message(warning)\n\n if (icon) {\n const normalized = normalizePayloadMarkdownIconRef(icon)\n if (normalized.warning) file.message(normalized.warning)\n }\n\n if (!label && !ariaLabel) file.message('Icon-only button requires an ariaLabel attribute.')\n\n const hChildren = [\n ...(icon && iconPosition === 'left' ? [makeIconPlaceholder(icon, iconPosition)] : []),\n ...(label\n ? [\n {\n type: 'text' as const,\n value: label,\n },\n ]\n : []),\n ...(icon && iconPosition === 'right' ? [makeIconPlaceholder(icon, iconPosition)] : []),\n ]\n\n return {\n name: 'button',\n type: 'leafDirective',\n attributes: Object.fromEntries(\n Object.entries(attributes).map(([key, value]) => [key, String(value)]),\n ),\n children: label ? [{ type: 'text', value: label }] : [],\n data: {\n hChildren,\n hName: 'a',\n hProperties: {\n ...(ariaLabel ? { ariaLabel } : {}),\n className: [\n 'pmd-button',\n `pmd-button--${variant}`,\n `pmd-button--${size}`,\n ],\n dataButton: '',\n dataDirective: 'button',\n dataIconPosition: icon ? iconPosition : undefined,\n dataSize: size,\n dataVariant: variant,\n href,\n ...(newTab\n ? {\n rel: 'noopener noreferrer',\n target: '_blank',\n }\n : {}),\n },\n },\n }\n}\n\nfunction splitParagraphButtonDirectives(\n node: Paragraph,\n file: MessageFile,\n config: MarkdownRenderConfig,\n): RootContent[] {\n const out: RootContent[] = []\n let paragraphLines: PhrasingContent[][] = []\n\n const flushParagraph = () => {\n const children = flattenParagraphLines(paragraphLines)\n\n if (children.length > 0) out.push({ type: 'paragraph', children })\n\n paragraphLines = []\n }\n\n const lines = splitParagraphLines(node)\n\n for (let index = 0; index < lines.length; ++index) {\n const lineChildren = lines[index]\n const text = getTextOnlyLine(lineChildren)\n const expanded = text ? collectExpandedDirectiveText(lines, index) : null\n const button = expanded ? makeButtonDirective(expanded.text, file, config) : undefined\n\n if (!button) {\n const leafName = text ? getLeafDirectiveName(text) : undefined\n if (leafName && leafName !== 'button') file.message(`Unknown directive \"${leafName}\".`)\n\n appendParagraphLine(paragraphLines, lineChildren)\n continue\n }\n\n flushParagraph()\n out.push(button as RootContent)\n index = expanded?.endIndex ?? index\n }\n\n flushParagraph()\n\n return out.length > 0 ? out : [node]\n}\n\nexport const remarkButtonDirectives: Plugin<[MarkdownRenderConfig?], Root> = (\n config: MarkdownRenderConfig = {},\n) => {\n return (tree, file) => {\n tree.children = tree.children.flatMap((node): RootContent[] => {\n if (!isParagraph(node)) return [node]\n\n return splitParagraphButtonDirectives(node, file, config)\n })\n }\n}\n"],"names":["hasUnclosedDirectiveAttributeBlock","parseButtonDirectiveLine","DEFAULT_BUTTON_ICON_POSITION","DEFAULT_BUTTON_SIZE","DEFAULT_BUTTON_VARIANT","isButtonIconPosition","isButtonSize","isButtonVariant","layoutDirectiveRegistry","normalizePayloadMarkdownIconRef","isParagraph","node","type","isText","makeText","value","splitParagraphLines","lines","currentLine","length","child","children","push","parts","split","index","collectExpandedDirectiveText","startIndex","firstText","getTextOnlyLine","endIndex","text","nextText","trim","startsWith","phrasingToText","Array","isArray","values","map","every","join","appendParagraphLine","flattenParagraphLines","flat","getAttribute","attributes","name","undefined","getBooleanAttribute","getLeafDirectiveName","trimmed","match","makeIconPlaceholder","icon","iconPosition","normalized","iconKey","key","properties","ariaHidden","className","dataPmdIcon","dataPmdIconRef","focusable","tagName","makeButtonDirective","line","file","_config","parsed","definition","get","label","href","variant","size","ariaLabel","newTab","warning","warnings","message","validateAttributes","hChildren","Object","fromEntries","entries","String","data","hName","hProperties","dataButton","dataDirective","dataIconPosition","dataSize","dataVariant","rel","target","splitParagraphButtonDirectives","config","out","paragraphLines","flushParagraph","lineChildren","expanded","button","leafName","remarkButtonDirectives","tree","flatMap"],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ function isLayoutToken(node) {
|
|
|
8
8
|
function isAppendableRootContent(node) {
|
|
9
9
|
return node.type !== 'vlLayoutToken';
|
|
10
10
|
}
|
|
11
|
-
function makeDirective(name, attributes = {}, parentHeadingDepth, cellHeadingDepth) {
|
|
11
|
+
function makeDirective(name, attributes = {}, label, parentHeadingDepth, cellHeadingDepth) {
|
|
12
12
|
return {
|
|
13
13
|
name,
|
|
14
14
|
type: 'containerDirective',
|
|
@@ -19,6 +19,7 @@ function makeDirective(name, attributes = {}, parentHeadingDepth, cellHeadingDep
|
|
|
19
19
|
children: [],
|
|
20
20
|
data: {
|
|
21
21
|
vlCellHeadingDepth: cellHeadingDepth,
|
|
22
|
+
vlDirectiveLabel: label,
|
|
22
23
|
vlParentHeadingDepth: parentHeadingDepth
|
|
23
24
|
}
|
|
24
25
|
};
|
|
@@ -86,7 +87,7 @@ export const remarkCompileLayouts = ()=>{
|
|
|
86
87
|
if (node.action === 'open') {
|
|
87
88
|
const definition = layoutDirectiveRegistry.get(node.name);
|
|
88
89
|
if (definition?.kind === 'section') {
|
|
89
|
-
const next = makeDirective('section', node.attributes);
|
|
90
|
+
const next = makeDirective('section', node.attributes, node.label);
|
|
90
91
|
append(next);
|
|
91
92
|
stack.push({
|
|
92
93
|
name: 'section',
|
|
@@ -95,7 +96,7 @@ export const remarkCompileLayouts = ()=>{
|
|
|
95
96
|
continue;
|
|
96
97
|
}
|
|
97
98
|
if (definition?.kind === 'cell') {
|
|
98
|
-
const next = makeDirective('cell', node.attributes);
|
|
99
|
+
const next = makeDirective('cell', node.attributes, node.label);
|
|
99
100
|
append(next);
|
|
100
101
|
stack.push({
|
|
101
102
|
name: 'cell',
|
|
@@ -104,7 +105,7 @@ export const remarkCompileLayouts = ()=>{
|
|
|
104
105
|
continue;
|
|
105
106
|
}
|
|
106
107
|
if (definition?.kind !== 'grid') {
|
|
107
|
-
const next = makeDirective(node.name, node.attributes);
|
|
108
|
+
const next = makeDirective(node.name, node.attributes, node.label);
|
|
108
109
|
append(next);
|
|
109
110
|
stack.push({
|
|
110
111
|
name: node.name,
|
|
@@ -115,7 +116,7 @@ export const remarkCompileLayouts = ()=>{
|
|
|
115
116
|
closeActiveGridInsideSection(stack);
|
|
116
117
|
const parentDepth = currentHeadingDepth ?? 1;
|
|
117
118
|
const cellDepth = parentDepth + 1;
|
|
118
|
-
const next = makeDirective(node.name, node.attributes, parentDepth, cellDepth);
|
|
119
|
+
const next = makeDirective(node.name, node.attributes, node.label, parentDepth, cellDepth);
|
|
119
120
|
append(next);
|
|
120
121
|
stack.push({
|
|
121
122
|
name: node.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/plugins/remarkCompileLayouts.ts"],"sourcesContent":["import type { Heading, Root, RootContent } from 'mdast'\nimport type { ContainerDirective } from 'mdast-util-directive'\nimport type { Plugin } from 'unified'\n\nimport type { LayoutName, LayoutToken } from '../../directives/types.js'\n\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\n\ntype LayoutNode = ContainerDirective | Root\n\ntype AppendableRootContent = Exclude<RootContent, LayoutToken>\n\ntype LayoutFrame = {\n cellHeadingDepth?: number\n name: 'root' | LayoutName\n node: LayoutNode\n parentHeadingDepth?: number\n}\n\nfunction isHeading(node: RootContent): node is Heading {\n return node.type === 'heading'\n}\n\nfunction isLayoutToken(node: RootContent): node is LayoutToken {\n return node.type === 'vlLayoutToken'\n}\n\nfunction isAppendableRootContent(node: RootContent): node is AppendableRootContent {\n return node.type !== 'vlLayoutToken'\n}\n\nfunction makeDirective(\n name: LayoutName,\n attributes: Record<string, boolean | string> = {},\n parentHeadingDepth?: number,\n cellHeadingDepth?: number,\n): ContainerDirective {\n return {\n name,\n type: 'containerDirective',\n attributes: Object.fromEntries(\n Object.entries(attributes).map(([key, value]) => [key, String(value)]),\n ),\n children: [],\n data: {\n vlCellHeadingDepth: cellHeadingDepth,\n vlParentHeadingDepth: parentHeadingDepth,\n },\n }\n}\n\nfunction getChildren(node: LayoutNode): AppendableRootContent[] {\n return node.children as AppendableRootContent[]\n}\n\nfunction top<T>(arr: T[]): T {\n return arr[arr.length - 1]\n}\n\nfunction isGridName(name: LayoutFrame['name']): name is '2col' | '3col' {\n return layoutDirectiveRegistry.isGridName(name)\n}\n\nfunction findNearestSectionIndex(stack: LayoutFrame[]): number {\n for (let i = stack.length - 1; i >= 0; --i) if (stack[i]?.name === 'section') return i\n\n return -1\n}\n\nfunction findNearestGridIndex(stack: LayoutFrame[]): number {\n for (let i = stack.length - 1; i >= 0; --i) if (isGridName(stack[i]?.name)) return i\n\n return -1\n}\n\nfunction closeTop(stack: LayoutFrame[]) {\n if (stack.length > 1) stack.pop()\n}\n\nfunction closeActiveGrid(stack: LayoutFrame[]): boolean {\n const gridIndex = findNearestGridIndex(stack)\n if (gridIndex < 0) return false\n\n while (stack.length - 1 >= gridIndex) stack.pop()\n\n return true\n}\n\nfunction closeActiveGridInsideSection(stack: LayoutFrame[]): boolean {\n const gridIndex = findNearestGridIndex(stack)\n const sectionIndex = findNearestSectionIndex(stack)\n\n if (gridIndex < 0 || sectionIndex < 0) return false\n if (gridIndex < sectionIndex) return false\n\n while (stack.length - 1 >= gridIndex) stack.pop()\n\n return true\n}\n\nfunction closeThroughSection(stack: LayoutFrame[]): boolean {\n const sectionIndex = findNearestSectionIndex(stack)\n if (sectionIndex < 0) return false\n\n while (stack.length - 1 >= sectionIndex) stack.pop()\n\n return true\n}\n\nexport const remarkCompileLayouts: Plugin<[], Root> = () => {\n return (tree, file) => {\n const input = [...tree.children]\n const rebuiltRoot: Root = { ...tree, children: [] }\n const stack: LayoutFrame[] = [{ name: 'root', node: rebuiltRoot }]\n const warnings: string[] = []\n\n let currentHeadingDepth: number | undefined\n\n const append = (node: AppendableRootContent) => getChildren(top(stack).node).push(node)\n\n for (const node of input) {\n if (isLayoutToken(node)) {\n if (node.action === 'open') {\n const definition = layoutDirectiveRegistry.get(node.name)\n\n if (definition?.kind === 'section') {\n const next = makeDirective('section', node.attributes)\n append(next)\n stack.push({ name: 'section', node: next })\n continue\n }\n\n if (definition?.kind === 'cell') {\n const next = makeDirective('cell', node.attributes)\n append(next)\n stack.push({ name: 'cell', node: next })\n continue\n }\n\n if (definition?.kind !== 'grid') {\n const next = makeDirective(node.name, node.attributes)\n append(next)\n stack.push({ name: node.name, node: next })\n continue\n }\n\n closeActiveGridInsideSection(stack)\n\n const parentDepth = currentHeadingDepth ?? 1\n const cellDepth = parentDepth + 1\n const next = makeDirective(node.name, node.attributes, parentDepth, cellDepth)\n\n append(next)\n stack.push({\n name: node.name,\n cellHeadingDepth: cellDepth,\n node: next,\n parentHeadingDepth: parentDepth,\n })\n continue\n }\n\n if (node.action === 'close') {\n if (stack.length === 1) {\n warnings.push('Encountered ::: with no open layout block.')\n continue\n }\n\n closeTop(stack)\n continue\n }\n\n if (node.action === 'closeGrid') {\n if (!closeActiveGrid(stack)) {\n warnings.push('Encountered :::endcol with no open grid.')\n continue\n }\n\n continue\n }\n\n if (node.action === 'closeSection') {\n if (!closeThroughSection(stack))\n warnings.push('Encountered :::end or :::endsection with no open section.')\n\n continue\n }\n }\n\n if (isHeading(node)) {\n const currentFrame = top(stack)\n\n if (isGridName(currentFrame.name)) {\n const parentDepth = currentFrame.parentHeadingDepth\n\n if (typeof parentDepth === 'number' && node.depth < parentDepth) closeTop(stack)\n }\n\n currentHeadingDepth = node.depth\n append(node)\n continue\n }\n\n if (isAppendableRootContent(node)) append(node)\n }\n\n while (stack.length > 1) {\n warnings.push(`Auto-closing unclosed layout block: ${top(stack).name}`)\n stack.pop()\n }\n\n tree.children = rebuiltRoot.children\n\n for (const warning of warnings) file.message(warning)\n }\n}\n"],"names":["layoutDirectiveRegistry","isHeading","node","type","isLayoutToken","isAppendableRootContent","makeDirective","name","attributes","parentHeadingDepth","cellHeadingDepth","Object","fromEntries","entries","map","key","value","String","children","data","vlCellHeadingDepth","vlParentHeadingDepth","getChildren","top","arr","length","isGridName","findNearestSectionIndex","stack","i","findNearestGridIndex","closeTop","pop","closeActiveGrid","gridIndex","closeActiveGridInsideSection","sectionIndex","closeThroughSection","remarkCompileLayouts","tree","file","input","rebuiltRoot","warnings","currentHeadingDepth","append","push","action","definition","get","kind","next","parentDepth","cellDepth","currentFrame","depth","warning","message"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/plugins/remarkCompileLayouts.ts"],"sourcesContent":["import type { Heading, Root, RootContent } from 'mdast'\nimport type { ContainerDirective } from 'mdast-util-directive'\nimport type { Plugin } from 'unified'\n\nimport type { LayoutName, LayoutToken } from '../../directives/types.js'\n\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\n\ntype LayoutNode = ContainerDirective | Root\n\ntype AppendableRootContent = Exclude<RootContent, LayoutToken>\n\ntype LayoutFrame = {\n cellHeadingDepth?: number\n name: 'root' | LayoutName\n node: LayoutNode\n parentHeadingDepth?: number\n}\n\nfunction isHeading(node: RootContent): node is Heading {\n return node.type === 'heading'\n}\n\nfunction isLayoutToken(node: RootContent): node is LayoutToken {\n return node.type === 'vlLayoutToken'\n}\n\nfunction isAppendableRootContent(node: RootContent): node is AppendableRootContent {\n return node.type !== 'vlLayoutToken'\n}\n\nfunction makeDirective(\n name: LayoutName,\n attributes: Record<string, boolean | string> = {},\n label?: string,\n parentHeadingDepth?: number,\n cellHeadingDepth?: number,\n): ContainerDirective {\n return {\n name,\n type: 'containerDirective',\n attributes: Object.fromEntries(\n Object.entries(attributes).map(([key, value]) => [key, String(value)]),\n ),\n children: [],\n data: {\n vlCellHeadingDepth: cellHeadingDepth,\n vlDirectiveLabel: label,\n vlParentHeadingDepth: parentHeadingDepth,\n },\n }\n}\n\nfunction getChildren(node: LayoutNode): AppendableRootContent[] {\n return node.children as AppendableRootContent[]\n}\n\nfunction top<T>(arr: T[]): T {\n return arr[arr.length - 1]\n}\n\nfunction isGridName(name: LayoutFrame['name']): name is '2col' | '3col' {\n return layoutDirectiveRegistry.isGridName(name)\n}\n\nfunction findNearestSectionIndex(stack: LayoutFrame[]): number {\n for (let i = stack.length - 1; i >= 0; --i) if (stack[i]?.name === 'section') return i\n\n return -1\n}\n\nfunction findNearestGridIndex(stack: LayoutFrame[]): number {\n for (let i = stack.length - 1; i >= 0; --i) if (isGridName(stack[i]?.name)) return i\n\n return -1\n}\n\nfunction closeTop(stack: LayoutFrame[]) {\n if (stack.length > 1) stack.pop()\n}\n\nfunction closeActiveGrid(stack: LayoutFrame[]): boolean {\n const gridIndex = findNearestGridIndex(stack)\n if (gridIndex < 0) return false\n\n while (stack.length - 1 >= gridIndex) stack.pop()\n\n return true\n}\n\nfunction closeActiveGridInsideSection(stack: LayoutFrame[]): boolean {\n const gridIndex = findNearestGridIndex(stack)\n const sectionIndex = findNearestSectionIndex(stack)\n\n if (gridIndex < 0 || sectionIndex < 0) return false\n if (gridIndex < sectionIndex) return false\n\n while (stack.length - 1 >= gridIndex) stack.pop()\n\n return true\n}\n\nfunction closeThroughSection(stack: LayoutFrame[]): boolean {\n const sectionIndex = findNearestSectionIndex(stack)\n if (sectionIndex < 0) return false\n\n while (stack.length - 1 >= sectionIndex) stack.pop()\n\n return true\n}\n\nexport const remarkCompileLayouts: Plugin<[], Root> = () => {\n return (tree, file) => {\n const input = [...tree.children]\n const rebuiltRoot: Root = { ...tree, children: [] }\n const stack: LayoutFrame[] = [{ name: 'root', node: rebuiltRoot }]\n const warnings: string[] = []\n\n let currentHeadingDepth: number | undefined\n\n const append = (node: AppendableRootContent) => getChildren(top(stack).node).push(node)\n\n for (const node of input) {\n if (isLayoutToken(node)) {\n if (node.action === 'open') {\n const definition = layoutDirectiveRegistry.get(node.name)\n\n if (definition?.kind === 'section') {\n const next = makeDirective('section', node.attributes, node.label)\n append(next)\n stack.push({ name: 'section', node: next })\n continue\n }\n\n if (definition?.kind === 'cell') {\n const next = makeDirective('cell', node.attributes, node.label)\n append(next)\n stack.push({ name: 'cell', node: next })\n continue\n }\n\n if (definition?.kind !== 'grid') {\n const next = makeDirective(node.name, node.attributes, node.label)\n append(next)\n stack.push({ name: node.name, node: next })\n continue\n }\n\n closeActiveGridInsideSection(stack)\n\n const parentDepth = currentHeadingDepth ?? 1\n const cellDepth = parentDepth + 1\n const next = makeDirective(node.name, node.attributes, node.label, parentDepth, cellDepth)\n\n append(next)\n stack.push({\n name: node.name,\n cellHeadingDepth: cellDepth,\n node: next,\n parentHeadingDepth: parentDepth,\n })\n continue\n }\n\n if (node.action === 'close') {\n if (stack.length === 1) {\n warnings.push('Encountered ::: with no open layout block.')\n continue\n }\n\n closeTop(stack)\n continue\n }\n\n if (node.action === 'closeGrid') {\n if (!closeActiveGrid(stack)) {\n warnings.push('Encountered :::endcol with no open grid.')\n continue\n }\n\n continue\n }\n\n if (node.action === 'closeSection') {\n if (!closeThroughSection(stack))\n warnings.push('Encountered :::end or :::endsection with no open section.')\n\n continue\n }\n }\n\n if (isHeading(node)) {\n const currentFrame = top(stack)\n\n if (isGridName(currentFrame.name)) {\n const parentDepth = currentFrame.parentHeadingDepth\n\n if (typeof parentDepth === 'number' && node.depth < parentDepth) closeTop(stack)\n }\n\n currentHeadingDepth = node.depth\n append(node)\n continue\n }\n\n if (isAppendableRootContent(node)) append(node)\n }\n\n while (stack.length > 1) {\n warnings.push(`Auto-closing unclosed layout block: ${top(stack).name}`)\n stack.pop()\n }\n\n tree.children = rebuiltRoot.children\n\n for (const warning of warnings) file.message(warning)\n }\n}\n"],"names":["layoutDirectiveRegistry","isHeading","node","type","isLayoutToken","isAppendableRootContent","makeDirective","name","attributes","label","parentHeadingDepth","cellHeadingDepth","Object","fromEntries","entries","map","key","value","String","children","data","vlCellHeadingDepth","vlDirectiveLabel","vlParentHeadingDepth","getChildren","top","arr","length","isGridName","findNearestSectionIndex","stack","i","findNearestGridIndex","closeTop","pop","closeActiveGrid","gridIndex","closeActiveGridInsideSection","sectionIndex","closeThroughSection","remarkCompileLayouts","tree","file","input","rebuiltRoot","warnings","currentHeadingDepth","append","push","action","definition","get","kind","next","parentDepth","cellDepth","currentFrame","depth","warning","message"],"mappings":"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"}
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import { visit } from 'unist-util-visit';
|
|
2
2
|
import { layoutDirectiveRegistry } from '../../directives/registry.js';
|
|
3
3
|
import { setDirectiveRenderData } from '../../directives/renderData.js';
|
|
4
|
+
function isMarkdownDirective(node) {
|
|
5
|
+
return Boolean(node && typeof node === 'object' && 'type' in node && [
|
|
6
|
+
'containerDirective',
|
|
7
|
+
'leafDirective'
|
|
8
|
+
].includes(node.type ?? ''));
|
|
9
|
+
}
|
|
4
10
|
function isContainerDirective(node) {
|
|
5
|
-
return
|
|
11
|
+
return node.type === 'containerDirective';
|
|
6
12
|
}
|
|
7
13
|
function transformDirective(node, file) {
|
|
14
|
+
if (node.type === 'leafDirective' && node.name !== 'button') return;
|
|
8
15
|
const definition = layoutDirectiveRegistry.get(node.name);
|
|
9
16
|
if (!definition) return;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
const renderProperties = isContainerDirective(node) ? definition.getMdastRenderProperties?.(node) : undefined;
|
|
18
|
+
if (isContainerDirective(node)) {
|
|
19
|
+
for (const warning of definition.validateMdast?.(node) ?? [])file.message(warning);
|
|
20
|
+
definition.transformMdast?.(node, {
|
|
21
|
+
isSupportedDirectiveName: (name)=>layoutDirectiveRegistry.isSupportedDirectiveName(name)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
setDirectiveRenderData(node, definition, renderProperties);
|
|
15
25
|
}
|
|
16
26
|
export const remarkLayoutDirectives = ()=>{
|
|
17
27
|
return (tree, file)=>{
|
|
18
28
|
visit(tree, (node)=>{
|
|
19
|
-
if (!
|
|
29
|
+
if (!isMarkdownDirective(node)) return;
|
|
20
30
|
if (!layoutDirectiveRegistry.isSupportedDirectiveName(node.name)) return;
|
|
21
31
|
transformDirective(node, file);
|
|
22
32
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/plugins/remarkLayoutDirectives.ts"],"sourcesContent":["import type { Root } from 'mdast'\nimport type { ContainerDirective } from 'mdast-util-directive'\nimport type { Plugin } from 'unified'\n\nimport { visit } from 'unist-util-visit'\n\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\nimport { setDirectiveRenderData } from '../../directives/renderData.js'\n\nfunction
|
|
1
|
+
{"version":3,"sources":["../../../src/core/plugins/remarkLayoutDirectives.ts"],"sourcesContent":["import type { Root } from 'mdast'\nimport type { ContainerDirective, LeafDirective } from 'mdast-util-directive'\nimport type { Plugin } from 'unified'\n\nimport { visit } from 'unist-util-visit'\n\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\nimport { setDirectiveRenderData } from '../../directives/renderData.js'\n\ntype MarkdownDirectiveNode = ContainerDirective | LeafDirective\n\nfunction isMarkdownDirective(node: unknown): node is MarkdownDirectiveNode {\n return Boolean(\n node &&\n typeof node === 'object' &&\n 'type' in node &&\n ['containerDirective', 'leafDirective'].includes(\n (node as { type?: string }).type ?? '',\n ),\n )\n}\n\nfunction isContainerDirective(node: MarkdownDirectiveNode): node is ContainerDirective {\n return node.type === 'containerDirective'\n}\n\ntype WarningSink = {\n message: (reason: string) => unknown\n}\n\nfunction transformDirective(node: MarkdownDirectiveNode, file: WarningSink) {\n if (node.type === 'leafDirective' && node.name !== 'button') return\n\n const definition = layoutDirectiveRegistry.get(node.name)\n\n if (!definition) return\n\n const renderProperties = isContainerDirective(node)\n ? definition.getMdastRenderProperties?.(node)\n : undefined\n\n if (isContainerDirective(node)) {\n for (const warning of definition.validateMdast?.(node) ?? []) file.message(warning)\n\n definition.transformMdast?.(node, {\n isSupportedDirectiveName: (name) => layoutDirectiveRegistry.isSupportedDirectiveName(name),\n })\n }\n\n setDirectiveRenderData(node, definition, renderProperties)\n}\n\nexport const remarkLayoutDirectives: Plugin<[], Root> = () => {\n return (tree: Root, file) => {\n visit(tree, (node) => {\n if (!isMarkdownDirective(node)) return\n if (!layoutDirectiveRegistry.isSupportedDirectiveName(node.name)) return\n\n transformDirective(node, file)\n })\n }\n}\n"],"names":["visit","layoutDirectiveRegistry","setDirectiveRenderData","isMarkdownDirective","node","Boolean","includes","type","isContainerDirective","transformDirective","file","name","definition","get","renderProperties","getMdastRenderProperties","undefined","warning","validateMdast","message","transformMdast","isSupportedDirectiveName","remarkLayoutDirectives","tree"],"mappings":"AAIA,SAASA,KAAK,QAAQ,mBAAkB;AAExC,SAASC,uBAAuB,QAAQ,+BAA8B;AACtE,SAASC,sBAAsB,QAAQ,iCAAgC;AAIvE,SAASC,oBAAoBC,IAAa;IACxC,OAAOC,QACLD,QACE,OAAOA,SAAS,YAChB,UAAUA,QACV;QAAC;QAAsB;KAAgB,CAACE,QAAQ,CAC9C,AAACF,KAA2BG,IAAI,IAAI;AAG5C;AAEA,SAASC,qBAAqBJ,IAA2B;IACvD,OAAOA,KAAKG,IAAI,KAAK;AACvB;AAMA,SAASE,mBAAmBL,IAA2B,EAAEM,IAAiB;IACxE,IAAIN,KAAKG,IAAI,KAAK,mBAAmBH,KAAKO,IAAI,KAAK,UAAU;IAE7D,MAAMC,aAAaX,wBAAwBY,GAAG,CAACT,KAAKO,IAAI;IAExD,IAAI,CAACC,YAAY;IAEjB,MAAME,mBAAmBN,qBAAqBJ,QAC1CQ,WAAWG,wBAAwB,GAAGX,QACtCY;IAEJ,IAAIR,qBAAqBJ,OAAO;QAC9B,KAAK,MAAMa,WAAWL,WAAWM,aAAa,GAAGd,SAAS,EAAE,CAAEM,KAAKS,OAAO,CAACF;QAE3EL,WAAWQ,cAAc,GAAGhB,MAAM;YAChCiB,0BAA0B,CAACV,OAASV,wBAAwBoB,wBAAwB,CAACV;QACvF;IACF;IAEAT,uBAAuBE,MAAMQ,YAAYE;AAC3C;AAEA,OAAO,MAAMQ,yBAA2C;IACtD,OAAO,CAACC,MAAYb;QAClBV,MAAMuB,MAAM,CAACnB;YACX,IAAI,CAACD,oBAAoBC,OAAO;YAChC,IAAI,CAACH,wBAAwBoB,wBAAwB,CAACjB,KAAKO,IAAI,GAAG;YAElEF,mBAAmBL,MAAMM;QAC3B;IACF;AACF,EAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { hasUnclosedDirectiveAttributeBlock } from '../../directives/attributes.js';
|
|
1
2
|
import { layoutDirectiveRegistry } from '../../directives/registry.js';
|
|
2
3
|
function isParagraph(node) {
|
|
3
4
|
return node.type === 'paragraph';
|
|
@@ -38,9 +39,42 @@ function splitParagraphLines(node) {
|
|
|
38
39
|
}
|
|
39
40
|
return lines;
|
|
40
41
|
}
|
|
42
|
+
function collectExpandedDirectiveText(lines, startIndex) {
|
|
43
|
+
const firstText = getTextOnlyLine(lines[startIndex]);
|
|
44
|
+
if (!firstText) return null;
|
|
45
|
+
if (!hasUnclosedDirectiveAttributeBlock(firstText)) return {
|
|
46
|
+
endIndex: startIndex,
|
|
47
|
+
text: firstText
|
|
48
|
+
};
|
|
49
|
+
let text = firstText;
|
|
50
|
+
for(let index = startIndex + 1; index < lines.length; ++index){
|
|
51
|
+
const nextText = getTextOnlyLine(lines[index]);
|
|
52
|
+
if (nextText === null) break;
|
|
53
|
+
if (nextText.trim().startsWith('::')) break;
|
|
54
|
+
text += `\n${nextText}`;
|
|
55
|
+
if (!hasUnclosedDirectiveAttributeBlock(text)) return {
|
|
56
|
+
endIndex: index,
|
|
57
|
+
text
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
endIndex: startIndex,
|
|
62
|
+
text: firstText
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function phrasingToText(node) {
|
|
66
|
+
if (node.type === 'text') return node.value;
|
|
67
|
+
if (node.type === 'inlineCode') return node.value;
|
|
68
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
69
|
+
const values = node.children.map((child)=>phrasingToText(child));
|
|
70
|
+
return values.every((value)=>typeof value === 'string') ? values.join('') : null;
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
41
74
|
function getTextOnlyLine(children) {
|
|
42
|
-
|
|
43
|
-
|
|
75
|
+
const values = children.map((child)=>phrasingToText(child));
|
|
76
|
+
if (!values.every((value)=>typeof value === 'string')) return null;
|
|
77
|
+
return values.join('');
|
|
44
78
|
}
|
|
45
79
|
function appendParagraphLine(lines, children) {
|
|
46
80
|
if (lines.length > 0) lines.push([
|
|
@@ -60,9 +94,12 @@ function splitParagraphLayoutDirectives(node, warn) {
|
|
|
60
94
|
if (children.length > 0) out.push(makeParagraph(children));
|
|
61
95
|
paragraphLines = [];
|
|
62
96
|
};
|
|
63
|
-
|
|
97
|
+
const lines = splitParagraphLines(node);
|
|
98
|
+
for(let index = 0; index < lines.length; ++index){
|
|
99
|
+
const lineChildren = lines[index];
|
|
64
100
|
const text = getTextOnlyLine(lineChildren);
|
|
65
|
-
const
|
|
101
|
+
const expanded = text ? collectExpandedDirectiveText(lines, index) : null;
|
|
102
|
+
const result = expanded ? parseLayoutDirective(expanded.text.trim()) : {
|
|
66
103
|
diagnostics: [],
|
|
67
104
|
token: null
|
|
68
105
|
};
|
|
@@ -73,6 +110,7 @@ function splitParagraphLayoutDirectives(node, warn) {
|
|
|
73
110
|
}
|
|
74
111
|
flushParagraph();
|
|
75
112
|
out.push(result.token);
|
|
113
|
+
index = expanded?.endIndex ?? index;
|
|
76
114
|
}
|
|
77
115
|
flushParagraph();
|
|
78
116
|
return out.length > 0 ? out : [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/plugins/remarkLiftLayoutDirectives.ts"],"sourcesContent":["import type { Paragraph, PhrasingContent, Root, RootContent, Text } from 'mdast'\nimport type { Plugin } from 'unified'\n\nimport type { LayoutToken } from '../../types/layoutToken.js'\n\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\n\nfunction isParagraph(node: RootContent): node is Paragraph {\n return node.type === 'paragraph'\n}\n\nfunction isText(node: Paragraph['children'][number]): node is Text {\n return node.type === 'text'\n}\n\nfunction parseLayoutDirective(text: string): {\n diagnostics: string[]\n token: LayoutToken | null\n} {\n return layoutDirectiveRegistry.parseMarkdownLineDetailed(text)\n}\n\nfunction makeParagraph(children: PhrasingContent[]): Paragraph {\n return {\n type: 'paragraph',\n children,\n }\n}\n\nfunction makeText(value: string): Text {\n return {\n type: 'text',\n value,\n }\n}\n\nfunction splitParagraphLines(node: Paragraph): PhrasingContent[][] {\n const lines: PhrasingContent[][] = [[]]\n\n const currentLine = () => lines[lines.length - 1]\n\n for (const child of node.children) {\n if (!isText(child)) {\n currentLine().push(child)\n continue\n }\n\n const parts = child.value.split(/\\r?\\n/)\n\n for (let index = 0; index < parts.length; ++index) {\n if (index > 0) lines.push([])\n\n if (parts[index]) currentLine().push(makeText(parts[index]))\n }\n }\n\n return lines\n}\n\nfunction
|
|
1
|
+
{"version":3,"sources":["../../../src/core/plugins/remarkLiftLayoutDirectives.ts"],"sourcesContent":["import type { Paragraph, PhrasingContent, Root, RootContent, Text } from 'mdast'\nimport type { Plugin } from 'unified'\n\nimport type { LayoutToken } from '../../types/layoutToken.js'\n\nimport { hasUnclosedDirectiveAttributeBlock } from '../../directives/attributes.js'\nimport { layoutDirectiveRegistry } from '../../directives/registry.js'\n\nfunction isParagraph(node: RootContent): node is Paragraph {\n return node.type === 'paragraph'\n}\n\nfunction isText(node: Paragraph['children'][number]): node is Text {\n return node.type === 'text'\n}\n\nfunction parseLayoutDirective(text: string): {\n diagnostics: string[]\n token: LayoutToken | null\n} {\n return layoutDirectiveRegistry.parseMarkdownLineDetailed(text)\n}\n\nfunction makeParagraph(children: PhrasingContent[]): Paragraph {\n return {\n type: 'paragraph',\n children,\n }\n}\n\nfunction makeText(value: string): Text {\n return {\n type: 'text',\n value,\n }\n}\n\nfunction splitParagraphLines(node: Paragraph): PhrasingContent[][] {\n const lines: PhrasingContent[][] = [[]]\n\n const currentLine = () => lines[lines.length - 1]\n\n for (const child of node.children) {\n if (!isText(child)) {\n currentLine().push(child)\n continue\n }\n\n const parts = child.value.split(/\\r?\\n/)\n\n for (let index = 0; index < parts.length; ++index) {\n if (index > 0) lines.push([])\n\n if (parts[index]) currentLine().push(makeText(parts[index]))\n }\n }\n\n return lines\n}\n\nfunction collectExpandedDirectiveText(\n lines: PhrasingContent[][],\n startIndex: number,\n): { endIndex: number; text: string } | null {\n const firstText = getTextOnlyLine(lines[startIndex])\n\n if (!firstText) return null\n if (!hasUnclosedDirectiveAttributeBlock(firstText))\n return {\n endIndex: startIndex,\n text: firstText,\n }\n\n let text = firstText\n\n for (let index = startIndex + 1; index < lines.length; ++index) {\n const nextText = getTextOnlyLine(lines[index])\n\n if (nextText === null) break\n if (nextText.trim().startsWith('::')) break\n\n text += `\\n${nextText}`\n\n if (!hasUnclosedDirectiveAttributeBlock(text))\n return {\n endIndex: index,\n text,\n }\n }\n\n return {\n endIndex: startIndex,\n text: firstText,\n }\n}\n\nfunction phrasingToText(node: PhrasingContent): null | string {\n if (node.type === 'text') return node.value\n if (node.type === 'inlineCode') return node.value\n if ('children' in node && Array.isArray(node.children)) {\n const values = node.children.map((child) => phrasingToText(child))\n\n return values.every((value): value is string => typeof value === 'string')\n ? values.join('')\n : null\n }\n\n return null\n}\n\nfunction getTextOnlyLine(children: PhrasingContent[]): null | string {\n const values = children.map((child) => phrasingToText(child))\n\n if (!values.every((value): value is string => typeof value === 'string')) return null\n\n return values.join('')\n}\n\nfunction appendParagraphLine(lines: PhrasingContent[][], children: PhrasingContent[]) {\n if (lines.length > 0) lines.push([makeText('\\n'), ...children])\n else lines.push(children)\n}\n\nfunction flattenParagraphLines(lines: PhrasingContent[][]): PhrasingContent[] {\n return lines.flat()\n}\n\nfunction splitParagraphLayoutDirectives(\n node: Paragraph,\n warn: (message: string) => void,\n): RootContent[] {\n const out: RootContent[] = []\n let paragraphLines: PhrasingContent[][] = []\n\n const flushParagraph = () => {\n const children = flattenParagraphLines(paragraphLines)\n\n if (children.length > 0) out.push(makeParagraph(children))\n\n paragraphLines = []\n }\n\n const lines = splitParagraphLines(node)\n\n for (let index = 0; index < lines.length; ++index) {\n const lineChildren = lines[index]\n const text = getTextOnlyLine(lineChildren)\n const expanded = text ? collectExpandedDirectiveText(lines, index) : null\n const result = expanded\n ? parseLayoutDirective(expanded.text.trim())\n : { diagnostics: [], token: null }\n\n for (const diagnostic of result.diagnostics) warn(diagnostic)\n\n if (!result.token) {\n appendParagraphLine(paragraphLines, lineChildren)\n continue\n }\n\n flushParagraph()\n out.push(result.token)\n index = expanded?.endIndex ?? index\n }\n\n flushParagraph()\n\n return out.length > 0 ? out : [node]\n}\n\nexport const remarkLiftLayoutDirectives: Plugin<[], Root> = () => {\n return (tree, file) => {\n tree.children = tree.children.flatMap((node): RootContent[] => {\n if (!isParagraph(node)) return [node]\n\n return splitParagraphLayoutDirectives(node, (message) => file.message(message))\n })\n }\n}\n"],"names":["hasUnclosedDirectiveAttributeBlock","layoutDirectiveRegistry","isParagraph","node","type","isText","parseLayoutDirective","text","parseMarkdownLineDetailed","makeParagraph","children","makeText","value","splitParagraphLines","lines","currentLine","length","child","push","parts","split","index","collectExpandedDirectiveText","startIndex","firstText","getTextOnlyLine","endIndex","nextText","trim","startsWith","phrasingToText","Array","isArray","values","map","every","join","appendParagraphLine","flattenParagraphLines","flat","splitParagraphLayoutDirectives","warn","out","paragraphLines","flushParagraph","lineChildren","expanded","result","diagnostics","token","diagnostic","remarkLiftLayoutDirectives","tree","file","flatMap","message"],"mappings":"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"}
|