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've been playing around with dropcaps in LaTeX (with the yfonts and lettrine packages), and one typographical effect you often see after dropcaps is having the entire first line of the paragraph typeset in small caps. It's clear how to get this effect by trial and error—run LaTeX, see what's on the first line, \textsc that, rerun LaTeX, see what's moved, and re-\textsc the appropriate text—but that's a royal pain, and it's too easy to forget to do. Is there a good way to get (La)TeX to detect the location of linebreaks in its typeset output? I presume I'd have to run LaTeX at least twice, since things could change mid-processing, but such is life with LaTeX.


Edit 1: I need this to work for math-mode ($...$) code as well—from the solutions so far suggested, this is not necessarily non-trivial.

share|improve this question
add comment

3 Answers

up vote 12 down vote accepted

Donald Arseneau's magaz package will do this for you. From memory, it uses roughly the same idea shown by Yiannis — that is, only a single pass is necessary — but I think it may be slightly more robust.

This solution will work with inline maths provided the maths does not break over the end of the line, as here:

\documentclass{article}
\usepackage{magaz}
\begin{document}
\FirstLine{There is no just \emph{ground}, therefore, $a+b=c$ for the charge $x\in\{0,1,2\}$ brought against me by certain ignoramuses.}
\end{document}

But putting the maths inside an \mbox seems to fix this problem.


Readers of this answer may wish to select a color for the first line. This requires a slightly different approach which is discussed in David Carlisle's answer in the thread Why does color meant for first typeset line ONLY (with package magaz) affect ENTIRE document?

share|improve this answer
    
This seems really nice—it parses the entire paragraph, which should let it do more optimal line-break detection—but it doesn't work. If I feed it the lorem ipsum paragraph, I get a "Bad text for \FirstLine" error; if I feed it just a fragment (less than a line) of it, said fragment gets deleted and the rest is typeset. Have you ever had any luck using magaz? –  Antal S-Z Oct 14 '10 at 23:43
    
By the lipsum text, do you mean \lipsum[1]? That might not work because it ends with a \par. I'll try the package out myself later today. –  Will Robertson Oct 14 '10 at 23:54
3  
Well, that was faster than it had any right to be, and easier too—magaz and pdfsync don't play nice together. Removing pdfsync made everything work. The hyphenation is slightly different than manual-small-capitalization, but it's only off by something like half a word. It looks like the only remaining problem is integrating it with dropcaps, which should be doable. –  Antal S-Z Oct 15 '10 at 0:09
1  
@Will Robertson: I compiled your example and got the piece "for the charge" twice. Strange! –  Hendrik Vogt Oct 16 '10 at 11:30
1  
@Antal Were you able to get magaz to play nicely with lettrine? I am trying to get initial capitals + first line small capitals, but it appears that \FirstLine gets tripped up by the initial capital, and winds up applying the special formatting to too much text. –  Aaron Mar 6 '11 at 6:31
show 6 more comments

Here is a TeXie solution!

    \documentclass[11pt]{article} 
    \begin{document}

    \def\firstline{\par\begingroup\Firstlinefont
      \def\zzz{}\dimen0\parindent
      \setbox0=\hbox{ }\advance\dimen0by-\wd0
      \x}
    \def\x{\afterassignment\y\z}
    \def\z#1 {\xdef\zz{#1\ }}
    \def\y{\setbox0=\hbox{\zz}
      \advance\dimen0 by\wd0
      \ifdim\dimen0<\hsize\let\next=\x
        \edef\zzz{\zzz\zz}
      \else\let\next=\endgroup
        \leavevmode\zzz\unskip\break\aftergroup\zz
      \fi
      \next}


    \let\Firstlinefont=\scshape  

    \firstline The first line of this paragraph is in small caps font series. You
    will need to hack the rest of the code to get it working with the lettrine package!

\end{document}
share|improve this answer
    
Clever! I like it. –  TH. Oct 14 '10 at 23:09
    
Thanks for this! I just plugged this into my document, and it mostly works, except for a couple of things. First: running it with lorem ipsum text yields suboptimal results for the first line. Since this just grabs words and sets them, it can't do any reflowing; thus, the first line is awkwardly widely spaced compared to a hand-tuned solution (which can fit an extra word). I don't know if there's a way around this, though Second: this chokes on math text, and while I can read your code, I don't know if I could modify it :-) Do you know if it'd be possible to support that? Again, thanks. –  Antal S-Z Oct 14 '10 at 23:40
    
