:從文檔骨架到交叉引用的核心命令與實(shí)操技巧)
1. 為什么排版工具值得花時(shí)間學(xué)很多人第一次接觸排版工具都是被逼的。導(dǎo)師甩過(guò)來(lái)一個(gè)模板說(shuō)“按這個(gè)格式改”然后你打開(kāi)一看滿(mǎn)屏的反斜杠和花括號(hào)頭都大了。但真正用進(jìn)去之后會(huì)發(fā)現(xiàn)這類(lèi)工具解決的是一個(gè)非常本質(zhì)的問(wèn)題內(nèi)容與格式的分離。你寫(xiě)的是文字排版是另一回事。用普通文字處理軟件你一邊寫(xiě)一邊調(diào)字體、調(diào)行距、調(diào)縮進(jìn)寫(xiě)著寫(xiě)著就忘了自己本來(lái)想說(shuō)什么。而用標(biāo)記語(yǔ)言的方式你只管寫(xiě)內(nèi)容格式交給命令和模板去控制。這個(gè)思路一旦習(xí)慣效率提升是肉眼可見(jiàn)的。這篇文章面向的是剛上手或者用了一段時(shí)間但總覺(jué)得不順手的人。我會(huì)把日常寫(xiě)作中最常用的命令操作拆開(kāi)講清楚包括文檔結(jié)構(gòu)、數(shù)學(xué)公式、表格圖片、交叉引用、參考文獻(xiàn)這幾個(gè)核心模塊。每個(gè)命令不僅告訴你“怎么寫(xiě)”還會(huì)解釋“為什么這么設(shè)計(jì)”以及我在實(shí)際使用中踩過(guò)的坑。不管你是寫(xiě)論文、做報(bào)告、整理筆記還是給團(tuán)隊(duì)寫(xiě)技術(shù)文檔這套東西都能用得上。下面直接從最基礎(chǔ)的文檔骨架開(kāi)始。2. 文檔骨架與中文排版的第一道坎2.1 文檔類(lèi)選擇article、report還是book任何一份文檔都是從\documentclass開(kāi)始的。這個(gè)命令決定了整個(gè)文檔的基礎(chǔ)排版規(guī)則。常見(jiàn)的選擇有這么幾種article適合短篇文檔、期刊論文、實(shí)驗(yàn)報(bào)告。沒(méi)有章的概念只有節(jié)。report適合長(zhǎng)篇報(bào)告、學(xué)位論文。有章的概念支持多級(jí)標(biāo)題。book適合書(shū)籍。有章、部分、前后附錄等完整結(jié)構(gòu)。選哪個(gè)不是隨便定的。如果你用article寫(xiě)學(xué)位論文寫(xiě)到后面發(fā)現(xiàn)需要“章”這一級(jí)結(jié)構(gòu)再改文檔類(lèi)會(huì)引發(fā)一堆連鎖問(wèn)題。我的建議是一開(kāi)始就按最終篇幅選。超過(guò)三十頁(yè)的內(nèi)容直接用report別猶豫。文檔類(lèi)后面可以跟選項(xiàng)比如字號(hào)和紙張\documentclass[12pt, a4paper]{article}12pt是正文字號(hào)a4paper是紙張大小。不寫(xiě)的話(huà)默認(rèn)是10pt和信紙尺寸。國(guó)內(nèi)用A4居多建議顯式指定。2.2 中文支持從踩坑到穩(wěn)定方案中文排版是很多人遇到的第一個(gè)大坑。早期方案是CJK宏包配置繁瑣字體還得手動(dòng)指定?,F(xiàn)在主流方案是ctex宏包或者ctexart文檔類(lèi)。最省事的做法是直接用ctexart\documentclass[UTF8]{ctexart}這樣中文支持、字體配置、段落縮進(jìn)都幫你處理好了。如果必須用article那就加載ctex宏包\documentclass[UTF8]{article} \usepackage{ctex}注意編碼一定要用UTF-8。如果源文件是GBK編碼編譯時(shí)中文會(huì)變成亂碼而且報(bào)錯(cuò)信息往往指向奇怪的地方排查起來(lái)很費(fèi)時(shí)間。我遇到過(guò)一種情況在舊編輯器里寫(xiě)的文檔換到新環(huán)境編譯中文全沒(méi)了。查了半天發(fā)現(xiàn)是文件編碼問(wèn)題。所以養(yǎng)成習(xí)慣源文件統(tǒng)一UTF-8編輯器默認(rèn)編碼也設(shè)成UTF-8。2.3 標(biāo)題層級(jí)與文檔結(jié)構(gòu)命令文檔的骨架靠這幾個(gè)命令撐起來(lái)\section{一級(jí)標(biāo)題} \subsection{二級(jí)標(biāo)題} \subsubsection{三級(jí)標(biāo)題}在report和book里還有\(zhòng)chapter{章標(biāo)題}。這些命令會(huì)自動(dòng)編號(hào)也會(huì)自動(dòng)寫(xiě)入目錄。有一個(gè)細(xì)節(jié)很多人不知道帶星號(hào)的版本不編號(hào)。比如\section*{致謝}這個(gè)標(biāo)題不會(huì)出現(xiàn)在目錄里也不會(huì)有編號(hào)。致謝、前言、附錄說(shuō)明這類(lèi)內(nèi)容通常用帶星號(hào)的版本。另外\tableofcontents生成目錄\newpage強(qiáng)制換頁(yè)\appendix切換附錄編號(hào)方式。這些命令組合起來(lái)一份文檔的骨架就搭好了。我個(gè)人的習(xí)慣是先寫(xiě)完整份文檔的所有標(biāo)題把結(jié)構(gòu)定下來(lái)再往里填內(nèi)容。這樣不會(huì)寫(xiě)著寫(xiě)著發(fā)現(xiàn)結(jié)構(gòu)亂了回頭調(diào)整成本很高。3. 數(shù)學(xué)公式從行內(nèi)到多行對(duì)齊3.1 行內(nèi)公式與行間公式的取舍數(shù)學(xué)公式分兩種行內(nèi)公式和行間公式。行內(nèi)公式用$...$包裹比如$a^2 b^2 c^2$它會(huì)嵌在文字中間。行間公式用\[...\]或者equation環(huán)境單獨(dú)占一行居中顯示。什么時(shí)候用行內(nèi)什么時(shí)候用行間我的判斷標(biāo)準(zhǔn)是看這個(gè)公式是否需要被引用。如果后面要提到“根據(jù)公式(1)”那就用equation環(huán)境它會(huì)自動(dòng)編號(hào)。如果只是順帶提一下的簡(jiǎn)單表達(dá)式行內(nèi)就夠了。行內(nèi)公式設(shè) $x 0$則有... 行間公式 \begin{equation} E mc^2 \label{eq:energy} \end{equation}\label是給公式起個(gè)名字后面用\ref{eq:energy}就能引用它的編號(hào)。這個(gè)機(jī)制后面講交叉引用時(shí)還會(huì)展開(kāi)。3.2 多行公式對(duì)齊align環(huán)境的正確用法寫(xiě)論文時(shí)經(jīng)常遇到多行公式需要對(duì)齊的情況。最常用的是align環(huán)境\begin{align} f(x) (x1)^2 \\ x^2 2x 1 \end{align}是對(duì)齊點(diǎn)\\是換行。對(duì)齊點(diǎn)通常放在等號(hào)前面這樣多行公式的等號(hào)會(huì)豎直對(duì)齊看起來(lái)非常整齊。如果不想讓某一行編號(hào)在那一行末尾加\nonumber。如果整組公式只想要一個(gè)編號(hào)用aligned環(huán)境嵌套在equation里。這里有個(gè)坑align環(huán)境里每一行默認(rèn)都會(huì)編號(hào)。如果你寫(xiě)了五行公式就會(huì)得到五個(gè)編號(hào)。很多時(shí)候這不是你想要的。所以要么用\nonumber逐個(gè)取消要么用align*完全不編號(hào)。3.3 矩陣、分段函數(shù)與常見(jiàn)符號(hào)矩陣用pmatrix、bmatrix、vmatrix等環(huán)境\begin{pmatrix} a b \\ c d \end{pmatrix}p是圓括號(hào)b是方括號(hào)v是豎線(xiàn)。矩陣?yán)锏姆指袅衆(zhòng)\分隔行。分段函數(shù)用cases環(huán)境\begin{equation} f(x) \begin{cases} x^2, x \geq 0 \\ -x, x 0 \end{cases} \end{equation}常見(jiàn)符號(hào)需要記一下\alpha、\beta、\sum、\int、\infty、\partial、\nabla。這些不用死記用多了自然就熟了。我建議在文檔里放一個(gè)常用符號(hào)表需要的時(shí)候查一下比翻手冊(cè)快。提示如果公式編譯報(bào)錯(cuò)先檢查花括號(hào)是否配對(duì)再檢查有沒(méi)有用了未加載宏包的命令。很多符號(hào)需要amsmath或amssymb宏包支持。4. 表格與圖片位置控制的藝術(shù)4.1 表格的基本結(jié)構(gòu)表格用tabular環(huán)境\begin{table}[htbp] \centering \caption{實(shí)驗(yàn)數(shù)據(jù)對(duì)比} \label{tab:data} \begin{tabular}{|c|c|c|} \hline 樣本 均值 標(biāo)準(zhǔn)差 \\ \hline A 3.2 0.5 \\ B 4.1 0.7 \\ \hline \end{tabular} \end{table}{|c|c|c|}定義了三列每列居中豎線(xiàn)分隔。\hline畫(huà)橫線(xiàn)。\caption是表格標(biāo)題\label用于引用。這里有個(gè)細(xì)節(jié)\caption要放在\begin{tabular}之前還是之后放在之前標(biāo)題在表格上方放在之后標(biāo)題在表格下方。學(xué)術(shù)論文里表格標(biāo)題通常在上方圖片標(biāo)題在下方。這不是硬性規(guī)定但跟著慣例走不會(huì)錯(cuò)。4.2 浮動(dòng)體位置參數(shù)htbp到底怎么用[htbp]這四個(gè)字母代表四種位置偏好hhere就放在這里ttop放到頁(yè)頂bbottom放到頁(yè)底ppage單獨(dú)放一頁(yè)它們是有優(yōu)先級(jí)的從左到右依次嘗試。但最終決定權(quán)在排版引擎手里。如果頁(yè)面剩余空間不夠它會(huì)自動(dòng)調(diào)整。很多人遇到的問(wèn)題是表格或圖片跑到了文檔末尾怎么都拉不回來(lái)。這時(shí)候可以試試加!比如[!ht]意思是“盡量滿(mǎn)足我的要求”。但說(shuō)實(shí)話(huà)浮動(dòng)體的位置控制是這類(lèi)工具的一個(gè)設(shè)計(jì)特點(diǎn)不是bug。它的邏輯是讓版面更美觀避免大片空白。我的經(jīng)驗(yàn)是不要跟浮動(dòng)體較勁。寫(xiě)的時(shí)候用[htbp]最后定稿時(shí)再統(tǒng)一調(diào)整。如果實(shí)在需要固定位置可以用float宏包的[H]參數(shù)強(qiáng)制“就在這里”。但這樣可能導(dǎo)致頁(yè)面出現(xiàn)大片空白慎用。4.3 圖片插入與尺寸控制圖片用graphicx宏包\usepackage{graphicx} \begin{figure}[htbp] \centering \includegraphics[width0.8\textwidth]{figure.png} \caption{系統(tǒng)架構(gòu)圖} \label{fig:arch} \end{figure}width0.8\textwidth表示圖片寬度是正文寬度的80%。這個(gè)比例很常用既不會(huì)太小看不清也不會(huì)撐滿(mǎn)頁(yè)面顯得擁擠。圖片格式方面PDF和PNG適合矢量圖和截圖JPG適合照片。如果圖片是PDF格式編譯方式要用pdflatex或xelatex不能用傳統(tǒng)的latex。注意圖片文件名不要用中文和空格。雖然某些環(huán)境下能識(shí)別但換一個(gè)編譯器就可能報(bào)錯(cuò)。用英文加下劃線(xiàn)或連字符省心。5. 交叉引用與參考文獻(xiàn)讓文檔自己維護(hù)邏輯5.1 label與ref的配對(duì)邏輯交叉引用的核心是\label和\ref的配對(duì)。\label放在需要被引用的位置\ref放在引用發(fā)生的位置。\section{實(shí)驗(yàn)方法} \label{sec:method} 如第\ref{sec:method}節(jié)所述...編譯后\ref{sec:method}會(huì)自動(dòng)替換成章節(jié)編號(hào)。如果后面插入了新章節(jié)導(dǎo)致編號(hào)變化引用處的數(shù)字會(huì)自動(dòng)更新。這就是“內(nèi)容與格式分離”的好處。\label的命名建議用“類(lèi)型:描述”的格式比如sec:method、fig:arch、tab:data、eq:energy。這樣一看就知道引用的是什么類(lèi)型的東西排查問(wèn)題時(shí)很方便。有一個(gè)經(jīng)典坑編譯兩次才能正確顯示引用。第一次編譯生成輔助文件第二次編譯才把引用數(shù)字填進(jìn)去。如果引用顯示為??再編譯一次就好了。5.2 參考文獻(xiàn)手動(dòng)管理與自動(dòng)管理參考文獻(xiàn)有兩種做法。手動(dòng)管理是直接用thebibliography環(huán)境\begin{thebibliography}{99} \bibitem{ref1} 作者. 文章標(biāo)題. 期刊名, 年份. \bibitem{ref2} 作者. 書(shū)名. 出版社, 年份. \end{thebibliography}引用時(shí)用\cite{ref1}。這種方式適合參考文獻(xiàn)不多的情況簡(jiǎn)單直接。自動(dòng)管理用BibTeX或BibLaTeX。把文獻(xiàn)信息存在.bib文件里用\bibliography{文件名}引入。這種方式適合文獻(xiàn)多、需要反復(fù)調(diào)整格式的場(chǎng)景。BibTeX的工作流程是先編譯一次生成.aux文件再運(yùn)行BibTeX處理文獻(xiàn)然后再編譯兩次。聽(tīng)起來(lái)麻煩但編輯器通常有一鍵完成的功能。我個(gè)人的選擇是少于二十篇文獻(xiàn)用手動(dòng)多于二十篇用BibTeX。手動(dòng)管理雖然原始但勝在可控不會(huì)出現(xiàn)莫名其妙的編譯錯(cuò)誤。5.3 引用格式的常見(jiàn)問(wèn)題引用格式報(bào)錯(cuò)通常有幾個(gè)原因.bib文件里有語(yǔ)法錯(cuò)誤、文獻(xiàn)類(lèi)型寫(xiě)錯(cuò)了、必填字段缺失。比如article必須有author、title、journal、year這幾個(gè)字段少一個(gè)就可能報(bào)錯(cuò)。還有一個(gè)常見(jiàn)問(wèn)題是中文文獻(xiàn)的處理。BibTeX對(duì)中文支持不太好可能需要用bibtex的變體或者手動(dòng)調(diào)整。如果中文文獻(xiàn)多可以考慮用BibLaTeX加biblatex-gb7714-2015樣式對(duì)中文支持更友好。6. 編譯流程與常見(jiàn)報(bào)錯(cuò)排查6.1 編譯引擎的選擇常見(jiàn)的編譯引擎有四種引擎特點(diǎn)適用場(chǎng)景l(fā)atex傳統(tǒng)引擎輸出DVI老項(xiàng)目不推薦新用pdflatex直接輸出PDF英文文檔兼容性好xelatex支持Unicode和系統(tǒng)字體中文文檔首選lualatex新一代引擎功能強(qiáng)復(fù)雜排版需求中文文檔我推薦xelatex配合ctex宏包字體配置最省心。pdflatex雖然也能處理中文但字體配置麻煩容易出問(wèn)題。6.2 報(bào)錯(cuò)信息的閱讀方法編譯報(bào)錯(cuò)信息往往很長(zhǎng)但關(guān)鍵信息通常在第一個(gè)錯(cuò)誤處。后面的錯(cuò)誤可能是連鎖反應(yīng)不用全看。常見(jiàn)錯(cuò)誤類(lèi)型Undefined control sequence用了未定義的命令通常是拼寫(xiě)錯(cuò)誤或缺少宏包。Missing $ inserted數(shù)學(xué)符號(hào)寫(xiě)在了數(shù)學(xué)環(huán)境外面。File not found圖片或文獻(xiàn)文件路徑不對(duì)。Runaway argument花括號(hào)不配對(duì)。排查時(shí)從第一個(gè)錯(cuò)誤開(kāi)始改完再編譯不要試圖一次改完所有錯(cuò)誤。因?yàn)楹竺娴腻e(cuò)誤可能是前面的錯(cuò)誤引起的。6.3 輔助文件與清理策略編譯過(guò)程中會(huì)生成一堆輔助文件.aux、.log、.toc、.out等。這些文件記錄了交叉引用、目錄、書(shū)簽等信息。正常情況下不用管它們但如果編譯出現(xiàn)奇怪的問(wèn)題可以刪掉這些輔助文件重新編譯。.log文件是排查問(wèn)題的關(guān)鍵。里面記錄了詳細(xì)的編譯過(guò)程包括加載了哪些宏包、處理了哪些頁(yè)面、報(bào)了什么錯(cuò)。遇到看不懂的報(bào)錯(cuò)打開(kāi).log文件搜索Error關(guān)鍵詞通常能找到線(xiàn)索。提示如果改了\label的名字一定要重新編譯兩次否則引用可能還是舊的編號(hào)。7. 幾個(gè)讓我少走彎路的實(shí)操習(xí)慣7.1 宏包加載順序有講究宏包加載順序會(huì)影響最終效果。一般來(lái)說(shuō)ctex或fontspec這類(lèi)字體相關(guān)的宏包要早加載hyperref要晚加載。因?yàn)閔yperref會(huì)修改很多內(nèi)部命令如果它先加載后面的宏包可能會(huì)覆蓋它的設(shè)置。一個(gè)比較穩(wěn)妥的順序是文檔類(lèi) → 字體和編碼 → 基礎(chǔ)功能宏包amsmath、graphicx→ 特殊功能宏包 →hyperref→ 自定義命令。7.2 自定義命令減少重復(fù)勞動(dòng)如果某個(gè)命令反復(fù)出現(xiàn)可以定義快捷方式\newcommand{\R}{\mathbb{R}} \newcommand{\dd}{\mathrmbextvpl}這樣寫(xiě)公式時(shí)用\R代替\mathbb{R}用\dd代替\mathrmbextvpl省時(shí)省力而且格式統(tǒng)一。如果后面想改樣式改一處定義就行不用全文替換。7.3 版本控制與增量編譯寫(xiě)長(zhǎng)文檔一定要用版本控制。每次改完一個(gè)章節(jié)就提交一次出問(wèn)題了可以回退。配合編輯器的自動(dòng)編譯功能改完保存就能看到效果效率很高。增量編譯是指只編譯改動(dòng)的部分不重新編譯整個(gè)文檔。對(duì)于幾十頁(yè)的文檔全量編譯可能要十幾秒增量編譯能把這個(gè)時(shí)間降到一兩秒。大多數(shù)現(xiàn)代編輯器都支持這個(gè)功能。7.4 模板改造的邊界很多人拿到模板后想大改比如換字體、調(diào)行距、改頁(yè)邊距。我的建議是先搞清楚模板為什么這么設(shè)計(jì)。學(xué)術(shù)模板的格式要求通常有明確依據(jù)隨意改動(dòng)可能導(dǎo)致格式審查不通過(guò)。如果確實(shí)需要調(diào)整用geometry宏包調(diào)頁(yè)邊距用setspace宏包調(diào)行距用titlesec宏包調(diào)標(biāo)題格式。這些宏包提供了標(biāo)準(zhǔn)化的接口比直接改內(nèi)部命令安全得多。我在實(shí)際使用中最大的體會(huì)是這類(lèi)工具的學(xué)習(xí)曲線(xiàn)確實(shí)存在但前期投入的時(shí)間會(huì)在后期成倍地省回來(lái)。尤其是寫(xiě)長(zhǎng)文檔的時(shí)候自動(dòng)編號(hào)、自動(dòng)目錄、自動(dòng)引用這些功能手動(dòng)做一遍要花幾個(gè)小時(shí)而且容易出錯(cuò)。一旦把常用命令練熟寫(xiě)作就變成了純粹的“寫(xiě)內(nèi)容”格式的事情完全不用操心。