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?

3 Answers3

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}

Peter Grill
  • 223,288
  • 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 04: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 05:04
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

JLDiaz
  • 55,732
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}}}
Alain Matthes
  • 95,075