有关于如何检查宏的参数是否为空的描述\ifx\\#1\\ 代表什么?
不幸的是,我无法让那里的任何例子发挥作用。
除此之外,我还使用了以下代码:
\documentclass{article}
\def\test#1.#2\\{%
\ifx\\#2\\
<no extension #2 is empty, because \\=\\>
\else
<extension is #2>
\fi%
}
\begin{document}
\test myfile.tex
\test myfile
\end{document}
我的代码有什么问题?我使用这些代码片段有什么问题?
在此先感谢您的帮助。
答案1
您使用的代码中没有\\
分隔符,因此可以找到第一个参数,但找不到第二个参数,并且文件在搜索期间结束\\
。
换句话说,您对\test
第一个参数的定义以第一个句点(在大括号级别 0 处)结尾,而第二个参数第一次出现时\\
并不存在。
此外,在第二次调用中没有句点,因此找不到第一个参数。
你必须更加谨慎地做这件事;就像这样:
\def\test#1{\xtest#1.\\}
\def\xtest#1.#2\\{%
\ifx\\#2\\%
\typeout{<no extension>}%
\else
\typeout{<extension is \removedot#2\\>}
\fi}
\def\removedot#1.\\{#1}
并将其称为
\test{file.tex}
\test{file}
让我们看看各种情况:
\test{file.tex}
变成
\xtest file.tex.\\
结果是分配
#1 = file, #2 = tex.
最后一个点将被删除\removedot
。
呼吁
\test{file}
会变成
\xtest file.\\
导致
#1 = file, #2 = <empty>
如预期的。
借助以下方法可以实现更简单的解析xparse
:
\usepackage{xparse}
\NewDocumentCommand{\test}{>{\SplitArgument{1}{.}}m}{\xtest #1}
\NewDocumentCommand{\xtest}{mm}
{%
\IfNoValueTF{#2}
{\typeout{No extension}}
{\typeout{Extension is #2}}%
}
这省去了\removedot
后期处理。
答案2
LaTeX 包含一个文件名解析器:
\documentclass{article}
\makeatletter
\def\test#1{%
\filename@parse{#1}%
\ifx\filename@ext\relax
#1 has no extension%
\else
the extension of #1 is \filename@ext
\fi}
\makeatother
\begin{document}
\test{myfile.tex}
\test{myfile}
\end{document}
答案3
\documentclass{article}
\usepackage{libertine}
\makeatletter
\def\test#1{\expandafter\test@i#1..\@nil}
\def\test@i#1.#2.#3\@nil{%
\ifx\relax#2\relax
<no extension #2 is empty, because \string\relax=\string\relax>
\else
<extension is #2>
\fi}
\makeatletter
\begin{document}
\test{myfile.tex}
\test{myfile}
\def\TEST{myfile.sty}
\test{\TEST}
\end{document}
如果你不想将参数放在括号中(这应该是首选方式),你可以使用类似
\def\test#1/{\expandafter\test@i#1..\@nil}
...
\test foo.bar/
\test foo/