6

I would like that (H) be at the left, and some text be in the middle of a line. However, the command below does not work since some text is at the right.

\centerline{(H)\hfill some text}

The following can do the job, but is there a more straightforward solution?

\centerline{\flushleft{(H)} \centerline{some text}}
6

For example:

\documentclass{article}
\begin{document}

\hrule % show line width

\noindent\rlap{(H)}\hfill some text\hfill\null\par

\hrule

\end{document}

Result

\noindent starts a new paragraph without indentation of the first line. \rlap prints its argument to the right. The middle text is centered by wrapping it in \hfill...\hfill. The \null at the end of the paragraph (\par) prevents that TeX removes the previous \hfill (TeX removes the last horizontal space at the end of the paragraph).

The \hfill at the right side can be replaced by the automatically inserted \parfillskip:

\noindent\rlap{(H)}\hfill some text{\setlength{\parfillskip}{\fill}\par}
  • \hspace*{\fill} is much better than using the undocumented \null – egreg Nov 6 '16 at 10:13
  • 1
    @egreg This also adds \parfillskip. This can be avoided by the longer \begingroup\setlength{\parfillskip}{\fill}\par\endgroup instead of the right \hfill. – Heiko Oberdiek Nov 6 '16 at 10:32
  • Uh? Usually \parfillskip uses fil glue. – egreg Nov 6 '16 at 10:43
  • 1
    Thank you, the border lines was not a part of question. – Name Nov 6 '16 at 11:40
  • @Name The border lines make it easier to see, that some text is in the middle of the line. – Heiko Oberdiek Nov 6 '16 at 11:51
6

Here's a fully LaTeX compliant solution.

\documentclass{article}
\usepackage{showframe} % just for the example

\newcommand{\lcrline}[3]{%
  \par % we want to be on a line by itself
  \noindent % no indent
  \makebox[\linewidth][s]{% spread to the line width
    \makebox[0pt][l]{#1}% text at left
    \hfill
    \makebox[0pt][c]{#2}% text at center
    \hfill
    \makebox[0pt][r]{#3}% text at right
  }%
  \par
}

\begin{document}

\lcrline{(H)}{some text}{}

\bigskip

\lcrline{Left}{Longer text in the middle}{Right}

\end{document}

enter image description here

Well, also

\def\lcrline#1#2#3{\par\hbox to \linewidth{\rlap{#1}\hss#2\hss\llap{#3}}

would work essentially the same. Why not using this? Because the above solution only uses documented commands in the LaTeX manual and, in case of a new version is released that breaks the macro above, you can hold it against the maintainers; the other one (similar in spirit to other answer to the present question) would be rejected with “we're responsible only for the documented features”.

An extended version that will warn in case there's overlap.

\documentclass{article}
\usepackage{showframe} % just for the example

\newcommand{\lcrline}[3]{%
  \par % we want to be on a line by itself
  %%% check for no overlapping
  \checklcrlineoverlap{#1}{#2}{#3}
  \noindent % no indent
  \makebox[\linewidth][s]{% spread to the line width
    \makebox[0pt][l]{#1}% text at left
    \hfill
    \makebox[0pt][c]{#2}% text at center
    \hfill
    \makebox[0pt][r]{#3}% text at right
  }%
  \par
}
\makeatletter
\newcommand\checklcrlineoverlap[3]{%
  \@tempswafalse
  \settowidth\@tempdima{#1}%
  \settowidth\@tempdimb{#2}%
  \ifdim\dimexpr\@tempdima+0.5\@tempdimb>.5\linewidth
    \@tempswatrue
  \fi
  \settowidth\@tempdima{#3}%
  \settowidth\@tempdimb{#2}%
  \ifdim\dimexpr\@tempdima+0.5\@tempdimb>.5\linewidth
    \@tempswatrue
  \fi
  \if@tempswa
    \@latex@warning{Overlap for \protect\lcrline}%
  \fi
}
\makeatother

\begin{document}

\lcrline{(H)}{some text}{}

\bigskip

\lcrline{Left}{Longer text in the middle}{Right}

\bigskip

\lcrline{Long long text at the left}{Longer longer text in the middle}{Right}

\bigskip

\lcrline{Left}{Longer longer text in the middle}{Long long text at the right}

\end{document}

The terminal and the log file would display

LaTeX Warning: Overlap for \lcrline on input line 47.

LaTeX Warning: Overlap for \lcrline on input line 51.
  • 1
    Thank you, the border lines was not a part of question. – Name Nov 6 '16 at 11:40
  • @Name I added them just for showing the alignment; remove the call to showframe. – egreg Nov 6 '16 at 11:49
  • I used \hss because... I don't know. Why in this case is \hfill the correct one? – Manuel Nov 6 '16 at 20:42
  • 1
    @Manuel Whatever… But \hss is not documented in the manual. – egreg Nov 6 '16 at 20:47
2
\usepackage{xparse}
\NewDocumentCommand\linetext{O{}mO{}}
  {\par\noindent
   \makebox[\textwidth][s]{\makebox[0pt][l]{#1}\hss\makebox[0pt][c]{#2}\hss\makebox[0pt][r]{#3}}}

And then use \linetext[left]{center}[right] where the first and third arguments are optional, hence you can write \linetext{center} or \linetext[left]{center} or \linetext{center}[right].

2

To your choice:

\documentclass{article}

\begin{document}

\leftline{(H)\hfil some text.}

or precisely

\leftline{\makebox[0pt][l]{(H)}\hfil some text.}

\noindent
(H)\hfil some text.

or precisely

\noindent
\makebox[0pt][l]{(H)}\hfil some text.

\end{document}

enter image description here

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.