diff --git a/REQUIRE b/REQUIRE index 126413bb..adcb5a0b 100644 --- a/REQUIRE +++ b/REQUIRE @@ -5,3 +5,4 @@ Reexport Compat Requires FixedSizeArrays +RecipesBase diff --git a/src/Plots.jl b/src/Plots.jl index 3601359d..e6e5ef31 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -8,6 +8,7 @@ using Reexport @reexport using Colors using Requires using FixedSizeArrays +@reexport using RecipesBase export AbstractPlot, diff --git a/src/plot.jl b/src/plot.jl index d9ad1065..f3763213 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -75,7 +75,7 @@ function plot!(plt::Plot, args...; kw...) userkw = preprocessArgs!(d) # for plotting recipes, swap out the args and update the parameter dictionary - args = _apply_recipe(d, userkw, args...) + args = RecipesBase.apply_recipe(d, userkw, args...) _add_markershape(d) dumpdict(d, "After plot! preprocessing") diff --git a/src/recipes.jl b/src/recipes.jl index fac61a42..f11bc839 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -17,10 +17,10 @@ plot!(plt::Plot, recipe::PlotRecipe, args...; kw...) = plot!(getRecipeXY(recipe) num_series(x::AMat) = size(x,2) num_series(x) = 1 -_apply_recipe(d::KW, kw::KW) = () +# _apply_recipe(d::KW, kw::KW) = () # if it's not a recipe, just do nothing and return the args -function _apply_recipe(d::KW, kw::KW, args...; issubplot=false) +function RecipesBase.apply_recipe(d::KW, kw::KW, args...; issubplot=false) if issubplot && !isempty(args) && !haskey(d, :n) && !haskey(d, :layout) # put in a sensible default d[:n] = maximum(map(num_series, args)) @@ -28,126 +28,126 @@ function _apply_recipe(d::KW, kw::KW, args...; issubplot=false) args end -macro kw(k, v) - esc(:(get!(d, $k, $v))) -end - -function _is_arrow_tuple(expr::Expr) - expr.head == :tuple && - isa(expr.args[1], Expr) && - expr.args[1].head == :(-->) -end - -function _equals_symbol(arg::Symbol, sym::Symbol) - arg == sym -end -function _equals_symbol(arg::Expr, sym::Symbol) - arg.head == :quote && arg.args[1] == sym -end - -# TODO: when this is moved out of Plots, also move the replacement of key aliases to just after the _apply_recipe calls -function replace_recipe_arrows!(expr::Expr) - for (i,e) in enumerate(expr.args) - if isa(e,Expr) - - # process trailing flags, like: - # a --> b, :quiet, :force - quiet, require, force = false, false, false - if _is_arrow_tuple(e) - for flag in e.args - if _equals_symbol(flag, :quiet) - quiet = true - elseif _equals_symbol(flag, :require) - require = true - elseif _equals_symbol(flag, :force) - force = true - end - end - e = e.args[1] - end - - # we are going to recursively swap out `a --> b, flags...` commands - if e.head == :(-->) - k, v = e.args - keyexpr = :(get(Plots._keyAliases, $k, $k)) - - set_expr = if force - # forced override user settings - :(d[$keyexpr] = $v) - else - # if the user has set this keyword, use theirs - :(get!(d, $keyexpr, $v)) - end - - expr.args[i] = if quiet - # quietly ignore keywords which are not supported - :($keyexpr in supportedArgs() ? $set_expr : nothing) - elseif require - # error when not supported by the backend - :($keyexpr in supportedArgs() ? $set_expr : error("In recipe: required keyword ", $k, " is not supported by backend $(backend_name())")) - else - set_expr - end - - # @show quiet, force, expr.args[i] - - elseif e.head != :call - # we want to recursively replace the arrows, but not inside function calls - # as this might include things like Dict(1=>2) - replace_recipe_arrows!(e) - end - end - end -end - - -macro recipe(funcexpr::Expr) - lhs, body = funcexpr.args - - if !(funcexpr.head in (:(=), :function)) - error("Must wrap a valid function call!") - end - if !(isa(lhs, Expr) && lhs.head == :call) - error("Expected `lhs = ...` with lhs as a call Expr... got: $lhs") - end - - # for parametric definitions, take the "curly" expression and add the func - front = lhs.args[1] - func = :(Plots._apply_recipe) - if isa(front, Expr) && front.head == :curly - front.args[1] = func - func = front - end - - # get the arg list, stripping out any keyword parameters into a - # bunch of get!(kw, key, value) lines - args = lhs.args[2:end] - kw_body = Expr(:block) - if isa(args[1], Expr) && args[1].head == :parameters - for kwpair in args[1].args - k, v = kwpair.args - push!(kw_body.args, :(get!(kw, $(QuoteNode(k)), $v))) - end - args = args[2:end] - end - - # replace all the key => value lines with argument setting logic - replace_recipe_arrows!(body) - - # now build a function definition for _apply_recipe, wrapping the return value in a tuple if needed - esc(quote - function $func(d::KW, kw::KW, $(args...); issubplot=false) - $kw_body - ret = $body - if typeof(ret) <: Tuple - ret - else - (ret,) - end - end - end) -end - +# macro kw(k, v) +# esc(:(get!(d, $k, $v))) +# end +# +# function _is_arrow_tuple(expr::Expr) +# expr.head == :tuple && +# isa(expr.args[1], Expr) && +# expr.args[1].head == :(-->) +# end +# +# function _equals_symbol(arg::Symbol, sym::Symbol) +# arg == sym +# end +# function _equals_symbol(arg::Expr, sym::Symbol) +# arg.head == :quote && arg.args[1] == sym +# end +# +# # TODO: when this is moved out of Plots, also move the replacement of key aliases to just after the _apply_recipe calls +# function replace_recipe_arrows!(expr::Expr) +# for (i,e) in enumerate(expr.args) +# if isa(e,Expr) +# +# # process trailing flags, like: +# # a --> b, :quiet, :force +# quiet, require, force = false, false, false +# if _is_arrow_tuple(e) +# for flag in e.args +# if _equals_symbol(flag, :quiet) +# quiet = true +# elseif _equals_symbol(flag, :require) +# require = true +# elseif _equals_symbol(flag, :force) +# force = true +# end +# end +# e = e.args[1] +# end +# +# # we are going to recursively swap out `a --> b, flags...` commands +# if e.head == :(-->) +# k, v = e.args +# keyexpr = :(get(Plots._keyAliases, $k, $k)) +# +# set_expr = if force +# # forced override user settings +# :(d[$keyexpr] = $v) +# else +# # if the user has set this keyword, use theirs +# :(get!(d, $keyexpr, $v)) +# end +# +# expr.args[i] = if quiet +# # quietly ignore keywords which are not supported +# :($keyexpr in supportedArgs() ? $set_expr : nothing) +# elseif require +# # error when not supported by the backend +# :($keyexpr in supportedArgs() ? $set_expr : error("In recipe: required keyword ", $k, " is not supported by backend $(backend_name())")) +# else +# set_expr +# end +# +# # @show quiet, force, expr.args[i] +# +# elseif e.head != :call +# # we want to recursively replace the arrows, but not inside function calls +# # as this might include things like Dict(1=>2) +# replace_recipe_arrows!(e) +# end +# end +# end +# end +# +# +# macro recipe(funcexpr::Expr) +# lhs, body = funcexpr.args +# +# if !(funcexpr.head in (:(=), :function)) +# error("Must wrap a valid function call!") +# end +# if !(isa(lhs, Expr) && lhs.head == :call) +# error("Expected `lhs = ...` with lhs as a call Expr... got: $lhs") +# end +# +# # for parametric definitions, take the "curly" expression and add the func +# front = lhs.args[1] +# func = :(Plots._apply_recipe) +# if isa(front, Expr) && front.head == :curly +# front.args[1] = func +# func = front +# end +# +# # get the arg list, stripping out any keyword parameters into a +# # bunch of get!(kw, key, value) lines +# args = lhs.args[2:end] +# kw_body = Expr(:block) +# if isa(args[1], Expr) && args[1].head == :parameters +# for kwpair in args[1].args +# k, v = kwpair.args +# push!(kw_body.args, :(get!(kw, $(QuoteNode(k)), $v))) +# end +# args = args[2:end] +# end +# +# # replace all the key => value lines with argument setting logic +# replace_recipe_arrows!(body) +# +# # now build a function definition for _apply_recipe, wrapping the return value in a tuple if needed +# esc(quote +# function $func(d::KW, kw::KW, $(args...); issubplot=false) +# $kw_body +# ret = $body +# if typeof(ret) <: Tuple +# ret +# else +# (ret,) +# end +# end +# end) +# end +# # --------------------------------------------------------------------------- diff --git a/src/subplot.jl b/src/subplot.jl index 421a9b27..14c2f69b 100644 --- a/src/subplot.jl +++ b/src/subplot.jl @@ -43,7 +43,7 @@ function subplot(args...; kw...) preprocessArgs!(d) # for plotting recipes, swap out the args and update the parameter dictionary - args = _apply_recipe(d, KW(kw), args...; issubplot=true) + args = RecipesBase.apply_recipe(d, KW(kw), args...; issubplot=true) _add_markershape(d) # figure out the layout @@ -120,7 +120,7 @@ function _preprocess_subplot(subplt::Subplot, d::KW, args = ()) userkw = preprocessArgs!(d) # for plotting recipes, swap out the args and update the parameter dictionary - args = _apply_recipe(d, userkw, args...; issubplot=true) + args = RecipesBase.apply_recipe(d, userkw, args...; issubplot=true) _add_markershape(d) dumpdict(d, "After subplot! preprocessing") diff --git a/test/REQUIRE b/test/REQUIRE index 3a5eafbd..2af8bee2 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -3,6 +3,7 @@ julia 0.4 Colors Reexport Requires +RecipesBase FactCheck Cairo Gadfly diff --git a/test/travis_commands.jl b/test/travis_commands.jl index f4d91d0a..6ee79fc5 100644 --- a/test/travis_commands.jl +++ b/test/travis_commands.jl @@ -7,6 +7,7 @@ Pkg.build("ImageMagick") Pkg.clone("GR") Pkg.build("GR") +Pkg.clone("https://github.com/JuliaPlots/RecipesBase.jl.git") Pkg.clone("https://github.com/tbreloff/ExamplePlots.jl.git"); # Pkg.clone("https://github.com/JunoLab/Blink.jl.git")