如何透過向檔案名稱傳遞參數來快速切換 .tex 檔案?

如何透過向檔案名稱傳遞參數來快速切換 .tex 檔案?

例如

我有兩個具有相似檔案名稱結構的 TeX 專案:

在此輸入影像描述

master.tex 的架構如下:

\input{preamble.tex} % <- \bibliography{Projekt_A_Literature} in preamble

% ...

\begin{document}

% ...

    \include{chapter/Projekt_A_cp1.tex}
    \include{chapter/Projket_A_cp2.tex}
    \include{chapter/Projekt_A_cp3.tex}

% ...

\end{document}

目的是:我可以輕鬆快速地更改要輸入的章節文件組。

\include{chpater/Project_A_cp1.tex}        \include{chpater/Project_B_cp1.tex}
\include{chpater/Project_A_cp2.tex}  ==>   \include{chpater/Project_B_cp2.tex} 
\include{chapter/Project_A_cp3.tex}        \include{chpater/Project_B_cp3.tex}

一個簡單但不優雅的方法是:

\newcommand{\prjindex}{A} $ or \def\prjindex{A}
%...
\begin{document}
  \include{chpater/Project_\prjindex_cp1.tex}
  \include{chpater/Project_\prjindex_cp2.tex}
  \include{chpater/Project_\prjindex_cp3.tex}    
\end{document}

這個解決方案的問題是,如果我不在主TeX檔案中編譯,它會給出類似的錯誤

未定義的控制序列....{Project_\prjindex_Literature.tex}。

所以我來這裡尋求更優雅的解決方案

答案1

似乎您需要一種“機制”來在未“手動”提供\prjindex定義的情況下進行自動檢測。\prjindex


初步評論:

通常原語的擴充\jobname形成了用於啟動編譯的檔案的名稱(不含副檔名)。

testfile.tex例如,如果您透過命令列編譯一個主文件的項目
latex testfile.tex
,則原語\jobname將擴展為短語testfile
由 提供的短語中的字元標記\jobname將始終屬於類別代碼 12(其他),而空格將始終屬於類別代碼 10(空格)。

testfile來自擴展的短語\jobname將用於

  • 建立 .log 檔案: .log 檔案將被命名為testfile.log
  • 建立主 .aux 檔案:該檔案將被命名為testfile.aux.
  • 建立保存目錄資料的 .toc 檔案:該檔案將命名為 .toc 檔案testfile.toc
  • 建立保存圖形清單資料的 .lof 檔案:該檔案將命名為 .lof 檔案testfile.lof
  • 建立保存表格清單資料的 .lot 檔案:該檔案將被命名為testfile.lot
  • ETC。

但對於當今大多數 TeX 發行版,您可以擁有 (La)TeX偏離通常的處理事情的方式:

對於當今大多數 TeX 發行版,您可以在命令列中提供命令列選項(‑‑jobname-選項),它可以讓您更改將提供的短語\jobname

testfile.tex例如,如果您透過命令列編譯一個主文件的項目
latex --jobname=foobar testfile.tex
,則原語\jobname將擴展為短語foobar

foobar在這種情況下,來自擴展的短語\jobname將用於

  • 建立 .log 檔案: .log 檔案將被命名為foobar.log
  • 建立主 .aux 檔案:該檔案將被命名為foobar.aux.
  • 建立保存目錄資料的 .toc 檔案:該檔案將命名為 .toc 檔案foobar.toc
  • 建立保存圖形清單資料的 .lof 檔案:該檔案將命名為 .lof 檔案foobar.lof
  • 建立保存表格清單資料的 .lot 檔案:該檔案將被命名為foobar.lot
  • ETC。

根據我下面的建議,LaTeX 需要處理一些事情在裡面通常的方式,即要編譯的東西沒有提供一些‑‑jobname-選項

因此,我下面的建議不適合使用此類(線上)LaTeX 平台/TeX 編輯器/使用者介面的人,這些介面在幕後配置為使用 - 選項‑‑jobname


