-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathembedder.ts
More file actions
93 lines (79 loc) · 2.62 KB
/
embedder.ts
File metadata and controls
93 lines (79 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import type { Options } from "prettier";
import { builders } from "prettier/doc.js";
import type { Embedder } from "../../types.js";
import {
preparePlaceholder,
printTemplateExpressions,
simpleRehydrateDoc,
} from "../utils.js";
import { language } from "./language.js";
const { line, group, indent, softline } = builders;
export const embedder: Embedder<Options> = async (
textToDoc,
print,
path,
options,
{ commentOrTag, embeddedOverrideOptions },
) => {
const resolvedOptions = {
...options,
...embeddedOverrideOptions,
};
const { node } = path;
const { createPlaceholder, placeholderRegex } = preparePlaceholder();
const text = node.quasis
.map((quasi, index, { length }) =>
index === length - 1
? quasi.value.cooked
: quasi.value.cooked + createPlaceholder(index),
)
.join("");
const leadingWhitespaces = text.match(/^\s+/)?.[0] ?? "";
const trailingWhitespaces = text.match(/\s+$/)?.[0] ?? "";
const trimmedText = text.slice(
leadingWhitespaces.length,
-trailingWhitespaces.length || undefined,
);
const expressionDocs = printTemplateExpressions(path, print);
const doc = await textToDoc(trimmedText, {
...resolvedOptions,
parser: resolvedOptions.embeddedTsParser ?? "typescript",
// set filepath to undefined to enable jsx auto detection:
// https://github.com/prettier/prettier/blob/427a84d24203e2d54160cde153a1e6a6390fe65a/src/language-js/parse/typescript.js#L49-L53
filepath: undefined,
});
const contentDoc = simpleRehydrateDoc(doc, placeholderRegex, expressionDocs);
if (
resolvedOptions.preserveEmbeddedExteriorWhitespaces?.includes(commentOrTag)
) {
// TODO: should we label the doc with { hug: false } ?
// https://github.com/prettier/prettier/blob/5cfb76ee50cf286cab267cf3cb7a26e749c995f7/src/language-js/embed/html.js#L88
return group([
"`",
leadingWhitespaces,
resolvedOptions.noEmbeddedMultiLineIndentation?.includes(commentOrTag)
? [group(contentDoc)]
: indent([group(contentDoc)]),
trailingWhitespaces,
"`",
]);
}
const leadingLineBreak = leadingWhitespaces.length ? line : softline;
const trailingLineBreak = trailingWhitespaces.length ? line : softline;
return group([
"`",
resolvedOptions.noEmbeddedMultiLineIndentation?.includes(commentOrTag)
? [leadingLineBreak, group(contentDoc)]
: indent([leadingLineBreak, group(contentDoc)]),
trailingLineBreak,
"`",
]);
};
/**
* Register the embedder to the EmbeddedEmbedders
*/
declare module "../types.js" {
interface EmbeddedEmbedders {
[language]: typeof embedder;
}
}