我想排版5 rows x 2 cols
方程式。我希望行中的方程式编号自动递增。对于列,我希望自动将a)
和附加b)
到行的方程式编号。这可能吗?
我试图在下面的 ascii 文本中可视化我想要的输出
Reference case Modified Case
-------------- -------------
a = k b (1a) a' = 3 b. (1b)
x = y^k (2a) y' = y^0.5 (2b)
z = e^(k) (3a) z' = e^1.1 (3b)
此外,每列内的所有=
符号都需要垂直对齐。作为奖励,如果代码能够灵活地处理 2-4 列并自动添加列后缀b)
,c)
并d)
正确应用,那就太好了。目前,我对 $5 \times n$ 方程式网格感到满意,但理想情况下,这种编号方案应该可以跨分页符工作,以便于扩展到多个页面。
如何实现这一点?如果需要的话,我很乐意接受 LuaTeX 解决方案。
答案1
下面的代码实现了equationgrid
允许对这些类型的方程使用以下语法的环境:
\begin{equationgrid}[Reference case, Modified Case]{one}%
a &= kb, a' &= 3b\\
x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}
\end{equationgrid}
equation
使用计数器和“列”计数器对方程式进行编号a
,,,,...:b
c
环境equationgrid
接受两个参数:
- 一个选修的标题行是用逗号分隔的列标题列表。
- 方程式需要 A —— 因为我坚信你不应该给方程式贴标签,
label
除非你打算以后引用它。在上面的例子中,可以使用 、 和 来引用\ref{one-1a}
子\ref{one-1b}
方程式。\ref{one-2a}
\ref{one-2b}
请注意,方程式本身用逗号分隔,用于\\
标记方程行的结尾。列数原则上是任意的。例如,您可以使用
\begin{equationgrid}{two}%
a &= kb, a' &= 3 b, a &= k b, a' &= 3 b\\
x &= y^k, y' &= y^{0.5}, x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}, z &= e^k, z' &= e^{1.1}
\end{equationgrid}
生产
(这些方程的方程参考是two-1a
,,two-1b
...,two-3d
。)这些方程是在align*
环境中排版的,因此这个环境和页面宽度限制了实际可以使用的列数。
代码使用LaTex3本质上是序列。首先,gridequation
使用换行符将环境的内容拆分成行\\
,然后使用逗号将行进一步拆分成列。完成后,方程式将重新组合,同时添加方程式编号和标签。
以下是代码:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
% two counters for the keeping track of grid rows and columns
\newcounter{GridEqnCol}[equation]
\newcounter{GridEqnRow}
\renewcommand\theGridEqnCol{(\theequation\alph{GridEqnCol})}
\renewcommand\theGridEqnRow{\arabic{GridEqnRow}\alph{GridEqnCol}}
\ExplSyntaxOn
\int_new:N \l_grid_row_int % grid row number
\seq_new:N \l_grid_col_seq % the column entries in one row
\seq_new:N \l_grid_head_seq % the optional column headers
\seq_new:N \l_grid_row_seq % the rows of the equation
\tl_new:N \l_grid_hline_tl % a hack to adjust the columns
\tl_new:N \l_grid_label_tl % for construction equation labels
% \begin{equationgrid}[column headers as csv]{label}...\end{equationgrid}
\NewDocumentEnvironment{equationgrid}{ o m b }{
% split the environment body into rows using the \\
\tl_clear:N \l_grid_hline_tl
\int_zero:N \l_grid_row_int
\setcounter{GridEqnRow}{0}
\tl_set:Nn \l_grid_label_tl {#2-}
\seq_set_split:Nnn \l_grid_row_seq { \\ } { #3 }
\IfNoValueTF{#1}{ \seq_clear:N \l_grid_head_seq }
{
\seq_set_split:Nnn \l_grid_head_seq {,} {#1}
\tl_put_right:Nx \l_grid_hline_tl {
\noexpand\cline{1-\int_eval:n{2+4*\seq_count:N \l_grid_head_seq} }
}
}
\begin{align*}
\seq_if_empty:NF \l_grid_head_seq {
\seq_map_function:NN \l_grid_head_seq \__grid_head:n
\\\tl_use:N \l_grid_hline_tl
}
\seq_map_inline:Nn \l_grid_row_seq { \__grid_row:n {##1} }
\end{align*}
}{}
% typeset an entry of the header row
\cs_new:Npn \__grid_head:n #1 { \multispan{2}{\textbf{#1}} &&& }
% typeset an equation row, adding equation numbers and references
\cs_new:Npn \__grid_row:n #1 {
\refstepcounter{equation}
\refstepcounter{GridEqnRow}
% split #1 into column entries using the ,
\seq_set_split:Nnn \l_grid_col_seq { , } {#1}
\seq_map_inline:Nn \l_grid_col_seq {
\refstepcounter{GridEqnCol}
\tl_set:No \l_tmpa_tl {\tl_use:N \l_grid_label_tl \theGridEqnRow}
% align* disables equation numbers so need \ltx@label instead of \label
\use:c{ltx@label}{ \tl_use:N \l_tmpa_tl }
##1 & \theGridEqnCol &&
}
\\
}
\ExplSyntaxOff
\begin{document}
\begin{equationgrid}[Reference case, Modified Case]{one}%
a &= kb, a' &= 3b\\
x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}
\end{equationgrid}
\begin{equationgrid}{two}%
a &= kb, a' &= 3 b, a &= k b, a' &= 3 b\\
x &= y^k, y' &= y^{0.5}, x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}, z &= e^k, z' &= e^{1.1}
\end{equationgrid}
As you see, equations \ref{one-1a} and \ref{two-1a} are similar.
\end{document}
最后一点需要注意:由于行\\
和列之间用逗号分隔,
,因此您不能在方程式中使用逗号。如果您想插入逗号,最简单的方法是使用\newcommand\comma{,}
。我遵循了 OP 的语法,但我可能会在每个方程式的末尾放一个逗号。
编辑
这是代码的更新版本,其中equationgrid
环境现在接受一个额外的可选参数,因为<...>
它给出了一个以逗号分隔的列索引列表,其中应省略方程编号。此外,您可以\notag
在任何单元格中放置命令以隐藏该单元格的方程编号(请注意,命令\notag
必须位于逗号之前!)。例如,
\begin{equationgrid}<1,3>{three}%
a &= kb, a' &= 3 b, a &= k b, a' &= 3 b\\
x &= y^k, y' &= y^{0.5}, x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}\notag, z &= e^k, z' &= e^{1.1}
\end{equationgrid}
抑制第 1 列和第 3 列以及第 3 行第 2 列的方程编号以产生:
以下是更新后的代码:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
% two counters for the keeping track of grid rows and columns
\newcounter{GridEqnCol}[equation]
\newcounter{GridEqnRow}
\renewcommand\theGridEqnCol{(\theequation\alph{GridEqnCol})}
\ExplSyntaxOn
\bool_new:N \g_print_eq_bool % suppress equation numbers in this column
\int_new:N \l_grid_row_int % grid row number
\seq_new:N \l_grid_col_seq % the column entries in one row
\seq_new:N \l_grid_head_seq % the optional column headers
\seq_new:N \l_grid_row_seq % the rows of the equation
\seq_new:N \l_suppress_eq_seq % suppress equation numbers in these columns
\tl_new:N \l_grid_hline_tl % a hack to adjust the columns
\tl_new:N \l_grid_label_tl % for construction equation labels
\renewcommand\theGridEqnRow{ \tl_use:N \l_grid_label_tl-\arabic{GridEqnRow}\alph{GridEqnCol} }
% \begin{equationgrid}<suppress column equation numbers>[column headers as csv]{label}...\end{equationgrid}
\NewDocumentEnvironment{equationgrid}{ D<>{} o m b }{
% split the environment body into rows using the \\
\tl_clear:N \l_grid_hline_tl
\int_zero:N \l_grid_row_int
\let\notag\relax % for completeness but not strictly necessary
\setcounter{GridEqnRow}{0}
\seq_set_split:Nnn \l_suppress_eq_seq { , } { #1 }
\tl_set:Nn \l_grid_label_tl {#3}
\seq_set_split:Nnn \l_grid_row_seq { \\ } { #4 }
\IfNoValueTF{#2}{ \seq_clear:N \l_grid_head_seq }
{
\seq_set_split:Nnn \l_grid_head_seq {,} {#2}
\tl_put_right:Nx \l_grid_hline_tl {
\noexpand\cline{1-\int_eval:n{2+4*\seq_count:N \l_grid_head_seq} }
}
}
\begin{align*}
\seq_if_empty:NF \l_grid_head_seq {
\seq_map_function:NN \l_grid_head_seq \__grid_head:n
\\\tl_use:N \l_grid_hline_tl
}
\seq_map_inline:Nn \l_grid_row_seq { \__grid_row:n {##1} }
\end{align*}
}{}
% typeset an entry of the header row
\cs_new:Npn \__grid_head:n #1 { \multispan{2}{\textbf{#1}} &&& }
% typeset an equation row, adding equation numbers and references
\cs_new:Npn \__grid_row:n #1 {
\refstepcounter{equation}
\refstepcounter{GridEqnRow}
% split #1 into column entries using the ,
\seq_set_split:Nnn \l_grid_col_seq { , } {#1}
\seq_map_inline:Nn \l_grid_col_seq {
\refstepcounter{GridEqnCol}
\bool_gset_true:N \g_print_eq_bool
\seq_if_in:NxT \l_suppress_eq_seq {\arabic{GridEqnCol}} { \bool_gset_false:N \g_print_eq_bool }
\str_if_in:nnT { ##1 } { \notag } { \bool_gset_false:N \g_print_eq_bool }
\bool_if:NT \g_print_eq_bool
{
% align* disables equation numbers so need \ltx@label instead of \label
\use:c{ltx@label}{ \theGridEqnRow }
}
##1 & \bool_if:NT \g_print_eq_bool {\theGridEqnCol} &&
}
\\
}
\cs_generate_variant:Nn \seq_if_in:NnF {NxF}
\ExplSyntaxOff
\begin{document}
\begin{equationgrid}[Reference case, Modified Case]{one}%
a &= kb, a' &= 3b\\
x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}
\end{equationgrid}
\begin{equationgrid}{two}%
a &= kb, a' &= 3 b, a &= k b, a' &= 3 b\\
x &= y^k, y' &= y^{0.5}, x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}, z &= e^k, z' &= e^{1.1}
\end{equationgrid}
As you see, equations \ref{one-1a} and \ref{two-1a} are similar.
\begin{equationgrid}<1,3>{three}%
a &= kb, a' &= 3 b, a &= k b, a' &= 3 b\\
x &= y^k, y' &= y^{0.5}, x &= y^k, y' &= y^{0.5} \\
z &= e^k, z' &= e^{1.1}\notag, z &= e^k, z' &= e^{1.1}
\end{equationgrid}
\end{document}
答案2
这是展示巨大潜力的绝佳机会pgfplotstable
\documentclass{article}
\usepackage{pgfplotstable,booktabs,colortbl}
\pgfplotsset{compat=1.13}
\begin{document}
\def\noteqnarrayskip{$\mkern\thickmuskip$}
\def\printlabel{printlabel}
\pgfplotstableread[col sep=&,row sep=\\]{
alhs & arhs & blhs & brhs \\
a_1 & = A^{11} & b_1 & = B^{11} \\
a_2 & = A^{22} & b_2 & = B^{22} \\
a_3 & = A^{33} & b_3 & = B^{33} \\
}\excelatequations
\pgfplotstableset{
create on use/placeholder4label/.style={
create col/set={labels fail}, % you will see `labels fail`
% if one day the mechanism of assigning labels breaks
}
}
\begin{table}
\caption{Everyone can excel.}
$$\pgfplotstabletypeset[
% booktabs-related
every head row/.style={before row=\toprule,after row=\midrule},
every last row/.style={after row=\bottomrule},
% arrange the columns into a table % notice the repetition
columns={alhs,arhs,placeholder4label,blhs,brhs,placeholder4label},
% put cell content into math $ $
assign cell content/.style={@cell content/.initial={$#1$}},
% compute and format label
columns/placeholder4label/.style={assign cell content/.code={
\pgfmathtruncatemacro\rowint{\pgfplotstablerow+1}%123...
\pgfmathtruncatemacro\colascii{(\pgfplotstablecol+1)/3+96}%abc...
\edef\equationlabel{(\rowint\char\colascii)}%\char97 = a
\pgfkeyslet{/pgfplots/table/@cell content}\equationlabel
}},
% set spaces properly
columns/alhs/.style={
column type={ r@\noteqnarrayskip }
},
columns/arhs/.style={
column type={ @{}l }
},
columns/blhs/.style={
column type={ r@\noteqnarrayskip }
},
columns/brhs/.style={
column type={ @{}l }
},
% set multicol % uncommon to hide implementation details
% every head row/.style=output empty row,
% every row no 0/.style={
% before row={
% \toprule
% \multicolumn 3c{big col A} & \multicolumn 3c{fat col B}\\
% \midrule}
% },
]\excelatequations$$
\end{table}
\end{document}
罕见之后