
是否可以檢查一個標記是否為分隔符,即(
, )
, |
, \vert
, \langle
,\rangle
等,而不直接檢查條件中的每個標記?
分隔符號的結構在這裡有很好的描述:https://tex.stackexchange.com/a/296650/213149。似乎使用\delimiter
命令
所以我的問題是如何使用純 TeX 或 LaTeX3 以某種通用的方式來偵測這樣的分隔符號。
例如,我想自訂巨集\isDelimiter{...}
來列印true
或false
在文件中,如果它的參數是分隔符號或不是分隔符號。
答案1
我不確定這對您的\veca
問題是否有用。反正…
\documentclass{article}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\isDelimiterTF}{mmm}
{
\antshar_isdel:Nnn #1 { #2 } { #3 }
}
% first check whether #1 is a control sequence
\cs_new:Nn \antshar_isdel:Nnn
{
\token_if_cs:NTF #1
{
\__antshar_isdel_cs:Nnn #1 { #2 } { #3 }
}
{
\__antshar_isdel_char:Nnn #1 { #2 } { #3 }
}
}
% it is a control sequence; first check the two exceptional cases \{ and \}
% which return true; otherwise go on: if the token is not expandable return false
\cs_new:Nn \__antshar_isdel_cs:Nnn
{
\str_case:nnF { #1 }
{
{\{}{#2}
{\}}{#2}
}
{
\token_if_expandable:NTF #1
{
\__antshar_isdel_csexp:Nnn #1 { #2 } { #3 }
}
{
#3
}
}
}
% the token is expandable, access its expansion
\cs_new:Nn \__antshar_isdel_csexp:Nnn
{
\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
}
% if the expansion begins with \delimiter return true, otherwise false
\cs_new:Nn \__antshar_isdel_exp:nnn
{
\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
}
\cs_generate_variant:Nn \__antshar_isdel_exp:nnn { o }
\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
{
\token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
}
% when the token is a character, look at its \delcode;
% if positive return true, otherwise false
\cs_new:Nn \__antshar_isdel_char:Nnn
{
\int_compare:nTF { \delcode`#1 > 0 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
\verb|a|: \isDelimiterTF{a}{T}{F}
\verb|(|: \isDelimiterTF{(}{T}{F}
\verb|]|: \isDelimiterTF{]}{T}{F}
\verb|\langle|: \isDelimiterTF{\langle}{T}{F}
\verb-\|-: \isDelimiterTF{\|}{T}{F}
\verb|\{|: \isDelimiterTF{\{}{T}{F}
\verb|\lbrace|: \isDelimiterTF{\lbrace}{T}{F}
\verb|\mbox|: \isDelimiterTF{\mbox}{T}{F}
\end{document}
我們如何辨識控制序列何時是分隔符號?它的第一級擴展應該以 or 開頭\delimiter
,如果是一個字符,它\delcode
應該是正的。
因此,對字元的檢查是顯而易見的。對於一個控制序列,我們首先需要看看它是否可擴展。但也需要我們照顧\{
,而且\}
有些特殊,所以這些情況自己解決。
如果我們正在檢查的控制序列不可擴展,則它不是分隔符號(也許其他例外,例如\{
和\}
必須添加一些字體包)。如果它是可擴展的,我們透過呼叫來查看它的第一級擴展
\__antshar_isdel_exp:onn { #1 } { #2 } { #3 }
因此o
參數類型將執行所需的一級擴展。這將成為
\__antshar_isdel_exp_aux:w #1 \q_nil \q_stop { #2 } { #3 }
的定義\__antshar_isdel_exp_aux:w
是
\cs_new:Npn \__antshar_isdel_exp_aux:w #1 #2 \q_stop #3 #4
{
\token_if_eq_meaning:NNTF #1 \delimiter { #3 } { #4 }
}
因此,我們正在檢查的控制序列擴展中的第一個標記變為 ,#1
其餘標記\q_nil
變為#2
。其餘的,即 和#3
是#4
的真文本和假文本\isDelimiterTF
。第一個參數是無分隔符號的,因此它將採用輸入流中的第一個標記作為其參數;當 TeX 找到 時,第二個參數結束\q_stop
。
奇怪的\q_nil
是,如果你嘗試的話,\isDelimiter{\empty}{T}{F}
擴充功能中將沒有任何內容;在這種情況下\q_nil
被視為#1
且#2
為空。但是,既然\q_nil
不是\delimiter
,一切都會過去。