rehype-highlight
Advanced tools
Comparing version 4.1.0 to 5.0.0
159
index.js
@@ -1,5 +0,156 @@ | ||
'use strict' | ||
var lowlight = require('lowlight') | ||
var createPlugin = require('./core') | ||
/** | ||
* @typedef {import('lowlight/lib/core.js').LowlightRoot} LowlightRoot | ||
* @typedef {import('lowlight/lib/core.js').HighlightSyntax} HighlightSyntax | ||
* @typedef {import('hast').Root} Root | ||
* @typedef {import('hast').Element} Element | ||
* @typedef {Root|Root['children'][number]} Node | ||
* | ||
* @typedef Options | ||
* Configuration. | ||
* @property {string} [prefix='hljs-'] | ||
* Prefix to use before classes. | ||
* @property {boolean|string[]} [subset] | ||
* Scope of languages to check when auto-detecting (default: all languages). | ||
* Pass `false` to not highlight code without language classes. | ||
* @property {boolean} [ignoreMissing=false] | ||
* Swallow errors for missing languages. | ||
* By default, unregistered syntaxes throw an error when they are used. | ||
* Pass `true` to swallow those errors and thus ignore code with unknown code | ||
* languages. | ||
* @property {string[]} [plainText=[]] | ||
* List of plain-text languages. | ||
* Pass any languages you would like to be kept as plain-text instead of | ||
* getting highlighted. | ||
* @property {Record<string, string|string[]>} [aliases={}] | ||
* Register more aliases. | ||
* Passed to `lowlight.registerAlias`. | ||
* @property {Record<string, HighlightSyntax>} [languages={}] | ||
* Register more languages. | ||
* Each key/value pair passed as arguments to `lowlight.registerLanguage`. | ||
*/ | ||
module.exports = createPlugin(lowlight) | ||
import {lowlight} from 'lowlight' | ||
import {toText} from 'hast-util-to-text' | ||
import {visit} from 'unist-util-visit' | ||
const own = {}.hasOwnProperty | ||
/** | ||
* Plugin to highlight the syntax of code with lowlight (`highlight.js`). | ||
* | ||
* @type {import('unified').Plugin<[Options?] | void[], Root>} | ||
*/ | ||
export default function rehypeHighlight(options = {}) { | ||
const {aliases, languages, prefix, plainText, ignoreMissing, subset} = options | ||
let name = 'hljs' | ||
if (aliases) { | ||
lowlight.registerAlias(aliases) | ||
} | ||
if (languages) { | ||
/** @type {string} */ | ||
let key | ||
for (key in languages) { | ||
if (own.call(languages, key)) { | ||
lowlight.registerLanguage(key, languages[key]) | ||
} | ||
} | ||
} | ||
if (prefix) { | ||
const pos = prefix.indexOf('-') | ||
name = pos > -1 ? prefix.slice(0, pos) : prefix | ||
} | ||
return (tree) => { | ||
// eslint-disable-next-line complexity | ||
visit(tree, 'element', (node, _, givenParent) => { | ||
const parent = /** @type {Node?} */ (givenParent) | ||
if ( | ||
!parent || | ||
!('tagName' in parent) || | ||
parent.tagName !== 'pre' || | ||
node.tagName !== 'code' || | ||
!node.properties | ||
) { | ||
return | ||
} | ||
const lang = language(node) | ||
if ( | ||
lang === false || | ||
(!lang && subset === false) || | ||
(lang && plainText && plainText.includes(lang)) | ||
) { | ||
return | ||
} | ||
if (!Array.isArray(node.properties.className)) { | ||
node.properties.className = [] | ||
} | ||
if (!node.properties.className.includes(name)) { | ||
node.properties.className.unshift(name) | ||
} | ||
/** @type {LowlightRoot} */ | ||
let result | ||
try { | ||
result = lang | ||
? lowlight.highlight(lang, toText(parent), {prefix}) | ||
: // @ts-expect-error: we checked that `subset` is not a boolean. | ||
lowlight.highlightAuto(toText(parent), {prefix, subset}) | ||
} catch (error) { | ||
if (!ignoreMissing || !/Unknown language/.test(error.message)) { | ||
throw error | ||
} | ||
return | ||
} | ||
if (!lang && result.data.language) { | ||
node.properties.className.push('language-' + result.data.language) | ||
} | ||
if (Array.isArray(result.children) && result.children.length > 0) { | ||
node.children = result.children | ||
} | ||
}) | ||
} | ||
} | ||
/** | ||
* Get the programming language of `node`. | ||
* | ||
* @param {Element} node | ||
* @returns {false|string|undefined} | ||
*/ | ||
function language(node) { | ||
const className = node.properties && node.properties.className | ||
let index = -1 | ||
if (!Array.isArray(className)) { | ||
return | ||
} | ||
while (++index < className.length) { | ||
const value = String(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) | ||
} | ||
} | ||
} |
{ | ||
"name": "rehype-highlight", | ||
"version": "4.1.0", | ||
"version": "5.0.0", | ||
"description": "rehype plugin to highlight code blocks with lowlight (highlight.js)", | ||
@@ -27,38 +27,37 @@ "license": "MIT", | ||
], | ||
"sideEffects": false, | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"files": [ | ||
"core.js", | ||
"index.js", | ||
"light.js" | ||
"index.d.ts", | ||
"index.js" | ||
], | ||
"dependencies": { | ||
"hast-util-to-text": "^2.0.0", | ||
"lowlight": "^1.10.0", | ||
"unist-util-visit": "^2.0.0" | ||
"@types/hast": "^2.0.0", | ||
"hast-util-to-text": "^3.0.0", | ||
"lowlight": "^2.0.0", | ||
"unified": "^10.0.0", | ||
"unist-util-visit": "^4.0.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^17.0.0", | ||
"nyc": "^15.0.0", | ||
"@types/tape": "^4.0.0", | ||
"c8": "^7.0.0", | ||
"prettier": "^2.0.0", | ||
"rehype": "11.0.0", | ||
"rehype": "12.0.0", | ||
"remark-cli": "^9.0.0", | ||
"remark-preset-wooorm": "^8.0.0", | ||
"rimraf": "^3.0.0", | ||
"tape": "^5.0.0", | ||
"tinyify": "^3.0.0", | ||
"xo": "^0.37.0" | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"xo": "^0.42.0" | ||
}, | ||
"scripts": { | ||
"build": "rimraf \"*.d.ts\" && tsc && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"build-bundle": "browserify . -s rehypeHighlight -o rehype-highlight.js", | ||
"build-mangle": "browserify . -s rehypeHighlight -o rehype-highlight.min.js -p tinyify", | ||
"build": "npm run build-bundle && npm run build-mangle", | ||
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test.js", | ||
"test": "npm run format && npm run build && npm run test-coverage" | ||
"test-api": "node --conditions development test.js", | ||
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
"nyc": { | ||
"check-coverage": true, | ||
"lines": 100, | ||
"functions": 100, | ||
"branches": 100 | ||
}, | ||
"prettier": { | ||
@@ -73,10 +72,3 @@ "tabWidth": 2, | ||
"xo": { | ||
"prettier": true, | ||
"esnext": false, | ||
"ignores": [ | ||
"rehype-highlight.js" | ||
], | ||
"rules": { | ||
"unicorn/prefer-includes": "off" | ||
} | ||
"prettier": true | ||
}, | ||
@@ -87,3 +79,9 @@ "remarkConfig": { | ||
] | ||
}, | ||
"typeCoverage": { | ||
"atLeast": 100, | ||
"detail": true, | ||
"strict": true, | ||
"ignoreCatch": true | ||
} | ||
} |
@@ -14,4 +14,12 @@ # rehype-highlight | ||
`rehype-highlight` is built to work with all syntaxes supported by | ||
[`highlight.js`][highlight-js]. | ||
It starts off with 35 [common languages][common] registered. | ||
You can add up to 191 languages. | ||
## Install | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
[npm][]: | ||
@@ -37,12 +45,15 @@ | ||
```js | ||
var vfile = require('to-vfile') | ||
var report = require('vfile-reporter') | ||
var rehype = require('rehype') | ||
var highlight = require('rehype-highlight') | ||
import {readSync} from 'to-vfile' | ||
import {reporter} from 'vfile-reporter' | ||
import {rehype} from 'rehype' | ||
import rehypeHighlight from 'rehype-highlight' | ||
const file = readSync('example.html') | ||
rehype() | ||
.data('settings', {fragment: true}) | ||
.use(highlight) | ||
.process(vfile.readSync('example.html'), function(err, file) { | ||
console.error(report(err || file)) | ||
.use(rehypeHighlight) | ||
.process(file) | ||
.then((file) => { | ||
console.error(reporter(file)) | ||
console.log(String(file)) | ||
@@ -64,4 +75,7 @@ }) | ||
### `rehype().use(highlight[, options])` | ||
This package exports no identifiers. | ||
The default export is `rehypeHighlight`. | ||
### `unified().use(rehypeHighlight[, options])` | ||
Syntax highlight `pre > code`. | ||
@@ -75,2 +89,7 @@ Uses [**lowlight**][lowlight] under the hood, which is a virtual version of | ||
`rehype-highlight` is built to work with all syntaxes supported by | ||
`highlight.js`. | ||
It starts off with 35 [common languages][common] registered. | ||
You can add up to 191 languages. | ||
##### `options` | ||
@@ -108,37 +127,11 @@ | ||
Register more languages (`Object<string | function>`, default: `{}`). | ||
Register more languages (`Record<string, Function>`, default: `{}`). | ||
Each key/value pair passed as arguments to | ||
[`lowlight.registerLanguage`][register-language]. | ||
## Browser | ||
`rehype-highlight` is built to work with all syntaxes supported by | ||
`highlight.js`. | ||
It starts off with 35 [common languages][common] registered. | ||
You can add up to 191 languages. | ||
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 | ||
@@ -217,1 +210,3 @@ | ||
[sanitize]: https://github.com/rehypejs/rehype-sanitize | ||
[common]: https://github.com/wooorm/lowlight#syntaxes |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15093
184
Yes
5
11
5
207
1
+ Added@types/hast@^2.0.0
+ Addedunified@^10.0.0
+ Added@types/hast@2.3.10(transitive)
+ Addedbail@2.0.2(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedfault@2.0.1(transitive)
+ Addedhast-util-is-element@2.1.3(transitive)
+ Addedhast-util-to-text@3.1.2(transitive)
+ Addedhighlight.js@11.8.0(transitive)
+ Addedis-buffer@2.0.5(transitive)
+ Addedis-plain-obj@4.1.0(transitive)
+ Addedlowlight@2.9.0(transitive)
+ Addedtrough@2.2.0(transitive)
+ Addedunified@10.1.2(transitive)
+ Addedunist-util-find-after@4.0.1(transitive)
+ Addedunist-util-is@5.2.1(transitive)
+ Addedunist-util-stringify-position@3.0.3(transitive)
+ Addedunist-util-visit@4.1.2(transitive)
+ Addedunist-util-visit-parents@5.1.3(transitive)
+ Addedvfile@5.3.7(transitive)
+ Addedvfile-message@3.1.4(transitive)
- Removedfault@1.0.4(transitive)
- Removedhast-util-is-element@1.1.0(transitive)
- Removedhast-util-to-text@2.0.1(transitive)
- Removedhighlight.js@10.7.3(transitive)
- Removedlowlight@1.20.0(transitive)
- Removedrepeat-string@1.6.1(transitive)
- Removedunist-util-find-after@3.0.0(transitive)
- Removedunist-util-is@4.1.0(transitive)
- Removedunist-util-visit@2.0.3(transitive)
- Removedunist-util-visit-parents@3.1.1(transitive)
Updatedhast-util-to-text@^3.0.0
Updatedlowlight@^2.0.0
Updatedunist-util-visit@^4.0.0