mirror of
				https://github.com/explosion/spaCy.git
				synced 2025-11-04 09:57:26 +03:00 
			
		
		
		
	Fix code syntax highlighting
This commit is contained in:
		
							parent
							
								
									46fb76c281
								
							
						
					
					
						commit
						47e4c62741
					
				
							
								
								
									
										4947
									
								
								website/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4947
									
								
								website/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
        "prettier": "prettier . --write"
 | 
					        "prettier": "prettier . --write"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
 | 
					        "@mapbox/rehype-prism": "^0.8.0",
 | 
				
			||||||
        "@mdx-js/loader": "^2.1.5",
 | 
					        "@mdx-js/loader": "^2.1.5",
 | 
				
			||||||
        "@mdx-js/react": "^2.1.5",
 | 
					        "@mdx-js/react": "^2.1.5",
 | 
				
			||||||
        "@next/mdx": "^13.0.2",
 | 
					        "@next/mdx": "^13.0.2",
 | 
				
			||||||
| 
						 | 
					@ -18,6 +19,7 @@
 | 
				
			||||||
        "@types/node": "18.11.9",
 | 
					        "@types/node": "18.11.9",
 | 
				
			||||||
        "@types/react": "18.0.25",
 | 
					        "@types/react": "18.0.25",
 | 
				
			||||||
        "@types/react-dom": "18.0.8",
 | 
					        "@types/react-dom": "18.0.8",
 | 
				
			||||||
 | 
					        "acorn": "^8.8.1",
 | 
				
			||||||
        "browser-monads": "^1.0.0",
 | 
					        "browser-monads": "^1.0.0",
 | 
				
			||||||
        "classnames": "^2.3.2",
 | 
					        "classnames": "^2.3.2",
 | 
				
			||||||
        "eslint": "8.27.0",
 | 
					        "eslint": "8.27.0",
 | 
				
			||||||
