1
1
mirror of https://github.com/mdx-js/mdx.git synced 2024-10-26 16:20:29 +03:00

Add more options to playground, directives, format, etc

Closes GH-2295.

Reviewed-by: Remco Haszing <remcohaszing@gmail.com>
Reviewed-by: Titus Wormer <tituswormer@gmail.com>
This commit is contained in:
Sébastien Lorber 2023-06-10 09:55:11 +02:00 committed by GitHub
parent 30e4a5d5d5
commit 7504cfb863
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 169 additions and 6 deletions

View File

@ -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: */

View File

@ -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 (
<div>
<div className="playground-editor">
<Tabs className="frame frame-resizeable">
<TabList className="frame-tab-bar frame-tab-bar-scroll">
<Tab
@ -166,6 +185,41 @@ export function Editor({children}) {
</TabPanel>
<TabPanel className="tab-panel-scrollable playground-editor-options-tab-panel">
<form className="frame-body frame-body-box">
<fieldset>
<label>
<input
type="radio"
name="language"
checked={!state.formatMd}
onChange={() => {
setConfig({...state, formatMd: false})
}}
/>{' '}
Use <code>MDX</code>
</label>
<span style={{margin: '1em'}}> </span>
<label>
<input
type="radio"
name="language"
checked={state.formatMd}
onChange={() => {
setConfig({...state, formatMd: true})
}}
/>{' '}
Use <code>CommonMark</code>
</label>
</fieldset>
<label>
<input
checked={state.position}
type="checkbox"
onChange={() =>
setConfig({...state, position: !state.position})
}
/>{' '}
Show positional info
</label>
<label>
<input
checked={state.gfm}
@ -201,6 +255,32 @@ export function Editor({children}) {
<code>remark-math</code>
</a>
</label>
<label>
<input
checked={state.directive}
type="checkbox"
onChange={() =>
setConfig({...state, directive: !state.directive})
}
/>{' '}
Use{' '}
<a href="https://github.com/remarkjs/remark-directive">
<code>remark-directive</code>
</a>
</label>
<label>
<input
checked={state.rehypeRaw}
type="checkbox"
onChange={() =>
setConfig({...state, rehypeRaw: !state.rehypeRaw})
}
/>{' '}
Use{' '}
<a href="https://github.com/rehypejs/rehype-raw">
<code>rehype-raw</code>
</a>
</label>
</form>
</TabPanel>
</Tabs>
@ -324,3 +404,15 @@ export function Editor({children}) {
</div>
)
}
function removePositionEsast(tree) {
visitEstree(tree, remove)
return tree
function remove(node) {
delete node.loc
delete node.start
delete node.end
delete node.range
}
}

57
package-lock.json generated
View File

@ -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",

View File

@ -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",