[Tex/LaTex] mdframed: how to design “exercise” box

mdframed

For theorems and a like I use mdframed package. For theorems, definitions I use standard design, meanwhile for examples and exercises I rather to have more exotic one …

So far I succeed to make the following solution:

\documentclass[12pt,twoside]{book}
    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage{lipsum}
    \usepackage{showframe}

\usepackage[framemethod=tikz]{mdframed}
\usetikzlibrary{calc, positioning, shapes.geometric}

\tikzset{
    node distance= 0mm and 3mm,
ws/.style={align=#1,
           font=\large\bfseries\sffamily, 
           draw, thin, fill=white,
           overlay,
           }
        }

\makeatletter
\mdfdefinestyle{example}%
{%
    hidealllines=true, 
    skipabove=2\baselineskip, skipbelow=-1ex,
    innertopmargin=0pt, innerbottommargin=0pt,%
    middlelinewidth=5pt, linecolor=red,%
    fontcolor=teal, font=\small\sffamily,%
%
settings={%\global\refstepcounter{example}
        \ifodd\value{page}
    \boolfalse{mdf@leftline}
    \booltrue{mdf@rightline}
        \else
    \booltrue{mdf@leftline}
    \boolfalse{mdf@rightline}
        \fi},
    innerrightmargin=\ifodd\value{page}0.5em\else 0.0em\fi, %rightmargin=7em,%
    innerleftmargin =\ifodd\value{page}0.0em\else 0.5em\fi, %leftmargin =7em,%
singleextra={
        \ifodd\value{page}
\node[ws=left,below right=of P] {\theexample};
        \else
\node[ws=right,below left=of O |- P]  {\theexample};
        \fi
             },%
}% end of mdfdefinestyle
\makeatother

\mdtheorem[style=example,
           ]{example}{Example}[chapter]

\mdtheorem[style=exercise,
           ]{exercise}{Exercise}[chapter]

\begin{document}
\chapter{test}

\begin{mdframed}[style=example]
    This is produced by \verb+\begin{mdframed}[style=example] ... \end{mdframed}+
\end{mdframed}
xxxxxxxxx 
\begin{example}
    This is produced by \verb+\begin{example} ... \end{example}+
\end{example}

\newpage
\lipsum[2]
\begin{mdframed}[style=example]
    \lipsum[2]
\end{mdframed}

\begin{example}
    \lipsum[2]
\end{example}

\end{document}

enter image description here

I like to have the "Example " instead of top of an example tex rather in the box with now with number on the right side of text (or on the left side, if page is even). Is this possible?

Any improvement of my code is also welcome!

Addendum:
Meanwhile I gave-up to manage solution with mdframed and define equivalent environments with tcolorbox (as suggested in early comments). With it the solution is:

\documentclass[12pt,twoside]{book}
    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage[many]{tcolorbox}
\usetikzlibrary{positioning}
    \usepackage{etoolbox}

    \usepackage{lipsum}
    \usepackage{showframe}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  EXERCISES                                                   %
%%==============================================================%
\newcounter{task}
\AtBeginEnvironment{task}{\linespread{.9}\selectfont}
%---------------------------------------------------------------%
\newtcolorbox[use counter=task,
              number within=section,
              ]{task}%
   {enhanced jigsaw,
    breakable,
    toggle left and right,
    boxrule=0mm,
    colback=white, colframe=red,
    top=0mm,bottom=1mm,left=1mm,right=1mm,
    arc=0mm,
    borderline={0.5pt}{0pt}{red, sharp corners},
    fontupper=\normalsize\sffamily, fontlower=\normalsize\sffamily,
    rightrule=1mm,
overlay={\renewcommand\thetcbcounter{\thesection-\arabic{\tcbcounter}}%
\tcbifoddpage{\node[font=\large\sffamily, text=red, inner sep=0mm,
                    below right=0mm and \marginparsep] at (frame.north east) {Vaja
                    \thetcbcounter};}
             {\node[font=\large\sffamily, text=red, inner sep=0mm,
                    below left=0mm and \marginparsep]  at (frame.north west) {Vaja
                    \thetcbcounter};}
        }%end of overlay
    }% end of task

