命令与 StrBefore 功能相同,但可扩展

命令与 StrBefore 功能相同,但可扩展

我正在寻找一个命令,如果输入是 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}

相关内容