我正在尝试创建一个以给定宏为名称的环境:
\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
。