Skip to content

Instantly share code, notes, and snippets.

@endiliey
Last active November 11, 2019 16:43
Show Gist options
  • Save endiliey/c1a323f4f817d6147bca5c6cb1cc3171 to your computer and use it in GitHub Desktop.
Save endiliey/c1a323f4f817d6147bca5c6cb1cc3171 to your computer and use it in GitHub Desktop.
Get the frontmatter and first non empty line content from a file
const Benchmark = require("benchmark");
const fm = require("front-matter");
const fs = require("fs-extra");
const glob = require("glob");
const path = require("path");
const readlinestream = require("./stream");
const matter = require("gray-matter");
async function grayMatter(fixtures) {
await Promise.all(
fixtures.map(async fixture => {
const string = await fs.readFile(fixture, "utf8");
return matter(string);
})
);
}
async function frontMatter(fixtures) {
await Promise.all(
fixtures.map(async fixture => {
const string = await fs.readFile(fixture, "utf8");
return fm(string);
})
);
}
async function linebyline(fixtures) {
await Promise.all(
fixtures.map(async fixture => {
const result = await readlinestream(fixture);
return result;
})
);
}
const fixturePaths = glob.sync(path.join(__dirname, "fixtures", "*.md"));
const suite = new Benchmark.Suite();
suite
.add("gray matter", {
defer: true,
fn: function(deferred) {
grayMatter(fixturePaths).then(data => {
deferred.resolve();
});
}
})
.add("line by line", {
defer: true,
fn: function(deferred) {
linebyline(fixturePaths).then(data => {
deferred.resolve();
});
}
})
.add("front matter", {
defer: true,
fn: function(deferred) {
frontMatter(fixturePaths).then(data => {
deferred.resolve();
});
}
})
// add listeners
.on("cycle", function(event) {
console.log(String(event.target));
})
.on("complete", function() {
console.log("Fastest is " + this.filter("fastest").map("name"));
})
.run({ async: true });
const path = require("path");
const fs = require("fs-extra");
const readline = require("readline");
const { once } = require("events");
const matter = require("gray-matter");
async function parseStream(filepath, limit = 32 * 1024) {
try {
const {size} = await fs.stat(filepath)
if (size <= limit) {
const string = await fs.readFile(filepath, 'utf8');
return matter(string);
}
// console.log(path.basename(filepath), "->", size);
const stream = fs.createReadStream(filepath, {
encoding: "utf8",
start: 0,
end: Math.ceil(0.1 * limit),
});
const rl = readline.createInterface({
input: stream,
crlfDelay: Infinity
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
let acc = [];
let count = 0;
// Only get content until frontmatter is closed and until first non empty line string
rl.on("line", line => {
acc.push(line);
// first non empty line content
if (count === 2 && !line.length > 0) {
rl.close();
rl.removeAllListeners();
stream.destroy();
return;
}
if (line.indexOf("---") === 0) {
count += 1;
}
});
await once(rl, "close");
return matter(acc.join("\n"));
} catch (err) {
console.error(err);
}
}
// parseStream("./example/with-data.md").then(data => console.log(data))
module.exports = parseStream;
// const file = path.join(__dirname, "fixtures/_lumin_.audionode.md");
// const { performance } = require("perf_hooks");
// let t0 = performance.now();
// parseStream(file).then(data => {
// console.log(data);
// console.log(performance.now() - t0);
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment