micromark / micromark-extension-frontmatter

micromark extension to support frontmatter (YAML, TOML, etc)
https://unifiedjs.com
MIT License
19 stars 2 forks source link

Calling twice mdast-util-from-markdown with micromark-extension-frontmatter returns frontmatter only for the first file #1

Closed crystalfp closed 4 years ago

crystalfp commented 4 years ago

Subject of the issue

Calling mdast-util-from-markdown with mdast-util-frontmatter and micromark-extension-frontmatter twice in sequence returns YAML front matter only for the first file.

Your environment

Steps to reproduce

var fs = require('fs')
var fromMarkdown = require('mdast-util-from-markdown')
var syntax = require('micromark-extension-frontmatter')
var frontmatter = require('mdast-util-frontmatter')

const options0 = {
    extensions: [syntax({type: "yaml", marker: {open: "-", close: "."}})],
    mdastExtensions: [frontmatter.fromMarkdown(["yaml"])]
};
const options1 = {
    extensions: [syntax({type: "yaml", marker: {open: "-", close: "."}})],
    mdastExtensions: [frontmatter.fromMarkdown(["yaml"])]
};
const options2 = {
    extensions: [syntax({type: "yaml", marker: {open: "-", close: "."}})],
    mdastExtensions: [options0.mdasExtensions[0]]
};
const options3 = {
    extensions: [options0.extensions[0]],
    mdastExtensions: [frontmatter.fromMarkdown(["yaml"])]
};
const doc = fs.readFileSync("example.md", "utf-8");
const t1 = fromMarkdown(doc, options0);
console.log(JSON.stringify(t1, undefined, 2));
const t2 = fromMarkdown(doc, options0); // see below
console.log(JSON.stringify(t2, undefined, 2));

The input file example.md contains:

---
title: 'CouchDB tool'
type: ToDo
status: Hot
...

# CouchDB to do
Split long text blocks

Does not matter if the two fromMarkdown() are called with the same or with different inputs.

Expected behavior

Both parse should return a block of "type": "yaml".

Actual behavior

1) Calling both fromMarkdown() with options0 fails. The yaml block from the first file is parsed as "type": "yaml" as it should. Instead the second time it is parsed as "type": "thematicBreak" + "type": "paragraph" 2) Calling second fromMarkdown() with options1 succeeds (completely separated option objects) 3) Calling second fromMarkdown() with options2 succeeds (they share the call to mdast-util-frontmatter) 3) Calling second fromMarkdown() with options3 fails (they share the call to micromark-extension-frontmatter) as case 1. This seems to point to something not reset in syntax(), but equally could be a problem with mdast-util-from-markdown for which fromMarkdown() does not re-initialize extensions at each call.

crystalfp commented 4 years ago

Workaround. Call both fromMarkdown() with the same option object. But before the second call add:

options.extensions[0] = syntax({type: "yaml", marker: {open: "-", close: "."}});

I don't like it, options should not carry status in my opinion, but at least I can continue with my experiments.

wooorm commented 4 years ago

Thanks that helped, pretty deep down, but working on a fix!

crystalfp commented 4 years ago

Tested. It works without my workaround! Thanks!