fix: improve mdx code block pipeline
This commit is contained in:
@@ -271,15 +271,19 @@
|
||||
background-color: oklch(0.10 0 0 / 0.85);
|
||||
color: var(--color-code-copy);
|
||||
}
|
||||
[data-rehype-pretty-code-figure]:hover .rehype-pretty-copy {
|
||||
[data-rehype-pretty-code-figure]:hover .rehype-pretty-copy,
|
||||
[data-rehype-pretty-code-figure] .rehype-pretty-copy:focus-visible,
|
||||
[data-rehype-pretty-code-figure] .rehype-pretty-copy:focus {
|
||||
opacity: 1;
|
||||
}
|
||||
[data-rehype-pretty-code-figure] .rehype-pretty-copy:hover {
|
||||
[data-rehype-pretty-code-figure] .rehype-pretty-copy:hover,
|
||||
[data-rehype-pretty-code-figure] .rehype-pretty-copy:focus-visible {
|
||||
@apply border-current;
|
||||
background-color: oklch(0.95 0 0 / 0.95);
|
||||
color: var(--color-code-copy-hover);
|
||||
}
|
||||
.dark [data-rehype-pretty-code-figure] .rehype-pretty-copy:hover {
|
||||
.dark [data-rehype-pretty-code-figure] .rehype-pretty-copy:hover,
|
||||
.dark [data-rehype-pretty-code-figure] .rehype-pretty-copy:focus-visible {
|
||||
background-color: oklch(0.15 0 0 / 0.95);
|
||||
}
|
||||
[data-rehype-pretty-code-figure] .rehype-pretty-copy.rehype-pretty-copied {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { LazyMotion, domAnimation, MotionConfig } from "motion/react";
|
||||
import { CodeCopyInit } from "@/components/ui/CodeCopyInit";
|
||||
|
||||
export function Providers({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
@@ -9,6 +10,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
||||
reducedMotion="user"
|
||||
transition={{ duration: 0.3, ease: [0.22, 1, 0.36, 1] }}
|
||||
>
|
||||
<CodeCopyInit />
|
||||
{children}
|
||||
</MotionConfig>
|
||||
</LazyMotion>
|
||||
|
||||
12
components/ui/CodeCopyInit.tsx
Normal file
12
components/ui/CodeCopyInit.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { registerCopyButton } from "@rehype-pretty/transformers";
|
||||
|
||||
export function CodeCopyInit() {
|
||||
useEffect(() => {
|
||||
registerCopyButton();
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -1,23 +1,49 @@
|
||||
/**
|
||||
* HAST visitor plugin that adds data-line-numbers attribute to code blocks
|
||||
* inside <pre> elements.
|
||||
* HAST visitor plugin that configures highlighted code blocks and adds
|
||||
* data-line-numbers attributes inside <pre> elements.
|
||||
*/
|
||||
import rehypePrettyCode from 'rehype-pretty-code'
|
||||
import { transformerCopyButton } from '@rehype-pretty/transformers'
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
const prettyCodeOptions = {
|
||||
theme: { light: 'github-light', dark: 'github-dark-dimmed' },
|
||||
keepBackground: false,
|
||||
grid: true,
|
||||
transformers: [
|
||||
transformerCopyButton({ jsx: true, visibility: 'hover', feedbackDuration: 2500 }),
|
||||
],
|
||||
}
|
||||
|
||||
/**
|
||||
* Rehype plugin that runs pretty-code with a React-safe copy button and then
|
||||
* adds line number indicators to code blocks.
|
||||
* @returns {import('unified').Plugin<[], import('hast').Root>}
|
||||
*/
|
||||
export default function codeBlockPipeline() {
|
||||
const prettyCode = rehypePrettyCode(prettyCodeOptions)
|
||||
const lineNumbers = addLineNumbers()
|
||||
|
||||
return async function transformer(tree, file) {
|
||||
await prettyCode.call(this, tree, file)
|
||||
lineNumbers(tree, file)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rehype plugin that adds line number indicators to code blocks.
|
||||
* @returns {import('unified').Plugin<[], import('hast').Root>}
|
||||
*/
|
||||
export default function addLineNumbers() {
|
||||
function addLineNumbers() {
|
||||
return function attacher(tree) {
|
||||
visit(tree, 'element', function visitor(node) {
|
||||
if (
|
||||
node.tagName === 'pre' &&
|
||||
node.children?.length === 1 &&
|
||||
node.children[0].type === 'element' &&
|
||||
node.children[0].tagName === 'code'
|
||||
) {
|
||||
const code = node.children[0]
|
||||
if (node.tagName === 'pre') {
|
||||
const code = node.children?.find(
|
||||
(child) => child.type === 'element' && child.tagName === 'code',
|
||||
)
|
||||
|
||||
if (!code) return
|
||||
|
||||
code.properties = code.properties || {}
|
||||
code.properties['data-line-numbers'] = ''
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { NextConfig } from 'next'
|
||||
import createMDX from '@next/mdx'
|
||||
|
||||
const mdxCodeBlockPipeline = new URL('./lib/mdx-hast-visitor.js', import.meta.url).pathname
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: 'export',
|
||||
trailingSlash: true,
|
||||
@@ -14,8 +16,7 @@ const withMDX = createMDX({
|
||||
'rehype-slug',
|
||||
['rehype-external-links', { target: '_blank', rel: ['nofollow', 'noopener', 'noreferrer'] }],
|
||||
'rehype-autolink-headings',
|
||||
['rehype-pretty-code', { theme: { light: 'github-light', dark: 'github-dark-dimmed' }, keepBackground: false, grid: true }],
|
||||
'/mnt/blog/new-blog/lib/mdx-hast-visitor.js',
|
||||
mdxCodeBlockPipeline,
|
||||
'rehype-katex',
|
||||
],
|
||||
},
|
||||
|
||||
8851
package-lock.json
generated
Normal file
8851
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
"dependencies": {
|
||||
"@mdx-js/loader": "^3.1.1",
|
||||
"@next/mdx": "^16.2.6",
|
||||
"@rehype-pretty/transformers": "^0.13.2",
|
||||
"@rehype-pretty/transformers": "npm:@jsr/rehype-pretty__transformers@^0.13.4",
|
||||
"@wrksz/themes": "^0.9.3",
|
||||
"gray-matter": "^4.0.3",
|
||||
"katex": "^0.17.0",
|
||||
|
||||
Reference in New Issue
Block a user