I am attempting to write my first macro. Cairo.jl, following its C roots, 
requires a context argument to be added at the start of many of its drawing 
functions. This results in lots of typing, which I think could be cleaned 
up with a macro.

Here's a snippet from one of the examples[1].

using Cairo
c = CairoRGBSurface(256,256);
cr = CairoContext(c);
...
new_path(cr); # current path is not consumed by cairo_clip()
rectangle(cr, 0, 0, 256, 256);
fill(cr);
set_source_rgb(cr, 0, 1, 0);
move_to(cr, 0, 0);
line_to(cr, 256, 256);
move_to(cr, 256, 0);
line_to(cr, 0, 256);
set_line_width(cr, 10.0);
stroke(cr);

What I would like to be able to do is use a macro to insert a common 
argument into each expression. The result might look something like...

using Cairo
c = CairoRGBSurface(256,256)
cr = CairoContext(c)

@withcontext cr, begin
  ...
  new_path()
  rectangle(0, 0, 256, 256)
  fill()
  set_source_rgb(0, 1, 0)
  move_to(0, 0)
  line_to(256, 256)
  move_to(256, 0)
  line_to(0, 256)
  set_line_width(10.0)
  stroke()
end

I have clumsily got this far.. 

macro withcontext(exprs...)
  common_arg = exprs.args[1]
  
  for i in 2:length(exprs)
    expr = exprs[i]
    insert!(expr, 2, common_arg)
  end
  return exprs[2:end]
end

..but haven't seen much success. Both lines of this tiny experiment are 
being wrapped up as a single expression.

julia> a = [1,2,3,4,5]
julia> @withcontext begin
  a 
  methods()
end
ERROR: type: getfield: expected DataType, got (Expr,)

I'm quite new to Julia and newer to macros - is this kind of thing even 
possible? Any suggestions?

With thanks,



Tim McNamara
http://timmcnamara.co.nz

[1] https://github.com/JuliaLang/Cairo.jl/blob/master/samples/sample_clip.jl

Reply via email to