# Design Rationale
This package is implemented according to several design criteria.
- Operation of interpolated expressions (`$`) should (mostly) mirror
what they would do with regular Julia strings, updated with hypertext
escaping sensibilities including proper escaping.
- Speed of construction is critically important. This library is
intended to be used deep within systems that generate extensive
number of very large reports, interactively or in batch.
- With exception of boolean attributes (which must be removed to be
false), templates are treated as-is and not otherwise modified.
- Within `"
#->
JavaScript translation can be accessed via the `js` function.
using HypertextLiteral: js
@htl ""
#->
The `@htl_str` form is useful for dynamically constructed templates.
templ = join("\$$x " for x in [:a,:b])
#-> "\$a \$b "
(a, b) = (:A, :B);
eval(:(@htl_str($templ)))
#-> A B
Within element content, most datatypes are serialized within a `` tag.
using Dates
@htl("$(Date("2021-07-28"))
")
#-> 2021-07-28
This automatic wrapping permits CSS to be used to style output.
For example, the following style will display `missing` as `"N/A"`.
```HTML
```
## Lexer Tests
There are several HTML syntax errors that we can detect as part of our
parser. For example, you shouldn't put comments within a script tag.
@htl("")
#-> ERROR: LoadError: "script escape or comment is not implemented"⋮
Our lexer currently doesn't bother with processor instructions or
doctype declarations. You could prepend these before your content.
@htl("")
#=>
ERROR: LoadError: DomainError with ")
#-> ERROR: LoadError: "DOCTYPE not supported"⋮
@htl("CDATA either.]]>")
#-> ERROR: LoadError: "CDATA not supported"⋮
It's a lexing error to have an attribute lacking a name.
@htl " "
#=>
ERROR: LoadError: DomainError with =value/>:
unexpected equals sign before attribute name⋮
=#
It's a lexing error to have an attribute lacking a value.
@htl ""
#=>
ERROR: LoadError: DomainError with =>:
missing attribute value⋮
=#
Tags can be ended using SGML ending.
@htl ">"
#-> >
We add an extra space to ensure adjacent values parse properly.
@htl " "
#->
@htl " "
#->
Attribute names and values can be spaced out.
@htl " "
#->
Invalid attribute names are reported.
@htl " "
#=>
ERROR: LoadError: DomainError with t """
#->
@htl "
ERROR: LoadError: DomainError with e/:
unexpected solidus in tag⋮
=#
@htl "
ERROR: LoadError: DomainError with <:
unexpected character in attribute name⋮
=#
Comments can contain interpolated values.
content = ""
@htl ""
#-> -->
Empty comments are permitted.
@htl ""
#->
Comments should not exist within a script tag.
@htl("")
#-> ERROR: LoadError: "script escape or comment is not implemented"⋮
Comments need to be well formed.
@htl " "
#=>
ERROR: LoadError: DomainError with !-> :
incorrectly opened comment⋮
=#
@htl " "
#=>
ERROR: LoadError: DomainError with -> :
abrupt closing of empty comment⋮
=#
@htl " "
#=>
ERROR: LoadError: DomainError with -> :
abrupt closing of empty comment⋮
=#
Comments cannot contain a nested comment.
@htl " -->"
#=>
ERROR: LoadError: DomainError with - nested …:
nested comment⋮
=#
Comments can contain content that is similar to a comment block, but
the recognition of these valid states is rather involved.
@htl ""
#->
@htl ""
#->
@htl ""
#->
@htl ""
#->
@htl ""
#->
@htl ""
#->
@htl ""
#->
Not so sure about this lexical production... perhaps it's a
transcription error from the specification?
@htl ""
#=>
ERROR: LoadError: DomainError with !>:
nested comment⋮
=#
Even though actual content may be permitted in these odd spots, we don't
generally permit interpolation.
@htl "