diff --git a/NEWS.md b/NEWS.md index baef3d1..221078b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,11 +8,15 @@ - Support `show(::IO, ::MIME"application/pdf", ::TypstString)` - Patch incorrect output from an assumption in `repr(::MIME, ::TypstString)` - Formatting options in `TypstString` are now passed as keyword parameters instead of `Pair{Symbol}`s - -#### `show_typst` - -- The `inline` setting has been renamed to `block` to be consistent with Typst's `equation` function - - This toggles the default behavior, which is now inline. +- `show_typst` + - Implemented for `Tuple`, `Typst`, and `Unsigned` + - `nothing` now corresponds to Typst's `none` + - `AbtractMatrix` and `AbstractVector` in `code` mode now correspond to a Typst array + - `OrdinalRange{<:Integer, <:Integer}` and `StepRangeLen{<:Integer, <:Integer, <:Integer}` in `markup` and `math` mode now correspond to a Typst vector + - New default setting `parenthesize = true` + - Used for `Complex` and `Rational` + - The `inline` setting has been renamed to `block` to be consistent with Typst's `equation` function + - This toggles the default behavior, which is now inline ### Commands diff --git a/docs/make.jl b/docs/make.jl index 312b5a6..d86211a 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -53,7 +53,6 @@ open(strings * ".typ"; truncate = true) do file print(file, " ") if is_vector print(file, "\"[true [1]]\"") - elseif is_matrix print(file, "\"[true 1; 1.0 [Any[\\n true 1; 1.0 nothing\\n]]]\"") elseif t <: Text print(file, "\"text\\\"[\\\\\\\"a\\\\\\\"]\\\"\"") elseif t <: StepRangeLen print(file, "\"StepRangeLen(0, 2, 4)\"") else show(file, repr(v)) diff --git a/docs/src/assets/strings.svg b/docs/src/assets/strings.svg index e6f2f61..50a4043 100644 --- a/docs/src/assets/strings.svg +++ b/docs/src/assets/strings.svg @@ -1,84 +1,90 @@ - + - + - + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + + + + + + + @@ -107,7 +113,7 @@ - + @@ -121,7 +127,7 @@ - + @@ -135,7 +141,7 @@ - + @@ -151,7 +157,7 @@ - + @@ -186,7 +192,7 @@ - + @@ -208,7 +214,7 @@ - + @@ -221,7 +227,7 @@ - + @@ -234,7 +240,7 @@ - + @@ -268,7 +274,7 @@ - + @@ -291,7 +297,7 @@ - + @@ -304,7 +310,7 @@ - + @@ -317,7 +323,7 @@ - + @@ -338,15 +344,22 @@ - + + + + + + + + - + @@ -354,108 +367,46 @@ - + - + - + - + - + - + - - - - - - + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + @@ -463,7 +414,7 @@ - + @@ -487,121 +438,73 @@ - + - + + + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + @@ -612,7 +515,7 @@ - + @@ -627,87 +530,56 @@ - + - + - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - - - - - - + - + - + - + - + - + @@ -718,7 +590,7 @@ - + @@ -733,79 +605,48 @@ - + - + - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - - - - - - + - + - + @@ -826,7 +667,7 @@ - + @@ -850,7 +691,7 @@ - + @@ -863,7 +704,7 @@ - + @@ -876,7 +717,7 @@ - + @@ -889,7 +730,7 @@ - + @@ -931,7 +772,7 @@ - + @@ -955,52 +796,44 @@ - + - + - + - + - - - - + + + + - - - - - - - - - - - - - - - - - - - + + + + - + - + + + + + + + + - + @@ -1045,7 +878,7 @@ - + @@ -1090,7 +923,7 @@ - + @@ -1104,7 +937,7 @@ - + @@ -1118,7 +951,7 @@ - + @@ -1132,7 +965,7 @@ - + @@ -1146,7 +979,7 @@ - + @@ -1160,7 +993,7 @@ - + @@ -1193,7 +1026,7 @@ - + @@ -1210,7 +1043,7 @@ - + @@ -1236,7 +1069,7 @@ - + @@ -1262,33 +1095,49 @@ - + - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + - + @@ -1299,7 +1148,7 @@ - + @@ -1319,7 +1168,7 @@ - + @@ -1346,7 +1195,7 @@ - + @@ -1357,7 +1206,7 @@ - + @@ -1368,7 +1217,7 @@ - + @@ -1385,7 +1234,7 @@ - + @@ -1402,22 +1251,22 @@ - + - + - + - + @@ -1448,7 +1297,7 @@ - + @@ -1491,7 +1340,7 @@ - + @@ -1542,109 +1391,163 @@ - + - - - - - - + - + - + - + - + - + - + - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1666,7 +1569,7 @@ - + @@ -1684,7 +1587,7 @@ - + @@ -1697,7 +1600,7 @@ - + @@ -1716,26 +1619,42 @@ - + - + - + - - - + + + + + + + + + + + + + + + + + - - + + + + - + @@ -1773,7 +1692,7 @@ - + @@ -1788,7 +1707,7 @@ - + @@ -1824,7 +1743,7 @@ - + @@ -1860,7 +1779,7 @@ - + @@ -1896,7 +1815,7 @@ - + @@ -1907,7 +1826,7 @@ - + @@ -1923,7 +1842,7 @@ - + @@ -1934,7 +1853,7 @@ - + @@ -1945,7 +1864,7 @@ - + @@ -1956,7 +1875,7 @@ - + @@ -2013,7 +1932,7 @@ - + @@ -2066,7 +1985,7 @@ - + @@ -2117,109 +2036,163 @@ - + - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -2270,7 +2243,7 @@ - + @@ -2284,7 +2257,7 @@ - + @@ -2299,7 +2272,7 @@ - + @@ -2314,7 +2287,7 @@ - + @@ -2329,32 +2302,414 @@ - + + + + + + - - - - + + + - + - + - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2381,7 +2736,7 @@ - + @@ -2402,7 +2757,7 @@ - + @@ -2415,7 +2770,7 @@ - + @@ -2430,7 +2785,7 @@ - + @@ -2451,6 +2806,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2603,6 +3037,12 @@ + + + + + + @@ -2615,20 +3055,8 @@ - - - - - - - - - - - - - - + + @@ -2636,11 +3064,29 @@ + + + - - + + + + + + + + + + + + + + + + + @@ -2660,44 +3106,20 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + @@ -2705,6 +3127,9 @@ + + + @@ -2765,6 +3190,12 @@ + + + + + + @@ -2822,30 +3253,51 @@ - - - - - - - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2873,5 +3325,14 @@ + + + + + + + + + diff --git a/docs/src/getting_started.md b/docs/src/getting_started.md index ad57eaa..85cddb6 100644 --- a/docs/src/getting_started.md +++ b/docs/src/getting_started.md @@ -13,7 +13,7 @@ If no such value exists, it is formatted to render in a canonical representation !!! note Although many of the values are rendered similarly across modes, - the underlying Typst source code differs between them. + the generated Typst source code differs between them. ```@eval using Markdown: parse diff --git a/docs/src/index.md b/docs/src/index.md index baa4198..190beed 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -31,7 +31,7 @@ $mat( "true", 1; 1.0, mat( "true", 1; - 1.0, "" + 1.0, #none ) )$ @@ -39,7 +39,7 @@ julia> TypstString(1 // 2; block = true) typst"$ 1 / 2 $" julia> typst"$ \(1 + 2im; mode = math) $" -typst"$ 1 + 2i $" +typst"$ (1 + 2i) $" julia> TypstCommand(["help"]) typst`help` diff --git a/docs/src/manual/internals.md b/docs/src/manual/internals.md index 0ea7d8a..adf2d2e 100644 --- a/docs/src/manual/internals.md +++ b/docs/src/manual/internals.md @@ -18,8 +18,11 @@ Typstry.indent Typstry.join_with Typstry.math_pad Typstry.mode +Typstry.parenthesize Typstry.print_parameters Typstry.print_quoted +Typstry.show_array +Typstry.show_vector Typstry.static_parse ``` diff --git a/src/strings.jl b/src/strings.jl index 31d28f5..d78ae22 100644 --- a/src/strings.jl +++ b/src/strings.jl @@ -96,7 +96,7 @@ julia> typst"\\(x // 2)" typst"\$1 / 2\$" julia> typst"\\(x // 2; mode = math)" -typst"1 / 2" +typst"(1 / 2)" julia> typst"\\\\(x)" typst"\\\\(x)" @@ -154,7 +154,7 @@ A constant `Vector` of Julia values and their corresponding `Type`s implemented const examples = [ 'a' => AbstractChar, 1.2 => AbstractFloat, - [true 1; 1.0 [Any[true 1; 1.0 nothing]]] => AbstractMatrix, + Any[true 1; 1.2 1 // 2] => AbstractMatrix, "a" => AbstractString, [true, [1]] => AbstractVector, true => Bool, @@ -167,7 +167,9 @@ const examples = [ 1 => Signed, StepRangeLen(0, 2, 4) => StepRangeLen{<:Integer, <:Integer, <:Integer}, text"[\"a\"]" => Text, - @typst_str("[\"a\"]") => TypstString + (true, 1, 1.2, 1 // 2) => Tuple, + @typst_str("[\"a\"]") => TypstString, + 0xff => Unsigned ] """ @@ -197,14 +199,15 @@ A constant `NamedTuple` containing the default `IOContext` settings used in # Examples ```jldoctest julia> Typstry.settings -(block = false, depth = 0, indent = " ", mode = markup) +(block = false, depth = 0, indent = " ", mode = markup, parenthesize = true) ``` """ const settings = ( block = false, depth = 0, indent = " ", - mode = markup + mode = markup, + parenthesize = true ) """ @@ -371,6 +374,19 @@ code::Mode = 0 """ mode(io) = io[:mode]::Mode +""" + parenthesize(io) + +Return `io[:parenthesize]::Bool`. + +# Examples +```jldoctest +julia> Typstry.parenthesize(IOContext(stdout, :parenthesize => true)) +true +``` +""" +parenthesize(io) = io[:parenthesize]::Bool + """ print_parameters(io, f, keys) @@ -412,6 +428,27 @@ julia> Typstry.print_quoted(stdout, TypstString("a")) """ print_quoted(io, s) = enclose(escape_raw_string, io, s, "\"") +""" + show_array(io, x) +""" +show_array(io, x) = enclose(io, x, "(", ")") do io, x + join_with(show_typst, io, x, ", ") + length(x) == 1 && print(io, ",") +end + +""" + show_vector(io, x) +""" +show_vector(io, x) = enclose(io, x, math_pad(io)) do io, x + _depth, _indent = depth(io), indent(io) + __depth = _depth + 1 + + print_parameters(io, "vec", [:delim, :gap]) + print(io, _indent ^ __depth) + join_with(show_typst, IOContext(io, :depth => __depth, :mode => math), x, ", "), + print(io, "\n", _indent ^ _depth, ")") +end + """ static_parse(args...; filename, kwargs...) @@ -426,8 +463,7 @@ static_parse(args...; filename, kwargs...) = """ show_typst(io, x) -Print to Typst format using required Julia settings -and optional Typst parameters in the `IOContext`. +Print to Typst format using Julia settings and Typst parameters in the `IOContext`. Settings are used in Julia to format the [`TypstString`](@ref) and can be any type. Parameters are passed to a function in the Typst source file and must be a `String` @@ -454,11 +490,11 @@ For additional information on printing and rendering, see also [Examples](@ref). | `AbstractString` | `:mode` | | | `AbstractVector` | `:block`, `:depth`, `:indent`, `:mode` | `:delim`, `:gap` | | `Bool` | `:mode` | | -| `Complex` | `:block`, `:mode` | | +| `Complex` | `:block`, `:mode`, `:parenthesize` | | | `Irrational` | `:mode` | | | `Nothing` | `:mode` | | | `OrdinalRange{<:Integer,\u00A0<:Integer}` | `:mode` | | -| `Rational` | `:block`, `:mode` | | +| `Rational` | `:block`, `:mode`, `:parenthesize` | | | `Regex` | `:mode` | | | `Signed` | | | | `StepRangeLen{<:Integer,\u00A0<:Integer,\u00A0<:Integer}` | `:mode` | | @@ -478,29 +514,21 @@ julia> show_typst(IOContext(stdout, :mode => code), "a") show_typst(io, x::AbstractChar) = mode(io) == code ? enclose(show, io, x, "\"") : show(io, x) -show_typst(io, x::AbstractMatrix) = +show_typst(io, x::AbstractMatrix) = mode(io) == code ? + show_array(io, x) : enclose((io, x; indent, depth) -> begin _depth = depth + 1 - print_parameters(io, "mat", [:delim, :augment, :gap, :row_gap, :column_gap]) + print_parameters(io, "mat", [:augment, :column_gap, :delim, :gap, :row_gap]) join_with((io, x; indent) -> begin print(io, indent ^ _depth) - join_with((io, x) -> show_typst(io, x), io, x, ", ") - end, IOContext(io, :mode => math, :depth => _depth), eachrow(x), ";\n"; indent) + join_with(show_typst, io, x, ", ") + end, IOContext(io, :depth => _depth, :mode => math), eachrow(x), ";\n"; indent) print(io, "\n", indent ^ depth, ")") - end, io, x, math_pad(io); indent = indent(io), depth = depth(io)) + end, IOContext(io, :parenthesize => false), x, math_pad(io); indent = indent(io), depth = depth(io)) show_typst(io, x::AbstractString) = mode(io) == markup ? enclose(escape_string, io, x, "\"") : enclose(escape_string, io, escape_string(x), "\"\\\"", "\\\"\"") # TODO: remove string allocation -show_typst(io, x::AbstractVector) = enclose(IOContext(io, :mode => math), x, math_pad(io)) do io, x - _depth, _indent = depth(io), indent(io) - __depth = _depth + 1 - - print_parameters(io, "vec", [:delim, :gap]) - print(io, _indent ^ __depth) - join_with(show_typst, IOContext(io, :depth => __depth), x, ", "), - print(io, "\n", _indent ^ _depth, ")") -end function show_typst(io, x::Bool) _mode = mode(io) @@ -509,23 +537,27 @@ function show_typst(io, x::Bool) else enclose(print, io, x, "\"") end end -show_typst(io, x::Complex) = - enclose((io, x) -> print(io, real(x), " + ", imag(x), "i"), io, x, math_pad(io)) +show_typst(io, x::Complex) = enclose( + (io, x) -> enclose((io, x) -> print(IOContext(io, :mode => math), real(x), " + ", imag(x), "i"), + io, x, (mode(io) == math && parenthesize(io) ? ("(", ")") : ("", ""))...), +io, x, math_pad(io)) show_typst(io, x::Irrational) = mode(io) == code ? show_typst(io, Float64(x)) : print(io, x) -show_typst(io, ::Nothing) = if mode(io) != markup print(io, "\"\"") end +function show_typst(io, ::Nothing) + code_mode(io) + print(io, "none") +end function show_typst(io, x::Rational) _mode = mode(io) - f = (io, x) -> begin + f = (io, x) -> enclose(io, x, (parenthesize(io) ? ("(", ")") : ("", ""))...) do io, x show_typst(io, numerator(x)) print(io, " / ") show_typst(io, denominator(x)) end - if _mode == code enclose(f, IOContext(io, :mode => code), x, "(", ")") - elseif _mode == markup enclose(f, IOContext(io, :mode => math), x, block(io) ? "\$ " : "\$") - else f(io, x) - end + _mode == markup ? + enclose(f, IOContext(io, :mode => math, :parenthesize => false), x, block(io) ? "\$ " : "\$") : + f(io, x) end function show_typst(io, x::Regex) code_mode(io) @@ -545,26 +577,31 @@ function show_typst(io, x::Text) print_quoted(io, repr(x)) # TODO: remove string allocation end show_typst(io, x::Typst) = show_typst(io, x.value) +function show_typst(io, x::Unsigned) + code_mode(io) + show(io, x) +end show_typst(io, x::Union{AbstractFloat, Signed, TypstString}) = print(io, x) -function show_typst(io, x::Union{ +function show_typst(io, x::Union{AbstractVector, Tuple}) + io = IOContext(io, :parenthesize => false) + mode(io) == code ? show_array(io, x) : show_vector(io, x) +end +show_typst(io, x::Union{ OrdinalRange{<:Integer, <:Integer}, StepRangeLen{<:Integer, <:Integer, <:Integer} -}) - code_mode(io) - - enclose((io, x) -> begin +}) = mode(io) == code ? + enclose(io, x, "range(", ")") do io, x show_typst(io, first(x)) enclose(show_typst, io, last(x) + 1, ", ", ", step: ") show_typst(io, step(x)) - end, IOContext(io, :mode => code), x, "range(", ")") -end + end : + show_vector(io, x) #= AbstractDict AbstractIrrational Enum Expr Symbol -Unsigned =# """ @@ -681,6 +718,15 @@ See also [`TypstString`](@ref). This method patches incorrect output from the assumption in `repr` that the parameter is already in the requested `MIME` type when the `MIME` type `istextmime` and the parameter is an `AbstractString`. + +# Examples +```jldoctest +julia> repr(MIME"text/plain"(), typst"a") +"typst\\\"a\\\"" + +julia> repr(MIME"text/typst"(), typst"a") +typst"a" +``` """ repr(::MIME"text/typst", ts::TypstString; kwargs...) = ts repr(m::MIME, ts::TypstString; kwargs...) = sprint(show, m, ts; kwargs...) @@ -714,12 +760,13 @@ See also [`Typst`](@ref) and [`TypstString`](@ref). !!! tip Implement this function for custom types to specify their default settings and parameters. -| Setting | Default | Type | Description | -|:----------|:-------------------------|:---------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `:block` | `false` | `Bool` | When `:mode => math`, specifies whether the enclosing dollar signs are padded with a space to render the element inline or its own block. | -| `:depth` | `0` | `Int` | The current level of nesting within container types to specify the degree of indentation. | -| `:indent` | `'\u00A0'\u00A0^\u00A04` | `String` | The string used for horizontal spacing by some elements with multi-line Typst formatting. | -| `:mode` | `markup` | [`Mode`](@ref) | The current Typst context where `code` follows the number sign, `markup` is at the top-level and enclosed in square brackets, and `math` is enclosed in dollar signs. | +| Setting | Default | Type | Description | +|:----------------|:-------------------------|:---------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `:block` | `false` | `Bool` | When `:mode => math`, specifies whether the enclosing dollar signs are padded with a space to render the element inline or its own block. | +| `:depth` | `0` | `Int` | The current level of nesting within container types to specify the degree of indentation. | +| `:indent` | `'\u00A0'\u00A0^\u00A04` | `String` | The string used for horizontal spacing by some elements with multi-line Typst formatting. | +| `:mode` | `markup` | [`Mode`](@ref) | The current Typst context where `code` follows the number sign, `markup` is at the top-level and enclosed in square brackets, and `math` is enclosed in dollar signs. | +| `:parenthesize` | `true` | `Bool` | Whether to enclose some mathematical elements in parentheses. | # Examples ```jldoctest