Skip to content

Commit 5b523bd

Browse files
authoredMar 2, 2020
feat(gatsby-remark-prismjs): add show invisibles plugin (#21439)
* 20642 Prism show invisibles plugin * feat(gatsby-remark-prismjs): add show invisibles tests * feat(gatsby-remark-prismjs): fixes eslint no-redeclare * feat(gatsby-remark-prismjs): fixes eslint no-redeclare * feat(gatsby-remark-prismjs): fix eslint no-redeclare * Revert "Merge branch 'topics/20642-remark-prismjs-plugin' of https://github.com/rbelow/gatsby into topics/20642-remark-prismjs-plugin" This reverts commit eaf1691, reversing changes made to a6b52bb.
1 parent 47b05fc commit 5b523bd

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/*.js
2+
/plugins
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const loadPrismShowInvisibles = require(`../../plugins/prism-show-invisibles`)
2+
3+
describe(`prism-show-invisibles`, () => {
4+
test(`should export a function`, () => {
5+
expect(typeof loadPrismShowInvisibles).toBe(`function`)
6+
})
7+
8+
test(`should not return`, () => {
9+
expect(loadPrismShowInvisibles()).toBeUndefined()
10+
})
11+
})

‎packages/gatsby-remark-prismjs/src/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const loadLanguageExtension = require(`./load-prism-language-extension`)
44
const highlightCode = require(`./highlight-code`)
55
const addLineNumbers = require(`./add-line-numbers`)
66
const commandLine = require(`./command-line`)
7+
const loadPrismShowInvisibles = require(`./plugins/prism-show-invisibles`)
78

89
module.exports = (
910
{ markdownAST },
@@ -13,6 +14,7 @@ module.exports = (
1314
aliases = {},
1415
noInlineHighlight = false,
1516
showLineNumbers: showLineNumbersGlobal = false,
17+
showInvisibles = false,
1618
languageExtensions = [],
1719
prompt = {
1820
user: `root`,
@@ -61,6 +63,7 @@ module.exports = (
6163
// line highlights if Prism is required by any other code.
6264
// This supports custom user styling without causing Prism to
6365
// re-process our already-highlighted markup.
66+
//
6467
// @see https://github.com/gatsbyjs/gatsby/issues/1486
6568
const className = `${classPrefix}${languageName}`
6669

@@ -73,6 +76,10 @@ module.exports = (
7376
numLinesNumber = addLineNumbers(node.value)
7477
}
7578

79+
if (showInvisibles) {
80+
loadPrismShowInvisibles(languageName)
81+
}
82+
7683
// Replace the node with the markup we need to make
7784
// 100% width highlighted code lines work
7885
node.type = `html`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const Prism = require(`prismjs`)
2+
3+
const env = {
4+
grammar: undefined,
5+
}
6+
7+
function loadEnv(language) {
8+
env.grammar = Prism.languages[language]
9+
if (!env.grammar) return
10+
}
11+
12+
module.exports = (language = `javascript`) => {
13+
loadEnv(language)
14+
15+
// Gatsby Prism Show Invisibles Plugin
16+
//
17+
// This file serves as an adapter module
18+
// for the original Prism Show Invisibles
19+
// implementation. The ported plugin code
20+
// is from npm's prismjs@1.17.1.
21+
//
22+
// @see https://github.com/PrismJS/prism/blob/v1.17.1/plugins/show-invisibles/prism-show-invisibles.js
23+
//
24+
// prism-show-invisibles.js:start
25+
if (
26+
(typeof self !== `undefined` && !self.Prism) ||
27+
(typeof global !== `undefined` && !global.Prism)
28+
) {
29+
return
30+
}
31+
32+
var invisibles = {
33+
tab: /\t/,
34+
crlf: /\r\n/,
35+
lf: /\n/,
36+
cr: /\r/,
37+
space: / /,
38+
}
39+
40+
/**
41+
* Handles the recursive calling of `addInvisibles` for one token.
42+
*
43+
* @param {Object|Array} tokens The grammar or array which contains the token.
44+
* @param {string|number} name The name or index of the token in `tokens`.
45+
*/
46+
function handleToken(tokens, name) {
47+
var value = tokens[name]
48+
49+
var type = Prism.util.type(value)
50+
switch (type) {
51+
case `RegExp`:
52+
var inside = {}
53+
tokens[name] = {
54+
pattern: value,
55+
inside: inside,
56+
}
57+
addInvisibles(inside)
58+
break
59+
60+
case `Array`:
61+
for (var i = 0, l = value.length; i < l; i++) {
62+
handleToken(value, i)
63+
}
64+
break
65+
66+
default:
67+
// 'Object'
68+
var inside = value.inside || (value.inside = {}) // eslint-disable-line no-redeclare
69+
addInvisibles(inside)
70+
break
71+
}
72+
}
73+
74+
/**
75+
* Recursively adds patterns to match invisible characters to the given grammar (if not added already).
76+
*
77+
* @param {Object} grammar
78+
*/
79+
function addInvisibles(grammar) {
80+
if (!grammar || grammar[`tab`]) {
81+
return
82+
}
83+
84+
// assign invisibles here to "mark" the grammar in case of self references
85+
for (var name in invisibles) {
86+
if (invisibles.hasOwnProperty(name)) {
87+
grammar[name] = invisibles[name]
88+
}
89+
}
90+
91+
/* eslint-disable no-redeclare */
92+
for (var name in grammar) {
93+
/* eslint-enable no-redeclare */
94+
if (grammar.hasOwnProperty(name) && !invisibles[name]) {
95+
if (name === `rest`) {
96+
addInvisibles(grammar[`rest`])
97+
} else {
98+
handleToken(grammar, name)
99+
}
100+
}
101+
}
102+
}
103+
104+
Prism.hooks.add(`before-highlight`, function(env) {
105+
addInvisibles(env.grammar)
106+
})
107+
// prism-show-invisibles.js:end
108+
109+
addInvisibles(env.grammar)
110+
}

0 commit comments

Comments
 (0)
Please sign in to comment.