Enabling line numbering in Gatsby code blocks
April 06, 2020
I want to be able to discuss code snippets in my posts. And when discussing code, I personally find that the ability to refer to line numbers is crucial.
However, sometimes line numbers serve no real purpose and I want to be able to omit them in case of one liners, git diffs and text dumps.
The solution is using PrismJS, and setting the right options.
npm install --save gatsby-transformer-remark gatsby-remark-prismjs prismjs
This results in an updated package.json
.
20-04-06|15:29|~/projects/casperlehmann$ git diff package.json
diff --git a/package.json b/package.json
index dce0a38..aa715bd 100644
--- a/package.json
+++ b/package.json
@@ -20,13 +20,13 @@
"gatsby-plugin-typography": "^2.3.25",
"gatsby-remark-copy-linked-files": "^2.1.40",
"gatsby-remark-images": "^3.1.50",
- "gatsby-remark-prismjs": "^3.3.36",
+ "gatsby-remark-prismjs": "^3.4.1",
"gatsby-remark-responsive-iframe": "^2.2.34",
"gatsby-remark-smartypants": "^2.1.23",
"gatsby-source-filesystem": "^2.1.56",
- "gatsby-transformer-remark": "^2.6.59",
+ "gatsby-transformer-remark": "^2.7.1",
"gatsby-transformer-sharp": "^2.3.19",
- "prismjs": "^1.19.0",
+ "prismjs": "^1.20.0",
"react": "^16.13.1",
"react-dom": "^16.12.0",
"react-helmet": "^5.2.1",
Well, there you go. It was already installed.
Next, in gatsby-config.js
, add to the gatsby-transformer-remark
plugin. It is important that showLineNumbers
is set to false
in order to apply it selectively.
20-04-06|15:32|~/projects/casperlehmann$ git diff gatsby-config.js
diff --git a/gatsby-config.js b/gatsby-config.js
index 0bf1fc9..e8b86c8 100644
--- a/gatsby-config.js
+++ b/gatsby-config.js
@@ -45,6 +45,71 @@ module.exports = {
plugins: [
[...]
[...]
[...]
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`,
`gatsby-remark-copy-linked-files`,
`gatsby-remark-smartypants`,
+ {
+ resolve: `gatsby-remark-prismjs`,
+ options: {
+ // Class prefix for <pre> tags containing syntax highlighting;
+ // defaults to 'language-' (e.g. <pre class="language-js">).
+ // If your site loads Prism into the browser at runtime,
+ // (e.g. 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-",
+ // This is used to allow setting a language for inline code
+ // (i.e. single backticks) by creating a separator.
+ // This separator is a string and will do no white-space
+ // stripping.
+ // A suggested value for English speakers is the non-ascii
+ // character '›'.
+ inlineCodeMarker: null,
+ // This lets you set up language aliases. For example,
+ // setting this to '{ sh: "bash" }' will let you use
+ // the language "sh" which will highlight using the
+ // bash highlighter.
+ aliases: {},
+ // This toggles the display of line numbers globally alongside the code.
+ // To use it, add the following line in gatsby-browser.js
+ // right after importing the prism color scheme:
+ // require("prismjs/plugins/line-numbers/prism-line-numbers.css")
+ // Defaults to false.
+ // If you wish to only show line numbers on certain code blocks,
+ // leave false and use the {numberLines: true} syntax below
+ showLineNumbers: false,
+ // If setting this to true, the parser won't handle and highlight inline
+ // code used in markdown i.e. single backtick code like `this`.
+ noInlineHighlight: false,
+ // This adds a new language definition to Prism or extend an already
+ // existing language definition. More details on this option can be
+ // found under the header "Add new language definition or extend an
+ // existing language" below.
+ languageExtensions: [
+ {
+ language: "superscript",
+ extend: "javascript",
+ definition: {
+ superscript_types: /(SuperType)/,
+ },
+ insertBefore: {
+ function: {
+ superscript_keywords: /(superif|superelse)/,
+ },
+ },
+ },
+ ],
+ // Customize the prompt used in shell output
+ // Values below are default
+ prompt: {
+ user: "root",
+ host: "localhost",
+ global: false,
+ },
+ // By default the HTML entities <>&'" are escaped.
+ // Add additional HTML escapes by providing a mapping
+ // of HTML entities and their escape value IE: { '}': '{' }
+ escapeEntities: {},
+ },
+ },
Adding recommended Gatsby styles to a style sheet. Start by creating src/styles/global.css
. It is important to add the highlights sectioning due to a bug in Gatsby that otherwise results in line numbers being out of line <— That’s a pun.
20-04-06|15:40|~/projects/casperlehmann$ git diff --untracked src
20-04-06|15:40|~/projects/casperlehmann$ git diff src
diff --git a/src/styles/global.css b/src/styles/global.css
new file mode 100644
index 0000000..3b70f33
--- /dev/null
+++ b/src/styles/global.css
@@ -0,0 +1,97 @@
+.gatsby-highlight-code-line {
+ background-color: #feb;
+ display: block;
+ margin-right: -1em;
+ margin-left: -1em;
+ padding-right: 1em;
+ padding-left: 0.75em;
+ border-left: 0.25em solid #f99;
+ }
+
+
+ /**
+ * Add back the container background-color, border-radius, padding, margin
+ * and overflow that we removed from <pre>.
+ */
+.gatsby-highlight {
+ background-color: #fdf6e3;
+ border-radius: 0.3em;
+ margin: 0.5em 0;
+ padding: 1em;
+ overflow: auto;
+ }
+
+ /**
+ * Remove the default PrismJS theme background-color, border-radius, margin,
+ * 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;
+ margin: 0;
+ padding: 0;
+ overflow: initial;
+ float: left; /* 1 */
+ min-width: 100%; /* 2 */
+ }
+
+ /**
+ * If you already use line highlighting
+ */
+
+/* Adjust the position of the line numbers */
+.gatsby-highlight pre[class*="language-"].line-numbers {
+ padding-left: 2.8em;
+ }
+
+ /**
+ * If you only want to use line numbering
+ */
+
+ .gatsby-highlight {
+ background-color: #fdf6e3;
+ border-radius: 0.3em;
+ margin: 0.5em 0;
+ padding: 1em;
+ overflow: auto;
+ }
+
+ .gatsby-highlight pre[class*="language-"].line-numbers {
+ padding: 0;
+ padding-left: 2.8em;
+ overflow: initial;
+ }
+
+ /**
+ * Add back the container background-color, border-radius, padding, margin
+ * and overflow that we removed from <pre>.
+ */
+.gatsby-highlight {
+ background-color: #fdf6e3;
+ border-radius: 0.3em;
+ margin: 0.5em 0;
+ padding: 1em;
+ overflow: auto;
+ }
+
+ /**
+ * Remove the default PrismJS theme background-color, border-radius, margin,
+ * 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;
+ margin: 0;
+ padding: 0;
+ overflow: initial;
+ float: left; /* 1 */
+ min-width: 100%; /* 2 */
+ }
+
+ .gatsby-highlight pre[class*="language-"].line-numbers {
+ padding-left: 2.8em; /* 3 */
+ }
In gatsby-browser.js
import this global css along with the supplied styles for Prism.
20-04-06|15:37|~/projects/casperlehmann$ git diff gatsby-browser.js
diff --git a/gatsby-browser.js b/gatsby-browser.js
index 3eae868..31b4030 100644
--- a/gatsby-browser.js
+++ b/gatsby-browser.js
@@ -3,3 +3,10 @@ import "typeface-montserrat"
import "typeface-merriweather"
import "prismjs/themes/prism.css"
+
+import "./src/styles/global.css"
+
+require("prismjs/themes/prism-solarizedlight.css")
+require("prismjs/plugins/line-numbers/prism-line-numbers.css")
Now, we can write code like this to render it in Markdown.
```javascript{numberLines: 104}
// Omit this: ^^^^^^^^^^^^^^^^ part when line numbers are not required.
// Change the number to change the value for the start of the range.
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`,
]
}
}
]
```
NB for escaping the entire code blog, another back-tick is added for a total of four back-ticks.
The result looks like this.
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`,
]
}
}
]
And that is how we add line numbers. We can even change numberLines parameter to a negative number to get relative line numbering. Neat.
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`,
]
}
}
]
What’s more, it even works with DAX.
Sum of Sales Amount (DK) = CALCULATE(
SUM('Sales'[Sales Amount]),
FILTER('Customer', 'Customer'[Country] = "DK")
)
Honestly, not much hassle. Definitely more straight forward than I imagined, and I’d say it works really well. Add, commit, push.
20-04-06|15:52|~/projects/casperlehmann$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: content/blog/enable-line-numbering-in-gatsby-code-blocks/index.md
modified: gatsby-browser.js
modified: gatsby-config.js
modified: package.json
new file: src/styles/global.css
Sources: