我如何确定参数的第一个字符是否是\?

我如何确定参数的第一个字符是否是\?

我定义了一个新命令,该命令在我想要的任何内容周围显示一个框,并希望它根据其参数是纯文本还是其他命令(例如\includegraphics)采取不同的行动。

为此,我认为检查参数的第一个字符是否为 会很简单\。我尝试过使用包\StrChar中的xstring,但它似乎对此不太满意。

\newcommand{\extractFirst}[1]{
   \StrChar{#1}{1}[\FirstChar]
   The first character is: '\FirstChar'\par
}

这能做到吗?

答案1

在这里,我利用了tokcycle包中的一个内部宏。

\count@stringtoks用于计算组成参数\string的标记。我们依赖这样一个事实:\string字符标记的 长度为一个字节,而\string任何宏标记的 长度至少为两个字节。使用此标准,我们可以区分宏和字符。

最重要的是,\count@stringtoks完全可扩展。

\documentclass{article}
\usepackage{tokcycle}
\makeatletter
\newcommand\extractFirst[1]{\testfirst#1\relax\relax}
\def\testfirst#1#2\relax{\tctestifnum{\count@stringtoks{#1}>1}{Macro}{Character}}
\makeatother
\begin{document}
\extractFirst{abc}

\extractFirst{a}

\extractFirst{\abc ab\c}

\extractFirst{\a ab\c}
\end{document}

在此处输入图片描述

如果您想避免加载包,重新创建\count@stringtoks宏所需的提取代码如下:

\documentclass{article}
\makeatletter
\newcommand\extractFirst[1]{\testfirst#1\relax\relax}
\def\testfirst#1#2\relax{\tctestifnum{\count@stringtoks{#1}>1}{Macro}{Character}}
% FROM TOKCYCLE:
\long\def\count@stringtoks#1{\tc@earg\count@toks{\string#1}}
\long\def\count@toks#1{\the\numexpr-1\count@@toks#1.\tc@endcnt}
\long\def\count@@toks#1#2\tc@endcnt{+1\tc@ifempty{#2}{\relax}{\count@@toks#2\tc@endcnt}}
\def\tc@ifempty#1{\tc@testxifx{\expandafter\relax\detokenize{#1}\relax}}
\long\def\tc@earg#1#2{\expandafter#1\expandafter{#2}}
\long\def\tctestifnum#1{\tctestifcon{\ifnum#1\relax}}
\long\def\tctestifcon#1{#1\expandafter\tc@exfirst\else\expandafter\tc@exsecond\fi}
\long\def\tc@testxifx{\tc@earg\tctestifx}
\long\def\tctestifx#1{\tctestifcon{\ifx#1}}
\long\def\tc@exfirst#1#2{#1}
\long\def\tc@exsecond#1#2{#2}
\makeatother
\begin{document}
\extractFirst{abc}

\extractFirst{a}

\extractFirst{\abc ab\c}

\extractFirst{\a ab\c}
\end{document}

答案2

您可以使用函数检查输入expl3

\documentclass{article}
\usepackage{xparse,xcolor}

\NewDocumentCommand{\mycommandmacro}{m}{%
  \fcolorbox{red}{white}{#1}%
}
\NewDocumentCommand{\mycommandnomacro}{m}{%
  \fcolorbox{blue}{black!10}{#1}%
}

\ExplSyntaxOn

\NewDocumentCommand{\mycommand}{m}
 {
  \tl_if_blank:nF { #1 }
   {
    \peek_catcode:NTF \c_group_begin_token
     {% argument starts with brace
      \ballu_mycommand_nomacro:w
     }
     {
      \ballu_mycommand_test:Nw
     }
    #1 \q_stop
   }
 }


\cs_new:Npn \ballu_mycommand_nomacro:w #1 \q_stop
 {
  \mycommandnomacro{#1}
 }

\cs_new:Npn \ballu_mycommand_test:Nw #1 #2 \q_stop
 {
  \token_if_cs:NTF #1
   {
    \mycommandmacro{#1#2}
   }
   {
    \mycommandnomacro{#1#2}
   }
 }

\ExplSyntaxOff

\begin{document}

\mycommand{abc}

\mycommand{{ab}c}

\mycommand{\mbox{abc}}

\mycommand{{\mbox{abc}}def}

X\mycommand{}X

X\mycommand{ }X

\end{document}

空白(空或仅有空格)参数什么也不做;这可能会被改变,这里它用于防御性编程。

初始支撑会触发“nomacro”变体。

在此处输入图片描述

相关内容