# drawing a line the width of the text using tikz [duplicate]

Possible Duplicate:
A line of length \textwidth in TikZ

I'm trying to learn tikz. In this MWE all I'm trying to do it to draw a line the width of \linewidth. I'm able to do this with a rule; I'm able to do this in pstricks. But when I try this with tikz the line comes out too short; moreover, it seems to depend on what's happening in my paragraph in a way I'm not expecting (particularly considering where I'm defining my nodes in both cases).

\documentclass{article}
\usepackage{tikz}
\usepackage{pst-node}
\pagestyle{empty}
\begin{document}

\noindent%
\raisebox{0ex}[0pt][0pt]{\makebox[0pt][r]{\color{red}\rule[-4in]{0.4pt}{4.5in}}}%
\hspace*{\fill}{\color{red}\Huge $\leftarrow$ Struts to show the end line $\rightarrow$}\hspace*{\fill}%
\raisebox{0ex}[0pt][0pt]{\makebox[0pt][l]{\color{red}\rule[-4in]{0.4pt}{4.5in}}}%
\vspace{1cm}

Creating a rule:\newline
\noindent\rule{\linewidth}{0.4pt}%
\vspace{1cm}

Using \texttt{pstricks}:\newline
\noindent\rput(0,0){\rnode{ps:left}{}}\hspace*{\fill}\rput(0,0){\rnode{ps:right}{}}%

\psline(ps:left)(ps:right)
\vspace{1cm}

Using \texttt{tikz} \textbf{(round I)}:\newline
\tikz \node (tkzlefta) at (0,0) {};
\tikz \node (tkzrighta) at (\linewidth,0) {};%
\noindent\tikz \draw (tkzlefta) -- (tkzrighta);

Using \texttt{tikz} \textbf{(round II)}:\newline
\tikz \node (tkzleftb) at (0,0) {};%
\tikz \node (tkzrightb) at (\linewidth,0) {};%

\noindent\tikz \draw (tkzleftb) -- (tkzrightb);

Using \texttt{tikz} \textbf{(round III)}:\newline
\tikz \coordinate (tkzleftc) at (0,0);%
\tikz \coordinate (tkzrightc) at (\linewidth,0);%

\noindent\tikz \draw (tkzleftc) -- (tkzrightc);

Using \texttt{tikz} \textbf{(round IV)}:\newline
\tikz \node[inner sep=0pt] (tkzleftd) at (0,0) {};%
\tikz \node[inner sep=0pt] (tkzrightd) at (\linewidth,0) {};%

\noindent\tikz \draw (tkzleftd) -- (tkzrightd);

\end{document}


I've incorporated HarishKumar's suggestion. Seems to work when I use coordinate (round III). But not working with inner sep=0pt applied to the nodes (round IV). Also, what's going on with the indentation in round I that's not occurring in round II? I would assume that the paragraph break should not be changing the placement of the nodes; but that's exactly what seems to be happening.

-

## marked as duplicate by Paul Gaborit, Thorsten, N.N., Stefan Kottwitz♦Dec 28 '12 at 9:16

@HarishKumar, I've followed your advice. It works with coordinates but now I'd like to know what happening in the other places where things are still not as I would like. What's making the difference between round I and round II? Why is round IV still not quite right? –  A.Ellett Dec 27 '12 at 23:13
I suggest that each line should be one 'tikzpicture', by putting the two nodes/coordinates and the \draw command into a \begin{tikzpicture}...\end{tikzpicture} environment, or using the \tikz{...} form (with braces) containing all three directives. Perhaps consult the manual to see how to do this. –  cyberSingularity Dec 27 '12 at 23:22
@Qrrbrbirlbel. Tried that. I see nodes now, but don't know how that helps me (other than it shows nodes that seem to have no connection to the end points of the line); they're not even draw close to the position I would expect to find them. –  A.Ellett Dec 27 '12 at 23:25
@HarishKumar, the end of line character only partially explains what's happening in round 1, but I don't see where there's an end of line error in round IV. –  A.Ellett Dec 27 '12 at 23:25
@A.Ellett Maybe you should add what your final goal is? Simply a horizontal rule? \noindent\tikz\draw (0,0) -- (\linewidth-\pgflinewidth,0); –  Qrrbrbirlbel Dec 27 '12 at 23:31

Node or coordinate does not matter at the point when you use three \tikz macros.

NB: If I say “TikZ picture” I mean either a solely \tikz macro or the tikzpicture environment.

Further reference on remember picture and overlay can be found in the PGF manual in section 16.13 “Referencing Nodes Outside the Current Pictures”, pp. 199f.)

As I already suggested in the comments, draw the nodes and you will find that those at (0,0) and at (\linewidth,0) are just sitting together. (Depending on the line-ending %s with a little space between them.)

Take a look at the following example:

### Code I

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\usepackage[pass,showframe]{geometry}
\tikzset{every node/.style={
draw,
%   inner sep=0pt,
}
}
\begin{document}
\noindent
\tikz \node (tkzlefta) at (0,0) {};% where am I?
\tikz \node (tkzrighta) at (\linewidth,0) {};% where am I?
\tikz \node[green] (bignumber) at (40cm,-1cm) {};% not on paper you say?

