@godxjp/markdown 31.19.0 → 31.20.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 +10 -9
- package/dist/index.d.ts +26 -4
- package/dist/index.js +34 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,15 +34,16 @@ as `react-markdown` + `remark-gfm` + `rehype-sanitize`, which is what the apps r
|
|
|
34
34
|
|
|
35
35
|
## Host extension points
|
|
36
36
|
|
|
37
|
-
| prop
|
|
38
|
-
|
|
|
39
|
-
| `remarkPlugins`
|
|
40
|
-
| `schema`
|
|
41
|
-
| `resolveUrl(url, key)`
|
|
42
|
-
| `headingId({ depth, text, index })`
|
|
43
|
-
| `components`
|
|
44
|
-
| `rehypePlugins`
|
|
45
|
-
| `mermaid={false}`
|
|
37
|
+
| prop | use |
|
|
38
|
+
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| `remarkPlugins` | Host markers (callouts, embeds). Their output is still sanitised. |
|
|
40
|
+
| `schema` | `{ tagNames, attributes }` the markers need. A rule for an attribute the base already constrains is merged into it (`code` `className` + `math-inline`). Cannot widen the URL policy. |
|
|
41
|
+
| `resolveUrl(url, key)` | Map a host scheme (`asset:…`) to a real URL before the sanitiser judges it. |
|
|
42
|
+
| `headingId({ depth, text, index })` | Use server-assigned anchors instead of slugs. |
|
|
43
|
+
| `components` | Element overrides. Mermaid fences are drawn before a host `pre` is asked, so a host code renderer keeps Mermaid. |
|
|
44
|
+
| `rehypePlugins` | Run after the sanitiser — presentation only. |
|
|
45
|
+
| `mermaid={false}` | Keep ```mermaid fences as code (or hand them to the host `pre`). |
|
|
46
|
+
| `allowedElements` / `unwrapDisallowed` | Narrow a body (an activity feed: `strong`, `em`, `del`, `code`). Only removes. |
|
|
46
47
|
|
|
47
48
|
## Stored versions
|
|
48
49
|
|
package/dist/index.d.ts
CHANGED
|
@@ -49,7 +49,12 @@ type SchemaExtension = {
|
|
|
49
49
|
/**
|
|
50
50
|
* The schema plus a host's additions. ADDITIVE: an extension can allow a tag or an attribute, never
|
|
51
51
|
* widen `protocols` or bring raw HTML back, so a consumer cannot loosen the URL policy by accident.
|
|
52
|
-
*
|
|
52
|
+
*
|
|
53
|
+
* A rule for an attribute the base ALREADY constrains is MERGED into that rule (gh#1116): the
|
|
54
|
+
* sanitiser reads the first rule it finds for an attribute, so appending `["className",
|
|
55
|
+
* "math-inline"]` beside the default `["className", /^language-./]` was silently ignored and the
|
|
56
|
+
* formula class stripped. Merged, it is one rule allowing both. An attribute the base allows with
|
|
57
|
+
* no value constraint stays unconstrained.
|
|
53
58
|
*/
|
|
54
59
|
declare function extendSchema(extension?: SchemaExtension): Options;
|
|
55
60
|
/**
|
|
@@ -84,7 +89,10 @@ type MarkdownProps = {
|
|
|
84
89
|
rehypePlugins?: PluggableList;
|
|
85
90
|
/** Tags / attributes a host plugin needs. Additive; cannot widen the URL policy. */
|
|
86
91
|
schema?: SchemaExtension;
|
|
87
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Element overrides (react-markdown `components`). A host `pre` renders every fence EXCEPT
|
|
94
|
+
* ```mermaid, which is drawn through the gate first; `mermaid={false}` hands those to it too.
|
|
95
|
+
*/
|
|
88
96
|
components?: Components;
|
|
89
97
|
/**
|
|
90
98
|
* Resolves a host-specific URL (`asset:…`, a wiki link) to a real one. Runs before the sanitiser
|
|
@@ -93,8 +101,22 @@ type MarkdownProps = {
|
|
|
93
101
|
resolveUrl?: (url: string, key: "href" | "src" | string) => string | undefined;
|
|
94
102
|
/** Heading anchors: GitHub slugs by default; a host with server-side anchors supplies its own. */
|
|
95
103
|
headingId?: HeadingIdResolver;
|
|
96
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* Render ```mermaid fences as gated diagrams (default true). They are drawn BEFORE a host `pre`
|
|
106
|
+
* is consulted, so a host code renderer keeps Mermaid; `false` hands mermaid fences to the host
|
|
107
|
+
* `pre` (or plain code) as well (gh#1116).
|
|
108
|
+
*/
|
|
97
109
|
mermaid?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* NARROW the elements a body may produce — an activity feed that shows only inline formatting.
|
|
112
|
+
* react-markdown's own options, applied after the sanitiser; they can only remove, never allow
|
|
113
|
+
* what the schema strips (gh#1116).
|
|
114
|
+
*/
|
|
115
|
+
allowedElements?: Options$1["allowedElements"];
|
|
116
|
+
disallowedElements?: Options$1["disallowedElements"];
|
|
117
|
+
allowElement?: Options$1["allowElement"];
|
|
118
|
+
/** With an element filter: keep a removed element's children (its text) instead of dropping it. */
|
|
119
|
+
unwrapDisallowed?: boolean;
|
|
98
120
|
};
|
|
99
121
|
/**
|
|
100
122
|
* THE ONE RENDERER (gh#1108). GFM — tables, task lists, fenced code, autolinks, footnotes,
|
|
@@ -106,7 +128,7 @@ type MarkdownProps = {
|
|
|
106
128
|
* Renders bare elements; the host wraps it (`<Prose>` from `@godxjp/ui/data-display`), so this
|
|
107
129
|
* package carries no UI-kit dependency.
|
|
108
130
|
*/
|
|
109
|
-
declare function Markdown({ children, remarkPlugins, rehypePlugins, schema, components, resolveUrl, headingId, mermaid, }: MarkdownProps): React.JSX.Element;
|
|
131
|
+
declare function Markdown({ children, remarkPlugins, rehypePlugins, schema, components, resolveUrl, headingId, mermaid, allowedElements, disallowedElements, allowElement, unwrapDisallowed, }: MarkdownProps): React.JSX.Element;
|
|
110
132
|
|
|
111
133
|
type MermaidSvgCheck = {
|
|
112
134
|
ok: true;
|
package/dist/index.js
CHANGED
|
@@ -178,10 +178,23 @@ var markdownSchema = {
|
|
|
178
178
|
h6: [...defaultSchema.attributes?.h6 ?? [], "id"]
|
|
179
179
|
}
|
|
180
180
|
};
|
|
181
|
+
var ruleName = (rule) => Array.isArray(rule) ? rule[0] : rule;
|
|
181
182
|
function extendSchema(extension = {}) {
|
|
182
183
|
const attributes = { ...markdownSchema.attributes };
|
|
183
184
|
for (const [tag, list] of Object.entries(extension.attributes ?? {})) {
|
|
184
|
-
|
|
185
|
+
const merged = [...attributes[tag] ?? []];
|
|
186
|
+
for (const rule of list) {
|
|
187
|
+
const name = ruleName(rule);
|
|
188
|
+
const at = merged.findIndex((existing2) => ruleName(existing2) === name);
|
|
189
|
+
if (at === -1) {
|
|
190
|
+
merged.push(rule);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const existing = merged[at];
|
|
194
|
+
if (!Array.isArray(existing)) continue;
|
|
195
|
+
merged[at] = Array.isArray(rule) ? [name, ...existing.slice(1), ...rule.slice(1)] : rule;
|
|
196
|
+
}
|
|
197
|
+
attributes[tag] = merged;
|
|
185
198
|
}
|
|
186
199
|
return {
|
|
187
200
|
...markdownSchema,
|
|
@@ -238,19 +251,25 @@ function Markdown({
|
|
|
238
251
|
components,
|
|
239
252
|
resolveUrl,
|
|
240
253
|
headingId,
|
|
241
|
-
mermaid = true
|
|
254
|
+
mermaid = true,
|
|
255
|
+
allowedElements,
|
|
256
|
+
disallowedElements,
|
|
257
|
+
allowElement,
|
|
258
|
+
unwrapDisallowed
|
|
242
259
|
}) {
|
|
243
260
|
const sanitizeSchema = React2.useMemo(() => extendSchema(schema), [schema]);
|
|
244
261
|
const merged = React2.useMemo(() => {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
262
|
+
if (!mermaid) return { ...components };
|
|
263
|
+
const HostPre = components?.pre;
|
|
264
|
+
const pre = (props) => {
|
|
265
|
+
const fence = fenceOf(props.node);
|
|
266
|
+
if (fence?.language === "mermaid") return /* @__PURE__ */ jsx2(MermaidDiagram, { source: fence.text });
|
|
267
|
+
if (HostPre)
|
|
268
|
+
return typeof HostPre === "string" ? React2.createElement(HostPre, props) : /* @__PURE__ */ jsx2(HostPre, { ...props });
|
|
269
|
+
const { node: _node, children: inner, ...rest } = props;
|
|
270
|
+
return /* @__PURE__ */ jsx2("pre", { ...rest, children: inner });
|
|
271
|
+
};
|
|
272
|
+
return { ...components, pre };
|
|
254
273
|
}, [components, mermaid]);
|
|
255
274
|
return /* @__PURE__ */ jsx2(
|
|
256
275
|
ReactMarkdown,
|
|
@@ -264,6 +283,10 @@ function Markdown({
|
|
|
264
283
|
],
|
|
265
284
|
urlTransform: safeUrl,
|
|
266
285
|
components: merged,
|
|
286
|
+
allowedElements,
|
|
287
|
+
disallowedElements,
|
|
288
|
+
allowElement,
|
|
289
|
+
unwrapDisallowed,
|
|
267
290
|
children
|
|
268
291
|
}
|
|
269
292
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/markdown",
|
|
3
|
-
"version": "31.
|
|
3
|
+
"version": "31.20.1",
|
|
4
4
|
"description": "The one Markdown renderer for GoDX apps: GFM + heading anchors, one sanitiser schema, a shared fixture corpus, and Mermaid drawn only after its SVG passes a fail-closed gate.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|