src/language-html/embed.js/embed
function embed(path, print, textToDoc, options) {
  const node = path.getValue();

  switch (node.type) {
    case "element": {
      if (isScriptLikeTag(node) || node.type === "interpolation") {
        // Fall through to "text"
        return;
      }

      if (!node.isSelfClosing && isVueNonHtmlBlock(node, options)) {
        const parser = inferScriptParser(node, options);
        if (!parser) {
          return;
        }

        const content = getNodeContent(node, options);
        let isEmpty = /^\s*$/.test(content);
        let doc = "";
        if (!isEmpty) {
          doc = textToDoc(
            htmlTrimPreserveIndentation(content),
            { parser, __embeddedInHtml: true },
            { stripTrailingHardline: true }
          );
          isEmpty = doc === "";
        }

        return [
          printOpeningTagPrefix(node, options),
          group(printOpeningTag(path, options, print)),
          isEmpty ? "" : hardline,
          doc,
          isEmpty ? "" : hardline,
          printClosingTag(node, options),
          printClosingTagSuffix(node, options),
        ];
      }
      break;
    }
    case "text": {
      if (isScriptLikeTag(node.parent)) {
        const parser = inferScriptParser(node.parent, options);
        if (parser) {
          const value =
            parser === "markdown"
              ? dedentString(node.value.replace(/^[^\S\n]*\n/, ""))
              : node.value;
          const textToDocOptions = { parser, __embeddedInHtml: true };
          if (options.parser === "html" && parser === "babel") {
            let sourceType = "script";
            const { attrMap } = node.parent;
            if (
              attrMap &&
              (attrMap.type === "module" ||
                (attrMap.type === "text/babel" &&
                  attrMap["data-type"] === "module"))
            ) {
              sourceType = "module";
            }
            textToDocOptions.__babelSourceType = sourceType;
          }
          return [
            breakParent,
            printOpeningTagPrefix(node, options),
            textToDoc(value, textToDocOptions, {
              stripTrailingHardline: true,
            }),
            printClosingTagSuffix(node, options),
          ];
        }
      } else if (node.parent.type === "interpolation") {
        const textToDocOptions = {
          __isInHtmlInterpolation: true, // to avoid unexpected `}}`
          __embeddedInHtml: true,
        };
        if (options.parser === "angular") {
          textToDocOptions.parser = "__ng_interpolation";
          textToDocOptions.trailingComma = "none";
        } else if (options.parser === "vue") {
          textToDocOptions.parser = options.__should_parse_vue_template_with_ts
            ? "__vue_ts_expression"
            : "__vue_expression";
        } else {
          textToDocOptions.parser = "__js_expression";
        }
        return [
          indent([
            line,
            textToDoc(node.value, textToDocOptions, {
              stripTrailingHardline: true,
            }),
          ]),
          node.parent.next &&
          needsToBorrowPrevClosingTagEndMarker(node.parent.next)
            ? " "
            : line,
        ];
      }
      break;
    }
    case "attribute": {
      if (!node.value) {
        break;
      }

      // lit-html: html`<my-element obj=${obj}></my-element>`
      if (
        /^PRETTIER_HTML_PLACEHOLDER_\d+_\d+_IN_JS$/.test(
          options.originalText.slice(
            node.valueSpan.start.offset,
            node.valueSpan.end.offset
          )
        )
      ) {
        return [node.rawName, "=", node.value];
      }

      // lwc: html`<my-element data-for={value}></my-element>`
      if (options.parser === "lwc") {
        const interpolationRegex = /^{.*}$/s;
        if (
          interpolationRegex.test(
            options.originalText.slice(
              node.valueSpan.start.offset,
              node.valueSpan.end.offset
            )
          )
        ) {
          return [node.rawName, "=", node.value];
        }
      }

      const embeddedAttributeValueDoc = printEmbeddedAttributeValue(
        node,
        (code, opts) =>
          // strictly prefer single quote to avoid unnecessary html entity escape
          textToDoc(
            code,
            { __isInHtmlAttribute: true, __embeddedInHtml: true, ...opts },
            { stripTrailingHardline: true }
          ),
        options
      );
      if (embeddedAttributeValueDoc) {
        return [
          node.rawName,
          '="',
          group(
            mapDoc(embeddedAttributeValueDoc, (doc) =>
              typeof doc === "string" ? doc.replace(/"/g, "&quot;") : doc
            )
          ),
          '"',
        ];
      }
      break;
    }
    case "front-matter":
      return printFrontMatter(node, textToDoc);
  }
}