diff --git a/examples/using-remark/src/layouts/index.js b/examples/using-remark/src/layouts/index.js index bc841d5f94b93..b9daba51ce719 100644 --- a/examples/using-remark/src/layouts/index.js +++ b/examples/using-remark/src/layouts/index.js @@ -7,6 +7,7 @@ import "typeface-space-mono" import "typeface-spectral" import "prismjs/themes/prism-solarizedlight.css" +import "prismjs/plugins/line-numbers/prism-line-numbers.css" class Layout extends React.Component { render() { diff --git a/examples/using-remark/src/pages/2017-04-04---code-and-syntax-highlighting/index.md b/examples/using-remark/src/pages/2017-04-04---code-and-syntax-highlighting/index.md index 896105b9d7550..99ba281a269ca 100644 --- a/examples/using-remark/src/pages/2017-04-04---code-and-syntax-highlighting/index.md +++ b/examples/using-remark/src/pages/2017-04-04---code-and-syntax-highlighting/index.md @@ -64,13 +64,13 @@ No language indicated, so no syntax highlighting. But let's throw in a tag. ``` -## Line highlighting +## Line highlighting & numbering -[gatsby-remark-prismjs][1] has its own line highlighting implementation which +[gatsby-remark-prismjs][1] has its own line highlighting & numbering implementation which differs a bit from PrismJS's own. You can find out everything about it in the [corresponding README][1]. - ```javascript{1-2,22} + ```javascript{1-2,22}{numberLines: true} // In your gatsby-config.js // Let's make this line very long so that our container has to scroll its overflow… plugins: [ @@ -99,7 +99,7 @@ differs a bit from PrismJS's own. You can find out everything about it in the ] ``` -```javascript{1-2,22} +```javascript{1-2,22}{numberLines: true} // In your gatsby-config.js // Let's make this line very long so that our container has to scroll its overflow… plugins: [ @@ -128,6 +128,20 @@ plugins: [ ] ``` +Line numbers can start from anywhere, here's an example showing a small extract from a larger chunk of code: + + ```{numberLines: 549} + ... + a long imaginary code block + ... + ``` + +```{numberLines: 549} +... + a long imaginary code block +... +``` + Let's do something crazy and add a list with another code example: - **A list item** diff --git a/examples/using-remark/src/utils/typography.js b/examples/using-remark/src/utils/typography.js index bbccbaa2bf8dc..909ebf6ec4219 100644 --- a/examples/using-remark/src/utils/typography.js +++ b/examples/using-remark/src/utils/typography.js @@ -140,6 +140,9 @@ const options = { minWidth: `100%`, textShadow: `none`, }, + ".gatsby-highlight pre[class*='language-'].line-numbers": { + paddingLeft: `2.8em`, + }, ".gatsby-highlight-code-line": { background: `#fff2cc`, display: `block`, diff --git a/packages/gatsby-remark-prismjs/.gitignore b/packages/gatsby-remark-prismjs/.gitignore index 54623385a53ce..a1eea9b0175b0 100644 --- a/packages/gatsby-remark-prismjs/.gitignore +++ b/packages/gatsby-remark-prismjs/.gitignore @@ -1,4 +1,5 @@ /index.js +/add-line-numbers.js /highlight-code.js /parse-line-number-range.js /load-prism-language.js diff --git a/packages/gatsby-remark-prismjs/README.md b/packages/gatsby-remark-prismjs/README.md index 93e2ab9b5647d..93fd60ee0b76b 100644 --- a/packages/gatsby-remark-prismjs/README.md +++ b/packages/gatsby-remark-prismjs/README.md @@ -39,6 +39,12 @@ plugins: [ // the language "sh" which will highlight using the // bash highlighter. aliases: {}, + // This toggles the display of line numbers alongside the code. + // To use it, add the following line in src/layouts/index.js + // right after importing the prism color scheme: + // `require("prismjs/plugins/line-numbers/prism-line-numbers.css");` + // Defaults to false. + showLineNumbers: false }, }, ], @@ -110,6 +116,7 @@ CSS along your PrismJS theme and the styles for `.gatsby-highlight-code-line`: * padding and overflow. * 1. Make the element just wide enough to fit its content. * 2. Always fill the visible space in .gatsby-highlight. + * 3. Adjust the position of the line numbers */ .gatsby-highlight pre[class*="language-"] { background-color: transparent; @@ -119,6 +126,20 @@ CSS along your PrismJS theme and the styles for `.gatsby-highlight-code-line`: float: left; /* 1 */ min-width: 100%; /* 2 */ } +.gatsby-highlight pre[class*="language-"].line-numbers { + paddingLeft: 2.8em; /* 3 */ +} +``` + +#### Optional: Add line numbering + +If you want to add line numbering alongside your code, you need to +import the corresponding CSS file from PrismJS, right after importing your +colorscheme in `layout/index.js`: + +```javascript +// layouts/index.js +require("prismjs/plugins/line-numbers/prism-line-numbers.css"); ``` ### Usage in Markdown @@ -139,6 +160,39 @@ This is some beautiful code: ] ``` +To see the line numbers alongside your code, you can use the `numberLines` option: + + ```javascript{numberLines: true} + // In your gatsby-config.js + plugins: [ + { + resolve: `gatsby-transformer-remark`, + options: { + plugins: [ + `gatsby-remark-prismjs`, + ] + } + } + ] + ``` + +You can also start numbering at any index you wish (here, numbering +will start at index 5): + + ```javascript{numberLines: 5} + // In your gatsby-config.js + plugins: [ + { + resolve: `gatsby-transformer-remark`, + options: { + plugins: [ + `gatsby-remark-prismjs`, + ] + } + } + ] + ``` + You can also add line highlighting. It adds a span around lines of code with a special class `.gatsby-highlight-code-line` that you can target with styles. See this README for more info. @@ -204,9 +258,21 @@ throw our overflow and background on `.gatsby-highlight`, and use `display:block` on `.gatsby-highlight-code-line` – all of this coming together to facilitate the desired line highlight behavior. +### Line numbering + +Because [the line numbering PrismJS plugin][7] runs client-side, a few adaptations were required to make it work: + +* A class `.line-numbers` is dynamically added to the `
` element.
+* A new node `` is added right before the closing `
`
+containing as many empty ``s as there are lines.
+
+See the [client-side PrismJS implementation][8] for reference.
+
[1]: https://github.com/PrismJS/prism/tree/8eb0ab6f76484ca47fa7acbf77657fab17b03ca7/plugins/line-highlight
[2]: https://github.com/facebook/react/blob/00ba97a354e841701b4b83983c3a3904895e7b87/docs/_config.yml#L10
[3]: http://prismjs.com/#plugins
[4]: https://facebook.github.io/react/tutorial/tutorial.html
[5]: https://github.com/PrismJS/prism/tree/1d5047df37aacc900f8270b1c6215028f6988eb1/themes
[6]: http://prismjs.com/
+[7]: https://prismjs.com/plugins/line-numbers/
+[8]: https://github.com/PrismJS/prism/blob/master/plugins/line-numbers/prism-line-numbers.js#L69-L115
diff --git a/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap
index 122be2ae1312a..7fc9e4cb89bad 100644
--- a/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap
+++ b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/index.js.snap
@@ -22,9 +22,7 @@ Object {
},
},
"type": "html",
- "value": "// Fake
- // Fake
// Fake
- // Fake
// Fake
- // Fake
//.foo {
+color: red;
+ }\`
${highlightCode(
- language,
- node.value,
- highlightLines
- )}
- `
+ + ``
+ + `${highlightCode(language, node.value, highlightLines)}`
+ + `
`
+ + `${numLinesNumber}`
+ + `
`
+ + `${highlightCode(
- languageName,
- node.value
- )}
`
+ node.value = `${highlightCode(languageName, node.value)}
`
})
}
diff --git a/packages/gatsby-remark-prismjs/src/parse-line-number-range.js b/packages/gatsby-remark-prismjs/src/parse-line-number-range.js
index 33f8473fded7e..2602b85a32a4c 100644
--- a/packages/gatsby-remark-prismjs/src/parse-line-number-range.js
+++ b/packages/gatsby-remark-prismjs/src/parse-line-number-range.js
@@ -5,11 +5,34 @@ module.exports = language => {
return ``
}
if (language.split(`{`).length > 1) {
- let [splitLanguage, rangeStr] = language.split(`{`)
- rangeStr = rangeStr.slice(0, -1)
+ let [splitLanguage, ...options] = language.split(`{`)
+ let highlightLines = [], numberLines = false, numberLinesStartAt
+ // Options can be given in any order and are optional
+ options.forEach((option) => {
+ option = option.slice(0, -1)
+ // Test if the option is for line hightlighting
+ if (rangeParser.parse(option).length > 0) {
+ highlightLines = rangeParser.parse(option).filter(n => n > 0)
+ }
+ option = option.split(`:`)
+ // Test if the option is for line numbering
+ // Option must look like `numberLines: true` or `numberLines: