我正在替换一个字符。如果我直接将该字符作为输入,它就可以正常工作。但是当从字符串中提取该字符,然后将其输入到命令中进行重新分配时,它不起作用。这是有问题的 MWC。请运行 XeTeX。
\documentclass{article}
\usepackage{fontspec}
\usepackage{xstring}
\usepackage{xparse}
\RequirePackage{stackengine}
\setmainfont[Script=Devanagari,Mapping=devanagarinumerals]{Shobhika}
\def\kdh#1{\topinset{\rule{4pt}{0.7pt}}{#1}{8pt}{1pt}} %dh
\ExplSyntaxOn
\tl_new:N \l_swar_string_tl
\cs_new_protected:Npn \swar_replace_with:f #1
{
\tl_set:Nn \l_swar_string_tl {#1}
\tl_replace_all:Nnn \l_swar_string_tl {धं} {\kdh{ध}}
\tl_use:N \l_swar_string_tl
}
\NewDocumentCommand \swar { m }
{
\swar_replace_with:f { #1 }
}
\ExplSyntaxOff
\begin{document}
Correct output is \swar{धं}\\
Incorrect output is \StrBehind{प धं}{ }[\this] \swar{\this}, it should be \swar{धं}
\end{document}
答案1
有2个1命令的基本签名n
和N
,两者都不以任何方式处理参数。您应该只定义签名包含n
或的函数N
,它们是“基本”函数并按应有的方式接受参数。
在您的情况下,参数似乎是一些文本,因此n
类型(一组带括号的标记)是正确的选择,因此您应该执行以下操作:
\cs_new_protected:Npn \swar_replace_with:n #1
{ ... }
然后,如果您想要一个扩展参数的版本\swar_replace_with:n
,f
您应该使用:
\cs_generate_variant:Nn \swar_replace_with:n { f }
然后您可以使用\swar_replace_with:f
,它将正确处理该参数。
虽然在我看来,o
(扩展参数一次)或x
(详尽扩展)变体可能比更好f
。
代码如下:
\documentclass{article}
\usepackage{fontspec}
\usepackage{xstring}
\usepackage{xparse}
\RequirePackage{stackengine}
% \setmainfont[Script=Devanagari,Mapping=devanagarinumerals]{Shobhika}
\def\kdh#1{\topinset{\rule{4pt}{0.7pt}}{#1}{8pt}{1pt}} %dh
\ExplSyntaxOn
\tl_new:N \l_swar_string_tl
\cs_new_protected:Npn \swar_replace_with:n #1
{
\tl_set:Nn \l_swar_string_tl {#1}
\tl_replace_all:Nnn \l_swar_string_tl {धं} {\kdh{X}} % ध
\tl_use:N \l_swar_string_tl
}
\cs_generate_variant:Nn \swar_replace_with:n { f }
\NewDocumentCommand \swar { m }
{ \swar_replace_with:f {#1} }
\ExplSyntaxOff
\begin{document}
Correct output is \swar{धं}\\
Incorrect output is \StrBehind{प धं}{ }[\this]\swar{\this}, it should be \swar{धं}
\end{document}
和输出(用X
而不是ध
因为我没有合适的字体):
1 6,实际上:n
和N
,是“正常”的;p
代表“参数指定”,就像你在 中看到的那样\cs_new:Npn
;T
和F
,与 相同n
,但它们表示条件的真假分支;D
,代表“不使用”,用于命名 TeX 基元; 和w
,当命令不遵循上述之一时应使用它。对于初学者,我建议阅读软件包expl3
和 LaTeX3 编程。