Skip to content

Commit

Permalink
feat(gatsby-transformer-remark): change excerpt behavior (#14723)
Browse files Browse the repository at this point in the history
Change gatsby-transformer-remark excerpt behavior

- Plain text even with separator
- New format for MARKDOWN
  • Loading branch information
riywo authored and freiksenet committed Jun 14, 2019
1 parent b8f2a03 commit 4f72687
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 26 deletions.
14 changes: 14 additions & 0 deletions packages/gatsby-transformer-remark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,20 @@ It's also possible to ask Gatsby to return excerpts formatted as HTML. You might
}
```

You can also get excerpts in Markdown format.

```graphql
{
allMarkdownRemark {
edges {
node {
excerpt(format: MARKDOWN)
}
}
}
}
```

## gray-matter options

`gatsby-transformer-remark` uses [gray-matter](https://github.com/jonschlinkert/gray-matter) to parse markdown frontmatter, so you can specify any of the options mentioned [here](https://github.com/jonschlinkert/gray-matter#options) in the `gatsby-config.js` file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ Object {

exports[`Excerpt is generated correctly from schema correctly uses excerpt separator 1`] = `
Object {
"excerpt": "Where oh where is my little pony?
",
"excerpt": "Where oh where is my little pony?",
"excerptAst": Object {
"children": Array [
Object {
Expand Down Expand Up @@ -162,6 +161,26 @@ Object {
}
`;

exports[`Excerpt is generated correctly from schema given HTML correctly uses excerpt separator 1`] = `
Object {
"excerpt": "<p>Where oh where <strong>is</strong> my little pony?</p>
",
}
`;

exports[`Excerpt is generated correctly from schema given MARKDOWN correctly uses excerpt separator 1`] = `
Object {
"excerpt": "Where oh where **is** my little pony?
",
}
`;

exports[`Excerpt is generated correctly from schema given PLAIN correctly uses excerpt separator 1`] = `
Object {
"excerpt": "Where oh where is my little pony?",
}
`;

exports[`Excerpt is generated correctly from schema given an html format, it correctly maps nested markdown to html 1`] = `
Object {
"excerpt": "<p>Where oh <a href=\\"nick.com\\"><em>where</em></a> <strong><em>is</em></strong> <img src=\\"pony.png\\" alt=\\"that pony\\">?</p>",
Expand Down
46 changes: 46 additions & 0 deletions packages/gatsby-transformer-remark/src/__tests__/extend-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,52 @@ In quis lectus sed eros efficitur luctus. Morbi tempor, nisl eget feugiat tincid
{ pluginOptions: { excerpt_separator: `<!-- end -->` } }
)

const contentWithSeparator = `---
title: "my little pony"
date: "2017-09-18T23:19:51.246Z"
---
Where oh where **is** my little pony?
<!-- end -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi auctor sit amet velit id facilisis. Nulla viverra, eros at efficitur pulvinar, lectus orci accumsan nisi, eu blandit elit nulla nec lectus. Integer porttitor imperdiet sapien. Quisque in orci sed nisi consequat aliquam. Aenean id mollis nisi. Sed auctor odio id erat facilisis venenatis. Quisque posuere faucibus libero vel fringilla.
In quis lectus sed eros efficitur luctus. Morbi tempor, nisl eget feugiat tincidunt, sem velit vulputate enim, nec interdum augue enim nec mauris. Nulla iaculis ante sed enim placerat pretium. Nulla metus odio, facilisis vestibulum lobortis vitae, bibendum at nunc. Donec sit amet efficitur metus, in bibendum nisi. Vivamus tempus vel turpis sit amet auctor. Maecenas luctus vestibulum velit, at sagittis leo volutpat quis. Praesent posuere nec augue eget sodales. Pellentesque vitae arcu ut est varius venenatis id maximus sem. Curabitur non consectetur turpis.
`

bootstrapTest(
`given PLAIN correctly uses excerpt separator`,
contentWithSeparator,
`excerpt(format: PLAIN)`,
node => {
expect(node).toMatchSnapshot()
expect(node.excerpt).toMatch(`Where oh where is my little pony?`)
},
{ pluginOptions: { excerpt_separator: `<!-- end -->` } }
)

bootstrapTest(
`given HTML correctly uses excerpt separator`,
contentWithSeparator,
`excerpt(format: HTML)`,
node => {
expect(node).toMatchSnapshot()
expect(node.excerpt).toMatch(
`<p>Where oh where <strong>is</strong> my little pony?</p>`
)
},
{ pluginOptions: { excerpt_separator: `<!-- end -->` } }
)

bootstrapTest(
`given MARKDOWN correctly uses excerpt separator`,
contentWithSeparator,
`excerpt(format: MARKDOWN)`,
node => {
expect(node).toMatchSnapshot()
expect(node.excerpt).toMatch(`Where oh where **is** my little pony?`)
},
{ pluginOptions: { excerpt_separator: `<!-- end -->` } }
)

const content = `---
title: "my little pony"
date: "2017-09-18T23:19:51.246Z"
Expand Down
112 changes: 88 additions & 24 deletions packages/gatsby-transformer-remark/src/extend-node-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,49 +409,112 @@ module.exports = (
return excerptAST
}

async function getExcerpt(
async function getExcerptHtml(
markdownNode,
{ format, pruneLength, truncate, excerptSeparator }
pruneLength,
truncate,
excerptSeparator
) {
if (format === `html`) {
const excerptAST = await getExcerptAst(markdownNode, {
pruneLength,
truncate,
excerptSeparator,
})
const html = hastToHTML(excerptAST, {
allowDangerousHTML: true,
})
return html
}
const excerptAST = await getExcerptAst(markdownNode, {
pruneLength,
truncate,
excerptSeparator,
})
const html = hastToHTML(excerptAST, {
allowDangerousHTML: true,
})
return html
}

if (markdownNode.excerpt) {
async function getExcerptMarkdown(
markdownNode,
pruneLength,
truncate,
excerptSeparator
) {
if (excerptSeparator) {
return markdownNode.excerpt
}
// TODO truncate respecting markdown AST
const excerptText = markdownNode.rawMarkdownBody
if (!truncate) {
return prune(excerptText, pruneLength, `…`)
}
return _.truncate(excerptText, {
length: pruneLength,
omission: `…`,
})
}

async function getExcerptPlain(
markdownNode,
pruneLength,
truncate,
excerptSeparator
) {
const text = await getAST(markdownNode).then(ast => {
let excerptNodes = []
visit(ast, node => {
if (node.type === `text` || node.type === `inlineCode`) {
excerptNodes.push(node.value)
}
if (node.type === `image`) {
excerptNodes.push(node.alt)
let isBeforeSeparator = true
visit(
ast,
node => isBeforeSeparator,
node => {
if (excerptSeparator && node.value === excerptSeparator) {
isBeforeSeparator = false
return
}
if (node.type === `text` || node.type === `inlineCode`) {
excerptNodes.push(node.value)
}
if (node.type === `image`) {
excerptNodes.push(node.alt)
}
}
return
})
)

const excerptText = excerptNodes.join(``)

if (excerptSeparator) {
return excerptText
}
if (!truncate) {
return prune(excerptNodes.join(``), pruneLength, `…`)
return prune(excerptText, pruneLength, `…`)
}
return _.truncate(excerptNodes.join(``), {
return _.truncate(excerptText, {
length: pruneLength,
omission: `…`,
})
})
return text
}

async function getExcerpt(
markdownNode,
{ format, pruneLength, truncate, excerptSeparator }
) {
if (format === `html`) {
return getExcerptHtml(
markdownNode,
pruneLength,
truncate,
excerptSeparator
)
} else if (format === `markdown`) {
return getExcerptMarkdown(
markdownNode,
pruneLength,
truncate,
excerptSeparator
)
}
return getExcerptPlain(
markdownNode,
pruneLength,
truncate,
excerptSeparator
)
}

const HeadingType = new GraphQLObjectType({
name: `MarkdownHeading`,
fields: {
Expand Down Expand Up @@ -487,6 +550,7 @@ module.exports = (
values: {
PLAIN: { value: `plain` },
HTML: { value: `html` },
MARKDOWN: { value: `markdown` },
},
})

Expand Down

0 comments on commit 4f72687

Please sign in to comment.