Fix code highlighting

This commit is contained in:
Marcus Blättermann 2022-12-20 08:51:10 +01:00
parent f1a54563f1
commit de3e2080b9
No known key found for this signature in database
GPG Key ID: A1E1F04008AC450D
7 changed files with 42 additions and 64 deletions

View File

@ -2,13 +2,11 @@ import MDX from '@next/mdx'
import PWA from 'next-pwa'
import remarkPlugins from './plugins/index.mjs'
import rehypePlugins from './plugins/rehypePlugins.mjs'
const withMDX = MDX({
extension: /\.mdx?$/,
options: {
remarkPlugins,
rehypePlugins,
providerImportSource: '@mdx-js/react',
},
experimental: {

View File

@ -5,7 +5,6 @@ import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
import path from 'path'
import Layout from '../src/templates'
import remarkPlugins from '../plugins/index.mjs'
import rehypePlugins from '../plugins/rehypePlugins.mjs'
import recordSection from '../meta/recordSections'
import { sidebarUsageFlat } from '../meta/sidebarFlat'
@ -94,10 +93,7 @@ export const getStaticProps: GetStaticProps<PropsPage, ParsedUrlQuery> = async (
const mdx = await serialize(fs.readFileSync(pathFileWithIndexAndExtension, 'utf-8'), {
parseFrontmatter: true,
mdxOptions: {
remarkPlugins,
rehypePlugins,
},
mdxOptions: { remarkPlugins },
})
if (!mdx.frontmatter) {

View File

@ -1,5 +0,0 @@
import rehypePrism from '@mapbox/rehype-prism'
const rehypePlugins = [rehypePrism]
export default rehypePlugins

View File

@ -54,32 +54,6 @@ function remarkCodeBlocks(userOptions = {}) {
const meta = getProps(Parser.parse(node.meta, { ecmaVersion: 'latest' }))
node.data.hProperties = Object.assign({}, hProps, attrs, meta)
if (meta.executable) {
node.type = 'mdxJsxFlowElement'
node.name = 'CodeBlock'
node.attributes = [
{
type: 'mdxJsxAttribute',
name: 'lang',
value: 'python',
},
{
type: 'mdxJsxAttribute',
name: 'executable',
value: true,
},
// Adding the children like this makes sure
// they don't get further formatted by Remark
{
type: 'mdxJsxAttribute',
name: 'children',
value: node.value,
},
]
node.data['_mdxExplicitJsx'] = true
}
}
})

View File

@ -2,10 +2,17 @@ import React, { Fragment, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import rangeParser from 'parse-numeric-range'
import { window } from 'browser-monads'
import Prism from 'prismjs'
// We manually load all the languages that are needed, which are currently only those:
import 'prismjs/components/prism-diff.min.js'
import 'prismjs/components/prism-bash.min.js'
import 'prismjs/components/prism-ini.min.js'
import 'prismjs/components/prism-jsx.min.js'
import 'prismjs/components/prism-json.min.js'
import 'prismjs/components/prism-markdown.min.js'
import 'prismjs/components/prism-python.min.js'
import 'prismjs/components/prism-yaml.min.js'
import CUSTOM_TYPES from '../../meta/type-annotations.json'
import { isString, htmlToReact } from './util'
@ -197,12 +204,7 @@ const checkoutForComment = (line) => {
)
}
const convertLine = (line, prompt) => {
const lineFlat = flattenReact(line).join('')
if (!lineFlat.startsWith(`${prompt} `)) {
return line
}
const handlePromot = ({ lineFlat, prompt }) => {
const lineWithoutPrompt = lineFlat.slice(prompt.length + 1)
const cliRegex = /^python -m spacy/
@ -244,6 +246,23 @@ const convertLine = (line, prompt) => {
)
}
const convertLine = ({ line, prompt, lang }) => {
const lineFlat = flattenReact(line).join('')
if (lineFlat.startsWith(`${prompt} `)) {
return handlePromot({ lineFlat, prompt })
}
return lang === 'none' || !lineFlat ? (
lineFlat
) : (
<span
dangerouslySetInnerHTML={{
__html: Prism.highlight(lineFlat, Prism.languages[lang], lang),
}}
/>
)
}
const addLineHighlight = (children, highlight) => {
if (!highlight) {
return children
@ -269,18 +288,18 @@ const addLineHighlight = (children, highlight) => {
})
}
const CodeHighlighted = ({ children, highlight }) => {
export const CodeHighlighted = ({ children, highlight, lang }) => {
const [html, setHtml] = useState()
useEffect(
() =>
setHtml(
addLineHighlight(
splitLines(children).map((line) => convertLine(line, '$')),
splitLines(children).map((line) => convertLine({ line, prompt: '$', lang })),
highlight
)
),
[children, highlight]
[children, highlight, lang]
)
return <>{html}</>
@ -304,8 +323,7 @@ export class Code extends React.Component {
}
render() {
const { lang, title, executable, github, prompt, wrap, highlight, className, children } =
this.props
const { lang, title, executable, github, wrap, highlight, className, children } = this.props
const codeClassNames = classNames(classes['code'], className, `language-${lang}`, {
[classes['wrap']]: !!highlight || !!wrap || lang === 'cli',
[classes['cli']]: lang === 'cli',
@ -327,7 +345,9 @@ export class Code extends React.Component {
<>
{title && <h4 className={classes['title']}>{title}</h4>}
<code className={codeClassNames}>
<CodeHighlighted highlight={highlight}>{children}</CodeHighlighted>
<CodeHighlighted highlight={highlight} lang={lang}>
{children}
</CodeHighlighted>
</code>
</>
)

View File

@ -1,17 +1,11 @@
import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import Prism from 'prismjs'
// We manually load all the languages that are needed, which are currently only those:
import 'prismjs/components/prism-json.min.js'
import 'prismjs/components/prism-python.min.js'
import 'prismjs/components/prism-yaml.min.js'
import 'prismjs/components/prism-ini.min.js'
import Icon from './icon'
import Link from './link'
import classes from '../styles/code.module.sass'
import { Code } from './code'
const defaultErrorMsg = `Can't fetch code example from GitHub :(
@ -45,9 +39,6 @@ const GitHubCode = ({ url, lang, errorMsg = defaultErrorMsg, className }) => {
}
}, [initialized, rawUrl, errorMsg])
const highlighted =
lang === 'none' || !code ? code : Prism.highlight(code, Prism.languages[lang], lang)
return (
<>
<header className={classes.header}>
@ -60,7 +51,11 @@ const GitHubCode = ({ url, lang, errorMsg = defaultErrorMsg, className }) => {
</code>
</Link>
</header>
<code className={codeClassNames} dangerouslySetInnerHTML={{ __html: highlighted }} />
{code && (
<Code className={codeClassNames} lang={lang}>
{code}
</Code>
)}
</>
)
}

View File

@ -298,8 +298,8 @@ const Model = ({
{name}
</H2>
<Aside title="Installation">
<CodeBlock lang="cli" prompt="$">
python -m spacy download {name}
<CodeBlock lang="bash" prompt="$">
$ python -m spacy download {name}
</CodeBlock>
</Aside>
{meta.description && <MarkdownToReact markdown={meta.description} />}