1 module elemi.html;
2 
3 import std.meta;
4 import std.traits;
5 
6 import elemi.xml;
7 import elemi.internal;
8 
9 public {
10 
11     import elemi.attribute;
12     import elemi.element;
13 
14 }
15 
16 // Magic elem alias
17 alias elem = elemH;
18 alias add = addH;
19 
20 /// Create a HTML element.
21 ///
22 /// Params:
23 ///     name = Name of the element.
24 ///     attrHTML = Unsanitized attributes to insert at compile-time.
25 ///     attributes = Attributes for the element as an associative array mapping attribute names to their values.
26 ///     content = Attributes (via `Attribute` and `attr`), children and text of the element.
27 /// Returns: a Element type, implictly castable to string.
28 template elemH(string name, Ts...) {
29 
30     Element elemH(T...)(T args) {
31 
32         enum tag = makeHTMLTag(name);
33 
34         return elemX!(tag, Ts)(args);
35 
36     }
37 
38 }
39 
40 /// Add a new node as a child of this node.
41 /// Returns: This node, to allow chaining.
42 Element addH(Ts...)(ref Element parent, Ts args)
43 if (allSatisfy!(isType, Ts)) {
44 
45     parent ~= args;
46     return parent;
47 
48 }
49 
50 Element addH(Ts...)(Element parent, Ts args)
51 if (allSatisfy!(isType, Ts)) {
52 
53     parent ~= args;
54     return parent;
55 
56 }
57 
58 template addH(Ts...)
59 if (Ts.length != 0) {
60 
61     Element addH(Args...)(ref Element parent, Args args) {
62 
63         parent ~= elemH!Ts(args);
64         return parent;
65 
66     }
67 
68     Element addH(Args...)(Element parent, Args args) {
69 
70         parent ~= elemH!Ts(args);
71         return parent;
72 
73     }
74 
75 }
76 
77 /// Check if the given tag is a HTML5 self-closing tag.
78 bool isVoidTag(string tag) pure @safe {
79 
80     switch (tag) {
81 
82         // Void element
83         case "area", "base", "br", "col", "command", "embed", "hr", "img", "input":
84         case "keygen", "link", "meta", "param", "source", "track", "wbr":
85 
86             return true;
87 
88         // Containers
89         default:
90 
91             return false;
92 
93     }
94 
95 }
96 
97 /// If the given tag is a void tag, make it a self-closing.
98 private string makeHTMLTag(string tag) pure @safe {
99 
100     assert(tag.length && tag[$-1] != '/', "Self-closing tags are applied automatically when working with html, please"
101         ~ " remove the slash.");
102 
103     return isVoidTag(tag) ? tag ~ "/" : tag;
104 
105 }