Skip to content

Commit c42671b

Browse files
author
Alexandre Kirszenberg
committed
Allow for multiple different remark sources
1 parent 91341b4 commit c42671b

File tree

5 files changed

+184
-80
lines changed

5 files changed

+184
-80
lines changed

packages/gatsby-transformer-remark/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ plugins: [
1414
{
1515
resolve: `gatsby-transformer-remark`,
1616
options: {
17+
18+
// Defaults to `() => true`
19+
filter: node => node.sourceInstanceName === `blog`,
20+
// Defaults to `MarkdownRemark`
21+
type: `BlogPost`,
1722
// CommonMark mode (default: true)
1823
commonmark: true,
1924
// Footnotes mode (default: true)

packages/gatsby-transformer-remark/src/__tests__/extend-node.js

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ const {
44
GraphQLList,
55
GraphQLSchema,
66
} = require(`gatsby/graphql`)
7-
const { onCreateNode } = require(`../gatsby-node`)
7+
const { Promise } = require(`bluebird`)
8+
const { onCreateNode, setFieldsOnGraphQLNodeType } = require(`../gatsby-node`)
89
const {
910
inferObjectStructureFromNodes,
1011
} = require(`../../../gatsby/src/schema/infer-graphql-type`)
@@ -14,7 +15,7 @@ const extendNodeType = require(`../extend-node-type`)
1415
async function queryResult(
1516
nodes,
1617
fragment,
17-
{ types = [] } = {},
18+
{ typeName = `MarkdownRemark`, types = [] } = {},
1819
{ additionalParameters = {}, pluginOptions = {} }
1920
) {
2021
const inferredFields = inferObjectStructureFromNodes({
@@ -51,7 +52,7 @@ async function queryResult(
5152
name: `LISTNODE`,
5253
type: new GraphQLList(
5354
new GraphQLObjectType({
54-
name: `MarkdownRemark`,
55+
name: typeName,
5556
fields: markdownRemarkFields,
5657
})
5758
),
@@ -559,3 +560,47 @@ This is [a reference]
559560
{ additionalParameters: { pathPrefix: `/prefix` } }
560561
)
561562
})
563+
564+
describe(`Adding fields to the GraphQL schema`, () => {
565+
it(`only adds fields when the GraphQL type matches the provided type`, async () => {
566+
const getNode = jest.fn()
567+
const getNodesByType = jest.fn()
568+
569+
expect(
570+
setFieldsOnGraphQLNodeType({
571+
type: { name: `MarkdownRemark` },
572+
getNode,
573+
getNodesByType,
574+
})
575+
).toBeInstanceOf(Promise)
576+
577+
expect(
578+
setFieldsOnGraphQLNodeType(
579+
{ type: { name: `MarkdownRemark` }, getNode, getNodesByType },
580+
{ type: `MarkdownRemark` }
581+
)
582+
).toBeInstanceOf(Promise)
583+
584+
expect(
585+
setFieldsOnGraphQLNodeType(
586+
{ type: { name: `MarkdownRemark` }, getNode, getNodesByType },
587+
{ type: `GatsbyTestType` }
588+
)
589+
).toEqual({})
590+
591+
expect(
592+
setFieldsOnGraphQLNodeType(
593+
{ type: { name: `GatsbyTestType` }, getNode, getNodesByType },
594+
{ type: `GatsbyTestType` }
595+
)
596+
).toBeInstanceOf(Promise)
597+
598+
expect(
599+
setFieldsOnGraphQLNodeType({
600+
type: { name: `GatsbyTestType` },
601+
getNode,
602+
getNodesByType,
603+
})
604+
).toEqual({})
605+
})
606+
})

packages/gatsby-transformer-remark/src/__tests__/gatsby-node.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,50 @@ Sed bibendum sem iaculis, pellentesque leo sed, imperdiet ante. Sed consequat ma
101101
expect(createParentChildLink).toHaveBeenCalledTimes(1)
102102
})
103103
})
104+
105+
it(`Filters nodes with the given filter function, if provided`, async () => {
106+
const content = ``
107+
108+
node.content = content
109+
node.sourceInstanceName = `gatsby-test-source`
110+
111+
const createNode = jest.fn()
112+
const createParentChildLink = jest.fn()
113+
const actions = { createNode, createParentChildLink }
114+
const createNodeId = jest.fn()
115+
createNodeId.mockReturnValue(`uuid-from-gatsby`)
116+
117+
await onCreateNode(
118+
{
119+
node,
120+
loadNodeContent,
121+
actions,
122+
createNodeId,
123+
},
124+
{
125+
filter: node =>
126+
node.sourceInstanceName === `gatsby-other-test-source`,
127+
}
128+
).then(() => {
129+
expect(createNode).toHaveBeenCalledTimes(0)
130+
expect(createParentChildLink).toHaveBeenCalledTimes(0)
131+
})
132+
133+
await onCreateNode(
134+
{
135+
node,
136+
loadNodeContent,
137+
actions,
138+
createNodeId,
139+
},
140+
{
141+
filter: node => node.sourceInstanceName === `gatsby-test-source`,
142+
}
143+
).then(() => {
144+
expect(createNode).toHaveBeenCalledTimes(1)
145+
expect(createParentChildLink).toHaveBeenCalledTimes(1)
146+
})
147+
})
104148
})
105149

