如何在自定义环境中检测和令牌?

如何在自定义环境中检测和令牌?

我想创建一个显示上下文无关语法的环境。具体来说,我希望能够编写

\begin{syntax*}
  Propositions & A,B & p \mid \lnot A \mid A \land B \mid A \lor B \\
   Contexts & \Gamma & \cdot \mid \Gamma, A
\end{syntax*}

产生以下输出。

在此处输入图片描述

align*通过与的和aligned环境类比amsmath,我也希望有一个syntaxed环境,以便在需要时可以将构造放置在其他数学环境内。

为了与环境保持一致amsmath,我考虑将上述代码处理成:

\begin{alignat*}{2}
  \text{\scshape propositions} &\quad& A,B &\Coloneqq p \mid \lnot A \mid A \land B \mid A \lor B \\
  \text{\scshape contexts} && \Gamma &\Coloneqq \cdot \mid \Gamma, A
\end{alignat*}

我如何检测&标记并分别抓取环境的每个单元?

这是一个示例文档。

\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}

\begin{document}

\begin{alignat*}{2}
  \text{\scshape propositions} &\quad& A,B &\Coloneqq p \mid \lnot A \mid A \land B \mid A \lor B \\
  \text{\scshape contexts} && \Gamma &\Coloneqq \cdot \mid \Gamma, A
\end{alignat*}

\begin{syntax*}
  Propositions & A,B & p \mid \lnot A \mid A \land B \mid A \lor B \\
   Contexts & \Gamma & \cdot \mid \Gamma, A
\end{syntax*}

\end{document}

答案1

使用array

\documentclass{article}
\usepackage{amsmath,mathtools,array}

\newenvironment{syntax}
 {%
  \renewcommand{\arraystretch}{1.5}%
  \begin{array}{ @{} >{$\scshape}r<{$} @{\quad} r @{{}\Coloneqq{}} l @{} }
 }
 {\end{array}}

\begin{document}

\begin{equation*}
\begin{syntax}
Propositions & A,B    & p \mid \lnot A \mid A \land B \mid A \lor B \\
    Contexts & \Gamma & \cdot \mid \Gamma, A
\end{syntax}
\end{equation*}

\end{document}

在此处输入图片描述

答案2

在此处输入图片描述

\documentclass{article}

\usepackage{array}

\newenvironment{syntax*}
{\center
\begin{tabular}{@{}>\scshape r@{\quad}>$r<$@{}>{${}\mathrel{::=}}l<$@{}}}
{\end{tabular}\endcenter}

\begin{document}


\begin{syntax*}
  Propositions & A,B & p \mid \lnot A \mid A \land B \mid A \lor B \\
   Contexts & \Gamma & \cdot \mid \Gamma, A
\end{syntax*}

\end{document}

答案3

这是您的语法环境的一个版本(为了简单起见,我省略了星号):

句法

这用于environ收集环境的主体,然后将其拆分多次。通过滥用全局集合操作,代码归结为:

\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}

\usepackage{environ}
\usepackage{expl3}

\ExplSyntaxOn
\cs_new:Npn \syntax_format:n #1 { \text{\scshape \tl_lower_case:n { #1 } } }
\cs_new:Npn \syntax_process:n #1
    {
        \begin{alignat*}{2}
        \seq_set_split:Nnn \l_tmpa_seq { \\ } { #1 }
        \seq_map_inline:Nn \l_tmpa_seq
            {
                \seq_gset_split:Nnn \l_tmpb_seq { & } { ##1 }
                \syntax_format:n { \seq_item:Nn \l_tmpb_seq { 1 } }
                &\quad&
                \seq_item:Nn \l_tmpb_seq { 2 } &\Coloneqq
                \seq_item:Nn \l_tmpb_seq { 3 }\\
            }
        \end{alignat*}
    }
\cs_generate_variant:Nn \syntax_process:n { V }
\NewEnviron{syntax}{
    \syntax_process:V \BODY
}
\ExplSyntaxOff

\begin{document}

\begin{alignat*}{2}
  \text{\scshape propositions} &\quad& A,B &\Coloneqq p \mid \lnot A \mid A \land B \mid A \lor B \\
  \text{\scshape contexts} && \Gamma &\Coloneqq \cdot \mid \Gamma, A
\end{alignat*}

\begin{syntax}
  Propositions & A,B & p \mid \lnot A \mid A \land B \mid A \lor B \\
   Contexts & \Gamma & \cdot \mid \Gamma, A
\end{syntax}

\end{document}

答案4

我稍微修改了 egreg 的解决方案。最重要的是,我在最后一列恢复到\arraystretch1这样array出现在那里的 s 就不会受到影响。

\RequirePackage { array }
\RequirePackage { collcell }
\RequirePackage { textcase }

\cs_new_protected:Npn \__syntax_text:n #1
  { \text { \scshape \MakeTextLowercase {#1} } }

\NewDocumentEnvironment { syntax* } { }
  { \__syntax_star_begin: }
  { \__syntax_star_end: }

\cs_new_protected:Npn \__syntax_star_begin:
  {
    \group_begin:
      \use:c { equation* }
        \cs_set:Npn \arraystretch { 1.5 }
        \use:c { array }
          {
            @{}
            >{ \collectcell \__syntax_text:n }
            r
            <{ \endcollectcell }
            @{ \quad }
            r
            @{ {} \Coloneqq {} }
            >{ \renewcommand\arraystretch{1} }
            l
            @{} 
          }
  }

\cs_new_protected:Npn \__syntax_star_end:
  {
        \use:c { endarray }
      \use:c { endequation* }
    \group_end:
  }

再次感谢 egreg 的帮助!

相关内容