[Tex/LaTex] LaTeX Verbatim Source Code Beside the Typeset Output

verbatim

I am a beginner to LaTeX, and I am reading Leslie Lamport's A Document Preparation System. In various places of his book, he puts the LaTeX source code beside the output obtained by running latex on the source. Even more interestingly, in order to keep the same height for both the source codes and the output on the page, some source codes are omitted by ellipsis. I am wondering how he has made it possible to omit the right portion of the source snippets such that the verbatim source codes occupy the same height as the output.

I have googled about the various verbatim packages. But it seems that none of them can be smart enough to keep the verbatim source codes occupy the same vertical distance as the output. I am now skeptical about if there exists such packages or you have to do it manually.

EDIT
I have screen-shot an example. I wonder if the author manually did the verbatim part or there is a package that can substitute the text with ellipsis when you require the height of the verbatim text (on the right of the example) to be the same as the real output (on the left of the example).
enter image description here

Best Answer

Here is an adaptation of Herbert's solution. The macro \DisplayAsLdots{} is used to wrap the contents of the source code which you want replaced with .... It uses \immediate\write18 to pre-processes the \jobname.vrb file through a sed script (thanks to David Carlisle and egreg) to produce the source code displayed on the right:

enter image description here

Notes:

  • This will only work on a Unix OS.
  • As Stephen Lehmke pointed out, there can not be any line breaks within the \DisplayAsLdots{} macro.
  • Since sed is greedy it will effectively gobble any other macros (and any content in between) that begin and end on the same line. So, code such as:

    \DisplayAsLdots{foo} xyz \label{bar}
    

    will be treated as if were (note where the parameter to \DisplayAsLdots ends):

    \DisplayAsLdots{foo xyz \label{bar}}
    

Further Enhancements:

  • Adapt to work on non-unix operating systems (perhaps a pure LaTeX solution that does not require temporary files).
  • Use \ldots instead of three periods.
  • Enhance the regular expression for sed to allow for line breaks in \DisplayAsLdots, and terminate the replacement with the proper matching closing brace (to fix 3rd point in Notes section above).

Comment on this Presentation Style:

As mentioned in the comments, I really dislike this method of presentation. This stems from the fact that this documentation appears as if it is intended to illustrate how to use itemize lists to novice users -- My feeling is that anything that could possibly distract the reader should be minimized. In this example there are two issues that come to mind:

  • The use of the . . . (and the associated missing text).
  • The fact that there is an alignment between the input and the output.

With LaTeX there really is no such thing as a line by line comparison with the input and the output, so to show an example where things appear to be aligned will require additional work from the reader to comprehend.

I would rather see the full input text and output so I can see the correspondence between the input and the output.

Keep in mind that this is just personal opinion, others might prefer this style.

Code:

\documentclass{article}
\usepackage{enumitem}
\usepackage{blindtext}
\usepackage{fancyvrb}
\usepackage{listings}

\setlist[itemize]{leftmargin=*}%

\newcommand*{\DisplayAsLdots}[1]{#1}%

\newlength\CodeWidth
\makeatletter
\newenvironment{ShowCode}[2][]
  {\lstset{#1}\VerbatimEnvironment%
   \global\CodeWidth=#2%
   \begin{VerbatimOut}{\jobname.vrb}}
  {\end{VerbatimOut}\settowidth\@tempdima{\lstinputlisting{\jobname.vrb}}%
   \ReplaceDisplayedLdots%
   \noindent%
   \minipage[t]{\CodeWidth}\vspace{0pt}\input{\jobname.vrb}\endminipage\hfill%
   \minipage[t]{\dimexpr\@tempdima-2\fboxsep-2\fboxrule\relax}
     \vspace{0pt}\lstinputlisting{\jobname.vrb.new}\endminipage}

\newcommand{\ReplaceDisplayedLdots}{%
    \immediate\write18{%
          cat \jobname.vrb%
        | sed -e 's|\string\\DisplayAsLdots{.*}|...|'%
        > ./\jobname.vrb.new%
    }%
}%
\makeatother


\begin{document}
\blindtext

\begin{ShowCode}[language={[LaTeX]TeX},frame=single,columns=fixed,
   basicstyle=\small\ttfamily,breaklines,
   keywordstyle=\bfseries,
]{0.50\linewidth}
\begin{itemize}
\item Each list is \DisplayAsLdots{marked with a \emph{label}.  The labels in this itemized list are}  bullets.
\item List can be \DisplayAsLdots{nested within} one another.
\begin{enumerate}
   \item The item labels \DisplayAsLdots{in an enumerated list are numberals or} letters.
   \item A list should \DisplayAsLdots{have at least} two items.
\end{enumerate}
\LaTeX\ permits at least four levels \DisplayAsLdots{of nested lists, which is} more than enough.

\item Blank lines \DisplayAsLdots{before an item} have no effect.
\end{itemize}
\end{ShowCode}
\end{document}
Related Question