#!/usr/bin/env julia using Faker, HypertextLiteral, Hyperscript, BenchmarkTools using HypertextLiteral: @htl_str # This is going to simulate a hierarchical report that lists a set of # companies, and for each company, a list of employees. Faker.seed(4321) make_employee() = ( first_name=Faker.first_name(), last_name=Faker.last_name(), title=Faker.job(), main_number=Faker.phone_number(), email=Faker.email(), cell_phone=Faker.cell_phone(), color= Faker.hex_color(), comments= Faker.paragraphs() ) make_customer() = ( company=Faker.company(), url=Faker.url(), phrase=Faker.catch_phrase(), active=Faker.date_time_this_decade(before_now=true, after_now=false), notes= Faker.sentence(number_words=rand(2:9), variable_nb_words=true), employees=[make_employee() for x in 1:rand(3:18)]) database = [make_customer() for x in 1:13] htl_database(d) = @htl(" <html> <head><title>Customers & Employees)</title></head> <body> $((map(d) do c; htl_customer(c); end))</body> </html> ") htl_customer(c) = @htl(" <dl> <dt>Company<dd>$(c.company) <dt>Phrase<dd>$(c.phrase) <dt>Active Since<dd>$(c.active) <dt>Employees<dd> <table> <tr><th>Last Name<th>First Name<th>Title <th>E-Mail<th>Office Phone<th>Cell Phone <th>Comments</tr> $((map(c.employees) do e; htl_employee(e); end))</table> </dl> ") htl_employee(e) = @htl(" <tr><td>$(e.last_name)<td>$(e.first_name)<td>$(e.title) <td><a href='mailto:$(e.email)'>$(e.email)</a> <td>$(e.main_number)<td>$(e.cell_phone) <td>$((@htl("<span>$c</span>") for c in e.comments)) ") htl_test() = begin io = IOBuffer() ob = htl_database(database) show(io, MIME("text/html"), ob) return io end # very silly test using attributes rather than elements... att_database(d) = @htl(""" <html> <head title="Customers & Employees"/> <body> $(map(d) do c; att_customer(c); end) </body> </html> """) att_customer(c) = @htl(""" <div> <form> <label>Company</label><input value=$(c.company)> <label>Phrase</label><input value='$(c.phrase)'> <label>Active Since</label><input value="$(c.active)"> <label>Employees</label> </form> $((map(c.employees) do e; att_employee(e); end)) </div> """) att_employee(e) = @htl(""" <form> <label>Last Name</label><input value=$(e.last_name)> <label>First Name</label><input value="$(e.first_name)"> <label>Title</label><input value='$(e.title)'> <label>E-Mail</label><input $(:value => e.email)> <label>Main</label><input $("value" => e.main_number))> <label>Cell</label><input $((value=e.main_number,))> $((@htl("<span $((value=x,))/>") for x in e.comments)) """) att_test() = begin io = IOBuffer() ob = att_database(database) show(io, MIME("text/html"), ob) return io end ee(x) = replace(replace(x, "&" => "&"), "<" => "<") ea(x) = replace(replace(x, "&" => "&"), "'" => "'") reg_database(d) = """ <html> <head><title>Customers & Employees</title></head> <body> $(join([reg_customer(c) for c in d])) </body> </html> """ reg_customer(c) = """ <dl> <dt>Company<dd>$(ee(c.company)) <dt>Phrase<dd>$(ee(c.phrase)) <dt>Active Since<dd>$(ee(c.active)) <dt>Employees<dd> <table> <tr><th>Last Name<th>First Name<th>Title <th>E-Mail<th>Office Phone<th>Cell Phone <th>Comments</tr> $(join([reg_employee(e) for e in c.employees])) </table> </dl> """ reg_employee(e) = """ <tr><td>$(ee(e.last_name))<td>$(ee(e.first_name))<td>$(e.title) <td><a href='mailto:$(ea(e.email))'>$(ee(e.email))</a> <td>$(ee(e.main_number))<td>$(ee(e.cell_phone)) <td>$(join(["<span>$(ee(c))</span>" for c in e.comments])) """ reg_test() = begin io = IOBuffer() ob = reg_database(database) show(io, ob) return io end @tags html head body title dl dt dd table tr th td span hs_database(d) = html(head(title("Customers & Employees")), body([hs_customer(c) for c in d]...)) hs_customer(c)= dl(dt("Company"), dd(c.company), dt("Phrase"), dd(c.phrase), dt("Active Since"), dd(c.active), dt("Employees"), dd( table(tr(th("Last Name"),th("First Name"),th("Title"), th("E-Mail"),th("Office Phone"),th("Cell Phone"), th("Comments")), [hs_employee(e) for e in c.employees]...))) hs_employee(e) = tr(td(e.last_name), td(e.first_name), td(e.title), td(href="mailto:$(e.email)", e.email), td(e.main_number), td(e.cell_phone), td([span(c) for c in e.comments]...)) hs_test() = begin io = IOBuffer() ob = hs_database(database) show(io, MIME("text/html"), ob) return io end function H(xs...) HTML() do io for x in xs show(io, MIME"text/html"(), x) end end end function entity(str::AbstractString) @assert length(str) == 1 entity(str[1]) end entity(ch::Char) = "&#$(Int(ch));" HE(x) = HTML(replace(x, r"[<&]" => entity)) HA(x) = HTML(replace(x, r"[<']" => entity)) #HE(x) = HTML(replace(replace(x, "&" => "&"), "<" => "<")) #HA(x) = HTML(replace(replace(x, "&" => "&"), "\"" => """)) cus_database(d) = H(HTML("<html><head><title>"), HE("Customers & Employees"), HTML("</title></head><body>"), [cus_customer(c) for c in d]..., HTML("</body></html>")) cus_customer(c) = H(HTML("<dl><dt>Company<dd>"), HE(c.company), HTML("<dt>Phrase<dd>"), HE(c.phrase), HTML("<dt>Active Siince<dd>"), HE(c.active), HTML(""" <dt>Employees<dd> <table> <tr><th>Last Name<th>First Name<th>Title <th>E-Mail<th>Office Phone<th>Cell Phone <th>Comments</tr>"""), [cus_employee(e) for e in c.employees]..., HTML("</table></dd></dl>")) cus_employee(e) = H(HTML("<tr><td>"), HE(e.last_name), HTML("<td>"), HE(e.first_name), HTML("<td>"), HE(e.title), HTML("<td><a href='mailto:"), HA(e.email), HTML("'>"), HE(e.email), HTML("</a>"), HTML("<td>"), HE(e.main_number), HTML("<td>"), HE(e.cell_phone), HTML("<td>"), [H(HTML("<span>"), HE(c), HTML("</span>")) for c in e.comments]...) cus_test() = begin io = IOBuffer() ob = cus_database(database) show(io, MIME("text/html"), ob) return io end nest_result(d) = @htl(" <html> <head><title>Customers & Employees)</title></head> <body> $((map(d) do c; @htl(" <dl> <dt>Company<dd>$(c.company) <dt>Phrase<dd>$(c.phrase) <dt>Active Since<dd>$(c.active) <dt>Employees<dd> <table> <tr><th>Last Name<th>First Name<th>Title <th>E-Mail<th>Office Phone<th>Cell Phone <th>Comments</tr> $((map(c.employees) do e; @htl(" <tr><td>$(e.last_name)<td>$(e.first_name)<td>$(e.title) <td><a href='mailto:$(e.email)'>$(e.email)</a> <td>$(e.main_number)<td>$(e.cell_phone) <td>$((@htl("<span>$c</span>") for c in e.comments)) "); end))</table> </dl>"); end))</body> </html> ") nest_test() = begin io = IOBuffer() ob = nest_result(database) show(io, MIME("text/html"), ob) return io end BenchmarkTools.DEFAULT_PARAMETERS.seconds = 20 @info("interpolate: ", @benchmark reg_test()) @info("Custom HTML: ", @benchmark cus_test()) @info("Hyperscript: ", @benchmark hs_test()) @info("HypertextLiteral: ", @benchmark htl_test()) @info("HTL (Attributes): ", @benchmark att_test()) @info("Nest Testing: ", @benchmark nest_test()) if false open("htl.html", "w") do f ob = htl_database(database) show(f, MIME("text/html"), ob) end open("hs.html", "w") do f ob = hs_database(database) show(f, MIME("text/html"), ob) end open("reg.html", "w") do f ob = reg_database(database) show(f, ob) end open("cus.html", "w") do f ob = cus_database(database) show(f, MIME("text/html"), ob) end end