From 50df8d67f3b81cc8b2fc0650757e6b44cec633ff Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 24 Jul 2011 23:41:00 +0000 Subject: new latex package jvlisting (22jul11) git-svn-id: svn://tug.org/texlive/trunk@23211 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/latex/jvlisting/jvlisting.dtx | 605 +++++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100644 Master/texmf-dist/source/latex/jvlisting/jvlisting.dtx (limited to 'Master/texmf-dist/source/latex/jvlisting/jvlisting.dtx') diff --git a/Master/texmf-dist/source/latex/jvlisting/jvlisting.dtx b/Master/texmf-dist/source/latex/jvlisting/jvlisting.dtx new file mode 100644 index 00000000000..3796931f94c --- /dev/null +++ b/Master/texmf-dist/source/latex/jvlisting/jvlisting.dtx @@ -0,0 +1,605 @@ +% \iffalse +% jvlisting.dtx - docstrip archive for the jvlisting macro package +% +% Copyright (C) 2011 Jochen Voss +% +% This work may be distributed and/or modified under the conditions of +% the LaTeX Project Public License, either version 1.3 of this license +% or (at your option) any later version. The latest version of this +% license is in +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.3 or later is part of all distributions of LaTeX version +% 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained' and the current +% Maintainer of this work is Jochen Voss . +% +% This work consists of the files jvlisting.dtx and the derived files +% jvlisting.sty, jvlisting.ins and examples.tex. +%<*driver> +\documentclass{ltxdoc} +\usepackage[text={6in,9in},centering]{geometry} +\usepackage{hyperref} +\usepackage{jvlisting} +\setlength{\parskip}{0pt plus.5ex} +\setlength{\listingskipamount}{.6ex plus.5ex minus.1ex} +\PageIndex +\NewListingEnvironment{xlist}{0}{\prelistingskip}% + {\listingfont\small\renewcommand{\baselinestretch}{0.95}}% + {\ListingTypesetLine}{\postlistingskip} +\begin{document} +\DocInput{jvlisting.dtx} +\end{document} +% +%<*examples> + +\documentclass{article} + +\usepackage[text={6in,9in},centering]{geometry} +\usepackage{jvlisting} +\setlength{\listingskipamount}{2\baselineskip} + +\begin{document} +% +%<*usage> +% \fi +\GetFileInfo{jvlisting.sty} +\title{The \textsf{jvlisting} package} +\date{\filedate\ \fileversion} +\author{Jochen Voss\\ \texttt{voss@seehuhn.de}\\ \texttt{http://seehuhn.de/}} +\maketitle + +\begin{abstract} + This package provides the \LaTeX\ environment \verb|listing|, an + alternative to the built-in \verb|verbatim| environment. The + \verb|listing| environment is specially taylored for including + listings of computer program source code into documents. The main + advantages over the original \verb|verbatim| environment are that + \verb|listing| environments automatically fix leading white-space + so that the environment and program listing can be indented with + the rest of the \LaTeX\ source code and that \verb|listing| + environments can easily be customised and extended. +\end{abstract} + +\tableofcontents + +\section{Basic Usage} + +The \verb|listing| environment allows to include source code of +computer programs in \LaTeX\ documents by including the code between +\verb|\begin{listing}| and \verb|\end{listing}|. + +\medskip + +\textbf{Example.} In order to typeset the listing of a simple Python +function (computing the cumulative sum of a list) you can use the +following code in your \LaTeX\ document. +\begin{xlist} + \begin{listing} + def cumsum(iterable): + return reduce(lambda res, x: res+[res[-1]+x], iterable, [0])[1:] + \end{listing} +\end{xlist} +\noindent +These commands result in the following output: +% \iffalse +% +%<*examples|usage> +% \fi + +\begin{listing} + def cumsum(iterable): + return reduce(lambda res, x: res+[res[-1]+x], iterable, [0])[1:] +\end{listing} +% \iffalse +% +%<*usage> +% \fi + +\medbreak + +Differently from the \LaTeX\ \verb|verbatim| environment, the +\verb|listing| environment can be indented to match the surrounding +document source. The following will work as expected: +\begin{xlist} + \begin{figure}[h] + \begin{listing} + def cumsum(iterable): + return reduce(lambda res, x: res+[res[-1]+x], iterable, [0])[1:] + \end{listing} + \end{figure} +\end{xlist} +\noindent +The Python code will be typeset using the same indentation as in the +example above, despite the fact that they have different indentation +in the \LaTeX\ source code. + +To make it easier to copy real program source code directly into your +\LaTeX\ file, the code in listings can be indented by TAB characters +instead of spaces. The TAB spacing is assumed to be 8 character +columns. + +In addition to the \LaTeX\ environment described above, there is also +a command \verb|\filelisting| to typeset source code contained in a +file. The command takes one argument, the name of the file to +include, and behaves very similar to the the \verb|verbatim| +environment. + +\medskip + +\textbf{Example.} In order to typeset the contents of a file +\verb|cumsum.py|, we could use the following command. +\begin{xlist} + \filelisting{cumsum.py} +\end{xlist} + +\bigbreak + +There are various parameters to customise how listings are typeset. +These parameters apply both to the \verb|verbatim| environment and to +the \verb|\filelisting| command. +\begin{itemize} +\item The amount of space inserted before and after a listing is + given by \verb|\listingskipamount|. The default value is + \verb|1ex|. Commands like the following can be used to adjust the + amount of space. + \begin{xlist} + \setlength{\listingskipamount}{1\baselineskip} + \end{xlist} +\item The indentation of the left margin of the typeset code is + determined by \verb|\listingindent|. The default value is + \verb|2em|. Commands like the following can be used to adjust + indentation. + \begin{xlist} + \setlength{\listingindent}{2cm} + \end{xlist} +\item The font used in the listing is controlled by the macro + \verb|\listingfont|. The default value is \verb|\normallistingfont| + which sets up a typewriter-like font. Example: The following + command can be used to obtain more compact listings by slightly + reducing the fontsize and the line spacing. + \begin{xlist} + \renewcommand{\listingfont}% + {\normallistingfont\small\renewcommand{\baselinestretch}{0.95}} + \end{xlist} +\item The penalty for page breaks inside a listing is given by + \verb|\listingpenalty|. The higher this value, the less attractive + page breaks inside the listing are to \LaTeX's page breaking + algorithm. The default value is 500. The following command can be + used to completely disable page breaks inside listings. + \begin{xlist} + \listingpenalty=10000 + \end{xlist} +\item The penalty for page breaks just before or after a listing is + given by \verb|\prelistingpenalty| (default value 100) and + \verb|\postlistingpenalty| (default value -50), respectively. +\end{itemize} + +\section{Extending the \textsf{listing} Environment} + +New \verb|listing|-like environments can be defined using the +\verb|\NewListingEnvironment| macro. This macro takes six arguments +and uses them to define a new \LaTeX\ environment. The arguments, in +order, are +\begin{enumerate} +\item The name of the new environment. +\item The number of extra arguments for the new environment + (normally~0). These extra arguments of the environment, if any, are + substituted into the initialisation commands (\textit{i.e.}\ into + the fourth argument of \verb|\NewListingEnvironment|); see the + \verb|copylisting| environment, below, for an example. +\item Commands to execute before the environment is entered + (\textit{e.g.}\ to add vertical whitespace). +\item Initialisation commands, executed inside the environment + (\textit{e.g.}\ font/margin setup). +\item The name of a macro (receiving one argument) which will be used + to typeset each line of input. +\item Commands to execute after the environment is completed. +\end{enumerate} + +\medskip + +\textbf{Example.} The \verb|listing| environment provided by the +\verb|jvlisting| package is defined using the following commands: +% \iffalse +% +%<*listingdef|usage> +% \fi + +% \begin{macrocode} +\let\listingfont=\normallistingfont +\newcommand{\ListingTypesetLine}[1]{\noindent\hskip\listingindent\strut + #1\par\penalty\listingpenalty} +\newcommand{\prelistingskip}{\endgraf\ifdim\lastskip<\listingskipamount + \removelastskip\penalty\prelistingpenalty\vskip\listingskipamount\fi} +\newcommand{\postlistingskip}{\endgraf\penalty\postlistingpenalty + \vskip\listingskipamount} +\NewListingEnvironment{listing}{0}{\prelistingskip}% + {\listingfont}{\ListingTypesetLine}{\postlistingskip} +% \end{macrocode} +% \iffalse +% +%<*usage> +% \fi + +\medbreak + +\textbf{Example.} An \verb|nlisting| environment which generates +listings with additional line numbers can be defined as follows: +% \iffalse +% +%<*examples|usage> +% \fi + +% \begin{macrocode} +\newcounter{lineno} +\newcommand{\typesetnline}[1]{\addtocounter{lineno}{1}% + \noindent\hskip\listingindent\llap{{\it\scriptsize\arabic{lineno}: }}% + \strut #1\par\penalty\listingpenalty} +\NewListingEnvironment{nlisting}{0}{\prelistingskip}% + {\setcounter{lineno}{0}\listingfont}{\typesetnline}{\postlistingskip} +% \end{macrocode} +% \iffalse +%> +%<*examples> +\begin{nlisting} + for i in [1, 2, 3]: + for j in ['a', 'b', 'c']: + print str(i)+j +\end{nlisting} +% +%<*usage> +% \fi + +\medbreak + +\textbf{Example.} The following code defines a new +\verb|copylisting| environment which does not only typeset the source +code, but also saves a copy in an external file. +% \iffalse +% +%<*examples|usage> +% \fi + +% \begin{macrocode} +\newwrite\outfile +\newcommand{\copytypeset}[1]{\immediate\write\outfile{#1}% + \ListingTypesetLine{#1}} +\NewListingEnvironment{copylisting}{1}{\prelistingskip}% + {\immediate\openout\outfile=#1\listingfont}{\copytypeset}% + {\immediate\closeout\outfile\postlistingskip} +% \end{macrocode} +% \iffalse +%> +%<*usage> +% \fi +Here we used the second argument to \verb|\NewListingEnvironment| to +indicate that the \verb|copylisting| environment should take an +additional parameter (the output file name). The new environment is +used as follows: +% \iffalse +% +%<*examples|usage> +% \fi + +% \begin{macrocode} +\begin{copylisting}{listing1.c} + #include + + int + main() + { + puts("hello, world!"); + return 0; + } +\end{copylisting} +% \end{macrocode} +% \iffalse +%> +%<*usage> +% \fi + +\section{Extending the \textsf{filelisting} Command} + +New \verb|filelisting|-like commands can be defined using the +\verb|\NewFileListingCommand| macro. This macro takes six arguments +and uses them to define a new macro. The arguments, in order, are +\begin{enumerate} +\item The name of the new command including the leading backslash. +\item The number of arguments for the new command (normally~1). These + arguments, including the first one which gives the file name, are + substituted into the third, fourth and sixth argument of + \verb|\NewFileListingCommand|); see the \verb|\prefixfilelisting| + command, below, for an example. +\item Commands to execute before the listing is started + (\textit{e.g.}\ to add vertical whitespace). +\item Initialisation commands, executed inside the scope of the + listing (\textit{e.g.}\ font/margin setup). +\item The name of a macro (receiving one argument) which will be used + to typeset each line of input. +\item Commands to execute after the listing is completed. +\end{enumerate} +The first argument of the newly defined macro always denotes the name +of the file to include. + +\medskip + +\textbf{Example.} Using the auxiliary functions for the +\verb|listing| environment, the built-in \verb|filelisting| command +can be defined as follows: +% \iffalse +% +%<*listingdef|usage> +% \fi + +% \begin{macrocode} +\NewFileListingCommand{\filelisting}{1}{\prelistingskip}% + {\listingfont}{\ListingTypesetLine}{\postlistingskip} +% \end{macrocode} +% \iffalse +% +%<*usage> +% \fi + +\medbreak + +\textbf{Example.} The following command defines a macro to read a +file and to prefix every line of the resulting listing with a given +string. +% \iffalse +% +%<*examples|usage> +% \fi + +% \begin{macrocode} +\newcommand{\pfxtypeset}[1]{\noindent\hskip\listingindent\strut + \pfx#1\par\penalty\listingpenalty} +\NewFileListingCommand{\prefixfilelisting}{2}{\prelistingskip}% + {\listingfont\def\pfx{#2}}{\pfxtypeset}{\postlistingskip} +% \end{macrocode} +% \iffalse +%> +%<*examples> +\prefixfilelisting{listing1.c}{c> } +% +%<*package> +% \fi + +% \section{Implementation} +% +% This section describes the internal implementation of the +% \verb|jvlisting| package. In order to avoid name clashes with other +% packages, the names of all internal macros defined in this package +% start with the prefix \verb|jvl@|. The following is the preamble +% for the package file. +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{jvlisting}[2011/06/27 v0.1 Formatted Program Listings] +% \end{macrocode} + +% \subsection{Processing the Lines of Input} +% +% We start by provinding a macro \verb|\jvl@iterlines| which can be +% used to iterate over all lines of input until a line containing some +% marker is found. The marker is given as the argument \verb|#1| to +% the \verb|\jvl@iterlines| macro. Each line is processed by +% appending the token \verb|\jvl@eol| (used later to recognise the end +% of line) and by prepending \verb|\jvl@dropempty| (for the first and +% last line) or \verb|\jvl@countspaces| (for all other lines). +% \begin{macrocode} +\def\jvl@iterlines#1{\obeylines + \expandafter\jvl@iterla\expandafter{#1}{\jvl@dropempty}} +{\obeylines +\gdef\jvl@iterla#1#2#3 + {\def\jvl@testmarker##1#1{}% + \expandafter\def\expandafter\w\expandafter{\jvl@testmarker#3#1}% + \ifx\w\empty% + \def\next{#2#3\jvl@eol\jvl@iterla{#1}{\jvl@countspaces}}% + \else% + \def\y##1#1##2#1{\jvl@dropempty ##1\jvl@eol\jvl@end##2}% + \def\next{\y#3#1}% + \fi\next}} +% \end{macrocode} + +% The next step in processing is to drop the first line (whatever +% comes directly after the opening \verb|begin| statement) and the +% last line (whatever comes directly after the closing \verb|end| +% statement), if they consist only of white space. +% \begin{macrocode} +\def\jvl@dropempty{\jvl@dropa{}} +\def\jvl@dropa#1#2{\ifx\jvl@eol#2% + \let\next=\relax + \else + \if#2 \def\next{\jvl@dropa{#1#2}}\else + \def\next{\jvl@countspaces #1#2}\fi + \fi\next} +% \end{macrocode} + +% Next we determine the indentation level of the current line by +% expanding TAB characters and then counting spaces. The result is +% stored in the scratch counter \verb|@tempcnta|. +% \begin{macrocode} +\def\jvl@countspaces{\@tempcnta=0\jvl@counta} +{\catcode`\^^I=12 +\gdef\jvl@counta#1{\expandafter\if\noexpand#1^^I% + \advance\@tempcnta by8\divide\@tempcnta by8\multiply\@tempcnta by8 + \let\next=\jvl@counta + \else + \expandafter\if\noexpand#1 % + \advance\@tempcnta by1 + \let\next=\jvl@counta + \else + \def\next{\jvl@fixspaces #1} + \fi + \fi\next}} +% \end{macrocode} + +% Using the value in \verb|@tempcnta|, we fix the indentation by first +% subtracting the common indentation level (stored in \verb|\jvl@idt|) +% and then inserting the required number of spaces (using +% \verb|\space|). +% \begin{macrocode} +\newcount\jvl@idt \jvl@idt=-1 +\def\jvl@fixspaces#1{\ifx\jvl@eol#1\else + \ifnum\jvl@idt<0 + \jvl@idt=\@tempcnta + \else + \ifnum\@tempcnta<\jvl@idt\jvl@idt=\@tempcnta\fi + \fi\fi\jvl@fixa#1} +\def\jvl@fixa{\ifnum\@tempcnta>\jvl@idt + \advance\@tempcnta by\m@ne + \def\next{\jvl@fixa\space}% + \else + \let\next\jvl@output + \fi\next} +% \end{macrocode} + +% Finally, by matching the \verb|jvl@eol| inserted by the +% \verb|\jvl@iterlines| function above, we can apply the output +% function \verb|\jvl@typeset| to the processed line. +% \begin{macrocode} +\def\jvl@output#1\jvl@eol{\jvl@typeset{#1}} +% \end{macrocode} +% The symbol \verb|\jvl@typeset| will be defined inside the +% \verb|\begin{listing}| command; since neested listings are not +% possible, using a global name for the output function is no +% problem. + +% \subsection{Defining Listing Environments} +% +% Given the code above, we can now define the +% \verb|\NewListingEnvironment| macro. Some care is needed when +% constructing the marker for use in the \verb|\jvl@iterlines| method, +% because the text we need to match uses category code 12 (``other'') +% for all characters. +% \begin{macrocode} +\begingroup + \catcode`|=0 \catcode`[=1 \catcode`]=2 + \catcode`\{=12 \catcode`\}=12 \catcode`\\=12 + |gdef|jvl@makemarker#1[% + |expandafter|gdef|csname jvl@@#1marker|endcsname[\end{#1}]] +|endgroup +\def\jvl@setup{\begingroup + \parskip0pt \advance\leftskip by\@totalleftmargin + \let\do\@makeother\dospecials \catcode`\^^I=12} +\def\NewListingEnvironment#1#2#3#4#5#6{\jvl@makemarker{#1}% + \expandafter\newcommand\csname #1\endcsname[#2]{#3\jvl@setup + #4\def\jvl@end{\end{#1}}\let\jvl@typeset=#5% + \expandafter\jvl@iterlines\csname jvl@@#1marker\endcsname}% + \expandafter\gdef\csname end#1\endcsname{\endgroup #6}} +% \end{macrocode} + +% \subsection{Reading Listings from File} +% +% When reading listings from a file, we get the lines terminated by +% \verb|^^M| characters. The following function is a replacement for +% \verb|\jvl@iterlines|, used to read lines from a file and to strip +% of the trailing \verb|^^M| characters: +% \begin{macrocode} +\newread\jvl@fileinput +\def\jvl@iterfile{\read\jvl@fileinput to\l + \ifeof\jvl@fileinput + \let\next\relax + \else + \expandafter\jvl@iterfa\l + \let\next\jvl@iterfile + \fi\next} +{\catcode`\^^M=12 +\gdef\jvl@iterfa#1^^M{\jvl@countspaces#1\jvl@eol}} +% \end{macrocode} +% +% In analogy to \verb|\NewListingEnvironment|, the following macro is +% used to define new functions for listing file contents. +% \begin{macrocode} +\def\NewFileListingCommand#1#2#3#4#5#6{% + \ifnum#2<1 + \PackageError{jvlisting}{% + Invalid number of arguments: `#2' + }{% + The second argument to \protect\NewFileListingCommand\space must be at + least 1. + }% + \fi + \newcommand{#1}[#2]{#3\jvl@setup\catcode`\^^M=12 + #4\let\jvl@typeset=#5% + \openin\jvl@fileinput=##1\jvl@iterfile\closein\jvl@fileinput + \endgroup #6 + } +} +% \end{macrocode} + +% \subsection{Finishing Touches} +% +% The following definitions provide default values for the +% customisable parameters of the \verb|listing| environment. +% \begin{macrocode} +\newskip\listingskipamount \listingskipamount=1ex +\newdimen\listingindent \listingindent=2em +\newcount\prelistingpenalty \prelistingpenalty=100 +\newcount\listingpenalty \listingpenalty=500 +\newcount\postlistingpenalty \postlistingpenalty=-50 +% \end{macrocode} + +% Finally, we need to define the font for use in listing environments. +% Some care is needed to avoid problems with spaces and ligatures. +% \begin{macrocode} +{\catcode`\ =\active% +\gdef\jvl@obeyspaces{\frenchspacing\catcode`\ =\active\let \space}} +{\catcode`\`=\active\gdef`{\relax\lq}} +\gdef\jvl@noligs{\catcode`\`=\active} +\def\normallistingfont{\normalfont\ttfamily + \jvl@obeyspaces\jvl@noligs\hyphenchar\font-1} +% \end{macrocode} +% \iffalse +% +%<*examples> + +\filelisting{listing1.c} + +\end{document} + +% +%<*install> +\input docstrip.tex +\keepsilent +\askforoverwritefalse + +\preamble + +Copyright (C) 2011 Jochen Voss + +This work may be distributed and/or modified under the conditions of +the LaTeX Project Public License, either version 1.3 of this license +or (at your option) any later version. The latest version of this +license is in + + http://www.latex-project.org/lppl.txt + +and version 1.3 or later is part of all distributions of LaTeX version +2005/12/01 or later. + +This work has the LPPL maintenance status `maintained' and the current +Maintainer of this work is Jochen Voss . + +This work consists of the files jvlisting.dtx and the derived files +jvlisting.sty, jvlisting.ins and examples.tex. +\endpreamble + +\generate{% + \file{jvlisting.ins}{\from{jvlisting.dtx}{install}}% + \usedir{tex/latex/jvlisting}% + \file{jvlisting.sty}{\from{jvlisting.dtx}{package}% + \from{jvlisting.dtx}{listingdef}}% + \file{examples.tex}{\from{jvlisting.dtx}{examples}}% +} +\endbatchfile +% +% \fi +% \endinput +% +% Local Variables: +% whitespace-style: (face trailing tabs lines-tail empty space-before-tab) +% whitespace-line-column: 78 +% End: -- cgit v1.2.3