当尝试回答此网站上的另一个问题时,我正在试验\peek_after:Nw
和\l_peek_token
。
我可以设置\l_peek_token
OK,但我想测试这个标记是否是几个字符之一,而不仅仅是一个字符。(只有一个字符很容易,我可以使用\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}