\noindent\tikz\draw (tkzlefta) -- (tkzrighta) -- (bignumber);
\end{document}


### Output I

What happens here?

The whole TikZ picture will be cropped (“bounding box”) and put in one (TeX) box. The coordinates (x,y) are not related to the physical paper.

Also take a close look at the line end. The horizontal line and the line to bignumber are not connected, because the node is there.

If you add remember picture to the \tikz and without % at the end of line (to have at least a little space between those nodes).

### Code II

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\usepackage[pass,showframe]{geometry}
\tikzset{every node/.style={
draw,
%   inner sep=0pt,
}
}
\begin{document}
\noindent
\tikz[remember picture] \node (tkzlefta) at (0,0) {};
\tikz[remember picture] \node (tkzrighta) at (\linewidth,0) {};
\tikz[remember picture] \node[green] (bignumber) at (40cm,-1cm) {};

\noindent\tikz\draw[blue] (tkzlefta) -- (tkzrighta) -- (bignumber);%
\tikz[overlay, remember picture]\draw[green] (tkzlefta) -- (tkzrighta) -- (bignumber);
\end{document}


### Output 2

This looks better as it uses the actual boxes (that TikZ remembers) to connect.

What have we learned?

1. TikZ outputs boxes, nothing else. The actual placement is up to TeX. (There is a special node current page, though.)
2. Without remember picture TikZ only remembers the coordinates but not the picture (picture is either \tikz or the tikzpicture environment).
3. With remember picture TikZ remembers the actual (comparatively) placement on TeX paper but still, the box is just typeset by TeX.
4. With remember picture and overlay TikZ finally connects the actual boxes!
5. Do not use nodes.

But that is not what you are after anyway?

There are a few ways to get what you want.

The first solution uses only one TikZ picture. This is typeset by TeX.
So you will need an otherwise empty paragraph and \noindent.

Here you can see that TikZ’s way to set the correct bounding box is not optimal as it apparently pads the line additional by .5\pgflinewidth on both ends.

The yellow line solves this with \hspace trickery but as \pgflinewidth is only known inside a TikZ picture we need to use -.2pt manually. (The standard line width (thin) in TikZ is .4pt.)

The green line uses TikZ \clip path that is in fact a rectangular (the line has a width!).

The second solution actually places coordinates at the start and the end of the line (hfill); this is also known as (Google Search); see the third solution. These solutions need to be compiled at least twice!

The TikZmark macro I provide is a very rudimentary one. There is a TikZ library that can deal with marks on different page, provides an extra coordinate system for “remembered” coordinates and and and …

## Solution 1 (one TikZ picture)

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\usepackage[pass,showframe]{geometry}
\begin{document}

\noindent\hrulefill

\noindent\tikz\draw[red] (0,0) -- (\linewidth,0);% gives Overfull \hbox (0.4pt too wide)

\noindent\hspace{-.2pt}\tikz\draw[yellow] (0,0) -- (\linewidth-.5\pgflinewidth,0);%

\noindent\tikz{% do a line width change in the \tikz macro: \tikz[line width=1pt]
\clip (0,-.5\pgflinewidth) rectangle ++(\linewidth,\pgflinewidth);
\draw[green] (0,0) -- (\linewidth,0);
}
\end{document}


## Solution 2 (“TikZmark” but without the actual macro)

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\usepackage[pass,showframe]{geometry}
\begin{document}

\noindent\hrulefill

\noindent\tikz[remember picture]\coordinate (tikzleft);%
\hfill%
\tikz[remember picture]\coordinate (tikzright);%
\tikz[remember picture, overlay]\draw (tikzleft)--(tikzright);

% The following is not pictured in the image below.
\noindent\tikz[remember picture]\coordinate (tikzleft2);%
\hfill%
\tikz[remember picture]{
\coordinate (tikzright2);
\draw[overlay] (tikzleft2) -- (tikzright2);
}%
\end{document}


