Skip to content
This repository was archived by the owner on Nov 3, 2019. It is now read-only.

Commit 4b85f9b

Browse files
old gatsby-remark-plugin support (#68)
* enable default options in mdx-loader * html to jsx plugins work * remove mdx-deck from kitchen-sink
1 parent 63242d7 commit 4b85f9b

File tree

5 files changed

+246
-13
lines changed

5 files changed

+246
-13
lines changed

packages/gatsby-plugin-mdx/extend-node-type.js

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,44 @@ const objRestSpread = require("@babel/plugin-proposal-object-rest-spread");
2626
const babel = require("@babel/core");
2727
const rawMDX = require("@mdx-js/mdx");
2828

29+
const debug = require("debug")("gatsby-mdx:extend-node-type");
2930
const mdx = require("./utils/mdx");
3031
const getTableOfContents = require("./utils/get-table-of-content");
3132
const defaultOptions = require("./utils/default-options");
33+
const getSourcePluginsAsRemarkPlugins = require("./utils/get-source-plugins-as-remark-plugins");
3234

3335
const stripFrontmatter = source => grayMatter(source).content;
36+
/*
37+
* function mutateNode({
38+
* pluginOptions,
39+
* mdxNode,
40+
* getNode,
41+
* files,
42+
* reporter,
43+
* cache
44+
* }) {
45+
* return Promise.each(pluginOptions.gatsbyRemarkPlugins, plugin => {
46+
* const requiredPlugin = require(plugin.resolve);
47+
* if (_.isFunction(requiredPlugin.mutateSource)) {
48+
* return requiredPlugin.mutateSource(
49+
* {
50+
* mdxNode,
51+
* files: fileNodes,
52+
* getNode,
53+
* reporter,
54+
* cache
55+
* },
56+
* plugin.pluginOptions
57+
* );
58+
* } else {
59+
* return Promise.resolve();
60+
* }
61+
* });
62+
* }
63+
* */
3464

3565
module.exports = (
36-
{ type /*store, pathPrefix, getNode, getNodes, cache, reporter*/ },
66+
{ type /*store*/, pathPrefix, getNode, getNodes, cache, reporter },
3767
pluginOptions
3868
) => {
3969
if (!type.name.endsWith(`Mdx`)) {
@@ -43,6 +73,33 @@ module.exports = (
4373
const options = defaultOptions(pluginOptions);
4474
const compiler = createMdxAstCompiler(options);
4575

76+
for (let plugin of options.gatsbyRemarkPlugins) {
77+
if (!plugin.resolve) {
78+
throw new Error(
79+
'gatsby-remark plugins must be configured in the form {resolve: "plugin", options: {}}'
80+
);
81+
}
82+
debug("requiring", plugin.resolve);
83+
const requiredPlugin = require(plugin.resolve);
84+
debug("required", plugin);
85+
if (_.isFunction(requiredPlugin.setParserPlugins)) {
86+
for (let parserPlugin of requiredPlugin.setParserPlugins(
87+
plugin.pluginOptions
88+
)) {
89+
if (_.isArray(parserPlugin)) {
90+
const [parser, parserPluginOptions] = parserPlugin;
91+
debug("adding mdPlugin with options", plugin, parserPluginOptions);
92+
options.mdPlugins.push([parser, parserPluginOptions]);
93+
// remark = remark.use(parser, options);
94+
} else {
95+
debug("adding mdPlugin", plugin);
96+
options.mdPlugins.push(parserPlugin);
97+
// remark = remark.use(parserPlugin);
98+
}
99+
}
100+
}
101+
}
102+
46103
return new Promise((resolve /*, reject*/) => {
47104
async function getAST(mdxNode) {
48105
return compiler.parse(stripFrontmatter(mdxNode.rawBody));
@@ -66,6 +123,15 @@ module.exports = (
66123
}
67124

68125
async function getCode(mdxNode, overrideOptions) {
126+
/* await mutateNode({
127+
* pluginOptions,
128+
* mdxNode,
129+
* files: getNodes().filter(n => n.internal.type === `File`),
130+
* getNode,
131+
* reporter,
132+
* cache
133+
* }); */
134+
69135
const code = await mdx(mdxNode.rawBody, {
70136
...options,
71137
...overrideOptions
@@ -106,6 +172,26 @@ ${code}`;
106172
}
107173
});
108174

175+
async function rawMDXWithGatsbyRemarkPlugins(content, opts, mdxNode) {
176+
const gatsbyRemarkPluginsAsMDPlugins = await getSourcePluginsAsRemarkPlugins(
177+
{
178+
gatsbyRemarkPlugins: options.gatsbyRemarkPlugins,
179+
mdxNode,
180+
// files,
181+
getNode,
182+
getNodes,
183+
reporter,
184+
cache,
185+
pathPrefix
186+
}
187+
);
188+
189+
return rawMDX(content, {
190+
...options,
191+
mdPlugins: options.mdPlugins.concat(gatsbyRemarkPluginsAsMDPlugins)
192+
});
193+
}
194+
109195
return resolve({
110196
code: {
111197
resolve(mdxNode) {
@@ -123,10 +209,24 @@ ${code}`;
123209
body: {
124210
type: GraphQLString,
125211
async resolve(mdxNode) {
212+
/* await mutateNode({
213+
* pluginOptions,
214+
* mdxNode,
215+
* files: getNodes().filter(n => n.internal.type === `File`),
216+
* getNode,
217+
* reporter,
218+
* cache
219+
* }); */
220+
126221
const { content } = grayMatter(mdxNode.rawBody);
127-
let code = await rawMDX(content, {
128-
...options
129-
});
222+
223+
let code = await rawMDXWithGatsbyRemarkPlugins(
224+
content,
225+
{
226+
...options
227+
},
228+
mdxNode
229+
);
130230

131231
const instance = new BabelPluginPluckImports();
132232
const result = babel.transform(code, {
@@ -146,6 +246,7 @@ ${code}`;
146246
const CACHE_DIR = `.cache`;
147247
const PLUGIN_DIR = `gatsby-mdx`;
148248
const REMOTE_MDX_DIR = `remote-mdx-dir`;
249+
149250
mkdirp.sync(
150251
path.join(options.root, CACHE_DIR, PLUGIN_DIR, REMOTE_MDX_DIR)
151252
);
@@ -165,9 +266,14 @@ ${code}`;
165266
.digest(`hex`);
166267

167268
const { content } = grayMatter(mdxNode.rawBody);
168-
let code = await rawMDX(content, {
169-
...options
170-
});
269+
270+
let code = await rawMDXWithGatsbyRemarkPlugins(
271+
content,
272+
{
273+
...options
274+
},
275+
mdxNode
276+
);
171277

172278
const instance = new BabelPluginPluckImports();
173279
babel.transform(code, {

packages/gatsby-plugin-mdx/mdx-loader.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const toMDAST = require("remark-parse");
1414
const squeeze = require("remark-squeeze-paragraphs");
1515

1616
const mdx = require("./utils/mdx");
17+
const getSourcePluginsAsRemarkPlugins = require("./utils/get-source-plugins-as-remark-plugins");
18+
const withDefaultOptions = require("./utils/default-options");
1719
const debug = require("debug")("gatsby-mdx:mdx-loader");
1820

1921
const DEFAULT_OPTIONS = {
@@ -78,7 +80,16 @@ const hasDefaultExport = (str, options) => {
7880

7981
module.exports = async function(content) {
8082
const callback = this.async();
81-
const { getNodes, pluginOptions } = getOptions(this);
83+
const {
84+
getNode,
85+
getNodes,
86+
reporter,
87+
cache,
88+
pathPrefix,
89+
pluginOptions
90+
} = getOptions(this);
91+
92+
const options = withDefaultOptions(pluginOptions);
8293

8394
const fileNode = getNodes().find(
8495
node =>
@@ -90,9 +101,9 @@ module.exports = async function(content) {
90101
// get the default layout for the file source group, or if it doesn't
91102
// exist, the overall default layout
92103
const defaultLayout = _.get(
93-
pluginOptions.defaultLayouts,
104+
options.defaultLayouts,
94105
source,
95-
_.get(pluginOptions.defaultLayouts, "default")
106+
_.get(options.defaultLayouts, "default")
96107
);
97108

98109
let code = content;
@@ -110,7 +121,21 @@ export default DefaultLayout
110121
${contentWithoutFrontmatter}`;
111122
}
112123

113-
code = await mdx(code, pluginOptions);
124+
const gatsbyRemarkPluginsAsMDPlugins = await getSourcePluginsAsRemarkPlugins({
125+
gatsbyRemarkPlugins: options.gatsbyRemarkPlugins,
126+
markdownNode: undefined,
127+
// files,
128+
getNode,
129+
getNodes,
130+
reporter,
131+
cache,
132+
pathPrefix
133+
});
134+
135+
code = await mdx(code, {
136+
...options,
137+
mdPlugins: options.mdPlugins.concat(gatsbyRemarkPluginsAsMDPlugins)
138+
});
114139

115140
return callback(
116141
null,

packages/gatsby-plugin-mdx/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "gatsby-mdx",
3-
"version": "0.0.15",
3+
"version": "0.1.0",
44
"description": "mdx integration for gatsby",
55
"main": "index.js",
66
"license": "MIT",
@@ -20,6 +20,7 @@
2020
"escape-string-regexp": "^1.0.5",
2121
"fs-extra": "^7.0.0",
2222
"gray-matter": "^4.0.1",
23+
"htmltojsx": "^0.3.0",
2324
"json5": "^1.0.1",
2425
"lodash": "^4.17.10",
2526
"mdast-util-to-string": "^1.0.4",
@@ -28,6 +29,7 @@
2829
"retext": "^5.0.0",
2930
"strip-markdown": "^3.0.1",
3031
"underscore.string": "^3.3.4",
32+
"unist-util-map": "^1.0.4",
3133
"unist-util-remove": "^1.0.1",
3234
"unist-util-visit": "^1.4.0"
3335
},

packages/gatsby-plugin-mdx/utils/default-options.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ module.exports = pluginOptions => {
1414
hastPlugins: [],
1515
mdPlugins: [],
1616
transformers: {},
17-
root: process.cwd()
17+
root: process.cwd(),
18+
gatsbyRemarkPlugins: []
1819
},
1920
pluginOptions
2021
);
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
const visit = require("unist-util-visit");
2+
const _ = require("lodash");
3+
const HTMLtoJSX = require("htmltojsx");
4+
const map = require("unist-util-map");
5+
const debug = require("debug")("get-source-plugins-as-remark-plugins");
6+
7+
let fileNodes;
8+
9+
const htmlToJSXConverter = new HTMLtoJSX({
10+
createClass: false
11+
});
12+
13+
// ensure only one `/` in new url
14+
const withPathPrefix = (url, pathPrefix) =>
15+
(pathPrefix + url).replace(/\/\//, `/`);
16+
17+
const isJSXRegex = /<[A-Z]/g;
18+
const htmlToJSXPlugin = () =>
19+
function transformer(ast) {
20+
const astMapped = map(ast, node => {
21+
if (node.type === "html" && !isJSXRegex.test(node.value)) {
22+
return { ...node, value: htmlToJSXConverter.convert(node.value) };
23+
} else {
24+
return node;
25+
}
26+
});
27+
return astMapped;
28+
};
29+
30+
module.exports = async function getSourcePluginsAsRemarkPlugins({
31+
gatsbyRemarkPlugins,
32+
mdxNode,
33+
getNode,
34+
getNodes,
35+
reporter,
36+
cache,
37+
pathPrefix
38+
}) {
39+
debug("getSourcePluginsAsRemarkPlugins");
40+
let pathPlugin = undefined;
41+
if (pathPrefix) {
42+
pathPlugin = () =>
43+
async function transformer(markdownAST) {
44+
// Ensure relative links include `pathPrefix`
45+
visit(markdownAST, `link`, node => {
46+
if (
47+
node.url &&
48+
node.url.startsWith(`/`) &&
49+
!node.url.startsWith(`//`)
50+
) {
51+
// TODO: where does withPathPrefix
52+
node.url = withPathPrefix(node.url, pathPrefix);
53+
}
54+
});
55+
return markdownAST;
56+
};
57+
}
58+
59+
if (process.env.NODE_ENV !== `production` || !fileNodes) {
60+
fileNodes = getNodes().filter(n => n.internal.type === `File`);
61+
}
62+
63+
// return list of mdPlugins
64+
const userPlugins = gatsbyRemarkPlugins
65+
.filter(plugin => {
66+
if (_.isFunction(require(plugin.resolve))) {
67+
return true;
68+
} else {
69+
debug("userPlugins: filtering out", plugin);
70+
return false;
71+
}
72+
})
73+
.map(plugin => {
74+
debug("userPlugins: contructing remark plugin for ", plugin);
75+
const requiredPlugin = require(plugin.resolve);
76+
return () =>
77+
async function transformer(markdownAST) {
78+
requiredPlugin(
79+
{
80+
markdownAST,
81+
markdownNode: mdxNode,
82+
getNode,
83+
files: fileNodes,
84+
pathPrefix,
85+
reporter,
86+
cache
87+
},
88+
plugin.pluginOptions || {}
89+
);
90+
return markdownAST;
91+
};
92+
});
93+
94+
if (pathPlugin) {
95+
return [pathPlugin, ...userPlugins, htmlToJSXPlugin];
96+
} else {
97+
return [...userPlugins, htmlToJSXPlugin];
98+
}
99+
};

0 commit comments

Comments
 (0)