是否存在 fontsize 環境?

是否存在 fontsize 環境?

毫無疑問,存在控制序列形式的字體大小開關(描述這裡例如\begin{small}...\end{small}。成功測試這些之後,我開始將它們納入我的 TeX 詞彙表中。

幾天前,@GonzaloMedina 評論了我的一個答案,即這些環境並不存在,依賴它們的結構純屬巧合。然後我試著多了解那些不祥的環境。這是不祥的,因為它們似乎沒有以某種方式記錄下來。 (我發現唯一試圖以某種系統化的方式解釋它們的是一些維基教科書資源。)

這些環境是真實的還是假的?

答案1

您可以使用LaTeX由 定義的任何命令\newcommand\begin{}...\end{}在其周圍包含一對命令,但是,不建議這樣做,因為這不是一個環境。

然而,有趣的是,分組無論如何都有效,但這是\begin...\end.

沒有像\begin{small}etc這樣的字體大小環境,因為沒有\begin{chapter}etc。

請參閱範例:

\documentclass{article}


\newcommand{\foo}{This does nothing}

\begin{document}
\begin{foo}

\end{foo}
\end{document}

編輯一些解釋

這段程式碼可以在 中找到latex.ltx,參見第 4058f 行。

\def\begin#1{%
  \@ifundefined{#1}%
    {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}%
    {\def\reserved@a{\def\@currenvir{#1}%
     \edef\@currenvline{\on@line}%
     \csname #1\endcsname}}%
  \@ignorefalse
  \begingroup\@endpefalse\reserved@a}

可以看出,that@ifundefined{foo}會被調用,這是錯誤的,因為它\foo被定義了,所以environment名稱foo被設定並且\csname #1\endcsname(即\foo)被調用。

現在\end{foo}:部分

\def\end#1{%
  \csname end#1\endcsname\@checkend{#1}%
  \expandafter\endgroup\if@endpe\@doendpe\fi
  \if@ignore\@ignorefalse\ignorespaces\fi}

環境會尋找\end...此處的程式碼\endfoo,程式碼未定義,但\csname endfoo\endcsname擴展為 a\relax且沒有發生任何不良情況。

應該注意的是,許多眾所周知的環境並不是用\newenvironment.例如,使用\fooand \def\endfoo、 see\endequation等指令就足夠了。\endenumerate

答案2

任何命令都可以用作環境,如果包圍大塊文字通常很方便,所以

{\small  zzz\par}

\begin{small}%
zzzz

\end{small}

或多或少是等價的。

但請注意,與 不同的是,由於正常的 TeX 標記化規則,\small後面的空格不會被刪除。\begin{small}此外,您幾乎總是需要\par在 之前有一個或空行,\end這在命令形式中也是如此,但在環境形式中更容易忘記,因為大多數自訂環境(例如在其最終程式碼中center包含隱式環境\par) ,但這裡不是這種情況。

另請參閱以下討論:

\end.... 巨集名稱在 LaTeX2e 中保留嗎?

答案3

實際上,“LaTeXbook”(確切地說是“LaTeX。文檔準備系統”,作者:Leslie Lamport)認可使用此類環境:在第 27 頁的末尾,我們發現:

每個聲明都有一個對應的同名環境(減去字元\)。打字

\begin{em} ... \end{em}

相當於打字{\em ... }

特別是,「環境」形式自動提供一個群組來保持聲明的效果在本地,就像環境中經常發生的那樣(\begin問題 a\begingroup\end相應的\endgroup)。現在,\small是一個聲明,因此上述內容適用。

這是有意為之的,所以我認為說這些環境「偶然」起作用是不正確的;事實上,如同已經觀察到的,缺少指令 like 的定義\endsmall不會造成任何問題,因為它被稱為 as \csname small\endcsname,因此相當於\relaxif undefined。

所以,最後我的答案是:「是的,這些環境是『真實的』」(無論這意味著什麼)。


添加

在看到一些評論後,我認為添加一些有關如何在 LaTeX2e 中實現環境的詳細資訊可能會很有用(我不會談論 LaTeX3,因為我沒有足夠的專業知識)。 Christian Hupfer 已經提供了 的確切代碼摘錄latex.ltx,但也許有人會發現以下附加註釋也很有用。

當您定義環境時FOO,LaTeX 只需定義兩個新命令,\FOO並且\endFOO:後者始終不帶參數,而前者俱有為環境指定的相同參數(如果有)FOO。當\begin{FOO}遇到a 時,會發生以下情況(除其他外):

  • \begingroup一組以;開始

  • \begin(在本例中)的參數FOO(在本地)保存在巨集中\@currenvir,以便稍後能夠檢查每個參數是否\end與正確的\begin;配對。

  • 該命令\FOO作為最後一件事執行;因此,它將吸收隨後的參數(\begin{fOO}如果存在)。

另一方面,當 LaTeX 出現時\end{FOO},會發生以下情況(除其他外):

  • \endFOO如果已定義,則執行(如果未定義,則不會發生任何情況,如上所述);

  • LaTeX 檢查 的參數\end是否等於\@currenvir ,若不等於則產生錯誤;

  • \endgroup發出an來關閉該組。

實際上,當我基於另一個標準環境定義一個新環境時,我更願意避免使用顯式的\beginand \end,這樣 的值\@currenvir就不會改變。例如,假設我想定義quote環境的變體,使其內容變成斜體;我更喜歡說,

\newenvironment{italquote}{%
  \quote
  \itshape
}{\endquote}

超過

\newenvironment{italquote}{%
  \begin{quote}%
  \itshape
}{\end{quote}}

特別是如果我自己不打算使用該環境的話。這樣,如果使用者在語句中拼錯了環境名稱\end,他們將收到有關錯誤終止環境的錯誤italquote,這是他們實際使用的環境,而不是有關錯誤終止quote環境的錯誤,他們可能不知道。

相關內容