Skip to content

Commit

Permalink
Prism plugin bugfix alt (#1491)
Browse files Browse the repository at this point in the history
* Replace class=language-* with data-language=* to avoid potential Prism bug

* Remark Prism plugin now accepts useDataAttribute option
Default behavior remains as before, to use a class='language-*' prefix. New behavior allows for a data-language=* alternate.
Snapshot tests added.

* Alternate, custom-class-prefix approach to fixing Prism+ReactLive bug

* Added README note about new plugin option

* Provided more context for the remark prism docs comment
  • Loading branch information
bvaughn authored and KyleAMathews committed Jul 13, 2017
1 parent f79aa5c commit d1b72df
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 6 deletions.
14 changes: 13 additions & 1 deletion packages/gatsby-remark-prismjs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@ plugins: [
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`,
{
resolve: `gatsby-remark-prismjs`,
options: {
// Class prefix for <pre> tags containing syntax highlighting;
// defaults to 'language-' (eg <pre class="language-js">).
// If your site loads Prism into the browser at runtime,
// (eg for use with libraries like react-live),
// you may use this to prevent Prism from re-processing syntax.
// This is an uncommon use-case though;
// If you're unsure, it's best to use the default value.
classPrefix: 'language-',
},
},
]
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/gatsby-remark-prismjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"unist-util-visit": "^1.1.1"
},
"devDependencies": {
"babel-cli": "^6.24.1"
"babel-cli": "^6.24.1",
"remark": "^7.0.1"
},
"keywords": [
"gatsby",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`remark prism plugin generates a <pre> tag with a custom class prefix if configured 1`] = `
Object {
"children": Array [
Object {
"lang": "js",
"position": Position {
"end": Object {
"column": 4,
"line": 3,
"offset": 17,
},
"indent": Array [
1,
1,
],
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "html",
"value": "<div class=\\"gatsby-highlight\\">
<pre class=\\"custom-js\\"><code><span class=\\"token comment\\" spellcheck=\\"true\\">// Fake</span>
</code></pre>
</div>",
},
],
"position": Object {
"end": Object {
"column": 4,
"line": 3,
"offset": 17,
},
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "root",
}
`;
exports[`remark prism plugin generates a <pre> tag with class="language-*" prefix by default 1`] = `
Object {
"children": Array [
Object {
"lang": "js",
"position": Position {
"end": Object {
"column": 4,
"line": 3,
"offset": 17,
},
"indent": Array [
1,
1,
],
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "html",
"value": "<div class=\\"gatsby-highlight\\">
<pre class=\\"language-js\\"><code><span class=\\"token comment\\" spellcheck=\\"true\\">// Fake</span>
</code></pre>
</div>",
},
],
"position": Object {
"end": Object {
"column": 4,
"line": 3,
"offset": 17,
},
"start": Object {
"column": 1,
"line": 1,
"offset": 0,
},
},
"type": "root",
}
`;
18 changes: 18 additions & 0 deletions packages/gatsby-remark-prismjs/src/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const remark = require(`remark`)
const plugin = require(`../index`)

describe(`remark prism plugin`, () => {
it(`generates a <pre> tag with class="language-*" prefix by default`, () => {
const code = '```js\n// Fake\n```'
const markdownAST = remark.parse(code)
plugin({ markdownAST })
expect(markdownAST).toMatchSnapshot()
})

it(`generates a <pre> tag with a custom class prefix if configured`, () => {
const code = '```js\n// Fake\n```'
const markdownAST = remark.parse(code)
plugin({ markdownAST }, { classPrefix: 'custom-' })
expect(markdownAST).toMatchSnapshot()
})
})
15 changes: 11 additions & 4 deletions packages/gatsby-remark-prismjs/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const visit = require(`unist-util-visit`)
const parseLineNumberRange = require(`./parse-line-number-range`)
const highlightCode = require(`./highlight-code`)

module.exports = ({ markdownAST }) => {
module.exports = ({ markdownAST }, { classPrefix = 'language-' } = {}) => {
visit(markdownAST, `code`, node => {
let language = node.lang
let { splitLanguage, highlightLines } = parseLineNumberRange(language)
Expand All @@ -15,17 +15,24 @@ module.exports = ({ markdownAST }) => {
// outcome without any additional CSS.
//
// @see https://github.com/PrismJS/prism/blob/1d5047df37aacc900f8270b1c6215028f6988eb1/themes/prism.css#L49-L54
let preCssClassLanguage = `none`
let languageName = `none`
if (language) {
language = language.toLowerCase()
preCssClassLanguage = language
languageName = language
}

// Allow users to specify a custom class prefix to avoid breaking
// line highlights if Prism is required by any other code.
// This supports custom user styling without causing Prism to
// re-process our already-highlighted markup.
// @see https://github.com/gatsbyjs/gatsby/issues/1486
const className = `${classPrefix}${languageName}`

// Replace the node with the markup we need to make
// 100% width highlighted code lines work
node.type = `html`
node.value = `<div class="gatsby-highlight">
<pre class="language-${preCssClassLanguage}"><code>${highlightCode(
<pre class="${className}"><code>${highlightCode(
language,
node.value,
highlightLines
Expand Down

0 comments on commit d1b72df

Please sign in to comment.