agent-canvas 0.1.36 → 0.1.37
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.
|
@@ -3,6 +3,27 @@ import { marked } from "marked";
|
|
|
3
3
|
|
|
4
4
|
marked.setOptions({ gfm: true, breaks: false });
|
|
5
5
|
|
|
6
|
+
/** Host tags that flow inline and must not break a prose run into separate blocks. */
|
|
7
|
+
const INLINE_TAGS = new Set([
|
|
8
|
+
"a", "abbr", "b", "br", "code", "del", "em", "i", "kbd", "mark",
|
|
9
|
+
"q", "s", "small", "span", "strong", "sub", "sup", "time", "u",
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
/** Custom components that render inline (e.g. <Priority>). */
|
|
13
|
+
const INLINE_COMPONENTS = new Set(["Priority"]);
|
|
14
|
+
|
|
15
|
+
function isInlineNode(node: React.ReactNode): boolean {
|
|
16
|
+
if (typeof node === "string" || typeof node === "number") return true;
|
|
17
|
+
if (!React.isValidElement(node)) return false;
|
|
18
|
+
const type = node.type;
|
|
19
|
+
if (typeof type === "string") return INLINE_TAGS.has(type);
|
|
20
|
+
if (typeof type === "function") {
|
|
21
|
+
const name = (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name;
|
|
22
|
+
return name ? INLINE_COMPONENTS.has(name) : false;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
6
27
|
function renderTextAsMarkdown(text: string, key: string): React.ReactNode {
|
|
7
28
|
const trimmed = text.trim();
|
|
8
29
|
if (!trimmed) return null;
|
|
@@ -18,30 +39,54 @@ function renderTextAsMarkdown(text: string, key: string): React.ReactNode {
|
|
|
18
39
|
);
|
|
19
40
|
}
|
|
20
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Render a run of inline content (text + inline JSX like <code>/<strong>) as a single
|
|
44
|
+
* flowing paragraph. Text segments are parsed as inline markdown; JSX passes through.
|
|
45
|
+
* No `data-md` attribute so the markdown exporter treats it as an inline container.
|
|
46
|
+
*/
|
|
47
|
+
function renderInlineRun(run: React.ReactNode[], key: string): React.ReactNode {
|
|
48
|
+
return (
|
|
49
|
+
<div key={key} className="prose-canvas">
|
|
50
|
+
{run.map((node, i) => {
|
|
51
|
+
if (typeof node === "string" || typeof node === "number") {
|
|
52
|
+
const html = marked.parseInline(String(node), { async: false }) as string;
|
|
53
|
+
return <span key={i} dangerouslySetInnerHTML={{ __html: html }} />;
|
|
54
|
+
}
|
|
55
|
+
return node;
|
|
56
|
+
})}
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
21
61
|
/**
|
|
22
62
|
* Auto-render markdown for string children, passing JSX children through.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
63
|
+
* Block-level JSX (Callout, Diff, etc.) breaks the prose into separate markdown blocks,
|
|
64
|
+
* while inline JSX (code, strong, links) stays within the surrounding paragraph so text
|
|
65
|
+
* keeps flowing instead of stacking one fragment per line.
|
|
25
66
|
*/
|
|
26
67
|
export function renderMarkdownChildren(children: React.ReactNode): React.ReactNode {
|
|
27
68
|
const kids = React.Children.toArray(children);
|
|
28
69
|
if (kids.length === 0) return null;
|
|
29
70
|
|
|
30
71
|
const result: React.ReactNode[] = [];
|
|
31
|
-
let
|
|
32
|
-
let
|
|
72
|
+
let segment: React.ReactNode[] = [];
|
|
73
|
+
let segIdx = 0;
|
|
33
74
|
|
|
34
75
|
const flush = () => {
|
|
35
|
-
if (
|
|
36
|
-
|
|
76
|
+
if (segment.length === 0) return;
|
|
77
|
+
const hasInlineJsx = segment.some((n) => typeof n !== "string" && typeof n !== "number");
|
|
78
|
+
if (hasInlineJsx) {
|
|
79
|
+
result.push(renderInlineRun(segment, `md-${segIdx++}`));
|
|
80
|
+
} else {
|
|
81
|
+
const node = renderTextAsMarkdown(segment.join(""), `md-${segIdx++}`);
|
|
37
82
|
if (node) result.push(node);
|
|
38
|
-
buffer = "";
|
|
39
83
|
}
|
|
84
|
+
segment = [];
|
|
40
85
|
};
|
|
41
86
|
|
|
42
87
|
for (const child of kids) {
|
|
43
|
-
if (
|
|
44
|
-
|
|
88
|
+
if (isInlineNode(child)) {
|
|
89
|
+
segment.push(child);
|
|
45
90
|
} else {
|
|
46
91
|
flush();
|
|
47
92
|
result.push(child);
|