@wgtechlabs/mdd-engine 0.1.0-pr.cab0713 → 0.1.0-pr.d58d6d6
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 +7 -4
- package/dist/alerts.d.ts +8 -0
- package/dist/alerts.js +56 -0
- package/dist/markdown.js +25 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,16 +84,19 @@ order: 1
|
|
|
84
84
|
---
|
|
85
85
|
# Installation
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
> [!NOTE]
|
|
88
|
+
> **Before you start**
|
|
89
|
+
>
|
|
90
|
+
> You need a local documentation project.
|
|
90
91
|
|
|
91
92
|
:::details[More information]
|
|
92
93
|
Ordinary **Markdown** works inside components.
|
|
93
94
|
:::
|
|
94
95
|
```
|
|
95
96
|
|
|
96
|
-
Use `
|
|
97
|
+
Use GitHub-style alerts with `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, or `CAUTION`. Put the exact uppercase marker on the opening line of a blockquote at the document root; nested blockquotes remain ordinary quotes. Alerts become semantic `aside` elements with `mdd-alert` and `mdd-<type>` classes. Their readable Markdown preserves the `> [!TYPE]` marker. The engine supplies meaning and labels; the reader composes the article, and themes supply icons and colors.
|
|
98
|
+
|
|
99
|
+
`:::details[More information]` remains supported and becomes `details`/`summary`; its label is optional, attributes are errors, and its readable Markdown uses a blockquote with a bold label. The old `:::note`, `:::tip`, and `:::warning` directives now fail with a `REMOVED_COMPONENT` migration diagnostic. See [alerts and migration](docs/ALERTS.md) for all five types, theme hooks, and how to preserve custom titles and bodies.
|
|
97
100
|
|
|
98
101
|
Title precedence is frontmatter title, first H1, then readable filename. Navigation uses `navTitle` when supplied. Explicit `order` sorts first; remaining siblings sort deterministically by label and path.
|
|
99
102
|
|
package/dist/alerts.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Root } from "mdast";
|
|
2
|
+
declare module "mdast" {
|
|
3
|
+
interface TextData {
|
|
4
|
+
mddAlertMarker?: true;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/** Recognize alerts only at the document root, using unescaped source syntax. */
|
|
8
|
+
export declare function transformAlerts(tree: Root, source: string): void;
|
package/dist/alerts.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Recognize alerts only at the document root, using unescaped source syntax. */
|
|
2
|
+
export function transformAlerts(tree, source) {
|
|
3
|
+
for (const node of tree.children) {
|
|
4
|
+
if (node.type !== "blockquote")
|
|
5
|
+
continue;
|
|
6
|
+
const paragraph = node.children[0];
|
|
7
|
+
const first = paragraph?.type === "paragraph" ? paragraph.children[0] : undefined;
|
|
8
|
+
const offset = paragraph?.position?.start.offset;
|
|
9
|
+
if (paragraph?.type !== "paragraph" ||
|
|
10
|
+
first?.type !== "text" ||
|
|
11
|
+
offset === undefined ||
|
|
12
|
+
paragraph.position?.start.line !== node.position?.start.line)
|
|
13
|
+
continue;
|
|
14
|
+
const marker = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\][\t ]*(?:\r\n|\r|\n|$)/.exec(source.slice(offset));
|
|
15
|
+
const kind = marker?.[1];
|
|
16
|
+
if (!kind)
|
|
17
|
+
continue;
|
|
18
|
+
first.value = first.value.slice(kind.length + 3);
|
|
19
|
+
const bodyStart = paragraph.children[0];
|
|
20
|
+
if (bodyStart?.type === "text") {
|
|
21
|
+
bodyStart.value = bodyStart.value.replace(/^[\t ]*(?:\r\n|\r|\n)?/, "");
|
|
22
|
+
if (!bodyStart.value)
|
|
23
|
+
paragraph.children.shift();
|
|
24
|
+
}
|
|
25
|
+
if (paragraph.children[0]?.type === "break")
|
|
26
|
+
paragraph.children.shift();
|
|
27
|
+
if (!paragraph.children.length)
|
|
28
|
+
node.children.shift();
|
|
29
|
+
const type = kind.toLowerCase();
|
|
30
|
+
const label = type.charAt(0).toUpperCase() + type.slice(1);
|
|
31
|
+
const markerText = {
|
|
32
|
+
type: "text",
|
|
33
|
+
value: `[!${kind}]`,
|
|
34
|
+
data: { mddAlertMarker: true },
|
|
35
|
+
};
|
|
36
|
+
node.children.unshift({
|
|
37
|
+
type: "paragraph",
|
|
38
|
+
children: [markerText],
|
|
39
|
+
data: {
|
|
40
|
+
hProperties: { className: ["mdd-component-label"] },
|
|
41
|
+
hChildren: [
|
|
42
|
+
{
|
|
43
|
+
type: "element",
|
|
44
|
+
tagName: "strong",
|
|
45
|
+
properties: {},
|
|
46
|
+
children: [{ type: "text", value: label }],
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
node.data = {
|
|
52
|
+
hName: "aside",
|
|
53
|
+
hProperties: { className: ["mdd-alert", `mdd-${type}`] },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
package/dist/markdown.js
CHANGED
|
@@ -12,6 +12,7 @@ import remarkStringify from "remark-stringify";
|
|
|
12
12
|
import { unified } from "unified";
|
|
13
13
|
import { SKIP, visit } from "unist-util-visit";
|
|
14
14
|
import { parseDocument as parseYaml } from "yaml";
|
|
15
|
+
import { transformAlerts } from "./alerts.js";
|
|
15
16
|
const parser = unified()
|
|
16
17
|
.use(remarkParse)
|
|
17
18
|
.use(remarkGfm)
|
|
@@ -44,8 +45,19 @@ const htmlRenderer = unified()
|
|
|
44
45
|
},
|
|
45
46
|
})
|
|
46
47
|
.use(rehypeStringify);
|
|
47
|
-
const markdownRenderer = unified()
|
|
48
|
-
|
|
48
|
+
const markdownRenderer = unified()
|
|
49
|
+
.use(remarkGfm)
|
|
50
|
+
.use(remarkStringify, {
|
|
51
|
+
handlers: {
|
|
52
|
+
text(node, _parent, state, info) {
|
|
53
|
+
// Only generated alert markers bypass normal Markdown escaping.
|
|
54
|
+
return node.data?.mddAlertMarker === true
|
|
55
|
+
? node.value
|
|
56
|
+
: state.safe(node.value, info);
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const removedNotices = new Set(["note", "tip", "warning"]);
|
|
49
61
|
/** Keep the same first-wins, reachable definitions that the HTML renderer uses. */
|
|
50
62
|
function retainReferencedDefinitions(tree) {
|
|
51
63
|
const definitions = new Map();
|
|
@@ -100,6 +112,7 @@ function unsafeUrl(url, image) {
|
|
|
100
112
|
}
|
|
101
113
|
export function parseDocument(source, file, diagnostics) {
|
|
102
114
|
const tree = parser.parse(source);
|
|
115
|
+
transformAlerts(tree, source);
|
|
103
116
|
retainReferencedDefinitions(tree);
|
|
104
117
|
const metadata = {};
|
|
105
118
|
const headings = [];
|
|
@@ -185,8 +198,12 @@ export function parseDocument(source, file, diagnostics) {
|
|
|
185
198
|
node.type !== "textDirective") {
|
|
186
199
|
return;
|
|
187
200
|
}
|
|
188
|
-
if (
|
|
189
|
-
report("
|
|
201
|
+
if (removedNotices.has(node.name)) {
|
|
202
|
+
report("REMOVED_COMPONENT", `The ${node.name} directive was removed; use > [!${node.name.toUpperCase()}] followed by quoted body lines. Keep any optional custom title as bold text in the alert body.`, node);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (node.type !== "containerDirective" || node.name !== "details") {
|
|
206
|
+
report("UNKNOWN_COMPONENT", `Unsupported component ${node.name}; use a GitHub alert or a details container.`, node);
|
|
190
207
|
return;
|
|
191
208
|
}
|
|
192
209
|
if (Object.keys(node.attributes ?? {}).length) {
|
|
@@ -195,7 +212,7 @@ export function parseDocument(source, file, diagnostics) {
|
|
|
195
212
|
if (index === undefined || !parent)
|
|
196
213
|
return;
|
|
197
214
|
const first = node.children[0];
|
|
198
|
-
const defaultLabel =
|
|
215
|
+
const defaultLabel = "Details";
|
|
199
216
|
const label = first?.type === "paragraph" && first.data?.directiveLabel
|
|
200
217
|
? first
|
|
201
218
|
: {
|
|
@@ -214,7 +231,7 @@ export function parseDocument(source, file, diagnostics) {
|
|
|
214
231
|
}
|
|
215
232
|
label.children = [{ type: "strong", children: label.children }];
|
|
216
233
|
label.data = {
|
|
217
|
-
hName:
|
|
234
|
+
hName: "summary",
|
|
218
235
|
hProperties: { className: ["mdd-component-label"] },
|
|
219
236
|
};
|
|
220
237
|
parent.children[index] = {
|
|
@@ -222,8 +239,8 @@ export function parseDocument(source, file, diagnostics) {
|
|
|
222
239
|
children: node.children,
|
|
223
240
|
position: node.position,
|
|
224
241
|
data: {
|
|
225
|
-
hName:
|
|
226
|
-
hProperties: { className: [
|
|
242
|
+
hName: "details",
|
|
243
|
+
hProperties: { className: ["mdd-details"] },
|
|
227
244
|
},
|
|
228
245
|
};
|
|
229
246
|
// Revisit the replacement so nested content is validated exactly once.
|