在編輯自動化文檔時,很容易出現在文檔多處提及相同內容的情況。例如,描述某具體設備的圖片,在多個工藝中都會用到,而又無法確定工藝出現順序,或者對於不同企業,工藝不盡相同。這時我們可能會希望,latex幫助我們保留第一次出現的圖片,而不輸出后出現的相同圖片,並且維護所有對這張圖片的引用。
要實現此功能,直覺地感到:
- 代碼要能判斷某個指令或標簽是否已經被定義;
- 若已經定義,則不執行任何操作;
- 若未定義,則定義之,並輸出內容。
在tex底層,存在一個識別指令名是否被定義的指令:\@ifundefined{指令名不帶斜杠}{執行內容}
對於該指令,有兩點需要注意:
- 指令的名稱包含符號 @,需要在使用之前執行\makeatletter將其視為一般字符,在之后執行\makeatother恢復其為特殊符號;
- 第一個參數是不帶斜杠的指令名,允許由其他宏指令組成。
而在已知一個要定義的名稱,而這個名稱需要由上下文決定的宏指令構成時,\newcommand就不適用了,因為它不支持從文本創建指令。此時需要tex的另一個指令:\@namedef{指令名不帶斜杠}{執行內容}
對於該指令,也同樣需要注意之前提到了兩點注意事項。
下面給出一個tex文件片段:
....... \newcommand\UserDefinedVar{Once} 工藝1采用了設備A,見圖\ref{Fig:DeviceA\UserDefinedVar}。 \makeatletter \@ifundefined{CommandDeviceA\UserDefinedVar}{ \begin{figure}[hbt] \centering \small \begin{tabular}{c} \includegraphics[width=0.8\textwidth]{ImageDevA} \\ \end{tabular} \caption{設備A示意圖}\label{Fig:DeviceA\UserDefinedVar} \end{figure} \@namedef{CommandDeviceA\UserDefinedVar}{} } \makeatother % \renewcommand\UserDefinedVar{Twice} 工藝2也采用了設備A,見圖\ref{Fig:DeviceA\UserDefinedVar}。 \makeatletter \@ifundefined{CommandDeviceA\UserDefinedVar}{ \begin{figure}[hbt] \centering \small \begin{tabular}{c} \includegraphics[width=0.8\textwidth]{ImageDevA} \\ \end{tabular} \caption{設備A示意圖}\label{Fig:DeviceA\UserDefinedVar} \end{figure} \@namedef{CommandDeviceA\UserDefinedVar}{} } \makeatother % \renewcommand\UserDefinedVar{ThirdTime} 工藝3同樣采用了設備A,見圖\ref{Fig:DeviceA\UserDefinedVar}。 \makeatletter \@ifundefined{CommandDeviceA\UserDefinedVar}{ \begin{figure}[hbt] \centering \small \begin{tabular}{c} \includegraphics[width=0.8\textwidth]{ImageDevA} \\ \end{tabular} \caption{設備A示意圖}\label{Fig:DeviceA\UserDefinedVar} \end{figure} \@namedef{CommandDeviceA\UserDefinedVar}{} } \makeatother .......
此片段在編譯后,只會出現一幅圖片,后兩段的引用指向第一次出現的標簽位置。
如果取消掉注釋的兩行,則用戶變量在過程中變化,編譯后會出現3幅圖片,每個段落引用各自的標簽位置。