考虑以下最小工作示例:
\documentclass{article}
\usepackage[framemethod=TikZ]{mdframed} % noteboxes, boxes, etc.
\newcounter{definition}
\newenvironment{definition}[1][]{%
\stepcounter{definition}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut Definition~\thedefinition};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut Definition~\thedefinition:~#1};}}%
}%
\mdfsetup{innertopmargin=1pt,linecolor=red!60,%
linewidth=2pt,topline=true,
frametitleaboveskip=\dimexpr-\ht\strutbox\relax,}
\begin{mdframed}[]\relax%
}{\end{mdframed}}
\newcounter{theorem}
\newenvironment{theorem}[1][]{%
\stepcounter{theorem}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut Theorem~\thetheorem};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut Theorem~\thetheorem:~#1};}}%
}%
\mdfsetup{innertopmargin=1pt,linecolor=black!60,%
linewidth=2pt,topline=true,
frametitleaboveskip=\dimexpr-\ht\strutbox\relax,}
\begin{mdframed}[]\relax%
}{\end{mdframed}}
\begin{document}
\section{Cats}
Warm kitty, sweet kitty, little ball of fur. Warm kitty, sweet kitty, purr, purr, purr.
\begin{definition}[Kitten.]
A kitten is a baby cat.
\end{definition}
\begin{theorem}[Kittens are warm.]
All kittens are warm.
\end{theorem}
\end{document}
它产生以下输出:
我想定义一些其他的像这样的盒子,例如公理:
\newcounter{axiom}
\newenvironment{axiom}[1][]{%
\stepcounter{axiom}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut Axiom~\theaxiom;}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut Axiom~\theaxiom:~#1};}}%
}%
\mdfsetup{innertopmargin=1pt,linecolor=blue!60,%
linewidth=2pt,topline=true,
frametitleaboveskip=\dimexpr-\ht\strutbox\relax,}
\begin{mdframed}[]\relax%
}{\end{mdframed}}
请注意,这是除颜色之外的其他框定义的完全副本,以及框“类型”(例如公理、定义或定理)。
因此,我认为我不应该多次复制并粘贴此样式来创建新框,而应该以某种方式将定义放入宏中。因此,我决定将定义填充到宏中,\newcommand
如下所示:
\newcommand{\defcustombox}[2]{%
\newenvironment{\expandafter\Makelowercase\expandafter{#1}}[1][]{%
\stepcounter{\expandafter\Makelowercase\expandafter{#1}}%
\ifstrempty{\#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut #1~\the<thing>};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut #1~\the<thing>:~##1};}}%
}%
\mdfsetup{innertopmargin=1pt,linecolor=#2!60,%
linewidth=2pt,topline=true,
frametitleaboveskip=\dimexpr-\ht\strutbox\relax,}
\begin{mdframed}[]\relax%
}{\end{mdframed}}
}
\defcustombox{Axiom}{blue} %example of expected usage
对于这次尝试,这些是我所知道的问题(如果你尝试的话,它不会编译):
- 宏的“内容”必须逐字输出(请注意,我没有转义宏主体中的任何特殊字符);我确实尝试手动转义所有内容,但这很容易出错,而且似乎不是“正确的方法”
- 嵌套参数必须加以区分!(我认为解决这个问题的方法是引用
##1
正在创建的宏的第一个参数时放在框中?我用它来区分内部命令的参数) \the<thing>
必须根据宏的第一个参数想出一种优雅的扩展方法\defcustombox
——它看起来像什么\\the\expandafter\MakeLowercase\expandafter{#1}
?
为了实现这个目标我们应该怎么做呢?
答案1
像这样:
\documentclass{article}
\usepackage[framemethod=TikZ]{mdframed} % noteboxes, boxes, etc.
\newcommand{\definebox}[2]{%
\newcounter{#1}
\newenvironment{#1}[1][]{%
\stepcounter{#1}%
\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=white]
{\strut \MakeUppercase#1~\csname the#1\endcsname\ifstrempty{##1}{}{:~##1}};}}%
\mdfsetup{innertopmargin=1pt,linecolor=#2,%
linewidth=2pt,topline=true,
frametitleaboveskip=\dimexpr-\ht\strutbox\relax,}%
\begin{mdframed}[]\relax%
}{\end{mdframed}}%
}
\definebox{definition}{red!60}
\definebox{theorem}{black}
\begin{document}
\section{Cats}
Warm kitty, sweet kitty, little ball of fur. Warm kitty, sweet kitty, purr, purr, purr.
\begin{definition}[Kitten.]
A kitten is a baby cat.
\end{definition}
\begin{theorem}[Kittens are warm.]
All kittens are warm.
\end{theorem}
\end{document}