Consider the following minimal working example:
\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}
It produces the following output:
I would like to define some other boxes like this, e.g. axiom:
\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}}
Note that this is a total copy of the other box definitions, except for colour, and what the box "type" is (e.g. axiom, vs. definition or theorem).
So, it seems to me that instead of copy and pasting this style multiple times to create new boxes, I should somehow put the definition into a macro. So I decide to stuff the definition into a \newcommand
as follows:
\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
For this attempt, these are the issues that I know of (it does not compile, if you try it out):
- the "content" of the macro has to be output verbatim (note that I have not escaped any of the special characters within the body of the macro); I did attempt to manually escape everything, but it is error-prone and doesn't seem to be "the right way"
- nested parameters have to be distinguished! (I think the solution to this is to put
##1
when referencing the first argument of the macro being created in the box? I use that to distinguish the inner command's argument) - have to come up with an elegant way of expanding
\the<thing>
based on the first argument of the\defcustombox
macro --- will it look something like\\the\expandafter\MakeLowercase\expandafter{#1}
?
What should one do to make this work?
\mdfdefinestyle
macro (see p.4, section 5, mdframed manual). – Paul Gaborit Feb 8 '18 at 7:19