我正在寻找一个命令,如果输入是 3.2,则允许我获得 3 作为输出。\StrBefore{3.2}{.}
它可以很好地完成此目的,但无法扩展,我需要在\setcounter
命令中的另一个宏中调用它,该命令应该有一个数字,然后扩展该\StrBefore
命令。有没有解决方法\StrBefore
,或者我需要一个不同的函数,哪一个?
\documentclass{book}
\usepackage{xstring}
\newcounter{try}
\newcommand{\foo}[1]{\StrBefore{#1}{.}}
\newcommand\test[1]{\setcounter{try}{\foo{#1}}%
\arabic{try}}
\begin{document}
Result of foo\{3.2\}: \foo{3.2}
Result of test\{3.2\}: \test{3.2}
\end{document}
答案1
一种方法是使用可选参数StrBefore
:
\documentclass{book}
\usepackage{xstring}
\usepackage{ifthen}
\newcounter{try}
\newcommand{\foo}[1]{\StrBefore{#1}{.}[\result]}
\newcommand\test[1]{\foo{#1}\setcounter{try}{\result}\arabic{try}}%
\begin{document}
Result of foo\{3.2\}: \foo{3.2}
Result of test\{3.2\}: \test{3.2}
\end{document}
答案2
另一种方法是自己解析它,而不需要任何分配(除了在前言中定义\foo
和辅助宏):
\documentclass{book}
%\usepackage{xstring}
%\newcommand{\foo}[1]{\StrBefore{#1}{.}}
\makeatletter
\def\fooex#1.#2\@nil{#1}
\newcommand{\foo}[1]{\fooex #1.\@nil}
\makeatother
\newcounter{try}
\newcommand\test[1]{\setcounter{try}{\foo{#1}}%
\arabic{try}}
\begin{document}
Result of foo\{3.2\}: \foo{3.2},
Result of foo\{32\}: \foo{32},
Result of test\{3.2\}: \test{3.2}
\end{document}
使用 Jonathan 的建议进行更新:将一个额外的内容传递.
给辅助宏,以便当输入字符串不包含一个字符串时发生一些合理的情况;使用\@nil
而不是\relax
作为“特殊标记”,现在需要\makeatletter
保护,因为 LaTeX 本身用于\@nil
类似目的,并且它不太可能出现在参数中(如果出现,则更有可能产生有意义的错误)。
答案3
这就是stringstrings
方法。需要了解的事情:
[q]
是安静模式,[v]
是详细模式。该包将字符串操作的结果存储在扩展结果中\thestring
,将字符串“查询”的结果存储在中 \theresult
。因此,在宏中\test
,您可以对扩展结果执行任何操作\thestring
(在本例中,我只是将其打印出来)。
\documentclass{book}
\usepackage{stringstrings}
\newcounter{tempdot}
\newcommand{\foo}[2][v]{%
\whereischar[q]{#2}{.}%
\setcounter{tempdot}{\theresult}%
\addtocounter{tempdot}{-1}%
\substring[#1]{#2}{1}{\thetempdot}%
}
\newcommand\test[1]{%
\foo[q]{#1}%
\thestring%
}
\begin{document}
\noindent
Result of foo\{3.2\}: \foo{3.2}\\
Result of test\{3.2\}: \test{3.2}
\end{document}