A评论下面已经澄清了我的问题,它与lua无关。在下面的代码片段中:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_protected:Npn \sops_format_set_expr:n #1 {
\tl_set:Nn \l_tmpa_tl {A+\overline{(B+A)}}
\tl_replace_all:Nnn \l_tmpa_tl {+}{\cup}
\tl_use:N \l_tmpa_tl
}
\NewDocumentCommand{\seval}{ m }{
$\sops_format_set_expr:n {#1}$
}
\ExplSyntaxOff
\begin{document}
\seval{A+-(B+A)}
\end{document}
有没有比(例如)用遍历字符串、沿途检查,然后将其拼凑在一起更好的方法来执行+
对 的替换?\cup
A+\overline{(B+A)}
\tl_head
head=group
背景:我正在制作一个小程序包来评估和格式化一些集合表达式。我有代码来执行评估,但是打印是一个问题。我在 lua 中编写了代码,它将评估形式为A+(B*C)
(+
解释为集合并集,并*
解释为交集)的表达式并打印结果集。找到一种合适的方法来处理补集,导致(我的感觉是)需要在 lua 中使用模式匹配来正确处理平衡分隔符。因此,部分代码在 lua 中执行一些字符串操作,并将其吐回 tex 进行格式化。
问题: 下面的代码尝试获取形式为的字符串-(<stuff>)
,并在 tex 中用 替换它\overline{(<stuff>)}
。请参阅我之前的一个问题以供参考。
\begingroup
\catcode`\%=12\relax
\gdef\patmatch{"%-(%b())","\noexpand\\overline{%1}"}
\endgroup
\def\setcomp#1{%
\directlua{
local s, _ = string.gsub("\luatexluaescapestring{#1}",\patmatch)
tex.sprint(s)
%tex.sprint(-2,s)
}
}
我想让 tex 解析结果字符串 (?) 以替换为 和*
。\cap
问题是,在替换中,tex 无法识别上述字符串替换中由 lua 处理的任何内容。以下代码“完成”了替换:+
\cup
+
\cs_new_protected:Npn \sops_format_set_expr:n #1 {
\tl_set:Nx \l_tmpa_tl {\setcomp{#1}}
\tl_replace_all:Nnn \l_tmpa_tl {+}{\cup}
\tl_use:N \l_tmpa_tl
}
\NewDocumentCommand{\seval}{ m }{
$\sops_format_set_expr:n {#1}$
}
当\seval
在类似 的程序上调用时\seval{A+-(B+A)}
,-(B+A)
首先由字符串替换处理并替换为\overline{(B+A)}
,而我们必须A+\overline{(B+A)}
扫描 以将 替换为+
。\cup
问题是第一次出现的+
(不涉及字符串替换的那个)被识别,而第二次则没有。我盲目地尝试使用string.sprint(-2,s)
上面第一个代码块中注释的 ,在这种情况下,第二个+
被识别,但宏没有被识别。
和往常一样,我的大脑太弱了,无法处理 tex/lua catcode 交互的复杂性。有人能解释一下问题是什么,以及如何修复它吗?MWE 如下。
\documentclass{article}
\usepackage{xparse}
\begingroup
\catcode`\%=12\relax
\gdef\patmatch{"%-(%b())","\noexpand\\overline{%1}"}
\endgroup
\def\setcomp#1{%
\directlua{
local s, _ = string.gsub("\luatexluaescapestring{#1}",\patmatch)
tex.sprint(s)
}
}
\ExplSyntaxOn
\cs_new_protected:Npn \sops_format_set_expr:n #1 {
\tl_set:Nx \l_tmpa_tl {\setcomp{#1}}
\tl_replace_all:Nnn \l_tmpa_tl {+}{\cup}
\tl_use:N \l_tmpa_tl
}
\NewDocumentCommand{\seval}{ m }{
$\sops_format_set_expr:n {#1}$
}
\ExplSyntaxOff
\begin{document}
\seval{A+-(B+A)}
\end{document}
答案1
唯一的问题是替换,它\tl_replace_…
不能像你预期的那样工作(里面的所有内容{}
都被隐藏了,无法找到)。所以有问题的行只是
\tl_replace_all:Nnn \l_tmpa_tl { + } { \cup }
选项1
加载etoolbox
并使用
\patchcmd \l_tmpa_tl { + } { \cup } { } { }
相反。问题是,这不像\tl_replace_all
但是那样工作\tl_replace_once
。
选项 2
加载l3regex
并替换该行
\regex_replace_all:nnN { \+ } { \c{cup} } \l_tmpa_tl