[metapost] augment drawoptions

Taco Hoekwater taco at elvenkind.com
Sat Apr 12 16:59:58 CEST 2008


Stephan Hennig wrote:
> 
>> In fact, I cannot come up an elegant solution to the problem that
>> does not require rewriting quite a bit of plain.mp.
> 
> I would find native support for local draw options (and altering draw
> options) a useful addition to MetaPost.  What do people think?

Can you explain a bit more what you have in mind?

TeX's concept of groups and saving does not really apply to metapost,
but you could define macros that do nesting and saving of values if
that is what you need.

The problem does not have so much to do with the metapost engine
as it does with the plain.mp macros. What you are asking is somewhat
similar to asking for generic font encoding support in plain.tex.
It is possible, but the result would not qualify as "plain" anymore.

My metapost coding isn't very good, so the real experts on the
list will probably have much nicer ideas, but here is a way you
can save _op_ in a nicely nested way, simply to demonstrate that
there are possible solutions:

%%%%%%%%%%
level:=0; % nesting level

let _begingroup = begingroup; % save those, will be redefined
let _endgroup = endgroup;

def stringified (expr v) =
   _begingroup % grouping needed to preverve "s" and "r"
   save s,r; r:=v;
   string s; s:="" ;
   forever: exitif r<=0; s:= s & "A"; r:=r-1; endfor;
   s % return 'level' times an "A"
   _endgroup
enddef;

def begingroup =
   level := level + 1; % nesting level up
   _begingroup % run primitive operation
   _begingroup % grouping needed to preverve "s"
   save s; string s;
   s := "let _saved_op_" & stringified (level) & "= _op_;";
   scantokens s; % creates an alias for current _op_
   _endgroup;
enddef;

def endgroup = % as begingroup, but reversed
   _begingroup
   save s; string s;
   s := "let _op_ = _saved_op_" & stringified (level) & "; ";
   scantokens s;
   _endgroup;
   _endgroup;
   level := level - 1;
enddef;

def addtodrawoptions(text t) =
    % I just realized _myop_ is not needed
    expandafter def expandafter _op_  expandafter = _op_ t enddef;
enddef;

beginfig(1);
   drawoptions(withcolor red);% Set colour.
   begingroup
     addtodrawoptions(withpen pencircle scaled 4bp);
     draw fullcircle scaled 100;
     begingroup
       addtodrawoptions(withpen pencircle withcolor green);
       draw fullcircle scaled 90;
     endgroup
     draw fullcircle scaled 80;
   endgroup
   draw fullcircle scaled 50 ;
endfig;
end
%%%%%%%%%%%%%

Best wishes,
Taco



More information about the metapost mailing list