以防萬一

  1. 所有那些在編譯期間其定義將被“自動檢測”的文件的名稱\prjindex(因為它不會“手動”定義)都具有模式-都表示項目並且不為空且不包含下劃線 ( ) -Projekt_⟨#1⟩_⟨#2⟩.tex⟨#1⟩_
, 和

  1. \prjindex呼叫 Latex 進行「獨立編譯」文件,在其編譯過程中,總是會發生「自動檢測」的定義沒有呼叫‑‑jobname- 選項(這意味著 -primitive 的擴展形成\jobname用於啟動編譯的檔案的名稱(不帶擴展名))
,我可以提供一個宏\GetPrjindexFromJobnameIfUndefined,其作用如下:

如果巨集\prjindex已經定義,則它不執行任何操作。

如果\prjindex未定義巨集,它會檢查\jobname-primitive 的擴充是否為 pattern 。如果不屬於該模式,則會觸發錯誤訊息。如果是該模式,將檢查是否為空。如果是這種情況,將觸發錯誤訊息。如果不是這種情況,巨集將被定義為擴展為.Projekt_⟨#1⟩_⟨#2⟩⟨#1⟩\prjindex⟨#1⟩

我無法決定該例程是否對您有用,因為您沒有詳細透露專案文件結構的這一部分是如何組織的,這使得可以編譯“獨立”的單個文件當通過或。Projekt_⟨#1⟩_⟨#2⟩.tex\input\include

如果所有專案檔案以某種方式共用相同的前導碼,您可以透過該前導碼使此例程可供所有專案檔案使用。

也許您可以將該例程(以及對它的呼叫)包含到您的例程中,如果已經定義了preamble.tex.該例程,則例程不會執行任何操作。 所以\prjindex

  • master.tex你可以定義的範圍內\prjindex 輸入preamble.tex.
  • 獨立編譯您的其中一個檔案的情況會導致輸入while尚未定義,這反過來會導致例程「自動檢測」並通過檢查.Projekt_⟨#1⟩_⟨#2⟩.tex\preamble.tex\prjindex\GetPrjindexFromJobnameIfUndefined\prjindex\jobname

\documentclass{article}

%%========Code for \GetPrjindexFromJobnameIfUndefined=========
\begingroup
\makeatletter
\def\prjprephrase{Projekt_}%
\def\prjpostphrase{_}%
% \jobname delivers everything but the space (which will be of catcode 10) 
% with catcode 12(other). Therefore "sanitizing" is needed for turning
% everything but the space into catcode 12(other):
\@onelevel@sanitize\prjprephrase
\@onelevel@sanitize\prjpostphrase
\newcommand\GetPrjindexFromJobnameIfUndefined[2]{%
  \endgroup
  \newcommand\GetPrjindexFromJobnameIfUndefined{%
    \@ifundefined{prjindex}{%
      \expandafter\GetPrjindexCheckPattern\jobname$#1#2$&%
    }{}%
  }%
  \@ifdefinable\GetPrjindexCheckPattern{%
    \def\GetPrjindexCheckPattern##1#1##2#2##3$##4&{%
      \GetPrjindexPatternfork
      &##4&{\expandafter\GetPrjindexExtractfrompattern\jobname$}%
      &#1#2$&{%
        \GenericError{(\string\prjindex)\space}{%
          Error on input line \the \inputlineno:\MessageBreak
          \string\GetPrjindexFromJobnameIfUndefined\space cannot extract the\MessageBreak
          \string\prjindex\space from \string\jobname's expansion.\MessageBreak
          (\string\GetPrjindexFromJobnameIfUndefined\space is defined\MessageBreak
           \space somewhere in this document.)\@gobble
        }{Have a look at the comments in this document.}%
        {%
          \string\GetPrjindexFromJobnameIfUndefined\space can extract the \string\prjindex\MessageBreak
          from \string\jobname's expansion only in case \string\jobname's expansion is\MessageBreak
          of pattern\MessageBreak
          \@spaces #1\string####1#2\string####2\MessageBreak
          while \string####1 is not empty.\MessageBreak
          If this is the case, the expansion of \string\prjindex\space will be \string####1.\MessageBreak
          \string####1 will not contain underscores (\string_).\MessageBreak
          \string####2 can contain underscores.\MessageBreak
        }%
      }%
      &&&&%
    }%
  }%
  \@ifdefinable\GetPrjindexPatternfork{%
    \def\GetPrjindexPatternfork##1&#1#2$&##2##3&&&&{##2}%
  }%
  \@ifdefinable\GetPrjindexExtractfrompattern{%
    \def\GetPrjindexExtractfrompattern#1##1#2##2${%
      \ifx\relax##1\relax
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
      {%
        \GenericError{(\string\prjindex)\space}{%
          Error on input line \the \inputlineno:\MessageBreak
          \string\prjindex\space is empty.\MessageBreak
          (\string\GetPrjindexFromJobnameIfUndefined\space is defined\MessageBreak
           \space somewhere in this document.)\@gobble
        }{Have a look at the comments in this document.}%
        {%
          \string\GetPrjindexFromJobnameIfUndefined\space can extract the \string\prjindex\MessageBreak
          from \string\jobname's expansion only in case \string\jobname's expansion is\MessageBreak
          of pattern\MessageBreak
          \@spaces #1\string####1#2\string####2\MessageBreak
          while \string####1 is not empty.\MessageBreak
          If this is the case, the expansion of \string\prjindex\space will be \string####1.\MessageBreak
          \string####1 will not contain underscores (\string_).\MessageBreak
          \string####2 can contain underscores.\MessageBreak
        }%
      }%
      {\newcommand*\prjindex{##1}}%
    }%
  }%
}%
\expandafter\expandafter\expandafter\GetPrjindexFromJobnameIfUndefined
\expandafter\expandafter\expandafter{\expandafter\prjprephrase\expandafter}%
\expandafter{\prjpostphrase}%
%%=====End of code for \GetPrjindexFromJobnameIfUndefined=====

