为什么仅用于第一行排版的颜色(使用 magaz 包)会影响整个文档?

为什么仅用于第一行排版的颜色(使用 magaz 包)会影响整个文档?

我正在尝试使用 magaz 包制作一个漂亮的布局,为某一部分的第一行赋予不同的样式。我见过的所有示例都以小写字母 {\scshape text} 或大写字母 的某种变体为特色\MakeUppercase{text}

我想改变字体和颜色。

这对于字体来说效果很好,但不幸的是颜色会影响整个文档,而不仅仅是第一行。

\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}

如您所见,我定义了一个命令\FirstLineCommand作为\FirstLineFont

如果我改用

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

效果很好。

显然,在乳胶语法方面我并不是一个专家,因此,在尝试在这里和那里添加额外的括号并移动颜色语句(并尝试代替{\color text})之后\textcolor{text},我仍然感到困惑。

如果您能帮我仅为该段落的第一行排版添加颜色,我会很高兴。

答案1

它无法处理颜色的原因在于,与字体不同,颜色不是框的原始属性,颜色是通过在颜色范围的开始和结束处设置颜色变化节点来实现的。如果在排版后拆分并重新组织框,则这些颜色节点可能会(并且通常会)与其文本分离。Donald 的软件包所做的框重新排列比平均水平要多:-)

在此处输入图片描述

\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}

上面的代码是一行补丁,用于\FirstLine在安全的地方添加颜色。评论中似乎说补丁技巧掩盖了代码的作用,因此这里有一个等效版本。

将上面的代码替换为下面的代码\makeatletter \makeatother,除了标记的行之外,其余代码与 magaz 中的代码相同%<<<<<<

\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

相关内容