@curvenote/renderers 0.6.12 → 1.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.
- package/dist/articles.d.ts.map +1 -1
- package/dist/articles.js +2 -11
- package/dist/components/admonition.d.ts +18 -0
- package/dist/components/admonition.d.ts.map +1 -0
- package/dist/components/admonition.js +146 -0
- package/dist/components/cite-figurebar.d.ts +5 -0
- package/dist/components/cite-figurebar.d.ts.map +1 -0
- package/dist/components/cite-figurebar.js +73 -0
- package/dist/components/cite-youtube.d.ts +6 -0
- package/dist/components/cite-youtube.d.ts.map +1 -0
- package/dist/components/cite-youtube.js +45 -0
- package/dist/components/cite.d.ts +12 -0
- package/dist/components/cite.d.ts.map +1 -0
- package/dist/components/cite.js +76 -0
- package/dist/components/definition-list.d.ts +3 -0
- package/dist/components/definition-list.d.ts.map +1 -0
- package/dist/components/definition-list.js +20 -0
- package/dist/components/faq.d.ts +5 -0
- package/dist/components/faq.d.ts.map +1 -0
- package/dist/components/faq.js +34 -0
- package/dist/components/hero.css +6 -0
- package/dist/components/hero.d.ts +28 -0
- package/dist/components/hero.d.ts.map +1 -0
- package/dist/components/hero.example.d.ts +3 -0
- package/dist/components/hero.example.d.ts.map +1 -0
- package/dist/components/hero.example.js +30 -0
- package/dist/components/hero.js +89 -0
- package/dist/components/images.d.ts +5 -0
- package/dist/components/images.d.ts.map +1 -0
- package/dist/components/images.js +7 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +6 -0
- package/dist/components/inlineError.d.ts +8 -0
- package/dist/components/inlineError.d.ts.map +1 -0
- package/dist/components/inlineError.js +6 -0
- package/dist/components/mermaid.d.ts +11 -0
- package/dist/components/mermaid.d.ts.map +1 -0
- package/dist/components/mermaid.js +59 -0
- package/dist/components/pdb.d.ts +5 -0
- package/dist/components/pdb.d.ts.map +1 -0
- package/dist/{pdbLink.js → components/pdb.js} +15 -5
- package/dist/hooks/useOpenAlex.d.ts +13 -0
- package/dist/hooks/useOpenAlex.d.ts.map +1 -0
- package/dist/hooks/useOpenAlex.js +33 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -18
- package/dist/transforms/articles.d.ts +4 -1
- package/dist/transforms/articles.d.ts.map +1 -1
- package/dist/transforms/articles.js +37 -51
- package/dist/transforms/index.d.ts +4 -6
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/index.js +11 -24
- package/dist/transforms/{outputs.d.ts → notebooks.d.ts} +1 -1
- package/dist/transforms/notebooks.d.ts.map +1 -0
- package/dist/transforms/{outputs.js → notebooks.js} +5 -6
- package/dist/utils/abstract.d.ts +40 -0
- package/dist/utils/abstract.d.ts.map +1 -0
- package/dist/utils/abstract.js +76 -0
- package/package.json +40 -28
- package/README.md +0 -6
- package/dist/any/index.d.ts +0 -5
- package/dist/any/index.d.ts.map +0 -1
- package/dist/any/index.js +0 -8
- package/dist/any/models.d.ts +0 -18
- package/dist/any/models.d.ts.map +0 -1
- package/dist/any/models.js +0 -49
- package/dist/any/renderers.d.ts +0 -5
- package/dist/any/renderers.d.ts.map +0 -1
- package/dist/any/renderers.js +0 -113
- package/dist/any/types.d.ts +0 -22
- package/dist/any/types.d.ts.map +0 -1
- package/dist/any/types.js +0 -1
- package/dist/cards.d.ts +0 -8
- package/dist/cards.d.ts.map +0 -1
- package/dist/cards.js +0 -15
- package/dist/cite.d.ts +0 -17
- package/dist/cite.d.ts.map +0 -1
- package/dist/cite.js +0 -94
- package/dist/collections.d.ts +0 -6
- package/dist/collections.d.ts.map +0 -1
- package/dist/collections.js +0 -12
- package/dist/pdbLink.d.ts +0 -6
- package/dist/pdbLink.d.ts.map +0 -1
- package/dist/transforms/cards.d.ts +0 -52
- package/dist/transforms/cards.d.ts.map +0 -1
- package/dist/transforms/cards.js +0 -68
- package/dist/transforms/collections.d.ts +0 -15
- package/dist/transforms/collections.d.ts.map +0 -1
- package/dist/transforms/collections.js +0 -44
- package/dist/transforms/outputs.d.ts.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@curvenote-theme/ui';
|
|
3
|
+
import { MyST } from 'myst-to-react';
|
|
4
|
+
import { cn } from '@curvenote/react-utils';
|
|
5
|
+
import './hero.css';
|
|
6
|
+
// Generate Tailwind classes for max-width based on breakpoints
|
|
7
|
+
function getMaxWidthClasses(maxWidth) {
|
|
8
|
+
if (maxWidth == null)
|
|
9
|
+
return [];
|
|
10
|
+
const maxWidths = Array.isArray(maxWidth) ? maxWidth : [maxWidth];
|
|
11
|
+
// Round to nearest 5 and clamp between 0 and 100
|
|
12
|
+
const [sm, md, lg, xl, twoXl] = maxWidths.map((n) => {
|
|
13
|
+
if (n == null)
|
|
14
|
+
return undefined;
|
|
15
|
+
if (typeof n !== 'number' || isNaN(n))
|
|
16
|
+
return undefined;
|
|
17
|
+
return Math.max(0, Math.min(100, Math.round(n / 5) * 5));
|
|
18
|
+
});
|
|
19
|
+
return [
|
|
20
|
+
`max-w-[${sm || 100}%]`,
|
|
21
|
+
sm ? `sm:max-w-[${sm}%]` : undefined,
|
|
22
|
+
md ? `md:max-w-[${md}%]` : undefined,
|
|
23
|
+
lg ? `lg:max-w-[${lg}%]` : undefined,
|
|
24
|
+
xl ? `xl:max-w-[${xl}%]` : undefined,
|
|
25
|
+
twoXl ? `2xl:max-w-[${twoXl}%]` : undefined,
|
|
26
|
+
].filter(Boolean);
|
|
27
|
+
}
|
|
28
|
+
// Generate Tailwind classes for overlays based on breakpoints
|
|
29
|
+
function getOverlayClasses(overlay) {
|
|
30
|
+
if (overlay == null)
|
|
31
|
+
return [];
|
|
32
|
+
const values = Array.isArray(overlay) ? overlay : [overlay, overlay, overlay, overlay, overlay];
|
|
33
|
+
// Round to nearest 5 and clamp between 0 and 100
|
|
34
|
+
const roundedValues = values.map((n) => {
|
|
35
|
+
if (n == null)
|
|
36
|
+
return undefined;
|
|
37
|
+
if (typeof n !== 'number' || isNaN(n))
|
|
38
|
+
return undefined;
|
|
39
|
+
return Math.max(-100, Math.min(100, Math.round(n / 10) * 10));
|
|
40
|
+
});
|
|
41
|
+
const backgrounds = roundedValues.map((value, index) => {
|
|
42
|
+
const modifier = ['sm', 'md', 'lg', 'xl', '2xl'][index];
|
|
43
|
+
if (modifier == 'sm' && value == null)
|
|
44
|
+
return `bg-black/10`;
|
|
45
|
+
if (value == null)
|
|
46
|
+
return undefined;
|
|
47
|
+
if (modifier == 'sm')
|
|
48
|
+
return `bg-${value < 0 ? 'white' : 'black'}/${Math.abs(value || 10)}`;
|
|
49
|
+
return `${modifier}:bg-${value < 0 ? 'white' : 'black'}/${Math.abs(value)}`;
|
|
50
|
+
});
|
|
51
|
+
return backgrounds.filter(Boolean);
|
|
52
|
+
}
|
|
53
|
+
export function HeroComponent({ className, backgroundImage, kicker, title, content, actions, footer, maxWidth, overlay, light = false, }) {
|
|
54
|
+
return (_jsxs("div", { className: cn('flex overflow-hidden relative flex-col min-h-[300px]', className), children: [backgroundImage && (_jsx("div", { className: "absolute inset-0 bg-center bg-no-repeat bg-cover", style: { backgroundImage: `url(${backgroundImage})` } })), overlay != null && _jsx("div", { className: cn('absolute inset-0', ...getOverlayClasses(overlay)) }), _jsx("div", { className: "container flex relative z-10 flex-1 items-center px-4 mx-auto my-20 sm:px-6 lg:px-8", children: _jsxs("div", { className: cn('max-w-4xl', ...getMaxWidthClasses(maxWidth)), children: [kicker && (_jsx("div", { className: cn('mb-2 text-sm font-medium tracking-wide uppercase', {
|
|
55
|
+
'text-gray-300': light === false,
|
|
56
|
+
'text-black': light === true,
|
|
57
|
+
}), children: kicker })), _jsx("h1", { className: cn('mb-6 text-4xl font-bold leading-tight sm:text-5xl lg:text-6xl', {
|
|
58
|
+
'text-white': light === false,
|
|
59
|
+
'text-black': light === true,
|
|
60
|
+
}), children: title }), content && (_jsx("div", { className: cn('mb-8 max-w-3xl text-lg leading-relaxed sm:text-xl', {
|
|
61
|
+
'text-gray-200': light === false,
|
|
62
|
+
'text-black': light === true,
|
|
63
|
+
}), children: content })), actions && actions.length > 0 && (_jsx("div", { className: "flex flex-col gap-4 sm:flex-row", children: actions.map((action, index) => (_jsx(Button, { variant: action.variant || 'default', size: "lg", className: cn('no-underline', {
|
|
64
|
+
'bg-transparent border-white text-white hover:bg-white hover:text-gray-900': action.variant === 'outline' && light === false,
|
|
65
|
+
'bg-white text-gray-900 hover:bg-gray-100': action.variant !== 'outline' && light === false,
|
|
66
|
+
'bg-transparent border-black text-black hover:bg-black/10': action.variant === 'outline' && light === true,
|
|
67
|
+
'bg-black text-gray-200 hover:bg-black/80': action.variant !== 'outline' && light === true,
|
|
68
|
+
}, action.className), asChild: !!action.href, onClick: action.onClick, children: action.href ? _jsx("a", { href: action.href, children: action.label }) : action.label }, index))) }))] }) }), footer && (_jsx("div", { className: "w-full backdrop-blur-lg bg-black/60", children: _jsx("div", { className: "container px-4 py-6 mx-auto sm:px-6 lg:px-8", children: _jsx("div", { className: "max-w-4xl text-sm leading-relaxed text-gray-300", children: footer }) }) }))] }));
|
|
69
|
+
}
|
|
70
|
+
const HeroRenderer = ({ node, className }) => {
|
|
71
|
+
// Extract properties from the node
|
|
72
|
+
const properties = node.data || {};
|
|
73
|
+
// Find children by type
|
|
74
|
+
const kicker = node.children?.find((child) => child.kind === 'kicker');
|
|
75
|
+
const title = node.children?.find((child) => child.kind === 'title');
|
|
76
|
+
const body = node.children?.find((child) => child.kind === 'body');
|
|
77
|
+
const actionNodes = node.children?.find((child) => child.kind === 'actions');
|
|
78
|
+
const footer = node.children?.find((child) => child.kind === 'footer');
|
|
79
|
+
const imageNode = node.children?.find((child) => child.kind === 'backgroundImage')
|
|
80
|
+
?.children?.[0];
|
|
81
|
+
const imageUrl = imageNode?.urlOptimized || imageNode?.url;
|
|
82
|
+
const actions = actionNodes?.children?.filter((child) => child.type === 'link');
|
|
83
|
+
return (_jsx(HeroComponent, { className: cn(className, node.class), backgroundImage: imageUrl, maxWidth: properties.maxWidth, overlay: properties.overlay, light: properties.light, kicker: kicker ? _jsx(MyST, { ast: kicker }) : undefined, title: title ? _jsx(MyST, { ast: title }) : undefined, content: body ? _jsx(MyST, { ast: body }) : undefined, actions: actions?.map((action) => ({
|
|
84
|
+
label: _jsx(MyST, { ast: action.children }),
|
|
85
|
+
href: action.url,
|
|
86
|
+
variant: action.variant || 'default',
|
|
87
|
+
})), footer: footer ? _jsx(MyST, { ast: footer }) : undefined }));
|
|
88
|
+
};
|
|
89
|
+
export const HERO_RENDERERS = { block: { 'block[kind=hero]': HeroRenderer } };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images.d.ts","sourceRoot":"","sources":["../../src/components/images.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAe1D,eAAO,MAAM,eAAe;;CAA2B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import {} from '@myst-theme/providers';
|
|
3
|
+
import { Image } from '@curvenote-theme/ui';
|
|
4
|
+
const ImageRenderer = ({ node }) => {
|
|
5
|
+
return (_jsx(Image, { src: node.url, srcOptimized: node.urlOptimized, urlSource: node.urlSource, alt: node.alt }));
|
|
6
|
+
};
|
|
7
|
+
export const IMAGE_RENDERERS = { image: ImageRenderer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inlineError.d.ts","sourceRoot":"","sources":["../../src/components/inlineError.tsx"],"names":[],"mappings":"AAGA,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,2CAO/D"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '@curvenote/react-utils';
|
|
3
|
+
import { AlertCircle } from 'lucide-react';
|
|
4
|
+
export function InlineError({ value, message, className }) {
|
|
5
|
+
return (_jsxs("span", { className: cn('text-yellow-600', className), title: message || value, children: [_jsx(AlertCircle, { width: "1rem", height: "1rem", className: "inline mr-1" }), value] }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NodeRenderer } from '@myst-theme/providers';
|
|
2
|
+
export declare function MermaidRenderer({ id, value, className, }: {
|
|
3
|
+
value: string;
|
|
4
|
+
id: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare const MermaidNodeRenderer: NodeRenderer;
|
|
8
|
+
export declare const MERMAID_RENDERERS: {
|
|
9
|
+
mermaid: NodeRenderer;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=mermaid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../src/components/mermaid.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAiC1D,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,KAAK,EACL,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAyCA;AAED,eAAO,MAAM,mBAAmB,EAAE,YAQjC,CAAC;AAEF,eAAO,MAAM,iBAAiB;;CAAmC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Modified from @myst-theme/diagrams/src/components/mermaid.tsx
|
|
3
|
+
// MIC License:
|
|
4
|
+
// Copyright (c) Project Jupyter
|
|
5
|
+
// Additional changes Copyright (c) Curvenote, Inc.
|
|
6
|
+
import { cn } from '@curvenote/react-utils';
|
|
7
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
let mermaidInstance = null;
|
|
10
|
+
async function getMermaid() {
|
|
11
|
+
if (!mermaidInstance) {
|
|
12
|
+
mermaidInstance = (async () => {
|
|
13
|
+
const { default: mermaid } = await import('mermaid');
|
|
14
|
+
mermaid.initialize({ startOnLoad: false });
|
|
15
|
+
return mermaid;
|
|
16
|
+
})();
|
|
17
|
+
}
|
|
18
|
+
return mermaidInstance;
|
|
19
|
+
}
|
|
20
|
+
async function parse(id, text) {
|
|
21
|
+
const mermaid = await getMermaid();
|
|
22
|
+
const { svg, bindFunctions } = await mermaid.render(id, text);
|
|
23
|
+
return { svg, bindFunctions };
|
|
24
|
+
}
|
|
25
|
+
function applyParseResult(element, svg, bindFunctions) {
|
|
26
|
+
element.innerHTML = svg;
|
|
27
|
+
bindFunctions?.(element);
|
|
28
|
+
}
|
|
29
|
+
export function MermaidRenderer({ id, value, className, }) {
|
|
30
|
+
const key = useId();
|
|
31
|
+
const divRef = useRef(null);
|
|
32
|
+
const [error, setError] = useState();
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!divRef.current)
|
|
35
|
+
return;
|
|
36
|
+
let cancelled = false;
|
|
37
|
+
const element = divRef.current;
|
|
38
|
+
parse(`mermaid-${key.replace(/:/g, '')}`, value)
|
|
39
|
+
.then(({ svg, bindFunctions }) => {
|
|
40
|
+
if (!cancelled && divRef.current === element) {
|
|
41
|
+
applyParseResult(element, svg, bindFunctions);
|
|
42
|
+
setError(undefined);
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
.catch((err) => {
|
|
46
|
+
if (!cancelled) {
|
|
47
|
+
setError(err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return () => {
|
|
51
|
+
cancelled = true;
|
|
52
|
+
};
|
|
53
|
+
}, [value, key]);
|
|
54
|
+
return (_jsxs("figure", { id: id, className: className, children: [_jsx("div", { ref: divRef }), error && (_jsxs("pre", { children: ["Error parsing mermaid graph.", '\n\n', error.message, '\n\n', value] }))] }));
|
|
55
|
+
}
|
|
56
|
+
export const MermaidNodeRenderer = ({ node, className }) => {
|
|
57
|
+
return (_jsx(MermaidRenderer, { id: node.html_id || node.identifier, value: node.value, className: cn(node.class, className) }));
|
|
58
|
+
};
|
|
59
|
+
export const MERMAID_RENDERERS = { mermaid: MermaidNodeRenderer };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GenericNode } from 'myst-common';
|
|
2
|
+
import type { NodeRenderer, NodeRenderers } from '@myst-theme/providers';
|
|
3
|
+
export declare const PDBLinkRenderer: NodeRenderer<GenericNode>;
|
|
4
|
+
export declare const LINK_RENDERERS: NodeRenderers;
|
|
5
|
+
//# sourceMappingURL=pdb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdb.d.ts","sourceRoot":"","sources":["../../src/components/pdb.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAkDzE,eAAO,MAAM,eAAe,EAAE,YAAY,CAAC,WAAW,CAgBrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,aAI5B,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { default as useSWR } from 'swr';
|
|
3
|
-
import { HoverPopover,
|
|
3
|
+
import { HoverPopover, MyST } from 'myst-to-react';
|
|
4
|
+
import { LinkCard } from '@curvenote-theme/ui';
|
|
4
5
|
const createQuery = (id) => `{"query":"query structure ($id: String!) {\n entry(entry_id:$id){\n rcsb_id\n struct {\n title\n }\n pubmed {\n rcsb_pubmed_container_identifiers {\n pubmed_id\n }\n rcsb_pubmed_central_id\n rcsb_pubmed_doi\n rcsb_pubmed_abstract_text\n rcsb_pubmed_affiliation_info\n }\n }\n}\n","variables":{"id":"${id}"},"operationName":"structure"}`;
|
|
5
6
|
const fetcher = (id) => fetch('https://data.rcsb.org/graphql', {
|
|
6
7
|
method: 'post',
|
|
@@ -19,12 +20,21 @@ function PDBChild({ pdb }) {
|
|
|
19
20
|
if (error) {
|
|
20
21
|
return (_jsxs("div", { className: "hover-document article w-[500px] sm:max-w-[500px]", children: ["Error loading ", pdb, "."] }));
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
+
console.log(data);
|
|
23
24
|
const rcsb_id = data.data.entry.rcsb_id;
|
|
24
25
|
const title = data.data.entry.struct.title;
|
|
25
26
|
const abstract = data.data.entry.pubmed.rcsb_pubmed_abstract_text;
|
|
26
|
-
return (_jsx(LinkCard, { loading: !data, url: `https://www.rcsb.org/structure/${pdb}`, title: _jsxs("
|
|
27
|
+
return (_jsx(LinkCard, { loading: !data, url: `https://www.rcsb.org/structure/${pdb}`, title: _jsxs("div", { className: "flex gap-2 items-stretch text-sm font-light", children: ["PDB ", rcsb_id] }), thumbnail: `https://cdn.rcsb.org/images/structures/${rcsb_id.toLowerCase()}_assembly-1.jpeg`, description: _jsxs(_Fragment, { children: [_jsx("div", { className: "mb-4 font-bold", children: title }), _jsx("p", { className: "overflow-hidden text-sm line-clamp-5", children: abstract })] }) }));
|
|
27
28
|
}
|
|
28
|
-
export
|
|
29
|
+
export const PDBLinkRenderer = ({ node }) => {
|
|
30
|
+
const pdb = node.data?.pdb;
|
|
31
|
+
if (!pdb) {
|
|
32
|
+
return (_jsx("a", { href: node.url, target: "_blank", rel: "noopener noreferrer", children: _jsx(MyST, { ast: node.children }) }));
|
|
33
|
+
}
|
|
29
34
|
return (_jsx(HoverPopover, { card: _jsx(PDBChild, { pdb: pdb }), children: _jsx("a", { href: `https://www.rcsb.org/structure/${pdb}`, target: "_blank", rel: "noopener noreferrer", children: _jsx(MyST, { ast: node.children }) }) }));
|
|
30
|
-
}
|
|
35
|
+
};
|
|
36
|
+
export const LINK_RENDERERS = {
|
|
37
|
+
link: {
|
|
38
|
+
'link[kind=pdb]': PDBLinkRenderer,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OpenAlexWork } from '../utils/abstract';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to fetch OpenAlex work data by DOI
|
|
4
|
+
* @param doi - DOI string (can include protocol or be clean)
|
|
5
|
+
* @returns SWR response with OpenAlex work data
|
|
6
|
+
*/
|
|
7
|
+
export declare function useOpenAlexWork(doiString?: string): {
|
|
8
|
+
data: OpenAlexWork | undefined;
|
|
9
|
+
error: any;
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
doi: string | null | undefined;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=useOpenAlex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOpenAlex.d.ts","sourceRoot":"","sources":["../../src/hooks/useOpenAlex.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgBtD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM;;;;;EAqBjD"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { doi } from 'doi-utils';
|
|
3
|
+
/**
|
|
4
|
+
* Fetcher function for OpenAlex API
|
|
5
|
+
*/
|
|
6
|
+
async function openAlexFetcher(url) {
|
|
7
|
+
const response = await fetch(url);
|
|
8
|
+
if (!response.ok) {
|
|
9
|
+
throw new Error(`Failed to fetch OpenAlex data: ${response.status} ${response.statusText}`);
|
|
10
|
+
}
|
|
11
|
+
return response.json();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Hook to fetch OpenAlex work data by DOI
|
|
15
|
+
* @param doi - DOI string (can include protocol or be clean)
|
|
16
|
+
* @returns SWR response with OpenAlex work data
|
|
17
|
+
*/
|
|
18
|
+
export function useOpenAlexWork(doiString) {
|
|
19
|
+
const cleanDoi = doiString ? doi.normalize(doiString) : null;
|
|
20
|
+
const { data, error, isLoading } = useSWR(cleanDoi ? `https://api.openalex.org/works/doi:${cleanDoi}` : null, openAlexFetcher, {
|
|
21
|
+
revalidateOnFocus: false,
|
|
22
|
+
revalidateOnReconnect: false,
|
|
23
|
+
dedupingInterval: 60000, // Cache for 1 minute
|
|
24
|
+
errorRetryCount: 2,
|
|
25
|
+
errorRetryInterval: 1000,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
data,
|
|
29
|
+
error,
|
|
30
|
+
isLoading,
|
|
31
|
+
doi: cleanDoi,
|
|
32
|
+
};
|
|
33
|
+
}
|
package/dist/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import './components/hero.css';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export { MYST_SPEC_VERSION } from '@myst-theme/common';
|
|
2
|
+
declare const renderers: import("@myst-theme/providers").NodeRenderers;
|
|
3
|
+
export * from './transforms';
|
|
4
|
+
export * from './components';
|
|
5
|
+
export * from './utils/abstract';
|
|
6
|
+
export * from './hooks/useOpenAlex';
|
|
7
|
+
export { renderers };
|
|
3
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,QAAA,MAAM,SAAS,+CAcb,CAAC;AAEH,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
|
+
import { DEFAULT_RENDERERS as mystRenderers } from 'myst-to-react';
|
|
1
2
|
import { mergeRenderers } from '@myst-theme/providers';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
3
|
+
import { MERMAID_RENDERERS } from './components/mermaid';
|
|
4
|
+
import { ARTICLES_RENDERERS } from './articles';
|
|
5
|
+
import { IMAGE_RENDERERS } from './components/images';
|
|
6
|
+
import { ADMONITION_RENDERERS } from './components/admonition';
|
|
7
|
+
import { HERO_RENDERERS } from './components/hero';
|
|
8
|
+
import { DEFINITION_LIST_RENDERERS } from './components/definition-list';
|
|
9
|
+
import { LINK_RENDERERS } from './components/pdb';
|
|
10
|
+
import { CITE_RENDERERS } from './components/cite';
|
|
11
|
+
import { PERSON_CARD_RENDERERS } from '@curvenote/ext-person/react';
|
|
12
|
+
import { BLOG_RENDERERS } from '@curvenote/ext-blog/react';
|
|
13
|
+
// import { FAQ_RENDERERS } from './faq';
|
|
14
|
+
import { ANY_RENDERERS } from '@curvenote/any-widget/react';
|
|
15
|
+
export { MYST_SPEC_VERSION } from '@myst-theme/common';
|
|
16
|
+
const renderers = mergeRenderers([
|
|
17
|
+
mystRenderers,
|
|
18
|
+
MERMAID_RENDERERS,
|
|
19
|
+
ARTICLES_RENDERERS,
|
|
20
|
+
IMAGE_RENDERERS,
|
|
21
|
+
ADMONITION_RENDERERS,
|
|
22
|
+
HERO_RENDERERS,
|
|
23
|
+
DEFINITION_LIST_RENDERERS,
|
|
24
|
+
LINK_RENDERERS,
|
|
13
25
|
CITE_RENDERERS,
|
|
14
26
|
PERSON_CARD_RENDERERS,
|
|
15
27
|
BLOG_RENDERERS,
|
|
16
|
-
LANDING_RENDERERS,
|
|
17
|
-
FOOTER_RENDERERS,
|
|
18
|
-
SCIENCEICON_RENDERERS,
|
|
19
28
|
ANY_RENDERERS,
|
|
20
|
-
|
|
21
|
-
ARTICLES_RENDERERS,
|
|
22
|
-
COLLECTIONS_RENDERERS,
|
|
29
|
+
// FAQ_RENDERERS,
|
|
23
30
|
]);
|
|
24
|
-
export * from './transforms
|
|
31
|
+
export * from './transforms';
|
|
32
|
+
export * from './components';
|
|
33
|
+
export * from './utils/abstract';
|
|
34
|
+
export * from './hooks/useOpenAlex';
|
|
35
|
+
export { renderers };
|
|
@@ -31,5 +31,8 @@ export type OutgoingArticlesDirective = IncomingArticlesDirective & {
|
|
|
31
31
|
* @param node
|
|
32
32
|
* @returns
|
|
33
33
|
*/
|
|
34
|
-
export declare function transformArticles(node: GenericParent
|
|
34
|
+
export declare function transformArticles(node: GenericParent, { apiUrl, venue }: {
|
|
35
|
+
apiUrl: string;
|
|
36
|
+
venue?: string;
|
|
37
|
+
}): Promise<void[]>;
|
|
35
38
|
//# sourceMappingURL=articles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"articles.d.ts","sourceRoot":"","sources":["../../src/transforms/articles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"articles.d.ts","sourceRoot":"","sources":["../../src/transforms/articles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC;IAC9B,CAAC,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC;IAC9B,CAAC,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC;IACxB,CAAC,WAAW,CAAC,CAAC,EAAE,OAAO,CAAC;IACxB,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;IACzB,CAAC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC;IAC3B,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,yBAAyB,GAAG,yBAAyB,GAAG;IAClE,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,aAAa,EACnB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,mBA0CtD"}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { selectAll } from 'unist-util-select';
|
|
11
2
|
import pLimit from 'p-limit';
|
|
12
3
|
/**
|
|
@@ -16,46 +7,41 @@ import pLimit from 'p-limit';
|
|
|
16
7
|
* @param node
|
|
17
8
|
* @returns
|
|
18
9
|
*/
|
|
19
|
-
export function transformArticles(node) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.error('Could not load listing', e);
|
|
57
|
-
}
|
|
58
|
-
}));
|
|
59
|
-
})));
|
|
60
|
-
});
|
|
10
|
+
export async function transformArticles(node, { apiUrl, venue }) {
|
|
11
|
+
const articlesDirectives = selectAll('curvenoteArticles', node);
|
|
12
|
+
const applyLimit = pLimit(5);
|
|
13
|
+
return Promise.all(articlesDirectives.map(async (n) => applyLimit(async () => {
|
|
14
|
+
const output = n; // same object, modified in place
|
|
15
|
+
// ensure defaults
|
|
16
|
+
if (!n.pagination)
|
|
17
|
+
output.pagination = 'more';
|
|
18
|
+
if (!n.layout)
|
|
19
|
+
output.layout = 'list';
|
|
20
|
+
// build the URL
|
|
21
|
+
const url = new URL(`${apiUrl}sites/${n.venue ?? venue}/works`);
|
|
22
|
+
if (n.collection)
|
|
23
|
+
url.searchParams.set('collection', n.collection);
|
|
24
|
+
if (n.status && n.collection)
|
|
25
|
+
url.searchParams.set('status', n.status);
|
|
26
|
+
else if (n.status && !n.collection)
|
|
27
|
+
console.warn('cn:articles directive provides status without collection, status will be ignored');
|
|
28
|
+
if (n['submission-kind'])
|
|
29
|
+
url.searchParams.set('kind', n['submission-kind']);
|
|
30
|
+
if (n.limit)
|
|
31
|
+
url.searchParams.set('limit', n.limit.toString());
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch(url.toString());
|
|
34
|
+
if (!res.ok)
|
|
35
|
+
throw new Error(`${res.status} ${res.statusText}`);
|
|
36
|
+
const data = (await res.json());
|
|
37
|
+
output.items = data.items;
|
|
38
|
+
output.total = data.total;
|
|
39
|
+
output.prev = data.links.prev;
|
|
40
|
+
output.next = data.links.next;
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
output.error = 'Could not load listing';
|
|
44
|
+
console.error('Could not load listing', e);
|
|
45
|
+
}
|
|
46
|
+
})));
|
|
61
47
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { PageLoader } from '@myst-theme/common';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export * from './outputs.js';
|
|
7
|
-
export declare function applyCustomTransforms(site: SiteDTO, page: PageLoader): Promise<void>;
|
|
2
|
+
export declare function applyCustomPageTransformsInPlace(page: PageLoader, opts?: {
|
|
3
|
+
apiUrl?: string;
|
|
4
|
+
venue?: string;
|
|
5
|
+
}): Promise<void>;
|
|
8
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transforms/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transforms/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKrD,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,UAAU,EAChB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,iBAS3C"}
|
package/dist/transforms/index.js
CHANGED
|
@@ -1,25 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { transformCards } from './cards.js';
|
|
13
|
-
import { transformDecorateNotebookOutputsWithSlugs } from './outputs.js';
|
|
14
|
-
export * from './articles.js';
|
|
15
|
-
export * from './collections.js';
|
|
16
|
-
export * from './cards.js';
|
|
17
|
-
export * from './outputs.js';
|
|
18
|
-
export function applyCustomTransforms(site, page) {
|
|
19
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
-
yield transformArticles(page.mdast);
|
|
21
|
-
yield transformCollections(page.mdast);
|
|
22
|
-
transformCards(site, page.mdast);
|
|
23
|
-
transformDecorateNotebookOutputsWithSlugs(page);
|
|
24
|
-
});
|
|
1
|
+
import {} from 'myst-common';
|
|
2
|
+
import { transformArticles } from './articles';
|
|
3
|
+
import { transformDecorateNotebookOutputsWithSlugs } from './notebooks';
|
|
4
|
+
export async function applyCustomPageTransformsInPlace(page, opts) {
|
|
5
|
+
if (opts?.apiUrl) {
|
|
6
|
+
await transformArticles(page.mdast, {
|
|
7
|
+
apiUrl: opts.apiUrl,
|
|
8
|
+
venue: opts.venue,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
transformDecorateNotebookOutputsWithSlugs(page);
|
|
25
12
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notebooks.d.ts","sourceRoot":"","sources":["../../src/transforms/notebooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,wBAAgB,yCAAyC,CAAC,IAAI,EAAE,UAAU,QAmBzE"}
|
|
@@ -2,19 +2,18 @@ import { normalizeLabel } from 'myst-common';
|
|
|
2
2
|
import { selectAll } from 'unist-util-select';
|
|
3
3
|
export function transformDecorateNotebookOutputsWithSlugs(page) {
|
|
4
4
|
selectAll('container[kind=figure]:has(output), embed:has(output), container[kind=table]:has(output)', page.mdast).forEach((node) => {
|
|
5
|
-
var _a, _b;
|
|
6
5
|
const { source } = node;
|
|
7
|
-
const
|
|
6
|
+
const outputs = selectAll('outputs', node);
|
|
8
7
|
if (source) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const sideEffectOutputs = outputs[0];
|
|
9
|
+
sideEffectOutputs.notebookSlug = source.slug ?? 'unknown';
|
|
10
|
+
sideEffectOutputs.html_id = normalizeLabel(source.label)?.html_id;
|
|
12
11
|
}
|
|
13
12
|
else {
|
|
14
13
|
console.warn(`no "source" on node`, node);
|
|
15
14
|
}
|
|
16
15
|
});
|
|
17
|
-
selectAll('block[kind=notebook-code] >
|
|
16
|
+
selectAll('block[kind=notebook-code] > outputs', page.mdast).forEach((node) => {
|
|
18
17
|
node.notebookSlug = page.slug;
|
|
19
18
|
});
|
|
20
19
|
}
|