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

(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

_op_stack_A
_op_stack_B
_op_stack_C
_op_stack_D
_op_stack_E

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 := "";
  forever:
    s := s & char (65+(r mod 26));
    r := r div 26;
    exitif r <= 0;
  endfor
  s% return v in reverse base 26 notation with digits A..Z.
_endgroup
enddef;

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

def endgroup =
  _begingroup
  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;
  _endgroup;
_endgroup;
enddef;

def addtodrawoptions(text t) =
  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 ;
  for i:=0 upto 4:
    scantokens( "showtoken _op_stack_" & _baseAZ_(i) );
  endfor
endfig;
end



More information about the metapost mailing list