From ccb6f621ab1a40475e93fa81789fcbe6a17fafda Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Thu, 21 Jun 2018 20:01:55 -0300 Subject: [PATCH 01/27] Support hide lines --- .../src/__tests__/__snapshots__/index.js.snap | 190 ++++++++++++++++++ .../src/__tests__/index.js | 93 +++++++++ .../gatsby-remark-embed-snippet/src/index.js | 24 ++- 3 files changed, 305 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index e46decdb2d876..90bc1087d399e 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -57,6 +57,65 @@ Object { } `; +exports[`gatsby-remark-embed-snippet CSS files should support hideline-range markers 1`] = ` +Object { + "children": Array [ + Object { + "children": Array [ + Object { + "position": Position { + "end": Object { + "column": 24, + "line": 1, + "offset": 23, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "html", + "value": "
+
html {
+padding: 50px;
+}
+
", + }, + ], + "position": Position { + "end": Object { + "column": 24, + "line": 1, + "offset": 23, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": Object { + "end": Object { + "column": 24, + "line": 1, + "offset": 23, + }, + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`gatsby-remark-embed-snippet CSS files should support highlight-line and highlight-next-line markers 1`] = ` Object { "children": Array [ @@ -237,6 +296,71 @@ Object { } `; +exports[`gatsby-remark-embed-snippet HTML files should support hideline-range markers 1`] = ` +Object { + "children": Array [ + Object { + "children": Array [ + Object { + "position": Position { + "end": Object { + "column": 25, + "line": 1, + "offset": 24, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "html", + "value": "
+
<html>
+<body>
+<p>
+<span>not hidden</span>
+</p>
+<ul>
+</ul>
+</body>
+</html>
+
", + }, + ], + "position": Position { + "end": Object { + "column": 25, + "line": 1, + "offset": 24, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": Object { + "end": Object { + "column": 25, + "line": 1, + "offset": 24, + }, + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`gatsby-remark-embed-snippet HTML files should support highlight-line and highlight-next-line markers 1`] = ` Object { "children": Array [ @@ -487,6 +611,72 @@ Object { } `; +exports[`gatsby-remark-embed-snippet JavaScript files should support hideline-range markers 1`] = ` +Object { + "children": Array [ + Object { + "children": Array [ + Object { + "position": Position { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "html", + "value": "
+
ReactDOM.render(
+<div>
+<ul>
+<li>Not hidden</li>
+<li>Not hidden</li>
+<li>Not hidden</li>
+</ul>
+</div>,
+document.getElementById('root')
+);
+
", + }, + ], + "position": Position { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": Object { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`gatsby-remark-embed-snippet JavaScript files should support highlight-line and highlight-next-line markers 1`] = ` Object { "children": Array [ diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index b516dfd76f0e5..b8ca07ca865df 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -149,6 +149,31 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) + + it(`should support hideline-range markers`, () => { + fs.readFileSync.mockReturnValue( + ` + html { + /* hideline-range{1,2} */ + height: 100%; + width: 100%; + padding: 50px; + } + ` + .replace(/^ +/gm, ``) + .trim() + ) + + const markdownAST = remark.parse(`\`embed:hello-world.css\``) + const transformed = plugin( + { markdownAST }, + { + directory: `examples`, + } + ) + + expect(transformed).toMatchSnapshot() + }) }) describe(`HTML files`, () => { @@ -220,6 +245,38 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) + + it(`should support hideline-range markers`, () => { + fs.readFileSync.mockReturnValue( + ` + + + +

+ hidden + not hidden +

+ + + + ` + .replace(/^ +/gm, ``) + .trim() + ) + + const markdownAST = remark.parse(`\`embed:hello-world.html\``) + const transformed = plugin( + { markdownAST }, + { + directory: `examples`, + } + ) + + expect(transformed).toMatchSnapshot() + }) }) describe(`JavaScript files`, () => { @@ -375,6 +432,42 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) + + it(`should support hideline-range markers`, () => { + fs.readFileSync.mockReturnValue( + ` + // hideline-range{1-2, 9-11, 16} + import React from 'react' + import { render } from "react-dom" + ReactDOM.render( +
+ +
, + document.getElementById('root') + ); + console.log('Hidden') + ` + .replace(/^ +/gm, ``) + .trim() + ) + + const markdownAST = remark.parse(`\`embed:hello-world.js\``) + const transformed = plugin( + { markdownAST }, + { + directory: `examples`, + } + ) + + expect(transformed).toMatchSnapshot() + }) }) describe(`Markdown files`, () => { diff --git a/packages/gatsby-remark-embed-snippet/src/index.js b/packages/gatsby-remark-embed-snippet/src/index.js index 715f24b4baddb..ed535110324d7 100644 --- a/packages/gatsby-remark-embed-snippet/src/index.js +++ b/packages/gatsby-remark-embed-snippet/src/index.js @@ -53,9 +53,27 @@ module.exports = ( throw Error(`Invalid snippet specified; no such file "${path}"`) } - // This method removes lines that contain only highlight directives, - // eg 'highlight-next-line' or 'highlight-range' comments. + // This method removes lines that contain only highlight or hideline directives, + // eg 'highlight-next-line', 'highlight-range' or 'hideline-range' comments. function filterDirectives(line, index) { + if (line.includes(`hideline-range`)) { + const match = line.match(/hideline-range{([^}]+)}/) + if (!match) { + console.warn(`Invalid match specified: "${line.trim()}"`) + return false + } + + const range = match[1] && match[1].replace(/\s/g, ``) + // hideline line numbers are 1-based but so are offsets. + // Remember that the current line (index) will be removed. + rangeParser.parse(range).forEach(offset => { + hiddenLines.push(index + offset) + }) + + // Strip lines that contain hideline-range comments. + return false + } + if (line.includes(`highlight-next-line`)) { // Although we're highlighting the next line, // We can use the current index since we also filter this lines. @@ -96,6 +114,7 @@ module.exports = ( // The order if these operations is important! // Filtering next-line comments impacts line-numbers for same-line comments. const highlightLines = [] + const hiddenLines = [] const code = fs .readFileSync(path, `utf8`) .split(`\n`) @@ -108,6 +127,7 @@ module.exports = ( return returnValue }) + .filter((line, index) => !hiddenLines.includes(index + 1)) // hide line numbers are 1-based. .map((line, index) => { if (line.includes(`highlight-line`)) { // Mark this line for highlighting. From 7da31621b76ea5e6b8e851797a8d580a0be9c9ab Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Thu, 21 Jun 2018 23:26:21 -0300 Subject: [PATCH 02/27] Update README --- .../gatsby-remark-embed-snippet/README.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/gatsby-remark-embed-snippet/README.md b/packages/gatsby-remark-embed-snippet/README.md index ece90834b1a2f..1007b1f19ffdb 100644 --- a/packages/gatsby-remark-embed-snippet/README.md +++ b/packages/gatsby-remark-embed-snippet/README.md @@ -110,6 +110,30 @@ baz: "highlighted" quz: "highlighted" ``` +### Hide Lines + +Also is possible specify a range of lines to be hide. + +#### JavaScript example + +```js +// hideline-range{1-3,9-11} +import React from "react" +import ReactDOM from "react-dom" + +function App() { + return ( +

Hello world!

+ ) +} + +const rootElement = document.getElementById("root") +ReactDOM.render(, rootElement) +``` + +Will produce something like this: +![screenshot from 2018-06-21 20-21-58](https://user-images.githubusercontent.com/5726140/41750161-cdf430cc-7590-11e8-9ccb-8829bcce0f14.png) + ## Installation `npm install --save gatsby-remark-embed-snippet` From a60891e4c994d9c5cad7319d84db1464149b0f46 Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Fri, 22 Jun 2018 15:10:58 -0300 Subject: [PATCH 03/27] Write test case --- .../src/__tests__/__snapshots__/index.js.snap | 66 +++++++++++++++++++ .../src/__tests__/index.js | 42 +++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index 90bc1087d399e..3450c0fd734ea 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -611,6 +611,72 @@ Object { } `; +exports[`gatsby-remark-embed-snippet JavaScript files should support hideline-range and highlight markers 1`] = ` +Object { + "children": Array [ + Object { + "children": Array [ + Object { + "position": Position { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "html", + "value": "
+
ReactDOM.render(
+<div>
+<ul>
+<li>Not hidden</li>
+<li>Not hidden</li>
+<li>Not hidden</li>
+</ul>
+</div>,
+document.getElementById('root')
+);
+
", + }, + ], + "position": Position { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": Object { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`gatsby-remark-embed-snippet JavaScript files should support hideline-range markers 1`] = ` Object { "children": Array [ diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index b8ca07ca865df..1d697105596f0 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -153,8 +153,8 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should support hideline-range markers`, () => { fs.readFileSync.mockReturnValue( ` + /* hideline-range{2-3} */ html { - /* hideline-range{1,2} */ height: 100%; width: 100%; padding: 50px; @@ -436,7 +436,7 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should support hideline-range markers`, () => { fs.readFileSync.mockReturnValue( ` - // hideline-range{1-2, 9-11, 16} + // hideline-range{1-2,9-11,16} import React from 'react' import { render } from "react-dom" ReactDOM.render( @@ -468,6 +468,44 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) + + it(`should support hideline-range and highlight markers`, () => { + fs.readFileSync.mockReturnValue( + ` + // hideline-range{1-2,9-11,16} + // highlight-range{1,4-6} + import React from 'react' + import { render } from "react-dom" + ReactDOM.render( +
+
    +
  • Not hidden
  • +
  • Not hidden
  • +
  • Not hidden
  • +
  • Hidden
  • +
  • Hidden
  • +
  • Hidden
  • +
+
, + // highlight-next-line + document.getElementById('root') + ); + console.log('Hidden') + ` + .replace(/^ +/gm, ``) + .trim() + ) + + const markdownAST = remark.parse(`\`embed:hello-world.js\``) + const transformed = plugin( + { markdownAST }, + { + directory: `examples`, + } + ) + + expect(transformed).toMatchSnapshot() + }) }) describe(`Markdown files`, () => { From a280b942652f670acebd7baa88aba0d9fad3d7b6 Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Mon, 25 Jun 2018 09:35:39 -0300 Subject: [PATCH 04/27] Update screenshot example URL --- packages/gatsby-remark-embed-snippet/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-remark-embed-snippet/README.md b/packages/gatsby-remark-embed-snippet/README.md index 1007b1f19ffdb..509c2effd3a18 100644 --- a/packages/gatsby-remark-embed-snippet/README.md +++ b/packages/gatsby-remark-embed-snippet/README.md @@ -132,7 +132,7 @@ ReactDOM.render(, rootElement) ``` Will produce something like this: -![screenshot from 2018-06-21 20-21-58](https://user-images.githubusercontent.com/5726140/41750161-cdf430cc-7590-11e8-9ccb-8829bcce0f14.png) +![screenshot from 2018-06-21 20-21-58](https://i.imgur.com/cYlAKZg.png) ## Installation From 92fcba33096a534578313f3c72ebea58b4e268c1 Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Tue, 26 Jun 2018 22:09:52 -0300 Subject: [PATCH 05/27] Create rule for hidden and highlighted rows do not overlap --- .../src/__tests__/__snapshots__/index.js.snap | 18 ++++---- .../src/__tests__/index.js | 42 +++++++++++++++++-- .../gatsby-remark-embed-snippet/src/index.js | 14 ++++++- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index 3450c0fd734ea..bb4608dd1769f 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -632,15 +632,15 @@ Object { }, "type": "html", "value": "
-
ReactDOM.render(
-<div>
+        
ReactDOM.render(
+<div>
 <ul>
-<li>Not hidden</li>
-<li>Not hidden</li>
-<li>Not hidden</li>
-</ul>
-</div>,
-document.getElementById('root')
+<li>Not hidden and highlighted</li>
+<li>Not hidden and highlighted</li>
+<li>Not hidden and highlighted</li>
+</ul>
+</div>,
+document.getElementById('root')
 );
", }, @@ -996,6 +996,8 @@ notHighlighted =
  • hidden
  • @@ -433,10 +437,10 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should support hideline-range markers`, () => { + it(`should support hideline-range and hideline-next-line markers`, () => { fs.readFileSync.mockReturnValue( ` - // hideline-range{1-2,9-11,16} + // hideline-range{1-2,9-11} import React from 'react' import { render } from "react-dom" ReactDOM.render( @@ -452,6 +456,7 @@ describe(`gatsby-remark-embed-snippet`, () => { , document.getElementById('root') ); + // hideline-next-line console.log('Hidden') ` .replace(/^ +/gm, ``) diff --git a/packages/gatsby-remark-embed-snippet/src/index.js b/packages/gatsby-remark-embed-snippet/src/index.js index 5c00e7e4089fd..89a991f9254f0 100644 --- a/packages/gatsby-remark-embed-snippet/src/index.js +++ b/packages/gatsby-remark-embed-snippet/src/index.js @@ -53,10 +53,18 @@ module.exports = ( throw Error(`Invalid snippet specified; no such file "${path}"`) } - // This method removes lines that contain only highlight or hideline directives, + // This method removes lines that contain only highlight or hide line directives, // eg 'highlight-next-line', 'highlight-range' or 'hideline-range' comments. function filterDirectives(line, index) { - if (line.includes(`hideline-range`)) { + if (line.includes(`hideline-next-line`)) { + // Although we're hiding the next line, + // We can use the current index since we also filter this lines. + // (Highlight line numbers are 1-based). + hiddenLines.push(index + 1) + + // Strip lines that contain hideline-next-line comments. + return false + } else if (line.includes(`hideline-range`)) { const match = line.match(/hideline-range{([^}]+)}/) if (!match) { console.warn(`Invalid match specified: "${line.trim()}"`) @@ -64,7 +72,7 @@ module.exports = ( } const range = match[1] && match[1].replace(/\s/g, ``) - // hideline line numbers are 1-based but so are offsets. + // Hide line numbers are 1-based but so are offsets. // Remember that the current line (index) will be removed. rangeParser.parse(range).forEach(offset => { hiddenLines.push(index + offset) From 0e62ca2b76d2a718d59764fad1d73f0ac689be13 Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Mon, 24 Sep 2018 10:54:53 -0300 Subject: [PATCH 11/27] Add blank lines in test case --- packages/gatsby-remark-embed-snippet/src/__tests__/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index 37ad9c780211e..1bf9fabd756d9 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -440,9 +440,11 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should support hideline-range and hideline-next-line markers`, () => { fs.readFileSync.mockReturnValue( ` - // hideline-range{1-2,9-11} + // hideline-range{1-2,11-13} import React from 'react' import { render } from "react-dom" + + ReactDOM.render(
      @@ -456,6 +458,8 @@ describe(`gatsby-remark-embed-snippet`, () => {
    , document.getElementById('root') ); + + // hideline-next-line console.log('Hidden') ` From 4cd6ab78ebf8194d8e8a53447f726bb3ff225de5 Mon Sep 17 00:00:00 2001 From: Washington Soares Date: Wed, 26 Sep 2018 13:42:23 -0300 Subject: [PATCH 12/27] Refactoring hideline-range test cases --- .../src/__tests__/__snapshots__/index.js.snap | 4 +-- .../src/__tests__/index.js | 27 +++++++++---------- .../gatsby-remark-embed-snippet/src/index.js | 1 + 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index c8387adf06022..94a94b1770045 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -320,9 +320,9 @@ Object {
    <html>
     <body>
     <p>
    -<span>not hidden</span>
     </p>
     <ul>
    +<li>not hidden</li>
     </ul>
     </body>
     </html>
    @@ -996,8 +996,6 @@ notHighlighted =
    ReactDOM.render(
    -<div>
    -<ul>
    -<li>Not hidden and highlighted</li>
    -<li>Not hidden and highlighted</li>
    -<li>Not hidden and highlighted</li>
    -</ul>
    -</div>,
    -document.getElementById('root')
    -);
    +<div> +<ul> +<li>Not hidden and highlighted</li><li>Not hidden and highlighted</li><li>Not hidden and highlighted</li></ul> +</div>, +document.getElementById('root'));
    ", }, ], diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index 6e77a6b7d4bc7..b2ae4862ade99 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -153,12 +153,12 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should support hideline-range and hideline-next-line markers`, () => { fs.readFileSync.mockReturnValue( ` - /* hideline-range{2-3} */ + /* hide-range{2-3} */ html { height: 100%; width: 100%; padding: 50px; - /* hideline-next-line */ + /* hide-next-line */ background: red; } ` @@ -254,17 +254,17 @@ describe(`gatsby-remark-embed-snippet`, () => {

    - + hidden hidden

      - +
    • hidden
    • hidden
    • not hidden
    - + hidden @@ -442,7 +442,7 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should support hideline-range and hideline-next-line markers`, () => { fs.readFileSync.mockReturnValue( ` - // hideline-range{1-2} + // hide-range{1-2} import React from 'react' import { render } from "react-dom" @@ -453,7 +453,7 @@ describe(`gatsby-remark-embed-snippet`, () => {
  • Not hidden
  • Not hidden
  • Not hidden
  • - // hideline-range{1-3} + // hide-range{1-3}
  • Hidden
  • Hidden
  • Hidden
  • @@ -463,7 +463,7 @@ describe(`gatsby-remark-embed-snippet`, () => { ); - // hideline-next-line + // hide-next-line console.log('Hidden') ` .replace(/^ +/gm, ``) @@ -484,7 +484,7 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should support hideline-range and highlight markers`, () => { fs.readFileSync.mockReturnValue( ` - // hideline-range{1-2,9-11,16} + // hide-range{2-3,10-12,18} // highlight-range{6-8} import React from 'react' import { render } from "react-dom" @@ -522,7 +522,7 @@ describe(`gatsby-remark-embed-snippet`, () => { it(`should throw error when hidden and highlighted lines overlap`, () => { fs.readFileSync.mockReturnValue( ` - // hideline-range{1-2,6} + // hide-range{2-3,7} // highlight-range{5-7,9} import React from 'react' import { render } from "react-dom" @@ -543,7 +543,7 @@ describe(`gatsby-remark-embed-snippet`, () => { const markdownAST = remark.parse(`\`embed:hello-world.js\``) expect(() => plugin({ markdownAST }, { directory: `examples` })).toThrow( - `Line 6 has been marked as both hidden an highlighted for file: examples/hello-world.js.` + `Line 8 has been marked as both hidden and highlighted.\n - Line 1: hide ("hide-range{2-3,7}")\n - Line 2: highlight ("highlight-range{5-7,9}")\nFile: hello-world.js` ) }) }) diff --git a/packages/gatsby-remark-embed-snippet/src/index.js b/packages/gatsby-remark-embed-snippet/src/index.js index 51e1419493b6b..47a5dd6e34bfe 100644 --- a/packages/gatsby-remark-embed-snippet/src/index.js +++ b/packages/gatsby-remark-embed-snippet/src/index.js @@ -70,13 +70,18 @@ module.exports = ( .join(` `) // Replace the node with the markup we need to make 100% width highlighted code lines work - node.type = `html` - node.value = `
    + try { + node.value = `
    ${highlightCode(
    -        language,
    -        code
    -      )}
    + language, + code + ).trim()}
    ` + node.type = `html` + } catch (e) { + // rethrow error pointing to a file + throw Error(`${e.message}\nFile: ${file}`) + } } }) diff --git a/packages/gatsby-remark-prismjs/.gitignore b/packages/gatsby-remark-prismjs/.gitignore index 343d521e61ad6..dcaffc008a64d 100644 --- a/packages/gatsby-remark-prismjs/.gitignore +++ b/packages/gatsby-remark-prismjs/.gitignore @@ -1 +1 @@ -/*.js \ No newline at end of file +/*.js diff --git a/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/highlight-line-range.js.snap b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/directives.js.snap similarity index 100% rename from packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/highlight-line-range.js.snap rename to packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/directives.js.snap diff --git a/packages/gatsby-remark-prismjs/src/__tests__/highlight-line-range.js b/packages/gatsby-remark-prismjs/src/__tests__/directives.js similarity index 98% rename from packages/gatsby-remark-prismjs/src/__tests__/highlight-line-range.js rename to packages/gatsby-remark-prismjs/src/__tests__/directives.js index 659c50e2e0443..88cf1f1dc3f2f 100644 --- a/packages/gatsby-remark-prismjs/src/__tests__/highlight-line-range.js +++ b/packages/gatsby-remark-prismjs/src/__tests__/directives.js @@ -1,7 +1,7 @@ -const highlightLineRange = require(`../highlight-line-range`) +const highlightLineRange = require(`../directives`) const fixtures = require(`./fixtures`) const output = highlighted => highlighted.map(({ code }) => code).join(`\n`) -const getHighlighted = lines => lines.filter(line => line.highlighted) +const getHighlighted = lines => lines.filter(line => line.highlight) describe(`highlighting a line range`, () => { describe(`highlight-line`, () => { it(`strips directive`, () => { diff --git a/packages/gatsby-remark-prismjs/src/highlight-line-range.js b/packages/gatsby-remark-prismjs/src/directives.js similarity index 50% rename from packages/gatsby-remark-prismjs/src/highlight-line-range.js rename to packages/gatsby-remark-prismjs/src/directives.js index 2c04883837a82..cc98b26e652db 100644 --- a/packages/gatsby-remark-prismjs/src/highlight-line-range.js +++ b/packages/gatsby-remark-prismjs/src/directives.js @@ -22,9 +22,17 @@ const COMMENT_START = new RegExp( `(#|\\/\\/|\\{\\/\\*|\\/\\*+|${HIGHLIGHTED_HTML_COMMENT_START})` ) +const createDirectiveRegExp = featureSelector => + new RegExp(`${featureSelector}-(next-line|line|start|end|range)({([^}]+)})?`) + const COMMENT_END = new RegExp(`(-->|\\*\\/\\}|\\*\\/)?`) -const DIRECTIVE = /highlight-(next-line|line|start|end|range)({([^}]+)})?/ -const END_DIRECTIVE = /highlight-end/ +const DIRECTIVE = createDirectiveRegExp(`(highlight|hide)`) +const HIGHLIGHT_DIRECTIVE = createDirectiveRegExp(`highlight`) + +const END_DIRECTIVE = { + highlight: /highlight-end/, + hide: /hide-end/, +} const PLAIN_TEXT_WITH_LF_TEST = /[^<]*\n[^<]*<\/span>/g @@ -46,98 +54,63 @@ const stripComment = line => `` ) -const wrap = line => +const highlightWrap = line => [``, line, ``].join(``) +// const wrapAndStripComment = line => wrap(stripComment(line)) -const wrapAndStripComment = line => wrap(stripComment(line)) - -const getHighlights = (line, code, index) => { - const [, directive, directiveRange] = line.match(DIRECTIVE) +const parseLine = (line, code, index, actions) => { + const [, feature, directive, directiveRange] = line.match(DIRECTIVE) + const flagSource = { + feature, + index, + directive: `${feature}-${directive}${directiveRange}`, + } switch (directive) { case `next-line`: - return [ - { - code: wrap(code[index + 1]), - highlighted: true, - }, - index + 1, - ] + actions.flag(feature, index + 1, flagSource) + actions.hide(index) + break case `start`: { - // find the next `highlight-end` directive, starting from next line + // find the next `${feature}-end` directive, starting from next line const endIndex = code.findIndex( - (line, idx) => idx > index && END_DIRECTIVE.test(line) + (line, idx) => idx > index && END_DIRECTIVE[feature].test(line) ) + const end = endIndex === -1 ? code.length : endIndex - const highlighted = code.slice(index + 1, end).map(line => { - return { - code: wrap(line), - highlighted: true, - } - }) - return [highlighted, end] + + actions.hide(index) + actions.hide(end) + + for (let i = index + 1; i < end; i++) { + actions.flag(feature, i, flagSource) + } + break } case `line`: - return [ - { - code: wrapAndStripComment(line), - highlighted: true, - }, - index, - ] + actions.flag(feature, index, flagSource) + actions.stripComment(index) + break case `range`: - // if range is not provided we ignore the directive - if (!directiveRange) { - console.warn(`Invalid match specified: "${line.trim()}"`) - return [ - { - code: code[index + 1], - highlighted: false, - }, - index + 1, - ] - } else { + actions.hide(index) + + if (directiveRange) { const strippedDirectiveRange = directiveRange.slice(1, -1) const range = rangeParser.parse(strippedDirectiveRange) if (range.length > 0) { - // if current line is 10 and range is {1-5, 7}, lastLineIndexInRange === 17 - let lastLineIndexInRange = index + 1 + range[range.length - 1] - // if range goes farther than code length, make lastLineIndexInRange equal to code length - if (lastLineIndexInRange > code.length) { - lastLineIndexInRange = code.length - } - const highlighted = code - .slice(index + 1, lastLineIndexInRange) - .map((line, idx) => { - return { - code: range.includes(idx + 1) ? wrap(line) : line, - highlighted: range.includes(idx + 1), - } - }) - return [highlighted, lastLineIndexInRange - 1] + range.forEach(relativeIndex => { + actions.flag(feature, index + relativeIndex, flagSource) + }) + break } - // if range is incorrect we ignore the directive - console.warn(`Invalid match specified: "${line.trim()}"`) - return [ - { - code: code[index + 1], - highlighted: false, - }, - index + 1, - ] } - default: - return [ - { - code: wrap(line), - highlighted: true, - }, - index, - ] + + console.warn(`Invalid match specified: "${line.trim()}"`) + break } } module.exports = function highlightLineRange(code, highlights = []) { - if (highlights.length > 0 || DIRECTIVE.test(code)) { + if (highlights.length > 0 || HIGHLIGHT_DIRECTIVE.test(code)) { // HACK split plain-text spans with line separators inside into multiple plain-text spans // separatered by line separator - this fixes line highlighting behaviour for jsx code = code.replace(PLAIN_TEXT_WITH_LF_TEST, match => @@ -145,36 +118,67 @@ module.exports = function highlightLineRange(code, highlights = []) { ) } - let highlighted = [] const split = code.split(`\n`) + const lines = split.map(code => { + return { code, highlight: false, hide: false, flagSources: [] } + }) + + const actions = { + flag: (feature, line, flagSource) => { + if (line >= 0 && line < lines.length) { + const lineMeta = lines[line] + lineMeta[feature] = true + lineMeta.flagSources.push(flagSource) + } + }, + hide: line => actions.flag(`hide`, line), + highlight: line => actions.flag(`highlight`, line), + stripComment: line => { + lines[line].code = stripComment(lines[line].code) + }, + } + + const transform = lines => + lines + .filter(({ hide, highlight, flagSources }, index) => { + if (hide && highlight) { + const formattedSources = flagSources + .map( + ({ feature, index, directive }) => + ` - Line ${index + 1}: ${feature} ("${directive}")` + ) + .join(`\n`) + throw Error( + `Line ${index + + 1} has been marked as both hidden and highlighted.\n${formattedSources}` + ) + } + + return !hide + }) + .map(line => { + if (line.highlight) { + line.code = highlightWrap(line.code) + } + return line + }) // If a highlight range is passed with the language declaration, e.g. // ``jsx{1, 3-4} // we only use that and do not try to parse highlight directives if (highlights.length > 0) { - return split.map((line, i) => { - if (highlights.includes(i + 1)) { - return { - highlighted: true, - code: wrap(line), - } - } - return { - code: line, - } + highlights.forEach(lineNumber => { + actions.highlight(lineNumber - 1) }) + return transform(lines) } + for (let i = 0; i < split.length; i++) { const line = split[i] if (DIRECTIVE.test(line)) { - const [highlights, index] = getHighlights(line, split, i) - highlighted = highlighted.concat(highlights) - i = index - } else { - highlighted.push({ - code: line, - }) + parseLine(line, split, i, actions) } } - return highlighted + + return transform(lines) } diff --git a/packages/gatsby-remark-prismjs/src/highlight-code.js b/packages/gatsby-remark-prismjs/src/highlight-code.js index d3751cc3a97ae..d8e1bb3f085e9 100644 --- a/packages/gatsby-remark-prismjs/src/highlight-code.js +++ b/packages/gatsby-remark-prismjs/src/highlight-code.js @@ -2,7 +2,7 @@ const Prism = require(`prismjs`) const _ = require(`lodash`) const loadPrismLanguage = require(`./load-prism-language`) -const highlightLineRange = require(`./highlight-line-range`) +const handleDirectives = require(`./directives`) module.exports = (language, code, lineNumbersHighlight = []) => { // (Try to) load languages on demand. @@ -22,7 +22,7 @@ module.exports = (language, code, lineNumbersHighlight = []) => { const grammar = Prism.languages[language] const highlighted = Prism.highlight(code, grammar, language) - const codeSplits = highlightLineRange(highlighted, lineNumbersHighlight) + const codeSplits = handleDirectives(highlighted, lineNumbersHighlight) let finalCode = `` @@ -30,7 +30,7 @@ module.exports = (language, code, lineNumbersHighlight = []) => { // Don't add back the new line character after highlighted lines // as they need to be display: block and full-width. codeSplits.forEach((split, idx) => { - split.highlighted + split.highlight ? (finalCode += split.code) : (finalCode += `${split.code}${idx == lastIdx ? `` : `\n`}`) }) From 53c4fae0d0370baed53edcc69e4410e0ce711787 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 12 Dec 2018 23:13:40 +0100 Subject: [PATCH 17/27] wip --- .../gatsby-remark-embed-snippet/README.md | 31 ++--- packages/gatsby-remark-prismjs/README.md | 114 ++++++++++-------- 2 files changed, 80 insertions(+), 65 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/README.md b/packages/gatsby-remark-embed-snippet/README.md index 574582ab5981c..16375b4095bee 100644 --- a/packages/gatsby-remark-embed-snippet/README.md +++ b/packages/gatsby-remark-embed-snippet/README.md @@ -57,7 +57,7 @@ range of lines to highlight, relative to a `highlight-range` comment. #### JavaScript example -```js +``` import React from "react" import ReactDOM from "react-dom" @@ -74,7 +74,7 @@ ReactDOM.render( #### CSS example -```css +``` html { /* highlight-range{1-2} */ height: 100%; @@ -88,7 +88,7 @@ html { #### HTML example -```html +```

    highlight me

    @@ -102,7 +102,7 @@ html { #### YAML example -```yaml +``` foo: "highlighted" # highlight-line bar: "not highlighted" # highlight-range{1-2} @@ -117,42 +117,43 @@ It's also possible to specify a range of lines to be hidden. #### JavaScript example ```js -// hideline-range{1-2} -import React from "react"; -import ReactDOM from "react-dom"; +// hide-range{1-2} +import React from "react" +import ReactDOM from "react-dom" function App() { return (
    -
      +
      • Not hidden
      • Not hidden
      • - // hideline-range{1-2} + {/* hide-range{1-2} */}
      • Hidden
      • Hidden
      • - // hideline-next-line + {/* hide-next-line */}
      • Hidden
    - ); + ) } // hideline-range{1-2} -const rootElement = document.getElementById("root"); -ReactDOM.render(, rootElement); +const rootElement = document.getElementById("root") +ReactDOM.render(, rootElement) ``` Will produce something like this: + ```js function App() { return (
    -
      +
      • Not hidden
      • Not hidden
    - ); + ) } ``` diff --git a/packages/gatsby-remark-prismjs/README.md b/packages/gatsby-remark-prismjs/README.md index 5f528c8e036cb..4a08424021c9c 100644 --- a/packages/gatsby-remark-prismjs/README.md +++ b/packages/gatsby-remark-prismjs/README.md @@ -193,6 +193,8 @@ This is some beautiful code: ] ``` +### Line numbering + To see the line numbers alongside your code, you can use the `numberLines` option: ```javascript{numberLines: true} @@ -226,6 +228,8 @@ will start at index 5): ] ``` +### Line highlighting + 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. @@ -238,66 +242,74 @@ code: - `highlight-start` highlights the lines until the matching `hightlight-end`; - `highlight-range{1, 4-6}` will highlight the next line, and the fourth, fifth and sixth lines. - ```jsx - class FlavorForm extends React.Component { // highlight-line - constructor(props) { - super(props); - this.state = {value: 'coconut'}; +```` +```jsx +class FlavorForm extends React.Component { // highlight-line + constructor(props) { + super(props); + this.state = {value: 'coconut'}; - this.handleChange = this.handleChange.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - } + this.handleChange = this.handleChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } - handleChange(event) { - // highlight-next-line - this.setState({value: event.target.value}); - } + handleChange(event) { + // highlight-next-line + this.setState({value: event.target.value}); + } - // highlight-start - handleSubmit(event) { - alert('Your favorite flavor is: ' + this.state.value); - event.preventDefault(); - } - // highlight-end - - render() { - return ( - { /* highlight-range{1,4-9,12} */ } -
    - - -
    - ); - } + // highlight-start + handleSubmit(event) { + alert('Your favorite flavor is: ' + this.state.value); + event.preventDefault(); } - ``` + // highlight-end + + render() { + return ( + { /* highlight-range{1,4-9,12} */ } +
    + + +
    + ); + } +} +``` +```` You can also specify the highlighted lines outside of the code block. In the following code snippet, lines 1 and 4 through 6 will get the line highlighting. The line range parsing is done with . - ```javascript{1,4-6} - // In your gatsby-config.js - plugins: [ - { - resolve: `gatsby-transformer-remark`, - options: { - plugins: [ - `gatsby-remark-prismjs`, - ] - } - } - ] - ``` +```` +```javascript{1,4-6} +// In your gatsby-config.js +plugins: [ + { + resolve: `gatsby-transformer-remark`, + options: { + plugins: [ + `gatsby-remark-prismjs`, + ] + } + } +] +``` +```` + +### Line hiding + +### Inline code blocks In addition to fenced code blocks, inline code blocks will be passed through PrismJS as well. @@ -311,6 +323,8 @@ Here's an example of how to use this if the `inlineCodeMarker` was set to `±`: This will be rendered in a `` with just the (syntax highlighted) text of `.some-class { background-color: red }` +### Disabling syntax highlighting + If you need to prevent any escaping or highlighting, you can use the `none` language; the inner contents will not be changed at all. From 734122667ed3cd0a226cf3d28b2bf0fc96649e28 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Tue, 18 Dec 2018 16:09:39 +0000 Subject: [PATCH 18/27] Add language tags to code fences --- packages/gatsby-remark-embed-snippet/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/README.md b/packages/gatsby-remark-embed-snippet/README.md index 16375b4095bee..5154bccfb6853 100644 --- a/packages/gatsby-remark-embed-snippet/README.md +++ b/packages/gatsby-remark-embed-snippet/README.md @@ -57,7 +57,7 @@ range of lines to highlight, relative to a `highlight-range` comment. #### JavaScript example -``` +```js import React from "react" import ReactDOM from "react-dom" @@ -74,7 +74,7 @@ ReactDOM.render( #### CSS example -``` +```css html { /* highlight-range{1-2} */ height: 100%; @@ -88,7 +88,7 @@ html { #### HTML example -``` +```html

    highlight me

    @@ -102,7 +102,7 @@ html { #### YAML example -``` +```yaml foo: "highlighted" # highlight-line bar: "not highlighted" # highlight-range{1-2} @@ -165,7 +165,7 @@ function App() { **Important**: This module must appear before `gatsby-remark-prismjs` in your plugins array, or the markup will have already been transformed into a code block and this plugin will fail to detect it and inline the file. -```javascript +```js // In your gatsby-config.js module.exports = { plugins: [ From 98cef728c6a91269ef1d0ef6ff0f718f2ce4d2d7 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Tue, 18 Dec 2018 16:19:49 +0000 Subject: [PATCH 19/27] Fix example syntax --- packages/gatsby-remark-embed-snippet/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-remark-embed-snippet/README.md b/packages/gatsby-remark-embed-snippet/README.md index 5154bccfb6853..17276d29aa921 100644 --- a/packages/gatsby-remark-embed-snippet/README.md +++ b/packages/gatsby-remark-embed-snippet/README.md @@ -137,7 +137,7 @@ function App() { ) } -// hideline-range{1-2} +// hide-range{1-2} const rootElement = document.getElementById("root") ReactDOM.render(, rootElement) ``` From d9e38d74b41d134d0718eae7aaba50e7c995c3dc Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Tue, 18 Dec 2018 22:58:09 +0000 Subject: [PATCH 20/27] Add demo page to the using-remark example site --- examples/using-remark/gatsby-config.js | 7 ++ examples/using-remark/package.json | 1 + .../code-examples/hide-and-highlight-lines.js | 16 +++ .../src/code-examples/hide-lines.js | 14 +++ .../src/code-examples/highlight-lines.js | 13 ++ .../using-remark/src/code-examples/plain.js | 12 ++ .../2017-04-05---embed-snippets/index.md | 113 ++++++++++++++++++ 7 files changed, 176 insertions(+) create mode 100644 examples/using-remark/src/code-examples/hide-and-highlight-lines.js create mode 100644 examples/using-remark/src/code-examples/hide-lines.js create mode 100644 examples/using-remark/src/code-examples/highlight-lines.js create mode 100644 examples/using-remark/src/code-examples/plain.js create mode 100644 examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md diff --git a/examples/using-remark/gatsby-config.js b/examples/using-remark/gatsby-config.js index 2782c68b8a677..3d39c5f5ed7b9 100644 --- a/examples/using-remark/gatsby-config.js +++ b/examples/using-remark/gatsby-config.js @@ -52,6 +52,13 @@ module.exports = { dashes: `oldschool`, }, }, + { + resolve: `gatsby-remark-embed-snippet`, + options: { + // Example code links are relative to this dir. + directory: `${__dirname}/src/code-examples/`, + }, + }, `gatsby-remark-prismjs`, `gatsby-remark-autolink-headers`, `gatsby-remark-katex`, diff --git a/examples/using-remark/package.json b/examples/using-remark/package.json index 848a472b0eda6..a671e7a115e2b 100644 --- a/examples/using-remark/package.json +++ b/examples/using-remark/package.json @@ -16,6 +16,7 @@ "gatsby-plugin-typography": "^2.2.0", "gatsby-remark-autolink-headers": "^2.0.5", "gatsby-remark-copy-linked-files": "^2.0.5", + "gatsby-remark-embed-snippet": "^3.1.2", "gatsby-remark-images": "^2.0.1", "gatsby-remark-katex": "^2.0.5", "gatsby-remark-prismjs": "^3.0.0", diff --git a/examples/using-remark/src/code-examples/hide-and-highlight-lines.js b/examples/using-remark/src/code-examples/hide-and-highlight-lines.js new file mode 100644 index 0000000000000..3911947b1ebf0 --- /dev/null +++ b/examples/using-remark/src/code-examples/hide-and-highlight-lines.js @@ -0,0 +1,16 @@ +/* hide-range{1-3} */ +import React from "react" +import ReactDOM from "react-dom" + +// highlight-next-line +const name = `Brian` + +// highlight-range{4-5} +// hide-next-line +ReactDOM.render( +
    +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) // hide-line +) // hide-line diff --git a/examples/using-remark/src/code-examples/hide-lines.js b/examples/using-remark/src/code-examples/hide-lines.js new file mode 100644 index 0000000000000..2c428b899d942 --- /dev/null +++ b/examples/using-remark/src/code-examples/hide-lines.js @@ -0,0 +1,14 @@ +/* hide-range{1-3} */ +import React from "react" +import ReactDOM from "react-dom" + +const name = `Brian` + +// hide-next-line +ReactDOM.render( +
    +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) // hide-line +) // hide-line diff --git a/examples/using-remark/src/code-examples/highlight-lines.js b/examples/using-remark/src/code-examples/highlight-lines.js new file mode 100644 index 0000000000000..8b458eb5d4cc0 --- /dev/null +++ b/examples/using-remark/src/code-examples/highlight-lines.js @@ -0,0 +1,13 @@ +import React from "react" +import ReactDOM from "react-dom" + +const name = `Brian` // highlight-line + +ReactDOM.render( +
    + {/* highlight-range{1-2} */} +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) +) diff --git a/examples/using-remark/src/code-examples/plain.js b/examples/using-remark/src/code-examples/plain.js new file mode 100644 index 0000000000000..b0c7e7a9d3e02 --- /dev/null +++ b/examples/using-remark/src/code-examples/plain.js @@ -0,0 +1,12 @@ +import React from "react" +import ReactDOM from "react-dom" + +const name = `Brian` + +ReactDOM.render( +
    +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) +) diff --git a/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md b/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md new file mode 100644 index 0000000000000..3c5cce4b1cfdb --- /dev/null +++ b/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md @@ -0,0 +1,113 @@ +--- +title: "Embed file contents within PrismJS blocks" +date: "2017-04-05" +draft: false +author: Daisy Buchanan +tags: + - remark + - Code Highlighting + - embed snippets +--- + +You can embed the contents of existing files within your Markdown using the [`gatsby-remark-embed-snippet`][1] with [`gatsby-remark-prismjs`][2]. + +Let's start by displaying file contents as a highlighted code block, then see how to control line highlighting and visibility from within the source file. + +## Embedding files + +After installing the required plugins you can embed a file within your Markdown by using `embed` snippets. To embed the file `src/code-examples/plain.js` you could write the following: + +
    embed:plain.js
    + +This will look like: + +`embed:plain.js` + +## Highlight lines + +You can highlight specific lines by adding special comments to the source file. Let's see how this works in `src/code-examples/highlight-lines.js`. + +Take a look at the `highlight-line` comment on line 4 and the `highlight-range` comment on line 8: + +```{numberLines: true} +import React from "react" +import ReactDOM from "react-dom" + +const name = `Brian` // highlight-line + +ReactDOM.render( +
    + {/* highlight-range{1-2} */} +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) +) +``` + +When the file is embedded with `embed:name-of-your-file.js`, it will display like this: + +`embed:highlight-lines.js` + +## Hide lines + +You can use similar comments to hide specific lines. Here's another example, this time using `src/code-examples/hide-lines.js`. Check out the `hide-line` comments on lines 1, 7, 13 and 14: + +```{numberLines: true} +/* hide-range{1-3} */ +import React from "react" +import ReactDOM from "react-dom" + +const name = `Brian` + +// hide-next-line +ReactDOM.render( +
    +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) // hide-line +) // hide-line +``` + +Which will display like this: + +`embed:hide-lines.js` + +## All together now + +You can mix line highlighting and hiding in the same file. This is from `src/code-examples/hide-and-highlight-lines.js` + +``` +/* hide-range{1-3} */ +import React from "react" +import ReactDOM from "react-dom" + +// highlight-next-line +const name = `Brian` + +// highlight-range{4-5} +// hide-next-line +ReactDOM.render( +
    +

    Hello, ${name}!

    +

    Welcome to this example

    +
    , + document.getElementById(`root`) // hide-line +) // hide-line +``` + +It'll look like this: + +`embed:hide-and-highlight-lines.js` + +## Related info + +You've learnt how to embed the contents of existing files into your Markdown using [`gatsby-remark-embed-snippet`][1] with [`gatsby-remark-prismjs`][2]. Hurray! + +If you'd prefer to write your code blocks directly within your Markdown, take a look at the example [Code and Syntax Highlighting with PrismJS][4]. + +[1]: https://www.gatsbyjs.org/packages/gatsby-remark-embed-snippet/ +[2]: https://www.gatsbyjs.org/packages/gatsby-remark-prismjs/ +[3]: http://prismjs.com/ +[4]: /code-and-syntax-highlighting/ From 353f078d61ff2d4dec2774ee2c42cdecdac26c49 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Tue, 18 Dec 2018 22:58:25 +0000 Subject: [PATCH 21/27] Fix missing layout --- examples/using-remark/src/pages/excerpt-example.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/using-remark/src/pages/excerpt-example.js b/examples/using-remark/src/pages/excerpt-example.js index aa9b6ac11813a..a0cab5a9007ba 100644 --- a/examples/using-remark/src/pages/excerpt-example.js +++ b/examples/using-remark/src/pages/excerpt-example.js @@ -1,5 +1,6 @@ import React from "react" import { Link, graphql } from "gatsby" +import Layout from "../layouts" import styles from "../styles" import presets from "../utils/presets" import { rhythm, scale } from "../utils/typography" @@ -9,7 +10,7 @@ class Index extends React.Component { const posts = this.props.data.allMarkdownRemark.edges return ( -
    +

    -
    + ) } } From 9d6e3aa8dd32140e209e2332eec5962e177e9dcd Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Tue, 18 Dec 2018 22:59:52 +0000 Subject: [PATCH 22/27] Reverse order to start with hello world, then on to specific subjects --- examples/using-remark/src/pages/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/using-remark/src/pages/index.js b/examples/using-remark/src/pages/index.js index 46ec6418571ce..a858b18e3fa60 100644 --- a/examples/using-remark/src/pages/index.js +++ b/examples/using-remark/src/pages/index.js @@ -78,7 +78,7 @@ export const pageQuery = graphql` query { allMarkdownRemark( limit: 2000 - sort: { fields: [frontmatter___date], order: DESC } + sort: { fields: [frontmatter___date], order: ASC } filter: { frontmatter: { draft: { ne: true }, example: { ne: true } } } ) { edges { From f727d862eb8461f5fa5ad4a3d790d3482de31d64 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Tue, 18 Dec 2018 23:25:50 +0000 Subject: [PATCH 23/27] Ignore errors for missing files --- .../src/__tests__/__snapshots__/index.js.snap | 55 +++++++++++++++++++ .../src/__tests__/index.js | 8 +-- .../gatsby-remark-embed-snippet/src/index.js | 4 +- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index 424a10fd78b1d..bc6d3037b737d 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -1494,6 +1494,61 @@ Object { } `; +exports[`gatsby-remark-embed-snippet should not modify embed inlinCode nodes if the target file does not exist 1`] = ` +Object { + "children": Array [ + Object { + "children": Array [ + Object { + "position": Position { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "inlineCode", + "value": "embed:hello-world.js", + }, + ], + "position": Position { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "indent": Array [], + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "paragraph", + }, + ], + "position": Object { + "end": Object { + "column": 23, + "line": 1, + "offset": 22, + }, + "start": Object { + "column": 1, + "line": 1, + "offset": 0, + }, + }, + "type": "root", +} +`; + exports[`gatsby-remark-embed-snippet should not modify non-embed inlineCode nodes 1`] = ` Object { "children": Array [ diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index b2ae4862ade99..82c4e68439749 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -38,14 +38,12 @@ describe(`gatsby-remark-embed-snippet`, () => { ) }) - it(`should error if an invalid file path is specified`, () => { + it(`should not modify embed inlinCode nodes if the target file does not exist`, () => { fs.existsSync.mockImplementation(path => path !== `examples/hello-world.js`) const markdownAST = remark.parse(`\`embed:hello-world.js\``) - - expect(() => plugin({ markdownAST }, { directory: `examples` })).toThrow( - `Invalid snippet specified; no such file "examples/hello-world.js"` - ) + const transformed = plugin({ markdownAST }, { directory: `examples` }) + expect(transformed).toMatchSnapshot() }) it(`should not modify non-embed inlineCode nodes`, () => { diff --git a/packages/gatsby-remark-embed-snippet/src/index.js b/packages/gatsby-remark-embed-snippet/src/index.js index 47a5dd6e34bfe..8b389b9e9b50f 100644 --- a/packages/gatsby-remark-embed-snippet/src/index.js +++ b/packages/gatsby-remark-embed-snippet/src/index.js @@ -45,8 +45,10 @@ module.exports = ( const file = value.substr(6) const path = normalizePath(`${directory}${file}`) + // no file? render the `embed:` as a normal string if (!fs.existsSync(path)) { - throw Error(`Invalid snippet specified; no such file "${path}"`) + // TODO: log a message during `gatsby develop`? + return } const code = fs.readFileSync(path, `utf8`).trim() From c676e15f304dcb4c48f306da4177a7696206d4be Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 19 Dec 2018 14:10:06 +0000 Subject: [PATCH 24/27] Port tests from remark-embed-snippet to remark-prismjs --- .../src/__tests__/__snapshots__/index.js.snap | 1163 +---------------- .../src/__tests__/index.js | 566 +------- .../__snapshots__/directives.js.snap | 325 ++++- .../src/__tests__/directives.js | 46 +- .../fixtures/hide-and-highlight-overlap.js | 13 + .../__tests__/fixtures/hide-and-highlight.js | 19 + .../src/__tests__/fixtures/hide-line-css.css | 8 + .../__tests__/fixtures/hide-line-html.html | 17 + .../src/__tests__/fixtures/hide-line.js | 23 + 9 files changed, 472 insertions(+), 1708 deletions(-) create mode 100644 packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight-overlap.js create mode 100644 packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight.js create mode 100644 packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-css.css create mode 100644 packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-html.html create mode 100644 packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line.js diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index bc6d3037b737d..3755e0a86b70d 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`gatsby-remark-embed-snippet CSS files should extract the correct Prism language 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the correct Prism language for CSS files 1`] = ` Object { "children": Array [ Object { @@ -57,1037 +57,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet CSS files should support hideline-range and hideline-next-line markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    html {
    -padding: 50px;
    -}
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet CSS files should support highlight-line and highlight-next-line markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    html {
    -height: 100%;}
    -
    -* {
    -box-sizing: border-box;}
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet CSS files should support highlight-range markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    html {
    -height: 100%;width: 100%;}
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 24, - "line": 1, - "offset": 23, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet HTML files should extract the correct Prism language 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    <html></html>
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet HTML files should support hideline-range and hideline-next-line markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    <html>
    -<body>
    -<p>
    -</p>
    -<ul>
    -<li>not hidden</li>
    -</ul>
    -</body>
    -</html>
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet HTML files should support highlight-line and highlight-next-line markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    <html>
    -<body>
    -<h1>highlighted</h1><p>
    -highlighted</p>
    -</body>
    -</html>
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet HTML files should support highlight-range markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    <html>
    -<body>
    -<p>
    -highlighted</p>
    -</body>
    -</html>
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should extract the correct Prism language 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    const foo = \\"bar\\";
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support JSX line highlight comments 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    <div>
    -<button>Add Item</button> 
    -<ReactCSSTransitionGroup
    -transitionName=\\"example\\"
    -transitionEnterTimeout={500}
    -transitionLeaveTimeout={300}>
    -{items}</ReactCSSTransitionGroup>
    -</div>
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support hideline-range and hideline-next-line markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    ReactDOM.render(
    -<div>
    -<ul>
    -<li>Not hidden</li>
    -<li>Not hidden</li>
    -<li>Not hidden</li>
    -</ul>
    -</div>,
    -document.getElementById('root')
    -);
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support hideline-range and highlight markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    ReactDOM.render(
    -<div>
    -<ul>
    -<li>Not hidden and highlighted</li><li>Not hidden and highlighted</li><li>Not hidden and highlighted</li></ul>
    -</div>,
    -document.getElementById('root'));
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support highlight-line and highlight-next-line markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    import React from 'react';
    -import ReactDOM from 'react-dom';
    -
    -ReactDOM.render(<h1>Hello, world!</h1>,
    -document.getElementById('root')
    -);
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support highlight-range markers 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    ReactDOM.render(
    -<h1>Hello, world!</h1>,document.getElementById('root'));
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support highlighting a range via JSX comments 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    <ul>
    -<li>Not highlighted</li>
    -<li>Highlighted</li><li>Highlighted</li><li>Highlighted</li><li>Not highlighted</li>
    -</div>
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet JavaScript files should support multiple highlight directives within a single file 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    let notHighlighted;
    -let highlighted;
    -notHighlighted = 1;
    -
    -highlighted = 2;
    -notHighlighted = 3;
    -highlighted = 4;
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet Markdown files should extract the correct Prism language 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    # Hi
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet YAML files should extract the correct Prism language 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    name: Brian Vaughn
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 25, - "line": 1, - "offset": 24, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - -exports[`gatsby-remark-embed-snippet YAML files should support highlight-line and highlight-next-line markers 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the correct Prism language for HTML files 1`] = ` Object { "children": Array [ Object { @@ -1108,8 +78,7 @@ Object { }, "type": "html", "value": "
    -
    foo: \\"highlighted\\"bar: \\"not highlighted\\"
    -baz: \\"highlighted\\"qux: \\"not highlighted\\"
    +
    <html></html>
    ", }, ], @@ -1145,7 +114,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet YAML files should support highlight-range markers 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the correct Prism language for JavaScript files 1`] = ` Object { "children": Array [ Object { @@ -1153,9 +122,9 @@ Object { Object { "position": Position { "end": Object { - "column": 25, + "column": 23, "line": 1, - "offset": 24, + "offset": 22, }, "indent": Array [], "start": Object { @@ -1166,16 +135,15 @@ Object { }, "type": "html", "value": "
    -
    foo: \\"highlighted\\"bar: \\"not highlighted\\"
    -baz: \\"highlighted\\"
    +
    const foo = \\"bar\\";
    ", }, ], "position": Position { "end": Object { - "column": 25, + "column": 23, "line": 1, - "offset": 24, + "offset": 22, }, "indent": Array [], "start": Object { @@ -1189,9 +157,9 @@ Object { ], "position": Object { "end": Object { - "column": 25, + "column": 23, "line": 1, - "offset": 24, + "offset": 22, }, "start": Object { "column": 1, @@ -1203,7 +171,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet shell scripts should extract the correct Prism language 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the correct Prism language for Markdown files 1`] = ` Object { "children": Array [ Object { @@ -1224,7 +192,7 @@ Object { }, "type": "html", "value": "
    -
    pwd
    +
    # Hi
    ", }, ], @@ -1260,7 +228,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet shell scripts should support highlight-line and highlight-next-line markers 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the correct Prism language for YAML files 1`] = ` Object { "children": Array [ Object { @@ -1268,9 +236,9 @@ Object { Object { "position": Position { "end": Object { - "column": 23, + "column": 25, "line": 1, - "offset": 22, + "offset": 24, }, "indent": Array [], "start": Object { @@ -1281,20 +249,15 @@ Object { }, "type": "html", "value": "
    -
    # Yarn
    -yarn init
    -yarn add react react-dom
    -# NPM
    -npm init
    -npm install --save react react-dom
    +
    name: Brian Vaughn
    ", }, ], "position": Position { "end": Object { - "column": 23, + "column": 25, "line": 1, - "offset": 22, + "offset": 24, }, "indent": Array [], "start": Object { @@ -1308,9 +271,9 @@ yarn init ], "position": Object { "end": Object { - "column": 23, + "column": 25, "line": 1, - "offset": 22, + "offset": 24, }, "start": Object { "column": 1, @@ -1322,7 +285,7 @@ yarn init } `; -exports[`gatsby-remark-embed-snippet shell scripts should support highlight-range markers 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the correct Prism language for shell scripts 1`] = ` Object { "children": Array [ Object { @@ -1343,8 +306,7 @@ Object { }, "type": "html", "value": "
    -
    echo \\"not highlighted\\"
    -echo \\"highlighted\\"echo \\"highlighted\\"echo \\"not highlighted\\"
    +
    pwd
    ", }, ], @@ -1380,7 +342,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet should convert embed inlineCode nodes to Prism code blocks 1`] = ` +exports[`gatsby-remark-embed-snippet Language detection should set the default Prism language for unknown file extensions 1`] = ` Object { "children": Array [ Object { @@ -1388,9 +350,9 @@ Object { Object { "position": Position { "end": Object { - "column": 23, + "column": 20, "line": 1, - "offset": 22, + "offset": 19, }, "indent": Array [], "start": Object { @@ -1401,15 +363,15 @@ Object { }, "type": "html", "value": "
    -
    const foo = \\"bar\\";
    +
    const foo = \\"bar\\";
    ", }, ], "position": Position { "end": Object { - "column": 23, + "column": 20, "line": 1, - "offset": 22, + "offset": 19, }, "indent": Array [], "start": Object { @@ -1423,9 +385,9 @@ Object { ], "position": Object { "end": Object { - "column": 23, + "column": 20, "line": 1, - "offset": 22, + "offset": 19, }, "start": Object { "column": 1, @@ -1437,7 +399,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet should error if an invalid range expression is specified 1`] = ` +exports[`gatsby-remark-embed-snippet should convert embed inlineCode nodes to Prism code blocks 1`] = ` Object { "children": Array [ Object { @@ -1458,7 +420,7 @@ Object { }, "type": "html", "value": "
    -
    console.log(\\"oops!\\");
    +
    const foo = \\"bar\\";
    ", }, ], @@ -1494,7 +456,7 @@ Object { } `; -exports[`gatsby-remark-embed-snippet should not modify embed inlinCode nodes if the target file does not exist 1`] = ` +exports[`gatsby-remark-embed-snippet should not modify embed inlineCode nodes if the target file does not exist 1`] = ` Object { "children": Array [ Object { @@ -1603,60 +565,3 @@ Object { "type": "root", } `; - -exports[`gatsby-remark-embed-snippet unknown file extensions should set the correct default Prism language 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 20, - "line": 1, - "offset": 19, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "html", - "value": "
    -
    const foo = \\"bar\\";
    -
    ", - }, - ], - "position": Position { - "end": Object { - "column": 20, - "line": 1, - "offset": 19, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 20, - "line": 1, - "offset": 19, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index 82c4e68439749..50b83e020e829 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -38,7 +38,7 @@ describe(`gatsby-remark-embed-snippet`, () => { ) }) - it(`should not modify embed inlinCode nodes if the target file does not exist`, () => { + it(`should not modify embed inlineCode nodes if the target file does not exist`, () => { fs.existsSync.mockImplementation(path => path !== `examples/hello-world.js`) const markdownAST = remark.parse(`\`embed:hello-world.js\``) @@ -60,30 +60,8 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should error if an invalid range expression is specified`, () => { - spyOn(console, `warn`) - - fs.readFileSync.mockReturnValue( - ` - // highlight-range 1 - console.log("oops!"); - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin({ markdownAST }, { directory: `examples` }) - - expect(transformed).toMatchSnapshot() - - expect(console.warn).toHaveBeenCalledWith( - `Invalid match specified: "// highlight-range 1"` - ) - }) - - describe(`CSS files`, () => { - it(`should extract the correct Prism language`, () => { + describe(`Language detection`, () => { + it(`should set the correct Prism language for CSS files`, () => { fs.readFileSync.mockReturnValue(`html { height: 100%; }`) const markdownAST = remark.parse(`\`embed:hello-world.css\``) @@ -97,87 +75,7 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should support highlight-line and highlight-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - html { - /* highlight-next-line */ - height: 100%; - } - - * { - box-sizing: border-box; /* highlight-line */ - } - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.css\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support highlight-range markers`, () => { - fs.readFileSync.mockReturnValue( - ` - html { - /* highlight-range{1,2} */ - height: 100%; - width: 100%; - } - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.css\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support hideline-range and hideline-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - /* hide-range{2-3} */ - html { - height: 100%; - width: 100%; - padding: 50px; - /* hide-next-line */ - background: red; - } - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.css\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - }) - - describe(`HTML files`, () => { - it(`should extract the correct Prism language`, () => { + it(`should set the correct Prism language for HTML files`, () => { fs.readFileSync.mockReturnValue(``) const markdownAST = remark.parse(`\`embed:hello-world.html\``) @@ -191,100 +89,7 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should support highlight-line and highlight-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - - -

    highlighted

    -

    - - highlighted -

    - - - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.html\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support highlight-range markers`, () => { - fs.readFileSync.mockReturnValue( - ` - - - -

    - highlighted -

    - - - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.html\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support hideline-range and hideline-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - - -

    - - hidden - hidden -

    -
      - -
    • hidden
    • -
    • hidden
    • -
    • not hidden
    • -
    - - hidden - - - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.html\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - }) - - describe(`JavaScript files`, () => { - it(`should extract the correct Prism language`, () => { + it(`should set the correct Prism language for JavaScript files`, () => { fs.readFileSync.mockReturnValue(`const foo = "bar";`) const markdownAST = remark.parse(`\`embed:hello-world.js\``) @@ -298,256 +103,7 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should support highlight-line and highlight-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - import React from 'react'; - import ReactDOM from 'react-dom'; - - // highlight-next-line - ReactDOM.render( -

    Hello, world!

    , - document.getElementById('root') - ); // highlight-line - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support highlight-range markers`, () => { - fs.readFileSync.mockReturnValue( - ` - // highlight-range{2,3} - ReactDOM.render( -

    Hello, world!

    , - document.getElementById('root') - ); - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support JSX line highlight comments`, () => { - fs.readFileSync.mockReturnValue( - ` -
    - {/* highlight-line */} - - - {/* highlight-next-line */} - {items} - -
    - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support highlighting a range via JSX comments`, () => { - fs.readFileSync.mockReturnValue( - ` -
      - {/* highlight-range{2-4} */} -
    • Not highlighted
    • -
    • Highlighted
    • -
    • Highlighted
    • -
    • Highlighted
    • -
    • Not highlighted
    • -
    - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support multiple highlight directives within a single file`, () => { - fs.readFileSync.mockReturnValue( - ` - let notHighlighted; - // highlight-range{1} - let highlighted; - - notHighlighted = 1; - - // highlight-next-line - highlighted = 2; - - // highlight-range{2} - notHighlighted = 3; - highlighted = 4; - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support hideline-range and hideline-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - // hide-range{1-2} - import React from 'react' - import { render } from "react-dom" - - - ReactDOM.render( -
    -
      -
    • Not hidden
    • -
    • Not hidden
    • -
    • Not hidden
    • - // hide-range{1-3} -
    • Hidden
    • -
    • Hidden
    • -
    • Hidden
    • -
    -
    , - document.getElementById('root') - ); - - - // hide-next-line - console.log('Hidden') - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support hideline-range and highlight markers`, () => { - fs.readFileSync.mockReturnValue( - ` - // hide-range{2-3,10-12,18} - // highlight-range{6-8} - import React from 'react' - import { render } from "react-dom" - ReactDOM.render( -
    -
      -
    • Not hidden and highlighted
    • -
    • Not hidden and highlighted
    • -
    • Not hidden and highlighted
    • -
    • Hidden
    • -
    • Hidden
    • -
    • Hidden
    • -
    -
    , - // highlight-next-line - document.getElementById('root') - ); - console.log('Hidden') - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should throw error when hidden and highlighted lines overlap`, () => { - fs.readFileSync.mockReturnValue( - ` - // hide-range{2-3,7} - // highlight-range{5-7,9} - import React from 'react' - import { render } from "react-dom" - ReactDOM.render( -
    -
      -
    • hidden
    • -
    -
    , - // highlight-next-line - document.getElementById('root') - ); - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.js\``) - - expect(() => plugin({ markdownAST }, { directory: `examples` })).toThrow( - `Line 8 has been marked as both hidden and highlighted.\n - Line 1: hide ("hide-range{2-3,7}")\n - Line 2: highlight ("highlight-range{5-7,9}")\nFile: hello-world.js` - ) - }) - }) - - describe(`Markdown files`, () => { - it(`should extract the correct Prism language`, () => { + it(`should set the correct Prism language for Markdown files`, () => { fs.readFileSync.mockReturnValue(`# Hi`) const markdownAST = remark.parse(`\`embed:hello-world.md\``) @@ -560,10 +116,8 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - }) - describe(`shell scripts`, () => { - it(`should extract the correct Prism language`, () => { + it(`should set the correct Prism language for shell scripts`, () => { fs.readFileSync.mockReturnValue(`pwd`) const markdownAST = remark.parse(`\`embed:hello-world.sh\``) @@ -577,60 +131,7 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should support highlight-line and highlight-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - # Yarn - yarn init - yarn add react react-dom # highlight-line - - # NPM - npm init - # highlight-next-line - npm install --save react react-dom - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.sh\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support highlight-range markers`, () => { - fs.readFileSync.mockReturnValue( - ` - # highlight-range{2-3} - echo "not highlighted" - echo "highlighted" - echo "highlighted" - echo "not highlighted" - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.sh\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - }) - - describe(`YAML files`, () => { - it(`should extract the correct Prism language`, () => { + it(`should set the correct Prism language for YAML files`, () => { fs.readFileSync.mockReturnValue(`name: Brian Vaughn`) const markdownAST = remark.parse(`\`embed:hello-world.yaml\``) @@ -644,56 +145,7 @@ describe(`gatsby-remark-embed-snippet`, () => { expect(transformed).toMatchSnapshot() }) - it(`should support highlight-line and highlight-next-line markers`, () => { - fs.readFileSync.mockReturnValue( - ` - foo: "highlighted" # highlight-line - bar: "not highlighted" - # highlight-next-line - baz: "highlighted" - qux: "not highlighted" - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.yaml\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - - it(`should support highlight-range markers`, () => { - fs.readFileSync.mockReturnValue( - ` - # highlight-range{1,3} - foo: "highlighted" - bar: "not highlighted" - baz: "highlighted" - ` - .replace(/^ +/gm, ``) - .trim() - ) - - const markdownAST = remark.parse(`\`embed:hello-world.yaml\``) - const transformed = plugin( - { markdownAST }, - { - directory: `examples`, - } - ) - - expect(transformed).toMatchSnapshot() - }) - }) - - describe(`unknown file extensions`, () => { - it(`should set the correct default Prism language`, () => { + it(`should set the default Prism language for unknown file extensions`, () => { const markdownAST = remark.parse(`\`embed:hello-world\``) const transformed = plugin( { markdownAST }, diff --git a/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/directives.js.snap b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/directives.js.snap index da5f0b4180ffe..adb6b7280e85c 100644 --- a/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/directives.js.snap +++ b/packages/gatsby-remark-prismjs/src/__tests__/__snapshots__/directives.js.snap @@ -1,18 +1,213 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`highlighting a line range highlight-line highlights line 1`] = `" return \\"hello world\\""`; +exports[`hiding lines should support hide markers in CSS 1`] = ` +Array [ + Object { + "code": "html {", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": " padding: 50px;", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "}", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, +] +`; + +exports[`hiding lines should support hide markers in HTML 1`] = ` +Array [ + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": " ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "

    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "

    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
      ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    • not hidden
    • ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": " ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, +] +`; + +exports[`hiding lines should support hide markers in JS 1`] = ` +Array [ + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "ReactDOM.render(", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
      ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    • Not hidden
    • ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    • Not hidden
    • ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    • Not hidden
    • ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    ,", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": ");", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, +] +`; + +exports[`highlighting lines highlight kitchen sink highlights multiple directives 1`] = ` +"import React, { Component } from \\"react\\" + state = { + count: 0, + } + count: state.count + 1, + render() { + const { count } = this.state + + " +`; -exports[`highlighting a line range highlight-next-line highlights correct line 1`] = `" return \\"hello world\\""`; +exports[`highlighting lines highlight-line highlights line 1`] = `" return \\"hello world\\""`; -exports[`highlighting a line range highlight-range does not highlight and warns if range is invalid 1`] = `""`; +exports[`highlighting lines highlight-next-line highlights correct line 1`] = `" return \\"hello world\\""`; -exports[`highlighting a line range highlight-range highlights correct lines 1`] = ` +exports[`highlighting lines highlight-range does not highlight and warns if range is invalid 1`] = `""`; + +exports[`highlighting lines highlight-range highlights correct lines 1`] = ` " a = 1 + 1 b = 2 + 2 return \\"hello world\\"" `; -exports[`highlighting a line range highlight-range highlights until end of code block if ranges goes farther 1`] = ` +exports[`highlighting lines highlight-range highlights until end of code block if ranges goes farther 1`] = ` " a = 1 + 1 b = 2 + 2 return \\"hello world\\" @@ -20,31 +215,121 @@ exports[`highlighting a line range highlight-range highlights until end of code " `; -exports[`highlighting a line range highlight-start / highlight-end highlights correct lines 1`] = ` +exports[`highlighting lines highlight-start / highlight-end highlights correct lines 1`] = ` " var a = \\"b\\" return a + \\"hello world\\"" `; -exports[`highlighting a line range highlight-start / highlight-end highlights without end directive 1`] = ` +exports[`highlighting lines highlight-start / highlight-end highlights without end directive 1`] = ` "var a = \\"b\\" return a + \\"hello world\\" " `; -exports[`highlighting a line range jsx comment highlights comment line 1`] = `" "`; +exports[`highlighting lines jsx comment highlights comment line 1`] = `" "`; -exports[`highlighting a line range jsx comment highlights comment line after Prism highlighting 1`] = `" <button>sup</button>"`; +exports[`highlighting lines jsx comment highlights comment line after Prism highlighting 1`] = `" <button>sup</button>"`; -exports[`highlighting a line range kitchen sink highlights multiple directives 1`] = ` -"import React, { Component } from \\"react\\" - state = { - count: 0, - } - count: state.count + 1, - render() { - const { count } = this.state - - " +exports[`highlighting lines yaml highlights yaml 1`] = `"- title: catorce"`; + +exports[`mixed highlight and hide lines should support mixed hide and highlight markers 1`] = ` +Array [ + Object { + "code": "ReactDOM.render(", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
      ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    • Not hidden and highlighted
    • ", + "flagSources": Array [ + Object { + "directive": "highlight-range{6-8}", + "feature": "highlight", + "index": 1, + }, + ], + "hide": false, + "highlight": true, + }, + Object { + "code": "
    • Not hidden and highlighted
    • ", + "flagSources": Array [ + Object { + "directive": "highlight-range{6-8}", + "feature": "highlight", + "index": 1, + }, + ], + "hide": false, + "highlight": true, + }, + Object { + "code": "
    • Not hidden and highlighted
    • ", + "flagSources": Array [ + Object { + "directive": "highlight-range{6-8}", + "feature": "highlight", + "index": 1, + }, + ], + "hide": false, + "highlight": true, + }, + Object { + "code": "
    ", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "
    ,", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": " document.getElementById('root')", + "flagSources": Array [ + Object { + "directive": "highlight-next-lineundefined", + "feature": "highlight", + "index": 15, + }, + ], + "hide": false, + "highlight": true, + }, + Object { + "code": ");", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, + Object { + "code": "", + "flagSources": Array [], + "hide": false, + "highlight": false, + }, +] `; -exports[`highlighting a line range yaml highlights yaml 1`] = `"- title: catorce"`; +exports[`mixed highlight and hide lines should support mixed hide and highlight markers 2`] = ` +"
  • Not hidden and highlighted
  • +
  • Not hidden and highlighted
  • +
  • Not hidden and highlighted
  • + document.getElementById('root')" +`; diff --git a/packages/gatsby-remark-prismjs/src/__tests__/directives.js b/packages/gatsby-remark-prismjs/src/__tests__/directives.js index 88cf1f1dc3f2f..bee3d216c94b4 100644 --- a/packages/gatsby-remark-prismjs/src/__tests__/directives.js +++ b/packages/gatsby-remark-prismjs/src/__tests__/directives.js @@ -2,7 +2,28 @@ const highlightLineRange = require(`../directives`) const fixtures = require(`./fixtures`) const output = highlighted => highlighted.map(({ code }) => code).join(`\n`) const getHighlighted = lines => lines.filter(line => line.highlight) -describe(`highlighting a line range`, () => { + +describe(`hiding lines`, () => { + it(`should support hide markers in CSS`, () => { + const processed = highlightLineRange(fixtures.hideLineCss) + expect(processed).toMatchSnapshot() + expect(processed.length).toEqual(4) + }) + + it(`should support hide markers in HTML`, () => { + const processed = highlightLineRange(fixtures.hideLineHtml) + expect(processed).toMatchSnapshot() + expect(processed.length).toEqual(10) + }) + + it(`should support hide markers in JS`, () => { + const processed = highlightLineRange(fixtures.hideLine) + expect(processed).toMatchSnapshot() + expect(processed.length).toEqual(14) + }) +}) + +describe(`highlighting lines`, () => { describe(`highlight-line`, () => { it(`strips directive`, () => { const highlights = highlightLineRange(fixtures.highlightLine) @@ -13,6 +34,7 @@ describe(`highlighting a line range`, () => { expect(output(getHighlighted(highlights))).toMatchSnapshot() }) }) + describe(`highlight-next-line`, () => { it(`strips directive`, () => { const highlights = highlightLineRange(fixtures.highlightNextLine) @@ -23,6 +45,7 @@ describe(`highlighting a line range`, () => { expect(output(getHighlighted(highlights))).toMatchSnapshot() }) }) + describe(`highlight-start / highlight-end`, () => { it(`strips directives`, () => { const highlights = highlightLineRange(fixtures.highlightStartEnd) @@ -40,6 +63,7 @@ describe(`highlighting a line range`, () => { expect(output(getHighlighted(highlights))).toMatchSnapshot() }) }) + describe(`highlight-range`, () => { it(`strips directives`, () => { const highlights = highlightLineRange(fixtures.highlightRange) @@ -65,6 +89,7 @@ describe(`highlighting a line range`, () => { expect(output(getHighlighted(highlights))).toMatchSnapshot() }) }) + describe(`jsx comment`, () => { it(`removes directive`, () => { const highlights = highlightLineRange(fixtures.highlightJsxComment) @@ -81,6 +106,7 @@ describe(`highlighting a line range`, () => { expect(output(getHighlighted(highlights))).toMatchSnapshot() }) }) + describe(`yaml`, () => { it(`strips directive`, () => { const highlights = highlightLineRange(fixtures.highlightYaml) @@ -91,7 +117,8 @@ describe(`highlighting a line range`, () => { expect(output(getHighlighted(highlights))).toMatchSnapshot() }) }) - describe(`kitchen sink`, () => { + + describe(`highlight kitchen sink`, () => { it(`strips directives`, () => { const highlights = highlightLineRange(fixtures.highlightKitchenSink) const code = output(highlights) @@ -111,3 +138,18 @@ describe(`highlighting a line range`, () => { }) }) }) + +describe(`mixed highlight and hide lines`, () => { + it(`should support mixed hide and highlight markers`, () => { + const processed = highlightLineRange(fixtures.hideAndHighlight) + expect(processed).toMatchSnapshot() + expect(processed.length).toEqual(11) + expect(output(getHighlighted(processed))).toMatchSnapshot() + }) + + it(`should error when hidden and highlighted lines overlap`, () => { + expect(() => highlightLineRange(fixtures.hideAndHighlightOverlap)).toThrow( + `Line 8 has been marked as both hidden and highlighted.\n - Line 1: hide ("hide-range{2-3,7}")\n - Line 2: highlight ("highlight-range{5-7,9}")` + ) + }) +}) diff --git a/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight-overlap.js b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight-overlap.js new file mode 100644 index 0000000000000..dedf83fb385f5 --- /dev/null +++ b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight-overlap.js @@ -0,0 +1,13 @@ +// hide-range{2-3,7} +// highlight-range{5-7,9} +import React from 'react' +import { render } from "react-dom" +ReactDOM.render( +
    +
      +
    • hidden
    • +
    +
    , + // highlight-next-line + document.getElementById('root') +); diff --git a/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight.js b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight.js new file mode 100644 index 0000000000000..99f116c586d30 --- /dev/null +++ b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-and-highlight.js @@ -0,0 +1,19 @@ +// hide-range{2-3,10-12,18} +// highlight-range{6-8} +import React from 'react' +import { render } from "react-dom" +ReactDOM.render( +
    +
      +
    • Not hidden and highlighted
    • +
    • Not hidden and highlighted
    • +
    • Not hidden and highlighted
    • +
    • Hidden
    • +
    • Hidden
    • +
    • Hidden
    • +
    +
    , + // highlight-next-line + document.getElementById('root') +); +console.log('Hidden') diff --git a/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-css.css b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-css.css new file mode 100644 index 0000000000000..332a5708f7360 --- /dev/null +++ b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-css.css @@ -0,0 +1,8 @@ +/* hide-range{2-3} */ +html { + height: 100%; + width: 100%; + padding: 50px; + /* hide-next-line */ + background: red; +} diff --git a/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-html.html b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-html.html new file mode 100644 index 0000000000000..b3f1503ef2778 --- /dev/null +++ b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line-html.html @@ -0,0 +1,17 @@ + + +

    + + hidden + hidden +

    +
      + +
    • hidden
    • +
    • hidden
    • +
    • not hidden
    • +
    + + hidden + + diff --git a/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line.js b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line.js new file mode 100644 index 0000000000000..8c87f8eded189 --- /dev/null +++ b/packages/gatsby-remark-prismjs/src/__tests__/fixtures/hide-line.js @@ -0,0 +1,23 @@ +// hide-range{1-2} +import React from 'react' +import { render } from "react-dom" + + +ReactDOM.render( +
    +
      +
    • Not hidden
    • +
    • Not hidden
    • +
    • Not hidden
    • + // hide-range{1-3} +
    • Hidden
    • +
    • Hidden
    • +
    • Hidden
    • +
    +
    , + document.getElementById('root') // hide-line +); + + +// hide-next-line +console.log('Hidden') From 4062fb118f5be323f66f4d55e22ce483bc75be19 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 19 Dec 2018 14:34:43 +0000 Subject: [PATCH 25/27] Fix lint errors --- docs/docs/gatsby-style-guide.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/docs/gatsby-style-guide.md b/docs/docs/gatsby-style-guide.md index a4752335aaaf2..5a627b4e4b00d 100644 --- a/docs/docs/gatsby-style-guide.md +++ b/docs/docs/gatsby-style-guide.md @@ -296,7 +296,9 @@ designed for scientific communication but might help avoid overspecialized wording. ## Best practices + ### Support software versions + When Gatsby commits to support a specific version of software (e.g. Node 6 and up), this is reflected in documentation. Gatsby documentation should be usable by all people on supported software, which means we don't introduce any commands or practices that can't be used by people on versions we've committed to support. In rare circumstances, we'll consider mentioning a newly introduced command or practice as side notes. For example, npm 5.2.0 (which comes with Node 8) introduced a command called `npx` that is not available for versions of Node below 8. Since Gatsby supports Node 6 and up, documentation should only introduce `npx` as an optional command in a note like so: @@ -304,9 +306,11 @@ For example, npm 5.2.0 (which comes with Node 8) introduced a command called `np > npm 5.2.0--bundled with Node 8--introduced a command called `npx`. Gatsby supports Node 6 and up, so we introduce `npx` here as an optional command for users of npm 5.2.0 or greater. ### Share best practices whenever possible + When there are multiple ways to complete a task, the docs should explain the following: + 1. The most fundamental way of completing the task -2. The most common way of completing a task +2. The most common way of completing a task 3. The best way to complete the task on the lowest supported versions of software 4. The best practice and why is it the best (if different than 3) 5. Any tips on how to pick an option @@ -320,6 +324,7 @@ The main tutorial at `/tutorial/` is optimized for users who are not experts in ## Tutorial ### Tutorial audience + Through research, it's clear that developers of all skill levels read the tutorial and go back to reference it later. The tutorial should prioritize helping users with the following attributes and goals. @@ -337,6 +342,7 @@ Looking for: - a way to start a site and/or app project that uses React ### Tutorial purpose + By following the steps in the tutorial, a user should: - Experience the value of Gatsby as quickly as possible. With Gatsby, a user typically values that it takes fewer steps (and is therefore easier) to: From 2a1b01c3c001ab4daa96865da85cb5c02d0757e1 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 19 Dec 2018 16:27:00 +0000 Subject: [PATCH 26/27] Re-enable errors for missing files --- .../2017-04-05---embed-snippets/index.md | 8 ++- .../src/__tests__/__snapshots__/index.js.snap | 55 ------------------- .../src/__tests__/index.js | 8 ++- .../gatsby-remark-embed-snippet/src/index.js | 4 +- 4 files changed, 12 insertions(+), 63 deletions(-) diff --git a/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md b/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md index 3c5cce4b1cfdb..51ded6872b525 100644 --- a/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md +++ b/examples/using-remark/src/pages/2017-04-05---embed-snippets/index.md @@ -17,7 +17,7 @@ Let's start by displaying file contents as a highlighted code block, then see ho After installing the required plugins you can embed a file within your Markdown by using `embed` snippets. To embed the file `src/code-examples/plain.js` you could write the following: -
    embed:plain.js
    +
    `embed:plain.js`
    This will look like: @@ -45,7 +45,11 @@ ReactDOM.render( ) ``` -When the file is embedded with `embed:name-of-your-file.js`, it will display like this: +When the file is embedded with: + +
    `embed:highlight-lines.js`
    + +it will display like this: `embed:highlight-lines.js` diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap index 3755e0a86b70d..dd74aa0c8cd86 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/__snapshots__/index.js.snap @@ -456,61 +456,6 @@ Object { } `; -exports[`gatsby-remark-embed-snippet should not modify embed inlineCode nodes if the target file does not exist 1`] = ` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "inlineCode", - "value": "embed:hello-world.js", - }, - ], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`; - exports[`gatsby-remark-embed-snippet should not modify non-embed inlineCode nodes 1`] = ` Object { "children": Array [ diff --git a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js index 50b83e020e829..a056f00828ec9 100644 --- a/packages/gatsby-remark-embed-snippet/src/__tests__/index.js +++ b/packages/gatsby-remark-embed-snippet/src/__tests__/index.js @@ -38,12 +38,14 @@ describe(`gatsby-remark-embed-snippet`, () => { ) }) - it(`should not modify embed inlineCode nodes if the target file does not exist`, () => { + it(`should error if an invalid file path is specified`, () => { fs.existsSync.mockImplementation(path => path !== `examples/hello-world.js`) const markdownAST = remark.parse(`\`embed:hello-world.js\``) - const transformed = plugin({ markdownAST }, { directory: `examples` }) - expect(transformed).toMatchSnapshot() + + expect(() => plugin({ markdownAST }, { directory: `examples` })).toThrow( + `Invalid snippet specified; no such file "examples/hello-world.js"` + ) }) it(`should not modify non-embed inlineCode nodes`, () => { diff --git a/packages/gatsby-remark-embed-snippet/src/index.js b/packages/gatsby-remark-embed-snippet/src/index.js index 8b389b9e9b50f..47a5dd6e34bfe 100644 --- a/packages/gatsby-remark-embed-snippet/src/index.js +++ b/packages/gatsby-remark-embed-snippet/src/index.js @@ -45,10 +45,8 @@ module.exports = ( const file = value.substr(6) const path = normalizePath(`${directory}${file}`) - // no file? render the `embed:` as a normal string if (!fs.existsSync(path)) { - // TODO: log a message during `gatsby develop`? - return + throw Error(`Invalid snippet specified; no such file "${path}"`) } const code = fs.readFileSync(path, `utf8`).trim() From 4e3c607a38f4792ed2c9ce1bea723b7506f95b00 Mon Sep 17 00:00:00 2001 From: Mike Allanson Date: Wed, 19 Dec 2018 19:31:52 +0000 Subject: [PATCH 27/27] Add info on hiding lines to the gatsby-remark-prismjs readme --- packages/gatsby-remark-prismjs/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/gatsby-remark-prismjs/README.md b/packages/gatsby-remark-prismjs/README.md index 4a08424021c9c..78336b1ad58b7 100644 --- a/packages/gatsby-remark-prismjs/README.md +++ b/packages/gatsby-remark-prismjs/README.md @@ -309,6 +309,19 @@ plugins: [ ### Line hiding +As well as highlighting lines, it's possible to _hide_ lines from the rendered output. Often this is handy when using `gatsby-remark-prismjs` along with [`gatsby-remark-embed-snippet`](https://www.gatsbyjs.org/packages/gatsby-remark-embed-snippet/). + +As with highlighting lines, you can control which lines to hide by adding directives as comments in your source code. + +The available directives are: + +- `hide-line` hides the current line; +- `hide-next-line` hides the next line; +- `hide-start` hides the lines until the matching `hide-end`; +- `hide-range{1, 4-6}` will hide the next line, and the fourth, fifth and sixth lines. + +The hide-line directives will always be hidden too. Check out [the using-remark example site](https://using-remark.gatsbyjs.org/embed-snippets/) to see how this looks on a live site. + ### Inline code blocks In addition to fenced code blocks, inline code blocks will be passed through