
다음 명령을 정의했습니다.
\newcommand{\formatcommand}[1]{
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
이것은 올바르게 작동합니다:
\formatcommand{}
\formatcommand{ }
그러나 내부에서 위의 명령을 사용하는 경우 \write18
,
\immediate\write18{\formatcommand{}}
s \def
가 확장되지 않는 것 같습니다. 이는 의 본문을 명령줄로 확장하지 않고 보낸 \def is not an executable...
것을 의미합니다 . 이 문제를 어떻게 해결할 수 있나요?\write18
\formatcommand{}
MWE
\documentclass[border=1cm]{standalone}
\begin{document}
\newcommand{\formatcommand}[1]{
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
\formatcommand{}
\formatcommand{ }
\immediate\write18{\formatcommand{}}
\end{document}
답변1
TeX이 명령의 내용을 작성할 때 \write
정의에서 발생하는 것과 유사하게 모든 자료를 확장합니다. \edef
즉, 확장 가능한 모든 명령이 확장되지만 실행은 발생하지 않습니다. 매크로 정의(또는 기타 할당)는 확장할 수 없으므로 \def
s는 쉘 명령으로 작성될 때 입력 스트림에 남아 있습니다.
해결책은 다음 \ifempty
매크로와 같이 빈 토큰 목록에 대해 완전히 확장 가능한 테스트를 사용하는 것입니다.
\makeatletter
\newcommand\ifempty[1]{%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\newcommand{\formatcommand}[1]{
echo "\ifempty{#1}{empty}{not empty}"
}
답변2
일반적으로 나는 siracusa'a 솔루션을 권장하지만 LuaTeX를 사용하는 경우 문제를 확장 가능한 방식으로 작성할 수 없는 경우 사용할 수 있는 또 다른 트릭이 있습니다.
LuaTeX에는 기본 요소가 있으며 \immediateassignment
확장 가능한 s를 \immediateassigned
허용합니다 \def
.
\documentclass[border=1cm]{standalone}
\begin{document}
\newcommand{\formatcommand}[1]{
\immediateassignment\def\temp{#1}
\immediateassignment\def\s{\ifx\temp\empty empty\else not empty\fi}
echo "\s"
}
\formatcommand{}
\formatcommand{ }
\immediate\write255{\formatcommand{}}
\end{document}
( LuaTeX에서는 shell-escape가 다르게 작동하기 때문에 터미널에 명령을 표시하기 위해 \write18
로 대체했기 때문에 명령을 실행하려면 더 큰 변경이 필요했을 것입니다.)\write255
를 사용하면 \immediateassigned
블록의 모든 할당을 확장 가능하게 만들 수 있습니다.
\documentclass[border=1cm]{standalone}
\begin{document}
\newcommand{\formatcommand}[1]{
\immediateassigned{%
\def\temp{#1}
\def\s{\ifx\temp\empty empty\else not empty\fi}
}%
echo "\s"
}
\formatcommand{}
\formatcommand{ }
\immediate\write255{\formatcommand{}}
\end{document}