6

I defined a question macro, then made it successively fancier. Right now, three macro should define a short hand for the following:

\section{Questions}
\begin{enumerate}
\item Q1...
\item Q2...
\end{enumerate}
\section{Exercises}
\begin{enumerate}
\item exercise 1
\item exercise 2
\end{enumerate}
\href{my.url.goes/here/specific}{Take the quiz}

The three commands defined to do this are:

\newcommand{\qqq}{\section{Question}\begin{enumerate}}
\newcommand{\exer}{\end{enumerate}\section{Exercises}\begin{enumerate}}
\newcommand{\endexer}[1]{\end{enumerate}\href{my.url.com/path/{#1}}{Take the quiz}}

A sample call to make this happen:

\qqq
\item What is 2+3?
\exer
\item Write a program to compute 2+3
\endexer{123}

should generate the url:

my.url.com/path/123

The error is:

! LaTeX Error: Command \endexer already defined. Or name \end... illegal, see p.192 of the manual.

I am not posting the MWE because I think this is a stupid syntax error based on something I am missing about \newcommand, but if I'm wrong, I will create an MWE and add it here.

  • The argument to \endexer goes in {}. But rather sake of code readability I'd recommend making this as environments instead. It gives the code a better structure – daleif May 24 '15 at 17:41
  • Whoops! I tried it both ways. I will replace it, it still doesn't work – Dov May 24 '15 at 17:51
  • 1
    You can not define a command starting with \end using \newcommand But it always helps if you provide an example that reproduces the error rather than make people spot errors by eye. – David Carlisle May 24 '15 at 17:55
  • there you are, you added the error message Or name \end... illegal which is telling you exactly that, you can not define \endexer this way. – David Carlisle May 24 '15 at 17:57
  • Related: tex.stackexchange.com/questions/199692/… – user31729 May 24 '15 at 18:03
7

The first problem you have is that you cannot create a macro starting with \end... when using \newcommand. This check is defined inside the LaTeX kernel as part of an \@ifdefinable condition. To circumvent this you need to use TeX directives. That is,

\def\endexer#1{<stuff>}

rather than

\newcommand{\endexer}[1]{<stuff>}

Secondly, the \newcommand syntax has the following structure (see source2e.pdf):

\newcommand*{\foo}[<i>][<j>]{<text>}
  • * is optional
  • \foo is the command to be created
  • <i> is the number of arguments to gobble (up to 9); this references mandatory or a possible optional argument
  • <j> is the default value of the first optional argument (if it exists does not exist); can only have one
  • <text> is the macro definition when using \foo

For \newcommand{\foo}[1]{stuff #1} you would use it as \foo{<stuff>}, not \foo[<stuff>]. This latter usage would have required a definition of \foo of the form

\newcommand{\foo}[1][]{<stuff>}

Note the second set of [], denoting that \foo takes an optional argument (that is empty by default/if not specified).

Specific to your case, use \endexer{123}, not \endexer[123].


Here is a minimal example:

enter image description here

\documentclass{article}
\usepackage{hyperref}
\newcommand{\qqq}{\section{Question}\begin{enumerate}}
\newcommand{\exer}{\end{enumerate}\section{Exercises}\begin{enumerate}}
\def\endexer#1{\end{enumerate}\href{my.url.com/path/{#1}}{Take the quiz}}
\begin{document}

\qqq
\item What is $2+3$?
\exer
\item Write a program to compute $2+3$.
\endexer{123}

\end{document}
  • Is there any downside to using tex rather than latex in this case? – Dov May 24 '15 at 18:18
  • @Dov: No, LaTeX is built on TeX. LaTeX just has an additional check to for this kind of thing (hence the discouraged approach). – Werner May 24 '15 at 18:31
  • @Dov It is better to use a different name (and so follow latex conventions) rather than use \def – David Carlisle May 24 '15 at 21:05
  • 1
    Thanks! Yes, not just interested in fixing the problem, trying to learn "how it's done" in Late. I can't believe "the manual" is a commercial book on an open source product! Yuck! – Dov May 24 '15 at 23:10
5

The names beginning with \end.... are reserved for implementing the end codes of environments, so you can not define \endexer with \newcommand. You could call the command \stopexer or \exerend or anything else that does not start with \end.

3

While I strongly discourage the use of newcommands for such cases, here is a more-readable way of doing it:

\documentclass[12pt,a4paper]{article}
\usepackage{hyperref}

\newcommand{\qqq}[1]{\section{Question}\begin{enumerate}#1\end{enumerate}}
\newcommand{\exer}[2]{\section{Exercises}\begin{enumerate}#1\end{enumerate} \href{my.url.com/path/{#2}}{Take the quiz}}

\begin{document}

\qqq{%
\item Q1 ...
\item Q2 ...}

\exer{%
\item exercise 1
\item exercise 2}
{path/to/quiz}

\end{document}

enter image description here

If you are repeating this, however, I recommend just adding a shortcut macro which can be called by pressing two keyboard buttons. Hiding the real syntax make it harder to fix bugs later and makes your code error prone. It is always a good practice to make your LaTeX code explicit.

  • +1 for saying that making code explicit is "always a good practice". – barbara beeton Jul 17 '15 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.