diff --git a/docs/_asset/index.css b/docs/_asset/index.css
index 9e5f6a527..076928355 100644
--- a/docs/_asset/index.css
+++ b/docs/_asset/index.css
@@ -748,6 +748,17 @@ button.success {
margin-block: calc(1 / 1.2 * (1em + 1ex));
}
+.playground-editor fieldset {
+ border: 0;
+ padding: 0;
+ margin: 0;
+ min-width: 0;
+}
+
+.playground-editor fieldset label {
+ display: inline;
+}
+
.frame {
/* gray-1 is used for unselected tabs, but gray-2 is really too much
* This is a perfect mix between the two: */
diff --git a/docs/_component/editor.client.js b/docs/_component/editor.client.js
index c51709646..e5832b534 100644
--- a/docs/_component/editor.client.js
+++ b/docs/_component/editor.client.js
@@ -5,10 +5,14 @@ import {VFile} from 'vfile'
import {VFileMessage} from 'vfile-message'
import {statistics} from 'vfile-statistics'
import {reporter} from 'vfile-reporter'
-import {evaluate} from '@mdx-js/mdx'
+import {evaluate, nodeTypes} from '@mdx-js/mdx'
import remarkGfm from 'remark-gfm'
+import rehypeRaw from 'rehype-raw'
import remarkFrontmatter from 'remark-frontmatter'
+import remarkDirective from 'remark-directive'
import remarkMath from 'remark-math'
+import {visit as visitEstree} from 'estree-util-visit'
+import {removePosition} from 'unist-util-remove-position'
import CodeMirror from 'rodemirror'
import {basicSetup} from 'codemirror'
import {markdown as langMarkdown} from '@codemirror/lang-markdown'
@@ -29,30 +33,41 @@ function useMdx(defaults) {
const [state, setState] = useState({...defaults, file: null})
const {run: setConfig} = useDebounceFn(
async (config) => {
- const file = new VFile({basename: 'example.mdx', value: config.value})
+ const basename = config.formatMd ? 'example.md' : 'example.mdx'
+ const file = new VFile({basename, value: config.value})
const capture = (name) => () => (tree) => {
file.data[name] = tree
}
const remarkPlugins = []
-
if (config.gfm) remarkPlugins.push(remarkGfm)
if (config.frontmatter) remarkPlugins.push(remarkFrontmatter)
if (config.math) remarkPlugins.push(remarkMath)
-
+ if (config.directive) remarkPlugins.push(remarkDirective)
remarkPlugins.push(capture('mdast'))
+ const rehypePlugins = []
+ if (config.rehypeRaw)
+ rehypePlugins.push([rehypeRaw, {passThrough: nodeTypes}])
+ rehypePlugins.push(capture('hast'))
+
try {
file.result = (
await evaluate(file, {
...runtime,
useDynamicImport: true,
remarkPlugins,
- rehypePlugins: [capture('hast')],
+ rehypePlugins,
recmaPlugins: [capture('esast')]
})
).default
+
+ if (!config.position) {
+ removePosition(file.data.mdast, {force: true})
+ removePosition(file.data.hast, {force: true})
+ removePositionEsast(file.data.esast)
+ }
} catch (error) {
const message =
error instanceof VFileMessage ? error : new VFileMessage(error)
@@ -107,9 +122,13 @@ export function Editor({children}) {
const defaultValue = children
const extensions = useMemo(() => [basicSetup, oneDark, langMarkdown()], [])
const [state, setConfig] = useMdx({
+ formatMd: false,
+ position: false,
gfm: false,
frontmatter: false,
+ directive: false,
math: false,
+ rehypeRaw: false,
value: defaultValue
})
const onUpdate = useCallback(
@@ -132,7 +151,7 @@ export function Editor({children}) {
}, [state])
return (
-
+
@@ -324,3 +404,15 @@ export function Editor({children}) {
)
}
+
+function removePositionEsast(tree) {
+ visitEstree(tree, remove)
+ return tree
+
+ function remove(node) {
+ delete node.loc
+ delete node.start
+ delete node.end
+ delete node.range
+ }
+}
diff --git a/package-lock.json b/package-lock.json
index 1e417f2e1..355c95969 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -46,6 +46,7 @@
"eslint-plugin-react-hooks": "^4.0.0",
"eslint-plugin-security": "^1.0.0",
"estree-util-value-to-estree": "^2.0.0",
+ "estree-util-visit": "^1.2.1",
"globby": "^13.0.0",
"hast-to-hyperscript": "^10.0.0",
"hast-util-select": "^5.0.0",
@@ -86,6 +87,7 @@
"rehype-slug": "^5.0.0",
"rehype-stringify": "^9.0.0",
"remark-cli": "^11.0.0",
+ "remark-directive": "^2.0.0",
"remark-frontmatter": "^4.0.0",
"remark-gemoji": "^7.0.0",
"remark-gfm": "^3.0.0",
@@ -100,6 +102,7 @@
"typescript": "^5.0.0",
"unified": "^10.0.0",
"unist-builder": "^3.0.0",
+ "unist-util-remove-position": "^4.0.2",
"unist-util-visit": "^4.0.0",
"uvu": "^0.5.0",
"vfile": "^5.0.0",
@@ -9081,6 +9084,25 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-directive": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-2.2.4.tgz",
+ "integrity": "sha512-sK3ojFP+jpj1n7Zo5ZKvoxP1MvLyzVG63+gm40Z/qI00avzdPCYxt7RBMgofwAva9gBjbDBWVRB/i+UD+fUCzQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "@types/unist": "^2.0.0",
+ "mdast-util-from-markdown": "^1.3.0",
+ "mdast-util-to-markdown": "^1.5.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-visit-parents": "^5.1.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/mdast-util-find-and-replace": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz",
@@ -9790,6 +9812,25 @@
"uvu": "^0.5.0"
}
},
+ "node_modules/micromark-extension-directive": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-2.2.0.tgz",
+ "integrity": "sha512-LWc2mGlJlPEcESz4IHNJR/tpJfWJEEFHGM+6vgCZGXkKMXc/y8rCKB07x5ZNnafIFe0/sjt6DIIihk78/Egj5Q==",
+ "dev": true,
+ "dependencies": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-factory-whitespace": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "parse-entities": "^4.0.0",
+ "uvu": "^0.5.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/micromark-extension-frontmatter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-1.0.0.tgz",
@@ -14099,6 +14140,22 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/remark-directive": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-2.0.1.tgz",
+ "integrity": "sha512-oosbsUAkU/qmUE78anLaJePnPis4ihsE7Agp0T/oqTzvTea8pOiaYEtfInU/+xMOVTS9PN5AhGOiaIVe4GD8gw==",
+ "dev": true,
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-directive": "^2.0.0",
+ "micromark-extension-directive": "^2.0.0",
+ "unified": "^10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/remark-frontmatter": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz",
diff --git a/package.json b/package.json
index f5f3d0096..cd60ef6b9 100644
--- a/package.json
+++ b/package.json
@@ -89,6 +89,7 @@
"rehype-slug": "^5.0.0",
"rehype-stringify": "^9.0.0",
"remark-cli": "^11.0.0",
+ "remark-directive": "^2.0.0",
"remark-frontmatter": "^4.0.0",
"remark-gemoji": "^7.0.0",
"remark-gfm": "^3.0.0",
@@ -104,6 +105,8 @@
"unified": "^10.0.0",
"unist-builder": "^3.0.0",
"unist-util-visit": "^4.0.0",
+ "estree-util-visit": "^1.2.1",
+ "unist-util-remove-position": "^4.0.2",
"uvu": "^0.5.0",
"vfile": "^5.0.0",
"vfile-message": "^3.0.0",