LaTeX 如何減少重複程式碼?使用自訂指令、環境與 \input

部落格EasyLaTeX 官方發布日期

在 LaTeX 專案中減少重複程式碼,可以從三個方面入手:用自訂指令重複使用相同格式,用環境重複使用固定的內容結構,再用 \input 管理多個檔案共用的程式碼。並不是所有重複內容都值得封裝,建議優先處理出現多次、寫法一致且後續可能一起修改的部分。

同一格式反覆手寫時:定義帶參數的指令

下面這份原始碼可以直接編譯,\vect、\code、\R 各定義一次,正文反覆呼叫:

LaTeX
\documentclass[11pt]{article}\usepackage{amsmath,amssymb}\newcommand{\vect}[1]{\boldsymbol{#1}}\newcommand{\code}[1]{\texttt{#1}}\newcommand{\R}{\mathbb{R}}\begin{document}For $\vect{x}\in\R^d$, open \code{main.tex}.​\end{document}

定義寫在 \begin{document} 之前,全文都能呼叫;寫在正文中,只有它之後的內容能用。指令名與已有套件撞車時會報 ! LaTeX Error: Command \R already defined.,換名即可;要覆蓋已有定義時用 \renewcommand,僅在指令未定義時提供預設值可用 \providecommand。

\newcommand 最多接受 9 個參數;參數到四五個時,呼叫處要對著定義才能看懂。

同一結構反覆出現時:定義環境

論文裡幾十個格式相同的表格適合抽成一個環境。下面的 resulttable 接受列格式和表頭行兩個參數:

LaTeX
\documentclass[11pt]{article}\usepackage{booktabs}\newenvironment{resulttable}[2]{%  \begin{table}[htbp]\centering  \begin{tabular}{#1}\toprule  #2\\\midrule}{%  \bottomrule\end{tabular}  \end{table}}\begin{document}\begin{resulttable}{lcc}{Model & Accuracy & F1}Baseline & 0.812 & 0.794 \\Ours & 0.867 & 0.851 \\\end{resulttable}\end{document}

之後每張表只寫資料行,\toprule、列格式、浮動體位置都由環境提供。

環境體內部出錯時,日誌報的行號是展開之後的位置,與原始碼行號對不上;這時先把這段定義和一個最小呼叫單獨放進測試檔案編譯,定位到具體行再放回主文件。

多個檔案共用片段時:拆出公共檔案

同一段導言區被幾個檔案各抄一份時,用 \input 解決。

preamble.tex:

LaTeX
\usepackage{amsmath,amssymb}\newcommand{\vect}[1]{\boldsymbol{#1}}

main.tex:

LaTeX
\documentclass{article}\input{preamble}\begin{document}$\vect{x}$\end{document}

\input 是純插入,本例把 main.tex 放在專案根目錄,路徑以編譯時的專案根目錄為基準,而不是寫這行 \input 的章節檔案位置;在 chapters/intro.tex 裡寫 \input{intro2} 會報檔案找不到,要寫成相對主檔案的 chapters/intro2。

章節級拆分用 \include 更合適:前後自動 \clearpage,每章生成獨立的 .aux,配合 \includeonly 可以只編譯改動的章節;\include 不能巢狀。

封裝之前先確認:三類片段才值得收斂

封裝有成本,三條同時滿足才動手:出現三次以上、每次內容一致(而不只是看起來相似)、以後會一起改。

只出現兩次的段落封裝之後,讀者要跳到另一個檔案才能看懂;各處有細微差異的片段強行統一,要加一排開關參數,呼叫處比原文更難讀。

改完之後:編譯並複核關鍵位置

編譯一次,核對三處:定義檔案是否在 \begin{document} 之前被引入、\input 路徑是否相對主檔案書寫、公式與表格的編號與交叉引用是否仍指向原位。

錯誤訊息觸發原因處理
! LaTeX Error: Command \foo already defined.指令或環境使用了已存在的名字換名;確認要覆蓋時用 \renewcommand
! LaTeX Error: Environment foo undefined.環境定義在被呼叫之後,或定義所在檔案沒有被執行到把定義移到導言區,檢查 \input 是否被引入
! LaTeX Error: File 'chapters/intro2.tex' not found.\input 路徑按當前檔案寫,而解析以主檔案目錄為基準改成相對主檔案的路徑
日誌行號與原始碼對不上指令體或環境體展開後報的位置單獨建一個只含定義與呼叫的小檔案編譯,定位到具體行

總結

  • 格式收進指令:\newcommand 一次定義,正文反覆呼叫;

  • 結構收進環境:表格、定理框這類骨架用 \newenvironment 封裝;

  • 跨檔案收進公共檔案:\input 摘導言區,\include 拆章節;

  • 先判斷再封裝:三條標準同時滿足才動手。

把主檔案和各章節一起匯入 EasyLaTeX 編輯器,編譯入口按 main.tex 設定。