-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Initial support for MDX #179
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,6 +98,32 @@ function queryMarkdownDocs(graphql) { | |
}); | ||
} | ||
|
||
function queryMdxDocs(graphql) { | ||
return graphql( | ||
` | ||
{ | ||
allMdx { | ||
edges { | ||
node { | ||
fileAbsolutePath | ||
code { | ||
body | ||
} | ||
} | ||
} | ||
} | ||
} | ||
` | ||
).then(result => { | ||
if (result.errors) { | ||
/* eslint no-console: "off" */ | ||
console.log(result.errors); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no logger? |
||
throw new Error(result.errors); | ||
} | ||
return result; | ||
}); | ||
} | ||
|
||
// Walks all markdown nodes and creates a doc page for each node | ||
function createDocMarkdownPages({ graphql, actions }) { | ||
const { createPage } = actions; | ||
|
@@ -139,7 +165,50 @@ function createDocMarkdownPages({ graphql, actions }) { | |
}); | ||
} | ||
|
||
// Walks all markdown nodes and creates a doc page for each node | ||
function createDocMdxPages({ graphql, actions }) { | ||
const { createPage } = actions; | ||
|
||
return queryMdxDocs(graphql) | ||
.then(result => { | ||
// const rootFolder = result.data.site.siteMetadata.config.ROOT_FOLDER; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why comment it out? is that temporary? |
||
// const pathToSlug = result.data.allMarkdownRemark.edges.map(({ node }) => ({ | ||
// source: node.fileAbsolutePath, | ||
// target: node.fields.slug | ||
// })); | ||
|
||
// let relativeLinks = {}; | ||
// result.data.allMdx.edges.forEach(edge => { | ||
// pathToSlug.forEach(({ source, target }) => { | ||
// relativeLinks = addToRelativeLinks({ | ||
// source, | ||
// target, | ||
// rootFolder, | ||
// edge, | ||
// relativeLinks | ||
// }); | ||
// }); | ||
// }); | ||
|
||
result.data.allMdx.edges.forEach(edge => { | ||
console.log('Creating MDX page at', edge.node.fields.path); | ||
|
||
const componentUrl = getPageTemplateUrl('DOC_MDX_PAGE_URL'); | ||
|
||
createPage({ | ||
path: edge.node.fields.path, | ||
component: componentUrl, | ||
context: { | ||
// relativeLinks, | ||
slug: edge.node.fields.path, | ||
toc: 'docs' | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
module.exports = function createDocPages({ graphql, actions }) { | ||
createDocMarkdownPages({ graphql, actions }); | ||
createDocMdxPages({ graphql, actions }); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
module.exports.processNewMDXNode = function processNewMDXNode( | ||
{ node, actions, getNode }, | ||
docNodes, | ||
tocNode | ||
) { | ||
debugger | ||
console.log('MDX Node', JSON.stringify(node, null, 2)); | ||
/* | ||
const { createNodeField } = actions; | ||
|
||
const fileNode = getNode(node.parent); | ||
const parsedFilePath = path.parse(fileNode.relativePath); | ||
const hasTitle = | ||
Object.prototype.hasOwnProperty.call(node, 'frontmatter') && | ||
Object.prototype.hasOwnProperty.call(node.frontmatter, 'title'); | ||
|
||
let slug; | ||
if (hasTitle) { | ||
slug = `/${_.kebabCase(node.frontmatter.title)}`; | ||
} else if (parsedFilePath.name !== 'index' && parsedFilePath.dir !== '') { | ||
slug = `/${parsedFilePath.dir}/${parsedFilePath.name}/`; | ||
} else if (parsedFilePath.dir === '') { | ||
slug = `/${parsedFilePath.name}/`; | ||
} else { | ||
slug = `/${parsedFilePath.dir}/`; | ||
} | ||
|
||
/* | ||
if (Object.prototype.hasOwnProperty.call(node, 'frontmatter')) { | ||
if (Object.prototype.hasOwnProperty.call(node.frontmatter, 'slug')) | ||
slug = `/${_.kebabCase(node.frontmatter.slug)}`; | ||
if (Object.prototype.hasOwnProperty.call(node.frontmatter, 'date')) { | ||
const date = moment(node.frontmatter.date, siteConfig.dateFromFormat); | ||
if (!date.isValid) | ||
console.warn(`WARNING: Invalid date.`, node.frontmatter); | ||
|
||
createNodeField({ | ||
node, | ||
name: 'date', | ||
value: date.toISOString() | ||
}); | ||
} | ||
} | ||
|
||
// createNodeField({ node, name: 'slug', value: slug }); | ||
// postNodes.push(node); | ||
|
||
// Update path | ||
let relPath = node.fields.slug; | ||
if (node.fileAbsolutePath) { | ||
const index = node.fileAbsolutePath.indexOf('docs'); | ||
if (index !== -1) { | ||
relPath = node.fileAbsolutePath.slice(index); | ||
} | ||
|
||
// relPath = path.relative(siteConfig.ROOT_FOLDER, node.fileAbsolutePath); | ||
const basename = path.basename(relPath, '.md'); | ||
const dirname = path.dirname(relPath); | ||
relPath = basename === 'README' ? dirname : `${dirname}/${basename}`; | ||
|
||
createNodeField({ node, name: 'path', value: relPath }); | ||
createNodeField({ node, name: 'slug', value: relPath }); | ||
node.frontmatter.path = relPath; | ||
} | ||
if (tocNode) { | ||
// this means toc node has been created. Any markdown file processed beyond this point wouldn't have its info | ||
// in the toc. | ||
// but we can inject it afterwards | ||
|
||
// the regular toc node generation process adds the full content of each markdown node to the toc. | ||
// we don't need as much. The app will only use the title and slug of the corresponding markdown | ||
// node for each toc entry. | ||
|
||
const nodeToEdit = parseToc([tocNode], relPath); | ||
if (nodeToEdit) { | ||
nodeToEdit.childMarkdownRemark = { | ||
fields: { | ||
slug: relPath | ||
}, | ||
frontmatter: { | ||
title: node.frontmatter.title | ||
}, | ||
}; | ||
} | ||
log.log({ color: COLOR.YELLOW }, `putting ${relPath} back in the TOC`)(); | ||
} else { | ||
// while toc node isn't created, we can add the docs nodes to docNodes, which is used to add data to the TOC | ||
// once the toc node is created, there is no reason to keep doing that | ||
docNodes[relPath] = node; | ||
} | ||
*/ | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React from 'react'; | ||
import { graphql } from 'gatsby'; | ||
// import { MDXRenderer } from 'gatsby-mdx'; | ||
|
||
// Query for the markdown doc by slug | ||
// (Note: We could just search the allMarkdown from WebsiteConfig ourselves) | ||
export const query = graphql` | ||
query mdxDocById($id: String) { | ||
mdx(id: { eq: $id }) { | ||
code { | ||
body | ||
} | ||
} | ||
} | ||
`; | ||
|
||
// function replaceLinks(props) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI I'm considering extending this functionality to more elements for the "regular" doc file (ie replacing h1, h2, pre, table etc. DOM elements generated by markdown and whose styling depends on scss by styled components). |
||
// const { body } = props.data.mdx.code; | ||
// const { code, relativeLinks } = props.pageContext; | ||
|
||
// return html.replace(/href="([^"]+)"/g, (link, href) => { | ||
// // don't rewrite external links, don't rewrite links to anchors | ||
// if (href.startsWith('http') || href.startsWith('#')) { | ||
// // TODO - we could style them differently though | ||
// return link; | ||
// } | ||
// const hrefWithoutLeadingSlash = href.startsWith('/') ? href.slice(1) : href; | ||
// // replace links to: | ||
// // - known physical files, either relative to this file or relative to root | ||
// // - known routes, either relative to the route of this page or to the home page | ||
// // by a link to their corresponding route, expresed relative to the home page | ||
// return `href="${relativeLinks[hrefWithoutLeadingSlash]}"`; | ||
// }); | ||
// } | ||
|
||
export default class DocTemplate extends React.Component { | ||
constructor(props) { | ||
debugger | ||
super(props); | ||
this.state = { html: 'works' }; | ||
console.error('markdown rendering with props', JSON.stringify(this.props, null, 2)); | ||
} | ||
|
||
render() { | ||
const { html } = this.state; | ||
return ( | ||
<div> | ||
<div | ||
className="markdown-body" | ||
dangerouslySetInnerHTML={{ __html: html }} | ||
/> | ||
</div> | ||
); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just want to point out that this is precisely where ocular-gatsby is useful. existing sites just have to upgrade ocular-gatsby, not change their manual configurations or add new dependencies :)