了解 itemize 开头的换行符

了解 itemize 开头的换行符

我对理解 LaTeX 如何排版文档存在根本性的问题。考虑一下我的代码

\documentclass{article}
\usepackage[margin = 0.75in]{geometry}
\begin{document}

\section*{ABC}
abc
\section*{ABC}
\begin{itemize}
    \item abc
\end{itemize}
\textbf{ABC}\\
abc\\  
\textbf{ABC}\\
\begin{itemize}
    \item abc
\end{itemize}
\end{document}      

它产生的输出是:-
乳胶流出

现在这从根本上来说是个问题。当我改变

\section*{ABC} 
abc

\section*{ABC}
\begin{itemize}
    \item abc
\end{itemize}

那么只有 abc 旁边会出现一个项目符号,而格式没有任何变化。

但是,当我在新行之后执行相同的操作时,如代码中所示

\textbf{ABC}\\
abc\\  
\textbf{ABC}\\
\begin{itemize}
    \item abc
\end{itemize}

然后由于某种原因,itemize 在呈现列表之前添加了一个新行。为什么?

答案1

让我们看看当你输入 时会发生什么\begin{itemize。现在应该变成\itemize,而\end{itemize}变成\enditemize。让我们看看\itemize会发生什么:

\def\itemize{%
  \ifnum \@itemdepth >\thr@@\@toodeep\else
    \advance\@itemdepth\@ne
    \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}%
    \expandafter
    \list
      \csname\@itemitem\endcsname
      {\def\makelabel##1{\hss\llap{##1}}}%
  \fi}

这是从latex.ltxLaTeX 内核定义文件 中获取的。因此,它会检查您是否超出了 的第三级itemize,如果超出,则发出错误\@toodeep,否则,它会推进该级别的计数器itemize,并将 定义为罗马数字的加号\@itemitem。然后,它使用带有参数 的命令,即,例如,如果为 1,这就是 的原因,它需要在 之前进行扩展,第二个参数是,其中是一个变量 space,它决定了项目标签的放置位置,并且意味着标签可以超出左边距。所以让我们再次从 中查看。labelitem\@itemdepth\list\csname\@itemitem\endcsname\<whatever there is in @itemitem>\labelitemi\@itemdepth\expandafter\@itemitem\list{\def\makelabel##1{\hss\llap{##1}}\hss\llap\listlatex.ltx

\def\list#1#2{%
  \ifnum \@listdepth >5\relax
    \@toodeep
  \else
    \global\advance\@listdepth\@ne
  \fi
  \rightmargin\z@
  \listparindent\z@
  \itemindent\z@
  \csname @list\romannumeral\the\@listdepth\endcsname
  \def\@itemlabel{#1}%
  \let\makelabel\@mklab
  \@nmbrlistfalse
  #2\relax
  \@trivlist
  \parskip\parsep
  \parindent\listparindent
  \advance\linewidth -\rightmargin
  \advance\linewidth -\leftmargin
  \advance\@totalleftmargin \leftmargin
  \parshape \@ne \@totalleftmargin \linewidth
  \ignorespaces}

同样,会检查您是否嵌套了 5 个以上的列表,如果是,则有\@toodeep,否则我们将嵌套列表的数量增加\@ne,即 1。然后我们将三个长度设置为 0(\z@0pt),然后使用命令\@list<roman numeral of list depth>(例如,\@listi如果我们处于嵌套的第一级)。\@listi等等不在latex.ltx,也不在plain.tex或中list.tex,所以我不知道在哪里看。\@itemlabel定义为第一个参数,然后\makelabel设置为\@mklab,即\def\@mklab#1{\hfil #1}。条件\@nmbrlist为假,执行参数 2,可能\relax将其与后面的内容分开,然后\@trivlist执行,然后有几个长度分配,然后是\ignorespaces。现在\@trivlist,再次在 中latex.ltx,定义如下:

\def\@trivlist{%
  \if@noskipsec \leavevmode \fi
  \@topsepadd \topsep
  \ifvmode
    \advance\@topsepadd \partopsep
  \else
    \unskip \par
  \fi
  \if@inlabel
    \@noparitemtrue
    \@noparlisttrue
  \else
    \if@newlist \@noitemerr \fi
    \@noparlistfalse
    \@topsep \@topsepadd
  \fi
  \advance\@topsep \parskip
  \leftskip \z@skip
  \rightskip \@rightskip
  \parfillskip \@flushglue
  \par@deathcycles \z@
  \@setpar{\if@newlist
             \advance\par@deathcycles \@ne
             \ifnum \par@deathcycles >\@m
               \@noitemerr
               {\@@par}%
             \fi
           \else
             {\@@par}%
           \fi}%
  \global \@newlisttrue
  \@outerparskip \parskip}

我不会尝试解释这到底是做什么的。我只看到\@newlisttrue执行了。\item除了一些无趣的事情之外,还调用了\@item,即:

\def\@item[#1]{%
    \if@noparitem
         \@donoparitem
    \else
        \if@inlabel
            \indent \par
        \fi
        \ifhmode
            \unskip\unskip \par
         \fi
         \if@newlist
              \if@nobreak
                   \@nbitem
              \else
                   \addpenalty\@beginparpenalty
                   \addvspace\@topsep
                   \addvspace{-\parskip}%
             \fi
         \else
             \addpenalty\@itempenalty
             \addvspace\itemsep
         \fi
         \global\@inlabeltrue
    \fi
 […]
}

对于\@newlisttrue,我们\@topsep添加了 垂直空间,假设\@nobreakfalse,这给了我们垂直空间。在 的省略部分\@item有一个\@newlisttrue,这意味着以下项目只有\itemsep垂直空间。事实上,\@donoparitem有一个\vskip\@tempskipa,这给了额外的垂直空间。当你有两个连续的列表时使用它,因为中间没有“段落”,也许在 之后\\,但无论如何它只是相对于 多了 2pt \@topsep。所以如果你在标题中给出[-10pt]可选参数\\,空间应该会消失。无论如何,正如我在评论中所说,\subsubsection可能是一个更好的主意,或者如果你有这个标题格式的命令,你可能想要制作一个没有 的星号变体\\。至于“它并不总是有换行符”部分,我们可以看看 的定义\section。我将在这里复制课堂上的一个report

\newcommand\section{\@startsection {section}{1}{\z@}%
                                   {-3.5ex \@plus -1ex \@minus -.2ex}%
                                   {2.3ex \@plus.2ex}%
                                   {\normalfont\Large\bfseries}}

因此本质上是对 的调用\@startsection。据我所知,该命令直接执行的操作与我们无关。它以调用\@sect:结束\@sect{#1}{#2}{#3}{#4}{#5}{#6}。查看 的定义\@sect,似乎无论如何都不会影响\item\@item\@donoparitem。所以我们到了最后,看到\@xsect{#5}。同样,这一切让我们感兴趣的是\@tempskipa #1\relax。无论如何,它似乎设置了,正如一个简单的测试所证明的那样。那么让我看一下的假设中\@noparitemfalse的 的定义。在命令之后,一个简单的测试显示为真,而 定义的上述部分中的其他条件都是假的。这意味着该部分所做的只是和。但这不是的错。所以它一定是默认值,其他命令会处理这些条件。这意味着回答这个问题会\@item\@noparitemfalse\section\ifhmode\@item\unskip\unskip \par\global\@inlabeltrue\section非常很复杂,需要调查这些条件的每一个用法。所以我不能结束这个。这就是“为什么会发生这种情况”的部分,或者说它的开始。

至于“我该如何解决这个问题”部分,请尝试以下操作:

\documentclass[a4paper]{report}

\makeatletter
\newcommand{\header}{\@ifstar{\@header}{\he@der}}
\newcommand{\@header}[1]{\textbf{#1}\hfill2014-15\hfil}
\newcommand{\he@der}[1]{\textbf{#1}\hfill2014-15\\}
\makeatother

\begin{document}
\noindent\header{Header 1}
Text for header 1, no itemize. \\
\header*{Header 2}
\begin{itemize}
\item Here is a Header with itemize. As you can see, no extra space is produced, and no extra vertical space is added.
\item Just remember the star after \verb"header" in this case.
\end{itemize}
Now let's put a simple paragraph: Lorem ipsum dolor sit amet, consectetuer and so on. \\
\header{Header 3}
Nothing strange happens at all. I hope this solves your problem. Naturally, you can add the \verb"\noindent" to the command definition, to avoid the \verb"\parindent" for a header. You can also add a \verb"\par" or \verb"\\" before the header.
\end{document}

通过这个 MWE,我得到:

在此处输入图片描述

如果这不是您想要的格式,您可以告诉我。无论如何,额外的空间不存在,并且额外的空间itemize不存在。当然,标题被视为文本,因此 itemize 和标题之间有垂直空间。如果您不想要那样,我可以尝试干预上面提到的那些条件,或者您可以添加一个\vspaceto \header,以便它只在您希望它出现时出现。

答案2

http://imgur.com/tlFDDUL

\documentclass{article}
\usepackage[margin = 0.75in]{geometry}
\begin{document}

\section*{ABC}
abc
\section*{ABC}
This is a really long paragraph depicting how \LaTeX\ typesets documents. This is a really long paragraph depicting how \LaTeX\ typesets documents. This is a really long paragraph depicting how \LaTeX\ typesets documents. This is a really long paragraph depicting how \LaTeX\ typesets documents.
\begin{itemize}
    \item abc
\end{itemize}
This is a really long paragraph that does not get indented because \LaTeX\ just left vertical mode from the \texttt{itemize} environment. This is a really long paragraph that does not get indented because \LaTeX\ just left vertical mode from the \texttt{itemize} environment. This is a really long paragraph that does not get indented because \LaTeX\ just left vertical mode from the \texttt{itemize} environment. 

This is a really long paragraph that shows how a whitespace between two paragraphs causes the second paragraph to get indented. No further formatting is needed. This is a really long paragraph that shows how a whitespace between two paragraphs causes the second paragraph to get indented. No further formatting is needed. This is a really long paragraph that shows how a whitespace between two paragraphs causes the second paragraph to get indented. No further formatting is needed.

A double slash \texttt{\textbackslash\textbackslash} forces a line break. A forced line break with the \texttt{itemize} environment subsequent thereto will first cause a line break, then \LaTeX\ will go into vertical mode to typeset the items. This involves an operation in vertical mode \emph{twice} rather than \emph{once}, as you intended it: \\
\begin{itemize}
    \item abc
\end{itemize}
Ufff, what an ugly space! Lesson learnt, I'd say!
\end{document}

相关内容