Skip to content

Commit

Permalink
fix(gatsby-remark-prismjs): Use gatsby-highlight class to calculate l…
Browse files Browse the repository at this point in the history
…ine numbers (#23031)

* Use gatsby-highlight class to calculate line nums

* Added highlight line test

* Added line num with highlight class snapshot test

* Minor correction, closing code-fence

* test: explicitely count line number rows instead of trying to match on pretty confusing html

* test: use new markup counting method on old test

Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
Co-authored-by: gatsbybot <mathews.kyle+gatsbybot@gmail.com>
  • Loading branch information
3 people authored Apr 17, 2020
1 parent 4828f3d commit 104f2cc
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/gatsby-remark-prismjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.7",
"babel-preset-gatsby-package": "^0.3.1",
"cheerio": "^1.0.0-rc.3",
"cross-env": "^5.2.1",
"prismjs": "^1.19.0",
"remark": "^9.0.0"
Expand Down
31 changes: 26 additions & 5 deletions packages/gatsby-remark-prismjs/src/__tests__/add-line-numbers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const addLineNumbers = require(`../add-line-numbers`)
const cheerio = require(`cheerio`)

describe(`returns the line numbers container`, () => {
it(`should return the <span> container with the right classes`, () => {
Expand All @@ -8,10 +9,30 @@ describe(`returns the line numbers container`, () => {
)
})
it(`should return return as many <span></span> children as there are code lines`, () => {
expect(addLineNumbers(`line1\nline2\nline3`)).toEqual(
`<span aria-hidden="true" class="line-numbers-rows" style="white-space: normal; width: auto; left: 0;">` +
`<span></span><span></span><span></span>` +
`</span>`
)
const basicCodeLines = `line1\nline2\nline3`

const basicCodeLinesWithLineNumbers = addLineNumbers(basicCodeLines)

const $ = cheerio.load(basicCodeLinesWithLineNumbers)
const numberOfLineNumbers = $(`.line-numbers-rows > span`).length

expect(numberOfLineNumbers).toEqual(3)
})
it(`should return as many <span></span> children as there are code lines and highlight classes`, () => {
//Expect 6 internal spans
const highlightedCode =
`line1\n` +
`<span class=\\"gatsby-highlight-code-line\\"></span>` +
`line2\n` +
` <span class=\\"gatsby-highlight-code-line\\"></span>` +
` line3\n` +
`line4`

const highlightedCodeWithLineNumbers = addLineNumbers(highlightedCode)

const $ = cheerio.load(highlightedCodeWithLineNumbers)
const numberOfLineNumbers = $(`.line-numbers-rows > span`).length

expect(numberOfLineNumbers).toEqual(4 + 2)
})
})
19 changes: 19 additions & 0 deletions packages/gatsby-remark-prismjs/src/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const remark = require(`remark`)
const cheerio = require(`cheerio`)
let plugin

describe(`remark prism plugin`, () => {
Expand Down Expand Up @@ -122,6 +123,24 @@ describe(`remark prism plugin`, () => {
expect(markdownAST).toMatchSnapshot()
})

it(`correctly counts line-numbers for markup using highlight classes`, () => {
const code =
`\`\`\`js\n` +
`function highlightTest() {\n` +
`// highlight-start\n` +
`return "this is a highlight test"\n` +
`// highlight-end\n` +
`}\n` +
`\`\`\``
const markdownAST = remark.parse(code)
plugin({ markdownAST }, { showLineNumbers: true })

const htmlResult = markdownAST.children[0].value
const $ = cheerio.load(htmlResult)
const numberOfLineNumbers = $(`.line-numbers-rows > span`).length
expect(numberOfLineNumbers).toEqual(3)
})

it(`does not add line-number markup when not configured globally`, () => {
const code = `\`\`\`js\n//.foo { \ncolor: red;\n }\``
const markdownAST = remark.parse(code)
Expand Down
8 changes: 7 additions & 1 deletion packages/gatsby-remark-prismjs/src/add-line-numbers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const GATSBY_HIGHLIGHT_LINE_CLASS = /gatsby-highlight-code-line/g

module.exports = (code = []) => {
// Generate as many `<span></span>` as there are code lines
const generateSpans = numberOfLines => {
Expand All @@ -8,7 +10,11 @@ module.exports = (code = []) => {
return spans
}

const numberOfLines = code.length === 0 ? 0 : code.split(`\n`).length
const numberOfLines =
code.length === 0
? 0
: code.split(`\n`).length +
(code.match(GATSBY_HIGHLIGHT_LINE_CLASS) || []).length

// Generate the container for the line numbers.
// Relevant code in the Prism Line Numbers plugin can be found here:
Expand Down
28 changes: 18 additions & 10 deletions packages/gatsby-remark-prismjs/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,36 @@ module.exports = (
// @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`

let highlightClassName = `gatsby-highlight`
if (highlightLines && highlightLines.length > 0)
highlightClassName += ` has-highlighted-lines`

const highlightedCode = highlightCode(
languageName,
node.value,
escapeEntities,
highlightLines,
noInlineHighlight
)

let numLinesStyle, numLinesClass, numLinesNumber
numLinesStyle = numLinesClass = numLinesNumber = ``
if (showLineNumbers) {
numLinesStyle = ` style="counter-reset: linenumber ${
numberLinesStartAt - 1
}"`
numLinesClass = ` line-numbers`
numLinesNumber = addLineNumbers(node.value)
numLinesNumber = addLineNumbers(highlightedCode)
}

if (showInvisibles) {
loadPrismShowInvisibles(languageName)
}

// Replace the node with the markup we need to make
// 100% width highlighted code lines work
node.type = `html`

let highlightClassName = `gatsby-highlight`
if (highlightLines && highlightLines.length > 0)
highlightClassName += ` has-highlighted-lines`

const useCommandLine =
[`bash`].includes(languageName) &&
(prompt.global ||
Expand All @@ -102,7 +110,7 @@ module.exports = (
+ `<pre${numLinesStyle} class="${className}${numLinesClass}">`
+ `<code class="${className}">`
+ `${useCommandLine ? commandLine(node.value, outputLines, promptUser, promptHost) : ``}`
+ `${highlightCode(languageName, node.value, escapeEntities, highlightLines, noInlineHighlight)}`
+ `${highlightedCode}`
+ `</code>`
+ `${numLinesNumber}`
+ `</pre>`
Expand Down

0 comments on commit 104f2cc

Please sign in to comment.