\GetPrjindexFromJobnameIfUndefined

\show\prjindex

\begin{document}
Some document
\end{document}

順便說一句:為了測試例程,我將上面的範例儲存為test.tex並編譯它,呼叫‑‑jobname具有不同值的 - 選項。

透過命令編譯,latex test.tex結果符合預期:

! Error on input line 80:
(\prjindex) \GetPrjindexFromJobnameIfUndefined cannot extract the
(\prjindex) \prjindex from \jobname's expansion.
(\prjindex) (\GetPrjindexFromJobnameIfUndefined is defined
(\prjindex)  somewhere in this document.)

Have a look at the comments in this document.
Type  H <return>  for immediate help.
 ...                                              

l.80 \GetPrjindexFromJobnameIfUndefined

? 
> \prjindex=undefined.
l.82 \show\prjindex

這是預料之中的,因為在本例中\jobname擴展到了test不屬於模式的範圍。
Projekt_⟨#1⟩_⟨#2⟩

透過命令編譯,latex ‑‑jobname=Projekt_A_4  test.tex結果符合預期:

\prjindex=macro:
->A.
l.82 \show\prjindex

(當範例儲存為Projekt_A_4.tex並透過命令編譯時,您會得到相同的結果latex Projekt_A_4.tex。)

透過命令編譯,latex ‑‑jobname=Projekt_B_4 test.tex結果符合預期:

\prjindex=macro:
->B.
l.82 \show\prjindex

(當範例儲存為Projekt_B_4.tex並透過命令編譯時,您會得到相同的結果latex Projekt_B_4.tex。)

透過命令編譯,latex ‑‑jobname=Projekt_JohannGambolputty_12345 test.tex結果符合預期:

\prjindex=macro:
->JohannGambolputty.
l.82 \show\prjindex

(當範例儲存為Projekt_JohannGambolputty_12345.tex並透過命令編譯時,您會得到相同的結果latex Projekt_JohannGambolputty_12345.tex。)

順便一提:

有時我會按如下方式組織我的專案文件:

序.tex

% Check whether the \documentclass-command was already invoked.
% If so, increment \inputlevel and stop inputting.
% If not so, don't stop imputting and thus do all the
% preamble-stuff, inclusive defining \inputlevel:
\expandafter\ifx\csname @twoclasseserror\endcsname\documentclass
  \xdef\inputlevel{\number\numexpr\inputlevel+1\relax}%
  \expandafter\endinput