After Will's suggestion I had a look at ftp.riken.go.jp/pub/CTAN/macros/latex/contrib/magaz/magaz.sty I did not try it but perhaps you should give it a go. Problem with my code it will not do hyphenation. What you are looking for is not easy:) –  Yiannis Lazarides Oct 14 '10 at 23:53
1  
Very elegant! but it fails to compile when the paragraph is shorter than a line ;-) (try with \firstline The first line of this paragraph). I shamelessly point this out because I had the same problem with the first version of my answer and it took me some toil to fix it! –  jfbu May 3 '11 at 7:12
    
@jfbu Thanks I would have a look! Donald Arseneau's code is the best, as it iterates 3-4 times to get everything right! –  Yiannis Lazarides May 4 '11 at 16:12
add comment

(I came to this from the duplicate question Emphasize first line of paragraph in LaTeX)

Yiannis solution is very nice. Here is another method, which leads to less visual differences between the first two lines in the way the inter-word spaces are treated. My code presumably leads to inferior results in general compared to Yiannis's (the emphasizing can extend to the beginning of the second line or end a bit too short in the first line), but I do propose it as it is simpler minded than Yiannis's sophisticated macros! Also it seems to work with the example including inline mathematics, and allows hyphenation at the end of the first line (but the emphasizing applies to entire words).

Inline math should be written (whenever there is a chance it will belong to the emphasized text) either without spaces (e.g. $a+b=c$) or be enclosed in doubled braces (e.g. {{$ a + b = c $}}). Then, breaking at the end of lines will work correctly.

