2

I'm trying to create an environment with a given macro as name:

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

However, the compiler gives the following error, though I don't define \problem directly:

LaTeX Error: Command \problem already defined.

The purpose is that I want to create a command, that supports creating an environment with a user-specified environment name.

Another issue arises when I want to define a counter with user-specified name. Although I managed to create the counter successfully, I don't how to refer to that counter, since the counter name should be in the form of \the followed by the counter name.

It seems the issue lies in the way how LaTeX does macro expansion. In fact, what I want to do is exactly what \newtheorm does, which creates an environment with user-given names.

Update: a full example

\documentclass{article}

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

\begin{document}

    \begin{aa}
        content
    \end{aa}

\end{document}

Compiler's error:

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

For defining a counter:

\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}

It gives an error:

root.tex (line 8)
You can't use `the letter a' after \the. (  \begin{aa} ...)
6
  • I can't replicate the problem with the current code snippet. You must have some other package included that defines a problem environment (or command). Also, \newenvironment takes 3 arguments, not just 2: One for the environment name, one for the \begin part of the environment and a final one for the \end part.
    – Werner
    Commented Sep 24, 2019 at 17:30
  • @Werner Using \newcommand{\newproblemset}[1]{\newenvironment{#1}{}{}} \newproblemset{aa} gives the same error \aa is defined. I'm using XeLaTeX.
    – SXKDZ
    Commented Sep 24, 2019 at 17:43
  • 2
    Please provide a minimal working example that replicates the current issue. It should start with \documentclass and end with \end{document} and allow us to copy-and-paste-and-compile and see exactly what you're experiencing. It should be minimal though, only the necessary packages that replicates the behaviour. Can you do that?
    – Werner
    Commented Sep 24, 2019 at 18:09
  • @Werner updated.
    – SXKDZ
    Commented Sep 25, 2019 at 0:10
  • Well, \aa is a command already (see the Comprehensive LaTeX Symbol List). It would be different for problem, which doesn't exist by default. Do you want to define \newproblemset to completely ignore whether a command already exists?
    – Werner
    Commented Sep 25, 2019 at 0:21

2 Answers 2

1

In your specific example, defining a new environment like aa won't work since the environment aa is defined by \aa and \endaa, and the former (\aa) is already defined by default as Angstrom.

You could create \newproblemset to completely ignore whether a command is already defined using the following definition:

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

The above definition sets \<#1> to \relax - one of the conditions used to check whether something already exists or not. Of course, you can go that one step further and issue a warning if the command already exists (but define the environment anyway):

\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}

This outputs

LaTeX Warning: Environment aa' will overwrite\aa'. on input line 11.

in the .log.

For printing the counter, instead of \the#1, you need \csname the#1\endcsname to properly constructing something that resembles \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}{}}

is missing the third argument to \newenvironment which isn't necessarily an error if you provide the argument when calling \newproblemset (although odd that you just supply the end code not the start code).

This runs without error and produces

enter image description here

\documentclass{article}

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

\begin{document}

\newproblemset{zz}{end code}

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

It also runs without error with your suggested name problem

\documentclass{article}

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

\begin{document}

\newproblemset{problem}{end code}

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

If you get the error shown then you have previously already defined a problem environment or (equivalently) a \problem command, in which case you will need \renewenvironment not \newenvironment.

1
  • Hello, thanks for your answer. I've included a full example. Could you please help me check that?
    – SXKDZ
    Commented Sep 25, 2019 at 0:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .