我定义了以下命令:
\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{}
到命令行而不进行扩展。如何解决这个问题?
平均能量损失
\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
当它们被写为 shell 命令时,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 的解决方案,但是如果你使用 LuaTeX,如果你的问题无法以可扩展的方式编写,那么你可以使用另一个技巧:
LuaTeX 具有原语\immediateassignment
和\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}
(我用 替换了\write18
在\write255
终端上显示命令,因为 shell-escape 在 LuaTeX 中的工作方式不同,因此执行命令需要进行更大的更改。)
使用\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}