Re: [Therion] Custom label style for a custom point
Tarquin No answer to your question, but to check that have seen these. I looked at a similar thing a while ago. You have probably found this thread https://www.mail-archive.com/therion@speleo.sk/msg07234.html Search for 'boxed label'. Sorry I have no time to figure out where I got to, I was going to write it up but did not get to it. Also the wiki has some discussion of alignment and rotation of symbols https://therion.speleo.sk/wiki/metapost#symbol_sizing_and_positioning (down the page just a little). My theory is that most Therion point symbols are defined so that alignments plot incorrectly if they also have a rotation applied. ie T:=identity aligned A rotated R scaled S shifted P; aligns your symbol, then rotates your alignment! and T:=identity rotated R aligned A scaled S shifted P; rotates your symbol, then applies the (correct) alignment. Yes, both labels and arrows seem to be quite complicated, and interrelated with other features. Bruce -----Original Message----- From: Therion <therion-bounces@speleo.sk> On Behalf Of Tarquin Wilton-Jones via Therion Sent: Wednesday, 27 November 2019 07:14 To: therion@speleo.sk Cc: Tarquin Wilton-Jones <tarquin.wilton-jones@ntlworld.com> Subject: [Therion] ***UNCHECKED*** Custom label style for a custom point Hi all, Next puzzle... I am trying to define a custom point type: p_u_ropelength This will allow me to specify rope lengths on a rigging topo. What I want is exactly what Therion does for a p_passageheight - a circle around a label, which has been the norm in UK topos for decades (though they are also sometimes written as a basic label with no circle). This should be easy, but Therion seems to hide the p_passageheight code, or at least put it somewhere I can't find it in order to work out how it works. I am guessing it calls p_label with txt set to the text, pos set to the point position, and mode set to 5 (p_label_mode_passageheight). But somehow it is also specifying the scale and I can't see how it does that since it ignores my attempts, and it also seems to work with Align there, while with my own code, it applies align with the most tiny fractional changes, instead of moving the label as far as I would have expected. Obviously I am doing something wrong. def p_u_ropelength (expr P,R,S,A)= T:=identity aligned A rotated R scaled S shifted P; if known ATTR_text: p_label(ATTR_text,P,R,5); fi; enddef; Does anyone have a nice working example where A and S are correctly respected, so that I can see how to apply them when calling p_label? Do I have to manually parse A and call the correct p_label.lft(...) to get the right alignment, or is there a way to ask it to do that? Incidentally, you can set orientation on a p_label, but not on a p_passageheight - the orientation is ignored. Seems like a bug... _______________________________________________ Therion mailing list Therion@speleo.sk https://mailman.speleo.sk/listinfo/therion
I looked at a similar thing a while ago. You have probably found this thread https://www.mail-archive.com/therion@speleo.sk/msg07234.html
Yes, thanks for the pointer though, because it means I am not alone. What makes me worry is that I have to modify Therion's own Metapost code for something so fundamental, which brings with it the chance that I might cause some breakage later when Therion gets updated. That particular workaround is pretty cool though, and I would love for it to become a standard feature for all labels, like: point label -style 5 -text "foo" That way, those of us who want to apply a different style to just a handful of labels, could do so without breaking all the others (Stacho's suggestion would have applied to all height labels at once, which is not desired here).
My theory is that most Therion point symbols are defined so that alignments plot incorrectly if they also have a rotation applied.
Quite likely, but for now I stick to the convention in my own symbols, not because it is right, but because it is (more) consistent.
I think I actually might have got it... Pretty sure that some optimisations are possible; eg. I am using a set of hardcoded S numbers -> TEX sizing strings. There might be an inbuilt method to do that for you, but I couldn't immediately see it. I don't know if these numbers are subject to change either - do different base scales change the value of S, for example? But it works. You can set the size of the text, the ornamentation of the text (using Therion's inbuilt string->TEX functionality), and the alignment of the text. Some ornamentation styles do not respect rotation - that is a bug in Therion's text processing. Perhaps someone will now point out a glaring problem (like strings containing \foo or } which I think will break the TEX, but I also think this happens elsewhere in Therion...). But hopefully this gives a nice base for other people who needed this functionality to work from. I don't quite know what the "\framed { text here }" part does, since it seems to have no effect, but Therion uses it for all of the ornamented labels but not for basic labels. vardef create_styled_label (expr plaintext,P,R,S,A,defaultstyle)= save textsize, style; 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; def p_u_ropelength (expr P,R,S,A)= T:=identity shifted P; U:=(0,0); if known ATTR_text: % approximate size (varies with proportional font) U:=(S*u*(length ATTR_text)/4,S*u*(length ATTR_text)/4); create_styled_label(ATTR_text,P,R,S,A,p_label_mode_passageheight); fi; enddef; initsymbol("p_u_ropelength"); You can see that all it does is to produce the right TEX string (so it respects scaling), and then calls the right version of p_label (so it respects alignment). It relies on p_label to support rotation. If the symbol has "-attr labelstyle 5" it will use that label style. There is then an example point symbol that uses it with a string stored in "-attr text", and sets its T and U accordingly. However, there is no requirement for it to be a dedicated point symbol - you could just as easily call it to put a label anywhere you choose, such as beside some existing symbol (so you could have a warning triangle symbol, with some text in a box beside it, for example). Aside; One other issue with replacing the p_label macro like Stacho suggested is that you end up using a small chunk of the existing Therion code. This in turn means that you need to license all of yours under GPL (because it is GPL not LGPL). If your survey is intended to be released under some other license, you can't make a derivative work from a chunk of Therion code.
participants (2)
-
Bruce Mutton -
Tarquin Wilton-Jones