In the interest of archiving the answer I ended up simply redefining the
p_label function:

# Overwrite the point label function to allow specifying
# style and label level
layout custom_label
        code metapost
                # Set the maximum label level that will appear
                max_level := 100;
                vardef set_label_level (expr mylevel)=
                        max_level := scantokens(mylevel);
                enddef;

                vardef p_label@#(expr txt,pos,rot,mode_)=

                        # Allow specifiying the style on a single label
                        if known ATTR_style:
                                mode := scantokens(ATTR_style);
                        else:
                                mode := mode_;
                        fi;

                        # Specify the level at which this label should appear
                        if known ATTR_level:
                                level := scantokens(ATTR_level);
                        else:
                                level := 0;
                        fi;

                        if (level <= max_level):
                                if (mode=1) or (mode=7):
                                        interim labeloffset:=(u/8);
                                fi;
                                lab:=thelabel@#(txt, pos);
                                if mode>1:
                                        pickup PenD
                                fi;
                                if mode=1:
                                        pickup pencircle scaled (u/6);
                                        drawdot(pos);
                                        process_label(pos,0);
                                elseif 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;
                        else:
                                # Metapost is expecting some sort of drawing so
                                # we just draw an empty string
                                lab:=thelabel@#("", pos);
                                process_label(pos,rot);
                        fi;
                enddef;
        endcode
endlayout

This has the levels functionality as well as displaying all text using the
correct fonts and characters.

On Sun, 17 Apr 2022 at 22:00, Rhys Tyers <rhystye...@gmail.com> wrote:

> Just in case a simplification makes the question/answer clearer, I'll
> retry my question from above:
>
> I define a user label:
>
> def p_u_label (expr P,R,S,A)=
>     lab:=thelabel(ATTR_text, P)
>     process_label(P, R)
> enddef;
> initsymbol("p_u_label");
>
> This for example will not print a Č character, but the standard Therion
> label will.
>
> How do I make this display text the same way that a normal Therion label
> does?
>
> I’ve read through a lot of the Therion source trying to find out where
> this happens but in the relevant bit
> <https://github.com/therion/therion/blob/master/mpost/thText.mp> there
> seems to be no extra magic happening.
>
> Thanks,
> Rhys
>
> On Wed, 13 Apr 2022 at 21:18, Rhys Tyers <rhystye...@gmail.com> wrote:
>
>> 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
>>
>>
_______________________________________________
Therion mailing list
Therion@speleo.sk
https://mailman.speleo.sk/listinfo/therion

Reply via email to