Skip to content

Instantly share code, notes, and snippets.

@elmasse
Last active July 2, 2018 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elmasse/0f7abf60f98427abb9157e375b558eba to your computer and use it in GitHub Desktop.
Save elmasse/0f7abf60f98427abb9157e375b558eba to your computer and use it in GitHub Desktop.
nextein-plugin-markdown-from-git
const fetch = require('isomorphic-fetch')
const fm = require('frontmatter')
const { readFileSync, statSync } = require('fs')
const { resolve, basename, extname, relative, dirname, sep } = require('path')
const pathToRegEx = require('path-to-regexp')
const parser = require('./parser')
module.exports = {
source : async ({ extension = 'md', entriesDir = ['posts'], remark = [], rehype = [] } = {}) => {
let all = []
for (const dir of entriesDir) {
const res = await fetch('https://api.github.com/repos/elmasse/nextein-www/git/trees/master?recursive=1')
const { tree = []} = await res.json()
const files = tree.filter(e => e.path.match(/^posts\/.*md$/))
const content = await Promise.all(
files
.map(async (file) => {
const res = await fetch(`https://raw.githubusercontent.com/elmasse/nextein-www/master/${file.path}`)
return await res.text()
})
)
return content
.map(a => { console.log(a); return a })
.map(fm)
.map(addEntry(files))
.map(addPage)
.map(addName)
.map(addCategory(dir))
.map(addDate)
.map(addUrl)
.map(parse({remark, rehype}))
}
}
}
const parse = (options) => (value) => {
const { content } = value
const instance = parser(options)
return {
...value,
content: instance.runSync(instance.parse(content)),
raw: content
}
}
const addPage = (value, idx) => {
const { data } = value
const { page = 'post' } = data
return { ...value, data: { ...data, page: 'post' } }
}
const addEntry = (paths) => (value, idx) => {
const { data } = value
return { ...value, data: { ...data, _entry: paths[idx].path } }
}
const addName = (value) => {
const { data } = value
return { ...value, data: { ...data, name: createEntryName({ ...data }) } }
}
const addCategory = (entriesPath) => (value) => {
const { data } = value
return { ...value, data: { ...data, category: createEntryCategory({ entriesPath, ...data }) } }
}
const addUrl = (value) => {
const { data } = value
return { ...value, data: { ...data, url: createEntryURL({ ...data }) } }
}
const addDate = (value) => {
const { data } = value
return { ...value, data: { ...data, date: new Date().toJSON()} }
}
const DATE_IN_FILE_REGEX = /^(\d{4}-\d{2}-\d{2})-(.+)$/
const DATE_MATCH_INDEX = 1
const NAME_MATCH_INDEX = 2
const DEFAULT_PERMALINK = '/:category?/:name'
const PERMALINK_CATEGORIES = ':category(.*)'
const extractFileName = (path) => basename(path, extname(path))
const createEntryName = ({ _entry }) => {
const name = extractFileName(_entry)
const match = name.match(DATE_IN_FILE_REGEX)
return (match) ? match[NAME_MATCH_INDEX] : name
}
const createEntryURL = (data) => {
const { page, date, permalink = DEFAULT_PERMALINK } = data
const toUrl = pathToRegEx.compile(permalink.replace(':category', PERMALINK_CATEGORIES))
const url = toUrl({ ...data, date: date.replace(/T.*Z/, '') }, { encode: v => v })
return page ? url : undefined
}
const createEntryDate = ({ _entry, date }) => {
const name = extractFileName(_entry)
const match = name.match(DATE_IN_FILE_REGEX)
return (date ? new Date(date) : (match) ? new Date(match[DATE_MATCH_INDEX]) : fileCreationDate(_entry)).toJSON()
}
const fileCreationDate = (path) => {
const { birthtime } = statSync(path)
return birthtime
}
const createEntryCategory = ({ entriesPath, category, _entry }) => {
if (category) return category
const categorySeparator = '/'
const root = resolve(process.cwd(), entriesPath)
const post = resolve(process.cwd(), _entry)
const folderCategory = relative(root, dirname(post)).replace(sep, categorySeparator)
return folderCategory || undefined
}
// export const transform = (options = OPTIONS, post) => {
// }
const unified = require('unified')
const markdown = require('remark-parse')
const remark2rehype = require('remark-rehype')
const raw = require('rehype-raw')
module.exports = ({ remark, rehype }) => unified()
.use(markdown)
.use(remark.map(mapPlugin))
.use(remark2rehype, { allowDangerousHTML: true })
.use(rehype.map(mapPlugin))
.use(raw)
const mapPlugin = p => {
if (Array.isArray(p)) {
const [ name, options ] = p
return [require(name), options]
}
return require(p)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment