Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Is it possible to get a (breakable) frame like this with mdframed? Or as a more general question. Can one access the coordinates of the frame that is drawn with TikZ?

desired result

With a pagebreak in it:
page 1
page 2

I build this example with the following code.

\documentclass{scrartcl}

\usepackage{environ}

\usepackage{tikz}
\usetikzlibrary{calc}

\NewEnviron{excursustikz}{%
   \par
   \vspace{0.5\baselineskip}%
   \noindent
   \begin{tikzpicture}%
      \node (body) [%
         text width=\textwidth-4pt-2ex,
         inner sep=0pt,
      ] {\BODY};
      \draw [
         line width=4pt,
         blue,
         line cap=round,
         rounded corners=2ex,
         ->
      ] ($(body.south west)+(5em,-2ex)$) -| ($(body.west)+(-2ex,0)$) |- %
        ($(body.north)+(-12em,2ex)$) .. controls +(0:10em) and +(190:5em) .. ++(20em,2ex);
      \node [blue,fill=white] at ($(body.north west)+(3.5em,2.36ex)$) {\sffamily\bfseries Excursus};
   \end{tikzpicture}%^
   \par
   \vspace{0.25\baselineskip}%
}

\usepackage{lipsum}

\begin{document}
\lipsum[1]
\begin{excursustikz}
   \lipsum[2]
\end{excursustikz}
\lipsum[3]
\end{document}

The node that I imagine to use is body, but I’m not sure if mdframed uses a node internally. Furthermore one has to care about a page spanning frame. In that case the line at the right should be broken, as if you cut the path in two parts.

share|improve this question
    
Your solutions seem to produce good results. I was going to suggest using \tikzmark, but handing the page crossing boundary is a bit more difficult. –  Peter Grill Mar 10 '12 at 17:57
    
@PeterGrill: This is the reason why I asked to “hack in” mdframed which handles the breaks very well and uses (can use) TikZ to draw the frames –  Tobi Mar 10 '12 at 18:24
    
mdframed knows how to break text when it encounters a page boundary, but not how to place material on a page before the start of an mdframed, which is the case you point out where the frame begins on a subsequent page. If you are only interested in the case where the mdframed begins on the same page as the text you want to point to, but that the text box can span pages, that is different. –  Peter Grill Mar 10 '12 at 18:28
    
@PeterGrill: Im not sure sure if I understand you right … I added two images showing the desired frame if it’s. So what I want to do is replace the top line by an arrow with the text and the bottom line should not span the whole line width. –  Tobi Mar 10 '12 at 18:44
    
@Tobi: What you want is perfectly possible. You can use mdframed for the computing and the lines can be drawn by the predefined coordinates O and P. For the settings in mdframed.sty I recommend topline=true,leftline=true,bottomline=true,rightline=false. –  Marco Daniel Mar 10 '12 at 19:48
show 4 more comments

1 Answer

up vote 8 down vote accepted

Update: To let mdframed know the right dimensions of the frame to calculate the page breaks we must give them as invisible margins (middleline) and adjust everything according to these. See the updated code below.


Marco’s comment lead me to the relevant parts in the manual. Here is my code

\documentclass{scrartcl}

\usepackage{tikz}
   \usetikzlibrary{calc,arrows}
\usepackage{etoolbox}
\usepackage[framemethod=tikz]{mdframed}

\tikzstyle{excursus arrow}=[%
   line width=4pt,
   draw=blue,
   rounded corners=2ex
]
\tikzstyle{excursus head}=[%
   fill=white,
   font={\bfseries\sffamily},
   text=blue,
   anchor=base,
]

\makeatletter
\newcommand{\drawexcursusarrow}{%
   \patchcmd{\mdf@putbox@single}{\mdfcreateextratikz}{
      \path let \p1=(P), \p2=(O) in (\x2,\y1) coordinate (Q);
      \path let \p1=(Q), \p2=(O) in (\x1,{(\y1-\y2)/2}) coordinate (M);
      \path [excursus arrow, round cap->]
         ($(O)+(5em,0ex)$) -| (M) |- %
         ($(Q)+(6em,0ex)$) .. controls +(0:16em) and +(185:6em) .. %
         ++(23em,2ex);
      \node [excursus head] at ($(Q)+(4.5em,-2pt)$) {Excursus};
   }{}{}%
   \patchcmd{\mdf@putbox@first}{\mdfcreateextratikz}{
      \path let \p1=(P), \p2=(O) in (\x2,\y1) coordinate (Q);
      \path [excursus arrow,->]
         (O) |- %
         ($(Q)+(6em,0ex)$) .. controls +(0:16em) and +(185:6em) .. %
         ++(23em,2ex);
      \node [excursus head] at ($(Q)+(4.5em,-2pt)$) {Excursus};
   }{}{}%
   \patchcmd{\mdf@putbox@second}{\mdfcreateextratikz}{
      \path let \p1=(P), \p2=(O) in (\x2,\y1) coordinate (Q);
      \path [excursus arrow,round cap-]
         ($(O)+(5em,0ex)$) -| (Q);
   }{}{}%
   \patchcmd{\mdf@putbox@middle}{\mdfcreateextratikz}{
      \path let \p1=(P), \p2=(O) in (\x2,\y1) coordinate (Q);
      \path [excursus arrow]
         (O) -- (Q);
   }{}{}%
}
\makeatother
\newmdenv[%
   middlelinewidth=24pt,
   middlelinecolor=green,
   rightline=false,
   innertopmargin=0ex,
   innerbottommargin=0ex,
   innerrightmargin=2pt,
   innerleftmargin=0ex,
   leftmargin=-11pt,
   skipabove=12pt,
   skipbelow=-1pt,%=12-24/2-2/2
   settings=\drawexcursusarrow,
]{excursus}

\usepackage{lipsum}

\begin{document}
\lipsum[3]
\begin{excursus}
   \lipsum[1]
\end{excursus}
\lipsum[3]
\end{document}

I used \pathcmd to differentiate between the broken and unbroken frames. Furthermore I draw the arrow with \drawexcursusarrow and apply this via the settings key only to the {excursus} environment, so my changes don’t effect the other frames.


Bonus question

is it possible to let mdframed ignore the descenders of the last line in the frame? Otherwise the (optical) innerbottomsep depends on these.

share|improve this answer
    
Nice one. You can define a command patchframes and execute it at the option settings ;-) –  Marco Daniel Mar 10 '12 at 23:33
    
@MarcoDaniel: Did it while you write the comment :-) and I added a bonus question, but maybe I should post this as a new question (?) –  Tobi Mar 10 '12 at 23:37
    
I can't understand the intention of your bonus question. –  Marco Daniel Mar 10 '12 at 23:45
    
I’ll post it as a fresh question an try to make it clear :-) –  Tobi Mar 10 '12 at 23:57
    
@MarcoDaniel: Here it is … –  Tobi Mar 11 '12 at 0:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.