在 MWE 中
\documentclass{article}
\usepackage{lmodern}
\usepackage{xparse}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand \DefGrRules { m } { \inft_def_gr_rules:n { #1 } }
\NewDocumentCommand \GrammarShowRules { } { \inft_grammar_show_rules: }
\seq_new:N \l__inft_gr_rules_seq
\cs_new:Nn \inft_def_gr_rules:n
{
\seq_set_from_clist:Nn \l__inft_gr_rules_seq { #1 }
}
\cs_new:Nn \inft_grammar_show_rules:
{
\seq_set_map:NNn \l_tmpa_seq \l__inft_gr_rules_seq
{
\seq_set_split:Nnn \l_tmpb_seq {->} { ##1 }
\seq_show:N \l_tmpb_seq
\seq_count:N \l_tmpb_seq
{ \seq_item:Nn \l_tmpb_seq { 1 } }
& \to
{ \seq_item:Nn \l_tmpb_seq { 2 } }
}
\seq_use:Nn \l_tmpa_seq { \\ }
}
\ExplSyntaxOff
\begin{document}
\DefGrRules{S -> X | , X -> aXYZ | aYZ, ZY -> YZ, aY -> ab, bY -> bb, bZ -> bc, cZ -> cc}
\begin{align*}
\GrammarShowRules
\end{align*}
\end{document}
\l_tmpb_seq
似乎有两个项目,正如 所确认的\seq_show:N \l_tmpb_seq
。但是,\seq_count:N \l_tmpb_seq
返回 0,并且用于访问项目的命令扩展为零。这是什么原因造成的?
我的目的是用 替换->
,\to
此外|
用\mathrel{} \middle| \mathrel{}
和 用 MWE 中省略的另一个命令来处理所有其他部分,因为甚至拆分都无法按预期进行。
答案1
的第三个参数\seq_set_map:NNn
需要完全展开。您可以使用可扩展的方法在 处拆分参数->
:
\documentclass{article}
\usepackage{lmodern}
\usepackage{xparse}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand \DefGrRules { m } { \inft_def_gr_rules:n { #1 } }
\NewDocumentCommand \GrammarShowRules { } { \inft_grammar_show_rules: }
\seq_new:N \l__inft_gr_rules_seq
\cs_new_protected:Nn \inft_def_gr_rules:n
{
\seq_set_from_clist:Nn \l__inft_gr_rules_seq { #1 }
}
\cs_new:Nn \inft_grammar_show_rules:
{
\seq_set_map:NNn \l_tmpa_seq \l__inft_gr_rules_seq
{
\__inft_gr_split:w ##1 \q_stop
}
\seq_use:Nn \l_tmpa_seq { \\ }
}
\cs_new:Npn \__inft_gr_split:w #1 -> #2 \q_stop
{
\exp_not:n { #1 & \to #2 }
}
\ExplSyntaxOff
\begin{document}
\DefGrRules{
S -> X |,
X -> aXYZ | aYZ,
ZY -> YZ,
aY -> ab,
bY -> bb,
bZ -> bc,
cZ -> cc
}
\begin{align*}
\GrammarShowRules
\end{align*}
\end{document}
答案2
为了多样化,这里有一种通过基于 LuaLaTeX 的方法实现排版目标的方法。下面的序言设置了两个 LaTeX 宏,\DefGrRules
和\GrammarShowRules
,它们充当两个相应的 Lua 函数(称为DefGrRules
和)的包装器GrammarShowRules
。前一个函数使用 Lua 的强大string.gsub
功能来完成大部分工作。
\documentclass{article}
\usepackage{amsmath} % for 'align*' env.
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
Rule = "" -- initialize string variable
function DefGrRules ( s )
s = s:gsub ( "->" , "&\\to" )
s = s:gsub ( "|" , "\\mathrel{}\\vert\\mathrel{}" )
s = s:gsub ( "," , "\\\\" )
Rule = s -- store result in string variable "Rule"
end
function GrammarShowRules ()
tex.sprint ( "\\begin{align*}" .. Rule .. "\\end{align*}" )
end
\end{luacode}
%% TeX-side code
\newcommand\DefGrRules[1]{\directlua{DefGrRules(\luastringN{#1})}}
\newcommand\GrammarShowRules{\directlua{GrammarShowRules()}}
\begin{document}
\DefGrRules{S -> X | , X -> aXYZ | aYZ, ZY -> YZ, aY -> ab, bY -> bb, bZ -> bc, cZ -> cc}
\GrammarShowRules
\end{document}