mirror of
https://github.com/fabe/gatsby-starter-deck.git
synced 2024-10-26 05:53:22 +03:00
Use Remark for Markdown Parsing (#12)
* Use remark for parsing markdown, enable local image embedding * Support loading multiple markdown files Closes #13
This commit is contained in:
parent
c7027370ba
commit
fd74d235f3
@ -38,7 +38,12 @@ $ yarn build
|
||||
|
||||
## Writing
|
||||
|
||||
###### [src/slides.md](src/slides.md)
|
||||
By default, use [src/slides/](src/slides/).
|
||||
|
||||
Markdown files are loaded in sorted path order. Slides are generated by
|
||||
splitting each markdown file along `<hr/>` elements (`---` in Markdown lingo).
|
||||
|
||||
Examples:
|
||||
|
||||
```md
|
||||
# This is the first slide
|
||||
@ -53,3 +58,4 @@ $ yarn build
|
||||
## Author
|
||||
|
||||
- Fabian Schultz ([@fschultz\_](https://twitter.com/fschultz_))
|
||||
- Frank Murphy ([AnIrishDuck](https://github.com/AnIrishDuck))
|
||||
|
@ -12,8 +12,27 @@ module.exports = {
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
options: {
|
||||
name: `slides`,
|
||||
path: `${__dirname}/src`,
|
||||
path: `${__dirname}/src/slides`,
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: `gatsby-transformer-remark`,
|
||||
options: {
|
||||
plugins: [
|
||||
`gatsby-remark-copy-images`,
|
||||
{
|
||||
resolve: `gatsby-remark-images`,
|
||||
options: {
|
||||
// It's important to specify the maxWidth (in pixels) of
|
||||
// the content container as this plugin uses this as the
|
||||
// base for generating different widths of each image.
|
||||
maxWidth: 1920,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
`gatsby-transformer-sharp`,
|
||||
`gatsby-plugin-sharp`,
|
||||
],
|
||||
};
|
||||
|
@ -1,56 +1,10 @@
|
||||
const path = require('path');
|
||||
const { createFilePath } = require('gatsby-source-filesystem')
|
||||
const remark = require('remark');
|
||||
const recommended = require('remark-preset-lint-recommended');
|
||||
const html = require('remark-html');
|
||||
const crypto = require('crypto');
|
||||
|
||||
exports.onCreateNode = ({
|
||||
node,
|
||||
actions,
|
||||
loadNodeContent,
|
||||
createNodeId,
|
||||
reporter,
|
||||
}) => {
|
||||
const { createNode } = actions;
|
||||
|
||||
if (
|
||||
node.internal.mediaType !== `text/markdown` &&
|
||||
node.internal.mediaType !== `text/x-markdown`
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const content = await loadNodeContent(node);
|
||||
const slides = content.split('---\n').map(body => body.trim());
|
||||
|
||||
slides.forEach((slide, index) => {
|
||||
remark()
|
||||
.use(recommended)
|
||||
.use(html)
|
||||
.process(slide, (err, file) => {
|
||||
const digest = crypto
|
||||
.createHash(`md5`)
|
||||
.update(String(file))
|
||||
.digest(`hex`);
|
||||
|
||||
createNode({
|
||||
id: createNodeId(`${node.id}_${index + 1} >>> Slide`),
|
||||
parent: node.id,
|
||||
children: [],
|
||||
internal: {
|
||||
type: `Slide`,
|
||||
contentDigest: digest,
|
||||
},
|
||||
html: String(file),
|
||||
index: index + 1,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
const _ = require('lodash')
|
||||
|
||||
// Remove trailing slash
|
||||
exports.onCreatePage = ({ page, actions }) => {
|
||||
@ -74,15 +28,16 @@ exports.onCreatePage = ({ page, actions }) => {
|
||||
};
|
||||
|
||||
// Create pages from markdown nodes
|
||||
exports.createPages = ({ actions, graphql }) => {
|
||||
const { createPage } = actions;
|
||||
exports.createPages = ({ actions, createNodeId, graphql }) => {
|
||||
const { createPage, createNode } = actions;
|
||||
const blogPostTemplate = path.resolve(`src/templates/slide.js`);
|
||||
|
||||
return graphql(`
|
||||
{
|
||||
allSlide {
|
||||
allMarkdownRemark {
|
||||
edges {
|
||||
node {
|
||||
fileAbsolutePath,
|
||||
html
|
||||
}
|
||||
}
|
||||
@ -93,9 +48,32 @@ exports.createPages = ({ actions, graphql }) => {
|
||||
return Promise.reject(result.errors);
|
||||
}
|
||||
|
||||
const slides = result.data.allSlide.edges;
|
||||
const slides = result.data.allMarkdownRemark.edges;
|
||||
slides.sort((a, b) => a.node.fileAbsolutePath > b.node.fileAbsolutePath ? 1 : -1)
|
||||
const nodes = slides.flatMap((s) => s.node.html.split('<hr>').map((html) => ({
|
||||
node: s.node, html
|
||||
})))
|
||||
|
||||
slides.forEach((slide, index) => {
|
||||
nodes.forEach(({ node, html }, index) => {
|
||||
const digest = crypto
|
||||
.createHash(`md5`)
|
||||
.update(html)
|
||||
.digest(`hex`);
|
||||
|
||||
createNode({
|
||||
id: createNodeId(`${node.id}_${index + 1} >>> Slide`),
|
||||
parent: node.id,
|
||||
children: [],
|
||||
internal: {
|
||||
type: `Slide`,
|
||||
contentDigest: digest,
|
||||
},
|
||||
html: html,
|
||||
index: index + 1,
|
||||
});
|
||||
})
|
||||
|
||||
nodes.forEach((slide, index) => {
|
||||
createPage({
|
||||
path: `/${index + 1}`,
|
||||
component: blogPostTemplate,
|
||||
|
@ -4,11 +4,18 @@
|
||||
"version": "2.0.0",
|
||||
"author": "Fabian Schultz <desk@fabianschultz.com>",
|
||||
"dependencies": {
|
||||
"gatsby": "^2.0.4",
|
||||
"gatsby": "^2.0.33",
|
||||
"gatsby-plugin-layout": "^1.0.1",
|
||||
"gatsby-plugin-offline": "^2.0.5",
|
||||
"gatsby-plugin-react-helmet": "^3.0.0",
|
||||
"gatsby-plugin-sharp": "^2.0.14",
|
||||
"gatsby-remark-copy-images": "^0.2.1",
|
||||
"gatsby-remark-copy-linked-files": "^2.0.7",
|
||||
"gatsby-remark-images": "^3.0.1",
|
||||
"gatsby-remark-relative-images": "^0.2.1",
|
||||
"gatsby-source-filesystem": "^2.0.1",
|
||||
"gatsby-transformer-remark": "^2.1.15",
|
||||
"gatsby-transformer-sharp": "^2.1.9",
|
||||
"react": "^16.5.1",
|
||||
"react-dom": "^16.5.1",
|
||||
"react-helmet": "^5.2.0",
|
||||
|
@ -50,6 +50,11 @@ html {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
#slide ul {
|
||||
text-align: left;
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--text);
|
||||
|
||||
|
@ -71,7 +71,7 @@ class TemplateWrapper extends Component {
|
||||
onSwipedRight={this.swipeRight}
|
||||
>
|
||||
<Transition location={location}>
|
||||
<div id="slide">{children}</div>
|
||||
<div id="slide" style={{'width': '100%'}}>{children}</div>
|
||||
</Transition>
|
||||
</Swipeable>
|
||||
</div>
|
||||
|
@ -4,7 +4,7 @@ Create presentations using Gatsby & React.
|
||||
|
||||
---
|
||||
|
||||
> Inscrutable icons litter the face of the devices even though the research
|
||||
> Inscrutable icons litter the face of the devices even though the research
|
||||
> community has long demonstrated that people cannot remember the meaning of
|
||||
> more than a small number of icons […] Who can remember what each icon
|
||||
> means? Not me.
|
||||
@ -23,12 +23,3 @@ Here's the source of the first slide:
|
||||
# Gatsby Deck
|
||||
|
||||
Create presentations using Gatsby & React.
|
||||
|
||||
---
|
||||
|
||||
![Monkey](//i.imgur.com/PnbINJ6.gif)
|
||||
|
||||
🌟 Star it on [GitHub](//github.com/fabe/gatsby-deck),
|
||||
or create your own with:
|
||||
|
||||
gatsby new my-slides https://github.com/fabe/gatsby-starter-deck
|
14
src/slides/02-outro.md
Normal file
14
src/slides/02-outro.md
Normal file
@ -0,0 +1,14 @@
|
||||
Images can be embedded from the local filesystem!
|
||||
|
||||
![xkcd on standards](./standards.png)
|
||||
|
||||
(attribution: xkcd.com)
|
||||
|
||||
---
|
||||
|
||||
![Monkey](//i.imgur.com/PnbINJ6.gif)
|
||||
|
||||
🌟 Star it on [GitHub](//github.com/fabe/gatsby-deck),
|
||||
or create your own with:
|
||||
|
||||
gatsby new my-slides https://github.com/fabe/gatsby-starter-deck
|
BIN
src/slides/standards.png
Normal file
BIN
src/slides/standards.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { graphql } from 'gatsby';
|
||||
|
||||
export default ({ data, transition }) => (
|
||||
<div>
|
||||
<div style={{'width': '100%'}}>
|
||||
<div
|
||||
style={transition && transition.style}
|
||||
dangerouslySetInnerHTML={{ __html: data.slide.html }}
|
||||
|
Loading…
Reference in New Issue
Block a user