\fi
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
\documentclass{article}%
% 
\newcommand*\inputlevel{1}%
\global\let\inputlevel=\inputlevel
%
% Whatsoever preamble-commands, etc.
%
% Here you can also place the code for defining \GetPrjindexFromJobnameIfUndefined
% and then invoke it for defining \prjindex:
%
%%========Code for \GetPrjindexFromJobnameIfUndefined=========
\begingroup
\makeatletter
\def\prjprephrase{Projekt_}%
\def\prjpostphrase{_}%
% \jobname delivers everything but the space (which will be of catcode 10) 
% with catcode 12(other). Therefore "sanitizing" is needed for turning
% everything but the space into catcode 12(other):
\@onelevel@sanitize\prjprephrase
\@onelevel@sanitize\prjpostphrase
\newcommand\GetPrjindexFromJobnameIfUndefined[2]{%
  \endgroup
  \newcommand\GetPrjindexFromJobnameIfUndefined{%
    \@ifundefined{prjindex}{%
      \expandafter\GetPrjindexCheckPattern\jobname$#1#2$&%
    }{}%
  }%
  \@ifdefinable\GetPrjindexCheckPattern{%
    \def\GetPrjindexCheckPattern##1#1##2#2##3$##4&{%
      \GetPrjindexPatternfork
      &##4&{\expandafter\GetPrjindexExtractfrompattern\jobname$}%
      &#1#2$&{%
        \GenericError{(\string\prjindex)\space}{%
          Error on input line \the \inputlineno:\MessageBreak
          \string\GetPrjindexFromJobnameIfUndefined\space cannot extract the\MessageBreak
          \string\prjindex\space from \string\jobname's expansion.\MessageBreak
          (\string\GetPrjindexFromJobnameIfUndefined\space is defined\MessageBreak
           \space somewhere in this document.)\@gobble
        }{Have a look at the comments in this document.}%
        {%
          \string\GetPrjindexFromJobnameIfUndefined\space can extract the \string\prjindex\MessageBreak
          from \string\jobname's expansion only in case \string\jobname's expansion is\MessageBreak
          of pattern\MessageBreak
          \@spaces #1\string####1#2\string####2\MessageBreak
          while \string####1 is not empty.\MessageBreak
          If this is the case, the expansion of \string\prjindex\space will be \string####1.\MessageBreak
          \string####1 will not contain underscores (\string_).\MessageBreak
          \string####2 can contain underscores.\MessageBreak
        }%
      }%
      &&&&%
    }%
  }%
  \@ifdefinable\GetPrjindexPatternfork{%
    \def\GetPrjindexPatternfork##1&#1#2$&##2##3&&&&{##2}%
  }%
  \@ifdefinable\GetPrjindexExtractfrompattern{%
    \def\GetPrjindexExtractfrompattern#1##1#2##2${%
      \ifx\relax##1\relax
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
      {%
        \GenericError{(\string\prjindex)\space}{%
          Error on input line \the \inputlineno:\MessageBreak
          \string\prjindex\space is empty.\MessageBreak
          (\string\GetPrjindexFromJobnameIfUndefined\space is defined\MessageBreak
           \space somewhere in this document.)\@gobble
        }{Have a look at the comments in this document.}%
        {%
          \string\GetPrjindexFromJobnameIfUndefined\space can extract the \string\prjindex\MessageBreak
          from \string\jobname's expansion only in case \string\jobname's expansion is\MessageBreak
          of pattern\MessageBreak
          \@spaces #1\string####1#2\string####2\MessageBreak
          while \string####1 is not empty.\MessageBreak
          If this is the case, the expansion of \string\prjindex\space will be \string####1.\MessageBreak
          \string####1 will not contain underscores (\string_).\MessageBreak
          \string####2 can contain underscores.\MessageBreak
        }%
      }%
      {\newcommand*\prjindex{##1}}%
    }%
  }%
}%
\expandafter\expandafter\expandafter\GetPrjindexFromJobnameIfUndefined
\expandafter\expandafter\expandafter{\expandafter\prjprephrase\expandafter}%
\expandafter{\prjpostphrase}%
%%=====End of code for \GetPrjindexFromJobnameIfUndefined=====
% 
% This will define \prjindex depending on the expansion of \jobname
% while \jobname usually represents the name of the file used for
% initiating compilation:
%
% !!! I don't know whether, e.g., online-latex-plattforms like overleaf
% !!! invoke latex using the -jobname-option, which would lead to
% !!! the expansion of \jobname deviating from the name of the file
% !!! used for initiating compilation.
%
\GetPrjindexFromJobnameIfUndefined
%
% With subsequent preamble-commands you can, if you wish, fork depending on
% the expansion of \prjindex. But be aware that like \jobname \prjindex also
% holds only characters of catcode 12(other) and spaces of catcode 10(space).
% Therefore when storing a string in a temporary macro (this should, like
% \prjindex not be defined in terms of \long, which is the case with
% \def or \newcommand*) and \ifx-comparing that temporary macro to \prjindex,
% make sure that the definition of that temporary macro is "sanitized" by
% means of \@onelevel@sanitize before doing the \ifx-comparison.
%
%  \usepackage...
%  \usepackage...
%
\begin{document}%
\endinput
|
| Place whatsoever comments remarks and explanations and manuals you wish to place 
| here. They won't be processed because LaTeX ceases reading and processing this
| file when encountering \endinput.

