Custom Metapost label can't display newlines or accents
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
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 <rhystyers1@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
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 <rhystyers1@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 <rhystyers1@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
On Sat, Apr 23, 2022 at 9:56 PM Rhys Tyers <rhystyers1@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.
Hi, sorry for a late answer -- there was some issue with our mailing list and the posts from the last few weeks were sent in a batch last Saturday. Regarding ATTR_text, therion doesn't do any special processing of special sequences like <br> or accented characters. Maybe it should (the same way as it does for standard -text attributes), I'll think about it. Martin
participants (2)
-
Martin Budaj -
Rhys Tyers