mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
79 lines
2.2 KiB
JavaScript
79 lines
2.2 KiB
JavaScript
![]() |
import assert from "node:assert/strict";
|
||
|
// eslint-disable-next-line n/no-unpublished-import
|
||
|
import { parse, postprocess, preprocess } from "../micromark/exports.mjs";
|
||
|
|
||
|
/**
|
||
|
* Markdown token.
|
||
|
*
|
||
|
* @typedef {Object} Token
|
||
|
* @property {string} type Token type.
|
||
|
* @property {number} startLine Start line (1-based).
|
||
|
* @property {number} startColumn Start column (1-based).
|
||
|
* @property {number} endLine End line (1-based).
|
||
|
* @property {number} endColumn End column (1-based).
|
||
|
* @property {string} text Token text.
|
||
|
* @property {Token[]} tokens Child tokens.
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Parses a Markdown document and returns tokens.
|
||
|
*
|
||
|
* @param {string} markdown Markdown document.
|
||
|
* @returns {Token[]} Markdown tokens.
|
||
|
*/
|
||
|
function micromarkParse(markdown) {
|
||
|
|
||
|
// Use micromark to parse document into Events
|
||
|
const encoding = undefined;
|
||
|
const eol = true;
|
||
|
const options = undefined;
|
||
|
const chunks = preprocess()(markdown, encoding, eol);
|
||
|
const parseContext = parse(options).document().write(chunks);
|
||
|
const events = postprocess(parseContext);
|
||
|
|
||
|
// Create Token objects
|
||
|
const document = [];
|
||
|
let current = {
|
||
|
"tokens": document
|
||
|
};
|
||
|
const history = [ current ];
|
||
|
for (const event of events) {
|
||
|
const [ kind, token, context ] = event;
|
||
|
const { type, start, end, _container } = token;
|
||
|
const { "column": startColumn, "line": startLine } = start;
|
||
|
const { "column": endColumn, "line": endLine } = end;
|
||
|
// sliceSerialize throws when called for a _container
|
||
|
const text = _container ? null : context.sliceSerialize(token);
|
||
|
if (kind === "enter") {
|
||
|
const previous = current;
|
||
|
history.push(previous);
|
||
|
current = {
|
||
|
type,
|
||
|
startLine,
|
||
|
startColumn,
|
||
|
endLine,
|
||
|
endColumn,
|
||
|
text,
|
||
|
"tokens": []
|
||
|
};
|
||
|
previous.tokens.push(current);
|
||
|
} else if (kind === "exit") {
|
||
|
assert.equal(type, current.type);
|
||
|
assert.equal(startLine, current.startLine);
|
||
|
assert.equal(startColumn, current.startColumn);
|
||
|
assert.equal(endLine, current.endLine);
|
||
|
assert.equal(endColumn, current.endColumn);
|
||
|
assert.equal(text, current.text);
|
||
|
current = history.pop();
|
||
|
assert.ok(current, "Empty history");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Return document
|
||
|
return document;
|
||
|
}
|
||
|
|
||
|
export {
|
||
|
micromarkParse as parse
|
||
|
};
|