-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
395 additions
and
203 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.