myst-to-react 0.1.18 → 0.1.20
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/dist/cjs/admonitions.d.ts +32 -0
- package/dist/cjs/admonitions.d.ts.map +1 -0
- package/dist/cjs/admonitions.js +126 -0
- package/dist/cjs/basic.d.ts +62 -0
- package/dist/cjs/basic.d.ts.map +1 -0
- package/dist/cjs/basic.js +125 -0
- package/dist/cjs/card.d.ts +27 -0
- package/dist/cjs/card.d.ts.map +1 -0
- package/dist/cjs/card.js +64 -0
- package/dist/cjs/cite.d.ts +6 -0
- package/dist/cjs/cite.d.ts.map +1 -0
- package/dist/cjs/cite.js +36 -0
- package/dist/cjs/code.d.ts +21 -0
- package/dist/cjs/code.d.ts.map +1 -0
- package/dist/cjs/code.js +66 -0
- package/dist/cjs/components/ClickPopover.d.ts +11 -0
- package/dist/cjs/components/ClickPopover.d.ts.map +1 -0
- package/dist/cjs/components/ClickPopover.js +18 -0
- package/dist/cjs/components/CopyIcon.d.ts +5 -0
- package/dist/cjs/components/CopyIcon.d.ts.map +1 -0
- package/dist/cjs/components/CopyIcon.js +28 -0
- package/dist/cjs/components/HoverPopover.d.ts +9 -0
- package/dist/cjs/components/HoverPopover.d.ts.map +1 -0
- package/dist/cjs/components/HoverPopover.js +32 -0
- package/dist/cjs/components/LinkCard.d.ts +11 -0
- package/dist/cjs/components/LinkCard.d.ts.map +1 -0
- package/dist/cjs/components/LinkCard.js +15 -0
- package/dist/cjs/convertToReact.d.ts +6 -0
- package/dist/cjs/convertToReact.d.ts.map +1 -0
- package/dist/cjs/convertToReact.js +30 -0
- package/dist/cjs/crossReference.d.ts +13 -0
- package/dist/cjs/crossReference.d.ts.map +1 -0
- package/dist/cjs/crossReference.js +92 -0
- package/dist/cjs/dropdown.d.ts +16 -0
- package/dist/cjs/dropdown.d.ts.map +1 -0
- package/dist/cjs/dropdown.js +27 -0
- package/dist/cjs/extensions/chemicalFormula.d.ts +7 -0
- package/dist/cjs/extensions/chemicalFormula.d.ts.map +1 -0
- package/dist/cjs/extensions/chemicalFormula.js +39 -0
- package/dist/cjs/extensions/index.d.ts +4 -0
- package/dist/cjs/extensions/index.d.ts.map +1 -0
- package/dist/cjs/extensions/index.js +9 -0
- package/dist/cjs/extensions/siunits.d.ts +7 -0
- package/dist/cjs/extensions/siunits.d.ts.map +1 -0
- package/dist/cjs/extensions/siunits.js +12 -0
- package/dist/cjs/footnotes.d.ts +11 -0
- package/dist/cjs/footnotes.d.ts.map +1 -0
- package/dist/cjs/footnotes.js +24 -0
- package/dist/cjs/grid.d.ts +11 -0
- package/dist/cjs/grid.d.ts.map +1 -0
- package/dist/cjs/grid.js +117 -0
- package/dist/cjs/heading.d.ts +14 -0
- package/dist/cjs/heading.d.ts.map +1 -0
- package/dist/cjs/heading.js +40 -0
- package/dist/cjs/iframe.d.ts +7 -0
- package/dist/cjs/iframe.d.ts.map +1 -0
- package/dist/cjs/iframe.js +24 -0
- package/dist/cjs/image.d.ts +11 -0
- package/dist/cjs/image.d.ts.map +1 -0
- package/dist/cjs/image.js +52 -0
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +45 -0
- package/dist/cjs/inlineError.d.ts +8 -0
- package/dist/cjs/inlineError.d.ts.map +1 -0
- package/dist/cjs/inlineError.js +9 -0
- package/dist/cjs/links/github.d.ts +12 -0
- package/dist/cjs/links/github.d.ts.map +1 -0
- package/dist/cjs/links/github.js +63 -0
- package/dist/cjs/links/index.d.ts +14 -0
- package/dist/cjs/links/index.d.ts.map +1 -0
- package/dist/cjs/links/index.js +68 -0
- package/dist/cjs/links/rrid.d.ts +5 -0
- package/dist/cjs/links/rrid.d.ts.map +1 -0
- package/dist/cjs/links/rrid.js +35 -0
- package/dist/cjs/links/wiki.d.ts +8 -0
- package/dist/cjs/links/wiki.d.ts.map +1 -0
- package/dist/cjs/links/wiki.js +39 -0
- package/dist/cjs/math.d.ts +13 -0
- package/dist/cjs/math.d.ts.map +1 -0
- package/dist/cjs/math.js +29 -0
- package/dist/cjs/reactive.d.ts +88 -0
- package/dist/cjs/reactive.d.ts.map +1 -0
- package/dist/cjs/reactive.js +64 -0
- package/dist/cjs/tabs.d.ts +12 -0
- package/dist/cjs/tabs.d.ts.map +1 -0
- package/dist/cjs/tabs.js +38 -0
- package/dist/types/admonitions.d.ts +32 -0
- package/dist/types/admonitions.d.ts.map +1 -0
- package/dist/types/basic.d.ts +62 -0
- package/dist/types/basic.d.ts.map +1 -0
- package/dist/types/card.d.ts +27 -0
- package/dist/types/card.d.ts.map +1 -0
- package/dist/types/cite.d.ts +6 -0
- package/dist/types/cite.d.ts.map +1 -0
- package/dist/types/code.d.ts +21 -0
- package/dist/types/code.d.ts.map +1 -0
- package/dist/types/components/ClickPopover.d.ts +11 -0
- package/dist/types/components/ClickPopover.d.ts.map +1 -0
- package/dist/types/components/CopyIcon.d.ts +5 -0
- package/dist/types/components/CopyIcon.d.ts.map +1 -0
- package/dist/types/components/HoverPopover.d.ts +9 -0
- package/dist/types/components/HoverPopover.d.ts.map +1 -0
- package/dist/types/components/LinkCard.d.ts +11 -0
- package/dist/types/components/LinkCard.d.ts.map +1 -0
- package/dist/types/convertToReact.d.ts +6 -0
- package/dist/types/convertToReact.d.ts.map +1 -0
- package/dist/types/crossReference.d.ts +13 -0
- package/dist/types/crossReference.d.ts.map +1 -0
- package/dist/types/dropdown.d.ts +16 -0
- package/dist/types/dropdown.d.ts.map +1 -0
- package/dist/types/extensions/chemicalFormula.d.ts +7 -0
- package/dist/types/extensions/chemicalFormula.d.ts.map +1 -0
- package/dist/types/extensions/index.d.ts +4 -0
- package/dist/types/extensions/index.d.ts.map +1 -0
- package/dist/types/extensions/siunits.d.ts +7 -0
- package/dist/types/extensions/siunits.d.ts.map +1 -0
- package/dist/types/footnotes.d.ts +11 -0
- package/dist/types/footnotes.d.ts.map +1 -0
- package/dist/types/grid.d.ts +11 -0
- package/dist/types/grid.d.ts.map +1 -0
- package/dist/types/heading.d.ts +14 -0
- package/dist/types/heading.d.ts.map +1 -0
- package/dist/types/iframe.d.ts +7 -0
- package/dist/types/iframe.d.ts.map +1 -0
- package/dist/types/image.d.ts +11 -0
- package/dist/types/image.d.ts.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/inlineError.d.ts +8 -0
- package/dist/types/inlineError.d.ts.map +1 -0
- package/dist/types/links/github.d.ts +12 -0
- package/dist/types/links/github.d.ts.map +1 -0
- package/dist/types/links/index.d.ts +14 -0
- package/dist/types/links/index.d.ts.map +1 -0
- package/dist/types/links/rrid.d.ts +5 -0
- package/dist/types/links/rrid.d.ts.map +1 -0
- package/dist/types/links/wiki.d.ts +8 -0
- package/dist/types/links/wiki.d.ts.map +1 -0
- package/dist/types/math.d.ts +13 -0
- package/dist/types/math.d.ts.map +1 -0
- package/dist/types/reactive.d.ts +88 -0
- package/dist/types/reactive.d.ts.map +1 -0
- package/dist/types/tabs.d.ts +12 -0
- package/dist/types/tabs.d.ts.map +1 -0
- package/package.json +18 -21
- package/src/admonitions.tsx +0 -183
- package/src/basic.tsx +0 -229
- package/src/card.tsx +0 -153
- package/src/cite.tsx +0 -43
- package/src/code.tsx +0 -119
- package/src/components/ClickPopover.tsx +0 -56
- package/src/components/CopyIcon.tsx +0 -40
- package/src/components/HoverPopover.tsx +0 -60
- package/src/components/LinkCard.tsx +0 -42
- package/src/convertToReact.ts +0 -33
- package/src/crossReference.tsx +0 -139
- package/src/dropdown.tsx +0 -69
- package/src/extensions/chemicalFormula.tsx +0 -42
- package/src/extensions/index.tsx +0 -10
- package/src/extensions/siunits.tsx +0 -15
- package/src/footnotes.tsx +0 -30
- package/src/grid.tsx +0 -127
- package/src/heading.tsx +0 -68
- package/src/iframe.tsx +0 -42
- package/src/image.tsx +0 -97
- package/src/index.tsx +0 -65
- package/src/inlineError.tsx +0 -15
- package/src/links/index.tsx +0 -132
- package/src/links/rrid.tsx +0 -81
- package/src/links/wiki.tsx +0 -119
- package/src/math.tsx +0 -81
- package/src/mermaid.tsx +0 -49
- package/src/myst.tsx +0 -226
- package/src/output/components.tsx +0 -34
- package/src/output/error.tsx +0 -20
- package/src/output/hooks.ts +0 -127
- package/src/output/index.tsx +0 -7
- package/src/output/jupyter.tsx +0 -86
- package/src/output/output.tsx +0 -79
- package/src/output/outputBlock.tsx +0 -21
- package/src/output/safe.tsx +0 -84
- package/src/output/selectors.ts +0 -15
- package/src/output/stream.tsx +0 -18
- package/src/reactive.tsx +0 -64
- package/src/tabs.tsx +0 -63
- package/src/types.ts +0 -6
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Link as RemixLink } from '@remix-run/react';
|
|
2
|
-
import { ExternalLinkIcon } from '@heroicons/react/outline';
|
|
3
|
-
import classNames from 'classnames';
|
|
4
|
-
|
|
5
|
-
export function LinkCard({
|
|
6
|
-
url,
|
|
7
|
-
title,
|
|
8
|
-
internal = false,
|
|
9
|
-
loading = false,
|
|
10
|
-
description,
|
|
11
|
-
thumbnail,
|
|
12
|
-
}: {
|
|
13
|
-
url: string;
|
|
14
|
-
internal?: boolean;
|
|
15
|
-
loading?: boolean;
|
|
16
|
-
title: React.ReactNode;
|
|
17
|
-
description?: React.ReactNode;
|
|
18
|
-
thumbnail?: string;
|
|
19
|
-
}) {
|
|
20
|
-
return (
|
|
21
|
-
<div className={classNames('w-[300px]', { 'animate-pulse': loading })}>
|
|
22
|
-
{internal && (
|
|
23
|
-
<RemixLink to={url} className="block" prefetch="intent">
|
|
24
|
-
{title}
|
|
25
|
-
</RemixLink>
|
|
26
|
-
)}
|
|
27
|
-
{!internal && (
|
|
28
|
-
<a href={url} className="block" target="_blank" rel="noreferrer">
|
|
29
|
-
<ExternalLinkIcon className="w-4 h-4 float-right" />
|
|
30
|
-
{title}
|
|
31
|
-
</a>
|
|
32
|
-
)}
|
|
33
|
-
{!loading && thumbnail && (
|
|
34
|
-
<img src={thumbnail} className="w-full max-h-[200px] object-cover object-top" />
|
|
35
|
-
)}
|
|
36
|
-
{loading && (
|
|
37
|
-
<div className="animate-pulse bg-slate-100 dark:bg-slate-800 w-full h-[150px] mt-4" />
|
|
38
|
-
)}
|
|
39
|
-
{!loading && description && <div className="mt-2">{description}</div>}
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
42
|
-
}
|
package/src/convertToReact.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type React from 'react';
|
|
2
|
-
import { createElement as e } from 'react';
|
|
3
|
-
import type { NodeRenderer } from './types';
|
|
4
|
-
import type { GenericNode } from 'mystjs';
|
|
5
|
-
|
|
6
|
-
export function toReact(
|
|
7
|
-
fragment: GenericNode[],
|
|
8
|
-
replacements: Record<string, NodeRenderer>,
|
|
9
|
-
): React.ReactNode {
|
|
10
|
-
if (fragment.length === 0) return undefined;
|
|
11
|
-
return fragment.map((node) => {
|
|
12
|
-
if (node.type === 'text') return node.value;
|
|
13
|
-
const custom = replacements[node.type] as NodeRenderer | undefined;
|
|
14
|
-
if (node.children) {
|
|
15
|
-
const children = toReact(node.children, replacements);
|
|
16
|
-
if (custom) {
|
|
17
|
-
return custom(node, children);
|
|
18
|
-
}
|
|
19
|
-
return e('div', { key: node.key }, children);
|
|
20
|
-
}
|
|
21
|
-
if (custom) {
|
|
22
|
-
return custom(node, node.value);
|
|
23
|
-
}
|
|
24
|
-
return e('span', { children: node.value, key: node.key });
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function mystToReact(
|
|
29
|
-
content: GenericNode,
|
|
30
|
-
replacements: Record<string, NodeRenderer>,
|
|
31
|
-
): React.ReactNode {
|
|
32
|
-
return toReact(content.children ?? [], replacements);
|
|
33
|
-
}
|
package/src/crossReference.tsx
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { selectAll } from 'unist-util-select';
|
|
2
|
-
import { EXIT, SKIP, visit } from 'unist-util-visit';
|
|
3
|
-
import type { Root } from 'mdast';
|
|
4
|
-
import type { CrossReference } from 'myst-spec';
|
|
5
|
-
import LinkIcon from '@heroicons/react/outline/LinkIcon';
|
|
6
|
-
import ExternalLinkIcon from '@heroicons/react/outline/ExternalLinkIcon';
|
|
7
|
-
import { useReferences, useXRefState, XRefProvider } from '@curvenote/ui-providers';
|
|
8
|
-
import { useParse } from '.';
|
|
9
|
-
import { InlineError } from './inlineError';
|
|
10
|
-
import type { NodeRenderer } from './types';
|
|
11
|
-
import { ClickPopover } from './components/ClickPopover';
|
|
12
|
-
import useSWR from 'swr';
|
|
13
|
-
import { Link } from '@remix-run/react';
|
|
14
|
-
|
|
15
|
-
const MAX_NODES = 3; // Max nodes to show after a header
|
|
16
|
-
|
|
17
|
-
function selectMdastNodes(mdast: Root, identifier: string) {
|
|
18
|
-
const identifiers = selectAll(`[identifier=${identifier}],[key=${identifier}]`, mdast);
|
|
19
|
-
const container = identifiers.filter(({ type }) => type === 'container' || type === 'math')[0];
|
|
20
|
-
const nodes = container ? [container] : [];
|
|
21
|
-
if (nodes.length === 0 && identifiers.length > 0 && mdast) {
|
|
22
|
-
let begin = false;
|
|
23
|
-
visit(mdast, (node) => {
|
|
24
|
-
if ((begin && node.type === 'heading') || nodes.length >= MAX_NODES) {
|
|
25
|
-
return EXIT;
|
|
26
|
-
}
|
|
27
|
-
if ((node as any).identifier === identifier && node.type === 'heading') begin = true;
|
|
28
|
-
if (begin) {
|
|
29
|
-
nodes.push(node);
|
|
30
|
-
return SKIP; // Don't traverse the children
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
if (nodes.length === 0 && identifiers.length > 0) {
|
|
35
|
-
// If we haven't found anything, push the first identifier that isn't a cite or crossReference
|
|
36
|
-
const resolved = identifiers.filter(
|
|
37
|
-
(node) => node.type !== 'crossReference' && node.type !== 'cite',
|
|
38
|
-
)[0];
|
|
39
|
-
nodes.push(resolved ?? identifiers[0]);
|
|
40
|
-
}
|
|
41
|
-
return nodes;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const fetcher = (...args: Parameters<typeof fetch>) =>
|
|
45
|
-
fetch(...args).then((res) => {
|
|
46
|
-
if (res.status === 200) return res.json();
|
|
47
|
-
throw new Error(`Content returned with status ${res.status}.`);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
export function ReferencedContent({
|
|
51
|
-
identifier,
|
|
52
|
-
close,
|
|
53
|
-
}: {
|
|
54
|
-
identifier: string;
|
|
55
|
-
close: () => void;
|
|
56
|
-
}) {
|
|
57
|
-
const { remote, url } = useXRefState();
|
|
58
|
-
const external = url?.startsWith('http') ?? false;
|
|
59
|
-
const lookupUrl = external ? `/api/lookup?url=${url}.json` : `${url}.json`;
|
|
60
|
-
const { data, error } = useSWR(remote ? lookupUrl : null, fetcher);
|
|
61
|
-
const references = useReferences();
|
|
62
|
-
const mdast = data?.mdast ?? references?.article;
|
|
63
|
-
const nodes = selectMdastNodes(mdast, identifier);
|
|
64
|
-
const htmlId = (nodes[0] as any)?.html_id || (nodes[0] as any)?.identifier;
|
|
65
|
-
const link = `${url}${htmlId ? `#${htmlId}` : ''}`;
|
|
66
|
-
const onClose = () => {
|
|
67
|
-
// Need to close it first because the ID is on the page twice ...
|
|
68
|
-
close();
|
|
69
|
-
setTimeout(() => {
|
|
70
|
-
const el = document.getElementById(htmlId);
|
|
71
|
-
el?.scrollIntoView({ behavior: 'smooth' });
|
|
72
|
-
}, 10);
|
|
73
|
-
};
|
|
74
|
-
const children = useParse({ type: 'block', children: nodes });
|
|
75
|
-
if (remote && !data) {
|
|
76
|
-
return <>Loading...</>;
|
|
77
|
-
}
|
|
78
|
-
if (remote && error) {
|
|
79
|
-
return <>Error loading remote page.</>;
|
|
80
|
-
}
|
|
81
|
-
if (!nodes || nodes.length === 0) {
|
|
82
|
-
return (
|
|
83
|
-
<>
|
|
84
|
-
<InlineError value={identifier || 'No Label'} message="Cross Reference Not Found" />
|
|
85
|
-
</>
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
return (
|
|
89
|
-
<div className="exclude-from-outline">
|
|
90
|
-
{remote && external && (
|
|
91
|
-
<a href={link} className="absolute top-4 right-1" target="_blank">
|
|
92
|
-
<ExternalLinkIcon className="w-4 h-4" />
|
|
93
|
-
</a>
|
|
94
|
-
)}
|
|
95
|
-
{remote && !external && (
|
|
96
|
-
<Link to={link} className="absolute top-4 right-1" prefetch="intent">
|
|
97
|
-
<ExternalLinkIcon className="w-4 h-4" />
|
|
98
|
-
</Link>
|
|
99
|
-
)}
|
|
100
|
-
{!remote && (
|
|
101
|
-
<button onClick={onClose} className="absolute top-4 right-1">
|
|
102
|
-
<LinkIcon className="w-4 h-4" />
|
|
103
|
-
</button>
|
|
104
|
-
)}
|
|
105
|
-
<div className="popout">{children}</div>
|
|
106
|
-
</div>
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export const CrossReferenceNode: NodeRenderer<CrossReference> = (node, children) => {
|
|
111
|
-
if (!children) {
|
|
112
|
-
return (
|
|
113
|
-
<InlineError
|
|
114
|
-
key={node.key}
|
|
115
|
-
value={node.label || node.identifier || 'No Label'}
|
|
116
|
-
message="Cross Reference Not Found"
|
|
117
|
-
/>
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
return (
|
|
121
|
-
<ClickPopover
|
|
122
|
-
key={node.key}
|
|
123
|
-
card={({ close }) => (
|
|
124
|
-
<XRefProvider remote={(node as any).remote} url={(node as any).url}>
|
|
125
|
-
<ReferencedContent identifier={node.identifier as string} close={close} />
|
|
126
|
-
</XRefProvider>
|
|
127
|
-
)}
|
|
128
|
-
as="span"
|
|
129
|
-
>
|
|
130
|
-
{children}
|
|
131
|
-
</ClickPopover>
|
|
132
|
-
);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const CROSS_REFERENCE_RENDERERS = {
|
|
136
|
-
crossReference: CrossReferenceNode,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
export default CROSS_REFERENCE_RENDERERS;
|
package/src/dropdown.tsx
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { NodeRenderer } from './types';
|
|
3
|
-
import { ChevronRightIcon } from '@heroicons/react/solid';
|
|
4
|
-
import classNames from 'classnames';
|
|
5
|
-
|
|
6
|
-
type DropdownSpec = {
|
|
7
|
-
type: 'details';
|
|
8
|
-
open?: boolean;
|
|
9
|
-
};
|
|
10
|
-
type SummarySpec = {
|
|
11
|
-
type: 'summary';
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const iconClass = 'h-8 w-8 inline-block pl-2 mr-2 -translate-y-[1px]';
|
|
15
|
-
|
|
16
|
-
export const SummaryTitle: NodeRenderer<SummarySpec> = (node, children) => {
|
|
17
|
-
return children;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
function Details({
|
|
21
|
-
title,
|
|
22
|
-
children,
|
|
23
|
-
open,
|
|
24
|
-
}: {
|
|
25
|
-
title: React.ReactNode;
|
|
26
|
-
children: React.ReactNode[];
|
|
27
|
-
open?: boolean;
|
|
28
|
-
}) {
|
|
29
|
-
return (
|
|
30
|
-
<details
|
|
31
|
-
className={classNames(
|
|
32
|
-
'rounded-md my-4 shadow dark:shadow-2xl dark:shadow-neutral-900 overflow-hidden',
|
|
33
|
-
)}
|
|
34
|
-
open={open}
|
|
35
|
-
>
|
|
36
|
-
<summary
|
|
37
|
-
className={classNames(
|
|
38
|
-
'm-0 text-lg font-medium py-1 min-h-[2em] pl-3',
|
|
39
|
-
'cursor-pointer hover:shadow-[inset_0_0_0px_20px_#00000003] dark:hover:shadow-[inset_0_0_0px_20px_#FFFFFF03]',
|
|
40
|
-
'bg-gray-100 dark:bg-slate-900',
|
|
41
|
-
)}
|
|
42
|
-
>
|
|
43
|
-
<span className="text-neutral-900 dark:text-white">
|
|
44
|
-
<span className="block float-right font-thin text-sm text-neutral-700 dark:text-neutral-200">
|
|
45
|
-
<ChevronRightIcon className={classNames(iconClass, 'transition-transform')} />
|
|
46
|
-
</span>
|
|
47
|
-
{title}
|
|
48
|
-
</span>
|
|
49
|
-
</summary>
|
|
50
|
-
<div className="px-4 py-1 bg-gray-50 dark:bg-stone-800">{children}</div>
|
|
51
|
-
</details>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const DetailsRenderer: NodeRenderer<DropdownSpec> = (node, children) => {
|
|
56
|
-
const [title, ...rest] = children as any[];
|
|
57
|
-
return (
|
|
58
|
-
<Details key={node.key} title={title} open={node.open}>
|
|
59
|
-
{rest}
|
|
60
|
-
</Details>
|
|
61
|
-
);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const DROPDOWN_RENDERERS = {
|
|
65
|
-
details: DetailsRenderer,
|
|
66
|
-
summary: SummaryTitle,
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export default DROPDOWN_RENDERERS;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { NodeRenderer } from '../types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Separate numbers and letters so that numbers can be <sub>2</sub>
|
|
5
|
-
* @param formula a string H2O
|
|
6
|
-
* @returns ['H', '2', '0']
|
|
7
|
-
*/
|
|
8
|
-
function parseFormula(formula?: string) {
|
|
9
|
-
return [...(formula ?? '')].reduce((acc, letter) => {
|
|
10
|
-
const last = acc.pop();
|
|
11
|
-
const isNumber = letter.match(/[0-9]/);
|
|
12
|
-
const lastIsNumber = last?.match(/[0-9]/);
|
|
13
|
-
if (isNumber) {
|
|
14
|
-
if (lastIsNumber) {
|
|
15
|
-
return [...acc, `${last ?? ''}${letter}`];
|
|
16
|
-
}
|
|
17
|
-
return [...acc, last, letter].filter((v) => !!v) as string[];
|
|
18
|
-
}
|
|
19
|
-
if (lastIsNumber) {
|
|
20
|
-
return [...acc, last, letter].filter((v) => !!v) as string[];
|
|
21
|
-
}
|
|
22
|
-
return [...acc, `${last ?? ''}${letter}`];
|
|
23
|
-
}, [] as string[]);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const ChemicalFormula: NodeRenderer = (node) => {
|
|
27
|
-
const parts = parseFormula(node.value);
|
|
28
|
-
return (
|
|
29
|
-
<code key={node.key} className="text-inherit">
|
|
30
|
-
{parts.map((letter, index) => {
|
|
31
|
-
if (letter.match(/[0-9]/)) return <sub key={index}>{letter}</sub>;
|
|
32
|
-
return <span key={index}>{letter}</span>;
|
|
33
|
-
})}
|
|
34
|
-
</code>
|
|
35
|
-
);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const CHEM_RENDERERS = {
|
|
39
|
-
chemicalFormula: ChemicalFormula,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export default CHEM_RENDERERS;
|
package/src/extensions/index.tsx
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { NodeRenderer } from '../types';
|
|
2
|
-
import CHEM_RENDERERS from './chemicalFormula';
|
|
3
|
-
import SI_RENDERERS from './siunits';
|
|
4
|
-
|
|
5
|
-
const EXT_RENDERERS: Record<string, NodeRenderer> = {
|
|
6
|
-
...CHEM_RENDERERS,
|
|
7
|
-
...SI_RENDERERS,
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export default EXT_RENDERERS;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { NodeRenderer } from '../types';
|
|
2
|
-
|
|
3
|
-
export const SIUnits: NodeRenderer = (node) => {
|
|
4
|
-
return (
|
|
5
|
-
<code key={node.key} className="text-inherit" title={`${node.num} ${node.units}`}>
|
|
6
|
-
{node.value}
|
|
7
|
-
</code>
|
|
8
|
-
);
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const SI_RENDERERS = {
|
|
12
|
-
si: SIUnits,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default SI_RENDERERS;
|
package/src/footnotes.tsx
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { GenericParent } from 'mystjs';
|
|
2
|
-
import { useReferences } from '@curvenote/ui-providers';
|
|
3
|
-
import type { NodeRenderer } from '.';
|
|
4
|
-
import { useParse } from '.';
|
|
5
|
-
import { ClickPopover } from './components/ClickPopover';
|
|
6
|
-
|
|
7
|
-
export function FootnoteDefinition({ identifier }: { identifier: string }) {
|
|
8
|
-
const references = useReferences();
|
|
9
|
-
const node = references?.footnotes?.[identifier];
|
|
10
|
-
const children = useParse(node as GenericParent);
|
|
11
|
-
return <>{children}</>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const FootnoteReference: NodeRenderer = (node) => {
|
|
15
|
-
return (
|
|
16
|
-
<ClickPopover
|
|
17
|
-
key={node.key}
|
|
18
|
-
card={<FootnoteDefinition identifier={node.identifier as string} />}
|
|
19
|
-
as="span"
|
|
20
|
-
>
|
|
21
|
-
<sup>[{node.number ?? node.identifier}]</sup>
|
|
22
|
-
</ClickPopover>
|
|
23
|
-
);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const FOOTNOTE_RENDERERS = {
|
|
27
|
-
footnoteReference: FootnoteReference,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export default FOOTNOTE_RENDERERS;
|
package/src/grid.tsx
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import classNames from 'classnames';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import type { NodeRenderer } from './types';
|
|
4
|
-
|
|
5
|
-
type GridSpec = {
|
|
6
|
-
type: 'grid';
|
|
7
|
-
columns: number[];
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const gridClassNames = {
|
|
11
|
-
main: [
|
|
12
|
-
'grid-cols-1',
|
|
13
|
-
'grid-cols-2',
|
|
14
|
-
'grid-cols-3',
|
|
15
|
-
'grid-cols-4',
|
|
16
|
-
'grid-cols-5',
|
|
17
|
-
'grid-cols-6',
|
|
18
|
-
'grid-cols-7',
|
|
19
|
-
'grid-cols-8',
|
|
20
|
-
'grid-cols-9',
|
|
21
|
-
'grid-cols-10',
|
|
22
|
-
'grid-cols-11',
|
|
23
|
-
'grid-cols-12',
|
|
24
|
-
],
|
|
25
|
-
sm: [
|
|
26
|
-
'sm:grid-cols-1',
|
|
27
|
-
'sm:grid-cols-2',
|
|
28
|
-
'sm:grid-cols-3',
|
|
29
|
-
'sm:grid-cols-4',
|
|
30
|
-
'sm:grid-cols-5',
|
|
31
|
-
'sm:grid-cols-6',
|
|
32
|
-
'sm:grid-cols-7',
|
|
33
|
-
'sm:grid-cols-8',
|
|
34
|
-
'sm:grid-cols-9',
|
|
35
|
-
'sm:grid-cols-10',
|
|
36
|
-
'sm:grid-cols-11',
|
|
37
|
-
'sm:grid-cols-12',
|
|
38
|
-
],
|
|
39
|
-
md: [
|
|
40
|
-
'md:grid-cols-1',
|
|
41
|
-
'md:grid-cols-2',
|
|
42
|
-
'md:grid-cols-3',
|
|
43
|
-
'md:grid-cols-4',
|
|
44
|
-
'md:grid-cols-5',
|
|
45
|
-
'md:grid-cols-6',
|
|
46
|
-
'md:grid-cols-7',
|
|
47
|
-
'md:grid-cols-8',
|
|
48
|
-
'md:grid-cols-9',
|
|
49
|
-
'md:grid-cols-10',
|
|
50
|
-
'md:grid-cols-11',
|
|
51
|
-
'md:grid-cols-12',
|
|
52
|
-
],
|
|
53
|
-
lg: [
|
|
54
|
-
'lg:grid-cols-1',
|
|
55
|
-
'lg:grid-cols-2',
|
|
56
|
-
'lg:grid-cols-3',
|
|
57
|
-
'lg:grid-cols-4',
|
|
58
|
-
'lg:grid-cols-5',
|
|
59
|
-
'lg:grid-cols-6',
|
|
60
|
-
'lg:grid-cols-7',
|
|
61
|
-
'lg:grid-cols-8',
|
|
62
|
-
'lg:grid-cols-9',
|
|
63
|
-
'lg:grid-cols-10',
|
|
64
|
-
'lg:grid-cols-11',
|
|
65
|
-
'lg:grid-cols-12',
|
|
66
|
-
],
|
|
67
|
-
xl: [
|
|
68
|
-
'xl:grid-cols-1',
|
|
69
|
-
'xl:grid-cols-2',
|
|
70
|
-
'xl:grid-cols-3',
|
|
71
|
-
'xl:grid-cols-4',
|
|
72
|
-
'xl:grid-cols-5',
|
|
73
|
-
'xl:grid-cols-6',
|
|
74
|
-
'xl:grid-cols-7',
|
|
75
|
-
'xl:grid-cols-8',
|
|
76
|
-
'xl:grid-cols-9',
|
|
77
|
-
'xl:grid-cols-10',
|
|
78
|
-
'xl:grid-cols-11',
|
|
79
|
-
'xl:grid-cols-12',
|
|
80
|
-
],
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const DEFAULT_NUM_COLUMNS = 3;
|
|
84
|
-
|
|
85
|
-
function getColumnClassName(classes: string[], number?: string | number): string {
|
|
86
|
-
const num = Number(number);
|
|
87
|
-
if (!number || Number.isNaN(num)) {
|
|
88
|
-
return getColumnClassName(classes, DEFAULT_NUM_COLUMNS);
|
|
89
|
-
}
|
|
90
|
-
return classes[num - 1] ?? classes[DEFAULT_NUM_COLUMNS];
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function gridColumnClasses(columns?: number[]): string {
|
|
94
|
-
if (!columns || columns.length <= 1) {
|
|
95
|
-
return getColumnClassName(gridClassNames.main, columns?.[0]);
|
|
96
|
-
}
|
|
97
|
-
if (columns.length !== 4) {
|
|
98
|
-
return getColumnClassName(gridClassNames.main, columns[0]);
|
|
99
|
-
}
|
|
100
|
-
return [
|
|
101
|
-
// getColumnClassName(gridClassNames.main, columns[0]),
|
|
102
|
-
getColumnClassName(gridClassNames.sm, columns[0]),
|
|
103
|
-
getColumnClassName(gridClassNames.md, columns[1]),
|
|
104
|
-
getColumnClassName(gridClassNames.lg, columns[2]),
|
|
105
|
-
getColumnClassName(gridClassNames.xl, columns[3]),
|
|
106
|
-
].join(' ');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function Grid({ columns, children }: { columns?: number[]; children: React.ReactNode }) {
|
|
110
|
-
const gridClasses = gridColumnClasses(columns);
|
|
111
|
-
const gutterClasses = 'gap-4';
|
|
112
|
-
return <div className={classNames('grid', gridClasses, gutterClasses)}>{children}</div>;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export const GridRenderer: NodeRenderer<GridSpec> = (node, children) => {
|
|
116
|
-
return (
|
|
117
|
-
<Grid key={node.key} columns={node.columns}>
|
|
118
|
-
{children}
|
|
119
|
-
</Grid>
|
|
120
|
-
);
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const GRID_RENDERERS = {
|
|
124
|
-
grid: GridRenderer,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export default GRID_RENDERERS;
|
package/src/heading.tsx
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { Heading } from 'myst-spec';
|
|
2
|
-
import type { NodeRenderer } from './types';
|
|
3
|
-
import { createElement as e } from 'react';
|
|
4
|
-
import classNames from 'classnames';
|
|
5
|
-
import { useXRefState } from '@curvenote/ui-providers';
|
|
6
|
-
|
|
7
|
-
function getHelpHashText(kind: string) {
|
|
8
|
-
return `Link to this ${kind}`;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function HashLink({
|
|
12
|
-
id,
|
|
13
|
-
kind,
|
|
14
|
-
align = 'left',
|
|
15
|
-
}: {
|
|
16
|
-
id: string;
|
|
17
|
-
kind: string;
|
|
18
|
-
align?: 'left' | 'right';
|
|
19
|
-
}) {
|
|
20
|
-
const { inCrossRef } = useXRefState();
|
|
21
|
-
// If we are in a cross-reference popout, hide the hash links
|
|
22
|
-
if (inCrossRef) return null;
|
|
23
|
-
const helpText = getHelpHashText(kind);
|
|
24
|
-
return (
|
|
25
|
-
<a
|
|
26
|
-
className={classNames(
|
|
27
|
-
'select-none absolute top-0 font-normal no-underline transition-opacity opacity-0 group-hover:opacity-70',
|
|
28
|
-
{
|
|
29
|
-
'left-0 -translate-x-[100%] pr-3': align === 'left',
|
|
30
|
-
'right-0 translate-x-[100%] pl-3': align === 'right',
|
|
31
|
-
},
|
|
32
|
-
)}
|
|
33
|
-
href={`#${id}`}
|
|
34
|
-
title={helpText}
|
|
35
|
-
aria-label={helpText}
|
|
36
|
-
>
|
|
37
|
-
#
|
|
38
|
-
</a>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const Heading: NodeRenderer<Heading> = (node, children) => {
|
|
43
|
-
const { enumerator, depth, key, identifier, html_id } = node;
|
|
44
|
-
const id = html_id || identifier || key;
|
|
45
|
-
const textContent = (
|
|
46
|
-
<>
|
|
47
|
-
<HashLink id={id} align="left" kind="Section" />
|
|
48
|
-
{enumerator && <span className="select-none mr-3">{enumerator}</span>}
|
|
49
|
-
<span className="heading-text">{children}</span>
|
|
50
|
-
</>
|
|
51
|
-
);
|
|
52
|
-
// The `heading-text` class is picked up in the Outline to select without the enumerator and "#" link
|
|
53
|
-
return e(
|
|
54
|
-
`h${depth}`,
|
|
55
|
-
{
|
|
56
|
-
key: node.key,
|
|
57
|
-
id,
|
|
58
|
-
className: 'relative group',
|
|
59
|
-
},
|
|
60
|
-
textContent,
|
|
61
|
-
);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const HEADING_RENDERERS = {
|
|
65
|
-
heading: Heading,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default HEADING_RENDERERS;
|
package/src/iframe.tsx
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { NodeRenderer } from './types';
|
|
2
|
-
|
|
3
|
-
export const IFrame: NodeRenderer = (node) => {
|
|
4
|
-
return (
|
|
5
|
-
<figure
|
|
6
|
-
key={node.key}
|
|
7
|
-
id={node.label || undefined}
|
|
8
|
-
style={{ textAlign: node.align || 'center' }}
|
|
9
|
-
>
|
|
10
|
-
<div
|
|
11
|
-
style={{
|
|
12
|
-
position: 'relative',
|
|
13
|
-
display: 'inline-block',
|
|
14
|
-
paddingBottom: '60%',
|
|
15
|
-
width: `min(max(${node.width || 70}%, 500px), 100%)`,
|
|
16
|
-
}}
|
|
17
|
-
>
|
|
18
|
-
<iframe
|
|
19
|
-
width="100%"
|
|
20
|
-
height="100%"
|
|
21
|
-
src={node.src}
|
|
22
|
-
allowFullScreen
|
|
23
|
-
allow="autoplay"
|
|
24
|
-
style={{
|
|
25
|
-
width: '100%',
|
|
26
|
-
height: '100%',
|
|
27
|
-
position: 'absolute',
|
|
28
|
-
top: 0,
|
|
29
|
-
left: 0,
|
|
30
|
-
border: 'none',
|
|
31
|
-
}}
|
|
32
|
-
></iframe>
|
|
33
|
-
</div>
|
|
34
|
-
</figure>
|
|
35
|
-
);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const IFRAME_RENDERERS = {
|
|
39
|
-
iframe: IFrame,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export default IFRAME_RENDERERS;
|