Skip to content

Commit

Permalink
Remove detection by default
Browse files Browse the repository at this point in the history
Previously, even without a class on `code`, its programming language
was inferred, and it was highlighted anyway.
It was possible to turn this by passing `subset: false`, an overload
of an option that also has another job.

This commit reverts this behavior, and removes the overload in favor of
a new option: pass `detect: true` to automatically detect the
programming language of code blocks.
The default, `detect: false`, does not do that.

If you had `subset: false`, you can remove that line.
If you want the previous behavior, pass `detect: true`.

Closes GH-21.
  • Loading branch information
wooorm committed Oct 12, 2022
1 parent 9c42989 commit 2c5a4ec
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 34 deletions.
14 changes: 8 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
* Configuration (optional).
* @property {string} [prefix='hljs-']
* Prefix to use before classes.
* @property {boolean|Array<string>} [subset]
* @property {boolean} [detect=false]
* Whether to detect the programming language on code without a language
* class.
* @property {Array<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.
Expand Down Expand Up @@ -41,7 +43,8 @@ const own = {}.hasOwnProperty
* @type {import('unified').Plugin<[Options?] | Array<void>, Root>}
*/
export default function rehypeHighlight(options = {}) {
const {aliases, languages, prefix, plainText, ignoreMissing, subset} = options
const {aliases, languages, prefix, plainText, ignoreMissing, subset, detect} =
options
let name = 'hljs'

if (aliases) {
Expand Down Expand Up @@ -83,7 +86,7 @@ export default function rehypeHighlight(options = {}) {

if (
lang === false ||
(!lang && subset === false) ||
(!lang && !detect) ||
(lang && plainText && plainText.includes(lang))
) {
return
Expand All @@ -103,8 +106,7 @@ export default function rehypeHighlight(options = {}) {
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})
: lowlight.highlightAuto(toText(parent), {prefix, subset})
} catch (error) {
const exception = /** @type {Error} */ (error)
if (!ignoreMissing || !/Unknown language/.test(exception.message)) {
Expand Down
33 changes: 17 additions & 16 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ them.
You can specify the code language (such as Python) with a `language-*` or
`lang-*` class, where the `*` can be for example `js` (so `language-js`), `md`,
`css`, etc.
By default, even without a class, all `<pre><code>` is highlighted by
automatically detecting which code language it seems to be.
You can prevent that with a `no-highlight` or `nohighlight` class on the
`<code>` or by passing `options.subset: false`.
By default, code without such a language class is not highlighted.
Pass `detect: true` to detect their programming language and highlight the code
anyway.
You can still prevent specific blocks from being highlighted with a
`no-highlight` or `nohighlight` class on the `<code>`.

**unified** is a project that transforms content with abstract syntax trees
(ASTs).
Expand Down Expand Up @@ -113,16 +114,12 @@ import {read} from 'to-vfile'
import {rehype} from 'rehype'
import rehypeHighlight from 'rehype-highlight'

main()

async function main() {
const file = await rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight)
.process(await read('example.html'))
const file = await rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight)
.process(await read('example.html'))

console.log(String(file))
}
console.log(String(file))
```

Now running `node example.js` yields:
Expand Down Expand Up @@ -151,11 +148,15 @@ Configuration (optional).

Prefix to use before classes (`string`, default: `'hljs-'`).

###### `options.detect`

Whether to detect the programming language on code without a language class
(`boolean`, default: `false`).

###### `options.subset`

Scope of languages to check when automatically detecting (`boolean` or
`Array<string>`, default: all languages).
Pass `false` to not highlight code without language classes.
Languages to check when automatically detecting (`Array<string>`, default: all
languages).

###### `options.plainText`

Expand Down
42 changes: 30 additions & 12 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test('rehypeHighlight', (t) => {
t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight)
.use(rehypeHighlight, {detect: true})
.processSync(
['<h1>Hello World!</h1>', '', '<pre><code></code></pre>'].join('\n')
)
Expand All @@ -33,18 +33,36 @@ test('rehypeHighlight', (t) => {
].join('\n')
)
.toString(),
['<h1>Hello World!</h1>', '', '<pre><code>"use strict";</code></pre>'].join(
'\n'
),
'should not highlight (no class)'
)

t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight, {detect: true})
.processSync(
[
'<h1>Hello World!</h1>',
'',
'<pre><code>"use strict";</code></pre>'
].join('\n')
)
.toString(),
[
'<h1>Hello World!</h1>',
'',
'<pre><code class="hljs language-javascript"><span class="hljs-meta">"use strict"</span>;</code></pre>'
].join('\n'),
'should highlight (no class)'
'should highlight (`detect`, no class)'
)

t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight, {subset: ['arduino']})
.use(rehypeHighlight, {detect: true, subset: ['arduino']})
.processSync(
[
'<h1>Hello World!</h1>',
Expand All @@ -58,13 +76,13 @@ test('rehypeHighlight', (t) => {
'',
'<pre><code class="hljs language-arduino"><span class="hljs-string">"use strict"</span>;</code></pre>'
].join('\n'),
'should highlight (no class, subset)'
'should highlight (detect, no class, subset)'
)

t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight, {subset: false})
.use(rehypeHighlight, {detect: false})
.processSync(
[
'<h1>Hello World!</h1>',
Expand All @@ -76,13 +94,13 @@ test('rehypeHighlight', (t) => {
['<h1>Hello World!</h1>', '', '<pre><code>"use strict";</code></pre>'].join(
'\n'
),
'should not highlight (no class, subset: false)'
'should not highlight (`detect: false`, no class)'
)

t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight, {prefix: 'foo'})
.use(rehypeHighlight, {prefix: 'foo', detect: true})
.processSync(
[
'<h1>Hello World!</h1>',
Expand All @@ -102,7 +120,7 @@ test('rehypeHighlight', (t) => {
t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight, {prefix: 'foo-'})
.use(rehypeHighlight, {prefix: 'foo-', detect: true})
.processSync(
[
'<h1>Hello World!</h1>',
Expand Down Expand Up @@ -296,7 +314,7 @@ test('rehypeHighlight', (t) => {
t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight, {subset: ['cpp']})
.use(rehypeHighlight, {subset: ['cpp'], detect: true})
.processSync(`<pre><code>def add(a, b):\n return a + b</code></pre>`)
.toString(),
'<pre><code class="hljs">def add(a, b):\n return a + b</code></pre>',
Expand Down Expand Up @@ -364,7 +382,7 @@ test('rehypeHighlight', (t) => {
t.equal(
rehype()
.data('settings', {fragment: true})
.use(rehypeHighlight)
.use(rehypeHighlight, {detect: true})
.processSync(
[
'<h1>Hello World!</h1>',
Expand All @@ -389,7 +407,7 @@ test('rehypeHighlight', (t) => {
[
'<h1>Hello World!</h1>',
'',
'<pre><code>"use strict";<br>console.log("very strict")</code></pre>'
'<pre><code class="language-javascript">"use strict";<br>console.log("very strict")</code></pre>'
].join('\n')
)
.toString(),
Expand Down Expand Up @@ -421,7 +439,7 @@ test('rehypeHighlight', (t) => {
[
'<h1>Hello World!</h1>',
'',
'<pre><code>test normal text</code></pre>'
'<pre><code class="language-scss">test normal text</code></pre>'
].join('\n')
)
.toString(),
Expand Down

0 comments on commit 2c5a4ec

Please sign in to comment.