First attempt

This commit is contained in:
Giorgio Calderone 2020-03-16 19:26:14 +01:00
parent 622ef39837
commit 3283f54741
2 changed files with 341 additions and 451 deletions

View File

@ -3,26 +3,24 @@ module Gnuplot
using StructC14N, ColorTypes, Printf, StatsBase, ReusePatterns, DataFrames
import Base.reset
import Base.println
import Base.write
import Base.iterate
import Base.convert
export gnuplot, quit, quitall, setverbose,
@gp, @gsp, exec, save, contourlines, hist
export @gp, @gsp, save, contourlines, hist
# ╭───────────────────────────────────────────────────────────────────╮
# │ TYPE DEFINITIONS │
# ╰───────────────────────────────────────────────────────────────────╯
#_____________________________________________________________________
# TYPE DEFINITIONS
#_____________________________________________________________________
# --------------------------------------------------------------------
# ---------------------------------------------------------------------
mutable struct DataSet
name::String
lines::Vector{String}
end
# --------------------------------------------------------------------
# ---------------------------------------------------------------------
mutable struct SinglePlot
cmds::Vector{String}
elems::Vector{String}
@ -31,7 +29,7 @@ mutable struct SinglePlot
end
# --------------------------------------------------------------------
# ---------------------------------------------------------------------
@quasiabstract mutable struct DrySession
sid::Symbol # session ID
datas::Vector{DataSet} # data sets
@ -40,8 +38,8 @@ end
end
# --------------------------------------------------------------------
@quasiabstract mutable struct Session <: DrySession
# ---------------------------------------------------------------------
@quasiabstract mutable struct GPSession <: DrySession
pin::Base.Pipe;
pout::Base.Pipe;
perr::Base.Pipe;
@ -50,27 +48,25 @@ end
end
# --------------------------------------------------------------------
# ---------------------------------------------------------------------
mutable struct State
sessions::Dict{Symbol, DrySession};
dry::Bool
cmd::String
default::Symbol; # default session name
initcmd::Vector{String} # Commands to initialize the gnuplot session (e.g., to set default terminal)
init::Vector{String} # Commands to initialize the gnuplot session (e.g., to set default terminal)
verbose::Bool; # verbosity level (true/false)
silent::Bool; # Silent flag
printlines::Int; # How many data lines are printed in log
State() = new(Dict{Symbol, DrySession}(), true, "gnuplot", :default, Vector{String}(), false, false, 4)
State() = new(Dict{Symbol, DrySession}(), true, "gnuplot", :default, Vector{String}(), false, 4)
end
const state = State()
state.dry = false
#_____________________________________________________________________
# "PRIVATE" (NON-EXPORTED) FUNCTIONS
#_____________________________________________________________________
# --------------------------------------------------------------------
# ╭───────────────────────────────────────────────────────────────────╮
# │ LOW LEVEL FUNCTIONS │
# ╰───────────────────────────────────────────────────────────────────╯
# ---------------------------------------------------------------------
"""
# CheckGnuplotVersion
@ -105,7 +101,7 @@ function CheckGnuplotVersion(cmd::AbstractString)
end
# --------------------------------------------------------------------
# ---------------------------------------------------------------------
function parseKeywords(; kwargs...)
template = (xrange=NTuple{2, Real},
yrange=NTuple{2, Real},
@ -136,176 +132,8 @@ function parseKeywords(; kwargs...)
end
# --------------------------------------------------------------------
function DrySession(sid::Symbol)
global state
(sid in keys(state.sessions)) &&
error("Gnuplot session $sid is already active")
out = DrySession(sid, Vector{DataSet}(), [SinglePlot()], 1)
return out
end
# --------------------------------------------------------------------
function getsession(sid::Symbol)
global state
if !(sid in keys(state.sessions))
#@info "Creating session $sid..."
if state.dry
gnuplot(sid)
else
gnuplot(sid, state.cmd)
end
end
return state.sessions[sid]
end
function getsession()
global state
return getsession(state.default)
end
# --------------------------------------------------------------------
"""
# println
Send a string to gnuplot's STDIN.
The commands sent through `send` are not stored in the current
session (use `newcmd` to save commands in the current session).
## Arguments:
- `gp`: a `Session` object;
- `str::String`: command to be sent;
- `capture=false`: set to `true` to capture and return the output.
"""
println(gp::DrySession, str::AbstractString) = nothing
function println(gp::Session, str::AbstractString)
global state
if !state.silent && state.verbose
printstyled(color=:yellow, "GNUPLOT ($(gp.sid)) $str\n")
end
w = write(gp.pin, strip(str) * "\n")
w <= 0 && error("Writing on gnuplot STDIN pipe returned $w")
#flush(gp.pin)
return w
end
println(gp::DrySession, d::DataSet) = nothing
function println(gp::Session, d::DataSet)
if typeof(gp) == concretetype(Session)
if !state.silent && state.verbose
for ii in 1:length(d.lines)
v = d.lines[ii]
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $v\n")
if ii == state.printlines
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ...\n")
if ii < length(d.lines)
v = d.lines[end]
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $v\n")
end
break
end
end
end
w = write(gp.pin, "\n")
w = write(gp.pin, join(d.lines, "\n"))
w = write(gp.pin, "\n")
w = write(gp.pin, "\n")
flush(gp.pin)
end
return nothing
end
# --------------------------------------------------------------------
writeread(gp::DrySession, str::AbstractString) = [""]
function writeread(gp::Session, str::AbstractString)
global state
silent = state.silent
state.silent = true
write(gp.pin, "print 'GNUPLOT_CAPTURE_BEGIN'\n")
println(gp, strip(str))
write(gp.pin, "print 'GNUPLOT_CAPTURE_END'\n")
flush(gp.pin)
out = Vector{String}()
while true
l = take!(gp.channel)
l == "GNUPLOT_CAPTURE_END" && break
push!(out, l)
end
state.silent = silent
return out
end
# --------------------------------------------------------------------
setWindowTitle(session::DrySession) = nothing
function setWindowTitle(session::Session)
term = writeread(session, "print GPVAL_TERM")[1]
if term in ("aqua", "x11", "qt", "wxt")
opts = writeread(session, "print GPVAL_TERMOPTIONS")[1]
if findfirst("title", opts) == nothing
writeread(session, "set term $term $opts title 'Gnuplot.jl: $(session.sid)'")
end
end
end
# --------------------------------------------------------------------
function reset(gp::DrySession)
gp.datas = Vector{DataSet}()
gp.plots = [SinglePlot()]
gp.curmid = 1
println(gp, "reset session")
return nothing
end
# --------------------------------------------------------------------
function setmulti(gp::DrySession, mid::Int)
@assert mid >= 0 "Multiplot ID must be a >= 0"
for i in length(gp.plots)+1:mid
push!(gp.plots, SinglePlot())
end
(mid > 0) && (gp.curmid = mid)
end
# --------------------------------------------------------------------
function newdatasource(gp::DrySession, v::Vector{T}; name="") where T <: AbstractString
(name == "") && (name = string("data", length(gp.datas)))
name = "\$$name"
accum = Vector{String}()
push!(accum, "$name << EOD")
append!(accum, v)
push!(accum, "EOD")
d = DataSet(name, accum)
push!(gp.datas, d)
println(gp, d) # Send directly to gnuplot process
return name
end
# --------------------------------------------------------------------
function newdatasource(gp::DrySession, args...; name="")
(name == "") && (name = string("data", length(gp.datas)))
name = "\$$name"
accum = dataset(args...)
accum[1] = name * accum[1]
d = DataSet(name, accum)
push!(gp.datas, d)
println(gp, d) # Send directly to gnuplot process
return name
end
# --------------------------------------------------------------------
function dataset(args...)
# ---------------------------------------------------------------------
function data2string(args...)
@assert length(args) > 0
# Check types of args
@ -339,7 +167,6 @@ function dataset(args...)
end
accum = Vector{String}()
push!(accum, " << EOD")
# All scalars
if minimum(dims) == 0
@ -351,7 +178,6 @@ function dataset(args...)
v *= " " * string(d)
end
push!(accum, v)
push!(accum, "EOD")
return accum
end
@ -369,7 +195,6 @@ function dataset(args...)
end
push!(accum, v)
end
push!(accum, "EOD")
return accum
end
@ -389,7 +214,6 @@ function dataset(args...)
i += 1
push!(accum, v)
end
push!(accum, "EOD")
return accum
end
@ -421,7 +245,6 @@ function dataset(args...)
i += 1
push!(accum, v)
end
push!(accum, "EOD")
return accum
else
#@info "Case 4"
@ -440,7 +263,6 @@ function dataset(args...)
i += 1
push!(accum, v)
end
push!(accum, "EOD")
return accum
end
end
@ -449,16 +271,224 @@ function dataset(args...)
end
# --------------------------------------------------------------------
"""
# newcmd
# ╭───────────────────────────────────────────────────────────────────╮
# │ SESSION CONSTRUCTORS AND getsession() │
# ╰───────────────────────────────────────────────────────────────────╯
# ---------------------------------------------------------------------
function DrySession(sid::Symbol)
global state
(sid in keys(state.sessions)) && error("Gnuplot session $sid is already active")
out = DrySession(sid, Vector{DataSet}(), [SinglePlot()], 1)
state.sessions[sid] = out
return out
end
Send a command to gnuplot process and store it in the current session.
# ---------------------------------------------------------------------
function GPSession(sid::Symbol)
function readTask(sid, stream, channel)
global state
saveOutput = false
while isopen(stream)
line = readline(stream)
if (length(line) >= 1) && (line[1] == Char(0x1b)) # Escape (xterm -ti vt340)
buf = Vector{UInt8}()
append!(buf, convert(Vector{UInt8}, [line...]))
push!(buf, 0x0a)
c = 0x00
while c != 0x1b
c = read(stream, 1)[1]
push!(buf, c)
end
c = read(stream, 1)[1]
push!(buf, c)
write(stdout, buf)
continue
end
if line == "GNUPLOT_CAPTURE_BEGIN"
saveOutput = true
else
if (line != "") && (line != "GNUPLOT_CAPTURE_END") && (state.verbose)
printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n")
end
(saveOutput) && (put!(channel, line))
(line == "GNUPLOT_CAPTURE_END") && (saveOutput = false)
end
end
delete!(state.sessions, sid)
return nothing
end
global state
CheckGnuplotVersion(state.cmd)
session = DrySession(sid)
pin = Base.Pipe()
pout = Base.Pipe()
perr = Base.Pipe()
proc = run(pipeline(`$(state.cmd)`, stdin=pin, stdout=pout, 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)
@async readTask(sid, perr, chan)
out = GPSession(getfield.(Ref(session), fieldnames(concretetype(DrySession)))...,
pin, pout, perr, proc, chan)
state.sessions[sid] = out
# Set window title
term = writeread(out, "print GPVAL_TERM")[1]
if term in ("aqua", "x11", "qt", "wxt")
opts = writeread(out, "print GPVAL_TERMOPTIONS")[1]
if findfirst("title", opts) == nothing
writeread(out, "set term $term $opts title 'Gnuplot.jl: $(out.sid)'")
end
end
for l in state.init
writeread(out, l)
end
return out
end
# ---------------------------------------------------------------------
function getsession(sid::Symbol=state.default)
global state
if !(sid in keys(state.sessions))
if state.dry
DrySession(sid)
else
GPSession(sid)
end
end
return state.sessions[sid]
end
# ╭───────────────────────────────────────────────────────────────────╮
# │ write() and writeread() │
# ╰───────────────────────────────────────────────────────────────────╯
# ---------------------------------------------------------------------
"""
# write
Send a string to gnuplot's STDIN.
The commands sent through `write` are not stored in the current
session (use `newcmd` to save commands in the current session).
## Arguments:
- `gp`: a `DrySession` object;
- `str::String`: command to be sent;
"""
write(gp::DrySession, str::AbstractString) = nothing
function write(gp::GPSession, str::AbstractString)
global state
if state.verbose
printstyled(color=:light_yellow, "GNUPLOT ($(gp.sid)) $str\n")
end
w = write(gp.pin, strip(str) * "\n")
w <= 0 && error("Writing on gnuplot STDIN pipe returned $w")
flush(gp.pin)
return w
end
write(gp::DrySession, d::DataSet) = nothing
function write(gp::GPSession, d::DataSet)
if state.verbose
v = ""
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $(d.name) << EOD\n")
n = min(state.printlines, length(d.lines))
for i in 1:n
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) $(d.lines[i])\n")
end
if n < length(d.lines)
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) ...\n")
end
printstyled(color=:light_black, "GNUPLOT ($(gp.sid)) EOD\n")
end
write(gp.pin, "\n")
write(gp.pin, "$(d.name) << EOD\n")
write(gp.pin, join(d.lines, "\n") * "\n")
write(gp.pin, "EOD\n")
write(gp.pin, "\n")
write(gp.pin, "\n")
flush(gp.pin)
return nothing
end
# ---------------------------------------------------------------------
writeread(gp::DrySession, str::AbstractString) = [""]
function writeread(gp::GPSession, str::AbstractString)
global state
verbose = state.verbose
state.verbose = false
write(gp, "print 'GNUPLOT_CAPTURE_BEGIN'")
write(gp, str)
write(gp, "print 'GNUPLOT_CAPTURE_END'")
out = Vector{String}()
while true
l = take!(gp.channel)
l == "GNUPLOT_CAPTURE_END" && break
push!(out, l)
end
state.verbose = verbose
return out
end
# ╭───────────────────────────────────────────────────────────────────╮
# │ PRIVATE FUNCTIONS TO MANIPULATE SESSIONS │
# ╰───────────────────────────────────────────────────────────────────╯
# ---------------------------------------------------------------------
function reset(gp::DrySession)
gp.datas = Vector{DataSet}()
gp.plots = [SinglePlot()]
gp.curmid = 1
write(gp, "reset session")
return nothing
end
# ---------------------------------------------------------------------
function setmulti(gp::DrySession, mid::Int)
@assert mid >= 0 "Multiplot ID must be a >= 0"
for i in length(gp.plots)+1:mid
push!(gp.plots, SinglePlot())
end
(mid > 0) && (gp.curmid = mid)
end
# ---------------------------------------------------------------------
function newdataset(gp::DrySession, accum::Vector{String}; name="")
(name == "") && (name = string("data", length(gp.datas)))
name = "\$$name"
d = DataSet(name, accum)
push!(gp.datas, d)
write(gp, d) # Send now to gnuplot process
return name
end
newdataset(gp::DrySession, args...; name="") = newdataset(gp, data2string(args...), name=name)
# ---------------------------------------------------------------------
function newcmd(gp::DrySession, v::String; mid::Int=0)
setmulti(gp, mid)
(v != "") && (push!(gp.plots[gp.curmid].cmds, v))
(length(gp.plots) == 1) && (println(gp, v))
(length(gp.plots) == 1) && (write(gp, v))
return nothing
end
@ -470,105 +500,80 @@ function newcmd(gp::DrySession; mid::Int=0, args...)
end
# --------------------------------------------------------------------
function newplotelem(gp::DrySession, name, opt=""; mid=0)
# ---------------------------------------------------------------------
function newplot(gp::DrySession, name, opt=""; mid=0)
setmulti(gp, mid)
push!(gp.plots[gp.curmid].elems, "$name $opt")
end
# --------------------------------------------------------------------
function quitsession(gp::DrySession)
# ---------------------------------------------------------------------
function quit(gp::DrySession)
global state
delete!(state.sessions, gp.sid)
return 0
end
function quitsession(gp::Session)
function quit(gp::GPSession)
close(gp.pin)
close(gp.pout)
close(gp.perr)
wait( gp.proc)
exitCode = gp.proc.exitcode
invoke(quitsession, Tuple{DrySession}, gp)
invoke(quit, Tuple{DrySession}, gp)
return exitCode
end
# --------------------------------------------------------------------
iterate(gp::DrySession) = ("#ID: $(gp.sid)", (true, 1, 1))
function iterate(gp::DrySession, state)
(onData, mid, ii) = state
if onData
if mid <= length(gp.datas)
if ii <= length(gp.datas[mid].lines)
return (gp.datas[mid].lines[ii], (true, mid, ii+1))
end
return iterate(gp, (true, mid+1, 1))
end
return ("", (false, 1, 1))
end
if mid <= length(gp.plots)
if ii <= length(gp.plots[mid].cmds)
return (gp.plots[mid].cmds[ii], (false, mid, ii+1))
end
if length(gp.plots[mid].elems) == 0
return ("", (false, mid+1, 1))
end
s = (gp.plots[mid].flag3d ? "splot " : "plot ") * " \\\n " *
join(gp.plots[mid].elems, ", \\\n ")
return (s, (false, mid+1, 1))
end
if mid == length(gp.plots)+1
s = ""
(length(gp.plots) > 1) && (s *= "unset multiplot;")
return (s, (false, mid+1, 1))
end
return nothing
end
# --------------------------------------------------------------------
# function convert(::Type{Vector{String}}, gp::DrySession)
# out = Vector{String}()
# for l in gp
# push!(out, l)
# end
# return out
# end
# --------------------------------------------------------------------
internal_save(gp::DrySession; kw...) = internal_save(gp, gp; kw...)
function internal_save(gp::DrySession, stream; term::AbstractString="", output::AbstractString="")
println(stream, "reset")
# ╭───────────────────────────────────────────────────────────────────╮
# │ dump() and driver() │
# ╰───────────────────────────────────────────────────────────────────╯
# ---------------------------------------------------------------------
dump(gp::DrySession; kw...) = dump(gp, gp; kw...)
function dump(gp::DrySession, stream; term::AbstractString="", output::AbstractString="")
write(stream, "reset\n")
if term != ""
former_term = writeread(gp, "print GPVAL_TERM")[1]
former_opts = writeread(gp, "print GPVAL_TERMOPTIONS")[1]
println(stream, "set term $term")
write(stream, "set term $term\n")
end
(output != "") && println(stream, "set output '$output'")
i = (!(typeof(stream) <: DrySession), 1, 1) # Skip data sources ?
while (next = iterate(gp, i)) != nothing
(s, i) = next
println(stream, s)
(output != "") && write(stream, "set output '$output'\n")
if !(typeof(stream) <: DrySession)
# Dump datasets
for i in 1:length(gp.datas)
d = gp.datas[i]
write(stream, d.name * " << EOD\n")
for j in 1:length(d.lines)
write(stream, d.lines[j] * "\n")
end
write(stream, "EOD\n")
end
end
(output != "") && println(stream, "set output")
for i in 1:length(gp.plots)
d = gp.plots[i]
for j in 1:length(d.cmds)
write(stream, d.cmds[j] * "\n")
end
s = (d.flag3d ? "splot " : "plot ") * " \\\n " *
join(d.elems, ", \\\n ")
write(stream, s * "\n")
end
(length(gp.plots) > 1) && write(stream, "unset multiplot\n")
(output != "") && write(stream, "set output\n")
if term != ""
println(stream, "set term $former_term $former_opts")
write(stream, "set term $former_term $former_opts\n")
end
output
return output
end
# --------------------------------------------------------------------
# ---------------------------------------------------------------------
function driver(args...; flag3d=false)
if length(args) == 0
gp = getsession()
internal_save(gp)
dump(gp)
return nothing
end
@ -587,8 +592,8 @@ function driver(args...; flag3d=false)
end
end
if AllArraysAreNotEmpty
last = newdatasource(gp, data...; name=dataname)
(dataplot != nothing) && (newplotelem(gp, last, dataplot))
last = newdataset(gp, data...; name=dataname)
(dataplot != nothing) && (newplot(gp, last, dataplot))
end
end
data = Vector{Any}()
@ -660,7 +665,7 @@ function driver(args...; flag3d=false)
(isPlot, flag3d, cmd) = isPlotCmd(arg)
if isPlot
gp.plots[gp.curmid].flag3d = flag3d
newplotelem(gp, cmd)
newplot(gp, cmd)
else
newcmd(gp, arg)
end
@ -674,7 +679,7 @@ function driver(args...; flag3d=false)
dataplot = ""
dataCompleted()
(doDump) && (internal_save(gp))
(doDump) && (dump(gp))
return nothing
end
@ -684,132 +689,6 @@ end
# EXPORTED FUNCTIONS
#_____________________________________________________________________
# --------------------------------------------------------------------
"""
`gnuplot(sid::Symbol)`
`gnuplot(sid::Symbol, cmd::AbstractString)`
Initialize a new session and (optionally) the associated Gnuplot process
## Arguments:
- `sid`: the session name (a Julia symbol);
- `cmd`: a string specifying the complete file path to a gnuplot executable. If not given a *dry* session will be created, i.e. a session without underlying gnuplot process.
"""
function gnuplot(sid::Symbol)
out = DrySession(sid)
state.sessions[sid] = out
return out
end
function gnuplot(sid::Symbol, cmd::AbstractString)
function readTask(sid, stream, channel)
global state
saveOutput = false
while isopen(stream)
line = readline(stream)
if (length(line) >= 1) && (line[1] == Char(0x1b)) # Escape (xterm -ti vt340)
buf = Vector{UInt8}()
append!(buf, convert(Vector{UInt8}, [line...]))
push!(buf, 0x0a)
c = 0x00
while c != 0x1b
c = read(stream, 1)[1]
push!(buf, c)
end
c = read(stream, 1)[1]
push!(buf, c)
write(stdout, buf)
continue
end
if line == "GNUPLOT_CAPTURE_BEGIN"
saveOutput = true
else
if (line != "") && (line != "GNUPLOT_CAPTURE_END") && (!state.silent)
printstyled(color=:cyan, "GNUPLOT ($sid) -> $line\n")
end
(saveOutput) && (put!(channel, line))
(line == "GNUPLOT_CAPTURE_END") && (saveOutput = false)
end
end
delete!(state.sessions, sid)
return nothing
end
global state
CheckGnuplotVersion(cmd)
session = DrySession(sid)
pin = Base.Pipe()
pout = Base.Pipe()
perr = Base.Pipe()
proc = run(pipeline(`$cmd`, stdin=pin, stdout=pout, 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)
@async readTask(sid, perr, chan)
out = Session(getfield.(Ref(session), fieldnames(concretetype(DrySession)))..., pin, pout, perr, proc, chan)
state.sessions[sid] = out
setWindowTitle(out)
for l in state.initcmd
writeread(out, l)
end
return out
end
function gnuplot()
global state
return gnuplot(state.default)
end
function gnuplot(cmd::AbstractString)
global state
return gnuplot(state.default, cmd)
end
# --------------------------------------------------------------------
"""
`quit()`
Quit the session and the associated gnuplot process (if any).
"""
function quit(sid::Symbol)
global state
if !(sid in keys(state.sessions))
error("Gnuplot session $sid do not exists")
end
return quitsession(state.sessions[sid])
end
"""
`quitall()`
Quit all the sessions and the associated gnuplot processes.
"""
function quitall()
global state
for sid in keys(state.sessions)
quit(sid)
end
return nothing
end
# --------------------------------------------------------------------
"""
`@gp args...`
@ -1015,6 +894,38 @@ end
# end
# ╭───────────────────────────────────────────────────────────────────╮
# │ FUNCTIONS MEANT TO BE INVOKED BY USERS │
# ╰───────────────────────────────────────────────────────────────────╯
# ---------------------------------------------------------------------
"""
`quit()`
Quit the session and the associated gnuplot process (if any).
"""
function quit(sid::Symbol)
global state
if !(sid in keys(state.sessions))
error("Gnuplot session $sid do not exists")
end
return quit(state.sessions[sid])
end
"""
`quitall()`
Quit all the sessions and the associated gnuplot processes.
"""
function quitall()
global state
for sid in keys(state.sessions)
quit(sid)
end
return nothing
end
# --------------------------------------------------------------------
"""
`exec(sid::Symbol, s::Vector{String})`
@ -1055,11 +966,6 @@ function setverbose(b::Bool)
end
function initcmd()
global state
return state.initcmd
end
# --------------------------------------------------------------------
"""
@ -1077,12 +983,12 @@ To save the data and command from a specific session pass the ID as first argume
In all cases the `term` keyword allows to specify a gnuplot terminal, and the `output` keyword allows to specify an output file.
"""
save( ; kw...) = internal_save(getsession() ; kw...)
save(sid::Symbol ; kw...) = internal_save(getsession(sid) ; kw...)
save( stream::IO ; kw...) = internal_save(getsession() , stream; kw...)
save(sid::Symbol, stream::IO ; kw...) = internal_save(getsession(sid), stream; kw...)
save( file::AbstractString; kw...) = open(file, "w") do stream; internal_save(getsession() , stream; kw...); end
save(sid::Symbol, file::AbstractString; kw...) = open(file, "w") do stream; internal_save(getsession(sid), stream; kw...); end
save( ; kw...) = dump(getsession() ; kw...)
save(sid::Symbol ; kw...) = dump(getsession(sid) ; kw...)
save( stream::IO ; kw...) = dump(getsession() , stream; kw...)
save(sid::Symbol, stream::IO ; kw...) = dump(getsession(sid), stream; kw...)
save( file::AbstractString; kw...) = open(file, "w") do stream; dump(getsession() , stream; kw...); end
save(sid::Symbol, file::AbstractString; kw...) = open(file, "w") do stream; dump(getsession(sid), stream; kw...); end
# --------------------------------------------------------------------

View File

@ -3,41 +3,30 @@ using Test, Gnuplot
x = [1, 2, 3]
y = [4, 5, 6]
s = Gnuplot.dataset(1)
@test all(s .== [" << EOD",
" 1" ,
"EOD" ])
s = Gnuplot.data2string(1)
@test all(s .== [" 1"])
s = Gnuplot.dataset(1, 2)
@test all(s .== [" << EOD",
" 1 2" ,
"EOD" ])
s = Gnuplot.data2string(1, 2)
@test all(s .== [" 1 2"])
s = Gnuplot.dataset(x)
@test all(s .== [" << EOD",
" 1" ,
s = Gnuplot.data2string(x)
@test all(s .== [" 1" ,
" 2" ,
" 3" ,
"EOD" ])
" 3" ])
s = Gnuplot.dataset(x, y)
@test all(s .== [ " << EOD",
" 1 4",
" 2 5",
" 3 6",
"EOD" ])
s = Gnuplot.data2string(x, y)
@test all(s .== [" 1 4",
" 2 5",
" 3 6"])
s = Gnuplot.dataset(x, y, x.+y)
@test all(s .== [ " << EOD",
" 1 4 5",
" 2 5 7",
" 3 6 9",
"EOD" ])
s = Gnuplot.data2string(x, y, x.+y)
@test all(s .== [" 1 4 5",
" 2 5 7",
" 3 6 9"])
z = [X+Y for X in x, Y in y];
s = Gnuplot.dataset(z)
@test all(s .== [" << EOD",
" 1 1 5" ,
s = Gnuplot.data2string(z)
@test all(s .== [" 1 1 5" ,
" 2 1 6" ,
" 3 1 7" ,
"" ,
@ -47,13 +36,11 @@ s = Gnuplot.dataset(z)
"" ,
" 1 3 7" ,
" 2 3 8" ,
" 3 3 9" ,
"EOD" ])
" 3 3 9" ])
s = Gnuplot.dataset(x, y, z)
@test all(s .== [" << EOD",
" 1 4 5" ,
s = Gnuplot.data2string(x, y, z)
@test all(s .== [" 1 4 5" ,
" 2 4 6" ,
" 3 4 7" ,
"" ,
@ -63,8 +50,7 @@ s = Gnuplot.dataset(x, y, z)
"" ,
" 1 6 7" ,
" 2 6 8" ,
" 3 6 9" ,
"EOD" ])
" 3 6 9" ])
@ -72,9 +58,8 @@ c = [[X, Y] for Y in y for X in x]; # First Y (i.e. rows) then X (i.e. columns)
u = getindex.(c, 1)
v = getindex.(c, 2)
s = Gnuplot.dataset(u, v, z)
@test all(s .== [" << EOD",
" 1 4 5" ,
s = Gnuplot.data2string(u, v, z)
@test all(s .== [" 1 4 5" ,
" 2 4 6" ,
" 3 4 7" ,
"" ,
@ -84,8 +69,7 @@ s = Gnuplot.dataset(u, v, z)
"" ,
" 1 6 7" ,
" 2 6 8" ,
" 3 6 9" ,
"EOD" ])
" 3 6 9" ])
#-----------------------------------------------------------------