¿Por qué el siguiente código no funciona?
\Requirepackage{amsthm}
\renewcommand\newtheorem[2]{%
\NewEnviron{\csname #1\endcsname}[1]{%
##1 : \BODY
}
}
He visto ejemplos del uso de \csname SOMENAME\endcsname
for macro sin argumentos pero no sé cómo hacerlo con a \NewEnviron
o \newcommand
con múltiples argumentos. Me aparece el error ! Missing \endcsname inserted
.
Respuesta1
No desea un nombre de comando para el nombre de un entorno. Sólo el nombre está bien.
Entonces, puedes hacer esto:
\documentclass{article}
\usepackage{amsthm,environ}
\renewcommand\newtheorem[2]{%
\NewEnviron{#1}[1]{%
##1 : \BODY
}%
}
\begin{document}
\newtheorem{acorns}{oaks}
\begin{acorns}{trees}
leaves and things
\end{acorns}
\end{document}
Tenga en cuenta que este código no requiereamstmo, podría usarlo \newcommand\newtheorem...
a menos que necesite el paquete por otros motivos.
Además, nunca hace nada con el segundo argumento, aunque cree el comando para que sea necesario. En el ejemplo anterior, nunca se hace nada con oaks
.
No estoy convencido de que esto sea realmente lo que quieres hacer. El resultado del código anterior es:
ComoChristian Hupfer señala, esto, por supuesto, romperá cualquier cosa que se use \newtheorem
en el sentido estándar. Comoegreg dice, no está del todo claro para qué \newtheorem
sirve una redefinición de este tipo. Parece casi seguro que causará problemas tarde o temprano... probablemente antes.
Respuesta2
¿Por qué el siguiente código no funciona?
Echemos un vistazo más de cerca a lo que \NewEnviron
hace:
Después de una breve cadena de macros para analizar correctamente la entrada del usuario, \NewEnviron
se utiliza \env@newenvironment
lo que se hizo \let
al \newenvironment
principio.
Ahora, \newenvironment
internamente hace entre otras cosas (un poco simplificado) algo como
\expandafter\def\csname <env-name>\endcsname{<begin-code>}
(Básicamente, hiciste lo correcto sin saber que los componentes internos ya se están ocupando de esto).
Si configura " <env-name>=\csname SOMENAME\endcsname
" (lo que resultaría del uso de su macro personalizada \newtheorem{SOMENAME}{}
), terminará con un \csname...\endcsname
par superfluo:
\expandafter\def\csname\csname SOMENAME\endcsname\endcsname...
\expandafter
(como probablemente ya sabes) en este caso lo toma \def
y lo almacena para mirar hacia el siguiente token y expandirlo primero. Aquí encuentra \csname
lo que busca lo siguiente \endcsname
y expande todo lo que hay entre medio y forma una secuencia de control a partir de eso. Este sería otro \csname
que nuevamente termina correctamente con el final \endcsname
. Entonces, realmente aplicas el \csname
mecanismo dos veces a 'ALGÚN NOMBRE' y esto significa que no terminas con \def\SOMENAME{<begin-code>}
(como planeaste), sino con
\def\<expansion of \SOMENAME>{<begin-code>}
Si \SOMENAME
estaba definido no teníamos ningún problema:
\documentclass{article}
\usepackage{environ}
\def\SOMENAME{somename}
\NewEnviron{\csname SOMENAME\endcsname}{somename-content: \BODY}
\begin{document}
\begin{somename}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Integer feugiat tempus urna, cursus placerat sapien mollis ac.
Donec a accumsan orci, in tristique ligula.
\end{somename}
\end{document}
Pero deberíasnodefinirlo; esta interfaz de usuario sería de alguna manera engañosa. Simplemente use \NewEnviron
exactamente lo mismo que \newenvironment
con respecto a la entrada del nombre del entorno:
\documentclass{article}
\usepackage{environ}
\newcommand{\FlorianEnvdefWrapper}[1]{%
\NewEnviron{#1}[1]{##1: \BODY}
}
\FlorianEnvdefWrapper{somename}
\begin{document}
\begin{somename}{foo-bar}
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Integer feugiat tempus urna, cursus placerat sapien mollis ac.
Donec a accumsan orci, in tristique ligula.
\end{somename}
\end{document}
Observación
Cambié el nombre de su macro de ejemplo para evitar conflictos con el amsthm
paquete. Creo que es mejor dejar esas cosas como están, en general. Seguramente hay excepciones, pero perder su funcionalidad por completo puede no ser la mejor opción si puedes evitarlo simplemente eligiendo otro nombre para tu comando.