平均能量损失

平均能量损失

当尝试回答此网站上的另一个问题时,我正在试验\peek_after:Nw\l_peek_token

我可以设置\l_peek_tokenOK,但我想测试这个标记是否是几个字符之一,而不仅仅是一个字符。(只有一个字符很容易,我可以使用\peek_meaning:NTF。)

我以为我可以轻松将其转换l_peek_token为字符串,然后用于\str_if_in:nnTF测试。但是,我不知道该怎么做。

我知道我可以使用一堆嵌套的\token_if_eq_meaning:NNTF,但是我发现这种语法很笨拙。

我怎样才能做到这一点?

平均能量损失

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new:Nn \__dcp_test_punct:
  {
    % What goes here to convert \l_peek_token to the right format?
    \str_if_in:nnTF {.,} { \l_peek_token }
      { ~Punctuation~found:~ }
      { ~Punctuation~not~found~ }
    ---
    % This works, but I find the syntax clumsy.
    \token_if_eq_meaning:NNTF \l_peek_token .
      { ~Punctuation~found:~ }
      {
        \token_if_eq_meaning:NNTF \l_peek_token ,
          { ~Punctuation~found:~ }
          { ~Punctuation~not~found~ }
      }
  }
\cs_new:Nn \__dcp_test_punct:n
  {
    \peek_after:Nw \__dcp_test_punct:
  }
\DeclareDocumentCommand {\testpunct} { m }
  {
    \__dcp_test_punct:n {#1}
  }
\ExplSyntaxOff
\begin{document}
\testpunct{A}.

\testpunct{A},

\testpunct{A}
\end{document}

答案1

经过进一步思考以及@egreg的评论,我决定采用略有不同的方法,并使用内联映射。它并不像我希望的那样紧凑\str_if_in:nnTF,但至少它不涉及嵌套布尔检查。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\bool_new:N \l__dcp_punct_found_bool
\cs_new_protected:Nn \__dcp_test_punct:
  {
    \bool_set_false:N \l__dcp_punct_found_bool
    \str_map_inline:nn { .,:;!? }
      {
        \token_if_eq_meaning:NNT \l_peek_token ##1
          {
            ~Punctuation~found:~
            \bool_set_true:N \l__dcp_punct_found_bool
            \str_map_break:
          }
      }
    \bool_if:NF \l__dcp_punct_found_bool
      { ~Punctuation~not~found~ }
  }
\cs_new_protected:Nn \__dcp_test_punct:n
  {
    \peek_after:Nw \__dcp_test_punct:
  }
\DeclareDocumentCommand {\testpunct} { +m }
  {
    \__dcp_test_punct:n {#1}
  }
\ExplSyntaxOff
\begin{document}
\testpunct{A}.

\testpunct{A},

\testpunct{A}:

\testpunct{A};

\testpunct{A}!

\testpunct{A}?

\testpunct{A}
\end{document}

输出

答案2

抱歉,我只是在玩弄\futurelet。将生成的隐式字符标记 (相关:关于 \futurelet 的一个问题) 的使用变得明确起来,\meaning这是 Christian Tellechea 建议我做的。

Christian 实际上提供了一个宏(在单独的封面下)\implicittomacro,它将 catcode 11/12 隐式字符标记转换为宏。你可以去我的回答关于 \futurelet 的一个问题,看看他的宏。

我的目标是能够使用listofitems包的功能来一次性搜索隐式标记的值以获取多个标点符号值,如规范中所述\setsepchar{.||,||:||;||!||?}。成功!

\documentclass{article}
\usepackage{listofitems,xcolor}
\newcommand\testpunct[1]{#1\futurelet\xfl\pdecide}
\def\pdecide{\bgroup\tiny\color{cyan}%
  \edef\ximp{\meaning\xfl}%
  \edef\tmp{\detokenize{the character }}%
  \expandafter\setsepchar\expandafter{\tmp}%
  \readlist\mylist{\ximp}%
  \ifnum\listlen\mylist[]<2\relax (Non catcode=12 follows)\else%
    \setsepchar{.||,||:||;||!||?}%
    \itemtomacro\mylist[2]\thecharacter%
    \readlist*\mychar{\thecharacter}%
    \ifnum\listlen\mychar[]=1\relax (Non-punctuation character follows \mychar[1])\else%
      (This Punctuation found: \mycharsep[1])%
    \fi%
  \fi%
\egroup}
\begin{document}
\testpunct{A}\relax

\testpunct{A}B

\testpunct{A}@

\testpunct{A}.

\testpunct{A},

\testpunct{A}:

\testpunct{A};

\testpunct{A}!

\testpunct{A}?

\testpunct{A}

\end{document}

在此处输入图片描述

相关内容