Skip to content

Commit

Permalink
docs: remark-code-import and remark-shiki-twoslash working
Browse files Browse the repository at this point in the history
But not together! See shikijs/twoslash#125 (comment)
  • Loading branch information
tonyxiao committed Dec 11, 2023
1 parent e507073 commit 5186d78
Show file tree
Hide file tree
Showing 5 changed files with 468 additions and 4 deletions.
45 changes: 44 additions & 1 deletion examples/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,47 @@ import {Thing} from './thing'
<code className="language-tsx">
{fs.readFileSync('./thing.tsx', 'utf8')}
</code>
</pre>
</pre>


```ts file=./example-qbo.mts#L3-L6
```

```twoslash include main
const a = 1
// - 1
const b = 2
// - 2
const c= 3
```

Let's talk a bit about `a`:

```ts twoslash
// @include: main-1
```

`a` can be added to another number

```ts twoslash
// @include: main-1
// ---cut---
const nextA = a + 13
```

You can see what happens when you add `a + b`

```ts twoslash
// @include: main-2
// ---cut---
const result = a + b
// ^?
```

Finally here is `c`:

```ts twoslash
// @include: main
// ---cut---
c.toString()
```
40 changes: 40 additions & 0 deletions examples/bin/mdxToMd.loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {createLoader} from '@mdx-js/node-loader'
import codeImport from 'remark-code-import'
import remarkShikiTwoslash from 'remark-shiki-twoslash'

// https://github.com/shikijs/twoslash/issues/125#issuecomment-1710838839
function remarkHtmlToJsx() {
async function transform(...args: any[]) {
// Async import since these packages are all in ESM
const {visit, SKIP} = await import('unist-util-visit')
const {mdxFromMarkdown} = await import('mdast-util-mdx')
const {fromMarkdown} = await import('mdast-util-from-markdown')
const {mdxjs} = await import('micromark-extension-mdxjs')

// This is a horror show, but it's the only way I could get the raw HTML into MDX.
const [ast] = args
visit(ast, 'html', (node) => {
const escapedHtml = JSON.stringify(node.value)
const jsx = `<div dangerouslySetInnerHTML={{__html: ${escapedHtml} }}/>`
const rawHtmlNode = fromMarkdown(jsx, {
extensions: [mdxjs()],
mdastExtensions: [mdxFromMarkdown()],
}).children[0]

Object.assign(node, rawHtmlNode)

return SKIP
})
}

return transform
}

// This extra file is needed due to limitation of the `register` api in node
export const {load} = createLoader({
remarkPlugins: [
[codeImport],
[remarkShikiTwoslash.default],
[remarkHtmlToJsx],
],
})
20 changes: 17 additions & 3 deletions examples/bin/mdxToMd.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
#!/usr/bin/env node --import tsx --loader=@mdx-js/node-loader
#!/usr/bin/env node --import tsx
/**
* Alternatively, you can run this script with npx
* npx tsx --loader=@mdx-js/node-loader ./bin/mdxToMd.ts ./README.mdx
* npx tsx ./bin/mdxToMd.ts ./README.mdx
*/
import {register} from 'node:module'
import {resolve as resolvePath} from 'node:path'
import {parseArgs} from 'node:util'
import {NodeHtmlMarkdown} from 'node-html-markdown'
import React from 'react'
import {renderToStaticMarkup} from 'react-dom/server'

register('./mdxToMd.loader.ts', import.meta.url)

const {
positionals: [filename],
} = parseArgs({allowPositionals: true})
values: {debug},
} = parseArgs({
options: {
debug: {type: 'boolean', alias: 'd'},
},
allowPositionals: true,
})
if (!filename) {
throw new Error('You must specify a filename')
}
Expand All @@ -22,6 +31,11 @@ const {default: Content} = await import(sourceMDX)

const htmlToMarkdown = new NodeHtmlMarkdown()
const html = renderToStaticMarkup(React.createElement(Content))

if (debug) {
console.log(html)
}

const markdown = htmlToMarkdown.translate(html)

console.log(markdown)
Loading

0 comments on commit 5186d78

Please sign in to comment.