From 993633886a2915778c0f7a2b0eda25c2cfd0df11 Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 09:52:09 +0200 Subject: [PATCH 1/7] Test --- src/Gnuplot.jl | 74 +++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Gnuplot.jl b/src/Gnuplot.jl index fa921c9..b0f4f23 100644 --- a/src/Gnuplot.jl +++ b/src/Gnuplot.jl @@ -216,11 +216,11 @@ Base.@kwdef mutable struct Options default::Symbol = :default term::String = "" mime::Dict{DataType, String} = Dict( - MIME"image/svg+xml" => "svg background rgb 'white' dynamic", - MIME"image/png" => "pngcairo", - MIME"image/jpeg" => "jpeg", - MIME"application/pdf" => "pdfcairo", - MIME"text/html" => "canvas mousing", + MIME"image/svg+xml" => "svg enhanced background rgb 'white' dynamic", + MIME"image/png" => "pngcairo enhanced", + MIME"image/jpeg" => "jpeg enhanced", + MIME"application/pdf" => "pdfcairo enhanced", + MIME"text/html" => "svg enhanced dynamic", # canvas mousing MIME"text/plain" => "dumb") init::Vector{String} = Vector{String}() verbose::Bool = false @@ -447,38 +447,38 @@ pagerTokens() = ["Press return for more:"] function GPSession(sid::Symbol) function readTask(sid, stream, channel) - function gpreadline(stream) - line = "" - while true - c = read(stream, Char) - (c == '\r') && continue - (c == '\n') && break - if c == Char(0x1b) # sixel - buf = Vector{UInt8}() - push!(buf, UInt8(c)) - while true - c = read(stream, Char) - push!(buf, UInt8(c)) - (c == Char(0x1b)) && break - end - c = read(stream, Char) - push!(buf, UInt8(c)) - write(stdout, buf) - continue - end - line *= c - for token in pagerTokens() # handle pager interaction - if (length(line) == length(token)) && (line == token) - return line - end - end - end - return line - end + # function gpreadline(stream) + # line = "" + # while true + # c = read(stream, Char) + # (c == '\r') && continue + # (c == '\n') && break + # if c == Char(0x1b) # sixel + # buf = Vector{UInt8}() + # push!(buf, UInt8(c)) + # while true + # c = read(stream, Char) + # push!(buf, UInt8(c)) + # (c == Char(0x1b)) && break + # end + # c = read(stream, Char) + # push!(buf, UInt8(c)) + # write(stdout, buf) + # continue + # end + # line *= c + # for token in pagerTokens() # handle pager interaction + # if (length(line) == length(token)) && (line == token) + # return line + # end + # end + # end + # return line + # end saveOutput = false while isopen(stream) - line = gpreadline(stream) + line = readline(stream) if line == "GNUPLOT_CAPTURE_BEGIN" saveOutput = true elseif line == "GNUPLOT_CAPTURE_END" @@ -512,7 +512,7 @@ function GPSession(sid::Symbol) pin = Base.Pipe() pout = Base.Pipe() perr = Base.Pipe() - proc = run(pipeline(`$(options.cmd)`, stdin=pin, stdout=pout, stderr=perr), wait=false) + proc = run(pipeline(`$(options.cmd)`, stdin=pin, stdout=stdout, stderr=perr), wait=false) chan = Channel{String}(32) # Close unused sides of the pipes @@ -523,7 +523,7 @@ function GPSession(sid::Symbol) Base.start_reading(perr.out) # Start reading tasks - @async readTask(sid, pout, chan) + #@async readTask(sid, pout, chan, :out) @async readTask(sid, perr, chan) out = GPSession(getfield.(Ref(session), fieldnames(DrySession))..., @@ -934,7 +934,7 @@ function execall(gp::GPSession; term::AbstractString="", output::AbstractString= gpexec(gp, s) end end - (length(gp.plots) > 1) && gpexec(gp, "unset multiplot") + gpexec(gp, "unset multiplot") (output != "") && gpexec(gp, "set output") if term != "" gpexec(gp, "set term $former_term $former_opts") From 00ef33a8a62b0126caeefa3eefaf0449ceb25734 Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 14:26:06 +0200 Subject: [PATCH 2/7] Stdout is no longer filtered --- src/Gnuplot.jl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Gnuplot.jl b/src/Gnuplot.jl index b0f4f23..d5a8104 100644 --- a/src/Gnuplot.jl +++ b/src/Gnuplot.jl @@ -184,7 +184,6 @@ mutable struct GPSession <: Session plots::Vector{SinglePlot} # commands and plot commands (one entry for each plot of the multiplot) curmid::Int # current multiplot ID pin::Base.Pipe; - pout::Base.Pipe; perr::Base.Pipe; proc::Base.Process; channel::Channel{String}; @@ -510,24 +509,20 @@ function GPSession(sid::Symbol) end pin = Base.Pipe() - pout = Base.Pipe() perr = Base.Pipe() proc = run(pipeline(`$(options.cmd)`, stdin=pin, stdout=stdout, stderr=perr), wait=false) chan = Channel{String}(32) # Close unused sides of the pipes - Base.close(pout.in) Base.close(perr.in) Base.close(pin.out) - Base.start_reading(pout.out) Base.start_reading(perr.out) # Start reading tasks - #@async readTask(sid, pout, chan, :out) @async readTask(sid, perr, chan) out = GPSession(getfield.(Ref(session), fieldnames(DrySession))..., - pin, pout, perr, proc, chan) + pin, perr, proc, chan) sessions[sid] = out return out @@ -867,7 +862,6 @@ end function quit(gp::GPSession) close(gp.pin) - close(gp.pout) close(gp.perr) wait( gp.proc) exitCode = gp.proc.exitcode From e687bb3716fddf6c8605db0c408c7f33a3c28860 Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 14:26:53 +0200 Subject: [PATCH 3/7] Stdout is no longer filtered --- src/Gnuplot.jl | 56 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Gnuplot.jl b/src/Gnuplot.jl index d5a8104..c2797fe 100644 --- a/src/Gnuplot.jl +++ b/src/Gnuplot.jl @@ -446,34 +446,34 @@ pagerTokens() = ["Press return for more:"] function GPSession(sid::Symbol) function readTask(sid, stream, channel) - # function gpreadline(stream) - # line = "" - # while true - # c = read(stream, Char) - # (c == '\r') && continue - # (c == '\n') && break - # if c == Char(0x1b) # sixel - # buf = Vector{UInt8}() - # push!(buf, UInt8(c)) - # while true - # c = read(stream, Char) - # push!(buf, UInt8(c)) - # (c == Char(0x1b)) && break - # end - # c = read(stream, Char) - # push!(buf, UInt8(c)) - # write(stdout, buf) - # continue - # end - # line *= c - # for token in pagerTokens() # handle pager interaction - # if (length(line) == length(token)) && (line == token) - # return line - # end - # end - # end - # return line - # end + function gpreadline(stream) + line = "" + while true + c = read(stream, Char) + (c == '\r') && continue + (c == '\n') && break + if c == Char(0x1b) # sixel + buf = Vector{UInt8}() + push!(buf, UInt8(c)) + while true + c = read(stream, Char) + push!(buf, UInt8(c)) + (c == Char(0x1b)) && break + end + c = read(stream, Char) + push!(buf, UInt8(c)) + write(stdout, buf) + continue + end + line *= c + for token in pagerTokens() # handle pager interaction + if (length(line) == length(token)) && (line == token) + return line + end + end + end + return line + end saveOutput = false while isopen(stream) From 8a8ce1f53318bcfbd89fe56b445a3756e5e7b90e Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 14:39:52 +0200 Subject: [PATCH 4/7] Stdout is no longer filtered --- src/Gnuplot.jl | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/Gnuplot.jl b/src/Gnuplot.jl index c2797fe..6c13356 100644 --- a/src/Gnuplot.jl +++ b/src/Gnuplot.jl @@ -452,19 +452,6 @@ function GPSession(sid::Symbol) c = read(stream, Char) (c == '\r') && continue (c == '\n') && break - if c == Char(0x1b) # sixel - buf = Vector{UInt8}() - push!(buf, UInt8(c)) - while true - c = read(stream, Char) - push!(buf, UInt8(c)) - (c == Char(0x1b)) && break - end - c = read(stream, Char) - push!(buf, UInt8(c)) - write(stdout, buf) - continue - end line *= c for token in pagerTokens() # handle pager interaction if (length(line) == length(token)) && (line == token) @@ -477,7 +464,7 @@ function GPSession(sid::Symbol) saveOutput = false while isopen(stream) - line = readline(stream) + line = gpreadline(stream) if line == "GNUPLOT_CAPTURE_BEGIN" saveOutput = true elseif line == "GNUPLOT_CAPTURE_END" From a47705be6befc1d854e0581ef692230d0c55c8d3 Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 14:46:11 +0200 Subject: [PATCH 5/7] Test updated --- test/runtests.jl | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 0ef5733..3ed3239 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,16 +1,15 @@ using Test, Gnuplot try - @info "Gnuplot version: " * string(Gnuplot.gpversion()) + @info "Gnuplot.jl version: " * string(Gnuplot.version()) + @info "gnuplot version: " * string(Gnuplot.gpversion()) catch Gnuplot.options.dry = true end -Gnuplot.options.term = "unknown" x = [1, 2, 3] y = [4, 5, 6] - s = Gnuplot.arrays2datablock(x) @test all(s .== [" 1" , " 2" , @@ -90,10 +89,32 @@ s = Gnuplot.arrays2datablock(1:3, 1:3, ["One", "Two", "Three"]) #----------------------------------------------------------------- +dummy = palette_names() pal = palette(:deepsea) @test pal == "set palette defined (0.0 '#2B004D', 0.25 '#4E0F99', 0.5 '#3C54D4', 0.75 '#48A9F8', 1.0 '#C5ECFF')\nset palette maxcol 5\n" -ls = linetypes(:Set1_5) -@test ls == "unset for [i=1:256] linetype i\nset linetype 1 lc rgb '#E41A1C' lw 1 dt solid pt 1 ps 1\nset linetype 2 lc rgb '#377EB8' lw 1 dt solid pt 2 ps 1\nset linetype 3 lc rgb '#4DAF4A' lw 1 dt solid pt 3 ps 1\nset linetype 4 lc rgb '#984EA3' lw 1 dt solid pt 4 ps 1\nset linetype 5 lc rgb '#FF7F00' lw 1 dt solid pt 5 ps 1\nset linetype cycle 5\n" +ls = linetypes(:Set1_5, lw=1.5, ps=2) +@test ls == "unset for [i=1:256] linetype i\nset linetype 1 lc rgb '#E41A1C' lw 1.5 dt solid pt 1 ps 2\nset linetype 2 lc rgb '#377EB8' lw 1.5 dt solid pt 2 ps 2\nset linetype 3 lc rgb '#4DAF4A' lw 1.5 dt solid pt 3 ps 2\nset linetype 4 lc rgb '#984EA3' lw 1.5 dt solid pt 4 ps 2\nset linetype 5 lc rgb '#FF7F00' lw 1.5 dt solid pt 5 ps 2\nset linetype cycle 5\n" + +dummy = terminals() +if "sixelgd" in terminals() + Gnuplot.options.term = "sixelgd enhanced" +elseif "sixel" in terminals() + Gnuplot.options.term = "sixel enhanced" +elseif "dumb" in terminals() + Gnuplot.options.term = "dumb enhanced ansi" +else + Gnuplot.options.term = "unknown" +end +Gnuplot.quitall() +@gp 1:9 +@info "using terminal: " terminal() + +test_terminal() +test_terminal("dumb") +try + test_terminal("sixelgd") +catch +end #----------------------------------------------------------------- # Test wth empty dataset @@ -247,8 +268,19 @@ Gnuplot.quitall() "splot x9, v, (u<0.5) ? -1 : sinc(x9,v) notitle") + +x = randn(5000); +y = randn(5000); +h = hist(x, y, nbins1=20, nbins2=20); +clines = contourlines(h, "levels discrete 15, 30, 45"); +@gp clines +@gp "set size ratio -1" +for i in 1:length(clines) + @gp :- clines[i].data "w l t '$(clines[i].z)' lw $i dt $i" +end + + Gnuplot.options.verbose = true -# Gnuplot.options.term = "sixel" not vailable in Travis CI @gp randn(10^6) randn(10^6) @gp :- 0. 0. Gnuplot.quit(:default) @@ -256,6 +288,4 @@ Gnuplot.quit(:default) Gnuplot.options.dry = true @gp hist(randn(1000)) -t = terminals() - Gnuplot.quitall() From deee2693dfb8ac327401a372e76f26daa2a63af6 Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 14:46:29 +0200 Subject: [PATCH 6/7] Disable show mechanism --- docs/make.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/make.jl b/docs/make.jl index 85e0141..8825f02 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,4 +1,5 @@ using Documenter, Gnuplot +empty!(Gnuplot.options.mime) makedocs(sitename="Gnuplot.jl", authors = "Giorgio Calderone", From 8f737205a1d4f5ccd5253282f0ece98755893fd9 Mon Sep 17 00:00:00 2001 From: Giorgio Calderone Date: Wed, 22 Apr 2020 17:56:50 +0200 Subject: [PATCH 7/7] Improved readTask and capture protocol --- src/Gnuplot.jl | 104 +++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/src/Gnuplot.jl b/src/Gnuplot.jl index 6c13356..b9894fd 100644 --- a/src/Gnuplot.jl +++ b/src/Gnuplot.jl @@ -220,7 +220,7 @@ Base.@kwdef mutable struct Options MIME"image/jpeg" => "jpeg enhanced", MIME"application/pdf" => "pdfcairo enhanced", MIME"text/html" => "svg enhanced dynamic", # canvas mousing - MIME"text/plain" => "dumb") + MIME"text/plain" => "dumb enhanced ansi") init::Vector{String} = Vector{String}() verbose::Bool = false preferred_format::Symbol = :auto @@ -442,47 +442,71 @@ end # --------------------------------------------------------------------- -pagerTokens() = ["Press return for more:"] -function GPSession(sid::Symbol) - function readTask(sid, stream, channel) - function gpreadline(stream) - line = "" - while true - c = read(stream, Char) - (c == '\r') && continue - (c == '\n') && break - line *= c - for token in pagerTokens() # handle pager interaction - if (length(line) == length(token)) && (line == token) - return line - end +function readTask(gp::GPSession) + pagerTokens() = ["Press return for more:"] + + repeatID = 0 + function gpreadline() + line = "" + while true + c = read(gp.perr, Char) + (c == '\r') && continue + (c == '\n') && break + line *= c + for token in pagerTokens() # handle pager interaction + if (length(line) == length(token)) && (line == token) + # GNUPLOT_CAPTURE_END maybe lost when pager is + # running: send it again. + repeatID += 1 + write(gp.pin, "\nprint 'GNUPLOT_CAPTURE_END $repeatID'\n") + line = "" end end - return line end + if line == "GNUPLOT_CAPTURE_BEGIN" + repeatID += 1 + write(gp.pin, "\nprint 'GNUPLOT_CAPTURE_END $repeatID'\n") + end + return line + end + try saveOutput = false - while isopen(stream) - line = gpreadline(stream) + while isopen(gp.perr) + line = gpreadline() if line == "GNUPLOT_CAPTURE_BEGIN" saveOutput = true - elseif line == "GNUPLOT_CAPTURE_END" - put!(channel, line) + elseif line == "GNUPLOT_CAPTURE_END $repeatID" saveOutput = false + put!(gp.channel, "GNUPLOT_CAPTURE_END") + elseif !isnothing(findfirst("GNUPLOT_CAPTURE_END", line)) + continue # old GNUPLOT_CAPTURE_END, ignore it else if line != "" if options.verbose || !saveOutput - printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n") + printstyled(color=:cyan, "GNUPLOT ($(gp.sid)) -> $line\n") end end - (saveOutput) && (put!(channel, line)) + (saveOutput) && (put!(gp.channel, line)) end end - delete!(sessions, sid) - return nothing + catch err + if isopen(gp.perr) + @error "Error occurred in readTask for session $(gp.sid)" + @show(err) + else + put!(gp.channel, "GNUPLOT_CAPTURE_END") + end end + if options.verbose + printstyled(color=:red, "GNUPLOT ($(gp.sid)) Process terminated\n") + end + delete!(sessions, gp.sid) +end + +function GPSession(sid::Symbol) session = DrySession(sid) if !options.dry try @@ -505,13 +529,13 @@ function GPSession(sid::Symbol) Base.close(pin.out) Base.start_reading(perr.out) - # Start reading tasks - @async readTask(sid, perr, chan) - out = GPSession(getfield.(Ref(session), fieldnames(DrySession))..., pin, perr, proc, chan) sessions[sid] = out + # Start reading tasks + @async readTask(out) + return out end @@ -596,33 +620,11 @@ function writeread(gp::GPSession, str::AbstractString) options.verbose = verbose write(gp, str) - options.verbose = false - write(gp, "print 'GNUPLOT_CAPTURE_END'") - options.verbose = verbose - out = Vector{String}() while true l = take!(gp.channel) - if l in pagerTokens() - # Consume all data from the pager - while true - write(gp, "") - sleep(0.5) - if isready(gp.channel) - while isready(gp.channel) - push!(out, take!(gp.channel)) - end - else - options.verbose = false - write(gp, "print 'GNUPLOT_CAPTURE_END'") - options.verbose = verbose - break - end - end - else - l == "GNUPLOT_CAPTURE_END" && break - push!(out, l) - end + l == "GNUPLOT_CAPTURE_END" && break + push!(out, l) end return out end