mirror of https://github.com/explosion/spaCy.git
72 lines
2.7 KiB
JavaScript
72 lines
2.7 KiB
JavaScript
|
/**
|
||
|
* Support titles, line highlights and more for code blocks
|
||
|
*/
|
||
|
|
||
|
const visit = require('unist-util-visit')
|
||
|
const parseAttr = require('md-attr-parser')
|
||
|
|
||
|
const defaultOptions = {
|
||
|
defaultPrefix: '###',
|
||
|
prefixMap: {
|
||
|
javascript: '///',
|
||
|
jsx: '///',
|
||
|
},
|
||
|
languageAliases: {},
|
||
|
prompts: ['$'],
|
||
|
}
|
||
|
|
||
|
function remarkCodeBlocks(userOptions = {}) {
|
||
|
const options = Object.assign({}, defaultOptions, userOptions)
|
||
|
|
||
|
function transformer(tree) {
|
||
|
visit(tree, 'code', node => {
|
||
|
if (node.value) {
|
||
|
const langName = node.lang || 'none'
|
||
|
const lang = options.languageAliases[langName] || langName
|
||
|
const prefix = options.prefixMap[lang] || options.defaultPrefix
|
||
|
const lines = node.value.split('\n')
|
||
|
let attrs = { lang }
|
||
|
const firstLine = lines[0].trim()
|
||
|
if (firstLine && firstLine.startsWith(prefix)) {
|
||
|
const title = firstLine.slice(prefix.length).trim()
|
||
|
attrs.title = title
|
||
|
// Check for attributes in title, e.g. {executable="true"}
|
||
|
const parsed = title.split(/\{(.*?)\}/)
|
||
|
if (parsed.length >= 2 && parsed[1]) {
|
||
|
const { prop } = parseAttr(parsed[1])
|
||
|
attrs = { ...attrs, ...prop, title: parsed[0].trim(), lang }
|
||
|
}
|
||
|
// Overwrite the code text with the rest of the lines
|
||
|
node.value = lines.slice(1).join('\n')
|
||
|
} else if (firstLine && /^https:\/\/github.com/.test(firstLine)) {
|
||
|
// GitHub URL
|
||
|
attrs.github = 'true'
|
||
|
}
|
||
|
// If it's a bash code block and single line, check for prompts
|
||
|
if (lang === 'bash') {
|
||
|
const [trueFirstLine, ...trueLines] = node.value.split('\n')
|
||
|
for (let prompt of options.prompts) {
|
||
|
if (trueFirstLine.startsWith(prompt)) {
|
||
|
const content = [
|
||
|
trueFirstLine.slice(prompt.length).trim(),
|
||
|
...trueLines,
|
||
|
]
|
||
|
attrs.prompt = prompt
|
||
|
node.value = content.join('\n')
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const data = node.data || (node.data = {})
|
||
|
const hProps = data.hProperties || (data.hProperties = {})
|
||
|
node.data.hProperties = Object.assign({}, hProps, attrs)
|
||
|
}
|
||
|
})
|
||
|
return tree
|
||
|
}
|
||
|
return transformer
|
||
|
}
|
||
|
|
||
|
module.exports = remarkCodeBlocks
|