Skip to content

Commit

Permalink
fix(transformer-remark): support any remark plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
hjvedvik committed Oct 25, 2018
1 parent 4d9fbe1 commit d9ff803
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 58 deletions.
78 changes: 24 additions & 54 deletions packages/transformer-remark/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
const path = require('path')
const isUrl = require('is-url')
const remark = require('remark')
const unified = require('unified')
const parse = require('gray-matter')
const words = require('lodash.words')
const markdown = require('remark-parse')
const visit = require('unist-util-visit')
const htmlToText = require('html-to-text')
const toHAST = require('mdast-util-to-hast')
const hastToHTML = require('hast-util-to-html')
const { HeadingType, HeadingLevels } = require('./lib/types/HeadingType')
const { normalizePlugins } = require('./lib/utils')

const imagePlugin = require('./lib/plugins/image')

const {
HeadingType,
HeadingLevels
} = require('./lib/types/HeadingType')

const {
GraphQLInt,
Expand All @@ -26,8 +30,9 @@ class RemarkTransformer {
this.nodeCache = nodeCache
this.queue = queue

this.remarkPlugins = this.normalizePlugins([
this.remarkPlugins = normalizePlugins([
// built-in plugins
'remark-parse',
'remark-slug',
'remark-fix-guillemets',
'remark-squeeze-paragraphs',
Expand All @@ -47,6 +52,8 @@ class RemarkTransformer {
'aria-hidden': 'true'
}
}],
// built-in plugins
imagePlugin,
// user plugins
...options.plugins || [],
...localOptions.plugins || []
Expand Down Expand Up @@ -103,59 +110,22 @@ class RemarkTransformer {
}
}

normalizePlugins (arr = []) {
return arr.map(entry => {
return Array.isArray(entry)
? [require(entry[0]), entry[1] || {}]
: [require(entry), {}]
})
}

toAST (node) {
return this.nodeCache(node, 'ast', () => {
const ast = remark().parse(node.internal.content)

// apply remark transforms to ast
for (const [attacher, options] of this.remarkPlugins) {
attacher(options)(ast)
}

return ast
})
}

toHAST (node) {
return this.nodeCache(node, 'hast', async () => {
const ast = await this.toAST(node)
const options = { allowDangerousHTML: true }
const dirname = path.dirname(node.internal.origin)
const images = []

if (path.isAbsolute(node.internal.origin)) {
visit(ast, 'image', node => {
if (!isUrl(node.url)) images.push(node)
})
}

for (const node of images) {
const { imageHTML, noscriptHTML } = await this.queue.add(
path.resolve(dirname, node.url)
)

node.type = 'html'
node.value = imageHTML + noscriptHTML
}

return toHAST(ast, options)
return unified()
.use(markdown)
.parse(node.internal.content)
})
}

toHTML (node) {
return this.nodeCache(node, 'html', async () => {
const hast = await this.toHAST(node)
const options = { allowDangerousHTML: true }

return hastToHTML(hast, options)
return this.nodeCache(node, 'html', () => {
return unified()
.data('node', node)
.data('queue', this.queue)
.use(this.remarkPlugins)
.use(require('remark-html'))
.process(node.internal.content)
})
}

Expand Down
40 changes: 40 additions & 0 deletions packages/transformer-remark/lib/plugins/image.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const path = require('path')
const isUrl = require('is-url')
const visit = require('unist-util-visit')

module.exports = function attacher () {
const node = this.data('node')
const queue = this.data('queue')

return async function transform (tree, file, callback) {
const dirname = path.dirname(node.internal.origin)
const images = []

if (path.isAbsolute(node.internal.origin)) {
visit(tree, 'image', node => {
if (!isUrl(node.url)) images.push(node)
})
}

for (const node of images) {
const data = node.data || {}
const props = data.hProperties || {}
const classNames = props.class || []

const { imageHTML, noscriptHTML } = await queue.add(
path.resolve(dirname, node.url),
{
alt: props.alt || node.alt,
width: props.width,
height: props.height,
classNames
}
)

node.type = 'html'
node.value = imageHTML + noscriptHTML
}

callback()
}
}
4 changes: 2 additions & 2 deletions packages/transformer-remark/lib/types/HeadingType.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
} = require('gridsome/graphql')

const HeadingType = new GraphQLObjectType({
name: 'MarkdownHeading',
name: 'RemarkHeading',
fields: {
depth: { type: GraphQLInt },
value: { type: GraphQLString },
Expand All @@ -15,7 +15,7 @@ const HeadingType = new GraphQLObjectType({
})

const HeadingLevels = new GraphQLEnumType({
name: 'HeadingLevels',
name: 'RemarkHeadingLevels',
values: {
h1: { value: 1 },
h2: { value: 2 },
Expand Down
13 changes: 13 additions & 0 deletions packages/transformer-remark/lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
exports.normalizePlugins = function (arr = []) {
const normalize = entry => {
return typeof entry === 'string'
? require(entry)
: entry
}

return arr.map(entry => {
return Array.isArray(entry)
? [normalize(entry[0]), entry[1] || {}]
: [normalize(entry), {}]
})
}
5 changes: 3 additions & 2 deletions packages/transformer-remark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
"html-to-text": "^4.0.0",
"is-url": "^1.2.4",
"lodash.words": "^4.2.0",
"mdast-util-to-hast": "^3.0.2",
"remark": "^9.0.0",
"remark-autolink-headings": "^5.0.0",
"remark-external-links": "^3.0.0",
"remark-fix-guillemets": "^1.0.15",
"remark-html": "^8.0.0",
"remark-parse": "^6.0.0",
"remark-slug": "^4.2.3",
"remark-squeeze-paragraphs": "^3.0.2",
"unified": "^7.0.0",
"unist-util-visit": "^1.4.0"
},
"publishConfig": {
Expand Down

0 comments on commit d9ff803

Please sign in to comment.