rtml/tags.rs
1use crate::*;
2
3pub trait Tag: std::fmt::Display + 'static {}
4
5pub trait TagValue: ToString {
6 fn render(&self) -> String {
7 return self.to_string();
8 }
9}
10
11macro_rules! tagit {
12 ($tag:ident, $trait:ident $(,$attr:ident)*) => {
13 #[allow(unused_variables)]
14 impl $tag {
15 pub fn type_check(&self, attr: &dyn $trait){}
16 }
17 #[warn(unused_variables)]
18 pub trait $trait {}
19 impl Tag for $tag {}
20
21 $(impl $trait for $attr {})*
22 };
23}
24
25tagit! {ATag, ACompat, download, href, hreflang, media, ping, referrerpolicy, rel, target }
26tagit! {AbbrTag, AbbrCompat}
27tagit! {AddressTag, AddressCompat}
28tagit! {AreaTag, AreaCompat, alt, coords, download, href, hreflang, media, rel, shape, target }
29tagit! {ArticleTag, ArticleCompat}
30tagit! {AsideTag, AsideCompat}
31tagit! {AudioTag, AudioCompat, autoplay, controls, _loop, muted, preload, src }
32tagit! {BTag, BCompat}
33tagit! {BaseTag, BaseCompat, href, target }
34tagit! {BdiTag, BdiCompat}
35tagit! {BdoTag, BdoCompat}
36tagit! {BlockquoteTag, BlockquoteCompat, cite }
37tagit! {BodyTag, BodyCompat}
38tagit! {BrTag, BrCompat}
39tagit! {ButtonTag, ButtonCompat, autofocus, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, name, _type, value }
40tagit! {CanvasTag, CanvasCompat, height, width }
41tagit! {CaptionTag, CaptionCompat}
42tagit! {CiteTag, CiteCompat}
43tagit! {CodeTag, CodeCompat}
44tagit! {ColTag, ColCompat, span }
45tagit! {ColgroupTag, ColgroupCompat, span }
46tagit! {DataTag, DataCompat, value }
47tagit! {DatalistTag, DatalistCompat}
48tagit! {DdTag, DdCompat}
49tagit! {DelTag, DelCompat, cite, datetime }
50tagit! {DetailsTag, DetailsCompat, open }
51tagit! {DfnTag, DfnCompat}
52tagit! {DialogTag, DialogCompat, open }
53tagit! {DivTag, DivCompat}
54tagit! {DlTag, DlCompat}
55tagit! {DtTag, DtCompat}
56tagit! {EmTag, EmCompat}
57tagit! {EmbedTag, EmbedCompat, height, src, _type, width }
58tagit! {FieldsetTag, FieldsetCompat, disabled, form, name }
59tagit! {FigcaptionTag, FigcaptionCompat}
60tagit! {FigureTag, FigureCompat}
61tagit! {FooterTag, FooterCompat}
62tagit! {FormTag, FormCompat, accept_charset, action, autocomplete, enctype, method, name, novalidate, target }
63tagit! {H1Tag, H1Compat}
64tagit! {H2Tag, H2Compat}
65tagit! {H3Tag, H3Compat}
66tagit! {H4Tag, H4Compat}
67tagit! {H5Tag, H5Compat}
68tagit! {H6Tag, H6Compat}
69tagit! {HeadTag, HeadCompat}
70tagit! {HeaderTag, HeaderCompat}
71tagit! {HrTag, HrCompat}
72tagit! {HtmlTag, HtmlCompat}
73tagit! {ITag, ICompat}
74tagit! {IframeTag, IframeCompat, allow, allowfullscreen, height, name, referrerpolicy, sandbox, src, srcdoc, width }
75tagit! {ImgTag, ImgCompat, alt, crossorigin, decoding, height, referrerpolicy, sizes, src, srcset, usemap, width }
76tagit! {InputTag, InputCompat, accept, alt, autocomplete, autofocus, checked, disabled, form, formaction, formenctype, formmethod, formnovalidate, formtarget, height, list, max, maxlength, min, minlength, multiple, name, pattern, placeholder, readonly, required, size, src, step, _type, value, width }
77tagit! {InsTag, InsCompat, cite, datetime }
78tagit! {KbdTag, KbdCompat}
79tagit! {LabelTag, LabelCompat, form }
80tagit! {LegendTag, LegendCompat}
81tagit! {LiTag, LiCompat, value }
82tagit! {LinkTag, LinkCompat, _as, crossorigin, href, hreflang, media, rel, sizes, _type }
83tagit! {MainTag, MainCompat}
84tagit! {MapTag, MapCompat, name }
85tagit! {MarkTag, MarkCompat}
86tagit! {MenuTag, MenuCompat, _type }
87tagit! {MetaTag, MetaCompat, charset, content, http_equiv, name }
88tagit! {MeterTag, MeterCompat, high, low, max, min, optimum, value }
89tagit! {NavTag, NavCompat}
90tagit! {NoscriptTag, NoscriptCompat}
91tagit! {ObjectTag, ObjectCompat, data, form, height, name, _type, width }
92tagit! {OlTag, OlCompat, reversed, start }
93tagit! {OptgroupTag, OptgroupCompat, disabled, label }
94tagit! {OptionTag, OptionCompat, disabled, label, selected, value }
95tagit! {OutputTag, OutputCompat, _for, form, name }
96tagit! {PTag, PCompat}
97tagit! {PictureTag, PictureCompat}
98tagit! {PreTag, PreCompat}
99tagit! {ProgressTag, ProgressCompat, max, value }
100tagit! {QTag, QCompat, cite }
101tagit! {RpTag, RpCompat}
102tagit! {RtTag, RtCompat}
103tagit! {RubyTag, RubyCompat}
104tagit! {STag, SCompat}
105tagit! {SampTag, SampCompat}
106tagit! {ScriptTag, ScriptCompat, _async, crossorigin, defer, integrity, nomodule, src, _type }
107tagit! {SectionTag, SectionCompat}
108tagit! {SelectTag, SelectCompat, autocomplete, autofocus, disabled, form, multiple, name, required, size }
109tagit! {SmallTag, SmallCompat}
110tagit! {SourceTag, SourceCompat, muted, media, sizes, src, srcset, _type }
111tagit! {SpanTag, SpanCompat}
112tagit! {StrongTag, StrongCompat}
113tagit! {StyleTag, StyleCompat, media, nonce, _type }
114tagit! {SubTag, SubCompat}
115tagit! {SummaryTag, SummaryCompat}
116tagit! {SupTag, SupCompat}
117tagit! {TableTag, TableCompat}
118tagit! {TbodyTag, TbodyCompat}
119tagit! {TdTag, TdCompat, colspan, headers, rowspan, scope }
120tagit! {TemplateTag, TemplateCompat}
121tagit! {TextareaTag, TextareaCompat, autocomplete, autofocus, cols, disabled, form, maxlength, minlength, name, placeholder, readonly, required, rows, wrap }
122tagit! {TfootTag, TfootCompat}
123tagit! {ThTag, ThCompat, colspan, headers, rowspan, scope }
124tagit! {TheadTag, TheadCompat}
125tagit! {TimeTag, TimeCompat, datetime }
126tagit! {TitleTag, TitleCompat}
127tagit! {TrTag, TrCompat}
128tagit! {TrackTag, TrackCompat, default, _kind, label, src, srclang }
129tagit! {UTag, UCompat}
130tagit! {UlTag, UlCompat}
131tagit! {VarTag, VarCompat}
132tagit! {VideoTag, VideoCompat, autoplay, controls, crossorigin, height, _loop, muted, playsinline, poster, preload, src, width }
133tagit! {WbrTag, WbrCompat}
134
135/// # Example
136/// ```
137/// # #[macro_use] extern crate rtml;
138/// # fn main() {
139/// use rtml::*;
140///
141/// assert_eq!(
142/// a![.href="https://www.example.com", "Link text"].render(),
143/// "<a href=\"https://www.example.com\">Link text</a>"
144/// );
145///
146/// assert_eq!(
147/// a![.href="/path/to/page", "Click here"].render(),
148/// "<a href=\"/path/to/page\">Click here</a>"
149/// );
150/// assert_eq!(
151/// a![.href="mailto:user@example.com", "Send email"].render(),
152/// "<a href=\"mailto:user@example.com\">Send email</a>"
153/// );
154///
155/// # }
156/// ```
157#[macro_export]
158macro_rules! a {
159 ($($all:tt)*) => {parse_double_tag!(ATag, $($all)*) };
160}
161
162/// # Example
163/// ```
164/// # #[macro_use] extern crate rtml;
165/// # fn main() {
166/// use rtml::*;
167///
168/// assert_eq!(
169/// abbr![.title="Hypertext Markup Language", "HTML"].render(),
170/// "<abbr title=\"Hypertext Markup Language\">HTML</abbr>"
171/// );
172///
173/// assert_eq!(
174/// abbr![.title="Scalable Vector Graphics", "SVG"].render(),
175/// "<abbr title=\"Scalable Vector Graphics\">SVG</abbr>"
176/// );
177/// # }
178/// ```
179#[macro_export]
180macro_rules! abbr {
181 ($($all:tt)*) => {parse_double_tag!(AbbrTag, $($all)*) };
182}
183
184/// # Example
185/// ```
186/// # #[macro_use] extern crate rtml;
187/// # fn main() {
188/// use rtml::*;
189///
190/// assert_eq!(
191/// address!["P. Sherman", br![], "42 Wallaby way", br![], "Sydney, Australia"].render(),
192/// "<address>P. Sherman<br>42 Wallaby way<br>Sydney, Australia</address>"
193/// );
194///
195/// # }
196/// ```
197#[macro_export]
198macro_rules! address {
199 ($($all:tt)*) => {parse_double_tag!(AddressTag, $($all)*) };
200}
201
202/// # Example
203/// ```
204/// # #[macro_use] extern crate rtml;
205/// # fn main() {
206/// use rtml::*;
207///
208/// assert_eq!(
209/// area![.shape="rect", .coords="0,0,100,100", .href="example.com"].render(),
210/// "<area shape=\"rect\" coords=\"0,0,100,100\" href=\"example.com\">"
211/// );
212///
213/// # }
214/// ```
215#[macro_export]
216macro_rules! area {
217 ($($all:tt)*) => {parse_single_tag!(AreaTag, $($all)*) };
218}
219
220/// # Example
221/// ```
222/// # #[macro_use] extern crate rtml;
223/// # fn main() {
224/// use rtml::*;
225///
226/// assert_eq!(
227/// article!["This is an article."].render(),
228/// "<article>This is an article.</article>"
229/// );
230///
231/// assert_eq!(
232/// article!["This is an article with a ", b!["bold"], " word."].render(),
233/// "<article>This is an article with a <b>bold</b> word.</article>"
234/// );
235/// # }
236/// ```
237#[macro_export]
238macro_rules! article {
239 ($($all:tt)*) => {parse_double_tag!(ArticleTag, $($all)*) };
240}
241
242/// # Example
243/// ```
244/// # #[macro_use] extern crate rtml;
245/// # fn main() {
246/// use rtml::*;
247///
248/// assert_eq!(
249/// aside!["This is an aside."].render(),
250/// "<aside>This is an aside.</aside>"
251/// );
252/// # }
253/// ```
254#[macro_export]
255macro_rules! aside {
256 ($($all:tt)*) => {parse_double_tag!(AsideTag, $($all)*) };
257}
258
259/// # Example
260/// ```
261/// # #[macro_use] extern crate rtml;
262/// # fn main() {
263/// use rtml::*;
264///
265/// assert_eq!(
266/// audio![.src="example.mp3"].render(),
267/// "<audio src=\"example.mp3\">"
268/// );
269///
270/// assert_eq!(
271/// audio![.src="example.mp3", .controls = "true"].render(),
272/// "<audio src=\"example.mp3\" controls=\"true\">"
273/// );
274/// # }
275/// ```
276#[macro_export]
277macro_rules! audio {
278 ($($all:tt)*) => {parse_single_tag!(AudioTag, $($all)*) };
279}
280
281/// # Example
282/// ```
283/// # #[macro_use] extern crate rtml;
284/// # fn main() {
285/// use rtml::*;
286///
287/// assert_eq!(
288/// b!["This is bold text"].render(),
289/// "<b>This is bold text</b>"
290/// );
291/// # }
292/// ```
293#[macro_export]
294macro_rules! b {
295 ($($all:tt)*) => {parse_double_tag!(BTag, $($all)*) };
296}
297
298/// # Example
299/// ```
300/// # #[macro_use] extern crate rtml;
301/// # fn main() {
302/// use rtml::*;
303///
304/// assert_eq!(
305/// base![.href="https://example.com"].render(),
306/// "<base href=\"https://example.com\">"
307/// );
308/// # }
309/// ```
310#[macro_export]
311macro_rules! base {
312 ($($all:tt)*) => {parse_single_tag!(BaseTag, $($all)*) };
313}
314
315/// # Example
316/// ```
317/// # #[macro_use] extern crate rtml;
318/// # fn main() {
319/// use rtml::*;
320///
321/// assert_eq!(
322/// bdi!["This text will be displayed in a different direction"].render(),
323/// "<bdi>This text will be displayed in a different direction</bdi>"
324/// );
325/// # }
326/// ```
327#[macro_export]
328macro_rules! bdi {
329 ($($all:tt)*) => {parse_double_tag!(BdiTag, $($all)*) };
330}
331
332/// # Example
333/// ```
334/// # #[macro_use] extern crate rtml;
335/// # fn main() {
336/// use rtml::*;
337///
338/// assert_eq!(
339/// bdo![.dir="rtl", "This text will be displayed in a right-to-left direction"].render(),
340/// "<bdo dir=\"rtl\">This text will be displayed in a right-to-left direction</bdo>"
341/// );
342/// # }
343/// ```
344#[macro_export]
345macro_rules! bdo {
346 ($($all:tt)*) => {parse_double_tag!(BdoTag, $($all)*) };
347}
348
349/// # Example
350/// ```
351/// # #[macro_use] extern crate rtml;
352/// # fn main() {
353/// use rtml::*;
354///
355/// assert_eq!(
356/// blockquote!["This is a blockquote."].render(),
357/// "<blockquote>This is a blockquote.</blockquote>"
358/// );
359///
360/// assert_eq!(
361/// blockquote![.cite="https://example.com","This is a blockquote with citation"].render(),
362/// "<blockquote cite=\"https://example.com\">This is a blockquote with citation</blockquote>"
363/// );
364/// # }
365/// ```
366#[macro_export]
367macro_rules! blockquote {
368 ($($all:tt)*) => {parse_double_tag!(BlockquoteTag, $($all)*) };
369}
370
371/// # Example
372/// ```
373/// # #[macro_use] extern crate rtml;
374/// # fn main() {
375/// use rtml::*;
376///
377/// assert_eq!(
378/// body!["This is the body"].render(),
379/// "<body>This is the body</body>"
380/// );
381/// # }
382/// ```
383#[macro_export]
384macro_rules! body {
385 ($($all:tt)*) => {parse_double_tag!(BodyTag, $($all)*) };
386}
387
388/// # Example
389/// ```
390/// # #[macro_use] extern crate rtml;
391/// # fn main() {
392/// use rtml::*;
393///
394/// assert_eq!(
395/// br![].render(),
396/// "<br>"
397/// );
398/// # }
399/// ```
400#[macro_export]
401macro_rules! br {
402 ($($all:tt)*) => {parse_single_tag!(BrTag, $($all)*) };
403}
404
405/// # Example
406/// ```
407/// # #[macro_use] extern crate rtml;
408/// # fn main() {
409/// use rtml::*;
410///
411/// assert_eq!(
412/// button!["Click me"].render(),
413/// "<button>Click me</button>"
414/// );
415///
416/// # }
417/// ```
418
419#[macro_export]
420macro_rules! button {
421 ($($all:tt)*) => {parse_double_tag!(ButtonTag, $($all)*) };
422}
423
424/// # Example
425/// ```
426/// # #[macro_use] extern crate rtml;
427/// # fn main() {
428/// use rtml::*;
429///
430/// assert_eq!(
431/// canvas![].render(),
432/// "<canvas></canvas>"
433/// );
434///
435/// assert_eq!(
436/// canvas![.width="300", .height="150"].render(),
437/// "<canvas width=\"300\" height=\"150\"></canvas>"
438/// );
439/// # }
440/// ```
441#[macro_export]
442macro_rules! canvas {
443 ($($all:tt)*) => {parse_double_tag!(CanvasTag, $($all)*) };
444}
445
446/// # Example
447/// ```
448/// # #[macro_use] extern crate rtml;
449/// # fn main() {
450/// use rtml::*;
451///
452/// assert_eq!(
453/// caption!["This is a caption"].render(),
454/// "<caption>This is a caption</caption>"
455/// );
456/// # }
457/// ```
458#[macro_export]
459macro_rules! caption {
460 ($($all:tt)*) => {parse_double_tag!(CaptionTag, $($all)*) };
461}
462
463/// # Example
464/// ```
465/// # #[macro_use] extern crate rtml;
466/// # fn main() {
467/// use rtml::*;
468///
469/// assert_eq!(
470/// cite!["This is a citation"].render(),
471/// "<cite>This is a citation</cite>"
472/// );
473/// # }
474/// ```
475#[macro_export]
476macro_rules! cite {
477 ($($all:tt)*) => {parse_double_tag!(CiteTag, $($all)*) };
478}
479
480/// # Example
481/// ```
482/// # #[macro_use] extern crate rtml;
483/// # fn main() {
484/// use rtml::*;
485///
486/// assert_eq!(
487/// code![ "h1![\"This is awesome!\"]" ].render(),
488/// "<code>h1![\"This is awesome!\"]</code>"
489/// );
490/// # }
491/// ```
492#[macro_export]
493macro_rules! code {
494 ($($all:tt)*) => {parse_double_tag!(CodeTag, $($all)*) };
495}
496
497/// # Example
498/// ```
499/// # #[macro_use] extern crate rtml;
500/// # fn main() {
501/// use rtml::*;
502///
503/// assert_eq!(
504/// col![.span="2", .style="background-color:red"].render(),
505/// "<col span=\"2\" style=\"background-color:red\">"
506/// );
507/// # }
508/// ```
509#[macro_export]
510macro_rules! col {
511 ($($all:tt)*) => {parse_single_tag!(ColTag, $($all)*) };
512}
513
514/// # Example
515/// ```
516/// # #[macro_use] extern crate rtml;
517/// # fn main() {
518/// use rtml::*;
519///
520/// assert_eq!(
521/// colgroup![col![], col![]].render(),
522/// "<colgroup><col><col></colgroup>"
523/// );
524///
525/// # }
526/// ```
527#[macro_export]
528macro_rules! colgroup {
529 ($($all:tt)*) => {parse_double_tag!(ColgroupTag, $($all)*) };
530}
531
532/// # Example
533/// ```
534/// # #[macro_use] extern crate rtml;
535/// # fn main() {
536/// use rtml::*;
537///
538/// assert_eq!(
539/// data!["123"].render(),
540/// "<data>123</data>"
541/// );
542///
543/// assert_eq!(
544/// data![.value = "456", "Data Value"].render(),
545/// "<data value=\"456\">Data Value</data>"
546/// );
547/// # }
548/// ```
549#[macro_export]
550macro_rules! data {
551 ($($all:tt)*) => {parse_double_tag!(DataTag, $($all)*) };
552}
553
554/// # Example
555/// ```
556/// # #[macro_use] extern crate rtml;
557/// # fn main() {
558/// use rtml::*;
559///
560/// assert_eq!(
561/// datalist![option!["option1"], option!["option2"], option!["option3"]].render(),
562/// "<datalist><option>option1</option><option>option2</option><option>option3</option></datalist>"
563/// );
564/// # }
565/// ```
566#[macro_export]
567macro_rules! datalist {
568 ($($all:tt)*) => {parse_double_tag!(DatalistTag, $($all)*) };
569}
570
571/// # Example
572/// ```
573/// # #[macro_use] extern crate rtml;
574/// # fn main() {
575/// use rtml::*;
576///
577/// assert_eq!(
578/// dd!["This is a definition"].render(),
579/// "<dd>This is a definition</dd>"
580/// );
581/// # }
582/// ```
583#[macro_export]
584macro_rules! dd {
585 ($($all:tt)*) => {parse_double_tag!(DdTag, $($all)*) };
586}
587
588/// # Example
589/// ```
590/// # #[macro_use] extern crate rtml;
591/// # fn main() {
592/// use rtml::*;
593///
594/// assert_eq!(
595/// del!["This text is deleted"].render(),
596/// "<del>This text is deleted</del>"
597/// );
598/// # }
599/// ```
600#[macro_export]
601macro_rules! del {
602 ($($all:tt)*) => {parse_double_tag!(DelTag, $($all)*) };
603}
604
605/// # Example
606/// ```
607/// # #[macro_use] extern crate rtml;
608/// # fn main() {
609/// use rtml::*;
610///
611/// assert_eq!(
612/// details![summary!["Details"], "This is the details content"].render(),
613/// "<details><summary>Details</summary>This is the details content</details>"
614/// );
615///
616/// # }
617#[macro_export]
618macro_rules! details {
619 ($($all:tt)*) => {parse_double_tag!(DetailsTag, $($all)*) };
620}
621
622/// # Example
623/// ```
624/// # #[macro_use] extern crate rtml;
625/// # fn main() {
626/// use rtml::*;
627///
628/// assert_eq!(
629/// dialog!["This is a dialog"].render(),
630/// "<dialog>This is a dialog</dialog>"
631/// );
632/// # }
633/// ```
634#[macro_export]
635macro_rules! dialog {
636 ($($all:tt)*) => {parse_double_tag!(DialogTag, $($all)*) };
637}
638
639/// # Example
640/// ```
641/// # #[macro_use] extern crate rtml;
642/// # fn main() {
643/// use rtml::*;
644///
645/// assert_eq!(
646/// div!{ "This is a div\"s inner text!" }.render(),
647/// "<div>This is a div\"s inner text!</div>"
648/// );
649/// # }
650/// ```
651#[macro_export]
652macro_rules! div {
653 ($($all:tt)*) => {parse_double_tag!(DivTag, $($all)*) };
654}
655
656/// # Example
657/// ```
658/// # #[macro_use] extern crate rtml;
659/// # fn main() {
660/// use rtml::*;
661///
662/// assert_eq!(
663/// dl![dt!["Term 1"], dd!["Definition 1"], dt!["Term 2"], dd!["Definition 2"]].render(),
664/// "<dl><dt>Term 1</dt><dd>Definition 1</dd><dt>Term 2</dt><dd>Definition 2</dd></dl>"
665/// );
666/// # }
667/// ```
668#[macro_export]
669macro_rules! dl {
670 ($($all:tt)*) => {parse_double_tag!(DlTag, $($all)*) };
671}
672
673/// # Example
674/// ```
675/// # #[macro_use] extern crate rtml;
676/// # fn main() {
677/// use rtml::*;
678///
679/// assert_eq!(
680/// dl![dt!["Term 1"], dd!["Definition 1"], dt!["Term 2"], dd!["Definition 2"]].render(),
681/// "<dl><dt>Term 1</dt><dd>Definition 1</dd><dt>Term 2</dt><dd>Definition 2</dd></dl>"
682/// );
683/// # }
684/// ```
685#[macro_export]
686macro_rules! dt {
687 ($($all:tt)*) => {parse_double_tag!(DtTag, $($all)*) };
688}
689
690/// # Example
691/// ```
692/// # #[macro_use] extern crate rtml;
693/// # fn main() {
694/// use rtml::*;
695///
696/// assert_eq!(
697/// em!["This is emphasized text"].render(),
698/// "<em>This is emphasized text</em>"
699/// );
700/// # }
701/// ```
702#[macro_export]
703macro_rules! em {
704 ($($all:tt)*) => {parse_double_tag!(EmTag, $($all)*) };
705}
706
707/// # Example
708/// ```
709/// # #[macro_use] extern crate rtml;
710/// # fn main() {
711/// use rtml::*;
712///
713/// assert_eq!(
714/// embed![.src="example.swf"].render(),
715/// "<embed src=\"example.swf\">"
716/// );
717///
718/// assert_eq!(
719/// embed![.src="example.swf", ._type="application/x-shockwave-flash", .width="400", .height="300"].render(),
720/// "<embed src=\"example.swf\" type=\"application/x-shockwave-flash\" width=\"400\" height=\"300\">"
721/// );
722/// # }
723/// ```
724#[macro_export]
725macro_rules! embed {
726 ($($all:tt)*) => {parse_single_tag!(EmbedTag, $($all)*) };
727}
728
729/// # Example
730/// ```
731/// # #[macro_use] extern crate rtml;
732/// # fn main() {
733/// use rtml::*;
734///
735/// assert_eq!(
736/// fieldset![legend!["This is a fieldset"], "This is the fieldset content"].render(),
737/// "<fieldset><legend>This is a fieldset</legend>This is the fieldset content</fieldset>"
738/// );
739/// # }
740/// ```
741#[macro_export]
742macro_rules! fieldset {
743 ($($all:tt)*) => {parse_double_tag!(FieldsetTag, $($all)*) };
744}
745
746/// # Example
747/// ```
748/// # #[macro_use] extern crate rtml;
749/// # fn main() {
750/// use rtml::*;
751///
752/// assert_eq!(
753/// figcaption!["This is a caption"].render(),
754/// "<figcaption>This is a caption</figcaption>"
755/// );
756/// # }
757/// ```
758#[macro_export]
759macro_rules! figcaption {
760 ($($all:tt)*) => {parse_double_tag!(FigcaptionTag, $($all)*) };
761}
762
763/// # Example
764/// ```
765/// # #[macro_use] extern crate rtml;
766/// # fn main() {
767/// use rtml::*;
768///
769/// assert_eq!(
770/// figure![img![.src="example.jpg"], figcaption!["This is a caption"]].render(),
771/// "<figure><img src=\"example.jpg\"><figcaption>This is a caption</figcaption></figure>"
772/// );
773/// # }
774/// ```
775#[macro_export]
776macro_rules! figure {
777 ($($all:tt)*) => {parse_double_tag!(FigureTag, $($all)*) };
778}
779
780/// # Example
781/// ```
782/// # #[macro_use] extern crate rtml;
783/// # fn main() {
784/// use rtml::*;
785///
786/// assert_eq!(
787/// footer!["This is a footer"].render(),
788/// "<footer>This is a footer</footer>"
789/// );
790/// # }
791/// ```
792#[macro_export]
793macro_rules! footer {
794 ($($all:tt)*) => {parse_double_tag!(FooterTag, $($all)*) };
795}
796
797/// # Example
798/// ```
799/// # #[macro_use] extern crate rtml;
800/// # fn main() {
801/// use rtml::*;
802///
803/// assert_eq!(
804/// form![.action="https://www.example.com", .method="post", "This is a form"].render(),
805/// "<form action=\"https://www.example.com\" method=\"post\">This is a form</form>"
806/// );
807/// # }
808/// ```
809#[macro_export]
810macro_rules! form {
811 ($($all:tt)*) => {parse_double_tag!(FormTag, $($all)*) };
812}
813
814/// # Example
815/// ```
816/// # #[macro_use] extern crate rtml;
817/// # fn main() {
818/// use rtml::*;
819///
820/// assert_eq!(
821/// h1!["This is a heading"].render(),
822/// "<h1>This is a heading</h1>"
823/// );
824/// # }
825/// ```
826#[macro_export]
827macro_rules! h1 {
828 ($($all:tt)*) => {parse_double_tag!(H1Tag, $($all)*) };
829}
830
831/// # Example
832/// ```
833/// # #[macro_use] extern crate rtml;
834/// # fn main() {
835/// use rtml::*;
836///
837/// assert_eq!(
838/// h2!["This is a heading"].render(),
839/// "<h2>This is a heading</h2>"
840/// );
841/// # }
842/// ```
843#[macro_export]
844macro_rules! h2 {
845 ($($all:tt)*) => {parse_double_tag!(H2Tag, $($all)*) };
846}
847
848/// # Example
849/// ```
850/// # #[macro_use] extern crate rtml;
851/// # fn main() {
852/// use rtml::*;
853///
854/// assert_eq!(
855/// h3!["This is a heading"].render(),
856/// "<h3>This is a heading</h3>"
857/// );
858/// # }
859/// ```
860#[macro_export]
861macro_rules! h3 {
862 ($($all:tt)*) => {parse_double_tag!(H3Tag, $($all)*) };
863}
864
865/// # Example
866/// ```
867/// # #[macro_use] extern crate rtml;
868/// # fn main() {
869/// use rtml::*;
870///
871/// assert_eq!(
872/// h4!["This is a heading"].render(),
873/// "<h4>This is a heading</h4>"
874/// );
875/// # }
876/// ```
877#[macro_export]
878macro_rules! h4 {
879 ($($all:tt)*) => {parse_double_tag!(H4Tag, $($all)*) };
880}
881
882/// # Example
883/// ```
884/// # #[macro_use] extern crate rtml;
885/// # fn main() {
886/// use rtml::*;
887///
888/// assert_eq!(
889/// h5!["This is a heading"].render(),
890/// "<h5>This is a heading</h5>"
891/// );
892/// # }
893/// ```
894#[macro_export]
895macro_rules! h5 {
896 ($($all:tt)*) => {parse_double_tag!(H5Tag, $($all)*) };
897}
898
899/// # Example
900/// ```
901/// # #[macro_use] extern crate rtml;
902/// # fn main() {
903/// use rtml::*;
904///
905/// assert_eq!(
906/// h6!["This is a heading"].render(),
907/// "<h6>This is a heading</h6>"
908/// );
909/// # }
910/// ```
911#[macro_export]
912macro_rules! h6 {
913 ($($all:tt)*) => {parse_double_tag!(H6Tag, $($all)*) };
914}
915
916/// # Example
917/// ```
918/// # #[macro_use] extern crate rtml;
919/// # fn main() {
920/// use rtml::*;
921///
922/// assert_eq!(
923/// head![title!["This is a title"], link![.rel="stylesheet", .href="example.css"]].render(),
924/// "<head><title>This is a title</title><link rel=\"stylesheet\" href=\"example.css\"></head>"
925/// );
926/// # }
927/// ```
928#[macro_export]
929macro_rules! head {
930 ($($all:tt)*) => {parse_double_tag!(HeadTag, $($all)*) };
931}
932
933/// # Example
934/// ```
935/// # #[macro_use] extern crate rtml;
936/// # fn main() {
937/// use rtml::*;
938///
939/// assert_eq!(
940/// header!["This is a header"].render(),
941/// "<header>This is a header</header>"
942/// );
943/// # }
944/// ```
945#[macro_export]
946macro_rules! header {
947 ($($all:tt)*) => {parse_double_tag!(HeaderTag, $($all)*) };
948}
949
950/// # Example
951/// ```
952/// # #[macro_use] extern crate rtml;
953/// # fn main() {
954/// use rtml::*;
955///
956/// assert_eq!(
957/// hr![].render(),
958/// "<hr>"
959/// );
960/// # }
961/// ```
962#[macro_export]
963macro_rules! hr {
964 ($($all:tt)*) => {parse_single_tag!(HrTag, $($all)*) };
965}
966
967/// # Example
968/// ```
969/// # #[macro_use] extern crate rtml;
970/// # fn main() {
971/// use rtml::*;
972///
973/// let result = html! {
974/// .lang = "en",
975/// head!{
976/// title!{
977/// "Title of the document"
978/// }
979/// },
980/// body!{
981/// div!{
982/// "text",
983/// h1!{
984/// "This is a heading"
985/// },
986/// p!{
987/// "This is a paragraph"
988/// }
989/// }
990/// }
991/// }.render();
992///
993/// println!("{}", result);
994///
995/// assert_eq!(
996/// html![head![title!["This is a title"]], body!["This is the body"]].render(),
997/// "<html><head><title>This is a title</title></head><body>This is the body</body></html>"
998/// );
999/// # }
1000/// ```
1001#[macro_export]
1002macro_rules! html {
1003 ($($all:tt)*) => {parse_double_tag!(HtmlTag, $($all)*) };
1004}
1005
1006/// # Example
1007/// ```
1008/// # #[macro_use] extern crate rtml;
1009/// # fn main() {
1010/// use rtml::*;
1011///
1012/// assert_eq!(
1013/// i!["This is in italic"].render(),
1014/// "<i>This is in italic</i>"
1015/// );
1016/// # }
1017/// ```
1018#[macro_export]
1019macro_rules! i {
1020 ($($all:tt)*) => {parse_double_tag!(ITag, $($all)*) };
1021}
1022
1023/// # Example
1024/// ```
1025/// # #[macro_use] extern crate rtml;
1026/// # fn main() {
1027/// use rtml::*;
1028///
1029/// assert_eq!(
1030/// iframe![.src="example.html"].render(),
1031/// "<iframe src=\"example.html\"></iframe>"
1032/// );
1033///
1034/// assert_eq!(
1035/// iframe![.src="example.html", .width="400", .height="300"].render(),
1036/// "<iframe src=\"example.html\" width=\"400\" height=\"300\"></iframe>"
1037/// );
1038/// # }
1039/// ```
1040#[macro_export]
1041macro_rules! iframe {
1042 ($($all:tt)*) => {parse_double_tag!(IframeTag, $($all)*) };
1043}
1044
1045/// # Example
1046/// ```
1047/// # #[macro_use] extern crate rtml;
1048/// # fn main() {
1049/// use rtml::*;
1050///
1051/// assert_eq!(
1052/// img![.src="example.jpg"].render(),
1053/// "<img src=\"example.jpg\">"
1054/// );
1055/// # }
1056/// ```
1057#[macro_export]
1058macro_rules! img {
1059 ($($all:tt)*) => {parse_single_tag!(ImgTag, $($all)*) };
1060}
1061
1062/// # Example
1063/// ```
1064/// # #[macro_use] extern crate rtml;
1065/// # fn main() {
1066/// use rtml::*;
1067///
1068/// assert_eq!(
1069/// input![._type="text", .name="name"].render(),
1070/// "<input type=\"text\" name=\"name\">"
1071/// );
1072///
1073/// assert_eq!(
1074/// input![._type="submit", .value="submit"].render(),
1075/// "<input type=\"submit\" value=\"submit\">"
1076/// );
1077/// # }
1078/// ```
1079#[macro_export]
1080macro_rules! input {
1081 ($($all:tt)*) => {parse_single_tag!(InputTag, $($all)*) };
1082}
1083
1084/// # Example
1085/// ```
1086/// # #[macro_use] extern crate rtml;
1087/// # fn main() {
1088/// use rtml::*;
1089///
1090/// assert_eq!(
1091/// ins![.datetime="2022-01-01", "This is inserted text"].render(),
1092/// "<ins datetime=\"2022-01-01\">This is inserted text</ins>"
1093/// );
1094/// # }
1095/// ```
1096#[macro_export]
1097macro_rules! ins {
1098 ($($all:tt)*) => {parse_double_tag!(InsTag, $($all)*) };
1099}
1100
1101/// # Example
1102/// ```
1103/// # #[macro_use] extern crate rtml;
1104/// # fn main() {
1105/// use rtml::*;
1106///
1107/// assert_eq!(
1108/// kbd!["This is keyboard input"].render(),
1109/// "<kbd>This is keyboard input</kbd>"
1110/// );
1111/// # }
1112/// ```
1113#[macro_export]
1114macro_rules! kbd {
1115 ($($all:tt)*) => {parse_double_tag!(KbdTag, $($all)*) };
1116}
1117
1118/// # Example
1119/// ```
1120/// # #[macro_use] extern crate rtml;
1121/// # fn main() {
1122/// use rtml::*;
1123///
1124/// assert_eq!(
1125/// label!["Name:"].render(),
1126/// "<label>Name:</label>"
1127/// );
1128/// # }
1129/// ```
1130#[macro_export]
1131macro_rules! label {
1132 ($($all:tt)*) => {parse_double_tag!(LabelTag, $($all)*) };
1133}
1134
1135/// # Example
1136/// ```
1137/// # #[macro_use] extern crate rtml;
1138/// # fn main() {
1139/// use rtml::*;
1140///
1141/// assert_eq!(
1142/// fieldset![legend!["This is a fieldset"], "This is the fieldset content"].render(),
1143/// "<fieldset><legend>This is a fieldset</legend>This is the fieldset content</fieldset>"
1144/// );
1145/// # }
1146/// ```
1147#[macro_export]
1148macro_rules! legend {
1149 ($($all:tt)*) => {parse_double_tag!(LegendTag, $($all)*) };
1150}
1151
1152/// # Example
1153/// ```
1154/// # #[macro_use] extern crate rtml;
1155/// # fn main() {
1156/// use rtml::*;
1157///
1158/// assert_eq!(
1159/// li!["Item 1"].render(),
1160/// "<li>Item 1</li>"
1161/// );
1162///
1163/// assert_eq!(
1164/// li![.value=5, "Item 5"].render(),
1165/// "<li value=\"5\">Item 5</li>"
1166/// );
1167/// # }
1168/// ```
1169#[macro_export]
1170macro_rules! li {
1171 ($($all:tt)*) => {parse_double_tag!(LiTag, $($all)*) };
1172}
1173
1174/// # Example
1175/// ```
1176/// # #[macro_use] extern crate rtml;
1177/// # fn main() {
1178/// use rtml::*;
1179///
1180/// assert_eq!(
1181/// link![.rel="stylesheet", .href="example.css"].render(),
1182/// "<link rel=\"stylesheet\" href=\"example.css\">"
1183/// );
1184/// # }
1185/// ```
1186#[macro_export]
1187macro_rules! link {
1188 ($($all:tt)*) => {parse_single_tag!(LinkTag, $($all)*) };
1189}
1190
1191/// # Example
1192/// ```
1193/// # #[macro_use] extern crate rtml;
1194/// # fn main() {
1195/// use rtml::*;
1196///
1197/// assert_eq!(
1198/// main!["This is the main content"].render(),
1199/// "<main>This is the main content</main>"
1200/// );
1201/// # }
1202/// ```
1203#[macro_export]
1204macro_rules! main {
1205 ($($all:tt)*) => {parse_double_tag!(MainTag, $($all)*) };
1206}
1207
1208/// # Example
1209/// ```
1210/// # #[macro_use] extern crate rtml;
1211/// # fn main() {
1212/// use rtml::*;
1213///
1214/// assert_eq!(
1215/// map![.name="example", area![.shape="rect", .coords="0,0,100,100", .href="example.html"]].render(),
1216/// "<map name=\"example\"><area shape=\"rect\" coords=\"0,0,100,100\" href=\"example.html\"></map>"
1217/// );
1218/// # }
1219#[macro_export]
1220macro_rules! map {
1221 ($($all:tt)*) => {parse_double_tag!(MapTag, $($all)*) };
1222}
1223
1224/// # Example
1225/// ```
1226/// # #[macro_use] extern crate rtml;
1227/// # fn main() {
1228/// use rtml::*;
1229///
1230/// assert_eq!(
1231/// mark!["This is marked text"].render(),
1232/// "<mark>This is marked text</mark>"
1233/// );
1234/// # }
1235/// ```
1236#[macro_export]
1237macro_rules! mark {
1238 ($($all:tt)*) => {parse_double_tag!(MarkTag, $($all)*) };
1239}
1240
1241/// # Example
1242/// ```
1243/// # #[macro_use] extern crate rtml;
1244/// # fn main() {
1245/// use rtml::*;
1246///
1247/// assert_eq!(
1248/// menu![li!["Item 1"], li!["Item 2"]].render(),
1249/// "<menu><li>Item 1</li><li>Item 2</li></menu>"
1250/// );
1251/// # }
1252/// ```
1253#[macro_export]
1254macro_rules! menu {
1255 ($($all:tt)*) => {parse_double_tag!(MenuTag, $($all)*) };
1256}
1257
1258/// # Example
1259/// ```
1260/// # #[macro_use] extern crate rtml;
1261/// # fn main() {
1262/// use rtml::*;
1263///
1264/// assert_eq!(
1265/// meta![.name="viewport", .content="width=device-width, initial-scale=1"].render(),
1266/// "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
1267/// );
1268/// # }
1269/// ```
1270#[macro_export]
1271macro_rules! meta {
1272 ($($all:tt)*) => {parse_single_tag!(MetaTag, $($all)*) };
1273}
1274
1275/// # Example
1276/// ```
1277/// # #[macro_use] extern crate rtml;
1278/// # fn main() {
1279/// use rtml::*;
1280///
1281/// assert_eq!(
1282/// meter![.value=2, .min=0, .max=5, "2 out of 5"].render(),
1283/// "<meter value=\"2\" min=\"0\" max=\"5\">2 out of 5</meter>"
1284/// );
1285/// # }
1286/// ```
1287#[macro_export]
1288macro_rules! meter {
1289 ($($all:tt)*) => {parse_double_tag!(MeterTag, $($all)*) };
1290}
1291
1292/// # Example
1293/// ```
1294/// # #[macro_use] extern crate rtml;
1295/// # fn main() {
1296/// use rtml::*;
1297///
1298/// assert_eq!(
1299/// nav![a![.href="home.html", "Home"], a![.href="about.html", "About"], a![.href="contact.html", "Contact"]].render(),
1300/// "<nav><a href=\"home.html\">Home</a><a href=\"about.html\">About</a><a href=\"contact.html\">Contact</a></nav>"
1301/// );
1302/// # }
1303/// ```
1304#[macro_export]
1305macro_rules! nav {
1306 ($($all:tt)*) => {parse_double_tag!(NavTag, $($all)*) };
1307}
1308
1309/// # Example
1310/// ```
1311/// # #[macro_use] extern crate rtml;
1312/// # fn main() {
1313/// use rtml::*;
1314///
1315/// assert_eq!(
1316/// noscript!["JavaScript is disabled."].render(),
1317/// "<noscript>JavaScript is disabled.</noscript>"
1318/// );
1319/// # }
1320/// ```
1321#[macro_export]
1322macro_rules! noscript {
1323 ($($all:tt)*) => {parse_double_tag!(NoscriptTag, $($all)*) };
1324}
1325
1326/// # Example
1327/// ```
1328/// # #[macro_use] extern crate rtml;
1329/// # fn main() {
1330/// use rtml::*;
1331///
1332/// assert_eq!(
1333/// ol![li!["Item 1"], li!["Item 2"]].render(),
1334/// "<ol><li>Item 1</li><li>Item 2</li></ol>"
1335/// );
1336/// # }
1337/// ```
1338#[macro_export]
1339macro_rules! ol {
1340 ($($all:tt)*) => {parse_double_tag!(OlTag, $($all)*) };
1341}
1342
1343/// # Example
1344/// ```
1345/// # #[macro_use] extern crate rtml;
1346/// # fn main() {
1347/// use rtml::*;
1348///
1349/// assert_eq!(
1350/// optgroup![.label="Fruits", option!["Apple"], option!["Banana"], option!["Cherry"]].render(),
1351/// "<optgroup label=\"Fruits\"><option>Apple</option><option>Banana</option><option>Cherry</option></optgroup>"
1352/// );
1353/// # }
1354/// ```
1355#[macro_export]
1356macro_rules! optgroup {
1357 ($($all:tt)*) => {parse_double_tag!(OptgroupTag, $($all)*) };
1358}
1359
1360/// # Example
1361/// ```
1362/// # #[macro_use] extern crate rtml;
1363/// # fn main() {
1364/// use rtml::*;
1365///
1366/// assert_eq!(
1367/// option!["Apple"].render(),
1368/// "<option>Apple</option>"
1369/// );
1370///
1371/// assert_eq!(
1372/// option![.value="a", "Apple"].render(),
1373/// "<option value=\"a\">Apple</option>"
1374/// );
1375/// # }
1376/// ```
1377#[macro_export]
1378macro_rules! option {
1379 ($($all:tt)*) => {parse_double_tag!(OptionTag, $($all)*) };
1380}
1381
1382/// # Example
1383/// ```
1384/// # #[macro_use] extern crate rtml;
1385/// # fn main() {
1386/// use rtml::*;
1387///
1388/// assert_eq!(
1389/// output!["10"].render(),
1390/// "<output>10</output>"
1391/// );
1392/// # }
1393/// ```
1394#[macro_export]
1395macro_rules! output {
1396 ($($all:tt)*) => {parse_double_tag!(OutputTag, $($all)*) };
1397}
1398
1399/// # Example
1400/// ```
1401/// # #[macro_use] extern crate rtml;
1402/// # fn main() {
1403/// use rtml::*;
1404///
1405/// assert_eq!(
1406/// p!["This is a paragraph"].render(),
1407/// "<p>This is a paragraph</p>"
1408/// );
1409/// # }
1410/// ```
1411#[macro_export]
1412macro_rules! p {
1413 ($($all:tt)*) => {parse_double_tag!(PTag, $($all)*) };
1414}
1415
1416#[macro_export]
1417macro_rules! picture {
1418 ($($all:tt)*) => {parse_double_tag!(PictureTag, $($all)*) };
1419}
1420
1421/// # Example
1422/// ```
1423/// # #[macro_use] extern crate rtml;
1424/// # fn main() {
1425/// use rtml::*;
1426///
1427/// assert_eq!(
1428/// pre![" var x = 5;\n var y = 10;\n var z = x + y;\n"].render(),
1429/// "<pre> var x = 5;\n var y = 10;\n var z = x + y;\n</pre>"
1430/// );
1431/// # }
1432/// ```
1433#[macro_export]
1434macro_rules! pre {
1435 ($($all:tt)*) => {parse_double_tag!(PreTag, $($all)*) };
1436}
1437
1438/// # Example
1439/// ```
1440/// # #[macro_use] extern crate rtml;
1441/// # fn main() {
1442/// use rtml::*;
1443///
1444/// assert_eq!(
1445/// progress![.value=50, .max=100, "50%"].render(),
1446/// "<progress value=\"50\" max=\"100\">50%</progress>"
1447/// );
1448/// # }
1449/// ```
1450#[macro_export]
1451macro_rules! progress {
1452 ($($all:tt)*) => {parse_double_tag!(ProgressTag, $($all)*) };
1453}
1454
1455/// # Example
1456/// ```
1457/// # #[macro_use] extern crate rtml;
1458/// # fn main() {
1459/// use rtml::*;
1460///
1461/// assert_eq!(
1462/// q!["This is a short quote."].render(),
1463/// "<q>This is a short quote.</q>"
1464/// );
1465///
1466/// assert_eq!(
1467/// q![.cite="https://www.example.com", "This is a short quote."].render(),
1468/// "<q cite=\"https://www.example.com\">This is a short quote.</q>"
1469/// );
1470/// # }
1471/// ```
1472#[macro_export]
1473macro_rules! q {
1474 ($($all:tt)*) => {parse_double_tag!(QTag, $($all)*) };
1475}
1476
1477/// # Example
1478/// ```
1479/// # #[macro_use] extern crate rtml;
1480/// # fn main() {
1481/// use rtml::*;
1482///
1483/// assert_eq!(
1484/// rp!["」"].render(),
1485/// "<rp>」</rp>"
1486/// );
1487/// # }
1488/// ```
1489#[macro_export]
1490macro_rules! rp {
1491 ($($all:tt)*) => {parse_double_tag!(RpTag, $($all)*) };
1492}
1493
1494/// # Example
1495/// ```
1496/// # #[macro_use] extern crate rtml;
1497/// # fn main() {
1498/// use rtml::*;
1499///
1500/// assert_eq!(
1501/// ruby![ "漢", rt!["ㄏㄢˋ"] ].render(),
1502/// "<ruby>漢<rt>ㄏㄢˋ</rt></ruby>"
1503/// );
1504/// # }
1505/// ```
1506#[macro_export]
1507macro_rules! rt {
1508 ($($all:tt)*) => {parse_double_tag!(RtTag, $($all)*) };
1509}
1510
1511/// # Example
1512/// ```
1513/// # #[macro_use] extern crate rtml;
1514/// # fn main() {
1515/// use rtml::*;
1516///
1517/// assert_eq!(
1518/// ruby![ "漢", rt!["ㄏㄢˋ"] ].render(),
1519/// "<ruby>漢<rt>ㄏㄢˋ</rt></ruby>"
1520/// );
1521/// # }
1522/// ```
1523#[macro_export]
1524macro_rules! ruby {
1525 ($($all:tt)*) => {parse_double_tag!(RubyTag, $($all)*) };
1526}
1527
1528/// # Example
1529/// ```
1530/// # #[macro_use] extern crate rtml;
1531/// # fn main() {
1532/// use rtml::*;
1533///
1534/// assert_eq!(
1535/// s!["This text is no longer accurate"].render(),
1536/// "<s>This text is no longer accurate</s>"
1537/// );
1538/// # }
1539/// ```
1540#[macro_export]
1541macro_rules! s {
1542 ($($all:tt)*) => {parse_double_tag!(STag, $($all)*) };
1543}
1544
1545/// # Example
1546/// ```
1547/// # #[macro_use] extern crate rtml;
1548/// # fn main() {
1549/// use rtml::*;
1550///
1551/// assert_eq!(
1552/// samp!["Sample output from a computer program"].render(),
1553/// "<samp>Sample output from a computer program</samp>"
1554/// );
1555/// # }
1556/// ```
1557#[macro_export]
1558macro_rules! samp {
1559 ($($all:tt)*) => {parse_double_tag!(SampTag, $($all)*) };
1560}
1561
1562/// # Example
1563/// ```
1564/// # #[macro_use] extern crate rtml;
1565/// # fn main() {
1566/// use rtml::*;
1567///
1568/// assert_eq!(
1569/// script![.src="script.js", ._type="text/javascript"].render(),
1570/// "<script src=\"script.js\" type=\"text/javascript\"></script>"
1571/// );
1572/// # }
1573/// ```
1574#[macro_export]
1575macro_rules! script {
1576 ($($all:tt)*) => {parse_double_tag!(ScriptTag, $($all)*) };
1577}
1578
1579/// # Example
1580/// ```
1581/// # #[macro_use] extern crate rtml;
1582/// # fn main() {
1583/// use rtml::*;
1584///
1585/// assert_eq!(
1586/// section![h1!["Section Title"], "Section content."].render(),
1587/// "<section><h1>Section Title</h1>Section content.</section>"
1588/// );
1589/// # }
1590/// ```
1591#[macro_export]
1592macro_rules! section {
1593 ($($all:tt)*) => {parse_double_tag!(SectionTag, $($all)*) };
1594}
1595
1596/// # Example
1597/// ```
1598/// # #[macro_use] extern crate rtml;
1599/// # fn main() {
1600/// use rtml::*;
1601///
1602/// assert_eq!(
1603/// select![
1604/// option!["Option 1"],
1605/// option!["Option 2"],
1606/// option!["Option 3"]
1607/// ].render(),
1608/// "<select><option>Option 1</option><option>Option 2</option><option>Option 3</option></select>"
1609/// );
1610/// # }
1611/// ```
1612#[macro_export]
1613macro_rules! select {
1614 ($($all:tt)*) => {parse_double_tag!(SelectTag, $($all)*) };
1615}
1616
1617/// # Example
1618/// ```
1619/// # #[macro_use] extern crate rtml;
1620/// # fn main() {
1621/// use rtml::*;
1622///
1623/// assert_eq!(
1624/// small!["This text is small"].render(),
1625/// "<small>This text is small</small>"
1626/// );
1627/// # }
1628/// ```
1629#[macro_export]
1630macro_rules! small {
1631 ($($all:tt)*) => {parse_double_tag!(SmallTag, $($all)*) };
1632}
1633
1634/// # Example
1635/// ```
1636/// # #[macro_use] extern crate rtml;
1637/// # fn main() {
1638/// use rtml::*;
1639///
1640/// assert_eq!(
1641/// source![.src="audio.ogg", ._type="audio/ogg"].render(),
1642/// "<source src=\"audio.ogg\" type=\"audio/ogg\">"
1643/// );
1644/// # }
1645/// ```
1646#[macro_export]
1647macro_rules! source {
1648 ($($all:tt)*) => {parse_single_tag!(SourceTag, $($all)*) };
1649}
1650
1651/// # Example
1652/// ```
1653/// # #[macro_use] extern crate rtml;
1654/// # fn main() {
1655/// use rtml::*;
1656///
1657/// assert_eq!(
1658/// span![.class="highlight", "This text is highlighted"].render(),
1659/// "<span class=\"highlight\">This text is highlighted</span>"
1660/// );
1661/// # }
1662/// ```
1663#[macro_export]
1664macro_rules! span {
1665 ($($all:tt)*) => {parse_double_tag!(SpanTag, $($all)*) };
1666}
1667
1668/// # Example
1669/// ```
1670/// # #[macro_use] extern crate rtml;
1671/// # fn main() {
1672/// use rtml::*;
1673///
1674/// assert_eq!(
1675/// strong!["This text is important"].render(),
1676/// "<strong>This text is important</strong>"
1677/// );
1678/// # }
1679/// ```
1680#[macro_export]
1681macro_rules! strong {
1682 ($($all:tt)*) => {parse_double_tag!(StrongTag, $($all)*) };
1683}
1684
1685/// # Example
1686/// ```
1687/// # #[macro_use] extern crate rtml;
1688/// # fn main() {
1689/// use rtml::*;
1690///
1691/// assert_eq!(
1692/// style![._type="text/css", "body {background-color: black;} h1 {color: white;}"].render(),
1693/// "<style type=\"text/css\">body {background-color: black;} h1 {color: white;}</style>"
1694/// );
1695/// # }
1696/// ```
1697#[macro_export]
1698macro_rules! style {
1699 ($($all:tt)*) => {parse_double_tag!(StyleTag, $($all)*) };
1700}
1701
1702/// # Example
1703/// ```
1704/// # #[macro_use] extern crate rtml;
1705/// # fn main() {
1706/// use rtml::*;
1707///
1708/// assert_eq!(
1709/// sub!["This text is a subscript"].render(),
1710/// "<sub>This text is a subscript</sub>"
1711/// );
1712/// # }
1713/// ```
1714#[macro_export]
1715macro_rules! sub {
1716 ($($all:tt)*) => {parse_double_tag!(SubTag, $($all)*) };
1717}
1718
1719/// # Example
1720/// ```
1721/// # #[macro_use] extern crate rtml;
1722/// # fn main() {
1723/// use rtml::*;
1724///
1725/// assert_eq!(
1726/// summary!["This is a summary"].render(),
1727/// "<summary>This is a summary</summary>"
1728/// );
1729/// # }
1730/// ```
1731#[macro_export]
1732macro_rules! summary {
1733 ($($all:tt)*) => {parse_double_tag!(SummaryTag, $($all)*) };
1734}
1735
1736/// # Example
1737/// ```
1738/// # #[macro_use] extern crate rtml;
1739/// # fn main() {
1740/// use rtml::*;
1741///
1742/// assert_eq!(
1743/// sup!["This text is a superscript"].render(),
1744/// "<sup>This text is a superscript</sup>"
1745/// );
1746/// # }
1747/// ```
1748#[macro_export]
1749macro_rules! sup {
1750 ($($all:tt)*) => {parse_double_tag!(SupTag, $($all)*) };
1751}
1752
1753/// # Example
1754/// ```
1755/// # #[macro_use] extern crate rtml;
1756/// # fn main() {
1757/// use rtml::*;
1758///
1759/// assert_eq!(
1760/// table![
1761/// tr![
1762/// td!["Cell 1,1"],
1763/// td!["Cell 1,2"]
1764/// ],
1765/// tr![
1766/// td!["Cell 2,1"],
1767/// td!["Cell 2,2"]
1768/// ]
1769/// ].render(),
1770/// "<table><tr><td>Cell 1,1</td><td>Cell 1,2</td></tr><tr><td>Cell 2,1</td><td>Cell 2,2</td></tr></table>"
1771/// );
1772/// # }
1773/// ```
1774#[macro_export]
1775macro_rules! table {
1776 ($($all:tt)*) => {parse_double_tag!(TableTag, $($all)*) };
1777}
1778
1779/// # Example
1780/// ```
1781/// # #[macro_use] extern crate rtml;
1782/// # fn main() {
1783/// use rtml::*;
1784///
1785/// assert_eq!(
1786/// tbody![
1787/// tr![
1788/// td!["Cell 1,1"],
1789/// td!["Cell 1,2"]
1790/// ],
1791/// tr![
1792/// td!["Cell 2,1"],
1793/// td!["Cell 2,2"]
1794/// ]
1795/// ].render(),
1796/// "<tbody><tr><td>Cell 1,1</td><td>Cell 1,2</td></tr><tr><td>Cell 2,1</td><td>Cell 2,2</td></tr></tbody>"
1797/// );
1798/// # }
1799/// ```
1800#[macro_export]
1801macro_rules! tbody {
1802 ($($all:tt)*) => {parse_double_tag!(TbodyTag, $($all)*) };
1803}
1804
1805/// # Example
1806/// ```
1807/// # #[macro_use] extern crate rtml;
1808/// # fn main() {
1809/// use rtml::*;
1810///
1811/// assert_eq!(
1812/// td!["Cell 1,1"].render(),
1813/// "<td>Cell 1,1</td>"
1814/// );
1815/// # }
1816/// ```
1817#[macro_export]
1818macro_rules! td {
1819 ($($all:tt)*) => {parse_double_tag!(TdTag, $($all)*) };
1820}
1821
1822/// # Example
1823/// ```
1824/// # #[macro_use] extern crate rtml;
1825/// # fn main() {
1826/// use rtml::*;
1827///
1828/// assert_eq!(
1829/// template![
1830/// h1!["Title"],
1831/// p!["Description"]
1832/// ].render(),
1833/// "<template><h1>Title</h1><p>Description</p></template>"
1834/// );
1835/// # }
1836/// ```
1837#[macro_export]
1838macro_rules! template {
1839 ($($all:tt)*) => {parse_double_tag!(TemplateTag, $($all)*) };
1840}
1841
1842/// # Example
1843/// ```
1844/// # #[macro_use] extern crate rtml;
1845/// # fn main() {
1846/// use rtml::*;
1847///
1848/// assert_eq!(
1849/// textarea![.name="message", "Default text"].render(),
1850/// "<textarea name=\"message\">Default text</textarea>"
1851/// );
1852/// # }
1853/// ```
1854#[macro_export]
1855macro_rules! textarea {
1856 ($($all:tt)*) => {parse_double_tag!(TextareaTag, $($all)*) };
1857}
1858
1859/// # Example
1860/// ```
1861/// # #[macro_use] extern crate rtml;
1862/// # fn main() {
1863/// use rtml::*;
1864///
1865/// assert_eq!(
1866/// table![
1867/// tr![
1868/// td!["Cell 1,1"]
1869/// ],
1870/// tfoot![
1871/// tr![
1872/// td!["Footer 1"]
1873/// ]
1874/// ]
1875/// ].render(),
1876/// "<table><tr><td>Cell 1,1</td></tr><tfoot><tr><td>Footer 1</td></tr></tfoot></table>"
1877/// );
1878/// # }
1879/// ```
1880#[macro_export]
1881macro_rules! tfoot {
1882 ($($all:tt)*) => {parse_double_tag!(TfootTag, $($all)*) };
1883}
1884
1885/// # Example
1886/// ```
1887/// # #[macro_use] extern crate rtml;
1888/// # fn main() {
1889/// use rtml::*;
1890///
1891/// assert_eq!(
1892/// table![
1893/// thead![
1894/// tr![
1895/// th!["Header 1"]
1896/// ]
1897/// ],
1898/// tbody![
1899/// tr![
1900/// td!["Cell 1,1"]
1901/// ]
1902/// ],
1903/// tfoot![
1904/// tr![
1905/// td!["Footer 1"]
1906/// ]
1907/// ]
1908/// ].render(),
1909/// "<table><thead><tr><th>Header 1</th></tr></thead><tbody><tr><td>Cell 1,1</td></tr></tbody><tfoot><tr><td>Footer 1</td></tr></tfoot></table>"
1910/// );
1911/// # }
1912/// ```
1913#[macro_export]
1914macro_rules! th {
1915 ($($all:tt)*) => {parse_double_tag!(ThTag, $($all)*) };
1916}
1917
1918/// # Example
1919/// ```
1920/// # #[macro_use] extern crate rtml;
1921/// # fn main() {
1922/// use rtml::*;
1923///
1924/// assert_eq!(
1925/// table![
1926/// thead![
1927/// tr![
1928/// th!["Header 1"]
1929/// ]
1930/// ],
1931/// tbody![
1932/// tr![
1933/// td!["Cell 1,1"]
1934/// ]
1935/// ],
1936/// tfoot![
1937/// tr![
1938/// td!["Footer 1"]
1939/// ]
1940/// ]
1941/// ].render(),
1942/// "<table><thead><tr><th>Header 1</th></tr></thead><tbody><tr><td>Cell 1,1</td></tr></tbody><tfoot><tr><td>Footer 1</td></tr></tfoot></table>"
1943/// );
1944/// # }
1945/// ```
1946#[macro_export]
1947macro_rules! thead {
1948 ($($all:tt)*) => {parse_double_tag!(TheadTag, $($all)*) };
1949}
1950
1951/// # Example
1952/// ```
1953/// # #[macro_use] extern crate rtml;
1954/// # fn main() {
1955/// use rtml::*;
1956///
1957/// assert_eq!(
1958/// time![
1959/// .datetime="2022-07-05T18:00:00Z",
1960/// "July 5th, 2022 6:00 PM"
1961/// ].render(),
1962/// "<time datetime=\"2022-07-05T18:00:00Z\">July 5th, 2022 6:00 PM</time>"
1963/// );
1964/// # }
1965/// ```
1966#[macro_export]
1967macro_rules! time {
1968 ($($all:tt)*) => {parse_double_tag!(TimeTag, $($all)*) };
1969}
1970
1971/// # Example
1972/// ```
1973/// # #[macro_use] extern crate rtml;
1974/// # fn main() {
1975/// use rtml::*;
1976///
1977/// assert_eq!(
1978/// title![
1979/// "Page Title"
1980/// ].render(),
1981/// "<title>Page Title</title>"
1982/// );
1983/// # }
1984/// ```
1985#[macro_export]
1986macro_rules! title {
1987 ($($all:tt)*) => {parse_double_tag!(TitleTag, $($all)*) };
1988}
1989
1990/// # Example
1991/// ```
1992/// # #[macro_use] extern crate rtml;
1993/// # fn main() {
1994/// use rtml::*;
1995///
1996/// assert_eq!(
1997/// table![
1998/// tr![
1999/// td!["Cell 1,1"]
2000/// ],
2001/// tfoot![
2002/// tr![
2003/// td!["Footer 1"]
2004/// ]
2005/// ]
2006/// ].render(),
2007/// "<table><tr><td>Cell 1,1</td></tr><tfoot><tr><td>Footer 1</td></tr></tfoot></table>"
2008/// );
2009/// # }
2010/// ```
2011#[macro_export]
2012macro_rules! tr {
2013 ($($all:tt)*) => {parse_double_tag!(TrTag, $($all)*) };
2014}
2015
2016/// # Example
2017/// ```
2018/// # #[macro_use] extern crate rtml;
2019/// # fn main() {
2020/// use rtml::*;
2021///
2022/// assert_eq!(
2023/// track![
2024/// ._kind="captions",
2025/// .src="https://example.com/captions.vtt",
2026/// .srclang="en",
2027/// .label="English Captions"
2028/// ].render(),
2029/// "<track kind=\"captions\" src=\"https://example.com/captions.vtt\" srclang=\"en\" label=\"English Captions\"></track>"
2030/// );
2031/// # }
2032/// ```
2033#[macro_export]
2034macro_rules! track {
2035 ($($all:tt)*) => {parse_double_tag!(TrackTag, $($all)*) };
2036}
2037
2038/// # Example
2039/// ```
2040/// # #[macro_use] extern crate rtml;
2041/// # fn main() {
2042/// use rtml::*;
2043///
2044/// assert_eq!(
2045/// u![
2046/// "Underlined text"
2047/// ].render(),
2048/// "<u>Underlined text</u>"
2049/// );
2050/// # }
2051/// ```
2052#[macro_export]
2053macro_rules! u {
2054 ($($all:tt)*) => {parse_double_tag!(UTag, $($all)*) };
2055}
2056
2057/// # Example
2058/// ```
2059/// # #[macro_use] extern crate rtml;
2060/// # fn main() {
2061/// use rtml::*;
2062///
2063/// assert_eq!(
2064/// ul![
2065/// li!["Item 1"],
2066/// li!["Item 2"],
2067/// li!["Item 3"]
2068/// ].render(),
2069/// "<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>"
2070/// );
2071/// # }
2072/// ```
2073#[macro_export]
2074macro_rules! ul {
2075 ($($all:tt)*) => {parse_double_tag!(UlTag, $($all)*) };
2076}
2077
2078/// # Example
2079/// ```
2080/// # #[macro_use] extern crate rtml;
2081/// # fn main() {
2082/// use rtml::*;
2083///
2084/// assert_eq!(
2085/// var![ "math" ].render(),
2086/// "<var>math</var>"
2087/// );
2088/// # }
2089/// ```
2090#[macro_export]
2091macro_rules! var {
2092 ($($all:tt)*) => {parse_double_tag!(VarTag, $($all)*) };
2093}
2094
2095/// # Example
2096/// ```
2097/// # #[macro_use] extern crate rtml;
2098/// # fn main() {
2099/// use rtml::*;
2100///
2101/// assert_eq!(
2102/// video![
2103/// .src="https://example.com/video.mp4",
2104/// .width="720",
2105/// .height="480",
2106/// .controls="true"
2107/// ].render(),
2108/// "<video src=\"https://example.com/video.mp4\" width=\"720\" height=\"480\" controls=\"true\"></video>"
2109/// );
2110/// # }
2111/// ```
2112#[macro_export]
2113macro_rules! video {
2114 ($($all:tt)*) => {parse_double_tag!(VideoTag, $($all)*) };
2115}
2116
2117/// # Example
2118/// ```
2119/// # #[macro_use] extern crate rtml;
2120/// # fn main() {
2121/// use rtml::*;
2122///
2123/// assert_eq!(
2124/// wbr![].render(),
2125/// "<wbr>"
2126/// );
2127/// # }
2128/// ```
2129#[macro_export]
2130macro_rules! wbr {
2131 ($($all:tt)*) => {parse_single_tag!(WbrTag, $($all)*) };
2132}
2133
2134#[macro_export]
2135macro_rules! parse_double_tag {
2136 () => {
2137 ""
2138 };
2139 (,$inner_left:expr $(,$inner:expr)*) => {
2140 render_fn!("{}{}", $inner_left, parse_double_tag!($(,$inner)*))
2141 };
2142 ($tag:ident,) => {
2143 render_fn!("<{}></{}>", $tag, $tag)
2144 };
2145 ($tag:ident $(,$inner:expr)*) => {
2146 render_fn!("<{}>{}</{}>", $tag, parse_double_tag!($(,$inner)*), $tag)
2147 };
2148 ($tag:ident $(,.$attr:ident = $value:expr)* $(,$inner:expr)*) => {
2149 render_fn!("<{}{}>{}</{}>", $tag, parse_attr!($tag $(,.$attr = $value)*), parse_double_tag!($(,$inner)*), $tag)
2150 };
2151}
2152
2153#[macro_export]
2154macro_rules! parse_single_tag {
2155 ($tag:ident,) => {
2156 render_fn!("<{}>", $tag)
2157 };
2158 ($tag:ident $(,.$attr:ident = $value:expr)*) => {
2159 render_fn!("<{}{}>", $tag, parse_attr!($tag $(,.$attr = $value)*))
2160 };
2161}
2162
2163#[macro_export]
2164macro_rules! parse_attr {
2165 () => { "" };
2166 ($tag:ident) => {
2167 ""
2168 };
2169 ($tag:ident, .$attr:ident = $value:expr $(,.$right_attr:ident$(-$nexts:ident)* = $right_expr:expr)*) => {{
2170 let ident = $attr;
2171 $tag.type_check(&ident);
2172 render_fn!(" {}{}{}", ident, parse_val!($value), parse_attr!($tag $(,.$right_attr = $right_expr)*))
2173 }};
2174}
2175
2176#[macro_export]
2177macro_rules! parse_val {
2178 () => {
2179 ""
2180 };
2181 ($val:expr) => {
2182 render_fn!("=\"{}\"", $val)
2183 };
2184}