106150
describe(`process graphql correctly`, () => {

packages/gatsby-transformer-remark/src/extend-node-type.js

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,59 @@ const safeGetCache = ({ getCache, cache }) => id => {
6868
return getCache(id)
6969
}
7070

71+
const HeadingType = new GraphQLObjectType({
72+
name: `MarkdownHeading`,
73+
fields: {
74+
value: {
75+
type: GraphQLString,
76+
resolve(heading) {
77+
return heading.value
78+
},
79+
},
80+
depth: {
81+
type: GraphQLInt,
82+
resolve(heading) {
83+
return heading.depth
84+
},
85+
},
86+
},
87+
})
88+
89+
const HeadingLevels = new GraphQLEnumType({
90+
name: `HeadingLevels`,
91+
values: {
92+
h1: { value: 1 },
93+
h2: { value: 2 },
94+
h3: { value: 3 },
95+
h4: { value: 4 },
96+
h5: { value: 5 },
97+
h6: { value: 6 },
98+
},
99+
})
100+
101+
const ExcerptFormats = new GraphQLEnumType({
102+
name: `ExcerptFormats`,
103+
values: {
104+
PLAIN: { value: `plain` },
105+
HTML: { value: `html` },
106+
},
107+
})
108+
109+
const wordCountType = new GraphQLObjectType({
110+
name: `wordCount`,
111+
fields: {
112+
paragraphs: {
113+
type: GraphQLInt,
114+
},
115+
sentences: {
116+
type: GraphQLInt,
117+
},
118+
words: {
119+
type: GraphQLInt,
120+
},
121+
},
122+
})
123+
71124
/**
72125
* Map that keeps track of generation of AST to not generate it multiple
73126
* times in parallel.
@@ -87,29 +140,31 @@ module.exports = (
87140
reporter,
88141
...rest
89142
},
90-
pluginOptions
143+
{
144+
type: typeName = `MarkdownRemark`,
145+
plugins = [],
146+
blocks,
147+
commonmark = true,
148+
footnotes = true,
149+
gfm = true,
150+
pedantic = true,
151+
tableOfContents = {
152+
heading: null,
153+
maxDepth: 6,
154+
},
155+
...grayMatterOptions
156+
} = {}
91157
) => {
92-
if (type.name !== `MarkdownRemark`) {
158+
if (type.name !== typeName) {
93159
return {}
94160
}
95-
pluginsCacheStr = pluginOptions.plugins.map(p => p.name).join(``)
161+
pluginsCacheStr = plugins.map(p => p.name).join(``)
96162
pathPrefixCacheStr = pathPrefix || ``
97163

98164
const getCache = safeGetCache({ cache, getCache: possibleGetCache })
99165

100166
return new Promise((resolve, reject) => {
101167
// Setup Remark.
102-
const {
103-
blocks,
104-
commonmark = true,
105-
footnotes = true,
106-
gfm = true,
107-
pedantic = true,
108-
tableOfContents = {
109-
heading: null,
110-
maxDepth: 6,
111-
},
112-
} = pluginOptions
113168
const tocOptions = tableOfContents
114169
const remarkOptions = {
115170
commonmark,
@@ -122,7 +177,7 @@ module.exports = (
122177
}
123178
let remark = new Remark().data(`settings`, remarkOptions)
124179

125-
for (let plugin of pluginOptions.plugins) {
180+
for (let plugin of plugins) {
126181
const requiredPlugin = require(plugin.resolve)
127182
if (_.isFunction(requiredPlugin.setParserPlugins)) {
128183
for (let parserPlugin of requiredPlugin.setParserPlugins(
@@ -167,7 +222,7 @@ module.exports = (
167222
fileNodes = getNodesByType(`File`)
168223
}
169224
// Use Bluebird's Promise function "each" to run remark plugins serially.
170-
await Promise.each(pluginOptions.plugins, plugin => {
225+
await Promise.each(plugins, plugin => {
171226
const requiredPlugin = require(plugin.resolve)
172227
if (_.isFunction(requiredPlugin.mutateSource)) {
173228
return requiredPlugin.mutateSource(
@@ -235,7 +290,7 @@ module.exports = (
235290
fileNodes = getNodesByType(`File`)
236291
}
237292
// Use Bluebird's Promise function "each" to run remark plugins serially.
238-
await Promise.each(pluginOptions.plugins, plugin => {
293+
await Promise.each(plugins, plugin => {
239294
const requiredPlugin = require(plugin.resolve)
240295
if (_.isFunction(requiredPlugin)) {
241296
return requiredPlugin(
@@ -362,44 +417,6 @@ module.exports = (
362417
}
363418
}
364419

365-
const HeadingType = new GraphQLObjectType({
366-
name: `MarkdownHeading`,
367-
fields: {
368-
value: {
369-
type: GraphQLString,
370-
resolve(heading) {
371-
return heading.value
372-
},
373-
},
374-
depth: {
375-
type: GraphQLInt,
376-
resolve(heading) {
377-
return heading.depth
378-
},
379-
},
380-
},
381-
})
382-
383-
const HeadingLevels = new GraphQLEnumType({
384-
name: `HeadingLevels`,
385-
values: {
386-
h1: { value: 1 },
387-
h2: { value: 2 },
388-
h3: { value: 3 },
389-
h4: { value: 4 },
390-
h5: { value: 5 },
391-
h6: { value: 6 },
392-
},
393-
})
394-
395-
const ExcerptFormats = new GraphQLEnumType({
396-
name: `ExcerptFormats`,
397-
values: {
398-
PLAIN: { value: `plain` },
399-
HTML: { value: `html` },
400-
},
401-
})
402-
403420
return resolve({
404421
html: {
405422
type: GraphQLString,
@@ -434,13 +451,13 @@ module.exports = (
434451
},
435452
async resolve(markdownNode, { format, pruneLength, truncate }) {
436453
if (format === `html`) {
437-
if (pluginOptions.excerpt_separator) {
454+
if (grayMatterOptions.excerpt_separator) {
438455
const fullAST = await getHTMLAst(markdownNode)
439456
const excerptAST = cloneTreeUntil(
440457
fullAST,
441458
({ nextNode }) =>
442459
nextNode.type === `raw` &&
443-
nextNode.value === pluginOptions.excerpt_separator
460+
nextNode.value === grayMatterOptions.excerpt_separator
444461
)
445462
return hastToHTML(excerptAST, {
446463
allowDangerousHTML: true,
@@ -558,20 +575,7 @@ module.exports = (
558575
},
559576
// TODO add support for non-latin languages https://github.com/wooorm/remark/issues/251#issuecomment-296731071
560577
wordCount: {
561-
type: new GraphQLObjectType({
562-
name: `wordCount`,
563-
fields: {
564-
paragraphs: {
565-
type: GraphQLInt,
566-
},
567-
sentences: {
568-
type: GraphQLInt,
569-
},
570-
words: {
571-
type: GraphQLInt,
572-
},
573-
},
574-
}),
578+
type: wordCountType,
575579
resolve(markdownNode) {
576580
let counts = {}
577581

packages/gatsby-transformer-remark/src/on-node-create.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,36 @@ const crypto = require(`crypto`)
33

44
module.exports = async function onCreateNode(
55
{ node, loadNodeContent, actions, createNodeId, reporter },
6-
pluginOptions
6+
{
7+
plugins = null,
8+
filter = () => true,
9+
type = `MarkdownRemark`,
10+
...grayMatterOptions
11+
} = {}
712
) {
813
const { createNode, createParentChildLink } = actions
914

1015
// We only care about markdown content.
1116
if (
12-
node.internal.mediaType !== `text/markdown` &&
13-
node.internal.mediaType !== `text/x-markdown`
17+
(node.internal.mediaType !== `text/markdown` &&
18+
node.internal.mediaType !== `text/x-markdown`) ||
19+
!filter(node)
1420
) {
1521
return
1622
}
1723

1824
const content = await loadNodeContent(node)
1925

2026
try {
21-
const data = grayMatter(content, pluginOptions)
27+
const data = grayMatter(content, grayMatterOptions)
2228

2329
const markdownNode = {
24-
id: createNodeId(`${node.id} >>> MarkdownRemark`),
30+
id: createNodeId(`${node.id} >>> ${type}`),
2531
children: [],
2632
parent: node.id,
2733
internal: {
2834
content: data.content,
29-
type: `MarkdownRemark`,
35+
type,
3036
},
3137
}
3238

0 commit comments

Comments
 (0)