考虑到答复,问题已得到改进……
在宏中\StrCut
,如果第一个参数包含“ç”,我们会收到错误消息。对于 ”\c{c}” 或大写“Ç”,也会发生同样的情况。当用普通的“c”替换时,不会出现错误。XeLaTeX 和 LuaLaTeX 都不会出现错误。
我认为\noexpandarg
不允许源字符串作为宏名。
它对其他重音字符(如“ã”、“á”等)有效(没有错误)……它对德语“ß”有效。它对“ç”无效。我承认这不是错误,但“ç”的这种特殊行为对我来说似乎很奇怪!
触发错误的示例:
\documentclass{article}
\usepackage{xstring}
\begin{document}
\newcommand{\myname}{João,is,good}
\StrCut{\myname}{,}\partone\parttwo
[\partone][\parttwo]
\renewcommand{\myname}{Straße,is,good}
\StrCut{\myname}{,}\partone\parttwo
[\partone][\parttwo]
\renewcommand{\myname}{Açai,is,not,good}
\StrCut{\myname}{,}\partone\parttwo
[\partone][\parttwo]
\renewcommand{\myname}{Açai,is,good,but,not,good}
\noexpandarg\StrCut{\myname}{,}\partone\parttwo
[\partone][\parttwo]
\end{document}
答案1
不是错误。您可以使用\noexpandarg
,但还有其他方法。
xstring
您可以在 中重新实现大部分(全部)内容expl3
。以下是\StrCut
:
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\xStrCut}{mmmm}
{
% #1 = tokens
% #2 = separator where to split at
% #3 = macro where to store the first part
% #4 = macro where to store the second part
\joao_xstrcut:nnNN { #1 } { #2 } #3 #4
}
\seq_new:N \l_joao_strcut_parts_seq
\cs_new_protected:Nn \joao_xstrcut:nnNN
{
\seq_set_split:Nnn \l_joao_strcut_parts_seq { #2 } { #1 }
\tl_clear_new:N #3
\tl_clear_new:N #4
\seq_pop_left:NN \l_joao_strcut_parts_seq #3
\tl_set:Nx #4 { \seq_use:Nn \l_joao_strcut_parts_seq { #2 } }
}
\ExplSyntaxOff
\begin{document}
\xStrCut{Açai,is,good}{,}\partone\parttwo
[\partone][\parttwo]
\end{document}
可以使用宏作为第一个参数的版本。\xStrCut*
在这种情况下,您需要使用。我认为重载很糟糕。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\xStrCut}{smmmm}
{
% #1 = optional *
% #2 = tokens
% #3 = separator where to split at
% #4 = macro where to store the first part
% #5 = macro where to store the second part
\IfBooleanTF{#1}
{
\joao_xstrcut:VnNN #2 { #3 } #4 #5
}
{
\joao_xstrcut:nnNN { #2 } { #3 } #4 #5
}
}
\seq_new:N \l_joao_strcut_parts_seq
\tl_new:N \l_joao_strcut_head_tl
\tl_new:N \l_joao_strcut_tail_tl
\cs_new_protected:Nn \joao_xstrcut:nnNN
{
\tl_if_exist:NF #3 { \tl_new:N #3 }
\tl_if_exist:NF #4 { \tl_new:N #4 }
\seq_set_split:Nnn \l_joao_strcut_parts_seq { #2 } { #1 }
\seq_pop_left:NN \l_joao_strcut_parts_seq #3
\tl_set:Nx #4 { \seq_use:Nn \l_joao_strcut_parts_seq { #2 } }
}
\cs_generate_variant:Nn \joao_xstrcut:nnNN { V }
\ExplSyntaxOff
\begin{document}
\xStrCut{Açai,is,good}{,}\partone\parttwo
[\partone][\parttwo]
\newcommand{\mytext}{Açai,is,good}
\xStrCut*{\mytext}{,}\partone\parttwo
[\partone][\parttwo]
\xStrCut*{\parttwo}{,}\parttwo\partthree
[\parttwo][\partthree]
\end{document}
答案2
在 luatex 或 xelatex 中ç
是一个简单的字符标记,例如c
,但在 pdflatex 中它是一对扩展为的标记\c{c}
。xstring
默认情况下,它会传递其参数,\edef
这会破坏任何此类命令,但它有一个\noexpandarg
开关可以防止这种情况发生。
\documentclass{article}
\usepackage{xstring}
\begin{document}
\noexpandarg
\StrCut{Açai,is,good}{,}\partone\parttwo % #### No error when "Acai"
[\partone][\parttwo]
\end{document}