後置碼.tex

\csname @\ifnum\inputlevel>1 second\else first\fi oftwo\endcsname
{%
  \end{document}%
}{%
  \xdef\inputlevel{\number\numexpr\inputlevel-1\relax}%
}%

項目_A_cp1.tex

%----------------------
\input{Preamble.tex}%
%----------------------
This is file \texttt{Projekt\string_A\string_cp1.tex}\par
This is the text in file \texttt{Projekt\string_\prjindex\string_cp1.tex}.\par
The file \texttt{Projekt\string_\prjindex\string_cp1.tex} invokes the file \texttt{Projekt\string_\prjindex\string_cp2.tex}:\par
\input{Projekt_\prjindex_cp2.tex}%
%----------------------
\input{Postamble.tex}%
%----------------------

項目_A_cp2.tex

%----------------------
\input{Preamble.tex}%
%----------------------
This is file \texttt{Projekt\string_A\string_cp2.tex}\par
This is the text in file \texttt{Projekt\string_\prjindex\string_cp2.tex}.\par
The file \texttt{Projekt\string_\prjindex\string_cp2.tex} invokes the file \texttt{Projekt\string_\prjindex\string_cp3.tex}:\par
\input{Projekt_\prjindex_cp3.tex}%
%----------------------
\input{Postamble.tex}%
%----------------------

項目_A_cp3.tex

%----------------------
\input{Preamble.tex}%
%----------------------
This is file \texttt{Projekt\string_A\string_cp3.tex}\par
This is the text in file \texttt{Projekt\string_\prjindex\string_cp3.tex}.\par
%----------------------
\input{Postamble.tex}%
%----------------------

項目_B_cp1.tex

%----------------------
\input{Preamble.tex}%
%----------------------
This is file \texttt{Projekt\string_B\string_cp1.tex}\par
This is the text in file \texttt{Projekt\string_\prjindex\string_cp1.tex}.\par
The file \texttt{Projekt\string_\prjindex\string_cp1.tex} invokes the file \texttt{Projekt\string_\prjindex\string_cp2.tex}:\par
\input{Projekt_\prjindex_cp2.tex}%
%----------------------
\input{Postamble.tex}%
%----------------------

項目_B_cp2.tex

%----------------------
\input{Preamble.tex}%
%----------------------
This is file \texttt{Projekt\string_B\string_cp2.tex}\par
This is the text in file \texttt{Projekt\string_\prjindex\string_cp2.tex}.\par
The file \texttt{Projekt\string_\prjindex\string_cp2.tex} invokes the file \texttt{Projekt\string_\prjindex\string_cp3.tex}:\par
\input{Projekt_\prjindex_cp3.tex}%
%----------------------
\input{Postamble.tex}%
%----------------------

