[Therion] Custom Metapost label can't display newlines or accents

Rhys Tyers rhystyers1 at gmail.com
Wed Apr 13 22:18:17 CEST 2022


Hello again,

I’m hoping someone can help me work out a metapost problem. The code is
available here
<https://github.com/iccaving/migovec-survey-data/blob/master/layouts/metapost/user_label.thl>
and pasted below.

None of us know anything about metapost so this is a copy/paste job of this
<https://www.mail-archive.com/therion@speleo.sk/msg07234.html> code with
some extensions. We want a label that can be turned displayed or hidden
depending on a level variable. In a system survey I turn off lots of labels
because there is lots of overlapping passage, but on more detailed ones I
turn them back on. This level thing works well.

What does not work is new lines or any non-ascii character. I have played
around with this for a while and can’t work out how to make it work.

I.e. this point:

point 174.2178 755.6161 u:label_MY -attr lvl 1 -attr text
"Hoover<br>Dam" -align tr -scale l

The <br> is not replaced by a new line and in fact the < and > are rendered
as question marks.
[image: image.png]


I think Therion does a substitution of <br> and it’s not real html or tex
but if I try to use tex in there like Hoover \\ Dam then it just errors
during compilation:

[495] (./mptextmp.mp) [496] [497] [498] (./mptextmp.mpfatal: Command
failed: etex --parse-first-line --interaction=nonstopmode
mpTXLjoJ.tex; see mpxerr.log
>> mptextmp.mp
>> mptextmp.mpx
! ! Unable to read mpx file.
l.2 btex
         \mainfont \thframed {\thnormalsize Hoover \\ Dam} etex

I think this is because we are somehow not rendering with tex, and only
rendering with metapost which has a limited character set, but I really
have no idea.

Any help would be greatly appreciated!

The metapost code:

layout user_label

    code metapost

        def p_LABEL(expr pos)=
            T:=identity shifted pos;
            pickup PenD;
            p:=fullcircle scaled .1u;
            thclean p; thdraw p;

            if known ATTR_text:
                text := scantokens(ATTR_text);
                thdrawoptions(withcolor .8red + .4blue);
                txtm:=image(
                draw txt;
                interim labeloffset:=0;
                label.urt(btex text etex);
                );
                % draw label
                lab:=thelabel@#(txtm, pos);
                draw lab _thop_; % use color
                thdrawoptions();
                bboxmargin:=0.8bp;
                write_circ_bbox((bbox lab) smoothed 2);

            enddef;

            def p_altitude(expr pos)=
                T:=identity shifted pos;
                pickup PenD;
                p:=(-.3u,0)--(.3u,0);
                thdraw p; thdraw p rotated 90;
                p:=fullcircle scaled .2u;
                thclean p; thdraw p;
            enddef;


            vardef p_label@#(expr txt,pos,rot,mode) =
                if mode=1:
                    thdrawoptions(withcolor .8red + .4blue);
                    p_altitude(pos);
                    % append "m" to label
                    picture txtm;
                    txtm:=image(
                    draw txt;
                    interim labeloffset:=0;
                    label.urt(btex \thaltitude m etex, lrcorner txt);
                    );
                    % give extra offset in case of l/r/t/b alignment
                    pair ctmp;
                    ctmp:=center thelabel@#("x", (0,0));
                    if (xpart ctmp * ypart ctmp)=0:
                        interim labeloffset:=(.4u);
                    else: % diagonal alignment
                        interim labeloffset:=(.2u);
                    fi;
                    % draw label
                    lab:=thelabel@#(txtm, pos);
                    draw lab _thop_; % use color
                    thdrawoptions();
                    bboxmargin:=0.8bp;
                    write_circ_bbox((bbox lab) smoothed 2);
                else:
                    if mode=7:
                        interim labeloffset:=(u/8);
                    fi;
                    lab:=thelabel@#(txt, pos);
                    if mode>1:
                        pickup PenD
                    fi;
                    if mode=2:
                        process_uplabel;
                    elseif mode=3:
                        process_downlabel;
                    elseif mode=4:
                        process_updownlabel;
                    elseif mode=5:
                        process_circledlabel;
                    elseif mode=6:
                        process_boxedlabel;
                    elseif mode=7:
                        process_label(pos,rot);  % station name
                    elseif mode=8:
                        process_filledlabel(pos, rot);
                    else:
                        process_label(pos,rot);
                    fi;
                fi;
            enddef;

            vardef set_label_level (expr mylevel)=
                maxl := scantokens(mylevel);
            enddef;


            def p_u_label_MY (expr P,R,S,A)=
                T:=identity shifted P;
                U:=(0,0);
                save lvl;
                save style;
                if known ATTR_style:
                    style:= scantokens(ATTR_style);
                else:
                    style :=0;
                fi;
                if known ATTR_text:
                    if known ATTR_lvl:
                        lvl := scantokens(ATTR_lvl);
                    else: lvl :=0;
                    fi;
                    if lvl < maxl+1:
                        U:=(S*u*(length ATTR_text)/4,S*u*(length ATTR_text)/4);
                        create_styled_label(ATTR_text,P,R,S,A,style);
                    else:;
                    fi;
                fi;
            enddef;
            initsymbol("p_u_label_MY");


            % https://www.mail-archive.com/therion@speleo.sk/msg07234.html
            % define a custom attribute called label_mode

            vardef create_styled_label (expr plaintext,P,R,S,A,defaultstyle)=
                save textsize, style, thetext;
                string textsize;
                if S = 0.5:
                    textsize:="\thtinysize";
                elseif S = 0.7:
                    textsize:="\thsmallsize";
                elseif S = 1.4:
                    textsize:="\thlargesize";
                elseif S = 2:
                    textsize:="\thhugesize";
                else: % normal is 1
                    textsize:="\thnormalsize";
                fi;
                if known ATTR_labelstyle:
                    style:=scantokens(ATTR_labelstyle);
                else:
                    style:=defaultstyle;
                fi;
                picture thetext;
                thetext:=thTEX("\thframed {" & textsize & " " &
plaintext & "}");
                if A = (-1,1):
                    p_label.ulft(thetext,P,R,style);

                elseif A = (0,1):
                    p_label.top(thetext,P,R,style);

                elseif A = (1,1):
                    p_label.urt(thetext,P,R,style);

                elseif A = (-1,0):
                    p_label.lft(thetext,P,R,style);

                elseif A = (1,0):
                    p_label.rt(thetext,P,R,style);

                elseif A = (-1,-1):
                    p_label.llft(thetext,P,R,style);

                elseif A = (0,-1):
                    p_label.bot(thetext,P,R,style);

                elseif A = (1,-1):
                    p_label.lrt(thetext,P,R,style);

                else:
                    p_label(thetext,P,R,style);

                fi;
            enddef;

        endcode
    endlayout
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.speleo.sk/pipermail/therion/attachments/20220413/4d24b215/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 27396 bytes
Desc: not available
URL: <http://mailman.speleo.sk/pipermail/therion/attachments/20220413/4d24b215/attachment-0001.png>


More information about the Therion mailing list