@myst-theme/site 0.4.0 → 0.4.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myst-theme/site",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "main": "./src/index.ts",
5
5
  "types": "./src/index.ts",
6
6
  "files": [
@@ -16,17 +16,18 @@
16
16
  "dependencies": {
17
17
  "@headlessui/react": "^1.7.15",
18
18
  "@heroicons/react": "^2.0.18",
19
- "@myst-theme/diagrams": "^0.4.0",
20
- "@myst-theme/frontmatter": "^0.4.0",
21
- "@myst-theme/jupyter": "^0.4.0",
22
- "@myst-theme/providers": "^0.4.0",
19
+ "@myst-theme/diagrams": "^0.4.2",
20
+ "@myst-theme/frontmatter": "^0.4.2",
21
+ "@myst-theme/jupyter": "^0.4.2",
22
+ "@myst-theme/common": "^0.4.2",
23
+ "@myst-theme/providers": "^0.4.2",
23
24
  "classnames": "^2.3.2",
24
25
  "lodash.throttle": "^4.1.1",
25
- "myst-common": "^1.1.0",
26
- "myst-spec-ext": "^1.1.0",
27
- "myst-config": "^1.1.0",
28
- "myst-demo": "^0.4.0",
29
- "myst-to-react": "^0.4.0",
26
+ "myst-common": "^1.1.1",
27
+ "myst-spec-ext": "^1.1.1",
28
+ "myst-config": "^1.1.1",
29
+ "myst-demo": "^0.4.2",
30
+ "myst-to-react": "^0.4.2",
30
31
  "nbtx": "^0.2.3",
31
32
  "node-cache": "^5.1.2",
32
33
  "node-fetch": "^2.6.11",
@@ -34,8 +35,6 @@
34
35
  "unist-util-select": "^4.0.1"
35
36
  },
36
37
  "peerDependencies": {
37
- "@remix-run/node": "^1.17.0",
38
- "@remix-run/react": "^1.17.0",
39
38
  "@types/react": "^16.8 || ^17.0 || ^18.0",
40
39
  "@types/react-dom": "^16.8 || ^17.0 || ^18.0",
41
40
  "react": "^16.8 || ^17.0 || ^18.0",
@@ -70,6 +70,25 @@ const Headings = ({ headings, activeId, highlight, selector }: Props) => (
70
70
  </ul>
71
71
  );
72
72
 
73
+ function cloneHeadingElement(originalElement: HTMLSpanElement) {
74
+ // Clone the original element
75
+ const clonedElement = originalElement.cloneNode(true) as HTMLSpanElement;
76
+
77
+ // Get all <abbr> elements in the cloned element
78
+ const abbrElements = clonedElement.getElementsByTagName('abbr');
79
+
80
+ // Move children of <abbr> elements to their parent
81
+ for (let i = 0; i < abbrElements.length; i++) {
82
+ const abbr = abbrElements[i];
83
+ const parent = abbr.parentNode as HTMLSpanElement;
84
+ while (abbr.firstChild) {
85
+ parent.insertBefore(abbr.firstChild, abbr);
86
+ }
87
+ parent.removeChild(abbr);
88
+ }
89
+ return clonedElement;
90
+ }
91
+
73
92
  function getHeaders(selector: string): HTMLHeadingElement[] {
74
93
  const headers = Array.from(document.querySelectorAll(selector)).filter((e) => {
75
94
  const parent = e.closest('.exclude-from-outline');
@@ -135,7 +154,9 @@ function useHeaders(selector: string) {
135
154
  })
136
155
  .filter((h) => !!h.text)
137
156
  .map(({ level, text, id }) => {
138
- const { innerText: title, innerHTML: titleHTML } = text as HTMLSpanElement;
157
+ const { innerText: title, innerHTML: titleHTML } = cloneHeadingElement(
158
+ text as HTMLSpanElement,
159
+ );
139
160
  return { title, titleHTML, id, level };
140
161
  });
141
162
 
@@ -1,7 +1,7 @@
1
1
  import classNames from 'classnames';
2
2
  import ArrowLeftIcon from '@heroicons/react/24/outline/ArrowLeftIcon';
3
3
  import ArrowRightIcon from '@heroicons/react/24/outline/ArrowRightIcon';
4
- import type { FooterLinks, NavigationLink } from '../types';
4
+ import type { FooterLinks, NavigationLink } from '@myst-theme/common';
5
5
  import { useLinkProvider, useBaseurl, withBaseurl } from '@myst-theme/providers';
6
6
 
7
7
  const FooterLink = ({
@@ -16,7 +16,7 @@ const FooterLink = ({
16
16
  return (
17
17
  <Link
18
18
  prefetch="intent"
19
- className="flex-1 block p-4 font-normal text-gray-600 no-underline border border-gray-200 rounded group hover:border-blue-600 dark:hover:border-blue-400 hover:text-blue-600 dark:hover:text-blue-400 dark:text-gray-100 dark:border-gray-500 shadow-sm hover:shadow-lg dark:shadow-neutral-700"
19
+ className="flex-1 block p-4 font-normal text-gray-600 no-underline border border-gray-200 rounded shadow-sm group hover:border-blue-600 dark:hover:border-blue-400 hover:text-blue-600 dark:hover:text-blue-400 dark:text-gray-100 dark:border-gray-500 hover:shadow-lg dark:shadow-neutral-700"
20
20
  to={withBaseurl(url, baseurl)}
21
21
  >
22
22
  <div className="flex h-full align-middle">
@@ -36,7 +36,7 @@ const FooterLink = ({
36
36
  };
37
37
 
38
38
  export function FooterLinksBlock({ links }: { links?: FooterLinks }) {
39
- if (!links) return null;
39
+ if (!links || (!links.navigation?.prev && !links.navigation?.next)) return null;
40
40
  return (
41
41
  <div className="flex pt-10 mb-10 space-x-4">
42
42
  {links.navigation?.prev && <FooterLink {...links.navigation?.prev} right />}
@@ -9,8 +9,7 @@ import {
9
9
  useBaseurl,
10
10
  withBaseurl,
11
11
  } from '@myst-theme/providers';
12
- import { getProjectHeadings } from '../../loaders';
13
- import type { Heading } from '../../types';
12
+ import { getProjectHeadings, type Heading } from '@myst-theme/common';
14
13
 
15
14
  type Props = {
16
15
  folder?: string;
package/src/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './utils';
2
- export * from './types';
3
2
  export * from './loaders';
4
3
  export * from './components';
5
4
  export * from './pages';
@@ -1,7 +1,4 @@
1
- export enum ErrorStatus {
2
- noSite = 'Site was not found',
3
- noArticle = 'Article was not found',
4
- }
1
+ import { ErrorStatus } from '@myst-theme/common';
5
2
 
6
3
  export function responseNoSite(): Response {
7
4
  // note: error boundary logic is dependent on the string sent here
@@ -1,5 +1,3 @@
1
1
  export * from './errors.server';
2
- export * as cdn from './cdn.server';
3
- export * from './utils';
4
2
  export * from './links';
5
3
  export * from './theme.server';
@@ -3,8 +3,8 @@ import { ReferencesProvider } from '@myst-theme/providers';
3
3
  import { Bibliography, ContentBlocks, FooterLinksBlock } from '../components';
4
4
  import { ErrorDocumentNotFound } from './ErrorDocumentNotFound';
5
5
  import { ErrorProjectNotFound } from './ErrorProjectNotFound';
6
- import type { PageLoader } from '../types';
7
- import type { GenericParent } from 'myst-common';
6
+ import type { PageLoader } from '@myst-theme/common';
7
+ import { copyNode, extractPart, type GenericParent } from 'myst-common';
8
8
  import { SourceFileKind } from 'myst-spec-ext';
9
9
  import {
10
10
  useComputeOptions,
@@ -17,18 +17,26 @@ import {
17
17
  ErrorTray,
18
18
  } from '@myst-theme/jupyter';
19
19
  import { FrontmatterBlock } from '@myst-theme/frontmatter';
20
+ import classNames from 'classnames';
20
21
 
21
22
  export const ArticlePage = React.memo(function ({
22
23
  article,
23
24
  hide_all_footer_links,
25
+ showAbstract,
26
+ hideKeywords,
24
27
  }: {
25
28
  article: PageLoader;
26
29
  hide_all_footer_links?: boolean;
30
+ showAbstract?: boolean;
31
+ hideKeywords?: boolean;
27
32
  }) {
28
33
  const canCompute = useCanCompute(article);
29
34
  const { binderBadgeUrl } = useComputeOptions();
30
35
  const { hide_title_block, hide_footer_links } = (article.frontmatter as any)?.design ?? {};
31
36
 
37
+ const tree = copyNode(article.mdast);
38
+ const keywords = article.frontmatter?.keywords ?? [];
39
+ const abstract = showAbstract ? extractPart(tree, 'abstract') : undefined;
32
40
  // take binder url from article frontmatter or fallback to project
33
41
  const binderUrl = article.frontmatter.binder ?? binderBadgeUrl;
34
42
 
@@ -53,7 +61,30 @@ export const ArticlePage = React.memo(function ({
53
61
  )}
54
62
  {canCompute && article.kind === SourceFileKind.Notebook && <NotebookToolbar showLaunch />}
55
63
  <ErrorTray pageSlug={article.slug} />
56
- <ContentBlocks pageKind={article.kind} mdast={article.mdast as GenericParent} />
64
+ {abstract && (
65
+ <>
66
+ <span className="font-semibold">Abstract</span>
67
+ <div className="px-6 py-1 m-3 rounded-sm bg-slate-50 dark:bg-slate-800">
68
+ <ContentBlocks mdast={abstract as GenericParent} className="col-body" />
69
+ </div>
70
+ {!hideKeywords && keywords.length > 0 && (
71
+ <div className="mb-10">
72
+ <span className="mr-2 font-semibold">Keywords:</span>
73
+ {keywords.map((k, i) => (
74
+ <span
75
+ key={k}
76
+ className={classNames({
77
+ "after:content-[','] after:mr-1": i < keywords.length - 1,
78
+ })}
79
+ >
80
+ {k}
81
+ </span>
82
+ ))}
83
+ </div>
84
+ )}
85
+ </>
86
+ )}
87
+ <ContentBlocks pageKind={article.kind} mdast={tree as GenericParent} />
57
88
  <Bibliography />
58
89
  <ConnectionStatusTray />
59
90
  {!hide_footer_links && !hide_all_footer_links && (
@@ -1,5 +1,5 @@
1
1
  import type { SiteManifest } from 'myst-config';
2
- import type { SiteLoader } from '../types';
2
+ import type { SiteLoader } from '@myst-theme/common';
3
3
  import { BaseUrlProvider, SiteProvider, Theme, ThemeProvider } from '@myst-theme/providers';
4
4
  import {
5
5
  Links,
@@ -1,172 +0,0 @@
1
- import fetch from 'node-fetch';
2
- import NodeCache from 'node-cache';
3
- import type { SiteManifest } from 'myst-config';
4
- import { responseNoArticle, responseNoSite } from './errors.server';
5
- import {
6
- getFooterLinks,
7
- getProject,
8
- updatePageStaticLinksInplace,
9
- updateSiteManifestStaticLinksInplace,
10
- } from './utils';
11
- import { redirect } from '@remix-run/node';
12
- import type { PageLoader } from '../types';
13
-
14
- interface CdnRouter {
15
- cdn?: string;
16
- }
17
-
18
- declare global {
19
- // Disable multiple caches when this file is rebuilt
20
- // eslint-disable-next-line
21
- var cdnRouterCache: NodeCache | undefined, configCache: NodeCache | undefined;
22
- }
23
-
24
- export type Host = string | { CDN: string; id: string };
25
-
26
- const DEFAULT_CDN = 'https://cdn.curvenote.com/';
27
-
28
- function getCdnRouterCache() {
29
- if (global.cdnRouterCache) return global.cdnRouterCache;
30
- console.log('Creating cdnRouterCache');
31
- // The router should update every minute
32
- global.cdnRouterCache = new NodeCache({ stdTTL: 30 });
33
- return global.cdnRouterCache;
34
- }
35
-
36
- export function getConfigCache() {
37
- if (global.configCache) return global.configCache;
38
- console.log('Creating configCache');
39
- // The config can be long lived as it is static (0 == ∞)
40
- global.configCache = new NodeCache({ stdTTL: 0 });
41
- return global.configCache;
42
- }
43
-
44
- async function getCdnPath(hostname: string): Promise<string | undefined> {
45
- const cached = getCdnRouterCache().get<CdnRouter>(hostname);
46
- if (cached) return cached.cdn;
47
- const response = await fetch(`https://api.curvenote.com/routers/${hostname}`);
48
- if (response.status === 404) {
49
- // Always hit the API again if it is not found!
50
- return;
51
- }
52
- const data = (await response.json()) as CdnRouter;
53
- getCdnRouterCache().set<CdnRouter>(hostname, data);
54
- return data.cdn;
55
- }
56
-
57
- function withPublicFolderUrl(baseUrl: string, url: string): string {
58
- return withBaseUrl(baseUrl, `public${url}`);
59
- }
60
-
61
- export async function getCdnLocation(host: Host) {
62
- if (typeof host === 'string') {
63
- const id = await getCdnPath(host);
64
- if (!id) throw responseNoSite();
65
- return { CDN: DEFAULT_CDN, id };
66
- }
67
- return host;
68
- }
69
-
70
- export async function getCdnBaseUrl(host: Host): Promise<string> {
71
- const { CDN, id } = await getCdnLocation(host);
72
- return `${CDN}${id}/`;
73
- }
74
-
75
- function withBaseUrl<T extends string | undefined>(baseUrl: string, url: T): T {
76
- if (!url) return url;
77
- return `${baseUrl}${url}` as T;
78
- }
79
-
80
- /**
81
- * Basic comparison for checking that the title and (possible) slug are the same
82
- */
83
- function foldTitleString(title?: string): string | undefined {
84
- return title?.replace(/[-\s_]/g, '').toLowerCase();
85
- }
86
-
87
- /**
88
- * If the site title and the first nav item are the same, remove it.
89
- */
90
- function removeSingleNavItems(config: SiteManifest) {
91
- if (
92
- config?.nav?.length === 1 &&
93
- foldTitleString(config.nav[0].title) === foldTitleString(config.title)
94
- ) {
95
- config.nav = [];
96
- }
97
- }
98
-
99
- export async function getConfig(host: Host): Promise<SiteManifest> {
100
- const location = await getCdnLocation(host);
101
- const baseUrl = await getCdnBaseUrl(location);
102
- const { id } = location;
103
- if (!id) throw responseNoSite();
104
- const cached = getConfigCache().get<SiteManifest>(id);
105
- // Load the data from an in memory cache.
106
- if (cached) return cached;
107
- const response = await fetch(withBaseUrl(baseUrl, 'config.json'));
108
- if (response.status === 404) throw responseNoSite();
109
- const data = (await response.json()) as SiteManifest;
110
- data.id = id;
111
- removeSingleNavItems(data);
112
- updateSiteManifestStaticLinksInplace(data, (url) => withPublicFolderUrl(baseUrl, url));
113
- getConfigCache().set<SiteManifest>(id, data);
114
- return data;
115
- }
116
-
117
- export async function getObjectsInv(host: Host): Promise<Buffer | undefined> {
118
- const baseUrl = await getCdnBaseUrl(host);
119
- if (!baseUrl) return;
120
- const url = `${baseUrl}objects.inv`;
121
- const response = await fetch(url);
122
- if (response.status === 404) return;
123
- const buffer = await response.buffer();
124
- return buffer;
125
- }
126
-
127
- async function getData(
128
- baseUrl: string,
129
- config?: SiteManifest,
130
- project?: string,
131
- slug?: string,
132
- ): Promise<PageLoader | null> {
133
- if (!slug || !config) throw responseNoArticle();
134
- const { id } = config;
135
- if (!id) throw responseNoSite();
136
- const projectPart = project ? `${project}/` : '';
137
- const response = await fetch(withBaseUrl(baseUrl, `content/${projectPart}${slug}.json`));
138
- if (response.status === 404) throw responseNoArticle();
139
- const data = (await response.json()) as PageLoader;
140
- return updatePageStaticLinksInplace(data, (url) => withPublicFolderUrl(baseUrl, url));
141
- }
142
-
143
- export async function getPage(
144
- host: Host,
145
- opts: {
146
- domain?: string;
147
- project?: string;
148
- loadIndexPage?: boolean;
149
- slug?: string;
150
- redirect?: boolean | string;
151
- },
152
- ): Promise<PageLoader | Response | null> {
153
- const projectName = opts.project;
154
- const baseUrl = await getCdnBaseUrl(host);
155
- const config = await getConfig(host);
156
- if (!config) throw responseNoSite();
157
- const project = getProject(config, projectName);
158
- if (!project) throw responseNoArticle();
159
- if (opts.slug === project.index && opts.redirect) {
160
- return redirect(
161
- `${typeof opts.redirect === 'string' ? opts.redirect : '/'}${projectName ?? ''}`,
162
- );
163
- }
164
- const slug = opts.loadIndexPage || opts.slug == null ? project.index : opts.slug;
165
- const loader = await getData(baseUrl, config, projectName, slug).catch((e) => {
166
- console.error(e);
167
- return null;
168
- });
169
- if (!loader) throw responseNoArticle();
170
- const footer = getFooterLinks(config, projectName, slug);
171
- return { ...loader, footer, domain: opts.domain as string, project: projectName as string };
172
- }
@@ -1,169 +0,0 @@
1
- import type { MinifiedOutput } from 'nbtx';
2
- import { walkOutputs } from 'nbtx';
3
- import type { SiteManifest } from 'myst-config';
4
- import { selectAll } from 'unist-util-select';
5
- import type { Image as ImageSpec, Link as LinkSpec } from 'myst-spec';
6
- import type { FooterLinks, Heading, NavigationLink, PageLoader } from '../types';
7
-
8
- type Image = ImageSpec & { urlOptimized?: string };
9
- type Link = LinkSpec & { static?: boolean };
10
- type Output = { data?: MinifiedOutput[] };
11
-
12
- type ManifestProject = Required<SiteManifest>['projects'][0];
13
- type ManifestProjectItem = ManifestProject['pages'][0];
14
-
15
- export function getProject(
16
- config?: SiteManifest,
17
- projectSlug?: string,
18
- ): ManifestProject | undefined {
19
- if (!config) return undefined;
20
- if (!projectSlug) return config.projects?.[0];
21
- const project = config.projects?.find((p) => p.slug === projectSlug);
22
- return project;
23
- }
24
-
25
- export function getProjectHeadings(
26
- config: SiteManifest,
27
- projectSlug?: string,
28
- opts: { addGroups: boolean } = { addGroups: false },
29
- ): Heading[] | undefined {
30
- const project = getProject(config, projectSlug);
31
- if (!project) return undefined;
32
- const headings: Heading[] = [
33
- {
34
- title: project.title,
35
- short_title: project.short_title,
36
- slug: project.index,
37
- path: project.slug ? `/${project.slug}` : '/',
38
- level: 'index',
39
- },
40
- ...project.pages.map((p) => {
41
- if (!('slug' in p)) return p;
42
- return { ...p, path: projectSlug ? `/${project.slug}/${p.slug}` : `/${p.slug}` };
43
- }),
44
- ];
45
- if (opts.addGroups) {
46
- let lastTitle = project.short_title || project.title;
47
- return headings.map((heading) => {
48
- if (!heading.slug || heading.level === 'index') {
49
- lastTitle = heading.short_title || heading.title;
50
- }
51
- return { ...heading, group: lastTitle };
52
- });
53
- }
54
- return headings;
55
- }
56
-
57
- function getHeadingLink(currentSlug: string, headings?: Heading[]): NavigationLink | undefined {
58
- if (!headings) return undefined;
59
- const linkIndex = headings.findIndex(({ slug }) => !!slug && slug !== currentSlug);
60
- const link = headings[linkIndex];
61
- if (!link?.path) return undefined;
62
- return {
63
- title: link.title,
64
- short_title: link.short_title,
65
- url: link.path,
66
- group: link.group,
67
- };
68
- }
69
-
70
- export function getFooterLinks(
71
- config?: SiteManifest,
72
- projectSlug?: string,
73
- slug?: string,
74
- ): FooterLinks {
75
- if (!slug || !config) return {};
76
- const pages = getProjectHeadings(config, projectSlug, {
77
- addGroups: true,
78
- });
79
- const found = pages?.findIndex(({ slug: s }) => s === slug) ?? -1;
80
- if (found === -1) return {};
81
- const prev = getHeadingLink(slug, pages?.slice(0, found).reverse());
82
- const next = getHeadingLink(slug, pages?.slice(found + 1));
83
- const footer: FooterLinks = {
84
- navigation: { prev, next },
85
- };
86
- return footer;
87
- }
88
-
89
- type UpdateUrl = (url: string) => string;
90
-
91
- export function updateSiteManifestStaticLinksInplace(
92
- data: SiteManifest,
93
- updateUrl: UpdateUrl,
94
- ): SiteManifest {
95
- data.actions?.forEach((action) => {
96
- if (!action.static) return;
97
- action.url = updateUrl(action.url);
98
- });
99
- // TODO: this needs to be based on the template.yml in the future
100
- if (data.logo) data.logo = updateUrl(data.logo);
101
- if (data.logo_dark) data.logo_dark = updateUrl(data.logo_dark);
102
- // Update the thumbnails to point at the CDN
103
- data.projects?.forEach((project) => {
104
- if (project.banner) project.banner = updateUrl(project.banner);
105
- if (project.bannerOptimized) project.bannerOptimized = updateUrl(project.bannerOptimized);
106
- if (project.thumbnail) project.thumbnail = updateUrl(project.thumbnail);
107
- if (project.thumbnailOptimized)
108
- project.thumbnailOptimized = updateUrl(project.thumbnailOptimized);
109
- if (project?.exports) {
110
- project.exports = project.exports.map((exp) => {
111
- if (!exp.url) return exp;
112
- return { ...exp, url: updateUrl(exp.url) };
113
- });
114
- }
115
- project.pages
116
- .filter((page): page is ManifestProjectItem => 'slug' in page)
117
- .forEach((page) => {
118
- if (page.thumbnail) page.thumbnail = updateUrl(page.thumbnail);
119
- if (page.thumbnailOptimized) page.thumbnailOptimized = updateUrl(page.thumbnailOptimized);
120
- });
121
- });
122
- return data;
123
- }
124
-
125
- export function updatePageStaticLinksInplace(data: PageLoader, updateUrl: UpdateUrl): PageLoader {
126
- if (data?.frontmatter?.thumbnail) {
127
- data.frontmatter.thumbnail = updateUrl(data.frontmatter.thumbnail);
128
- }
129
- if (data?.frontmatter?.thumbnailOptimized) {
130
- data.frontmatter.thumbnailOptimized = updateUrl(data.frontmatter.thumbnailOptimized);
131
- }
132
- if (data?.frontmatter?.banner) {
133
- data.frontmatter.banner = updateUrl(data.frontmatter.banner);
134
- }
135
- if (data?.frontmatter?.bannerOptimized) {
136
- data.frontmatter.bannerOptimized = updateUrl(data.frontmatter.bannerOptimized);
137
- }
138
- if (data?.frontmatter?.exports) {
139
- data.frontmatter.exports = data.frontmatter.exports.map((exp) => {
140
- if (!exp.url) return exp;
141
- return { ...exp, url: updateUrl(exp.url) };
142
- });
143
- }
144
- // Fix all of the images to point to the CDN
145
- const images = selectAll('image', data.mdast) as Image[];
146
- images.forEach((node) => {
147
- node.url = updateUrl(node.url);
148
- if (node.urlOptimized) {
149
- node.urlOptimized = updateUrl(node.urlOptimized);
150
- }
151
- });
152
- const links = selectAll('link,linkBlock,card', data.mdast) as Link[];
153
- const staticLinks = links.filter((node) => node.static);
154
- staticLinks.forEach((node) => {
155
- // These are static links to thinks like PDFs or other referenced files
156
- node.url = updateUrl(node.url);
157
- });
158
- const outputs = selectAll('output', data.mdast) as Output[];
159
- outputs.forEach((node) => {
160
- if (!node.data) return;
161
- walkOutputs(node.data, (obj) => {
162
- // The path will be defined from output of myst
163
- // Here we are re-assigning it to the current domain
164
- if (!obj.path) return;
165
- obj.path = updateUrl(obj.path);
166
- });
167
- });
168
- return data;
169
- }
package/src/types.ts DELETED
@@ -1,52 +0,0 @@
1
- import type { Root } from 'mdast';
2
- import type { Dependency, SourceFileKind } from 'myst-spec-ext';
3
- import type { References } from 'myst-common';
4
- import type { SiteManifest } from 'myst-config';
5
- import type { PageFrontmatter } from 'myst-frontmatter';
6
- import type { Theme } from '@myst-theme/providers';
7
-
8
- export type Heading = {
9
- slug?: string;
10
- path?: string;
11
- title: string;
12
- short_title?: string;
13
- level: number | 'index';
14
- group?: string;
15
- };
16
-
17
- export type SiteLoader = {
18
- theme: Theme;
19
- config?: SiteManifest;
20
- CONTENT_CDN_PORT?: string | number;
21
- MODE?: 'app' | 'static';
22
- BASE_URL?: string;
23
- };
24
-
25
- export type NavigationLink = {
26
- group?: string;
27
- title: string;
28
- url: string;
29
- short_title?: string;
30
- };
31
-
32
- export type FooterLinks = {
33
- navigation?: {
34
- prev?: NavigationLink;
35
- next?: NavigationLink;
36
- };
37
- };
38
-
39
- export type PageLoader = {
40
- kind: SourceFileKind;
41
- file: string;
42
- sha256: string;
43
- slug: string;
44
- domain: string; // This is written in at render time in the site
45
- project: string; // This is written in at render time in the site
46
- frontmatter: PageFrontmatter;
47
- mdast: Root;
48
- references: References;
49
- footer?: FooterLinks;
50
- // This may not be defined
51
- dependencies?: Dependency[];
52
- };