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 make a nice layout that gives a different style to the first line in a section using the package magaz. All examples I have seen feature some variation of small caps {\scshape text} or upper case \MakeUppercase{text}.

I would like to change the font and the color.

This works well for the font but the color unfortunately affects the entire document rather than just the first line.

\documentclass[12pt,english,american]{article}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}

\makeatletter

\usepackage{mathpazo}
\usepackage{xcolor} 
\usepackage{magaz}

\newcommand{\FirstLineCommand}[1]{\noindent\fontfamily{iwona}\fontseries{bc}\selectfont{\textcolor{red}{#1}}}

\renewcommand\FirstLineFont{\FirstLineCommand}

\makeatother

\usepackage{babel}
\begin{document}
\selectlanguage{english}%

Hello just testing.

Normal \textcolor{red}{color switching} should work.

\FirstLine{Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.}

Some more text.
\end{document}

As you can see, I define a command \FirstLineCommand to pass on to the magaz package as a \FirstLineFont

If I use instead

\newcommand{\FirstLineCommand}[1]{\noindent\fontfamily{iwona}\fontseries{bc}\selectfont{\MakeUppercase{#1}}}

that works just fine.

I am clearly not a guru when it comes to latex syntax, so after some tinkering with adding extra braces here and there and moving the color statement around (and trying {\color text} instead of \textcolor{text}, I'm still stumped.

I'd be happy if you could help me color the first typeset line of the paragraph only.

share|improve this question
    
Welcome to TeX.sx! Notice that changing the color is a close-to-impossible task because such change modifies the line-breaking, and LaTeX always breaks lines only after a whole paragraph is finished. However, change of the colour should be possible, but I think you have to use LuaLaTeX for it. –  tohecz Dec 9 '12 at 21:47
    
sorry, I wrote a non-sense, it should be: "Notice that changing the font variant ..." –  tohecz Dec 9 '12 at 21:56
    
@tohecz, the font variant can be changed using the magaz package. It's not perfect (for example ideally you'd like a different linespacing if the first line is set larger), but magaz sets the paragraph 3 different times to make it work in many cases, even if the line breaking would be different. –  Lev Bishop Dec 9 '12 at 21:59
    
@tohecz and @Lev Bishop, thank you for your welcoming comments. The font series (is this what you mean by font variant?) is changed by magaz as intended. I used iwona bold condensed for illustration. Incidentally, magaz changes the font as intended also for hyphenated words. Unfortunately I found my example code garbled somewhat answering your comments. I have re-edited my post, please run it through pdflatex to see how it comes out - everything is as intended except the color. –  Andreas Dec 9 '12 at 22:20
add comment

1 Answer 1

up vote 17 down vote accepted

The reason that it fails for colour is that unlike fonts colour is not a primitive property of the box, colour is implemented by having colour change nodes at the start and end of a colour range. If you split up and re-organise a box after it is typeset those colour nodes can (and usually will) get separated from their text. Donald's package does more than the average amount of box re-arranging:-)

enter image description here

\documentclass[12pt,english,american]{article}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}



\usepackage{mathpazo}
\usepackage{xcolor} 
\usepackage{magaz}
\newcommand{\FirstLineCommand}[1]{\noindent\fontfamily{iwona}\fontseries{bc}\selectfont{#1}}

\renewcommand\FirstLineFont{\FirstLineCommand}


\makeatletter

\let\xfl\FirstLine
\long\def\foo#1\ifvoid\mz@firstbox#2!!{%
\def\FirstLine##1{#1%
\setbox\mz@firstbox\hbox to \textwidth{\textcolor{red}{\unhbox\mz@firstbox\unskip\unskip\unpenalty}}%
 \ifvoid\mz@firstbox
#2}}
\expandafter\foo\FirstLine{#1}!!

\makeatother

\usepackage{babel}
\begin{document}
\selectlanguage{english}%

Hello just testing.

Normal \textcolor{red}{color switching} should work.

\FirstLine{Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.}

Some more text.
\end{document}

The code above is a one-line patch to \FirstLine to add the colour at a safe place. It seems in comments that the patch trickery is obscuring what the code is doing so here is an equivalent version.

Replace the code above between \makeatletter \makeatother by the following which is identical to the code in magaz apart from the line marked %<<<<<<

\makeatletter

\renewcommand\FirstLine[1]{%
 \relax\if@inlabel\noindent\fi % produce any pending list item label
 \begingroup
 % typeset text 3 times: 1) using all breaks to count segments; 2) with
 % a full first line and \FirstLineFont to get first line and remaining
 % segments; 3) Using current font, keeping only `remaining segments'
 % on a single line. 
 \setbox\z@\box\mz@firstbox \setbox\z@\box\mz@remains % void the global boxes
 \setbox\@tempboxa\vbox{% 1) use all breaks
   \hbadness\maxdimen \hfuzz\maxdimen
   \hsize\z@ \leftskip\z@skip \rightskip\z@skip \parfillskip\fill
   \parshape\z@ \pretolerance\m@ne \tolerance\@ne 
   \doublehyphendemerits\z@ \finalhyphendemerits\z@
   #1\global\mathchardef\mz@spf\spacefactor\@@par
   \global\mathchardef\mz@numl\prevgraf
   %{\message{^^J^^J^^JText has \number\mz@numl\space segments:}\showhyphens{#1\unskip\unskip}}%
 }% end vbox "1)"
 \setbox\@tempboxa\vbox{% 2) first line, plus other segments
   \parshape \tw@ \z@\linewidth \z@\maxdimen 
   \doublehyphendemerits\z@ \finalhyphendemerits\z@
   %\linepenalty\z@
   % note no \hbadness\maxdimen \hfuzz\maxdimen at this stage
   \pretolerance\m@ne \parfillskip\fill
   {\FirstLineFont{#1}\@@par}%
   \ifnum\prevgraf>\tw@ % Bad argument: not simple text or too much text
     \mz@handlebad{#1}%
   \else
     \unskip\unkern\unskip\unpenalty \unskip\unkern\unskip\unpenalty
     \ifnum\prevgraf<\tw@ % All text fits on first line
       \global\setbox\mz@firstbox\lastbox % Grab that line
       %{\message{Entire text fits: }\showhyphens{\unhcopy\mz@firstbox\unskip\unskip\unpenalty}}%
       \setbox\z@\hbox{\unhcopy\mz@firstbox}%
       \begingroup
       \advance\linewidth-0.4em\relax
       \expandafter\endgroup
       \ifdim\wd\z@>0.97\linewidth
         %\message{^^JHandle wide first line: \the\wd\z@\space vs \the\linewidth. }%
         \global\setbox\mz@firstbox\hbox to\wd\mz@firstbox{%
             \unhcopy\mz@firstbox\unskip\unskip\unpenalty}% remove \parfillskip
         \global\setbox\mz@remains\hbox{}% Trigger keeping of full wide line
       \fi        % else \mz@remains remains void
     \else % 2 lines: text fills first line with some left over
       \setbox\z@\lastbox % remainders to \z@
       \ifvoid\z@ % could not grab last line 
         \mz@handlebad{#1}%
       \else 
         \unskip\unkern\unskip\unpenalty \unskip\unkern\unskip\unpenalty
         \global\setbox\mz@firstbox\lastbox % grab first line
         % Note: counting segments in this first line will be wrong if the line
         % ended with a hyphenation.  It could be possible to detect and adjust
         % for the resulting extra segment if it is deemed desirable to count the
         % first line directly.
         %{\message{First line is: }\showhyphens{\unhcopy\mz@firstbox\unskip}}%
         %{\message{Remaining segments are: }\showhyphens{\unhcopy\z@\unskip\unskip}}%
         %
         % 2a) break up "remaining segments":
         \hsize\z@ \hbadness\maxdimen \hfuzz\maxdimen
         \leftskip\z@skip \rightskip\z@skip \parfillskip\fill
         \parshape\z@ \pretolerance\m@ne \tolerance\@ne 
         {\everypar{}\noindent}% mid-par so no \everypar or \parindent
         \nobreak % \nobreak because leftskip adds breakpoint
         \unhbox\z@\unskip\unskip\unpenalty\@@par % gives number of "extra segments"
         %\message{There are \number\mz@numl\space segments in total and \the\prevgraf\space "remaining segments". }%
         \@tempcnta\mz@numl \advance\@tempcnta-\prevgraf 
         %\message{Number of segs in 1st line: \the\@tempcnta. }%
         \advance\@tempcnta\@ne % number of segs in 1st line plus 1
         \edef\@tempa{\the\@tempcnta\space}% 3) Collect "other segments"
         \@whilenum \@tempcnta>\@ne\do{% build \parshape lines
           \edef\@tempa{\@tempa \z@\z@}%
           \advance\@tempcnta\m@ne
         }%
         %\message{Parshape: \@tempa \z@\maxdimen}%
         \parshape \@tempa \z@\maxdimen
         #1\@@par
         \unskip\unkern\unskip\unpenalty \unskip\unkern\unskip\unpenalty
         \global\setbox\mz@remains\lastbox 
       \fi
     \fi
   \fi
 }% end vbox "2)"
 \endgroup
\setbox\mz@firstbox\hbox to \textwidth{\textcolor{red}{\unhbox\mz@firstbox\unskip\unskip\unpenalty}}%<<<<<<<<<<<<<<<<<<<<<<<<<<
 \ifvoid\mz@firstbox
   #1% Error case: just output the text
 \else
   {\everypar{}\noindent}\nobreak % everypar was captured in firstbox
   \ifvoid\mz@remains % partial line only
     % Unbox the partial line. This allows equal stretching of spaces across
     % the line, but admits a slight chance that some \FirstLineFont may
     % carry over to the second line.
     \unhbox\mz@firstbox 
     \unskip\unskip\unpenalty % remove \rightskip \parfillskip \nobreak
     \allowbreak % allow a break rather than get dragged to next line (??)
   \else % full first line 
     % Output whole box to prevent unexpected linebreaks, especially for
     % an overfull line and at the bogus discretionary that TeX leaves before
     % a final (used) hyphen.
     \box\mz@firstbox\break 
     \unhbox\mz@remains
     \unskip\unskip\unpenalty % remove \rightskip \parfillskip \nobreak
     % (or remove forced \break for empty remains)
   \fi
   \spacefactor\mz@spf
 \fi
}

\makeatother
share|improve this answer
    
thank you for your illuminating answer. It is good to know that color is a state variable, which is not obvious from the latex syntax. Now I have to find a resource to help me understand your code. Since the "expandafter" command jumps out at me, I am wondering if the same could be written somewhat more concisely with the atbeginend package or similar. –  Andreas Dec 9 '12 at 22:48
    
well the fact that the \color top level syntax looks like a font change but is implemented completely differently isn't an accident, it was an intentional design decision, sorry if that threw you:) The \foo stuff simply expands Donald's macro and adds the colour command at a safe place, so it just avoids copying the whole existing definition which is quite long (and very clever:-) It can probably be done using one of the existing "patch" commands, but doing it that way meant I knew exactly where the change was going. –  David Carlisle Dec 9 '12 at 22:53
    
Thank you, @David, for your explanation. Syntactically hiding what's under the hood - not always a bad thing, it helps my forgetful brain switching those colors off (when doing it manually). So foo applies the color from the first box to the textwidth, by unboxing, then reboxing with setbox? I see that FirstLine (i.e. the paragraph) is expanded first, so the first line is typeset. Which macro of Donald's are you referring to? –  Andreas Dec 9 '12 at 23:44
    
\foo looks similar to magaz.sty but that is much longer (I don't understand what precautions are included there). If enough readers find this interesting, perhaps a rewriting of magaz may result from this that can handle color. For now it looks like I could drop in the font where @David added the \textcolor in \foo to completely bypass magaz, right? –  Andreas Dec 9 '12 at 23:46
    
the package essentially only has one macro, \FirstLine which does "stuff" in particular it typesets the paragraph multiple times to figure out where the first line breaks, to avoid problems with colour This holds off adding the colour until the very final stage when FirstLine is re-assembling everything. basically it just inserts some code at line 167 of magaz.sty which takes the \mz@firstbox in which the package has assembled the first line and re-packages it with colour back into the same box register so the remainder of the \FirstLine macro can assemble the paragraph as before. –  David Carlisle Dec 9 '12 at 23:50
show 3 more comments

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.