From a2c86936a99e695b5175f893d481171c8ce572fb Mon Sep 17 00:00:00 2001 From: Titus Date: Fri, 29 Sep 2023 20:57:34 +0200 Subject: [PATCH] Fix site * new very fast, more spacious, playground * proper syntax highlighting for MDX * static (except for playground), no RSC, super fast, can be hosted everywhere --- .husky/.gitignore | 1 - .husky/pre-commit | 4 - docs/{404.server.mdx => 404.mdx} | 4 +- docs/_asset/editor.jsx | 497 ++ docs/_asset/index.client.js | 18 - docs/_asset/index.css | 198 +- docs/_asset/index.js | 84 + docs/_asset/root.client.js | 28 - docs/_component/{blog.server.js => blog.jsx} | 0 docs/_component/copy.client.js | 54 - docs/_component/editor.client.js | 418 -- .../{foot-site.server.js => foot-site.jsx} | 0 docs/_component/{home.server.js => home.jsx} | 4 +- .../icon/{github.server.js => github.jsx} | 0 .../icon/{mdx.server.js => mdx.jsx} | 0 ...llective.server.js => open-collective.jsx} | 0 .../icon/{twitter.server.js => twitter.jsx} | 0 .../{layout.server.js => layout.jsx} | 4 +- .../{nav-site.server.js => nav-site.jsx} | 10 +- docs/_component/{nav.server.js => nav.jsx} | 0 docs/_component/{note.server.js => note.jsx} | 0 .../{snowfall.server.js => snowfall.jsx} | 0 docs/_config.js | 1 + docs/blog/{conf.server.mdx => conf.mdx} | 2 +- ...om-pragma.server.mdx => custom-pragma.mdx} | 14 +- docs/blog/{index.server.mdx => index.mdx} | 2 +- .../{shortcodes.server.mdx => shortcodes.mdx} | 4 +- docs/blog/{v1.server.mdx => v1.mdx} | 2 +- docs/blog/{v2.server.mdx => v2.mdx} | 12 +- .../community/{about.server.mdx => about.mdx} | 2 +- .../{contribute.server.mdx => contribute.mdx} | 4 +- .../community/{index.server.mdx => index.mdx} | 2 +- .../{projects.server.mdx => projects.mdx} | 2 +- .../{sponsor.server.mdx => sponsor.mdx} | 0 .../{support.server.mdx => support.mdx} | 2 +- ...nding-mdx.server.mdx => extending-mdx.mdx} | 4 +- ...started.server.mdx => getting-started.mdx} | 52 +- docs/docs/{index.server.mdx => index.mdx} | 2 +- ...mdx.server.mdx => troubleshooting-mdx.mdx} | 30 +- .../{using-mdx.server.mdx => using-mdx.mdx} | 32 +- ...what-is-mdx.server.mdx => what-is-mdx.mdx} | 28 +- docs/guides/{embed.server.mdx => embed.mdx} | 10 +- ...frontmatter.server.mdx => frontmatter.mdx} | 6 +- docs/guides/{gfm.server.mdx => gfm.mdx} | 4 +- docs/guides/{index.server.mdx => index.mdx} | 2 +- docs/guides/{math.server.mdx => math.mdx} | 8 +- ...on-demand.server.mdx => mdx-on-demand.mdx} | 8 +- ...ing.server.mdx => syntax-highlighting.mdx} | 22 +- docs/{index.server.mdx => index.mdx} | 6 +- docs/migrating/{v1.server.mdx => v1.mdx} | 6 +- docs/migrating/{v2.server.mdx => v2.mdx} | 42 +- .../{esbuild.server.md => esbuild.md} | 0 docs/packages/{index.server.mdx => index.mdx} | 2 +- docs/packages/{loader.server.md => loader.md} | 0 docs/packages/{mdx.server.md => mdx.md} | 0 .../{node-loader.server.md => node-loader.md} | 0 docs/packages/{preact.server.md => preact.md} | 0 docs/packages/{react.server.md => react.md} | 0 .../{register.server.md => register.md} | 0 .../{remark-mdx.server.md => remark-mdx.md} | 0 docs/packages/{rollup.server.md => rollup.md} | 0 docs/packages/{vue.server.md => vue.md} | 0 .../{playground.server.mdx => playground.mdx} | 12 +- ...nts.server.mdx => table-of-components.mdx} | 45 +- package-lock.json | 5720 ++++++++--------- package.json | 90 +- packages/esbuild/readme.md | 8 +- packages/esbuild/test/index.js | 3 + packages/loader/readme.md | 4 +- packages/mdx/lib/plugin/recma-document.js | 10 +- packages/mdx/lib/plugin/recma-jsx-rewrite.js | 2 +- packages/mdx/readme.md | 60 +- packages/mdx/test/compile.js | 6 +- packages/mdx/test/evaluate.js | 24 +- packages/node-loader/readme.md | 4 +- packages/preact/readme.md | 2 +- packages/react/readme.md | 2 +- packages/register/readme.md | 4 +- packages/remark-mdx/readme.md | 4 +- packages/rollup/readme.md | 4 +- packages/vue/package.json | 2 +- packages/vue/readme.md | 2 +- ....0.0-experimental-1159ff619-20220324.patch | 80 - ...-experimental-1159ff619-20220324.patch.bak | 80 - renovate.json5 | 7 - script/jsx-loader.js | 69 +- tsconfig.json | 3 +- website/bundle.js | 47 - website/generate.js | 296 + website/generate.server.js | 172 - website/loader-react-server.js | 6 - website/loader.js | 7 +- website/mdx-config.js | 158 +- website/post.js | 117 +- website/prep.js | 20 +- website/prerender.js | 229 - 96 files changed, 4108 insertions(+), 4828 deletions(-) delete mode 100644 .husky/.gitignore delete mode 100755 .husky/pre-commit rename docs/{404.server.mdx => 404.mdx} (80%) create mode 100644 docs/_asset/editor.jsx delete mode 100644 docs/_asset/index.client.js create mode 100644 docs/_asset/index.js delete mode 100644 docs/_asset/root.client.js rename docs/_component/{blog.server.js => blog.jsx} (100%) delete mode 100644 docs/_component/copy.client.js delete mode 100644 docs/_component/editor.client.js rename docs/_component/{foot-site.server.js => foot-site.jsx} (100%) rename docs/_component/{home.server.js => home.jsx} (83%) rename docs/_component/icon/{github.server.js => github.jsx} (100%) rename docs/_component/icon/{mdx.server.js => mdx.jsx} (100%) rename docs/_component/icon/{open-collective.server.js => open-collective.jsx} (100%) rename docs/_component/icon/{twitter.server.js => twitter.jsx} (100%) rename docs/_component/{layout.server.js => layout.jsx} (98%) rename docs/_component/{nav-site.server.js => nav-site.jsx} (84%) rename docs/_component/{nav.server.js => nav.jsx} (100%) rename docs/_component/{note.server.js => note.jsx} (100%) rename docs/_component/{snowfall.server.js => snowfall.jsx} (100%) rename docs/blog/{conf.server.mdx => conf.mdx} (98%) rename docs/blog/{custom-pragma.server.mdx => custom-pragma.mdx} (98%) rename docs/blog/{index.server.mdx => index.mdx} (90%) rename docs/blog/{shortcodes.server.mdx => shortcodes.mdx} (95%) rename docs/blog/{v1.server.mdx => v1.mdx} (99%) rename docs/blog/{v2.server.mdx => v2.mdx} (98%) rename docs/community/{about.server.mdx => about.mdx} (99%) rename docs/community/{contribute.server.mdx => contribute.mdx} (98%) rename docs/community/{index.server.mdx => index.mdx} (90%) rename docs/community/{projects.server.mdx => projects.mdx} (97%) rename docs/community/{sponsor.server.mdx => sponsor.mdx} (100%) rename docs/community/{support.server.mdx => support.mdx} (97%) rename docs/docs/{extending-mdx.server.mdx => extending-mdx.mdx} (99%) rename docs/docs/{getting-started.server.mdx => getting-started.mdx} (97%) rename docs/docs/{index.server.mdx => index.mdx} (91%) rename docs/docs/{troubleshooting-mdx.server.mdx => troubleshooting-mdx.mdx} (98%) rename docs/docs/{using-mdx.server.mdx => using-mdx.mdx} (96%) rename docs/docs/{what-is-mdx.server.mdx => what-is-mdx.mdx} (96%) rename docs/guides/{embed.server.mdx => embed.mdx} (96%) rename docs/guides/{frontmatter.server.mdx => frontmatter.mdx} (97%) rename docs/guides/{gfm.server.mdx => gfm.mdx} (98%) rename docs/guides/{index.server.mdx => index.mdx} (90%) rename docs/guides/{math.server.mdx => math.mdx} (95%) rename docs/guides/{mdx-on-demand.server.mdx => mdx-on-demand.mdx} (96%) rename docs/guides/{syntax-highlighting.server.mdx => syntax-highlighting.mdx} (94%) rename docs/{index.server.mdx => index.mdx} (96%) rename docs/migrating/{v1.server.mdx => v1.mdx} (97%) rename docs/migrating/{v2.server.mdx => v2.mdx} (97%) rename docs/packages/{esbuild.server.md => esbuild.md} (100%) rename docs/packages/{index.server.mdx => index.mdx} (92%) rename docs/packages/{loader.server.md => loader.md} (100%) rename docs/packages/{mdx.server.md => mdx.md} (100%) rename docs/packages/{node-loader.server.md => node-loader.md} (100%) rename docs/packages/{preact.server.md => preact.md} (100%) rename docs/packages/{react.server.md => react.md} (100%) rename docs/packages/{register.server.md => register.md} (100%) rename docs/packages/{remark-mdx.server.md => remark-mdx.md} (100%) rename docs/packages/{rollup.server.md => rollup.md} (100%) rename docs/packages/{vue.server.md => vue.md} (100%) rename docs/{playground.server.mdx => playground.mdx} (60%) rename docs/{table-of-components.server.mdx => table-of-components.mdx} (92%) delete mode 100644 patches/react-server-dom-webpack+0.0.0-experimental-1159ff619-20220324.patch delete mode 100644 patches/react-server-dom-webpack+0.0.0-experimental-1159ff619-20220324.patch.bak create mode 100644 website/generate.js delete mode 100644 website/generate.server.js delete mode 100644 website/loader-react-server.js delete mode 100644 website/prerender.js diff --git a/.husky/.gitignore b/.husky/.gitignore deleted file mode 100644 index 31354ec13..000000000 --- a/.husky/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_ diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 36af21989..000000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx lint-staged diff --git a/docs/404.server.mdx b/docs/404.mdx similarity index 80% rename from docs/404.server.mdx rename to docs/404.mdx index df0860264..9810d665b 100644 --- a/docs/404.server.mdx +++ b/docs/404.mdx @@ -1,5 +1,5 @@ -import {Note} from './_component/note.server.js' -export {Home as default} from './_component/home.server.js' +import {Note} from './_component/note.jsx' +export {Home as default} from './_component/home.jsx' export const navExclude = true # 404: Not found diff --git a/docs/_asset/editor.jsx b/docs/_asset/editor.jsx new file mode 100644 index 000000000..960de7f10 --- /dev/null +++ b/docs/_asset/editor.jsx @@ -0,0 +1,497 @@ +/* @jsxRuntime automatic @jsxImportSource react */ + +/** + * @typedef {import('@wooorm/starry-night').Grammar} Grammar + * @typedef {import('mdx/types.js').MDXModule} MDXModule + * @typedef {import('react-error-boundary').FallbackProps} FallbackProps + * @typedef {import('unified').PluggableList} PluggableList + * @typedef {import('unist').Node} UnistNode + */ + +/** + * @typedef EvalOk + * @property {true} ok + * @property {JSX.Element} value + * + * @typedef EvalNok + * @property {false} ok + * @property {Error} value + * + * @typedef {EvalOk | EvalNok} EvalResult + */ + +import {compile, nodeTypes, run} from '@mdx-js/mdx' +import {createStarryNight} from '@wooorm/starry-night' +import sourceCss from '@wooorm/starry-night/source.css' +import sourceJs from '@wooorm/starry-night/source.js' +import sourceJson from '@wooorm/starry-night/source.json' +import sourceMdx from '@wooorm/starry-night/source.mdx' +import sourceTs from '@wooorm/starry-night/source.ts' +import sourceTsx from '@wooorm/starry-night/source.tsx' +import textHtmlBasic from '@wooorm/starry-night/text.html.basic' +import textMd from '@wooorm/starry-night/text.md' +import {visit as visitEstree} from 'estree-util-visit' +import {toJsxRuntime} from 'hast-util-to-jsx-runtime' +import {useEffect, useState} from 'react' +// @ts-expect-error: untyped. +import {Fragment, jsx, jsxs} from 'react/jsx-runtime' +import ReactDom from 'react-dom/client' +import {ErrorBoundary} from 'react-error-boundary' +import rehypeRaw from 'rehype-raw' +import remarkDirective from 'remark-directive' +import remarkFrontmatter from 'remark-frontmatter' +import remarkGfm from 'remark-gfm' +import remarkMath from 'remark-math' +import {removePosition} from 'unist-util-remove-position' +import {visit} from 'unist-util-visit' +import {VFile} from 'vfile' + +const runtime = {Fragment, jsx, jsxs} + +const sample = `# Hello, world! + +Below is an example of markdown in JSX. + +
+ Try and change the background color to \`tomato\`. +
` + +/** @type {ReadonlyArray} */ +const grammars = [ + sourceCss, + sourceJs, + // @ts-expect-error: TS is wrong: this is not a JSON file. + sourceJson, + sourceMdx, + sourceTs, + sourceTsx, + textHtmlBasic, + textMd +] + +/** @type {Awaited>} */ +let starryNight + +const body = document.querySelector('.body') + +if (body && window.location.pathname === '/playground/') { + const root = document.createElement('div') + root.classList.add('playground') + body.after(root) + init(root) +} + +/** + * @param {Element} main + */ +function init(main) { + const root = ReactDom.createRoot(main) + + createStarryNight(grammars).then( + /** + * @returns {undefined} + */ + function (x) { + starryNight = x + + const missing = starryNight.missingScopes() + if (missing.length > 0) { + throw new Error('Unexpected missing required scopes: `' + missing + '`') + } + + root.render() + } + ) +} + +function Playground() { + const [value, setValue] = useState(sample) + const [directive, setDirective] = useState(false) + const [frontmatter, setFrontmatter] = useState(false) + const [gfm, setGfm] = useState(false) + const [markdown, setMarkdown] = useState(false) + const [math, setMath] = useState(false) + const [raw, setRaw] = useState(false) + const [positions, setPositions] = useState(false) + const [output, setOutput] = useState('result') + const [evalResult, setEvalResult] = useState( + /** @type {unknown} */ (undefined) + ) + + useEffect( + function () { + go().then( + function (ok) { + setEvalResult({ok: true, value: ok}) + }, + /** + * @param {Error} error + */ + function (error) { + setEvalResult({ok: false, value: error}) + } + ) + + async function go() { + /** @type {PluggableList} */ + const recmaPlugins = [] + /** @type {PluggableList} */ + const rehypePlugins = [] + /** @type {PluggableList} */ + const remarkPlugins = [] + + if (directive) remarkPlugins.unshift(remarkDirective) + if (frontmatter) remarkPlugins.unshift(remarkFrontmatter) + if (gfm) remarkPlugins.unshift(remarkGfm) + if (math) remarkPlugins.unshift(remarkMath) + if (raw) rehypePlugins.unshift([rehypeRaw, {passThrough: nodeTypes}]) + + const file = new VFile({ + basename: markdown ? 'example.md' : 'example.mdx', + value + }) + + if (output === 'mdast') remarkPlugins.push([capture, {name: 'mdast'}]) + if (output === 'hast') rehypePlugins.push([capture, {name: 'hast'}]) + if (output === 'esast') recmaPlugins.push([capture, {name: 'esast'}]) + /** @type {UnistNode | undefined} */ + let tree + + await compile(file, { + outputFormat: output === 'result' ? 'function-body' : 'program', + recmaPlugins, + rehypePlugins, + remarkPlugins, + useDynamicImport: true + }) + + if (output === 'result') { + /** @type {MDXModule} */ + const mod = await run(String(file), runtime) + + return ( + +
{mod.default({})}
+
+ ) + } + + if (tree) { + return ( +
+              
+                {toJsxRuntime(
+                  starryNight.highlight(
+                    JSON.stringify(tree, undefined, 2),
+                    'source.json'
+                  ),
+                  runtime
+                )}
+              
+            
+ ) + } + + // `output === 'code'` + return ( +
+            
+              {toJsxRuntime(
+                starryNight.highlight(String(file), 'source.js'),
+                runtime
+              )}
+            
+          
+ ) + + /** + * @param {{name: string}} options + */ + function capture(options) { + /** + * @param {UnistNode} node + */ + return function (node) { + const clone = structuredClone(node) + + if (!positions) { + if (options.name === 'esast') { + cleanEstree(clone) + } else { + cleanUnistTree(clone) + } + } + + tree = clone + } + } + } + }, + [directive, frontmatter, gfm, markdown, math, output, positions, raw, value] + ) + + const scope = markdown ? 'text.md' : 'source.mdx' + const compiledResult = /** @type {EvalResult | undefined} */ (evalResult) + /** @type {JSX.Element | undefined} */ + let display + + if (compiledResult) { + if (compiledResult.ok) { + display = compiledResult.value + } else { + display = ( +
+

Could not compile code:

+ +
+ ) + } + } + + return ( + <> +
+
+
+
+ {toJsxRuntime(starryNight.highlight(value, scope), runtime)} + {/* Trailing whitespace in a `textarea` is shown, but not in a `div` + with `white-space: pre-wrap`. + Add a `br` to make the last newline explicit. */} + {/\n[ \t]*$/.test(value) ?
: undefined} +
+