The code defines two user commands \decorate and \Decorate (as well as other commands to decide the style of the emphasized text). \decorate is used as \decorate{TEXT} (where TEXT cannot contain a \par token), and \Decorate is to be put at the beginning of a paragraph (so can't be used in a \parbox for example, contrarily to the lowercase form).

Both admit an optional parameter (default value 0.95) which gives a rough idea of the number of lines to which the emphasizing will be applied.

And \Decorate has a starred version \Decorate* which tries to provoke expansion of the paragraph to which it is applied (see the end of the code for a comparative illustration). It is not possible though to use \lipsum[1] as an argument (even with option nopar to package lipsum), but lipsum@i is ok.

\documentclass[a4paper]{article}
\makeatletter

\def\addtobufferwithaspace#1#2{\expandafter\def\expandafter#1%
               \expandafter{#1 #2}}

\def\deco@step#1{%
   \setbox1=\hbox{\deco@buffer{} #1}%
   \dimen0\hsize\advance\dimen0-\parindent\relax
   #1
   \ifdim\wd1>\deco@scale\dimen0
     \expandafter\deco@trail
   \else
     \addtobufferwithaspace\deco@buffer{#1}%
     \expandafter\deco@parsei
   \fi
}

\def\deco@trail#1\@nil{\deemphasizingcommand #1}

\def\deco@parsei#1{\ifnot@nil{#1}{\deco@parse #1}}

\def\deco@parse #1 {\deco@step{#1}}

\newcommand*{\decorate}[2][.95]{%
   \def\deco@scale{#1}%
   \def\deco@buffer{\emphasizingcommand}%
   \emphasizingcommand
   \deco@parse #2 \@nil
   \deemphasizingcommand
}

\def\@@Decorate[#1] #2\par{\decorate[#1]{#2}\par}

\def\@@eDecorate[#1] #2\par{%
     \def\@decorate{\decorate[#1]}%
     \edef\@Decorated{\noexpand\@decorate{#2}}%
     \@Decorated\par}

\newcommand*\@Decorate[1][.95]{\@@Decorate[#1] }
\newcommand*\@eDecorate[1][.95]{\@@eDecorate[#1] }

\newcommand*\Decorate{\@ifstar{\@eDecorate}{\@Decorate}}

\makeatother

\newcommand{\emphasizingcommand}{\bfseries} 
\newcommand{\deemphasizingcommand}{\normalfont\normalsize} 
\usepackage[nopar]{lipsum}

\begin{document}

\Decorate
  I am (of course) shocked! and appalled! I have a particular typesetting
  task, described below. Trying to find out how to emphasize the line of text
  automatically. The issue here is that I have no idea where the line would
  break.  Ideally it would be start paragraph with slanted shape and then
  revert to upright shape upon first line break.  

\Decorate[.5] I am (of course) shocked! and appalled! I have a particular
  typesetting task, described below. Trying to find out how to emphasize the
  line of text automatically.

\renewcommand{\emphasizingcommand}{\bfseries\slshape}

\noindent\parbox{5cm}{\decorate{
  I am (of course) shocked! and appalled! I have a particular typesetting
  task, described below. Trying to find out how to emphasize the line of text
  automatically. The issue here is that I have no idea where the line would
  break.  }}
\parbox{3cm}{\decorate{
  I am (of course) shocked! and appalled! I have a particular typesetting
  task, described below. Trying to find out how to emphasize the line of text
  automatically. The issue here is that I have no idea where the line would
  break.  }}
\parbox{2.5cm}{\raggedright\decorate{
  I am (of course) shocked! and appalled! I have a particular typesetting
  task, described below. Trying to find out how to emphasize the line of text
  automatically. The issue here is that I have no idea where the line would
  break.  }}
\parbox{2.5cm}{\raggedleft\decorate{
  I am (of course) shocked! and appalled! I have a particular typesetting
  task, described below. Trying to find out how to emphasize the line of text
  automatically. The issue here is that I have no idea where the line would
  break.  }}

\renewcommand{\emphasizingcommand}{\ttfamily\Large\frenchspacing}
\renewcommand{\deemphasizingcommand}{\normalfont\normalsize\nonfrenchspacing}

\begin{center}
  \begin{minipage}{0.5\linewidth}
    \centering
    \Decorate[1.5] 
    I am (of course) shocked! and appalled! I have a
    particular typesetting task, described below. Trying to find out how to
    emphasize the line of text automatically. The issue here is that I have no
    idea where the line would break.  Ideally it would be start paragraph with
    slanted shape and then revert to upright shape upon first line break.
    \par
  \end{minipage}
\end{center}

\renewcommand{\emphasizingcommand}{\scshape}

\Decorate There is no just \emph{ground}, therefore, \mbox{$ a + b = c $} for
  the charge $x\in\{0,1,2\}$ brought against me by certain ignoramuses $ x
  \in\{ 0,1,2 \}$.

\Decorate Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Ut purus elit, vestibulum ut, placerat ac,
adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu
libero, nonummy eget, consectetuer id, vulputate a, magna.

\Decorate[4] Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Ut purus elit, vestibulum ut, placerat ac,
adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu
libero, nonummy eget, consectetuer id, vulputate a, magna.


\renewcommand{\emphasizingcommand}{\bfseries}
%% \clearpage

\decorate{Let's try with  a short sentence.}
\decorate[.2]{And another one.}
\decorate[.2]{And another one.}
\decorate[.2]{And another one.}

\makeatletter

\Decorate* \lipsum@v

\Decorate* \lipsum@vi

\Decorate*[1] \lipsum@vii

\makeatother

\def\tmpa{dolor sit amet, consectetuer
adipiscing elit. Ut purus elit, }

\Decorate[.1] \tmpa \tmpa

\Decorate*[.1] \tmpa \tmpa

\end{document}
share|improve this answer
    
Regarding inline math, $ a + b = c $, or more generally any space inbetween the two $, will make decorate choke; but the fix is simply to add braces: {$ a + b = c $}. No need here for an mbox. Also, the braces are needed only for the math which will belong to the first line or the very beginning of the second... –  jfbu Apr 29 '11 at 20:41
    
I have edited my answer, as the previous version was faulty in case of an argument shorter than a (typeset) line. Inline math which will end up in the first line should be typed either without spaces ($a+b=c$) or enclosed in an \mbox (contrarily to my previous comment, with the new version braces are not enough). –  jfbu Apr 30 '11 at 10:05
    
I again edited my answer, this time to add the \Decorate form which is more convenient to use in the source. I also added a starred variant which tries to expand its argument before formatting; this is not always usable, but does help sometimes. See the code and its output. –  jfbu Apr 30 '11 at 17:50
    
Regarding inline mathematics, in fact no \mbox is necessary: but one should use doubled braces like {{$ a + b = c$}}, or as mentioned before write up the code without any space $a+b=c$. –  jfbu May 1 '11 at 21:42
add 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.