创建一个以给定宏命名的环境/计数器

创建一个以给定宏命名的环境/计数器

我正在尝试创建一个以给定宏为名称的环境:

\newcommand{\newproblemset}[1]{\newenvironment{#1}{}}
\newproblemset{problem}

\problem但是,尽管我没有直接定义,但编译器却给出了以下错误:

LaTeX Error: Command \problem already defined.

目的是我想要创建一个命令,支持使用用户指定的环境名称创建环境。

当我想定义一个具有用户指定名称的计数器时,会出现另一个问题。虽然我成功地创建了计数器,但我不知道如何引用该计数器,因为计数器名称应该是\the后跟计数器名称的形式。

问题似乎出在 LaTeX 进行宏扩展的方式上。事实上,我想要做的正是它所做的\newtheorm,即创建一个具有用户给定名称的环境。

更新:完整示例

\documentclass{article}

\newcommand{\newproblemset}[1]{\newenvironment{#1}{c1}{c2}}
\newproblemset{aa}

\begin{document}

    \begin{aa}
        content
    \end{aa}

\end{document}

编译器错误:

root.tex
LaTeX Error: Command \aa already defined.

定义计数器:

\documentclass{article}

\newcommand{\newproblemset}[1]{\newcounter{#1}[section]\renewenvironment{#1}{c1 \refstepcounter{#1} \the#1 }{c2}}
\newproblemset{aa}

\begin{document}

    \begin{aa}
        aa
    \end{aa}

\end{document}

它给出了一个错误:

root.tex (line 8)
You can't use `the letter a' after \the. (  \begin{aa} ...)

答案1

在您的具体示例中,定义一个新的环境(如)aa将不起作用,因为该环境由和aa定义,并且\aa\endaa前者(\aa)已经默认定义如同埃。

您可以\newproblemset使用以下定义来完全忽略命令是否已定义:

\newcommand{\newproblemset}[1]{%
  \expandafter\let\csname #1\endcsname\relax% Remove definition of \<#1>
  \newenvironment{#1}{c1}{c2}}% Define new environment

上面的定义设置\<#1>\relax- 用于检查某项命令是否已经存在的条件之一。当然,如果命令已经存在,您可以更进一步并发出警告(但无论如何都要定义环境):

\documentclass{article}

\makeatletter
\newcommand{\newproblemset}[1]{%
  \ifcsname #1\endcsname
    \@latex@warning{Environment `#1' will overwrite `\expandafter\string\csname #1\endcsname'.}%
    \expandafter\let\csname #1\endcsname\relax % Make sure \<#1> is available for (re)definition
  \fi
  \newenvironment{#1}{c1}{c2}}% Define new environment
\makeatother

\newproblemset{aa}

\begin{document}

\begin{aa}
content
\end{aa}

\end{document}

这输出

LaTeX 警告:环境aa' will overwrite\aa'。在输入行 11。

在里面.log

为了打印计数器,而不是\the#1,您需要\csname the#1\endcsname正确构建类似于的东西\the#1

\documentclass{article}

\makeatletter
\newcommand{\newproblemset}[1]{%
  \ifcsname #1\endcsname
    \@latex@warning{Environment `#1' will overwrite `\expandafter\string\csname #1\endcsname'.}%
    \expandafter\let\csname #1\endcsname\relax % Make sure \<#1> is available for (re)definition
  \fi
  \newcounter{#1}[section]% Define a new counter
  \newenvironment{#1}{c1 \refstepcounter{#1}\csname the#1\endcsname}{c2}}
\makeatother

\newproblemset{aa}

\begin{document}

\begin{aa}
aa
\end{aa}

\end{document}

答案2

\newcommand{\newproblemset}[1]{\newenvironment{#1}{}}

缺少第三个参数,\newenvironment如果在调用时提供该参数,则不一定是错误\newproblemset(尽管奇怪的是,您只提供了结束代码而不是开始代码)。

运行没有错误,并且生成

在此处输入图片描述

\documentclass{article}

    \newcommand{\newproblemset}[1]{\newenvironment{#1}{}}

\begin{document}

\newproblemset{zz}{end code}

\begin{zz}
  abc
\end{zz}
\end{document}

它也可以以您建议的名称无错误地运行problem

\documentclass{article}

    \newcommand{\newproblemset}[1]{\newenvironment{#1}{}}

\begin{document}

\newproblemset{problem}{end code}

\begin{problem}
  abc
\end{problem}
\end{document}

如果您收到所显示的错误,则说明您之前已经定义了一个problem环境或(等效地)一个\problem命令,在这种情况下您\renewenvironment不需要\newenvironment

相关内容