0

Suppose I have the following in tikz:

\node[right] at (0,0) {$A=\{1\}$};

But I would like to write this as five separate nodes, each representing a character in the above. In other words, one node for each:

A

=

{

1

}

I spent a long time experimenting, but could find no apparent pattern. In fact, it turns out that

\documentclass{beamer}
\usepackage{tikz}
\usefonttheme[onlymath]{serif}

\begin{document}

\begin{frame}
\begin{tikzpicture}[scale=1]
\node[right] at (0,0) {$A=\{1\}$};
\end{tikzpicture}

\end{document}

is equivalent (more or less) to

\documentclass{beamer}
\usepackage{tikz}
\usefonttheme[onlymath]{serif}

\begin{document}

\begin{frame}
\begin{tikzpicture}[scale=1]
\node[right] at (0,0.04) {$A$};
\node[right] at (0.405,-0.025) {$=$};
\node[right] at (0.805,0) {$\{$};
\node[right] at (1,0.03) {$1$};
\node[right] at (1.18,0) {$\}$};
\end{tikzpicture}
\end{frame}

\end{document}

Seriously, WTF? Is there a better way to do this?

  • 1
    in luatex you could (in theory) dissect the typeset box to determine the glyph positions but in classic tex it's basically impossible to unpick a typeset box. For a trivial expression as you have in the example you could calculate the spacing by hand as you know there is a \thickmuskip either side of the = but in general you would have to re-implement all tex math typesetting logic in tex macros. – David Carlisle Jan 26 at 0:16
  • 2
    what is your actual use case, there is probably a different way of achieving the end goal – David Carlisle Jan 26 at 0:20
  • Similarly to @DavidCarlisle I think this may be an XY question. Are you by chance looking for \subnode that ships with tikzmark? – Schrödinger's cat Jan 26 at 0:22
  • And if it's only about not wanting to manually position but being okay with multiple nodes there is the chains library. – TeXnician Jan 26 at 21:36
  • Compare [anchor=west] with [anchor=base west]. Also [inner sep] affects spacing, and one should use ${}={}$ with math operators. – John Kormylo Jan 27 at 15:09
1

This is not a serious answer but just a code that does something along the lines you want.

\documentclass{article}
\usepackage{tikz}
\usepackage{soul}
\newcounter{nodepart}
\usetikzlibrary{positioning}
\makeatletter
\DeclareRobustCommand*{\SplitMathNodes}{%
  \SOUL@setup
  \def\SOUL@preamble{\setcounter{nodepart}{0}}%
  \def\SOUL@everytoken{\stepcounter{nodepart}%
    \ifnum\value{nodepart}=1
     \node[inner sep=0pt] 
     (\pgfkeysvalueof{/tikz/nodepart}-\number\value{nodepart}) {$\the\SOUL@token$};
    \else
     \node[inner sep=0pt,
        base right=0pt of \pgfkeysvalueof{/tikz/nodepart}-\the\numexpr\value{nodepart}-1]
    (\pgfkeysvalueof{/tikz/nodepart}-\number\value{nodepart})   {$\the\SOUL@token$};
    \fi}%
  \SOUL@
}
\makeatother
\begin{document}
\begin{tikzpicture}[nodepart/.initial=A]
\SplitMathNodes{A=\{1\}}
\foreach \X in {1,...,\number\value{nodepart}}
{\draw[stealth-] (\pgfkeysvalueof{/tikz/nodepart}-\X)--(\pgfkeysvalueof{/tikz/nodepart}-\X|-0,1em) node[above,font=\tiny\sffamily]{\X};}
\end{tikzpicture}
\end{document}

enter image description here

As you can see, it decomposes your expressions in its atoms, and turns them into nodes. Using the base right key allows us to avoid using explicit coordinates.

So far so good. BUT the spacing will in general not be great. Even worse, you cannot feed something like E=mc^2 in the expression because it won't understand the ^. You can probably fix some of these issues but in the end the true LaTeX output will never be perfectly obtained.

It appears to me that this might be an XY question, though. Two tools that come to my mind which achieve similar things are

  • \subnode which ships with the tikzmark library, and
  • the text effects along path decoration which also allows you to access each character of an expression.

It might very well be that they allow you to do what you want to do with the decomposed node.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.