8

I am trying to convert the statement

drawarrow (0,0)--(100,100) dashed evenly withcolor green;

to

newinternal string varA ; 
varA := "dashed evenly withcolor green" ; 
drawarrow (0,0)--(100,100) varA ;

but it fails in the line of drawarrow. Any help would be appreciated. Thank you.

chsk
  • 3,667
  • Or you could just do drawoptions(dashed evenly withcolor green); then draw your arrow(s), then set things back to normal with drawoptions(). – Thruston Apr 24 '21 at 21:23

3 Answers3

9

dashed evenly withcolor green is not a string, but a list of tokens. You want

def varA = dashed evenly withcolor green enddef;

so a macro. Full example

def varA = dashed evenly withcolor green enddef;

beginfig(1); drawarrow (0,0)--(100,100) varA ; endfig; end.

enter image description here

egreg
  • 1,121,712
4

Instead of def, you can also apply scantokens which converts from string to tokens. Just ensure your string is MetaPost sensible code:

newinternal string varA ; 
varA := "dashed evenly withcolor green"; 
drawarrow (0,0)--(100,100) scantokens(varA);

You're now able to store a list of strings to be later tokenized, but it's not that useful unless you really need chunks of MetaPost as strings. Another example:

string Vars[]; 
Vars[1] := "dashed evenly withcolor green"; 
Vars[2] := "dashed evenly withcolor red"; 
drawarrow (0,0)--( 100, 100) scantokens(Vars[1]);
drawarrow (0,0)--(-100,-100) scantokens(Vars[2]);

I wouldn't actually recommend it as you might be caught by some expansion issues (as @egreg says, MetaPost, like TeX, works with tokens and thus faces the same issues), but it's fine for the simplest cases.

1

Plain Metapost already provides a mechanism to apply the same set of drawing options to a sequence of drawing commands. So another way to achieve what (I think) you are trying to do, would be as follows

prologues := 3;
outputtemplate := "%j%c.eps";
defaultfont := "phvr8r";
beginfig(1);
drawoptions(dashed evenly withcolor 1/2 green);
drawarrow origin -- (100, 100);
label.urt("Green but not dashed", (100, 100));

drawoptions(withcolor 2/3 red);
drawarrow origin -- 84 dir 72;
drawarrow origin -- 74 dir 82;

drawoptions(); % back to default colors and style
drawarrow origin -- 84 dir 13;

endfig; end.

Compile this with mpost to get

enter image description here

Notes

  • drawing options that you set with drawoptions apply to all subsequent draw, fill, or label commands until you call drawoptions again.

  • notice that the colour applies to both labels and drawing, but the dashes are only applied to the drawn arrow.

  • drawoptions resets all the options, so the second one changes the colour explicitly, but also implicitly resets the line style.

  • hence the call drawoptions(); will reset everything to defaults

  • in plain MP, the beginfig macro automatically calls drawoptions() to reset everything for you at the start of each figure.

Thruston
  • 42,268