如何在环境的最终代码中使用传递给自定义环境的参数?

如何在环境的最终代码中使用传递给自定义环境的参数?

当我对表格使用通用样式时,我想节省一些输入内容。

但是因为\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}

相关内容