texblog

Fancy boxes for theorem, lemma, and proof with mdframed

The mdframed package implements a box environment that automatically breaks boxes across multiple pages. Moreover, it allows flexible box designs. An example from the documentation that I particularly like is titled: “Theorem with separate header and the help of TikZ (complex)”. In this article, I use the example to create environments for theorems, lemmas, and proofs, adding a few minor enhancements.

 
The basics explained

In the preamble, we load the mdframed package and define the environments for theorem, lemma, and proof. AS we want to use TikZ syntax later on, we load the package with the framemethod=TikZ option.

\usepackage[framemethod=TikZ]{mdframed}

 
Next, we define a counter for continuous numbering of the environment. Here, I will only show how to do so for theorems, but it is similar for lemmas and proofs. We might want the counter to be reset at the beginning of every section. This is achieved through the optional argument of the newcounter command. Also, we may decide the value of the counter to be displayed as: “section.theorem”. For that, we redefine the command that produces the counter value: \thetheo. Alternatively, to reset the counter at every chapter and display “chapter.theorem”, use chapter in the code instead.

\newcounter{theo}[section]\setcounter{theo}{0}
\renewcommand{\thetheo}{\arabic{section}.\arabic{theo}}

 
With that, we are ready to define a new environment for theorem. This is slightly more complex, so I will go step-by-step and provide the complete code further below for those who are more interested in the complete code.

 
To define a new environment, we use the newenvironment command. It takes three arguments plus an optional argument (args) to define the number of parameters that we want our environment to take.

\newenvironment{name}[args]{begin_def}{end_def}

 
The first parameter name is the name of the environment that we want to create. Here, we may choose may anything that has not been defined already. I use theo, as we want to create a theorem environment. Moreover, we’d like to make use of the page break property provided by the mdframed environment. Therefore, we use \begin{mdframed} and \end{mdframed} as begin and end definitions. Also, we define that the environment takes two arguments/parameters ([2]). Of these two parameters, one is optional and empty by default (extra []) and the other is compulsory. The first, optional argument is for the title which the theorem may or may not have. The second argument, which has to be provided, is for the label to reference the environment. If you prefer, you can also make this an optional parameter.

At the beginning, we increase the theorem counter by one and make the counter available to the \ref command for referencing. For that, we use \refstepcounter.

