9

I want to number the lines in a mdframed environment with the line numbers appearing on the left of the frame, outside of it.

\documentclass{article}
\usepackage[framemethod=latex]{mdframed}

\newdimen\linenumbersep

\newcommand{\linenumber}[1]{%
  \linenumbersep 4pt%
  \advance\linenumbersep\mdflength{innerleftmargin}%
  \advance\linenumbersep\mdflength{innerlinewidth}%
  \advance\linenumbersep\mdflength{middlelinewidth}%
  \advance\linenumbersep\mdflength{outerlinewidth}%
  \advance\linenumbersep\mdflength{linewidth}%
  \makebox[0pt][r]{{\rmfamily\tiny#1}\hspace*{\linenumbersep}}}

\begin{document}

\ttfamily

\begin{mdframed}
\linenumber{1}(define fact\\
\linenumber{2}  (lambda (n)\\
\linenumber{3}  (if (= n 0)\\
\linenumber{4}  1\\
\linenumber{5}  (* n (fact (- n 1))))))
\end{mdframed}

\end{document}

After typesetting this document, I get

enter image description here

as expected. But when the tikz method is used for drawing the frame by changing the second line of the source document

\usepackage[framemethod=tikz]{mdframed}

the line numbers are not visible anymore, giving

enter image description here

Is it possible to make this example work with the tikz method?

I want to use something like this in a package I am writing to typeset a program listing with the help of Pygments. The line numbers would be generated automatically.

Ulrike Fischer
  • 327,261
Romildo
  • 4,093

1 Answers1

8

mdframed clips the box at the frame. But I don't know if it intended or a bug.

Edit 2017:

The problem seems to have been resolved. The patch it no longer needed.

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


\newdimen\linenumbersep

\newcommand{\linenumber}[1]{%
  \linenumbersep 4pt%
  \advance\linenumbersep\mdflength{innerleftmargin}%
  \advance\linenumbersep\mdflength{innerlinewidth}%
  \advance\linenumbersep\mdflength{middlelinewidth}%
  \advance\linenumbersep\mdflength{outerlinewidth}%
  \advance\linenumbersep\mdflength{linewidth}%
  \makebox[0pt][r]{{\rmfamily\tiny#1}\hspace*{\linenumbersep}}}

\begin{document}

\ttfamily


\begin{mdframed}
\linenumber{1}(define fact\\
\linenumber{2}  (lambda (n)\\
\linenumber{3}  (if (= n 0)\\
\linenumber{4}  1\\
\linenumber{5}  (* n (fact (- n 1))))))
\end{mdframed}

\makeatletter
\renewrobustcmd*\mdf@tikzbox@tfl[1]{%three or four borders
    \path(0,0)rectangle(\mdfboundingboxwidth,\mdfboundingboxheight);% replace \clip by \path
    \begin{scope}[mdfcorners]%
       \clip[preaction=mdfouterline]%
            [postaction=mdfbackground]%
            [postaction=mdfinnerline]#1;%
    \end{scope}%
    \path[mdfmiddleline,mdfcorners]#1;
  }%

\begin{mdframed}
\linenumber{1}(define fact\\
\linenumber{2}  (lambda (n)\\
\linenumber{3}  (if (= n 0)\\
\linenumber{4}  1\\
\linenumber{5}  (* n (fact (- n 1))))))
\end{mdframed}    

\end{document}

code output

Ulrike Fischer
  • 327,261
  • @percusse: If you mean that you get an error like this ! Package babel Error: You haven't loaded the option ngerman yet. ignore it. It will disappear at the next compilation. – Ulrike Fischer Feb 14 '12 at 14:43
  • @UlrikeFischer: It isn't a bug. It was the only way to allow three lines. – Marco Daniel Feb 14 '12 at 16:30
  • @MarcoDaniel: Does that mean that numbering the lines in this way (so that they appear outside of the frame) and having a three lines frame at the same time is not possible with the tikz method? With the postscript method it works. – Romildo Feb 14 '12 at 16:41
  • @Romildo: Ulrikes shows you a way ;-) I have to test some other solutions. – Marco Daniel Feb 14 '12 at 18:41