@ztl-uwu/nuxt-content
Version:
Write your content inside your Nuxt app
204 lines (203 loc) • 5.05 kB
JavaScript
import { toString } from "mdast-util-to-string";
import { preprocess, postprocess } from "micromark";
import { stringifyPosition } from "unist-util-stringify-position";
import { parse } from "./parser.js";
const own = {}.hasOwnProperty;
const initialPoint = {
line: 1,
column: 1,
offset: 0
};
export const fromCSV = function(value, encoding, options) {
if (typeof encoding !== "string") {
options = encoding;
encoding = void 0;
}
return compiler()(
postprocess(
parse(options).write(preprocess()(value, encoding, true))
)
);
};
function compiler() {
const config = {
enter: {
column: opener(openColumn),
row: opener(openRow),
data: onenterdata,
quotedData: onenterdata
},
exit: {
row: closer(),
column: closer(),
data: onexitdata,
quotedData: onexitQuotedData
}
};
return compile;
function compile(events) {
const tree = {
type: "root",
children: []
};
const stack = [tree];
const tokenStack = [];
const context = {
stack,
tokenStack,
config,
enter,
exit,
resume
};
let index = -1;
while (++index < events.length) {
const handler = config[events[index][0]];
if (own.call(handler, events[index][1].type)) {
handler[events[index][1].type].call(
Object.assign(
{
sliceSerialize: events[index][2].sliceSerialize
},
context
),
events[index][1]
);
}
}
if (tokenStack.length > 0) {
const tail = tokenStack[tokenStack.length - 1];
const handler = tail[1] || defaultOnError;
handler.call(context, void 0, tail[0]);
}
tree.position = {
start: point(
events.length > 0 ? events[0][1].start : initialPoint
),
end: point(
events.length > 0 ? events[events.length - 2][1].end : initialPoint
)
};
return tree;
}
function point(d) {
return {
line: d.line,
column: d.column,
offset: d.offset
};
}
function opener(create, and) {
return open;
function open(token) {
enter.call(this, create(token), token);
if (and) {
and.call(this, token);
}
}
}
function enter(node, token, errorHandler) {
const parent = this.stack[this.stack.length - 1];
parent.children.push(node);
this.stack.push(node);
this.tokenStack.push([token, errorHandler]);
node.position = {
start: point(token.start)
};
return node;
}
function closer(and) {
return close;
function close(token) {
if (and) {
and.call(this, token);
}
exit.call(this, token);
}
}
function exit(token, onExitError) {
const node = this.stack.pop();
const open = this.tokenStack.pop();
if (!open) {
throw new Error(
"Cannot close `" + token.type + "` (" + stringifyPosition({
start: token.start,
end: token.end
}) + "): it\u2019s not open"
);
} else if (open[0].type !== token.type) {
if (onExitError) {
onExitError.call(this, token, open[0]);
} else {
const handler = open[1] || defaultOnError;
handler.call(this, token, open[0]);
}
}
node.position.end = point(token.end);
return node;
}
function resume() {
return toString(this.stack.pop());
}
function onenterdata(token) {
const parent = this.stack[this.stack.length - 1];
let tail = parent.children[parent.children.length - 1];
if (!tail || tail.type !== "text") {
tail = text();
tail.position = {
start: point(token.start)
};
parent.children.push(tail);
}
this.stack.push(tail);
}
function onexitdata(token) {
const tail = this.stack.pop();
tail.value += this.sliceSerialize(token).trim().replace(/""/g, '"');
tail.position.end = point(token.end);
}
function onexitQuotedData(token) {
const tail = this.stack.pop();
const value = this.sliceSerialize(token);
tail.value += this.sliceSerialize(token).trim().substring(1, value.length - 1).replace(/""/g, '"');
tail.position.end = point(token.end);
}
function text() {
return {
type: "text",
value: ""
};
}
function openColumn() {
return {
type: "column",
children: []
};
}
function openRow() {
return {
type: "row",
children: []
};
}
}
function defaultOnError(left, right) {
if (left) {
throw new Error(
"Cannot close `" + left.type + "` (" + stringifyPosition({
start: left.start,
end: left.end
}) + "): a different token (`" + right.type + "`, " + stringifyPosition({
start: right.start,
end: right.end
}) + ") is open"
);
} else {
throw new Error(
"Cannot close document, a token (`" + right.type + "`, " + stringifyPosition({
start: right.start,
end: right.end
}) + ") is still open"
);
}
}