@orz/ui-markdown 0.0.0-stage → 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +175 -2
  3. package/dist/attachment-links.d.ts +20 -0
  4. package/dist/attachment-links.d.ts.map +1 -0
  5. package/dist/attachment-links.js +27 -0
  6. package/dist/attachment-links.js.map +1 -0
  7. package/dist/content.d.ts +31 -0
  8. package/dist/content.d.ts.map +1 -0
  9. package/dist/content.js +78 -0
  10. package/dist/content.js.map +1 -0
  11. package/dist/embeds.d.ts +18 -0
  12. package/dist/embeds.d.ts.map +1 -0
  13. package/dist/embeds.js +59 -0
  14. package/dist/embeds.js.map +1 -0
  15. package/dist/external-links.d.ts +23 -0
  16. package/dist/external-links.d.ts.map +1 -0
  17. package/dist/external-links.js +43 -0
  18. package/dist/external-links.js.map +1 -0
  19. package/dist/index.d.ts +7 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +6 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/lib/markdown-processor.d.ts +23 -0
  24. package/dist/lib/markdown-processor.d.ts.map +1 -0
  25. package/dist/lib/markdown-processor.js +35 -0
  26. package/dist/lib/markdown-processor.js.map +1 -0
  27. package/dist/lib/rehype-details.d.ts +13 -0
  28. package/dist/lib/rehype-details.d.ts.map +1 -0
  29. package/dist/lib/rehype-details.js +256 -0
  30. package/dist/lib/rehype-details.js.map +1 -0
  31. package/dist/lib/rehype-source-lines.d.ts +23 -0
  32. package/dist/lib/rehype-source-lines.d.ts.map +1 -0
  33. package/dist/lib/rehype-source-lines.js +77 -0
  34. package/dist/lib/rehype-source-lines.js.map +1 -0
  35. package/dist/lib/remark-frontmatter-table.d.ts +119 -0
  36. package/dist/lib/remark-frontmatter-table.d.ts.map +1 -0
  37. package/dist/lib/remark-frontmatter-table.js +212 -0
  38. package/dist/lib/remark-frontmatter-table.js.map +1 -0
  39. package/dist/lib/remark-rejected-urls.d.ts +23 -0
  40. package/dist/lib/remark-rejected-urls.d.ts.map +1 -0
  41. package/dist/lib/remark-rejected-urls.js +79 -0
  42. package/dist/lib/remark-rejected-urls.js.map +1 -0
  43. package/dist/markdown.d.ts +30 -0
  44. package/dist/markdown.d.ts.map +1 -0
  45. package/dist/markdown.js +146 -0
  46. package/dist/markdown.js.map +1 -0
  47. package/dist/plugin.d.ts +39 -0
  48. package/dist/plugin.d.ts.map +1 -0
  49. package/dist/plugin.js +2 -0
  50. package/dist/plugin.js.map +1 -0
  51. package/package.json +66 -3
  52. package/styles.css +293 -0
