# Insert \hfill after each character

I am creating a title page as follows:

\begin{titlepage}
\vspace*{1in}
\begin{center}
\parbox{0.8\textwidth}[s]{\HUGE%
T\hfill H\hfill I\hfill S\hfill
\hfill\hfill\hfill\hfill %space = 4xhfill
I\hfill S %no hfill after the last character of the line.
}\\
\parbox{0.8\textwidth}[s]{\HUGE%
M\hfill Y\hfill
\hfill\hfill\hfill\hfill
T\hfill I\hfill T\hfill L\hfill E
}\\
\end{center}
\vspace*{\fill}
\vspace*{1in}
\end{titlepage}


\HUGE is defined as follows: \def\HUGE{\fontsize{60}{60}\selectfont}.

I would like to replace the many X\hfill with an automated macro that inserts \hfill after each character automatically and replaces any whitespace with four \hfill, i.e. a macro that would allow me to write:

...
\begin{center}
\titleline{0.8\titlewidth}{THIS IS}\\
\titleline{0.8\titlewidth}{MY TITLE}\\
\end{center}
...


I am using (Xe)LaTeX and would like to make that macro in a package that would work on both systems, on classes such as article and book. I have no experience with other document classes.

Thank you.

-
take a look at the soul package (texdoc soul -- it's in tex live). this can be used to provide letterspacing and a lot more besides. comment on your code: multiple \hfills in one line can result in some serious warnings. – barbara beeton Jun 30 '12 at 21:49
@barbarabeeton: soul doesn't provide me with what I want; however, it is a nice addition to packages that I may find useful in the future. Also, I wasn't aware of any consequences at using multiple \hfills. – Minustar Jun 30 '12 at 22:09
Rather than using \hfill I'd suggest to give a look at the letter spacing features of microtype. I'd add that looking for a macro based solution that automatically inserts spaces is too much, for a title that won't have much more than 20 characters. – egreg Jul 1 '12 at 8:19

I don't particularly care for the output, but the following does more or less exactly what you wanted.

\documentclass{article}
\usepackage{lipsum}

% The user-facing command
\newcommand\titleline[2][0.8\linewidth]{%
}

\makeatletter
% rescan the argument with catcode 12 for spaces (so that they aren't ignored).
\begingroup\catcode =12\relax\xdef\tmp{\scantokens{#1\noexpand}}\endgroup%
}
% save catcode 12 space
\begingroup\catcode =12\relax\gdef\otherspace{ }\endgroup
% an end marker

\def\tmp{#1}%
\ifx\tmp\otherspace%
\hfill\hfill%
\else%
\hfill#1%
\fi%
\fi%
}

\begin{document}
\begin{center}
\titleline{THIS IS}
\titleline{MY TITLE}
\end{center}

\lipsum[1]
\end{document}


-
May I ask what the \noexpand is for? – Ryan Reich Jul 2 '12 at 1:14
@RyanReich: See tex.stackexchange.com/questions/9826/… – Caramdir Jul 2 '12 at 1:24

Here's a microtype based solution. I've used \Huge, but the principle is the same:

\documentclass{article}
\usepackage{microtype}
\begin{document}
\centering
\parbox{.8\textwidth}{\Huge
\parfillskip=0pt
\hrule
\medskip
\textls[200]{THIS IS MY TITLE}

\medskip
\hrule}
\end{document}


One of the keys is to set \parfillskip to zero, so TeX won't add any space to fill the paragraph's last line. You can adjust the optional argument to \textls until the result is satisfying; I believe that no automated solution can substitute your eye.

-

Here's an option using a regular \makebox. The optional alignment specification s spreads out its contents to fit within the given box width. Here's a minimal example:

\documentclass{article}
\begin{document}
\centering
\rule{.5\linewidth}{1pt} \par
\makebox[.5\linewidth][c]{THIS IS MY TITLE} \par
\makebox[.5\linewidth][s]{T H I S {} I S {} M Y {} T I T L E} \par
\makebox[.5\linewidth][s]{T H I S {} {} I S {} {} M Y {} {} T I T L E} \par
\rule{.5\linewidth}{1pt}
\end{document}


Adding {} increases the space allowed for interword spaces.

-

A solution using tikz and text along path decoration:

\documentclass{article}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{decorations.text}

\def\HUGE{\fontsize{60}{60}\selectfont}
\newlength{\heighttitle}%
\newlength{\depthtitle}%
\newcommand\bigtitle[2][\linewidth]{%
\noindent\HUGE\centering%
\begin{tikzpicture}
\path%
[postaction={decoration={text along path, text={|\HUGE|#2},
text align=fit to path}, decorate}]
(0,0) -- (#1,0);
\begin{pgfinterruptpicture}%
\setlength{\heighttitle}{\heightof{\HUGE #2}}%
\global\heighttitle=\heighttitle
\setlength{\depthtitle}{\depthof{\HUGE #2}}%
\global\depthtitle=\depthtitle
\end{pgfinterruptpicture}%
\coordinate (h) at (0pt,\heighttitle);
\coordinate (d) at (0pt,-\depthtitle);
\path[use as bounding box]
(current bounding box.west |- d)
rectangle
(current bounding box.east |- h);
\end{tikzpicture}\par%
}

\begin{document}
\begin{titlepage}
\bigtitle[.8\linewidth]{THIS IS}
\bigtitle[.8\linewidth]{MY TITLE}
\vfill
\bigtitle[\linewidth]{THIS IS}
\bigtitle[\linewidth]{MY TITLE}
\end{titlepage}
\begin{titlepage}

\end{titlepage}
\end{document}


-
TeX.SX rule 34: No matter what the problem is, someone will post a TikZ-based solution. ;) – Caramdir Jul 1 '12 at 0:58
@Caramdir: ;) It's not a perfect solution (right vertical alignment are not perfect). A solution without TikZ is obviously possible (desirable?) but I don't know how to split a string... – Paul Gaborit Jul 1 '12 at 1:21
@Caramdir: I found a way to split a string: xstring. See my other answer. – Paul Gaborit Jul 1 '12 at 9:01

Here's a solution using xstring and etoolbox:

\documentclass{article}
\usepackage{lmodern}
\usepackage{xstring}
\usepackage{etoolbox}
\def\HUGE{\fontsize{60}{60}\selectfont}
\newcommand\bigtitle[2][\linewidth]{%
{\def\result{\HUGE}%
\StrSplit{#2}{1}{\firstchar}{\rest}%
\eappto\result{\firstchar}%
\IfStrEq{\rest}{}{}{\restbigtitle{\rest}}%
\noindent\HUGE\centering
\makebox[#1]{\result}\par}

}
\newcommand\restbigtitle[1]{%
\StrSplit{#1}{1}{\firstchar}{\rest}%
\IfStrEq{\firstchar}{ }{%
\eappto\result{\hfill\hfill\hfill}%
}{%
\eappto\result{\hfill\firstchar}%
}%
\IfStrEq{\rest}{}{}{\restbigtitle{\rest}}%
}
\begin{document}
\begin{titlepage}
\null
\vfill
\bigtitle{THIS IS}
\bigtitle{MY TITLE}
\vfill
\bigtitle[.8\linewidth]{THIS IS}
\bigtitle[.8\linewidth]{MY TITLE}
\vfill
\bigtitle{THIS IS MY}
\bigtitle{TITLE}
\vfill
\null
\end{titlepage}
\end{document}


Edit: I use makebox instead of minipage to allow warning about overfull \hbox if text is too large.

-

I remember an answer from egreg to one of my questions and it may be a possibility.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\mytitle}{m}
{
\tl_map_inline:nn { #1 } { ##1 \hfill }
}
\ExplSyntaxOff

\begin{document}

\begin{minipage}{.4\textwidth}
\Huge
\mytitle{{THIS}  {IS} \\ {MY} {TITLE}\\}
\end{minipage}

\end{document}


-