答案1
您有多种选择。我在此过程中使用了以下辅助宏:
\newcommand\meta[1]{$\langle$#1$\rangle$}
如果下一行以 开头,则我们必须\relax
在 后面放置,否则这将被解释为 的可选参数。\\
[
\\
tabular
也许是最简单的。
\begin{tabular}{ll@{ $\rightarrow$ }l}
[4] & \meta{Instruction} & \meta{Assign} \\\relax
[5] & & \meta{If} \\\relax
[6] & & \meta{While} \\\relax
[7] & & \meta{Print} \\\relax
[8] & & \meta{Read} \\\relax
[9] & \meta{Assign} & [VarName] := \meta{ExprArith}
\end{tabular}
tabbing
只是因为这很少被使用。
\begin{tabbing}
[4] \= \meta{Instruction} \= $\rightarrow$ \meta{Assign} \\\relax
[5] \> \> $\rightarrow$ \meta{If} \\\relax
[6] \> \> $\rightarrow$ \meta{While} \\\relax
[7] \> \> $\rightarrow$ \meta{Print} \\\relax
[8] \> \> $\rightarrow$ \meta{Read} \\\relax
[9] \> \meta{Assign} \> $\rightarrow$ [VarName] := \meta{ExprArith}
\end{tabbing}
完整示例显示tabular
和tabbing
:
\documentclass[]{article}
\usepackage{array}
\newcommand\meta[1]{$\langle$#1$\rangle$}
\begin{document}
\begin{tabular}{ll@{ $\rightarrow$ }l}
[4] & \meta{Instruction} & \meta{Assign} \\\relax
[5] & & \meta{If} \\\relax
[6] & & \meta{While} \\\relax
[7] & & \meta{Print} \\\relax
[8] & & \meta{Read} \\\relax
[9] & \meta{Assign} & [VarName] := \meta{ExprArith}
\end{tabular}
\begin{tabbing}
[4] \= \meta{Instruction} \= $\rightarrow$ \meta{Assign} \\\relax
[5] \> \> $\rightarrow$ \meta{If} \\\relax
[6] \> \> $\rightarrow$ \meta{While} \\\relax
[7] \> \> $\rightarrow$ \meta{Print} \\\relax
[8] \> \> $\rightarrow$ \meta{Read} \\\relax
[9] \> \meta{Assign} \> $\rightarrow$ [VarName] := \meta{ExprArith}
\end{tabbing}
\end{document}
结果:
其他选择
相反,tabular
您可以使用longtable
它来获取可分页的内容。
description
环境enumitem
诚然,这有点儿像 hack,但你也可以定义一个格式化宏并使用列表description
。以下定义\myformatter
格式化每行的开头。它需要两个可选参数,第一个应该是第二列的最宽条目,在本例中Instruction
,第二个应该是行号中最宽的数字。
\documentclass[]{article}
\newcommand\meta[1]{$\langle$#1$\rangle$}
\newcounter{mylinenumber}
\makeatletter
\NewDocumentCommand\myformatter { O{} O{0} m }
{%
[\phantom{#2}\llap{\arabic{mylinenumber}}]% right aligned, brackets outside
%[\rlap{\arabic{mylinenumber}}\phantom{#2}]% left aligned, brackets outside
%\phantom{[#2]}\llap{[\arabic{mylinenumber}]}% right aligned, brackets packed
%\rlap{[\arabic{mylinenumber}]}\phantom{[#2]}% left aligned, brackets packed
\hspace{1em}%
\ifx\@itemlabel#3%
\else
\rlap{\meta{#3}}%
\fi
\phantom{\meta{#1}}%
\hspace{.5em}$\rightarrow$\hspace{.5em}%
\stepcounter{mylinenumber}%
\ignorespaces
}
\makeatother
\usepackage{enumitem}
\begin{document}
\setcounter{mylinenumber}{6}% number of the first row
\begin{description}[{format=\normalfont\myformatter[Instruction][10]}]
\item[Instruction] \meta{Assign}
\item \meta{If}
\item \meta{While}
\item \meta{Print}
\item \meta{Read}
\item[Assign] [VarName] := \meta{ExprArith}
\end{description}
\end{document}
结果:
有多种方式可以对齐括号和行号,上面显示的是未注释掉的方式。选择您最喜欢的版本,注释掉其他版本,同时保留您喜欢的对齐方式(每行后面的注释应该会提示这是什么样子)。
在方法中自动添加行号tabular
。
\documentclass[]{article}
\usepackage{array}
\newcommand\meta[1]{$\langle$#1$\rangle$}
\newcounter{mylinenumber}
\newcommand*\mylinenumber[1][0]
{%
[\phantom{#1}\llap{\arabic{mylinenumber}}]%
\stepcounter{mylinenumber}%
}
\begin{document}
\setcounter{mylinenumber}{4}% number of the first row
\begin{tabular}{>{\mylinenumber\hspace{1em}}l@{ $\rightarrow$ }l}
\meta{Instruction} & \meta{Assign} \\\relax
& \meta{If} \\\relax
& \meta{While} \\\relax
& \meta{Print} \\\relax
& \meta{Read} \\\relax
\meta{Assign} & [VarName] := \meta{ExprArith}
\end{tabular}
\end{document}