Skip to content

Commit

Permalink
Add light plugin
Browse files Browse the repository at this point in the history
Closes GH-14.

Reviewed-by: Titus Wormer <[email protected]>
  • Loading branch information
arturcarvalho authored Feb 19, 2021
1 parent c244fde commit bf464d7
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 106 deletions.
112 changes: 112 additions & 0 deletions core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
'use strict'

var toText = require('hast-util-to-text')
var visit = require('unist-util-visit')

module.exports = createPlugin

function createPlugin(lowlight) {
return function (options) {
var settings = options || {}
var name = 'hljs'
var pos

if (settings.aliases) {
lowlight.registerAlias(settings.aliases)
}

if (settings.languages) {
// eslint-disable-next-line guard-for-in
for (let name in settings.languages) {
lowlight.registerLanguage(name, settings.languages[name])
}
}

if (settings.prefix) {
pos = settings.prefix.indexOf('-')
name = pos > -1 ? settings.prefix.slice(0, pos) : settings.prefix
}

return transformer

function transformer(tree) {
visit(tree, 'element', visitor)
}

function visitor(node, index, parent) {
var props
var result
var lang

if (!parent || parent.tagName !== 'pre' || node.tagName !== 'code') {
return
}

lang = language(node)

if (
lang === false ||
(!lang && settings.subset === false) ||
(settings.plainText && settings.plainText.indexOf(lang) > -1)
) {
return
}

props = node.properties

if (!props.className) {
props.className = []
}

if (props.className.indexOf(name) < 0) {
props.className.unshift(name)
}

try {
result = lang
? lowlight.highlight(lang, toText(parent), options)
: lowlight.highlightAuto(toText(parent), options)
} catch (error) {
if (
!settings.ignoreMissing ||
!/Unknown language/.test(error.message)
) {
throw error
}

result = {}
}

if (!lang && result.language) {
props.className.push('language-' + result.language)
}

if (result.value) {
node.children = result.value
}
}
}
}

// Get the programming language of `node`.
function language(node) {
var className = node.properties.className || []
var index = -1
var value

while (++index < className.length) {
value = className[index]

if (value === 'no-highlight' || value === 'nohighlight') {
return false
}

if (value.slice(0, 5) === 'lang-') {
return value.slice(5)
}

if (value.slice(0, 9) === 'language-') {
return value.slice(9)
}
}
}
107 changes: 2 additions & 105 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,108 +1,5 @@
'use strict'

var toText = require('hast-util-to-text')
var lowlight = require('lowlight')
var visit = require('unist-util-visit')

module.exports = attacher

function attacher(options) {
var settings = options || {}
var name = 'hljs'
var pos

if (settings.aliases) {
lowlight.registerAlias(settings.aliases)
}

if (settings.languages) {
// eslint-disable-next-line guard-for-in
for (let name in settings.languages) {
lowlight.registerLanguage(name, settings.languages[name])
}
}

if (settings.prefix) {
pos = settings.prefix.indexOf('-')
name = pos > -1 ? settings.prefix.slice(0, pos) : settings.prefix
}

return transformer

function transformer(tree) {
visit(tree, 'element', visitor)
}

function visitor(node, index, parent) {
var props
var result
var lang

if (!parent || parent.tagName !== 'pre' || node.tagName !== 'code') {
return
}

lang = language(node)

if (
lang === false ||
(!lang && settings.subset === false) ||
(settings.plainText && settings.plainText.indexOf(lang) > -1)
) {
return
}

props = node.properties

if (!props.className) {
props.className = []
}

if (props.className.indexOf(name) < 0) {
props.className.unshift(name)
}

try {
result = lang
? lowlight.highlight(lang, toText(parent), options)
: lowlight.highlightAuto(toText(parent), options)
} catch (error) {
if (!settings.ignoreMissing || !/Unknown language/.test(error.message)) {
throw error
}

result = {}
}

if (!lang && result.language) {
props.className.push('language-' + result.language)
}

if (result.value) {
node.children = result.value
}
}
}

// Get the programming language of `node`.
function language(node) {
var className = node.properties.className || []
var index = -1
var value

while (++index < className.length) {
value = className[index]

if (value === 'no-highlight' || value === 'nohighlight') {
return false
}

if (value.slice(0, 5) === 'lang-') {
return value.slice(5)
}
var createPlugin = require('./core')

if (value.slice(0, 9) === 'language-') {
return value.slice(9)
}
}
}
module.exports = createPlugin(lowlight)
5 changes: 5 additions & 0 deletions light.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict'
var lowlight = require('lowlight/lib/core')
var createPlugin = require('./core')

module.exports = createPlugin(lowlight)
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
"Titus Wormer <[email protected]> (https://wooorm.com)"
],
"files": [
"index.js"
"core.js",
"index.js",
"light.js"
],
"dependencies": {
"hast-util-to-text": "^2.0.0",
Expand Down
31 changes: 31 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,37 @@ Register more languages (`Object<string | function>`, default: `{}`).
Each key/value pair passed as arguments to
[`lowlight.registerLanguage`][register-language].

## Browser

It is not suggested to require `rehype-highlight` in the browser as it will
include all the highlighters.

> :warning: Please configure `languages`, as otherwise nothing gets highlighted.
In the example below, only the JavaScript and TypeScript
highlighters are included:

```js
var vfile = require('to-vfile')
var report = require('vfile-reporter')
var rehype = require('rehype')
var highlight = require('rehype-highlight/light')

rehype()
.data('settings', {fragment: true})
.use(highlight, {
// Don’t forget to define the languages you need
languages: {
javascript: require('highlight.js/lib/languages/javascript'),
typescript: require('highlight.js/lib/languages/typescript')
}
})
.process(vfile.readSync('example.html'), function (error, file) {
console.error(report(error || file))
console.log(String(file))
})
```

## Security

Use of `rehype-highlight` *should* be safe to use as `lowlight` *should* be safe
Expand Down
Loading

0 comments on commit bf464d7

Please sign in to comment.