如何在语法环境中设置缩进?

如何在语法环境中设置缩进?

我正在使用mdwtoolssyntax包来编写 BNF 语法,我想知道是否有办法设置parindent以便每条生产线都默认居中而不是左对齐?

最小示例

\documentclass[10pt,letterpaper]{article}  
\usepackage{mdwtab}
\usepackage{syntax} 

\setlength{\grammarparsep}{0.25cm}   % vertical distance between production rules
\setlength{\grammarindent}{1cm}      % horizontal indent distance


\renewcommand{\syntleft}{}          % do not display '<' associated with variable, for example <A>
\renewcommand{\syntright}{}         % do not display '>' associated with variable, for example <A>

% Note: the empty line between production rules is not optional!

\begin{document}
    \begin{grammar}
        <A> $\rightarrow$ B | c | d

        <B> $\rightarrow$ B

        <C> $\rightarrow$ D 
    \end{grammar}
\end{document}

更新\phantom解决方案)

\begin{grammar}\centering
        <S> $\ra$ abB 

        <A> $\ra$ aaBb

        <B> $\ra$ bbAa

        <A> $\ra$ $\lambda$
\end{grammar}

答案1

您可以使用\centeringright after\begin{grammar}将每个产品置于其自己的行的中心:

\begin{grammar}\centering
    <A> $\rightarrow$ B | c | d

    <B> $\rightarrow$ B \phantom{| c | d}

    <C> $\rightarrow$ D \phantom{| c | d}
\end{grammar}

另一种方法;grammar环境被定义为一个列表,因此您可以定义一个类似的环境,以手动指定长度\leftmargin。在下面的例子中,我定义了一个mygrammar带有可选参数的环境,允许您控制\leftmargin

\documentclass[10pt,letterpaper]{article}  
\usepackage{mdwtab}
\usepackage{syntax} 
\usepackage{lipsum} % to geberate text for the example 

\setlength{\grammarparsep}{0.25cm}   % vertical distance between production rules
\setlength{\grammarindent}{1cm}      % horizontal indent distance


\renewcommand{\syntleft}{}          % do not display '<' associated with variable, for example <A>
\renewcommand{\syntright}{}         % do not display '>' associated with variable, for example <A>

% Note: the empty line between production rules is not optional!

\makeatletter
\newenvironment{mygrammar}[1][0pt]{%
\list{}{%
\labelwidth\grammarindent%
\leftmargin\dimexpr\grammarindent+#1\relax%
\advance\grammarindent\labelsep
\itemindent\z@%
\listparindent\z@%
\parsep\grammarparsep%
}%
\let\\\@normalcr
\syntaxShortcuts\relax\relax%
\def\alt{\\\llap{\textbar\quad}}%
\def\gr@setpar{%
\def\par{%
\parshape\@ne\@totalleftmargin\linewidth%
\@@par%
\catcode`\<12%
\everypar{%
\everypar{}%
\catcode`\<\active%
\gr@implitem%
}%
}%
}%
\gr@setpar%
\par%
\let\gr@leftsq\[%
\let\gr@rightsq\]%
\def\gr@endsyntdiag]{\end{syntdiag}\gr@setpar\par}%
\def\[{\@ifnextchar[{\begin{syntdiag}\@gobble}\gr@leftsq}%
\def\]{\@ifnextchar]\gr@endsyntdiag\gr@rightsq}%
}{%
\@newlistfalse%
\everypar{}%
\endlist%
}
\makeatother

\begin{document}

\begin{grammar}    

  <A> $\rightarrow$ B | c | d

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{grammar}

\begin{mygrammar}    

  <A> $\rightarrow$ B | c | d

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{mygrammar}

\begin{mygrammar}[3cm]    

  <A> $\rightarrow$ B | c | d

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{mygrammar}

\begin{mygrammar}[6cm]    

  <A> $\rightarrow$ B | c | d

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{mygrammar}

\end{document}

在此处输入图片描述

这是另一种更自动化的方法:您只需提供最长的行作为新定义环境的强制参数Cgrammar,即可获得居中和左对齐的内容:

