使用标记列表中的字距调整命令

使用标记列表中的字距调整命令

我编写了一些命令,旨在简化从形式语法推导的排版。

\documentclass{article}

\usepackage{lmodern}
\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn

\seq_new:N \l__inft_gr_vars_seq
\seq_new:N \l__inft_gr_alph_seq

\keys_define:nn { inft / gr }
{   
  variables .code:n = { \seq_set_from_clist:Nn \l__inft_gr_vars_seq { #1 } },
  alphabet  .code:n = { \seq_set_from_clist:Nn \l__inft_gr_alph_seq { #1 } }
}

\NewDocumentCommand \DefineGrammar { m }
{
  \keys_set:nn { inft / gr } { #1 }
}

\NewDocumentCommand \GrammarDrv { m }
{
  \inft_grammar_drv:n { #1 }
}

\cs_new:Nn \inft_grammar_drv:n
{
  \seq_set_split:Nnn \l_tmpa_seq { => } { #1 }
  \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq
    { \exp_not:n { \inft_word:nn { \width} { ##1 } } }
  \seq_use:Nn \l_tmpb_seq { \Rightarrow }
}

\cs_new:Nn \inft_char:nn
{
  \makebox[#1]
  { 
    \str_case_x:nnF { \tl_to_str:n {#2} }
    {
      { ##                } { \texttt{\#}            }
      { \c_underscore_str } { \scalebox{.87}{$\Box$} }
      { \c_tilde_str      } { $\varepsilon$          }
      {                   } { $\varepsilon$          }
    }
    { \texttt{#2} }
  }
}

\cs_new:Nn \inft_word:nn
{
  \tl_if_blank:nTF {#2}
  {
    \inft_char:nn { #1 } { }
  }
  {
    \tl_set:Nn \l_tempa {#2}
    \tl_map_inline:Nn \l_tempa 
    {   
      \seq_if_in:NnTF \l__inft_gr_vars_seq ##1
      { 
        \inft_gr_var:n { ##1 } 
      }
      {
        \seq_if_in:NnTF \l__inft_gr_alph_seq ##1
        {  
          \inft_char:nn { #1 } { ##1 } 
        }
        {
          { ##1 }
        }
      }
    }
  }
}

\cs_new:Nn \inft_gr_var:n
{
  \tl_if_single:nTF { #1 }
    { #1          }
    { \mathit{#1} }
}

\ExplSyntaxOff

\begin{document}

\DefineGrammar{variables = {S, X, Y, Z}, alphabet = {a, b, c}}

\par (1) $\GrammarDrv{S => aXYZ}$ 
\par (2) $\GrammarDrv{S => aXY{{\kern-1.7pt}}Z}$ 
\par (3) $\GrammarDrv{S => aXY{\kern-1.7pt}Z}$ 

\end{document}  

输出

MWE 的输出

表明:(1) 只要不实施特定规则,就需要手动调整字距;(2) 如果字距调整命令受到两对括号的“保护”,则该命令可以正常工作;(3) 如果字距调整命令仅被一对括号包围,则该命令会中断。

我该如何修改我的命令使得(3)能够按预期工作?

答案1

这个问题已由曼努埃尔在他上面的评论中。

在第 61 行和第 66 行中,第二个参数##1必须\seq_if_in:NnTF用括号括起来,因为它是 类型n。更正后的版本是

\seq_if_in:NnTF \l__inft_gr_vars_seq { ##1 }

\seq_if_in:NnTF \l__inft_gr_alph_seq { ##1 }

分别。

校正后的 MWE 输出

相关内容