diff --git a/packages/gatsby-remark-prismjs/README.md b/packages/gatsby-remark-prismjs/README.md index b8f69c0bfe823..d572012e37089 100644 --- a/packages/gatsby-remark-prismjs/README.md +++ b/packages/gatsby-remark-prismjs/README.md @@ -16,7 +16,19 @@ plugins: [ resolve: `gatsby-transformer-remark`, options: { plugins: [ - `gatsby-remark-prismjs`, + { + resolve: `gatsby-remark-prismjs`, + options: { + // Class prefix for
 tags containing syntax highlighting;
+            // defaults to 'language-' (eg 
).
+            // 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-',
+          },
+        },
       ]
     }
   }
diff --git a/packages/gatsby-remark-prismjs/package.json b/packages/gatsby-remark-prismjs/package.json
index d0bdb9fbaaa60..22de6066d5e42 100644
--- a/packages/gatsby-remark-prismjs/package.json
+++ b/packages/gatsby-remark-prismjs/package.json
@@ -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",
diff --git a/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap
new file mode 100644
index 0000000000000..5b2e7c22e5abb
--- /dev/null
+++ b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap
@@ -0,0 +1,89 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`remark prism plugin generates a 
 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": "
+
// Fake
+
+
", + }, + ], + "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
 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": "
+
// Fake
+
+
", + }, + ], + "position": Object { + "end": Object { + "column": 4, + "line": 3, + "offset": 17, + }, + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; diff --git a/packages/gatsby-remark-prismjs/src/__tests__/index.js b/packages/gatsby-remark-prismjs/src/__tests__/index.js new file mode 100644 index 0000000000000..ffe04b638c80a --- /dev/null +++ b/packages/gatsby-remark-prismjs/src/__tests__/index.js @@ -0,0 +1,18 @@ +const remark = require(`remark`) +const plugin = require(`../index`) + +describe(`remark prism plugin`, () => { + it(`generates a
 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 
 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()
+  })
+})
diff --git a/packages/gatsby-remark-prismjs/src/index.js b/packages/gatsby-remark-prismjs/src/index.js
index 175f37474914b..29cdfa266e3f9 100644
--- a/packages/gatsby-remark-prismjs/src/index.js
+++ b/packages/gatsby-remark-prismjs/src/index.js
@@ -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)
@@ -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 = `
-
${highlightCode(
+      
${highlightCode(
       language,
       node.value,
       highlightLines