[metapost] augment drawoptions

Stephan Hennig mailing_list at arcor.de
Mon Apr 14 14:11:09 CEST 2008

Taco Hoekwater schrieb:

> 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:

Here's another attempt.  It is very similar to yours, but with two

(i) level (here _op_level_) is not stringified into a series of A's, but
converted to base 26 with digits A..Z.  This should lead to shorter
strings and macro names and could possibly be useful in massive
recursive programming.  (Actually, macro _baseAZ_ returns base 26
notation of a value in reverse order, that is, 26 is returned as AB
instead of BA, but this is no problem as long as the return values are
determined and unique.)

(ii) When _op_ is popped from the stack the obsolete macro _op_stack_XXX
is additionally "emptied".

A final loop shows the definition of


As can be seen macros _op_stack_A to _op_stack_C are defined, but empty,
whereas _op_stack_D is of type "tag".  Is there a way to completely
remove a macro, i.e., make an identifier a tag again?

Best regards,
Stephan Hennig

let _begingroup = begingroup; % save those, will be redefined
let _endgroup = endgroup;
numeric _op_level_;% nesting level
_op_level_ := 0;

def _baseAZ_(expr v) =
_begingroup% grouping needed to preverve "s" and "r"
save s, r; string s;
  r := v; s := "";
    s := s & char (65+(r mod 26));
    r := r div 26;
    exitif r <= 0;
  s% return v in reverse base 26 notation with digits A..Z.

def begingroup =
    save s; string s;
    s := "let _op_stack_" & _baseAZ_(_op_level_) & "=_op_";
    scantokens s;
    _op_level_ := _op_level_ + 1;

def endgroup =
  save s, n; string s, n;
    _op_level_ := _op_level_ - 1;
    n := _baseAZ_(_op_level_);
%     s := "let _op_=_op_stack_" & n;
    s := "let _op_=_op_stack_" & n & ";def _op_stack_" & n & "=enddef";
    scantokens s;

def addtodrawoptions(text t) =
  expandafter def expandafter _op_  expandafter = _op_ t enddef;

  drawoptions(withcolor red);% Set colour.
    addtodrawoptions(withpen pencircle scaled 4bp);
    draw fullcircle scaled 100;
      addtodrawoptions(withpen pencircle withcolor green);
      draw fullcircle scaled 90;
    draw fullcircle scaled 80;
  draw fullcircle scaled 50 ;
  for i:=0 upto 4:
    scantokens( "showtoken _op_stack_" & _baseAZ_(i) );

More information about the metapost mailing list