simplified gatsby sourcing

This commit is contained in:
jasongao97 2022-07-26 15:25:53 -04:00
parent 1db5100551
commit 66e28644cc
14 changed files with 377 additions and 2740 deletions

View file

@ -5,12 +5,13 @@ module.exports = {
},
plugins: [
{
resolve: `gatsby-plugin-mdx`,
resolve: `gatsby-source-filesystem`,
options: {
extensions: [`.mdx`],
gatsbyRemarkPlugins: ['gatsby-remark-prismjs'],
name: `pages`,
path: `${__dirname}/content/`,
},
},
`gatsby-transformer-json`,
`gatsby-plugin-postcss`,
],
};

View file

@ -1,42 +1,2 @@
const path = require('path');
exports.sourceNodes = require('./gatsby/source-nodes.js');
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions;
const result = await graphql(`
query {
allMdx {
edges {
node {
id
parent {
... on SourceRemark {
title
}
}
}
}
}
}
`);
if (result.errors) {
reporter.panicOnBuild('🚨 ERROR: Loading "createPages" query');
}
// Create blog post pages.
const posts = result.data.allMdx.edges;
// you'll call `createPage` for each result
posts.forEach(({ node }) => {
createPage({
path: `/${node.parent.title}/`,
component: path.resolve(`./src/layouts/PostLayout.js`),
context: {
id: node.id,
},
});
});
};
exports.onCreateNode = require('./gatsby/on-create-node.js');
exports.createPages = require('./gatsby/create-pages.js');

35
gatsby/create-pages.js Normal file
View file

@ -0,0 +1,35 @@
const path = require('path');
module.exports = async ({ graphql, actions, reporter }) => {
const { createPage } = actions;
const result = await graphql(`
query {
allChaptersJson {
edges {
node {
slug
id
}
}
}
}
`);
if (result.errors) {
reporter.panicOnBuild('🚨 ERROR: Loading "createPages" query');
}
// Create a page for each chapter
const pages = result.data.allChaptersJson.edges;
pages.forEach(({ node }) => {
createPage({
path: `/${node.slug}/`,
component: path.resolve(`./src/layouts/ChapterLayout.js`),
context: {
id: node.id,
},
});
});
};

View file

@ -1,46 +0,0 @@
import { parseFragment } from 'parse5';
import { fromParse5 } from 'hast-util-from-parse5';
import { toMdast } from 'hast-util-to-mdast';
import { toMarkdown } from 'mdast-util-to-markdown';
import { toString } from 'hast-util-to-string';
import { toHtml } from 'hast-util-to-html';
import { mdxToMarkdown } from 'mdast-util-mdx';
import { mathToMarkdown } from 'mdast-util-math';
export const convert = (html) => {
const parse5 = parseFragment(html);
const hast = fromParse5(parse5);
const mdast = toMdast(hast, {
handlers: {
table(h, node) {
return h(node, 'html', toHtml(node, { space: 'table' }));
},
div(h, node) {
if (node.properties['example-path']) {
return h(node, 'mdxJsxFlowElement', {
name: 'Example',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'path',
value: node.properties['example-path'],
},
],
});
}
},
equation(h, node) {
if (node.properties.dataType === 'inline') {
return h(node, 'inlineMath', toString(node));
}
return h(node, 'math', toString(node));
},
},
});
return toMarkdown(mdast, {
listItemIndent: 'one',
extensions: [mathToMarkdown(), mdxToMarkdown()],
});
};

15
gatsby/on-create-node.js Normal file
View file

@ -0,0 +1,15 @@
module.exports = async ({ node, actions, loadNodeContent }) => {
const { createNodeField } = actions;
if (node.internal.mediaType !== `text/html`) {
return;
}
// load the html source to every HTML file node
const content = await loadNodeContent(node);
createNodeField({
node,
name: 'html',
value: content,
});
};

View file

@ -1,34 +0,0 @@
const fs = require('fs/promises');
const path = require('path');
const CONTENT_DIR = 'content/';
module.exports = async ({ actions, createNodeId, createContentDigest }) => {
const { createNode } = actions;
const { convert } = await import('./lib/convert-file.mjs');
const fileNames = await fs.readdir(CONTENT_DIR);
await Promise.all(fileNames.map(importFile));
async function importFile(fileName, index) {
const html = String(await fs.readFile(path.resolve(CONTENT_DIR, fileName)));
const content = convert(html);
const node = {
id: createNodeId(`source-remark-${fileName}`),
parent: null,
children: [],
title: fileName.split('.html')[0],
internal: {
type: `SourceRemark`,
mediaType: 'text/markdown',
content: String(content),
contentDigest: createContentDigest(content),
},
};
createNode(node);
}
};

