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.
Files changed (187) hide show
  1. package/dist/cjs/admonitions.d.ts +32 -0
  2. package/dist/cjs/admonitions.d.ts.map +1 -0
  3. package/dist/cjs/admonitions.js +126 -0
  4. package/dist/cjs/basic.d.ts +62 -0
  5. package/dist/cjs/basic.d.ts.map +1 -0
  6. package/dist/cjs/basic.js +125 -0
  7. package/dist/cjs/card.d.ts +27 -0
  8. package/dist/cjs/card.d.ts.map +1 -0
  9. package/dist/cjs/card.js +64 -0
  10. package/dist/cjs/cite.d.ts +6 -0
  11. package/dist/cjs/cite.d.ts.map +1 -0
  12. package/dist/cjs/cite.js +36 -0
  13. package/dist/cjs/code.d.ts +21 -0
  14. package/dist/cjs/code.d.ts.map +1 -0
  15. package/dist/cjs/code.js +66 -0
  16. package/dist/cjs/components/ClickPopover.d.ts +11 -0
  17. package/dist/cjs/components/ClickPopover.d.ts.map +1 -0
  18. package/dist/cjs/components/ClickPopover.js +18 -0
  19. package/dist/cjs/components/CopyIcon.d.ts +5 -0
  20. package/dist/cjs/components/CopyIcon.d.ts.map +1 -0
  21. package/dist/cjs/components/CopyIcon.js +28 -0
  22. package/dist/cjs/components/HoverPopover.d.ts +9 -0
  23. package/dist/cjs/components/HoverPopover.d.ts.map +1 -0
  24. package/dist/cjs/components/HoverPopover.js +32 -0
  25. package/dist/cjs/components/LinkCard.d.ts +11 -0
  26. package/dist/cjs/components/LinkCard.d.ts.map +1 -0
  27. package/dist/cjs/components/LinkCard.js +15 -0
  28. package/dist/cjs/convertToReact.d.ts +6 -0
  29. package/dist/cjs/convertToReact.d.ts.map +1 -0
  30. package/dist/cjs/convertToReact.js +30 -0
  31. package/dist/cjs/crossReference.d.ts +13 -0
  32. package/dist/cjs/crossReference.d.ts.map +1 -0
  33. package/dist/cjs/crossReference.js +92 -0
  34. package/dist/cjs/dropdown.d.ts +16 -0
  35. package/dist/cjs/dropdown.d.ts.map +1 -0
  36. package/dist/cjs/dropdown.js +27 -0
  37. package/dist/cjs/extensions/chemicalFormula.d.ts +7 -0
  38. package/dist/cjs/extensions/chemicalFormula.d.ts.map +1 -0
  39. package/dist/cjs/extensions/chemicalFormula.js +39 -0
  40. package/dist/cjs/extensions/index.d.ts +4 -0
  41. package/dist/cjs/extensions/index.d.ts.map +1 -0
  42. package/dist/cjs/extensions/index.js +9 -0
  43. package/dist/cjs/extensions/siunits.d.ts +7 -0
  44. package/dist/cjs/extensions/siunits.d.ts.map +1 -0
  45. package/dist/cjs/extensions/siunits.js +12 -0
  46. package/dist/cjs/footnotes.d.ts +11 -0
  47. package/dist/cjs/footnotes.d.ts.map +1 -0
  48. package/dist/cjs/footnotes.js +24 -0
  49. package/dist/cjs/grid.d.ts +11 -0
  50. package/dist/cjs/grid.d.ts.map +1 -0
  51. package/dist/cjs/grid.js +117 -0
  52. package/dist/cjs/heading.d.ts +14 -0
  53. package/dist/cjs/heading.d.ts.map +1 -0
  54. package/dist/cjs/heading.js +40 -0
  55. package/dist/cjs/iframe.d.ts +7 -0
  56. package/dist/cjs/iframe.d.ts.map +1 -0
  57. package/dist/cjs/iframe.js +24 -0
  58. package/dist/cjs/image.d.ts +11 -0
  59. package/dist/cjs/image.d.ts.map +1 -0
  60. package/dist/cjs/image.js +52 -0
  61. package/dist/cjs/index.d.ts +9 -0
  62. package/dist/cjs/index.d.ts.map +1 -0
  63. package/dist/cjs/index.js +45 -0
  64. package/dist/cjs/inlineError.d.ts +8 -0
  65. package/dist/cjs/inlineError.d.ts.map +1 -0
  66. package/dist/cjs/inlineError.js +9 -0
  67. package/dist/cjs/links/github.d.ts +12 -0
  68. package/dist/cjs/links/github.d.ts.map +1 -0
  69. package/dist/cjs/links/github.js +63 -0
  70. package/dist/cjs/links/index.d.ts +14 -0
  71. package/dist/cjs/links/index.d.ts.map +1 -0
  72. package/dist/cjs/links/index.js +68 -0
  73. package/dist/cjs/links/rrid.d.ts +5 -0
  74. package/dist/cjs/links/rrid.d.ts.map +1 -0
  75. package/dist/cjs/links/rrid.js +35 -0
  76. package/dist/cjs/links/wiki.d.ts +8 -0
  77. package/dist/cjs/links/wiki.d.ts.map +1 -0
  78. package/dist/cjs/links/wiki.js +39 -0
  79. package/dist/cjs/math.d.ts +13 -0
  80. package/dist/cjs/math.d.ts.map +1 -0
  81. package/dist/cjs/math.js +29 -0
  82. package/dist/cjs/reactive.d.ts +88 -0
  83. package/dist/cjs/reactive.d.ts.map +1 -0
  84. package/dist/cjs/reactive.js +64 -0
  85. package/dist/cjs/tabs.d.ts +12 -0
  86. package/dist/cjs/tabs.d.ts.map +1 -0
  87. package/dist/cjs/tabs.js +38 -0
  88. package/dist/types/admonitions.d.ts +32 -0
  89. package/dist/types/admonitions.d.ts.map +1 -0
  90. package/dist/types/basic.d.ts +62 -0
  91. package/dist/types/basic.d.ts.map +1 -0
  92. package/dist/types/card.d.ts +27 -0
  93. package/dist/types/card.d.ts.map +1 -0
  94. package/dist/types/cite.d.ts +6 -0
  95. package/dist/types/cite.d.ts.map +1 -0
  96. package/dist/types/code.d.ts +21 -0
  97. package/dist/types/code.d.ts.map +1 -0
  98. package/dist/types/components/ClickPopover.d.ts +11 -0
  99. package/dist/types/components/ClickPopover.d.ts.map +1 -0
  100. package/dist/types/components/CopyIcon.d.ts +5 -0
  101. package/dist/types/components/CopyIcon.d.ts.map +1 -0
  102. package/dist/types/components/HoverPopover.d.ts +9 -0
  103. package/dist/types/components/HoverPopover.d.ts.map +1 -0
  104. package/dist/types/components/LinkCard.d.ts +11 -0
  105. package/dist/types/components/LinkCard.d.ts.map +1 -0
  106. package/dist/types/convertToReact.d.ts +6 -0
  107. package/dist/types/convertToReact.d.ts.map +1 -0
  108. package/dist/types/crossReference.d.ts +13 -0
  109. package/dist/types/crossReference.d.ts.map +1 -0
  110. package/dist/types/dropdown.d.ts +16 -0
  111. package/dist/types/dropdown.d.ts.map +1 -0
  112. package/dist/types/extensions/chemicalFormula.d.ts +7 -0
  113. package/dist/types/extensions/chemicalFormula.d.ts.map +1 -0
  114. package/dist/types/extensions/index.d.ts +4 -0
  115. package/dist/types/extensions/index.d.ts.map +1 -0
  116. package/dist/types/extensions/siunits.d.ts +7 -0
  117. package/dist/types/extensions/siunits.d.ts.map +1 -0
  118. package/dist/types/footnotes.d.ts +11 -0
  119. package/dist/types/footnotes.d.ts.map +1 -0
  120. package/dist/types/grid.d.ts +11 -0
  121. package/dist/types/grid.d.ts.map +1 -0
  122. package/dist/types/heading.d.ts +14 -0
  123. package/dist/types/heading.d.ts.map +1 -0
  124. package/dist/types/iframe.d.ts +7 -0
  125. package/dist/types/iframe.d.ts.map +1 -0
  126. package/dist/types/image.d.ts +11 -0
  127. package/dist/types/image.d.ts.map +1 -0
  128. package/dist/types/index.d.ts +9 -0
  129. package/dist/types/index.d.ts.map +1 -0
  130. package/dist/types/inlineError.d.ts +8 -0
  131. package/dist/types/inlineError.d.ts.map +1 -0
  132. package/dist/types/links/github.d.ts +12 -0
  133. package/dist/types/links/github.d.ts.map +1 -0
  134. package/dist/types/links/index.d.ts +14 -0
  135. package/dist/types/links/index.d.ts.map +1 -0
  136. package/dist/types/links/rrid.d.ts +5 -0
  137. package/dist/types/links/rrid.d.ts.map +1 -0
  138. package/dist/types/links/wiki.d.ts +8 -0
  139. package/dist/types/links/wiki.d.ts.map +1 -0
  140. package/dist/types/math.d.ts +13 -0
  141. package/dist/types/math.d.ts.map +1 -0
  142. package/dist/types/reactive.d.ts +88 -0
  143. package/dist/types/reactive.d.ts.map +1 -0
  144. package/dist/types/tabs.d.ts +12 -0
  145. package/dist/types/tabs.d.ts.map +1 -0
  146. package/package.json +18 -21
  147. package/src/admonitions.tsx +0 -183
  148. package/src/basic.tsx +0 -229
  149. package/src/card.tsx +0 -153
  150. package/src/cite.tsx +0 -43
  151. package/src/code.tsx +0 -119
  152. package/src/components/ClickPopover.tsx +0 -56
  153. package/src/components/CopyIcon.tsx +0 -40
  154. package/src/components/HoverPopover.tsx +0 -60
  155. package/src/components/LinkCard.tsx +0 -42
  156. package/src/convertToReact.ts +0 -33
  157. package/src/crossReference.tsx +0 -139
  158. package/src/dropdown.tsx +0 -69
  159. package/src/extensions/chemicalFormula.tsx +0 -42
  160. package/src/extensions/index.tsx +0 -10
  161. package/src/extensions/siunits.tsx +0 -15
  162. package/src/footnotes.tsx +0 -30
  163. package/src/grid.tsx +0 -127
  164. package/src/heading.tsx +0 -68
  165. package/src/iframe.tsx +0 -42
  166. package/src/image.tsx +0 -97
  167. package/src/index.tsx +0 -65
  168. package/src/inlineError.tsx +0 -15
  169. package/src/links/index.tsx +0 -132
  170. package/src/links/rrid.tsx +0 -81
  171. package/src/links/wiki.tsx +0 -119
  172. package/src/math.tsx +0 -81
  173. package/src/mermaid.tsx +0 -49
  174. package/src/myst.tsx +0 -226
  175. package/src/output/components.tsx +0 -34
  176. package/src/output/error.tsx +0 -20
  177. package/src/output/hooks.ts +0 -127
  178. package/src/output/index.tsx +0 -7
  179. package/src/output/jupyter.tsx +0 -86
  180. package/src/output/output.tsx +0 -79
  181. package/src/output/outputBlock.tsx +0 -21
  182. package/src/output/safe.tsx +0 -84
  183. package/src/output/selectors.ts +0 -15
  184. package/src/output/stream.tsx +0 -18
  185. package/src/reactive.tsx +0 -64
  186. package/src/tabs.tsx +0 -63
  187. 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
- }
@@ -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
- }
@@ -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;
@@ -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;