項目_B_cp3.tex

%----------------------
\input{Preamble.tex}%
%----------------------
This is file \texttt{Projekt\string_B\string_cp3.tex}\par
This is the text in file \texttt{Projekt\string_\prjindex\string_cp3.tex}.\par
%----------------------
\input{Postamble.tex}%
%----------------------

這樣,每個檔案Projekt_A_cp1.texProjekt_A_cp2.texProjekt_A_cp3.tex 各自的每個檔案Projekt_B_cp1.texProjekt_B_cp2.texProjekt_B_cp3.tex 既可以用於「獨立」編譯,也可以透過同一專案的另一個檔案呼叫\input或透過\include同一專案的另一個檔案呼叫。

Preamble.tex可以包含根據 的含義進行分叉的程式碼\prjindex,因此對於同一前導文件中的不同項目可以以不同的方式處理事情。

答案2

我不確定問題是什麼,但您肯定需要更改程式碼:\include必須的參數不是.tex擴展名。

\documentclass{book}

% why shouldn't this be elegant
\newcommand{\projectindex}{B}

\begin{document}

\include{chapter/Project_\projectindex_cp1}
\include{chapter/Project_\projectindex_cp2}
\include{chapter/Project_\projectindex_cp3}

\end{document}

這是編譯此程式碼時的終端輸出

pdflatex sun
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./sun.tex
LaTeX2e <2019-10-01> patch level 3
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/book.cls
Document Class: book 2019/10/25 v1.4k Standard LaTeX document class
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/bk10.clo)) (./sun.aux
(./chapter/Project_B_cp1.aux) (./chapter/Project_B_cp2.aux)
(./chapter/Project_B_cp3.aux)) (./chapter/Project_B_cp1.tex
Chapter 1.
) [1{/usr/local/texlive/2019/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
(./chapter/Project_B_cp2.tex [2]
Chapter 2.
) [3] (./chapter/Project_B_cp3.tex [4]
Chapter 3.
) [5] (./sun.aux (./chapter/Project_B_cp1.aux) (./chapter/Project_B_cp2.aux)
(./chapter/Project_B_cp3.aux)) )</usr/local/texlive/2019/texmf-dist/fonts/type1
/public/amsfonts/cm/cmbx12.pfb></usr/local/texlive/2019/texmf-dist/fonts/type1/
public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2019/texmf-dist/fonts/type1/pu
blic/amsfonts/cm/cmsl10.pfb>
Output written on sun.pdf (5 pages, 30009 bytes).

如果我更改為\newcommand{\projectindex}{A},兩次運行 LaTeX 後我得到

pdflatex sun
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./sun.tex
LaTeX2e <2019-10-01> patch level 3
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/book.cls
Document Class: book 2019/10/25 v1.4k Standard LaTeX document class
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/bk10.clo)) (./sun.aux
(./chapter/Project_A_cp1.aux) (./chapter/Project_A_cp2.aux)
(./chapter/Project_A_cp3.aux)) (./chapter/Project_A_cp1.tex
Chapter 1.
) [1{/usr/local/texlive/2019/texmf-var/fonts/map/pdftex/updmap/pdftex.map}]
(./chapter/Project_A_cp2.tex [2]
Chapter 2.
) [3] (./chapter/Project_A_cp3.tex [4]
Chapter 3.
) [5] (./sun.aux (./chapter/Project_A_cp1.aux) (./chapter/Project_A_cp2.aux)
(./chapter/Project_A_cp3.aux)) )</usr/local/texlive/2019/texmf-dist/fonts/type1
/public/amsfonts/cm/cmbx12.pfb></usr/local/texlive/2019/texmf-dist/fonts/type1/
public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2019/texmf-dist/fonts/type1/pu
blic/amsfonts/cm/cmsl10.pfb>
Output written on sun.pdf (5 pages, 29893 bytes).
Transcript written on sun.log.

如您所見,包含了預期的文件。

相關內容