시나리오: yyyy-mm-dd
파일에서 cs로 형식의 날짜를 읽습니다. 이 cs는 나중에 '현재 날짜' 매크로와 비교되어 특정 방식으로 몇 가지 인수를 외부 파일에 씁니다. 현재 날짜 매크로는 다음과 같습니다.
% \def\TODAY{}
% \def\Today{\the\year-\TwoDigits{\the\month}-\TwoDigits{\the\day} }
\def\TODAY{\xdef\Today{\the\year-\TwoDigits{\the\month}-\TwoDigits{\the\day}}}
이는 의도한 대로 작동하므로 라벨링 작업에 적합합니다 \ref{yyyy-mm-dd}
. 추가 항목이 없고 'd Today를 \TODAY
사용하면 \def
작동하지 않는 비교가 됩니다. etoolbox
'는 \ifstrequal
내가 이전에 사용했던 것이 아닙니다. 날짜가 변경될 때마다 나는 단일을 사용 \xdef
하고 나중에 해당 매크로를 에 전달했으며 \ifx
, 그것이 작동하도록 하려면 날짜를 추가하여 정의해야 했습니다 .편집하다놀랍게도 읽은 내용 뒤에 단일 공백이 삽입됩니다.
현재는 뭔가를 고치고 있는 것 같은데 어떻게든 깨뜨려서 지금은 전혀 일치하지 않습니다. 첫 번째 범인은 내 cmd가 강력해서 이를 수정하는 대신 \TwoDigits
다시 변경했다는 것 입니다 . 후자는 사용자 수준 명령을 위한 것이므로 생략하겠습니다. 그러나 mwe의 결과는 나에게 명확하지 않습니다.\def
\NewDocumentCommand
0.txt
2001-01-01
한 줄이 기록되고 출력이 닫힌 것처럼 한 줄이 포함되고 그 뒤에 새로운 줄이 포함됩니다.
질문:
- 문자열로 확장되어야 하는 것(매크로, cs, 명령?)을 비교하는 '올바른' 방법은 무엇입니까?
\edef
여기에서 작업 하면 어떨까요\xdef
? 완전한 확장이라고 생각했는데 실제로 이전에는 (내 버전 관리가 거의 없어서 이에 대한 mwe를 줄 수 없었습니다) 작동했습니다.- 견고함의 중요성은 무엇입니까? 필요하거나, 의무적이거나, 관련이 없을 때 간단한 경험 법칙이 있나요?
- 그것은 와 함께 작동
xstring
합니다\IfStrEqual
오직이 비교의 대괄호가 아닌 의정의에 삽입된 경우 (예: )입니다 . 왜?
\datemacro
{\datemacro }
\ifstrequal
아마도 확장되지 않을 것입니다. 인수가 와 같은지 테스트하기 위해 명령에서 한 번 사용했습니다.&
이것은 작동합니다. #1은 확장으로 간주되지 않는 입력이 되는 것입니까?
편집하다: 구분된 인수가 아닌 매크로에 사용되는 것을 잊어버렸습니다 \ifx
. 죄송합니다.
예시 1;
\documentclass{article}
\usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
\usepackage{etoolbox}
\newread\periods
\openin\periods=0.txt
\begin{document}\setlength\parindent{0pt}\fontsize{20}{20}\selectfont
\def\testi{2001-01-01}
\edef\testii{2001-01-01}
\def\testiii{2001-01-01 }
\edef\testiiii{2001-01-01 }
\global\read\periods to \DDD
\ifstrequal{\testi}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\DDD}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testi}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\DDD}{\DDD}{T\\}{F\\}% T
\ifx{\testi}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testiii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testiiii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\DDD}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testi}{\DDD} T\\\else F\\\fi% F
\ifx{\testii}{\DDD} T\\\else F\\\fi% F
\ifx{\testiii}{\DDD} T\\\else F\\\fi% F
\ifx{\testiiii}{\DDD} T\\\else F\\\fi% F
\ifx{\DDD}{\DDD} T\\\else F\\\fi% F
\ifcsequal{\testi}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\DDD}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testi}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\testiiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\DDD}{\DDD}{T\\}{F\\}% T
\end{document}
예시 2;
\documentclass{article}
\usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
\usepackage{etoolbox,xstring}
\def\TwoDigits#1{\ifnum#1<10 0#1\else#1\fi}
\newcount\month
\month 1\relax
\newcount\day
\day 1\relax
\newread\periods
\openin\periods=0.txt
\global\read\periods to \DDD
\def\testi{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day}}%
\edef\testii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day}}%
\def\testiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%
\edef\testiiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%
\begin{document}\setlength\parindent{0pt}
DDD is \DDD.% space between cs and .
\ifstrequal{\testi}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\DDD}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testi}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\DDD}{\DDD}{T\\}{F\\}% T
\ifx\testi{2001-01-01} T\\\else F\\\fi% F
\ifx\testii{2001-01-01} T\\\else F\\\fi% F
\ifx\testiii{2001-01-01} T\\\else F\\\fi% F
\ifx\testiiii{2001-01-01} T\\\else F\\\fi% F
\ifx\DDD{2001-01-01} T\\\else F\\\fi% F
\ifx\testi\DDD T\\\else F\\\fi% F
\ifx\testii\DDD T\\\else F\\\fi% F
\ifx\testiii\DDD T\\\else F\\\fi% F
\ifx\testiiii\DDD T\\\else F\\\fi% T
\ifx\DDD\DDD T\\\else F\\\fi% T
\ifcsequal{\testi}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\DDD}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testi}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\DDD}{\DDD}{T\\}{F\\}% T
\IfStrEq{\testi}{\DDD}{T\\}{F\\}% F
\IfStrEq{\testii}{\DDD}{T\\}{F\\}% F
\IfStrEq{\testi }{\DDD}{T\\}{F\\}% F
\IfStrEq{\testii }{\DDD}{T\\}{F\\}% F
\IfStrEq{\testiii}{\DDD}{T\\}{F\\}% T
\IfStrEq{\testiiii}{\DDD}{T\\}{F\\}% T
\IfStrEq{\DDD}{\DDD}{T\\}{F\\}% T
\end{document}
답변1
\ifstrequal
문서에서 etoolbox
:
\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
두 문자열을 비교하여 동일하면 ⟨true⟩를 실행하고, 그렇지 않으면 ⟨false⟩를 실행합니다. 문자열은 테스트에서 확장되지 않으며 비교는 범주 코드에 구애받지 않습니다. ⟨string⟩ 인수의 제어 시퀀스 토큰은 토큰화 해제되어 문자열로 처리됩니다. 이 명령은 강력합니다.
따라서 다음과 정확히 동일하지 \ifstrequal{\testi}{...}
않으면 true를 반환하지 않습니다....
\testi
문자열로.
반면에,
\expandafter\ifstrequal\expandafter{\DDD}{2001-01-01 }{T}{F}
을 반환 T
하지만 \read
줄 끝을 확인하여 생성된 트랄링 공간을 확인하세요.
\ifx
이는 기본 조건문이며 적절한 구문과 함께 사용해야 합니다. 확장 없이 토큰 \ifx AB
을 비교합니다 . 그래서 와 비교할 것입니다 .A
B
\ifx{\DDD}...
{
\DDD
\ifcsequal
\ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}
\ifdefequal
제어 시퀀스 이름을 인수로 사용한다는 점을 제외 하면 비슷합니다 .
따라서 및 를 \ifcsequal{\testi}{\DDD}
모두 확장하므로 두 개의 내장된 제어 시퀀스가 모두 와 동일하기 때문에 false를 반환하는 것과 동일합니다 .\testi
\DDD
\ifcsequal{2001-01-01}{2001-01-01 }
\relax
\ifdefequal
여기서 마침내 true를 반환하는 코드를 얻을 수 있습니다. 참고해서 사용하시면
\def\testiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%
그럼 \ifdefequal{\testiii}{\DDD}
돌아올 것이다거짓, 첫 번째 레벨 확장만 살펴보기 때문입니다. 반면에 \edef
버전이 작동합니다.
\IfStrEq
이는 (정상적인 조건에서) 인수를 완전히 확장하므로 \testiiii
또는 둘 중 하나와의 비교가 \testiiii
작동합니다.
견고성
의 견고성은 \ifstrequal
전혀 관련이 없습니다. 글쎄요, 실제로는 완전히는 아닙니다. TeX 엔진이 지원한다면 \expanded
(TeX Live 2019 출시와 함께 몇 주 안에 모두 지원될 예정입니다) 다음과 같습니다.
\expanded{\ifstrequal}{\testiii}{\DDD}{T}{F}}
돌아올 것이며 이것이 작동하려면 T
견고성이 결정적입니다.\ifstrequal
작동 테스트를 사용하십시오.