5

I was wondering if there is a way to get the following behavior using TikZ (overlaying text with at a location relative to the anchor point in the text)

enter image description here

The code would look like this:

Here is a list:

\begin{itemize}
\item One
\item Two
\item Three
\end{itemize}

Here's what I want:

\begin{itemize}
\item \placetext{2007,-0.3cm,0cm} One
\item \placetext{2009,-0.3cm,0cm} Two
\item \placetext{2012,-0.3cm,0cm} Three
\end{itemize}

where the command \placetext{text,x_location,y_location} should place the text text at the relative location x_location and y_location from the anchor point on the text.

I have been experimenting with the following code that I found in this thread to ask LaTeX and TikZ to print text that "does not take space" with no success.

\makebox[0pt][c]{%
\begin{tikzpicture}[scale=4, overlay]
\node[draw=none,fill=none]  {Hello};\end{tikzpicture}}

Is this possible at all with TikZ? How can I do it?

7

You don't need tikz for this:

\documentclass{article}
\begin{document}

\def\placetext#1#2#3{%
\setlength{\unitlength}{1cm}%
\begin{picture}(0,0)%
\put(#2,#3){\llap{#1}}%
\end{picture}%
}

Here's what I want:

\begin{itemize}
\item \placetext{2007}{-.5}{0}One  % Note: no space after the macro
\item \placetext{2009}{-.5}{0}Two
\item \placetext{2012}{-.5}{0}Three
\item Four
\end{itemize}
\end{document}

Output

Update

If for some reason (for example, in order to apply tikz styles to the "floating" text), youn insist in using tikz, you can still use \tikz inside \put, using LaTeX picture environment. But there is a caveat. If you don't use any path from (0,0) to the text position, the resulting box generated by tikz would not contain (0,0) and thus will not be properly positioned. Also you have to set correctly the baseline of the tikz picture, in order to align it properly with the \item text.

Here you have a MWE:

\documentclass{article}
\usepackage{tikz}
\def\placetext#1#2#3{%
\begin{picture}(0,0)%
\put(0,0){\llap{\tikz[baseline=(m.base)]\path (0,0)--(#2,#3) 
  node[left, fill=orange!30] (m) {#1};}}
\end{picture}%
}

\begin{document}
Here's what I want:

\begin{itemize}
\item \placetext{2007}{-.7}{0}One
\item \placetext{2009}{-.7}{0}Two
\item \placetext{2012}{-.7}{0}Three
\item Four
\end{itemize}
\end{document}

Output

8

Here is a TikZ solution using the infamous \tikzmark macro to mark a particular place in the document, and \PlaceText to place the text. The \PlaceText macro accepts an optional first parameter that can be used to customize the text, as shown in the second two cases below:

enter image description here

Note:

  • This does require two runs. First one to determine the locations, and the second to do the drawing.
  • The name of the mark passed to \tikzmark is arbitrary and has no relation to the text, but the same name that was used to name the mark needs to be passed to the \PlaceText macro.

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

\newcommand*{\PlaceText}[4][]{%
    \begin{tikzpicture}[overlay,remember picture]
        \node [anchor=base, #1] at ($(#2) + (#3)$) {#4};
    \end{tikzpicture}%
}%

\begin{document}
Here's what I want:
\begin{itemize}
  \item \tikzmark{First} One
  \item \tikzmark{Second} Two
  \item \tikzmark{Third} Three
\end{itemize}

\PlaceText{-0.85cm,0.0cm}{First}{2007}
\PlaceText[text=black, fill=red!30, draw=black, dashed]{-0.85cm,0.0cm}{Second}{2009}
\PlaceText[text=blue, fill=yellow]{-0.85cm,0.0cm}{Third}{2012}

\end{document}
  • Not that it's a big deal, but I just realized after the recent spate of \tikzmark answers that you should be using \coordinate rather than \node. Because you are making a coordinate. – Ryan Reich Jul 10 '12 at 4:48
  • @RyanReich: Hmmm...Yes, the \tikzmark should use \coordinate. Good point... I think it is left over since sometimes there were cases where \tikzmark had to measure the width of the node for later use. I will try to go thru these this weekend and fix that. – Peter Grill Jul 10 '12 at 5:04
3

You can get the result without tikz and without picture.

\documentclass{article}
\usepackage{xcolor} 
\newcommand\placetext[2][-0.5cm]{\hspace*{#1}\llap{\colorbox{yellow}{#2}}\hspace*{-#1}} 
\begin{document}

Here's what I want:

\begin{itemize}
\item \placetext{2007}One 
\item \placetext{2009}Two 
\item \placetext{2012}Three 
\item Four
\end{itemize}
\end{document} 

enter image description here

It's possible to get some refinements with \raisebox if you want to use another argument for a vertical adjustment.

Another idea from egreg is to define \placetext with a \makebox

\newcommand\placetext[2][0.5cm]{\makebox[0pt][r]{\colorbox{yellow}{#2}\hspace{#1}}}
  • Why not \makebox[0pt][r]{#2\hspace{#1}}? – egreg Jul 10 '12 at 10:44
  • @egreg yes it's possible but what is the advantage ? – Alain Matthes Jul 10 '12 at 10:58
  • The code is more compact and manageable. Also \makebox is "color safe", while \llap isn't. – egreg Jul 10 '12 at 11:00
  • What do you mean by "color safe" ? I updated my example and I added a color. – Alain Matthes Jul 10 '12 at 11:54
  • Try \color instead of \colorbox. It might work, but the color declaration could also spill out. – egreg Jul 10 '12 at 12:43

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.