Skip to content

Commit d818d7c

Browse files
authored
Merge pull request #251 from bvaughn/gatsby-remark-codepen-examples
Added custom remark transform for Codepen example links
2 parents 330e26e + 4614ab0 commit d818d7c

File tree

8 files changed

+76
-7
lines changed

8 files changed

+76
-7
lines changed

content/docs/components-and-props.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ ReactDOM.render(
7676
);
7777
```
7878

79-
<a href="/codepen/components-and-props/rendering-a-component" target="_blank">Try it on CodePen</a>.
79+
[](codepen://components-and-props/rendering-a-component).
8080

8181
Let's recap what happens in this example:
8282

@@ -118,7 +118,7 @@ ReactDOM.render(
118118
);
119119
```
120120

121-
<a href="/codepen/components-and-props/composing-components" target="_blank">Try it on CodePen</a>.
121+
[](codepen://components-and-props/composing-components).
122122

123123
Typically, new React apps have a single `App` component at the very top. However, if you integrate React into an existing app, you might start bottom-up with a small component like `Button` and gradually work your way to the top of the view hierarchy.
124124

@@ -152,7 +152,7 @@ function Comment(props) {
152152
}
153153
```
154154

155-
<a href="/codepen/components-and-props/extracting-components" target="_blank">Try it on CodePen</a>.
155+
[](codepen://components-and-props/extracting-components).
156156

157157
It accepts `author` (an object), `text` (a string), and `date` (a date) as props, and describes a comment on a social media website.
158158

@@ -231,7 +231,7 @@ function Comment(props) {
231231
}
232232
```
233233

234-
<a href="/codepen/components-and-props/extracting-components-continued" target="_blank">Try it on CodePen</a>.
234+
[](codepen://components-and-props/extracting-components-continued).
235235

236236
Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times (`Button`, `Panel`, `Avatar`), or is complex enough on its own (`App`, `FeedStory`, `Comment`), it is a good candidate to be a reusable component.
237237

content/docs/hello-world.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ redirect_from:
1212
- "docs/getting-started-zh-CN.html"
1313
---
1414

15-
The easiest way to get started with React is to use <a href="/codepen/hello-world" target="_blank">this Hello World example code on CodePen</a>. You don't need to install anything; you can just open it in another tab and follow along as we go through examples. If you'd rather use a local development environment, check out the [Installation](/docs/installation.html) page.
15+
The easiest way to get started with React is to use [this Hello World example code on CodePen](codepen://hello-world). You don't need to install anything; you can just open it in another tab and follow along as we go through examples. If you'd rather use a local development environment, check out the [Installation](/docs/installation.html) page.
1616

1717
The smallest React example looks like this:
1818

content/docs/introducing-jsx.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ ReactDOM.render(
4646
);
4747
```
4848

49-
<a href="/codepen/introducing-jsx" target="_blank">Try it on CodePen.</a>
49+
[](codepen://introducing-jsx).
5050

5151
We split JSX over multiple lines for readability. While it isn't required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of [automatic semicolon insertion](http://stackoverflow.com/q/2846283).
5252

gatsby-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ module.exports = {
5656
},
5757
},
5858
'gatsby-remark-autolink-headers',
59+
'gatsby-remark-codepen-examples',
5960
'gatsby-remark-use-jsx',
6061
{
6162
resolve: 'gatsby-remark-prismjs',

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
},
8686
"devDependencies": {
8787
"eslint-config-prettier": "^2.6.0",
88-
"recursive-readdir": "^2.2.1"
88+
"recursive-readdir": "^2.2.1",
89+
"unist-util-map": "^1.0.3"
8990
}
9091
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const {existsSync} = require('fs');
2+
const {join} = require('path');
3+
const map = require('unist-util-map');
4+
5+
const CODEPEN_PROTOCOL = 'codepen://';
6+
const DEFAULT_LINK_TEXT = 'Try it on CodePen';
7+
8+
// TODO target="_blank"
9+
module.exports = ({markdownAST}) => {
10+
map(markdownAST, (node, index, parent) => {
11+
// eg convert
12+
// from: [](codepen:introducing-jsx)
13+
// to: <a href="/codepen/introducing-jsx" target="_blank">Try it on CodePen</a>
14+
// from: [Try the Hello World example on CodePen](codepen:hello-world)
15+
// to: <a href="/codepen/hello-world" target="_blank">Try the Hello World example on CodePen</a>
16+
if (node.type === 'link' && node.url.startsWith(CODEPEN_PROTOCOL)) {
17+
const href = node.url.replace(CODEPEN_PROTOCOL, '/codepen/');
18+
const text =
19+
node.children.length === 0 ? DEFAULT_LINK_TEXT : node.children[0].value;
20+
21+
// Verify that the specified example file exists.
22+
const filePath = join(__dirname, `../../${href}.js`);
23+
if (!existsSync(filePath)) {
24+
console.error(
25+
`Invalid Codepen link specified; no such file "${filePath}"`,
26+
);
27+
process.exit(1);
28+
}
29+
30+
const anchorOpenNode = {
31+
type: 'html',
32+
value: `<a href="${href}" target="_blank">`,
33+
};
34+
35+
const textNode = {
36+
type: 'text',
37+
value: text,
38+
};
39+
40+
const anchorCloseNode = {
41+
type: 'html',
42+
value: '</a>',
43+
};
44+
45+
parent.children.splice(
46+
index,
47+
1,
48+
anchorOpenNode,
49+
textNode,
50+
anchorCloseNode,
51+
);
52+
}
53+
54+
// No change
55+
return node;
56+
});
57+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "gatsby-remark-codepen-examples",
3+
"version": "0.0.1"
4+
}

yarn.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9795,6 +9795,12 @@ unist-util-is@^2.0.0:
97959795
version "2.1.1"
97969796
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b"
97979797

9798+
unist-util-map@^1.0.3:
9799+
version "1.0.3"
9800+
resolved "https://registry.yarnpkg.com/unist-util-map/-/unist-util-map-1.0.3.tgz#26a913d7cddb3cd3e9a886d135d37a3d1f54e514"
9801+
dependencies:
9802+
object-assign "^4.0.1"
9803+
97989804
unist-util-modify-children@^1.0.0:
97999805
version "1.1.1"
98009806
resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz#66d7e6a449e6f67220b976ab3cb8b5ebac39e51d"

0 commit comments

Comments
 (0)