I'm quite new to this language and can't figure out the error in following code. Any help would be appreciated !



u := 10mm;
v := 0.8u;

for i=1 upto 5:
    pickup pensquare scaled 0.6pt;
    draw (-v*i,-0.1u)..(-v*i,0.1u)
        withcolor(0.5, 0.5, 0.5);
    draw (v*i,-0.1u)..(v*i,0.1u)
        withcolor(0.5, 0.5, 0.5);

    label.bot(textext("$" & (decimal (-v*i)) & "$"), (-v*i, -0.2u))
        withcolor(0.5, 0.5, 0.5);
    label.bot(textext("$" & (decimal (v*i)) & "$"), (v*i, -0.2u))
        withcolor(0.5, 0.5, 0.5);


gives following error:

! Missing `,' has been inserted.
<to be read again> 
<for(1)> ...hcolor(0.5,0.5,0.5);label.bot(textext(
l.59     endfor
  • Where is textext defined? Commented Jan 21, 2019 at 7:58
  • textext is a MetaFun macro, so you have to process the file with mpost '&metafun' test.mp. Unfortunately, the output will only contain “unknown”. I asked on the mailing list why this is happening: mailman.ntg.nl/pipermail/ntg-context/2019/093806.html Commented Jan 21, 2019 at 7:59
  • @AndrewSwann I think it is part of metafun, which is part of ConTeXt.
    – flowian
    Commented Jan 21, 2019 at 8:00
  • It is also in latexmp, perhaps that has not been loaded. Commented Jan 21, 2019 at 8:01
  • How are you compiling the document?
    – Aditya
    Commented Jan 21, 2019 at 13:18

3 Answers 3


The error

The "some reason" is that in your MWE (as given) the textext macro is not defined, so MetaPost reads "textext" as a variable name token instead, in the hope that it will be able to expand it into an appropriate parameter for the label macro. When the tokenizer gets to the ( token, it can't add this to the variable name token that it's just read in any legal way, so it assigns the token to the first parameter for label and moves on to look for the next parameter. But label is defined (in plain.mp) with a comma token to separate the parameters, so the next thing in the input should be a , but it in fact is is a (. At this point the tokenizer admits defeat and throws the error that you see.

What can you do about it?

  1. As you have already discovered you can abandon textext altogether and just get a plain label. But that's a bit disappointing because it means the negative numbers in your loop get hyphens instead of mathematical minus signs (see the hack below for a quick way round this).

  2. As suggested in the comments, you can call mpost with the &metafun option so that it loads all the useful macros written for Context, including textext().

  3. You can put "input TEX" at the top of your program, and then replace your calls to textext() with calls to TEX() -- this works with plain mpost

  4. You can wrap your code up in an mplib shell like this, with the immensely useful \mplibtextextlabel{enable} option and compile with lualatex:

    u := 10mm; v := 0.8u;
    drawoptions(withcolor 1/2 white);
    for i=-5 upto 5:
        if i <> 0:
            draw (v*i, -1/10 u) .. (v*i, 1/10 u);
            label.bot("$" & decimal i & "$", (v*i, -1/5 u));
    draw (left--right) scaled 5.5v;

    (I made a couple of trivial tidy-ups...). Notice that this has the (great) advantage that you don't need a verbatimtex block. You just put your normal latex preamble in, to get: enter image description here

You may be able to guess by now that I would recommend option 4.

The promised hack

If you want to stick with plain MP, but you still want typographical minus signs in a loop, then here is a hack. First you need to choose a default font that is not cmr10. If you want Computer Modern then do

defaultfont := "texnansi-lmr10";  % for Computer Modern Roman

if you want Times (as in the OP) then do

defaultfont := "ptmr8r";

then you can try the following:

string minus_sign;
minus_sign := char 143; % if you are using the texnansi encoding
minus_sign := char 12;  % if you are using the 8r encoding
for x=-10 upto 10: 
   label(if x<0: minus_sign & fi decimal abs(x), (x*u,-5)); 

This is similar in spirit to Thruston's answer, but uses ConTeXt (rather than LaTeX). ConTeXt can directly compile Metapost files using

context filename.mp

provided you don't have any latexism in your code. This is roughly equivalent to compiling a ConTeXt document


So, if you want to change fonts etc., you can set a ConTeXt environment with all the relevant setups, and then run

context --environment=<name-of-environment-file> <name-of-mp-file>
  • I was thinking about this as well (of course) but keep in mind that OP is using the mathptmx package. I don't know whether there is an equivalent in ConTeXt. Commented Jan 21, 2019 at 20:30
  • Isn't \setupbodyfont[pagella] functionally equivalent?
    – Aditya
    Commented Jan 21, 2019 at 21:24
  • It's more similar to TeX Gyre Termes but not quite the same and only applies to math mode. Commented Jan 21, 2019 at 22:09

For some reason textext caused the problem.

Following simple label worked well inside for cycle.

label.bot(decimal (-0.8*i), (-v*i, -0.2u))

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .