LaTeX浮動體

【注】筆記來自《LaTeX入門》——劉海洋。

1. 簡介

圖片或表格通常都佔有較大的一塊,直接放在文檔常常會造成分頁的困難,即前一頁放不下,放在後一頁又會造成很大的留白。其他一些大塊的內容也可能有類似的問題,比如程序算法、大型公式和不宜斷開的特殊形狀段落。LaTeX 中通過引入浮動體來解決這類問題。

  • 「浮動體」是一個活動的盒子,它可以把內容放在距離浮動體代碼前後不遠的地方,通常就是浮動體代碼所在地,也可以放在頁面開頭、末尾或者單獨的一頁中。

  • 「浮動體」的另一個作用是給圖表添加一個標題。LaTeX 的浮動體環境爲圖表標題提供了專門的命令進行自動編號、自動生成目錄的功能,通過第三方宏包還可以對標題格式進行整體設計。

2. 使用

2.1 環境

LaTeX 的標準文檔類預定義了兩種浮動體環境:figuretable,通常分別用於圖和表的排版。figure 環境的語法格式爲:

\begin{figure}[<允許位置>]
    <任意內容>
\end{figure}

table 環境與之類似。其中可選參數 <允許位置> 用來設定浮動環境可以出現在頁面的位置,即 h,t,b,p 四個選項的組合(默認爲 tbp):

  • h:此處(here),浮動體的內容被放在代碼所在的上下文位置。
  • t:頁頂(top),浮動體被放在一頁的頂部,這可以是代碼環境所在頁面或之後的頁面。
  • b:頁底(bottom),浮動體被放在一頁的底部,這可以是代碼環境所在頁面或之後的頁面。
  • p:獨立一頁(page),一個或多個浮動體被放在單獨的頁面中,這個頁面被稱爲「浮動頁」。與之對應,有正文的頁面被稱爲「文本頁」。

比如用選項 hbp 表示允許浮動體出現在環境所在位置、頁面底部或單獨一頁。浮動體允許位置選項的順序並不重要,LaTeX 總是以 htbp 的順序嘗試放置浮動體。不過單獨的一個 h 選項通常並不總能滿足,LaTeX 會把它放寬爲 ht 兩個可能,因此以下三種浮動體環境開頭是等價的:

\begin{figure}[ht]
\begin{figure}[th]
\begin{figure}[h]

【注】如果圖表較多,最好將浮動圖表的位置限定設置得寬鬆一些,以防止浮動體積壓過多,導致最後統一輸出。

2.2 應用

浮動體最常見的應用就是直接在 table 環境中放置 tabular 生成的表格,或者在 figure 環境中放置 \includegraphics 命令插入圖片。經常還在前面使用 \centering 命令讓圖表居中放置:

\begin{figure}[htbp]    % 允許在各個位置
    \centering
    \includegraphics{picture}
\end{figure}
\begin{table}           % 默認在頁面頂部、底部或單獨一頁
    \centering
    \begin{tabular}{|c|c|}
        \hline
        圖形 & \verb=figure= 環境 \\
        \hline
        表格 & \verb=table= 環境 \\
        \hline
    \end{tabular}
\end{table}

無論是 figure 環境還是 table 環境,浮動環境的名稱和內容並沒有必然聯繫。一個浮動體只是一個與版心等寬的盒子,內容可以任意放置。figure 環境也可以使用 TeX 代碼或者是 ASCII 字符畫的圖形,甚至放置算法、代碼或者很長,table 環境中也可以是以插圖形式得到的表格,甚至內容可以和名稱毫無關係。

2.3 標題

浮動體的另一個重要功能就是使用 \caption 命令加標題,其語法格式爲:

\caption{<標題>}
\caption{<短標題>}{<長標題>}

可選的參數短標題用於圖表目錄,而交叉引用的標題 \label 需要放在 \caption 後面,或者 <標題><長標題> 中。在 \caption<長標題> 中可以進行長達多段的敘述,但 <短標題> 或單獨的 <標題> 中不允許分段。

\begin{figure}[htp]
    \centering
    \includegraphics{picture}
    \caption[圖片]{這是一張圖片}\label{fig:picture}
    % 或者 \caption[圖片]{\label{fig:picture}這是一張圖片}
\end{figure}

【注】更復雜的標題控制可參見 LaTeX標題控制

2.4 雙欄

以上環境都是考慮在單欄文檔中,對於雙欄或多欄文檔,figuretable 環境就成爲只佔一欄的浮動盒子(寬度是 \columnwidth),其用法與單欄環境相同。

