diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index d77d3a0..9151731 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,9 +1,12 @@ name: TagBot on: - schedule: - - cron: 0 * * * * + issue_comment: # THIS BIT IS NEW + types: + - created + workflow_dispatch: jobs: TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' runs-on: ubuntu-latest steps: - uses: JuliaRegistries/TagBot@v1 diff --git a/.gitignore b/.gitignore index 1face5b..fae4405 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.jl.*.cov *.jl.mem .DS_Store +/Manifest.toml diff --git a/Project.toml b/Project.toml index 69bc634..03148ba 100644 --- a/Project.toml +++ b/Project.toml @@ -1,10 +1,10 @@ name = "Hyperscript" uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" author = ["Yuri Vishnevsky "] -version = "0.0.4" - -[compat] -julia = "1" +version = "0.0.5" [deps] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1" diff --git a/README.md b/README.md index bf6027c..ea29a29 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,31 @@ print(Pretty(node)) Note that the extra white space can affect layout, particularly in conjunction with CSS properties like [white-space](https://developer.mozilla.org/en-US/docs/Web/CSS/white-space). +Vectors of nodes can be written as an html-file using the `savehtml` function. Here's an example: + +```julia +@tags head meta body h1 h2 ul li + +doc = [ + head( + meta(charset="UTF-8"), + ), + body( + [ + h1("My title"), + "Some text", + h2("A list"), + ul(li.(["First point", "Second Point"])) + ] ) +]; + +savehtml("/tmp/hyper.html", doc); + +read("/tmp/hyper.html", String) +# +#

My title

Some text

A list

+``` + ## CSS In addition to HTML and SVG, Hyperscript also supports CSS: diff --git a/src/Hyperscript.jl b/src/Hyperscript.jl index 7e78464..0ce9d13 100644 --- a/src/Hyperscript.jl +++ b/src/Hyperscript.jl @@ -59,7 +59,7 @@ export @tags, @tags_noescape, m, css, Style, styles, render, Pretty, savehtml, s # Units include(joinpath(@__DIR__, "cssunits.jl")) -export px, pt, em, #= (this one conflicts with Base) rem, =# vh, vw, vmin, vmax, pc +export px, pt, em, #= (this one conflicts with Base) rem, =# vh, vw, vmin, vmax, pc, fr ## Basic definitions @@ -130,7 +130,7 @@ function processattrs(ctx, tag, attrs) ) end -function flat(xs::Union{Base.Generator, Tuple, Array}) +function flat(xs::Union{Base.Generator, Tuple, AbstractArray}) out = Any[] # Vector{Any} for node children and attribute values for x in xs append!(out, flat(x)) @@ -138,6 +138,7 @@ function flat(xs::Union{Base.Generator, Tuple, Array}) out end flat(x) = (x,) +flat(x::AbstractRange) = (x,) ## Rendering @@ -178,8 +179,8 @@ printescaped(io::IO, x::AbstractChar, escapes) = printescaped(io, string(x), esc # allocation via sprint. future use: sprint(printescaped, x, escapes)) printescaped(io::IO, x, escapes) = printescaped(io, sprint(print, x), escapes) -# pass numbers through untrammelled -kebab(camel::String) = join(islowercase(c) || isnumeric(c) || c == '-' ? c : '-' * lowercase(c) for c in camel) +# pass numbers (and 1-character attributes) through untrammelled +kebab(camel::String) = length(camel) > 1 ? join(islowercase(c) || isnumeric(c) || c == '-' ? c : '-' * lowercase(c) for c in camel) : camel ## HTMLSVG @@ -238,7 +239,7 @@ renderdomchild(io, rctx::RenderContext, ctx, x::Nothing) = nothing # Render and escape other HTMLSVG children, including CSS nodes, in the parent context. # If a child is `showable` with text/html, render with that using `repr`. renderdomchild(io, rctx::RenderContext, ctx, x) = - showable(MIME("text/html"), x) ? print(io, repr(MIME("text/html"), x)) : printescaped(io, x, escapechild(ctx)) + showable(MIME("text/html"), x) ? show(io, MIME("text/html"), x) : printescaped(io, x, escapechild(ctx)) # All camelCase attribute names from HTML 4, HTML 5, SVG 1.1, SVG Tiny 1.2, and SVG 2 const HTML_SVG_CAMELS = Dict(lowercase(x) => x for x in [ diff --git a/src/cssunits.jl b/src/cssunits.jl index b569995..f09add7 100644 --- a/src/cssunits.jl +++ b/src/cssunits.jl @@ -49,4 +49,5 @@ const vh = BareUnit{Unit{:vh}}() const vw = BareUnit{Unit{:vw}}() const vmin = BareUnit{Unit{:vmin}}() const vmax = BareUnit{Unit{:vmax}}() -const pc = BareUnit{Unit{Symbol("%")}}() \ No newline at end of file +const pc = BareUnit{Unit{Symbol("%")}}() +const fr = BareUnit{Unit{:fr}}() diff --git a/test/runtests.jl b/test/runtests.jl index 5342fac..6dd06f9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -90,6 +90,8 @@ end ## Generators, arrays, and tuples # Arrays are flattened @renders m("p", [1, 2, 3]) s`

123

` +# AbstractArrays are flattened +@renders m("p", BitArray([0, 1, 0])) s`

falsetruefalse

` # Generators are flattened @renders m("p", (x for x in 1:3)) s`

123

` # Tuples are flattened @@ -278,3 +280,18 @@ import Hyperscript: px, em @test string(5 * (1px + 2em)) == "calc(5 * (1px + 2em))" @test string(5 * (1px + 3px + 4.3em)) == "calc(5 * (4px + 4.3em))" @test string(3.2 * (4.3em + 1px + 3px)) == "calc(3.2 * ((4.3em + 1px) + 3px))" + +# IOContext passthrough. +struct MyType +end +Base.show(io::IO, ::MIME"text/html", ::MyType) = print(io, get(io, :key, "")) + +let + io = IOBuffer() + show(io, MIME("text/html"), m("div")(MyType())) + @test String(take!(io)) == "
" + + ctx = IOContext(io, :key => "value") + show(ctx, MIME("text/html"), m("div")(MyType())) + @test String(take!(io)) == "
value
" +end