Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to automatically adjust the title page to get a pleasing result independent of the title size. This means that I have to count the number of line breaks in an argument.

My MWE (not very pleasing to make it really minimal)

\documentclass{book}

\makeatletter

\newcommand{\maketitlepage}[1]{% the title page is generated here
  \edef\caesar@titlespace{\the\dimexpr 210pt - 15pt * #1 \relax}% calculate the necessary space
  \cleardoublepage%
  \begingroup%
  {%
  \noindent\LARGE\@author\par
  \vfill%
  \noindent\fontsize{30}{38}\selectfont\@title\par
  \vfill%
  \vspace{\caesar@titlespace}%
  \Large\noindent\publisher\par
  }%
  \endgroup%
  \clearpage%
}

\makeatother

\title{This is\\a title}
\author{John Doe}
\newcommand{\publisher}{Some University}

\begin{document}
\maketitlepage{2} % two lines
\title{This is\\new\\a title}
\maketitlepage{3} % three lines

\end{document}

Please note that I manually count the lines and provide \maketitlepage the extra argument. I cannot figure out how to calculate it automatically.

share|improve this question
2  
Wouldn't be easier (and more logical) to measure the total height of the title? This is surely possible using \sbox, \vbox and \ht. As well, it would be bullet-proof for the case when a normal linebreak appears. –  tohecz Nov 7 '12 at 15:54
    
Yes, that would probably be even better. Could you give a short answer how to achieve that? –  Andy Nov 7 '12 at 15:58
    
I did measuring first and then divided by baselinskip to get a rought linecount but decided to do the loop counting lines instead exactly:-) –  David Carlisle Nov 7 '12 at 21:18
add comment

1 Answer

up vote 8 down vote accepted
\documentclass{article}

\title{aaa\\b\\bb}

\begin{document}

\makeatletter

\setbox0\vbox{\noindent\fontsize{30}{38}\selectfont\@title\par
\count@\z@
\loop
\unskip\unpenalty\unskip\unpenalty\unskip
\setbox0\lastbox
\ifvoid0
\xdef\numlines{\the\count@}%
\else
\advance\count@\@ne
\repeat}

\show\numlines
\stop

this leaves the number of lines in \numlines :

> \numlines=macro:
->3.
l.20 \show\numlines

If instead you just want to go by the height of the title just do something like the following instead:

\setbox0\vbox{\noindent\fontsize{30}{38}\selectfont\@title}

\ifdim\ht0> 70pt .... \else ... \fi
share|improve this answer
1  
I have no idea how \lastbox works. Is the key here to use \unskip\unpenalty\unskip\unpenalty\unskip (for whatever reason) until \lastbox becomes void? Would you elaborate on the contents inside \loop...\repeat? –  Werner Nov 7 '12 at 22:18
    
@Werner \lastbox removes the last item from the current list if it was a box (and in this case stores it in box register 0) the unskip and unpenalty through away any baseline glue or inter-line penaltites. With a bit of luck there are no \special or \mark nodes so if each iteration of the loop \lastbox should take off a line of text until there is no line left when it will be void. –  David Carlisle Nov 7 '12 at 22:47
    
@Werner A more careful loop that checks for all the possible node types with comments and better explanation in egreg's answer here tex.stackexchange.com/questions/28064/… –  David Carlisle Nov 7 '12 at 22:48
    
Your solution got a performance hit (unfortunately down) in the latest TeXLive using LuaLaTeX. Does anyone know why this is or even how to achieve the same using some (faster?!) lua code? –  Andy Dec 18 '13 at 12:09
    
@Andy does it? That's bizarre as it's classic tex code that would have run in tex82, I'm surprised that bit of luatex changed much. If it's reproducible you could try raising it on the luatex support list. I expect it can't be answered without the sources open in a debugger:-) –  David Carlisle Dec 18 '13 at 14:21
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.