当我对表格使用通用样式时,我想节省一些输入内容。
但是因为\caption
必须\label
在浮点数中使用,所以我想通过参数将这些宏的值传递到我的环境中。
我想将这些保存在我的环境的最终代码中,以便轻松地将标题保存在表格的底部。
以下是我的问题的 MWE:
\documentclass[
fontsize=12pt,
a4paper
]{scrreprt}
\newenvironment{bordertab}[2]
{
\begin{table}
\centering
\begin{tabular}{| l c r |}
\hline
}
{
\hline
\end{tabular}
\caption{#1}
\label{tab:b:#2}
\end{table}
}
\begin{document}
\begin{bordertab}{A table with a border}{ex1}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9 \\
\end{bordertab}
\end{document}
以及使用 LaTeX 时遇到的错误:
! Illegal parameter number in definition of \reserved@a.
<to be read again>
1
l.28 ^^I\end{bordertab}
You meant to type ## instead of #, right?
Or maybe a } was forgotten somewhere earlier, and things
are all screwed up? I'm going to assume that you meant ##.
! You can't use `macro parameter character #' in restricted horizontal mode.
<argument> \ignorespaces ##
1
l.28 ^^I\end{bordertab}
Sorry, but I'm not programmed to handle this case;
I'll just pretend that you didn't ask for it.
If you're in the wrong mode, you might be able to
return to the right one by typing `I}' or `I$' or `I\par'.
! You can't use `macro parameter character #' in restricted horizontal mode.
<argument> \ignorespaces ##
1
l.28 ^^I\end{bordertab}
Sorry, but I'm not programmed to handle this case;
I'll just pretend that you didn't ask for it.
If you're in the wrong mode, you might be able to
return to the right one by typing `I}' or `I$' or `I\par'.
! Illegal parameter number in definition of \reserved@a.
<to be read again>
2
l.28 ^^I\end{bordertab}
You meant to type ## instead of #, right?
Or maybe a } was forgotten somewhere earlier, and things
are all screwed up? I'm going to assume that you meant ##.
答案1
将值保存在宏中,然后可以在环境结束时使用这些值。
\documentclass[
fontsize=12pt,
a4paper
]{scrreprt}
\newcommand\bordertabA{} % make sure \bordertabA is not in use.
\newcommand\bordertabB{} % make sure \bordertabB is not in use.
\newenvironment{bordertab}[2]
{\def\bordertabA{#1}%
\def\bordertabB{#2}%
\begin{table}
\centering
\begin{tabular}{| l c r |}
\hline
}
{
\hline
\end{tabular}
\caption{\bordertabA}
\label{tab:b:\bordertabB}
\end{table}
}
\begin{document}
\begin{bordertab}{A table with a border}{ex1}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9 \\
\end{bordertab}
\end{document}
通过宏传递参数是必要的,因为定义
\newenvironment{myenv}[n]{begin code}{end code}
大致相当于定义
\newcommand\myenv[n]{begin code}
\newcommand\endmyenv{end code}
因此参数仅可用于 begin 代码。#1
在 end 代码中使用将导致观察到的错误illegal parameter number
,因为没有参数。
答案2
问题不在于\caption
或\label
接收#
参数的命令。问题是,当您指定带有参数的环境时,必须#
属于<begin>
此环境的一部分:
\newenvironment{myenv}[1]{here goes #1}{no #1's here!!}
鉴于这一事实,您只需将标题放在顶部即可:
\newenvironment{bordertab}[2]
{
\begin{table}
\centering
\caption{#1}
\label{tab:b:#2}
\begin{tabular}{| l c r |}
\hline
}
{
\hline
\end{tabular}
\end{table}
}
当然,这样做的缺点是,标题放在顶部,而我们希望它放在底部。为了解决这个问题,可以使用非常有用的包 floatrow
,将所有表格浮动设置为底部,此外,我们可以为设置一个可选参数bordertab
,将位置重置为顶部。此外,floatrow
将所有浮动设置为\centering
开箱即用,这样就不再需要了。
\documentclass[
fontsize=12pt,
a4paper
]{scrreprt}
\usepackage{floatrow}
\newenvironment{bordertab}[3][top]
{\floatsetup[table]{capposition=#1}
\begin{table}
\caption{#2}
\label{tab:b:#3}
\begin{tabular}{| l c r |}
\hline
}
{
\hline
\end{tabular}
\end{table}
}
\begin{document}
\begin{bordertab}{A table with a border}{ex1}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9 \\
\end{bordertab}
\begin{bordertab}[bottom]{A tabl}{ex2}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9 \\
\end{bordertab}
\end{document}