| 
						 | 
					@ -27,7 +29,9 @@
 | 
				
			||||||
        "md-attr-parser": "^1.3.0",
 | 
					        "md-attr-parser": "^1.3.0",
 | 
				
			||||||
        "next": "13.0.2",
 | 
					        "next": "13.0.2",
 | 
				
			||||||
        "next-mdx-remote": "^4.2.0",
 | 
					        "next-mdx-remote": "^4.2.0",
 | 
				
			||||||
 | 
					        "parse-numeric-range": "^1.3.0",
 | 
				
			||||||
        "prettier": "^2.7.1",
 | 
					        "prettier": "^2.7.1",
 | 
				
			||||||
 | 
					        "prismjs": "^1.29.0",
 | 
				
			||||||
        "prop-types": "^15.8.1",
 | 
					        "prop-types": "^15.8.1",
 | 
				
			||||||
        "react": "18.2.0",
 | 
					        "react": "18.2.0",
 | 
				
			||||||
        "react-dom": "18.2.0",
 | 
					        "react-dom": "18.2.0",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,9 +92,7 @@ export const getStaticProps: GetStaticProps<PropsPage, ParsedUrlQuery> = async (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const mdx = await serialize(fs.readFileSync(pathFileWithIndexAndExtension, 'utf-8'), {
 | 
					    const mdx = await serialize(fs.readFileSync(pathFileWithIndexAndExtension, 'utf-8'), {
 | 
				
			||||||
        parseFrontmatter: true,
 | 
					        parseFrontmatter: true,
 | 
				
			||||||
        mdxOptions: {
 | 
					        mdxOptions: { remarkPlugins },
 | 
				
			||||||
            remarkPlugins,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!mdx.frontmatter) {
 | 
					    if (!mdx.frontmatter) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,8 @@ const getProps = (estree) => {
 | 
				
			||||||
        return {}
 | 
					        return {}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const estreeBodyFirstNode = estree.body[0]
 | 
					    const estreeBodyFirstNode =
 | 
				
			||||||
 | 
					        estree.body[0].type === 'BlockStatement' ? estree.body[0].body[0] : estree.body[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (estreeBodyFirstNode.type !== 'ExpressionStatement' || !estreeBodyFirstNode.expression) {
 | 
					    if (estreeBodyFirstNode.type !== 'ExpressionStatement' || !estreeBodyFirstNode.expression) {
 | 
				
			||||||
        return {}
 | 
					        return {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,12 @@
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Support titles, line highlights and more for code blocks
 | 
					 * Support titles, line highlights and more for code blocks
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					import { Parser } from 'acorn'
 | 
				
			||||||
import { visit } from 'unist-util-visit'
 | 
					import { visit } from 'unist-util-visit'
 | 
				
			||||||
import parseAttr from 'md-attr-parser'
 | 
					import parseAttr from 'md-attr-parser'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import getProps from './getProps.mjs'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const defaultOptions = {
 | 
					const defaultOptions = {
 | 
				
			||||||
    defaultPrefix: '###',
 | 
					    defaultPrefix: '###',
 | 
				
			||||||
    prefixMap: {
 | 
					    prefixMap: {
 | 
				
			||||||
| 
						 | 
					@ -43,12 +45,15 @@ function remarkCodeBlocks(userOptions = {}) {
 | 
				
			||||||
                    firstLine.startsWith('%%GITHUB_')
 | 
					                    firstLine.startsWith('%%GITHUB_')
 | 
				
			||||||
                ) {
 | 
					                ) {
 | 
				
			||||||
                    // GitHub URL
 | 
					                    // GitHub URL
 | 
				
			||||||
                    attrs.github = 'true'
 | 
					                    attrs.github = node.value
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const data = node.data || (node.data = {})
 | 
					                const data = node.data || (node.data = {})
 | 
				
			||||||
                const hProps = data.hProperties || (data.hProperties = {})
 | 
					                const hProps = data.hProperties || (data.hProperties = {})
 | 
				
			||||||
                node.data.hProperties = Object.assign({}, hProps, attrs)
 | 
					
 | 
				
			||||||
 | 
					                const meta = getProps(Parser.parse(node.meta, { ecmaVersion: 'latest' }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                node.data.hProperties = Object.assign({}, hProps, attrs, meta)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,18 @@
 | 
				
			||||||
import React, { Fragment } from 'react'
 | 
					import React, { Fragment, useEffect, useState } from 'react'
 | 
				
			||||||
import PropTypes from 'prop-types'
 | 
					import PropTypes from 'prop-types'
 | 
				
			||||||
import classNames from 'classnames'
 | 
					import classNames from 'classnames'
 | 
				
			||||||
import highlightCode from 'gatsby-remark-prismjs/highlight-code.js'
 | 
					 | 
				
			||||||
import 'prismjs-bibtex'
 | 
					 | 
				
			||||||
import rangeParser from 'parse-numeric-range'
 | 
					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 CUSTOM_TYPES from '../../meta/type-annotations.json'
 | 
				
			||||||
import { isString, htmlToReact } from './util'
 | 
					import { isString, htmlToReact } from './util'
 | 
				
			||||||
| 
						 | 
					@ -71,7 +79,8 @@ export const TypeAnnotation = ({ lang = 'python', link = true, children }) => {
 | 
				
			||||||
    const code = Array.isArray(children) ? children.join('') : children || ''
 | 
					    const code = Array.isArray(children) ? children.join('') : children || ''
 | 
				
			||||||
    const [rawText, meta] = code.split(/(?= \(.+\)$)/)
 | 
					    const [rawText, meta] = code.split(/(?= \(.+\)$)/)
 | 
				
			||||||
    const rawStr = rawText.replace(/\./g, TMP_DOT)
 | 
					    const rawStr = rawText.replace(/\./g, TMP_DOT)
 | 
				
			||||||
    const rawHtml = lang === 'none' || !code ? code : highlightCode(lang, rawStr)
 | 
					    const rawHtml =
 | 
				
			||||||
 | 
					        lang === 'none' || !code ? code : Prism.highlight(rawStr, Prism.languages[lang], lang)
 | 
				
			||||||
    const html = rawHtml.replace(new RegExp(TMP_DOT, 'g'), '.').replace(/\n/g, ' ')
 | 
					    const html = rawHtml.replace(new RegExp(TMP_DOT, 'g'), '.').replace(/\n/g, ' ')
 | 
				
			||||||
    const result = htmlToReact(html)
 | 
					    const result = htmlToReact(html)
 | 
				
			||||||
    const elements = Array.isArray(result) ? result : [result]
 | 
					    const elements = Array.isArray(result) ? result : [result]
 | 
				
			||||||
| 
						 | 
					@ -94,12 +103,48 @@ export const TypeAnnotation = ({ lang = 'python', link = true, children }) => {
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function replacePrompt(line, prompt, isFirst = false) {
 | 
					const splitLines = (children) => {
 | 
				
			||||||
    let result = line
 | 
					    const listChildrenPerLine = []
 | 
				
			||||||
    const hasPrompt = result.startsWith(`${prompt} `)
 | 
					
 | 
				
			||||||
    const showPrompt = hasPrompt || isFirst
 | 
					    if (typeof children === 'string') {
 | 
				
			||||||
    if (hasPrompt) result = result.slice(2)
 | 
					        listChildrenPerLine.push(...children.split('\n'))
 | 
				
			||||||
    return result && showPrompt ? `<span data-prompt="${prompt}">${result}</span>` : result
 | 
					    } else {
 | 
				
			||||||
 | 
					        listChildrenPerLine.push([])
 | 
				
			||||||
 | 
					        let indexLine = 0
 | 
				
			||||||
 | 
					        if (Array.isArray(children)) {
 | 
				
			||||||
 | 
					            children.forEach((child) => {
 | 
				
			||||||
 | 
					                if (typeof child === 'string' && child.includes('\n')) {
 | 
				
			||||||
 | 
					                    const listString = child.split('\n')
 | 
				
			||||||
 | 
					                    listString.forEach((string, index) => {
 | 
				
			||||||
 | 
					                        listChildrenPerLine[indexLine].push(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (index !== listString.length - 1) {
 | 
				
			||||||
 | 
					                            indexLine += 1
 | 
				
			||||||
 | 
					                            listChildrenPerLine[indexLine] = []
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    listChildrenPerLine[indexLine].push(child)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            listChildrenPerLine[indexLine].push(children)
 | 
				
			||||||
 | 
					            indexLine += 1
 | 
				
			||||||
 | 
					            listChildrenPerLine[indexLine] = []
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const listLine = listChildrenPerLine[listChildrenPerLine.length - 1]
 | 
				
			||||||
 | 
					    if (listLine === '' || (listLine.length === 1 && listLine[0] === '')) {
 | 
				
			||||||
 | 
					        listChildrenPerLine.pop()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return listChildrenPerLine.map((childrenPerLine, index) => (
 | 
				
			||||||
 | 
					        <>
 | 
				
			||||||
 | 
					            {childrenPerLine}
 | 
				
			||||||
 | 
					            {index !== listChildrenPerLine.length - 1 && '\n'}
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					    ))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function parseArgs(raw) {
 | 
					function parseArgs(raw) {
 | 
				
			||||||
| 
						 | 
					@ -123,21 +168,59 @@ function parseArgs(raw) {
 | 
				
			||||||
    return result
 | 
					    return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function convertLine(line, i) {
 | 
					const flattenReact = (children) => {
 | 
				
			||||||
    const cliRegex = /^(\$ )?python -m spacy/
 | 
					    if (children === null || children === undefined || children === false) {
 | 
				
			||||||
    if (cliRegex.test(line)) {
 | 
					        return []
 | 
				
			||||||
        const text = line.replace(cliRegex, '')
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (typeof children === 'string') {
 | 
				
			||||||
 | 
					        return [children]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (children.props) {
 | 
				
			||||||
 | 
					        return flattenReact(children.props.children)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return children.flatMap(flattenReact)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const checkoutForComment = (line) => {
 | 
				
			||||||
 | 
					    const lineParts = line.split(' # ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (lineParts.length !== 2) {
 | 
				
			||||||
 | 
					        return line
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <>
 | 
				
			||||||
 | 
					            {lineParts[0]}
 | 
				
			||||||
 | 
					            {` `}
 | 
				
			||||||
 | 
					            <span class="token comment">
 | 
				
			||||||
 | 
					                {`# `}
 | 
				
			||||||
 | 
					                {lineParts[1]}
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const handlePromot = ({ lineFlat, prompt }) => {
 | 
				
			||||||
 | 
					    const lineWithoutPrompt = lineFlat.slice(prompt.length + 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const cliRegex = /^python -m spacy/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!cliRegex.test(lineWithoutPrompt)) {
 | 
				
			||||||
 | 
					        return <span data-prompt={prompt}>{checkoutForComment(lineWithoutPrompt)}</span>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const text = lineWithoutPrompt.replace(cliRegex, '')
 | 
				
			||||||
    const args = parseArgs(text)
 | 
					    const args = parseArgs(text)
 | 
				
			||||||
    const cmd = Object.keys(args).map((key, i) => {
 | 
					    const cmd = Object.keys(args).map((key, i) => {
 | 
				
			||||||
        const value = args[key]
 | 
					        const value = args[key]
 | 
				
			||||||
        return value === null || value === true || i === 0 ? key : `${key} ${value}`
 | 
					        return value === null || value === true || i === 0 ? key : `${key} ${value}`
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
            <Fragment key={line}>
 | 
					        <span data-prompt={prompt}>
 | 
				
			||||||
                <span data-prompt={i === 0 ? '$' : null} className={classes['cli-arg-subtle']}>
 | 
					            <span className={classes['cli-arg-subtle']}>python -m</span> <span>spacy</span>{' '}
 | 
				
			||||||
                    python -m
 | 
					 | 
				
			||||||
                </span>{' '}
 | 
					 | 
				
			||||||
                <span>spacy</span>{' '}
 | 
					 | 
				
			||||||
            {cmd.map((item, j) => {
 | 
					            {cmd.map((item, j) => {
 | 
				
			||||||
                const isCmd = j === 0
 | 
					                const isCmd = j === 0
 | 
				
			||||||
                const url = isCmd ? `/api/cli#${item.replace(' ', '-')}` : null
 | 
					                const url = isCmd ? `/api/cli#${item.replace(' ', '-')}` : null
 | 
				
			||||||
| 
						 | 
					@ -158,47 +241,67 @@ function convertLine(line, i) {
 | 
				
			||||||
                    </Fragment>
 | 
					                    </Fragment>
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            })}
 | 
					            })}
 | 
				
			||||||
            </Fragment>
 | 
					        </span>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    const htmlLine = replacePrompt(highlightCode('bash', line), '$')
 | 
					 | 
				
			||||||
    return htmlToReact(htmlLine)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function formatCode(html, lang, prompt) {
 | 
					const convertLine = ({ line, prompt, lang }) => {
 | 
				
			||||||
    if (lang === 'cli') {
 | 
					    const lineFlat = flattenReact(line).join('')
 | 
				
			||||||
        const lines = html
 | 
					    if (lineFlat.startsWith(`${prompt} `)) {
 | 
				
			||||||
            .trim()
 | 
					        return handlePromot({ lineFlat, prompt })
 | 
				
			||||||
            .split('\n')
 | 
					    }
 | 
				
			||||||
            .map((line) =>
 | 
					
 | 
				
			||||||
                line
 | 
					    return lang === 'none' || !lineFlat ? (
 | 
				
			||||||
                    .split(' | ')
 | 
					        lineFlat
 | 
				
			||||||
                    .map((l, i) => convertLine(l, i))
 | 
					    ) : (
 | 
				
			||||||
                    .map((l, j) => (
 | 
					        <span
 | 
				
			||||||
                        <Fragment key={j}>
 | 
					            dangerouslySetInnerHTML={{
 | 
				
			||||||
                            {j !== 0 && <span> | </span>}
 | 
					                __html: Prism.highlight(lineFlat, Prism.languages[lang], lang),
 | 
				
			||||||
                            {l}
 | 
					            }}
 | 
				
			||||||
                        </Fragment>
 | 
					        />
 | 
				
			||||||
                    ))
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        return lines.map((line, i) => (
 | 
					 | 
				
			||||||
            <Fragment key={i}>
 | 
					 | 
				
			||||||
                {i !== 0 && <br />}
 | 
					 | 
				
			||||||
                {line}
 | 
					 | 
				
			||||||
            </Fragment>
 | 
					 | 
				
			||||||
        ))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    const result = html
 | 
					
 | 
				
			||||||
        .split('\n')
 | 
					const addLineHighlight = (children, highlight) => {
 | 
				
			||||||
        .map((line, i) => {
 | 
					    if (!highlight) {
 | 
				
			||||||
            let newLine = prompt ? replacePrompt(line, prompt, i === 0) : line
 | 
					        return children
 | 
				
			||||||
            if (lang === 'diff' && !line.startsWith('<')) {
 | 
					 | 
				
			||||||
                newLine = highlightCode('python', line)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
            return newLine
 | 
					    const listHighlight = rangeParser(highlight)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (listHighlight.length === 0) {
 | 
				
			||||||
 | 
					        return children
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return children.map((child, index) => {
 | 
				
			||||||
 | 
					        const isHighlight = listHighlight.includes(index + 1)
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <span
 | 
				
			||||||
 | 
					                className={classNames({
 | 
				
			||||||
 | 
					                    'gatsby-highlight-code-line': isHighlight,
 | 
				
			||||||
 | 
					                })}
 | 
				
			||||||
 | 
					                key={index}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                {child}
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
        .join('\n')
 | 
					}
 | 
				
			||||||
    return htmlToReact(result)
 | 
					
 | 
				
			||||||
 | 
					export const CodeHighlighted = ({ children, highlight, lang }) => {
 | 
				
			||||||
 | 
					    const [html, setHtml] = useState()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    useEffect(
 | 
				
			||||||
 | 
					        () =>
 | 
				
			||||||
 | 
					            setHtml(
 | 
				
			||||||
 | 
					                addLineHighlight(
 | 
				
			||||||
 | 
					                    splitLines(children).map((line) => convertLine({ line, prompt: '$', lang })),
 | 
				
			||||||
 | 
					                    highlight
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        [children, highlight, lang]
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return <>{html}</>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Code extends React.Component {
 | 
					export class Code extends React.Component {
 | 
				
			||||||
| 
						 | 
					@ -207,14 +310,13 @@ export class Code extends React.Component {
 | 
				
			||||||
    static defaultProps = {
 | 
					    static defaultProps = {
 | 
				
			||||||
        lang: 'none',
 | 
					        lang: 'none',
 | 
				
			||||||
        executable: null,
 | 
					        executable: null,
 | 
				
			||||||
        github: false,
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static propTypes = {
 | 
					    static propTypes = {
 | 
				
			||||||
        lang: PropTypes.string,
 | 
					        lang: PropTypes.string,
 | 
				
			||||||
        title: PropTypes.string,
 | 
					        title: PropTypes.string,
 | 
				
			||||||
        executable: PropTypes.oneOf(['true', 'false', true, false, null]),
 | 
					        executable: PropTypes.oneOf(['true', 'false', true, false, null]),
 | 
				
			||||||
        github: PropTypes.oneOf(['true', 'false', true, false, null]),
 | 
					        github: PropTypes.string,
 | 
				
			||||||
        prompt: PropTypes.string,
 | 
					        prompt: PropTypes.string,
 | 
				
			||||||
        highlight: PropTypes.string,
 | 
					        highlight: PropTypes.string,
 | 
				
			||||||
        className: PropTypes.string,
 | 
					        className: PropTypes.string,
 | 
				
			||||||
| 
						 | 
					@ -236,8 +338,7 @@ export class Code extends React.Component {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        const { lang, title, executable, github, prompt, wrap, highlight, className, children } =
 | 
					        const { lang, title, executable, github, wrap, highlight, className, children } = this.props
 | 
				
			||||||
            this.props
 | 
					 | 
				
			||||||
        const codeClassNames = classNames(classes['code'], className, `language-${lang}`, {
 | 
					        const codeClassNames = classNames(classes['code'], className, `language-${lang}`, {
 | 
				
			||||||
            [classes['wrap']]: !!highlight || !!wrap || lang === 'cli',
 | 
					            [classes['wrap']]: !!highlight || !!wrap || lang === 'cli',
 | 
				
			||||||
            [classes['cli']]: lang === 'cli',
 | 
					            [classes['cli']]: lang === 'cli',
 | 
				
			||||||
| 
						 | 
					@ -246,7 +347,7 @@ export class Code extends React.Component {
 | 
				
			||||||
        const { Juniper } = this.state
 | 
					        const { Juniper } = this.state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (github) {
 | 
					        if (github) {
 | 
				
			||||||
            return <GitHubCode url={children} className={ghClassNames} lang={lang} />
 | 
					            return <GitHubCode url={github} className={ghClassNames} lang={lang} />
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!!executable && Juniper) {
 | 
					        if (!!executable && Juniper) {
 | 
				
			||||||
            return (
 | 
					            return (
 | 
				
			||||||
| 
						 | 
					@ -256,16 +357,14 @@ export class Code extends React.Component {
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const codeText = Array.isArray(children) ? children.join('') : children || ''
 | 
					 | 
				
			||||||
        const highlightRange = highlight ? rangeParser.parse(highlight).filter((n) => n > 0) : []
 | 
					 | 
				
			||||||
        const rawHtml = ['none', 'cli'].includes(lang)
 | 
					 | 
				
			||||||
            ? codeText
 | 
					 | 
				
			||||||
            : highlightCode(lang, codeText, highlightRange)
 | 
					 | 
				
			||||||
        const html = formatCode(rawHtml, lang, prompt)
 | 
					 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <>
 | 
					            <>
 | 
				
			||||||
                {title && <h4 className={classes['title']}>{title}</h4>}
 | 
					                {title && <h4 className={classes['title']}>{title}</h4>}
 | 
				
			||||||
                <code className={codeClassNames}>{html}</code>
 | 
					                <code className={codeClassNames}>
 | 
				
			||||||
 | 
					                    <CodeHighlighted highlight={highlight} lang={lang}>
 | 
				
			||||||
 | 
					                        {children}
 | 
				
			||||||
 | 
					                    </CodeHighlighted>
 | 
				
			||||||
 | 
					                </code>
 | 
				
			||||||
            </>
 | 
					            </>
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
import React, { useState, useEffect } from 'react'
 | 
					import React, { useState, useEffect } from 'react'
 | 
				
			||||||
import PropTypes from 'prop-types'
 | 
					import PropTypes from 'prop-types'
 | 
				
			||||||
import classNames from 'classnames'
 | 
					import classNames from 'classnames'
 | 
				
			||||||
import highlightCode from 'gatsby-remark-prismjs/highlight-code.js'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Icon from './icon'
 | 
					import Icon from './icon'
 | 
				
			||||||
import Link from './link'
 | 
					import Link from './link'
 | 
				
			||||||
import classes from '../styles/code.module.sass'
 | 
					import classes from '../styles/code.module.sass'
 | 
				
			||||||
 | 
					import { Code } from './code'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const defaultErrorMsg = `Can't fetch code example from GitHub :(
 | 
					const defaultErrorMsg = `Can't fetch code example from GitHub :(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,8 +39,6 @@ const GitHubCode = ({ url, lang, errorMsg = defaultErrorMsg, className }) => {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }, [initialized, rawUrl, errorMsg])
 | 
					    }, [initialized, rawUrl, errorMsg])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const highlighted = lang === 'none' || !code ? code : highlightCode(lang, code)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <>
 | 
					        <>
 | 
				
			||||||
            <header className={classes.header}>
 | 
					            <header className={classes.header}>
 | 
				
			||||||
| 
						 | 
					@ -53,7 +51,11 @@ const GitHubCode = ({ url, lang, errorMsg = defaultErrorMsg, className }) => {
 | 
				
			||||||
                    </code>
 | 
					                    </code>
 | 
				
			||||||
                </Link>
 | 
					                </Link>
 | 
				
			||||||
            </header>
 | 
					            </header>
 | 
				
			||||||
            <code className={codeClassNames} dangerouslySetInnerHTML={{ __html: highlighted }} />
 | 
					            {code && (
 | 
				
			||||||
 | 
					                <Code className={codeClassNames} lang={lang}>
 | 
				
			||||||
 | 
					                    {code}
 | 
				
			||||||
 | 
					                </Code>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
        </>
 | 
					        </>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -298,8 +298,8 @@ const Model = ({
 | 
				
			||||||
                {name}
 | 
					                {name}
 | 
				
			||||||
            </H2>
 | 
					            </H2>
 | 
				
			||||||
            <Aside title="Installation">
 | 
					            <Aside title="Installation">
 | 
				
			||||||
                <CodeBlock lang="cli" prompt="$">
 | 
					                <CodeBlock lang="bash" prompt="$">
 | 
				
			||||||
                    python -m spacy download {name}
 | 
					                    $ python -m spacy download {name}
 | 
				
			||||||
                </CodeBlock>
 | 
					                </CodeBlock>
 | 
				
			||||||
            </Aside>
 | 
					            </Aside>
 | 
				
			||||||
            {meta.description && <MarkdownToReact markdown={meta.description} />}
 | 
					            {meta.description && <MarkdownToReact markdown={meta.description} />}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user