\begin{document}
\chapter{Chapter title}
\section{Test of "task" environment defined\newline 
         with use of "tcolorbox" package}
I looking for equivalent solution with package \verb+mdframed+, so far my attempts was unsuccessful.
\begin{task}
    This is produced by \verb+\begin{task}{}{} ... \end{task}+ defined with \verb+tcolorbox+
\end{task}
\lipsum[2]
\begin{task}
    \lipsum[1-2]
\end{task}
\end{document}

which gives:

enter image description here

Result is almost satisfactory … in it I miss identification if the "Vaja …" is on the second page or not. if it is, I like to add (in second line) "nadaljevanje" (continue), but this I left for time when I will finished text book, where I use this environment.

Now I testing of G. Bay solution. As is, it works, unfortunately without numbering, as I expected, however, with its integration in my collection mdframed based theorems, definitions etc, I still have problems.

In final solution I like to obtain similar solution of use as is used in other mdframed theorems, for example at definition:

    \begin{definition}{Informacija}{info}
    \index{informacije!definicija}
Informacija je enaka nezanesljivosti, ki jo nastop dogodka odstrani.
    \end{definition}
Iz definicije \ref{def:info} sledi:

So I sill looking for any suggestion.

Best Answer

If I understand correctly this is more or less what you had in mind:

Example title at even/odd pages

Basically what did was add the following:

frametitle={\ifodd\value{page} \rlap{\hspace*{15pt} Example}  \else \llap{Example \hspace*{15pt}}\fi},, %This is used to overright the numbering rightafter the "Example" in the original frame title (which was above the text)
frametitlealignment={\ifodd\value{page} \raggedleft \else \raggedright\fi},
  • The word "Example" is not directly above the title as before, it's now beside.
  • There is no numbering on it.
  • The word "Example" does change from left/right on odd/even pages.
  • The word "Example" gets correctly positioned even when the mdframed spread across pagebreak.

Note how the example environment still uses the frametitle with numbering above the text, unlike the style=example. Additional tuning might be required to change text color/font or box it, etc.

Full code:

\documentclass[12pt,twoside]{book}
    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage{lipsum}
    \usepackage{showframe}

\usepackage[framemethod=tikz]{mdframed}
\usetikzlibrary{calc, positioning, shapes.geometric}

\tikzset{
    node distance= 0mm and 3mm,
ws/.style={align=#1,
           font=\large\bfseries\sffamily, 
           draw, thin, fill=white,
           overlay,
           }
        }

\makeatletter
\mdfdefinestyle{example}%
{%
    hidealllines=true, 
    skipabove=2\baselineskip, skipbelow=-1ex,
    innertopmargin=0pt, innerbottommargin=0pt,%
    middlelinewidth=5pt, linecolor=red,%
    fontcolor=teal, font=\small\sffamily,%
    frametitle={\ifodd\value{page} \rlap{\hspace*{15pt} Example}  \else \llap{Example \hspace*{15pt}}\fi},, %This is used to overright the numbering rightafter the "Example" in the original frame title (which was above the text)
    frametitlealignment={\ifodd\value{page} \raggedleft \else \raggedright\fi},
%
%
settings={%\global\refstepcounter{example}
        \ifodd\value{page}
    \boolfalse{mdf@leftline}
    \booltrue{mdf@rightline}
        \else
    \booltrue{mdf@leftline}
    \boolfalse{mdf@rightline}
        \fi},
    innerrightmargin=\ifodd\value{page}0.5em\else 0.0em\fi, %rightmargin=7em,%
    innerleftmargin =\ifodd\value{page}0.0em\else 0.5em\fi, %leftmargin =7em,%
singleextra={
%        \ifodd\value{page}
%\node[ws=left,below right=of P] {Example}; %These were the numbers beside them
%        \else
%\node[ws=right,below left=of O |- P]  {Example};
%        \fi
             },%
}% end of mdfdefinestyle
\makeatother

\mdtheorem[style=example,
           ]{example}{Example}[chapter]