此外,LaTeX 標準文檔類還提供了跨欄排版的圖表環境 figure*table*,用來產生跨欄排版的浮動體。跨欄浮動體只允許排在頁面的頂部(t)或單獨的浮動頁面(p)中,其他位置參數會被忽略。figure*table* 環境的默認位置都是 tp。在大多數情況下,使用 table*figure* 環境的效果就是把內容排在後面一頁的頂部。

3. 詳解

儘管環境參數中可以設置位置,但浮動體的位置並不總能令人滿意,在圖表較多時這個問題尤爲明顯。

3.1 其他參數

LaTeX 對每個位置的浮動體的總數和佔用大小有一定限制,超出限制的浮動體會被排在較後的頁面中,但可以在 <允許位置> 選項中增加一個 ! 符號來忽略這些參數限制。因此,在 LaTeX 中最寬鬆的浮動體位置就是 !htbp。在位置選項中加上 ! 號將使浮動體相對更靠近文字或靠前出現,如果使用這一手段浮動體仍然被排在很靠後的位置,就可能需要將浮動體適當前移一段距離。

! 位置選項相反,\suppressfloats 命令用於禁止浮動體出現在當前頁,從而將浮動體的位置向後推。\suppressfloats 命令可以帶一個可選參數 tb,表示本頁頂部或底部禁止放置浮動體。

  • 限制浮動環境數量和佔用大小的參數
