htmlgen.nim 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Do yourself a favor and import the module
  10. ## as `from htmlgen import nil` and then fully qualify the macros.
  11. ##
  12. ## *Note*: The Karax project (`nimble install karax`) has a better
  13. ## way to achieve the same, see https://github.com/pragmagic/karax/blob/master/tests/nativehtmlgen.nim
  14. ## for an example.
  15. ##
  16. ##
  17. ## This module implements a simple `XML`:idx: and `HTML`:idx: code
  18. ## generator. Each commonly used HTML tag has a corresponding macro
  19. ## that generates a string with its HTML representation.
  20. ##
  21. ## MathML
  22. ## ======
  23. ##
  24. ## `MathML <https://wikipedia.org/wiki/MathML>`_ is supported, MathML is part of HTML5.
  25. ## `MathML <https://wikipedia.org/wiki/MathML>`_ is an Standard ISO/IEC 40314 from year 2015.
  26. ## MathML allows you to `draw advanced math on the web <https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math#Examples>`_,
  27. ## `visually similar to Latex math. <https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics#Example>`_
  28. ##
  29. ## Examples
  30. ## ========
  31. ##
  32. ## ```Nim
  33. ## var nim = "Nim"
  34. ## echo h1(a(href="https://nim-lang.org", nim))
  35. ## ```
  36. ##
  37. ## Writes the string:
  38. ##
  39. ## <h1><a href="https://nim-lang.org">Nim</a></h1>
  40. ##
  41. import
  42. macros, strutils
  43. const
  44. coreAttr* = " accesskey class contenteditable dir hidden id lang " &
  45. "spellcheck style tabindex title translate " ## HTML DOM Core Attributes
  46. eventAttr* = "onabort onblur oncancel oncanplay oncanplaythrough onchange " &
  47. "onclick oncuechange ondblclick ondurationchange onemptied onended " &
  48. "onerror onfocus oninput oninvalid onkeydown onkeypress onkeyup onload " &
  49. "onloadeddata onloadedmetadata onloadstart onmousedown onmouseenter " &
  50. "onmouseleave onmousemove onmouseout onmouseover onmouseup onmousewheel " &
  51. "onpause onplay onplaying onprogress onratechange onreset onresize " &
  52. "onscroll onseeked onseeking onselect onshow onstalled onsubmit " &
  53. "onsuspend ontimeupdate ontoggle onvolumechange onwaiting " ## HTML DOM Event Attributes
  54. ariaAttr* = " role " ## HTML DOM Aria Attributes
  55. commonAttr* = coreAttr & eventAttr & ariaAttr ## HTML DOM Common Attributes
  56. proc getIdent(e: NimNode): string =
  57. case e.kind
  58. of nnkIdent:
  59. result = e.strVal.normalize
  60. of nnkAccQuoted:
  61. result = getIdent(e[0])
  62. for i in 1 .. e.len-1:
  63. result.add getIdent(e[i])
  64. else: error("cannot extract identifier from node: " & toStrLit(e).strVal, e)
  65. proc delete[T](s: var seq[T], attr: T): bool =
  66. var idx = find(s, attr)
  67. if idx >= 0:
  68. var L = s.len
  69. s[idx] = s[L-1]
  70. setLen(s, L-1)
  71. result = true
  72. proc xmlCheckedTag*(argsList: NimNode, tag: string, optAttr = "", reqAttr = "",
  73. isLeaf = false): NimNode =
  74. ## use this procedure to define a new XML tag
  75. # copy the attributes; when iterating over them these lists
  76. # will be modified, so that each attribute is only given one value
  77. var req = splitWhitespace(reqAttr)
  78. var opt = splitWhitespace(optAttr)
  79. result = newNimNode(nnkBracket)
  80. result.add(newStrLitNode("<"))
  81. result.add(newStrLitNode(tag))
  82. # first pass over attributes:
  83. for i in 0 ..< argsList.len:
  84. if argsList[i].kind == nnkExprEqExpr:
  85. var name = getIdent(argsList[i][0])
  86. if name.startsWith("data-") or delete(req, name) or delete(opt, name):
  87. result.add(newStrLitNode(" "))
  88. result.add(newStrLitNode(name))
  89. result.add(newStrLitNode("=\""))
  90. result.add(argsList[i][1])
  91. result.add(newStrLitNode("\""))
  92. else:
  93. error("invalid attribute for '" & tag & "' element: " & name, argsList[i])
  94. # check each required attribute exists:
  95. if req.len > 0:
  96. error(req[0] & " attribute for '" & tag & "' element expected", argsList)
  97. if isLeaf:
  98. for i in 0 ..< argsList.len:
  99. if argsList[i].kind != nnkExprEqExpr:
  100. error("element " & tag & " cannot be nested", argsList[i])
  101. result.add(newStrLitNode(" />"))
  102. else:
  103. result.add(newStrLitNode(">"))
  104. # second pass over elements:
  105. for i in 0 ..< argsList.len:
  106. if argsList[i].kind != nnkExprEqExpr: result.add(argsList[i])
  107. result.add(newStrLitNode("</"))
  108. result.add(newStrLitNode(tag))
  109. result.add(newStrLitNode(">"))
  110. result = nestList(ident"&", result)
  111. macro a*(e: varargs[untyped]): untyped =
  112. ## Generates the HTML `a` element.
  113. result = xmlCheckedTag(e, "a", "href target download rel hreflang type " &
  114. commonAttr)
  115. macro abbr*(e: varargs[untyped]): untyped =
  116. ## Generates the HTML `abbr` element.
  117. result = xmlCheckedTag(e, "abbr", commonAttr)
  118. macro address*(e: varargs[untyped]): untyped =
  119. ## Generates the HTML `address` element.
  120. result = xmlCheckedTag(e, "address", commonAttr)
  121. macro area*(e: varargs[untyped]): untyped =
  122. ## Generates the HTML `area` element.
  123. result = xmlCheckedTag(e, "area", "coords download href hreflang rel " &
  124. "shape target type" & commonAttr, "alt", true)
  125. macro article*(e: varargs[untyped]): untyped =
  126. ## Generates the HTML `article` element.
  127. result = xmlCheckedTag(e, "article", commonAttr)
  128. macro aside*(e: varargs[untyped]): untyped =
  129. ## Generates the HTML `aside` element.
  130. result = xmlCheckedTag(e, "aside", commonAttr)
  131. macro audio*(e: varargs[untyped]): untyped =
  132. ## Generates the HTML `audio` element.
  133. result = xmlCheckedTag(e, "audio", "src crossorigin preload " &
  134. "autoplay mediagroup loop muted controls" & commonAttr)
  135. macro b*(e: varargs[untyped]): untyped =
  136. ## Generates the HTML `b` element.
  137. result = xmlCheckedTag(e, "b", commonAttr)
  138. macro base*(e: varargs[untyped]): untyped =
  139. ## Generates the HTML `base` element.
  140. result = xmlCheckedTag(e, "base", "href target" & commonAttr, "", true)
  141. macro bdi*(e: varargs[untyped]): untyped =
  142. ## Generates the HTML `bdi` element.
  143. result = xmlCheckedTag(e, "bdi", commonAttr)
  144. macro bdo*(e: varargs[untyped]): untyped =
  145. ## Generates the HTML `bdo` element.
  146. result = xmlCheckedTag(e, "bdo", commonAttr)
  147. macro big*(e: varargs[untyped]): untyped =
  148. ## Generates the HTML `big` element.
  149. result = xmlCheckedTag(e, "big", commonAttr)
  150. macro blockquote*(e: varargs[untyped]): untyped =
  151. ## Generates the HTML `blockquote` element.
  152. result = xmlCheckedTag(e, "blockquote", " cite" & commonAttr)
  153. macro body*(e: varargs[untyped]): untyped =
  154. ## Generates the HTML `body` element.
  155. result = xmlCheckedTag(e, "body", "onafterprint onbeforeprint " &
  156. "onbeforeunload onhashchange onmessage onoffline ononline onpagehide " &
  157. "onpageshow onpopstate onstorage onunload" & commonAttr)
  158. macro br*(e: varargs[untyped]): untyped =
  159. ## Generates the HTML `br` element.
  160. result = xmlCheckedTag(e, "br", commonAttr, "", true)
  161. macro button*(e: varargs[untyped]): untyped =
  162. ## Generates the HTML `button` element.
  163. result = xmlCheckedTag(e, "button", "autofocus disabled form formaction " &
  164. "formenctype formmethod formnovalidate formtarget menu name type value" &
  165. commonAttr)
  166. macro canvas*(e: varargs[untyped]): untyped =
  167. ## Generates the HTML `canvas` element.
  168. result = xmlCheckedTag(e, "canvas", "width height" & commonAttr)
  169. macro caption*(e: varargs[untyped]): untyped =
  170. ## Generates the HTML `caption` element.
  171. result = xmlCheckedTag(e, "caption", commonAttr)
  172. macro center*(e: varargs[untyped]): untyped =
  173. ## Generates the HTML `center` element.
  174. result = xmlCheckedTag(e, "center", commonAttr)
  175. macro cite*(e: varargs[untyped]): untyped =
  176. ## Generates the HTML `cite` element.
  177. result = xmlCheckedTag(e, "cite", commonAttr)
  178. macro code*(e: varargs[untyped]): untyped =
  179. ## Generates the HTML `code` element.
  180. result = xmlCheckedTag(e, "code", commonAttr)
  181. macro col*(e: varargs[untyped]): untyped =
  182. ## Generates the HTML `col` element.
  183. result = xmlCheckedTag(e, "col", "span" & commonAttr, "", true)
  184. macro colgroup*(e: varargs[untyped]): untyped =
  185. ## Generates the HTML `colgroup` element.
  186. result = xmlCheckedTag(e, "colgroup", "span" & commonAttr)
  187. macro data*(e: varargs[untyped]): untyped =
  188. ## Generates the HTML `data` element.
  189. result = xmlCheckedTag(e, "data", "value" & commonAttr)
  190. macro datalist*(e: varargs[untyped]): untyped =
  191. ## Generates the HTML `datalist` element.
  192. result = xmlCheckedTag(e, "datalist", commonAttr)
  193. macro dd*(e: varargs[untyped]): untyped =
  194. ## Generates the HTML `dd` element.
  195. result = xmlCheckedTag(e, "dd", commonAttr)
  196. macro del*(e: varargs[untyped]): untyped =
  197. ## Generates the HTML `del` element.
  198. result = xmlCheckedTag(e, "del", "cite datetime" & commonAttr)
  199. macro details*(e: varargs[untyped]): untyped =
  200. ## Generates the HTML `details` element.
  201. result = xmlCheckedTag(e, "details", commonAttr & "open")
  202. macro dfn*(e: varargs[untyped]): untyped =
  203. ## Generates the HTML `dfn` element.
  204. result = xmlCheckedTag(e, "dfn", commonAttr)
  205. macro dialog*(e: varargs[untyped]): untyped =
  206. ## Generates the HTML `dialog` element.
  207. result = xmlCheckedTag(e, "dialog", commonAttr & "open")
  208. macro `div`*(e: varargs[untyped]): untyped =
  209. ## Generates the HTML `div` element.
  210. result = xmlCheckedTag(e, "div", commonAttr)
  211. macro dl*(e: varargs[untyped]): untyped =
  212. ## Generates the HTML `dl` element.
  213. result = xmlCheckedTag(e, "dl", commonAttr)
  214. macro dt*(e: varargs[untyped]): untyped =
  215. ## Generates the HTML `dt` element.
  216. result = xmlCheckedTag(e, "dt", commonAttr)
  217. macro em*(e: varargs[untyped]): untyped =
  218. ## Generates the HTML `em` element.
  219. result = xmlCheckedTag(e, "em", commonAttr)
  220. macro embed*(e: varargs[untyped]): untyped =
  221. ## Generates the HTML `embed` element.
  222. result = xmlCheckedTag(e, "embed", "src type height width" &
  223. commonAttr, "", true)
  224. macro fieldset*(e: varargs[untyped]): untyped =
  225. ## Generates the HTML `fieldset` element.
  226. result = xmlCheckedTag(e, "fieldset", "disabled form name" & commonAttr)
  227. macro figure*(e: varargs[untyped]): untyped =
  228. ## Generates the HTML `figure` element.
  229. result = xmlCheckedTag(e, "figure", commonAttr)
  230. macro figcaption*(e: varargs[untyped]): untyped =
  231. ## Generates the HTML `figcaption` element.
  232. result = xmlCheckedTag(e, "figcaption", commonAttr)
  233. macro footer*(e: varargs[untyped]): untyped =
  234. ## Generates the HTML `footer` element.
  235. result = xmlCheckedTag(e, "footer", commonAttr)
  236. macro form*(e: varargs[untyped]): untyped =
  237. ## Generates the HTML `form` element.
  238. result = xmlCheckedTag(e, "form", "accept-charset action autocomplete " &
  239. "enctype method name novalidate target" & commonAttr)
  240. macro h1*(e: varargs[untyped]): untyped =
  241. ## Generates the HTML `h1` element.
  242. result = xmlCheckedTag(e, "h1", commonAttr)
  243. macro h2*(e: varargs[untyped]): untyped =
  244. ## Generates the HTML `h2` element.
  245. result = xmlCheckedTag(e, "h2", commonAttr)
  246. macro h3*(e: varargs[untyped]): untyped =
  247. ## Generates the HTML `h3` element.
  248. result = xmlCheckedTag(e, "h3", commonAttr)
  249. macro h4*(e: varargs[untyped]): untyped =
  250. ## Generates the HTML `h4` element.
  251. result = xmlCheckedTag(e, "h4", commonAttr)
  252. macro h5*(e: varargs[untyped]): untyped =
  253. ## Generates the HTML `h5` element.
  254. result = xmlCheckedTag(e, "h5", commonAttr)
  255. macro h6*(e: varargs[untyped]): untyped =
  256. ## Generates the HTML `h6` element.
  257. result = xmlCheckedTag(e, "h6", commonAttr)
  258. macro head*(e: varargs[untyped]): untyped =
  259. ## Generates the HTML `head` element.
  260. result = xmlCheckedTag(e, "head", commonAttr)
  261. macro header*(e: varargs[untyped]): untyped =
  262. ## Generates the HTML `header` element.
  263. result = xmlCheckedTag(e, "header", commonAttr)
  264. macro html*(e: varargs[untyped]): untyped =
  265. ## Generates the HTML `html` element.
  266. result = xmlCheckedTag(e, "html", "xmlns" & commonAttr, "")
  267. macro hr*(): untyped =
  268. ## Generates the HTML `hr` element.
  269. result = xmlCheckedTag(newNimNode(nnkArgList), "hr", commonAttr, "", true)
  270. macro i*(e: varargs[untyped]): untyped =
  271. ## Generates the HTML `i` element.
  272. result = xmlCheckedTag(e, "i", commonAttr)
  273. macro iframe*(e: varargs[untyped]): untyped =
  274. ## Generates the HTML `iframe` element.
  275. result = xmlCheckedTag(e, "iframe", "src srcdoc name sandbox width height loading" &
  276. commonAttr)
  277. macro img*(e: varargs[untyped]): untyped =
  278. ## Generates the HTML `img` element.
  279. result = xmlCheckedTag(e, "img", "crossorigin usemap ismap height width loading" &
  280. commonAttr, "src alt", true)
  281. macro input*(e: varargs[untyped]): untyped =
  282. ## Generates the HTML `input` element.
  283. result = xmlCheckedTag(e, "input", "accept alt autocomplete autofocus " &
  284. "checked dirname disabled form formaction formenctype formmethod " &
  285. "formnovalidate formtarget height inputmode list max maxlength min " &
  286. "minlength multiple name pattern placeholder readonly required size " &
  287. "src step type value width" & commonAttr, "", true)
  288. macro ins*(e: varargs[untyped]): untyped =
  289. ## Generates the HTML `ins` element.
  290. result = xmlCheckedTag(e, "ins", "cite datetime" & commonAttr)
  291. macro kbd*(e: varargs[untyped]): untyped =
  292. ## Generates the HTML `kbd` element.
  293. result = xmlCheckedTag(e, "kbd", commonAttr)
  294. macro keygen*(e: varargs[untyped]): untyped =
  295. ## Generates the HTML `keygen` element.
  296. result = xmlCheckedTag(e, "keygen", "autofocus challenge disabled " &
  297. "form keytype name" & commonAttr)
  298. macro label*(e: varargs[untyped]): untyped =
  299. ## Generates the HTML `label` element.
  300. result = xmlCheckedTag(e, "label", "form for" & commonAttr)
  301. macro legend*(e: varargs[untyped]): untyped =
  302. ## Generates the HTML `legend` element.
  303. result = xmlCheckedTag(e, "legend", commonAttr)
  304. macro li*(e: varargs[untyped]): untyped =
  305. ## Generates the HTML `li` element.
  306. result = xmlCheckedTag(e, "li", "value" & commonAttr)
  307. macro link*(e: varargs[untyped]): untyped =
  308. ## Generates the HTML `link` element.
  309. result = xmlCheckedTag(e, "link", "href crossorigin rel media hreflang " &
  310. "type sizes" & commonAttr, "", true)
  311. macro main*(e: varargs[untyped]): untyped =
  312. ## Generates the HTML `main` element.
  313. result = xmlCheckedTag(e, "main", commonAttr)
  314. macro map*(e: varargs[untyped]): untyped =
  315. ## Generates the HTML `map` element.
  316. result = xmlCheckedTag(e, "map", "name" & commonAttr)
  317. macro mark*(e: varargs[untyped]): untyped =
  318. ## Generates the HTML `mark` element.
  319. result = xmlCheckedTag(e, "mark", commonAttr)
  320. macro marquee*(e: varargs[untyped]): untyped =
  321. ## Generates the HTML `marquee` element.
  322. result = xmlCheckedTag(e, "marquee", coreAttr &
  323. "behavior bgcolor direction height hspace loop scrollamount " &
  324. "scrolldelay truespeed vspace width onbounce onfinish onstart")
  325. macro meta*(e: varargs[untyped]): untyped =
  326. ## Generates the HTML `meta` element.
  327. result = xmlCheckedTag(e, "meta", "name http-equiv content charset" &
  328. commonAttr, "", true)
  329. macro meter*(e: varargs[untyped]): untyped =
  330. ## Generates the HTML `meter` element.
  331. result = xmlCheckedTag(e, "meter", "value min max low high optimum" &
  332. commonAttr)
  333. macro nav*(e: varargs[untyped]): untyped =
  334. ## Generates the HTML `nav` element.
  335. result = xmlCheckedTag(e, "nav", commonAttr)
  336. macro noscript*(e: varargs[untyped]): untyped =
  337. ## Generates the HTML `noscript` element.
  338. result = xmlCheckedTag(e, "noscript", commonAttr)
  339. macro `object`*(e: varargs[untyped]): untyped =
  340. ## Generates the HTML `object` element.
  341. result = xmlCheckedTag(e, "object", "data type typemustmatch name usemap " &
  342. "form width height" & commonAttr)
  343. macro ol*(e: varargs[untyped]): untyped =
  344. ## Generates the HTML `ol` element.
  345. result = xmlCheckedTag(e, "ol", "reversed start type" & commonAttr)
  346. macro optgroup*(e: varargs[untyped]): untyped =
  347. ## Generates the HTML `optgroup` element.
  348. result = xmlCheckedTag(e, "optgroup", "disabled" & commonAttr, "label", false)
  349. macro option*(e: varargs[untyped]): untyped =
  350. ## Generates the HTML `option` element.
  351. result = xmlCheckedTag(e, "option", "disabled label selected value" &
  352. commonAttr)
  353. macro output*(e: varargs[untyped]): untyped =
  354. ## Generates the HTML `output` element.
  355. result = xmlCheckedTag(e, "output", "for form name" & commonAttr)
  356. macro p*(e: varargs[untyped]): untyped =
  357. ## Generates the HTML `p` element.
  358. result = xmlCheckedTag(e, "p", commonAttr)
  359. macro param*(e: varargs[untyped]): untyped =
  360. ## Generates the HTML `param` element.
  361. result = xmlCheckedTag(e, "param", commonAttr, "name value", true)
  362. macro picture*(e: varargs[untyped]): untyped =
  363. ## Generates the HTML `picture` element.
  364. result = xmlCheckedTag(e, "picture", commonAttr)
  365. macro pre*(e: varargs[untyped]): untyped =
  366. ## Generates the HTML `pre` element.
  367. result = xmlCheckedTag(e, "pre", commonAttr)
  368. macro progress*(e: varargs[untyped]): untyped =
  369. ## Generates the HTML `progress` element.
  370. result = xmlCheckedTag(e, "progress", "value max" & commonAttr)
  371. macro q*(e: varargs[untyped]): untyped =
  372. ## Generates the HTML `q` element.
  373. result = xmlCheckedTag(e, "q", "cite" & commonAttr)
  374. macro rb*(e: varargs[untyped]): untyped =
  375. ## Generates the HTML `rb` element.
  376. result = xmlCheckedTag(e, "rb", commonAttr)
  377. macro rp*(e: varargs[untyped]): untyped =
  378. ## Generates the HTML `rp` element.
  379. result = xmlCheckedTag(e, "rp", commonAttr)
  380. macro rt*(e: varargs[untyped]): untyped =
  381. ## Generates the HTML `rt` element.
  382. result = xmlCheckedTag(e, "rt", commonAttr)
  383. macro rtc*(e: varargs[untyped]): untyped =
  384. ## Generates the HTML `rtc` element.
  385. result = xmlCheckedTag(e, "rtc", commonAttr)
  386. macro ruby*(e: varargs[untyped]): untyped =
  387. ## Generates the HTML `ruby` element.
  388. result = xmlCheckedTag(e, "ruby", commonAttr)
  389. macro s*(e: varargs[untyped]): untyped =
  390. ## Generates the HTML `s` element.
  391. result = xmlCheckedTag(e, "s", commonAttr)
  392. macro samp*(e: varargs[untyped]): untyped =
  393. ## Generates the HTML `samp` element.
  394. result = xmlCheckedTag(e, "samp", commonAttr)
  395. macro script*(e: varargs[untyped]): untyped =
  396. ## Generates the HTML `script` element.
  397. result = xmlCheckedTag(e, "script", "src type charset async defer " &
  398. "crossorigin" & commonAttr)
  399. macro section*(e: varargs[untyped]): untyped =
  400. ## Generates the HTML `section` element.
  401. result = xmlCheckedTag(e, "section", commonAttr)
  402. macro select*(e: varargs[untyped]): untyped =
  403. ## Generates the HTML `select` element.
  404. result = xmlCheckedTag(e, "select", "autofocus disabled form multiple " &
  405. "name required size" & commonAttr)
  406. macro slot*(e: varargs[untyped]): untyped =
  407. ## Generates the HTML `slot` element.
  408. result = xmlCheckedTag(e, "slot", commonAttr)
  409. macro small*(e: varargs[untyped]): untyped =
  410. ## Generates the HTML `small` element.
  411. result = xmlCheckedTag(e, "small", commonAttr)
  412. macro source*(e: varargs[untyped]): untyped =
  413. ## Generates the HTML `source` element.
  414. result = xmlCheckedTag(e, "source", "type" & commonAttr, "src", true)
  415. macro span*(e: varargs[untyped]): untyped =
  416. ## Generates the HTML `span` element.
  417. result = xmlCheckedTag(e, "span", commonAttr)
  418. macro strong*(e: varargs[untyped]): untyped =
  419. ## Generates the HTML `strong` element.
  420. result = xmlCheckedTag(e, "strong", commonAttr)
  421. macro style*(e: varargs[untyped]): untyped =
  422. ## Generates the HTML `style` element.
  423. result = xmlCheckedTag(e, "style", "media type" & commonAttr)
  424. macro sub*(e: varargs[untyped]): untyped =
  425. ## Generates the HTML `sub` element.
  426. result = xmlCheckedTag(e, "sub", commonAttr)
  427. macro summary*(e: varargs[untyped]): untyped =
  428. ## Generates the HTML `summary` element.
  429. result = xmlCheckedTag(e, "summary", commonAttr)
  430. macro sup*(e: varargs[untyped]): untyped =
  431. ## Generates the HTML `sup` element.
  432. result = xmlCheckedTag(e, "sup", commonAttr)
  433. macro table*(e: varargs[untyped]): untyped =
  434. ## Generates the HTML `table` element.
  435. result = xmlCheckedTag(e, "table", "border sortable" & commonAttr)
  436. macro tbody*(e: varargs[untyped]): untyped =
  437. ## Generates the HTML `tbody` element.
  438. result = xmlCheckedTag(e, "tbody", commonAttr)
  439. macro td*(e: varargs[untyped]): untyped =
  440. ## Generates the HTML `td` element.
  441. result = xmlCheckedTag(e, "td", "colspan rowspan headers" & commonAttr)
  442. macro `template`*(e: varargs[untyped]): untyped =
  443. ## Generates the HTML `template` element.
  444. result = xmlCheckedTag(e, "template", commonAttr)
  445. macro textarea*(e: varargs[untyped]): untyped =
  446. ## Generates the HTML `textarea` element.
  447. result = xmlCheckedTag(e, "textarea", "autocomplete autofocus cols " &
  448. "dirname disabled form inputmode maxlength minlength name placeholder " &
  449. "readonly required rows wrap" & commonAttr)
  450. macro tfoot*(e: varargs[untyped]): untyped =
  451. ## Generates the HTML `tfoot` element.
  452. result = xmlCheckedTag(e, "tfoot", commonAttr)
  453. macro th*(e: varargs[untyped]): untyped =
  454. ## Generates the HTML `th` element.
  455. result = xmlCheckedTag(e, "th", "colspan rowspan headers abbr scope axis" &
  456. " sorted" & commonAttr)
  457. macro thead*(e: varargs[untyped]): untyped =
  458. ## Generates the HTML `thead` element.
  459. result = xmlCheckedTag(e, "thead", commonAttr)
  460. macro time*(e: varargs[untyped]): untyped =
  461. ## Generates the HTML `time` element.
  462. result = xmlCheckedTag(e, "time", "datetime" & commonAttr)
  463. macro title*(e: varargs[untyped]): untyped =
  464. ## Generates the HTML `title` element.
  465. result = xmlCheckedTag(e, "title", commonAttr)
  466. macro tr*(e: varargs[untyped]): untyped =
  467. ## Generates the HTML `tr` element.
  468. result = xmlCheckedTag(e, "tr", commonAttr)
  469. macro track*(e: varargs[untyped]): untyped =
  470. ## Generates the HTML `track` element.
  471. result = xmlCheckedTag(e, "track", "kind srclang label default" &
  472. commonAttr, "src", true)
  473. macro tt*(e: varargs[untyped]): untyped =
  474. ## Generates the HTML `tt` element.
  475. result = xmlCheckedTag(e, "tt", commonAttr)
  476. macro u*(e: varargs[untyped]): untyped =
  477. ## Generates the HTML `u` element.
  478. result = xmlCheckedTag(e, "u", commonAttr)
  479. macro ul*(e: varargs[untyped]): untyped =
  480. ## Generates the HTML `ul` element.
  481. result = xmlCheckedTag(e, "ul", commonAttr)
  482. macro `var`*(e: varargs[untyped]): untyped =
  483. ## Generates the HTML `var` element.
  484. result = xmlCheckedTag(e, "var", commonAttr)
  485. macro video*(e: varargs[untyped]): untyped =
  486. ## Generates the HTML `video` element.
  487. result = xmlCheckedTag(e, "video", "src crossorigin poster preload " &
  488. "autoplay mediagroup loop muted controls width height" & commonAttr)
  489. macro wbr*(e: varargs[untyped]): untyped =
  490. ## Generates the HTML `wbr` element.
  491. result = xmlCheckedTag(e, "wbr", commonAttr, "", true)
  492. macro portal*(e: varargs[untyped]): untyped =
  493. ## Generates the HTML `portal` element.
  494. result = xmlCheckedTag(e, "portal", "width height type src disabled" & commonAttr, "", false)
  495. macro math*(e: varargs[untyped]): untyped =
  496. ## Generates the HTML `math` element. MathML https://wikipedia.org/wiki/MathML
  497. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/math#Examples
  498. result = xmlCheckedTag(e, "math", "mathbackground mathcolor href overflow" & commonAttr)
  499. macro maction*(e: varargs[untyped]): untyped =
  500. ## Generates the HTML `maction` element. MathML https://wikipedia.org/wiki/MathML
  501. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/maction
  502. result = xmlCheckedTag(e, "maction", "mathbackground mathcolor href" & commonAttr)
  503. macro menclose*(e: varargs[untyped]): untyped =
  504. ## Generates the HTML `menclose` element. MathML https://wikipedia.org/wiki/MathML
  505. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/menclose
  506. result = xmlCheckedTag(e, "menclose", "mathbackground mathcolor href notation" & commonAttr)
  507. macro merror*(e: varargs[untyped]): untyped =
  508. ## Generates the HTML `merror` element. MathML https://wikipedia.org/wiki/MathML
  509. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/merror
  510. result = xmlCheckedTag(e, "merror", "mathbackground mathcolor href" & commonAttr)
  511. macro mfenced*(e: varargs[untyped]): untyped =
  512. ## Generates the HTML `mfenced` element. MathML https://wikipedia.org/wiki/MathML
  513. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mfenced
  514. result = xmlCheckedTag(e, "mfenced", "mathbackground mathcolor href open separators" & commonAttr)
  515. macro mfrac*(e: varargs[untyped]): untyped =
  516. ## Generates the HTML `mfrac` element. MathML https://wikipedia.org/wiki/MathML
  517. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mfrac
  518. result = xmlCheckedTag(e, "mfrac", "mathbackground mathcolor href linethickness numalign" & commonAttr)
  519. macro mglyph*(e: varargs[untyped]): untyped =
  520. ## Generates the HTML `mglyph` element. MathML https://wikipedia.org/wiki/MathML
  521. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mglyph
  522. result = xmlCheckedTag(e, "mglyph", "mathbackground mathcolor href src valign" & commonAttr)
  523. macro mi*(e: varargs[untyped]): untyped =
  524. ## Generates the HTML `mi` element. MathML https://wikipedia.org/wiki/MathML
  525. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mi
  526. result = xmlCheckedTag(e, "mi", "mathbackground mathcolor href mathsize mathvariant" & commonAttr)
  527. macro mlabeledtr*(e: varargs[untyped]): untyped =
  528. ## Generates the HTML `mlabeledtr` element. MathML https://wikipedia.org/wiki/MathML
  529. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mlabeledtr
  530. result = xmlCheckedTag(e, "mlabeledtr", "mathbackground mathcolor href columnalign groupalign rowalign" & commonAttr)
  531. macro mmultiscripts*(e: varargs[untyped]): untyped =
  532. ## Generates the HTML `mmultiscripts` element. MathML https://wikipedia.org/wiki/MathML
  533. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mmultiscripts
  534. result = xmlCheckedTag(e, "mmultiscripts", "mathbackground mathcolor href subscriptshift superscriptshift" & commonAttr)
  535. macro mn*(e: varargs[untyped]): untyped =
  536. ## Generates the HTML `mn` element. MathML https://wikipedia.org/wiki/MathML
  537. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mn
  538. result = xmlCheckedTag(e, "mn", "mathbackground mathcolor href mathsize mathvariant" & commonAttr)
  539. macro mo*(e: varargs[untyped]): untyped =
  540. ## Generates the HTML `mo` element. MathML https://wikipedia.org/wiki/MathML
  541. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo
  542. result = xmlCheckedTag(e, "mo",
  543. "mathbackground mathcolor fence form largeop lspace mathsize mathvariant movablelimits rspace separator stretchy symmetric" & commonAttr)
  544. macro mover*(e: varargs[untyped]): untyped =
  545. ## Generates the HTML `mover` element. MathML https://wikipedia.org/wiki/MathML
  546. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mover
  547. result = xmlCheckedTag(e, "mover", "mathbackground mathcolor accent href" & commonAttr)
  548. macro mpadded*(e: varargs[untyped]): untyped =
  549. ## Generates the HTML `mpadded` element. MathML https://wikipedia.org/wiki/MathML
  550. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mpadded
  551. result = xmlCheckedTag(e, "mpadded", "mathbackground mathcolor depth href lspace voffset" & commonAttr)
  552. macro mphantom*(e: varargs[untyped]): untyped =
  553. ## Generates the HTML `mphantom` element. MathML https://wikipedia.org/wiki/MathML
  554. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mphantom
  555. result = xmlCheckedTag(e, "mphantom", "mathbackground" & commonAttr)
  556. macro mroot*(e: varargs[untyped]): untyped =
  557. ## Generates the HTML `mroot` element. MathML https://wikipedia.org/wiki/MathML
  558. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mroot
  559. result = xmlCheckedTag(e, "mroot", "mathbackground mathcolor href" & commonAttr)
  560. macro mrow*(e: varargs[untyped]): untyped =
  561. ## Generates the HTML `mrow` element. MathML https://wikipedia.org/wiki/MathML
  562. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mrow
  563. result = xmlCheckedTag(e, "mrow", "mathbackground mathcolor href" & commonAttr)
  564. macro ms*(e: varargs[untyped]): untyped =
  565. ## Generates the HTML `ms` element. MathML https://wikipedia.org/wiki/MathML
  566. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/ms
  567. result = xmlCheckedTag(e, "ms", "mathbackground mathcolor href lquote mathsize mathvariant rquote" & commonAttr)
  568. macro mspace*(e: varargs[untyped]): untyped =
  569. ## Generates the HTML `mspace` element. MathML https://wikipedia.org/wiki/MathML
  570. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mspace
  571. result = xmlCheckedTag(e, "mspace", "mathbackground mathcolor href linebreak" & commonAttr)
  572. macro msqrt*(e: varargs[untyped]): untyped =
  573. ## Generates the HTML `msqrt` element. MathML https://wikipedia.org/wiki/MathML
  574. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msqrt
  575. result = xmlCheckedTag(e, "msqrt", "mathbackground mathcolor href" & commonAttr)
  576. macro mstyle*(e: varargs[untyped]): untyped =
  577. ## Generates the HTML `mstyle` element. MathML https://wikipedia.org/wiki/MathML
  578. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mstyle
  579. result = xmlCheckedTag(e, "mstyle", ("mathbackground mathcolor href decimalpoint displaystyle " &
  580. "infixlinebreakstyle scriptlevel scriptminsize scriptsizemultiplier" & commonAttr))
  581. macro msub*(e: varargs[untyped]): untyped =
  582. ## Generates the HTML `msub` element. MathML https://wikipedia.org/wiki/MathML
  583. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msub
  584. result = xmlCheckedTag(e, "msub", "mathbackground mathcolor href subscriptshift" & commonAttr)
  585. macro msubsup*(e: varargs[untyped]): untyped =
  586. ## Generates the HTML `msubsup` element. MathML https://wikipedia.org/wiki/MathML
  587. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msubsup
  588. result = xmlCheckedTag(e, "msubsup", "mathbackground mathcolor href subscriptshift superscriptshift" & commonAttr)
  589. macro msup*(e: varargs[untyped]): untyped =
  590. ## Generates the HTML `msup` element. MathML https://wikipedia.org/wiki/MathML
  591. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/msup
  592. result = xmlCheckedTag(e, "msup", "mathbackground mathcolor href superscriptshift" & commonAttr)
  593. macro mtable*(e: varargs[untyped]): untyped =
  594. ## Generates the HTML `mtable` element. MathML https://wikipedia.org/wiki/MathML
  595. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtable
  596. result = xmlCheckedTag(e, "mtable", ("mathbackground mathcolor href align " &
  597. "alignmentscope columnalign columnlines columnspacing columnwidth " &
  598. "displaystyle equalcolumns equalrows frame framespacing groupalign " &
  599. "rowalign rowlines rowspacing side width" & commonAttr))
  600. macro mtd*(e: varargs[untyped]): untyped =
  601. ## Generates the HTML `mtd` element. MathML https://wikipedia.org/wiki/MathML
  602. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtd
  603. result = xmlCheckedTag(e, "mtd",
  604. "mathbackground mathcolor href columnalign columnspan groupalign rowalign rowspan" & commonAttr)
  605. macro mtext*(e: varargs[untyped]): untyped =
  606. ## Generates the HTML `mtext` element. MathML https://wikipedia.org/wiki/MathML
  607. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mtext
  608. result = xmlCheckedTag(e, "mtext", "mathbackground mathcolor href mathsize mathvariant" & commonAttr)
  609. macro munder*(e: varargs[untyped]): untyped =
  610. ## Generates the HTML `munder` element. MathML https://wikipedia.org/wiki/MathML
  611. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/munder
  612. result = xmlCheckedTag(e, "munder", "mathbackground mathcolor href accentunder align" & commonAttr)
  613. macro munderover*(e: varargs[untyped]): untyped =
  614. ## Generates the HTML `munderover` element. MathML https://wikipedia.org/wiki/MathML
  615. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/munderover
  616. result = xmlCheckedTag(e, "munderover", "mathbackground mathcolor href accentunder accent align" & commonAttr)
  617. macro semantics*(e: varargs[untyped]): untyped =
  618. ## Generates the HTML `semantics` element. MathML https://wikipedia.org/wiki/MathML
  619. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics
  620. result = xmlCheckedTag(e, "semantics", "mathbackground mathcolor href definitionURL encoding cd src" & commonAttr)
  621. macro annotation*(e: varargs[untyped]): untyped =
  622. ## Generates the HTML `annotation` element. MathML https://wikipedia.org/wiki/MathML
  623. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics
  624. result = xmlCheckedTag(e, "annotation", "mathbackground mathcolor href definitionURL encoding cd src" & commonAttr)
  625. macro `annotation-xml`*(e: varargs[untyped]): untyped =
  626. ## Generates the HTML `annotation-xml` element. MathML https://wikipedia.org/wiki/MathML
  627. ## https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics
  628. result = xmlCheckedTag(e, "annotation", "mathbackground mathcolor href definitionURL encoding cd src" & commonAttr)
  629. runnableExamples:
  630. let nim = "Nim"
  631. assert h1(a(href = "https://nim-lang.org", nim)) ==
  632. """<h1><a href="https://nim-lang.org">Nim</a></h1>"""
  633. assert form(action = "test", `accept-charset` = "Content-Type") ==
  634. """<form action="test" accept-charset="Content-Type"></form>"""
  635. assert math(
  636. semantics(
  637. mrow(
  638. msup(
  639. mi("x"),
  640. mn("42")
  641. )
  642. )
  643. )
  644. ) == "<math><semantics><mrow><msup><mi>x</mi><mn>42</mn></msup></mrow></semantics></math>"
  645. assert math(
  646. semantics(
  647. annotation(encoding = "application/x-tex", title = "Latex on Web", r"x^{2} + y")
  648. )
  649. ) == """<math><semantics><annotation encoding="application/x-tex" title="Latex on Web">x^{2} + y</annotation></semantics></math>"""