使用 expl3 对序列进行嵌套拆分

使用 expl3 对序列进行嵌套拆分

在 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} 

相关内容