41

I presume Drew Neil (of Vimcasts.org fame) used some TeX typesetting engine (XeLaTeX?) to typeset his excellent book, Practical Vim. See a screenshot below.

I really like the way his "tip boxes" stand out of the main text and catch the reader's attention, without being too flashy or "in-your-face". What package(s) do you think he used to produce those fancy boxes (the "Tip 2" bit, in particular)? The mdframed package doesn't seem to offer that level of customisation. The tcolorbox package is a more likely candidate, but I didn't spot any box similar to that shown below in the manual...

How do you think the author generated those boxes?

enter image description here

doncherry
  • 54,637
jub0bs
  • 58,916

1 Answers1

58

Both mdframed and tcolorbox are powerful and offer highly customizable boxes; below I show some options to achieve the desired box using each of those packages.

Since both packages offer the possibility of designing the frames from scratch and an easy system of predefined coordinates, the possibilities are endless.

For each package I will show two versions: one better suited for the case in which the box doesn't contain page breaks and the other one, for the case in which page breaks can occur inside the box.

First, let's consider an option using tcolorbox and appropriate if no page breaks occur inside the box:

\documentclass{article}
\usepackage[many]{tcolorbox}
\usepackage{lipsum}

\newtcolorbox[auto counter]{mybox}{
freelance,
colback=white,
frame code={},
interior titled code={
  \fill[rounded corners=8pt,gray!30]
    (title.south west) --
    (title.south) -- 
    ([yshift=20pt]title.south) --
    ([yshift=20pt,xshift=4cm]title.south) --
    ([xshift=4cm]title.south) --
    (title.south east) {[sharp corners] --
    ([yshift=-6pt]title.south east) -- 
    ([yshift=-6pt]title.south west) } -- cycle;
  \draw[rounded corners=8pt,gray,line width=1pt]
    (title.west|-frame.south west) --
    (title.south west) --
    (title.south) -- 
    ([yshift=20pt]title.south) --
    ([yshift=20pt,xshift=4cm]title.south) --
    ([xshift=4cm]title.south) --
    (title.south east) --
    (title.east|-frame.south east) --
    cycle;
  \node at ([xshift=2cm,yshift=4pt,anchor=south]title.south) 
    {\sffamily\Large Tip~\thetcbcounter};  
  },
title={\mbox{}},
top=12pt,
fontupper=\sffamily\Large,
oversize=0.5cm,
before={\vskip24pt\par\noindent},
after={\par\vskip12pt}
}

\begin{document}

\lipsum[2]
\begin{mybox}
Don't Repeat Yourself
\end{mybox}
\lipsum[2]
\begin{mybox}
Don't Repeat Yourself
\end{mybox}

\end{document}

enter image description here

Now, the version allowing page breaks:

\documentclass{article}
\usepackage[many]{tcolorbox}
\usepackage{lipsum}

\newtcolorbox[auto counter]{mybox}{
breakable,
freelance,
colback=white,
frame code={},
overlay unbroken={
  \fill[rounded corners=8pt,gray!30]
    (title.south west) --
    (title.south) -- 
    ([yshift=20pt]title.south) --
    ([yshift=20pt,xshift=4cm]title.south) --
    ([xshift=4cm]title.south) --
    (title.south east) {[sharp corners] --
    ([yshift=-6pt]title.south east) -- 
    ([yshift=-6pt]title.south west) } -- cycle;
  \draw[rounded corners=8pt,gray,line width=1pt]
    (title.west|-frame.south west) --
    (title.south west) --
    (title.south) -- 
    ([yshift=20pt]title.south) --
    ([yshift=20pt,xshift=4cm]title.south) --
    ([xshift=4cm]title.south) --
    (title.south east) --
    (title.east|-frame.south east) --
    cycle;
  \node at ([xshift=2cm,yshift=4pt,font=]title.south) 
    {\sffamily\Large Tip~\thetcbcounter};  
    }, 
overlay first={
  \fill[rounded corners=8pt,gray!30]
    (title.south west) --
    (title.south) -- 
    ([yshift=20pt]title.south) --
    ([yshift=20pt,xshift=4cm]title.south) --
    ([xshift=4cm]title.south) --
    (title.south east) {[sharp corners] --
    ([yshift=-6pt]title.south east) -- 
    ([yshift=-6pt]title.south west) } -- cycle;
    \draw[rounded corners=8pt,gray,line width=1pt]
    (title.west|-frame.south) --
    (title.south west) --
    (title.south) -- 
    ([yshift=20pt]title.south) --
    ([yshift=20pt,xshift=4cm]title.south) --
    ([xshift=4cm]title.south) --
    (title.south east) --
    (title.south east|-frame.south);
  \node at ([xshift=2cm,yshift=4pt,font=]title.south) 
    {\sffamily\Large Tip~\thetcbcounter};  
  },
overlay middle={
  \draw[rounded corners=8pt,gray,line width=1pt]
    (title.west|-frame.south) --
    (title.west|-frame.north);
  \draw[rounded corners=8pt,gray,line width=1pt]
    (title.east|-frame.south) --
    (title.east|-frame.north);
  },
overlay last={
  \draw[rounded corners=8pt,gray,line width=1pt]
    (title.west|-frame.north) --
    (title.west|-frame.south) --
    (title.east|-frame.south) --
    (title.east|-frame.north);
  },
title={\mbox{}},
top=12pt,
fontupper=\sffamily\Large,
oversize=0.5cm,
before={\vskip28pt\par\noindent},
after={\par\vskip12pt},
}