@@ -0,0 +1,212 @@
1
+ /**
2
+ * The flavours `remark-frontmatter` is switched on for. A module constant because it is passed as a
3
+ * plugin option, and a fresh array on every render is a fresh plugin list:
4
+ * react-markdown rebuilds the whole document, and a rebuilt text node
5
+ * collapses whatever selection was sitting in it (T-60).
6
+ */
7
+ export const FRONTMATTER_FLAVOURS = ["yaml", "toml"];
8
+ /** The separator each flavour writes between a key and its value. */
9
+ const SEPARATOR = { yaml: ":", toml: "=" };
10
+ /** Absolute offset each 1-based source line starts at. */
11
+ function lineStartsOf(source) {
12
+ const starts = [0];
13
+ for (let i = 0; i < source.length; i++) {
14
+ if (source[i] === "\n")
15
+ starts.push(i + 1);
16
+ }
17
+ return starts;
18
+ }
19
+ /**
20
+ * Cut a frontmatter block into fields, one line at a time — deliberately not
21
+ * by parsing YAML (T-240).
22
+ *
23
+ * Decorating the rendered text by source offset rests on every rendered
24
+ * character sitting at a known source offset: a word-level highlight is mapped
25
+ * back onto the source by addition, a text node is entered only while its span
26
+ * and its value agree character for character, and a reader's line/column
27
+ * selection is turned into an offset. Parsing and rendering the
28
+ * *result* breaks all three at once — a key can be normalised, the order
29
+ * reshuffled, `~` spelled `null` — so what comes out of here is only ever a
30
+ * verbatim slice of the source. That is also what lets an annotation anchor on
31
+ * one key or one value, and what lets the page's own search find them.
32
+ *
33
+ * The price, stated where a reader will look for it: a `meta:` with indented
34
+ * children lands whole in one value cell, because a continuation line has
35
+ * nothing but its indentation to say it is one. `white-space: pre-wrap` on the
36
+ * cell keeps that readable; expanding a nested map into rows of its own needs
37
+ * real YAML semantics and is out of scope here.
38
+ */
39
+ export function frontmatterFields(source, block, sep) {
40
+ const starts = lineStartsOf(source);
41
+ const fields = [];
42
+ // Between the two fences: the opening one is the block's first line, the
43
+ // closing one its last.
44
+ for (let line = block.start.line + 1; line <= block.end.line - 1; line++) {
45
+ const from = starts[line - 1];
46
+ if (from === undefined)
47
+ continue;
48
+ const next = starts[line];
49
+ const to = next === undefined ? source.length : next - 1;
50
+ const text = source.slice(from, to);
51
+ const at = text.indexOf(sep);
52
+ // A key is one unindented token, so what stands before the FIRST separator
53
+ // decides: `url: https://x.test/a:b` is one field whose value keeps the
54
+ // second colon, while `two words: three` is prose continuing the field
55
+ // above. The padding TOML writes around `=` is not part of the token —
56
+ // testing the trimmed candidate is what lets `name = "bot-one"` open a
57
+ // field, which is how TOML is ordinarily spelled. Leading indentation
58
+ // survives the trim, which is what makes an indented line a continuation.
59
+ const key = at < 0 ? "" : text.slice(0, at).trimEnd();
60
+ const opens = at >= 0 && !/\s/.test(key);
61
+ const last = fields.at(-1);
62
+ if (!opens) {
63
+ if (last === undefined) {
64
+ fields.push({
65
+ key: null,
66
+ value: { start: from, end: to },
67
+ line,
68
+ endLine: line,
69
+ });
70
+ continue;
71
+ }
72
+ last.value.end = to;
73
+ last.endLine = line;
74
+ continue;
75
+ }
76
+ let value = from + at + sep.length;
77
+ while (value < to && (source[value] === " " || source[value] === "\t")) {
78
+ value++;
79
+ }
80
+ fields.push({
81
+ // The trimmed token, so the padding around a TOML `=` belongs to neither
82
+ // cell — the same way the `|` between two table cells belongs to neither.
83
+ key: { start: from, end: from + key.length },
84
+ value: { start: value, end: to },
85
+ line,
86
+ endLine: line,
87
+ });
88
+ }
89
+ return fields;
90
+ }
91
+ /**
92
+ * A position for a generated node. Only the offsets are load-bearing — every
93
+ * consumer reads those, and `lineColAt` derives line and column off the source
94
+ * — so the columns are left at the line's start rather than invented.
95
+ */
96
+ function spanOf(range, line, endLine) {
97
+ return {
98
+ start: { line, column: 1, offset: range.start },
99
+ end: { line: endLine, column: 1, offset: range.end },
100
+ };
101
+ }
102
+ /**
103
+ * One cell, holding its slice of the source twice over.
104
+ *
105
+ * The mdast `text` child is what an index over the mdast reads, and `hChildren` is
106
+ * what gets rendered — because the two doors do not agree. `mdast-util-to-hast`
107
+ * runs every mdast `text` node through `trimLines`, which strips the leading
108
+ * indentation off each line of a value: the nested map that `white-space:
109
+ * pre-wrap` exists to keep readable would arrive on the page already flattened,
110
+ * and the rendered text would stop being a slice of the source, which is the
111
+ * invariant offset-based decoration stands on. `hChildren` is handed to hast
112
+ * verbatim. Both are cut from the same `slice`, so they cannot drift apart.
113
+ */
114
+ function cellOf(type, tagName, source, range, line, endLine) {
115
+ const position = spanOf(range, line, endLine);
116
+ const value = source.slice(range.start, range.end);
117
+ // An empty range sends no child at all: there is nothing to slice, and a
118
+ // childless cell is what leaves it group-less in an index over the mdast — abstaining
119
+ // rather than claiming to hold prose it does not have.
120
+ const children = value === "" ? [] : [{ type: "text", value, position }];
121
+ return {
122
+ type,
123
+ data: {
124
+ hName: tagName,
125
+ hChildren: children.map((child) => ({ ...child })),
126
+ },
127
+ children,
128
+ position,
129
+ };
130
+ }
131
+ const keyCell = (source, range, line) => cellOf("frontmatterKey", "th", source, range, line, line);
132
+ const valueCell = (source, range, line, endLine) => cellOf("frontmatterValue", "td", source, range, line, endLine);
133
+ /** The subtree one frontmatter block becomes. */
134
+ function tableOf(source, block, fields) {
135
+ const rows = fields.map((field) => ({
136
+ type: "frontmatterField",
137
+ data: { hName: "tr" },
138
+ children: [
139
+ // Both cells always, even where the key is null: a consumer that reads
140
+ // this as a table takes its width from its first row, so a
141
+ // keyless field leading the block would narrow the whole frontmatter
142
+ // to one column and drop every value out of the diff. The CSS gives
143
+ // the row whose key cell is empty its full width back.
144
+ keyCell(source, field.key ?? { start: field.value.start, end: field.value.start }, field.line),
145
+ valueCell(source, field.value, field.line, field.endLine),
146
+ ],
147
+ position: spanOf({ start: field.key?.start ?? field.value.start, end: field.value.end }, field.line, field.endLine),
148
+ }));
149
+ const first = fields[0];
150
+ const last = fields.at(-1);
151
+ const body = {
152
+ type: "frontmatterBody",
153
+ data: { hName: "tbody" },
154
+ children: rows,
155
+ position: spanOf({
156
+ start: first?.key?.start ?? first?.value.start ?? block.start.offset ?? 0,
157
+ end: last?.value.end ?? block.end.offset ?? 0,
158
+ }, first?.line ?? block.start.line, last?.endLine ?? block.end.line),
159
+ };
160
+ return {
161
+ type: "frontmatter",
162
+ data: {
163
+ hName: "table",
164
+ hProperties: { className: ["markdown-frontmatter"] },
165
+ },
166
+ children: [body],
167
+ // The whole block, both fences included: that is the range a wholly-new
168
+ // frontmatter is highlighted over, and the source a removed one is quoted
169
+ // from.
170
+ position: block,
171
+ };
172
+ }
173
+ /**
174
+ * remark plugin: swap each `yaml` / `toml` node for a two-column table of its
175
+ * fields (T-240). It consumes what `remark-frontmatter` produces, so it has to
176
+ * run after it.
177
+ *
178
+ * A table-shaped subtree rather than a bespoke one, because anything that
179
+ * already compares tables reads that shape: it knows `table` / `tableRow` /
180
+ * `tableCell`, pairs rows by their leftmost cell, and splices a removed row
181
+ * back where it stood. Frontmatter is a two-column table whose keys are the
182
+ * row keys, so nothing new has to be taught — the data is laid out at an
183
+ * entrance that exists.
184
+ *
185
+ * Custom node types plus `data.hName`, not real mdast `table` nodes: the
186
+ * `table` handler in `mdast-util-to-hast` makes row 0 a `<thead>` header, and
187
+ * frontmatter has no header — the first field would be drawn as one. `hName`
188
+ * renames an element after that handler has run and cannot undo what it did,
189
+ * so the unknown-node route is the only one that controls the output exactly.
190
+ * It also puts the `<tbody>` there explicitly, which is what keeps a pass
191
+ * that restores a removed field's stand-in row from appending it to the end of
192
+ * the table instead of into its body.
193
+ */
194
+ export const remarkFrontmatterTable = () => (tree, file) => {
195
+ const source = String(file);
196
+ const children = [];
197
+ for (const child of tree.children) {
198
+ const sep = SEPARATOR[child.type];
199
+ if (sep === undefined || child.position === undefined) {
200
+ children.push(child);
201
+ continue;
202
+ }
203
+ const fields = frontmatterFields(source, child.position, sep);
204
+ // Nothing between the fences: the node goes, and with it the two `<hr>`s
205
+ // that used to stand in for it.
206
+ if (fields.length === 0)
207
+ continue;
208
+ children.push(tableOf(source, child.position, fields));
209
+ }
210
+ tree.children = children;
211
+ };
212
+ //# sourceMappingURL=remark-frontmatter-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remark-frontmatter-table.js","sourceRoot":"","sources":["../../src/lib/remark-frontmatter-table.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Root } from "mdast";
2
+ import type { Plugin } from "unified";
3
+ /**
4
+ * Show a link whose protocol is refused as the source the author wrote.
5
+ *
6
+ * react-markdown blanks the `href` of anything outside its protocol list,
7
+ * which stops the script but leaves a link-shaped thing that reloads the page
8
+ * when clicked. The same principle unsupported HTML is held to applies here:
9
+ * what cannot be rendered is shown as what was typed.
10
+ *
11
+ * The substitution is byte-for-byte the node's own source, so an index built
12
+ * over the mdast keeps reading the block as exact and every decoration offset
13
+ * inside it stays where it was. Doing this on the hast side instead would leave
14
+ * such an index believing the block is a link the width of its label while the
15
+ * DOM holds the longer source, and a decoration pass would drop what it cannot
16
+ * place in silence.
17
+ *
18
+ * A node with no position — one another plugin synthesised — keeps the
19
+ * blanked attribute it has today: the script is still stopped, and only that
20
+ * one link goes on showing nothing of where it pointed.
21
+ */
22
+ export declare const remarkRejectedUrlsAsText: Plugin<[], Root>;
23
+ //# sourceMappingURL=remark-rejected-urls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remark-rejected-urls.d.ts","sourceRoot":"","sources":["../../src/lib/remark-rejected-urls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,IAAI,EAAQ,MAAM,OAAO,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AA+BtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,CA4BnD,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { defaultUrlTransform } from "react-markdown";
2
+ /**
3
+ * Whether react-markdown will refuse this URL's protocol.
4
+ *
5
+ * Asked of the renderer's own transform rather than of a second protocol
6
+ * list: a safety predicate written twice is a safety predicate that will
7
+ * eventually disagree with itself, and this one already has an answer.
8
+ */
9
+ function rejected(url) {
10
+ return url !== "" && defaultUrlTransform(url) === "";
11
+ }
12
+ /** The node's own source, carrying its position so the offsets still line up. */
13
+ function asSource(node, source) {
14
+ const start = node.position?.start.offset;
15
+ const end = node.position?.end.offset;
16
+ if (start === undefined || end === undefined)
17
+ return null;
18
+ return {
19
+ type: "text",
20
+ value: source.slice(start, end),
21
+ position: node.position,
22
+ };
23
+ }
24
+ function definitionsOf(node, found) {
25
+ if (node.type === "definition")
26
+ found.set(node.identifier, node.url);
27
+ if (!("children" in node))
28
+ return;
29
+ for (const child of node.children)
30
+ definitionsOf(child, found);
31
+ }
32
+ /**
33
+ * Show a link whose protocol is refused as the source the author wrote.
34
+ *
35
+ * react-markdown blanks the `href` of anything outside its protocol list,
36
+ * which stops the script but leaves a link-shaped thing that reloads the page
37
+ * when clicked. The same principle unsupported HTML is held to applies here:
38
+ * what cannot be rendered is shown as what was typed.
39
+ *
40
+ * The substitution is byte-for-byte the node's own source, so an index built
41
+ * over the mdast keeps reading the block as exact and every decoration offset
42
+ * inside it stays where it was. Doing this on the hast side instead would leave
43
+ * such an index believing the block is a link the width of its label while the
44
+ * DOM holds the longer source, and a decoration pass would drop what it cannot
45
+ * place in silence.
46
+ *
47
+ * A node with no position — one another plugin synthesised — keeps the
48
+ * blanked attribute it has today: the script is still stopped, and only that
49
+ * one link goes on showing nothing of where it pointed.
50
+ */
51
+ export const remarkRejectedUrlsAsText = () => (tree, file) => {
52
+ const source = String(file);
53
+ // A reference's URL lives on the definition line, which markdown never
54
+ // renders — the reader is left with `[a][r]`, and the bad URL stays off
55
+ // the page exactly as it is today.
56
+ const definitions = new Map();
57
+ definitionsOf(tree, definitions);
58
+ const urlOf = (node) => {
59
+ if (node.type === "link" || node.type === "image")
60
+ return node.url;
61
+ if (node.type === "linkReference" || node.type === "imageReference") {
62
+ return definitions.get(node.identifier);
63
+ }
64
+ return undefined;
65
+ };
66
+ const visit = (parent) => {
67
+ parent.children = parent.children.map((child) => {
68
+ const url = urlOf(child);
69
+ if (url !== undefined && rejected(url)) {
70
+ return asSource(child, source) ?? child;
71
+ }
72
+ if ("children" in child)
73
+ visit(child);
74
+ return child;
75
+ });
76
+ };
77
+ visit(tree);
78
+ };
79
+ //# sourceMappingURL=remark-rejected-urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remark-rejected-urls.js","sourceRoot":"","sources":["../../src/lib/remark-rejected-urls.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,GAAG,KAAK,EAAE,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;AACvD,CAAC;AAED,iFAAiF;AACjF,SAAS,QAAQ,CAAC,IAAW,EAAE,MAAc;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC;IACtC,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,IAAW,EAAE,KAA0B;IAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;QAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC;QAAE,OAAO;IAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;QAAE,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GACnC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;IACnB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,uEAAuE;IACvE,wEAAwE;IACxE,mCAAmC;IACnC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAEjC,MAAM,KAAK,GAAG,CAAC,IAAW,EAAsB,EAAE;QAChD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC;QACnE,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACpE,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,MAAc,EAAQ,EAAE;QACrC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,GAAG,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvC,OAAO,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC;YAC1C,CAAC;YACD,IAAI,UAAU,IAAI,KAAK;gBAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC,CAA2B,CAAC;IAC/B,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { type Ref } from "react";
2
+ import type { MarkdownPlugin } from "./plugin.ts";
3
+ /**
4
+ * The plugins of the nearest enclosing `<Markdown>`; undefined outside one. A document embedded
5
+ * inside a document reads them, so it is drawn the way its host is.
6
+ */
7
+ export declare const MarkdownPluginsContext: import("react").Context<readonly MarkdownPlugin[] | undefined>;
8
+ export type MarkdownProps = {
9
+ children: string;
10
+ /**
11
+ * Keep this array stable: a module constant, or a memo. See `<Markdown>`.
12
+ * The first plugin is outermost: its wrappers render first, and their `Next` reaches the second.
13
+ */
14
+ plugins?: readonly MarkdownPlugin[];
15
+ /** Added to the `.markdown-body` root. */
16
+ className?: string;
17
+ ref?: Ref<HTMLDivElement>;
18
+ };
19
+ /**
20
+ * GitHub-style markdown: GFM, refused links drawn as their source, YAML and TOML frontmatter as a
21
+ * two-column table, and raw HTML escaped to its source except `<details>`/`<summary>` folds.
22
+ * Plugins append remark and rehype passes to that chain and wrap elements and code blocks; they
23
+ * cannot remove any of it. Code blocks are drawn through `@orz/ui-content`'s registry.
24
+ *
25
+ * Keep `plugins` stable. A fresh array, or a fresh plugin object in it, makes react-markdown
26
+ * reparse the document and React remount every overridden element, and either one collapses a live
27
+ * text selection inside it (T-60).
28
+ */
29
+ export declare function Markdown({ children, plugins, className, ref, }: MarkdownProps): import("react").JSX.Element;
30
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,GAAG,EAET,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,aAAa,CAAC;AAIrB;;;GAGG;AACH,eAAO,MAAM,sBAAsB,gEAEvB,CAAC;AAkJb,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IACpC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,OAAoB,EACpB,SAAS,EACT,GAAG,GACJ,EAAE,aAAa,+BA6Cf"}
@@ -0,0 +1,146 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Content } from "@orz/ui-content";
3
+ import { createContext, createElement, useMemo, } from "react";
4
+ import ReactMarkdown, {} from "react-markdown";
5
+ import { MARKDOWN_SYNTAX_PLUGINS } from "./lib/markdown-processor.js";
6
+ import { rehypeDetails } from "./lib/rehype-details.js";
7
+ import { CODE_CONTENT_START_ATTR, parseSourceLoc, SOURCE_LINE_ATTR, } from "./lib/rehype-source-lines.js";
8
+ const NO_PLUGINS = [];
9
+ /**
10
+ * The plugins of the nearest enclosing `<Markdown>`; undefined outside one. A document embedded
11
+ * inside a document reads them, so it is drawn the way its host is.
12
+ */
13
+ export const MarkdownPluginsContext = createContext(undefined);
14
+ /**
15
+ * Pull the code text and fence tag out of a `<pre>` element's hast node.
16
+ * Returns null for shapes that aren't a plain fenced block, which then
17
+ * keep the default `<pre>` rendering.
18
+ */
19
+ function parseFence(pre) {
20
+ const code = pre?.children.find((child) => child.type === "element" && child.tagName === "code");
21
+ if (code === undefined)
22
+ return null;
23
+ const className = Array.isArray(code.properties.className)
24
+ ? code.properties.className
25
+ : [];
26
+ const tag = className
27
+ .find((name) => typeof name === "string" ? name.startsWith("language-") : false)
28
+ ?.slice("language-".length);
29
+ const text = code.children
30
+ .filter((child) => child.type === "text")
31
+ .map((child) => child.value)
32
+ .join("");
33
+ // Fenced blocks always carry a trailing newline; a code renderer would
34
+ // show it as an empty last line.
35
+ return { text: text.replace(/\n$/, ""), tag };
36
+ }
37
+ function RegistryFence({ code, lang }) {
38
+ return (_jsx(Content, { source: { kind: "inline", text: code, lang }, placement: "document" }));
39
+ }
40
+ function fenceChain(plugins) {
41
+ let current = RegistryFence;
42
+ for (const plugin of [...plugins].reverse()) {
43
+ const Wrapper = plugin.fence;
44
+ if (Wrapper === undefined)
45
+ continue;
46
+ const Inner = current;
47
+ current = function FenceWrapper(props) {
48
+ return _jsx(Wrapper, { ...props, Next: Inner });
49
+ };
50
+ }
51
+ return current;
52
+ }
53
+ function preFor(Fence) {
54
+ return function MarkdownPre({ node, children, ...props }) {
55
+ const fence = parseFence(node);
56
+ if (fence === null)
57
+ return _jsx("pre", { ...props, children: children });
58
+ // Whatever draws the fence must not drop the source-line stamp a caller
59
+ // anchors selections to (T-52). A wrapper re-carries it, plus where the
60
+ // code content starts: the stamped range opens on the ``` marker for
61
+ // fenced blocks but on the first code line for indented ones.
62
+ const stamp = props[SOURCE_LINE_ATTR];
63
+ const loc = typeof stamp === "string" ? parseSourceLoc(stamp) : null;
64
+ // Decoration classes ride on the <pre> too (T-158) and would otherwise
65
+ // vanish in the swap.
66
+ const className = ["markdown-fence", props.className]
67
+ .filter(Boolean)
68
+ .join(" ");
69
+ const wrapperProps = loc === null
70
+ ? { className }
71
+ : {
72
+ [SOURCE_LINE_ATTR]: stamp,
73
+ [CODE_CONTENT_START_ATTR]: (() => {
74
+ // Whether there is a marker line to skip is answered by the line
75
+ // count, not by reading the opening line: a fence inside a
76
+ // blockquote opens on "> ```ts", whose `>` survives trimStart().
77
+ const span = loc.end - loc.start + 1;
78
+ const contentLines = fence.text === "" ? 0 : fence.text.split("\n").length;
79
+ return loc.start + (span - contentLines >= 1 ? 1 : 0);
80
+ })(),
81
+ className,
82
+ };
83
+ return (_jsx("div", { ...wrapperProps, children: _jsx(Fence, { code: fence.text, lang: fence.tag, loc: loc }) }));
84
+ };
85
+ }
86
+ function elementChain(tag, plugins) {
87
+ let current = function Plain({ node: _node, ...props }) {
88
+ return createElement(tag, props);
89
+ };
90
+ for (const plugin of [...plugins].reverse()) {
91
+ const Wrapper = plugin.components?.[tag];
92
+ if (Wrapper === undefined)
93
+ continue;
94
+ const Inner = current;
95
+ current = function ElementWrapper(props) {
96
+ return _jsx(Wrapper, { ...props, Next: Inner });
97
+ };
98
+ }
99
+ return current;
100
+ }
101
+ function componentsFor(plugins) {
102
+ const components = {
103
+ pre: preFor(fenceChain(plugins)),
104
+ };
105
+ const tags = new Set(plugins.flatMap((plugin) => Object.keys(plugin.components ?? {})));
106
+ for (const tag of tags) {
107
+ if (tag === "pre")
108
+ continue;
109
+ components[tag] = elementChain(tag, plugins);
110
+ }
111
+ return components;
112
+ }
113
+ /**
114
+ * GitHub-style markdown: GFM, refused links drawn as their source, YAML and TOML frontmatter as a
115
+ * two-column table, and raw HTML escaped to its source except `<details>`/`<summary>` folds.
116
+ * Plugins append remark and rehype passes to that chain and wrap elements and code blocks; they
117
+ * cannot remove any of it. Code blocks are drawn through `@orz/ui-content`'s registry.
118
+ *
119
+ * Keep `plugins` stable. A fresh array, or a fresh plugin object in it, makes react-markdown
120
+ * reparse the document and React remount every overridden element, and either one collapses a live
121
+ * text selection inside it (T-60).
122
+ */
123
+ export function Markdown({ children, plugins = NO_PLUGINS, className, ref, }) {
124
+ // The override map must be referentially stable across re-renders: every
125
+ // entry is a component built here, and a fresh map makes React treat each
126
+ // one as a NEW component type, unmounting and rebuilding those DOM
127
+ // subtrees on every parent render. Rebuilt text nodes silently collapse
128
+ // any live text selection — which is what broke annotating a selection
129
+ // (T-60): a floating button's own appearance re-rendered the document and
130
+ // destroyed the selection it was offering to annotate.
131
+ const components = useMemo(() => componentsFor(plugins), [plugins]);
132
+ // `rehypeDetails` goes first so that every later pass walks the tree the
133
+ // reader will get, rather than one where a fold is still a pair of raw HTML
134
+ // strings. The memos are the identity rule above, applied to the plugin
135
+ // lists react-markdown compares.
136
+ const remarkPlugins = useMemo(() => [
137
+ ...MARKDOWN_SYNTAX_PLUGINS,
138
+ ...plugins.flatMap((plugin) => plugin.remarkPlugins ?? []),
139
+ ], [plugins]);
140
+ const rehypePlugins = useMemo(() => [
141
+ rehypeDetails,
142
+ ...plugins.flatMap((plugin) => plugin.rehypePlugins ?? []),
143
+ ], [plugins]);
144
+ return (_jsx("div", { ref: ref, className: className ? `markdown-body ${className}` : "markdown-body", children: _jsx(MarkdownPluginsContext.Provider, { value: plugins, children: _jsx(ReactMarkdown, { remarkPlugins: remarkPlugins, rehypePlugins: rehypePlugins, components: components, children: children }) }) }));
145
+ }
146
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { Element } from "hast";
2
+ import type { ComponentProps, ComponentType, JSX } from "react";
3
+ import type { PluggableList } from "unified";
4
+ /** What react-markdown hands an element override: the element's props, plus its hast node. */
5
+ export type ElementProps<Tag extends keyof JSX.IntrinsicElements> = ComponentProps<Tag> & {
6
+ node?: Element;
7
+ };
8
+ /** Tags a plugin may wrap. `<pre>` is `<Markdown>`'s own: it reads fences out of it. */
9
+ export type WrappableTag = Exclude<keyof JSX.IntrinsicElements, "pre">;
10
+ export type FenceProps = {
11
+ /** The contents, without the trailing newline every fence carries. */
12
+ code: string;
13
+ /** The info string's first word as written; undefined for an indented block. */
14
+ lang: string | undefined;
15
+ /** 1-based inclusive source lines of the whole block, markers included; null when unstamped. */
16
+ loc: {
17
+ start: number;
18
+ end: number;
19
+ } | null;
20
+ };
21
+ export type ElementWrapper<Tag extends WrappableTag> = ComponentType<ElementProps<Tag> & {
22
+ Next: ComponentType<ElementProps<Tag>>;
23
+ }>;
24
+ export type MarkdownPlugin = {
25
+ name: string;
26
+ /** Appended, in list order, after the fixed syntax chain. */
27
+ remarkPlugins?: PluggableList;
28
+ /** Appended, in list order, after `rehypeDetails`. */
29
+ rehypePlugins?: PluggableList;
30
+ /** Wrap any element. `Next` renders it the way the plugins after this one would. */
31
+ components?: {
32
+ [Tag in WrappableTag]?: ElementWrapper<Tag>;
33
+ };
34
+ /** Wrap a parsed code block. The innermost `Next` is the registry. */
35
+ fence?: ComponentType<FenceProps & {
36
+ Next: ComponentType<FenceProps>;
37
+ }>;
38
+ };
39
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,8FAA8F;AAC9F,MAAM,MAAM,YAAY,CAAC,GAAG,SAAS,MAAM,GAAG,CAAC,iBAAiB,IAC9D,cAAc,CAAC,GAAG,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3C,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;AAEvE,MAAM,MAAM,UAAU,GAAG;IACvB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,gGAAgG;IAChG,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,GAAG,SAAS,YAAY,IAAI,aAAa,CAClE,YAAY,CAAC,GAAG,CAAC,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAA;CAAE,CAC/D,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,sDAAsD;IACtD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,oFAAoF;IACpF,UAAU,CAAC,EAAE;SAAG,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC;KAAE,CAAC;IAC7D,sEAAsE;IACtE,KAAK,CAAC,EAAE,aAAa,CAAC,UAAU,GAAG;QAAE,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;KAAE,CAAC,CAAC;CACzE,CAAC"}
package/dist/plugin.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":""}