Skip to content

Commit

Permalink
Merge d70316a into c849d21
Browse files Browse the repository at this point in the history
  • Loading branch information
mrzmmr committed Sep 23, 2018
2 parents c849d21 + d70316a commit 3380c0f
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 203 deletions.
37 changes: 0 additions & 37 deletions example/example.js

This file was deleted.

10 changes: 7 additions & 3 deletions example/example.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
+++
title = "Hello World!"
+++
---
title: 'Example'
list:
- one
- 0
- false
---

# Other markdown
19 changes: 19 additions & 0 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
var unified = require('unified')
var parser = require('remark-parse')
var compiler = require('remark-stringify')
var frontmatter = require('remark-frontmatter')
var reporter = require('vfile-reporter')
var toVfile = require('to-vfile')
var yaml = require('yaml').parse
var extract = require('..')

unified()
.use(parser)
.use(compiler)
.use(frontmatter)
.use(extract, yaml)
.process(toVfile.readSync('./example.md'), function (err, file) {
console.error(reporter(err || file))
console.log(file.toString())
console.log(file.data)
})
5 changes: 2 additions & 3 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
"name": "remark-extract-frontmatter-example",
"dependencies": {
"remark-frontmatter": "^1.2.1",
"remark-html": "^8.0.0",
"remark-parse": "^5.0.0",
"remark-stringify": "^5.0.0",
"to-vfile": "^5.0.1",
"toml": "^2.3.3",
"unified": "^7.0.0"
"unified": "^7.0.0",
"vfile-reporter": "^5.0.0"
}
}
197 changes: 176 additions & 21 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,184 @@
const frontmatter = (tree, options) => {
const parser = (options || {}).parser || (v => v)
const type = (options || {}).type || 'yaml'
const {children} = tree
const data = []
let i = -1
let child

while (++i < children.length - 1) {
child = children[i]

if (child.type && child.type === type) {
data.push(parser(child.value))
module.exports = extract

var xtend = require('xtend')

function extract (options) {
var blockTokenizers
var blockMethods
var tokenizer
var parsers
var methods
var method
var parse
var name
var index
var i

options = settings(options)

if (!options || !options.parsers) {
return
}

parsers = options.parsers
parser = this.Parser

if (isParser(parser)) {
proto = parser.prototype
blockTokenizers = proto.blockTokenizers
blockMethods = proto.blockMethods
methods = locate(blockMethods)

if (!methods || methods.length < 1) {
return
}

index = blockMethods.indexOf(methods[0])
i = -1

while (++i < methods.length){
/**
* Block method to identify tokenizer
*/
method = methods[i]
/**
* Name of the parser for frontmatter, e.g. "yaml"
*/
name = method.replace('FrontMatter', '')
/**
* Actual function to parse frontmatter, e.g. `yaml.parse`
*/
parse = parsers[name]
/**
* The tokenizer to decorate
*/
tokenizer = blockTokenizers[method]
/**
* Only decorate if a parser was given
*/
if (parse) {
/**
* Replace Tokenizer with decorated tokenizer
*/
blockTokenizers[method] = decorate(tokenizer, parse, name, options)
}
}
}
}

/**
* Returns a decorator for blockTokenizer
* tokenizer - The tokenizer to decorate, e.g. yamlFrontMatter
* parse - A parse function to run on found frontmatter, e.g. `yamljs.parse`
* name - The name of type of frontmatter to be parsed, e.g. "yaml"
* options - Any options to use
*/
function decorate (tokenizer, parse, name, options) {
return decorator

function decorator (eat, value, silent) {
var node = tokenizer(eat, value, silent)
var file = this.file
var frontmatter
var data


if (node && node.value) {
try {
frontmatter = parse(node.value)

if (options.name) {
file.data[options.name] = file.data[options.name] || {}
file.data[options.name] = xtend({}, file.data[options.name], frontmatter)
} else {
file.data = xtend({}, file.data, frontmatter)
}
} catch (err) {
error(err, file, name, options)
}

return node
}
}
}

/**
* Handles errors such as creating a new `vfile.message` when parsing fails
* err - The Error object produced
* name - The name of type of frontmatter, e.g. 'yaml'
* options - Any options
*/
function error (err, file, name, options) {
var message = err.message
var column = err.column
var line = err.line
var type = err.name
var method = 'message'

if (options.throws) {
method = 'fail'
}

return data
file[method](
message,
{ line: line, column: column },
'parseFrontMatter:' + name + ':' + type
)
}

module.exports = options => (tree, file) => {
const data = frontmatter(tree, options)
if (file.data.frontmatter) {
file.data.frontmatter = [ ...file.data.frontmatter, ...data ]
} else {
file.data.frontmatter = data

/**
* Locate any frontMatter methods that have been attatched to the Parser
* methods - A list of blockMethods, e.g. [ "yamlFrontMatter" ]
*/
function locate (methods) {
var found = []
var i = -1

while (++i < methods.length) {
if (methods[i] && methods[i].match(/FrontMatter$/)) {
found.push(methods[i])
}
}

return found
}

module.exports.frontmatter = frontmatter
/**
* Formats options passed. If options is a function then assume its a yaml
* parser. Any keys other than the known options, `name`, `throws` are
* assumed to be a parser type and put in `parsers`
*
* options - Object of options, or a function to parse frontmatter
* options.throws - Boolean whether to throw when there's an error or not
* options.name - The name to store parsed frontmatter as in
*/
function settings (options) {
var parsers
var throws
var name

if (options && typeof options === 'function') {
options = { yaml: options }
}

if (options && typeof options === 'object' && !Array.isArray(options)) {
throws = options.throws || false
name = options.name || null
delete options.throws
delete options.name
}

parsers = options
options = {
parsers: parsers,
throws: throws,
name: name
}

return options
}

function isParser (parser) {
return Boolean(parser && parser.prototype && parser.prototype.blockMethods)
}
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "remark-extract-frontmatter",
"version": "1.1.1",
"version": "2.0.0",
"description": "Stores front matter from markdown in VFiles data property",
"main": "index.js",
"scripts": {
Expand All @@ -15,8 +15,10 @@
},
"keywords": [
"remark",
"plugin",
"frontmatter",
"plugin",
"yaml",
"toml",
"markdown"
],
"author": "Paul Zimmer",
Expand All @@ -33,7 +35,11 @@
"remark-stringify": "^5.0.0",
"rimraf": "^2.6.2",
"tap": "^12.0.1",
"toml": "^2.3.3",
"unified": "^7.0.0",
"yamljs": "^0.3.0"
"yaml": "^1.0.0"
},
"dependencies": {
"xtend": "^4.0.1"
}
}

0 comments on commit 3380c0f

Please sign in to comment.