"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const doc_1 = require("prettier/doc"); const { dedentToRoot, group, hardline, indent, join, line, literalline, softline } = doc_1.builders; // Replace the string content newlines within a doc tree with literallines so // that all of the indentation lines up appropriately function replaceNewlines(doc) { return doc_1.utils.mapDoc(doc, (currentDoc) => typeof currentDoc === "string" && currentDoc.includes("\n") ? currentDoc.split(/(\n)/g).map((v, i) => (i % 2 === 0 ? v : literalline)) : currentDoc); } // Get the start and end element tags from the current node on the tree function getElementTags(path, opts, print) { const node = path.getValue(); const { OPEN, Name, attribute, START_CLOSE, SLASH_OPEN, END_NAME, END } = node.children; const parts = [OPEN[0].image, Name[0].image]; if (attribute) { parts.push(indent([line, join(line, path.map(print, "children", "attribute"))])); } if (!opts.bracketSameLine) { parts.push(softline); } return { openTag: group([...parts, START_CLOSE[0].image]), closeTag: group([SLASH_OPEN[0].image, END_NAME[0].image, END[0].image]) }; } // Get the name of the parser that is represented by the given element node, // return null if a matching parser cannot be found function getParser(node, opts) { const { Name, attribute } = node.children; const parser = Name[0].image.toLowerCase(); // We don't want to deal with some weird recursive parser situation, so we // need to explicitly call out the XML parser here and just return null if (parser === "xml") { return null; } // If this is a style tag with a text/css type, then we can skip straight to // saying that this needs a CSS parser if (parser === "style" && attribute && attribute.some((attr) => attr.children.Name[0].image === "type" && attr.children.STRING[0].image === '"text/css"')) { return "css"; } // If there is a plugin that has a parser that matches the name of this // element, then we're going to assume that's correct for embedding and go // ahead and switch to that parser if (opts.plugins.some((plugin) => typeof plugin !== "string" && plugin.parsers && Object.prototype.hasOwnProperty.call(plugin.parsers, parser))) { return parser; } return null; } // Get the source string that will be passed into the embedded parser from the // content of the inside of the element node function getSource(content) { return content.chardata .map((node) => { const { SEA_WS, TEXT } = node.children; const [{ image }] = SEA_WS || TEXT; return { offset: node.location.startOffset, printed: image }; }) .sort(({ offset }) => offset) .map(({ printed }) => printed) .join(""); } const embed = (path, print, textToDoc, opts) => { const node = path.getValue(); // If the node isn't an element node, then skip if (node.name !== "element") { return null; } // If the name of the node does not correspond to the name of a parser that // prettier knows about, then skip const parser = getParser(node, opts); if (!parser) { return null; } // If the node does not actually contain content, or it contains any content // that is not just plain text, then skip const content = node.children.content[0].children; if (Object.keys(content).length !== 1 || !content.chardata) { return null; } // Get the open and close tags of this element, then return the properly // formatted content enclosed within them const nodePath = path; const { openTag, closeTag } = getElementTags(nodePath, opts, print); return group([ openTag, literalline, dedentToRoot(replaceNewlines(doc_1.utils.stripTrailingHardline(textToDoc(getSource(content), { ...opts, parser })))), hardline, closeTag ]); }; exports.default = embed;