generated from kawarimidoll/deno-dev-template
-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
mod.ts
77 lines (72 loc) · 1.74 KB
/
mod.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
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
/**
* Render markup tag.
* @param tagName (required)
* @param attributes (optional)
* @param children (optional)
* @return rendered tag
*
* Examples:
*
* ```ts
* import { tag } from "./mod.ts"
* import { assertEquals } from "https://deno.land/std/testing/asserts.ts"
*
* // common usage
* assertEquals(
* tag("div", { id: "foo", class: "bar" }, "Hello world!"),
* `<div id="foo" class="bar">Hello world!</div>`,
* );
*
* // void (no-close) tag
* assertEquals(
* tag("meta", { charset: "utf-8" }),
* `<meta charset="utf-8">`,
* );
*
* // nested tags
* assertEquals(
* tag( "ul", { class: "nav" }, tag("li", "first"), tag("li", "second")),
* `<ul class="nav"><li>first</li><li>second</li></ul>`,
* );
* ```
*/
export function tag(
tagName: string,
attributesOrFirstChild?: Record<string, string | number> | string,
...children: Array<string>
): string {
if (/\s/.test(tagName)) {
throw new Error("tagName has whitespace characters.");
}
const isVoidTag = [
"area",
"base",
"br",
"col",
"embed",
"hr",
"img",
"input",
"link",
"meta",
"param",
"source",
"track",
"wbr",
].includes(tagName);
const attrs: Array<string> = [];
if (typeof attributesOrFirstChild === "string") {
children.unshift(attributesOrFirstChild);
} else if (attributesOrFirstChild != null) {
Object.entries(attributesOrFirstChild)
.forEach(([k, v]) => attrs.push(` ${k}="${v}"`));
}
const close = isVoidTag ? "" : `${children.join("")}</${tagName}>`;
return `<${tagName}${attrs.join("")}>${close}`;
}
// character references
export const NBSP = " ";
export const LT = "<";
export const GT = ">";
export const AMP = "&";
export const QUOT = """;