From a3e7c8b7ed095e1f8a71c8c19c52a76d9501f129 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Tue, 7 Nov 2017 11:35:35 +0000 Subject: [PATCH] Added gatsby-remark-babel-repl-link plug-in --- content/tutorial/tutorial.md | 2 +- examples/tutorial-expanded-version.js | 8 +++ gatsby-config.js | 6 ++ package.json | 1 + .../gatsby-remark-babel-repl-link/index.js | 68 +++++++++++++++++++ .../package.json | 4 ++ .../gatsby-remark-codepen-examples/index.js | 3 +- yarn.lock | 4 ++ 8 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 examples/tutorial-expanded-version.js create mode 100644 plugins/gatsby-remark-babel-repl-link/index.js create mode 100644 plugins/gatsby-remark-babel-repl-link/package.json diff --git a/content/tutorial/tutorial.md b/content/tutorial/tutorial.md index 4fcf1a937..9ca297200 100644 --- a/content/tutorial/tutorial.md +++ b/content/tutorial/tutorial.md @@ -129,7 +129,7 @@ return React.createElement('div', {className: 'shopping-list'}, ); ``` -[See full expanded version.](https://babeljs.io/repl/#?babili=false&evaluate=false&lineWrap=false&presets=react&targets=&browsers=&builtIns=false&debug=false&experimental=false&loose=false&spec=false&playground=true&code=%3Cdiv%20className%3D%22shopping-list%22%3E%0A%20%20%3Ch1%3EShopping%20List%20for%20%7Bprops.name%7D%3C%2Fh1%3E%0A%20%20%3Cul%3E%0A%20%20%20%20%3Cli%3EInstagram%3C%2Fli%3E%0A%20%20%20%20%3Cli%3EWhatsApp%3C%2Fli%3E%0A%20%20%20%20%3Cli%3EOculus%3C%2Fli%3E%0A%20%20%3C%2Ful%3E%0A%3C%2Fdiv%3E) +[See full expanded version.](babel-repl://tutorial-expanded-version) If you're curious, `createElement()` is described in more detail in the [API reference](/docs/react-api.html#createelement), but we won't be using it directly in this tutorial. Instead, we will keep using JSX. diff --git a/examples/tutorial-expanded-version.js b/examples/tutorial-expanded-version.js new file mode 100644 index 000000000..767a233fb --- /dev/null +++ b/examples/tutorial-expanded-version.js @@ -0,0 +1,8 @@ +
+

Shopping List for {props.name}

+ +
\ No newline at end of file diff --git a/gatsby-config.js b/gatsby-config.js index a645f86a5..35a5bf445 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -62,6 +62,12 @@ module.exports = { directory: 'examples', }, }, + { + resolve: 'gatsby-remark-babel-repl-link', + options: { + directory: 'examples', + }, + }, 'gatsby-remark-use-jsx', { resolve: 'gatsby-remark-prismjs', diff --git a/package.json b/package.json index 8501d1def..e888cb43f 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ }, "devDependencies": { "eslint-config-prettier": "^2.6.0", + "lz-string": "^1.4.4", "recursive-readdir": "^2.2.1", "unist-util-map": "^1.0.3" } diff --git a/plugins/gatsby-remark-babel-repl-link/index.js b/plugins/gatsby-remark-babel-repl-link/index.js new file mode 100644 index 000000000..e3f13e20c --- /dev/null +++ b/plugins/gatsby-remark-babel-repl-link/index.js @@ -0,0 +1,68 @@ +const {existsSync, readFileSync} = require('fs'); +const LZString = require('lz-string'); +const {join} = require('path'); +const map = require('unist-util-map'); + +const PROTOCOL = 'babel-repl://'; + +// Matches compression used in Babel REPL +// https://github.com/babel/website/blob/master/js/repl/UriUtils.js +const compress = string => + LZString.compressToBase64(string) + .replace(/\+/g, '-') // Convert '+' to '-' + .replace(/\//g, '_') // Convert '/' to '_' + .replace(/=+$/, ''); // Remove ending '=' + +module.exports = ({markdownAST}, {directory}) => { + map(markdownAST, (node, index, parent) => { + if (!directory.endsWith('/')) { + directory += '/'; + } + + if (node.type === 'link' && node.url.startsWith(PROTOCOL)) { + let filePath = node.url.replace(PROTOCOL, directory); + if (!filePath.endsWith('.js')) { + filePath += '.js'; + } + filePath = join(__dirname, '../..', filePath); + + // Verify that the specified example file exists. + if (!existsSync(filePath)) { + console.error( + `Invalid Babel REPL link specified; no such file "${filePath}"`, + ); + process.exit(1); + } + + const code = compress(readFileSync(filePath, 'utf8')); + const href = `https://babeljs.io/repl/#?presets=react&code_lz=${code}`; + const text = node.children[0].value; + + const anchorOpenNode = { + type: 'html', + value: ``, + }; + + const textNode = { + type: 'text', + value: text, + }; + + const anchorCloseNode = { + type: 'html', + value: '', + }; + + parent.children.splice( + index, + 1, + anchorOpenNode, + textNode, + anchorCloseNode, + ); + } + + // No change + return node; + }); +}; diff --git a/plugins/gatsby-remark-babel-repl-link/package.json b/plugins/gatsby-remark-babel-repl-link/package.json new file mode 100644 index 000000000..a0318cc57 --- /dev/null +++ b/plugins/gatsby-remark-babel-repl-link/package.json @@ -0,0 +1,4 @@ +{ + "name": "gatsby-remark-babel-repl-link", + "version": "0.0.1" +} \ No newline at end of file diff --git a/plugins/gatsby-remark-codepen-examples/index.js b/plugins/gatsby-remark-codepen-examples/index.js index f1da51e4f..7e4ff3327 100644 --- a/plugins/gatsby-remark-codepen-examples/index.js +++ b/plugins/gatsby-remark-codepen-examples/index.js @@ -5,7 +5,6 @@ const map = require('unist-util-map'); const CODEPEN_PROTOCOL = 'codepen://'; const DEFAULT_LINK_TEXT = 'Try it on CodePen'; -// TODO target="_blank" module.exports = ({markdownAST}, {directory}) => { map(markdownAST, (node, index, parent) => { if (!directory.startsWith('/')) { @@ -22,7 +21,7 @@ module.exports = ({markdownAST}, {directory}) => { // from: [Try the Hello World example on CodePen](codepen:hello-world) // to: Try the Hello World example on CodePen if (node.type === 'link' && node.url.startsWith(CODEPEN_PROTOCOL)) { - const href = node.url.replace(CODEPEN_PROTOCOL, `${directory}`); + const href = node.url.replace(CODEPEN_PROTOCOL, directory); const text = node.children.length === 0 ? DEFAULT_LINK_TEXT : node.children[0].value; diff --git a/yarn.lock b/yarn.lock index 9640d346a..abe90f6bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6086,6 +6086,10 @@ ltcdr@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ltcdr/-/ltcdr-2.2.1.tgz#5ab87ad1d4c1dab8e8c08bbf037ee0c1902287cf" +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + macaddress@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"