\begin{document}

\lipsum[2]
\begin{mybox}
\lipsum[4-6]
\end{mybox}
\lipsum[2]

\end{document}

enter image description here

And using mdframed; first a version suitable for no page breaks (if a page break occurs using this version, the box breaks, but no frame is drawn). The version for page breaks can be found below at the end of this answer.

\documentclass{article}
\usepackage[framemethod=tikz]{mdframed}
\usetikzlibrary{calc}
\usepackage{lipsum}

\newcounter{tip}

\newmdenv[
hidealllines=true,
innertopmargin=14pt,
innerbottommargin=8pt,
skipabove=10pt,
font=\sffamily\Large,
leftmargin=-0.5cm,
rightmargin=-0.5cm,
singleextra={
  \coordinate (aux) at ( $ (O)!0.5!(P) $ );
  \fill[rounded corners=8pt,line width=1pt,gray!30]
    (O|-P) -- 
    (aux|-P) --
    ([yshift=20pt]aux|-P) --
    ([yshift=20pt,xshift=4cm]aux|-P) --
    ([xshift=4cm]aux|-P) -- 
    (P) {[sharp corners] --
    ([yshift=-6pt]P) -- 
    ([yshift=-6pt]O|-P) } -- cycle;
  \draw[rounded corners=8pt,line width=1pt,gray]
    (O|-P) -- 
    (aux|-P) --
    ([yshift=20pt]aux|-P) --
    ([yshift=20pt,xshift=4cm]aux|-P) --
    ([xshift=4cm]aux|-P) -- 
    (P) --
    (P|-O) --
    (O) -- cycle;
  \node at ([xshift=2cm,yshift=6pt]aux|-P)
    {\refstepcounter{tip}\sffamily\Large Tip~\thetip} ; 
  },
]{mybox}

\begin{document}

\lipsum[2]
\begin{mybox}
Don't Repeat Yourself
\end{mybox}
\lipsum[2]
\begin{mybox}
Don't Repeat Yourself
\end{mybox}

\end{document}

enter image description here

Here's the an option using mdframed for the case in which page breaks might occur inside the box:

\documentclass{article}
\usepackage[framemethod=tikz]{mdframed}
\usetikzlibrary{calc}
\usepackage{lipsum}

\newcounter{tip}

