\input 인수로 확장되지 않는 강력한 명령

\input 인수로 확장되지 않는 강력한 명령

정말 도움이 필요했습니다. 저는 몇 년 동안 LaTeX를 아무렇지도 않게 사용해왔지만 세부 사항이나 문제에 대해 자세히 알아볼 필요가 거의 없었으며 이를 파악할 수 없습니다.

문제

나는 .cls(아마도) 문제가 있는 라인이 있는 내 조직에서 나에게 제공된 파일로 작업하고 있습니다. 입력된 포인트 크기의 두 번째 자리를 저장한 다음 이를 사용하여 .clo파일을 입력하는 매크로를 정의합니다. 페어링된 MWE는 다음과 같습니다.

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{mwe}

\RequirePackage{etoolbox}
\newrobustcmd\@ptsize{}

\DeclareOption{10pt}{\renewrobustcmd\@ptsize{0}}
\DeclareOption{11pt}{\renewrobustcmd\@ptsize{1}}
\DeclareOption{12pt}{\renewrobustcmd\@ptsize{2}}

\ExecuteOptions{11pt}
\ProcessOptions
\input{size1\@ptsize.clo}

.tex또한 컴파일할 MWE 파일도 만들었습니다 .

\documentclass[11pt]{mwe}

\begin{document}
    
\end{document}

그러나 (LaTeX Workshop을 사용하는 VSCode 내에서) 이것을 사용하여 컴파일할 때 latexmk -synctex=1 -interaction=nonstopmode -file-line-error -pdf -outdir=%OUTDIR% %DOC%다음과 같은 메시지와 함께 이 로그 파일을 얻습니다.

`File `[email protected]' not found`

로그는 다음과 같이 말합니다.

