mirror of
https://github.com/primer/css.git
synced 2025-01-05 21:22:57 +03:00
use ERB converts for octicon() and avatar_for()
This commit is contained in:
parent
7aa05a9d04
commit
b82a3fc69f
84
lib/erb-to-html.js
Normal file
84
lib/erb-to-html.js
Normal file
@ -0,0 +1,84 @@
|
||||
const visit = require('unist-util-visit')
|
||||
const cache = new Map()
|
||||
|
||||
module.exports = options => {
|
||||
const convert = converter(options)
|
||||
return tree => {
|
||||
visit(tree, 'code', (node, parent, index) => {
|
||||
const match = node.lang ? node.lang.match(/^[a-z]+/) : null
|
||||
const lang = match ? match[0] : null
|
||||
if (lang === 'erb' || lang === 'html') {
|
||||
const erb = node.value
|
||||
const html = convert(node.value)
|
||||
|
||||
if (html && !html.includes('<%')) {
|
||||
node.value = html
|
||||
node.lang = node.lang.replace(/^erb/, 'html')
|
||||
}
|
||||
} else {
|
||||
// console.warn(`Unknown code block lang: ${node.lang}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function converter({converters = {}}) {
|
||||
return erb => {
|
||||
const blocks = erb.match(/<%=[^%]+%>/g)
|
||||
if (blocks && blocks.length) {
|
||||
let html = erb
|
||||
console.warn(`Replacing ${blocks.length} ERB block(s)...`)
|
||||
for (const input of blocks) {
|
||||
const output = convert(input)
|
||||
if (output !== input) {
|
||||
html = replaceAll(html, input, output)
|
||||
}
|
||||
}
|
||||
return html
|
||||
}
|
||||
}
|
||||
|
||||
function convert(block) {
|
||||
if (cache.has(block)) {
|
||||
return cache.get(block)
|
||||
}
|
||||
|
||||
const [_, method, argString] = block.match(/<%= *(\w+)[ \(]([^\)]+)\)? *%>/)
|
||||
const parts = argString.split(/, */)
|
||||
const args = []
|
||||
const kwargs = {}
|
||||
for (const part of parts) {
|
||||
let match
|
||||
if (match = part.match(/^:(.+) => (.+)$/)) {
|
||||
kwargs[unquote(match[1])] = unquote(match[2])
|
||||
} else if (match = part.match(/^(.+): (.+)$/)) {
|
||||
kwargs[unquote(match[1])] = unquote(match[2])
|
||||
} else {
|
||||
args.push(unquote(part))
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof converters[method] === 'function') {
|
||||
let output = converters[method](args, kwargs)
|
||||
output = `<!-- ${block} -->\n${output}`
|
||||
cache.set(block, output)
|
||||
return output
|
||||
} else {
|
||||
console.warn(`Unable to convert: ${block}`)
|
||||
return block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replaceAll(str, input, output) {
|
||||
let result = str
|
||||
while (result.includes(input)) {
|
||||
result = result.replace(input, output)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
function unquote(str) {
|
||||
return str.replace(/^\s*"([^"]+)"\s*$/, (_, value) => value)
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
const {getOptions} = require('loader-utils')
|
||||
const mdx = require('@mdx-js/mdx')
|
||||
const octicons = require('@primer/octicons')
|
||||
|
||||
const emoji = require('remark-emoji')
|
||||
const images = require('remark-images')
|
||||
const rehypePrism = require('./rehype-prism')
|
||||
const textr = require('remark-textr')
|
||||
const toc = require('remark-toc')
|
||||
const erbToHTML = require('./erb-to-html')
|
||||
|
||||
const mdxExportJSONByDefault = require('mdx-constant')
|
||||
const grayMatter = require('gray-matter')
|
||||
@ -22,7 +24,22 @@ module.exports = async function(source) {
|
||||
[toc, {heading: '(table of|section)? contents'}],
|
||||
images,
|
||||
emoji,
|
||||
[textr, {plugins: [typographicBase]}]
|
||||
[textr, {plugins: [typographicBase]}],
|
||||
[erbToHTML, {
|
||||
converters: {
|
||||
octicon: ([icon], attrs) => {
|
||||
if (octicons[icon]) {
|
||||
return octicons[icon].toSVG(attrs)
|
||||
} else {
|
||||
throw new Error(`No such octicon: "${icon}"`)
|
||||
}
|
||||
},
|
||||
avatar_for: ([username, size], kwargs) => {
|
||||
const attrs = Object.entries(kwargs).map(([key, value]) => ` ${key}="${value}"`).join(' ')
|
||||
return `<img src="https://github.com/github.png?s=${size * 2}" width="${size}" height="${size}"${attrs}>`
|
||||
}
|
||||
}
|
||||
}]
|
||||
],
|
||||
hastPlugins: [rehypePrism],
|
||||
compilers: [mdxExportJSONByDefault('frontMatter', data)]
|
||||
|
Loading…
Reference in New Issue
Block a user