-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxml-tag.ts
45 lines (40 loc) · 1.34 KB
/
xml-tag.ts
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
import { escapeHtml } from "./escape-html.ts";
import { TemplateLiteral } from "./template-literal.ts";
export type XmlTagAttributeValue = string;
export interface XmlTagAttributeValueSupplier {
(name: string, options?: XmlTagOptions): XmlTagAttributeValue;
}
export interface XmlTagAttributes {
[name: string]: XmlTagAttributeValue | XmlTagAttributeValueSupplier;
}
export interface XmlTagOptions {
readonly escapeResult?: boolean;
}
export function xmlTag(
tagName: string,
attributes?: XmlTagAttributes,
options?: XmlTagOptions,
): TemplateLiteral {
const { escapeResult } = options || { escapeResult: false };
return (literals: TemplateStringsArray, ...placeholders: string[]) => {
let result = "";
for (let i = 0; i < placeholders.length; i++) {
result += literals[i];
result += placeholders[i];
}
result += literals[literals.length - 1];
let tagStart = `<${tagName}`;
if (attributes) {
for (const attr of Object.entries(attributes)) {
const [name, valueSupplier] = attr;
const value = typeof valueSupplier == "string"
? valueSupplier
: valueSupplier(name, options);
tagStart += ` ${name}="${value.replaceAll('"', """)}"`;
}
}
tagStart += ">";
return tagStart + (escapeResult ? escapeHtml(result) : result) +
`</${tagName}>`;
};
}