This is pdfTeX, Version 3.14159265-2.6-1.40.21 (MiKTeX 20.11) (preloaded format=pdflatex 2020.11.3)  3 NOV 2020 08:57
entering extended mode
**"path/to/mwe/mwe.tex"
("path/to/mwe/mwe.tex"
LaTeX2e <2020-10-01> patch level 2
L3 programming layer <2020-10-27> xparse <2020-03-03> ("path/to\mwe\mwe.cls" <-- In case it matters, these slashes
Document Class: mwe                                                              really do switch directions
(path\to\tex/latex/etoolbox\etoolbox.sty                                     <-- Here as well
Package: etoolbox 2020/10/05 v2.5k e-TeX tools for LaTeX (JAW)
\etb@tempcnta=\count175
)

! LaTeX Error: File `[email protected]' not found.

Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: clo)

Enter file name: 

잠재적인 해결책

문제는 다음과 같습니다. via and 대신 and 를 통해 정의 .cls되도록 파일 을 변경하면 위의 MWE 파일이 제대로 작동하여 빈(2페이지 분량) PDF가 생성됩니다.@ptsize\newcommand\renewcommand\newrobustcmd\renewrobustcmd.tex

누구든지 a) 이런 일이 발생하는 이유를 설명하고(내가 아는 한 이 .cls파일은 내 조직의 다른 사람들에게 잘 작동함) b) 이 문제에 대한 모범 사례 접근 방식이 무엇인지 설명할 수 있습니까? 미리 감사드립니다!

답변1

동작의 차이는 다음 예제 코드에서 확인할 수 있습니다.

\makeatletter
\protected\def\@ptsize{1}
\input{size1\@ptsize.clo}
\stop

예전에는 input 을 사용했지만 size11.clo2020-10-01 LaTeX 릴리스부터는 더 이상 입력하지 않고 다음과 같은 오류가 발생합니다.

! LaTeX Error: File `[email protected]' not found.

Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: clo)

Enter file name:

이는 LaTeX의 파일 이름 구문 분석 메커니즘이 의도적으로 변경된 것입니다. 이는 보호된 매크로를 확장하지 않는 보다 강력한 파서(다른 여러 기능과 함께)로 대체되었습니다. 새로운 파서의 동작은 강력한 매크로에 관한 올바른 동작입니다.할 수 없다어떤 식으로든 중단될 수 있으므로 확장 전용 컨텍스트에서 작업합니다( ~할 수 있다 찾다 ~의 ~의 저것 ) 따라서 확장하지 않는 것이 합리적입니다.

조직의 클래스 파일은 일부 데이터(일반적으로 "토큰 목록"이라고 함)를 저장하기 위해 강력한 명령을 오용합니다. 그러한 데이터는 대부분 항상 다른 매크로에서 사용할 수 있어야 하므로 확장해야 하므로 견고하거나 보호될 수 없습니다. 클래스 파일을 편집할 수 있는 경우 올바른 방법은 다음 \(re)newrobustcmd으로 바꾸는 것입니다 \(re)newcommand.

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{mwe}

\RequirePackage{etoolbox}
\newcommand\@ptsize{}

\DeclareOption{10pt}{\renewcommand\@ptsize{0}}
\DeclareOption{11pt}{\renewcommand\@ptsize{1}}
\DeclareOption{12pt}{\renewcommand\@ptsize{2}}

\ExecuteOptions{11pt}
\ProcessOptions
\input{size1\@ptsize.clo}

참고로 오류 메시지는

! LaTeX Error: File `[email protected]' not found.

파일 이름 파서가 \escapechar=-1와 함께 작동하고 와 \@ptsize일치하여 가 되기 때문에 그렇게 보입니다 .\string@ptsize

답변2

모호한 이유로 강력한 매크로에서 검색할 수 있는 데이터를 저장해야 하는 경우, \expandafter/ \romannumeral/인수 교환 트릭을 ​​사용하여 확장을 트리거하고 토큰의 올바른 순서로 배치할 수 있습니다.

파일 mwe.cls:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{mwe}

\RequirePackage{etoolbox}
\newrobustcmd\@ptsize{}

\DeclareOption{10pt}{\renewrobustcmd\@ptsize{0}}
\DeclareOption{11pt}{\renewrobustcmd\@ptsize{1}}
\DeclareOption{12pt}{\renewrobustcmd\@ptsize{2}}

\newcommand\exchangeargs[2]{#2#1}

\ExecuteOptions{11pt}
\ProcessOptions
% It is not relied on \input expanding and putting into correct order
% tokens of its argument.
% Instead \romannumeral-expansion brings all tokens into
% correct order before \input and \input's filename-parsing 
% come into action.
% (This way things might sustain more changes to \input's 
% filename-parsing.)
\expandafter\input\expandafter{%
  \romannumeral
  \expandafter\exchangeargs\expandafter{\@ptsize}{\z@ size1}.clo%
}

내 시스템에서 파일을 컴파일하는 중입니다 test.tex.

\documentclass{mwe}
\stop

다음 콘솔 출력이 생성됩니다.

$ pdflatex test.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2020-10-01> patch level 2
L3 programming layer <2020-10-27> xparse <2020-03-03> (./mwe.cls
Document Class: mwe 
(/usr/local/texlive/2020/texmf-dist/tex/latex/etoolbox/etoolbox.sty)
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/size11.clo)) )
No pages of output.
Transcript written on test.log.

그리고 이 파일은 test.log:

This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex 2020.11.23)  4 DEC 2020 19:47
entering extended mode
 restricted \write18 enabled.
 %&-line parsing enabled.
**test.tex
(./test.tex
LaTeX2e <2020-10-01> patch level 2
L3 programming layer <2020-10-27> xparse <2020-03-03> (./mwe.cls
Document Class: mwe 
(/usr/local/texlive/2020/texmf-dist/tex/latex/etoolbox/etoolbox.sty
Package: etoolbox 2020/10/05 v2.5k e-TeX tools for LaTeX (JAW)
\etb@tempcnta=\count175
)
(/usr/local/texlive/2020/texmf-dist/tex/latex/base/size11.clo
File: size11.clo 2020/04/10 v1.4m Standard LaTeX file (size option)
)) ) 
Here is how much of TeX's memory you used:
 364 strings out of 479485
 4393 string characters out of 5871962
 273140 words of memory out of 5000000
 17462 multiletter control sequences out of 15000+600000
 535388 words of font info for 30 fonts, out of 8000000 for 9000
 1141 hyphenation exceptions out of 8191
 52i,1n,59p,208b,36s stack positions out of 5000i,500n,10000p,200000b,80000s

No pages of output.
PDF statistics:
 0 PDF objects out of 1000 (max. 8388607)
 0 named destinations out of 1000 (max. 500000)
 1 words of extra memory for PDF output out of 10000 (max. 10000000)

귀하의 질문에:

a) 이런 일이 발생하는 이유를 설명합니다. (내가 아는 한, 이 .cls 파일은 내 조직의 다른 사람들에게 잘 작동합니다.)

LaTeX 2ε-커널에 중요한 변경 사항이 도입되었습니다. 최근 변경 사항 중 하나는 \input{...}강력한 매크로 주장 내에서 확장되지 않는다는 것입니다 .

이러한 변화는 좋은 동시에 성가신 일입니다. 많은 일에 있어서 지금은 작동 방식이 더 엄격해 보이기 때문에 좋은 것입니다. 코드를 다시 보고 익숙해져야 하기 때문에 귀찮습니다. ;-)

아마도 조직의 다른 사람들은 최신 LaTeX 2ε-커널 릴리스 중 하나를 사용하지 않을 것이므로 LaTeX 2ε-커널의 최신 릴리스에 도입된 변경 사항은 해당 컴퓨터에서 작동하는 방식에 영향을 미치지 않습니다. .

b) 이 문제에 대한 모범 사례 접근 방식은 무엇입니까?

이것이 "모범 사례"인지는 모르겠지만 지난 2년 동안 너무 많은 변화가 있었기 때문에 LaTeX 2ε-커널 매크로에 의존하여 20년 넘게 익숙했던 방식으로 작업하는 것을 중단했습니다. ;-)

특히 나는 이틀 전과 같은 방식으로 확장을 수행하면서 다른 사람이 관리하는 코드에 더 이상 의존하지 않기 때문에 다른 사람의 매크로에 대한 인수로 항목이 넘겨지기 전에 내 코드에서 모든 확장 작업을 수행하는 경우가 많습니다.

나는 변화와 혁신에 만족하지 않기 때문에 이렇게 하는 것이 아닙니다.

나는 가능한 한 많은 LaTeX 2ε 릴리스와 호환되는 내 코드를 만들기 위해 그렇게 합니다.

관련 정보