\newmdenv[
hidealllines=true,
innertopmargin=16pt,
innerbottommargin=10pt,
font=\sffamily\Large,
leftmargin=-0.5cm,
rightmargin=-0.5cm,
skipabove=35pt,
skipbelow=15pt,
singleextra={
  \coordinate (aux) at ( $ (O)!0.5!(P) $ );
  \fill[rounded corners=8pt,line width=1pt,gray!30]
    (O|-P) -- 
    (aux|-P) --
    ([yshift=20pt]aux|-P) --
    ([yshift=20pt,xshift=4cm]aux|-P) --
    ([xshift=4cm]aux|-P) -- 
    (P) {[sharp corners] --
    ([yshift=-6pt]P) -- 
    ([yshift=-6pt]O|-P) } -- cycle;
  \draw[rounded corners=8pt,line width=1pt,gray]
    (O|-P) -- 
    (aux|-P) --
    ([yshift=20pt]aux|-P) --
    ([yshift=20pt,xshift=4cm]aux|-P) --
    ([xshift=4cm]aux|-P) -- 
    (P) --
    (P|-O) --
    (O) -- cycle;
  \node at ([xshift=2cm,yshift=6pt]aux|-P)
    {\refstepcounter{tip}\sffamily\Large Tip~\thetip} ; 
  },
firstextra={
  \coordinate (aux) at ( $ (O)!0.5!(P|-O) $ );
  \fill[rounded corners=8pt,line width=1pt,gray!30,overlay]
    (O|-P) -- 
    (aux|-P) --
    ([yshift=20pt]aux|-P) --
    ([yshift=20pt,xshift=4cm]aux|-P) --
    ([xshift=4cm]aux|-P) -- 
    (P) {[sharp corners] --
    ([yshift=-6pt]P) -- 
    ([yshift=-6pt]O|-P) } -- cycle;
  \draw[rounded corners=8pt,line width=1pt,gray,overlay]
    (O) --
    (O|-P) -- 
    (aux|-P) --
    ([yshift=20pt]aux|-P) --
    ([yshift=20pt,xshift=4cm]aux|-P) --
    ([xshift=4cm]aux|-P) -- 
    (P) --
    (P|-O);
  \node[overlay] at ([xshift=2cm,yshift=6pt]aux|-P)
    {\refstepcounter{tip}\sffamily\Large Tip~\thetip} ; 
  },
middleextra={
  \draw[rounded corners=8pt,line width=1pt,gray,overlay]
    (O|-P) -- 
    (O);
  \draw[rounded corners=8pt,line width=1pt,gray,overlay]
    (P) -- 
    (P|-O);
  },
secondextra={
  \coordinate (aux) at ( $ (O)!0.5!(P|-O) $ );
  \draw[rounded corners=8pt,line width=1pt,gray,overlay]
    (O|-P) -- 
    (O) --
    (P|-O) --
    (P);
  },
]{mybox}

\begin{document}

\lipsum[2]
\begin{mybox}
\lipsum[4-6]
\end{mybox}
\lipsum[2]

\end{document}

enter image description here

Gonzalo Medina
  • 505,128
  • 2
    That's excellent, Gonzalo. Note, however, that the vertical spacing above such a box is insufficient: try \begin{mybox}Don't repeat yourself!\end{mybox}\begin{mybox}Don't repeat yourself!\end{mybox}. – jub0bs Apr 17 '14 at 02:03
  • 1
    @Jubobs I'll add some improvements in the few minutes. I am designing now the solution with mdframed. – Gonzalo Medina Apr 17 '14 at 02:09
  • 1
    No rush! Take your time :) – jub0bs Apr 17 '14 at 02:10
  • @Jubobs all options added; perhaps some simplifications and improvements are still admissible; I'll review the code in the morning (bed time here). – Gonzalo Medina Apr 17 '14 at 04:29
  • Such a complete answer! I wasn't even asking for a complete solution, just general directions (I'm not familiar with either package). Thanks a lot. – jub0bs Apr 17 '14 at 13:05
  • @Jubobs You're welcome. I introduced some minor modifications to the code. – Gonzalo Medina Apr 17 '14 at 15:11
  • 20
    +1 for having two "Don't Repeat Yourself" boxes. – wchargin Apr 17 '14 at 16:11
  • Please one question: How can i limit the size of this tip to be for example 0.75% of the page width – Dr Adel Apr 24 '14 at 02:58
  • @DrAdel Which of the versions, the one with mdframed or the one with tcolorbox? Perhaps you meant 75% and not 0.75%? – Gonzalo Medina Apr 24 '14 at 03:21
  • @DrAdel for the tcolorbox version, change oversize=-0.5cm to oversize=-0.25\textwidth. For the mdframed change the values for leftmargin and rightmargin to 0.125\textwidth. – Gonzalo Medina Apr 24 '14 at 04:03
  • @GonzaloMedina Beautiful. Is it easy to enlarge the margins (leftmargin=... & rightmargin=...) for a certain instance of the Tip, but not for all others in the counted sequence? – O0123 Apr 19 '16 at 09:54