8

Here is a code that computes the length of a line and attaches it to the line. So far, so good, but in math mode somehow additional zeros get appended to the distance.

\documentclass{article}
\usepackage{amsmath}

\usepackage{tikz}
\usetikzlibrary{decorations.text,decorations.pathreplacing,decorations.pathmorphing}
\makeatletter 
\tikzset{%
 type/.code={\pgfextra{
\pgfmathsetmacro{\MyLen}{veclen(\the\pgf@pathmaxx-\the\pgf@pathminx,\the\pgf@pathmaxy-\the\pgf@pathminy)/28.45365}
 \global\xdef\NewLen{\MyLen}}}
}
\makeatother

\tikzset{
dimstyle/.style={postaction={type,decorate,
   decoration={text along path,raise=2pt,
   text={$L=\NewLen$},text align=center}},
   },decoration={brace},decorate
}

\begin{document}
\begin{tikzpicture}
   \coordinate (A) at (0,0);
    \coordinate (B) at (3,4);

   \draw [dimstyle] (A)--(B);
\end{tikzpicture}

\end{document}

enter image description here

On the other hand, if I replace in the above text={$L=\NewLen$} by text={$L=$\NewLen} (i.e. print in text rather than math mode), I get

enter image description here

Question: Where do the additional zeros come from?

  • 1
    Off-topic: I think that \global\xdef is redundant. As far as I understand \xdef is the short form of \global\edef, so \global\xdef would be \global\global\edef. – Phelype Oleinik Feb 27 '18 at 20:32
  • Why not just avoid it with $L={}$\NewLen – Steven B. Segletes Feb 27 '18 at 20:36
  • 2
    You want to see something really crazy, try text={$L={\NewLen}$} – Steven B. Segletes Feb 27 '18 at 20:40
  • 1
    @StevenB.Segletes Sure, I could avoid it like this, my question is why this happens. Note also that the code does not terminate if I put \NewLen in \text{}. –  Feb 27 '18 at 20:40
  • @StevenB.Segletes I know, and our messages crossed. –  Feb 27 '18 at 20:41
  • @PhelypeOleinik Yes, you're definitely right. Note, however, that removing the \global won't change the situation. –  Feb 27 '18 at 20:42
  • 2
    Check out \pgfmathprintnumber and number format starting on page 945 (section 92). – John Kormylo Feb 27 '18 at 20:49
  • 1
    @StevenB.Segletes You want to see something really, really crazy, try text={$L=\the\dimexpr\NewLen pt\relax$}. This means that the additional zeros aren't a number truncation thing, but it's TikZ repeating the last character of the input string... – Phelype Oleinik Feb 27 '18 at 20:52
  • @JohnKormylo Thanks! That's certainly helpful, but it is not clear to me how this explains the feature. Notice that in math mode it will add enough digits to fill the available space, i.e. `\coordinate (A) at (0,0); \coordinate (B) at (6,8);

    \draw [dimstyle] (A)--(B);` will give you much more digits.

    –  Feb 27 '18 at 20:54
  • 1
    @marmot It looks like TikZ is repeating the last character only if it is math mode. Try text={$L=\NewLen$~}. Very strange... – Phelype Oleinik Feb 27 '18 at 20:55
  • @PhelypeOleinik Yes, further evidence can be obtained by making the distance longer like here. –  Feb 27 '18 at 20:56
  • You might experiment with number format={assume math mode=true} – John Kormylo Feb 27 '18 at 20:58
  • @JohnKormylo Thanks again. Certainly your statements contain the key. Yet I'm lacking the full picture. –  Feb 27 '18 at 21:00
  • 2
    Just text={$a$} suffices to trigger the repetition. It has nothing to do with number printing. – egreg Feb 27 '18 at 21:11
  • 1
    I traced the problem to the file texmf-dist/tex/generic/pgf/libraries/decorations/pgflibrarydecorations.text.code.tex. In there, the macro \pgf@lib@dec@text@scanchar scans the text recursively until it is \pgfutil@empty (which is an empty macro). The problem is that the text never gets emptied. Once the scanner reaches the second $ it starts the scanning again. This is as far as I could go :( – Phelype Oleinik Feb 27 '18 at 21:17
  • Here I found a related question, this great feature seems not to be limited to math mode nor to numbers. –  Feb 27 '18 at 21:17
  • @PhelypeOleinik Makes sense and most likely also explains the feature here. So you can answer two questions at once ;-) –  Feb 27 '18 at 21:19
  • @marmot Yes, I checked and the process in \pgf@lib@dec@text@scanchar is the same for both questions. But I don't know why it happens, I just discovered where. – Phelype Oleinik Feb 27 '18 at 21:24
  • 2
    See https://tex.stackexchange.com/questions/75256/how-to-insert-math-with-curly-brackets-into-tikz-decoration-text-along-path#comment160873_75257 Indeed, text={$L=\NewLen${}} avoids the repetition. – egreg Feb 27 '18 at 21:36
  • 1
    Note that you can also avoid it using text effects along path. text along path always does this: text, numbers, symbols, whatever. The example here is needlessly complex: most of the included elements are not needed to trigger the issue. – cfr Feb 27 '18 at 23:27
  • @cfr I am not disputing any of your statements. It is just that I was initially very surprised, and so were many others. And IMHO it is sort of an issue that might get fixed, nobody really needs these repetitions. –  Feb 28 '18 at 01:16
  • I don't know why it adds zeros (although I suppose I should). But I do know the manual states in the text along path decoration docs: "However, even modestly complex mathematical typesetting is unlikely to be successful along a path (or even desirable)." – Mark Wibrow Feb 28 '18 at 07:30
  • @MarkWibrow Yes. But naively I would expect "However, even modestly complex mathematical typesetting is unlikely to be successful along a path (or even desirable)." to cause an error, and not this repetition. Please note also that this is not limited to mathematical expressions, as you can see here and to some extent also here . (Obviously, I was not aware of these posts when I submitted my question.) So there seems to be something on top of "Please don't do math here". –  Feb 28 '18 at 13:52

1 Answers1

7

In pgflibrarydecorations.text.code.tex line 274-277

\def\pgf@lib@dec@text@endoftext{%
  \let\pgfdecoraterestoftext\pgfutil@empty%
  \let\pgf@lib@dec@text@char\pgfutil@empty%
}

it should be
\pgfdecorationrestoftext instead of
\pgfdecoraterestoftext.

MWE:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\makeatletter
\def\pgf@lib@dec@text@endoftext{%
    \let\pgfdecorationrestoftext\pgfutil@empty%
    \let\pgf@lib@dec@text@char\pgfutil@empty%
}

\begin{document}
\begin{tikzpicture}
   \coordinate (A) at (0,0);
   \coordinate (B) at (3,4);
   \draw[decorate,decoration={text along path,text={$abc$},text align=center}](A)--(B);
   \draw(A)--(B);
\end{tikzpicture}

\end{document}
Symbol 1
  • 36,855