\write18에서 \def를 확장하세요.

\write18에서 \def를 확장하세요.

다음 명령을 정의했습니다.

\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즉, 확장 가능한 모든 명령이 확장되지만 실행은 발생하지 않습니다. 매크로 정의(또는 기타 할당)는 확장할 수 없으므로 \defs는 쉘 명령으로 작성될 때 입력 스트림에 남아 있습니다.

해결책은 다음 \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}

관련 정보