## Solution 3 (\tikzmark)

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\usepackage[pass,showframe]{geometry}
\newcommand*{\tikzmark}[2][]{%
\tikz[remember picture, #1]\coordinate (#2);%
}
\begin{document}

\noindent\hrulefill

\noindent\tikzmark{tikzleft}\hfill\tikzmark{tikzright}%
\tikz[remember picture, overlay]\draw (tikzleft)--(tikzright);
\end{document}


## Output (solution 2 and 3)

-
So this is where some of my confusion is coming in. The line seems to be drawn (close to) correctly. But, the nodes are not shown in the positions at the end of the line. Why? How can the line be drawn as it is when the nodes are adjacent to each other? –  A.Ellett Dec 27 '12 at 23:50
OMG, this is fantastic. You've given me a lot food for thought. I've got to play with this a bit to see what I understand. But thank you for the extensive explanation. –  A.Ellett Dec 28 '12 at 0:38

A node will not produce a geometric point even if the text is empty and the inner sep is set to zero. To produce a point, one should use \coordinate. Also the end of line character should be taken care of by adding the % at the end. Also, it may be noted that you are defining a node here by means of horizontal dimensions, not vertical dimensions that are fixed with the page. Hence the node position will/can vary vertically.

\documentclass{article}
\usepackage{tikz}
\usepackage{pst-node}
\pagestyle{empty}
\tikzset{every node/.style=draw}
\begin{document}

\noindent%
\raisebox{0ex}[0pt][0pt]{\makebox[0pt][r]{\color{red}\rule[-5in]{0.4pt}{5.5in}}}%
\hspace*{\fill}{\color{red}\Huge $\leftarrow$ Struts to show the end line $\rightarrow$}\hspace*{\fill}%
\raisebox{0ex}[0pt][0pt]{\makebox[0pt][l]{\color{red}\rule[-5in]{0.4pt}{5.5in}}}%
\vspace{1cm}

Creating a rule:\newline
\noindent\rule{\linewidth}{0.4pt}%
\vspace{1cm}

Using \texttt{pstricks}:\newline
\noindent\rput(0,0){\rnode{ps:left}{}}\hspace*{\fill}\rput(0,0){\rnode{ps:right}{}}%

\psline(ps:left)(ps:right)
\vspace{1cm}

Using \texttt{tikz} \textbf{(round I)}:\newline
\tikz \node (tkzlefta) at (0,0) {};
\tikz \node (tkzrighta) at (\linewidth,0) {};%
\noindent\tikz \draw (tkzlefta) -- (tkzrighta);%

Using \texttt{tikz} \textbf{(round II)}:\newline
\tikz \node (tkzleftb) at (0,0) {};%
\tikz \node (tkzrightb) at (\linewidth,0) {};%
\noindent\tikz \draw (tkzleftb) -- (tkzrightb);%

Using \texttt{tikz} \textbf{(round III)}: Using coordinates and \% at the end\newline
\tikz \coordinate (tkzleftc) at (0,0);%
\tikz \coordinate (tkzrightc) at (\linewidth,0);% % < put % here
\noindent\tikz \draw (tkzleftc) -- (tkzrightc);

Using \texttt{tikz} \textbf{(round IV)}: \verb|inner sep = 0pt|\\%
\tikz \node[inner sep=0pt] (tkzleftd) at (0,0) {};%
\tikz \node[inner sep=0pt] (tkzrightd) at (\linewidth,0) {};%
\noindent\tikz \draw (tkzleftd.center) -- (tkzrightd.center);%

Using \texttt{tikz} \textbf{(round V)}: You can see the nodes drawn at left and right:\\%
{\tikz \node[inner sep=0pt] (tkzleftd) at (0,0) {};%
\hfill
\tikz \node[inner sep=0pt] (tkzrightd) at (\linewidth,0) {};%

\noindent\tikz \draw (tkzleftd) -- (tkzrightd);}%

Using \texttt{tikz} \textbf{(round VI)}: You should draw it from centers of nodes:\\%
{\tikz \node[inner sep=0pt] (tkzleftd) at (0,0) {};%
\hfill
\tikz \node[inner sep=0pt] (tkzrightd) at (\linewidth,0) {};%

\noindent\tikz \draw (tkzleftd.center) -- (tkzrightd.center);}%

Conclusion: Don't use nodes but coordinates. or

\noindent\tikz\draw (0,0) -- (\linewidth,0);

\end{document}


# Conclusion:

DON'T use nodes when you want a point but coordinate.

Just to answer why the nodes are put together despite their defined position: When you use \tikz the picture is just treated like a text so no separate bounding box from tikz is provided unlike the tikzpicture environment Hence the two nodes are put in a way like two letters by tex.

Using Qrrbrbirlbel's code we just demonstrate this:

\documentclass{article}
\usepackage{tikz}
\pagestyle{empty}
\usepackage[pass,showframe]{geometry}
\tikzset{every node/.style={
draw,
%   inner sep=0pt,
}
}
\begin{document}

Using \verb|\tikz|:

\noindent
\tikz \node (tkzlefta) at (0,0) {};% where am I?
\tikz \node (tkzrighta) at (\linewidth,0) {};% where am I?
%\tikz \node[green] (bignumber) at (40cm,-1cm) {};% not on paper you say?
%
%\noindent\tikz\draw (tkzlefta) -- (tkzrighta) -- (bignumber);

Using \verb|tikzpicture| environment:

\noindent
\begin{tikzpicture}
\node (tkzlefta) at (0,0) {};% where am I?
\node (tkzrighta) at (\linewidth,0) {};% where am I?
% \node[green] (bignumber) at (40cm,-1cm) {};% not on paper you say?
%
%\draw (tkzlefta) -- (tkzrighta) -- (bignumber);
\end{tikzpicture}
\end{document}


-
This does solve the particular problem I asked. Unfortunately, I now have many more questions as I play around with this and get all sorts of effects I'm not expecting: for example, instead of using ".center" using ".east" or ".west" and getting things shifted around. Oh how I hate learning new things when you already have another approach you understand (pstricks). But I do want to learn tikz; so, I dive in. You answer is very helpful. I am sure I'll be back soon with more questions. –  A.Ellett Dec 28 '12 at 0:30