\mdtheorem[style=exercise,
           ]{exercise}{Exercise}[chapter]

\begin{document}
\chapter{test}

\begin{mdframed}[style=example]
    This is produced by \verb+\begin{mdframed}[style=example] ... \end{mdframed}+
\end{mdframed}
xxxxxxxxx 
\begin{example}
    This is produced by \verb+\begin{example} ... \end{example}+
\end{example}

\newpage
\lipsum[2]
\begin{mdframed}[style=example]
        \lipsum[2]
\end{mdframed}

\begin{mdframed}[style=example]
\lipsum[2]
\lipsum[2]
\lipsum[2]
\lipsum[2]

\end{mdframed}

\end{document}

Edit: After some details added I modified the code to meet:

  • Numbering after word "example"
  • Left/right according to even/odd page.
  • A "continue" text when the frame splits over another page.

To do that I used the firstextra (add "Exemple numbering" to all frames) and the secondextra (add "continue" only to first part of splited frames). Read more at secion 7 Hooks and Bools of mdframed manual. And if you wish to add a "continued from" in the last part of the splited frame check this question.

continue on the next page...

\documentclass[12pt,twoside]{book}
    \usepackage[T1]{fontenc}
    \usepackage[utf8]{inputenc}
    \usepackage{lipsum}
    \usepackage{showframe}
\usepackage[framemethod=tikz]{mdframed}
\usetikzlibrary{calc, positioning, shapes.geometric}

\tikzset{
    node distance= 0mm and 3mm,
ws/.style={align=#1,
           font=\large\bfseries\sffamily, 
           draw, thin, fill=white,
           overlay,
           }
        }
%\newcounter{example} maybe this is unnecessary
\makeatletter
\mdfdefinestyle{example}%
{%
    hidealllines=true,    
    skipabove=2\baselineskip, skipbelow=-1ex,
    innertopmargin=0pt, innerbottommargin=0pt,%
    middlelinewidth=5pt, linecolor=red,%
    fontcolor=teal, font=\small\sffamily,%
%
settings={\global\refstepcounter{example} %this was commented, it is now active
        \ifodd\value{page}
    \boolfalse{mdf@leftline}
    \booltrue{mdf@rightline}
        \else
    \booltrue{mdf@leftline}
    \boolfalse{mdf@rightline}
        \fi},
    innerrightmargin=\ifodd\value{page}0.5em\else 0.0em\fi, %rightmargin=7em,%
    innerleftmargin =\ifodd\value{page}0.0em\else 0.5em\fi, %leftmargin =7em,%
    %
singleextra={
    \ifodd\value{page}
    \node[ws=left,draw=none,below right=of P] { Example \theexample };
            \else
    \node[ws=right,draw=none,below left=of O |- P]  {Example \theexample };
            \fi
                 },%
firstextra={
\ifodd\value{page}
\node[ws=left,draw=none,below right=of P] { Example \theexample };
\node[ws=left,yshift=-2em,below right=of P] { continue \ldots };
        \else
\node[ws=right,draw=none,below left=of O |- P]  {Example \theexample };
\node[ws=right,draw=none,yshift=-2em,below left=of O |- P]  {continue \ldots };
        \fi
             },%
}% end of mdfdefinestyle
\makeatother

\mdtheorem[style=example,
           ]{example}{Example}[chapter]

\mdtheorem[style=exercise,
           ]{exercise}{Exercise}[chapter]

\begin{document}
\chapter{test}

\begin{mdframed}[style=example]
    This is produced by \verb+\begin{mdframed}[style=example] \end{mdframed}+
\end{mdframed}
xxxxxxxxx 
\begin{mdframed}[style=example]
    This is produced by \verb+\begin{mdframed}[style=example] \end{mdframed}+
\end{mdframed}
\newpage
\lipsum[2]
\begin{mdframed}[style=example]
        \lipsum[2]
\end{mdframed}

\begin{mdframed}[style=example]
\lipsum[2]
\lipsum[2]
\lipsum[2]
\lipsum[2]
\end{mdframed}
\end{document}
Related Question