參數 類型 默認值 描述
topnumber 計數器 2 文本頁頂部浮動體的最大數量
bottomnumber 計數器 1 文本頁底部浮動體的最大數量
totalnumber 計數器 3 文本頁上所有浮動體的最大數量
dbltopnumber 計數器 2 topnumber 的跨雙欄版本
\topfraction 0.7 文本頁頂部浮動體的最大佔用空間比
\bottomfraction 0.3 文本頁底部浮動體的最大佔用空間比
\textfraction 0.2 文本頁中文本所佔的最小空間比例
\floatpagefraction 0.5 浮動頁中浮動體所佔的最小空間比例
\dbltopfraction 0.7 \topfraction 的跨雙欄版本
\dblfloatfraction 0.5 \floatpagefraction 的跨雙欄版本
\floatsep 彈性長度 12 \pm 2 pt 文本頁上,處於頁頂或頁底的多個浮動體之間的垂直間距
\textfloatset 彈性長度 19 \pm 3 pt 文本頁上,處於頁頂或頁底的浮動體與正文之間的垂直間距
\intextsep 彈性長度 12 \pm 2 pt 文本頁上,使用 h 位置選項排在頁面中間的浮動體與上下文之間的垂直間距
\dblfloatset 彈性長度 12 \pm 2 pt \floatsep 的跨雙欄版本
\dbltextfloatsep 彈性長度 19 \pm 3 pt \textfloatsep 的跨雙欄版本
% 設置「限制浮動環境數量和佔用大小的參數」示例
\setcounter{topnumber}{4}
\setcounter{bottomnumber}{4}
\renewcommand{\textfraction}{0.15}
\renewcommand{\topfraction}{0.85}
  • 控制浮動頁面間距的內部命令(內部命令一般只在宏包或文檔類中修改,如果要在正文導言區進行設置,可以在前後分別加上 \makeatletter\makeatother
參數 類型 默認值 描述
\@fptop 彈性長度 0 pt + 1 fil 浮動頁中頁面頂部與浮動體的垂直間距
\@fpsep 彈性長度 8 pt + 2 fil 浮動頁中多個浮動體之間的垂直間距
\@fpbot 彈性長度 0 pt + 1 fil 浮動頁中頁面底部與浮動體之間的垂直間距

3.2 浮動機制

LaTeX 會把浮動環境做成一個個盒子,所有未輸出的浮動體按次序放在隊列中處理。LaTeX 所使用的浮動規則可描述爲:

  • 浮動體會排在所有位置選項允許的位置中儘可能靠前的地方,但 h 選項優先於 t 選項。總體來說,浮動體的位置選項參數優先級按照 h,t,b,p 的順序依次降低。
  • 浮動體不會排在比浮動環境所處位置更靠前的頁面中。只有在 t 選項生效時,浮動體會排在環境代碼位置的同一頁更靠前的位置。
  • 對於相同類型的浮動環境,多個浮動體會按次序輸出,即當前 figure 不會在更早的 figure 之前輸出。但可以在更早的 table 之前輸出。特別需要注意的是,雙欄文檔中,跨欄的 figure*table* 環境和不跨欄的 figuretable 也沒有先後制約的關係,因此在雙欄環境應該避免混用。
  • 只有浮動體 <允許位置> 可選參數中的位置纔會放置浮動體。如果省略這個參數,默認位置參數爲 tbp,雙欄的跨欄浮動體則是 tp。當僅使用了 h 位置時,LaTeX 會將其擴充爲 ht 併發出警告。雙欄的跨欄浮動體只有 t,p 選項可以生效,其餘選項默認忽略。
  • 浮動體的輸出不能造成頁面的上溢出。即浮動體輸出時,垂直高度不能超過版心的位置。
  • 浮動體的輸出必須遵守「3.1」節中的參數限制。但如果 <允許位置> 參數中有 ! 號,有關文本頁的限制將被忽略,只有浮動頁的限制起效(\floatpagefraction\dblfloatpagefraction
  • LaTeX 最多保存 18 個未處理的浮動體。如果有過多的浮動體積壓不能及時輸出,就會報錯。通常遇到這種問題只要增加浮動體允許的輸出位置參數,或是使用 \clearpage 立即輸出所有的浮動體。如果確實要求保留原參數中設定的位置,則可以使用 morefloats 宏包增大保存未處理浮動體的限制。
  • 腳註和邊注也是特殊的浮動體,它們的輸出位置與普通浮動體不同,但同樣具有浮動的效果,會佔用未處理的浮動體個數。對於太長而排不下的腳註和邊注會排在後面的頁面。

上面最後三條規則在遇到 \clearpage\cleardoublepage\end{document} 時會被打破,此時所有隊列中未處理的浮動體都會直接輸出,<允許位置>p 選項也會打開以保證可以將所有浮動體輸出。

【注】由上文的浮動機制可知,雙欄文檔中帶星號跨欄的浮動環境與不帶星號的環境不能按順序輸出,這是個 BUG 。

  • 對於使用 LaTex 2e 版本的用戶,可以使用 fixltx2e 宏包來修正這個錯誤。fixltx2e 是對 LaTeX 2e 核心的修正代碼,除了雙欄浮動體還做了一些其他改進。
  • 對於使用 2015 年之後的 LaTeX 版本的用戶,內核已經修復這些 BUG,不再需要額外使用宏包。

4. 擴展

4.1 float 宏包

浮動圖表的目的使用浮動的位置來避免糟糕的分頁,但如果不在乎因爲圖表太大而產生的分頁,而要求有確定的位置,即要求不使用「浮動」環境。把圖表簡單地放在 centerquote 等環境中就可以做到這一點。float 宏包爲標準的浮動環境提供了一個新的 H 位置選項用來產生沒有浮動效果的圖表環境,它的使用和一般的浮動環境沒有什麼區別。

% 導言區
\usepackage{float}
% ……
\begin{figure}[H]
    \centering
    \includegraphics[height=1cm]{picture}
    \caption{不浮動的圖片}
\end{figure}

【注】H(Here)選項不能與 h,t,b,p 等其他位置選項混用。

事實上,使用了 H 選項的 figuretable 環境就不再是一個浮動體,而只是一個前後間距與內容格式都與普通浮動環境相同的一個大盒子。float 宏包提供的 H 選項比用 center 環境和 caption 宏包的 \captionof 命令來模擬普通浮動環境的格式要更準確,也更自然一些。

4.1.1 \newfloat 命令

float 宏包還提供了定義新浮動環境的功能,這是由 \newfloat 命令完成的,其語法格式如下:

\newfloat{<環境名>}{<位置>}{<目錄文件擴展名>}[<上級計數器>]

其中,<位置> 是浮動環境默認的位置選項,可以使用 h,t,b,p 或單獨的 H<目錄文件擴展名> 是用於產生與圖表目錄類似的目錄的輔助文件擴展名。而可選的 <上級計數器> 則可以讓浮動環境按章節編號。使用 \newfloat 定義了新的浮動體後,一般還要用 \floatname 命令定義這個浮動體的標題標籤名。

% 導言區
\usepackage{float}
\newfloat{flowchart}{htbp}{loflow}[chapter]
\floatname{flowchart}{流程圖}
% 正文
\begin{flowchart}
    \centering
    \includegraphics{picture}
    \caption{這是新的浮動體}
\end{flowchart}

4.1.2 \floatstyle 命令

float 宏包還提供了 \floatstyle{<格式>} 命令,可以使之後用 \newfloat 定義的所有浮動體按指定的格式輸出。也可以在後面使用 \restylefloat{<環境名>} 來指定變換原有浮動環境的格式,可選的格式如下:

  • plain:默認格式,它與標準文檔類 figuretable 環境的格式基本相同,只是 \caption 產生的標題總在浮動體環境的底部。
  • plaintop:標題在頂部,其餘與 plain 格式相同。
  • boxed:浮動體內容在一個線框中,標題在線框下面。
  • ruled:浮動體類似三線表的格式,標題在頂部,標題前後與浮動體後面各有一條橫線。
\floatstyle{ruled}
\restylefloat{flowchart}
% 正文
\begin{flowchart}
    \fbox{A} $\longrightarrow$ \fbox{B} \\
    \fbox{C} $\longrightarrow$ \fbox{D}
\caption{基本流程圖}
\end{flowchart}

【注】使用 float 宏包的 \newfloat\restylefloat 重定義浮動環境中只能使用一個 \caption 標題,標題的位置也固定爲頂部或底部,這對於排版並列圖表非常不便。caption 宏包個別功能也因此受到影響,ruled 格式中標題格式則完全固定。因此,如果對標題有較高要求,更高的方式是是噢能夠 newfloat 宏包的 \DeclareFloatingEnvironment 命令來定義新的浮動體,其語法格式如下:

\DeclareFloatingEnvironment[<選項表>]{<環境名>}

其中,<選項表> 可以使用下面的選項:

  • name=<標籤名>
  • listname=<目錄名>
  • fileext=<目錄文件擴展名>(默認是lo<環境名>
  • placement=<位置參數>
  • within=<上級計數器>(可以爲 none
  • chapterlistsgaps=onoff(在目錄中,設置不同章浮動體標題間是否增加額外間距)

此時,定義流程圖的格式可以使用如下命令:

\usepackage{newfloat}
\DeclareFloatingEnvironment[fileext=loflow,placement=htbp,within=chapter,name=流程圖,listname=流程圖目錄]{flowchart}

使用這種方式定義的新浮動體環境沒有標題方面的限制,可以與 caption 更好的結合。並且可以使用 \listof<環境名>s 這樣的命令來輸出目錄,比如前面定義的流程圖可以使用 \listofflowcharts 來輸出目錄。

4.1.3 \floatplacement 命令

float 宏包的 \floatplacement 可以重定義浮動環境的默認位置參數,比如讓圖表環境都允許 h 位置:

\floatplacement{figure}{htbp}
\floatplacement{table}{htbp}

4.1.4 \listof 命令

float 中的 \listof{<環境名>}{<標題>} 命令的功能與命令 \listoffigures\listoftables 類似,用來輸出新定義的浮動環境的標題目錄:

\listof{flowchart}{流程圖目錄}

4.2 placeins 宏包

placeins 宏包提供了一個 \FloatBarrier 命令,它會在所在的位置產生一個無形的屏障,所有之前的浮動體都必須在這個屏障之前輸出。\FloatBarrier 命令的功能類似 \clearpage,不過只要可能,\FloatBarrier 命令會避免直接分頁。placeins 宏包有幾個選項:

  • section 選項會在每個 \section 命令之前隱含地增加一個 \FloatBarrier 命令,使浮動體侷限在一節的範圍之內。
  • abovebelow 選項可以放寬 \FloatBarrier 命令的位置限制,使浮動體可以出現在同一頁的較前或較後的位置。

4.3 afterpage 宏包

float 宏包的 H 選項給出了確切的「此處」位置,也可以使用 afterpage 宏包來得到確切的「下一頁頂部」位置。afterpage 宏包提供了一個 \afterpage 命令,可以把參數中的內容放在下一頁的開頭,同時不影響正常的正文流向。因此,可以使用以下代碼來得到下一頁頂部的浮動圖表環境:

% 導言區
\usepackage{afterpage}
% ……
\afterpage{\begin{figure}[H]
    % ……
\end{figure}}

而如果使用以下代碼則會產生與 placeins\FloatBarrier 有類似的效果,它強制所有浮動體在下一頁之前輸出完畢:

% 導言區
\usepackage{afterpage}
% ……
\afterpage{\clearpage}
% 或 \afterpage{\FloatBarrier}

4.4 endfloat 宏包

有些期刊會要求稿件將所有的圖表放在整個文章的末尾,但把整個浮動環境挪到文檔末尾卻非常不方便修改,endfloat 宏包就解決了這個問題。引用 endfloat 宏包後,所有的浮動圖表都會被放在文檔最後。也可以使用 \processdelayedfloats 命令直接輸出之前延遲輸出的浮動圖表,比如放在文檔正文之後,參考文獻列表之前。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章