From 2019ae0fb4ee2f7de482dd52a887ad5761024545 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Fri, 18 Oct 2024 13:40:36 +0200 Subject: [PATCH 1/4] use Runic formatting on code base --- .github/workflows/runic.yml | 22 ++++ docs/make.jl | 14 ++- ext/ColorsExt.jl | 26 ++-- ext/ContourExt.jl | 2 +- ext/MeasurementsExt.jl | 36 ++++-- ext/StatsBaseExt.jl | 34 ++++-- src/PGFPlotsX.jl | 40 ++++--- src/axiselements.jl | 233 +++++++++++++++++++++++------------- src/axislike.jl | 10 +- src/build.jl | 65 ++++++---- src/options.jl | 39 +++--- src/precompile_PGFPlotsX.jl | 22 ++-- src/tikzdocument.jl | 135 ++++++++++++--------- src/tikzpicture.jl | 4 +- src/utilities.jl | 14 +-- test/runtests.jl | 22 ++-- test/test_build.jl | 144 ++++++++++++---------- test/test_elements.jl | 114 +++++++++++------- test/test_options.jl | 60 ++++++---- test/utilities.jl | 12 +- 20 files changed, 642 insertions(+), 406 deletions(-) create mode 100644 .github/workflows/runic.yml diff --git a/.github/workflows/runic.yml b/.github/workflows/runic.yml new file mode 100644 index 00000000..fe9afc38 --- /dev/null +++ b/.github/workflows/runic.yml @@ -0,0 +1,22 @@ +name: Runic formatting +on: + push: + branches: + - 'master' + - 'release-' + tags: + - '*' + pull_request: +jobs: + runic: + name: Runic + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # - uses: julia-actions/setup-julia@v2 + # with: + # version: '1' + # - uses: julia-actions/cache@v2 + - uses: fredrikekre/runic-action@v1 + with: + version: '1.0.0' diff --git a/docs/make.jl b/docs/make.jl index 232a9c22..8fff0e1f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,12 +1,14 @@ using Documenter, PGFPlotsX PGFPlotsX.latexengine!(PGFPlotsX.LUALATEX) -DocMeta.setdocmeta!(PGFPlotsX, :DocTestSetup, :(using PGFPlotsX); recursive=true) +DocMeta.setdocmeta!(PGFPlotsX, :DocTestSetup, :(using PGFPlotsX); recursive = true) using Contour, Colors, DataFrames, Distributions makedocs( modules = [PGFPlotsX], - format = Documenter.HTML(; assets = ["assets/custom.css"], - prettyurls = get(ENV, "CI", nothing) == "true"), + format = Documenter.HTML(; + assets = ["assets/custom.css"], + prettyurls = get(ENV, "CI", nothing) == "true" + ), sitename = "PGFPlotsX.jl", doctest = true, strict = true, @@ -22,7 +24,7 @@ makedocs( "man/picdoc.md", "man/save.md", "man/internals.md", - ], + ], "Examples" => [ "examples/coordinates.md", "examples/tables.md", @@ -31,7 +33,7 @@ makedocs( "examples/juliatypes.md", "examples/convenience.md", "examples/latex.md", - ] + ], ] ) @@ -39,5 +41,5 @@ makedocs( deploydocs( repo = "github.com/KristofferC/PGFPlotsX.jl.git", - push_preview=true, + push_preview = true, ) diff --git a/ext/ColorsExt.jl b/ext/ColorsExt.jl index 1f693916..5d74f62a 100644 --- a/ext/ColorsExt.jl +++ b/ext/ColorsExt.jl @@ -7,15 +7,17 @@ PGFPlotsX.EXTENSIONS_SUPPORTED ? (using Colors) : (using ..Colors) function _rgb_for_printing(c::Colors.Colorant) rgb = convert(Colors.RGB{Float64}, c) # round colors since pgfplots cannot parse scientific notation, eg 1e-10 - round.((Colors.red(rgb), Colors.green(rgb), Colors.blue(rgb)); digits = 4) + return round.((Colors.red(rgb), Colors.green(rgb), Colors.blue(rgb)); digits = 4) end function PGFPlotsX.print_opt(io::IO, c::Colors.Colorant) rgb_64 = _rgb_for_printing(c) - print(io, "rgb,1:", - "red," , rgb_64[1], ";", - "green,", rgb_64[2], ";", - "blue," , rgb_64[3]) + return print( + io, "rgb,1:", + "red,", rgb_64[1], ";", + "green,", rgb_64[2], ";", + "blue,", rgb_64[3] + ) end # For printing surface plots with explicit color, pgfplots manual 4.6.7. @@ -23,25 +25,27 @@ end # we should introduce a wrapper type. function PGFPlotsX.print_tex(io::IO, c::Colors.Colorant) rgb_64 = _rgb_for_printing(c) - print(io, "rgb=", rgb_64[1], ",", rgb_64[2], ",", rgb_64[3]) + return print(io, "rgb=", rgb_64[1], ",", rgb_64[2], ",", rgb_64[3]) end function PGFPlotsX.print_tex(io::IO, c::Tuple{String, Colors.Colorant}, ::Any) name, color = c rgb_64 = _rgb_for_printing(color) - print(io, "\\definecolor{$name}{rgb}{$(rgb_64[1]), $(rgb_64[2]), $(rgb_64[3])}") + return print(io, "\\definecolor{$name}{rgb}{$(rgb_64[1]), $(rgb_64[2]), $(rgb_64[3])}") end -function PGFPlotsX.print_tex(io::IO, - c::Tuple{String, Vector{<:Colors.Colorant}}, - ::Any) +function PGFPlotsX.print_tex( + io::IO, + c::Tuple{String, Vector{<:Colors.Colorant}}, + ::Any + ) name, colors = c println(io, "\\pgfplotsset{ colormap={$name}{") for col in colors rgb_64 = _rgb_for_printing(col) println(io, "rgb=(", join(rgb_64, ","), ")") end - println(io, "}}") + return println(io, "}}") end end diff --git a/ext/ContourExt.jl b/ext/ContourExt.jl index 1818195f..55eb2946 100644 --- a/ext/ContourExt.jl +++ b/ext/ContourExt.jl @@ -20,7 +20,7 @@ function PGFPlotsX.TableData(c::Contour.ContourCollection; kwargs...) push!(ns, n) end end - PGFPlotsX.TableData(hcat(colx, coly, colz); colnames=["x", "y", "z"], scanlines=cumsum(ns), kwargs...) + return PGFPlotsX.TableData(hcat(colx, coly, colz); colnames = ["x", "y", "z"], scanlines = cumsum(ns), kwargs...) end end diff --git a/ext/MeasurementsExt.jl b/ext/MeasurementsExt.jl index 9adab396..651f8fd9 100644 --- a/ext/MeasurementsExt.jl +++ b/ext/MeasurementsExt.jl @@ -4,23 +4,35 @@ import PGFPlotsX PGFPlotsX.EXTENSIONS_SUPPORTED ? (using Measurements) : (using ..Measurements) -function PGFPlotsX.Coordinates(x::AbstractVector{T}, y::AbstractVector; - kwargs...) where T <: Measurements.Measurement{<:Real} - PGFPlotsX.Coordinates(Measurements.value.(x), y; - xerror = Measurements.uncertainty.(x), kwargs...) +function PGFPlotsX.Coordinates( + x::AbstractVector{T}, y::AbstractVector; + kwargs... + ) where {T <: Measurements.Measurement{<:Real}} + return PGFPlotsX.Coordinates( + Measurements.value.(x), y; + xerror = Measurements.uncertainty.(x), kwargs... + ) end -function PGFPlotsX.Coordinates(x::AbstractVector, y::AbstractVector{T}; - kwargs...) where T <: Measurements.Measurement{<:Real} - PGFPlotsX.Coordinates(x, Measurements.value.(y); - yerror = Measurements.uncertainty.(y), kwargs...) +function PGFPlotsX.Coordinates( + x::AbstractVector, y::AbstractVector{T}; + kwargs... + ) where {T <: Measurements.Measurement{<:Real}} + return PGFPlotsX.Coordinates( + x, Measurements.value.(y); + yerror = Measurements.uncertainty.(y), kwargs... + ) end -function PGFPlotsX.Coordinates(x::AbstractVector{T}, y::AbstractVector{T}; - kwargs...) where T <: Measurements.Measurement{<:Real} - PGFPlotsX.Coordinates(Measurements.value.(x), Measurements.value.(y); +function PGFPlotsX.Coordinates( + x::AbstractVector{T}, y::AbstractVector{T}; + kwargs... + ) where {T <: Measurements.Measurement{<:Real}} + return PGFPlotsX.Coordinates( + Measurements.value.(x), Measurements.value.(y); xerror = Measurements.uncertainty.(x), - yerror = Measurements.uncertainty.(y), kwargs...) + yerror = Measurements.uncertainty.(y), kwargs... + ) end end diff --git a/ext/StatsBaseExt.jl b/ext/StatsBaseExt.jl index 3d74358d..f6ef329d 100644 --- a/ext/StatsBaseExt.jl +++ b/ext/StatsBaseExt.jl @@ -4,27 +4,35 @@ import PGFPlotsX PGFPlotsX.EXTENSIONS_SUPPORTED ? (using StatsBase) : (using ..StatsBase) -function PGFPlotsX.TableData(h::StatsBase.Histogram{T, 1}; - kwargs...) where T - PGFPlotsX.TableData(hcat(h.edges[1], vcat(h.weights, 0)); kwargs...) +function PGFPlotsX.TableData( + h::StatsBase.Histogram{T, 1}; + kwargs... + ) where {T} + return PGFPlotsX.TableData(hcat(h.edges[1], vcat(h.weights, 0)); kwargs...) end -function PGFPlotsX.TableData(histogram::StatsBase.Histogram{T, 2}; - kwargs...) where T - PGFPlotsX.TableData(StatsBase.midpoints(histogram.edges[1]), - StatsBase.midpoints(histogram.edges[2]), - histogram.weights; kwargs...) +function PGFPlotsX.TableData( + histogram::StatsBase.Histogram{T, 2}; + kwargs... + ) where {T} + return PGFPlotsX.TableData( + StatsBase.midpoints(histogram.edges[1]), + StatsBase.midpoints(histogram.edges[2]), + histogram.weights; kwargs... + ) end function PGFPlotsX.TableData(e::StatsBase.ECDF; n = 100, kwargs...) x = range(extrema(e)...; length = n) - PGFPlotsX.TableData(hcat(x, map(e, x)); kwargs...) + return PGFPlotsX.TableData(hcat(x, map(e, x)); kwargs...) end -function PGFPlotsX.Coordinates(histogram::StatsBase.Histogram{T, 2}) where T - PGFPlotsX.Coordinates(StatsBase.midpoints(histogram.edges[1]), - StatsBase.midpoints(histogram.edges[2]), - histogram.weights) +function PGFPlotsX.Coordinates(histogram::StatsBase.Histogram{T, 2}) where {T} + return PGFPlotsX.Coordinates( + StatsBase.midpoints(histogram.edges[1]), + StatsBase.midpoints(histogram.edges[2]), + histogram.weights + ) end end diff --git a/src/PGFPlotsX.jl b/src/PGFPlotsX.jl index 9c007a6c..34f2eba8 100644 --- a/src/PGFPlotsX.jl +++ b/src/PGFPlotsX.jl @@ -45,7 +45,7 @@ print_tex(a) = print_tex(stdout, a) function print_tex(::Type{String}, args...) io = IOBuffer() print_tex(io, args...) - String(take!(io)) + return String(take!(io)) end include("options.jl") @@ -79,7 +79,7 @@ print_tex(io::IO, vector::AbstractVector) = foreach(elt -> print_tex(io, elt), v Real numbers are printed as is, except for non-finite representation. """ function print_tex(io::IO, x::Real) - if isfinite(x) + return if isfinite(x) print(io, x) elseif isnan(x) print(io, "nan") @@ -97,9 +97,15 @@ print_tex(io::IO, dt::Date) = Dates.format(io, dt, dateformat"YYYY-mm-dd") print_tex(io::IO, dt::DateTime) = Dates.format(io, dt, dateformat"YYYY-mm-dd HH:MM") -print_tex(io::IO, v) = throw(ArgumentError(string("No tex function available for data of type $(typeof(v)). ", - "Define one by overloading print_tex(io::IO, data::T) ", - "where T is the type of the data to dispatch on."))) +print_tex(io::IO, v) = throw( + ArgumentError( + string( + "No tex function available for data of type $(typeof(v)). ", + "Define one by overloading print_tex(io::IO, data::T) ", + "where T is the type of the data to dispatch on." + ) + ) +) """ @@ -130,18 +136,20 @@ end function __init__() pushdisplay(PGFPlotsXDisplay()) - atreplinit(i -> begin - if PlotDisplay() in Base.Multimedia.displays - popdisplay(PGFPlotsXDisplay()) + atreplinit( + i -> begin + if PlotDisplay() in Base.Multimedia.displays + popdisplay(PGFPlotsXDisplay()) + end + pushdisplay(PGFPlotsXDisplay()) end - pushdisplay(PGFPlotsXDisplay()) - end) - - @static if !EXTENSIONS_SUPPORTED - @require Colors="5ae59095-9a9b-59fe-a467-6f913c188581" include("../ext/ColorsExt.jl") - @require Contour="d38c429a-6771-53c6-b99e-75d170b6e991" include("../ext/ContourExt.jl") - @require StatsBase="2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" include("../ext/StatsBaseExt.jl") - @require Measurements="eff96d63-e80a-5855-80a2-b1b0885c5ab7" include("../ext/MeasurementsExt.jl") + ) + + return @static if !EXTENSIONS_SUPPORTED + @require Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" include("../ext/ColorsExt.jl") + @require Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" include("../ext/ContourExt.jl") + @require StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" include("../ext/StatsBaseExt.jl") + @require Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" include("../ext/MeasurementsExt.jl") end end diff --git a/src/axiselements.jl b/src/axiselements.jl index d206fd21..4c3533dc 100644 --- a/src/axiselements.jl +++ b/src/axiselements.jl @@ -26,7 +26,7 @@ function print_tex(io::IO, f::Expression) end end multiple_f && print(io, ")") - nothing + return nothing end ############## @@ -36,7 +36,7 @@ end """ Types we accept as coordinates. Need to support [`print_tex`](@ref). """ -const CoordinateType = Union{Real,AbstractString,Date} +const CoordinateType = Union{Real, AbstractString, Date} struct Coordinate{N} data::NTuple{N, CoordinateType} @@ -44,18 +44,24 @@ struct Coordinate{N} errorplus::Union{Nothing, NTuple{N, Real}} errorminus::Union{Nothing, NTuple{N, Real}} meta::Any - function Coordinate(data::NTuple{N, CoordinateType}, - error::Union{Nothing, NTuple{N, Real}}, - errorplus::Union{Nothing, NTuple{N, Real}}, - errorminus::Union{Nothing, NTuple{N, Real}}, meta) where N + function Coordinate( + data::NTuple{N, CoordinateType}, + error::Union{Nothing, NTuple{N, Real}}, + errorplus::Union{Nothing, NTuple{N, Real}}, + errorminus::Union{Nothing, NTuple{N, Real}}, meta + ) where {N} @argcheck 2 ≤ N ≤ 3 "A Coordinate has to be two- or three dimensional." - @argcheck(!(error ≠ nothing && - (errorplus ≠ nothing || errorminus ≠ nothing)), - "You can specify *either* `error`, or `errorplus`/`errorminus`.") + @argcheck( + !( + error ≠ nothing && + (errorplus ≠ nothing || errorminus ≠ nothing) + ), + "You can specify *either* `error`, or `errorplus`/`errorminus`." + ) error ≠ nothing && @argcheck all(isfinite, error) errorplus ≠ nothing && @argcheck all(isfinite, errorplus) errorminus ≠ nothing && @argcheck all(isfinite, errorminus) - new{N}(data, error, errorplus, errorminus, meta) + return new{N}(data, error, errorplus, errorminus, meta) end end @@ -78,8 +84,10 @@ Metadata can be provided in `meta`. Users rarely need to use this constructor, see methods of [`Coordinates`](@ref) for constructing coordinates from arrays. """ -Coordinate(data; error = nothing, errorplus = nothing, errorminus = nothing, - meta = nothing) = Coordinate(data, error, errorplus, errorminus, meta) +Coordinate( + data; error = nothing, errorplus = nothing, errorminus = nothing, + meta = nothing +) = Coordinate(data, error, errorplus, errorminus, meta) """ $SIGNATURES @@ -97,13 +105,13 @@ Convenience constructor for 3-dimensional coordinates. Coordinate(x::CoordinateType, y::CoordinateType, z; args...) = Coordinate((x, y, z); args...) -function print_tex(io::IO, data::NTuple{N, CoordinateType}, ::Coordinate) where N +function print_tex(io::IO, data::NTuple{N, CoordinateType}, ::Coordinate) where {N} print(io, "(") for (i, x) in enumerate(data) i == 1 || print(io, ",") print(io, x) end - print(io, ")") + return print(io, ")") end # Print raw strings inside coordinates. Compared to generic `print_tex`, print no newline, @@ -114,7 +122,7 @@ function print_tex(io::IO, coordinate::Coordinate) @unpack data, error, errorplus, errorminus, meta = coordinate print_tex(io, data, coordinate) function _print_error(prefix, error) - if error ≠ nothing + return if error ≠ nothing print(io, " $(prefix) ") print_tex(io, error, coordinate) end @@ -127,7 +135,7 @@ function print_tex(io::IO, coordinate::Coordinate) print_tex(io, meta, coordinate) print(io, "]") end - println(io) + return println(io) end struct Coordinates{N} @@ -135,7 +143,7 @@ struct Coordinates{N} end coordinate_or_nothing(data, args...) = - all(x -> x isa AbstractString || isfinite(x)===true, data) ? Coordinate(data, args...) : nothing + all(x -> x isa AbstractString || isfinite(x) === true, data) ? Coordinate(data, args...) : nothing """ $SIGNATURES @@ -171,15 +179,15 @@ function Coordinates(itr) check_N(N) = common_N == 0 ? common_N = N : @argcheck N == common_N "Incompatible dimensions." ensure_c(::Union{Nothing, Tuple{}}) = nothing - ensure_c(c::Coordinate{N}) where N = (check_N(N); c) + ensure_c(c::Coordinate{N}) where {N} = (check_N(N); c) ensure_c(x) = throw(ArgumentError("Can't interpret $x as a coordinate.")) - function ensure_c(data::NTuple{N, Union{CoordinateType, Missing}}) where N + function ensure_c(data::NTuple{N, Union{CoordinateType, Missing}}) where {N} check_N(N) - coordinate_or_nothing(data) + return coordinate_or_nothing(data) end data = [ensure_c(data) for data in itr] @argcheck common_N ≠ 0 "Could not determine dimension from coordinates" - Coordinates{common_N}(data) + return Coordinates{common_N}(data) end expand_errors(_::Nothing...) = nothing @@ -192,19 +200,31 @@ expand_errors(data::Union{Real, Nothing}...) = map(x -> x isa Nothing ? 0 : x, d Two dimensional coordinates from two vectors, with error bars. """ -function Coordinates(x::AbstractVector, y::AbstractVector; - xerror = nothing, yerror = nothing, - xerrorplus = nothing, yerrorplus = nothing, - xerrorminus = nothing, yerrorminus = nothing, - meta = nothing) - Coordinates{2}(@. coordinate_or_nothing(tuple(x, y), - expand_errors(xerror, - yerror), - expand_errors(xerrorplus, - yerrorplus), - expand_errors(xerrorminus, - yerrorminus), - meta)) +function Coordinates( + x::AbstractVector, y::AbstractVector; + xerror = nothing, yerror = nothing, + xerrorplus = nothing, yerrorplus = nothing, + xerrorminus = nothing, yerrorminus = nothing, + meta = nothing + ) + return Coordinates{2}( + @. coordinate_or_nothing( + tuple(x, y), + expand_errors( + xerror, + yerror + ), + expand_errors( + xerrorplus, + yerrorplus + ), + expand_errors( + xerrorminus, + yerrorminus + ), + meta + ) + ) end """ @@ -212,23 +232,35 @@ end Three dimensional coordinates from two vectors, with error bars. """ -function Coordinates(x::AbstractVector, y::AbstractVector, z::AbstractVector; - xerror = nothing, yerror = nothing, zerror = nothing, - xerrorplus = nothing, yerrorplus = nothing, - zerrorplus = nothing, xerrorminus = nothing, - yerrorminus = nothing, zerrorminus = nothing, - meta = nothing) - Coordinates{3}(@. coordinate_or_nothing(tuple(x, y, z), - expand_errors(xerror, - yerror, - zerror), - expand_errors(xerrorplus, - yerrorplus, - zerrorplus), - expand_errors(xerrorminus, - yerrorminus, - zerrorminus), - meta)) +function Coordinates( + x::AbstractVector, y::AbstractVector, z::AbstractVector; + xerror = nothing, yerror = nothing, zerror = nothing, + xerrorplus = nothing, yerrorplus = nothing, + zerrorplus = nothing, xerrorminus = nothing, + yerrorminus = nothing, zerrorminus = nothing, + meta = nothing + ) + return Coordinates{3}( + @. coordinate_or_nothing( + tuple(x, y, z), + expand_errors( + xerror, + yerror, + zerror + ), + expand_errors( + xerrorplus, + yerrorplus, + zerrorplus + ), + expand_errors( + xerrorminus, + yerrorminus, + zerrorminus + ), + meta + ) + ) end """ @@ -236,7 +268,7 @@ end Return new coordinates, inserting [`nothing`](@ref) after every `stride` lines. """ -function insert_scanlines(coordinates::Coordinates{N}, stride) where N +function insert_scanlines(coordinates::Coordinates{N}, stride) where {N} data = Vector{Union{Nothing, Coordinate{N}}}() for (i, coordinate) in enumerate(coordinates.data) push!(data, coordinate) @@ -244,7 +276,7 @@ function insert_scanlines(coordinates::Coordinates{N}, stride) where N push!(data, nothing) end end - Coordinates(data) + return Coordinates(data) end """ @@ -262,12 +294,18 @@ z = sin.(x) + cos.(y') Coordinates(x, y, z) ``` """ -function Coordinates(x::AbstractVector, y::AbstractVector, z::AbstractMatrix; - meta::Union{Nothing, AbstractMatrix} = nothing) +function Coordinates( + x::AbstractVector, y::AbstractVector, z::AbstractMatrix; + meta::Union{Nothing, AbstractMatrix} = nothing + ) meta ≠ nothing && @argcheck size(meta) == size(z) - insert_scanlines(Coordinates(matrix_xyz(x, y, z)...; - meta = meta ≠ nothing ? vec(meta) : meta), - length(x)) + return insert_scanlines( + Coordinates( + matrix_xyz(x, y, z)...; + meta = meta ≠ nothing ? vec(meta) : meta + ), + length(x) + ) end print_tex(io::IO, ::Nothing, ::Coordinates) = println(io) @@ -278,8 +316,9 @@ function print_tex(io::IO, coordinates::Coordinates) for coordinate in coordinates.data print_tex(io, coordinate, coordinates) end + return end - println(io, "}") + return println(io, "}") end ######### @@ -330,18 +369,20 @@ for `surf` and `mesh` plots. They are expanded using [`expand_scanlines`](@ref). """ struct TableData data::AbstractMatrix - colnames::Union{Nothing, Vector{<: AbstractString}} + colnames::Union{Nothing, Vector{<:AbstractString}} scanlines::AbstractVector{Int} rowsep::Bool - function TableData(data::AbstractMatrix, - colnames::Union{Nothing, Vector{<: AbstractString}}, - scanlines::AbstractVector{Int}, - rowsep::Bool = ROWSEP) + function TableData( + data::AbstractMatrix, + colnames::Union{Nothing, Vector{<:AbstractString}}, + scanlines::AbstractVector{Int}, + rowsep::Bool = ROWSEP + ) if colnames ≠ nothing @argcheck allunique(colnames) "Column names are not unique." @argcheck length(colnames) == size(data, 2) end - new(data, colnames, scanlines, rowsep) + return new(data, colnames, scanlines, rowsep) end end @@ -366,6 +407,7 @@ function print_tex(io::IO, tabledata::TableData) _rowsep() end end + return end @@ -374,11 +416,15 @@ end `data` provided directly as a matrix. """ -function TableData(data::AbstractMatrix; - colnames = nothing, scanlines = 0, rowsep = ROWSEP) - TableData(data, - colnames ≡ nothing ? colnames : collect(string(c) for c in colnames), - expand_scanlines(scanlines, size(data, 1)), rowsep) +function TableData( + data::AbstractMatrix; + colnames = nothing, scanlines = 0, rowsep = ROWSEP + ) + return TableData( + data, + colnames ≡ nothing ? colnames : collect(string(c) for c in colnames), + expand_scanlines(scanlines, size(data, 1)), rowsep + ) end """ @@ -389,9 +435,11 @@ Columns, given as vectors. Use of this constructor is encouraged for conversion, passing on keyword arguments. """ -TableData(columns::Vector{<: AbstractVector}, colnames = nothing, scanlines = 0; - rowsep::Bool = ROWSEP) = - TableData(reduce(hcat, columns); colnames=nothing, scanlines=0, rowsep=rowsep) +TableData( + columns::Vector{<:AbstractVector}, colnames = nothing, scanlines = 0; + rowsep::Bool = ROWSEP +) = + TableData(reduce(hcat, columns); colnames = nothing, scanlines = 0, rowsep = rowsep) """ $SIGNATURES @@ -399,10 +447,14 @@ TableData(columns::Vector{<: AbstractVector}, colnames = nothing, scanlines = 0; Named columns provided as a vector of pairs, eg `[:x => 1:10, :y => 11:20]`. Symbols or strings are accepted as column names. """ -function TableData(name_column_pairs::Vector{<: Pair}; - scanlines = 0, rowsep::Bool = ROWSEP) - TableData(reduce(hcat, last.(name_column_pairs)); colnames=first.(name_column_pairs), - scanlines=scanlines, rowsep=rowsep) +function TableData( + name_column_pairs::Vector{<:Pair}; + scanlines = 0, rowsep::Bool = ROWSEP + ) + return TableData( + reduce(hcat, last.(name_column_pairs)); colnames = first.(name_column_pairs), + scanlines = scanlines, rowsep = rowsep + ) end TableData(rest::AbstractVector...; kwargs...) = TableData(collect(rest); kwargs...) @@ -413,7 +465,7 @@ TableData(name_column_pairs::Pair...; kwargs...) = function TableData(x::AbstractVector, y::AbstractVector, z::AbstractMatrix; kwargs...) colnames = ["x", "y", "z"] columns = reduce(hcat, matrix_xyz(x, y, z)) - return TableData(columns; colnames=colnames, scanlines=length(x), kwargs...) + return TableData(columns; colnames = colnames, scanlines = length(x), kwargs...) end @@ -435,7 +487,7 @@ function TableData(table; kwargs...) error("`$(typeof(table))` does not support the Table interface") end colnames = string.(Tables.columnnames(Tables.columns(table))) - TableData(Tables.matrix(table); colnames=colnames, kwargs...) + return TableData(Tables.matrix(table); colnames = colnames, kwargs...) end struct Table <: OptionType @@ -490,7 +542,7 @@ function print_tex(io::IO, table::Table) @unpack options, content = table all_options = merge(container_options(content, table), options) print(io, "table") - if content isa String + return if content isa String print_options(io, all_options, newline = false) print(io, "{") print(io, content) @@ -518,13 +570,13 @@ struct Graphics <: OptionType end function Graphics(filename::AbstractString, args::Vararg{PGFOption}) - Graphics(dictify(args), filename) + return Graphics(dictify(args), filename) end function print_tex(io::IO, t::Graphics) print(io, "graphics") print_options(io, t.options; newline = false) - println(io, "{", t.filename, "}") + return println(io, "{", t.filename, "}") end ######## @@ -550,8 +602,10 @@ struct Plot <: OptionType trailing::AbstractVector{Any} # FIXME can/should we be more specific? end -Plot(is3d::Bool, incremental::Bool, options::Options, data::PlotData, - trailing::Tuple) = Plot(is3d, incremental, options, data, collect(trailing)) +Plot( + is3d::Bool, incremental::Bool, options::Options, data::PlotData, + trailing::Tuple +) = Plot(is3d, incremental, options, data, collect(trailing)) Base.push!(p::Plot, args...; kwargs...) = (push!(p.trailing, args...; kwargs...); p) Base.append!(p::Plot, args...; kwargs...) = (append!(p.trailing, args...; kwargs...); p) @@ -614,7 +668,7 @@ Plot3Inc(data::PlotData, trailing...) = Plot(true, true, Options(), data, trailing) function save(filename::AbstractString, plot::Plot; kwargs...) - save(filename, Axis(plot); kwargs...) + return save(filename, Axis(plot); kwargs...) end function print_tex(io::IO, plot::Plot) @@ -628,8 +682,9 @@ function print_tex(io::IO, plot::Plot) for t in trailing print_tex(io, t) end - println(io, ";") + return println(io, ";") end + return end struct Legend @@ -679,6 +734,7 @@ function print_tex(io::IO, legendentry::LegendEntry) print(io, "{") print(io, name) println(io, "}") + return end ############### @@ -697,6 +753,7 @@ end function print_tex(io::IO, legend_image::LegendImage) print(io, "\\addlegendimage") print_options(io, legend_image.options; newline = false, brackets = "{}") + return end ################### @@ -720,6 +777,7 @@ function print_tex(io::IO, vline::VLine) print_options(io, vline.options; newline = false) x = print_tex(String, vline.x) println(io, "({axis cs:$(x),0}|-{rel axis cs:0,1}) -- ({axis cs:$(x),0}|-{rel axis cs:0,0});") + return end struct HLine @@ -739,6 +797,7 @@ function print_tex(io::IO, hline::HLine) print_options(io, hline.options; newline = false) y = print_tex(String, hline.y) println(io, "({rel axis cs:1,0}|-{axis cs:0,$(y)}) -- ({rel axis cs:0,0}|-{axis cs:0,$(y)});") + return end ################### @@ -763,6 +822,7 @@ function print_tex(io::IO, vband::VBand) print_options(io, vband.options; newline = false) xmin, xmax = print_tex.(String, (vband.xmin, vband.xmax)) println(io, "({axis cs:$(xmin),0}|-{rel axis cs:0,1}) rectangle ({axis cs:$(xmax),0}|-{rel axis cs:0,0});") + return end struct HBand @@ -783,4 +843,5 @@ function print_tex(io::IO, hband::HBand) print_options(io, hband.options; newline = false) ymin, ymax = print_tex.(String, (hband.ymin, hband.ymax)) println(io, "({rel axis cs:1,0}|-{axis cs:0,$(ymin)}) rectangle ({rel axis cs:0,0}|-{axis cs:0,$(ymax)});") + return end diff --git a/src/axislike.jl b/src/axislike.jl index c8a262e1..f66a5fa6 100644 --- a/src/axislike.jl +++ b/src/axislike.jl @@ -37,18 +37,18 @@ function print_tex(io::IO, axislike::T) where {T <: AxisLike} for elt in contents print_tex(io, elt, axislike) end + return end - println(io, "\\end{", name, "}") + return println(io, "\\end{", name, "}") end -function save(filename::AbstractString, axislike::AxisLike; kwargs...) +function save(filename::AbstractString, axislike::AxisLike; kwargs...) = save(filename, TikzPicture(axislike); kwargs...) -end macro define_axislike(name, latex_environment) @argcheck latex_environment isa String _name = esc(name) - quote + return quote Base.@__doc__ struct $(_name) <: AxisLike options::Options contents::Vector{Any} @@ -160,6 +160,8 @@ function print_tex(io::IO, groupplot::GroupPlot) print_tex(io, elt) end end + return end println(io, raw"\end{groupplot}") + return end diff --git a/src/build.jl b/src/build.jl index cd94026c..caf9f79b 100644 --- a/src/build.jl +++ b/src/build.jl @@ -16,9 +16,13 @@ function latexengine() return ACTIVE_LATEX_ENGINE[] = enum end end - throw(MissingExternalProgramError("No LaTeX installation found, figures will not be generated. ", - "Make sure either pdflatex, xelatex or lualatex are installed and that ", - "the PATH variable is correctly set.")) + throw( + MissingExternalProgramError( + "No LaTeX installation found, figures will not be generated. ", + "Make sure either pdflatex, xelatex or lualatex are installed and that ", + "the PATH variable is correctly set." + ) + ) end return ACTIVE_LATEX_ENGINE[] end @@ -47,7 +51,7 @@ function run_latex_once(filename::AbstractString, eng::LaTeXEngine, flags) cmd = `$(_engine_cmd(eng)) $flags $file` @debug "running latex command $cmd in dir $dir" succ = cd(dir) do - success(cmd) + return success(cmd) end logfile = _replace_fileext(filename, ".log") log = if !isfile(logfile) @@ -56,7 +60,7 @@ function run_latex_once(filename::AbstractString, eng::LaTeXEngine, flags) else read(logfile, String) end - succ, log, cmd + return succ, log, cmd end function rm_tmpfiles(filename::AbstractString) @@ -65,6 +69,7 @@ function rm_tmpfiles(filename::AbstractString) rm(logfile; force = true) rm(auxfile; force = true) rm(filename; force = true) + return end DEFAULT_FLAGS = Union{String}[] # no default flags currently @@ -93,15 +98,15 @@ The default preamble for LaTeX documents. Don't change this, customize """ DEFAULT_PREAMBLE = String[ - "\\usepackage{pgfplots}", - "\\pgfplotsset{compat=newest}", - "\\usepgfplotslibrary{groupplots}", - "\\usepgfplotslibrary{polar}", - "\\usepgfplotslibrary{smithchart}", - "\\usepgfplotslibrary{statistics}", - "\\usepgfplotslibrary{dateplot}", - "\\usepgfplotslibrary{ternary}", - ] + "\\usepackage{pgfplots}", + "\\pgfplotsset{compat=newest}", + "\\usepgfplotslibrary{groupplots}", + "\\usepgfplotslibrary{polar}", + "\\usepgfplotslibrary{smithchart}", + "\\usepgfplotslibrary{statistics}", + "\\usepgfplotslibrary{dateplot}", + "\\usepgfplotslibrary{ternary}", +] # Collects the full preamble from the different sources, default and custom function _default_preamble() @@ -159,12 +164,18 @@ Relies on external programs, see the manual. Part of the API, but not exported. """ -function convert_pdf_to_png(pdf::AbstractString, - png::AbstractString = _replace_fileext(pdf, ".png"); - engine::PNGEngine=png_engine(), dpi::Number=150) +function convert_pdf_to_png( + pdf::AbstractString, + png::AbstractString = _replace_fileext(pdf, ".png"); + engine::PNGEngine = png_engine(), dpi::Number = 150 + ) if engine == NO_PNG_ENGINE - throw(MissingExternalProgramError("No PDF to PNG converter found, we looked for `pdftocairo` and `pdftoppm`. ", - "Make sure one of these are installed and available at PATH and restart Julia.")) + throw( + MissingExternalProgramError( + "No PDF to PNG converter found, we looked for `pdftocairo` and `pdftoppm`. ", + "Make sure one of these are installed and available at PATH and restart Julia." + ) + ) end if engine == PNG_PDF_TO_CAIRO cmd = `pdftocairo -png -r $dpi -singlefile $pdf $png` @@ -207,12 +218,18 @@ Relies on external programs, see the manual. Part of the API, but not exported. """ -function convert_pdf_to_svg(pdf::AbstractString, - svg::AbstractString = _replace_fileext(pdf, ".svg"); - engine=svg_engine()) +function convert_pdf_to_svg( + pdf::AbstractString, + svg::AbstractString = _replace_fileext(pdf, ".svg"); + engine = svg_engine() + ) if engine == NO_SVG_ENGINE - throw(MissingExternalProgramError("No PDF to SVG converter found, we looked for `pdftocairo` and `pdf2svg`. ", - "Make sure one of these are installed and available at PATH and restart Julia.")) + throw( + MissingExternalProgramError( + "No PDF to SVG converter found, we looked for `pdftocairo` and `pdf2svg`. ", + "Make sure one of these are installed and available at PATH and restart Julia." + ) + ) end if engine == SVG_PDF_TO_CAIRO cmd = `pdftocairo -svg -l 1 $pdf $svg` diff --git a/src/options.jl b/src/options.jl index 981c7813..43080253 100644 --- a/src/options.jl +++ b/src/options.jl @@ -11,6 +11,7 @@ normalize_key(x) = error("Invalid pgf key $x") function Base.show(io::IO, ::MIME"text/plain", options::Options) print_options(io, options; newline = false) + return end # Wrapper to wrap arguments in the `@pgf {theme...,}` syntax to @@ -38,8 +39,8 @@ macro is used in scripts and interactive code. When `print_empty = false` (the default), empty options are not printed. Use `print_empty = true` to force printing a `[]` in this case. """ -function Options(args::Union{Pair,MergeEntry}...; print_empty::Bool = false) - d = OrderedDict{String,Any}() +function Options(args::Union{Pair, MergeEntry}...; print_empty::Bool = false) + d = OrderedDict{String, Any}() for arg in args if arg isa Pair k, v = arg @@ -64,8 +65,10 @@ Base.copy(options::Options) = deepcopy(options) function Base.merge(options::Options, others::Options...) args = (options, others...) - Options(mapreduce(opts -> opts.dict, merge, args), - mapreduce(opts -> opts.print_empty, |, args)) + return Options( + mapreduce(opts -> opts.dict, merge, args), + mapreduce(opts -> opts.print_empty, |, args) + ) end function prockey(key) @@ -73,8 +76,8 @@ function prockey(key) return :($(normalize_key(key)) => nothing) elseif @capture(key, @raw_str(str_)) return :($(normalize_key(str)) => nothing) - elseif @capture(key, (a_ : b_) | (a_ => b_) | (a_ = b_)) - return :($(normalize_key(a))=>$b) + elseif @capture(key, (a_:b_) | (a_ => b_) | (a_ = b_)) + return :($(normalize_key(a)) => $b) elseif @capture(key, g_...) return :($MergeEntry($g)) end @@ -138,7 +141,7 @@ axis_opt = @pgf {theme..., title = "My figure"} Use `{}` for empty options that print as `[]` in LaTeX. """ macro pgf(ex) - esc(prewalk(procmap, ex)) + return esc(prewalk(procmap, ex)) end """ @@ -158,13 +161,13 @@ Base.delete!(o::OptionType, args...; kwargs...) = (delete!(o.options, args...; k Base.copy(a::OptionType) = deepcopy(a) -function Base.merge!(options::Union{Options,OptionType}, others::Options...) +function Base.merge!(options::Union{Options, OptionType}, others::Options...) for other in others for (k, v) in other.dict options[k] = v end end - options + return options end """ @@ -190,36 +193,35 @@ function print_options(io::IO, options::Options; newline = true, brackets = "[]" print_opt(io, options) print(io, brackets[2]) end - newline ? println(io) : print(io, " ") + return newline ? println(io) : print(io, " ") end print_tex(io::IO, options::Options) = print_options(io, options; newline = false) -accum_opt!(d::AbstractDict, opt::Union{String,Symbol}) = d[normalize_key(opt)] = nothing +accum_opt!(d::AbstractDict, opt::Union{String, Symbol}) = d[normalize_key(opt)] = nothing accum_opt!(d::AbstractDict, opt::Pair) = d[normalize_key(first(opt))] = last(opt) function accum_opt!(d::AbstractDict, opt::AbstractDict) for (k, v) in opt d[normalize_key(k)] = v end + return end function Base.append!(options::Options, opts) for opt in opts accum_opt!(options.dict, opt) end - options + return options end -function Base.push!(options::Options, opts::Union{String,Pair}...) - append!(options, opts) -end +Base.push!(options::Options, opts::Union{String, Pair}...) = append!(options, opts) function dictify(args) options = Options() for arg in args accum_opt!(options.dict, arg) end - options + return options end function print_opt(io::IO, options::Options) @@ -232,9 +234,10 @@ function print_opt(io::IO, options::Options) print(io, "}") end if i != length(dict) - print(io, ", ") + print(io, ", ") end end + return end print_opt(io::IO, s) = print_tex(io, s) @@ -244,6 +247,7 @@ function print_opt(io::IO, v::AbstractVector) i == 1 || print(io, ",") print_opt(io, o) end + return end function print_opt(io::IO, t::Tuple) @@ -253,6 +257,7 @@ function print_opt(io::IO, t::Tuple) print_opt(io, t[i]) i != length(t) && print(io, "}") end + return end print_opt(io::IO, str::AbstractString) = print(io, str) diff --git a/src/precompile_PGFPlotsX.jl b/src/precompile_PGFPlotsX.jl index b2fe4947..d2b22a10 100644 --- a/src/precompile_PGFPlotsX.jl +++ b/src/precompile_PGFPlotsX.jl @@ -1,4 +1,4 @@ -const __bodyfunction__ = Dict{Method,Any}() +const __bodyfunction__ = Dict{Method, Any}() # Find keyword "body functions" (the function that contains the body # as written by the developer, called after all missing keyword-arguments @@ -22,7 +22,7 @@ function __lookup_kwbody__(mnokw::Method) # where `mkw` is the name of the "active" keyword body-function. ast = Base.uncompressed_ast(mnokw) if isa(ast, Core.CodeInfo) && length(ast.code) >= 2 - callexpr = ast.code[end-1] + callexpr = ast.code[end - 1] if isa(callexpr, Expr) && callexpr.head == :call fsym = callexpr.args[1] if isa(fsym, Symbol) @@ -51,15 +51,17 @@ end function _precompile_() ccall(:jl_generating_output, Cint, ()) == 1 || return nothing - Base.precompile(Tuple{Core.kwftype(typeof(PGFPlotsX.Type)),NamedTuple{(:print_empty,), Tuple{Bool}},Type{PGFPlotsX.Options},Pair{String, Nothing},Pair{String, Nothing}}) - Base.precompile(Tuple{Type{Axis},PGFPlotsX.Options,Plot}) - Base.precompile(Tuple{Type{Coordinates},StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}},Vector{Float64}}) - Base.precompile(Tuple{typeof(display),PGFPlotsX.PGFPlotsXDisplay,Axis}) - Base.precompile(Tuple{typeof(print_tex),IOStream,TikzPicture,TikzDocument}) - Base.precompile(Tuple{typeof(procmap),Expr}) - let fbody = try __lookup_kwbody__(which(PGFPlotsX.save, (String,TikzDocument,))) catch missing end + Base.precompile(Tuple{Core.kwftype(typeof(PGFPlotsX.Type)), NamedTuple{(:print_empty,), Tuple{Bool}}, Type{PGFPlotsX.Options}, Pair{String, Nothing}, Pair{String, Nothing}}) + Base.precompile(Tuple{Type{Axis}, PGFPlotsX.Options, Plot}) + Base.precompile(Tuple{Type{Coordinates}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}, Vector{Float64}}) + Base.precompile(Tuple{typeof(display), PGFPlotsX.PGFPlotsXDisplay, Axis}) + Base.precompile(Tuple{typeof(print_tex), IOStream, TikzPicture, TikzDocument}) + Base.precompile(Tuple{typeof(procmap), Expr}) + return let fbody = try + __lookup_kwbody__(which(PGFPlotsX.save, (String, TikzDocument))) + catch missing end if !ismissing(fbody) - Base.precompile(fbody, (Bool,PGFPlotsX.LaTeXEngine,Vector{String},Int64,Bool,typeof(PGFPlotsX.save),String,TikzDocument,)) + Base.precompile(fbody, (Bool, PGFPlotsX.LaTeXEngine, Vector{String}, Int64, Bool, typeof(PGFPlotsX.save), String, TikzDocument)) end end end diff --git a/src/tikzdocument.jl b/src/tikzdocument.jl index 4ebf0d25..3ec2a671 100644 --- a/src/tikzdocument.jl +++ b/src/tikzdocument.jl @@ -18,7 +18,7 @@ struct TikzDocument "Add to the preamble." preamble::Vector{Any} function TikzDocument(elements...; use_default_preamble = true, preamble = []) - new(collect(Any, elements), use_default_preamble, preamble) + return new(collect(Any, elements), use_default_preamble, preamble) end end @@ -51,7 +51,7 @@ end MissingExternalProgramError(strs...) = MissingExternalProgramError(join(strs)) function Base.showerror(io::IO, e::MissingExternalProgramError) - print(io, e.str) + return print(io, e.str) end """ @@ -64,12 +64,14 @@ Keywords specify options, some specific to some output formats. `pgfsave` is an alias which is exported. """ -function save(filename::AbstractString, td::TikzDocument; - include_preamble::Bool = true, - latex_engine = latexengine(), - buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), - dpi = 150, - showing_ide = false) +function save( + filename::AbstractString, td::TikzDocument; + include_preamble::Bool = true, + latex_engine = latexengine(), + buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), + dpi = 150, + showing_ide = false + ) filebase, fileext = splitext(filename) if showing_ide td = deepcopy(td) @@ -85,11 +87,15 @@ function save(filename::AbstractString, td::TikzDocument; elseif fileext == ".pdf" savepdf(filename, td; latex_engine = latex_engine, buildflags = buildflags) elseif fileext == ".png" - savepng(filename, td; - latex_engine = latex_engine, buildflags = buildflags, dpi = dpi) + savepng( + filename, td; + latex_engine = latex_engine, buildflags = buildflags, dpi = dpi + ) else - allowed_file_endings = vcat(["tex", "pdf", "png", "svg"], - lstrip.(STANDALONE_TIKZ_FILEEXTS, '.')) + allowed_file_endings = vcat( + ["tex", "pdf", "png", "svg"], + lstrip.(STANDALONE_TIKZ_FILEEXTS, '.') + ) throw(ArgumentError("allowed file endings are $(join(allowed_file_endings, ", ")).")) end return @@ -98,10 +104,12 @@ end const pgfsave = save # TeX -function savetex(filename::AbstractString, td::TikzDocument; - include_preamble::Bool = true) - open(filename, "w") do io - savetex(io, td; include_preamble = include_preamble) +function savetex( + filename::AbstractString, td::TikzDocument; + include_preamble::Bool = true + ) + return open(filename, "w") do io + return savetex(io, td; include_preamble = include_preamble) end end @@ -141,33 +149,37 @@ function print_tex(io::IO, td::TikzDocument; include_preamble::Bool = true) end println(io, "\\begin{document}") else - print_tex(io,"% Recommended preamble:") + print_tex(io, "% Recommended preamble:") for preamble_line in preamble - print_tex(io,replace(preamble_line,r"^"m => s"% "),td) + print_tex(io, replace(preamble_line, r"^"m => s"% "), td) end end for element in td.elements print_tex(io, element, td) end - if include_preamble + return if include_preamble println(io, "\\end{document}") end end _HAS_WARNED_SHELL_ESCAPE = false -function savepdf(filename::AbstractString, td::TikzDocument; - latex_engine = latexengine(), - buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), - run_count = 0, tmp = tempname()) +function savepdf( + filename::AbstractString, td::TikzDocument; + latex_engine = latexengine(), + buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), + run_count = 0, tmp = tempname() + ) global _HAS_WARNED_SHELL_ESCAPE, _OLD_LUALATEX run_again = false tmp_tex = tmp * ".tex" tmp_pdf = tmp * ".pdf" savetex(tmp_tex, td) - latex_success, log, latexcmd = run_latex_once(tmp_tex, - latex_engine, buildflags) + latex_success, log, latexcmd = run_latex_once( + tmp_tex, + latex_engine, buildflags + ) if !latex_success @debug "LaTeX command $latexcmd failed" @@ -175,8 +187,10 @@ function savepdf(filename::AbstractString, td::TikzDocument; @debug "The log indicates luatex85.sty is not found, trying again without require" _OLD_LUALATEX = true run_again = true - elseif (occursin("Maybe you need to enable the shell-escape feature", log) || - occursin("Package pgfplots Error: sorry, plot file{", log)) + elseif ( + occursin("Maybe you need to enable the shell-escape feature", log) || + occursin("Package pgfplots Error: sorry, plot file{", log) + ) if !_HAS_WARNED_SHELL_ESCAPE @warn("Detecting need of --shell-escape flag, enabling it for the rest of the session and running latex again") _HAS_WARNED_SHELL_ESCAPE = true @@ -192,9 +206,13 @@ function savepdf(filename::AbstractString, td::TikzDocument; else latexerrormsg(log) rm_tmpfiles(tmp_tex) - error(string("The latex command $latexcmd failed ", - "shell-escape feature seemed to not be ", - "detected even though it was passed as a flag")) + error( + string( + "The latex command $latexcmd failed ", + "shell-escape feature seemed to not be ", + "detected even though it was passed as a flag" + ) + ) end else latexerrormsg(log) @@ -208,21 +226,23 @@ function savepdf(filename::AbstractString, td::TikzDocument; error("ran latex 5 times without converging, log is:\n$log") end if run_again - savepdf(filename, td; latex_engine=latex_engine, buildflags=buildflags, - run_count=run_count+1, tmp = tmp) + savepdf( + filename, td; latex_engine = latex_engine, buildflags = buildflags, + run_count = run_count + 1, tmp = tmp + ) return end rm_tmpfiles(tmp_tex) - mv(tmp_pdf, filename; force = true) + return mv(tmp_pdf, filename; force = true) end const _SHOWABLE = Union{Plot, AbstractVector{Plot}, AxisLike, TikzDocument, TikzPicture} function Base.show(io::IO, ::MIME"application/pdf", p::_SHOWABLE) filename = tempname() * ".pdf" - save(filename, p; showing_ide=_is_ide()) + save(filename, p; showing_ide = _is_ide()) write(io, read(filename)) - rm(filename; force = true) + return rm(filename; force = true) end # Copyright TikzPictures.jl (see LICENSE.md) @@ -242,9 +262,10 @@ function latexerrormsg(s) end end end + return end -global _tikzid = round(UInt64, time() * 1e6) +global _tikzid = round(UInt64, time() * 1.0e6) # The purpose of this is to not have IJulia call latex twice every time # we show a figure (https://github.com/JuliaLang/IJulia.jl/issues/574) @@ -264,20 +285,22 @@ Generates an interim PDF which is deleted; use `keep_pdf = true` to copy it to `filename` with the extension (if any) replaced by `".pdf"`. This overwrites an existing PDF file with the same name. """ -function savesvg(filename::AbstractString, td::TikzDocument; - latex_engine = latexengine(), - buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), - keep_pdf = false) +function savesvg( + filename::AbstractString, td::TikzDocument; + latex_engine = latexengine(), + buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), + keep_pdf = false + ) tmp_pdf = tempname() * ".pdf" savepdf(tmp_pdf, td, latex_engine = latex_engine, buildflags = buildflags) if _is_ijulia() && showing_Ijulia tmp_ijulia_pdf = tempname() * ".pdf" hsh = hash(sprint(print_tex, td)) cp(tmp_pdf, tmp_ijulia_pdf) - Ijulia_cache[[1,2]] = [hsh, tmp_ijulia_pdf] + Ijulia_cache[[1, 2]] = [hsh, tmp_ijulia_pdf] end convert_pdf_to_svg(tmp_pdf, filename) - if keep_pdf + return if keep_pdf mv(tmp_pdf, _replace_fileext(filename, ".pdf"); force = true) else rm(tmp_pdf) @@ -291,7 +314,8 @@ function Base.show(f::IO, ::MIME"image/svg+xml", td::_SHOWABLE) global _tikzid filename = tempname() * ".svg" global showing_Ijulia = true - try save(filename, td; showing_ide=_is_ide()) + try + save(filename, td; showing_ide = _is_ide()) finally global showing_Ijulia = false end @@ -306,13 +330,15 @@ function Base.show(f::IO, ::MIME"image/svg+xml", td::_SHOWABLE) s = replace(s, "image id=\"" => "image style=\"image-rendering: pixelated;\" id=\"") _tikzid += 1 println(f, s) - rm(filename; force = true) + return rm(filename; force = true) end -function savepng(filename::AbstractString, td::TikzDocument; - latex_engine = latexengine(), - buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), - dpi::Number = 150) +function savepng( + filename::AbstractString, td::TikzDocument; + latex_engine = latexengine(), + buildflags = vcat(DEFAULT_FLAGS, CUSTOM_FLAGS), + dpi::Number = 150 + ) found_ijulia_cache_matching = false local tmp if _is_ijulia() && showing_Ijulia && Ijulia_cache[1] != nothing @@ -328,29 +354,30 @@ function savepng(filename::AbstractString, td::TikzDocument; savepdf(tmp, td, latex_engine = latex_engine, buildflags = buildflags) end filebase = splitext(filename)[1] - convert_pdf_to_png(tmp, filebase; dpi=dpi) - found_ijulia_cache_matching && rm(tmp; force=true) + convert_pdf_to_png(tmp, filebase; dpi = dpi) + return found_ijulia_cache_matching && rm(tmp; force = true) end Base.showable(::MIME"image/png", ::_SHOWABLE) = png_engine() !== NO_PNG_ENGINE function Base.show(io::IO, ::MIME"image/png", p::_SHOWABLE) filename = tempname() * ".png" global showing_Ijulia = true - try save(filename, p; showing_ide=_is_ide()) + try + save(filename, p; showing_ide = _is_ide()) finally global showing_Ijulia = false end write(io, read(filename)) - rm(filename; force = true) + return rm(filename; force = true) end _DISPLAY_PDF = true enable_interactive(v::Bool) = global _DISPLAY_PDF = v _is_ijulia() = isdefined(Main, :IJulia) && Main.IJulia.inited _is_vscode() = isdefined(Main, :_vscodeserver) || (isdefined(Main, :VSCodeServer) && Main.VSCodeServer.PLOT_PANE_ENABLED[] == true) -_is_ide() = _is_ijulia() || _is_vscode() +_is_ide() = _is_ijulia() || _is_vscode() function Base.display(d::PGFPlotsXDisplay, p::_SHOWABLE) - if _DISPLAY_PDF + return if _DISPLAY_PDF filename = tempname() .* ".pdf" save(filename, p) try diff --git a/src/tikzpicture.jl b/src/tikzpicture.jl index 90a0e25b..62d7b370 100644 --- a/src/tikzpicture.jl +++ b/src/tikzpicture.jl @@ -11,7 +11,7 @@ struct TikzPicture <: OptionType options::Options elements::Vector{TikzElementOrStr} # Plots, nodes etc function TikzPicture(options::Options, elements::TikzElementOrStr...) - new(options, collect(TikzElementOrStr, elements)) + return new(options, collect(TikzElementOrStr, elements)) end end @@ -28,8 +28,10 @@ function print_tex(io::IO, tp::TikzPicture) print_tex(io, element, tp) end println(io, "\\end{tikzpicture}") + return end function save(filename::AbstractString, tp::TikzPicture; kwargs...) save(filename, TikzDocument(tp); kwargs...) + return end diff --git a/src/utilities.jl b/src/utilities.jl index 838f0cf6..d0ac3bb7 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -8,14 +8,14 @@ function add_indent(str::AbstractString) isterminated = endswith(str, "\n") lines = split(str, '\n') if isterminated - lines = lines[1:(end-1)] + lines = lines[1:(end - 1)] end indent = (str) -> isempty(strip(str)) ? str : " " * str result = join(indent.(lines), '\n') if isterminated result *= "\n" end - result + return result end """ @@ -27,7 +27,7 @@ indented with four spaces. function print_indent(f, io_main::IO) io = IOBuffer() f(io) - print(io_main, add_indent(String(take!(io)))) + return print(io_main, add_indent(String(take!(io)))) end """ @@ -37,8 +37,8 @@ Print `elt` to `io` with indentation. Shortcut for the function wrapper of `print_indent` for a single element. """ function print_indent(io_main::IO, elt) - print_indent(io_main) do io - print_tex(io, elt) + return print_indent(io_main) do io + return print_tex(io, elt) end end @@ -54,7 +54,7 @@ function _replace_fileext(filename, ext) if filename == new_filename error("$filename already has extension $ext.") end - new_filename + return new_filename end """ @@ -68,5 +68,5 @@ function matrix_xyz(x::AbstractVector, y::AbstractVector, z::AbstractMatrix) x_grid = @. first(tuple(x, y')) y_grid = @. last(tuple(x, y')) @argcheck size(x_grid) == size(y_grid) == size(z) "Incompatible sizes." - vec(x_grid), vec(y_grid), vec(z) + return vec(x_grid), vec(y_grid), vec(z) end diff --git a/test/runtests.jl b/test/runtests.jl index f9284a99..c77380fb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,14 +13,20 @@ end @info "LaTeX engine" PGFPlotsX.latexengine() PGFPlotsX.latexengine!(PGFPlotsX.PDFLATEX) -GNUPLOT_VERSION = try chomp(read(`gnuplot -V`, String)); catch; nothing; end +GNUPLOT_VERSION = try + chomp(read(`gnuplot -V`, String)) +catch + nothing +end HAVE_GNUPLOT = GNUPLOT_VERSION ≠ nothing @info "External binaries" PGFPlotsX.png_engine() PGFPlotsX.svg_engine() GNUPLOT_VERSION -if !(PGFPlotsX.png_engine() !== PGFPlotsX.NO_PNG_ENGINE && - PGFPlotsX.svg_engine() !== PGFPlotsX.NO_SVG_ENGINE && - HAVE_GNUPLOT) +if !( + PGFPlotsX.png_engine() !== PGFPlotsX.NO_PNG_ENGINE && + PGFPlotsX.svg_engine() !== PGFPlotsX.NO_SVG_ENGINE && + HAVE_GNUPLOT + ) @warn "External binaries `pdf2svg`, `pdftoppm`, and `gnuplot` need to be installed for complete test coverage." end @@ -31,6 +37,8 @@ include("test_options.jl") include("test_elements.jl") -mktempdir() do tmp; cd(tmp) do - include("test_build.jl") -end end +mktempdir() do tmp + return cd(tmp) do + return include("test_build.jl") + end +end diff --git a/test/test_build.jl b/test/test_build.jl index 29881655..1e7c8120 100644 --- a/test/test_build.jl +++ b/test/test_build.jl @@ -1,5 +1,5 @@ function is_file_starting_with(filename, bytes::DenseVector{UInt8}) - isfile(filename) && read(filename, length(bytes)) == bytes + return isfile(filename) && read(filename, length(bytes)) == bytes end function is_file_starting_with(filename, regex::Regex, nlines = 1) @@ -9,27 +9,28 @@ function is_file_starting_with(filename, regex::Regex, nlines = 1) for _ in 1:nlines content *= readline(io; keep = false) end + return end - occursin(regex, content) + return occursin(regex, content) end is_png_file(filename) = is_file_starting_with(filename, b"\x89PNG") is_pdf_file(filename) = is_file_starting_with(filename, b"%PDF") -is_tex_document(filename) = # may have a \Require in the first line +is_tex_document(filename) = # may have a \Require in the first line is_file_starting_with(filename, r"\\documentclass\[tikz\]{standalone}", 2) function is_tikz_standalone(filename) if !isfile(filename) return false end - s = read(filename,String) - m = match(r"^([^%].*$)"m,s) # First non-commented non-empty line + s = read(filename, String) + m = match(r"^([^%].*$)"m, s) # First non-commented non-empty line if nothing ≡ m return false end - return occursin(r"\\begin{tikzpicture}",m.captures[1]) + return occursin(r"\\begin{tikzpicture}", m.captures[1]) end is_svg_file(filename) = is_file_starting_with(filename, r"", 2) @@ -96,40 +97,44 @@ end end end -@testset "show(io, mime, plot)" begin; mktempdir() do dir; cd(dir) do - tmp = tempname() - io = IOBuffer() - a = Axis(Plot(Expression("x^2"))) - # pdf - let tmp = tmp * ".pdf", mime = MIME"application/pdf"() - show(io, mime, a) - write(tmp, take!(io)) - @test is_pdf_file(tmp) - rm(tmp; force=true) - end - # svg - let tmp = tmp * ".svg", mime = MIME"image/svg+xml"() - if PGFPlotsX.svg_engine() !== PGFPlotsX.NO_SVG_ENGINE - show(io, mime, a) - write(tmp, take!(io)) - @test is_svg_file(tmp) - rm(tmp; force=true) - else - @test_throws MethodError show(io, mime, a) - end - end - # png - let tmp = tmp * ".png", mime = MIME"image/png"() - if PGFPlotsX.png_engine() !== PGFPlotsX.NO_PNG_ENGINE - show(io, mime, a) - write(tmp, take!(io)) - @test is_png_file(tmp) - rm(tmp; force=true) - else - @test_throws MethodError show(io, mime, a) +@testset "show(io, mime, plot)" begin + mktempdir() do dir + cd(dir) do + tmp = tempname() + io = IOBuffer() + a = Axis(Plot(Expression("x^2"))) + # pdf + let tmp = tmp * ".pdf", mime = MIME"application/pdf"() + show(io, mime, a) + write(tmp, take!(io)) + @test is_pdf_file(tmp) + rm(tmp; force = true) + end + # svg + let tmp = tmp * ".svg", mime = MIME"image/svg+xml"() + if PGFPlotsX.svg_engine() !== PGFPlotsX.NO_SVG_ENGINE + show(io, mime, a) + write(tmp, take!(io)) + @test is_svg_file(tmp) + rm(tmp; force = true) + else + @test_throws MethodError show(io, mime, a) + end + end + # png + let tmp = tmp * ".png", mime = MIME"image/png"() + if PGFPlotsX.png_engine() !== PGFPlotsX.NO_PNG_ENGINE + show(io, mime, a) + write(tmp, take!(io)) + @test is_png_file(tmp) + rm(tmp; force = true) + else + @test_throws MethodError show(io, mime, a) + end + end end end -end end end +end @testset "gnuplot / shell-escape" begin if HAVE_GNUPLOT @@ -139,23 +144,26 @@ end end end cd(dir) do @pgf p = Axis( + { + colorbar, + xlabel = "x", + ylabel = "y", + domain = "1:2", + y_domain = "74:87.9", + view = (0, 90), + }, + Plot3( { - colorbar, - xlabel = "x", - ylabel = "y", - domain = "1:2", - y_domain = "74:87.9", - view = (0, 90), - }, - Plot3( - { - contour_gnuplot = { - number = 30, - labels = false}, - thick, - samples = 40, + contour_gnuplot = { + number = 30, + labels = false, }, - Expression(expr))) + thick, + samples = 40, + }, + Expression(expr) + ) + ) pgfsave(tmp_pdf, p) @test is_pdf_file(tmp_pdf) rm(tmp_pdf) @@ -168,14 +176,22 @@ end tmp_pdf = tempname() * ".pdf" mktempdir() do dir cd(dir) do - @pgf a = [Axis({legend_to_name = "named", + @pgf a = [ + Axis( + { + legend_to_name = "named", title = "k = $k", legend_columns = 2, - legend_entries = {"\$x^k\$", "\$(x + 1)^k\$"}}, - PlotInc(Expression("x^$k")), - PlotInc(Expression("(x + 1)^$k"))) - for k in 1:3] - p = TikzPicture("\\matrix{", a[1], "&", a[2], "&", a[3], raw"\\\\};", - raw"\node at (.5, -4.5) {\ref{named}};") + legend_entries = {"\$x^k\$", "\$(x + 1)^k\$"}, + }, + PlotInc(Expression("x^$k")), + PlotInc(Expression("(x + 1)^$k")) + ) + for k in 1:3 + ] + p = TikzPicture( + "\\matrix{", a[1], "&", a[2], "&", a[3], raw"\\\\};", + raw"\node at (.5, -4.5) {\ref{named}};" + ) pgfsave(tmp_pdf, p) @test is_pdf_file(tmp_pdf) rm(tmp_pdf) @@ -189,9 +205,11 @@ end cd(dir) do PGFPlotsX.CLASS_OPTIONS[1] = "varwidth" push!(PGFPlotsX.CLASS_OPTIONS, "crop = false") - td = TikzDocument("\\begin{tabular}{cc}", - TikzPicture(Axis(Plot(Expression("x^2")))), - "& A \\end{tabular}") + td = TikzDocument( + "\\begin{tabular}{cc}", + TikzPicture(Axis(Plot(Expression("x^2")))), + "& A \\end{tabular}" + ) pgfsave(tmp_pdf, td) @test is_pdf_file(tmp_pdf) rm(tmp_pdf) diff --git a/test/test_elements.jl b/test/test_elements.jl index ad6b7582..d04fdb42 100644 --- a/test/test_elements.jl +++ b/test/test_elements.jl @@ -11,20 +11,26 @@ end @testset "coordinate" begin # invalid coordinates - @test_throws ArgumentError PGFPlotsX.Coordinate((1, )) # dimension not 2 or 3 - @test_throws ArgumentError PGFPlotsX.Coordinate((1, 2); # can't specify both - error = (0, 0), errorplus = (0, 0)) - @test_throws MethodError Coordinates((1, 2); error = (3, )) # incompatible dims + @test_throws ArgumentError PGFPlotsX.Coordinate((1,)) # dimension not 2 or 3 + @test_throws ArgumentError PGFPlotsX.Coordinate( + (1, 2); # can't specify both + error = (0, 0), errorplus = (0, 0) + ) + @test_throws MethodError Coordinates((1, 2); error = (3,)) # incompatible dims # valid forms @test squashed_repr_tex(PGFPlotsX.Coordinate((1, 2))) == "(1,2)" # NOTE important not to have whitespace @test squashed_repr_tex(PGFPlotsX.Coordinate((1, 2); error = (3, 4))) == "(1,2) +- (3,4)" @test squashed_repr_tex(PGFPlotsX.Coordinate((1, 2); errorminus = (3, 4))) == "(1,2) -= (3,4)" - @test squashed_repr_tex(PGFPlotsX.Coordinate((1, 2); - errorminus = (3, 4), - errorplus = (5, 6))) == - "(1,2) += (5,6) -= (3,4)" + @test squashed_repr_tex( + PGFPlotsX.Coordinate( + (1, 2); + errorminus = (3, 4), + errorplus = (5, 6) + ) + ) == + "(1,2) += (5,6) -= (3,4)" @test squashed_repr_tex(PGFPlotsX.Coordinate((1, 2); meta = "blue")) == "(1,2) [blue]" @test squashed_repr_tex(PGFPlotsX.Coordinate((NaN, 1))) == "(NaN,1)" @test squashed_repr_tex(PGFPlotsX.Coordinate(("a fish", 1))) == "(a fish,1)" @@ -44,19 +50,21 @@ end # skip empty @test Coordinates([(2, 3), (), nothing]).data == [PGFPlotsX.Coordinate((2, 3)), nothing, nothing] - @test Coordinates(1:2, 3:4, (1:2)./((3:4)')).data == - Coordinates(Any[1, 2, NaN, 1, 2, NaN], - Any[3, 3, NaN, 4, 4, NaN], - Any[1/3, 2/3, NaN, 1/4, 2/4, NaN]).data + @test Coordinates(1:2, 3:4, (1:2) ./ ((3:4)')).data == + Coordinates( + Any[1, 2, NaN, 1, 2, NaN], + Any[3, 3, NaN, 4, 4, NaN], + Any[1 / 3, 2 / 3, NaN, 1 / 4, 2 / 4, NaN] + ).data # from iterables @test Coordinates(enumerate(3:4)).data == PGFPlotsX.Coordinate.([(1, 3), (2, 4)]) - @test Coordinates((x, 1/x) for x in -1:1).data == + @test Coordinates((x, 1 / x) for x in -1:1).data == [PGFPlotsX.Coordinate((-1, -1.0)), nothing, PGFPlotsX.Coordinate((1, 1.0))] let x = 1:3, y = -1:1, z = x ./ y @test Coordinates(x, y, z).data == - Coordinates((x, y, x / y) for (x,y) in zip(x, y)).data + Coordinates((x, y, x / y) for (x, y) in zip(x, y)).data end # from Measurements let x = [1.0 ± 0.1, 2.0 ± 0.2] @@ -70,8 +78,8 @@ end end # missing values - @test Coordinates([1,2], [3,missing]).data == Coordinates([(1,3), nothing]).data - @test Coordinates([(1,3), (2,missing)]).data == Coordinates([(1,3), nothing]).data + @test Coordinates([1, 2], [3, missing]).data == Coordinates([(1, 3), nothing]).data + @test Coordinates([(1, 3), (2, missing)]).data == Coordinates([(1, 3), nothing]).data # meta printing @test squashed_repr_tex(Coordinates([1], [1]; meta = [RGB(0.1, 0.2, 0.3)])) == @@ -80,10 +88,10 @@ end @testset "tables" begin # compare results to these using ≅, defined above - table_named_noopt = Table(hcat(1:10, 11:20); colnames=["a", "b"], scanlines=Int[]) - table_unnamed_noopt = Table(hcat(1:10, 11:20); colnames=nothing, scanlines=Int[]) - opt = @pgf { meaningless = "option" } - table_named_opt = Table(opt, hcat(1:10, 11:20); colnames=["a", "b"], scanlines=Int[]) + table_named_noopt = Table(hcat(1:10, 11:20); colnames = ["a", "b"], scanlines = Int[]) + table_unnamed_noopt = Table(hcat(1:10, 11:20); colnames = nothing, scanlines = Int[]) + opt = @pgf {meaningless = "option"} + table_named_opt = Table(opt, hcat(1:10, 11:20); colnames = ["a", "b"], scanlines = Int[]) # named columns, without options @test Table(:a => 1:10, :b => 11:20) ≅ table_named_noopt @@ -103,23 +111,31 @@ end # matrix and edges let x = randn(10), y = randn(5), z = cos.(x .+ y') - @test Table(x, y, z) ≅ Table(PGFPlotsX.Options(), - hcat(PGFPlotsX.matrix_xyz(x, y, z)...); - colnames=["x", "y", "z"], scanlines=10) + @test Table(x, y, z) ≅ Table( + PGFPlotsX.Options(), + hcat(PGFPlotsX.matrix_xyz(x, y, z)...); + colnames = ["x", "y", "z"], scanlines = 10 + ) end # dataframe @test Table(DataFrame(a = 1:5, b = 6:10)) ≅ - Table(PGFPlotsX.Options(), hcat(1:5, 6:10), colnames=["a", "b"], scanlines=0) + Table(PGFPlotsX.Options(), hcat(1:5, 6:10), colnames = ["a", "b"], scanlines = 0) # can't determine if it is named or unnamed @test_throws ArgumentError Table([1:10, :a => 11:20]) - @test squashed_repr_tex(Table(PGFPlotsX.Options(), - [1 NaN; - -Inf 4.0], - ["xx", "yy"], - [1])) == "table[row sep={\\\\}]\n{\nxx yy \\\\\n1.0 nan \\\\\n\\\\\n-inf 4.0 \\\\\n}" + @test squashed_repr_tex( + Table( + PGFPlotsX.Options(), + [ + 1 NaN; + -Inf 4.0 + ], + ["xx", "yy"], + [1] + ) + ) == "table[row sep={\\\\}]\n{\nxx yy \\\\\n1.0 nan \\\\\n\\\\\n-inf 4.0 \\\\\n}" end @testset "table file" begin @@ -144,8 +160,12 @@ end # printing incremental w/ options, 2D and 3D @test squashed_repr_tex(PlotInc(data2)) == "\\addplot+\ntable[row sep={\\\\}]\n{\nx y \\\\\n1 3 \\\\\n2 4 \\\\\n}\n;" - @test squashed_repr_tex(@pgf Plot3Inc({xtick = 1:3}, - Table(x = 1:2, y = 3:4, z = 5:6))) == + @test squashed_repr_tex( + @pgf Plot3Inc( + {xtick = 1:3}, + Table(x = 1:2, y = 3:4, z = 5:6) + ) + ) == "\\addplot3+[xtick={1,2,3}]\ntable[row sep={\\\\}]\n{\nx y z \\\\\n1 3 5 \\\\\n2 4 6 \\\\\n}\n;" end @@ -160,16 +180,16 @@ end @test repr_tex(Expression("x^2")) == "{x^2}" @test repr_tex(Expression(["x^2", "y^2"])) == "(\n{x^2},\n{y^2})" # graphics - @test repr_tex(@pgf Graphics({ testopt = 1}, "filename")) == + @test repr_tex(@pgf Graphics({testopt = 1}, "filename")) == "graphics[testopt={1}] {filename}\n" # coordinates, tables, and plot c = Coordinates([(1, 2), (3, 4)]) @test repr_tex(c) == "coordinates {\n (1,2)\n (3,4)\n}\n" t = Table(x = 1:2, y = 3:4) @test repr_tex(t) == "table[row sep={\\\\}]\n{\n x y \\\\\n 1 3 \\\\\n 2 4 \\\\\n}\n" - @test repr_tex(@pgf Plot({ no_marks }, c)) == + @test repr_tex(@pgf Plot({no_marks}, c)) == "\\addplot[no marks]\n coordinates {\n (1,2)\n (3,4)\n }\n ;\n" - @test repr_tex(@pgf Plot({ no_marks }, t, "trailing")) == + @test repr_tex(@pgf Plot({no_marks}, t, "trailing")) == "\\addplot[no marks]\n table[row sep={\\\\}]\n {\n x y \\\\\n" * " 1 3 \\\\\n 2 4 \\\\\n }\n trailing\n ;\n" # legend @@ -179,7 +199,7 @@ end l = LegendEntry("a") @test repr_tex(l) == "\\addlegendentry {a}\n" # axis - @test repr_tex(@pgf Axis({ optaxis }, Plot({ optplot }, c), l)) == + @test repr_tex(@pgf Axis({optaxis}, Plot({optplot}, c), l)) == "\\begin{axis}[optaxis]\n \\addplot[optplot]\n" * " coordinates {\n (1,2)\n (3,4)\n }\n" * " ;\n \\addlegendentry {a}\n\\end{axis}\n" @@ -224,21 +244,23 @@ end end @testset "colors" begin - @test squashed_repr_tex(@pgf { color = RGB(1e-10, 1, 1) }) == + @test squashed_repr_tex(@pgf {color = RGB(1.0e-10, 1, 1)}) == "[color={rgb,1:red,0.0;green,1.0;blue,1.0}]" - @test squashed_repr_tex(@pgf { color = HSV(1, 1e-10, 1) }) == + @test squashed_repr_tex(@pgf {color = HSV(1, 1.0e-10, 1)}) == "[color={rgb,1:red,1.0;green,1.0;blue,1.0}]" end @testset "Axis, SemiLogXAxis, SemiLogYAxis and LogLogAxis inside GroupPlot" begin - gp = @pgf GroupPlot({group_style={group_size="2 by 2"}}, - Axis(), SemiLogXAxis(), SemiLogYAxis(), LogLogAxis()) + gp = @pgf GroupPlot( + {group_style = {group_size = "2 by 2"}}, + Axis(), SemiLogXAxis(), SemiLogYAxis(), LogLogAxis() + ) @test repr_tex(gp) == """ - \\begin{groupplot}[group style={group size={2 by 2}}] - \\nextgroupplot - \\nextgroupplot[xmode=log,ymode=normal] - \\nextgroupplot[xmode=normal,ymode=log] - \\nextgroupplot[xmode=log,ymode=log] - \\end{groupplot} - """ + \\begin{groupplot}[group style={group size={2 by 2}}] + \\nextgroupplot + \\nextgroupplot[xmode=log,ymode=normal] + \\nextgroupplot[xmode=normal,ymode=log] + \\nextgroupplot[xmode=log,ymode=log] + \\end{groupplot} + """ end diff --git a/test/test_options.jl b/test/test_options.jl index deec80f7..77064ca0 100644 --- a/test/test_options.jl +++ b/test/test_options.jl @@ -1,8 +1,8 @@ # test that the @pfg macro is expanded correctly module TestModule -using PGFPlotsX: @pgf -testpgf() = @pgf { ymax = 1 } + using PGFPlotsX: @pgf + testpgf() = @pgf {ymax = 1} end @testset "pgf escape" begin @@ -14,56 +14,68 @@ end a = 1 b = 2 theme = @pgf {color = "white"} - opt = @pgf { xmax = a + b, title = "42", justkey, raw"rawstring", under_scores => 3, - "quoted spaces" => 5, theme... } + opt = @pgf { + xmax = a + b, title = "42", justkey, raw"rawstring", under_scores => 3, + "quoted spaces" => 5, theme..., + } @test opt["color"] == "white" @test opt["under scores"] == 3 @test opt["quoted spaces"] == 5 - @test repr_tex(opt) == repr_tex(Options("xmax" => 3, "title" => "42", - "justkey" => nothing, "rawstring" => nothing, - "under scores" => 3, "quoted spaces" => 5, - "color" => "white")) + @test repr_tex(opt) == repr_tex( + Options( + "xmax" => 3, "title" => "42", + "justkey" => nothing, "rawstring" => nothing, + "under scores" => 3, "quoted spaces" => 5, + "color" => "white" + ) + ) f(x...) = tuple(x...) - y = @pgf f({ look, we, are = f(1, 2, 3), nesting = { stuff = 9 }}) + y = @pgf f({look, we, are = f(1, 2, 3), nesting = {stuff = 9}}) @test length(y) == 1 - @test repr_tex(y[1]) == repr_tex(Options("look" => nothing, - "we" => nothing, - "are" => (1, 2, 3), - "nesting" => Options("stuff" => 9))) + @test repr_tex(y[1]) == repr_tex( + Options( + "look" => nothing, + "we" => nothing, + "are" => (1, 2, 3), + "nesting" => Options("stuff" => 9) + ) + ) end @testset "pgf empty" begin - @test squashed_repr_tex(@pgf Plot({}, Table("x" => [1,2,3]))) == + @test squashed_repr_tex(@pgf Plot({}, Table("x" => [1, 2, 3]))) == "\\addplot[]\ntable[row sep={\\\\}]\n{\nx \\\\\n1 \\\\\n2 \\\\\n3 \\\\\n}\n;" # note [] end @testset "nested options vector" begin - cycle_list = [@pgf({ color = RGB(1, 1, 1), mark = "+"}), - @pgf({ color = RGB(1, 0, 1), mark = "o"})] - opt = @pgf { cycle_list = cycle_list } + cycle_list = [ + @pgf({color = RGB(1, 1, 1), mark = "+"}), + @pgf({color = RGB(1, 0, 1), mark = "o"}), + ] + opt = @pgf {cycle_list = cycle_list} @test repr_tex(opt) == "[cycle list={color={rgb,1:red,1.0;green,1.0;blue,1.0}, mark={+},color={rgb,1:red,1.0;green,0.0;blue,1.0}, mark={o}}] " end @testset "operations on options" begin - O1 = @pgf { a = 1 } + O1 = @pgf {a = 1} # copy O2 = copy(O1) @test O1 ≅ O2 # merge - @test merge(O1, @pgf { b = 2 }) ≅ @pgf { a = 1, b = 2 } - O3 = @pgf { a = 1, b = 2, c = 3 } - @test merge(O1, @pgf({ b = 2 }), @pgf({ c = 3 })) ≅ O3 + @test merge(O1, @pgf {b = 2}) ≅ @pgf {a = 1, b = 2} + O3 = @pgf {a = 1, b = 2, c = 3} + @test merge(O1, @pgf({b = 2}), @pgf({c = 3})) ≅ O3 # merge! - @test merge!(O1, @pgf({ b = 2 }), @pgf({ c = 3 })) ≡ O1 + @test merge!(O1, @pgf({b = 2}), @pgf({c = 3})) ≡ O1 @test O1 ≅ O3 # merge! for OptionType - P = Plot(O2, Table([1], [1])); # don't print, nonsensical - @test merge!(P, @pgf({ b = 2 }), @pgf({ c = 3 })) ≡ P + P = Plot(O2, Table([1], [1])) # don't print, nonsensical + @test merge!(P, @pgf({b = 2}), @pgf({c = 3})) ≡ P @test P.options ≅ O3 end diff --git a/test/utilities.jl b/test/utilities.jl index fae009b7..10feae58 100644 --- a/test/utilities.jl +++ b/test/utilities.jl @@ -12,7 +12,7 @@ Useful for unit testing printed representations. function squash_whitespace(str::AbstractString) lines = split(str, '\n') squashed_lines = map(line -> replace(strip(line), r" +" => " "), lines) - strip(replace(join(squashed_lines, "\n"), r"\n{2,}" => "\n\n"), '\n') + return strip(replace(join(squashed_lines, "\n"), r"\n{2,}" => "\n\n"), '\n') end @test squash_whitespace("\n\n a line \nsome other line\n\n\ndone\n") == @@ -24,10 +24,14 @@ squashed_repr_tex(args...) = squash_whitespace(repr_tex(args...)) "A simple comparison of fields for unit tests." ≅(x, y) = x == y -function ≅(x::T, y::T) where T <: Union{PGFPlotsX.Coordinate, Coordinates, - Table, TableData, Plot, Options} +function ≅(x::T, y::T) where { + T <: Union{ + PGFPlotsX.Coordinate, Coordinates, + Table, TableData, Plot, Options, + }, + } for f in fieldnames(T) getfield(x, f) ≅ getfield(y, f) || return false end - true + return true end From a0488cc78d768e6d118fe444000d1475f0c41661 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Fri, 18 Oct 2024 13:47:05 +0200 Subject: [PATCH 2/4] get rid of some implicit returns that now had a bit of a weird `return` added to them --- ext/ColorsExt.jl | 12 ++++++++---- src/PGFPlotsX.jl | 3 ++- src/axiselements.jl | 21 ++++++++++++++------- src/axislike.jl | 3 ++- src/tikzdocument.jl | 24 ++++++++++++++++-------- src/utilities.jl | 9 ++++++--- 6 files changed, 48 insertions(+), 24 deletions(-) diff --git a/ext/ColorsExt.jl b/ext/ColorsExt.jl index 5d74f62a..fbbca874 100644 --- a/ext/ColorsExt.jl +++ b/ext/ColorsExt.jl @@ -12,12 +12,13 @@ end function PGFPlotsX.print_opt(io::IO, c::Colors.Colorant) rgb_64 = _rgb_for_printing(c) - return print( + print( io, "rgb,1:", "red,", rgb_64[1], ";", "green,", rgb_64[2], ";", "blue,", rgb_64[3] ) + return end # For printing surface plots with explicit color, pgfplots manual 4.6.7. @@ -25,13 +26,15 @@ end # we should introduce a wrapper type. function PGFPlotsX.print_tex(io::IO, c::Colors.Colorant) rgb_64 = _rgb_for_printing(c) - return print(io, "rgb=", rgb_64[1], ",", rgb_64[2], ",", rgb_64[3]) + print(io, "rgb=", rgb_64[1], ",", rgb_64[2], ",", rgb_64[3]) + return end function PGFPlotsX.print_tex(io::IO, c::Tuple{String, Colors.Colorant}, ::Any) name, color = c rgb_64 = _rgb_for_printing(color) - return print(io, "\\definecolor{$name}{rgb}{$(rgb_64[1]), $(rgb_64[2]), $(rgb_64[3])}") + print(io, "\\definecolor{$name}{rgb}{$(rgb_64[1]), $(rgb_64[2]), $(rgb_64[3])}") + return end function PGFPlotsX.print_tex( @@ -45,7 +48,8 @@ function PGFPlotsX.print_tex( rgb_64 = _rgb_for_printing(col) println(io, "rgb=(", join(rgb_64, ","), ")") end - return println(io, "}}") + println(io, "}}") + return end end diff --git a/src/PGFPlotsX.jl b/src/PGFPlotsX.jl index 34f2eba8..090f076c 100644 --- a/src/PGFPlotsX.jl +++ b/src/PGFPlotsX.jl @@ -79,7 +79,7 @@ print_tex(io::IO, vector::AbstractVector) = foreach(elt -> print_tex(io, elt), v Real numbers are printed as is, except for non-finite representation. """ function print_tex(io::IO, x::Real) - return if isfinite(x) + if isfinite(x) print(io, x) elseif isnan(x) print(io, "nan") @@ -89,6 +89,7 @@ function print_tex(io::IO, x::Real) else throw(ArgumentError("Don't know how to print $x for LaTeX.")) end + return end print_tex(io::IO, ::Missing) = print(io, "nan") diff --git a/src/axiselements.jl b/src/axiselements.jl index 4c3533dc..8fefe6ad 100644 --- a/src/axiselements.jl +++ b/src/axiselements.jl @@ -111,7 +111,8 @@ function print_tex(io::IO, data::NTuple{N, CoordinateType}, ::Coordinate) where i == 1 || print(io, ",") print(io, x) end - return print(io, ")") + print(io, ")") + return end # Print raw strings inside coordinates. Compared to generic `print_tex`, print no newline, @@ -122,10 +123,11 @@ function print_tex(io::IO, coordinate::Coordinate) @unpack data, error, errorplus, errorminus, meta = coordinate print_tex(io, data, coordinate) function _print_error(prefix, error) - return if error ≠ nothing + if error ≠ nothing print(io, " $(prefix) ") print_tex(io, error, coordinate) end + return end _print_error("+-", error) _print_error("+=", errorplus) @@ -135,7 +137,8 @@ function print_tex(io::IO, coordinate::Coordinate) print_tex(io, meta, coordinate) print(io, "]") end - return println(io) + println(io) + return end struct Coordinates{N} @@ -318,7 +321,8 @@ function print_tex(io::IO, coordinates::Coordinates) end return end - return println(io, "}") + println(io, "}") + return end ######### @@ -542,7 +546,7 @@ function print_tex(io::IO, table::Table) @unpack options, content = table all_options = merge(container_options(content, table), options) print(io, "table") - return if content isa String + if content isa String print_options(io, all_options, newline = false) print(io, "{") print(io, content) @@ -553,6 +557,7 @@ function print_tex(io::IO, table::Table) print_indent(io, content) println(io, "}") end + return end ############ @@ -576,7 +581,8 @@ end function print_tex(io::IO, t::Graphics) print(io, "graphics") print_options(io, t.options; newline = false) - return println(io, "{", t.filename, "}") + println(io, "{", t.filename, "}") + return end ######## @@ -682,7 +688,8 @@ function print_tex(io::IO, plot::Plot) for t in trailing print_tex(io, t) end - return println(io, ";") + println(io, ";") + return end return end diff --git a/src/axislike.jl b/src/axislike.jl index f66a5fa6..9453b04f 100644 --- a/src/axislike.jl +++ b/src/axislike.jl @@ -39,7 +39,8 @@ function print_tex(io::IO, axislike::T) where {T <: AxisLike} end return end - return println(io, "\\end{", name, "}") + println(io, "\\end{", name, "}") + return end function save(filename::AbstractString, axislike::AxisLike; kwargs...) = diff --git a/src/tikzdocument.jl b/src/tikzdocument.jl index 3ec2a671..57c66153 100644 --- a/src/tikzdocument.jl +++ b/src/tikzdocument.jl @@ -51,7 +51,8 @@ end MissingExternalProgramError(strs...) = MissingExternalProgramError(join(strs)) function Base.showerror(io::IO, e::MissingExternalProgramError) - return print(io, e.str) + print(io, e.str) + return end """ @@ -157,9 +158,10 @@ function print_tex(io::IO, td::TikzDocument; include_preamble::Bool = true) for element in td.elements print_tex(io, element, td) end - return if include_preamble + if include_preamble println(io, "\\end{document}") end + return end _HAS_WARNED_SHELL_ESCAPE = false @@ -233,7 +235,8 @@ function savepdf( return end rm_tmpfiles(tmp_tex) - return mv(tmp_pdf, filename; force = true) + mv(tmp_pdf, filename; force = true) + return end const _SHOWABLE = Union{Plot, AbstractVector{Plot}, AxisLike, TikzDocument, TikzPicture} @@ -242,7 +245,8 @@ function Base.show(io::IO, ::MIME"application/pdf", p::_SHOWABLE) filename = tempname() * ".pdf" save(filename, p; showing_ide = _is_ide()) write(io, read(filename)) - return rm(filename; force = true) + rm(filename; force = true) + return end # Copyright TikzPictures.jl (see LICENSE.md) @@ -300,11 +304,12 @@ function savesvg( Ijulia_cache[[1, 2]] = [hsh, tmp_ijulia_pdf] end convert_pdf_to_svg(tmp_pdf, filename) - return if keep_pdf + if keep_pdf mv(tmp_pdf, _replace_fileext(filename, ".pdf"); force = true) else rm(tmp_pdf) end + return end Base.showable(::MIME"image/svg+xml", td::_SHOWABLE) = svg_engine() !== NO_SVG_ENGINE @@ -330,7 +335,8 @@ function Base.show(f::IO, ::MIME"image/svg+xml", td::_SHOWABLE) s = replace(s, "image id=\"" => "image style=\"image-rendering: pixelated;\" id=\"") _tikzid += 1 println(f, s) - return rm(filename; force = true) + rm(filename; force = true) + return end function savepng( @@ -368,7 +374,8 @@ function Base.show(io::IO, ::MIME"image/png", p::_SHOWABLE) global showing_Ijulia = false end write(io, read(filename)) - return rm(filename; force = true) + rm(filename; force = true) + return end _DISPLAY_PDF = true enable_interactive(v::Bool) = global _DISPLAY_PDF = v @@ -377,7 +384,7 @@ _is_vscode() = isdefined(Main, :_vscodeserver) || (isdefined(Main, :VSCodeServer _is_ide() = _is_ijulia() || _is_vscode() function Base.display(d::PGFPlotsXDisplay, p::_SHOWABLE) - return if _DISPLAY_PDF + if _DISPLAY_PDF filename = tempname() .* ".pdf" save(filename, p) try @@ -388,4 +395,5 @@ function Base.display(d::PGFPlotsXDisplay, p::_SHOWABLE) else throw(MethodError(display, (d, p))) end + return end diff --git a/src/utilities.jl b/src/utilities.jl index d0ac3bb7..92a40493 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -27,7 +27,8 @@ indented with four spaces. function print_indent(f, io_main::IO) io = IOBuffer() f(io) - return print(io_main, add_indent(String(take!(io)))) + print(io_main, add_indent(String(take!(io)))) + return end """ @@ -37,9 +38,11 @@ Print `elt` to `io` with indentation. Shortcut for the function wrapper of `print_indent` for a single element. """ function print_indent(io_main::IO, elt) - return print_indent(io_main) do io - return print_tex(io, elt) + print_indent(io_main) do io + print_tex(io, elt) + return end + return end """ From caf5ca84272a07c50e2951cfd38c64671bb25eb7 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Fri, 18 Oct 2024 13:52:39 +0200 Subject: [PATCH 3/4] fixup --- src/axiselements.jl | 5 ++--- src/axislike.jl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/axiselements.jl b/src/axiselements.jl index 8fefe6ad..11391e9d 100644 --- a/src/axiselements.jl +++ b/src/axiselements.jl @@ -673,9 +673,8 @@ Plot3Inc(options::Options, data::PlotData, trailing...) = Plot3Inc(data::PlotData, trailing...) = Plot(true, true, Options(), data, trailing) -function save(filename::AbstractString, plot::Plot; kwargs...) - return save(filename, Axis(plot); kwargs...) -end +save(filename::AbstractString, plot::Plot; kwargs...) = + save(filename, Axis(plot); kwargs...) function print_tex(io::IO, plot::Plot) @unpack is3d, incremental, options, data, trailing = plot diff --git a/src/axislike.jl b/src/axislike.jl index 9453b04f..f42340a2 100644 --- a/src/axislike.jl +++ b/src/axislike.jl @@ -43,7 +43,7 @@ function print_tex(io::IO, axislike::T) where {T <: AxisLike} return end -function save(filename::AbstractString, axislike::AxisLike; kwargs...) = +save(filename::AbstractString, axislike::AxisLike; kwargs...) = save(filename, TikzPicture(axislike); kwargs...) macro define_axislike(name, latex_environment) From 05934143789d2da5a3069f767beab9535050f4d7 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Fri, 18 Oct 2024 15:16:13 +0200 Subject: [PATCH 4/4] Update runic.yml --- .github/workflows/runic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/runic.yml b/.github/workflows/runic.yml index fe9afc38..0e4a2997 100644 --- a/.github/workflows/runic.yml +++ b/.github/workflows/runic.yml @@ -19,4 +19,4 @@ jobs: # - uses: julia-actions/cache@v2 - uses: fredrikekre/runic-action@v1 with: - version: '1.0.0' + version: '1'