自己命令创建新环境

自己命令创建新环境

下面的代码不是很简单,但我希望您能够理解该代码。

\setcounter{errorcontextlines}{999}
\documentclass{scrartcl}
\usepackage{lipsum,ntheorem}
\usepackage[ntheorem]{mdframed}
\makeatletter
%\newtheorem{<envname>}[<numberedlike>]{<caption>}[<within>]
%\newmdtheoremenv[<mdframed-options>]{<envname>}[<numberedlike>]{<caption>}[<within>]
%\md@tempa[<mdframed-options>]
%\md@tempb{<envname>}%
%\md@tempc[<numberedlike>]%
%\md@tempd{<caption>}%
%\md@tempe[<within>]%
\newrobustcmd*\newmdtheoremenv{%
   \kernel@ifnextchar[%]
     {\newmdtheoremenv@i}{\newmdtheoremenv@i[]}%
}
\newrobustcmd*\newmdtheoremenv@i[2][]{%
\def\md@tempa{#1}%
\def\md@tempb{#2}%
    \kernel@ifnextchar[%]
     {\newmdtheoremenv@ii}{\newmdtheoremenv@ii[]}%
}

%\newmdtheoremenv@ii[<mdframed-options>]{<envname>}[<numberedlike>]{<caption>}
\newrobustcmd*\newmdtheoremenv@ii[2][]{%
\def\md@tempc{#1}%
\def\md@tempd{#2}%
    \kernel@ifnextchar[%]
     {\newmdtheoremenv@iii}{\newmdtheoremenv@iii[]}%
}

%\newmdtheoremenv@ii[<mdframed-options>]{<envname>}[<numberedlike>]{<caption>}[<within>]
\newrobustcmd*\newmdtheoremenv@iii[1][]{%
   \def\md@tempe{#1}%
   \ifboolexpr{ not (test {\ifdefempty{\md@tempc}})
              and 
             not (test {\ifdefempty{\md@tempe}})
           }{%
             \md@PackageWarning{You defined {\string\newtheorem} with ^^J
                                both optional arguments^^J 
                                <numeredlike> and <within>. This isn't allowed^^J
                                \mdframedpackagename will use <numeredlike>\MessageBreak}%
             \newtheorem{\csname md\md@tempb \endcsname}[\md@tempc]{\md@tempd}%
            }%
            {\ifdefempty{\md@tempc}{}{\newtheorem{md\md@tempb}[\md@tempc]{\md@tempd}}%
             \ifdefempty{\md@tempe}{}{\newtheorem{md\md@tempb}{\md@tempd}[\md@tempe]}%
            }%
   \ifboolexpr{test {\ifdefempty{\md@tempc}}
                and 
               test {\ifdefempty{\md@tempe}}
               }{%
               \newtheorem{md\md@tempb}{\md@tempd}%
               }{}%
\expandafter\global\expandafter\@namedef\expandafter{\md@tempb}{%
   \expandafter\mdfsetup\expandafter{\md@tempa}%
               \begin{mdframed}[]\begin{md\md@tempb}%
    }%
\expandafter\global\expandafter\@namedef\expandafter{end\md@tempb}{%
              \end{md\md@tempb}\end{mdframed}%
   }%
}
\makeatother
\begin{document}
{\small\verb+\newmdtheoremenv[mdframed-options]{envname}[numberedlike]{caption}[within]+}
\newmdtheoremenv[linecolor=blue,backgroundcolor=red]{beispiel}{Beispiel}
%\newmdtheoremenv[linecolor=red,backgroundcolor=yellow]{spiel}{Spiel}
\begin{beispiel}[Antwort]
Test
\end{beispiel}

\vspace*{2em}

%\hallo

\vspace*{2em}

%\begin{spiel}%[Antwort]
%Test
%\end{spiel}
\end{document}

我正在尝试创建命令\newmdtheoremenv。在最小示例中,只要只\newmdtheoremenv使用一个命令,它就可以正常工作。当我使用第二个命令时,第一个命令将被覆盖。我该如何避免这种情况,以及如何修改示例以便可以多次使用\newmdtheoremenv该命令。\newmdtheoremenv

答案1

不幸的是,马丁的答案不起作用,因为宏\md@tempa和类似的东西在定义时没有扩展,所以所有定理都具有与最后定义的定理相同的标签。

\setcounter{errorcontextlines}{999}
\documentclass{scrartcl}
\usepackage{lipsum,ntheorem}
\usepackage[ntheorem]{mdframed}
\makeatletter
%\newtheorem{<envname>}[<numberedlike>]{<caption>}[<within>]
%\newmdtheoremenv[<mdframed-options>]{<envname>}[<numberedlike>]{<caption>}[<within>]
%\md@tempa[<mdframed-options>]
%\md@tempb{<envname>}%
%\md@tempc[<numberedlike>]%
%\md@tempd{<caption>}%
%\md@tempe[<within>]%
\renewrobustcmd*\newmdtheoremenv{%
   \kernel@ifnextchar[%]
     {\newmdtheoremenv@i}{\newmdtheoremenv@i[]}%
}
\def\newmdtheoremenv@i[#1]#2{%
    \def\md@tempa{#1}%
    \def\md@tempb{#2}%
    \kernel@ifnextchar[%]
     {\newmdtheoremenv@ii}{\newmdtheoremenv@ii[]}%
}

\def\newmdtheoremenv@ii[#1]#2{%
    \def\md@tempc{#1}%
    \def\md@tempd{#2}%
    \kernel@ifnextchar[%]
     {\newmdtheoremenv@iii}{\newmdtheoremenv@iii[]}%
}

\def\newmdtheoremenv@iii[#1]{%
   \def\md@tempe{#1}%
   \ifboolexpr{ not (test {\ifdefempty{\md@tempc}})
              and 
             not (test {\ifdefempty{\md@tempe}})
           }{%
             \md@PackageWarning{You defined {\string\newtheorem} with ^^J
                                both optional arguments^^J 
                                <numberedlike> and <within>. This isn't allowed^^J
                                \mdframedpackagename will use <numeredlike>\MessageBreak}%
             \begingroup\edef\x{\endgroup
               \noexpand\newtheorem{\csname md\md@tempb\endcsname}[\md@tempc]{\md@tempd}}\x
            }%

            {\ifdefempty{\md@tempc}{}{
               \begingroup\edef\x{\endgroup
                 \noexpand\newtheorem{md\md@tempb}[\md@tempc]{\md@tempd}}\x
}%
             \ifdefempty{\md@tempe}{}{
               \begingroup\edef\x{\endgroup
                 \noexpand\newtheorem{md\md@tempb}{\md@tempd}[\md@tempe]}\x
}%
            }%
   \ifboolexpr{test {\ifdefempty{\md@tempc}}
                and 
               test {\ifdefempty{\md@tempe}}
               }{%
                 \begingroup\edef\x{\endgroup
                   \noexpand\newtheorem{md\md@tempb}{\md@tempd}}\x
               }{}%
   \expandafter\protected@xdef\csname\md@tempb\endcsname{\noexpand\mdfsetup{\md@tempa}%
               \noexpand\begin{mdframed}[]\noexpand\begin{md\md@tempb}%
    }%
   \expandafter\protected@xdef\csname end\md@tempb\endcsname{%
              \noexpand\end{md\md@tempb}\noexpand\end{mdframed}%
   }%
}
\makeatother
\begin{document}
{\small\verb+\newmdtheoremenv[mdframed-options]{envname}[numberedlike]{caption}[within]+}
\newmdtheoremenv[linecolor=blue,backgroundcolor=red]{beispiel}[section]{Beispiel}
\newmdtheoremenv[linecolor=red,backgroundcolor=yellow]{spiel}[subsection]{Spiel}

\begin{beispiel}[Antwort]
Test
\end{beispiel}

\vspace*{2em}

\begin{spiel}%[Antwort]
Test
\end{spiel}
\end{document}

笔记

我已经使用了,\renewrobustcmd因为该机制已经包含在我的版本中框架

答案2

您当前定义环境,以便它们使用临时宏,这些宏在每次新声明时都会被覆盖。您需要先正确扩展它们。此外,您不需要扩展的参数,\@namedef因为它无论如何都会被底层扩展\csname .. \endcsname

\setcounter{errorcontextlines}{999}
\documentclass{scrartcl}
\usepackage{lipsum,ntheorem}
\usepackage[ntheorem]{mdframed}
\makeatletter
%\newtheorem{<envname>}[<numberedlike>]{<caption>}[<within>]
%\newmdtheoremenv[<mdframed-options>]{<envname>}[<numberedlike>]{<caption>}[<within>]
%\md@tempa[<mdframed-options>]
%\md@tempb{<envname>}%
%\md@tempc[<numberedlike>]%
%\md@tempd{<caption>}%
%\md@tempe[<within>]%
\newrobustcmd*\newmdtheoremenv{%
   \kernel@ifnextchar[%]
     {\newmdtheoremenv@i}{\newmdtheoremenv@i[]}%
}
\def\newmdtheoremenv@i[#1]#2{%
    \def\md@tempa{#1}%
    \def\md@tempb{#2}%
    \kernel@ifnextchar[%]
     {\newmdtheoremenv@ii}{\newmdtheoremenv@ii[]}%
}

\def\newmdtheoremenv@ii[#1]#2{%
    \def\md@tempc{#1}%
    \def\md@tempd{#2}%
    \kernel@ifnextchar[%]
     {\newmdtheoremenv@iii}{\newmdtheoremenv@iii[]}%
}

\def\newmdtheoremenv@iii[#1]{%
   \def\md@tempe{#1}%
   \ifboolexpr{ not (test {\ifdefempty{\md@tempc}})
              and 
             not (test {\ifdefempty{\md@tempe}})
           }{%
             \md@PackageWarning{You defined {\string\newtheorem} with ^^J
                                both optional arguments^^J 
                                <numeredlike> and <within>. This isn't allowed^^J
                                \mdframedpackagename will use <numeredlike>\MessageBreak}%
             \newtheorem{\csname md\md@tempb \endcsname}[\md@tempc]{\md@tempd}%
            }%
            {\ifdefempty{\md@tempc}{}{\newtheorem{md\md@tempb}[\md@tempc]{\md@tempd}}%
             \ifdefempty{\md@tempe}{}{\newtheorem{md\md@tempb}{\md@tempd}[\md@tempe]}%
            }%
   \ifboolexpr{test {\ifdefempty{\md@tempc}}
                and 
               test {\ifdefempty{\md@tempe}}
               }{%
               \newtheorem{md\md@tempb}{\md@tempd}%
               }{}%
   \expandafter\protected@xdef\csname\md@tempb\endcsname{\noexpand\mdfsetup{\md@tempa}%
               \noexpand\begin{mdframed}[]\noexpand\begin{md\md@tempb}%
    }%
   \expandafter\protected@xdef\csname end\md@tempb\endcsname{%
              \noexpand\end{md\md@tempb}\noexpand\end{mdframed}%
   }%
}
\makeatother
\begin{document}
{\small\verb+\newmdtheoremenv[mdframed-options]{envname}[numberedlike]{caption}[within]+}
\newmdtheoremenv[linecolor=blue,backgroundcolor=red]{beispiel}{Beispiel}
\newmdtheoremenv[linecolor=red,backgroundcolor=yellow]{spiel}{Spiel}

\begin{beispiel}[Antwort]
Test
\end{beispiel}

\vspace*{2em}

\begin{spiel}%[Antwort]
Test
\end{spiel}
\end{document}

相关内容