Add location information to parseFrontMatter() (#17948)
This commit is contained in:
1 parent
6df61307be
commit
4ec2648e61
12 files changed
+93
-40
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import cleanFrontMatter from "../utils/front-matter/clean.js";
|
||||
import isFrontMatter from "../utils/front-matter/is-front-matter.js";
|
||||
|
||||
const ignoredProperties = new Set([
|
||||
@@ -12,9 +13,7 @@ const ignoredProperties = new Set([
|
||||
]);
|
||||
|
||||
function clean(original, cloned, parent) {
|
||||
if (isFrontMatter(original) && original.language === "yaml") {
|
||||
delete cloned.value;
|
||||
}
|
||||
cleanFrontMatter(original, cloned);
|
||||
|
||||
if (
|
||||
original.type === "css-comment" &&
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { hardline } from "../document/builders.js";
|
||||
import isFrontMatter from "../utils/front-matter/is-front-matter.js";
|
||||
import printFrontMatter from "../utils/front-matter/print.js";
|
||||
|
||||
function embed(path) {
|
||||
const { node } = path;
|
||||
|
||||
if (node.type === "front-matter") {
|
||||
if (isFrontMatter(node) && node.language === "yaml") {
|
||||
return async (textToDoc) => {
|
||||
const doc = await printFrontMatter(node, textToDoc);
|
||||
return doc ? [doc, hardline] : undefined;
|
||||
|
||||
@@ -377,14 +377,12 @@ function parseNestedCSS(node, options) {
|
||||
}
|
||||
|
||||
function parseWithParser(parse, text, options) {
|
||||
const parsed = parseFrontMatter(text);
|
||||
const { frontMatter } = parsed;
|
||||
text = parsed.content;
|
||||
const { frontMatter, content: textToParse } = parseFrontMatter(text);
|
||||
|
||||
let result;
|
||||
|
||||
try {
|
||||
result = parse(text, {
|
||||
result = parse(textToParse, {
|
||||
// Prevent file access https://github.com/postcss/postcss/blob/4f4e2932fc97e2c117e1a4b15f0272ed551ed59d/lib/previous-map.js#L18
|
||||
map: false,
|
||||
});
|
||||
@@ -407,11 +405,13 @@ function parseWithParser(parse, text, options) {
|
||||
calculateLoc(result, text);
|
||||
|
||||
if (frontMatter) {
|
||||
frontMatter.source = {
|
||||
startOffset: 0,
|
||||
endOffset: frontMatter.raw.length,
|
||||
result.frontMatter = {
|
||||
...frontMatter,
|
||||
source: {
|
||||
startOffset: frontMatter.start.index,
|
||||
endOffset: frontMatter.end.index,
|
||||
},
|
||||
};
|
||||
result.frontMatter = frontMatter;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import isFrontMatter from "../utils/front-matter/is-front-matter.js";
|
||||
import cleanFrontMatter from "../utils/front-matter/clean.js";
|
||||
|
||||
const ignoredProperties = new Set([
|
||||
"sourceSpan",
|
||||
@@ -28,13 +28,10 @@ function clean(original, cloned) {
|
||||
return null;
|
||||
}
|
||||
|
||||
cleanFrontMatter(original, cloned);
|
||||
|
||||
// may be formatted by multiparser
|
||||
if (
|
||||
isFrontMatter(original) ||
|
||||
original.type === "yaml" ||
|
||||
original.type === "toml"
|
||||
) {
|
||||
delete cloned.raw;
|
||||
if (original.type === "yaml") {
|
||||
delete cloned.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,10 @@ function embed(path, options) {
|
||||
return printAttribute(path, options);
|
||||
|
||||
case "front-matter":
|
||||
return (textToDoc) => printFrontMatter(node, textToDoc);
|
||||
if (node.language === "yaml") {
|
||||
return (textToDoc) => printFrontMatter(node, textToDoc);
|
||||
}
|
||||
break;
|
||||
|
||||
case "angularControlFlowBlockParameters":
|
||||
if (!embeddedAngularControlFlowBlocks.has(path.parent.name)) {
|
||||
|
||||
@@ -21,7 +21,7 @@ import HTML_TAGS from "./utils/html-tags.evaluate.js";
|
||||
import isUnknownNamespace from "./utils/is-unknown-namespace.js";
|
||||
|
||||
/**
|
||||
* @import AngularHtmlParser, {ParseOptions as AngularHtmlParserParseOptions} from "angular-html-parser"
|
||||
* @import {ParseOptions as AngularHtmlParserParseOptions} from "angular-html-parser"
|
||||
* @import {Node as AstNode, Attribute, Element} from "angular-html-parser/lib/compiler/src/ml_parser/ast.js"
|
||||
* @import {ParseTreeResult} from "angular-html-parser/lib/compiler/src/ml_parser/parser.js"
|
||||
*/
|
||||
@@ -348,7 +348,7 @@ function parse(
|
||||
options = {},
|
||||
shouldParseFrontMatter = true,
|
||||
) {
|
||||
const { frontMatter, content } = shouldParseFrontMatter
|
||||
const { frontMatter, content: textToParse } = shouldParseFrontMatter
|
||||
? parseFrontMatter(text)
|
||||
: { frontMatter: null, content: text };
|
||||
|
||||
@@ -358,15 +358,24 @@ function parse(
|
||||
const rawAst = {
|
||||
type: "root",
|
||||
sourceSpan: new ParseSourceSpan(start, end),
|
||||
children: ngHtmlParser(content, parseOptions, options),
|
||||
children: ngHtmlParser(textToParse, parseOptions, options),
|
||||
};
|
||||
|
||||
if (frontMatter) {
|
||||
const start = new ParseLocation(file, 0, 0, 0);
|
||||
const end = start.moveBy(frontMatter.raw.length);
|
||||
frontMatter.sourceSpan = new ParseSourceSpan(start, end);
|
||||
const [start, end] = [frontMatter.start, frontMatter.end].map(
|
||||
(location) =>
|
||||
new ParseLocation(
|
||||
file,
|
||||
location.index,
|
||||
location.line - 1,
|
||||
location.column,
|
||||
),
|
||||
);
|
||||
// @ts-expect-error -- not a real AstNode
|
||||
rawAst.children.unshift(frontMatter);
|
||||
rawAst.children.unshift({
|
||||
...frontMatter,
|
||||
sourceSpan: new ParseSourceSpan(start, end),
|
||||
});
|
||||
}
|
||||
|
||||
const ast = new Node(rawAst);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import collapseWhiteSpace from "collapse-white-space";
|
||||
import cleanFrontMatter from "../utils/front-matter/clean.js";
|
||||
import isFrontMatter from "../utils/front-matter/is-front-matter.js";
|
||||
import { FORMAT_PRAGMAS } from "../utils/pragma/pragma.evaluate.js";
|
||||
import { startWithPragma } from "./pragma.js";
|
||||
@@ -10,7 +11,6 @@ const ignoredProperties = new Set([
|
||||
function clean(original, cloned, parent) {
|
||||
// for codeblock
|
||||
if (
|
||||
original.type === "front-matter" ||
|
||||
original.type === "code" ||
|
||||
original.type === "yaml" ||
|
||||
original.type === "import" ||
|
||||
@@ -20,6 +20,8 @@ function clean(original, cloned, parent) {
|
||||
delete cloned.value;
|
||||
}
|
||||
|
||||
cleanFrontMatter(original, cloned);
|
||||
|
||||
if (original.type === "list") {
|
||||
delete cloned.isAligned;
|
||||
}
|
||||
|
||||
@@ -90,10 +90,7 @@ function genericPrint(path, options, print) {
|
||||
|
||||
switch (node.type) {
|
||||
case "front-matter":
|
||||
return options.originalText.slice(
|
||||
node.position.start.offset,
|
||||
node.position.end.offset,
|
||||
);
|
||||
return node.raw;
|
||||
case "root":
|
||||
/* c8 ignore next 3 */
|
||||
if (node.children.length === 0) {
|
||||
|
||||
@@ -11,10 +11,10 @@ const frontMatter = function () {
|
||||
proto.blockTokenizers.frontMatter = tokenizer;
|
||||
|
||||
function tokenizer(eat, value) {
|
||||
const parsed = parseFrontMatter(value);
|
||||
const { frontMatter } = parseFrontMatter(value);
|
||||
|
||||
if (parsed.frontMatter) {
|
||||
return eat(parsed.frontMatter.raw)(parsed.frontMatter);
|
||||
if (frontMatter) {
|
||||
return eat(frontMatter.raw)(frontMatter);
|
||||
}
|
||||
}
|
||||
tokenizer.onlyAtStart = true;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import isFrontMatter from "./is-front-matter.js";
|
||||
|
||||
function clean(original, cloned) {
|
||||
if (isFrontMatter(original) && original.language === "yaml") {
|
||||
delete cloned.end;
|
||||
delete cloned.raw;
|
||||
delete cloned.value;
|
||||
}
|
||||
}
|
||||
|
||||
export default clean;
|
||||
@@ -1,5 +1,24 @@
|
||||
const DELIMITER_LENGTH = 3;
|
||||
|
||||
/**
|
||||
@typedef {{index: number, line: number, column: number}} Position
|
||||
@typedef {{
|
||||
type: "front-matter",
|
||||
language: string,
|
||||
explicitLanguage: string | null,
|
||||
value: string,
|
||||
startDelimiter: string,
|
||||
endDelimiter: string,
|
||||
raw: string,
|
||||
start: Position,
|
||||
end: Position,
|
||||
}} FrontMatter
|
||||
*/
|
||||
|
||||
/**
|
||||
@param {string} text
|
||||
@returns {FrontMatter | undefined}
|
||||
*/
|
||||
function getFrontMatter(text) {
|
||||
const startDelimiter = text.slice(0, DELIMITER_LENGTH);
|
||||
|
||||
@@ -48,15 +67,29 @@ function getFrontMatter(text) {
|
||||
}
|
||||
|
||||
const raw = text.slice(0, frontMatterEndIndex);
|
||||
/** @type {string[]} */
|
||||
let lines;
|
||||
|
||||
return {
|
||||
type: "front-matter",
|
||||
language,
|
||||
explicitLanguage,
|
||||
explicitLanguage: explicitLanguage || null,
|
||||
value: text.slice(firstLineBreakIndex + 1, endDelimiterIndex),
|
||||
startDelimiter,
|
||||
endDelimiter: raw.slice(-DELIMITER_LENGTH),
|
||||
raw,
|
||||
start: { line: 1, column: 0, index: 0 },
|
||||
end: {
|
||||
index: raw.length,
|
||||
get line() {
|
||||
lines ??= raw.split("\n");
|
||||
return lines.length;
|
||||
},
|
||||
get column() {
|
||||
lines ??= raw.split("\n");
|
||||
return lines.at(-1).length;
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -67,11 +100,12 @@ function parse(text) {
|
||||
return { content: text };
|
||||
}
|
||||
|
||||
const { raw } = frontMatter;
|
||||
|
||||
return {
|
||||
frontMatter,
|
||||
content: raw.replaceAll(/[^\n]/gu, " ") + text.slice(raw.length),
|
||||
get content() {
|
||||
const { raw } = frontMatter;
|
||||
return raw.replaceAll(/[^\n]/gu, " ") + text.slice(raw.length);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ async function print(node, textToDoc) {
|
||||
const doc = value ? await textToDoc(value, { parser: "yaml" }) : "";
|
||||
return markAsRoot([
|
||||
node.startDelimiter,
|
||||
node.explicitLanguage,
|
||||
node.explicitLanguage ?? "",
|
||||
hardline,
|
||||
doc,
|
||||
doc ? hardline : "",
|
||||
|
||||
Reference in new issue
Block a user