\documentclass[10pt,letterpaper]{article}  
\usepackage{mdwtab}
\usepackage{syntax} 
\usepackage{lipsum} % to geberate text for the example 

\setlength{\grammarparsep}{0.25cm}   % vertical distance between production rules
\setlength{\grammarindent}{1cm}      % horizontal indent distance


\renewcommand{\syntleft}{}          % do not display '<' associated with variable, for example <A>
\renewcommand{\syntright}{}         % do not display '>' associated with variable, for example <A>

% Note: the empty line between production rules is not optional!

\newlength\longest
\newlength\LeftMargin
\makeatletter
\newenvironment{Cgrammar}[1]{%
\list{}{%
\settowidth\longest{#1}
\setlength\LeftMargin{\dimexpr0.5\linewidth-0.5\longest}
\labelwidth\grammarindent%
\leftmargin\dimexpr\grammarindent+\LeftMargin\relax%
\advance\grammarindent\labelsep
\itemindent\z@%
\listparindent\z@%
\parsep\grammarparsep%
}%
\let\\\@normalcr
\syntaxShortcuts\relax\relax%
\def\alt{\\\llap{\textbar\quad}}%
\def\gr@setpar{%
\def\par{%
\parshape\@ne\@totalleftmargin\linewidth%
\@@par%
\catcode`\<12%
\everypar{%
\everypar{}%
\catcode`\<\active%
\gr@implitem%
}%
}%
}%
\gr@setpar%
\par%
\let\gr@leftsq\[%
\let\gr@rightsq\]%
\def\gr@endsyntdiag]{\end{syntdiag}\gr@setpar\par}%
\def\[{\@ifnextchar[{\begin{syntdiag}\@gobble}\gr@leftsq}%
\def\]{\@ifnextchar]\gr@endsyntdiag\gr@rightsq}%
}{%
\@newlistfalse%
\everypar{}%
\endlist%
}
\makeatother

\begin{document}

\begin{grammar}    

  <A> $\rightarrow$ B | c | d

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{grammar}

\lipsum[1]
\begin{Cgrammar}{A> $\rightarrow$ B | c | d}

  <A> $\rightarrow$ B | c | d

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{Cgrammar}

\lipsum[1]
\begin{Cgrammar}{<A> $\rightarrow$ B | c | d | e}

  <A> $\rightarrow$ B | c | d | e

   <B> $\rightarrow$ B

   <C> $\rightarrow$ D 
\end{Cgrammar}

\lipsum[1]
\begin{Cgrammar}{<A> $\ra$ aaBb}
        <S> $\ra$ abB 

        <A> $\ra$ aaBb

        <B> $\ra$ bbAa

        <A> $\ra$ $\lambda$
\end{Cgrammar}


\end{document}

答案2

您可以\centering按照@Gonzalo 的建议使用,并充分使用\phantom{...}以获得所需的对齐:

\begin{grammar}\centering
    <A> $\rightarrow$ B | c | d

    <B> $\rightarrow$ B \phantom{| c | d}

    <C> $\rightarrow$ D \phantom{| c | d}
\end{grammar}

在此处输入图片描述

\phantom{<stuff>}制作一个宽度为 的框<stuff>,但不排版任何内容。

对于您的另一个示例,可以使用产品右侧 (RHS) 上最大项目的预定义长度。然后,使用此长度,将每个 RHS 放入一个盒子中:

\newlength{\widest}% Length of widest element
\settowidth{\widest}{aaBb}% Widest element is "aaBb"
\newcommand{\rhs}[1]{\makebox[\widest][l]{#1}}
...
\begin{grammar}\centering
  <S> $\rightarrow$ \rhs{abB}

  <A> $\rightarrow$ \rhs{aaBb}

  <B> $\rightarrow$ \rhs{bbAa}

  <A> $\rightarrow$ \rhs{$\lambda$}
\end{grammar}

另一种居中方法,这次使用 boxed 来对齐 BNF 产生式

calc包裹还提供了一个\widthof{<stuff>}命令,您可以使用它并删除新长度的声明,就像我做的那样。但是,上面说明了这个概念。

相关内容