diff --git a/packages/gatsby-remark-images/package.json b/packages/gatsby-remark-images/package.json
index 07be9a75590ee..7fabab416130e 100644
--- a/packages/gatsby-remark-images/package.json
+++ b/packages/gatsby-remark-images/package.json
@@ -12,7 +12,8 @@
"is-relative-url": "^2.0.0",
"lodash": "^4.17.4",
"slash": "^1.0.0",
- "unist-util-select": "^1.5.0"
+ "unist-util-select": "^1.5.0",
+ "unist-util-visit-parents": "^2.0.1"
},
"devDependencies": {
"@babel/cli": "7.0.0-beta.52",
diff --git a/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap b/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap
index 1739a79db4e72..2b6a2ce33edab 100644
--- a/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap
+++ b/packages/gatsby-remark-images/src/__tests__/__snapshots__/index.js.snap
@@ -1,5 +1,75 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`it handles goofy nesting properly 1`] = `
+"
+
+
+
+
+
+ "
+`;
+
+exports[`it leaves images that are already linked alone 1`] = `
+"
+
+
+
+
+
+ "
+`;
+
+exports[`it leaves linked HTML img tags alone 1`] = `
+"
+
+
+
+
+
+
+
+"
+`;
+
+exports[`it leaves single-line linked HTML img tags alone 1`] = `
+"
+
+
+
+
+
+ "
+`;
+
exports[`it transforms HTML img tags 1`] = `
"
diff --git a/packages/gatsby-remark-images/src/__tests__/index.js b/packages/gatsby-remark-images/src/__tests__/index.js
index dc66744e49448..40d30dcfa61e3 100644
--- a/packages/gatsby-remark-images/src/__tests__/index.js
+++ b/packages/gatsby-remark-images/src/__tests__/index.js
@@ -146,3 +146,64 @@ test(`it leaves non-relative HTML img tags alone`, async () => {
const nodes = await plugin(createPluginOptions(content, imagePath))
expect(nodes[0].value).toBe(content)
})
+
+test(`it leaves images that are already linked alone`, async () => {
+ const imagePath = `image/my-image.jpg`
+ const content = `
+[](https://google.com)
+`
+
+ const nodes = await plugin(createPluginOptions(content, imagePath))
+ const node = nodes.pop()
+
+ expect(node.type).toBe(`html`)
+ expect(node.value).toMatchSnapshot()
+ expect(node.value).not.toMatch(``)
+})
+
+test(`it leaves linked HTML img tags alone`, async () => {
+ const imagePath = `images/this-image-already-has-a-link.jpeg`
+
+ const content = `
+
+
+
+ `.trim()
+
+ const nodes = await plugin(createPluginOptions(content, imagePath))
+ const node = nodes.pop()
+
+ expect(node.type).toBe(`html`)
+ expect(node.value).toMatchSnapshot()
+ expect(node.value).not.toMatch(``)
+})
+
+test(`it leaves single-line linked HTML img tags alone`, async () => {
+ const imagePath = `images/this-image-already-has-a-link.jpeg`
+
+ const content = `
+
+ `.trim()
+
+ const nodes = await plugin(createPluginOptions(content, imagePath))
+ const node = nodes.pop()
+
+ expect(node.type).toBe(`html`)
+ expect(node.value).toMatchSnapshot()
+ expect(node.value).not.toMatch(``)
+})
+
+test(`it handles goofy nesting properly`, async () => {
+ const imagePath = `images/this-image-already-has-a-link.jpeg`
+
+ const content = `
+ ****
+ `.trim()
+
+ const nodes = await plugin(createPluginOptions(content, imagePath))
+ const node = nodes.pop()
+
+ expect(node.type).toBe(`html`)
+ expect(node.value).toMatchSnapshot()
+ expect(node.value).not.toMatch(``)
+})
diff --git a/packages/gatsby-remark-images/src/index.js b/packages/gatsby-remark-images/src/index.js
index 36a00d1bfd2df..b1f30caa64b03 100644
--- a/packages/gatsby-remark-images/src/index.js
+++ b/packages/gatsby-remark-images/src/index.js
@@ -1,4 +1,5 @@
-const select = require(`unist-util-select`)
+// const select = require(`unist-util-select`)
+const visitWithParents = require(`unist-util-visit-parents`)
const path = require(`path`)
const isRelativeUrl = require(`is-relative-url`)
const _ = require(`lodash`)
@@ -29,15 +30,34 @@ module.exports = (
const options = _.defaults(pluginOptions, defaults)
+ const findParentLinks = ({ children }) =>
+ children.some(
+ node =>
+ (node.type === `html` && !!node.value.match(/ {
+ const inLink = ancestors.some(findParentLinks)
+
+ rawHtmlNodes.push({ node, inLink })
+ })
+
// This will only work for markdown syntax image tags
- const markdownImageNodes = select(markdownAST, `image`)
+ let markdownImageNodes = []
+
+ visitWithParents(markdownAST, `image`, (node, ancestors) => {
+ const inLink = ancestors.some(findParentLinks)
- // This will also allow the use of html image tags
- const rawHtmlNodes = select(markdownAST, `html`)
+ markdownImageNodes.push({ node, inLink })
+ })
// Takes a node and generates the needed images and then returns
// the needed HTML replacement for the image
- const generateImagesAndUpdateNode = async function(node, resolve) {
+ const generateImagesAndUpdateNode = async function(node, resolve, inLink) {
// Check if this markdownNode has a File parent. This plugin
// won't work if the image isn't hosted locally.
const parentNode = getNode(markdownNode.parent)
@@ -138,7 +158,7 @@ module.exports = (
+ ({ node, inLink }) =>
new Promise(async (resolve, reject) => {
const fileType = node.url.slice(-3)
@@ -207,7 +227,11 @@ module.exports = (
fileType !== `gif` &&
fileType !== `svg`
) {
- const rawHTML = await generateImagesAndUpdateNode(node, resolve)
+ const rawHTML = await generateImagesAndUpdateNode(
+ node,
+ resolve,
+ inLink
+ )
if (rawHTML) {
// Replace the image node with an inline HTML node.
@@ -226,7 +250,7 @@ module.exports = (
Promise.all(
// Complex because HTML nodes can contain multiple images
rawHtmlNodes.map(
- node =>
+ ({ node, inLink }) =>
new Promise(async (resolve, reject) => {
if (!node.value) {
return resolve()
@@ -265,7 +289,8 @@ module.exports = (
) {
const rawHTML = await generateImagesAndUpdateNode(
formattedImgTag,
- resolve
+ resolve,
+ inLink
)
if (rawHTML) {