\newenvironment{theo}[2][]{%
    \refstepcounter{theo}

    % Code for box design goes here.

\begin{mdframed}[]\relax}{%
\end{mdframed}}

 
The next step is to add code for the box design. We distinguish two cases: with and without title. We do this by checking if the first, optional argument is empty (\ifstringempty{#1}). Next, we use the mdfsetup command to change the default box design for both cases. The code is essentially the same, with the only difference that when a title is provided, it is printed. TikZ syntax makes it relatively easy to add a heading with a blue background. The heading contains the word “Theorem”, the counter value and, the title if available (else condition).

Through last bit of code, another mdfsetup, we make some final changes. We add a frame around the entire box and raise the title slightly, such that it is placed on top of the frame rather than inside the box.

\ifstrempty{#1}%
% if condition (without title)
{\mdfsetup{%
    frametitle={%
        \tikz[baseline=(current bounding box.east),outer sep=0pt]
        \node[anchor=east,rectangle,fill=blue!20]
        {\strut Theorem~\thetheo};}
    }%
% else condition (with title)
}{\mdfsetup{%
    frametitle={%
        \tikz[baseline=(current bounding box.east),outer sep=0pt]
        \node[anchor=east,rectangle,fill=blue!20]
        {\strut Theorem~\thetheo:~#1};}%
    }%
}%
% Both conditions
\mdfsetup{%
    innertopmargin=10pt,linecolor=blue!20,%
    linewidth=2pt,topline=true,%
    frametitleaboveskip=\dimexpr-\ht\strutbox\relax%
}

 
We are now ready to use the newly defined theorem environment, as illustrated in the example below. Moreover, the example shows how we can reference the theorem in the text, using the \ref command.

\begin{theo}[Pythagoras' theorem]{thm:pythagoras}
In a right triangle, the square of the hypotenuse is equal to the sum of the squares of the catheti.
$$a^2+b^2=c^2$$
\end{theo}
In mathematics, the Pythagorean theorem, also known as Pythagoras' theorem (see theorem \ref{thm:pythagoras}), is a relation in Euclidean geometry among the three sides of a right triangle.

Text modified from Wikipedia: Pythagorean theorem.

 
With that, we are ready to put everything together and define similar environment for lemma and proof. Code for all three environments is provided below. Feel free to make use and change them to your liking.

 
Theorem

\newcounter{theo}[section]\setcounter{theo}{0}
\renewcommand{\thetheo}{\arabic{section}.\arabic{theo}}
\newenvironment{theo}[2][]{%
\refstepcounter{theo}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=blue!20]
{\strut Theorem~\thetheo};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=blue!20]
{\strut Theorem~\thetheo:~#1};}}%
}%
\mdfsetup{innertopmargin=10pt,linecolor=blue!20,%
linewidth=2pt,topline=true,%
frametitleaboveskip=\dimexpr-\ht\strutbox\relax
}
\begin{mdframed}[]\relax%
\label{#2}}{\end{mdframed}}

 
Lemma

\newcounter{lem}[section]\setcounter{lem}{0}
\renewcommand{\thelem}{\arabic{section}.\arabic{lem}}
\newenvironment{lem}[2][]{%
\refstepcounter{lem}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=green!20]
{\strut Lemma~\thelem};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=green!20]
{\strut Lemma~\thetheo:~#1};}}%
}%
\mdfsetup{innertopmargin=10pt,linecolor=green!20,%
linewidth=2pt,topline=true,%
frametitleaboveskip=\dimexpr-\ht\strutbox\relax
}
\begin{mdframed}[]\relax%
\label{#2}}{\end{mdframed}}

 
Proof

\newcounter{prf}[section]\setcounter{prf}{0}
\renewcommand{\theprf}{\arabic{section}.\arabic{prf}}
\newenvironment{prf}[2][]{%
\refstepcounter{prf}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=red!20]
{\strut Proof~\theprf};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=red!20]
{\strut Proof~\thetheo:~#1};}}%
}%
\mdfsetup{innertopmargin=10pt,linecolor=red!20,%
linewidth=2pt,topline=true,%
frametitleaboveskip=\dimexpr-\ht\strutbox\relax
}
\begin{mdframed}[]\relax%
\label{#2}}{\end{mdframed}}

 
To automatically add the qed symbol, load the amsthm package and place the command \qed just before \end{mdframed}.

% Load package
\usepackage{amsthm}

% Change last line of above code
\begin{mdframed}[]\relax%
\label{#2}}{\qed\end{mdframed}}

 
Complete code example

\documentclass{article}
\usepackage[framemethod=TikZ]{mdframed}
\usepackage{amsthm}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Theorem
\newcounter{theo}[section] \setcounter{theo}{0}
\renewcommand{\thetheo}{\arabic{section}.\arabic{theo}}
\newenvironment{theo}[2][]{%
\refstepcounter{theo}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=blue!20]
{\strut Theorem~\thetheo};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=blue!20]
{\strut Theorem~\thetheo:~#1};}}%
}%
\mdfsetup{innertopmargin=10pt,linecolor=blue!20,%
linewidth=2pt,topline=true,%
frametitleaboveskip=\dimexpr-\ht\strutbox\relax
}
\begin{mdframed}[]\relax%
\label{#2}}{\end{mdframed}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Lemma
\newcounter{lem}[section] \setcounter{lem}{0}
\renewcommand{\thelem}{\arabic{section}.\arabic{lem}}
\newenvironment{lem}[2][]{%
\refstepcounter{lem}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=green!20]
{\strut Lemma~\thelem};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=green!20]
{\strut Lemma~\thelem:~#1};}}%
}%
\mdfsetup{innertopmargin=10pt,linecolor=green!20,%
linewidth=2pt,topline=true,%
frametitleaboveskip=\dimexpr-\ht\strutbox\relax
}
\begin{mdframed}[]\relax%
\label{#2}}{\end{mdframed}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Proof
\newcounter{prf}[section]\setcounter{prf}{0}
\renewcommand{\theprf}{\arabic{section}.\arabic{prf}}
\newenvironment{prf}[2][]{%
\refstepcounter{prf}%
\ifstrempty{#1}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=red!20]
{\strut Proof~\theprf};}}
}%
{\mdfsetup{%
frametitle={%
\tikz[baseline=(current bounding box.east),outer sep=0pt]
\node[anchor=east,rectangle,fill=red!20]
{\strut Proof~\theprf:~#1};}}%
}%
\mdfsetup{innertopmargin=10pt,linecolor=red!20,%
linewidth=2pt,topline=true,%
frametitleaboveskip=\dimexpr-\ht\strutbox\relax
}
\begin{mdframed}[]\relax%
\label{#2}}{\qed\end{mdframed}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Examples
\begin{document}
\section{Theorem and lemma examples with title}
\begin{theo}[Pythagoras' theorem]{thm:pythagoras}
In a right triangle, the square of the hypotenuse is equal to the sum of the squares of the catheti.
\[a^2+b^2=c^2\]
\end{theo}
In mathematics, the Pythagorean theorem, also known as Pythagoras' theorem (see theorem \ref{thm:pythagoras}), is a relation in Euclidean geometry among the three sides of a right triangle.

\begin{lem}[B\'ezout's identity]{lem:bezout}
Let $a$ and $b$ be nonzero integers and let $d$ be their greatest common divisor. Then there exist integers $x$ and $y$ such that:
\[ax+by=d\]
\end{lem}
This is a reference to Bezout's lemma \ref{lem:bezout}


\section{Theorem and proof examples without title}

\begin{theo}{thm:theorem1}
There exist two irrational numbers $x$, $y$ such that $x^y$ is rational.
\end{theo}

\begin{prf}{prf:proof1}
If $x=y=\sqrt{2}$ is an example, then we are done; otherwise $\sqrt{2}^{\sqrt{2}}$ is irrational, in which case taking $x=\sqrt{2}^{\sqrt{2}}$ and $y=\sqrt{2}$ gives us:
\[\bigg(\sqrt{2}^{\sqrt{2}}\bigg)^{\sqrt{2}}=\sqrt{2}^{\sqrt{2}\sqrt{2}}=\sqrt{2}^{2}=2.\]
\end{prf}
\end{document}

 
For more details see the mdframed package documentation or drop me a comment below.

Exit mobile version