How to get a properly centred horizontal rule?

I'm trying to produce a horizontal rule 2/3 the textwidth and centred. It's much harder than expected, as it pulls to the left. I've tried putting noindent but that makes it worse, as this MNWE shows:

\documentclass[12pt]{article}
\begin{document}
This line is 2/3 textwidth with hspace\{stretch\} either side and no indent:

\noindent\hspace{\stretch{1}}\rule{0.67\textwidth}{0.1pt}\hspace{\stretch{1}}

This line is 2/3 textwidth with hspace\{stretch\} either side:

\hspace{\stretch{1}}\rule{0.67\textwidth}{0.1pt}\hspace{\stretch{1}}

This line is 4/5 textwidth with hspace\{stretch\} either side:

\hspace{\stretch{1}}\rule{0.8\textwidth}{0.1pt}\hspace{\stretch{1}}

This line is 9/10 textwidth with hspace\{stretch\} either side:

\hspace{\stretch{1}}\rule{0.9\textwidth}{0.1pt}\hspace{\stretch{1}}

This line is full textwidth:

\hspace{\stretch{1}}\rule{\textwidth}{0.1pt}\hspace{\stretch{1}}

This line is full linewidth:

\hspace{\stretch{1}}\rule{\linewidth}{0.1pt}\hspace{\stretch{1}}

\end{document}


I've also tried just using \hfills instead of the \hspace{\stretch{1}}s, but that produces the same effect. What am I missing?

-
After studying the various answers, I see what I missed. My real work uses scrbook which is setting \parindent0cm in some way or other, but that isn't operative here. When I added that at the start of my MNWE, it then looked fine. I was fooled because none of my text wrapped to a second line, and so the centering of text and rules looked different. Silly me. –  JGC Apr 27 at 22:48

And a very short version: \centerline{\rule{0.6667\linewidth}{.2pt}}:

\documentclass{article}

\begin{document}

\parindent2cm

document document document document document
document document document document document
document document document document document
document document document document document
document document document document document

\centerline{\rule{0.6667\linewidth}{.2pt}}

\end{document}


-
Thank you; this is simple and effective. I'd not come across \centerline before; it doesn't seem to crop up often in tutorials. –  JGC Apr 27 at 22:37
@JGC \centerline is a plain TeX construction, so often omitted in LaTeX tutorials. –  Przemysław Scherwentke Apr 27 at 22:45

The following example defines macro \parseprule for a rule that separates paragraphs with width of 2/3 the current line width (\linewidth takes into account lists). It also raises the line to approximately get in the middle between the paragraphs.

\documentclass{article}
\usepackage{lipsum}

\newcommand*{\parseprule}{%
\par
\begingroup
\centering
\raisebox{.2\baselineskip}{%
\rule{.6667\linewidth}{.4pt}%
}%
\par
\endgroup
}

\begin{document}
\lipsum[2]

\par{\centering\raisebox{.2\baselineskip}{\rule{.9\linewidth}{.4pt}}\par}

\lipsum[2]

\parseprule

\lipsum[2]

\end{document}


Remarks:

• \centering does not insert vertical space as environment center.

• TeX uses the settings for a paragraph that are active at the end of the paragraph. Therefore the first \par is outside the group to end the previous paragraph not in the scope of \centering. The last \par is inside the group, because the paragraph with the rule should be centered.

• \strut as approximation for the height/depth ratio of a line uses 0.7\baselineskip for the height and 0.3\baselineskip for the depth. Therefore the macro raises the line from the baseline to 0.2\baselineskip.

General remarks

• Paragraph indentation. TeX adds the space \parindent at the start of a new paragraph unless it is suppressed by \noindent. \centering sets \parindent to 0pt, thus it does not matter, if the paragraph starts with \noindent or not.

• At the paragraph end, TeX removes a preceding horizontal skip space. Usually this is the space by the end of line. If the paragraph ends with \hfill then it is removed. Then TeX inserts \parfillskip. Default is 0pt plus 1fil, that allows that the text of the last line does not need to fill the space.

• Each line gets the spaces \leftskip and \rightskip at both ends, usually they are zero, but this can change in lists, for example. \centering uses them for centering the line by setting them both to 0pt plus 1fil.

-

What is wrong with?

\documentclass[12pt]{article}
\usepackage[showframe]{geometry}
\usepackage{lipsum}
\begin{document}

\lipsum[1]
\noindent\hfil\rule{.666\linewidth}{.4pt}\hfill

\lipsum[1]

\end{document}


-
I think the \hfillat the end gets eaten (and replaced with \parfilskip), henc is superfluous; in fact, if this were not the case, it would be stronger than the \hfilin the beginning! –  Hagen von Eitzen Apr 26 at 21:32

You need to play around with the indentation lengths:

\documentclass{article}
\begin{document}

This line is 2/3 \verb|\textwidth| with \verb|\hfill| either side and \verb|\noindent|:

\noindent\makebox[\linewidth]{\hfill\rule{.6667\textwidth}{.4pt}\hfill}

This line is 2/3 \verb|\textwidth| with \verb|\hfill| either side without \verb|\noindent|:

\makebox[\dimexpr\linewidth-\parindent]{\hfill\rule{.6667\textwidth}{.4pt}\hfill\hspace*{\parindent}}

Also see:

\mbox{}\hfill\rule{.6667\linewidth}{.4pt}\hfill\hspace*{\parindent}

\end{document}


Note that while I mention \textwidth, I actually use \linewidth. As such, the above will change if you're calling it from inside a list environment where margins have been adjusted.

If you're going to use this often as some form of textual divider, I suggest following the advice in Consistent typography and create a macro to house the rule.

The above can be combined with Totally sweet horizontal rules in LaTeX.

-