rehype-pretty / rehype-pretty-code Goto Github PK
View Code? Open in Web Editor NEWBeautiful code blocks for Markdown or MDX.
Home Page: https://rehype-pretty.pages.dev
License: MIT License
Beautiful code blocks for Markdown or MDX.
Home Page: https://rehype-pretty.pages.dev
License: MIT License
When styling with a custom theme (for example, light and dark theme), the data theme only applies to the code
element, and not the wrapping pre
. This makes it a bit harder to style properly since you can't style the pre
element at all, since you can't change the style depending on the children's data keys.
Using a custom renderer for the pre
element in react to look at the children's value
Add the data-theme
to the pre
element
Pr : #32 , if any contributors think it's not a good idea, feel free to tell me so, I will delete the pr ! =)
Add line numbers length to CSS variable can create dynamic line numbers width.
code > .line::before {
counter-increment: line;
content: counter(line);
/* Other styling */
display: inline-block;
- width: 1rem;
+ width: calc(var(--line-numbers-length) * 1rem);
margin-right: 2rem;
text-align: right;
color: gray;
}
Has anyone tried using rehype-pretty-code
with MDsveX? Just installing it and adding it to the list of rehypePlugins
doesn't seem to work.
Steps I tried (without any apparent effect)
pnpm add -D rehype-pretty-code shiki
followed by
import adapter from '@sveltejs/adapter-static'
import { mdsvex } from 'mdsvex'
import rehype_pretty_code from 'rehype-pretty-code'
import preprocess from 'svelte-preprocess'
/** @type {import('@sveltejs/kit').Config} */
export default {
extensions: [`.svelte`, `.svx`, `.md`],
preprocess: [
preprocess(),
mdsvex({
rehypePlugins: [rehype_pretty_code], // doesn't appear to work
extensions: [`.svx`, `.md`],
}),
],
kit: {
adapter: adapter(),
},
}
Related issue: pngwn/MDsveX#388
The types provided for the options object say that all items are required, yet the documentation and source code suggest that not all the options are required.
For nearly a year, the world highlighter has been able to highlight any series of characters including ones that span across syntax boundaries or spaces, so word
is not the right terminology. We should deprecate onVisitHighlightedWord
and emit a warning to change it to one of these:
onVisitHighlightedString
onVisitHighlightedCharacters
/ onVisitHighlightedChars
onVisitHighlightedText
Which one though 🤔
Hey! 👋
Not sure if this is expected behavior, but I noticed that the plain text language, i.e. txt
, outputs the entire code inside a single <span class="line">
. The whitespace is preserved, though, but the single line naturally causes problems with CSS.
I created a repro so you can quickly run it yourself.
import { unified } from 'unified'
import markdown from 'remark-parse'
import toRehype from 'remark-rehype'
import prettyCode from 'rehype-pretty-code'
import stringify from 'rehype-stringify'
const toHtml = unified()
.use(markdown)
.use(toRehype)
.use(prettyCode)
.use(stringify)
.process
const result = await toHtml(`
~~~txt
first line
second line
third line
~~~
`)
console.log(String(result))
The above logs the following HTML:
<div data-rehype-pretty-code-fragment=""><pre><code data-language="txt" data-theme="default"><span class="line"><span style="color: #d8dee9ff">first line
second line
third line</span></span></code></pre></div>
I can confirm that it also works with https://astro.build v2:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import rehypePrettyCode from 'rehype-pretty-code';
export default defineConfig({
integrations: [mdx()],
markdown: {
syntaxHighlight: false, // don't use default mechanism
rehypePlugins: [[rehypePrettyCode, options]]
}
})
Property 'children' does not exist on type 'Node<Data>'.ts
The Node
type is the following (from hast
which exports it from uinst
):
export interface Node<TData extends object = Data> {
type: string;
data?: TData | undefined;
position?: Position | undefined;
}
In here the usage example has node.children
and node.properties
but neither children nor properties
are properties of type Node
.
For the new feature, filter meta string, it'd be neat to have these props available in the pre block. My own usecase is that I'd like more control over the title block when replacing the pre block, eg:
pre: (props) => {
const ref = useRef<HTMLElement>(null);
// able to poke around props to get language, theme, and custom 'filename'
return <>
<div>{filename} {morestuff}</div>
<pre>
{cloneElement(props.children as ReactElement, { ref })}
</pre>
</>
}
A thought: since they'll be key value pairs, they could potentially become data attributes eg data-${key}="${value}"
? Not sure.
Would be great if it had an option that would add a class
or data-*
attribute to the code block.
The following package has such option, but I'm not sure if your package has it as well, but it's undocumented?
rehype-prism-plus
In short, this is their syntax
```js {1,3-4} showLineNumbers
I added the styles with counter
, but I don't want to have such style everywhere, especially not on single line blocks.
BTW – Great package, I am just developing new personal portfolio/blog and I found this some time ago through Twitter. Keep it up!
In the doc, it only mentions how to use it with @next/mdx
, but if I don't use @next/mdx
, how should I do?
The following code is how I use it:
import { Octokit } from "octokit"
import rehypeAutolinkHeadings from "rehype-autolink-headings"
import rehypePrettyCode from "rehype-pretty-code"
import rehypeSlug from "rehype-slug"
import rehypeStringify from "rehype-stringify"
import remarkGfm from "remark-gfm"
import remarkParse from "remark-parse"
import remarkRehype from "remark-rehype"
import { unified } from "unified"
const token = process.env.GITHUB_API_TOKEN ?? ""
const org = process.env.GITHUB_TARGET_ORG ?? ""
const repo = process.env.GITHUB_TARGET_REPO ?? ""
const sdk = new Octokit({ auth: token })
export async function getIssue(slug: string) {
const res = await sdk.rest.issues.get({
owner: org,
repo,
issue_number: Number(slug),
})
const processedContent = await unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkRehype)
.use(rehypeSlug)
.use(rehypeAutolinkHeadings)
.use(rehypePrettyCode, { theme: "one-dark-pro" })
.use(rehypeStringify)
.process(res.data.body ?? "")
const htmlContent = String(processedContent)
return {
...res.data,
htmlContent,
}
}
When I build it, it reports the following error:
./src/lib/github-issues.ts:42:10
Type error: Argument of type 'Plugin<[(Options | undefined)?] | void[], Root, string>' is not assignable to parameter of type 'Preset | PluggableList'.
40 | .use(rehypeAutolinkHeadings)
41 | .use(rehypePrettyCode, { theme: "one-dark-pro" })
> 42 | .use(rehypeStringify)
| ^
43 | .process(res.data.body ?? "")
44 | const htmlContent = String(processedContent)
45 |
ELIFECYCLE Command failed with exit code 1.
VS Code also report the same error:
Although this is a nextjs 13 app router project, but I don't use @next/mdx
. It works fine if I replace the rehype-pretty-code
by rehype-highlight
or rehype-prism-plus
.
Thank you!
```js filename="a/hello/file.js"
console.log("hello")
```
originally reported in shuding/nextra#1088
I was able to syntax-highlight the code displayed in MDX using rehype-pretty-code in Next13, but here is the site (https://rehype-pretty-code.netlify.app/ )
However, all of the Meta strings listed on this site do not work.
I have done a lot of research and could not figure out why, so I would appreciate it if you could let me know.
Below is the actual code and an image of Meta strings not working.
MDX file
import Layout from "@/components/layout";
import { postsFileNames, postsPath } from "@/utils/mdxUtils";
import path from "path";
import matter from "gray-matter";
import { MDXRemote } from "next-mdx-remote";
import { serialize } from "next-mdx-remote/serialize";
import mdxStyles from "@/components/mdx/mdx.module.css"
import rehypePrettyCode from "rehype-pretty-code";
export default function About({ source }) {
return (
<>
<div className="bg-white ">
<div className="mx-auto max-w-screen-xl px-4 md:px-8">
<div className={mdxStyles.mdx}>
<MDXRemote {...source}></MDXRemote>
</div>
</div>
</div>
</>
);
}
export async function getStaticProps() {
const content = fs.readFileSync(path.join(postsPath, "pages/about.mdx"));
const options = {
// Use one of Shiki's packaged themes
theme: "dark-plus",
keepBackground: true,
};
const mdxSource = await serialize(content, {
mdxOptions: {
remarkPlugins: [],
rehypePlugins: [[rehypePrettyCode,options]],
},
});
return { props: { source: mdxSource } };
}
"dependencies": {
"@chakra-ui/react": "^2.6.1",
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@mdx-js/loader": "^2.3.0",
"@next/mdx": "^13.4.3",
"@types/node": "20.2.1",
"@types/react": "18.2.6",
"@types/react-dom": "18.2.4",
"autoprefixer": "10.4.14",
"eslint": "8.41.0",
"eslint-config-next": "13.4.3",
"framer-motion": "^10.12.12",
"gray-matter": "^4.0.3",
"next": "13.4.3",
"next-mdx-remote": "^4.4.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"rehype-pretty-code": "^0.9.5",
"shiki": "^0.14.2",
"tailwindcss": "3.3.2",
"typescript": "5.0.4"
}
I want to suggest to avoid creating <div />
/<span />
wrappers for code blocks/inline code blocks
Instead, data-rehype-pretty-code-fragment
attribute can be attached directly in <pre />
/<code />
elements
<div data-rehype-pretty-code-fragment>
<pre>
...
<span data-rehype-pretty-code-fragment>
<code>
...
Before
<pre data-rehype-pretty-code-fragment>
...
<code data-rehype-pretty-code-fragment>
...
Unable to build next app, found this while trying to update to the latest version
https://github.com/shuding/nextra/actions/runs/3337967625/jobs/5525004171#step:11:199
Here are the options I'm using:
const prettyCodeOptions = {
theme: 'material-palenight',
onVisitLine(node) {
if (node.children.length === 0) {
node.children = [{ type: 'text', value: ' ' }]
}
},
onVisitHighlightedLine(node) {
node.properties.className.push('highlighted')
},
onVisitHighlightedWord(node) {
node.properties.className = ['highlighted', 'word']
}
}
the markdown file I'm trying to highlight contains the following code fence block
import Link from 'next/link'
import Example from './example.mdx'
const Home = () => {
return <Example name="alice" />
}
export default Home
Thank you
I want to wrap some mdx code blocks with Sanpack components, like how react.org does it:
<Sandpack>
``js
function playWithThisInteractiveExample() {...}
``
</Sandpack>
Hi!
Thanks for this great package - I'm trying to use a custom font (Fira Mono) in code-blocks, is this possible?
Thanks!
It seems that 8885e75 has drastic performance degradation on memory usage.
Reproduction: https://github.com/brillout/rehype-pretty-code_performance-degradation-reproduction.
(Btw. thanks for rehype-pretty-code
, FYI I'm using it for https://vite-plugin-ssr.com/ and https://telefunc.com/ and I really like the code blocks :-).)
It would be nice if it was easily possible to mark certain parts of code examples collapsible (imports in my case) with a little [+] or [-] icon.
Is this something that the summary
tag could provide or would I have to reach out to radix-ui's collapsible or is it not possible at all?
Sorry if this out of scope!
That way, readers can translate your content into their own language, without it messing up code snippets
Context:
https://twitter.com/joshwcomeau/status/1646275569657470978
Hello again :)
I recently tried to migrate a project to nextjs 13 that I had using their library and as I had contemplated, I assumed that this version would break with compatibility.
Apparently, it seems that the vscode-onigurama WebAssembly file could not be opened.
For a little more context, this is my package.json
There is an issue with the functionality of specifying the starting line number when using showLineNumbers{n}
with Multiple Themes.
Markdown
```ts showLineNumbers{3}
//code
```
When the above markdown is written, the style="counter-set:line 2"
is only applied to one theme.
Output HTML
<div data-rehype-pretty-code-fragment="">
<pre data-language="ts" data-theme="dark">
<code data-line-numbers="" style="counter-set:line 2" data-language="ts" data-theme="dark" data-line-numbers-max-digits="1">
...
</code>
</pre>
<pre data-language="ts" data-theme="light">
<code data-line-numbers="" data-language="ts" data-theme="light" data-line-numbers-max-digits="1">
</code>
</pre>
</div>
const prettyCodeOptions: Partial<PrettyCodeOptions> = {
theme: {
dark: 'one-dark-pro',
/* 💡Copy https://github.com/saicharan-m/light-plus-noctis/blob/main/themes/Noctis%20Light%2B-color-theme.json */
light: JSON.parse(readFileSync('./code_theme/light-plus-noctis.json', 'utf-8')),
},
onVisitLine(node: any) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty
// lines to be copy/pasted
if (node.children.length === 0) {
node.children = [{ type: 'text', value: ' ' }]
}
},
onVisitHighlightedLine(node: any) {
node.properties.className.push('line--highlighted')
},
onVisitHighlightedWord(node: any, id: string) {
node.properties.className = ['word--highlighted']
if (id) {
/* 💡 In markdown:' ```ts /target1/#y /target2/#b ' will highlight all matched text yellow or blue*/
const colorClass = {
y: 'yellow',
b: 'blue',
}[id]
node.properties.className.push(colorClass)
}
},
}
Hello!
I'm having trouble getting any themes to apply. I am using rehype-pretty-code
within a Remix app using mdx-bundler
. It seems like no matter what I pass for the theme:
key, output remains styled as the default theme.
const rehypePrettyCodeOptions = {
theme: 'one-dark-pro',
}
async function compileMdxImpl<FrontmatterType extends Record<string, unknown>>({
slug,
files,
}: {
slug: string
files: Array<GitHubFile>
}) {
const { default: remarkAutolinkHeader } = await import("remark-autolink-headings");
const { default: remarkGfm } = await import('remark-gfm')
const { default: remarkSlug } = await import('remark-slug')
const { default: rehypePrettyCode } = await import('rehype-pretty-code')
// truncated
try {
const { code, frontmatter } = await bundleMDX({
source: indexFile.content,
files: filesObject,
xdmOptions: options => ({
remarkPlugins: [
...(options.remarkPlugins ?? []),
remarkSlug,
[remarkAutolinkHeader, { behavior: 'wrap' }],
remarkGfm,
],
rehypePlugins: [
...(options.rehypePlugins ?? []),
[rehypePrettyCode, rehypePrettyCodeOptions],
],
}),
})
return { code, frontmatter: frontmatter as FrontmatterType }
} catch (e) {
throw new Error(`MDX Compilation failed for ${slug}`)
}
}
so this system works (i.e I see my other remark/rehype plugins working). I see this generated HTML for my codeblock (note the data-theme="default"
and not the expected one-dark-pro
):
<div data-rehype-pretty-code-fragment=""><div data-rehype-pretty-code-title="" data-language="tsx" data-theme="default">hello!!!</div><pre data-language="tsx" data-theme="default"><code data-language="tsx" data-theme="default"><span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> </span><span style="color:#E06C75">Bar</span><span style="color:#ABB2BF"> </span><span style="color:#C678DD">from</span><span style="color:#ABB2BF"> </span><span style="color:#98C379">'./Bar'</span></span>
<span class="line"> </span>
<span class="line"><span style="color:#C678DD">interface</span><span style="color:#ABB2BF"> </span><span style="color:#E5C07B">Props</span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#ABB2BF"> </span><span data-rehype-pretty-code-wrapper="true" class="word"><span style="color:#E06C75">name</span><span style="color:#ABB2BF">: </span><span style="color:#E5C07B">string</span></span></span>
<span class="line"><span style="color:#ABB2BF">}</span></span>
<span class="line"> </span>
<span class="line"><span style="color:#C678DD">const</span><span style="color:#ABB2BF"> </span><span style="color:#61AFEF">Foo</span><span style="color:#ABB2BF"> </span><span style="color:#56B6C2">=</span><span style="color:#ABB2BF"> ({ </span><span style="color:#E06C75;font-style:italic">name</span><span style="color:#ABB2BF"> }: </span><span style="color:#E5C07B">Props</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#ABB2BF"> {</span></span>
<span class="line"><span style="color:#ABB2BF"> </span><span style="color:#C678DD">return</span><span style="color:#ABB2BF"> <</span><span style="color:#E06C75">div</span><span style="color:#ABB2BF">>Hello, </span><span style="color:#C678DD">{</span><span style="color:#E06C75">name</span><span style="color:#C678DD">}</span><span style="color:#ABB2BF">!</</span><span style="color:#E06C75">div</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">}</span></span></code></pre></div>
Any working example with Astro MDX?
Because the <span>
tags break up words by syntax boundaries, we can't highlight text like theme: 'x'
in a code block, only theme
, or x
, without any punctuation.
I experimented with removing the <span>
tags, .textContent
, etc, but didn't come up with a viable solution.
cc: @renrizzolo maybe you have some ideas?
I tried to highlight multiple words like this:
```sh /"Nenad Novakovic"|"[email protected]"/
And also like this:
```sh /"Nenad Novakovic"/ /"[email protected]"/
But neither approach has worked. In the docs, I saw an example with a single word only. Is this not a possibility yet and may I know if the regex going to be an option?
Good day!
I have been using the library in these weeks and I have been fascinated with everything it can do.
Lately I've had a problem using it in production with next-mdx-remote, it seems to be the platform I use, it can't find shiki in production.
I am attaching some screenshots of how I am implementing the rendering in production using the vercel ISR to generate and update the pages.
Hi, currently when using MDX custom components and rehype-pretty-code, the following props are passed through to the component:
style: { backgroundColor: '#282c34' },
'data-language': 'js',
'data-theme': 'default',
Is is possible to pass additional props to the component? For example:
Consider a code fence:
```js copyEnabled
if (entry[0].boundingClientRect.y < 0) {
logo.dataset.spin = 'false';
} else {
if (!isSpinning) logo.dataset.spin = 'true';
isSpinning = false;
}
Here copyEnabled
is custom metadata. This copyEnabled
metadata should be available as a prop to the MDX custom component.
This way we can conditionally control the components through markdown very easily.
Hey James! 👋
In my Remix app I noticed that changing the theme only takes after restarting the server (try changing the theme in this repro). First I thought that the problem was in Remix itself, then somewhere in mdx-bundler, perhaps esbuild, but eventually I figured out that it's (probably) because of the way highlighterCache
works.
It's true that in my case this is a development-only problem, but one case where this is a bigger problem is if you wanted to compile Markdown twice using different pairs of light
and dark
themes, I think that currently isn't possible because the highlighters are cached using those keys.
I'm not sure how to solve this problem, maybe use the hash of the theme object as the key?
Hi there, I'm super excited about this for my new site. I am trying to not wrap my outputted code in the <div data-rehype-pretty-code-fragment=""></div>
tag. I see in the code that this should be possible, but I'm not sure how to. Any help would be appreciated
Right now the wordHighlighter
range works per line, not per occurrence of words. So this fails to highlight the occurrences of words correctly:
```js /word/1,2
const word = 'word'; // word
const word2 = 'word'; // word
```
Only the word
const and the word
string on the first line should be highlighted, but it highlights every occurrence of word
on the first and second lines.
I think this function needs to take an argument:
cc: @renrizzolo
When I try to use the theme, warn when vite build:
[plugin:vite:resolve] Module "crypto" has been externalized for browser compatibility
[plugin:vite:resolve] Module "process" has been externalized for browser compatibility
[plugin:vite:resolve] Module "url" has been externalized for browser compatibility,
[plugin:vite:resolve] Module "path" has been externalized for browser compatibility,
etc
I tried this plugin with xdm:
import fs from 'node:fs/promises'
import { compile } from 'xdm'
import { createRemarkPlugin } from '@atomiks/mdx-pretty-code'
const prettyCode = createRemarkPlugin({
shikiOptions: {
theme: JSON.parse(
await fs.readFile('node_modules/shiki/themes/github-light.json', 'utf8')
)
}
})
const mdxContent = `
# Hello World
~~~js
console.log('Hello World')
~~~
`.trim()
const result = await compile(mdxContent, {
remarkPlugins: [prettyCode],
})
console.log(String(result))
But I'm getting the following error:
Error: Cannot handle unknown node `raw`
at Object.unknown (file:///Users/silvenon/Code/test/node_modules/hast-util-to-estree/index.js:155:9)
at Object.one [as handle] (file:///Users/silvenon/Code/test/node_modules/zwitch/index.js:52:17)
at all (file:///Users/silvenon/Code/test/node_modules/hast-util-to-estree/index.js:583:28)
at Object.root (file:///Users/silvenon/Code/test/node_modules/hast-util-to-estree/index.js:508:20)
at Object.one [as handle] (file:///Users/silvenon/Code/test/node_modules/zwitch/index.js:52:17)
at toEstree (file:///Users/silvenon/Code/test/node_modules/hast-util-to-estree/index.js:119:24)
at file:///Users/silvenon/Code/test/node_modules/xdm/lib/plugin/rehype-recma.js:15:20
at wrapped (file:///Users/silvenon/Code/test/node_modules/trough/index.js:111:16)
at next (file:///Users/silvenon/Code/test/node_modules/trough/index.js:62:23)
at done (file:///Users/silvenon/Code/test/node_modules/trough/index.js:145:7)
I tried the same with @mdx-js/mdx
and it works as expected. Maybe it's an incompatibility with micromark?
I want to pass a variable to rehype-pretty-code
as content in MDX,
something like this:
```mdx title="Demo.mdx"
{frontmatter.rawmdx}
\```
frontmatter.rawmdx
is created byastro-m2dx
Is It possible?
some imagine syntax:
```mdx title="Demo.mdx" content={frontmatter.rawmdx}
\```
I'm looking for a way to start the line numbers from a specific number (every code block will be different, based to the code section I'm showing from the whole file).
I managed to set it up manually using:
code[data-line-numbers] > .line:first-of-type::before {
counter-set: line 100;
}
or
counter-reset: line 100;
So the numbers start at 100.
But I didn't find a way to set the number (100) from the markdown code block itself.
Or maybe even put it in a custom attribute so I can get it in the css like this: attr(data-start-at)
.
Am I missing something?
I noticed this behaviour of double rendering the wrapping container for code blocks that include title.
For those that do not include a title, there's only one wrapping container.
Is this intentional for some reason or it's a mistake?
Notice SS that's attached, double data-rehype-pretty-code-fragment
div(s).
Hi!
I needed to match a pattern containing a /
character, therefore /
being used as the hard-coded delimiter proved limiting.
Would you consider a PR building upon this core change (I used patch-package to get things going quickly):
diff --git a/node_modules/rehype-pretty-code/dist/rehype-pretty-code.cjs b/node_modules/rehype-pretty-code/dist/rehype-pretty-code.cjs
index 54c1c36..26d8a36 100644
--- a/node_modules/rehype-pretty-code/dist/rehype-pretty-code.cjs
+++ b/node_modules/rehype-pretty-code/dist/rehype-pretty-code.cjs
@@ -12897,12 +12897,12 @@ function rehypePrettyCode(options = {}) {
const wordIdsMap = new Map();
const wordMatches = meta
- ? [...meta.matchAll(/\/(.*?)\/(\S*)/g)]
+ ? [...meta.matchAll(/(?<delimiter>["\/])(?<word>.*?)\k<delimiter>(?<wordIdAndOrRange>\S*)/g)]
: undefined;
if (Array.isArray(wordMatches)) {
wordMatches.forEach((name, index) => {
- const word = wordMatches[index][1];
- const wordIdAndOrRange = wordMatches[index][2];
+ const { word, wordIdAndOrRange } = name.groups;
words.push(word);
const [range, id] = wordIdAndOrRange.split('#');
"node": "^12.16.0 || >=13.2.0"
I feel like it’s fine using them."
and /
?). I feel like we could provide a sane, exported default list and also allow developers to provide their own as an escape hatch (and because we’d export the default list, they could build upon it for maximum compatibility/future-proofness).
words
/word
in particular, as word
may actually contain multiple words (any pattern the developer wants to match within the code block, really). I didn’t alter that naming but I’d propose doing it in the PR.What do you think?
I'd like to write MDX file, which contains code examples for multiple languages. In order to reduce amount of space taken by code examples, it would be nice to have dropdown/switch component for toggling between languages. Example screenshot taken from geeksforgeeks
As far as I understand, rehype-pretty-code
can't currently be used to achieve that as it only exposes a function, which is a a rehype plugin and it can't be used inside a react component.
When running rehype-pretty-code
in CJS is fails because of dependency unified
is ESM only. So, it can not be require
d
failed to load config from /Users/manualmeida/repos/builderio/qwik/packages/docs/vite.config.ts
error during build:
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/manualmeida/repos/builderio/qwik/node_modules/.pnpm/[email protected]/node_modules/unified/index.js from /Users/manualmeida/repos/builderio/qwik/node_modules/.pnpm/[email protected][email protected]/node_modules/rehype-pretty-code/dist/rehype-pretty-code.cjs not supported.
Hi!
May I ask for the list of supported languages?
Thanks for this awesome project!
When the markdown uses a language that is not registered in shiki (e.g. "console") then the whole mdx compile will fail. Is there a way to avoid failing the whole compilation and just skip syntax highlighting (or fallback to plain text) if language is not registered?
Thank you
1 of 1 unhandled error
Server Error
Error: No language registration for console
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
getGrammar
file:///Users/thien/Code/memos-pub/node_modules/shiki/dist/index.js (2175:19)
codeToThemedTokens
file:///Users/thien/Code/memos-pub/node_modules/shiki/dist/index.js (2184:30)
Object.codeToHtml
file:///Users/thien/Code/memos-pub/node_modules/shiki/dist/index.js (2201:24)
<unknown>
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (12699:25)
overload
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (359:16)
node (�[33melement<pre>�[39m)
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (264:31)
node (�[33mroot�[39m)
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (281:79)
visitParents
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (221:30)
visit
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (351:7)
<unknown>
file:///Users/thien/Code/memos-pub/node_modules/rehype-pretty-code/dist/rehype-pretty-code.js (12623:5)
Hello thank you for this package.
Trying to use it as such; doing server side rendering in nextjs:
import fs from 'fs';
import ReactMarkdown from 'react-markdown';
import matter from 'gray-matter';
import get_post_metadata from '@helpers/get_post_metadata';
import rehypePrettyCode from 'rehype-pretty-code';
import remarkGfm from 'remark-gfm'; // allows github flavored markdown
import rehypeRaw from "rehype-raw"; // allows raw html in markdown
import rehypeSlug from 'rehype-slug'; // adds id to headings
import remarkUnwrapImages from 'remark-unwrap-images'; // removes p tag around images
import remarkExternalLinks from 'remark-external-links'; // manage external links
import remarkToc from 'remark-toc'
const get_post_content = (slug: string) => {
const folder = 'blog/';
const file = `${folder}${slug}.md`;
const content = fs.readFileSync(file, 'utf8');
return matter(content);
}
// a next function to generate static paths for the dynamic pages
export const generateStaticParams = (): Array<{ slug: string }> => {
const posts = get_post_metadata();
return posts.map((post: PostMetadata) => {
return { slug: post.slug }
});
}
const PostPage = (props: any) => {
const slug = props.params.slug;
const post = get_post_content(slug);
return (
<>
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkUnwrapImages, remarkExternalLinks, remarkToc]}
rehypePlugins={[rehypeRaw, rehypeSlug, rehypePrettyCode]}
>
{post.content}
</ReactMarkdown>
</>
)
}
export default PostPage;
I'm getting this error:
1 of 1 unhandled error
Next.js is up to date
Unhandled Runtime Error
Error: `runSync` finished async. Use `run` instead
Call Stack
assertDone
node_modules/unified/lib/index.js (566:10)
assertDone
node_modules/unified/lib/index.js (352:4)
runSync
node_modules/react-markdown/lib/react-markdown.js (106:29)
type
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1399:17)
attemptResolveElement
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1736:20)
resolveModelToJSON
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1201:13)
stringify
<anonymous>
stringify
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2348:13)
processModelChunk
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2054:25)
retryTask
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2101:6)
performWork
node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1496:13)
listOnTimeout
node:internal/timers (569:17)
process.processTimers
node:internal/timers (512:7)
I checked the source code and I found runSync
being used. What can I do, I'm rather new to Next so I'm thinking it has to do with async vs sync code? I'm a little lost please help.
I'm interested in a highlighter that supports the R
language or at least the possibility of extending it which I believe this library does.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.