2794
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -23,35 +23,28 @@
},
"homepage": "https://github.com/nature-of-code/noc-notion#readme",
"dependencies": {
"@mdx-js/mdx": "^1.6.22",
"@mdx-js/react": "^1.6.22",
"@notionhq/client": "^2.0.0",
"@tailwindcss/typography": "^0.5.4",
"autoprefixer": "^10.4.7",
"dotenv": "^16.0.0",
"gatsby": "^4.19.1",
"gatsby-plugin-mdx": "^3.19.0",
"gatsby-plugin-postcss": "^5.19.0",
"gatsby-remark-prismjs": "^6.19.0",
"hast-util-from-parse5": "^7.1.0",
"gatsby-source-filesystem": "^4.19.0",
"gatsby-transformer-json": "^4.19.0",
"hast-util-to-html": "^8.0.3",
"hast-util-to-mdast": "^8.3.1",
"hast-util-to-string": "^2.0.0",
"hastscript": "^7.0.2",
"lodash-es": "^4.17.21",
"magicbook": "^0.1.20",
"magicbook-codesplit": "^0.1.6",
"magicbook-katex": "0.0.7",
"mdast-util-math": "^2.0.1",
"mdast-util-mdx": "^2.0.0",
"mdast-util-to-markdown": "^1.3.0",
"parse5": "^7.0.0",
"postcss": "^8.4.14",
"prismjs": "^1.28.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rehype-format": "^4.0.1",
"rehype-parse": "^8.0.4",
"rehype-react": "^7.1.1",
"tailwindcss": "^3.1.6",
"unified": "^10.1.2",
"unist-util-visit": "^4.1.0"
},
"devDependencies": {}

View file

@ -36,17 +36,18 @@ async function main() {
}
async function importDatabase(pages) {
const db = {
pages: pages.map((page) => {
return {
title: page.properties['Title'],
src: `./${page.properties['File Name']}.html`,
slug: page.properties['Slug'],
};
}),
};
const chapters = pages.map((page) => {
return {
title: page.properties['Title'],
src: `./${page.properties['File Name']}.html`,
slug: page.properties['Slug'],
};
});
await fs.writeFile(`${DESTINATION_FOLDER}/db.json`, JSON.stringify(db));
await fs.writeFile(
`${DESTINATION_FOLDER}/chapters.json`,
JSON.stringify(chapters),
);
}
async function importPage({ id, properties }) {

View file

@ -77,13 +77,7 @@ function transform(block) {
{
dataCodeLanguage: block.code.language,
},
[
h(
'code',
{ class: `language-${block.code.language}` },
block.code.rich_text.map(transformText),
),
],
block.code.rich_text.map(transformText),
);
// List

View file

@ -0,0 +1,20 @@
import { createElement, Fragment, useEffect, useState } from 'react';
import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeReact from 'rehype-react';
export function useRehypeProcessor(text) {
const [Content, setContent] = useState(Fragment);
useEffect(() => {
unified()
.use(rehypeParse, { fragment: true })
.use(rehypeReact, { createElement, Fragment })
.process(text)
.then((file) => {
setContent(file.result);
});
}, [text]);
return Content;
}

View file

@ -0,0 +1,30 @@
import React from 'react';
import { graphql } from 'gatsby';
import { useRehypeProcessor } from '../hooks/useRehypeProcessor';
export default function ChapterLayout({ data }) {
const { chaptersJson } = data;
const body = useRehypeProcessor(chaptersJson.src.fields.html);
return (
<div className="px-4">
<div className="my-8 mx-auto w-[640px] prose">{body}</div>
</div>
);
}
export const query = graphql`
query ChapterById($id: String!) {
chaptersJson(id: { eq: $id }) {
id
slug
title
src {
fields {
html
}
}
}
}
`;

View file

@ -1,27 +0,0 @@
import React from 'react';
import { graphql } from 'gatsby';
import { MDXRenderer } from 'gatsby-plugin-mdx';
import { MDXProvider } from '@mdx-js/react';
import Example from '../components/Example';
export default function PostLayout({ data }) {
const { body } = data.mdx;
return (
<div className="px-4">
<MDXProvider components={{ Example }}>
<div className="my-8 mx-auto w-[640px] prose">
<MDXRenderer>{body}</MDXRenderer>
</div>
</MDXProvider>
</div>
);
}
export const query = graphql`
query PostBySlug($id: String!) {
mdx(id: { eq: $id }) {
body
}
}
`;

View file

@ -7,12 +7,10 @@ export default function IndexPage({ data }) {
<div className="my-8 mx-auto w-[640px] prose">
<h1>Nature of Code</h1>
<ul>
{data.allMdx.edges.map(({ node }) => {
{data.allChaptersJson.edges.map(({ node }) => {
return (
<li key={node.parent.title}>
<Link
to={`${node.parent.title}/`}
>{`${node.parent.title}/`}</Link>
<li key={node.id}>
<Link to={`/${node.slug}`}>{node.title}</Link>
</li>
);
})}
@ -23,16 +21,13 @@ export default function IndexPage({ data }) {
}
export const query = graphql`
query QueryPages {
allMdx {
query QueryChapters {
allChaptersJson {
edges {
node {
id
parent {
... on SourceRemark {
title
}
}
title
slug
}
}
}