Coder Social home page Coder Social logo

rehype-pretty / rehype-pretty-code Goto Github PK

View Code? Open in Web Editor NEW
919.0 919.0 58.0 2.77 MB

Beautiful code blocks for Markdown or MDX.

Home Page: https://rehype-pretty.pages.dev

License: MIT License

JavaScript 5.44% TypeScript 71.35% CSS 2.60% MDX 20.20% Shell 0.42%
markdown mdx shiki syntax-highlighting vscode

rehype-pretty-code's People

Contributors

anasrar avatar atomiks avatar beamcode avatar beaussan avatar blake-mealey avatar dimamachina avatar ezzatron avatar gendelbendel avatar george1410 avatar goodbyenjn avatar juice49 avatar jxom avatar kaf-lamed-beyt avatar likilee avatar mashirozx avatar niksumeiko avatar o-az avatar okwasniewski avatar renrizzolo avatar shuding avatar silvenon avatar thien-do avatar ttwrpz avatar zzzkan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

rehype-pretty-code's Issues

Add the data-theme key to the wrapping pre element

Problem

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.

image

Possible workaround

Using a custom renderer for the pre element in react to look at the children's value

Possible solution

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 ! =)

Line numbers length

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;
}

MDsveX compatible?

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

[Deprecation] Change `word` terminology

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 🤔

Problems compiling using Next JS 12

Hello, I have found a small inconvenience when compiling a project in NextJS, apparently it cannot import shiki by default, but when I review the file I see that it is well exported
I attach a screenshot of the error in question and the version that I am using in the project

image

Plain text language isn't being split into lines

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>

Recipe for Astro

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]]
  }
})

Incorrect types

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.

Expose filtered meta props

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.

Add an option that would show line numbers

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!

How to use it with `unified` manually?

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:

image

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.

image

Thank you!

Highlighting works, but Meta strings do not work

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.
image
MDX file
image

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

  "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"
  }

Avoid creating wrappers `<div data-rehype-pretty-code-fragment>` and `<span data-rehype-pretty-code-fragment>``

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

Before

<div data-rehype-pretty-code-fragment>
  <pre>
    ...

<span data-rehype-pretty-code-fragment>
  <code>
    ...

After

Before

<pre data-rehype-pretty-code-fragment>
  ...

<code data-rehype-pretty-code-fragment>
  ...

TypeError: nodesToWrap.at is not a function at wordHighlighter

word highlighter works on local machine but seems to be throwing an error when deploying to Vercel

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

Using custom Font

Hi!

Thanks for this great package - I'm trying to use a custom font (Fira Mono) in code-blocks, is this possible?

Thanks!

Feature request: Fold certain lines

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!

Is compatibility with NextJS 13 contemplated?

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.

image

For a little more context, this is my package.json

image

showLineNumbers{n} didn't work with Multiple Theme

Issue Description

There is an issue with the functionality of specifying the starting line number when using showLineNumbers{n} with Multiple Themes.

Issue Reproduction

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>

My Options Object

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)
    }
  },
}

Best way to implement file title to the code block ?

Hi,

First of all, I love the style of this code block rehype plugin !

I was wondering how this plugin can be used to render blocks like this, with the file name / lang icon :

image

What would be the best way to implement it ? Can it be implemented with the current state of the library ?

Unable to set themes

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">=&gt;</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"> &lt;</span><span style="color:#E06C75">div</span><span style="color:#ABB2BF">&gt;Hello, </span><span style="color:#C678DD">{</span><span style="color:#E06C75">name</span><span style="color:#C678DD">}</span><span style="color:#ABB2BF">!&lt;/</span><span style="color:#E06C75">div</span><span style="color:#ABB2BF">&gt;</span></span>
<span class="line"><span style="color:#ABB2BF">}</span></span></code></pre></div>

Highlight Words

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!

Shiki could be integrated into the rehype-pretty-code package?

image
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.

image

image

image

Possibility to pass additional props to MDX custom components through the code blocks

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.

Caching highlighters requires restarting the app after changing the theme

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.

https://github.com/atomiks/rehype-pretty-code/blob/d64e67bf4f2865066a61f0408f0c69bf81b68fb9/src/index.js#L73-L75

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?

Word highlighting range does not work when multiple words are on one line

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:

https://github.com/atomiks/rehype-pretty-code/blob/0c14334d1a92b00ee6f09006062ef196787e260e/src/word-highlighter/wordHighlighter.js#L32

cc: @renrizzolo

[plugin:vite:resolve] Module "path" has been externalized for browser compatibility

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

Doesn't seem to work with xdm (MDX 2)

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?

Pass variable as content in MDX ?

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 by astro-m2dx

Is It possible?

some imagine syntax:

```mdx title="Demo.mdx" content={frontmatter.rawmdx}
\```

custom start at line number

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?

Double wrapper output when rendering code block with title

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).

Screenshot 2022-02-05 at 00 22 49

Support arbitrary delimiter in wordHighlighter

Hi!

Context

I needed to match a pattern containing a / character, therefore / being used as the hard-coded delimiter proved limiting.

Proposal

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('#');

Remarks

  • Here’s a test sample on Regex101 (I used PCRE as I feel like it’s closer to V8’s Irregexp engine than EcmaScript’s, but it works regardless the engine).
  • I leveraged named capture groups to increase readibility, which have been supported since Node 10. As rehype-pretty-code requires "node": "^12.16.0 || >=13.2.0" I feel like it’s fine using them.

Questions

  • There still is a hard-coded list of allowed delimiters, hence that will never cover all use-cases (eg. what if my pattern contains both " 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).
    • Another option would be to support pattern-matching within the pattern-matching. It seems you considered it for the doc reads Note regex itself is not yet supported.
  • Hacking on the code, I felt like the naming for some variables is subpar. 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?

Support for rendering inside a custom component

Goal

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

image

Problem

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.

CJS build is broken, using a dependency that is ESM only

When running rehype-pretty-code in CJS is fails because of dependency unified is ESM only. So, it can not be required

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.

Supported languages

Hi!

May I ask for the list of supported languages?

Thanks for this awesome project!

Fallback to plain text if language is not registered

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)

Error: `runSync` finished async. Use `run` instead

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.