UNPKG

2.63 kBPlain TextView Raw
1import { SyntaxMap } from "./mapping/markdown-syntax-map";
2import { ASTNodeTypes, TxtNode } from "@textlint/ast-node-types";
3import traverse from "traverse";
4import debug0 from "debug";
5import { parseMarkdown } from "./parse-markdown";
6
7const debug = debug0("@textlint/markdown-to-ast");
8
9export { ASTNodeTypes as Syntax };
10
11/**
12 * parse markdown text and return ast mapped location info.
13 * @param {string} text
14 * @returns {TxtNode}
15 */
16export function parse<T extends TxtNode>(text: string): T {
17 // remark-parse's AST does not consider BOM
18 // AST's position does not +1 by BOM
19 // So, just trim BOM and parse it for `raw` property
20 // textlint's SourceCode also take same approach - trim BOM and check the position
21 // This means that the loading side need to consider BOM position - for example fs.readFile and text slice script.
22 // https://github.com/micromark/micromark/blob/0f19c1ac25964872a160d8b536878b125ddfe393/lib/preprocess.mjs#L29-L31
23 const hasBOM = text.charCodeAt(0) === 0xfeff;
24 const textWithoutBOM = hasBOM ? text.slice(1) : text;
25 const ast = parseMarkdown(textWithoutBOM);
26 traverse(ast).forEach(function (node: TxtNode) {
27 // eslint-disable-next-line no-invalid-this
28 if (this.notLeaf) {
29 if (node.type) {
30 const replacedType = SyntaxMap[node.type as keyof typeof SyntaxMap];
31 if (!replacedType) {
32 debug(`replacedType : ${replacedType} , node.type: ${node.type}`);
33 } else {
34 node.type = replacedType;
35 }
36 }
37 // map `range`, `loc` and `raw` to node
38 if (node.position) {
39 const position = node.position;
40 const positionCompensated = {
41 start: { line: position.start.line, column: Math.max(position.start.column - 1, 0) },
42 end: { line: position.end.line, column: Math.max(position.end.column - 1, 0) }
43 };
44 const range = [position.start.offset, position.end.offset] as [number, number];
45 node.loc = positionCompensated;
46 node.range = range;
47 node.raw = textWithoutBOM.slice(range[0], range[1]);
48 // Compatible for https://github.com/syntax-tree/unist, but it is hidden
49 Object.defineProperty(node, "position", {
50 enumerable: false,
51 configurable: false,
52 writable: false,
53 value: position
54 });
55 }
56 }
57 });
58 return ast as T;
59}