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.
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 there seems to be no extra magic happening.
Thanks,
RhysOn Wed, 13 Apr 2022 at 21:18, Rhys Tyers <rhystyers1@gmail.com> wrote:Hello again,
I’m hoping someone can help me work out a metapost problem. The code is available here and pasted below.
None of us know anything about metapost so this is a copy/paste job of this 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 lThe
<br>is not replaced by a new line and in fact the<and>are rendered as question marks.
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 likeHoover \\ Damthen 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} etexI 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