From 2d4540d64b15951be359031a8a5303a28bf887cd Mon Sep 17 00:00:00 2001 From: michael Date: Tue, 18 Mar 2003 00:17:19 +0000 Subject: [PATCH] + version 1.0 of listings package --- docs/packages/listings/listings.dtx | 22214 +++++++++++++++++--------- docs/packages/listings/listings.ins | 128 +- docs/packages/listings/lstdrvrs.dtx | 4035 +++-- docs/packages/listings/lstdrvrs.ins | 108 +- docs/packages/listings/lstpatch.sty | 533 +- 5 files changed, 18800 insertions(+), 8218 deletions(-) diff --git a/docs/packages/listings/listings.dtx b/docs/packages/listings/listings.dtx index bf01c57456..d7fc2a5322 100644 --- a/docs/packages/listings/listings.dtx +++ b/docs/packages/listings/listings.dtx @@ -1,7111 +1,15103 @@ -% \iffalse -% -% NOTE: This file contains very long lines (upto approx 270 characters). -% I haven't wrapped them since I won't do that by hand and haven't -% written any program doing the work. -% -% If you want to read this .dtx file, you might get in trouble with -% such long lines! -% -% -% S O F T W A R E L I C E N S E -% ================================= -% -% The files listings.dtx and listings.ins and all files generated -% from only these two files are referred as 'the listings package' or -% simply 'the package'. A driver file is any file generated mainly from -% lstdrvrs.dtx. -% -% Copyright. -% The listings package is copyright 1996--1998 Carsten Heinz. -% The driver files are copyright 1997, 1998 or 1997--1998 any -% individual author listed in these files. -% -% Distribution. -% The listings package as well as lstdrvrs.dtx and all driver files -% are distributed freely. You are not allowed to take money for the -% distribution, except for a nominal charge for copying etc.. -% -% Use of the package. -% The listings package is free for any non-commercial use. Commercial -% use needs (i) explicit permission of the author of this package and -% (ii) the payment of a license fee. This fee is to be determined in -% each instance by the commercial user and the package author and is -% to be payed as donation to the LaTeX3 project. -% -% No warranty. -% The listings package as well as lstdrvrs.dtx and all driver files -% are distributed without any warranty, express or implied, as to -% merchantability or fitness for any particular purpose. -% -% Modification advice. -% Permission is granted to change the listings package as well as -% lstdrvrs.dtx. You are not allowed to distribute any changed version -% of the package or any changed version of lstdrvrs.dtx, neither under -% the same name nor under a different one. Tell the author of the -% package about your local changes: other users will welcome removed -% bugs, new features and additional programming languages. -% -% Contacts. -% Send comments and ideas on the package, error reports and additional -% programming languages to -% -% Carsten Heinz -% Tellweg 6 -% 42275 Wuppertal -% Germany -% -% or preferably to -% -% cheinz@gmx.de -% -% Trademarks -% appear throughout this documentation without any trademark symbol, -% so you can't assume that a name is free. There is no intention of -% infringement; the usage is to the benefit of the trademark owner. -% -% end of software license -% -%<*driver> -\documentclass{ltxdoc} - -\usepackage[doc]{listings}[1998/11/09] -\newif\iffancyvrb -\IfFileExists{fancyvrb.sty} - {\fancyvrbtrue \usepackage{fancyvrb}} - {\fancyvrbfalse} - -\EnableCrossrefs -\CodelineIndex -\OldMakeindex -\OnlyDescription - -\begin{document} - \DocInput{listings.dtx} -\end{document} -% -% \fi ^^A balance the \iffancyvrb! :-) -% \fi -% -% -% \makeatletter -%^^A -%^^A A modified `environment' environment -%^^A -%\def\aspect{^^A -% \def\SpecialMainEnvIndex##1{^^A -% \@bsphack ^^A -% \index{aspects:\levelchar{\protect\ttfamily##1}\encapchar main}^^A -% \@esphack}^^A -% \begingroup \catcode`\\12 \MakePrivateLetters ^^A -% \m@cro@ \iffalse} -%\let\endaspect\endmacro -% -%^^A -%^^A We define a sample environment. All material between -%^^A \begin{lstsample} and \end{lstsample} is executed -%^^A 'on the left side' and typeset verbatim on the right. -%^^A -%^^A The environment is *not* designed for purposes other than -%^^A this documentation. -% \lst@Environment{lstsample}[1]\is -% {\gdef\lst@sample{#1}^^A -% \lst@BeginWriteFile{listings.tmp}^^A -% \def\lst@BOLGobble##1{}}^^A to gobble each first % -% {\lst@EndWriteFile ^^A -%^^A We execute the code resp. typset it verbatim (= empty language -%^^A with \ttfamily). -% \begin{center} -% \small ^^A \lstCC@Let{`\^^M}\space ^^A -% \begin{minipage}{0.45\linewidth}^^A -% \MakePercentComment\lst@sample -% \input{listings.tmp}\MakePercentIgnore^^A -% \end{minipage} -% \qquad -% \begin{minipage}{0.45\linewidth} -% \lstset{language={},style={},basicstyle=\ttfamily,baseem=0.51}^^A -% \hbox to \linewidth{\lstbox\lstinputlisting{listings.tmp}\hss} -% \end{minipage} -% \end{center}} -% -%^^A -%^^A We redefine the appearance of part, section, ... -%^^A -%\def\@part[#1]#2{\addcontentsline{toc}{part}{#1}% -% {\parindent\z@ \raggedright \interlinepenalty\@M -% \normalfont \huge \bfseries #2\markboth{}{}\par}% -% \nobreak\vskip 3ex\@afterheading} -%\renewcommand*\l@section[2]{% -% \ifnum \c@tocdepth >\z@ -% \addpenalty\@secpenalty -% \addvspace{.25em \@plus\p@}% -% \setlength\@tempdima{1.5em}% -% \begingroup -% \parindent \z@ \rightskip \@pnumwidth -% \parfillskip -\@pnumwidth -% \leavevmode ^^A \bfseries -% \advance\leftskip\@tempdima -% \hskip -\leftskip -% #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par -% \endgroup -% \fi} -%\renewcommand*\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -%\renewcommand*\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -%\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}% -% {1.25ex \@plus1ex \@minus.2ex}% -% {-1em}% -% {\normalfont\normalsize\bfseries}} -% -%^^A -%^^A Suppress warning -%^^A -% \let\lstenv@DroppedWarning\relax -% \makeatother -% -%^^A -%^^A The following definitions come in handy soon. -%^^A There will be more in future. -%^^A -% \newcommand\lsthelper[4]{#1\ifx\empty#2\empty\typeout{^^JWarning: #1 has unknown email^^J}\else\space\texttt{<#2>}{}\fi} -% \newcommand\lstthanks[2]{#1\ifx\empty#2\empty\typeout{^^JWarning: #1 has unknown email^^J}\fi} -% \newcommand\lst{\texttt{lst}} -% \lstdefinelanguage[doc]{Pascal}{^^A -% keywords={alfa,and,array,begin,boolean,byte,case,char,const,div,^^A -% do,downto,else,end,false,file,for,function,get,goto,if,in,^^A -% integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,^^A -% procedure,put,read,readln,real,record,repeat,reset,rewrite,set,^^A -% text,then,to,true,type,unpack,until,var,while,with,write,writeln},^^A -% sensitive=false,^^A -% doublecomment={(*}{*)}{\{}{\}},^^A -% stringizer=[d]{'}}^^A -% \lstset{defaultdialect=[doc]Pascal} -% \lstset{language=Pascal} -% -% -%^^A -%^^A The long awaited beginning of documentation -%^^A -% \newbox\abstractbox -% \setbox\abstractbox=\vbox{ -% \begin{abstract} -% Listings.dtx is a source code printer for \LaTeX\ --- which always means \LaTeXe\ in this documentation. -% You can typeset stand alone files as well as enter listings using an environment similar to \texttt{verbatim} as well as you can print fragments using a command similar to |\verb|. -%^^A Since listings.dtx is a package and not a cross compiler, all listings are up to date without maintaining differences between (changed) source files and cross compiled files. -% The package supports a wide spectrum of programming languages --- some come already with \texttt{lstdrvrs.dtx}. -% Finally: Many parameters control the output. -% \end{abstract}} -% -% \title{{Listings.dtx} Version {0.19}} -% \author{Copyright 1996--1998 Carsten Heinz} -% \date{\box\abstractbox} -% -% \makeatletter\@twocolumntrue\makeatother -% \maketitle -% {\makeatletter\@starttoc{toc}} -%\iftrue -% \vfill -% \noindent \textbf{Again incompatibilities!} -% And there are certainly teething troubles since the complete kernel has been rewritten. -% So read this manual with care. -%\fi -% \onecolumn -% -% -% \part{User's guide} -% -% -% \section{Preface} -% -% The files \texttt{listings.dtx} and \texttt{listings.ins} and all files generated from only these two files are referred as 'the \textsf{listings} package' or simply 'the package'. -% A driver file is any file generated mainly from \texttt{lstdrvrs.dtx}. -% -% \paragraph{Alternatives.} -% The \textsf{listings} package is certainly not the final utility for typesetting source code listings. -% Other programs do their jobs very well if you are not satiesfied with \textsf{listings}. -% I should mention \textsf{a2ps} and the \textsf{LGrind} package. -% Let me know if you're using none of these solutions; I'd like to extend my suggestions. -% -% \paragraph{Reading this manual.} -% In any case you should read section ''\emph{\ref{uGettingStarted}. Getting started}'' step by step. -% You either start from the scratch there or you get in touch with the new user interface and other changes. -% That section is an introduction and doesn't cover all of the \textsf{listings} package, but the most common. -% After reading it you are prepared for the main reference if you need more details, more control or more features. -% -% \paragraph{Sorry!} -% On 1998/11/02 I decided to make major changes to the user interface, which were planned for version 0.2. -% But it's better to get the interface stable as soon as possible. -% In particular I must say sorry to all people I posted a pre-version of \textsf{listings} 0.19. -% -% \paragraph{Thanks.} -% There are many people I have to thank for fruitful communication, posting their ideas, giving error reports (first bug finder is listed), adding programming languages to \texttt{lstdrvrs.dtx}, etc.. -% If you want to know that in detail, search for the names in the implementation part. -%^^A -%^^A Thanks for error reports (first bug finder only), new programming languages, etc. -%^^A Special thanks for communication which lead to kernel extensions. -%^^A -% Special thanks go to (alphabetical order) -% \begin{quote} -% \hyphenpenalty=10000\relax \rightskip=0pt plus \linewidth\relax -% \lstthanks{Andreas~Bartelt}{Andreas.Bartelt@Informatik.Uni-Oldenburg.DE}, -% \lstthanks{Jan~Braun}{Jan.Braun@tu-bs.de}, -% \lstthanks{Denis~Girou}{Denis.Girou@idris.fr}, -% \lstthanks{Arne~John~Glenstrup}{panic@diku.dk}, -% \lstthanks{Rolf~Niepraschk}{NIEPRASCHK@PTB.DE}, -% \lstthanks{Rui~Oliveira}{rco@di.uminho.pt} and -% \lstthanks{Boris~Veytsman}{boris@plmsc.psu.edu}. -% \end{quote} -% Moreover I wish to thank -% \begin{quote} -% \hyphenpenalty=10000\relax \rightskip=0pt plus \linewidth\relax -% \lstthanks{Bj{\o}rn~{\AA}dlandsvik}{bjorn@imr.no}, -% \lstthanks{Gaurav~Aggarwal}{gaurav@ics.uci.edu}, -% \lstthanks{Kai~Below}{below@tu-harburg.de}, -% \lstthanks{Detlev~Dr\"oge}{droege@informatik.uni-koblenz.de}, -% \lstthanks{Anders~Edenbrandt}{Anders.Edenbrandt@dna.lth.se}, -% \lstthanks{Harald~Harders}{h.harders@tu-bs.de}, -% \lstthanks{Christian~Haul}{haul@dvs1.informatik.tu-darmstadt.de}, -% \lstthanks{J\"urgen~Heim}{heim@astro.uni-tuebingen.de}, -% \lstthanks{Dr.~Jobst~Hoffmann}{HOFFMANN@rz.rwth-aachen.de}, -% \lstthanks{Knut~M\"uller}{knut@physik3.gwdg.de}, -% \lstthanks{Zvezdan~V.~Petkovic}{zpetkovic@acm.org}, -% \lstthanks{Michael~Piotrowski}{mxp@linguistik.uni-erlangen.de}, -% \lstthanks{Ralf~Quast}{rquast@hs.uni-hamburg.de}, -% \lstthanks{Aslak~Raanes}{araanes@ifi.ntnu.no}, -% \lstthanks{Detlef~Reimers}{dreimers@aol.com}, -% \lstthanks{Magne~Rudshaug}{magne@ife.no}, -% \lstthanks{Andreas~Stephan}{astepha@wmpi04.math.uni-wuppertal.de}, -% \lstthanks{Dominique~de~Waleffe}{ddw@miscrit.be}, -% \lstthanks{Herbert~Weinhandl}{weinhand@grz08u.unileoben.ac.at}, -% \lstthanks{J\"orn~Wilms}{wilms@rocinante.colorado.edu} and -% \lstthanks{Kai~Wollenweber}{kai@ece.WPI.EDU}. -% \end{quote} -% -%^^A \lsthelper{Andreas Bartelt}{Andreas.Bartelt@Informatik.Uni-Oldenburg.DE}{1997/09/11}{single line comes out using \inputlisting inside \fbox} -%^^A \lsthelper{Michael Piotrowski}{mxp@linguistik.uni-erlangen.de}{1997/11/04}{! Use of \lstdrv@perl@TestCommentCut doesn't match its definition^^J\lst@line ->I^^JRF::LangID -- Statistical identification of language for IRF/1^^J^^J(POD ist Zeile '=irgendwas' bis Zeile '=cut')} -%^^A \lsthelper{Bj{\o}rn {\AA}dlandsvik}{bjorn@imr.no}{1997/10/27}{listings.sty is incompatible to inputenc.sty} -% -% -% \section{Software license} -% -% \paragraph{Copyright.} -% The \textsf{listings} package is copyright 1996--1998 Carsten Heinz. -% The driver files are copyright 1997, 1998 or 1997--1998 any individual author listed in these files. -% -% \paragraph{Distribution.} -% The \textsf{listings} package as well as \texttt{lstdrvrs.dtx} and all driver files are distributed freely. -% You are not allowed to take money for the distribution, except for a nominal charge for copying etc.. -% -% \paragraph{Use of the package.} -% The \textsf{listings} package is free for any non-commercial use. -% Commercial use needs (i) explicit permission of the author of this package and (ii) the payment of a license fee. -% This fee is to be determined in each instance by the commercial user and the package author and is to be payed as donation to the \LaTeX3 project. -% -% \paragraph{No warranty.} -% The \textsf{listings} package as well as \texttt{lstdrvrs.dtx} and all driver files are distributed without any warranty, express or implied, as to merchantability or fitness for any particular purpose. -% -% \paragraph{Modification advice.} -% Permission is granted to change the \textsf{listings} package as well as \texttt{lstdrvrs.dtx}. -% You are not allowed to distribute any changed version of the package or any changed version of \texttt{lstdrvrs.dtx}, neither under the same name nor under a different one. -% Tell the author of the package about your local changes: other users will welcome removed bugs, new features and additional programming languages. -% -% \paragraph{Contacts.} -% Send comments and ideas on the package, error reports and additional programming languages to \emph{Carsten Heinz, Tellweg 6, 42275 Wuppertal, Germany} or preferably to \texttt{cheinz@gmx.de}. -% -% \paragraph{Trademarks} -% appear throughout this documentation without any trademark symbol, so you can't assume that a name is free. -% There is no intention of infringement; the usage is to the benefit of the trademark owner. -% -% -% \section{Getting started}\label{uGettingStarted} -% -% -% \iffalse -% \subsection{Installation} -% -% \begin{enumerate} -% \item You need \texttt{listings.dtx} and \texttt{listings.ins} to install the \textsf{listings} package. -% \texttt{lstdrvrs.dtx} contains some language drivers. -% Move \texttt{.dtx} and \texttt{.ins} files into a separate folder if you want to. -% \item Remove all \texttt{lst???.sty} files if you update from an earlier version. -% \item Run \texttt{listings.ins} through \TeX. -% This creates the kernel \texttt{listings.sty} and two interface files \texttt{lst017.sty} and \texttt{lstfvrb.sty}. -% If you have \texttt{lstdrvrs.dtx}, a configuration file \texttt{listings.cfg} and a couple of driver files are also generated. -% \item Copy all created \texttt{.sty} and \texttt{.cfg} files to a directory searched by \TeX. -% \end{enumerate} -% \fi -% -% -% \subsection{Package loading} -% -% As usual in \LaTeX\ the package is loaded by |\usepackage[|\meta{options}|]{listings}|, where |[|\meta{options}|]| is optional. -% Note that \textsf{listings} 0.19 needs more save stack size than any previous version. -% The following options are available: -% \begin{description} -% \item[\texttt{0.17}] -% Use this option to compile documents created with version 0.17 of the \textsf{listings} package. -% Note that you can't use old driver files and that the option does not guarantee full compatibility. -% If you want to polish up an old document, use this option together with new commands and keys. -% There shouldn't be many problems, but I haven't made deep tests. -% \item[\normalfont\texttt{index} and \texttt{procnames}] define the 'index' respectively 'procnames' aspect, whatever that means. -% \item[\normalfont\texttt{ndkeywords} and \texttt{rdkeywords}] define second respectively third order keywords. -% \end{description} -% Note: Each option slows down the package, so it becomes quite slow if you use all options, for example. -% Note also that you can't activate any optional feature after package loading --- except you're a hacker and read the implementation part. -% -% Here is some kind of minimal file. -% \begin{verbatim} -% \documentclass{article} -% -% \usepackage{listings} -% %\usepackage[ndkeywords,index]{listings}% with some options -% -% \begin{document} -% -% \lstset{language=Pascal} -% % Any example may be inserted here. -% -% \end{document}\end{verbatim} -% \label{uMinimalFile}It loads the \textsf{listings} package without any option, but shows how the package is loaded with index option and second order keywords. -% Moreover we select Pascal as programming language. -% -% If you need more than one programming language in your document, I recommend the preamble command |\lstloadlanguages|, which loads the given programming languages only, e.g.\ |\lstloadlanguages{Pascal,Fortran,C++}|. -% You find more details in section \ref{uLanguagesAndStyles}. -% -% -% \subsection{Typesetting listings} -% -% You can print (a) stand alone files, (b) source code from \texttt{.tex} files or (c) code fragments within a paragraph. -% The difference between (b) and (c) is something like between display and text formulas (|$$| and |$|). -% -% We begin with code fragments. -% If you want '\lstinline!var i:integer;!', you can simply write '|\lstinline!var i:integer;!|'. -% The exclamation marks delimit the code fragment. -% They could be replaced by any character not in the code fragment, i.e.\ '|\lstinline$var i:integer;$|' would produce the same output. -% -% The \texttt{lstlisting} environment typesets the source code in between. -% It has one parameter, which we leave empty for the moment. -% \begin{lstsample}{} -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -% -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% Like most examples this shows the \LaTeX\ source code on the right and the result on the left. -% If you insert the \LaTeX\ code in the minimal file and run it through \TeX, the listing uses the whole text width. -% -% Finally examples for stand alone files: -% \begin{lstsample}{\lstset{baseem=0.5}} -%\lstinputlisting{listings.tmp} -% \end{lstsample} -% \noindent -% Do you wonder about the left hand side? -% Well, the file \texttt{listings.tmp} contains the current example. -% This is exactly the line you see on the right. -% If you want this line to be typeset in Pascal mode, you get what you've got. -% If you want the lines $3,4,\ldots,10$ of \texttt{testfile.pas}, write -% \begin{verbatim} -% \lstinputlisting[first=3,last=10]{testfile.pas}\end{verbatim} -% But be sure that the first line does exist, or you will get a ''runaway argument'' error. -% -% Problems could arise if you (try to) put a listing in a box, tabular environment or something similar. -% The |\lstbox| command in section \ref{uTypesettingListings} might solve this. -% If you use an extended character table in your listings, you must use the |extendedchars| key, see section \ref{uSomeSpecialKeys}. -% -% -% \subsection{The ''key=value'' interface} -% -% The \textsf{listings} package uses \textsf{keyval.sty} from the \textsf{graphics} bundle by David Carlisle. -% Each 'aspect' or 'parameter' you can control has an associated key. -% To select a programming language, for example, you need the key |language|, the sign |=| and the name of the language as value. -% The command |\lstset| gets this construction as argument. -% You have seen this in the minimal file on page \pageref{uMinimalFile}. -% You can set more than one parameter with a single |\lstset| if you separate two or more ''key=value'' constructions by commas: -% \begin{verbatim} -% \lstset{language=Pascal,keywordstyle=\bfseries}\end{verbatim} -% If the value itself contains a comma, you must enclose the value in braces: -% \begin{verbatim} -% \lstset{keywords={one,two,three}}\end{verbatim} -% |\lstset{keywords=one,two,three}| would set the one and only keyword |one| and gives an error message since the parameters |two| and |three| do not exist. -% -% Two final notes: -% (1) Some keys has default values, e.g.\ |flexiblecolumns=true| turns flexible columns on, but |flexiblecolumns| without any |=true| would do the same since the value true is default for that key. -% But you must use the value |false| if you want to turn them off. -% (2) |\lstset| sets the values local to the current group. -% Just forget it if you don't know what that means. -% The command |\lstinputlisting| (as seen above) and the environment (as you see below) both have optional arguments. -% If you use a key=value list as optional argument, these selections are valid for the particular listing only and the previous values are restored afterwards. -% For example, if the current language is Pascal, but you want \texttt{testfile.f95} from line 3 on, write -% \begin{verbatim} -% \lstinputlisting[first=3,language=Fortran]{testfile.f95}\end{verbatim} -% Afterwards Pascal is still the current language. -% Note that |\lstinline| has no optional parameter. -% -% -% \subsection{Figure out the appearance} -% -% Keywords are typeset bold, comments in italic shape and spaces in strings appear as '\textvisiblespace' (without the two quotes). -% You can change that default behaviour: -% \begin{verbatim} -%\lstset{ -% basicstyle=\small, % print whole listing small -% keywordstyle=\bfseries\underbar,% 'underlined' bold keywords -% nonkeywordstyle={}, % nothing happens to other identifiers -% commentstyle=\itshape, % default -% stringstyle=\ttfamily, % typewriter font for strings -% blankstring=true} % blank spaces are blank in strings\end{verbatim} -% We typeset a previous example with these styles again. -%\lstset{basicstyle=\small, -% keywordstyle=\bfseries\underbar,nonkeywordstyle={}, -% commentstyle=\itshape,stringstyle=\ttfamily,blankstring=true} -% \begin{lstsample}{} -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -% -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% The style definitions above use two kind of commands; on the one hand |\ttfamily| or |\bfseries| taking no arguments and on the other |\underline|, which gets exactly one argument. -% The \emph{very last} token of |keywordstyle|, |nonkeywordstyle| and |labelstyle| (see below) \emph{may} be a macro getting exactly one argument, namely the (non)keyword or label. -% All other tokens \emph{must not} take any arguments --- or you will get deep in trouble. -% \lstset{style={},blankstring=false} -% -% \textbf{Warning:} -% You shouldn't use striking styles too often, but 'too often' depends on how many keywords the source code contains, for example. -% Your eyes would concentrate on the framed, bold red printed keywords only, and your brain must compensate this. -% Reading such source code could be very exhausting. -% If it were longer, the last example would be quite good in this sense. -% Believe me. -% -% -% \subsection{Line numbers} -% -% You want tiny line numbers each second line? -% Here you are: -% \begin{lstsample}{} -%\lstset{labelstyle=\tiny,% <=== -% labelstep=2}% <=== -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -% -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% |labelstep=0| turns line numbering off. -% In the sequel we use |labelstyle=\tiny| and |labelstep=2|, even if it doesn't appear in the verbatim part. -% And now we try to interrupt (continue) a listing. -% For this purpose we use |{ }| as argument to the environment. -% \begin{lstsample}{\lstset{labelstyle=\tiny,labelstep=2}} -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -% -%\end{lstlisting} -% -%And we continue the listing: -% -%\begin{lstlisting}{ }% <=== -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% Note that the empty line at the end of the first part is not printed, but it is responsible for correct line numbering. -% |{ }| continued the previous '|{}|'-listing. -% In general the argument is the name of the listing. -% An empty (= |{}|) named listing always starts with line number one, no matter whether line numbers are printed or not. -% A space (= |{ }|) named listing continues the last empty or space named one. -% That's easy. -% And this mechanism becomes easier if you use real names for your listings. -% In that case all listings with the same name use a common line counter: the second (same named) listing continues automatically the first. -% Even if there are other listings in between. -% \begin{lstsample}{\lstset{labelstyle=\tiny,labelstep=2}} -%\begin{lstlisting}{Test}% <=== -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -% -%\end{lstlisting} -% -%And we continue the listing: -% -%\begin{lstlisting}{Test}% <=== -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% The next |Test| listing goes on with line number {\makeatletter\lstno@Test}. -% Note that listing names are case sensitive. -% -% -% \subsection{Tabulators and form feeds} -% -% You might get some unexpected output if your source code contains a tabulator or form feed. -% The package assumes tabulator stops at columns 9,17,25,33,\ldots, and a form feed prints an empty line. -% This is predefined via -% \begin{verbatim} -% \lstset{tabsize=8,formfeed=\bigbreak}\end{verbatim} -% If you change the eight to the number $n$, you will get tabulator stops at columns $n+1,\allowbreak 2n+1,\allowbreak 3n+1,$ and so on. -% If you want a new page every form feed, use |formfeed=\newpage|. -% \lstset{tabsize=4} -% \begin{lstsample}{} -%\lstset{tabsize=4} -%\begin{lstlisting}{} -%123456789 -% { one tabulator } -% { two tabs } -%123 { 123 and two tabs } -%\end{lstlisting} -% \end{lstsample} -% \lstset{tabsize=8}\noindent -% Unfortunately both sides are typeset with |tabsize=4|. -% -% -% \subsection{Indent the listing} -% -% The examples are typeset with centered \texttt{minipage}s. -% That's the reason why you can't see that line numbers are printed in the margin (default). -% Now we separate the 'minipage margin' and the minipage by a vertical rule: -% \begin{lstsample}{\lstset{frame=l,frametextsep=0pt,labelstyle=\tiny,labelstep=2}} -%Some text before -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -%\end{lstlisting} -% \end{lstsample} -% \noindent -% The listing is lined up with the normal text. -% You can change this if you want. -% The parameter |indent| 'moves' the listing to the right (or left if the skip is negative). -% \begin{lstsample}{\lstset{frame=l,frametextsep=0pt,labelstyle=\tiny,labelstep=2}} -%Some text before -%\lstset{indent=2em}% <=== -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -%\end{lstlisting} -% -%\begin{lstlisting}{ } -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% Note that |\lstset{indent=2em}| also changes the indent for the second listings. -% If you want to indent a single listing only, use the argument of |\lstset| as optional argument to the listing environment: -% \begin{lstsample}{\lstset{frame=l,frametextsep=0pt,labelstyle=\tiny,labelstep=2}} -%\begin{lstlisting}[indent=2em]{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -%\end{lstlisting} -% -%\begin{lstlisting}{ } -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -% \end{lstsample} -% \noindent -% Such local changes apply to all supported parameters. -% -% If you use environments like \texttt{itemize} or \texttt{enumerate}, there is 'natural' indention coming from these environments. -% By default the \textsf{listings} package respects this. -% But you might use |wholeline=true| (or |false|) to make your own decision. -% \begin{lstsample}{\lstset{frame=l,frametextsep=0pt,labelstyle=\tiny,labelstep=2}} -%\begin{itemize} -%\item First item: -% -%\begin{lstlisting}{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -%\end{lstlisting} -% -%\item Second item: -%\lstset{wholeline=true}% <=== -%\begin{lstlisting}{ } -%Write('Keywords are case '); -%WritE('insensitive here.'); -%\end{lstlisting} -%\end{itemize} -% \end{lstsample} -% \noindent -% You can use |wholeline| together with |indent|, of course. -% Refer section \ref{uListingAlignment} for a description of |spread|. -% -% -% \subsection{Fixed and flexible columns} -% -% The first thing a reader notices is --- except different styles for keywords etc. --- the column alignment of a listing. -% The problem: I don't like listings in typewriter fonts and other fonts need not to have a fixed width. -% But we don't want -% \begin{itemize}\item[]\begin{tabular}{@{}l} -% if\ x=y\ then\ write('alignment')\\ -% \ \ \ \ \ \ \ else\ print('alignment'); -% \end{tabular}\end{itemize} -% only because spaces are not wide enough. -% There is a simple trick to avoid such things. -% We make boxes of the same width and put one character in each box: -% \def\docharfbox#1#2{\fbox{\hbox to#1em{\hss\vphantom{fy}#2\hss}}} -% \def\docharbox#1#2{\hbox to#1em{\hss#2\hss}} -% \begin{itemize}\item[] -% \def\makeboxes#1{\docharfbox1#1\ifx#1\relax\else\expandafter\makeboxes\fi} -% \makeboxes if\ x=y\ then\ write\relax\space\ldots\\ -% \makeboxes \ \ \ \ \ \ \ else \ print\relax\space\ldots -% \end{itemize} -% Going this way the alignment of columns can't be disturbed. -% \def\makeboxes#1{\docharbox{0.45}#1\ifx#1\relax\else\expandafter\makeboxes\fi} -% But if the boxes are not wide enough, we get '\makeboxes if\ x=y\ then\relax\ldots', and choosing the width so that the widest character fits in leads to -% \def\makeboxes#1{\docharbox{1}#1\ifx#1\relax\else\expandafter\makeboxes\fi} -% '\makeboxes if\ x=y\ then\ write\relax\ldots'. -% Both are not acceptable. -% Since all input will be cut up in units, we can put each unit in a box, which width is multiplied by the number of characters we put in, of course. -% The result is -% \def\makeboxes#1#2{\docharfbox{#1}{#2}\ifx#2\relax\else\expandafter\makeboxes\fi} -% \makeboxes{1.4}{i\hss f}{.7}{\ }{.7}{x}{.7}{=}{.7}{y}{.7}{\ }{2.8}{t\hss h\hss e\hss n}{.7}{\ }{3.5}{w\hss r\hss i\hss t\hss e}{.7}\relax\space. -% Since we put wide and thin characters in the same box, the width of a single character box need not to be the width of the widest character. -% The empirical value {\makeatletter\lst@baseemfixed}em (which is called 'base em' later) is a compromise between overlapping characters and the number of boxes not exceeding the text width, i.e.\ how many characters fit a line without getting an overfull |\hbox|. -% -% \begingroup -% But overlapping characters are a problem if you use many upper case letters, e.g.\ \docharbox{3}{W\hss O\hss M\hss E\hss N} --- blame me and not the women, in fact \docharbox{1.8}{M\hss E\hss N} doesn't look better. -% To go around this problem the \textsf{listings} package supports more 'flexible columns' in contrast to the fixed columns above. -% Arne John Glenstrup (whose idea the format is) pointed out that he had good experience with flexible columns and assembler listings. -% The differences can be summed up as follows: The fixed column format ruins the nice spacing intended by the font designer, and the flexible format ruins the column alignment (possibly) intended by the programmer. -% We illustrate that: -% \lstset{style={},language={}} -% \def\sample{\begin{lstlisting}{}^^J\ WOMEN\ \ are^^J \ \ \ \ \ \ \ MEN^^J WOMEN are^^J better MEN^^J \end{lstlisting}} -% \begin{center}\begin{tabular}{c@{\qquad\quad}c@{\qquad\quad}c} -% verbatim&fixed columns&flexible columns\\ -% &with {\makeatletter\lst@baseemfixed}em&with {\makeatletter\lst@baseemflexible}em\\ \noalign{\medskip} -% \setkeys{lst}{basicstyle=\ttfamily,baseem=0.51}\lstbox\sample&\lstset{flexiblecolumns=false}\lstbox\sample&\lstset{flexiblecolumns=true}\lstbox\sample\lstset{flexiblecolumns=false} -% \end{tabular}\end{center} -% Hope this helps. -% Note the varying numbers of spaces between 'WOMEN' and 'are' and look at the different outputs. -% The flexible column format typesets all characters at their natural width. -% In particular characters never overlap. -% If a word needs more space than reserved ('WOMEN'), the rest of the line moves to the right. -% Sometimes a following word needs less space than reserved, or there are spaces following each other. -% Such 'surplus' space is used to fix the column alignment: -% The blank space in the third line have been printed properly, but the two blanks in the first line have been printed as one blank space. -% We can show all this more drastic if we reduce the width of a single character box: -% \begin{center}\lstset{baseem={0.3,0.0}}\begin{tabular}{c@{\qquad\quad}c@{\qquad\quad}c} -% &{\makeatletter\lst@baseemfixed}em&{\makeatletter\lst@baseemflexible}em\\ \noalign{\medskip} -% \setkeys{lst}{basicstyle=\ttfamily,baseem=0.51}\lstbox\sample&\lstset{flexiblecolumns=false}\lstbox\sample&\lstset{flexiblecolumns=true}\lstbox\sample\lstset{flexiblecolumns=false} -% \end{tabular}\end{center} -% In flexible column mode the first 'MEN' moves to the left since the blanks before are $7\cdot 0.0$em$=0$em wide. -% Even in flexible mode you shouldn't reduce 'base em' to less than 0.33333em ($\approx$ width of a single space). -% \endgroup -% -% You want to know how to select the flexible column format and how to reset to fixed columns? -% Try |flexiblecolumns=true| and |flexiblecolumns=false|. -% -% -% \subsection{Selecting other languages}\label{uSelectingOtherLanguages} -% -% You already know that |language=|\meta{language name} selects programming languages --- at least Pascal and Fortran. -% But that's not the whole truth. -% Both languages know different dialects (= version or implementation), for example Fortran 77 and Fortran 90. -% You can choose such special versions with the optional argument of |language|. -% Write -% \begin{verbatim} -% \lstset{language=[77]Fortran}% Fortran 77 -% \lstset{language=[XSC]Pascal}% Pascal XSC\end{verbatim} -% to select Fortran 77 and Pascal XSC, respectively. -% -% We give a list of all languages and dialects supported by \texttt{lstdrvrs.dtx}. -% Use the given names as (optional) values to |language|. -% An 'empty' language is also defined: |\lstset{language={}}| detects no keywords, no comments, no strings, \ldots -% \begin{center} -% \begin{tabular}{ll} -% Ada & Lisp \\ -% Algol (|68|,|60|) & Logo \\ -% C (|ANSI|,|Objective|)& Matlab \\ -% Cobol (|1985|,|1974|,|ibm|) & Mercury \\ -% Comal 80 & Modula-2 \\ -% C++ (|ANSI|,|Visual|) & Oberon-2 \\ -% csh & Pascal (|Standard|,|XSC|,|Borland6|) \\ -% Delphi & Perl \\ -% Eiffel & PL/I \\ -% Elan & Prolog \\ -% Euphoria & Simula (|67|,|CII|,|DEC|,|IBM|) \\ -% Fortran (|95|,|90|,|77|) & SQL \\ -% IDL & TeX (|plain|,|primitive|,|LaTeX|,|alLaTeX|) \\ -% HTML & VHDL \\ -% Java -% \end{tabular} -% \end{center} -% The configuration file \texttt{listings.cfg} defines each first dialect as default dialect, i.e.\ |\lstset{language=C}| selects ANSI C. -% After -% \begin{verbatim} -% \lstset{defaultdialect=[Objective]C}\end{verbatim} -% Objective-C becomes default dialect for C, but the language is \emph{not} selected with that command. -% -% \medskip -% Remark: The driver files define the languages with |\lstdefinelanguage|. -% The languages have all 'bugs' coming from the language commands, e.g.\ in Ada and Matlab it is still possible that the package assumes a string where none exists. -% See \texttt{lstdrvrs.dtx} for more remarks on special programming languages. -% -% -% \section{Main reference} -% -% \newcommand\UTODO[1]{} -% \newenvironment{TODO}{\begin{quote}\footnotesize To do:}{\end{quote}} -% \newenvironment{macrosyntax} -% {\list{}{\itemindent-\leftmargin\labelsep=0pt\relax % -% \def\makelabel##1{\lstmklab##1,\relax}}} -% {\endlist} -% \def\lstmklab#1,#2\relax{% -% \ifx\empty#2\empty % -% \lstmklabb#1,,\relax % -% \else -% \lstmklabb#1,#2\relax % -% \fi} -% \def\lstmklabb#1,#2,\relax{% -% \llap{\scriptsize\itshape#2}% -% \rlap{\hskip-\itemindent\hskip\labelwidth\hskip\linewidth#1}} -% -% In this section we list all user environments, commands and keys together with their parameters and possible values. -% Sometimes there are examples or more detailed information at the end of the subsections. -% All user macros have the prefix \lst. -% This avoids naming conflicts with other packages or document classes. -% -% In the sequel the label \emph{changed} indicates any change in behaviour or syntax of a command, environment or key, so read these items carefully. -% Keys strongly related to special programming languages have the label \emph{lang.spec.}. -% Usually they are available only if you have loaded the corresponding programming language. -% All other labels should be clear. -% The numbers in the right margin give the version number of introduction (either as internal or as user macro/key). -% -% Note that commands, environments and keys can be distinguished easily: -% A command begins with a backslash and a key is presented in ''|key=|\meta{value}'' fashion. -% All the rest are environments, which is in fact a single one. -% -% -% \subsection{Typesetting listings}\label{uTypesettingListings} -% -% \begin{macrosyntax} -% \item[0.1,changed] |\lstinputlisting[|\meta{key=value list}|]{|\meta{file name}|}| -% -% typesets the source code file using the active language and style (locally modified by the key=value list). -% Empty lines at the end of listing are dropped. -% -% The keys |first| and |last| determines the printed line range. -% Default is \emph{always} 1--9999999, where 'always' means that you can't set |first| and |last| globally. -% If you don't want a whole file, you must specify the line range. -% The example |\lstinputlisting[first=3,last=10]{testfile.pas}| would print lines 3,4,\ldots,10 of \texttt{testfile.pas} if file and lines are present. -% -% The boolean key |print| controls whether or not |\lstinputlisting| typesets a listing: -% |print=false| speed up things for draft versions of your document and |print=true| typesets the stand alone files. -% -% Note: The keys |first|, |last| and |print| only apply to |\lstinputlisting|. -%^^A -%^^A TODO: That's not true. -%^^A The key |first| also applies to lstlisting. -%^^A It sets the line number of the first line. -%^^A -% -% \item[0.15,changed] |lstlisting[|\meta{key=value list}|]{|\meta{name}|}| -% -% typesets source code between |\begin{lstlisting}{|\meta{name}|}| (+ line break) and |\end{lstlisting}|, but empty lines at the end of listing are dropped. -% Characters on the same line as the end of environment are \emph{not} dropped, i.e.\ source code right before and \LaTeX\ code after the end of environment is typeset respectively executed. -% If \meta{name} is not empty and the listing is not continued, the name appears in the list of listings.\\ -% Same named listings have common line counter, i.e.\ the second (same named) listing continues the first, the third continues the second, and so on. -% There are two exceptions: An empty named listing always starts with line number 1 and is continued with listings named |{ }| (single blank space). -% -% The key |resetlineno| (given without any value) sets the line number of the first line to 1. -% You can also specify a number, e.g.\ |resetlineno=10|. -% |advancelineno=|\meta{number} advances the number of the first line by \meta{number}. -% These two keys take also effect on |{}| and |{ }| named listings. -% -% Note: The keys |resetlineno| and |advancelineno| only apply to the environment and must be used in the optional key=value list. -% -% \item[0.18,new] |\lstinline| -% -% works like |\verb|, but uses the active language and style, of course. -% You can write '|\lstinline!var i:integer;!|' and get '\lstinline!var i:integer;!'. -% Note that these listings always use flexible columns and that |\lstinline| has no optional key=value list. -%\UTODO{implement optional key=value list} -% -% \item[0.18,new] |\lstbox[|\meta{b$\vert$c$\vert$t}|]| -% -% is used right before |\lstinputlisting| or a listing environment. -% Without |\lstbox| the listing uses a new paragraph and the complete line width, even if the listing is one character wide. -% |\lstbox| returns the listing as a |\hbox|, which has the necessary width only (line numbers possibly not included). -% Use this command within explicit |\hbox|es, |$$|\ldots|$$|, etc.. -% The optional argument gives the vertical position of the listing: bottom, center (default) or top. -% \end{macrosyntax} -% -% -% \subsection{List of listings} -% -% \begin{macrosyntax} -% \item[0.16] |\listoflistings| -% -% prints a list of listings. -% The names are the file names or names of the listings. -% -% \item[0.16] |\listlistingsname| -% -% contains the header name, which is 'Listings' by default. -% You may adjust it via |\renewcommand\listlistingsname{whatever}|. -% -% \item[0.19,new] |\lstname| -% -% contains the name of the current (last) listing in \emph{printable} form. -% After |pre=\subsubsection{\lstname}| each listing begins a new subsubsection, which name is the listing name. -% The key |pre| is described in section \ref{uSomeSpecialKeys}. -% You can also use it to index all listings, but then you must expand the content first. -% Simply write |\expandafter\index\expandafter{\lstname}| (as value to |pre| if you want). -% -% \item[0.19,new] |\lstintname| -% -% contains the name of the current (last) listing possibly in nonprintable form. -% Use this macro inside |\label| and |\ref| for example. -% But be aware that a reference counter must be defined --- or the label is the current section, subsection, and so on. -% You might use it like this: -% \begin{verbatim} -% \lstset{pre=\caption{\lstname}\label{lst\lstintname}} -% -% \begin{figure} -% \begin{lstlisting}{Empty} -% \end{lstlisting} -% \end{figure} -% -% Figure \ref{lstEmpty} shows an empty listing.\end{verbatim} -% Here \emph{all} listings get a caption and a label (unless |pre| is redefined). -% \end{macrosyntax} -% -% -% \subsection{Basic style keys}\label{uBasicStyleKeys} -% -% \begin{macrosyntax} -% \item[0.18,new] |basicstyle=|\meta{basic style and size} -% \item[0.11] |keywordstyle=|\meta{style for keywords} -% \item[0.19,new,optional] |ndkeywordstyle=|\meta{style for second keywords} -% \item[0.19,new,optional] |rdkeywordstyle=|\meta{style for third keywords} -% \item[0.18,new] |nonkeywordstyle=|\meta{style} -% \item[0.11] |commentstyle=|\meta{style} -% \item[0.12] |stringstyle=|\meta{style} -% \item[0.16] |labelstyle=|\meta{style} -% -% Each value of these keys determines the font and size (or more general style) in which special parts of a listing appear. -% The \emph{last} token of the (non,nd,rd) keyword and label style might be an one-parameter command like |\textbf| or |\underline|. -% -% \item[0.16,bug] |labelstep=|\meta{step} -% -% No line numbers are printed if \meta{step} is zero. -% Otherwise all lines with ''line number $\equiv 0$ modulo \meta{step}'' get a label, which appearance is controlled by the label style. -% -% Bug: If a comment (or string) goes over several lines, the line numbers (if on) also have comment (string) style. -% The easiest work-around is possibly the use of |\normalfont| in |\lstlabelstyle|. -% -% \item[0.12] |blankstring=|\meta{true$\vert$false} -% -% let blank spaces in strings appear as blank spaces respectively as \textvisiblespace. -% The latter is predefined. -% -% \item[0.12] |tabsize=|\meta{number} -% -% sets tabulator stops at columns $n+1$, $2n+1$, $3n+1$, etc. if $n=$\meta{number}. -% Each tabulator in a listing moves the current column to the next tabulator stop. -% It is initialized with |tabsize=8|. -% -% \item[0.19,new] |formfeed=|\meta{token sequence} -% -% Whenever a listing contains a form feed \meta{token sequence} is executed. -% It is initialized with |formfeed=\bigbreak|. -% \end{macrosyntax} -% -% -% \subsection{Fixed and flexible columns} -% -% \begin{macrosyntax} -% \item[0.18,new] |flexiblecolumns=|\meta{true$\vert$false} -% -% selects the flexible respectively the fixed column format. -% -% \item[0.16,addon] |baseem=|\meta{width in units of em}\quad or\quad|baseem={|\meta{fixed}|,|\meta{flexible mode}|}| -% -% sets the width of a single character box for fixed and flexible mode (both to the same value or individually). -% It's pre-defined via |baseem={|{\makeatletter\lst@baseemfixed}|,|{\makeatletter\lst@baseemflexible}|}|. -% \end{macrosyntax} -% -% -% \subsection{Listing alignment}\label{uListingAlignment} -% -% \begin{macrosyntax} -% \item[0.19,new] |indent=|\meta{dimension} -% -% indents each listing by \meta{dimension}, which is initialized with 0pt. -% This command is the best way to move line numbers (and the listing) to the right. -% -% \item[0.19,new] |wholeline=|\meta{true$\vert$false} -% -% prevents or lets the package use indention from list environments like \texttt{enumerate} or \texttt{itemize}. -% -% \item[0.16,bug,addon] |spread=|\meta{dimension}\quad or\quad|spread={|\meta{inner}|,|\meta{outer}|}| -% -% defines \emph{additional} line width for listings, which may avoid overfull |\hbox|es if a listing has long lines. -% The inner and outer spread is given explicitly or is equally shared. -% It is initialized via |spread=0pt|. -% For one sided documents 'inner' and 'outer' have the effect of 'left' and 'right'. -% Note that |\lstbox| doesn't use this spread but |indent| (which is always 'left'). -% -% Bug (two sided documents): -% At top of page it's possible that the package uses inner instead of outer spread or vice versa. -% This happens when \TeX\ finally moves one or two source code lines to the next page, but hasn't decided it when the \textsf{listings} package processes them. -% Work-around: interrupt the listing and/or use an explicit |\newpage|. -% -% \item[0.17] |lineskip=|\meta{additional space between lines} -% -% specifies the additional space between lines in listings. -% You may write |lineskip=-1pt plus 1pt minus 0.5pt| for example, but 0pt is the default. -% -% \item[0.19,new] |outputpos=|\meta{c$\vert$l$\vert$r} -% -% controls horizontal orientation of smallest output units (keywords, identifiers, etc.). -% The arguments work as follows, where vertical bars visualize the effect: -% $\vert$\hbox to 4.2em{\hss l\hss i\hss s\hss t\hss i\hss n\hss g\hss }$\vert$, -% $\vert$\hbox to 4.2em{l\hss i\hss s\hss t\hss i\hss n\hss g\hss }$\vert$ and -% $\vert$\hbox to 4.2em{\hss l\hss i\hss s\hss t\hss i\hss n\hss g}$\vert$ -% in fixed column mode resp.\ -% $\vert$\hbox to 3.15em{\hss listing\hss}$\vert$, -% $\vert$\hbox to 3.15em{listing\hss}$\vert$ and -% $\vert$\hbox to 3.15em{\hss listing}$\vert$ -% with flexible columns (using pre-defined |baseem|). -% By default the output is centered. -% To make all things clear: You may write |outputpos=c|, |outputpos=l| or |outputpos=r|. -% \end{macrosyntax} -% -% -% \subsection{Escaping to \LaTeX} -% -% \textbf{Note:} {\itshape Any escape to \LaTeX\ may disturb the column alignment since the package can't control the spacing there.} -% \begin{macrosyntax} -% \item[0.18,new] |texcl=|\meta{true$\vert$false} -% -% activates or deactivates \LaTeX\ comment lines, see the example below. -% -% \item[0.19,new] |mathescape=|\meta{true$\vert$false} -% -% activates or deactivates special behaviour of the dollar sign. -% If activated, a dollar sign acts as \TeX's text math shift (not display style!). -% -% \item[0.19,new] |escapechar=|\meta{single character} (or empty) -% -% The given character escapes the user to \LaTeX: -% All code between two such characters is interpreted as \LaTeX\ code. -% Note that \TeX's special characters must be entered with a preceding backslash, e.g.\ |escapechar=\%|. -% \end{macrosyntax} -% Some examples clarify these commands. -% Since |texcl| only makes sense with comment lines, we will use C++ comment lines here (without saying how to define them). -% Note that only the first example runs through a C++ compiler if the source code is placed in a separate file. -% All \LaTeX\ escapes are local here, but you can also use |\lstset|. -% \lstset{commentline=//} -% \begin{lstsample}{} -%\begin{lstlisting}[texcl]{} -%// calculate $a_{ij}$ -% A[i][j] = A[j][j]/A[i][j]; -%\end{lstlisting} -% \end{lstsample} -% -% \begin{lstsample}{} -%\begin{lstlisting}[mathescape]{} -%// calculate $a_{ij}$ -% $a_{ij} = a_{jj}/a_{ij}$; -%\end{lstlisting} -% \end{lstsample} -% -% \begin{lstsample}{} -%\lstset{escapechar=\%} -%\begin{lstlisting}{} -%// calc%ulate $a_{ij}$% -% %$a_{ij} = a_{jj}/a_{ij}$%; -%\end{lstlisting} -% \end{lstsample} -% \lstset{commentline={}} -% \noindent -% In the first example the whole comment line is typset in '\LaTeX\ mode' --- except the comment line indicators |//|. -% Note that |texcl| uses comment style. -% In the second example the comment line upto $a_{ij}$ have been typeset in comment style and by the \textsf{listings} package. -% The '$a_{ij}$' itself is typeset in '\TeX\ math mode' without comment style. -% About the half comment line of the third example have been typeset by this package. -% The rest is in '\LaTeX\ mode' without comment style. -% -% To avoid problems with the current and future version of this package: -% \begin{enumerate} -% \item Don't use any command of the \textsf{listings} package when you have escaped to \LaTeX. -% \item Any environment must start and end inside the same escape. -% \item You might use |\def|, |\edef|, etc., but do not assume that the definitions are present later --- except they are |\global|. -% \item |\if \else \fi|, groups, math shifts |$| and |$$|, \ldots\ must be balanced each escape. -% \item \ldots -% \end{enumerate} -% Expand that list yourself and mail me about new items. -% -% -% \subsection{Some special keys}\label{uSomeSpecialKeys} -% -% \begin{macrosyntax} -% \item[0.18,new] |extendedchars=|\meta{true$\vert$false} -% -% allows or prohibits extended characters in listings, i.e.\ characters with codes 128--255. -% If you use extended characters, you should load the \texttt{inputenc} or \texttt{fontenc} package! -% -% \item[0.19,new,lang.spec.]|printpod=|\meta{true$\vert$false} -% -% prints or drops PODs in Perl. -% -% \item[0.12,addon] |pre=[|\meta{continue}|]{|\meta{commands to execute}|}| -% \item[0.12,addon] |post=[|\meta{continue}|]{|\meta{commands to execute}|}| -% -% The given control sequences are executed before and after typesetting resp.\ when continuing a listing, but in all cases inside a group. -% The commands are not executed if you use |\lstbox| or |\lstinline| (since the user given pre and post commands are assumed to be unsave inside |\hbox|). -% By default \meta{continue} is empty. -% The other arguments are pre-set empty. -% \end{macrosyntax} -% -% \begin{lstsample}{} -%\lstset{flexiblecolumns} -%\lstset{pre=[% -% We continue the listing. -% ]A simple prelisting example.} -%\begin{lstlisting}{} -%{ Get listings.dtx. Now! } -%\end{lstlisting} -% -%\begin{lstlisting}{ } -%{ You have it already? Good. } -%\end{lstlisting} -% -%\begin{lstlisting}{ } -%{ Tell your friends about it. } -%\end{lstlisting} -% \end{lstsample} -%\lstset{style={}} -% -% -% \subsection{Languages and styles}\label{uLanguagesAndStyles} -% -% \begin{macrosyntax} -% \item[0.17,changed] |language=[|\meta{dialect}|]|\meta{language name} -% -% activates a (dialect of a) programming language. -% All arguments are case \emph{insensitive} here. -% -% \item[0.19,new] |\lstloadlanguages{|\meta{list of languages}|}| -% -% can only be used in the preamble. -% It loads all specified languages, where each language is given in the form |[|\meta{dialect}|]|\meta{language}. -% List of languages means a comma separated list. -% -% \item[0.18,new] |style=|\meta{style name} -% -% activates a style. -% The arguments is case \emph{insensitive}. -% -% \item[0.19,new] |\lstdefinestyle{|\meta{style name}|}{|\meta{key=value list}|}| -% -% stores the key=value list: You can select the style via |style| using te style name as argument. -% \end{macrosyntax} -% After package loading a 'standard' style and an 'empty' language are active. -% The style is defined as follows. -% \begin{verbatim} -% \lstdefinestyle{} -% {basicstyle={}, -% keywordstyle=\bfseries,nonkeywordstyle={}, -% commentstyle=\itshape, -% stringstyle={}, -% labelstyle={},labelstep=0 -% }\end{verbatim} -% -% -% \subsection{Language definitions} -% -% \begin{macrosyntax} -% \item[0.19,new] |\lstdefinelanguage[|\meta{dialect}|]{|\meta{language}|}{|\meta{key=value list}|}| -% -% defines a programming language. -% Use any 'language' key=value list and the definition is yours. -% -% \item[0.19,new] |\lstdefinedrvlanguage[|\meta{dialect}|]{|\meta{language}|}{|\meta{key=value list}|}| -% -% defines a programming language only if the user has requested the language. -% Thus this command can only be used in driver files. -% -% \item[0.19,new] |defaultdialect=[|\meta{dialect}|]|\meta{language} -% -% defines a default dialect for a language, that means a dialect which is selected whenever you leave out the optional dialect. -% If you have defined a default dialect other than empty, for example |defaultdialect=[iama]fool|, you can't select the 'empty' dialect, even not with |language=[]fool|. -% -% Note that a configuration file possibly defines some default dialects. -% -% \item[0.18,new] |\lstalias{|\meta{alias}|}{|\meta{language}|}| -% -% defines an alias for a programming language. -% Any dialect of \meta{alias} selects in fact the same dialect of \meta{language}. -% It's also possible to define an alias for one dialect: |\lstalias[|\meta{dialect alias}|]{|\meta{alias}|}[|\meta{dialect}|]{|\meta{language}|}|. -% Here all four parameters are \emph{non}optional. -% An alias with empty \meta{dialect} will select the default dialect. -% Note that aliases can't be nested: The two aliases |\lstalias{foo1}{foo2}| and |\lstalias{foo2}{foo3}| redirect |foo1| not to |foo3|. -% -% Note that a configuration file possibly defines some aliases. -% -% \item[0.18,new] |\lststorekeywords|\meta{macro}|{|\meta{keywords}|}| -% -% stores \meta{keywords} in \meta{macro} for use with keyword keys. -% This command can't be used in a language definition since it is a command and not a key. -% \end{macrosyntax} -% -% Now come all the language keys, which might be used in the key=value list of |\lstdefinelanguage|. -% Note: {\itshape If you want to enter {\upshape|\|, |{|, |}|, |%|, |#|} or {\upshape|&|} inside or as an argument here, you must do it with a preceding backslash!} -% -% \begin{macrosyntax} -% \item[0.11] |keywords={|\meta{keywords}|}| -% \item[0.11] |morekeywords={|\meta{additional keywords}|}| -% \item[0.18,new] |deletekeywords={|\meta{keywords to remove}|}| -% -% \item[0.19,new,optional] |ndkeywords={|\meta{second keywords}|}| -% \item[0.19,new,optional] |morendkeywords={|\meta{additional second keywords}|}| -% \item[0.19,new,optional] |deletendkeywords={|\meta{second keywords to remove}|}| -% -% \item[0.19,new,optional] |rdkeywords={|\meta{third keywords}|}| -% \item[0.19,new,optional] |morerdkeywords={|\meta{additional third keywords}|}| -% \item[0.19,new,optional] |deleterdkeywords={|\meta{third keywords to remove}|}| -% -% Each 'keyword' argument (here and below) is a list of keywords separated by commas. -% You might use macros defined with |\lststorekeywords| as elements (i.e.\ also separated by commas). -% |keywords={save,Test,test}| defines three keywords (if keywords are case sensitive). -% If you want to remove them all, simply write |keywords={}| --- in |\lstset|'s argument, in an optional argument or in a language definition. -% The characters |\|, |{|, and |}| (entered as |\\|, |\{| and |\}|) are \emph{not} allowed within a keyword. -% You might use each of -%^^A -%^^A We need some definitions here. -%^^A -%\makeatletter ^^A -%\def\lstspec#1{^^A -% \ifx\relax#1\else ^^A -% {\lstset{keywords=#1}\setbox\@tempboxa\hbox{\lstinline a#1a}}^^A -% \lst@ifspec\lstinline a#1a\fi ^^A -% \expandafter\lstspec ^^A -% \fi}^^A -%\lst@AddToHook{Output}{\lstspectest}^^A -%\gdef\lstspecfalse{\global\let\lst@ifspec\iffalse}^^A -%\gdef\lstspectest{^^A -% \global\let\lst@ifspec=\iftrue ^^A -% \ifx\lst@thestyle\lst@keywordstyle\else ^^A -% \lstspecfalse ^^A -% \fi}^^A -%\makeatother ^^A -% {\lstset{language={}}^^A -% \lstspec !"\#$\%\&'()*+-./:;<=>?[]^`\relax.} -%^^A -%^^A a comma also works! -%^^A -%^^A End of test. -%^^A -% But note that you must enter |\#|, |\%| and |\&| instead of |#|, |%| and |&|. -% -% \item[0.14] |sensitive=|\meta{true$\vert$false} -% -% makes the keywords (first, second and third) case sensitive resp.\ insensitive. -%^^A It would be nice to have |\lst|\meta{\texttt{nd}$\vert$\texttt{rd}}|sensitive|\meta{\texttt{true}\textbar\texttt{false}}? -% This key affect the keywords only in the phase of typesetting. -% In all other situations keywords are case sensitive, i.e.\ |deletekeywords={save,Test}| removes 'save' and 'Test', but neither 'SavE' nor 'test'. -% -% \item[0.19,new] |alsoletters={|\meta{character sequence}|}| -% \item[0.19,new] |alsodigits={|\meta{character sequence}|}| -% \item[0.19,new] |alsoother={|\meta{character sequence}|}| -% -% These keys support the 'special character' auto-detection of the keyword commands. -% For our purpose here, identifiers are out of letters (|A|--|Z|,|a|--|z|,|_|,|@|,|$|) and digits (|0|--|9|), but an identifier must begin with a letter. -% If you write |keywords={one-two,\#include}|, the minus becomes necessarily a digit and the sharp a letter since the keywords can't be detected otherwise. -% The three keys overwrite such default behaviour. -% Each character of the sequence becomes a letter, digit and other, respectively. -% Note that the auto-detection might fail if you remove keywords and always fails if you use special characters not listed above. -%^^A -%^^A TODO: This is mainly due to improper \lst@ReplaceIn inside ..MakeKeywordArg.. -%^^A -% -% \item[0.19,new] |stringtest=|\meta{true$\vert$false} -% -% enables or disables string tests: -% If activated, line exceeding strings issue warnings and the package exits string mode. -% -% \item[0.12,addon] |stringizer=[|\meta{b$\vert$d$\vert$m$\vert$bd}|]{|\meta{character sequence}|}| -% -% Each character might start a string or character literal. -% 'Stringizers' match each other, i.e.\ starting and ending delimiters are the same. -% The optional argument controls how the stringzier(s) itself is/are represented in a string or character literal: -% It is preceded by a |b|ackslash, |d|oubled (or both is allowed via |bd|) or it is |m|atlabed. -% The latter one is a special type for Ada and Matlab and possibly more languages, where the stringizers are also used for other purposes. -% In general the stringizer is also doubled, but a string does not start after a letter or a right parenthesis. -% -% \item[0.19,new,lang.spec.] |texcs={|\meta{list of control sequences \textup(without backslashes\textup)}|}| -% -% defines control sequences for \TeX\ and \LaTeX. -% -% \item[0.18,new,lang.spec.] |cdirectives={|\meta{list of compiler directives}|}| -% -% defines compiler directives in C, C++ and Objective-C. -% \end{macrosyntax} -% If you have already defined any of the following comments and you want to remove it, let all arguments to the comment key empty. -% \begin{macrosyntax} -% \item[0.13,changed] |commentline=|\meta{1or2 chars} -% -% The characters (\emph{in the given order}) start a comment line, which in general starts with the comment separator and ends at end of line. -% If the character sequence |//| starts a comment line (like in C++, Comal 80 or Java), |commentline=//| is the correct declaration. -% For Matlab it would be |commentline=\%| --- note the preceding backslash. -% -% \item[0.18,new] |fixedcommentline=[|\meta{n=preceding columns}|]{|\meta{character sequence}|}| -% -% Each given character becomes a 'fixed comment line' separator: It starts a comment line if and only if it is in column $n+1$. -% Fortran 77 declares its comments via |fixedcommentline={*Cc}| ($n=0$ is default). -% -% \item[0.13,changed] |singlecomment={|\meta{1or2 chars}|}{|\meta{1or2 chars}|}| -% \item[0.13,changed] |doublecomment={|\meta{1or2 chars}|}{|\meta{1or2 chars}|}{|\meta{1or2 chars}|}{|\meta{1or2 chars}|}| -% -% Here we have two or four comment separators. -% The first starts and the second ends a comment, and similarly the third and fourth separator for double comments. -% If you need three such comments use |singlecomment| and |doublecomment| at the same time. -% C, Java, PL/I, Prolog and SQL all define single comments via |singlecomment={/*}{*/}|, and Algol does it with |singlecomment={\#}{\#}|, which means that the sharp delimits both beginning and end of a single comment. -% -% \item[0.13,changed] |nestedcomment={|\meta{1or2 chars}|}{|\meta{1or2 chars}|}| -% -% is similar to |singlecomment|, but comments can be nested. -% Identical arguments are not allowed --- think a while about it! -% Modula-2 and Oberon-2 use |nestedcomment={(*}{*)}|. -% -% \item[0.17,lang.spec.] |keywordcomment={|\meta{keywords}|}| -% \item[0.17,lang.spec.] |doublekeywordcommentsemicolon={|\meta{keywords}|}{|\meta{keywords}|}{|\meta{keywords}|}| -% -% A (paired) keyword comment begins with a keyword and ends with the same keyword. -% Consider |keywordcomment={comment,co}|. -% Then '\textbf{comment}\allowbreak\ldots\textbf{comment}' and '\textbf{co}\ldots\textbf{co}' are comments.\\ -%^^A -% Defining a double keyword comment (semicolon) needs three keyword lists, e.g.\ |{end}{else,end}{comment}|. -% A semicolon always ends such a comment. -% Any keyword of the first argument begins a comment and any keyword of the second argument ends it (and a semicolon also); a comment starting with any keyword of the third argument is terminated with the next semicolon only. -% In the example all possible comments are '\textbf{end}\ldots\textbf{else}', '\textbf{end}\ldots\textbf{end}' (does not start a comment again) and '\textbf{comment}\ldots;' and '\textbf{end}\ldots;'. -% Maybe a curious definition, but Algol and Simula use such comments.\\ -%^^A -% Note: The keywords here need not to be a subset of the defined keywords. -% They won't appear in keyword style if they aren't. -% \end{macrosyntax} -% -% -% \section{Experimental features} -% -% This section describes the more or less unestablished parts of the \textsf{listings} package. -% It's unlikely that they are removed, but they are liable to (heavy) changes and maybe improvements. -% -% -% \subsection{Interface to \textsf{fancyvrb}} -% -% The \textsf{fancyvrb} package --- fancy verbatims --- from Timothy van Zandt provides macros for reading, writing and typesetting verbatim code. -% It has some remarkable features the \textsf{listings} package doesn't have --- some are also possible with \textsf{listings}, but you must find somebody who implements them ; -- ). -% The \textsf{fancyvrb} package is available from \texttt{CTAN: macros/latex/contrib/supported/fancyvrb}. -% -% \begin{macrosyntax} -% \item [0.19,new]|fancyvrb=|\meta{true$\vert$false} -% -% activates or deactivates the interface. -% This defines an appropiate version of |\FancyVerbFormatLine| to make the two packages work together. -% If active, the verbatim code read by the \textsf{fancyvrb} package is typeset by the \textsf{listings} package, i.e.\ with emphasized keywords, strings, comments, and so on. -% --- You should know that |\FancyVerbFormatLine| is responsible for the typesetting a single code line. -% -% If \textsf{fancyvrb} and \textsf{listings} provide similar functionality, use \textsf{fancyvrb}'s. -% -% Note that this is the first interface. -% It works only with |Verbatim|, neither with |BVerbatim| nor |LVerbatim|. -% And you shouldn't use \textsf{defineactive}. (As I can see it doesn't matter since it does nothing at all.) -% I hope to remove some restrictions in future. -% \end{macrosyntax} -% -% \iffancyvrb -% \begin{lstsample}{} -%\lstset{commentline=\ }% :-) -% -%\begin{Verbatim}[commandchars=\\\{\}] -%First verbatim line. -%\fbox{Second} verbatim line. -%\end{Verbatim} -% -%\lstset{fancyvrb} -%\begin{Verbatim}[commandchars=\\\{\}] -%First verbatim line. -%\fbox{Second} verbatim line. -%\end{Verbatim} -%\lstset{fancyvrb=false} -% \end{lstsample} -% \noindent -% The last two lines are wider than the first two since |baseem| equals not the width of a single typewriter character. -% \else -% \begin{center} -% \textsf{fancyvrb} seems to be unavailable on your platform, thus the example couldn't be printed here. -% \end{center} -% \fi -% -% -% \subsection{Listings inside arguments}\label{uListingsInsideArguments} -% -% There are some things to consider if you want to use |\lstinline| or the listing environment inside arguments. -% Since \TeX\ reads the argument before the '\lst-macro' is executed, this package can't do anything to preserve the input: -% Spaces shrink to one space, the tabulator and the end of line are converted to spaces, the comment character is not printable, and so on. -% Hence, you must work a little bit more. -% You have to put a backslash in front of each of the following four characters: |\{}%|. -% Moreover you must protect spaces in the same manner if: (i) there are two or more spaces following each other or (ii) the space is the first character in the line. -% That's not enough: Each line must be terminated with a 'line feed' |^^J|. -% Finally you can't escape to \LaTeX\ inside such listings. -% -% The easiest examples are with |\lstinline| since we need no line feed. -% \begin{verbatim} -%\footnote{\lstinline!var i:integer;! and -% \lstinline!protected\ \ spaces! and -% \fbox{\lstinline!\\\{\}\%!}}\end{verbatim} -% yields\lstset{language=Pascal}\footnote{\lstinline!var i:integer;! and \lstinline!protected\ \ spaces! and \fbox{\lstinline!\\\{\}\%!}} if the current language is Pascal. -% The environment possibly needs a preceding |\lstbox|, as the following examples show. -% -%{\let\smallbreak\relax\lstset{language={}} -% \begin{lstsample}{} -%\fbox{\lstbox -%\begin{lstlisting}{}^^J -%\ !"#$\%&'()*+,-./^^J -%0123456789:;<=>?^^J -%@ABCDEFGHIJKLMNO^^J -%PQRSTUVWXYZ[\\]^_^^J -%`abcdefghijklmno^^J -%pqrstuvwxyz\{|\}~^^J -%\end{lstlisting}} -% \end{lstsample} -% -% \lstset{language={}} -% \begin{lstsample}{} -%\fbox{\lstbox -%\begin{lstlisting}{}^^J -%We need no protection here,^^J -%\ but\ \ in\ \ this\ \ line.^^J -%\end{lstlisting}} -% \end{lstsample} -%} -% -% -% \subsection{Frames} -% -% \begin{macrosyntax} -% \item [0.19,new] |frame=|\meta{any subset of \textup{\texttt{tlrbTLRB}}} -% -% The characters |tlrbTLRB| are attached to lines at the |t|op of a listing, on the |l|eft, |r|ight and at the |b|ottom. -% There are two lines if you use upper case letters. -% If you want a single frame around a listing, write |frame=tlrb| or |frame=bltr| for example (but as optional argument or argument to |\lstset|, of course). -% If you want double lines at the top and on the left and no other lines, write |frame=TL|. -% Note that frames reside outside the listing's space. -% Use |spread| if you want to shrink frames (to |\linewidth| for example) and use |indent| if you want to move line number inside frames. -% -% \item [0.19,new] |framerulewidth=|\meta{dimension} -% \item [0.19,new] |framerulesep=|\meta{dimension} -% -% These keys control the width of the rules and the space between double rules. -% The predefined values are {\makeatletter\lst@framewidth} width and {\makeatletter\lst@framesep} separation. -% -%\iffalse -% \item [0.19,new] |frametextsep=|\meta{dimension} -% -% controls the space between frame and listing, but currently only between the listing and vertical frame lines. -% The predefined value is {\makeatletter\lst@frametextsep}. -%\fi -% \end{macrosyntax} -% |frame| does not work with |\lstbox| or |fancyvrb=true|! -% And there are certainly more problems with other commands. -% Take the time to report in. -% -% \begin{lstsample}{} -%\begin{lstlisting}[frame=tLBr]{} -%for i:=maxint to 0 do -%begin -% { do nothing } -%end; -%\end{lstlisting} -% \end{lstsample} -% -% -% \subsection{Export of identifiers} -% -%^^A \lsthelper{Aslak Raanes}{araanes@ifi.ntnu.no}{1997/11/24}{export function names} -% It would be nice to export function or procedure names, for example to index them automatically or to use them in |\listoflistings| instead of a listing name. -% In general that's a dream so far. -% The problem is that programming languages use various syntaxes for function and procedure declaration or definition. -% A general interface is completely out of the scope of this package --- that's the work of a compiler and not of a pretty printing tool. -% However, it is possible for particular languages: in Pascal each function or procedure definition and variable declaration is preceded by a particular keyword. -% \begin{macrosyntax} -% \item [0.19,new,optional] |index={|\meta{identifiers}|}| -% -% \meta{identifiers} is a comma-separated list of identifiers. -% Each appearance of such an identifier is indexed. -% -% \item [0.19,new,optional] |indexmacro=|\meta{'one parameter' macro} -% -% The specified macro gets exactly one parameter, namely the identifier, and must do the indexing. -% It is predefined as |indexmacro=\lstindexmacro|, which definition is -% \begin{verbatim} -% \newcommand\lstindexmacro[1]{\index{{\ttfamily#1}}}\end{verbatim} -% \item[0.19,new,optional] |prockeywords={|\meta{keywords}|}| -% -% \meta{keywords} is a comma-separated list of keywords, which indicate a function or procedure definition. -% Any identifier following such a keyword appears in 'procname' style. -% For Pascal you might use -% \begin{verbatim} -% prockeywords={program,procedure,function}\end{verbatim} -% -% \item[0.19,new,optional] |procnamestyle=|\meta{style for procedure names} -% -% defines the style in which procedure and function names appear. -% -% \item[0.19,new,optional] |indexprocnames=|\meta{true$\vert$false} -% -% If activated, procedure and function names are also indexed (if used with |index| option). -% \end{macrosyntax} -% -% -% \section{Troubleshooting} -% -% The known bugs have already been described. -% This section deals with problems concerning not only the \textsf{listings} package. -% -% -% \subsection{Problems with \texttt{.fd} files} -% -% You probably get the following error message with a different font definition file: -% \begin{verbatim} -%! LaTeX Error: Command textparagraph unavailable in encoding T1. -% -%See the LaTeX manual or LaTeX Companion for explanation. -%Type H for immediate help. -% ... -% -%l.68 \P -% rovidesFile{omscmr.fd} -%?\end{verbatim} -% So, what happened? -% (a) The \textsf{listings} package redefines the character table to print listings. -% (b) \LaTeX\ loads the font definition files on demand. -% (a) plus (b) gives the error: \LaTeX\ loads the \texttt{.fd} files with modified character table. -% And that goes wrong. -% The work-around is quite easy: Input the \texttt{.fd} file before typesetting the listing. -% -% -% \subsection{Language definitions} -% -% Language definitions and also some style definitions tend to have long definition parts. -% This is why we tend to forget commas between the key=value elements. -% If you select a language and get a |Missing = inserted for \ifnum| error, this is surely due to a missing comma after |keywords=|value. -% If you encounter unexspected characters after selecting a language (or style), you have either forgotten a comma or you have given to many arguments to a key, for example |commentline={--}{!}|. -% -% -% \section{Forthcoming} -% -% \begin{itemize} -% \item I'd like to support more languages, for example Maple, Mathematica, PostScript, Reduce and so on. -% Fortunately my lifetime is limited, so other people may do that work. -% Write a language definition and (e-)mail it to me (with a proposal in which file to place the definition). -% -% \item There will possibly a boolean |blanklisting=|\meta{true$\vert$false} or a $*$-version of the environment. -% -% \item 'procnames' is already interesting, but marks (and indexes) only the function definitions so far. -% It would be quite easy to mark also the following function calls: -% Write another 'keyword class' which is empty at the very beginning (and can be reset with a key); each function definition appends a 'keyword' which will appear in 'procnamestyle'. -% But this would be another 'keyword test' within an inner loop. -% \item I plan to put all language definitions in a single file. -% \end{itemize} -% -% -% \StopEventually{} -% -% -% \part{Implementation} -% -% \CheckSum{5520} -% \DoNotIndex{\[,\{,\},\],\1,\2,\3,\4,\5,\6,\7,\8,\9,\0} -% \DoNotIndex{\`,\,,\!,\#,\$,\&,\',\(,\),\+,\.,\:,\;,\<,\=,\>,\?,\_} -% \DoNotIndex{\@@end,\@@par,\@currenvir,\@depth,\@dottedtocline,\@ehc} -% \DoNotIndex{\@empty,\@firstoftwo,\@gobble,\@gobbletwo,\@gobblefour,\@height} -% \DoNotIndex{\@ifnextchar,\@ifundefined,\@namedef,\@ne,\@secondoftwo} -% \DoNotIndex{\@spaces,\@starttoc,\@undefined,\@whilenum,\@width} -% \DoNotIndex{\A,\active,\addtocontents,\advance,\aftergroup,\batchmode} -% \DoNotIndex{\begin,\begingroup,\bfseries,\bgroup,\box,\bigbreak,\bullet} -% \DoNotIndex{\c@page,\catcode,\contentsname,\csname,\def,\divide,\do,\dp} -% \DoNotIndex{\edef,\egroup,\else,\end,\endcsname,\endgroup,\endinput} -% \DoNotIndex{\endlinechar,\escapechar,\everypar,\expandafter,\f@family} -% \DoNotIndex{\fi,\footnotesize,\gdef,\global,\hbox,\hss,\ht} -% \DoNotIndex{\if,\ifdim,\iffalse,\ifnum,\ifodd,\iftrue,\ifx} -% \DoNotIndex{\ignorespaces,\index,\input,\itshape,\kern} -% \DoNotIndex{\lccode,\l@ngrel@x,\leftskip,\let,\linewidth,\llap} -% \DoNotIndex{\long,\lowercase,\m@ne,\makeatletter,\mathchardef} -% \DoNotIndex{\message,\multiply,\NeedsTeXFormat,\newbox,\new@command} -% \DoNotIndex{\newcommand,\newcount,\newdimen,\newtoks,\noexpand} -% \DoNotIndex{\noindent,\normalbaselines,\normalbaselineskip} -% \DoNotIndex{\offinterlineskip,\par,\parfillskip,\parshape} -% \DoNotIndex{\parskip,\ProcessOptions,\protect,\ProvidesPackage} -% \DoNotIndex{\read,\relax,\removelastskip,\rightskip,\rlap,\setbox} -% \DoNotIndex{\smallbreak,\smash,\space,\string,\strut,\strutbox} -% \DoNotIndex{\the,\thepage,\ttdefault,\ttfamily,\tw@,\typeout,\uppercase} -% \DoNotIndex{\vbox,\vcenter,\vrule,\vtop,\wd,\xdef,\z@,\zap@space} -% \DoNotIndex{\char,\closeout,\immediate,\newwrite,\openout,\write} -% \DoNotIndex{\vskip} -% -% \DoNotIndex{\define@key,\setkeys} -% -% \DoNotIndex{\textasciicircum,\textasciitilde,\textasteriskcentered} -% \DoNotIndex{\textbackslash,\textbar,\textbraceleft,\textbraceright} -% \DoNotIndex{\textdollar,\textendash,\textgreater,\textless} -% \DoNotIndex{\textunderscore,\textvisiblespace} -% -% \DoNotIndex{\filename@area,\filename@base,\filename@ext} -% \DoNotIndex{\filename@parse,\IfFileExists,\InputIfFileExists} -% \DoNotIndex{\DeclareOption,\MessageBreak} -% \DoNotIndex{\GenericError,\GenericInfo,\GenericWarning} -% -% \DoNotIndex{\blankstringfalse,\blankstringtrue,\commentstyle} -% \DoNotIndex{\DeclareCommentLine,\DeclareDoubleComment} -% \DoNotIndex{\DeclareNestedComment,\DeclarePairedComment} -% \DoNotIndex{\DeclareSingleComment,\inputlisting,\inputlisting@,\keywords} -% \DoNotIndex{\keywordstyle,\labelstyle,\listingfalse,\listingtrue} -% \DoNotIndex{\morekeywords,\normallisting,\postlisting,\prelisting} -% \DoNotIndex{\selectlisting,\sensitivefalse,\sensitivetrue} -% \DoNotIndex{\spreadlisting,\stringizer,\stringstyle,\tablength} -% -% \DoNotIndex{\lst@AddToHook@,\lst@Aspect@,\is,\lst@AspectGobble} -% \DoNotIndex{\lst@DeleteKeysIn@,\lst@Environment@} -% \DoNotIndex{\lst@IfNextChars@,\lst@IfNextChars@@,\lst@KCOutput@} -% \DoNotIndex{\lst@MakeActive@,\lst@MSkipUptoFirst@,\lst@ReplaceIn@} -% \DoNotIndex{\lst@LocateLanguage@,\lst@SKS@,\lstalias@,\lstalias@@} -% \DoNotIndex{\lstbaseem@,\lstbox@,\lstCC@ECUse@,\lstCC@Escape@} -% \DoNotIndex{\lstCC@CBC@,\lstCC@CBC@@,\lstCC@CommentLine@} -% \DoNotIndex{\lstCC@EndKeywordComment@,\lstCC@FixedCL@} -% \DoNotIndex{\lstCC@ProcessEndPOD@,\lstCC@SpecialUseAfter@} -% \DoNotIndex{\lstCC@Stringizer@,\lstdrvlanguage@,\lstenv@AddArg@} -% \DoNotIndex{\lstenv@Process@,\lstenv@ProcessJ@,\lstinputlisting@} -% \DoNotIndex{\lstoutputpos@,\lstresetlineno@,\lstresetlineno@@} -% \DoNotIndex{\lstspread@} -% \DoNotIndex{\lstnestedcomment@,\lstpost@,\lstpre@,\lststringizer@} -% -% -% \section{Overture} -% -% The version 0.19 kernel needs 1 token register, 6 counters and 5 dimensions. -% The macros, boxes and counters |\@temp?a| and |\@temp?b| and the dimension |\@tempdima| are also used, see the index. -% And I shouldn't forget |\@gtempa|. -% Furthermore, the required \textsf{keyval} package allocates one token register. -% The \textsf{fancyvrb} interface needs one box. -% -% Before considering the implementation, here some conventions I used: -% \begin{itemize} -% \item All public macros have lower case letters and the prefix \lst. -% \item The name of all private macros and variables use the prefixes (possibly not up to date): -% \begin{itemize} -% \item |lst@| for a general macro or variable, -% \item |lstenv@| if it is defined for the listing |env|ironment, -% \item |lstCC@| for |c|haracter |c|lass macros, -% \item |lsts@| for |s|aved character meanings, -% \item |lstf@| for frame declaration, -% \item |\lsthk@|\meta{name of hook} holds hook material, -% \item a language may define (|Pre| for prepare, |SCT| for select char table) -% \begin{itemize} -% \item[] |\lstPre@|\meta{language} -% \item[] |\lstPre@|\meta{language}|@|\meta{dialect} -% \item[] |\lstSCT@|\meta{language} -% \item[] |\lstSCT@|\meta{language}|@|\meta{dialect} -% \end{itemize} -% where the first two are executed (if they exist) one time each listing (before selecting character table, but after executing the hook Before\-Select\-Char\-Table). -% The other two macros are called possibly more than once, namely whenever the package selects the character table. -% The specialized \meta{dialect} versions are called after the more general \meta{language} macros. -% \item |lstk@| is reserved for keyword tests, -% -% \item |\lstlang@|\meta{language}|@|\meta{dialect} contains a language definition, -% \item |\lststy@|\meta{the style} contains style definition, -% -% \item |\lstloc@|\meta{language} keeps location (= file name without extension) of a language definition if it's not |lst|\meta{language}, -% \item |\lsta@|\meta{language}|@|\meta{dialect} contains alias, -% \item |\lstaa@|\meta{language} contains alias for all dialects of a language, -% \item |\lstdd@|\meta{language} contains default dialect of a language (if present). -% \end{itemize} -% \item If a submacro does the main work, e.g.\ |\lstinputlisting@| does it for |\lstinputlisting|, we use the suffix |@|. -% \item To distinguish procedure-like macros from macros holding data, the name of procedure macros use upper case letters with each beginning word, e.g.\ |\lst@AddTo|. -% \end{itemize} -% -% The kernel starts with identification and option declaration and processing. -% \begingroup -% \begin{macrocode} -%<*kernel> -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{listings}[1998/11/09 v0.19 by Carsten Heinz] -\RequirePackage{keyval} -% \end{macrocode} -% \begin{macrocode} -\DeclareOption{0.17}{\@namedef{lst@0.17}{}} -\DeclareOption{index}{\@namedef{lst@index}{}} -\DeclareOption{procnames}{\@namedef{lst@prockeywords}{}} -\DeclareOption{ndkeywords}{\@namedef{lst@ndkeywords}{}} -\DeclareOption{rdkeywords}{\@namedef{lst@rdkeywords}{}} -\DeclareOption{doc}{\@namedef{lst@doc}{}} -\ProcessOptions -% -% \end{macrocode} -% Note that |doc| option is designed for this documentation only. -% \endgroup -% -% \begingroup -% \begin{macrocode} -%<*info> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@InfoInfo} -% \begin{macro}{\lst@InfoWarning} -% \begin{macro}{\lst@InfoError} -% Each macro gets one argument, which is printed (\texttt{.log} and/or screen) as info, warning or error. -% \begin{macrocode} -\def\lst@InfoInfo#1{% - \GenericInfo % - {(Listings) \@spaces\@spaces\space\space}% - {Listings Info: #1}} -% \end{macrocode} -% \begin{macrocode} -\def\lst@InfoWarning#1{% - \GenericWarning % - {(Listings) \@spaces\@spaces\@spaces\space}% - {Listings Warning: #1}} -% \end{macrocode} -% \begin{macrocode} -\def\lst@InfoError#1{% - \GenericError % - {(Listings) \@spaces\@spaces\@spaces\space}% - {Listings Error: #1}% - {See the package documentation for explanation.}% - {You're using a debug version of listings.sty.^^J% - Contact your system administrator to install nondebug one.}} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{General problems and \TeX{}niques} -% -% -% \subsection{Quick 'if parameter empty'} -% -% There are many situations where you have to look whether or not a macro parameter is empty. -% Let's say, we want to test |#1|. -% The \emph{natural} way would be something like -% \begin{verbatim} -% \def\test{#1}% -% \ifx \test\empty % -% % #1 is empty -% \else % -% % #1 is not empty -% \fi %\end{verbatim} -% where |\empty| is defined by |\def\empty{}|, of course. -% And now the \emph{mad} way: -% \begin{verbatim} -% \ifx \empty#1\empty % -% % #1 is empty -% \else % -% % #1 is not empty -% \fi %\end{verbatim} -% If the parameter is empty, the |\empty| left from |#1| is compared with the |\empty| on the right. -% All is fine since they are the same. -% If the parameter is not empty, the |\empty| on the left is compared with the first token of the parameter. -% Assuming this token is not equivalent to |\empty| the |\else| section is executed, as desired. -% -% The mad way works if and only if the first token of the parameter is not equivalent to |\empty|. -% You must check if this meets your purpose. -% The two |\empty|s might be replaced by any other macro, which is not equivalent to the first token of the parameter. -% But the definition of that macro shouldn't be too complex since this would slow down the |\ifx|. -% In the examples above the mad version needs about $45\%$ of the natural's time. -% Note that this \TeX{}nique lost its importance from version 0.18 on. -% -% -% \subsection{Replacing characters}\label{iReplacingCharacters} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% In this section we define the macro -% \begin{macrosyntax} -% \item |\lst@ReplaceIn|\meta{macro}|{|\meta{replacement list $c_1m_1$\ldots$c_nm_n$}|}| -% \end{macrosyntax} -% Each character $c_i$ inside the given macro is replaced by the macro $m_i$. -% In fact, $c_i$ may be a character sequence (enclosed in braces and possibly containing macros), but $m_i$ must be a single macro which is not equivalent to |\empty| --- use |\relax| instead. -% |\lst@ReplaceIn\lst@arg{_\textunderscore {--}\textendash}| is allowed but not |\lst@ReplaceIn\lst@arg{\textunderscore_\textendash{--}}|. -% These restrictions can be dropped, see the TODO part below. -% -% We derive the main macro from \LaTeX's |\zap@space|: -% \begin{verbatim} -% \def\zap@space#1 #2{% -% #1% -% \ifx#2\@empty\else\expandafter\zap@space\fi -% #2}\end{verbatim} -% It is called like this: -% \begin{verbatim} -% \zap@space Some characters with(out) sense and \@empty -% \expandafter\zap@space\lst@arg{} \@empty -% \edef\lst@arg{\expandafter\zap@space\lst@arg{} \@empty}\end{verbatim} -% Note that |{}|\textvisiblespace\ produces a space holding up the syntax of |\zap@space|: it's defined with a space between the two parameters. -% If we want to replace a space by a visible space, we could use -% \begin{verbatim} -% \def\lst@temp#1 #2{% -% #1% -% \ifx#2\@empty\else % -% \noexpand\textvisiblespace % -% \expandafter\lst@temp % -% \fi #2}\end{verbatim} -% The additional |\noexpand\textvisiblespace| inserts visible spaces where spaces have been. -% We want to replace several characters and thus have to save our intermediate results. -% So we will follow the third '|\edef|' example. -% But there is some danger: After replacing the first character, the macro $m_1$ will expand inside the next |\edef|. -% Knowing that letters don't expand, we simply say that $m_1$ is a letter. -% Such changes must be local, so \ldots -% -% \begin{macro}{\lst@ReplaceIn} -% we open a group, store the original macro contents in |\@gtempa| and start a loop. -% Afterwards we close the group and assign the modified character string to our given macro. -% \begin{macrocode} -\def\lst@ReplaceIn#1#2{% - \bgroup \global\let\@gtempa#1% - \lst@ReplaceIn@#2\@empty\@empty % - \egroup \let#1\@gtempa} -% \end{macrocode} -% If we haven't reached the end of the list (the two |\@empty|s), we let the macro $m_i$ be a letter and define an appropiate macro to replace the character (sequence) |#2| by the macro |#3|. -% \begin{macrocode} -\def\lst@ReplaceIn@#1#2{% - \ifx\@empty#2\else % - \let#2=a% - \def\lst@temp##1#1##2{##1% - \ifx\@empty##2\else % - #2\expandafter\lst@temp % - \fi ##2}% -% \end{macrocode} -% Now we call that macro using |\xdef| (since the changes in |\@gtempa| must exist after closing a group). -% Finally we continue the loop. -% \begin{macrocode} - \xdef\@gtempa{\expandafter\lst@temp\@gtempa#1\@empty}% - \expandafter\lst@ReplaceIn@ % - \fi} -% \end{macrocode} -% \begin{TODO} -% This |\lst@ReplaceIn| is currently sufficient. -% If we need to replace character sequences by character sequences (instead of single macros), we have to make some minor changes. -% The main difference is that we build the new contents inside |\lst@temp| instead of using |\edef|. -% Note that the improved version is much slower than the macros above.\vspace*{-\baselineskip} -% \begin{verbatim} -%\def\lst@ReplaceIn#1#2{\lst@ReplaceIn@#1#2\@empty\@empty} -%\def\lst@ReplaceIn@#1#2#3{% -% \ifx\@empty#3\else % -% \def\lst@temp##1#2##2{% -% \ifx\@empty##2% -% \lst@lAddTo#1{##1}% -% \else % -% \lst@lAddTo#1{##1#3}% -% \expandafter\lst@temp % -% \fi ##2}% -% \let\@tempa#1\let#1\@empty % -% \expandafter\lst@temp\@tempa#2\@empty % -% \expandafter\lst@ReplaceIn@\expandafter#1% -% \fi}\end{verbatim} -% \removelastskip -% Even here you will have a problem replacing a single brace, if it has the meaning of opening or closing a group: -% You can't enter it as an argument! -% \end{TODO} -% \end{macro} -% -% \begin{macro}{\lst@DeleteKeysIn} -% We define another macro, which looks quite similar to |\lst@ReplaceIn|. -% The arguments are two macros containing a comma separated keyword list. -% All keywords in the second list are removed from the first. -% \begin{macrocode} -\def\lst@DeleteKeysIn#1#2{% - \bgroup \global\let\@gtempa#1% - \let\lst@dollar=A\let\lst@minus=B\let\lst@underscore=C% - \expandafter\lst@DeleteKeysIn@#2,\relax,% - \egroup \let#1\@gtempa} -% \end{macrocode} -% To terminate the loop we remove the very last |\lst@DeleteKeysIn@| with |\@gobble|. -% \begin{macrocode} -\def\lst@DeleteKeysIn@#1,{% - \ifx\relax#1\@empty % - \expandafter\@gobble % - \else % - \ifx\@empty#1\@empty\else % - \def\lst@temp##1,#1##2{##1\ifx\@empty##2\else % - \ifx,##2\else #1\fi \expandafter\lst@temp\fi ##2}% - \xdef\@gtempa{% - \expandafter\lst@temp\expandafter,\@gtempa,#1\@empty}% - \fi % - \fi % - \lst@DeleteKeysIn@} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Looking ahead for character sequences} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@IfNextChars} -% The macro |\@ifnextchar|\meta{single character}|{|\meta{then part}|}{|\meta{else part}|}| from the \LaTeX{} kernel is well known: -% Whether or not the character behind the three arguments --- usually a character from the 'user input stream' --- equals the given single character the 'then' or 'else' part is executed. -% We define a macro which looks for an arbitrary character sequence stored in a macro:{} -% \begin{macrosyntax} -% \item |\lst@IfNextChars|\meta{macro}|{|\meta{then part}|}{|\meta{else part}|}| -% \end{macrosyntax} -% Note an important difference: -% \LaTeX's |\@ifnextchar| doesn't remove the character behind the arguments, but we remove the characters until it is possible to decide whether the 'then' or 'else' part must be executed. -% However, we save these characters in a macro called |\lst@eaten|, so they can be inserted if necessary. -% -% We save the arguments and call the macro which does the comparisons. -% \begin{macrocode} -\def\lst@IfNextChars#1#2#3{% - \let\lst@tofind#1\def\@tempa{#2}\def\@tempb{#3}% - \let\lst@eaten\@empty \lst@IfNextChars@} -% \end{macrocode} -% This macro reads the next character from the input and compares it with the next character from |\lst@tofind|. -% We append |#1| to the eaten characters and get the character we are looking for (via |\lst@IfNextChars@@|). -% \begin{macrocode} -\def\lst@IfNextChars@#1{% - \lst@lAddTo\lst@eaten{#1}% - \expandafter\lst@IfNextChars@@\lst@tofind\relax % - \ifx #1\lst@temp % -% \end{macrocode} -% If the characters are the same, we either execute |\@tempa| or continue the test. -% \begin{macrocode} - \ifx\lst@tofind\@empty % - \let\lst@next\@tempa % - \else % - \let\lst@next\lst@IfNextChars@ % - \fi % - \expandafter\lst@next % - \else % -% \end{macrocode} -% If the characters are different, we have to call |\@tempb|. -% \begin{macrocode} - \expandafter\@tempb % - \fi} -% \end{macrocode} -% Finally comes the subsubmacro |\lst@IfNextChars@@| used above, which assigns the next character to |\lst@temp| and the rest upto |\relax| to |\lst@tofind|. -% If the implementation is not clear, read the last sentence again. -% \begin{macrocode} -\def\lst@IfNextChars@@#1#2\relax{\let\lst@temp#1\def\lst@tofind{#2}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@IfNextCharsArg} -% The difference between |\lst@IfNextChars| and the macro here is that the first parameter is a character sequence and not a macro. -% Moreover, the character sequence is made active here. -% \begin{macrocode} -\def\lst@IfNextCharsArg#1#2#3{% - \lst@MakeActive{#1}\let\lst@tofind\lst@arg % - \def\@tempa{#2}\def\@tempb{#3}% - \let\lst@eaten\@empty \lst@IfNextChars@} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Catcode changes of characters already read}\label{iCatcodeChangesOfCharactersAlreadyRead} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% Here we define two important macros: -% \begin{macrosyntax} -% \item |\lst@MakeActive{|\meta{character sequence}|}| -% -% stores the character sequence in |\lst@arg|, but all characters become active. -% The string must \emph{not} contain a begin group, end group or escape character (|{}\|); it may contain a left brace, right brace or backslash with other meaning (=catcodes). -% This command would be quite surplus if \meta{character sequence} is not already read by \TeX{} (since such catcodes can be changed easily). -% It is explicitly allowed that the charcaters have been read, e.g.\ in |\def\test{\lst@MakeActive{ABC}}| |\test|! -% -% Note that |\lst@MakeActive| changes |\lccode|s 0--9 without restoring them. -% \item |\lst@IfNextCharActive{|\meta{then part}|}{|\meta{else part}|}| -% -% executes 'then' part if next character behind the arguments is active, and the 'else' part otherwise. -% \end{macrosyntax} -% \TeX{} knows sixteen different catcodes, which say whether a character is a letter, a space, a math shift character, subscript character, and so on. -% A character gets its catcode right after reading it and \TeX{} has no primitive command to change a catcode of characters already read. -% Consider for example |\def\mathmode#1{$#1$}|. -% After that definition there is no chance to say: ''\emph{Print} the two dollar signs and the argument between instead of entering math mode''. -% And if we write |\mathmode{a_i}| and have just entered the macro |\mathmode|, the argument |a_i| is read and it's too late to change the meaning of the subscript character to a printable underbar, for example. -% But that's not the whole truth: We can change character-catcodes of an argument. -% In fact, we replace the characters by characters with same ASCII codes but different catcodes. -% It's not the same but suffices since the result is the same. -% Here we treat the very special case that all characters become active. -% A prototype macro would be -% \begin{verbatim} -% \def\MakeActive#1{\lccode`\~=`#1\lowercase{\def\lst@arg{~}}}|\end{verbatim} -% But this macro handles a single character only: -% The |\lowercase| changes the ASCII code of |~| to that of |#1| since we have said that |~| is the lower case version of |#1|. -% Fortunately the |\lowercase| doesn't change the catcode, so we have an active version of |#1|. -% Note that |~| is usually active. -% -% \begin{macro}{\lst@MakeActive} -% We won't do this character by character. -% To increase speed we change nine characters at the same time (if nine characters are left). -% We get the argument, empty |\lst@arg| and begin a loop: -% \begin{macrocode} -\def\lst@MakeActive#1{% - \let\lst@arg\@empty \lst@MakeActive@#1% - \relax\relax\relax\relax\relax\relax\relax\relax\relax} -% \end{macrocode} -% There are nine |\relax|es since |\lst@MakeActive@| has nine parameters and we don't want any problems in the case that |#1| is empty. -% We need nine active characters now instead of a single |~|. -% We make these catcode changes local and define the coming macro |\global|. -% \begin{macrocode} -\begingroup -\catcode`\^^@=\active \catcode`\^^A=\active \catcode`\^^B=\active % -\catcode`\^^C=\active \catcode`\^^D=\active \catcode`\^^E=\active % -\catcode`\^^F=\active \catcode`\^^G=\active \catcode`\^^H=\active % -% \end{macrocode} -% First we |\let| the next operation be |\relax|. -% This aborts our loop for processing all characters (default and possibly changed later). -% Then we look if we have at least one character. -% If this is not the case, the loop terminates and all is done. -% \begin{macrocode} -\gdef\lst@MakeActive@#1#2#3#4#5#6#7#8#9{\let\lst@next\relax % - \ifx#1\relax % - \else \lccode`\^^@=`#1% -% \end{macrocode} -% Otherwise we say that |^^@|=chr(0) is the lower case version of the first character. -% Then we test the second character. -% If there is none, we append the lower case |^^@| to |\lst@arg|. -% Otherwise we say that |^^A|=chr(1) is the lower case version of the second character and we test the next argument, and so on. -% \begin{macrocode} - \ifx#2\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@}}% - \else \lccode`\^^A=`#2% - \ifx#3\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A}}% - \else \lccode`\^^B=`#3% - \ifx#4\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B}}% - \else \lccode`\^^C=`#4% - \ifx#5\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B^^C}}% - \else \lccode`\^^D=`#5% - \ifx#6\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B^^C^^D}}% - \else \lccode`\^^E=`#6% - \ifx#7\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B^^C^^D^^E}}% - \else \lccode`\^^F=`#7% - \ifx#8\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B^^C^^D^^E^^F}}% - \else \lccode`\^^G=`#8% - \ifx#9\relax % - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B^^C^^D^^E^^F^^G}}% -% \end{macrocode} -% If nine characters are present, we append (lower case versions of) nine active characters and call this macro again via redefining |\lst@next|. -% \begin{macrocode} - \else \lccode`\^^H=`#9% - \lowercase{\lst@lAddTo\lst@arg{^^@^^A^^B^^C^^D^^E^^F^^G^^H}}% - \let\lst@next\lst@MakeActive@ % - \fi \fi \fi \fi \fi \fi \fi \fi \fi % - \lst@next} -\endgroup -% \end{macrocode} -% This |\endgroup| restores the catcodes of chr(0)--chr(8), but not the catcodes of the characters inside |\lst@MakeActive@| since they are already read. -% \end{macro} -% -% \begin{macro}{\lst@IfNextCharActive} -% The implementation is easy now: We compare the character |#3| with its active version |\lowercase{~}|. -% Note that the right brace between |\ifx~| and |#3| ends the |\lowercase|. -% The |\egroup| before restores the |\lccode|. -% \begin{macrocode} -\def\lst@IfNextCharActive#1#2#3{% - \bgroup \lccode`\~=`#3\lowercase{\egroup % - \ifx~}#3% - \def\lst@next{#1#3}% - \else % - \def\lst@next{#2#3}% - \fi \lst@next} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{An application to \ref{iCatcodeChangesOfCharactersAlreadyRead}}\label{iAnApplicationTo} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% We need a brief look on how the listing processing works. -% Right before processing a listing we redefine all characters, for example to preserve successive spaces or to give the tabulator a different meaning. -% More precisely, each character becomes active in the sense of \TeX, but that's not so important now. -% After the listing we switch back to the original meanings and all is fine. -% If an environment is used inside an argument the listing is already read when the environment is executed and we can do nothing to preserve the characters. -% However, (under certain circumstances) the environment can be used inside an argument --- that's at least what I've said in the user's guide. -% And now we have to work for it coming true. -% We define the macro -% \begin{macrosyntax} -% \item |\lstenv@AddArg{|\meta{\TeX{} material (already read)}|}| -% \end{macrosyntax} -% which \emph{appends} a 'verbatim' version of the argument to |\lstenv@arg|, but all appended characters are active. -% Since it's not a character to character conversion, 'verbatim' needs to be explained. -% All characters can be typed in as they are, except |\|, |{|, |}| and |%|. -% If you want one of these, you must write |\\|, |\{|, |\}| or |\%| instead. -% If two spaces should follow each other, the second (third, fourth, \ldots) space must be entered as |\|\textvisiblespace. -% -% \begin{macro}{\lstenv@AddArg} -% We call a submacro (similar to |\zap@space|) to preserve single spaces. -% \begin{macrocode} -\def\lstenv@AddArg#1{\lstenv@AddArg@#1 \@empty} -% \end{macrocode} -% We will need an active space: -% \begin{macrocode} -\begingroup \lccode`\~=`\ \relax \lowercase{% -% \end{macrocode} -% We make all characters upto the first space (with catcode 10) active and append these (plus an active space) to |\lstenv@arg|. -% If we haven't found the end |\@empty| of the input, we continue the process. -% \begin{macrocode} -\gdef\lstenv@AddArg@#1 #2{% - \lst@MakeActive{#1}% - \ifx\@empty#2\expandafter% - \lst@lAddTo\expandafter\lstenv@arg\expandafter{\lst@arg}% - \else \expandafter% - \lst@lAddTo\expandafter\lstenv@arg\expandafter{\lst@arg~}% - \expandafter\lstenv@AddArg@ % - \fi #2} -% \end{macrocode} -% Finally we end the |\lowercase| and close a group. -% \begin{macrocode} -}\endgroup -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{How to define \lst-aspects}\label{iHowToDefineLstAspects} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% This section contains commands used in defining the style and language aspects. -% There are two command classes: one extends the internal capabilities, and the other actually defines the aspects. -% \begin{macrosyntax} -% \item |\lst@Aspect{|\meta{aspect name}|}{|\meta{definition}|}| -% -% is the one and only command in the latter class. -% It defines the aspect using the \textsf{keyval} package. -% -% \item |\lst@AddToHook||{|\meta{name of hook}|}{|\meta{\TeX{} material}|}| -% -% \item |\lst@AddToHookAtTop||{|\meta{name of hook}|}{|\meta{\TeX{} material}|}| -% -% Both add \TeX{} material at predefined points. -% The first command appends the code, whereas the second places it in front of existing hook material. -% \end{macrosyntax} -% The following hooks are supported (possibly not up to date): -% \begin{center}\begin{tabular}{rp{0.6\linewidth}} -% name of hook & point/aim of execution\\ \hline -% |InitVars| & initializes variables each listing\\ -% |ExitVars| & deinits variables each listing\\ -% |OnExit| & executed at the very end of typesetting\\ -% |EveryLine| & called at the beginning of each line\\ -% |EOL| & executed after printing a source code line\\ -% |InitVarsEOL| & prepares variables for the next line\\ -% |EndGroup| & executed whenever the package closes a group (end of comment or string, e.g.)\\ -% |Output| & called before a printing unit with letters and digits is typeset\\ -% |OutputOther| & called before any other printing unit is typeset\\ -% |BeforeSelectCharTable| & executed before the package changes the character table\\ -% |SelectCharTable| & executed after the package has selected the standard character table\\ -% &\\ -% |SetStyle| & called before |\lststy@|\meta{style}\\ -% |SetLanguage| & called before |\lstlang@|\meta{language}|@|\meta{dialect}\\ -% \end{tabular}\end{center} -% For example, the hooks make keywords case insensitive (if necessary) before the package processes a listing and call the keyword style before a keyword is printed. -% -% \begin{macro}{\lst@Aspect} -% The command defines the aspect only if not already present. -% |\lst@ifnew| becomes true (if and) only if a new aspect is defined. -% \begin{macrocode} -\def\lst@Aspect#1{% - \@ifundefined{KV@lst@#1}% - {\let\lst@ifnew\iftrue}{\let\lst@ifnew\iffalse}% - \lst@ifnew % -% \lst@InfoInfo{New aspect `#1'}% - \else % -% \lst@InfoWarning{Gobble aspect `#1'}% - \expandafter\@gobblefour % - \fi % - \lstdefine@key{lst}{#1}} -% \end{macrocode} -% Now come renamed copies from two \textsf{keyval} macros, but the key definitions are made globally. -% \begin{macrocode} -\def\lstdefine@key#1#2{% - \@ifnextchar[{\lstKV@def{#1}{#2}}{\global\@namedef{KV@#1@#2}####1}} -\def\lstKV@def#1#2[#3]{% - \global\@namedef{KV@#1@#2@default\expandafter}\expandafter % - {\csname KV@#1@#2\endcsname{#3}}% - \global\@namedef{KV@#1@#2}##1} -% \end{macrocode} -% \begin{macrocode} -\let\lst@ifnew\iftrue % init -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@AddToHook} -% \begin{macro}{\lst@AddToHookAtTop} -% The definitions are mainly in terms of |\lst@AddTo| and |\lst@AddToAtTop|. -% But we test whether the hook already exists. -% \begin{macrocode} -\def\lst@AddToHook#1{% - \lst@ifnew % - \@ifundefined{lsthk@#1}{% -% \lst@InfoInfo{New hook `#1'}% - \expandafter\gdef\csname lsthk@#1\endcsname{}}{}% - \def\lst@next{\lst@AddToHook@\lst@AddTo{#1}}% - \expandafter\lst@next % - \else % - \expandafter\@gobble % - \fi} -% \end{macrocode} -% The submacro makes it possible to use \texttt{if}s inside the second argument (which is the third here). -% \begin{macrocode} -\long\def\lst@AddToHook@#1#2#3{% - \expandafter#1\csname lsthk@#2\endcsname{#3}} -% \end{macrocode} -% \begin{TODO} -% The usage of |\lst@ifnew| is still unsatisfactory: -% Defining an aspect and its hooks twice doesn't add the \TeX\ material a second time, but defining hooks and then the aspect would do so. -% \end{TODO} -% \begin{macrocode} -\def\lst@AddToHookAtTop#1{% - \lst@ifnew % - \@ifundefined{lsthk@#1}{% -% \lst@InfoInfo{New hook `#1'}% - \expandafter\gdef\csname lsthk@#1\endcsname{}}{}% - \def\lst@next{\lst@AddToHook@\lst@AddToAtTop{#1}}% - \expandafter\lst@next % - \else % - \expandafter\@gobble % - \fi} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@AddTo} -% \begin{macro}{\lst@AddToAtTop} -% These macros add the second argument to the macro |#1|. -% But the definition is global! -% \begin{macrocode} -\long\def\lst@AddTo#1#2{% - \expandafter\gdef\expandafter#1\expandafter{#1#2}} -% \end{macrocode} -% We need a couple of |\expandafter|s now. -% Simply note that we have\\ -% {\small\hspace*{2em} -% |\expandafter\gdef\expandafter#1\expandafter{\lst@temp|$\langle$\textit{contents of }|#1|$\rangle$|}| -% }\\ -% after the first phase of expansion. -% \begin{macrocode} -\def\lst@AddToAtTop#1#2{\def\lst@temp{#2}% - \expandafter\expandafter\expandafter\gdef % - \expandafter\expandafter\expandafter#1% - \expandafter\expandafter\expandafter{\expandafter\lst@temp#1}} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@lAddTo} -% A local version of |\lst@AddTo|. -% \begin{macrocode} -\def\lst@lAddTo#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} -% \end{macrocode} -% \end{macro} -% -% \begingroup -% \noindent Since some hooks are unused and never defined by the hook macros above, we define them here: -% \begin{macrocode} -\global\let\lsthk@OutputOther\@empty -\global\let\lsthk@SetStyle\@empty -\global\let\lsthk@SetLanguage\@empty -\global\let\lsthk@PreSet\@empty -\global\let\lsthk@PostSet\@empty -% \end{macrocode} -% \endgroup -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Interfacing with \textsf{keyval}} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% The \textsf{keyval} package passes the value via the one and only paramater |#1| to the definition part of the aspect macro. -% The following commands may be used to analyse the value. -% \begin{macrosyntax} -% \item |\lstKV@SetIfKey|\meta{macro}|{#1}| -% -% \meta{macro} becomes true (more precisely |\iftrue|) if the first character of |#1| equals |t| or |T|. -% It becomes false otherwise. -% -% \item |\lstKV@OptArg|\meta{submacro}|[|\meta{default arg.}|]{#1}| -% -% calls \meta{submacro} with |#1| and with inserted |[|\meta{default arg.}|]| if |#1| has no optional argument. -% \end{macrosyntax} -% -% \begin{macro}{\lstKV@SetIfKey} -% We simply test the first character of |#2|. -% \begin{macrocode} -\def\lstKV@SetIfKey#1#2{\lstKV@SetIfKey@#1#2\relax} -\def\lstKV@SetIfKey@#1#2#3\relax{\lowercase{% - \expandafter\let\expandafter#1% - \csname \ifx #2t}iftrue\else iffalse\fi\endcsname} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstKV@OptArg} -% We read the arguments and insert default if necesary, what else? -% \begin{macrocode} -\def\lstKV@OptArg#1[#2]#3{\lstKV@OptArg@{#1}{#2}#3\@} -\def\lstKV@OptArg@#1#2{% - \@ifnextchar[{\lstKV@OptArg@@{#1}}% - {\lstKV@OptArg@@{#1}[#2]}} -\def\lstKV@OptArg@@#1[#2]#3\@{#1[#2]{#3}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstset} -% Finally this main user interface macro: -% \begin{macrocode} -\def\lstset#1{\lsthk@PreSet\setkeys{lst}{#1}\lsthk@PostSet} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Internal modes}\label{iInternalModes} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@mode} -% \begin{macro}{\lst@EnterMode} -% \begin{macro}{\lst@LeaveMode} -% While typesetting a listing we will enter 'modes' to distinguish comments from strings, comment lines from single comments, \TeX\ comment lines from fixed comment lines, and so on. -% The counter |\lst@mode| keeps the current mode number. -% \begin{macrocode} -\newcount\lst@mode -% \end{macrocode} -% Each mode opens a group level, stores the mode number and execute mode specific tokens. -% Moreover we keep all these changes in mind (locally). -% \begin{macrocode} -\def\lst@EnterMode#1#2{% - \bgroup \lst@mode=#1\relax #2% - \lst@lAddTo\lst@entermodes{\lst@EnterMode{#1}{#2}}} -% \end{macrocode} -% Leaving a mode simply closes the group and calls the hook |\lsthk@EndGroup|. -% \begin{macrocode} -\def\lst@LeaveMode{\egroup\lsthk@EndGroup} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVars}{\let\lst@entermodes\@empty} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lst@NewMode} -% defines a new mode number. -% We simply use |\mathchardef| and advance the number in |\lst@newmode|, which is a macro --- we don't waste another counter. -% \begin{macrocode} -\def\lst@NewMode#1{% - \ifx\@undefined#1% - \global\mathchardef#1=\lst@newmode\relax % - \lst@mode=\lst@newmode\relax \advance\lst@mode\@ne % - \edef\lst@newmode{\the\lst@mode}% - \fi} -% \end{macrocode} -% We start with number 0. -% The negative range is reserved for nested comments. -% \begin{macrocode} -\def\lst@newmode{0} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@nomode} -% \begin{macro}{\lst@Pmode} -% The very first mode initializes |\lst@mode| (every listing). -% The other mode indicates active listing processing. -% \begin{macrocode} -\lst@NewMode\lst@nomode -\lst@AddToHook{InitVars}{\lst@modefalse \lst@mode\lst@nomode} -\lst@NewMode\lst@Pmode -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@modetrue} -% \begin{macro}{\lst@modefalse} -% If |\lst@ifmode| is true, no mode change is allowed --- except leaving the mode. -% \begin{macrocode} -\def\lst@modetrue{\let\lst@ifmode\iftrue} -\def\lst@modefalse{\let\lst@ifmode\iffalse} -% \end{macrocode} -% Note: |\lst@ifmode| is \emph{not} obsolete since |\lst@mode|$\neq$|\lst@nomode| does \emph{not} imply |\lst@ifmode|$=$|\iftrue|. -% And even the other implication is not true. -% It will happen that we enter a mode without setting |\lst@ifmode| true, and we'll set it true without assigning any mode! -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@InterruptModes} -% \begin{macro}{\lst@ReenterModes} -% Since we kept all mode changes in mind, it is possible two interrupt and re-enter the current mode. -% This is useful for \TeX\ comment lines, for example. -% \begin{macrocode} -\def\lst@InterruptModes{% - \ifx\lst@entermodes\@empty\else % - \global\let\lst@reenter\lst@entermodes % - \lst@LeaveAllModes % - \fi} -% \end{macrocode} -% The last |\ifx| is not necessay since empty |\lst@entermodes| implies that we don't leave any mode. -% But we need the |\ifx| in the following macro since empty |\lst@reenter| doesn't tell us anything about the current mode. -% \begin{macrocode} -\def\lst@ReenterModes{% - \ifx\lst@reenter\@empty\else % - \lst@LeaveAllModes \lst@reenter % - \global\let\lst@reenter\@empty % - \fi} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVars}{\global\let\lst@reenter\@empty} -% \end{macrocode} -% Note that these macros can't be nested: -% If you 'interrupt modes', enter some modes and say 'interrupt modes' again, then two 're-enter modes' will \emph{not} take you back in front of the first 'interrupt modes'. -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@LeaveAllModes} -% This is some kind of emergency macro. -% Since any mode is terminated by closing a group, leaving all modes means closing groups until the mode equals |\lst@nomode|. -% We'll need that macro to end a listing correctly. -% \begin{macrocode} -\def\lst@LeaveAllModes{% - \ifnum\lst@mode=\lst@nomode % - \expandafter\lsthk@EndGroup % - \else % - \expandafter\egroup\expandafter\lst@LeaveAllModes % - \fi} -\lst@AddToHook{ExitVars}{\lst@LeaveAllModes} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@egroupmode} -% We allocate a 'processing mode' and define a general purpose 'egroup' mode: close a group at end of line. -% \begin{macrocode} -\lst@NewMode\lst@egroupmode -\lst@AddToHook{EOL} - {\ifnum\lst@mode=\lst@egroupmode \lst@LeaveMode \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Styles and languages} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@Normalize} -% normalizes the contents of the macro |#1| by making all characters lower case and stripping off spaces. -% \begin{macrocode} -\def\lst@Normalize#1{% - \lowercase\expandafter{\expandafter\edef\expandafter#1% - \expandafter{\expandafter\zap@space#1 \@empty}}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstdefinestyle} -% The internal macro name of a style is |\lststy@|\emph{the style} (normalized). -% If called, it simply sets the keys to given values. -% \begin{macrocode} -\newcommand\lstdefinestyle[2]{% - \def\lst@temp{lststy@#1}\lst@Normalize\lst@temp % - \global\@namedef\lst@temp{\setkeys{lst}{#2}}} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{style} -% We give an error message if the necessary macro doesn't exist. -% \begin{macrocode} -\lst@Aspect{style} - {\def\lst@temp{lststy@#1}\lst@Normalize\lst@temp % - \@ifundefined\lst@temp % - {\PackageError{Listings}{Style `#1' undefined}% - {You might have misspelt the name here or before.^^J% - Type to proceed without changing the style.}}% -% \end{macrocode} -% Otherwise we execute the hook and call the macro. -% \begin{macrocode} - {\lsthk@SetStyle \csname\lst@temp\endcsname % -% \lst@InfoInfo{\expandafter\string % -% \csname\lst@temp\endcsname\space called}% - }} -% \end{macrocode} -% \begin{TODO} -% It's easy to crash the listings package with |style| (and also with |language|). -% Define |\lstdefinestyle{crash}{style=crash}| and write |\lstset{style=crash}|. -% \TeX's capacity will exceed (parameter stack size), sorry. -% Only bad girls use such recursive calls, but only good girls use this package. -% Thus this problem is of minor interest. -% \end{TODO} -% \end{aspect} -% -% \begin{macro}{\lstdefinelanguage} -% Nearly |\lstdefinestyle|: -% \begin{macrocode} -\newcommand\lstdefinelanguage[3][]{% - \def\@tempa{#2@#1}\lst@Normalize\@tempa % - \global\@namedef{lstlang@\@tempa}{\lstset{#3}}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstdefinedrvlanguage} -% The driver file \texttt{lstpascal.sty} contains a couple of Pascal dialects. -% It is unnecessary to hold all these dialects in memory if the user selects Standard Pascal only. -% There are different scopes: -% \begin{itemize} -% \item[--] All code outside any (style or language) definition is executed. -% Definitions should be |\global| since a driver file is input inside a group. -% Note also that |@| is a letter and |"| has catcode 12 (other). -% \item[--] All languages declared with |\lstdefinelanguage| are defined. -% \item[--] A language declared with |\lstdefinedrvlanguage| is defined if and only if the user has requested that language. -% \end{itemize} -% We either do the definition or drop it: -% \begin{macrocode} -\newcommand\lstdefinedrvlanguage[3][]{% - \def\@tempa{lstlang@#2@#1}\lst@Normalize\@tempa % - \ifx\@tempa\lst@requested % - \global\@namedef{\@tempa}{\lstset{#3}}% - \fi} -% \end{macrocode} -% \begin{TODO} -% The command syntax is liable to changes. -% I conjecture that it will be something like the following. -% \begin{macrosyntax} -% \item[0.2] |\lstdefinedrvlanguage|[|[|\meta{dialect}|]|]|{|\meta{language}|}|\\ -% \qquad[|[|\meta{base dialect}|]|]|{|\meta{base language (e.g.\ empty)}|}|\\ -% \qquad|{|\meta{key=value list}|}|\\ -% \qquad[|[|\meta{list of extras (keywordcomments,texcs,etc.)}|]|] -% \end{macrosyntax} -% To make 'extras' user assessible (without loading a language) a command |\lstloadextras| would be nice. -% In any case such a macro is needed to load the extras for the supported languages. -% All in all there should be the following files in future: The kernel |listings.sty|, the language definitions in |lstdrvrs.sty| (or |lstdef.sty|?) and extras in a file |lstextra.sty|. -% \end{TODO} -% \end{macro} -% -% \begin{macro}{\lstloadlanguages} -% We iterate through the list and locate and load each language. -% \begin{macrocode} -\def\lstloadlanguages#1{\lstloadlanguages@#1,\relax,} -\def\lstloadlanguages@#1,{% - \ifx\relax#1\@empty \else % - \lstKV@OptArg\lstloadlanguages@@[]{#1}% - \expandafter\lstloadlanguages@ % - \fi} -\def\lstloadlanguages@@[#1]#2{% - \lst@LocateLanguage[#1]{#2}% - \@ifundefined{\lst@requested}% - {{\catcode`\^^M=9\catcode`\"=12\makeatletter % - \input{\lst@driver.sty}}}% - {}} -\@onlypreamble\lstloadlanguages -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{language} -% If the language macro |\lstlang@|\emph{language}|@|\emph{dialect} doesn't exist, we must load the driver file. -% In that case the character |@| becomes a letter and we change the catcode of the double quote for compatibility with \texttt{german.sty}. -% Moreover we make the EOL character being ignored (which removes unwanted spaces if we've forgotten |%| at end of line). -% \begin{macrocode} -\lst@Aspect{language}{\lstKV@OptArg\lstlanguage@[]{#1}} -\def\lstlanguage@[#1]#2{% - \lst@LocateLanguage[#1]{#2}% - \@ifundefined{\lst@requested}% - {{\catcode`\^^M=9\catcode`\"=12\makeatletter % - \input{\lst@driver.sty}}}{}% -% \end{macrocode} -% We give an error message, if the language/dialect is undefined now. -% \begin{macrocode} - \@ifundefined{\lst@requested}% - {\PackageError{Listings}% - {\ifx\@empty\lst@dialect@\else \lst@dialect@\space of \fi % - \lst@language@\space undefined}{The driver file is not - loadable or doesn't support the language.^^J% - Type to proceed without changing the language.}}% -% \end{macrocode} -% Otherwise we execute the hook and select the language. -% \begin{macrocode} - {\lsthk@SetLanguage % -% \lst@InfoInfo{\expandafter\string % -% \csname\lst@requested\endcsname\space called}% - \csname\lst@requested\endcsname % - \def\lst@language{#1}\lst@Normalize\lst@language % - \def\lst@dialect{#2}\lst@Normalize\lst@dialect}} -% \end{macrocode} -% \end{aspect} -% -% \begin{aspect}{defaultdialect} -% We simply store the dialect. -% \begin{macrocode} -\lst@Aspect{defaultdialect}{\lstKV@OptArg\lstdefaultdialect@[]{#1}} -\def\lstdefaultdialect@[#1]#2{% - \def\lst@temp{#2}\lst@Normalize\lst@temp % - \global\@namedef{lstdd@\lst@temp}{#1}} -% \end{macrocode} -% \end{aspect} -% -% Languages might have a user name and a different internal name. -% Moreover we don't always use the standard driver file |lst|\meta{language}|.sty|. -% If the user writes |language=[fuu]foo|, this could mean that we select (internally) dialect |faa| of language |fee|, which is located in driver file |fii.sty|. -% We define the following macros: -% \begin{macrosyntax} -% \item |\lst@DriverLocation{|\meta{language}|}{|\meta{file name without extension}|}| -% -% Afterwards the package inputs the given driver file to load the language. -% -% \item |\lst@LocateLanguage[|\meta{dialect}|]{|\meta{language}|}| -% -% returns the driver file name in |\lst@driver| and |\lst@requested| contains name of driver macro (i.e.\ with prefix |lstlang@|, without backslash). -% The macro automatically chooses aliases. -% \end{macrosyntax} -% All language and dialect arguments are standardized, i.e.\ we make them free of spaces and lower case. -% -% \begin{macro}{\lstalias} -% The names are stored in |\lsta@|\emph{language}|@|\emph{dialect} and |\lstaa@|\emph{language}. -% \begin{macrocode} -\newcommand\lstalias{\@ifnextchar[{\lstalias@}{\lstalias@@}} -% \end{macrocode} -% \begin{macrocode} -\def\lstalias@[#1]#2[#3]#4{% - \def\lst@temp{lsta@#2@#1}\lst@Normalize\lst@temp % - \global\@namedef{\lst@temp}{#4@#3}} -% \end{macrocode} -% \begin{macrocode} -\def\lstalias@@#1#2{% - \def\lst@temp{lstaa@#1}\lst@Normalize\lst@temp % - \global\@namedef{\lst@temp}{#2}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@DriverLocation} -% We simply define a macro containing the file name. -% \begin{macrocode} -\def\lst@DriverLocation#1#2{% - \def\lst@temp{lstloc@#1}\lst@Normalize\lst@temp % - \expandafter\gdef\csname\lst@temp\endcsname{#2}% - \expandafter\lst@Normalize\csname\lst@temp\endcsname} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@LocateLanguage} -% First we test for a language alias, \ldots -% \begin{macrocode} -\def\lst@LocateLanguage[#1]#2{% - \def\lst@language@{#2}\lst@Normalize\lst@language@ % - \@ifundefined{lstaa@\lst@language@}{}% - {\edef\lst@language@{\csname lstaa@\lst@language@\endcsname}% - \lst@Normalize\lst@language@}% -% \end{macrocode} -% then we set the default dialect if necessary. -% \begin{macrocode} - \def\lst@dialect@{#1}% - \ifx\@empty\lst@dialect@ % - \@ifundefined{lstdd@\lst@language@}{}% - {\expandafter\let\expandafter\lst@dialect@ % - \csname lstdd@\lst@language@\endcsname}% - \fi % - \lst@Normalize\lst@dialect@ % -% \end{macrocode} -% Now we are ready for an alias for a language dialect. -% \begin{macrocode} - \edef\lst@requested{\lst@language@ @\lst@dialect@}% - \@ifundefined{lsta@\lst@requested}{}% - {\expandafter\let\expandafter\lst@requested % - \csname lsta@\lst@requested\endcsname % - \lst@Normalize\lst@requested}% -% \end{macrocode} -% Finally we get the driver file name and set the default dialect. -% \begin{macrocode} - \expandafter\lst@LocateLanguage@\lst@requested\relax} -\def\lst@LocateLanguage@#1@#2\relax{% - \edef\lst@driver{\@ifundefined{lstloc@#1}{lst#1}% - {\csname lstloc@#1\endcsname}}% - \ifx\@empty#2\@empty % - \@ifundefined{lstdd@#1}% - {\def\lst@dialect@{#2}}% - {\expandafter\let\expandafter\lst@dialect@ % - \csname lstdd@#1\endcsname}% - \fi % - \edef\lst@requested{lstlang@#1@\lst@dialect@}% - \lst@Normalize\lst@requested} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{Typesetting a listing} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@lineno} -% This counter keeps the current line number. -% A register is global if and only if the allocation line shows |% \global|. -% \begin{macrocode} -\newcount\lst@lineno \global\lst@lineno\@ne % \global -% \end{macrocode} -% The counter is initialized and advances every line (which means |\everypar|). -% \begin{macrocode} -\lst@AddToHook{InitVars} - {\global\lst@lineno\@ne % - \expandafter\everypar\expandafter{\the\everypar % - \global\advance\lst@lineno\@ne}} -% \end{macrocode} -% And we (try to) ensure correct line numbers for continued listings. -% \begin{macrocode} -\lst@AddToHook{ExitVars} - {\ifx\lst@NewLine\relax\else % - \global\advance\lst@lineno-2\relax % - \setbox\@tempboxa\vbox{\lst@NewLine}% - \fi} -% \end{macrocode} -% \begin{TODO} -% We only try to. -% If there is source code before |\end{lstlisting}|, it goes wrong: the line number is one too less. -% \end{TODO} -% \end{macro} -% -% \begin{macro}{\lst@PrintFileName} -% makes use of |\lst@ReplaceIn|: -% \begin{macrocode} -\def\lst@PrintFileName#1{% - \def\lst@arg{#1}% - \lst@ReplaceIn\lst@arg{_\textunderscore $\textdollar -\textendash}% - \lst@arg} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@SetName} -% As proposed by \lsthelper{Boris Veytsman}{boris@plmsc.psu.edu}{1998/03/22}{listing name accessible for user} the name of a listing (file name or argument to the environment) is user accessible now. -% It is set using this macro: -% \begin{macrocode} -\def\lst@SetName#1{% - \gdef\lst@intname{#1}\global\let\lstintname\lst@intname % - \let\lst@arg\lst@intname % - \lst@ReplaceIn\lst@arg{_\textunderscore $\textdollar -\textendash}% - \global\let\lstname\lst@arg} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{List of listings} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\listoflistings} -% Instead of imitating |\listoffigures| we make some local adjustments and call |\tableofcontents|. -% This has the advantage that redefinitions (e.g.\ without any |\MakeUppercase| inside) also take effect on the list of listings. -% \begin{macrocode} -\newcommand\listoflistings{\bgroup % - \let\contentsname\listlistingsname % - \let\lst@temp\@starttoc \def\@starttoc##1{\lst@temp{lol}}% - \tableofcontents \egroup} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\listlistingsname} -% Simply the header name: -% \begin{macrocode} -\newcommand\listlistingsname{Listings} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@AddToLOL} -% adds an entry to the list of listings. -% The first parameter is the name of the listing and the second is unused so far. -% \begin{macrocode} -\newcommand\lst@AddToLOL[2]{% - \ifx\@empty#1\@empty \else % - \addtocontents{lol}{\protect\lstlolline{#1}{#2}% - {\lst@language}{\thepage}}% - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstlolline} -% prints one 'lol' line. -% Using |\lst@PrintFileFile| removes a bug first reported by \lsthelper{Magne Rudshaug}{magne@ife.no}{1998/01/09}{_ and list of listings}. -% \begin{macrocode} -\newcommand\lstlolline[4]{% - \@dottedtocline{1}{1.5em}{2.3em}{\lst@PrintFileName{#1}}{#4}} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Init and EOL} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% We need some macros to initialize registers and variables before typesetting a listing and for the update every line. -% -% \begin{macro}{\lst@Init} -% The argument |#1| (assigned at the end) is either |\relax| or |\lstenv@backslash| since the backslash has a special meaning for the environment. -% The line number is used as current label (proposed by \lsthelper{Boris Veytsman}{boris@plmsc.psu.edu}{1998/03/25}{make line numbers referenced via \label and \ref}). -% The end of line character chr(13)=|^^M| controls the processing, see the definition of |\lst@MProcessListing| below. -% The vertical space in the macro code is for clarity. -% \begin{macrocode} -\def\lst@Init#1{% - \begingroup \normalbaselines \smallbreak % - \def\@currentlabel{\the\lst@lineno}% - \lst@prelisting % -% \end{macrocode} -% \begin{macrocode} - \lsthk@BeforeSelectCharTable % - \normalbaselines \everypar{\lsthk@EveryLine}% - \lsthk@InitVars \lsthk@InitVarsEOL % -% \end{macrocode} -% \begin{macrocode} - \csname lstPre@\lst@language\endcsname % - \csname lstPre@\lst@language @\lst@dialect\endcsname % - \lstCC@Let{"000D}\lst@MProcessListing % - \let\lstCC@Backslash#1% - \lst@EnterMode{\lst@Pmode}{\lst@SelectCharTable}} -% \end{macrocode} -% Note: From version 0.19 on 'listing processing' is implemented as an internal mode, namely a mode with special character table. -% \begin{macrocode} -\lst@AddToHook{InitVars} - {\rightskip\z@ \leftskip\z@ \parfillskip=0pt plus 1fil % - \let\par\@@par} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@DeInit} -% Here we output the remaining characters, update some variables and do some other things. -% \begin{macrocode} -\def\lst@DeInit{% - \lst@PrintToken \lst@EOLUpdate \par\removelastskip % - \lsthk@ExitVars % - \smallbreak\lst@postlisting % - \endgroup} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@EOLUpdate} -% This macro seems to be obsolete since in version 0.19 it degenerates to -% \begin{macrocode} -\def\lst@EOLUpdate{\lsthk@EOL \lsthk@InitVarsEOL}% -% \end{macrocode} -% But in future it might come in handy again. -% \end{macro} -% -% \begin{macro}{\lst@MProcessListing} -% This is what we have to do at EOL while processing a listing. -% We output all remaining characters and update the variables. -% We call |\endinput| if the next line number is greater than the last printing line. -% Finally we gobble characters to come to beginning of line. -% \begin{macrocode} -\def\lst@MProcessListing{% - \lst@PrintToken \lst@EOLUpdate % - \ifnum\lst@lastline<\lst@lineno \expandafter\endinput \fi % - \lst@BOLGobble} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@BOLGobble} -% But this is initially |\relax|. -% \begin{macrocode} -\let\lst@BOLGobble\relax -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{The input command} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{TODO} -% There is a conflict concerning |\lst@firstline|: It contains either the line number of the first code line or line number. -% This must be clarified before |lstlisting| can use the keys |first| and |last|. -% \end{TODO} -% -% \begin{aspect}{print} -% \begin{aspect}{first} -% \begin{aspect}{last} -% These aspects affect the input command only, not the environment. -% \begin{macrocode} -\lst@Aspect{print}[t]{\lstKV@SetIfKey\lst@ifprint{#1}} -\lst@Aspect{first}{\def\lst@firstline{#1}} -\lst@Aspect{last}{\def\lst@lastline{#1}} -\lstset{print=true}% init -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% -% \begin{macro}{\lstinputlisting} -% We define the main command. -% First we take care of the optional paramater and set it to $[1,9999999]$ if none is given. -% \begin{macrocode} -\newcommand\lstinputlisting[2][]{% - \begingroup % - \def\lst@firstline{1}\def\lst@lastline{9999999}\lstset{#1}% - \IfFileExists{#2}{\lst@InputListing{#2}}% - {\filename@parse{#2}% - \edef\reserved@a{\noexpand\lst@MissingFileError - {\filename@area\filename@base}% - {\ifx\filename@ext\relax tex\else\filename@ext\fi}}% - \reserved@a}% - \endgroup % - \lsthk@OnExit} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@MissingFileError} -% is a derivation of \LaTeX's |\@missingfileerror|: -% \begin{macrocode} -\def\lst@MissingFileError#1#2{% - \typeout{^^J! Package Listings Error: File `#1.#2' not found.^^J^^J% - Type X to quit or to proceed,^^J% - or enter new name. (Default extension: #2)^^J}% - \message{Enter file name: }% - {\endlinechar\m@ne \global\read\m@ne to\@gtempa}% -% \end{macrocode} -% Typing |x| or |X| exits. -% \begin{macrocode} - \ifx\@gtempa\@empty \else % - \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi - \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi -% \end{macrocode} -% In all other cases we try the new file name (with default extension). -% \begin{macrocode} - \filename@parse\@gtempa % - \edef\filename@ext{% - \ifx\filename@ext\relax#2\else\filename@ext\fi}% - \edef\reserved@a{\noexpand\IfFileExists % - {\filename@area\filename@base.\filename@ext}% - {\noexpand\lst@InputListing % - {\filename@area\filename@base.\filename@ext}}% - {\noexpand\lst@MissingFileError - {\filename@area\filename@base}{\filename@ext}}}% - \expandafter\reserved@a % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@InputListing} -% The one and only argument is the file name. -% We either add this name to the list of listings or the name plus a bullet to indicate that the listing has been skipped. -% Note that |\lst@Init| takes |\relax| as an argument. -% \begin{macrocode} -\def\lst@InputListing#1{% - \lst@SetName{#1}% - \lst@ifprint % - \lst@AddToLOL{#1}{}% - \lst@Init\relax \lst@SkipUptoFirst \input{#1}\lst@DeInit % - \else % - \lst@AddToLOL{#1$^\bullet$}{}% - \begin{center}% - \footnotesize --- Listing of #1 has been skipped. --- - \end{center}% - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@SkipUptoFirst} -% The end of line character either processes the listing or is responsible for skipping lines upto first printing line. -% \begin{macrocode} -\def\lst@SkipUptoFirst{% - \ifnum\lst@lineno=\lst@firstline\else % -% \end{macrocode} -% To skip input lines we begin a new group level (which makes our changes local) and prohibit mode changes. -% We redefine the end of line character and all output macros becomes equivalent to |\relax|, i.e.\ nothing is typeset. -% \begin{macrocode} - \bgroup \lst@modetrue % - \let\lst@Output\relax \let\lst@OutputOther\relax % - \let\lst@GotoTabStop\relax % - \lstCC@Let{"000D}\lst@MSkipUptoFirst % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@MSkipUptoFirst} -% At the moment we use a fast and not 'everything is looking good' way. -% When |\lst@MSkipUptoFirst| is executed, one input line has already been skipped. -% We end the group opened in |\lst@SkipUptoFirst|. -% This restores the definition of the end of line character chr(13). -% Then we look whether to skip more lines or not. -% \begin{macrocode} -\def\lst@MSkipUptoFirst{\egroup % - \global\advance\lst@lineno\@ne % - \ifnum\lst@lineno=\lst@firstline\else % - \expandafter\lst@MSkipUptoFirst@ % - \fi} -% \end{macrocode} -% The argument of |\lst@MSkipUptoFirst@| ends with the next active chr(13), which means that the next input line is read. -% Again we look whether to skip more lines or not. -% \begin{macrocode} -\begingroup \lccode`\~=`\^^M% -\lowercase{\gdef\lst@MSkipUptoFirst@#1~}{% - \global\advance\lst@lineno\@ne % - \ifnum\lst@lineno=\lst@firstline\else % - \expandafter\lst@MSkipUptoFirst@ % - \fi} -\endgroup -% \end{macrocode} -% \begin{TODO} -% This definition gives rise to a ''runaway argument'' if first line doesn't exist (no |^^M| is found). -% -% We could define |\lst@MSkipUptoFirst| exactly as |\lst@MProcessListing|, except that we start the normal line processing if we reach the first printing line. -% In that case all comments and strings are processed, but not output. -% Everything looks good, even if the first printing line is in the middle of a comment. -% We need to do the following things: -% \begin{enumerate} -% \item Install an \texttt{if} to choose between speed and good looking, which must be noticed in |\lst@SkipUptoFirst|. -% There we must (locally) switch to |\lsttexcloff|. -% \item Call |\lst@BeginDropOutput{\lst@nomode}| in |\lst@SkipUptoFirst| instead of |\bgroup\lst@modetrue| and assigning |\relax|es. -% \item Define |\lst@MSkipUptoFirstExact| by copying |\lst@MProcessListing| and renaming it. -% Replace the |\ifnum| by\vspace*{-0.5\baselineskip} -% \begin{verbatim} -%\ifnum\lst@lineno=lst@firstline % -% \lst@LeaveMode \global\lst@column\z@ \global\lst@pos\z@ % -%\fi\end{verbatim} -% \item Make the fine tuning if necessary. -% \end{enumerate} -% \end{TODO} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{The environment}\label{iTheEnvironment} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@Environment} -% This is the first attempt to provide a general macro, which defines the \lst-environments. -% The syntax comes from \LaTeX's |\newenvironment|: -% \begin{macrosyntax} -% \item |\lst@Environment{|\meta{name}|}[|\meta{number of parameters}|][|\meta{opt.~default~arg.}|]\is|\\ -% |{|\meta{begin code}|}|\\ -% |{|\meta{end code}|}| -% \end{macrosyntax} -% Note the additional |\is|. -% I should mention that such environments could also be used in command fashion -% \begin{verbatim} -% \lstlisting{my name} -% Here comes the listing. -% \endlstlisting\end{verbatim} -% But now the implementation. -% We define undefined environments only: -% \begin{macrocode} -\def\lst@Environment#1#2\is#3#4{% - \@ifundefined{#1}{\lst@Environment@{#1}{#2}{#3}{#4}}% - {% -% \lst@InfoWarning{Multiple environment `#1'}% - }} -% \end{macrocode} -% A lonely 'end environment' produces an error: -% \begin{macrocode} -\def\lst@Environment@#1#2#3#4{% - \global\@namedef{end#1}{\lstenv@Error{#1}}% -% \end{macrocode} -% The 'main' environment macro defines the environment name (for later use) and calls a submacro (getting all arguments). -% We open a group and redefine the (active) EOL character to be |\relax|. -% This ensures |\@ifnextchar[| not to read characters of the listing --- it reads the active EOL instead. -% \begin{macrocode} - \global\@namedef{#1}{% - \def\lstenv@name{#1}% - \begingroup \lstCC@Let{"000D}\relax % - \csname#1@\endcsname}% -% \end{macrocode} -% The submacro is defined via |\new@command|. -% We misuse |\l@ngrel@x| to make the definition |\global|. -% The submacro defines the first and last line, which are possibly changed by the user's \meta{begin code} |#3|. -% \begin{macrocode} - \let\l@ngrel@x\global % - \expandafter\new@command\csname#1@\endcsname#2% - {\def\lst@firstline{1}\def\lst@lastline{9999999}% - #3% -% \end{macrocode} -% The definition of the string which terminates the environment (|end{lstlisting}| or |endlstlisting|, for example) needs some care since the braces must not have catcodes 1 and 2 (or |\lst@MakeActive| fails). -% We enter them as |\{| and |\}| (with preceding |\noexpand|s). -% \begin{macrocode} - \ifx\@currenvir\lstenv@name % - \edef\lst@temp{end\noexpand\{\lstenv@name\noexpand\}}% - \else % - \edef\lst@temp{end\lstenv@name}% - \fi % - \expandafter\lst@MakeActive\expandafter{\lst@temp}% - \let\lstenv@endstring\lst@arg % -% \end{macrocode} -% We redefine (locally) 'end environment' inside the 'begin environment' macro since ending is legal now. -% Note that the redefinition also works inside a \TeX\ comment line. -% \begin{macrocode} - \@namedef{end#1}{\lst@DeInit #4\endgroup \lsthk@OnExit}% -% \end{macrocode} -% Finally the 'begin environment' macro starts the processing. -% \begin{macrocode} - \lstenv@Process}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@Error} -% have been used above. -% \begin{macrocode} -\def\lstenv@Error#1{\PackageError{Listings}{Extra \string\end#1}% - {I'm ignoring this, since I wasn't doing a \csname#1\endcsname.}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@backslash} -% We have the problem of finding end of environment, and we've already defined the 'end environment' string. -% Coming to a backslash we either end the listing or process a backslash and insert the eaten characters again. -% (Eaten means that these characters have been read (and removed) from the input to test for |\lstenv@endstring|.) -% \begin{macrocode} -\def\lstenv@backslash{% - \lst@IfNextChars\lstenv@endstring % - {\lstenv@End}% - {\lsts@backslash \lst@eaten}}% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@End} -% This macro is called by the backslash macro and terminates a listing environment: -% We call the 'end environment' macro as a command or using |\end|. -% \begin{macrocode} -\def\lstenv@End{% - \ifx\@currenvir\lstenv@name % - \edef\lst@next{\noexpand\end{\lstenv@name}}% - \else % - \def\lst@next{\csname end\lstenv@name\endcsname}% - \fi % - \lst@next} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@Process} -% First some initialization, then call a submacro. -% \begin{macrocode} -\def\lstenv@Process{% - \lst@Init\lstenv@backslash % - \global\lst@lineno\lst@firstline\relax % - \let\lstenv@ifdropped\iffalse \lstenv@Process@} -% \end{macrocode} -% \begin{macrocode} -\def\lstenv@droppedtrue{\let\lstenv@ifdropped\iftrue} -% \end{macrocode} -% We execute either |\lstenv@ProcessM| or |\lstenv@ProcessJ| according to whether we find an active EOL or a nonactive |^^J|. -% \begin{macrocode} -\begingroup \lccode`\~=`\^^M% -\lowercase{\gdef\lstenv@Process@#1{% - \ifx~#1% - \expandafter\lstenv@ProcessM % - \else\ifx^^J#1% - \expandafter\expandafter\expandafter\lstenv@ProcessJ % - \else % - \lstenv@droppedtrue % - \expandafter\expandafter\expandafter\lstenv@Process@ % - \fi \fi} -}\endgroup -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@DroppedWarning} -% gives a warning if characters have been dropped. -% \begin{macrocode} -\def\lstenv@DroppedWarning{% - \lstenv@ifdropped % - \PackageWarning{Listings}{Text dropped after begin of listing}% - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@ProcessM} -% There is nothing to do if we've found an active EOL, except giving a warning if necessary. -% \begin{macrocode} -\def\lstenv@ProcessM{\lstenv@DroppedWarning \lst@BOLGobble} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@ProcessJ} -% Now comes the horrible scenario: A listing inside an argument. -% We've already worked in section \ref{iAnApplicationTo} for this. -% Here we must get the listing, i.e.\ all characters upto 'end environment'. -% We must distinguish the cases 'command fashion' and 'environment'. -% \begin{macrocode} -\def\lstenv@ProcessJ{% - \lstenv@DroppedWarning % - \lst@DontEscapeToLaTeX % - \let\lstenv@arg\@empty % - \ifx\@currenvir\lstenv@name % - \expandafter\lstenv@ProcessJEnv % - \else % -% \end{macrocode} -% The first case is pretty simple: The code is terminated by |\end|\meta{name of environment}. -% Thus we expand that control sequence before defining a temporary macro, which gets all characters upto that control sequence. -% Inside the temporary macro we assign the argument and call a submacro doing the rest. -% \begin{macrocode} - \expandafter\def\expandafter\lst@temp\expandafter##1% - \csname end\lstenv@name\endcsname{% - \lstenv@AddArg{##1}\lstenv@ProcessJ@}% -% \end{macrocode} -% Back to the definition of |\lstenv@ProcessJ| we call the temporary macro. -% \begin{macrocode} - \expandafter\lst@temp % - \fi} -% \end{macrocode} -% We must append an active backslash and the 'end string' to |\lstenv@arg|. -% So all other processing won't notice that the code has been inside an argument. -% But the EOL character is chr(10)=|^^J| now and not chr(13). -% Finally we execute |\lstenv@arg| to typeset the listing. -% Note that we need |\lccode`\A=`\A| to preserve the argument of |\lstCC@Let| --- but obviously we could also write |\lstCC@Let{10}|\ldots -% \begin{macrocode} -\begingroup \lccode`\~=`\\ \lccode`\A=`\A -\lowercase{\gdef\lstenv@ProcessJ@{% - \expandafter\lst@lAddTo\expandafter\lstenv@arg % - \expandafter{\expandafter\ \expandafter~\lstenv@endstring}% - \lstCC@Let{"000A}\lst@MProcessListing \def\lst@BOLGobble##1{}% - \expandafter\lst@BOLGobble\lstenv@arg} -}\endgroup -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstenv@ProcessJEnv} -% Here we get all characters upto an |\end| (and the following argument). -% If the following argument equals |\lstenv@name|, we have found the end of environment and start typesetting. -% \begin{macrocode} -\def\lstenv@ProcessJEnv#1\end#2{\def\lst@temp{#2}% - \ifx\lstenv@name\lst@temp % - \lstenv@AddArg{#1}% - \expandafter\lstenv@ProcessJ@ % - \else % -% \end{macrocode} -% Otherwise we append the characters including the eaten |\end| and the eaten argument to current |\lstenv@arg|. -% And we look again for the end of environment. -% \begin{macrocode} - \lstenv@AddArg{#1\\end\{#2\}}% - \expandafter\lstenv@ProcessJEnv % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{environment}{lstlisting} -% The awkward work is done, here we deal with continued line numbering. -% \lsthelper{Boris Veytsman}{boris@plmsc.psu.edu}{1998/03/25}{continue line numbering: a.c b.c a.c} proposed to continue line numbers according to listing names. -% Thus we must save the name and either make a LOL item or define the first line number. -% Note that the macro |\lstno@| will be undefined or equivalent to |\relax|, so we always start with line number 1 in case of an empty name. -% Moreover we first test if the user has forgotten the name argument. -% \begin{macrocode} -\lst@Environment{lstlisting}[2][]\is - {\lstenv@TestEOLChar{#2}% - \expandafter\ifx\csname lstno@\lst@intname\endcsname \relax % - \ifx\lst@intname\@empty\else \lst@AddToLOL{#2}{}\fi % - \else % - \edef\lst@firstline{\csname lstno@\lst@intname\endcsname}% - \let\lst@prelisting\lst@@prelisting % - \let\lst@postlisting\lst@@postlisting % - \fi % - \lstset{#1}} -% \end{macrocode} -% At the end of environment we simply save the current line number. -% If the listing name is empty, we use a space instead of the name. -% This leaves the macro |\lstno@| undefined. -% \begin{macrocode} - {\ifx\lst@intname\@empty % - \expandafter\xdef\csname lstno@ \endcsname{\the\lst@lineno}% - \else % - \expandafter\xdef\csname lstno@\lst@intname\endcsname % - {\the\lst@lineno}% - \fi} -% \end{macrocode} -% \end{environment} -% -% \begin{macro}{\lstenv@TestEOLChar} -% \begin{macro}{\lstenv@EOLCharError} -% Here we test for the two possible EOL characters. -% \begin{macrocode} -\begingroup \lccode`\~=`\^^M\lowercase{% -\gdef\lstenv@TestEOLChar#1{% - \lst@SetName{}% - \ifx~#1\lstenv@EOLCharError \else % - \ifx^^J#1\lstenv@EOLCharError \else % - \lst@SetName{#1}% - \fi % - \fi} -}\endgroup -% \end{macrocode} -% A simple error message. -% \begin{macrocode} -\def\lstenv@EOLCharError{% - \PackageError{Listings} - {Oops! It seems you've forgotten the argument to\MessageBreak % - a listing environment. Assuming empty argument}% - {Type to proceed.}} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{aspect}{advancelineno} -% \begin{aspect}{resetlineno} -% The last two aspects in this section simply advance/reset the first line. -% \begin{macrocode} -\lst@Aspect{advancelineno} - {\global\lst@lineno\lst@firstline\relax % - \global\advance\lst@lineno#1\relax % - \edef\lst@firstline{\the\lst@lineno}} -\lst@Aspect{resetlineno}[1]{\def\lst@firstline{#1}} -% \end{macrocode} -% \end{aspect}\end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Inline listings} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lstinline} -% We redefine some macros here since they are possibly not save inside |\hbox|. -% Furthermore we use flexible columns and suppress \TeX\ comment lines. -% After doing initialization we redefine |\everypar| and the new line macro. -% We don't want them. -% \begin{macrocode} -\def\lstinline{\hbox\bgroup % - \let\smallbreak\relax % - \let\lst@prelisting\relax \let\lst@postlisting\relax % - \let\lst@ifflexible\iftrue \lst@DontEscapeToLaTeX % - \def\lst@firstline{1}\def\lst@lastline{1}% - \lst@Init\relax \everypar{}\global\let\lst@NewLine\relax % - \lst@IfNextCharActive\lst@InlineM\lst@InlineJ} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@InlineM} -% \begin{macro}{\lst@InlineJ} -% treat the cases of 'normal' inlines and inline listings inside an argument. -% In the first case the given character ends the inline listing and EOL (within such a listing) immediately ends it and produces an error message. -% \begin{macrocode} -\def\lst@InlineM#1{% - \lstCC@Def{`#1}{\lst@DeInit\egroup}% - \lstCC@Def{"000D}{\lst@DeInit\egroup % - \PackageError{Listings}{lstinline ended by EOL}\@ehc}} -% \end{macrocode} -% In the other case we get all characters upto |#1| (via temporary macro), make these characters active, execute (typeset) them and end the listing. -% That's all about it. -% \begin{macrocode} -\def\lst@InlineJ#1{% - \def\lst@temp##1#1{% - \let\lstenv@arg\@empty \lstenv@AddArg{##1}% - \lstenv@arg \lst@DeInit\egroup}% - \lst@temp} -% \end{macrocode} -% \end{macro}\end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{The box command} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lstbox} -% The macro opens the |\hbox| right at the beginning and indicate its usage. -% Then we adjust some \lst-parameters: -% We switch to |\lstlistingtrue| since the command is intend to be used with small listings only; -% |\smallbreak|s preceding and following each listing are removed by redefining |\smallbreak|. -% \begin{macrocode} -\newcommand\lstbox{% - \hbox\bgroup % - \let\lst@ifbox\iftrue % - \let\smallbreak\relax % - \let\lst@prelisting\relax \let\lst@postlisting\relax % - \let\lst@@prelisting\relax\let\lst@@postlisting\relax % - \lst@outerspread\z@ \lst@innerspread\z@ % - \@ifnextchar[{\lstbox@}{\lstbox@[c]}} -% \end{macrocode} -% Here we have to choose the right box --- in fact |\vcenter| isn't a box. -% \begin{macrocode} -\def\lstbox@[#1]{% - \hbox to\z@\bgroup % - $\if#1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi % - \bgroup}% -% \end{macrocode} -% We need to -% \begin{macrocode} -\let\lst@ifbox\iffalse -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@EndBox} -% And the counterpart: We have to close some groups (and use |\hss| inside the |\hbox| to $0$pt). -% The outer |\hbox| gets its correct width using a |\vrule|. -% \begin{macrocode} -\def\lst@EndBox{% - \egroup $\hss \egroup % - \vrule width\lst@maxwidth height\z@ depth\z@ % - \egroup} -% \end{macrocode} -% But that macro is called (if and) only if we've begun a |\lstbox| before. -% Note that we are possibly inside a \lst-environment here, so we have to execute |\lst@EndBox| either now or after closing the environment group. -% \begin{macrocode} -\lst@AddToHook{OnExit} - {\lst@ifbox % - \global\advance\lst@maxwidth-\lst@innerspread % - \global\advance\lst@maxwidth-\lst@outerspread % - \ifx\@currenvir\lstenv@name % - \expandafter\expandafter\expandafter\aftergroup % - \fi % - \expandafter\lst@EndBox % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@maxwidth} -% is to be allocated: -% \begin{macrocode} -\newdimen\lst@maxwidth % \global -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVars}{\global\lst@maxwidth\z@} -% \end{macrocode} -% Determine width of just printed line and update |\lst@maxwidth|. -% Here we assume that all characters of the line have been output. -% \begin{macrocode} -\lst@AddToHook{InitVarsEOL} - {\@tempdima \lst@column\lst@width % - \advance\@tempdima -\lst@pos\lst@width % - \ifdim\lst@lostspace<\z@ \advance\@tempdima -\lst@lostspace \fi % - \ifdim\@tempdima>\lst@maxwidth \global\lst@maxwidth\@tempdima \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{First \lst-aspects and related macros} -% -% In fact we've already defined some aspects, e.g.\ |language| and |style|. -% -% -% \subsection{Keywords} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{TODO} -% The internal keyword managing should be reorganised, so that is also handles the special characters $<,>,\vert,\sim$. -% \end{TODO} -% We have to decide whether or not a given character sequence is a reserved word. -% For example, if the character sequence is |key|, we define a macro -% \begin{verbatim} -% \def\lst@temp#1,key,#2\relax{...}\end{verbatim} -% Afterwards we call the macro with the following arguments: -% \begin{itemize} -% \item[] |,|all current keywords|,key,\relax| -% \end{itemize} -% The additional |,key,\relax| holds up the syntax of |\lst@temp|. -% When \TeX{} passes the arguments, the second is empty if and only if |key| is not a current keyword. -% So we know whether or not to select keyword style. -% -% Since \TeX{} always passes two arguments to |\lst@temp|, the whole 'input' |\lst@keywords,#1,\relax| is split in two parts. -% So there is no need to sort the keywords by probability. -% Alternatively you could do so and make a loop for the keyword tests, which terminates right after finding a keyword. -% You might think and guess that's faster than the \TeX{}nique used here. -% If your source code uses the three or four most common keywords only, you are right. -% In fact the very first versions 0.1 and 0.11 have used something like loops (even something faster), which in general is slower than this here. -% \begin{TODO} -% There exists a faster way. -% For each keyword we make |\lstk@|\emph{the keyword} equivalent to keyword style. -% |\csname lstk@|\emph{test word}|\endcsname| expands to |\relax| if the control sequence is undefined and to keyword style otherwise. -% That's the complete keyword test! -% It works very well, but needs more of \TeX{}'s memory. -% Therefore we should define also 'memory saving' and/or 'speeding up' option. -% -% Note: A keyword or character string in this state might contain |\lst@underscore| and |\lst@minus| (and possibly more macro names), which will expand inside |\csname|\ldots|\endcsname|. -% Hence the definition of |\lstk@|\emph{the keyword} needs some care. -% An easy trick: During keyword definition and keyword testing the macros should expand to |_| and |-|, respectively. -% But the reassignments of |_|, |-|, \ldots\ also need time, so the implemented way is possibly faster \ldots -% \end{TODO} -% -% \begin{macro}{\lst@SetStyleFor} -% |\relax| terminates the argument here since it is faster than enclosing it in braces. -% All the rest should be clear from the discussion above. -% \begin{macrocode} -\def\lst@SetStyleFor#1\relax{% - \def\lst@temp##1,#1,##2\relax{% - \ifx\@empty##2\@empty \let\lst@thestyle\lst@nonkeywordstyle % - \else \let\lst@thestyle\lst@keywordstyle\fi}% - \expandafter\lst@temp\expandafter,\lst@keywords,#1,\relax}% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@SetStyleForNonSensitive} -% We implement a case insensitive version. -% Use of two |\uppercase|s normalize the argument. -% \begin{macrocode} -\def\lst@SetStyleForNonSensitive#1\relax{% - \uppercase{\def\lst@temp##1,#1},##2\relax{% - \ifx\@empty##2\@empty \let\lst@thestyle\lst@nonkeywordstyle % - \else \let\lst@thestyle\lst@keywordstyle\fi}% - \uppercase{% - \expandafter\lst@temp\expandafter,\lst@keywords,#1},\relax}% -% \end{macrocode} -% Note: This macro and the coming |\lst@IfOneOfNonSensitive| both assume that the keywords in |\lst@keywords| are already upper case! -% \end{macro} -% -% The code above must be activated, of course: -% We detect keywords if and only if we haven't entered a special mode (comment, string, etc.). -% \begin{macrocode} -\lst@AddToHook{Output} - {\lst@ifmode % - \let\lst@thestyle\relax % - \else % - \expandafter\lst@SetStyleFor\the\lst@token\relax % - \fi} -% \end{macrocode} -% -% \begin{macro}{\lst@IfOneOf} -% \begin{macro}{\lst@IfOneOfNonSensitive} -% These macros are very familiar with the keyword tests. -% Roughly speaking the fixed |\lst@keywords| is replaced by an arbitrary macro. -% The first argument has the same meaning and is terminated by |\relax|, whereas the second must be a macro name. -% If and only if that macro (= keyword list) contains the first argument, the third parameter is executed (and the fourth otherwise). -% \begin{macrocode} -\def\lst@IfOneOf#1\relax#2{% - \def\lst@temp##1,#1,##2\relax{% - \ifx \@empty##2\@empty \expandafter\@secondoftwo % - \else \expandafter\@firstoftwo \fi}% - \expandafter\lst@temp\expandafter,#2,#1,\relax}% -% \end{macrocode} -% \begin{macrocode} -\def\lst@IfOneOfNonSensitive#1\relax#2{% - \uppercase{\def\lst@temp##1,#1},##2\relax{% - \ifx \@empty##2\@empty \expandafter\@secondoftwo % - \else \expandafter\@firstoftwo \fi}% - \uppercase\expandafter{% - \expandafter\lst@temp\expandafter,#2,#1},\relax}% -% \end{macrocode} -% Instead of |\lst@SetStyleFor key\relax|, we could also write -% \begin{verbatim} -% \lst@IfOneOf key\relax \lst@keywords % -% {\let\lst@thestyle\lst@keywordstyle} -% {\let\lst@thestyle\lst@nonkeywordstyle}\end{verbatim} -% \end{macro}\end{macro} -% -% \begin{macro}{\lststorekeywords} -% Note that this command stores the keywords globally. -% \begin{macrocode} -\newcommand\lststorekeywords[2]{\gdef#1{#2}} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{sensitive} -% Announcement and init: -% \begin{macrocode} -\lst@Aspect{sensitive}[t]{\lstKV@SetIfKey\lst@ifsensitive{#1}} -\lst@AddToHook{SetLanguage}{\let\lst@ifsentitive\iftrue} -% \end{macrocode} -% \end{aspect} -% -% \noindent -% Now we consider the aspects getting keywords from the user. -% They work up the keywords a little bit, namely using |\lst@Make|\ldots|KeywordArg|. -% -% \begin{aspect}{keywords} -% \lsthelper{Ralf Quast}{rquast@hs.uni-hamburg.de}{1998/01/08}{name \keywords incompatible with AMS classes} reported a naming conflict with AMS classes. -% Usage of \textsf{keyval} package removes it. -% The easy definition: -% \begin{macrocode} -\lst@Aspect{keywords} - {\lst@MakeSpecKeywordArg{#1}\let\lst@keywords\lst@arg} -% \end{macrocode} -% We have to delete all current keywords before selecting a new language --- otherwise keywords from the previous language would be present if the user specifies no keywords. -% \begin{macrocode} -\lst@AddToHook{SetLanguage}{\let\lst@keywords\@empty} -% \end{macrocode} -% If the user wants case insensitive keywords, she'll get it: -% We assign the correct test macros and make all keywords upper case. -% Note that these changes are local. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifsensitive\else % - \let\lst@SetStyleFor\lst@SetStyleForNonSensitive % - \let\lst@IfOneOf\lst@IfOneOfNonSensitive % - \lst@MakeMacroUppercase\lst@keywords % - \fi} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lst@MakeMacroUppercase} -% This macro makes the contents of a given macro (if present) upper case. -% \begin{macrocode} -\def\lst@MakeMacroUppercase#1{% - \ifx#1\@undefined\else \uppercase\expandafter{% - \expandafter\def\expandafter#1\expandafter{#1}}% - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{morekeywords} -% Add keywords or append control sequence with argument: -% \begin{macrocode} -\lst@Aspect{morekeywords} - {\lst@MakeMoreSpecKeywordArg{,#1}% - \expandafter\lst@lAddTo\expandafter\lst@keywords % - \expandafter{\lst@arg}} -% \end{macrocode} -% \end{aspect} -% -% \begin{aspect}{deletekeywords} -% The 'submacro' |\lst@DeleteKeysIn| has been defined in section \ref{iReplacingCharacters}. -% \begin{macrocode} -\lst@Aspect{deletekeywords} - {\lst@MakeKeywordArg{#1}% - \lst@DeleteKeysIn\lst@keywords\lst@arg} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lst@MakeKeywordArg} -% \begin{macro}{\lst@MakeSpecKeywordArg} -% \begin{macro}{\lst@MakeMoreSpecKeywordArg} -% The keyword commands don't save their parameters as they are. -% All spaces are removed and underscores, dollars and minuses are replaced by |\lst@underscore|, |\lst@dollar| and |\lst@minus|. -% The first thing prepares keyword tests and the second the output. -% The macro |\lst@arg| holds the parameter free of spaces, underscores and minuses. -% Use of |\zap@space| was proposed by \lsthelper{Rolf Niepraschk}{NIEPRASCHK@PTB.DE}{1997/04/24}{use \zap@space}. -% \begin{macrocode} -\def\lst@MakeKeywordArg#1{\edef\lst@arg{\zap@space#1 \@empty}% - \lst@ReplaceIn\lst@arg{_\lst@underscore $\lst@dollar -\lst@minus}} -% \end{macrocode} -% The following two macros also scan for special characters like \#, $<$ and $>$. -% \begin{macrocode} -\def\lst@MakeSpecKeywordArg{% - \let\lst@ialsodigit\@empty \let\lst@ialsoletter\@empty % - \lst@MakeMoreSpecKeywordArg} -% \end{macrocode} -% \begin{macrocode} -\def\lst@MakeMoreSpecKeywordArg#1{\edef\lst@arg{\zap@space#1 \@empty}% - \lstCC@lettertrue % - \expandafter\lst@SpecialKeywordScan\lst@arg\relax % - \lst@ReplaceIn\lst@arg{_\lst@underscore $\lst@dollar -\lst@minus}} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lst@SpecialKeywordScan} -% How does this scan work? -% Whenever we encounter a non-letter or non-digit in a keyword, we call |\lst@SKSAdd| to store that character. -% If we reach the end of keyword list, we terminate the loop by gobbling one token after the latest |\fi|. -% \begin{macrocode} -\def\lst@SpecialKeywordScan#1{% - \ifx\relax#1% - \expandafter\@gobble % - \else % -% \end{macrocode} -% If the current character is a comma, the next character must be (or become) a letter since it starts a keyword. -% This switch is turned false after reading the next character. -% \begin{macrocode} - \ifx,#1% - \lstCC@lettertrue % - \else % - \ifnum`#1<"40\relax % - \ifnum`#1<"30\relax \lst@SKSAdd#1\else % - \ifnum`#1>"39\relax \lst@SKSAdd#1\else % -% \end{macrocode} -% If we've found a digit, we do a special test to decide whether the digit becomes a letter or not. -% \begin{macrocode} - \lst@SKS@#1% - \fi \fi % - \else % - \ifnum`#1<"5B\relax \else % - \ifnum`#1="5F\relax \else % - \ifnum`#1<"61\relax \lst@SKSAdd#1\else % - \ifnum`#1<"7B\relax \else % - \ifnum`#1<"80\relax \lst@SKSAdd#1 % - \fi \fi \fi \fi \fi % - \fi % - \lstCC@letterfalse % - \fi % - \fi \lst@SpecialKeywordScan} -% \end{macrocode} -% The special test for digits: Since any digit is already a digit it needs only to become a letter if necessary. -% \begin{macrocode} -\def\lst@SKS@#1{\lstCC@ifletter \lst@SKSAdd#1\fi} -% \end{macrocode} -% The macros |\lst@ialsoletter| and |\lst@ialsodigit| contain the characters. -% If not already contained in the appropiate macro, we append the character. -% Refer |\lst@SelectStyleFor| how we scan for a substring (of length 1). -% \begin{macrocode} -\def\lst@SKSAdd#1{% - \lstCC@ifletter % - \def\lst@temp##1#1##2\relax{% - \ifx\@empty##2\@empty % - \lst@lAddTo\lst@ialsoletter{#1}% - \fi}% - \expandafter\lst@temp\lst@ialsoletter#1\relax % - \else % - \def\lst@temp##1#1##2\relax{% - \ifx\@empty##2\@empty % - \lst@lAddTo\lst@ialsodigit{#1}% - \fi}% - \expandafter\lst@temp\lst@ialsodigit#1\relax % - \fi} -% \end{macrocode} -% \begin{macrocode} -\let\lst@ialsoletter\@empty \let\lst@ialsodigit\@empty % init -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{alsoletter} -% \begin{aspect}{alsodigit} -% \begin{aspect}{alsoother} -% For now three easy definitions --- easy since I don't explain the last hook. -% \begin{macrocode} -\lst@Aspect{alsoletter}{\def\lst@alsoletter{#1}} -\lst@Aspect{alsodigit}{\def\lst@alsodigit{#1}} -\lst@Aspect{alsoother}{\def\lst@alsoother{#1}} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{SetLanguage} - {\let\lst@alsoletter\@empty % - \let\lst@alsodigit\@empty % - \let\lst@alsoother\@empty} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{SelectCharTable} - {\lstCC@ChangeBasicClass\lstCC@ProcessOther\lst@alsoother % - \lstCC@ChangeBasicClass\lstCC@ProcessDigit\lst@ialsodigit % - \lstCC@ChangeBasicClass\lstCC@ProcessDigit\lst@alsodigit % - \lstCC@ChangeBasicClass\lstCC@ProcessLetter\lst@ialsoletter % - \lstCC@ChangeBasicClass\lstCC@ProcessLetter\lst@alsoletter} -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% -% \begin{macro}{\lst@minus} -% What is the |\ifx|\ldots{} in |\lst@minus| good for? -% If you use typewriter fonts, it ensures that |----| is typeset |----| and not $-$$-$$-$$-$ as in version 0.17. -% Bug encountered by \lsthelper{Dr. Jobst Hoffmann}{HOFFMANN@rz.rwth-aachen.de}{1998/03/30}{\lst@minus\ and typewriter fonts}. -% \begin{macrocode} -\def\lst@minus{\ifx\f@family\ttdefault-{}\else$-$\fi} -\def\lst@dollar{\ifx\f@family\ttdefault\textdollar\else\textdollar\fi} -\def\lst@asterisk{\ifx\f@family\ttdefault*\else\textasteriskcentered\fi} -\def\lst@less{\ifx\f@family\ttdefault<\else\textless\fi} -\def\lst@greater{\ifx\f@family\ttdefault>\else\textgreater\fi} -\def\lst@backslash{\ifx\f@family\ttdefault\char92\else\textbackslash\fi} -\def\lst@underscore{% - \ifx\f@family\ttdefault\char95\else\textunderscore\fi} -\def\lst@lbrace{\ifx\f@family\ttdefault\char123\else\textbraceleft\fi} -\def\lst@bar{\ifx\f@family\ttdefault|\else\textbar\fi} -\def\lst@rbrace{\ifx\f@family\ttdefault\char125\else\textbraceright\fi} -% \end{macrocode} -% |\ttdefault| is defined |\long|, so the |\ifx| doesn't work since |\f@family| isn't defined |\long|! -% We go around this problem by redefining |\ttdefault| locally: -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable}{\edef\ttdefault{\ttdefault}} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{basicstyle} -% \begin{aspect}{keywordstyle} -% \begin{aspect}{nonkeywordstyle} -% We shouldn't forget these style aspects. -% \begin{macrocode} -\lst@Aspect{basicstyle}{\def\lst@basicstyle{#1}} -\lst@Aspect{keywordstyle}{\def\lst@keywordstyle{#1}} -\lst@Aspect{nonkeywordstyle}{\def\lst@nonkeywordstyle{#1}} -% \end{macrocode} -% \lsthelper{Anders Edenbrandt}{Anders.Edenbrandt@dna.lth.se}{1997/04/22}{preload of .fd files} found a bug with \texttt{.fd} files. -% Here's my solution: Since we will change catcodes, these files can't be read on demand --- it would yield to obscure error messages. -% The |\setbox| sequence ensures (most times) that they are read before. -% We simply typeset distinct characters from each \texttt{.fd} file. -% Note: We never output that box. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@basicstyle % - \setbox\@tempboxa\hbox{\lst@loadfd % - {\lst@keywordstyle \lst@loadfd}% - {\lst@nonkeywordstyle \lst@loadfd}}} -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% -% \begin{macro}{\lst@loadfd} -% These are hopefully all necessary characters. -% \begin{macrocode} -\def\lst@loadfd{a0\lst@asterisk\lst@less} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{ndkeywords} -% \begin{aspect}{ndkeywordstyle} -% \begin{aspect}{morendkeywords} -% \begin{aspect}{deletendkeywords} -% We define a second keyword class in the same manner if the user wants it. -% \begin{macrocode} -\@ifundefined{lst@ndkeywords}{}{% -\let\lst@ndkeywords\@empty \let\lst@ndkeywordstyle\@empty % init -\lst@Aspect{ndkeywords} - {\lst@MakeSpecKeywordArg{#1}\let\lst@ndkeywords\lst@arg} -\lst@AddToHook{SetLanguage}{\let\lst@ndkeywords\@empty} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifsensitive\else % - \lst@MakeMacroUppercase\lst@ndkeywords % - \fi} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{ndkeywordstyle}{\def\lst@ndkeywordstyle{#1}} -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{{\lst@ndkeywordstyle \lst@loadfd}}} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{morendkeywords} - {\lst@MakeMoreSpecKeywordArg{,#1}% - \expandafter\lst@lAddTo\expandafter\lst@ndkeywords % - \expandafter{\lst@arg}} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{deletendkeywords} - {\lst@MakeKeywordArg{#1}% - \lst@DeleteKeysIn\lst@ndkeywords\lst@arg} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{Output} - {\lst@ifmode\else % - \expandafter\lst@IfOneOf\the\lst@token\relax \lst@ndkeywords % - {\let\lst@thestyle\lst@ndkeywordstyle}{}% - \fi} -% \end{macrocode} -% Finally we end the argument from |\@ifundefined|. -% \begin{macrocode} -} -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect}\end{aspect} -% -% \begin{aspect}{rdkeywords} -% \begin{aspect}{rdkeywordstyle} -% \begin{aspect}{morerdkeywords} -% \begin{aspect}{deleterdkeywords} -% That's the power of \lst-aspects: An optional third keyword class. -% \begin{macrocode} -\@ifundefined{lst@rdkeywords}{}{% -\let\lst@rdkeywords\@empty \let\lst@rdkeywordstyle\@empty % init -\lst@Aspect{rdkeywords} - {\lst@MakeSpecKeywordArg{#1}\let\lst@rdkeywords\lst@arg} -\lst@AddToHook{SetLanguage}{\let\lst@rdkeywords\@empty} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifsensitive\else % - \lst@MakeMacroUppercase\lst@rdkeywords % - \fi} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{rdkeywordstyle}{\def\lst@rdkeywordstyle{#1}} -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{{\lst@rdkeywordstyle \lst@loadfd}}} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{morerdkeywords} - {\lst@MakeMoreSpecKeywordArg{,#1}% - \expandafter\lst@lAddTo\expandafter\lst@rdkeywords % - \expandafter{\lst@arg}} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{deleterdkeywords} - {\lst@MakeKeywordArg{#1}% - \lst@DeleteKeysIn\lst@rdkeywords\lst@arg} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{Output} - {\lst@ifmode\else % - \expandafter\lst@IfOneOf\the\lst@token\relax \lst@rdkeywords % - {\let\lst@thestyle\lst@rdkeywordstyle}{}% - \fi} -} -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect}\end{aspect} -% -% -% \subsection{Export of indentifiers} -% -% \begin{aspect}{index} -% We implement this aspect in the same manner. -% \begin{macrocode} -\@ifundefined{lst@index}{}{% -\lst@Aspect{index}{\lst@MakeSpecKeywordArg{#1}\let\lst@index\lst@arg} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifsensitive\else % - \lst@MakeMacroUppercase\lst@index % - \fi} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{Output} - {\lst@ifmode\else % - \expandafter\lst@IfOneOf\the\lst@token\relax \lst@index % - {\expandafter\lst@indexmacro\expandafter{\the\lst@token}}{}% - \fi} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{indexmacro}{\let\lst@indexmacro#1} -\newcommand\lstindexmacro[1]{\index{{\ttfamily#1}}} -\let\lst@index\@empty \let\lst@indexmacro\lstindexmacro % init -} -% \end{macrocode} -% \end{aspect} -% -% \begin{aspect}{procnamestyle} -% \begin{aspect}{prockeywords} -% \begin{aspect}{indexprocnames} -% The 'idea' here is the usage of a global |\lst@ifprocname| indicating a preceding 'procedure keyword'. -% All the other is known stuff. -% \begin{macrocode} -\@ifundefined{lst@prockeywords}{}{% -\lst@Aspect{prockeywords}{% - \lst@MakeSpecKeywordArg{#1}\let\lst@prockeywords\lst@arg} -\lst@Aspect{procnamestyle}{\def\lst@procnamestyle{#1}} -\lst@Aspect{indexprocnames}[t]{\lstKV@SetIfKey\lst@ifindexproc{#1}} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{\lst@procnamestyle\lst@loadfd}% - \lst@ifsensitive\else % - \lst@MakeMacroUppercase\lst@prockeywords % - \fi % - \lst@ifindexproc \ifx\lst@indexmacro\@undefined % - \let\lst@indexmacro\@gobble % - \fi \fi} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{Output} - {\lst@ifmode\else % - \lst@ifprocname % - \let\lst@thestyle\lst@procnamestyle % - \expandafter\lst@indexmacro\expandafter{\the\lst@token}% - \lst@procnamefalse % - \else \expandafter% - \lst@IfOneOf\the\lst@token\relax \lst@prockeywords % - {\lst@procnametrue}{}% - \fi % - \fi} -% \end{macrocode} -% \begin{macrocode} -\def\lst@procnametrue{\global\let\lst@ifprocname\iftrue} -\def\lst@procnamefalse{\global\let\lst@ifprocname\iffalse} -% \end{macrocode} -% \begin{macrocode} -\let\lst@prockeywords\@empty % init -\lstset{procnamestyle={},indexprocnames=false}% init -\lst@procnamefalse % init -} -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Labels} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \lsthelper{Rolf Niepraschk}{NIEPRASCHK@PTB.DE}{1997/04/24}{labels} asked for this feature. -% -% \begin{aspect}{labelstyle} -% \begin{aspect}{labelsep} -% \begin{aspect}{labelstep} -% The usual stuff: -% Definition with check for legal step count, \ldots -% \begin{macrocode} -\lst@Aspect{labelstyle}{\def\lst@labelstyle{#1}} -\lst@Aspect{labelsep}{\def\lst@labelsep{#1}} -\lst@Aspect{labelstep}% - {\ifnum #1>\m@ne % - \def\lst@labelstep{#1}% - \else % - \PackageError{Listings}{Nonnegative integer expected}% - {You can't use `#1' as step count for labels.^^J% - I'll forget it and proceed.}% - \fi} -% \end{macrocode} -% and load of \texttt{.fd} files (if necessary). -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{\lst@stringstyle \lst@loadfd}} -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% -% \begin{macro}{\lst@skiplabels} -% But there are more things to do. -% \begin{macrocode} -\newcount\lst@skiplabels % \global -% \end{macrocode} -% We calculate how many lines must skip their label. -% The formula is -% $$|\lst@skiplabels|= -% \textrm{\emph{first printing line}}\bmod|\lst@labelstep|.$$ -% Note that we use a nonpositive representative for |\lst@skiplabels|. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\ifnum\lst@labelstep>\z@ % - \global\lst@skiplabels\lst@firstline\relax % - \global\divide\lst@skiplabels\lst@labelstep % - \global\multiply\lst@skiplabels-\lst@labelstep % - \global\advance\lst@skiplabels\lst@firstline\relax % - \ifnum\lst@skiplabels>\z@ % - \global\advance\lst@skiplabels -\lst@labelstep\relax % - \fi % -% \end{macrocode} -% If |\lst@labelstep| is nonpositive (in fact zero), no labels are printed: -% \begin{macrocode} - \else % - \let\lst@SkipOrPrintLabel\relax % - \fi} -\lst@AddToHook{EveryLine}{\lst@SkipOrPrintLabel} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@SkipOrPrintLabel} -% But default is this. -% We use the fact that |\lst@skiplabels| is nonpositive. -% The counter advances every line and if that counter is zero, we print a line number and decrement the counter by |\lst@labelstep|. -% \begin{macrocode} -\def\lst@SkipOrPrintLabel{% - \ifnum\lst@skiplabels=\z@ % - \global\advance\lst@skiplabels-\lst@labelstep\relax % - \llap{\lst@labelstyle{\the\lst@lineno}\kern\lst@labelsep}% - \fi % - \global\advance\lst@skiplabels\@ne} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Parshape and lineskip} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@innerspread} -% \begin{macro}{\lst@outerspread} -% Just allocate these dimensions. -% \begin{macrocode} -\newdimen\lst@innerspread \newdimen\lst@outerspread -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{aspect}{wholeline} -% \begin{aspect}{indent} -% \begin{aspect}{spread} -% Usual stuff. -% \begin{macrocode} -\lst@Aspect{wholeline}[t]{\lstKV@SetIfKey\lst@ifwholeline{#1}} -\lst@Aspect{indent}{\def\lst@indent{#1}} -\lst@Aspect{spread}{\lstspread@#1,,\relax} -% \end{macrocode} -% \lsthelper{Harald Haders}{h.haders@tu-bs.de}{1998/03/30}{inner- and outerspread} had the idea of two spreads (inner and outer). -% We either divide the dimension by two or assign the two dimensions to inner- and outerspread. -% \begin{macrocode} -\def\lstspread@#1,#2,#3\relax{% - \lst@innerspread#1\relax % - \ifx\@empty#2\@empty % - \divide\lst@innerspread\tw@\relax % - \lst@outerspread\lst@innerspread % - \else % - \lst@outerspread#2\relax % - \fi} -% \end{macrocode} -% \begin{macrocode} -\lstset{wholeline=false,indent=\z@,spread=\z@}% init -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% -% \begin{macro}{\lst@parshape} -% The definition itself is easy. -% Note that we use this parshape every line (in fact every paragraph). -% Furthermore we must repeat the parshape if we close a group level --- or the shape is forgotten. -% \begin{macrocode} -\def\lst@parshape{% - \parshape\@ne % - \ifodd\c@page -\lst@innerspread\else -\lst@outerspread\fi % - \linewidth} -\lst@AddToHookAtTop{EveryLine}{\lst@parshape} -\lst@AddToHookAtTop{EndGroup}{\lst@parshape} -% \end{macrocode} -% We calculate the line width and (inner/outer) indent for a listing. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\advance\linewidth\lst@innerspread % - \advance\linewidth\lst@outerspread % - \advance\linewidth-\lst@indent\relax % - \advance\lst@innerspread-\lst@indent\relax % - \advance\lst@outerspread-\lst@indent\relax % - \lst@ifwholeline % - \advance\linewidth\@totalleftmargin % - \else % - \advance\lst@innerspread-\@totalleftmargin % - \advance\lst@outerspread-\@totalleftmargin % - \fi % - \if@twoside\else \lst@outerspread\lst@innerspread \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{lineskip} -% Finally we come to this attribute --- the introduction is due to communication with \lsthelper{Andreas Bartelt}{Andreas.Bartelt@Informatik.Uni-Oldenburg.DE}{1997/09/11}{problem with redefed \parskip; \lstlineskip introduced}. -% \begin{macrocode} -\lst@Aspect{lineskip}{\def\lst@lineskip{#1}} -\lst@AddToHook{BeforeSelectCharTable}{\parskip\lst@lineskip\relax} -\lstset{lineskip=\z@}% init -% \end{macrocode} -% \end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Frames} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% -% \begin{aspect}{framerulewidth} -% \begin{aspect}{framerulesep} -% \begin{aspect}{frametextsep} -% We only have to store the arguments. -% \begin{macrocode} -\lst@Aspect{framerulewidth}{\def\lst@framewidth{#1}} -\lst@Aspect{framerulesep}{\def\lst@framesep{#1}} -\lst@Aspect{frametextsep}{\def\lst@frametextsep{#1}} -% \end{macrocode} -% \begin{macrocode} -\lstset{framerulewidth=.4pt,framerulesep=2pt,frametextsep=3pt}% init -% \end{macrocode} -% \end{aspect}\end{aspect}\end{aspect} -% -% \begin{aspect}{frame} -% The main aspect saves the argument, resets all supported types |tlrbTLRB| to |\relax| and defines the user specified frame. -% \begin{macrocode} -\lst@Aspect{frame} - {\def\lst@frame{#1}% - \lstframe@\relax tlrbTLRB\relax % - \lstframe@\@empty#1\relax} -% \end{macrocode} -% This submacro defines the macros to be equivalent to |#1| (which is |\relax| or |\@empty|). -% The second argument is the list of characters terminated by |\relax|. -% \begin{macrocode} -\def\lstframe@#1#2{% - \ifx\relax#2\else % - \expandafter\let\csname lstf@#2\endcsname#1% - \expandafter\lstframe@\expandafter#1% - \fi} -% \end{macrocode} -% \begin{macrocode} -\lstset{frame={}}% init -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lst@framev} -% \begin{macro}{\lst@frameV} -% These macros typeset one or two vertical rules: -% \begin{macrocode} -\def\lst@framev{\hbox{\strut\vrule width\lst@framewidth}} -\def\lst@frameV{\hbox{\strut % - \vrule width\lst@framewidth\kern\lst@framesep % - \vrule width\lst@framewidth}} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@framelr} -% We typeset left and right frame rule every line (if not made |\relax|). -% Note that |\lst@framel| is possibly redefined and thus equivalent to |\lst@frameL|. -% \begin{macrocode} -\lst@AddToHook{EveryLine}{\lst@framelr} -\def\lst@framelr{% - \llap{\lst@framel\kern\lst@indent\kern\lst@frametextsep}% - \rlap{\kern\linewidth\kern\lst@frametextsep\lst@framer}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@frameh} -% This is the main macro for horizontal lines. -% The first parameter gives the size of the left and right corner. -% The other two parameters typeset these corners (and get the size parameter). -% Now: We move to the correct horizontal position, set the left corner, the horizontal line and the right corner. -% \begin{macrocode} -\def\lst@frameh#1#2#3{% - \hbox to\z@{% - \kern\ifodd\c@page -\lst@innerspread\else -\lst@outerspread\fi % - \kern-\lst@indent % -% \end{macrocode} -% \begin{macrocode} - \kern-\lst@frametextsep % - \ifx\lstf@L\@empty % - \llap{#2#1}% - \else \ifx\lstf@l\@empty % - \llap{#20}% - \fi \fi % - \vrule\@width\lst@frametextsep % -% \end{macrocode} -% \begin{macrocode} - \vrule\@width\lst@indent % - \vrule\@width\linewidth\@height\lst@framewidth % -% \end{macrocode} -% \begin{macrocode} - \vrule\@width\lst@frametextsep % - \ifx\lstf@R\@empty % - \rlap{#3#1}% - \else \ifx\lstf@r\@empty % - \rlap{#30}% - \fi \fi % - \hss}} -% \end{macrocode} -% Note: There are no paramaters with numbers 20 and 30. -% It's |#2| respectively |#3| with size argument 0. -% \end{macro} -% -% \begin{macro}{\lst@framet} -% \begin{macro}{\lst@frameb} -% \begin{macro}{\lst@frameT} -% \begin{macro}{\lst@frameB} -% Now we can derive the 'top' and 'bottom' frame macros quite easily: -% \begin{macrocode} -\def\lst@framet{\lst@frameh0\lst@frameTL\lst@frameTR}% -\let\lst@frameb\lst@framet -\def\lst@frameT{% - \lst@frameh1\lst@frameTL\lst@frameTR % - \vskip\lst@framesep % - \lst@frameh0\lst@frameTL\lst@frameTR} -\def\lst@frameB{% - \lst@frameh0\lst@frameBL\lst@frameBR % - \vskip\lst@framesep % - \lst@frameh1\lst@frameBL\lst@frameBR} -% \end{macrocode} -% These macros are executed where needed. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\ifx\lstf@T\@empty % - \offinterlineskip\par\noindent\lst@frameT % - \else \ifx\lstf@t\@empty % - \offinterlineskip\par\noindent\lst@framet % - \else % - \let\lst@framet\relax % - \fi \fi % -% \end{macrocode} -% \begin{TODO} -% Replace |\offinterlineskip| by |\nointerlineskip|? -% \end{TODO} -% We look which frame types we have on the left and on the right. -% \begin{macrocode} - \let\lst@framel\relax \let\lst@framer\relax % - \ifx\lstf@L\@empty % - \let\lst@framel\lst@frameV % - \else % - \ifx\lstf@l\relax\else \let\lst@framel\lst@framev \fi % - \fi % - \ifx\lstf@R\@empty % - \let\lst@framer\lst@frameV % - \else % - \ifx\lstf@r\relax\else \let\lst@framer\lst@framev \fi % - \fi % -% \end{macrocode} -% We can speed up things if there are no vertical frames. -% \begin{macrocode} - \ifx\lst@framel\relax \ifx\lst@framer\relax % - \let\lst@framelr\relax % - \fi \fi % -% \end{macrocode} -% Finally we close the space between the horizontal rule and the first line (the 'depth' of the current line). -% \begin{macrocode} - \ifx\lst@framelr\relax\else \ifx\lst@framet\relax\else % - {\setbox\strutbox\hbox{% - \vrule\@height0pt\@depth.3\normalbaselineskip\@width\z@}% - \kern\ifodd\c@page-\lst@innerspread\else-\lst@outerspread\fi % - \lst@framelr}% - \fi \fi} -% \end{macrocode} -% The frame at the bottom: -% \begin{macrocode} -\lst@AddToHook{ExitVars} - {\ifx\lstf@B\@empty % - \offinterlineskip\everypar{}\par\noindent\lst@frameB % - \else \ifx\lstf@b\@empty % - \offinterlineskip\everypar{}\par\noindent\lst@framet % - \fi \fi} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lst@frameTL} -% \begin{macro}{\lst@frameTR} -% \begin{macro}{\lst@frameBL} -% \begin{macro}{\lst@frameBR} -% The 'corner' macros are left. -% All save the vertical rule in a temporary box to zero the depth or height of that box. -% Then we typeset the vertical and horizontal rule (in reversed order). -% \begin{macrocode} -\def\lst@frameTL#1{% - \@tempdima\lst@framesep \advance\@tempdima\lst@framewidth % - \multiply\@tempdima#1\relax % - \setbox\@tempboxa\hbox to\z@{% - \vrule\@width\lst@framewidth\@height\z@\@depth\@tempdima\hss}% - \dp\@tempboxa\z@ % - \advance\@tempdima\lst@framewidth % - \box\@tempboxa \vrule\@width\@tempdima\@height\lst@framewidth} -% \end{macrocode} -% \begin{macrocode} -\def\lst@frameTR#1{% - \@tempdima\lst@framesep \advance\@tempdima\lst@framewidth % - \multiply\@tempdima#1\relax % - \setbox\@tempboxa\hbox to\z@{\hss % - \vrule\@width\lst@framewidth\@height\z@\@depth\@tempdima}% - \dp\@tempboxa\z@ % - \advance\@tempdima\lst@framewidth % - \vrule\@width\@tempdima\@height\lst@framewidth \box\@tempboxa} -% \end{macrocode} -% \begin{macrocode} -\def\lst@frameBL#1{% - \@tempdima\lst@framesep \advance\@tempdima\lst@framewidth % - \multiply\@tempdima#1\relax % - \advance\@tempdima\lst@framewidth % - \setbox\@tempboxa\hbox to\z@{% - \vrule\@width\lst@framewidth\@height\@tempdima\hss}% - \ht\@tempboxa\z@ % - \box\@tempboxa \vrule\@width\@tempdima\@height\lst@framewidth} -% \end{macrocode} -% \begin{macrocode} -\def\lst@frameBR#1{% - \@tempdima\lst@framesep \advance\@tempdima\lst@framewidth % - \multiply\@tempdima#1\relax % - \advance\@tempdima\lst@framewidth % - \setbox\@tempboxa\hbox to\z@{\hss % - \vrule\@width\lst@framewidth\@height\@tempdima}% - \ht\@tempboxa\z@ % - \vrule\@width\@tempdima\@height\lst@framewidth \box\@tempboxa} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro}\end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Pre and post listing} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{pre} -% \begin{aspect}{post} -% A rather trivial section. -% \begin{macrocode} -\lst@Aspect{pre}{\lstKV@OptArg\lstpre@[]{#1}} -\lst@Aspect{post}{\lstKV@OptArg\lstpost@[]{#1}} -% \end{macrocode} -% \begin{macrocode} -\def\lstpre@[#1]#2{% - \def\lst@prelisting{#2}\def\lst@@prelisting{#1}} -\def\lstpost@[#1]#2{% - \def\lst@postlisting{#2}\def\lst@@postlisting{#1}} -% \end{macrocode} -% \begin{macrocode} -\lstset{pre={},post={}}% init -% \end{macrocode} -% \end{aspect}\end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{\TeX\ comment lines} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% Communication with \lsthelper{J\"orn Wilms}{wilms@rocinante.colorado.edu}{1997/07/07}{\TeX\ comments} is responsible for this feature. -% Some characters have a special functionality in \TeX{}, e.g.\ the underbar or the dollar sign. -% These meanings are unwanted while typesetting normal source code, i.e.\ we have to define our own character table. -% But for the comment lines we must interrupt the current processing and switch back to the original meanings. -% And at the end we must restore all previous things. -% -% \begin{aspect}{texcl} -% Announcing the aspect: -% \begin{macrocode} -\lst@Aspect{texcl}[t]{\lstKV@SetIfKey\lst@iftexcl{#1}} -\lstset{texcl=false}% init -% \end{macrocode} -% Things at EOL are easy, but we must allocate new modes for (\TeX) comment lines first. -% \begin{macrocode} -\lst@NewMode\lst@TeXCLmode -\lst@NewMode\lst@CLmode -\lst@AddToHook{EOL} - {\ifnum\lst@mode=\lst@TeXCLmode % - \lst@LeaveAllModes \lst@ReenterModes % - \fi % - \ifnum\lst@mode=\lst@CLmode \lst@LeaveMode \fi} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lstCC@BeginCommentLine} -% \begin{macro}{\lstCC@@BeginCommentLine} -% The first macro starts comment lines indicated by a single character (like |%| in \TeX), whereas the second does this for comment lines indicated by two characters (like |//| in C++). -% According to the macro naming these two macros belong more or less to section \ref{iCharacterClasses}. -% But we present them here because of \TeX\ comment lines. -% -% We print preceding characters (if any), begin the comment and output the comment separator. -% \begin{macrocode} -\def\lstCC@BeginCommentLine#1{% - \lst@NewLine \lst@PrintToken % - \lst@EnterMode{\lst@CLmode}{\lst@modetrue\lst@commentstyle}% - #1\relax % -% \end{macrocode} -% If the user don't want \TeX\ comment lines, there is nothing more to do. -% Otherwise we have to print the comment separator and interrupt the normal processing. -% \begin{macrocode} - \lst@iftexcl % - \lst@PrintToken % - \lst@LeaveMode \lst@InterruptModes % - \lst@EnterMode{\lst@TeXCLmode}{\lst@modetrue\lst@commentstyle}% - \fi} -% \end{macrocode} -% Now comes the same, but we process a 'two character'-separator. -% \begin{macrocode} -\def\lstCC@@BeginCommentLine#1#2{% - \lst@NewLine \lst@PrintToken % - \lst@EnterMode{\lst@CLmode}{\lst@modetrue\lst@commentstyle}% - #1\relax#2\relax % - \lst@iftexcl % - \lst@PrintToken % - \lst@LeaveMode \lst@InterruptModes % - \lst@EnterMode{\lst@TeXCLmode}{\lst@modetrue\lst@commentstyle}% - \fi} -% \end{macrocode} -% \end{macro}\end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{Doing output} -% -% -% \subsection{Output aspects and helpers} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{flexiblecolumns} -% Do you have any idea what to write here? -% \begin{macrocode} -\lst@Aspect{flexiblecolumns}[t]{\lstKV@SetIfKey\lst@ifflexible{#1}} -\lstset{flexiblecolumns=false}% init -% \end{macrocode} -% We assign the correct output macros defined below. -% As you can see there are three main macros, which handle letters, all other printing characters and tabulator stops. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifflexible % - \let\lst@Output\lst@OutputFlexible % - \let\lst@OutputOther\lst@OutputOtherFlexible % - \let\lst@GotoTabStop\lst@GotoTabStopFlexible % - \fi} -% \end{macrocode} -% \end{aspect} -% -% \begin{aspect}{baseem} -% We look whether or not the user gives two numbers, i.e.\ we test for a comma. -% \begin{macrocode} -\lst@Aspect{baseem}{\lstbaseem@#1,,\relax} -% \end{macrocode} -% Here we check for legal arguments \ldots -% \begin{macrocode} -\def\lstbaseem@#1,#2,#3\relax{% - \def\lst@next{\PackageError{Listings}% - {Nonnegative number(s) expected}% - {Separate one or two such numbers by a comma, next time.^^J% - Now type to proceed.}}% - \ifdim #1em<\z@\else % - \def\lst@baseemfixed{#1}% - \let\lst@baseemflexible\lst@baseemfixed % -% \end{macrocode} -% and do the comma test. -% \begin{macrocode} - \ifx\@empty#2\@empty % - \let\lst@next\relax % - \else \ifdim #2em<\z@\else % - \def\lst@baseemflexible{#2}% - \let\lst@next\relax % - \fi \fi % - \fi \lst@next} -% \end{macrocode} -% \begin{macrocode} -\lstset{baseem={0.6,0.45}}% init -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lst@width} -% The dimension holds the width of a single character box while typesetting a listing. -% \begin{macrocode} -\newdimen\lst@width -\lst@AddToHook{InitVars} - {\lst@width=\lst@ifflexible\lst@baseemflexible % - \else\lst@baseemfixed\fi em\relax} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{tabsize} -% We check for a legal argument before saving it. -% \begin{macrocode} -\lst@Aspect{tabsize} - {\ifnum#1>\z@ % - \def\lst@tabsize{#1}% - \else % - \PackageError{Listings}{Strict positive integer expected} - {You can't use `#1' as tabulator length.^^J% - Type to forget it and to proceed.}% - \fi} -% \end{macrocode} -% Default tabsize is 8 as proposed by \lsthelper{Rolf Niepraschk}{NIEPRASCHK@PTB.DE}{1997/04/24}{tabsize=8}. -% \begin{macrocode} -\lstset{tabsize=8}% init -% \end{macrocode} -% \end{aspect} -% -% Before looking at the output macros, we have to introduce some registers. -% -% \begin{macro}{\lst@token} -% \begin{macro}{\lst@length} -% The token register contains the current character string, for example |char| if we have just read these characters and a whitespace before. -% The counter |\lst@length| holds the length of the string and that's 4 in the example. -% \begin{macrocode} -\newtoks\lst@token \newcount\lst@length -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVarsEOL}{\lst@token{}\lst@length\z@} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@lastother} -% This is not a \TeX{} register. -% This macro is equivalent to the last 'other' character, other in the sense of section \ref{iCharacterClasses}. -% \begin{macrocode} -\lst@AddToHook{InitVarsEOL}{\let\lst@lastother\@empty} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@column} -% \begin{macro}{\lst@pos} -% With the two counters it is possible to determine the current column. -% It's the sum of |\lst@column| and |\lst@length| plus one minus |\lst@pos| --- |\lst@pos| will be nonpositive. -% It seems to be troublesome to decide whether a new line has just begun or not, i.e.\ if the current column number is one. -% And that's true. -% \begin{macrocode} -\newcount\lst@column \newcount\lst@pos % \global -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVarsEOL}{\global\lst@pos\z@ \global\lst@column\z@} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@lostspace} -% The output macros have to keep track of the difference between the real and desired (current) line width; the latter one given by 'current column times |\lst@width|'. -% More precisely, |\lst@lostspace| equals 'current column times |\lst@width|' minus 'width of so far printed line'. -% Whenever this dimension is positive we can insert space to fix the column alignment. -% \begin{macrocode} -\newdimen\lst@lostspace % \global -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVarsEOL}{\global\lst@lostspace\z@} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@UseLostSpace} -% This is a service macro for the fixed and flexible column output. -% We insert space and reset it (if and) only if |\lst@lostspace| is positive. -% \begin{macrocode} -\def\lst@UseLostSpace{% - \ifdim\lst@lostspace>\z@ % - \kern\lst@lostspace \global\lst@lostspace\z@ % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@InsertLostSpace} -% \begin{macro}{\lst@InsertHalfLostSpace} -% Ditto, but insert always (even if negative). -% \begin{macrocode} -\def\lst@InsertLostSpace{\kern\lst@lostspace \global\lst@lostspace\z@} -\def\lst@InsertHalfLostSpace{% - \global\lst@lostspace.5\lst@lostspace \kern\lst@lostspace} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{aspect}{outputpos} -% Note that there are two |\relax|es \ldots -% \begin{macrocode} -\lst@Aspect{outputpos}{\lstoutputpos@#1\relax\relax} -% \end{macrocode} -% or an empty argument would be bad here. -% We simply test for |l|, |c| and |r|. -% If none of them is given, we issue a warning and assume |r| --- it's default since it looks most bad to me. -% The fixed column format makes use of |\lst@lefthss| and |\lst@righthss|, whereas the flexible needs only |\lst@leftinsert|. -% \begin{macrocode} -\def\lstoutputpos@#1#2\relax{% - \ifx #1l% - \let\lst@lefthss\relax \let\lst@righthss\hss % - \let\lst@leftinsert\relax % - \else\ifx #1c% - \let\lst@lefthss\hss \let\lst@righthss\hss % - \let\lst@leftinsert\lst@InsertHalfLostSpace % - \else % - \let\lst@lefthss\hss \let\lst@righthss\relax % - \let\lst@leftinsert\lst@InsertLostSpace % - \ifx #1r\else \PackageWarning{Listings}% - {Unknown positioning for output boxes}% - \fi % - \fi\fi} -% \end{macrocode} -% \begin{macrocode} -\lstset{outputpos=c}% init -% \end{macrocode} -% \end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Dropping empty lines} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@NewLineMacro} -% This macro is assigned to |\lst@NewLine|, which is executed whenever the (next) line is not empty. -% Once called, it deactivates itself. -% \begin{macrocode} -\def\lst@NewLineMacro{% - \global\let\lst@NewLine\relax \par\noindent\hbox{}} -\lst@AddToHook{InitVars}{\global\let\lst@NewLine\lst@NewLineMacro} -% \end{macrocode} -% What we have said about |\lst@NewLine| is not the whole truth. -% Most times we'll assign |\lst@NewLineMacro|, but sometimes we append |\par\noindent\hbox{}| to prepare a new line, namely in the case that the last line has been empty. -% Then |\lst@NewLine| deactivates itself and begins two, three or more (empty) lines. -% This drops empty lines at the end of a listing. -% \begin{macrocode} -\lst@AddToHook{EOL} - {\ifx\lst@NewLine\relax % - \global\let\lst@NewLine\lst@NewLineMacro % - \else % - \lst@AddTo\lst@NewLine{\par\noindent\hbox{}}% - \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Fixed columns} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@OutputOther} -% This macro outputs a character string with nonletters. -% If there is anything to output, we possibly start a new line. -% \begin{macrocode} -\def\lst@OutputOther{% - \ifnum\lst@length=\z@\else % - \lst@NewLine \lst@UseLostSpace % -% \end{macrocode} -% The box must take |\lst@length| characters, each |\lst@width| wide. -% \begin{macrocode} - \hbox to \lst@length\lst@width{% - \lst@lefthss % - \lsthk@OutputOther % - \expandafter\lst@FillOutputBox\the\lst@token\relax % - \lst@righthss}% -% \end{macrocode} -% Finally we hold up the current column, empty the token and close the starting 'if token not empty'. -% \begin{macrocode} - \global\advance\lst@pos -\lst@length % - \lst@token{}\lst@length\z@ % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@Output} -% We reset |\lst@lastother| and use |\lst@thestyle|. -% \begin{macrocode} -\def\lst@Output{% - \let\lst@lastother\relax % - \ifnum\lst@length=\z@\else % - \lst@NewLine \lst@UseLostSpace % - \hbox to \lst@length\lst@width{% - \lst@lefthss % - \lsthk@Output \lst@thestyle{% - \expandafter\lst@FillOutputBox\the\lst@token\relax}% - \lst@righthss}% - \global\advance\lst@pos -\lst@length % - \lst@token{}\lst@length\z@ % - \fi} -% \end{macrocode} -% Note that |\lst@lastother| becomes equivalent to |\relax| and not equivalent to |\@empty| as in all other places (e.g.\ InitVarsEOL). -% I don't know whether this will be important in future or not. -% \end{macro} -% -% \begin{macro}{\lst@FillOutputBox} -% Filling up a box is easy. -% If we come to the end (the |\relax| from above), we do nothing. -% Otherwise we output the argument, insert dynamic space and call the macro again. -% \begin{macrocode} -\def\lst@FillOutputBox#1{% - \ifx\relax#1\else #1\hss\expandafter\lst@FillOutputBox \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@GotoTabStop} -% For fixed column format we only need to advance |\lst@lostspace| (which is inserted by the output macros above) and update the column. -% \begin{macrocode} -\def\lst@GotoTabStop{% - \global\advance\lst@lostspace \lst@length\lst@width % - \global\advance\lst@column\lst@length \lst@length\z@}% -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Flexible columns} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@OutputOtherFlexible} -% If there is something to output, we first insert the space lost by the flexible column format. -% Then we typeset the box and update the lost space. -% Note that we don't use any |\hss| here. -% \begin{macrocode} -\def\lst@OutputOtherFlexible{% - \ifnum\lst@length=\z@\else % - \lst@NewLine \lst@UseLostSpace % - \setbox\@tempboxa\hbox{\lsthk@OutputOther\the\lst@token}% - \lst@CalcLostSpaceAndOutput % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@OutputFlexible} -% Nothing is new here. -% \begin{macrocode} -\def\lst@OutputFlexible{% - \let\lst@lastother\relax % - \ifnum\lst@length=\z@\else % - \lst@NewLine \lst@UseLostSpace % - \setbox\@tempboxa\hbox{% - \lsthk@Output \lst@thestyle{\the\lst@token}}% - \lst@CalcLostSpaceAndOutput % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@GotoTabStopFlexible} -% Here we look whether or not the line already contains printing characters. -% \begin{macrocode} -\def\lst@GotoTabStopFlexible{% - \ifx\lst@NewLine\relax % -% \end{macrocode} -% If some characters are already printed, we output a box, which has the width of a blank space. -% Possibly more space is inserted, but that's upto the current value of |\lst@lostspace|. -% \begin{macrocode} - \setbox\@tempboxa\hbox{\lst@outputblank}\@tempdima\wd\@tempboxa% - \setbox\@tempboxa\hbox{}\wd\@tempboxa\@tempdima % - \lst@CalcLostSpaceAndOutput % - \global\lst@pos\z@ % - \else % -% \end{macrocode} -% Otherwise (no printed characters) we do the same as for fixed columns. -% \begin{macrocode} - \global\advance\lst@lostspace \lst@length\lst@width % - \global\advance\lst@column\lst@length \lst@length\z@ % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@CalcLostSpaceAndOutput} -% The update of |\lst@lostspace| is simple, refer its definition above (difference between \ldots). -% \begin{macrocode} -\def\lst@CalcLostSpaceAndOutput{% - \global\advance\lst@lostspace \lst@length\lst@width % - \global\advance\lst@lostspace-\wd\@tempboxa % -% \end{macrocode} -% Moreover we keep track of |\lst@pos| and reset some variables. -% \begin{macrocode} - \global\advance\lst@pos -\lst@length % - \lst@token{}\lst@length\z@ % -% \end{macrocode} -% Before |\@tempboxa| is output, we insert appropiate space if there is enough lost space. -% \begin{macrocode} - \ifdim\lst@lostspace>\z@ \lst@leftinsert \fi % - \box\@tempboxa} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Dropping the whole output} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@BeginDropOutput} -% It's sometimes useful to process a part of a listing as usual, but to drop the output. -% This macro does the main work and gets one argument, namely the internal mode it enters. -% We save |\lst@NewLine|, restore it |\aftergroup| and redefine the output macros. -% \begin{macrocode} -\def\lst@BeginDropOutput#1{% - \let\lst@BDOsave\lst@NewLine % - \lst@EnterMode{#1}% - {\lst@modetrue % - \let\lst@Output\lst@EmptyOutput % - \let\lst@OutputOther\lst@EmptyOutputOther % - \let\lst@GotoTabStop\lst@EmptyGotoTabStop % - \aftergroup\lst@BDORestore}} -% \end{macrocode} -% Restoring |\lst@NewLine| is quite easy: -% \begin{macrocode} -\def\lst@BDORestore{\global\let\lst@NewLine\lst@BDOsave} -% \end{macrocode} -% Note that there is no |\lst@EndDropOutput| since this macro would be equivalent to |\lst@LeaveMode|. -% \end{macro} -% -% \begin{macro}{\lst@EmptyOutputOther} -% \begin{macro}{\lst@EmptyOutput} -% \begin{macro}{\lst@EmptyGotoTabStop} -% Here we only keep track of registers (possibly) needed by other processing macros. -% \begin{macrocode} -\def\lst@EmptyOutputOther{% - \global\advance\lst@pos -\lst@length % - \lst@token{}\lst@length\z@} -% \end{macrocode} -% \begin{macrocode} -\def\lst@EmptyOutput{\let\lst@lastother\relax \lst@EmptyOutputOther} -% \end{macrocode} -% \begin{macrocode} -\def\lst@EmptyGotoTabStop{% - \global\advance\lst@column\lst@length \lst@length\z@} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Writing to an external file} -% -% The macros are defined (if and) only if the |doc| option is used. -% \begingroup -% \begin{macrocode} -%<*kernel> -\@ifundefined{lst@doc}{}{% -% \end{macrocode} -% \endgroup -% -% \begin{macro}{\lstdoc@out} -% The file we will write to. -% \begin{macrocode} -\newwrite\lstdoc@out -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@BeginWriteFile} -% redefines some macros to meet our purpose. -% The file with name |#1| is opened at the end of the macro. -% \begin{macrocode} -\def\lst@BeginWriteFile#1{% - \begingroup % - \lsthk@SetLanguage % - \let\lstCC@ifec\iffalse % - \let\lst@Output\lstdoc@Output % - \let\lst@OutputOther\lstdoc@Output % - \let\lst@GotoTabStop\lstdoc@GotoTabStop % - \let\lstCC@ProcessSpace\lstdoc@ProcessSpace % - \let\lst@MProcessListing\lstdoc@MProcessListing % - \let\smallbreak\relax % - \let\lst@prelisting\relax \let\lst@postlisting\relax % - \let\lst@@prelisting\relax \let\lst@@postlisting\relax % - \let\lstCC@Use\lstdoc@Use % - \let\lst@DeInit\lstdoc@DeInit % - \immediate\openout\lstdoc@out=#1\relax} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@EndWriteFile} -% closes the file and restores original macro meanings. -% \begin{macrocode} -\def\lst@EndWriteFile{\immediate\closeout\lstdoc@out \endgroup} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstdoc@Output} -% keeps only track of horizontal position. -% \begin{macrocode} -\def\lstdoc@Output{\global\advance\lst@pos -\lst@length \lst@length\z@} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstdoc@ProcessSpace} -% \begin{macro}{\lstdoc@GotoTabStop} -% We append the appropiate number of spaces. -% Note that |\lstCC@Append| increases |\lst@length| by 1, thus we need -2. -% \begin{macrocode} -\def\lstdoc@ProcessSpace{\lstCC@Append{ }} -\def\lstdoc@GotoTabStop{% - \@whilenum \lst@length>\z@ \do % - {\lstCC@Append{ }\advance\lst@length-2\relax}} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lstdoc@MProcessListing} -% writes one line to external file. -% \begin{macrocode} -\def\lstdoc@MProcessListing{% - \immediate\write\lstdoc@out{\the\lst@token}% - \lst@token{}\lst@length\z@ % - \lst@BOLGobble} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstdoc@DeInit} -% We write the rest to file and end processing. -% \begin{macrocode} -\def\lstdoc@DeInit{% - \ifnum\lst@length=\z@\else % - \immediate\write\lstdoc@out{\the\lst@token}% - \fi % - \egroup \smallbreak\lst@postlisting \endgroup} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstdoc@Use} -% Any processed character appends the character itself to |\lst@token| (but with catcode 12 or 10). -% The original |\lstCC@Use| is defined in section \ref{iCharacterTables}. -% \begin{macrocode} -\def\lstdoc@Use#1#2#3{% - \ifnum#2=\z@ % - \expandafter\@gobbletwo % - \else % - \catcode#2=\active \lccode`\~=#2\lccode`\/=#2% - \lowercase{\def~{\lstCC@Append{/}}}% - \fi % - \lstdoc@Use#1} -% \end{macrocode} -% \end{macro} -% -% \begingroup -% \begin{macrocode} -}% of \@ifundefined{lst@doc}{}{% -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Keyword comments} -% -% \begingroup -% \begin{macrocode} -%<*keywordcomments> -% \end{macrocode} -% \endgroup -% \begin{aspect}{keywordcomment} -% \begin{aspect}{doublekeywordcommentsemicolon} -% The same stuff as for the other comment commands. -% \begin{macrocode} -\lst@Aspect{keywordcomment} - {\lst@MakeKeywordArg{#1}\let\lst@KCkeywords\lst@arg % - \let\lst@DefKC\lstCC@KeywordComment} -% \end{macrocode} -% \begin{macrocode} -\lst@Aspect{doublekeywordcommentsemicolon}{\lstDKCS@#1} -\gdef\lstDKCS@#1#2#3% - {\lst@MakeKeywordArg{#1}\let\lst@KCAkeywordsB\lst@arg % - \lst@MakeKeywordArg{#2}\let\lst@KCAkeywordsE\lst@arg % - \lst@MakeKeywordArg{#3}\let\lst@KCBkeywordsB\lst@arg % - \let\lst@DefKC\lstCC@DoubleKeywordCommentS} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{SelectCharTable}{\lst@DefKC} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifsensitive\else % - \lst@MakeMacroUppercase\lst@KCkeywords % - \lst@MakeMacroUppercase\lst@KCAkeywordsB % - \lst@MakeMacroUppercase\lst@KCAkeywordsE % - \lst@MakeMacroUppercase\lst@KCBkeywordsB % - \fi} -\lst@AddToHook{SetLanguage}{% - \let\lst@DefKC\relax \let\lst@KCkeywords\@undefined % - \let\lst@KCAkeywordsB\@undefined \let\lst@KCAkeywordsE\@undefined % - \let\lst@KCBkeywordsB\@undefined} -% \end{macrocode} -% \end{aspect}\end{aspect} -% -% \begin{macro}{\lstCC@KeywordComment} -% For this type of keyword comments we save the old output macro and install a new one. -% Note that |\lstCC@KeywordComment| is executed after selecting the character table via |\lst@DefKC|. -% \begin{macrocode} -\gdef\lstCC@KeywordComment{% - \let\lst@Output@\lst@Output \let\lst@Output\lst@KCOutput} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@KCOutput} -% And now we look how the output works here. -% It starts as all the time. -% But if the current character sequence in |\lst@token| is one of the given keywords, we call a macro which starts and ends keyword comments. -% |\lst@next| is redefined there. -% After doing all this, we output the token as usual and go on. -% \begin{macrocode} -\gdef\lst@KCOutput{% - \ifnum\lst@length=\z@\else % - \let\lst@next\relax % - \expandafter\lst@IfOneOf \the\lst@token\relax \lst@KCkeywords % - {\lst@KCOutput@\lst@BeginKC}{}% - \lst@Output@ \lst@next % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@KCOutput@} -% Now we are in the situation that the current token is attached to a keyword comment. -% By default |\lst@next| becomes equivalent to the first argument, which is either |\lst@BeginKC| or |\lst@BeginDKCA| or |\lst@BeginDKCB|. -% Moreover we save the current token. -% \begin{macrocode} -\gdef\lst@KCOutput@#1{\let\lst@next#1% - \expandafter\def\expandafter\lst@save\expandafter{\the\lst@token}% -% \end{macrocode} -% If we are not in 'keyword comment mode', nothing else is done here. -% But if we are, we must end the comment. -% The problem: Closing the comment group also ruins the current character string in |\lst@token|. -% The solution: We define a global macro to restore the token and |\lst@length|. -% |\@gtempa| becomes -% \begin{itemize}\item[] -% |\lst@token{|\meta{current character string}|}\lst@length|\meta{current length}|\relax| -% \end{itemize} -% \begin{macrocode} - \lst@ifmode \ifnum\lst@mode=\lst@KCmode % - \xdef\@gtempa{% - \noexpand\lst@token{\the\lst@token}% - \noexpand\lst@length\the\lst@length\relax}% -% \end{macrocode} -% This macro is executed after closing the comment group. -% We redefine |\lst@next| just to |\relax|. -% \begin{macrocode} - \aftergroup\@gtempa \lst@LeaveMode \let\lst@next\relax % - \fi \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@BeginKC} -% We call |\lstCC@BeginComment| and define |\lst@KCkeywords| to be the current token (possibly made upper case) since we want a matching keyword. -% Note: It's a local definition, i.e.\ after ending the comment all comment starting keywords are restored. -% \begin{macrocode} -\gdef\lst@BeginKC{% - \lstCC@BeginComment\lst@KCmode \let\lst@KCkeywords\lst@save % - \lst@ifsensitive\else \lst@MakeMacroUppercase\lst@KCkeywords \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@DoubleKeywordCommentS} -% Let's look at the next macro collection. -% The first macro is the same as the first from above --- except that we must install a different semicolon, which is done at the very beginning. -% \begin{macrocode} -\gdef\lstCC@DoubleKeywordCommentS{% - \lstCC@EndKeywordComment{"003B}% - \let\lst@Output@\lst@Output \let\lst@Output\lst@DKCOutput} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@DKCOutput} -% The second macro is also the same as above, but if we haven't found a keyword from the |KCA| list, we try the |KCB| list. -% \begin{macrocode} -\gdef\lst@DKCOutput{% - \ifnum\lst@length=\z@\else % - \let\lst@next\relax % - \expandafter\lst@IfOneOf \the\lst@token\relax\lst@KCAkeywordsB % - {\lst@KCOutput@\lst@BeginDKCA}{% - \expandafter\lst@IfOneOf \the\lst@token\relax\lst@KCBkeywordsB % - {\lst@KCOutput@\lst@BeginDKCB}{}}% - \lst@Output@ \lst@next % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@BeginDKCA} -% \begin{macro}{\lst@BeginDKCB} -% To begin a keyword comment, we assign appropiate lists of keywords, which might end the comment. -% \begin{macrocode} -\gdef\lst@BeginDKCA{\lstCC@BeginComment\lst@KCmode % - \let\lst@KCAkeywordsB\lst@KCAkeywordsE \let\lst@KCBkeywordsB\@empty} -% \end{macrocode} -% \begin{macrocode} -\gdef\lst@BeginDKCB{\lstCC@BeginComment\lst@KCmode % - \let\lst@KCAkeywordsB\@empty \let\lst@KCBkeywordsB\@empty} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lstCC@EndKeywordComment} -% Above we've installed a 'end keyword comment' semicolon. -% Before reading further you should be familiar with section \ref{iCharacterTables}. -% Roughly speaking we define commands there, which annouces the source code character $0041_{\mathrm{hex}}$='A' to be the upper case letter 'A'. -% The macro here announces a character to end keyword comments. -% \begin{macrocode} -\gdef\lstCC@EndKeywordComment#1{% - \lccode`\~=#1\lowercase{\lstCC@EndKeywordComment@~}{#1}} -% \end{macrocode} -% Looking at the submacro, |#1| is an active character with ASCII code |#2|. -% We must save a previous meaning of |#1| --- or we couldn't output the character since we've forgotten it. -% Afterwards we can redefine it: If we are in comment mode and furthermore in keyword comment mode, the 'end keyword comment' character ends the comment, as desired. -% Note that we output the old meaning of the character first. -% \begin{macrocode} -\gdef\lstCC@EndKeywordComment@#1#2{% - \expandafter\let\csname lstCC@EKC#2\endcsname#1% - \def#1{% - \ifnum\lst@mode=\lst@KCmode % - \let\lstCC@next\lstCC@EndComment % - \else % - \let\lstCC@next\relax % - \fi % - \csname lstCC@EKC#2\endcsname \lstCC@next}} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{Character classes}\label{iCharacterClasses} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \TeX{} knows sixteen category codes. -% We define our own character classes here. -% Each input character becomes active in the sense of \TeX{} and characters of different classes expand to different meanings. -% We use the following ones: -% \begin{itemize} -% \item letters --- characters identifiers are of; -% \item digits --- characters for identifiers or numerical constants; -% \item spaces --- characters treated as blank spaces; -% \item tabulators --- characters treated as tabulators; -% \item stringizers --- characters beginning and ending strings; -% \item comment indicators --- characters or character sequences beginning and ending comments; -% \item special classes support particular programming languages; -% \item others --- all other characters. -% \end{itemize} -% How these classes work together? -% The digit '3' appends the digit to the current character string, e.g.\ |ear| becomes |ear3|. -% The next nonletter causes the output of the gathered characters. -% Then we collect all coming nonletters until reaching a letter again. -% This causes the output of the nonletters, and so on. -% -% But there are more details. -% Stringizers and comment indicators change the processing mode until the string or the comment is over. -% For example, no keyword tests are done within a string or comment. -% A tabulator immediately outputs the gathered characters, without looking whether they are letters or not. -% Afterwards it is possible to determine the tabulator skip. -% And there is one thing concerning spaces: -% Many spaces following each other disturb the column alignment since they are not wide enough. -% Hence, when column alignment is on, we output the space(s) preceding a space. -% -% The above classes can be divided into three types: -% \begin{itemize} -% \item The 'letter', 'digit' and 'other' class all put characters into the 'output queue' (using |\lstCC@Append| or |\lstCC@AppendOther|, see below). -% \item Stringizer, comment indicators and special classes don't affect the output queue directly. -% For example, before a character becomes a stringizer, the 'letter', 'digit' or 'other' meaning is saved. -% Now the stringizer accesses the output queue via this saved meaning. -% \item Spaces and tabulators don't put any character into the output queue, but may affect the queue to do their job, as mentioned above. -% Instances of these classes are not overwritten (in contrast to letters, digits and others). -% \end{itemize} -% Some easy implementation before looking closer \ldots -% -% \begin{macro}{\lstCC@Append} -% This macro appends the argument to the current character string and increases the counter |\lst@length|. -% \begin{macrocode} -\def\lstCC@Append#1{\advance\lst@length\@ne % - \expandafter\lst@token\expandafter{\the\lst@token#1}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@AppendOther} -% Nearly the same, but we save the argument (a single character or a single macro) in |\lst@lastother|. -% \begin{macrocode} -\def\lstCC@AppendOther#1{\advance\lst@length\@ne \let\lst@lastother#1% - \expandafter\lst@token\expandafter{\the\lst@token#1}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ifletter} -% This \texttt{if} indicates whether the last character has been a letter or not. -% \begin{macrocode} -\def\lstCC@lettertrue{\let\lstCC@ifletter\iftrue} -\def\lstCC@letterfalse{\let\lstCC@ifletter\iffalse} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{InitVars}{\lstCC@letterfalse} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@PrintToken} -% This macro outputs the current character string in letter or nonletter mode. -% \begin{macrocode} -\def\lst@PrintToken{% - \lstCC@ifletter % - \lst@Output\lstCC@letterfalse % - \else % - \lst@OutputOther \let\lst@lastother\@empty % - \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Character tables}\label{iCharacterTables} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% Before looking at interesting character classes we do some rather tedious coding. -% Consider a source file of a programming language now. -% For example, the character $41_{\mathrm{hex}}=65_{\mathrm{dec}}$ usually belongs to the letter class and represents the letter 'A'. -% The listings package says |\lstCC@Use\lstCC@ProcessLetter|\ldots|{"41}{A}|\ldots\ to make this clear. -% Roughly speaking it expands to |\def A{\lstCC@ProcessLetter A}|, but the first 'A' is active and the second not. -% -% \begin{macro}{\lstCC@Def} -% \begin{macro}{\lstCC@Let} -% For speed we won't used these helpers too often. -% The letter 'A' definition from above could be achieved via |\lstCC@Def{"41}{\lstCC@ProcessLetter A}|. -% \begin{macrocode} -\def\lstCC@Def#1{\catcode#1=\active\lccode`\~=#1\lowercase{\def~}} -\def\lstCC@Let#1{\catcode#1=\active\lccode`\~=#1\lowercase{\let~}} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lst@SelectCharTable} -% Each input character becomes active and gets the correct meaning here. -% We change locally the catcode of the double quote for compatibility with \texttt{german.sty}. -% Note that some macros take one argument and others a series of arguments which is terminated by |{"00}{}| (or an equivalent expression). -% \begin{macrocode} -\begingroup \catcode`\"=12 -\gdef\lst@SelectCharTable{% - \lstCC@Tabulator{"09}% - \lstCC@Space{"20}% - \lstCC@Use \lstCC@ProcessOther % - {"21}!{"22}"{"23}\#{"25}\%{"26}\&{"27}'{"28}({"29})% - {"2A}\lst@asterisk{"2B}+{"2C},{"2D}\lst@minus{"2E}.% - {"2F}/{"3A}:{"3B};{"3C}\lst@less{"3D}={"3E}\lst@greater{"3F}?% - {"5B}[{"5C}\lst@backslash{"5D}]{"5E}\textasciicircum{"60}{`}% - {"7B}\lst@lbrace{"7C}\lst@bar{"7D}\lst@rbrace % - {"7E}\textasciitilde{"7F}-% - \z@\@empty % - \lstCC@Use \lstCC@ProcessDigit % - {"30}0{"31}1{"32}2{"33}3{"34}4{"35}5{"36}6{"37}7{"38}8{"39}9% - \z@\@empty % - \lstCC@Use \lstCC@ProcessLetter % - {"24}\lst@dollar{"40}@% - {"41}A{"42}B{"43}C{"44}D{"45}E{"46}F{"47}G{"48}H{"49}I{"4A}J% - {"4B}K{"4C}L{"4D}M{"4E}N{"4F}O{"50}P{"51}Q{"52}R{"53}S{"54}T% - {"55}U{"56}V{"57}W{"58}X{"59}Y{"5A}Z{"5F}\lst@underscore % - {"61}a{"62}b{"63}c{"64}d{"65}e{"66}f{"67}g{"68}h{"69}i{"6A}j% - {"6B}k{"6C}l{"6D}m{"6E}n{"6F}o{"70}p{"71}q{"72}r{"73}s{"74}t% - {"75}u{"76}v{"77}w{"78}x{"79}y{"7A}z% - \z@\@empty % -% \end{macrocode} -% Define extended characters 128--255. -% \begin{macrocode} - \lstCC@ifec \lstCC@DefEC \fi % -% \end{macrocode} -% Finally we call some (hook) macros and initialize the backslash if necessary. -% \begin{macrocode} - \lsthk@SelectCharTable % - \csname lstSCT@\lst@language\endcsname % - \csname lstSCT@\lst@language @\lst@dialect\endcsname % - \ifx\lstCC@Backslash\relax\else % - \lccode`\~="5C\lowercase{\let\lsts@backslash~}% - \lstCC@Let{"5C}\lstCC@Backslash % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@DefEC} -% Currently each character in the range 128--255 is treated as a letter. -% \begin{macrocode} -\catcode`\^^@=12 -\gdef\lstCC@DefEC{% - \lstCC@ECUse \lstCC@ProcessLetter % - ^^80^^81^^82^^83^^84^^85^^86^^87^^88^^89^^8a^^8b^^8c^^8d^^8e^^8f% - ^^90^^91^^92^^93^^94^^95^^96^^97^^98^^99^^9a^^9b^^9c^^9d^^9e^^9f% - ^^a0^^a1^^a2^^a3^^a4^^a5^^a6^^a7^^a8^^a9^^aa^^ab^^ac^^ad^^ae^^af% - ^^b0^^b1^^b2^^b3^^b4^^b5^^b6^^b7^^b8^^b9^^ba^^bb^^bc^^bd^^be^^bf% - ^^c0^^c1^^c2^^c3^^c4^^c5^^c6^^c7^^c8^^c9^^ca^^cb^^cc^^cd^^ce^^cf% - ^^d0^^d1^^d2^^d3^^d4^^d5^^d6^^d7^^d8^^d9^^da^^db^^dc^^dd^^de^^df% - ^^e0^^e1^^e2^^e3^^e4^^e5^^e6^^e7^^e8^^e9^^ea^^eb^^ec^^ed^^ee^^ef% - ^^f0^^f1^^f2^^f3^^f4^^f5^^f6^^f7^^f8^^f9^^fa^^fb^^fc^^fd^^fe^^ff% - ^^00} -\endgroup -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{extendedchars} -% The user aspect. -% \begin{macrocode} -\lst@Aspect{extendedchars}[t]{\lstKV@SetIfKey\lstCC@ifec{#1}} -\lstset{extendedchars=false}% init -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lstCC@Use} -% Now we define the |\lstCC@|\ldots|Use| macros used above. -% We either define the character with code |#2| to be |#1#3| (where |#1| is |\lstCC@ProcessLetter| for example) or we gobble the two token after |\fi| to terminate the loop. -% \begin{macrocode} -\def\lstCC@Use#1#2#3{% - \ifnum#2=\z@ % - \expandafter\@gobbletwo % - \else % - \catcode#2=\active \lccode`\~=#2\lowercase{\def~}{#1#3}% - \fi % - \lstCC@Use#1} -% \end{macrocode} -% Limitation: Each second argument to |\lstCC@Use| (beginning with the third one) must be exactly one character or one control sequence. -% The reason is not the definition here. -% |\lst@AppendOther| says |\let\lst@lastother#1| and that works with the mentioned limitation only. -% I'll get over this since |\let| is faster than |\def|, and that's the motivation. -% \emph{Caution}: Don't change that |\let| to a definition with |\def|. -% All |\ifx\lst@lastother|\ldots{} in all character classes wouldn't work any more! -% And rewriting all this would slow down the package. -% Beware of that. -% \end{macro} -% -% \begin{macro}{\lstCC@ECUse} -% Here we have two arguments only, namely |\lstCC@ProcessLetter|,\ldots\ and the character (and no character code). -% Reaching end of list (|^^00|) we terminate the loop. -% Otherwise we do the same as in |\lstCC@Use| if the character is not active. -% But if the character is active, we save the meaning before redefinition. -% \begin{macrocode} -\def\lstCC@ECUse#1#2{% - \ifnum`#2=\z@ % - \expandafter\@gobbletwo % - \else % - \ifnum\catcode`#2=\active % - \lccode`\~=`#2\lccode`\/=`#2\lowercase{\lstCC@ECUse@#1~/}% - \else % - \catcode`#2=\active \lccode`\~=`#2\lowercase{\def~}{#1#2}% - \fi % - \fi % - \lstCC@ECUse#1} -% \end{macrocode} -% As mentioned, we save the meaning before redefinition. -% \begin{macrocode} -\def\lstCC@ECUse@#1#2#3{% - \expandafter\let\csname lsts@EC#3\endcsname #2% - \edef#2{\noexpand#1\expandafter\noexpand\csname lsts@EC#3\endcsname}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@Tabulator} -% \begin{macro}{\lstCC@Space} -% The similar space and tabulator macros have one argument only (no loop and no macro or character). -% \begin{macrocode} -\def\lstCC@Tabulator#1{\lstCC@Let{#1}\lstCC@ProcessTabulator} -\def\lstCC@Space#1{\lstCC@Let{#1}\lstCC@ProcessSpace} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lstCC@ChangeBasicClass} -% Finally we define a macro (collection) with the ability of moving a basic \emph{instance} of class to another class, e.g. making the digit '0' be a letter. -% The word 'basic' means any instance defined with |\lstCC@Use| or |\lstCC@ECUse|. -% The first argument of |\lstCC@ChangeBasicClass| gives the new class and the second argument is a macro containing a character sequence. -% These characters are changed. -% First we make all these characters active and call a submacro. -% \begin{macrocode} -\def\lstCC@ChangeBasicClass#1#2{% - \ifx\@empty#2\else % - \expandafter\lst@MakeActive\expandafter{#2}% - \expandafter\lstCC@CBC@\expandafter#1\lst@arg\@empty % - \fi} -% \end{macrocode} -% The submacro terminates (gobble two token after |\fi|) if it reaches |\@empty|. -% Otherwise another submacro redfines the character. -% Note that we expand the old meaning before calling the second submacro and that the second |\lstCC@CBC@@| is used as 'meaning' delimiter. -% \begin{macrocode} -\def\lstCC@CBC@#1#2{% - \ifx\@empty#2% - \expandafter\@gobbletwo % - \else % - \expandafter\lstCC@CBC@@#2\lstCC@CBC@@#1#2% - \fi % - \lstCC@CBC@#1} -% \end{macrocode} -% \begin{macrocode} -\def\lstCC@CBC@@#1#2\lstCC@CBC@@#3#4{\def#4{#3#2}} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Letters, digits and others} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lstCC@ProcessLetter} -% To process a letter we look at the last character. -% If it hasn't been a letter, we output the preceding other characters first and switch to letter mode. -% Finally we append the current letter |#1|. -% \begin{macrocode} -\def\lstCC@ProcessLetter#1{% - \lstCC@ifletter\else \lst@OutputOther\lstCC@lettertrue \fi % - \lstCC@Append{#1}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessOther} -% 'Other' characters are the other way round. -% If the last character has been a letter, the preceding letters are output and we switch to nonletter mode. -% Finally we append the current other character. -% \begin{macrocode} -\def\lstCC@ProcessOther#1{% - \lstCC@ifletter \lst@Output\lstCC@letterfalse \fi % - \lstCC@AppendOther{#1}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessDigit} -% A digit simply appends the character to the current character string. -% But we must use the right macro. -% This allow digits to be part of an identifier or a numerical constant. -% \begin{macrocode} -\def\lstCC@ProcessDigit#1{% - \lstCC@ifletter \lstCC@Append{#1}\else \lstCC@AppendOther{#1}\fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Tabulators and spaces} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% Here we have to take care of two things: -% First dropping empty lines at the end of a listing, and second the flexible column format. -% In both cases we use |\lst@lostspace| for the implementation. -% Whenever this dimension is positive we insert that space before |\lst@token| is output. -% -% We've defined |\lst@EOLUpdate| to drop empty lines at the end of a listing. -% |\lst@NewLine| isn't executed or reset in that case. -% Instead we append control sequences. -% But: Lines containing tabulators and spaces only should also be viewed as empty. -% In order to achieve this tabulators and spaces at the beginning of a line advance |\lst@lostspace| and don't output any characters. -% The space is inserted if there comes a letter for example. -% If there are only tabulators and spaces, the line is 'empty' since we haven't done any output. -% -% We have to do more for flexible columns. -% The whitespaces can fix the column alignment: -% If the real line is wider than it should be (|\lst@lostspace|$<$0pt), a tabulator is at least one space wide; all the other width is used to make |\lst@lostspace| more positive. -% Spaces do the same: If there are two or more spaces, at least one space is printed; the others fix the column alignment. -% If we process a string, all spaces are output, of course. -% -% \begin{macro}{\lstCC@ProcessTabulator} -% A tabulator outputs the preceding characters. -% \begin{macrocode} -\def\lstCC@ProcessTabulator{% - \lst@PrintToken % -% \end{macrocode} -% Then we must calculate how many columns we need to reach the next tabulator stop. -% Each printed character decrements the counter |\lst@pos|. -% Hence we can simply add |\lst@tabsize| until |\lst@pos| is strict positive. -% That's all. -% We assign it to |\lst@length|, reset |\lst@pos| \ldots -% \begin{macrocode} - \global\advance\lst@column -\lst@pos % - \@whilenum \lst@pos<\@ne \do % - {\global\advance\lst@pos\lst@tabsize}% - \lst@length\lst@pos \global\lst@pos\z@ %} -% \end{macrocode} -% and go to the tabulator stop, e.g.\ |\lst@length| columns forward: -% \begin{macrocode} - \lst@GotoTabStop} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@AppendSpecialSpace} -% Sometimes we have special spaces: -% If there are at least two spaces, i.e.\ if the last character have been a space, we output preceding characters and advance |\lst@lostspace| to avoid alignment problems. -% Otherwise we append a space to the current character string. -% We'll need that macro soon. -% \begin{macrocode} -\def\lstCC@AppendSpecialSpace{% - \ifx\lst@lastother\lst@outputblank % - \lst@OutputOther % - \global\advance\lst@lostspace\lst@width % - \global\advance\lst@pos\m@ne % - \else % - \lstCC@AppendOther\lst@outputblank % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lst@outputblank} -% It's better not to forget this. -% \begin{macrocode} -\def\lst@outputblank{\ } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessSpace} -% If the last character has been a letter, we output the current character string and append one space. -% \begin{macrocode} -\def\lstCC@ProcessSpace{% - \lstCC@ifletter % - \lst@Output\lstCC@letterfalse % - \lstCC@AppendOther\lst@outputblank % -% \end{macrocode} -% Otherwise we look whether we are in string mode or not. -% In the first case we must append a space; in the second case we must test if the hitherto line is empty. -% \begin{macrocode} - \else \ifnum\lst@mode=\lst@stringmode % - \lstCC@AppendOther\lst@outputblank % - \else \ifx\lst@NewLine\relax % -% \end{macrocode} -% If the line is not empty we either advance |\lst@lostspace| or append a space to the current character string. -% \begin{macrocode} - \lstCC@AppendSpecialSpace % - \else \ifnum\lst@length=\z@ % -% \end{macrocode} -% If the line is empty so far, we advance |\lst@lostspace|. -% Otherwise we append the space. -% \begin{macrocode} - \global\advance\lst@lostspace\lst@width % - \global\advance\lst@pos\m@ne % - \else % - \lstCC@AppendSpecialSpace % - \fi % - \fi \fi \fi} -% \end{macrocode} -% Note that this version works for fixed and flexible column output. -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Stringizer} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lst@legalstringizer} -% Currently there are three different stringizer types: 'd'oubled, 'b'ackslashed and 'm'atlabed. -% The naming of the first two is due to how the stringizer is represented in a string. -% Pascal doubles it, i.e.\ the string |'| is represented by four single quotes |''''|, where the first and last enclose the string and the two middle quotes represent the desired stringizer. -% In C++ we would write |"\""|: A backslash indicates that the next double quote belongs to the string and is not the end of string. -% The matlabed version is described below. -% I introduced it after communication with \lsthelper{Zvezdan V. Petkovic}{zpetkovic@acm.org}{1997/11/26}{'single stringizer' not a stringizer in Ada (and Matlab)}. -% \begin{macrocode} -\def\lst@legalstringizer{d,b,m,bd,db} -% \end{macrocode} -% Furthermore we have the two mixed types |bd| and |db|, which in fact equal |b|. -% \end{macro} -% -% \begin{aspect}{stringizer} -% Here we test whether the user type is supported or not (leading to an error message). -% In the first case we (re-) define |\lst@DefStrings|. -% \begin{macrocode} -\lst@Aspect{stringizer}{\lstKV@OptArg\lststringizer@[d]{#1}} -\def\lststringizer@[#1]#2% - {\lst@IfOneOf#1\relax \lst@legalstringizer % - {\def\lst@DefStrings{\lstCC@Stringizer[#1]#2\@empty}}% - {\PackageError{Listings}{Illegal stringizer type `#1'}% - {Available types are \lst@legalstringizers.}}} -\lst@AddToHook{SetLanguage}{\let\lst@DefStrings\@empty} -\lst@AddToHook{SelectCharTable}{\lst@DefStrings} -% \end{macrocode} -% The just added hook defines the strings after selecting the standard character table. -% This adjusts the character table to the user's demands. -% \end{aspect} -% -% \begin{macro}{\lstCC@Stringizer} -% This macro is similar to |\lstCC@ECUse|, but we build the 'use'd name before defining the characters \ldots -% \begin{macrocode} -\def\lstCC@Stringizer[#1]{% - \expandafter\lstCC@Stringizer@ % - \csname lstCC@ProcessStringizer@#1\endcsname} -\def\lstCC@Stringizer@#1#2{% - \ifx\@empty#2% - \expandafter\@gobbletwo % -% \end{macrocode} -% which is terminated by |\@empty|. -% Otherwise we save the old meaning in |\lsts@s|\meta{the character} (with catcode 12) and redefine it. -% \begin{macrocode} - \else % - \catcode`#2=\active \lccode`\~=`#2\lccode`\/=`#2% - \lowercase{% - \expandafter\let\csname lsts@s/\endcsname~% - \def~{#1/}}% - \fi % - \lstCC@Stringizer@#1} -% \end{macrocode} -% And now we define all 'process stringizer' macros. -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessStringizer@d} -% 'd' means no extra work. -% Reaching the (first) stringizer enters string mode and coming to the next leaves it, and so on. -% Then the character sequence |''''| produces the right output: -% The second quote leaves string mode, but we enter it immediately since the stringizer is doubled. -% And now the implementation. -% First we output any preceding letters. -% \begin{macrocode} -\def\lstCC@ProcessStringizer@d#1{% - \lstCC@ifletter \lst@Output\lstCC@letterfalse \fi % -% \end{macrocode} -% If we already process a string, we execute the saved meaning and look whether the last other (that's the stringizer) is the matching stringizer --- a single quote must not end a string starting with a double quote. -% The macro |\lstCC@EndString| is defined at the end of this section. -% \begin{macrocode} - \ifnum\lst@mode=\lst@stringmode % - \csname lsts@s#1\endcsname % - \ifx\lst@lastother\lstCC@closestring % - \lstCC@EndString % - \fi % - \else % - \lst@OutputOther % -% \end{macrocode} -% If we don't process a string, we test whether or not a string is allowed. -% |\lstCC@BeginString| enters string mode and defines the closing stringizer. -% This 'begin string' macro gets one argument, hence we expand the control sequence name before executing the macro (if necessary). -% \begin{macrocode} - \lst@ifmode\else % - \expandafter\expandafter\expandafter\lstCC@BeginString % - \fi % - \csname lsts@s#1\endcsname % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessStringizer@b} -% 'b' means an extra if: Only if the last other is not a backslash (5-th line) the stringizer can close the string. -% The rest is the same as above. -% \begin{macrocode} -\def\lstCC@ProcessStringizer@b#1{% - \lstCC@ifletter \lst@Output\lstCC@letterfalse \fi % - \ifnum\lst@mode=\lst@stringmode % - \let\lst@temp\lst@lastother \csname lsts@s#1\endcsname % - \ifx\lst@temp\lst@backslash\else %!def of "005C - \ifx\lst@lastother\lstCC@closestring % - \lstCC@EndString % - \fi \fi % - \else % - \lst@OutputOther % - \lst@ifmode\else % - \expandafter\expandafter\expandafter\lstCC@BeginString % - \fi % - \csname lsts@s#1\endcsname % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessStringizer@bd} -% \begin{macro}{\lstCC@ProcessStringizer@db} -% are just the same and the same as |\lstCC@ProcessStringizer@b|: -% \begin{macrocode} -\let\lstCC@ProcessStringizer@bd\lstCC@ProcessStringizer@b -\let\lstCC@ProcessStringizer@db\lstCC@ProcessStringizer@bd -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lstCC@ProcessStringizer@m} -% 'm'atlabed is designed for programming languages where stringizers (for character or string literals) are also used for other purposes, like Matlab or Ada. -% Here we enter string mode only if the last character has not been a letter and has not been a right parenthesis. -% Hence, we have to move the |\lstCC@ifletter| and change the main |\else| part. -% By the way: The stringizer is doubled in a string. -% \begin{macrocode} -\def\lstCC@ProcessStringizer@m#1{% - \ifnum\lst@mode=\lst@stringmode % - \lstCC@ifletter \lst@Output\lstCC@letterfalse \fi % - \csname lsts@s#1\endcsname % - \ifx\lst@lastother\lstCC@closestring % - \lstCC@EndString % - \fi % - \else % -% \end{macrocode} -% And now the real 'm' changes: -% \begin{macrocode} - \lstCC@ifletter % - \lst@Output\lstCC@letterfalse % - \else % - \lst@OutputOther % - \let\lstCC@next\relax % - \ifx\lst@lastother)\else \lst@ifmode\else % - \let\lstCC@next\lstCC@BeginString % - \fi \fi % - \expandafter\expandafter\expandafter\lstCC@next % - \fi % - \csname lsts@s#1\endcsname % - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{stringstyle} -% \begin{aspect}{blankstring} -% We insert some easy definitions. -% \begin{macrocode} -\lst@Aspect{stringstyle}{\def\lst@stringstyle{#1}} -% \end{macrocode} -% Thanks to \lsthelper{Knut M\"uller}{knut@physik3.gwdg.de}{1997/04/28}{\blankstringtrue} for reporting problem with |\blankstringtrue|. -% The problem has gone. -% \begin{macrocode} -\lst@Aspect{blankstring}[t]{\lstKV@SetIfKey\lst@ifblankstring{#1}} -% \end{macrocode} -% \begin{macrocode} -\lstset{blankstring=false}% init -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{\lst@stringstyle \lst@loadfd}} -% \end{macrocode} -% \end{aspect}\end{aspect} -% -% \begin{macro}{\lst@stringmode} -% It's time for a new mode allocation: -% \begin{macrocode} -\lst@NewMode\lst@stringmode -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@BeginString} -% \begin{macro}{\lstCC@EndString} -% To activate string mode we do te usual things, but here we also assign the correct closing stringizer and |\lst@outputblank|. -% Note that you know that |\lst@NewLine| deactivates itself. -% \begin{macrocode} -\def\lstCC@BeginString#1{% - \lst@NewLine % - \lst@EnterMode{\lst@stringmode}{\lst@modetrue\lst@stringstyle}% - #1% - \let\lstCC@closestring\lst@lastother % - \lst@ifblankstring\else \let\lst@outputblank\textvisiblespace \fi} -% \end{macrocode} -% We terminate that mode selection after printing the collected other characters --- at least the closing stringizer. -% And we reset some registers. -% \begin{macrocode} -\def\lstCC@EndString{% - \lst@OutputOther \lst@LeaveMode \lst@token{}\lst@length\z@} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{aspect}{stringtest} -% We |\let| the test macro |\relax| if necessary. -% \begin{macrocode} -\lst@Aspect{stringtest}[t]{\lstKV@SetIfKey\lst@ifstringtest{#1}} -\lst@AddToHook{SetLanguage}{\let\lst@ifstringtest\iftrue} -\lst@AddToHook{BeforeSelectCharTable} - {\lst@ifstringtest\else \let\lst@TestStringMode\relax \fi} -% \end{macrocode} -% Default definition of the test macro: -% \begin{macrocode} -\def\lst@TestStringMode{% - \ifnum\lst@mode=\lst@stringmode % - \PackageWarning{Listings}{String constant exceeds line}% - \lst@LeaveMode \lst@token{}\lst@length\z@ % - \fi} -\lst@AddToHook{EOL}{\lst@TestStringMode} -% \end{macrocode} -% \end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Comments} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{commentstyle} -% Again we start with an easy definition. -% \begin{macrocode} -\lst@Aspect{commentstyle}{\def\lst@commentstyle{#1}} -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{\lst@commentstyle \lst@loadfd}} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lstCC@BeginComment} -% \begin{macro}{\lstCC@@BeginComment} -% \begin{macro}{\lstCC@EndComment} -% These macros start and end a comment, respectively. -% The |@@| version also eat (and output) one or two characters. -% In that case the characters belong to the comment indicator. -% |\relax| ensures that the characters are really eaten, i.e.\ the characters can't end the current comment or start a new one. -% Note again that |\lst@NewLine| deactivates itself. -% \begin{macrocode} -\def\lstCC@BeginComment#1{% - \lst@NewLine \lst@PrintToken % - \lst@EnterMode{#1}{\lst@modetrue\lst@commentstyle}} -% \end{macrocode} -% \begin{macrocode} -\def\lstCC@@BeginComment#1#2#3{% - \lst@NewLine \lst@PrintToken % - \lst@EnterMode{#1}{\lst@modetrue\lst@commentstyle}% - \lst@mode\lst@nomode #2\relax#3\relax \lst@mode#1\relax} -% \end{macrocode} -% \begin{macrocode} -\def\lstCC@EndComment{% - \lst@PrintToken \lst@LeaveMode \let\lst@lastother\@empty} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lstCC@TestCArg} -% Comment commands allow a single character like |!| or two characters like |//|. -% The calling syntax of this testing macro is -% \begin{macrosyntax} -% \item |\lstCC@TestCArg|\meta{characters to test}|\@empty\relax|\meta{macro} -% \end{macrosyntax} -% \meta{macro} is called after doing the test and gets three arguments: -% The given two characters as active characters (where the second equals |\@empty| if and only if a single character is given), and the third is a catcode 12 version of the first character. -% \begin{macrocode} -\begingroup \catcode`\^^@=\active -\gdef\lstCC@TestCArg#1#2#3\relax#4{% - \lccode`\~=`#1\lccode`\/=`#1% - \ifx\@empty#2% - \lowercase{\def\lst@temp{~\@empty/}}% - \else \lccode`\^^@=`#2% - \lowercase{\def\lst@temp{~^^@/}}% - \fi % -% \end{macrocode} -% If neither |#2| nor |#3| equals |\@empty|, the user has given more than two characters: -% \begin{macrocode} - \ifx\@empty#2\else \ifx\@empty#3\else \lstCC@TestCArgError \fi\fi % -% \end{macrocode} -% \begin{macrocode} - \expandafter #4\lst@temp} -\endgroup -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@TestCArgError} -% \begin{macrocode} -\def\lstCC@TestCArgError{% - \PackageError{Listings}{At most 2 characters allowed}% - {The package doesn't provide more than two characters here.^^J% - I'll simply use the first two only and proceed.}} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@next} -% \begin{macro}{\lstCC@bnext} -% \begin{macro}{\lstCC@enext} -% We initialize some macros used in the sequel. -% \begin{macrocode} -\lst@AddToHook{BeforeSelectCharTable} - {\let\lstCC@next\relax \let\lstCC@bnext\relax\let\lstCC@enext\relax} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lst@DefSC} -% \begin{macro}{\lst@DefNC} -% \begin{macro}{\lst@DefDC} -% \begin{macro}{\lst@DefCL} -% \begin{macro}{\lst@DefFCL} -% These macros are redefined by comment aspects. -% The comments are reset every language selection, and every listing we define the comment characters after selecting the standard character table. -% \begin{macrocode} -\lst@AddToHook{SetLanguage} - {\let\lst@DefSC\relax \let\lst@DefNC\relax \let\lst@DefDC\relax % - \let\lst@DefCL\relax \let\lst@DefFCL\relax} -\lst@AddToHook{SelectCharTable} - {\lst@DefSC \lst@DefNC \lst@DefDC \lst@DefCL \lst@DefFCL} -% \end{macrocode} -% \end{macro}\end{macro}\end{macro}\end{macro} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsubsection{Comment lines} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{commentline} -% We define the user aspect: -% \begin{macrocode} -\lst@Aspect{commentline}{\def\lst@DefCL{\lstCC@CommentLine{#1}}} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lstCC@CommentLine} -% Comment lines become undefined if the one and only argument is empty. -% \begin{macrocode} -\def\lstCC@CommentLine#1{% - \ifx\@empty#1\@empty\else % - \lstCC@TestCArg#1\@empty\relax\lstCC@CommentLine@ % - \fi} -% \end{macrocode} -% The next submacro actually defines the comment characters. -% We save the old meaning --- or we couldn't use the original meaning any more. -% \begin{macrocode} -\def\lstCC@CommentLine@#1#2#3{% - \expandafter\let\csname lsts@CL#3\endcsname#1% -% \end{macrocode} -% The redefinitions: -% If a single character indicates a comment, the next operation is either |\relax| (since no mode change is allowed) or |\lstCC@BeginCommentLine|. -% And we execute the saved character meaning. -% \begin{macrocode} - \ifx\@empty#2% - \def#1{% - \lst@ifmode \let\lstCC@next\relax \else % - \let\lstCC@next\lstCC@BeginCommentLine % - \fi % - \expandafter\lstCC@next \csname lsts@CL#3\endcsname}% - \else % -% \end{macrocode} -% Comment lines indicated by a sequence of two characters are just the same. -% But: We enter comment mode (if and) only if the next character equals |#2|. -% And we use a different macro to enter comment mode. -% \begin{macrocode} - \def#1##1{% - \let\lstCC@next\relax % - \lst@ifmode\else \ifx##1#2% - \let\lstCC@next\lstCC@@BeginCommentLine % - \fi \fi % - \expandafter\lstCC@next \csname lsts@CL#3\endcsname##1}% - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{fixedcommentline} -% \begin{macro}{\lst@FCLmode} -% Another user aspect \ldots -% \begin{macrocode} -\lst@Aspect{fixedcommentline}{\lstKV@OptArg\lstfcommentline@[0]{#1}} -\def\lstfcommentline@[#1]#2% - {\def\lst@DefFCL{\lstCC@FixedCL[#1]#2\@empty}} -% \end{macrocode} -% and a mode allocation. -% \begin{macrocode} -\lst@NewMode\lst@FCLmode -% \end{macrocode} -% \end{macro}\end{aspect} -% -% \begin{macro}{\lstCC@FixedCL} -% Note that we can't use |\lstCC@TestCArg| here since the argument might consist of more than two characters. -% We enter a loop which is terminated by |\@empty|. -% \begin{macrocode} -\def\lstCC@FixedCL[#1]#2{% - \ifx\@empty#2\else % - \lccode`\~=`#2\lccode`\/=`#2% - \lowercase{\lstCC@FixedCL@~/}{#1}% - \def\lstCC@next{\lstCC@FixedCL[#1]}% - \expandafter\lstCC@next % - \fi} -% \end{macrocode} -% But now comes the same as above: We save the old meaning of |#1| and redefine it. -% We enter comment mode (if and) only if the character is in column |#3|+1. -% \begin{macrocode} -\def\lstCC@FixedCL@#1#2#3{% - \expandafter\let\csname lsts@FCL#2\endcsname#1% - \def#1{\let\lstCC@next\relax % - \lst@ifmode\else % - \@tempcnta\lst@column % - \advance\@tempcnta\lst@length % - \advance\@tempcnta-\lst@pos % - \ifnum\@tempcnta=#3% - \let\lstCC@next\lstCC@BeginCommentLine % - \fi % - \fi % - \expandafter\lstCC@next \csname lsts@FCL#2\endcsname}} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsubsection{Single and double comments} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{singlecomment} -% \begin{aspect}{doublecomment} -% Define the user commands \ldots -% \begin{macrocode} -\lst@Aspect{singlecomment}{\def\lst@DefSC{\lstCC@SingleComment#1{}}} -\lst@Aspect{doublecomment}{\def\lst@DefDC{\lstCC@DoubleComment#1{}{}{}}} -% \end{macrocode} -% \end{aspect}\end{aspect} -% -% \begin{macro}{\lst@SCmode} -% \begin{macro}{\lst@DCmodeA} -% \begin{macro}{\lst@DCmodeB} -% and allocate new internal modes. -% \begin{macrocode} -\lst@NewMode\lst@SCmode \lst@NewMode\lst@DCmodeA\lst@NewMode\lst@DCmodeB -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lstCC@SingleComment} -% \begin{macro}{\lstCC@DoubleComment} -% All must be done twice here, for the beginning and end of a comment. -% The use of additional arguments like |{SC}\lst@SCmode| make it possible to define single and double comments with the same macros. -% \begin{macrocode} -\def\lstCC@SingleComment#1#2{% - \ifx\@empty#1\@empty\else % - \lstCC@TestCArg#1\@empty\relax\lstCC@CommentB{SC}\lst@SCmode % - \lstCC@TestCArg#2\@empty\relax\lstCC@CommentE{SC}\lst@SCmode % - \fi} -% \end{macrocode} -% Note the order: We define 'begin comment' and afterwards 'end comment'. -% This becomes important if |#1| equals |#2|, for example. -% Each such comment definition saves the old character meaning, which is executed after doing all comment specific. -% If we define 'end comment' first and then 'begin comment', |#1| would start a comment and then execute the old definition, which is 'end comment'. -% Since we are in comment mode now (and since |#1| equals |#2|), 'end comment' leaves comment mode immediately. -% That would be very bad! -% \begin{macrocode} -\def\lstCC@DoubleComment#1#2#3#4{% - \ifx\@empty#1\@empty\else % - \lstCC@TestCArg#1\@empty\relax\lstCC@CommentB{DCA}\lst@DCmodeA % - \lstCC@TestCArg#3\@empty\relax\lstCC@CommentB{DCB}\lst@DCmodeB % - \lstCC@TestCArg#2\@empty\relax\lstCC@CommentE{DCA}\lst@DCmodeA % - \lstCC@TestCArg#4\@empty\relax\lstCC@CommentE{DCB}\lst@DCmodeB % - \fi} -% \end{macrocode} -% \end{macro}\end{macro} -% -% \begin{macro}{\lstCC@CommentB} -% is not different from |\lstCC@CommentLine@| at all: -% The save name |#3| there is replaced by |B#4#3| and instead of |\lst@CLmode| we use |#5|. -% \begin{macrocode} -\def\lstCC@CommentB#1#2#3#4#5{% - \expandafter\let\csname lsts@B#4#3\endcsname#1% - \ifx\@empty#2% - \def#1{% - \lst@ifmode \let\lstCC@bnext\relax \else % - \def\lstCC@bnext{\lstCC@BeginComment#5}% - \fi % - \lstCC@bnext \csname lsts@B#4#3\endcsname}% - \else % - \def#1##1{% - \let\lstCC@bnext\relax % - \lst@ifmode\else \ifx##1#2% - \def\lstCC@bnext{\lstCC@@BeginComment#5}% - \fi \fi % - \expandafter\lstCC@bnext \csname lsts@B#4#3\endcsname##1}% - \fi} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@CommentE} -% Here we insert |\ifnum\lst@mode=#5| (6-th line), where |#5| is |\lst@SCmode| for example. -% This ensures that comment delimiters match each other. -% \begin{macrocode} -\def\lstCC@CommentE#1#2#3#4#5{% - \expandafter\let\csname lsts@E#4#3\endcsname#1% - \ifx\@empty#2% - \def#1{% - \def\lstCC@enext{\csname lsts@E#4#3\endcsname}% - \lst@ifmode \ifnum\lst@mode=#5% - \def\lstCC@enext{\csname lsts@E#4#3\endcsname % - \lstCC@EndComment}% - \fi \fi % - \lstCC@enext}% - \else % - \def#1##1{% - \def\lstCC@enext{\csname lsts@E#4#3\endcsname ##1}% - \lst@ifmode \ifnum\lst@mode=#5\ifx##1#2% - \def\lstCC@enext{\csname lsts@E#4#3\endcsname ##1% - \lstCC@EndComment}% - \fi \fi \fi % - \lstCC@enext}% - \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsubsection{Nested comments} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{nestedcomment} -% The user aspect \ldots -% \begin{macrocode} -\lst@Aspect{nestedcomment}{\lstnestedcomment@#1} -\def\lstnestedcomment@#1#2% - {\def\@tempa{#1}\def\@tempb{#2}% - \ifx\@tempa\@tempb \ifx\@tempa\@empty\else % - \PackageError{Listings}{Identical delimitors}% - {These delimitors make no sense with nested comments.}% - \fi \fi % - \def\lst@DefNC{\lstCC@NestedComment{#1}{#2}}} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lstCC@NestedComment} -% and the internal macro. -% \begin{macrocode} -\def\lstCC@NestedComment#1#2{% - \ifx\@empty#1\@empty\else % - \lstCC@TestCArg#2\@empty\relax\lstCC@NCommentE % - \lstCC@TestCArg#1\@empty\relax\lstCC@NCommentB % - \fi} -% \end{macrocode} -% Note the order: We define 'end comment' and afterwards 'begin comment'. -% \end{macro} -% -% \begin{macro}{\lstCC@NCommentB} -% The redefinition of the character is different now. -% Since we define nested comments, we have to count the comment depth. -% If we already process a nested comment, we increase that depth by making |\lst@mode| more negative. -% \begin{macrocode} -\def\lstCC@NCommentB#1#2#3{% - \let\lsts@BNC #1% - \ifx\@empty#2% - \def#1{% - \let\lstCC@bnext\relax % - \lst@ifmode % - \ifnum\lst@mode<\z@ % - \advance\lst@mode\m@ne % - \fi % - \else % - \def\lstCC@bnext{\lstCC@BeginComment\m@ne}% - \fi % - \lstCC@bnext \lsts@BNC}% - \else % - \def#1##1{% - \let\lstCC@bnext\relax % - \lst@ifmode % - \ifnum\lst@mode<\z@ \ifx##1#2% - \advance\lst@mode\m@ne % - \fi \fi % - \else % - \ifx##1#2% - \def\lstCC@bnext{\lstCC@@BeginComment\m@ne}% - \fi % - \fi % - \lstCC@bnext \lsts@BNC ##1}% - \fi} -% \end{macrocode} -% \begin{TODO} -% The third argument (|\catcode| 12 version of the first) is unused so far --- also in |\lst@NCommentE|. -% If we are in need of 'double' nested comments, we will use this argument for the save name, as we've already done it for normal double comments (and comment lines). -% \end{TODO} -% \end{macro} -% -% \begin{macro}{\lstCC@NCommentE} -% If we are in nested comment mode, we either end the comment or decrease the comment depth by making |\lst@mode| less negative. -% \begin{macrocode} -\def\lstCC@NCommentE#1#2#3{% - \let\lsts@ENC #1% - \ifx\@empty#2% - \def#1{% - \let\lstCC@enext\relax % - \lst@ifmode \ifnum\lst@mode<\z@ % - \ifnum\lst@mode=\m@ne % - \let\lstCC@enext\lstCC@EndComment % - \else % - \advance\lst@mode\@ne % - \fi - \fi \fi % - \lsts@ENC \lstCC@enext}% - \else % - \def#1##1{% - \def\lstCC@enext{\lsts@ENC ##1}% - \ifx##1#2% - \lst@ifmode \ifnum\lst@mode<\z@ % - \ifnum\lst@mode=\m@ne % - \def\lstCC@enext{% - \lsts@ENC ##1\lstCC@EndComment}% - \else % - \advance\lst@mode\@ne % - \fi - \fi \fi % - \fi % - \lstCC@enext}% - \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Escape characters} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% The introduction of this character class is due to a communication with \lsthelper{Rui Oliveira}{rco@di.uminho.pt}{1998/06/05}{escape characters}. -% -% \begin{macro}{\lstCC@Escape} -% gets three arguments all in all. -% The first is the escape character, the second is executed when the escape starts and the third right before ending it. -% We use the same grouping mechanism as for \TeX\ comment lines. -% \begin{macrocode} -\def\lstCC@Escape#1{\lccode`\~=`#1\lowercase{\lstCC@Escape@~}} -\def\lstCC@Escape@#1#2#3{% - \def#1{% - \lst@NewLine\lst@UseLostSpace \lst@PrintToken % - \lst@InterruptModes % - \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}% -% \end{macrocode} -% After doing the grouping we must define the character to end the escape. -% \begin{macrocode} - \catcode`#1=\active % - \def#1{#3\lst@LeaveAllModes \lst@ReenterModes}% - #2}} -% \end{macrocode} -% \begin{macrocode} -\lst@NewMode\lst@TeXmode -% \end{macrocode} -% \end{macro} -% -% \begin{aspect}{escapechar} -% This aspect defines |\lst@DefEsc|, which is executed after selecting the standard character table. -% \begin{macrocode} -\lst@Aspect{escapechar} - {\ifx\@empty#1\@empty % - \let\lst@DefEsc\relax % - \else % - \def\lst@DefEsc{\lstCC@Escape{#1}\@empty\@empty}% - \fi} -% \end{macrocode} -% \begin{macrocode} -\lstset{escapechar={}}% init -\lst@AddToHook{SelectCharTable}{\lst@DefEsc} -% \end{macrocode} -% \end{aspect} -% -% \begin{aspect}{mathescape} -% A switch tested after character table selection. -% We use |\lstCC@Escape| with math shifts as arguments. -% \begin{macrocode} -\lst@Aspect{mathescape}[t]{\lstKV@SetIfKey\lst@ifmathescape{#1}} -\lstset{mathescape=false}% init -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{SelectCharTable} - {\lst@ifmathescape \lstCC@Escape{\$}{$}{$}\fi} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lst@DontEscapeToLaTeX} -% This macro came in handy. -% \begin{macrocode} -\def\lst@DontEscapeToLaTeX{% - \let\lst@iftexcl\iffalse % - \let\lst@DefEsc\relax % - \let\lst@ifmathescape\iffalse} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{More \texttt{lst}-aspects and classes} -% -% -% \subsection{Form feeds} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{formfeed} -% We begin with the announcement --- the introduction is due to communication with \lsthelper{Jan Braun}{Jan.Braun@tu-bs.de}{1998/04/27}{\lstformfeed}. -% \begin{macrocode} -\lst@Aspect{formfeed}{\def\lst@formfeed{#1}} -\lstset{formfeed=\bigbreak}% init -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{SelectCharTable}{\lstCC@Let{`\^^L}\lstCC@FormFeed} -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lstCC@FormFeed} -% Here we either execute some macros or append them to |\lst@NewLine|. -% \begin{macrocode} -\def\lstCC@FormFeed{% - \lst@PrintToken % - \ifx\lst@NewLine\relax % - \lst@EOLUpdate \lst@formfeed % - \else % - \lst@lAddTo\lst@NewLine{\lst@EOLUpdate \lst@formfeed}% - \fi} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{\TeX\ control sequences} -% -% \begingroup -% \begin{macrocode} -%<*tex> -% \end{macrocode} -% \endgroup -% \begin{aspect}{texcs} -% In general, it's the same as |keywords|, but control sequences are case sensitive, have a preceding backslash, \ldots -% \begin{macrocode} -\lst@Aspect{texcs}{\def\lst@texcs{#1}} -\lst@AddToHook{SetLanguage}{\let\lst@texcs\@empty} -% \end{macrocode} -% \begin{macrocode} -\lst@AddToHook{Output} - {\lst@ifmode\else \ifx\lst@lastother\lst@backslash % - \expandafter\lst@IfOneOf\the\lst@token\relax \lst@texcs % - {\let\lst@thestyle\lst@keywordstyle}% - {\let\lst@thestyle\relax}% - \fi \fi} -% \end{macrocode} -% \end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Compiler directives in C} -% -% \begingroup -% \begin{macrocode} -%<*c> -% \end{macrocode} -% \endgroup -% \begin{aspect}{cdirectives} -% First some usual stuff: -% \begin{macrocode} -\lst@Aspect{cdirectives} - {\lst@MakeKeywordArg{,#1}\let\lst@cdirectives\lst@arg} -\lst@AddToHook{SetLanguage}{\let\lst@cdirectives\relax} -% \end{macrocode} -% If the user has defined directives, we redefine the character |#| (but save the old meaning before): -% \begin{macrocode} -\lst@AddToHook{SelectCharTable} - {\ifx\lst@cdirectives\relax\else % - \lccode`\~=`\#\lowercase{\let\lsts@CCD~\def~}% - {\lst@ifmode\else % -% \end{macrocode} -% We enter 'directive mode' only if we are in column 1. -% Note that 'directive mode' is |\lst@egroupmode| without setting |\lst@ifmode| true. -% \begin{macrocode} - \@tempcnta\lst@column % - \advance\@tempcnta\lst@length % - \advance\@tempcnta-\lst@pos % - \ifnum\@tempcnta=\z@ % - \lst@EnterMode{\lst@egroupmode}% - {\expandafter\lst@lAddTo\expandafter\lst@keywords% - \expandafter{\lst@cdirectives}}% - \fi % - \fi % - \ifnum\lst@mode=\lst@egroupmode % - {\lst@keywordstyle\lsts@CCD\lst@PrintToken}% - \else \lsts@CCD % - \fi}% - \fi} -% \end{macrocode} -% \end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{PODs in Perl} -% -% \begingroup -% \begin{macrocode} -%<*perl> -% \end{macrocode} -% \endgroup -% \begin{aspect}{printpod} -% We begin with two user commands, which I introduced after communication with \lsthelper{Michael Piotrowski}{mxp@linguistik.uni-erlangen.de}{1997/11/11}{\lstprintpodtrue/false}. -% \begin{macrocode} -\lst@Aspect{printpod}[t]{\lstKV@SetIfKey\lst@ifprintpod{#1}} -\lstset{printpod=false}% init -% \end{macrocode} -% \end{aspect} -% -% \begin{macro}{\lst@PODmode} -% Define a new mode and use |\global| since we are (possibly) in a driver file and thus inside a group. -% \begin{macrocode} -\global\lst@NewMode\lst@PODmode -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@PODcut} -% We'll need the active character string |cut|: -% \begin{macrocode} -\lst@MakeActive{cut}\global\let\lstCC@PODcut\lst@arg % -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessPOD} -% And now the POD character class; only |=| will belong to it. -% If we are in column 1 \ldots -% \begin{macrocode} -\gdef\lstCC@ProcessPOD{% - \let\lstCC@next\relax % - \@tempcnta\lst@column % - \advance\@tempcnta\lst@length % - \advance\@tempcnta-\lst@pos % - \ifnum\@tempcnta=\z@ % -% \end{macrocode} -% and if we are already in POD mode, we either end it or proceed according to whether next characters are |cut| or not. -% \begin{macrocode} - \ifnum\lst@mode=\lst@PODmode % - \def\lstCC@next{\lst@IfNextChars\lstCC@PODcut % - {\lstCC@ProcessEndPOD}% - {\lsts@POD\lst@eaten}}% - \else % -% \end{macrocode} -% If we are in column 1 and not in POD mode, we either start a usual comment or drop the output. -% \begin{macrocode} - \lst@ifprintpod % - \lstCC@BeginComment\lst@PODmode % - \else % - \lst@BeginDropOutput\lst@PODmode % - \fi % - \let\lstCC@next\lsts@POD % - \fi % - \fi \lstCC@next}% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstCC@ProcessEndPOD} -% If the character behind |=cut| is neither |^^M| nor |^^J|, we don't end the POD. -% \begin{macrocode} -\gdef\lstCC@ProcessEndPOD#1{% - \let\lstCC@next\lstCC@ProcessEndPOD@ % - \ifnum`#1=`\^^M\else \ifnum`#1=`\^^J\else % - \def\lstCC@next{\lsts@POD\lst@eaten#1}% - \fi \fi % - \lstCC@next} -% \end{macrocode} -% The ending actions depend on |\lst@ifprintpod|: Print |=cut| (or not) and end the POD. -% \begin{macrocode} -\gdef\lstCC@ProcessEndPOD@{% - \lst@ifprintpod \lsts@POD\lst@eaten\lst@PrintToken \fi % - \lst@LeaveMode} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{Special use of \texttt{\#} in Perl} -% -% \begingroup -% \begin{macrocode} -%<*perl> -% \end{macrocode} -% \endgroup -% \begin{macro}{\lstCC@SpecialUseAfter} -% We need |#| not to begin a comment in Perl if it follows |$|. -% We'll define a special use of |#| after |$| via |\lstCC@SpecialUseAfter{\$}{\#}{\lstCC@ProcessOther\#}| where the third argument is executed coming to |$#|. -% Note that the submacro gets two of the three arguments. -% \begin{macrocode} -\gdef\lstCC@SpecialUseAfter#1{% - \lccode`\~=`#1\lccode`\/=`#1\lowercase{\lstCC@SpecialUseAfter@~/}} -% \end{macrocode} -% We save the old meaning of the first character (|$|) and redefine it to check for the character |#3|. -% \begin{macrocode} -\gdef\lstCC@SpecialUseAfter@#1#2#3#4{% - \expandafter\let\csname lsts@SUA#2\endcsname#1% - \def#1##1{% - \ifnum`##1=`#3% - \def\lstCC@next{\csname lsts@SUA#3\endcsname\relax #4}% - \else % - \def\lstCC@next{\csname lsts@SUA#3\endcsname ##1}% - \fi % - \lstCC@next}} -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{Epilogue} -% -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% Most initialization has already been done, see all |% init| marked lines. -% Here is more: -% \begin{macrocode} -\lstset{labelsep=5pt,sensitive=true} -\lstdefinelanguage{}{} -\lstdefinestyle{} - {basicstyle={},% - keywordstyle=\bfseries,nonkeywordstyle={},% - commentstyle=\itshape,stringstyle={},% - labelstyle={},labelstep=0} -\lst@mode=\z@ -\lstset{language={},style={}} -% \end{macrocode} -% Finally we load compatibility mode, a patch file and the configuration file. -% \begin{macrocode} -\@ifundefined{lst@0.17}{}{\input{lst017.sty}} -\InputIfFileExists{lstpatch.sty}{}{} -\InputIfFileExists{listings.cfg}{}{} -% \end{macrocode} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \section{Interfaces to other packages} -% -% -% \subsection{Compatibility mode} -% -% \begingroup -% \begin{macrocode} -%<*0.17> -% \end{macrocode} -% \endgroup -% We give a warning first. -% \begin{macrocode} -\message{^^J% -*** You have requested compatibility mode `0.17'.^^J% -*** This mode is for documents created for version 0.17 only.^^J% -*** I T\@spaces I S\@spaces N O T\@spaces F U L L Y\@spaces % -C O M P A T I B L E.^^J^^J} -% \end{macrocode} -% -% -% \paragraph{Language names.} -% -% Since some programming languages changed their names, we define aliases here. -% \begin{macrocode} -\lstalias[]{blank}[]{} -\lstalias{cpp}{C++} -\lstalias[vc]{C++}[Visual]{C++} -\lstalias{comal}{Comal 80} -\lstalias{modula}{Modula-2} -\lstalias{oberon}{Oberon-2} -\lstalias[]{pxsc}[XSC]{Pascal} -\lstalias[]{tp}[Borland6]{Pascal} -\lstalias{pli}{PL/I} -% \end{macrocode} -% -% -% \paragraph{User commands.} -% -% Old commands in terms of keys: -% \begin{macrocode} -\def\inputlisting{% - \@ifnextchar[\inputlisting@{\inputlisting@[1,999999]}} -\def\inputlisting@[#1,#2]{\lstinputlisting[first=#1,last=#2]} -% \end{macrocode} -% \begin{macrocode} -\newcommand\selectlisting[2][]{\lstset{language=[#1]#2}} -\def\listingtrue{\lstset{print=true}} -\def\listingfalse{\lstset{print=false}} -\def\tablength#1{\lstset{tabsize=#1}}\tablength{4}% init -\def\keywordstyle#1{\lstset{keywordstyle={#1}}} -\def\commentstyle#1{\lstset{commentstyle={#1}}} -\def\stringstyle#1{\lstset{stringstyle={#1}}} -\def\labelstyle#1{\lstset{labelstyle={#1}}} -\newcommand\stringizer[2][d]{\lstset{stringizer=[#1]#2}} -\def\blankstringtrue{\lstset{blankstring=true}} -\def\blankstringfalse{\lstset{blankstring=false}} -\def\spreadlisting#1{\lstset{spread={#1}}} -\def\prelisting#1{\def\lst@pre{#1}} -\def\postlisting#1{\def\lst@post{#1}} -\def\normallisting{% - \lstset{style={},spread=\z@,pre={},post={}}} -\def\keywords#1{\lstset{keywords={#1}}} -\def\morekeywords#1{\lstset{morekeywords={#1}}} -\def\sensitivetrue{\lstset{sensitive=true}} -\def\sensitivefalse{\lstset{sensitive=false}} -\let\lst@stringblank\textvisiblespace -% \end{macrocode} -% We define the (new) old environment. -% \begin{macrocode} -\lst@Environment{listing}[1][]\is - {\ifx\@empty#1\@empty\else \lst@AddToLOL{#1}{}\fi} - {} -% \end{macrocode} -% -% -% \paragraph{Comments.} -% -% The implementation of old comment commands in terms of the new ones is all the same: -% If the last argument is empty, we remove the comment; otherwise we execute the new key with correct syntax. -% \begin{macrocode} -\def\DeclareCommentLine#1\relax{% - \ifx\@empty#1\@empty % - \let\lst@DefCL\relax % - \else % - \lstset{commentline=#1}% - \fi} -% \end{macrocode} -% \begin{macrocode} -\def\DeclareSingleComment#1 #2\relax{% - \ifx\@empty#2\@empty % - \let\lst@DefSC\relax \let\lst@DefDC\relax % - \else % - \lstset{singlecomment={#1}{#2}}% - \fi} -% \end{macrocode} -% \begin{macrocode} -\def\DeclarePairedComment#1\relax{ - \ifx\@empty#1\@empty % - \let\lst@DefSC\relax \let\lst@DefDC\relax % - \else % - \lstset{singlecomment={#1}{#1}}% - \fi} -% \end{macrocode} -% \begin{macrocode} -\def\DeclareNestedComment#1 #2\relax{% - \ifx\@empty#2\@empty % - \let\lst@DefSC\relax \let\lst@DefDC\relax % - \else % - \lstset{nestedcomment={#1}{#2}}% - \fi} -% \end{macrocode} -% \begin{macrocode} -\def\DeclareDoubleComment#1 #2 #3 #4\relax{% - \ifx\@empty#4\@empty % - \let\lst@DefSC\relax \let\lst@DefDC\relax % - \else % - \lstset{doublecomment={#1}{#2}{#3}{#4}}% - \fi} -% \end{macrocode} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \subsection{\textsf{fancyvrb}} -% -% \lsthelper{Denis Girou}{Denis.Girou@idris.fr}{1998/07/26}{fancyvrb} asked whether \textsf{fancyvrb} and \textsf{listings} could work together. -% Here's the first try. -% \begingroup -% \begin{macrocode} -%<*kernel> -% \end{macrocode} -% \endgroup -% \begin{aspect}{fancyvrb} -% We set the boolean and input the interface file (first time only). -% \begin{macrocode} -\lst@Aspect{fancyvrb}[t]{% - \lstKV@SetIfKey\lst@iffancyvrb{#1}% - \lstfancyvrb@} -\def\lstfancyvrb@{\input{lstfvrb.sty}\lstfancyvrb@} -% \end{macrocode} -% \end{aspect} -% \begingroup -% \begin{macrocode} -% -% \end{macrocode} -% -% \begin{macrocode} -%<*fancyvrb> -% \end{macrocode} -% We will use |@|-protected names: -% \begin{macrocode} -\begingroup \makeatletter -% \end{macrocode} -% \endgroup -% \begin{macro}{\lstFV@Def} -% \begin{macro}{\lstFV@Let} -% \begin{macro}{\lstFV@Use} -% \begin{macro}{\lstFV@ECUse} -% \begin{macro}{\lstFV@Tabulator} -% \begin{macro}{\lstFV@Space} -% \begin{macro}{\lstFV@Stringizer@} -% These are copies of the |\lstCC@|\ldots\ macros, but all catcode changes are removed. -% \begin{macrocode} -\gdef\lstFV@Def#1{\lccode`\~=#1\lowercase{\def~}}% -\gdef\lstFV@Let#1{\lccode`\~=#1\lowercase{\let~}}% -% \end{macrocode} -% \begin{macrocode} -\gdef\lstFV@Use#1#2#3{% - \ifnum#2=\z@ % - \expandafter\@gobbletwo % - \else % - \lccode`\~=#2\lowercase{\def~}{#1#3}% - \fi % - \lstFV@Use#1}% -% \end{macrocode} -% \begin{macrocode} -\gdef\lstFV@ECUse#1#2{% - \ifnum`#2=\z@ % - \expandafter\@gobbletwo % - \else % - \ifnum\catcode`#2=\active % - \lccode`\~=`#2\lccode`\/=`#2\lowercase{\lstCC@ECUse@#1~/}% - \else % - \lccode`\~=`#2\lowercase{\def~}{#1#2}% - \fi % - \fi % - \lstFV@ECUse#1}% -% \end{macrocode} -% \begin{macrocode} -\gdef\lstFV@Tabulator#1{\lstFV@Let{#1}\lstCC@ProcessTabulator}% -\gdef\lstFV@Space#1{\lstFV@Let{#1}\lstCC@ProcessSpace}% -% \end{macrocode} -% \begin{macrocode} -\gdef\lstFV@Stringizer@#1#2{% - \ifx\@empty#2% - \expandafter\@gobbletwo % - \else % - \lccode`\~=`#2\lccode`\/=`#2% - \lowercase{% - \expandafter\let\csname lsts@s/\endcsname~% - \def~{#1/}}% - \fi % - \lstFV@Stringizer@#1}% -% \end{macrocode} -% \end{macro}\end{macro}\end{macro}\end{macro} -% \end{macro}\end{macro}\end{macro} -% -% \begin{macro}{\lstFV@FancyVerbFormatLine} -% This macro will be assigned to |\FancyVerbFormatLine|: We convert the argument and typeset it. -% \begin{macrocode} -\gdef\lstFV@FancyVerbFormatLine#1{% - \let\lstenv@arg\@empty\lstenv@AddArg{#1}% - \lstenv@arg \lst@PrintToken\lst@EOLUpdate}% -% \end{macrocode} -% \begin{TODO} -% This old macro is overwritten below. -% \end{TODO} -% \end{macro} -% -% \begin{macro}{\lstfancyvrb@} -% The command assigns some new macros (if it's not already done). -% \begin{macrocode} -\gdef\lstfancyvrb@{% - \ifx\FV@VerbatimBegin\lstFV@VerbatimBegin\else % - \let\lstFV@OldVB\FV@VerbatimBegin % - \let\lstFV@OldVE\FV@VerbatimEnd % - \let\FV@VerbatimBegin\lstFV@VerbatimBegin % - \let\FV@VerbatimEnd\lstFV@VerbatimEnd % - \fi % -% \end{macrocode} -% And we assign the correct |\FancyVerbFormatLine| macro. -% \begin{macrocode} - \lst@iffancyvrb % - \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine\else % - \let\lstFV@FVFL\FancyVerbFormatLine % - \let\FancyVerbFormatLine\lstFV@FancyVerbFormatLine % - \fi % - \else % - \ifx\lstFV@FVFL\@undefined\else % - \let\FancyVerbFormatLine\lstFV@FVFL % - \fi % - \fi}% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstFV@VerbatimBegin} -% We initialize things if necessary. -% \begin{macrocode} -\gdef\lstFV@VerbatimBegin{% - \lstFV@OldVB % - \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine % - \lst@DontEscapeToLaTeX % - \let\smallbreak\relax \let\normalbaselines\relax % - \let\lst@prelisting\relax \let\lst@postlisting\relax % - \def\lst@firstline{1}\def\lst@lastline{999999}% -% \end{macrocode} -% \begin{macrocode} - \let\lstCC@Use\lstFV@Use % - \let\lstCC@ECUse\lstFV@ECUse % - \let\lstCC@Tabulator\lstFV@Tabulator % - \let\lstCC@Space\lstFV@Space % - \let\lstCC@Stringizer@\lstFV@Stringizer@ % -% \end{macrocode} -% \begin{macrocode} - \def\lst@next{% - \lst@Init\relax % - \everypar{}\global\let\lst@NewLine\relax}% - \expandafter\lst@next % - \fi}% -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstFV@VerbatimEnd} -% A (particular) box and macro must exist after |\lst@DeInit|. -% We store them globally. -% \begin{macrocode} -\gdef\lstFV@VerbatimEnd{% - \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine % - \global\setbox\lstFV@gtempboxa\box\@tempboxa % - \global\let\@gtempa\FV@ProcessLine % - \lst@DeInit % - \let\FV@ProcessLine\@gtempa % - \setbox\@tempboxa\box\lstFV@gtempboxa % - \fi % - \lstFV@OldVE}% -% \end{macrocode} -% \begin{macrocode} -\newbox\lstFV@gtempboxa % -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\lstFV@FancyVerbFormatLine} -% A slightly different definition now: |\lstenv@AddArg{#1}| has been replaced by |\lstFV@Convert#1@|. -% The '@' terminates the input |#1|. -% \begin{macrocode} -\gdef\lstFV@FancyVerbFormatLine#1{% - \let\lst@arg\@empty\lstFV@Convert#1@% - \lst@arg \lst@PrintToken\lst@EOLUpdate}% -% \end{macrocode} -% And this macro is to be defined right now. -% \begin{macrocode} -\gdef\lstFV@Convert{% - \@ifnextchar\bgroup{\lstFV@Convert@Arg}{\lstFV@Convert@}}% -% \end{macrocode} -% Coming to a begin group character ('\{' with catcode 1) we convert the and add the conversion together with group delimiters to |\lst@arg|. -% We also add |\lst@PrintToken|, which prints all collected characters before we forget them. -% Finally we continue the conversion. -% \begin{macrocode} -\gdef\lstFV@Convert@Arg#1{% - {\let\lst@arg\@empty \lstFV@Convert#1@\global\let\@gtempa\lst@arg}% - \expandafter\lst@lAddTo\expandafter\lst@arg\expandafter{% - \expandafter{\@gtempa\lst@PrintToken}}% - \lstFV@Convert}% -% \end{macrocode} -% If we haven't found a |\bgroup|, we look whether we've found the end of the input. -% If not, we convert one token ((non)active character or control sequence) and continue conversion. -% \begin{macrocode} -\gdef\lstFV@Convert@#1{% - \ifx @#1\else % - \expandafter\lstFV@Convert@@\string#1\@empty\@empty\relax{#1}% - \expandafter\lstFV@Convert % - \fi}% -% \end{macrocode} -% |\string#1| from above expands to 'backslash + some characters' if |#1| is a control sequence. -% In this case the argument |#2| here equals not |\@empty|. -% The other implication: If |#2| equals |\@empty|, |\string#1| necessarily expanded to a single character, which can't be a control sequence (|\escapechar>=0| granted). -% Thus, we add an active character if and only if the second argument equals |\@empty|, and we append the control sequence otherwise. -% In the latter case we must print all preceding characters (and all the lost space). -% \begin{macrocode} -\gdef\lstFV@Convert@@#1#2#3\relax#4{% - \ifx\@empty#2% - \lccode`\~=`#4\lowercase{\lst@lAddTo\lst@arg~}% - \else % - \lst@lAddTo\lst@arg{\lst@UseLostSpace\lst@PrintToken#4}% - \fi}% -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -\endgroup % -% \end{macrocode} -% \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% -% \begingroup\small -% \section{History} -% Only major changes after version 0.15 are listed here. -% Previous changes are still present in the \texttt{.dtx}-file. -% Introductory version numbers of the user commands are listed in the user's guide. -% \renewcommand\labelitemi{--} -% \begin{itemize} -% \iffalse -% \item[0.1] from 1996/03/09 -% \item test version to look whether package is possible or not -% \item[0.11] from 1996/08/19 -% \item additional blank option (= language) -% \item alignment improved by rewriting some macros -% \item[0.12] from 1997/01/16 -% \item nearly 'perfect' alignment now -% \item[0.13] from 1997/02/11 -% \item additional languages: Eiffel, Fortran 90, Modula-2, Pascal XSC -% \item load on demand: language specific macros moved to driver files -% \item comments are declared now and not implemented for each language again (this makes the \TeX{} sources easier to read) -% \item[0.14] from 1997/02/18 -% \item user's guide rewritten -% \item implementation guide uses macro environment from the doc package -% \item (non) case sensitivity implemented, e.g.\ Pascal is not -% \item multiple stringizer implemented, i.e.\ Modula-2 handles both string types: quotes and double quotes -% \item comment declaration is user-accessible now -% \item package compatible to \verb!german.sty! now -% \item[0.15] from 1997/04/18 -% \item additional languages: Java, Turbo Pascal -% \item package renamed from listing.dtx to listings.dtx, since there is already a package named listing -% \fi -% \item[0.16] from 1997/06/01 -% \iffalse -% \item changed '$<$' to '$>$' in \verb!\lst@SkipUptoFirst! -% \item bug removed: \verb!\lst@Init! must be placed before \verb!\lst@SkipUptoFirst! -% \fi -% \item listing environment rewritten -% \item[0.17] from 1997/09/29 -% \item |\spreadlisting| works correct now (e.g.\ page numbers move not right any more) -% \item speed up things (quick 'if parameter empty', all |\long| except one removed, faster \verb!\lst@GotoNextTabStop!, etc.) -% \item alignment of wide other characters improved (e.g.\ $==$) -% \iffalse -% \item many new languages: Ada, Algol, Cobol, Comal 80, Elan, Fortran 77, Lisp, Logo, Matlab, Oberon, Perl, PL/I, Simula, SQL, \TeX{} -% \fi -% \item[pre-0.18] from 1998/03/24 (unpublished) -% \item bug concerning |\labelstyle| removed (now oldstylenum example works) -% \item experimental implementation of character classes -% \item[0.19] from 1998/11/09 -% \item character classes and \lst-aspects (new) seem to be the ultimate, all became implemented in these terms -% \item \lst-aspects became an application (new) to \textsf{keyval} and hooks -% \item \textsf{fancyvrb} support -% \end{itemize} -% -% -% \setcounter{IndexColumns}{2} -% \PrintIndex -% -% -% \Finale -% -\endinput +% \iffalse +% +% Trademarks appear throughout this documentation without any trademark +% symbol, so you can't assume that a name is free. There is no intention +% of infringement; the usage is to the benefit of the trademark owner. +% +% +% S O F T W A R E L I C E N S E +% ================================= +% +% The files listings.dtx and listings.ins and all files generated +% from only these two files are referred to as `the listings package' +% or simply `the package'. A `driver' is generated from lstdrvrs.dtx. +% +% Copyright. +% The listings package is copyright 1996--2002 Carsten Heinz. +% The language drivers are copyright 1997/1998/1999/2000/2001/2002 any +% individual author listed in the driver files. +% +% Distribution and warranty. +% The listings package as well as lstdrvrs.dtx and all drivers are +% distributed under the terms of the LaTeX Project Public License +% from CTAN archives in directory macros/latex/base/lppl.txt. +% Either version 1.0 or, at your option, any later version. +% +% Use of the package. +% The listings package is free software. However, if you distribute the +% package as part of a commercial product or if you use the package to +% prepare a commercial document (books, journals, and so on), I'd like +% to encourage you to make a donation to the LaTeX3 fund. The size of +% this `license fee' should depend on the value of the package for your +% product. For more information about LaTeX see +% http://www.latex-project.org +% +% No matter whether you use the package for a commercial or non-commercial +% document, please send me a copy of the document (.dvi, .ps, .pdf, +% hardcopy, etc.) to support further development---it is easier to +% introduce new features or simplify things if I see how the package is +% used by other people. +% +% Modification advice. +% Permission is granted to modify the listings package as well as +% lstdrvrs.dtx. You are not allowed to distribute a modified version +% of the package or lstdrvrs.dtx unless you change the file names and +% provide the original files. In any case it is better to contact the +% address below; other users will welcome removed bugs, new features, +% and additional programming languages. +% +% Contacts. +% Send comments and ideas on the package, error reports and additional +% programming languages to +% +% Carsten Heinz +% Tellweg 6 +% 42275 Wuppertal +% Germany +% +% or preferably to +% +% cheinz@gmx.de +% +% end of software license +% +% +%<*driver> +\documentclass[a4paper]{ltxdoc} +\DisableCrossrefs +\OnlyDescription + +\usepackage{lstdoc} +\makeindex + +\begin{document} + \DocInput{listings.dtx} +\end{document} +% +% \fi +% +%^^A +%^^A Command/key to aspect relation +%^^A ================================ +%^^A +%\lstisaspect[strings]{string,morestring,deletestring,stringstyle,showstringspaces} +%\lstisaspect[comments]{comment,morecomment,deletecomment,commentstyle} +%\lstisaspect[pod]{printpod,podcomment} +%\lstisaspect[escape]{texcl,escapebegin,escapeend,escapechar,escapeinside,mathescape} +%\lstisaspect[keywords]{sensitive,classoffset,keywords,morekeywords,deletekeywords,keywordstyle,ndkeywords,morendkeywords,deletendkeywords,ndkeywordstyle,keywordsprefix,otherkeywords} +%\lstisaspect[emph]{emph,moreemph,deleteemph,emphstyle} +%\lstisaspect[tex]{texcs,moretexcs,deletetexcs,texcsstyle} +%\lstisaspect[directives]{directives,moredirectives,deletedirectives,directivestyle} +%\lstisaspect[html]{keywordsinside,usekeywordsinside} +%\lstisaspect[keywordcomments]{keywordcomment,morekeywordcomment,deletekeywordcomment,keywordcommentsemicolon} +%\lstisaspect[index]{index,moreindex,deleteindex,indexstyle,\string\lstindexmacro} +%\lstisaspect[procnames]{procnamestyle,indexprocnames,procnamekeys,moreprocnamekeys,deleteprocnamekeys} +%\lstisaspect[style]{style,\string\lstdefinestyle,\string\lst@definestyle,\string\lststylefiles} +%\lstisaspect[language]{language,alsolanguage,defaultdialect,\string\lstalias,\string\lstdefinelanguage,\string\lst@definelanguage,\string\lstloadlanguages,\string\lstlanguagefiles} +%\lstisaspect[formats]{format,fmtindent,\string\lstdefineformat,\string\lst@defineformat,\string\lstformatfiles} +%\lstisaspect[labels]{numbers,numberstyle,numbersep,stepnumber,numberblanklines,firstnumber,\string\thelstnumber} +%\lstisaspect[lineshape]{xleftmargin,xrightmargin,resetmargins,linewidth,lineskip,breaklines,breakindent,breakautoindent,prebreak,postbreak} +%\lstisaspect[frames]{framexleftmargin,framexrightmargin,framextopmargin,framexbottommargin,backgroundcolor,fillcolor,rulecolor,rulesepcolor,rulesep,framerule,framesep,frameshape,frameround,frame} +%\lstisaspect[make]{makemacrouse} +%\lstisaspect[fancyvrb]{fancyvrb} +%\lstisaspect[lgrind]{lgrindef,\string\lstlgrindeffile} +%\lstisaspect[hyper]{hyperref,morehyperref,deletehyperref,hyperanchor,hyperlink} +%\lstisaspect[kernel]{basewidth,fontadjust,columns,flexiblecolumns,identifierstyle,^^A +% tabsize,showtabs,tab,showspaces,keepspaces,formfeed,SelectCharTable,^^A +% MoreSelectCharTable,extendedchars,alsoletter,alsodigit,alsoother,excludedelims,^^A +% literate,basicstyle,print,firstline,lastline,nolol,captionpos,abovecaptionskip,^^A +% belowcaptionskip,label,title,caption,\string\lstlistingname,boxpos,float,^^A +% floatplacement,aboveskip,belowskip,everydisplay,showlines,emptylines,gobble,name,^^A +% \string\lstname,\string\lstlistlistingname,\string\lstlistoflistings,^^A +% \string\lstnewenvironment,\string\lstinline,\string\lstinputlisting,lstlisting,^^A +% \string\lstloadaspects,\string\lstset,\string\thelstlisting,\string\lstaspectfiles,^^A +% inputencoding,delim,moredelim,deletedelim} +%\lstisaspect[doc]{lstsample,lstxsample}^^A environment +% +%^^A +%^^A The long awaited beginning of documentation +%^^A ============================================= +%^^A +%\newbox\abstractbox +%\setbox\abstractbox=\vbox{ +% \begin{abstract} +% The \packagename{listings} package is a source code printer for \LaTeX. +% You can typeset stand alone files as well as listings with an environment +% similar to \texttt{verbatim} as well as you can print code snippets using +% a command similar to |\verb|. +% Many parameters control the output and if your preferred programming +% language isn't already supported, you can make your own definition. +% \end{abstract}} +% +% \title{\vspace*{-2\baselineskip}The \textsf{Listings} Package} +% \author{Copyright 1996--2002\\ Carsten Heinz \textless\lstemail\textgreater} +% \date{2002/04/01\footnote{Documentation revised 2002/10/13: table +% \ref{uPredefinedLanguages} of predefined languages and credits in +% section \ref{uClosingAndCredits} have been updated. Patch file 1.0\,i +% of same date includes several bug-fixes.}^^A +% \enspace\enspace Version 1.0\\ \box\abstractbox} +% \def\lstemail{\href{mailto:cheinz@gmx.de}{\texttt{cheinz@gmx.de}}} +% \ifhyper +% \hypersetup{pdfsubject=Package guide,pdfauthor=Carsten Heinz } +% \fi +% +% \csname @twocolumntrue\endcsname +% \maketitle +%^^A \enlargethispage{2\baselineskip} +% \csname @starttoc\endcsname{toc} +% \onecolumn +% +% +% \section*{Preface} +% +% \paragraph{Reading this manual} +% If you are experienced with the \packagename{listings} package, you should +% read the paragraph ``\emph{News and changes}'' below. Otherwise read section +% \lstref{uGettingStarted} step by step and then go on with +% section \ref{uTheNextSteps}. +% +% \paragraph{News and changes} +% This is the first release of the package with a major version number unequal +% to zero. And many changes have been made since version 0.21. +% One main task was to synchronize the keys of \packagename{listings} and +% \packagename{fancyvrb}. So user's of both packages can switch between them +% without learning new keys---as long as the same functionality is provided. +% The table lists (hopefully) all renamed keys and all removed keys. +% \begin{table}[hbp] +% \footnotesize +% \begin{center} +% \begin{tabular}{rlrl} +% \emph{0.21}&\emph{now}&\emph{0.21}&\emph{now}\\[1ex] +% \texttt{first} & \texttt{firstline} & --- & \texttt{numbers}\\ +% \texttt{last} & \texttt{lastline} & \texttt{labelstep} & \texttt{stepnumber}\\ +% \texttt{stringspaces} & \texttt{showstringspaces} & \texttt{labelstyle} & \texttt{numberstyle}\\ +% \texttt{visiblespaces} & \texttt{showspaces} & \cs{thelstlabel} & \cs{thelstnumber}\\ +% \texttt{visibletabs} & \texttt{showtabs} & \texttt{labelsep} & \texttt{numbersep}\\ +% \texttt{framerulewidth} & \texttt{framerule} & \texttt{firstlabel} & \texttt{firstnumber}\\ +% \texttt{framerulesep} & \texttt{rulesep} & \texttt{advancelabel} & ---\\ +% \texttt{frametextsep} & \texttt{framesep} & \texttt{spread} & ---\\ +% \texttt{framespread} & superceded by & \texttt{indent} & \texttt{xleftmargin}$^3$\\ +% & \texttt{framexleftmargin} & --- & \texttt{xrightmargin}\\ +% & \texttt{framexrightmargin} & \texttt{wholeline} & \texttt{resetmargins}\\ +% & \texttt{framextopmargin} & \texttt{defaultclass} & \texttt{classoffset}\\ +% & \texttt{framexbottommargin} & \texttt{stringtest} & ---\\ +% \texttt{framerulecolor} & \texttt{rulecolor}$^1$ & \texttt{outputpos} & ---\\ +% --- & \texttt{columns}$^2$ +% \end{tabular} +% \end{center} +% \parindent=20pt\relax +% \par\indent $^1$ \emph{All} color-keys require now an explicit \cs{color} command in the value. +% \par\indent $^2$ Please look at section \ref{uFixedAndFlexibleColumns}. +% \par\indent $^3$ Now frames are also moved! +% \end{table} +% As stated in the footnote, some keys changed their behaviour, for example +% you will have to write \keyname{backgroundcolor}|=\color|\marg{color} +% instead of omitting the color command as in version 0.21. Another +% modification is that the name argument of \texttt{lstlisting} has been +% replaced by the key \keyname{name} and an addon to \keyname{firstnumber}. +% But don't panic, you don't need to remove all empty name arguments in your +% old sources, the argument is still allowed. +% +% The package documentation has also been revised. Please notice the new +% sections \ref{uLanguageDefinitions} and \ref{uDelimiters}. +% +% Eventually note that all experimental features and all \dag-marked keys might +% change in future. All others are fixed! +% +% \paragraph{Thanks} +% There are many people I have to thank for fruitful communication, posting +% their ideas, giving error reports, adding programming languages to +% \texttt{lstdrvrs.dtx}, and so on. Their names are listed in section +% \ref{uClosingAndCredits}. +% +% \vfill +% \paragraph{Trademarks} +% Trademarks appear throughout this documentation without any trademark +% symbol; they are the property of their respective trademark owner. +% There is no intention of infringement; the usage is to the benefit of the +% trademark owner. +% +% +% \clearpage +% +% +% \part{User's guide} +% +% +% \section{Getting started}\label{uGettingStarted} +% +% +% \subsection{A minimal file}\label{uAMinimalFile} +% +% Before using the \packagename{listings} package, you should be familiar with +% the \LaTeX\ typesetting system. You need not to be an expert. +% Here is a minimal file for \packagename{listings}. +% \begin{verbatim} +% \documentclass{article} +% \usepackage{listings} +% \begin{document} +% \lstset{language=Pascal} +% % Insert Pascal examples here. +% \end{document}\end{verbatim} +% Now type in this first example and run it through \LaTeX. +% \begin{advise} +% \item Must I do that really? +% \advisespace +% Yes and no. Some books about programming say this is good. +% What a mistake! Typing takes time---wasted if the code is clear to +% you. And if you need that time to understand what is going on, the +% author of the book should reconsider the concept of presenting the +% crucial things---you might want to say that about this guide even---or +% you're simply unexperienced with programming. If only the latter case +% applies, you should spend more time on reading (good) books about +% programming, (good) documentations, and (good) source code from other +% people. Of course you should also make your own experiments. +% You will learn a lot. However, running the example through \LaTeX\ +% shows whether the \packagename{listings} package is installed. +% \item The example doesn't work. +% \advisespace +% Are the two packages \packagename{listings} and \packagename{keyval} +% installed on your system? Read section \ref{rInstallation} on the +% installation process. If this doesn't help, you should consult your +% system administrator, the local \TeX\ and \LaTeX\ guides, or a \TeX\ +% FAQ. And after you checked \emph{all} these sources, you might want to +% write a post to a \TeX\ newsgroup like \texttt{comp.text.tex}. +% \item Should I read the software license before using this package? +% \advisespace +% Yes, but read this \emph{Getting started} section first to decide +% whether you are willing to use the package.^^A ;-) +% \end{advise} +% +% +% \subsection{Typesetting listings} +% +% Three types of source codes are supported: code snippets, code segments, and +% listings of stand alone files; the first inside paragraphs and the others as +% separate paragraphs---the difference is the same as between text style and +% display style formulas. +% \begin{advise} +% \item No matter what kind of source you have, if a listing contains national +% characters like \'e, \L, \"a, or whatever, you must tell it the +% package! Section \lstref{uSpecialCharacters} discusses this issue. +% \end{advise} +% +% \paragraph{Code snippets} +% The well-known \LaTeX\ command |\verb| typesets code snippets verbatim. +% The new command |\lstinline| pretty-prints the code, for example +%`\lstinline!var i:integer;!' is typeset by +%`{\rstyle|\lstinline|}|!var i:integer;!|'. The exclamation marks delimit +% the code and can be replaced by any character not in the code; +% |\lstinline$var i:integer;$| gives the same result. +% +% \paragraph{Displayed code} +% The \texttt{lstlisting} environment typesets the enclosed source code. Like +% most examples, the following one shows verbatim \LaTeX\ code on the right +% and the result on the left. You might take the right-hand side, put it into +% the minimal file, and run it through \LaTeX. +% \begin{lstsample}[lstlisting]{}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% It can't be easier. +% \begin{advise} +% \item That's not true. The name `\texttt{listing}' is shorter. +% \advisespace +% Indeed. But other packages already define environments with that name. +% To be compatible with such packages, all commands and environments of +% the \packagename{listings} package use the prefix `\texttt{lst}'. +% \end{advise} +% The environment provides an optional argument. It tells the package to +% perform special tasks, for example, to print only the lines 2--5: +% \begin{lstsample}{\lstset{frame=trbl,framesep=0pt}\label{gFirstKey=ValueList}}{} +% \begin{lstlisting}[firstline=2, +% lastline=5] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item Hold on! I've several questions. +% Where comes the frame from and what is it good for? +% \advisespace +% You can put frames around all listings except code snippets. +% You will learn it later. The frame shows that empty lines at the end +% of listings aren't printed. This is line 5 in the example. +% \item Hey, you can't drop my empty lines! +% \advisespace +% You can tell the package not to drop them: +% The key `\ikeyname{showlines}' controls these empty lines and is +% described in section \ref{rTypesettingListings}. Warning: First +% read ahead on how to use keys in general. +% \item I get obscure error messages when using `\ikeyname{firstline}'. +% \advisespace +% That shouldn't happen. Make a bug report as described in section +% \lstref{uTroubleshooting}. +% \end{advise} +% +% \paragraph{Stand alone files} +% Finally we come to |\lstinputlisting|, the command to pretty-print stand +% alone files. It has one optional and one file name argument. +% Note that you possibly need to specify the relative path to the file. +% Here now the result is printed below the verbatim code since both together +% don't fit the text width. +% \begin{lstsample}{\lstset{comment=[l]\%,columns=fullflexible}}{\lstset{alsoletter=\\,emph=\\lstinputlisting,emphstyle=\rstyle}\lstaspectindex{\lstinputlisting}{}} +% \lstinputlisting[lastline=4]{listings.sty} +% \end{lstsample} +% \begin{advise} +% \item The spacing is different in this example. +% \advisespace +% Yes. The two previous examples have aligned columns, i.e.~columns with +% identical numbers have the same horizontal position---this package +% makes small adjustments only. The columns in the example here are not +% aligned. This is explained elsewhere (keyword: full flexible column +% format). +% \end{advise} +% +% Now you know all pretty-printing commands and environments. It remains +% to learn the parameters which control the work of the \packagename{listings} +% package. This is, however, the main task. Here are some of them. +% +% +% \subsection{Figure out the appearance}\label{gFigureOutTheAppearance} +% +% Keywords are typeset bold, comments in italic shape, and spaces in strings +% appear as \textvisiblespace. You don't like these settings? Look at this: +%\ifcolor +% \begin{lstxsample}[basicstyle,keywordstyle,identifierstyle,commentstyle,stringstyle,showstringspaces] +% \lstset{% general command to set parameter(s) +% basicstyle=\small, % print whole listing small +% keywordstyle=\color{black}\bfseries\underbar, +% % underlined bold black keywords +% identifierstyle=, % nothing happens +% commentstyle=\color{white}, % white comments +% stringstyle=\ttfamily, % typewriter type for strings +% showstringspaces=false} % no special string spaces +% \end{lstxsample} +%\else +% \begin{lstxsample}[basicstyle,keywordstyle,identifierstyle,commentstyle,stringstyle,showstringspaces] +% \lstset{% general command to set parameter(s) +% basicstyle=\small, % print whole listing small +% keywordstyle=\bfseries\underbar, +% % underlined bold keywords +% identifierstyle=, % nothing happens +% commentstyle=\itshape, % default +% stringstyle=\ttfamily, % typewriter type for strings +% showstringspaces=false} % no special string spaces +% \end{lstxsample} +%\fi +% \begin{lstsample}{}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +%\ifcolor +% \begin{advise} +% \item You've requested white coloured comments, but I can see the comment +% on the left side. +% \advisespace +% There are a couple of possible reasons: +% (1) You've printed the documentation on nonwhite paper. +% (2) If you are viewing this documentation as a \texttt{.dvi}-file, your +% viewer seems to have problems with colour specials. Try to print +% the page on white paper. +% (3) If a printout on white paper shows the comment, the colour +% specials aren't suitable for your printer or printer driver. +% Recreate the documentation and try it again---and ensure that +% the \packagename{color} package is well-configured. +% \end{advise} +%\fi +% The styles use two different kinds of commands. |\ttfamily| and |\bfseries| +% both take no arguments but |\underbar| does; it underlines the following +% argument. In general, the \emph{very last} command might read exactly one +% argument, namely some material the package typesets. There's one exception. +% The last command of \ikeyname{basicstyle} \emph{must not} read any +% tokens---or you will get deep in trouble. +% \begin{advise} +% \item `|basicstyle=\small|' looks fine, but comments look really bad with +% `|commentstyle=\tiny|' and empty basic style, say. +% \advisespace +% Don't change the font size inside listings. +% \item But I really want it! +% \advisespace +% The package adjusts internal data after selecting the basic style at +% the beginning of each listing. This is a problem if you change the +% font size for comments or strings, for example. +% Section \ref{rColumnAlignment} shows how to overcome this. +% But once again: Don't change the font size inside listings unless you +% really know what you are doing. +% \end{advise} +% +% \paragraph{Warning}\label{wStrikingStyles} +% You should be very careful with striking styles; the last example is rather +% moderate---it can get horrible. \emph{Always use decent highlighting.} +% Unfortunately it is difficult to give more recommendations since they depend +% on the type of document you're creating. Slides or other presentations often +% require more striking styles than books, for example. +% In the end, it's \emph{you} who have to find the golden mean! +% +% +% \subsection{Seduce to use}\label{gSeduceToUse} +% +% You know all pretty-printing commands and some main parameters. Here now +% comes a small and incomplete overview of other features. The table of +% contents and the index also provide information. +% +% \paragraph{Line numbers} +% are available for all displayed listings, e.g.~tiny numbers on the left, each +% second line, with 5pt distance to the listing: +% \begin{lstxsample}[numbers,numberstyle,stepnumber,numbersep] +% \lstset{numbers=left, numberstyle=\tiny, stepnumber=2, numbersep=5pt} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item I can't get rid of line numbers in subsequent listings. +% \advisespace +% `|numbers=none|' turns them off. +% \item Can I use these parameters in the optional arguments? +% \advisespace +% Of course. Note that optional arguments modify values for one +% particular listing only: you change the appearance, step or distance +% of line numbers for a single listing. The previous values are +% restored afterwards. +% \end{advise} +% The environment allows you to interrupt your listings: you can end a listing +% and continue it later with the correct line number even if there are other +% listings in between. Read section \ref{uLineNumbers} for a thorough +% discussion. +% +% \paragraph{Floating listings} +% Displayed listings may float: +% \begin{lstsample}{\lstset{frame=tb}}{} +% \begin{lstlisting}[float,caption=A floating example] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% Don't care about the parameter \ikeyname{caption} now. And if you put the +% example into the minimal file and run it through \LaTeX, please don't wonder: +% you'll miss the horizontal rules since they are described elsewhere. +% \begin{advise} +% \item \LaTeX's float mechanism allows to determine the placement of floats. +% What's about that? +% \advisespace +% You can write `|float=tp|', for example. +% \end{advise} +% +% \paragraph{Other features} +% There are still features not mentioned so far: automatic breaking of long +% lines, the possibility to use \LaTeX\ code in listings, automated indexing, +% or personal language definitions. +% One more little teaser? Here you are. But note that the result is not +% produced by the \LaTeX\ code on the right alone. The main parameter is +% hidden. +% \begin{lstsample}{\lstset{literate={:=}{{$\gets$}}1 {<=}{{$\leq$}}1 {>=}{{$\geq$}}1 {<>}{{$\neq$}}1}}{} +% \begin{lstlisting} +% if (i<=0) then i := 1; +% if (i>=0) then i := 0; +% if (i<>0) then i := 0; +% \end{lstlisting} +% \end{lstsample} +% +% You're not sure whether you should use \packagename{listings}? +% Read the next section! +% +% +% \subsection{Alternatives} +% +% \begin{advise} +% \item Why do you list alternatives? +% \advisespace +% Well, it's always good to know the competitors.^^A :-) +% \item I've read the descriptions below and the \packagename{listings} package +% seems to incorporate all the features. Why should I use one of the +% other programs? +% \advisespace +% Firstly, the descriptions give a taste and not a complete overview, +% secondly, \packagename{listings} lacks some properties, and eventually, +% you should use the program matching your needs most precisely. +% \end{advise} +% This package is certainly not the final utility for typesetting source code. +% Other programs do their job very well---if you are not satisfied with +% \packagename{listings}. Some are independent of \LaTeX, other come as +% separate program plus \LaTeX\ package, and other more are packages which +% don't pretty-print the source code. The second type inlcudes converters, +% cross compilers, and preprocessors. Such programs create \LaTeX\ files +% you can use in your document or stand alone ready-to-run \LaTeX\ files. +% +% Note that I'm not dealing with any literate programming tool here, which +% could also be an alternative. However, you should have heard of the +% \texttt{WEB} system, the tool Prof.~Donald E.~Knuth developed and made use +% of to document and implement \TeX. +% +% \paragraph{\packagename{a2ps}} +% started as `ASCII to PostScript' converter, but today you can invoke the +% program with \texttt{--pretty-print=}\meta{language} option. If your +% favourite programming language is not already supported, you can write your +% own so-called style sheet. You can request line numbers, borders, headers, +% multiple pages per sheet, and many more. You can even print symbols like +% $\forall$ or $\alpha$ instead of their verbose forms. If you just want +% program listings and not a document with some listings, this is the best +% choice. +% +% Visit the home page at +% \href{http://www.infres.enst.fr/~demaille/a2ps}^^A +% {http://www.infres.enst.fr/\textasciitilde demaille/a2ps}. +% +% \paragraph{\packagename{cvt2ltx}} +% is a family of `source code to \LaTeX' converters for C, Objective C, \Cpp, +% IDL and Perl. Different styles, line numbers and other qualifiers can be +% chosen by command-line option. Unfortunately it isn't documented how other +% programming languages can be added. +% +% Available via ftp from +% \href{ftp://axp3.sv.fh-mannheim.de/cvt2latex}^^A +% {ftp://axp3.sv.fh-mannheim.de/cvt2latex}. +% +% \paragraph{\packagename{\Cpp2\LaTeX}} +% is a C/\Cpp\ to \LaTeX\ converter. You can specify the fonts for comments, +% directives, keywords, and strings, or the size of a tabulator. But as far as +% I know you can't number lines. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/support/C++2LaTeX-1_1pl1}^^A +% {\textrm{CTAN}/support/C++2LaTeX-1\textunderscore 1pl1}. +% +% \paragraph{\packagename{S\LaTeX}} +% is a pretty-printing Scheme program (invokes \LaTeX\ automatically) +% especially designed for Scheme and other Lisp dialects. It supports stand +% alone files, text and display listings, and you can even nest the +% commands/environments if you use \LaTeX\ code in comments, for example. +% Keywords, constants, variables, and symbols are definable and use of +% different styles is possible. No line numbers. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/support/slatex}^^A +% {\textrm{CTAN}/support/slatex}. +% +% \paragraph{\packagename{tiny\textunderscore c2ltx}} +% is a C/\Cpp/Java to \LaTeX\ converter based on \packagename{cvt2ltx} (or the +% other way round?). It supports line numbers, block comments, \LaTeX\ code +% in/as comments, and smart line breaking. Font selection and tabulators are +% hard-coded, i.e.~you have to rebuild the program if you want to change the +% appearance. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/support/tiny_c2l}^^A +% {\textrm{CTAN}/support/tiny\textunderscore c2l}. +% +% \paragraph{\packagename{listing}} +% ---note the missing \packagename{s}---is not a pretty-printer and the +% aphorism about documentation at the end of \texttt{listing.sty} is not +% true.\space ^^A :-) +% It defines |\listoflistings| and a nonfloating environment for listings. +% All font selection and indention must be done by hand. However, it's +% useful if you have another tool doing that work, e.g.~\packagename{LGrind}. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/contrib/other/misc}^^A +% {\textrm{CTAN}/macros/latex/contrib/other/misc}. +% +% \begin{advise} +% \item Why don't you list \packagename{LGrind}? +% \advisespace +% \packagename{LGrind} contains nonfree code and became nonfree software. +% It is a cross compiler and comes with many predefined programming +% languages. It supports code snippets, displayed listings, line numbers +% to the left or right, arbitrary \LaTeX\ code in the source code, +% printing symbols instead of verbose names, font setup, and more. +% It is available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/nonfree/support/lgrind} +% {\textrm{CTAN}/nonfree/support/lgrind}. +% \end{advise} +% +% \paragraph{\packagename{alg}} +% provides essentially the same functionality as \packagename{algorithms}. +% So read the next paragraph and note that the syntax will be different. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/contrib/other/alg}^^A +% {\textrm{CTAN}/macros/latex/contrib/other/alg}. +% +% \paragraph{\packagename{algorithms}} +% goes a quite different way. You describe an algorithm and the package +% formats it, for example +% \begin{center} +% \begin{minipage}{0.45\linewidth} +%\ifalgorithmic +% \begin{algorithmic} +% \IF {$i\leq0$} +% \STATE $i\gets1$ +% \ELSE\IF {$i\geq0$} +% \STATE $i\gets0$ +% \ENDIF\ENDIF +% \end{algorithmic} +%\else +% \packagename{algorithms} not installed. +%\fi +% \end{minipage} +% \begin{minipage}{0.45\linewidth} +% \begin{verbatim} +%\begin{algorithmic} +%\IF{$i\leq0$} +%\STATE $i\gets1$ +%\ELSE\IF{$i\geq0$} +%\STATE $i\gets0$ +%\ENDIF\ENDIF +%\end{algorithmic}\end{verbatim} +% \end{minipage} +% \end{center} +% As this example shows, you get a good looking algorithm even from a bad +% looking input. The package provides a lot more constructs like |for|-loops, +% |while|-loops, or comments. You can request line numbers, `ruled', `boxed' +% and floating algorithms, a list of algorithms, and you can customize the +% terms \textbf{if}, \textbf{then}, and so on. +% +% Available from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/contrib/supported/algorithms}^^A +% {\textrm{CTAN}/macros/latex/contrib/supported/algorithms}. +% +% \paragraph{\packagename{pretprin}} +% is a package for pretty-printing texts in formal languages---as the title +% in TUGboat, Volume 19 (1998), No.~3 states. It provides environments which +% pretty-print \emph{and} format the source code. Analyzers for Pascal and +% Prolog are defined; adding other languages is easy---if you are or get a bit +% familiar with automatons and formal languages. +% +% Available from +% \href{http://www.mimuw.edu.pl/~wolinski/pretprin.html}^^A +% {http://www.mimuw.edu.pl/\textasciitilde wolinski/pretprin.html}. +% +% \paragraph{\packagename{alltt}} +% defines an environment similar to \texttt{verbatim} except that |\|, |{| and +% |}| have their usual meanings. This means that you can use commands in the +% verbatims, e.g.~select different fonts or enter math mode. +% +% This package is part of the \LaTeX\ base distribution. +% +% \paragraph{\packagename{moreverb}} +% requires \packagename{verbatim} and provides verbatim output to a file, +% `boxed' verbatims and line numbers. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/contrib/supported/moreverb}^^A +% {\textrm{CTAN}/macros/latex/contrib/supported/moreverb}. +% +% \paragraph{\packagename{verbatim}} +% defines an improved version of the standard \texttt{verbatim} environment and +% a command to input files verbatim. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/required/tools}^^A +% {\textrm{CTAN}/macros/latex/required/tools}. +% +% \paragraph{\packagename{fancyvrb}} +% is, roughly spoken, a super set of \packagename{alltt}, +% \packagename{moreverb}, and \packagename{verbatim}, but many more parameters +% control the output. The package provides frames, line numbers on the left or +% on the right, automatic line breaking (difficult), and more. For example, an +% interface to \packagename{listings} exists, i.e.~you can pretty-print source +% code automatically. +% The package \packagename{fvrb-ex} builds above \packagename{fancyvrb} and +% defines environments to present examples similar to the ones in this guide. +% +% Available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/contrib/supported/fancyvrb}^^A +% {\textrm{CTAN}/macros/latex/contrib/supported/fancyvrb}. +% +% +% \section{The next steps}\label{uTheNextSteps} +% +% Now, before actually using the \packagename{listings} package, you should +% \emph{really} read the software license. It does not cost much time and +% provides information you probably need to know. +% +% +% \subsection{Software license}\label{uSoftwareLicense} +% +% The files \texttt{listings.dtx} and \texttt{listings.ins} and all +% files generated from only these two files are referred to as `the +% \packagename{listings} package' or simply `the package'. A `driver' +% is generated from \texttt{lstdrvrs.dtx}. +% +% \paragraph{Copyright} +% The \packagename{listings} package is copyright 1996--2002 Carsten Heinz. +% The drivers are copyright 1997/1998/1999/2000/2001/2002 any individual +% author listed in the driver files. +% +% \paragraph{Distribution and warranty} +% The \packagename{listings} package as well as \texttt{lstdrvrs.dtx} and all +% drivers are distributed under the terms of the \LaTeX\ Project Public +% License from CTAN archives in directory |macros/latex/base/lppl.txt|, +% either version 1.0 or any later version. +% +% \paragraph{Use of the package} +% The \packagename{listings} package is \emph{free} software. However, if you +% distribute the package as part of a commercial product or if you use the +% package to prepare a commercial document (books, journals, and so on), +% I'd like to encourage you to make a donation to the \LaTeX3 fund. +% The size of this `license fee' should depend on the value of the package +% for your product. For more information about \LaTeX3 see +% \href{http://www.latex-project.org}^^A +% {http://www.latex-project.org}. +% +% No matter whether you use the package for a commercial or non-commercial +% document, please send me a copy of the document (\texttt{.dvi}, +% \texttt{.ps}, \texttt{.pdf}, hardcopy, etc.) to support further +% development---it is easier to introduce new features or simplify things +% if I see how the package is used by other people. +% +% \paragraph{Modification advice} +% Permission is granted to modify the \packagename{listings} package as well +% as \texttt{lstdrvrs.dtx}. You are not allowed to distribute a modified +% version of the \packagename{listings} package or \texttt{lstdrvrs.dtx} +% unless you change the file names \emph{and} provide the original files. +% In any case it is better to contact the address below; other users will +% welcome removed bugs, new features, and additional programming languages. +% +% \paragraph{Contacts} +% Read section \lstref{uTroubleshooting} on how to submit a bug report. +% Send all other comments, ideas, and additional programming languages to +% \emph{Carsten Heinz, Tellweg 6, 42275 Wuppertal, Germany} or preferably to +% \lstemail\ using \texttt{listings} in the subject. +% +% \paragraph{Mailing list} +% This is mainly an announcement list regarding new versions, bugs, patches, +% and work-arounds. So I recommend it for system administrators, maintainers +% of \LaTeX\ installations, or people who absolutely need the latest bugs. +% To join the list, send an email to \lstemail\ with subject +% \texttt{subscribe listings}. +% +% +% \subsection{Package loading}\label{uPackageLoading} +% +% As usual in \LaTeX, the package is loaded by +% |\usepackage[|\meta{options}|]{listings}|, +% where |[|\meta{options}|]| is optional and gives a comma separated list of +% options. Each either loads an additional \packagename{listings} aspect, or +% changes default properties. Usually you don't have to take care of such +% options. But in some cases it could be necessary: if you want to compile +% documents created with an earlier version of this package or if you use +% special features. Here's an incomplete list of possible options. +% \begin{advise} +% \item Where is a list of all options? +% \advisespace +% In the developer's guide since they were introduced to debug the +% package more easily. Read section \ref{uHowTos} on how to get that +% guide. +% \end{advise} +% \begin{description} +% \item[\normalfont\texttt{0.21}]\leavevmode +% +% compiles a document created with version 0.21. +% +% \item[\normalfont\texttt{draft}]\leavevmode +% +% The package prints no stand alone files, but shows the captions and +% defines the corresponding labels. +% Note that a global |\documentclass|-option \texttt{draft} is +% recognized, so you don't need to repeat it as a package option. +% +% \item[\normalfont\texttt{savemem}]\leavevmode +% +% tries to save some of \TeX's memory. If you switch between languages +% often, it could also reduce compile time. But all this depends on the +% particular document and its listings. +% \end{description} +% Note that various experimental features also need explicit loading via +% options. Read the respective lines in section \ref{rExperimentalFeatures}. +% +% \medbreak +% After package loading it is recommend to load all used dialects of programming +% languages with the following command. It is faster to load several languages +% with one command than loading each language on demand. +% \begin{syntax} +% \item {\rstyle\icmdname\lstloadlanguages}\marg{comma separated list of languages} +% +% Each language is of the form \oarg{dialect}\meta{language}. Without +% the optional \oarg{dialect} the package loads a default dialect. So +% write `|[Visual]C++|' if you want Visual \Cpp\ and `|[ISO]C++|' for +% ISO \Cpp. Both together can be loaded by the command +% |\lstloadlanguages{[Visual]C++,[ISO]C++}|. +% +% Table \ref{uPredefinedLanguages} on page \pageref{uPredefinedLanguages} +% shows all defined languages and their dialects. +% \end{syntax} +%^^A After or even before language loading, you might want to define default +%^^A dialects---just to be independent of configuration files. +% +% +% \subsection{The key=value interface}\label{uTheKey=ValueInterface} +% +% This package uses the \packagename{keyval} package from the +% \packagename{graphics} bundle by David Carlisle. Each parameter is +% controlled by an associated key and a user supplied value. For example, +% \ikeyname{firstline} is a key and |2| a valid value for this key. +% +% The command {\rstyle\icmdname\lstset} gets a comma separated list of +% ``key|=|value'' pairs. The first list with more than a single entry is on +% page \pageref{gFirstKey=ValueList}: |firstline=2,lastline=5|. +% \begin{advise} +% \item So I can write `|\lstset{firstline=2,lastline=5}|' once for all? +% \advisespace +% No. `\ikeyname{firstline}' and `\ikeyname{lastline}' belong to a small +% set of +% keys which are used on individual listings. However, your command is +% not illegal---it has no effect. You have to use these keys inside the +% optional argument of the environment or input command. +% \item What's about a better example of a key|=|value list? +% \advisespace +% There is one in section \ref{gFigureOutTheAppearance}. +% \item `|language=[77]Fortran|' does not work inside an optional argument. +% \advisespace +% You must put braces around the value if a value with optional argument +% is used inside an optional argument. In the case here write +% `|language={[77]Fortran}|' to select Fortran 77. +% \item If I use the `\ikeyname{language}' key inside an optional argument, the +% language isn't active when I typeset the next listing. +% \advisespace +% All parameters set via `|\lstset|' keep their values up to the end of +% the current environment or group. Afterwards the previous values are +% restored. The optional parameters of the two pretty-printing commands +% and the `\texttt{lstlisting}' environment take effect on the particular +% listing only, i.e.~values are restored immediately. For example, you +% can select a main language and change it for special listings. +% \item \icmdname\lstinline\ has an optional argument? +% \advisespace +% Yes. And from this fact comes a limitation: you can't use the left +% bracket `|[|' as delimiter except you specify at least an empty +% optional argument as in `|\lstinline[][var i:integer;[|'. +% If you forget this, you will either get a ``runaway argument'' error +% from \TeX, or an error message from the \packagename{keyval} package. +% \end{advise} +% +% +% \subsection{Programming languages}\label{uProgrammingLanguages} +% +% You already know how to activate programming languages---at least Pascal. +% An optional parameter selects particular dialects of a language. For example, +% |language=[77]Fortran| selects Fortran 77 and |language=[XSC]Pascal| does the +% same for Pascal XSC. The general form is +% {\rstyle\ikeyname{language}}|=|\oarg{dialect}\meta{language}. +% If you want to get rid of keyword, comment, and string detection, use +% |language={}| as argument to |\lstset| or as optional argument. +% +% Table \ref{uPredefinedLanguages} shows all predefined languages and dialects. +% Use the listed names as \meta{language} and \meta{dialect}, respectively. If +% no dialect or `empty' is given in the table, just don't specify a dialect. +% Each underlined dialect is default; it is selected if you leave out +% the optional argument. The predefined defaults are the newest language +% versions or standard dialects. +%^^A +%^^A Make table of predefined languages. +%^^A +%\let\lstlanguages\empty +%\makeatletter +%\@for\lst@temp:={lstlang1.sty,lstlang2.sty,lstlang3.sty}\do +% {\IfFileExists\lst@temp{}{\let\lstlanguages\relax}} +%\makeatother +%\ifx\lstlanguages\relax +% \PackageWarningNoLine{Listings} +% {Standard drivers not available.\MessageBreak +% Please check your installation.\MessageBreak +% Compilation aborted} +% \csname @@end\expandafter\endcsname +%\fi +%\lstscanlanguages\lstlanguages{lstlang1.sty,lstlang2.sty,lstlang3.sty}{}^^A +%\def\topfigrule{\hrule\kern-0.4pt\relax}^^A +%\let\botfigrule\topfigrule +%\belowcaptionskip=\smallskipamount +% \begin{table}[tb] +% \small +% \caption{Predefined languages. +% Note that some definitions are preliminary, for example HTML and XML. +% Each underlined dialect is default dialect}\label{uPredefinedLanguages}^^A +% \makeatletter +% \setbox\@tempboxa\hbox{^^A +% \InputIfFileExists{listings.cfg}{\lst@InputCatcodes}{}}^^A +% \lstprintlanguages\lstlanguages +% \end{table} +%^^A +%^^A end of table +%^^A +%\lstset{defaultdialect=[doc]Pascal}^^A restore +% \begin{advise} +% \item How can I define default dialects? +% \advisespace +% Check section \ref{rLanguagesAndStyles} for `\keyname{defaultdialect}'. +% \item I have C code mixed with assembler lines. Can \packagename{listings} +% pretty-print such source code, i.e.~highlight keywords and comments of +% both languages? +% \advisespace +% `\ikeyname{alsolanguage}|=|\oarg{dialect}\meta{language}' selects a +% language additionally to the active one. So you only have to write a +% language definition for your assembler dialect, which doesn't interfere +% with the definition of C, say. Moreover you might want to use the key +% `\keyname{classoffset}' described in section \ref{rLanguagesAndStyles}. +% \item How can I define my own language? +% \advisespace +% This is discussed in section \ref{rLanguageDefinitions}. And if you +% think that other people could benefit by your definition, you might +% want to send it to the address in section \ref{uSoftwareLicense}. +% Then it will be published under the \LaTeX\ Project Public License. +% \end{advise} +% Note that the arguments \meta{language} and \meta{dialect} are case +% insensitive and that spaces have no effect. +% +% +% \subsection{Special characters}\label{uSpecialCharacters} +% +% +% \paragraph{Tabulators} +% You might get unexpected output if your sources contain tabulators. +% The package assumes tabulator stops at columns 9, 17, 25, 33, and so on. +% This is predefined via |tabsize=8|. If you change the eight to the number +% $n$, you will get tabulator stops at columns $n+1,2n+1,3n+1,$ and so on. +% \begin{lstsample}[tabsize]{}{} +% \lstset{tabsize=2} +% \begin{lstlisting} +% 123456789 +% { one tabulator } +% { two tabs } +% 123 { 123 + two tabs } +% \end{lstlisting} +% \end{lstsample} +% For better illustration, the left-hand side uses |tabsize=2| but the verbatim +% code |tabsize=4|. Note that |\lstset| modifies the values for all following +% listings in the same environment or group. This is no problem here since the +% examples are typeset inside minipages. If you want to change settings for a +% single listing, use the optional argument. +% +% +% \paragraph{Visible tabulators and spaces} +% One can make spaces and tabulators visible: +% \begin{lstsample}[showspaces,showtabs,tab]{}{} +% \lstset{showspaces=true, +% showtabs=true, +% tab=\rightarrowfill} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% If you request \ikeyname{showspaces} but no \ikeyname{showtabs}, +% tabulators are converted to visible spaces. +% The default definition of \ikeyname{tab} produces a `wide visible space' +% \lstinline[showtabs]! !. So you might want to use |$\to$|, |$\dashv$| +% or something else instead. +% \begin{advise} +% \item Some sort of advice: (1) You should really indent lines of source code +% to make listings more readable. (2) Don't indent some lines with +% spaces and others via tabulators. Changing the tabulator size (of your +% editor or pretty-printing tool) completely disturbs the columns. +% (3) As a consequence, never share your files with differently tab sized +% people!^^A true only if you use tabulators, just :-) +% \item To make the \LaTeX\ code more readable, I indent the environments' +% program listings. How can I remove that indention in the output? +% \advisespace +% Read `How to gobble characters' in section \ref{uHowTos}. +% \end{advise} +% +% +% \paragraph{Form feeds} +% Another special character is a form feed causing an empty line by default. +% {\rstyle\ikeyname{formfeed}}|=\newpage| would result in a new page every +% form feed. Please note that such definitions (even the default) might get +% in conflict with frames. +% +% +% \paragraph{National characters} +% If you type in such characters directly as characters of codes 128--255 and +% use them also in listings, let the package know it---or you'll get really +% funny results. {\rstyle\ikeyname{extendedchars}}|=true| allows and +% |extendedchars=false| prohibits extended characters in listings. If you use +% them, you should load \packagename{fontenc}, \packagename{inputenc} and/or +% any other package which defines the characters. +% \begin{advise} +% \item I have problems using \packagename{inputenc} together with +% \packagename{listings}. +% \advisespace +% This could be a compatibility problem. Make a bug report as described +% in section \lstref{uTroubleshooting}. +% \end{advise} +% The extended characters don't cover Arabic, Chinese, Hebrew, Japanese, and so +% on. Read section \ref{uNationalCharacters} for details on work-arounds. +% +% +% \subsection{Line numbers}\label{uLineNumbers} +% +% You already know the keys \ikeyname{numbers}, \ikeyname{numberstyle}, +% \ikeyname{stepnumber}, and \ikeyname{numbersep} from section +% \ref{gSeduceToUse}. Here now we deal with continued listings. +% You have two options to get consistent line numbering across listings. +% +% \begin{lstsample}[firstnumber]{\lstset{numbers=left,numberstyle=\tiny,stepnumber=2,numbersep=5pt}}{} +% \begin{lstlisting}[firstnumber=100] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% \end{lstlisting} +% And we continue the listing: +% \begin{lstlisting}[firstnumber=last] +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% In the example, \ikeyname{firstnumber} is initially set to 100; some lines +% later the value is \texttt{last}, which continues the numbering of the last +% listing. Note that the empty line at the end of the first part is not printed +% here, but it counts for line numbering. You should also notice that you can +% write |\lstset{firstnumber=last}| once and get consecutively numbered code +% lines---except you specify something different for a particular listing. +% +% On the other hand you can use |firstnumber=auto| and name your listings. +% Listings with identical names (case sensitive!) share a line counter. +% \begin{lstsample}[name]{\lstset{numbers=left,numberstyle=\tiny,stepnumber=2,numbersep=5pt}}{} +% \begin{lstlisting}[name=Test] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% +% \end{lstlisting} +% And we continue the listing: +% \begin{lstlisting}[name=Test] +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% The next |Test| listing goes on with line number {\makeatletter\lstno@Test}, +% no matter whether there are other listings in between. +% \begin{advise} +% \item Okay. And how can I get decreasing line numbers? +% \advisespace +% Sorry, what? +% \advisespace +% Decreasing line numbers as on page \pageref{rDecreasingLabels}. +% \advisespace +% May I suggest to demonstrate your individuality by other means? +% If you differ, you should try a negative `\ikeyname{stepnumber}' +% (together with `\ikeyname{firstnumber}'). +% \end{advise} +% +% Read section \ref{uHowTos} on how to reference line numbers. +% +% +% \subsection{Layout elements} +% +% It's always a good idea to structure the layout by vertical space, +% horizontal lines, or different type sizes and typefaces. The best to stress +% whole listings are---not all at once---colours, frames, vertical space, and +% captions. The latter are also good to refer to listings, of course. +% +% \paragraph{Vertical space} +% The keys {\rstyle\ikeyname{aboveskip}} and {\rstyle\ikeyname{belowskip}} +% control the vertical space above and below displayed listings. Both keys get +% a dimension or skip as value and are initialized to |\medskipamount|. +% +% \paragraph{Frames} +% The key \ikeyname{frame} takes the verbose values \keyvalue{none}, +% \keyvalue{leftline}, \keyvalue{topline}, \keyvalue{bottomline}, +% \keyvalue{lines} (top and bottom), \keyvalue{single} for single frames, or +% \keyvalue{shadowbox}. +% \begin{lstsample}[frame]{}{} +% \begin{lstlisting}[frame=single] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item The rules aren't aligned. +% \advisespace +% This could be a bug of this package or a problem with your +% \texttt{.dvi} driver. \emph{Before} sending a bug report to the package +% author, modify the parameters described in section \ref{rFrames} +% heavily. And do this step by step! +% For example, begin with `|framerule=10mm|'. If the rules are +% misaligned by the same (small) amount as before, the problem does not +% come from the rule width. So continue with the next parameter. +% \end{advise} +% Alternatively you can control the rules at the \texttt{t}op, \texttt{r}ight, +% \texttt{b}ottom, and \texttt{l}eft directly by using the four initial letters +% for single rules and their upper case versions for double rules. +% \begin{lstsample}[frame]{}{} +% \begin{lstlisting}[frame=trBL] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% Note that a corner is drawn if and only if both adjacent rules are requested. +% You might think that the lines should be drawn up to the edge, but what's +% about round corners? The key \ikeyname{frameround} must get exactly four +% characters as value. The first character is attached to the upper right +% corner and it continues clockwise. `\texttt{t}' as character makes the +% corresponding corner round. +% \begin{lstsample}[frameround]{}{} +% \lstset{frameround=fttt} +% \begin{lstlisting}[frame=trBL] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% Note that \ikeyname{frameround} has been used together with |\lstset| and thus +% the value affects all following listings in the same group or environment. +% Since the listing is inside a \texttt{minipage} here, this is no problem. +% \begin{advise} +% \item Dont' use frames all the time, in particular not with short listings. +% This would emphasize nothing. Use frames for $10\%$ or even less of +% your listings, for your most important ones. +% \item If you use frames on floating listings, do you really want frames? +% \advisespace +% No, I want to separate floats from text. +% \advisespace +% Then it is better to redefine \LaTeX's `|\topfigrule|' and +% `|\botfigrule|'. For example, you could write +% `|\renewcommand*\topfigrule{\hrule\kern-0.4pt\relax}|' and make the +% same definition for |\botfigrule|. +% \end{advise} +% +% \paragraph{Captions} +% Now we come to \ikeyname{caption} and \ikeyname{label}. You might guess that +% they can be used in the same manner as \LaTeX's |\caption| and |\label| +% commands: +% \begin{lstsample}[caption,label]{\lstset{xleftmargin=.05\linewidth}}{} +% \begin{lstlisting}[caption={Useless code},label=useless] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% Afterwards you could refer to the listing via |\ref{useless}|. By default +% such a listing gets an entry in the list of listings, which can be printed +% with the command {\rstyle\icmdname\lstlistoflistings}. The key +% {\rstyle\ikeyname{nolol}} suppresses an entry for both the environment or +% the input command. Moreover, you can specify a short caption for the list +% of listings: +% \keyname{caption}|={|\oarg{short}\meta{long}|}|. +% Note that the whole value is enclosed in braces since an optional value is +% used in an optional argument. +% +% If you don't want the label \texttt{\lstlistingname} plus number, you should +% use \ikeyname{title}: +% \begin{lstsample}[title]{\lstset{xleftmargin=.05\linewidth}}{} +% \begin{lstlisting}[title={`Caption' without label}] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item Something goes wrong with `\keyname{title}' in my document: in front of +% the title is a delimiter. +% \advisespace +% The result depends on the document class; some are not compatible. +% Contact the package author for a work-around. +% \end{advise} +% +% \paragraph{Colours} +% One more element. You need the \packagename{color} package and can then +% request coloured background via +% \ikeyname{backgroundcolor}|=|\meta{color command}. +% \begin{advise} +% \item Great! I love colours. +% \advisespace +% Fine, yes, really. And I like to remind you of the warning about +% striking styles on page \pageref{wStrikingStyles}. +% \end{advise} +%\ifcolor +% \begin{lstxsample}[backgroundcolor] +% \lstset{backgroundcolor=\color{yellow}} +% \end{lstxsample} +%\else +% \begin{verbatim} +% color package not installed\end{verbatim} +%\fi +% \begin{lstsample}{}{} +% \begin{lstlisting}[frame=single, +% framerule=0pt] +% for i:=maxint to 0 do +% begin +% j:=square(root(i)); +% end; +% \end{lstlisting} +% \end{lstsample} +% The example also shows how to get coloured space around the whole listing: +% use a frame whose rules has no width. +% +% +% \subsection{Emphasize identifiers}\label{uEmphasizeIdentifiers} +% +% Recall the pretty-printing commands and environment. |\lstinline| prints +% code snippets, |\lstinputlisting| whole files, and \texttt{lstlisting} +% pieces of code which reside in the \LaTeX\ file. And what are these +% different `types' of source code good for? Well, it just happens that a +% sentence contains a code fragment. Whole files are typically included in or +% as an appendix. Nevertheless some books about programming also include such +% listings in normal text sections---to increase the number of pages. +% Nowadays source code should be shipped on disk or CD-ROM and only the main +% header or interface files should be typeset for reference. So, please, don't +% misuse the \packagename{listings} package. But let's get back to the topic. +% +% Obviously `\texttt{lstlisting} source code' isn't used to make an executable +% program from. Such source code has some kind of educational purpose or even +% didactic. +% \begin{advise} +% \item What's the difference between educational and didactic? +% \advisespace +% Something educational can be good or bad, true or false. +% Didactic is true by definition.^^A :-) +% \end{advise} +% Usually \emph{keywords} are highlighted when the package typesets a piece of +% source code. This isn't necessary for readers knowing the programming +% language well. The main matter is the presentation of interface, library or +% other functions or variables. If this is your concern, here come the right +% keys. Let's say, you want to emphasize the functions |square| and |root|, +% for example, by underlining them. Then you could do it like this: +% \begin{lstxsample}[emph,emphstyle] +% \lstset{emph={square,root},emphstyle=\underbar} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% j:=square(root(i)); +% end; +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item Note that the list of identifiers |{square,root}| is enclosed in +% braces. Otherwise the \packagename{keyval} package would complain +% about an undefined key \keyname{root} since the comma finishes the +% key=value pair. +% Note also that you \emph{must} put braces around the value if you +% use an optional argument of a key inside an optional argument of a +% pretty-printing command. Though it is not necessary, the following +% example uses these braces. They are typically forgotten when they +% become necessary, +% \end{advise} +% +% Both keys have an optional \meta{class number} argument for multiple +% identifier lists: +%\ifcolor +% \begin{lstxsample}[emph,emphstyle] +% \lstset{emph={square}, emphstyle=\color{red}, +% emph={[2]root,base},emphstyle={[2]\color{blue}}} +% \end{lstxsample} +%\else +% \begin{lstxsample}[emph,emphstyle] +% \lstset{emph={square}, emphstyle=\underbar, +% emph={[2]root,base},emphstyle={[2]\fbox}} +% \end{lstxsample} +%\fi +% \begin{lstsample}{}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% j:=square(root(i)); +% end; +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item What is the maximal \meta{class number}? +% \advisespace +% $2^{31}-1=2\,147\,483\,647$. But \TeX's memory will exceed before you +% can define so many different classes. +% \end{advise} +% +% One final hint: Keep the lists of identifiers disjoint. Never use a keyword +% in an `emphasize' list or one name in two different lists. Even if your +% source code is highlighted as expected, there is no guarantee that it is +% still the case if you change the order of your listings or if you use the +% next release of this package. +% +% +%\iffalse +% \subsection{*Listing alignment}\label{uListingAlignment} +% +% The examples are typeset with centered \texttt{minipage}s. That's the reason +% why you can't see that line numbers are printed in the margin. Now we +% separate the minipage margin and the minipage by a vertical rule: +% \begin{lstsample}{\lstset{frame=l,framesep=0pt,numberstyle=\tiny,stepnumber=2,numbersep=5pt}}{} +% Some text before +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% The listing is lined up with the normal text. The parameter \ikeyname{xleftmargin} +% moves the listing to the right (or left if the dimension is negative). +% \begin{lstsample}{\lstset{frame=l,framesep=0pt,numberstyle=\tiny,stepnumber=2,numbersep=5pt}}{} +% Some text before +% \begin{lstlisting}[xleftmargin=15pt] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% +% \begin{lstlisting}{ } +% Write('Insensitive'); +% WritE('keywords.'); +% \end{lstlisting} +% \end{lstsample} +% Note again that optional arguments change settings for single listings. +% +% If you use environments like \texttt{itemize} or \texttt{enumerate}, there +% is `natural' indention coming from these environments. By default the +% \packagename{listings} package respects this. But you might use +% |resetmargins=true| (or |false|) to make your own decision. You can use it +% together with |xleftmargin|, of course. +% \begin{advise} +% \item I get heavy overfull |\hbox|es from some listings. +% \advisespace +% This comes from long lines in your listings. You have some options +% to get rid of the overful |\hbox|es. Firstly I recommend to typeset +% listings in smaller fonts than the surrounding text, for example +% `|basicstyle=\small|'. Secondly you might want to use the flexible +% column format. Thirdly you can increase the line width or set it +% explicitly, refer section \ref{rMarginsAndLineShape}. +% If all this doesn't help, you might want to change +% `\ikeyname{basewidth}', but be careful! The two unknown items are +% explained in the next section. +% \end{advise} +% +% You might need to control the vertical position of listings with the +% \ikeyname{boxpos} key, for example, if you use them in \texttt{minipage} or +% \texttt{tabular} environments. Here `listings' means \texttt{lstlisting} or +% |\lstinputlisting|. As the following example shows, you can even place such +% listings inside paragraphs, but you must force the package to do this by +% enclosing the listing in |\hbox{| and |}|. +% \begin{advise} +% \item Is it good form to use the \TeX-primitive `|\hbox|' in a \LaTeX\ +% document? +% \advisespace +% No, it's not. But \LaTeX's `|\mbox|' does not work in this example: +% \end{advise} +% \begin{lstsample}{}{} +% Here are some multi-line listings inside a paragraph. +% The `boxpos' key controls their vertical alignment: +% \hbox{\begin{lstlisting}[boxpos=c] +% center +% center +% \end{lstlisting}} +% \hbox{\begin{lstlisting}[boxpos=b] +% bottom baseline +% bottom baseline +% \end{lstlisting}} +% \hbox{\begin{lstlisting}[boxpos=t] +% top baseline +% top baseline +% \end{lstlisting}} +% \end{lstsample} +%\fi +% +% +% \subsection{Indexing}\label{uIndexing} +% +% is just like emphasizing identifiers---I mean the usage: +% \begin{lstxsample}[index] +% \lstset{index={square},index={[2]root}} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% j:=square(root(i)); +% end; +% \end{lstlisting} +% \end{lstsample} +% Of course, you can't see anything here. You will have to look at the index. +% \begin{advise} +% \item Why the `\ikeyname{index}' key is able to work with multiple identifier +% lists? +% \advisespace +% This question is strongly related to the `{\rstyle\ikeyname{indexstyle}}' +% key. Someone might want to create multiple indexes or want to insert +% prefixes like `|constants|', `|functions|', `|keywords|', and so on. +% The `\ikeyname{indexstyle}' key works like the other style keys except +% that the last token \emph{must} take an argument, namely the +% (printable form of the) current identifier. +% +% You can define `|\newcommand\indexkeywords[1]{\index{keywords, #1}}|' +% and make similar definitions for constant or function names. Then +% `|indexstyle=[1]\indexkeywords|' might meet your purpose. This becomes +% easier if you want to create multiple indexes with the +% \packagename{index} package +% (\href{ftp://ftp.dante.de/tex-archive/macros/latex/contrib/supported/camel} +% {CTAN/macros/latex/contrib/supported/camel}). +% If you have defined appropriate new indexes, it is possible to write +% `|indexstyle=\index[keywords]|', for example. +% +% \item Let's say, I want to index all keywords. It would be annoying to +% type in all the keywords again, specifically if the used programming +% language changes frequently. +% \advisespace +% Just read ahead. +% \end{advise} +% The \ikeyname{index} key has in fact two optional arguments. The first is the +% well-known \meta{class number}, the second is a comma separated list of other +% keyword classes whose identifiers are indexed. The indexed identifiers then +% change automatically with the defined keywords---not automagically, it's not +% an illusion.^^A :-) +% +% Eventually you need to know the names of the keyword classes. It's usually +% the key name followed by a class number, for example, |emph2|, |emph3|, +% \ldots, |keywords2| or |index5|. But there is no number for the first order +% classes |keywords|, |emph|, |directives|, and so on. +% \begin{advise} +% \item `|index=[keywords]|' does not work. +% \advisespace +% The package can't guess which optional argument you mean. Hence you +% must specify both if you want to use the second one. You should try +% `|index=[1][keywords]|'. +% \end{advise} +% +% +% \subsection{Fixed and flexible columns}\label{uFixedAndFlexibleColumns} +% +% The first thing a reader notices---except different styles for keywords, +% etc.---is the column alignment. Arne John Glenstrup invented the flexible +% column format in 1997. Since then some efforts were made to develop this +% branch farther. Currently three column formats are provided: fixed, flexible, +% and full flexible. Take a close look at the following examples. +% \begin{center} +% \lstset{style={},language={}} +% \def\sample{\begin{lstlisting}^^J WOMEN\ \ are^^A +% ^^J \ \ \ \ \ \ \ MEN^^A +% ^^J WOMEN are^^A +% ^^J better MEN^^J \end{lstlisting}} +% \begin{tabular}{@{}c@{\qquad\quad}c@{\qquad\quad}c@{\qquad\quad}c@{}} +% {\rstyle\ikeyname{columns}}|=| & \texttt{fixed} & \texttt{flexible} & \texttt{fullflexible}\\ +% & (at {\makeatletter\lst@widthfixed}) +% & (at {\makeatletter\lst@widthflexible}) +% & (at {\makeatletter\lst@widthflexible})\\ +% \noalign{\medskip} +% \lstset{basicstyle=\ttfamily,basewidth=0.51em}\sample +% & \lstset{columns=fixed}\sample +% & \lstset{columns=flexible}\sample +% & \lstset{columns=fullflexible}\sample +% \end{tabular} +% \end{center} +% \begin{advise} +% \item Why are women better men? +% \advisespace +% Do you want to philosophize? Well, have I ever said that the +% statement ``women are better men'' is true? I can't even remember this +% about ``women are men'' \ldots ^^A ;-)) +% \end{advise} +% In the abstract one can say: The fixed column format ruins the spacing +% intended by the font designer, while the flexible formats ruin the column +% alignment (possibly) intended by the programmer. Common to all is that the +% input characters are translated into a sequence of basic output units like +% \begingroup \lstset{gobble=6,xleftmargin=\leftmargini} +% \makeatletter +%^^A Make \fbox around each output unit. +% \fboxsep=0pt +% \def\lst@alloverstyle#1{\fbox{\kern-\fboxrule\strut#1}\kern-\fboxrule} +% \begin{lstlisting}[basewidth=1em] +% if x=y then write('align') +% else print('align'); +% \end{lstlisting} +% Now, the fixed format puts $n$ characters into a box of width $n\times{} +% $`base width', where the base width is {\makeatletter\lst@widthfixed} in the +% example. The format shrinks and stretches the space between the characters +% to make them fit the box. As shown in the example, some character strings look +% \hbox to 2em{b\hss a\hss d} +% or +% \hbox to 2em{w\hss o\hss r\hss s\hss e}, +% but the output is vertically aligned. +% \endgroup +% +% If you don't need or like this, you should use a flexible format. All +% characters are typeset at their natural width. In particular, they never +% overlap. If a word requires more space than reserved, the rest of the line +% simply moves to the right. The difference between the two formats is that the +% full flexible format cares about nothing else and the normal flexible format +% tries to fix the column alignment if a character string needs less space +% than `reserved'. In the flexible example above, the two MENs are vertically +% aligned since some space has been inserted in the fourth line to fix the +% alignment. In the full flexible format, the two MENs are not aligned. +% +% Note that both flexible modes printed the two blanks in the first line as a +% single blank, but for different reasons: the normal flexible format fixes +% the column alignment and the full flexible format doesn't care about the +% second space. +% +% +% \section{Advanced techniques}\label{uAdvancedTechniques} +% +% +% \subsection{Style definitions} +% +% It is obvious that a pretty-printing tool like this requires some kind of +% language selection and definition. The first has already been described and +% the latter is convered by the next section. However, it is very convenient +% to have the same for printing styles: at a central place of your document +% they can be modified easily and the changes take effect on all listings. +% +% Similar to languages, +% {\rstyle\ikeyname{style}}|=|\meta{style name} +% activates a previously defined style. A definition is as easy: +% {\rstyle|\lstdefinestyle|}\marg{style name}\marg{key=value list}. +% Keys not used in such a definition are untouched by the corresponding style +% selection, of course. For example, you could write +% \begin{verbatim} +% \lstdefinestyle{numbers} +% {numbers=left, stepnumber=1, numberstyle=\tiny, numbersep=10pt} +% \lstdefinestyle{nonumbers} +% {numbers=none}\end{verbatim} +% and switch from listings with line numbers to listings without ones and vice +% versa simply by |style=nonumbers| and |style=numbers|, respectively. +% \begin{advise} +% \item You could even write +% `|\lstdefinestyle{C++}{language=C++,style=numbers}|'. +% Style and language names are independent of each other and so might +% coincide. Moreover it is possible to activate other styles. +% +% \item It's easy to crash the package using styles. Write +% '|\lstdefinestyle{crash}{style=crash}|' and '|\lstset{style=crash}|'. +% \TeX's capacity will exceed, sorry [parameter stack size]. Only bad +% boys use such recursive calls, but only good girls use this package. +% Thus the problem is of minor interest.^^A :-) +% \end{advise} +% +% +% \subsection{Language definitions}\label{uLanguageDefinitions} +% +% This is like style definitions except for an optional dialect name and an +% optional base language---and, of course, a different command name and +% specialized keys. In the simple case it's +% {\rstyle|\lstdefinelanguage|}\marg{language name}\marg{key=value list}. +% For many programming languages it is sufficient to specify keywords and +% standard function names, comments, and strings. Let's look at an example. +% \begin{lstxsample}[morekeywords,sensitive,morecomment,morestring] +% \lstdefinelanguage{rock} +% {morekeywords={one,two,three,four,five,six,seven,eight, +% nine,ten,eleven,twelve,o,clock,rock,around,the,tonight}, +% sensitive=false, +% morecomment=[l]{//}, +% morecomment=[s]{/*}{*/}, +% morestring=[b]", +% } +% \end{lstxsample} +% \begingroup \csname lst@EndWriteFile\endcsname +% \bigbreak +% +% \noindent +% There isn't much to say about keywords. They are defined like identifiers +% you want to emphasize. Additionally you need to specify whether they are +% case sensitive or not. And yes: you could insert |[2]| in front of the +% keyword \texttt{one} to define the keywords as `second order' and print them +% in |keywordstyle={[2]...}|. +% \begin{advise} +% \item I get a `\texttt{Missing = inserted for }|\ifnum|' error when I select +% my language. +% \advisespace +% Did you forget the comma after `|keywords={...}|'? And if you encounter +% unexpected characters after selecting a language (or style), you have +% probably forgotten a different comma or you have given to many +% arguments to a key, for example, |morecomment=[l]{--}{!}|. +% \end{advise} +% +% So let's turn to comments and strings. Each value starts with a +% \emph{mandatory} \oarg{type} argument followed by a changing number of +% opening and closing delimiters. Note that each delimiter (pair) requires a +% key=value on its own, even if types are equal. Hence, you'll need to insert +% \texttt{morestring=[b]'} if single quotes open and close string or character +% literals in the same way as double quotes do in the example. +% +% Eventually you need to know the types and their numbers of delimiters. The +% reference guide contains full lists, here we discuss only the most common. +% For strings these are {\rstyle\texttt{b}} and {\rstyle\texttt{d}} with one +% delimiter each. This delimiter opens and closes the string and inside a +% string it is either escaped by a \texttt backslash or it is \texttt doubled. +% The comment type {\rstyle\texttt{l}} requires exactly one delimiter, which +% starts a comment on any column. This comment goes up to the end of line. +% The other two most common comment types are {\rstyle\texttt{s}} and +% {\rstyle\texttt{n}} with two delimiters each. The first delimiter opens a +% comment which is terminated by the second delimiter. In contrast to the +% \texttt s-type, \texttt n-type comments can be nested. +% \begin{lstxsample}[b,d,l,s,n] +% \lstset{morecomment=[l]{//}, +% morecomment=[s]{/*}{*/}, +% morecomment=[n]{(*}{*)}, +% morestring=[b]", +% morestring=[d]'} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% "str\"ing " not a string +% 'str''ing ' not a string +% // comment line +% /* comment/**/ not a comment +% (* nested (**) still comment +% comment *) not a comment +% \end{lstlisting} +% \end{lstsample} +% \begin{advise} +% \item Is it \emph{that} easy? +% \advisespace +% Almost. There are some troubles you can run into. For example, if +% `\texttt{-*}' starts a comment line and `\texttt{-*-}' a string +% (unlikely but possible), then you must define the shorter delimiter +% first. +% Another problem: by default some characters are not allowed inside +% keywords, for example `\texttt{-}', `\texttt{:}', `\texttt{.}', and +% so on. The reference guide covers this problem by introducing some +% more keys, which let you adjust the standard character table +% appropriately. But note that white space characters are prohibited +% inside keywords. +% \end{advise} +% Finally remember that this section is only an introduction to language +% definitions. There are more keys and possibilities. +% +% +% \subsection{Delimiters}\label{uDelimiters} +% +% You already know two special delimiter classes: comments and strings. +% However, their full syntax hasn't been described so far. For example, +% \ikeyname{commentstyle} applies to all comments---except you specify +% something different. The \emph{optional} \oarg{style} argument follows the +% \emph{mandatory} \oarg{type} argument. +%\ifcolor +% \begin{lstxsample} +% \lstset{morecomment=[l][keywordstyle]{//}, +% morecomment=[s][\color{white}]{/*}{*/}} +% \end{lstxsample} +%\else +% \begin{lstxsample} +% \lstset{morecomment=[l][keywordstyle]{//}, +% morecomment=[s][\underbar]{/*}{*/}} +% \end{lstxsample} +%\fi +% \begin{lstsample}{}{} +% \begin{lstlisting} +% // bold comment line +% a single /* comment */ +% \end{lstlisting} +% \end{lstsample} +% As you can see, you have the choice between specifying the style explicitly +% by \LaTeX\ commands or implicitly by other style keys. But, you're right, +% some implicitly defined styles have no seperate keys, for example the second +% order keyword style. Here---and never with the number 1---you just append +% the order to the base key: \texttt{keywordstyle2}. +% +% You ask for an application? Here you are: one can define different printing +% styles for `subtypes' of a comment, for example +%\ifcolor +% \begin{lstxsample} +% \lstset{morecomment=[s][\color{blue}]{/*+}{*/}, +% morecomment=[s][\color{red}]{/*-}{*/}} +% \end{lstxsample} +%\else +% \begin{lstxsample} +% \lstset{morecomment=[s][\upshape]{/*+}{*/}, +% morecomment=[s][\bfseries]{/*-}{*/}} +% \end{lstxsample} +%\fi +% \begin{lstsample}{\lstset{morecomment=[s]{/*}{*/}}}{} +% \begin{lstlisting} +% /* normal comment */ +% /*+ keep cool */ +% /*- danger! */ +% \end{lstlisting} +% \end{lstsample} +% Here, the comment style is not applied to the second and third line. +% \begin{advise} +% \item Please remember that both `extra' comments must be defined \emph{after} +% the normal comment, since the delimiter `\texttt{/*}' is a substring of +% `\texttt{/*+}' and `\texttt{/*-}'. +% +% \item I have another question. Is `\texttt{language=}\meta{different +% language}' the only way to remove such additional delimiters? +% \advisespace +% Call {\rstyle\ikeyname{deletecomment}} and/or +% {\rstyle\ikeyname{deletestring}} with the same arguments to remove +% the delimiters (but you don't need to provide the optional style +% argument). +% \end{advise} +% Eventually, you might want to use the prefix \texttt{i} on any comment type. +% Then the comment is not only invisible, it is completely discarded from the +% output! +% \begin{lstxsample}[is] +% \lstset{morecomment=[is]{/*}{*/}} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% begin /* comment */ end +% begin/* comment */end +% \end{lstlisting} +% \end{lstsample} +% +% Okay, and now for the real challenges. More general delimiters can be defined +% by the key {\rstyle\ikeyname{moredelim}}. Legal types are {\rstyle\texttt{l}} +% and {\rstyle\texttt{s}}. These types can be preceded by an \texttt{i}, but +% this time \emph{only the delimiters} are discarded from the output. This way +% you can select styles by markers. +% \begin{lstxsample} +% \lstset{moredelim=[is][\ttfamily]{|}{|}} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% roman |typewriter| +% \end{lstlisting} +% \end{lstsample} +% You can even let the package detect keywords, comments, strings, and other +% delimiters inside the contents. +% \begin{lstxsample} +% \lstset{moredelim=*[s][\itshape]{/*}{*/}} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% /* begin +% (* comment *) +% ' string ' */ +% \end{lstlisting} +% \end{lstsample} +% Moreover, you can force the styles being applied cumulative. +% \begin{lstxsample} +% \lstset{moredelim=**[is][\ttfamily]{|}{|}, % cumulative +% moredelim=*[s][\itshape]{/*}{*/}} % not so +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{lstlisting} +% /* begin +% ' string ' +% |typewriter| */ +% +% | begin +% ' string ' +% /*typewriter*/ | +% \end{lstlisting} +% \end{lstsample} +% Look carefully at the output and note the differences. The second +% \texttt{begin} is not printed in bold typewriter type since standard +% \LaTeX\ has no such font. +% +% This suffices for an introduction. Now go and find some more applications. +% +% +% \subsection{Closing and credits}\label{uClosingAndCredits} +% +% You've seen a lot of keys but you are far away from knowing all of them. +% The next step is the real use of the \packagename{listings} package. +% Please take the following advices. Firstly, look up the known commands and +% keys in the reference guide to get a notion of the notation there. Secondly, +% poke about around these keys to learn some other parameters. Then, hopefully, +% you'll be prepared if you encounter any problems or need some special things. +% +% \begin{advise} +% \item +% There is one question `you' haven't asked all the last pages: who is to +% blame. The author has written the guides, coded the \packagename{listings} +% package and some language drivers. Other people defined more languages or +% contributed their ideas; many others made bug reports, but only the first +% bug finder is listed. +%^^A +%^^A Thanks for error reports (first bug finder only), new programming +%^^A languages, etc. +%^^A Special thanks for communication which lead to kernel extensions. +%^^A +% Special thanks go to (alphabetical order) +% \begin{quote} +% \hyphenpenalty=10000\relax \rightskip=0pt plus \linewidth +% \lstthanks{Andreas~Bartelt}{Andreas.Bartelt@Informatik.Uni-Oldenburg.DE}, +% \lstthanks{Jan~Braun}{Jan.Braun@tu-bs.de}, +% \lstthanks{Denis~Girou}{Denis.Girou@idris.fr}, +% \lstthanks{Arne~John~Glenstrup}{panic@diku.dk}, +% \lstthanks{Frank~Mittelbach}{frank.mittelbach@latex-project.org}, +% \lstthanks{Rolf~Niepraschk}{niepraschk@PTB.DE}, +% \lstthanks{Rui~Oliveira}{rco@di.uminho.pt}, +% \lstthanks{Jens~Schwarzer}{schwarzer@schwarzer.dk}, and +% \lstthanks{Boris~Veytsman}{boris@plmsc.psu.edu}. +% \end{quote} +% Moreover I wish to thank +% \begin{quote} +% \hyphenpenalty=10000\relax \rightskip=0pt plus \linewidth +% \lstthanks{Bj{\o}rn~{\AA}dlandsvik}{bjorn@imr.no}, +% \lstthanks{Gaurav~Aggarwal}{gaurav@ics.uci.edu}, +% \lstthanks{Jason~Alexander}{jalex@ea.oac.uci.edu}, +% \lstthanks{Donald~Arseneau}{ASND@erich.triumf.ca}, +% \lstthanks{Claus~Atzenbeck}{Claus.Atzenbeck@stud.uni-regensburg.de}, +% \lstthanks{Peter~Bartke}{bartke@inf.fu-berlin.de} (big thankyou), ^^A beta tester +% \lstthanks{Oliver~Baum}{oli.baum@web.de}, +% \lstthanks{Ralph~Becket}{rbeck@microsoft.com}, +% \lstthanks{Olaf~Trygve~Berglihn}{olafb@pvv.org}, ^^A {1999/11/29}{3-char comment delimiter don't work (Python)} +% \lstthanks{Peter~Biechele}{peter.biechele@physik.uni-freiburg.de}, +% \lstthanks{Kai~Below}{below@tu-harburg.de}, +% \lstthanks{Beat~Birkhofer}{beat@birkhofer.ch}, +% \lstthanks{Fr\'ed\'eric~Boulanger}{Frederic.Boulanger@supelec.fr}, +% \lstthanks{Martin~Brodbeck}{Martin.Brodbeck@gmx.de}, +% \lstthanks{Walter~E.~Brown}{WB@fnal.gov}, +% \lstthanks{Achim~D.~Brucker}{brucker@informatik.uni-freiburg.de}, +% \lstthanks{David~Carlisle}{carlisle@cs.man.ac.uk}, +% \lstthanks{Bradford~Chamberlain}{brad@cs.washington.edu}, +% \lstthanks{Patrick~Cousot}{Patrick.Cousot@wanadoo.fr}, +% \lstthanks{Xavier~Cr\'egut}{cregut@enseeiht.fr}, +% \lstthanks{Holger~Danielsson}{dani@fbg.schwerte.de}, +% \lstthanks{Andreas~Deininger}{deininger@uni-kassel.de}, +% \lstthanks{Robert~Denham}{Robert.Denham@dnr.qld.gov.au}, +% \lstthanks{Detlev~Dr\"oge}{droege@informatik.uni-koblenz.de}, +% \lstthanks{Anders~Edenbrandt}{Anders.Edenbrandt@dna.lth.se}, +% \lstthanks{Chris~Edwards}{edwch00p@infoscience.otago.ac.nz}, +% \lstthanks{David~John~Evans}{Matrix.Software@dial.pipex.com}, +% \lstthanks{Daniel~Gerigk}{Daniel.Gerigk@ePost.de}, +% \lstthanks{KP~Gores}{kp.gores@web.de}, +% \lstthanks{Christian~Gudrian}{Christian.Gudrian@kawo1.rwth-aachen.de}, +% \lstthanks{Carsten~Hamm}{carsten.hamm@siemens.com}, +% \lstthanks{Harald~Harders}{h.harders@tu-bs.de}, +% \lstthanks{Christian~Haul}{haul@dvs1.informatik.tu-darmstadt.de}, +% \lstthanks{Aidan~Philip~Heerdegen}{Aidan.Heerdegen@anu.edu.au}, +% \lstthanks{Jim~Hefferon}{jhefferon@smcvt.edu}, +% \lstthanks{Heiko~Heil}{info@heiko-heil.de}, +% \lstthanks{J\"urgen~Heim}{heim@astro.uni-tuebingen.de}, +% \lstthanks{Dr.~Jobst~Hoffmann}{HOFFMANN@rz.rwth-aachen.de}, +% \lstthanks{Torben~Hoffmann}{toho@it.dtu.dk}, +% \lstthanks{Richard~Hoefter}{hoefter@gmx.de}, +% \lstthanks{Berthold~H\"ollmann}{bhoel@starship.python.net}, +% \lstthanks{Hermann~H\"uttler}{hermann.huettler@gmx.net}, +% \lstthanks{Ralf~Imh\"auser}{snoopy@tribal.line.org}, +% \lstthanks{R.~Isernhagen}{R.Isernhagen@FH-Wolfenbuettel.DE}, +% \lstthanks{Oldrich~Jedlicka}{ojedlick@students.zcu.cz}, +% \lstthanks{Marcin~Kasperski}{Marcin.Kasperski@softax.com.pl}, +% \lstthanks{Christian~Kindinger}{chkind@uni-wuppertal.de}, +% \lstthanks{Steffen~Klupsch}{steffen@vlsi.informatik.tu-darmstadt.de}, +% \lstthanks{Peter~K\"oller}{pkoeller@metaprojekt.de} (big thankyou), ^^A beta tester +% \lstthanks{Stefan~Lagotzki}{info@lagotzki.de}, +% \lstthanks{Rene~H.~Larsen}{rhl@traceroute.dk}, +% \lstthanks{Olivier~Lecarme}{ol@i3s.unice.fr}, +% \lstthanks{Thomas~Leduc}{Thomas.Leduc@lsv.ens-cachan.fr}, +% \lstthanks{Dr.~Peter~Leibner}{Peter.Leibner@sta.siemens.de}, +% \lstthanks{Thomas~Leonhardt}{leonhardt@informatik.tu-darmstadt.de} (big thankyou), ^^A beta tester +% \lstthanks{Magnus~Lewis-Smith}{Magnus.Lewis-Smith@pace.co.uk}, +% \lstthanks{Knut~Lickert}{knut.lickert@gmx.de}, +% \lstthanks{Kris~Luyten}{no email available}, +% \lstthanks{Jos\'e~Romildo~Malaquias}{romildo@urano.iceb.ufop.br}, +% \lstthanks{Andreas~Matthias}{amat@kabsi.at}, +% \lstthanks{Knut~M\"uller}{knut@physik3.gwdg.de}, +% \lstthanks{Svend~Tollak~Munkejord}{svendm@efisms.energy.sintef.no}, +% \lstthanks{Gerd~Neugebauer}{gerd.neugebauer@gmx.de}, +% \lstthanks{Torsten~Neuer}{tneuer@inwise.de}, +% \lstthanks{Michael~Niedermair}{m.g.n@gmx.de}, +% \lstthanks{Heiko~Oberdiek}{oberdiek@ruf.uni-freiburg.de}, +% \lstthanks{Markus~Pahlow}{pahlowm@mar.dfo-mpo.gc.ca}, +% \lstthanks{Zvezdan~V.~Petkovic}{zpetkovic@acm.org}, +% \lstthanks{Michael~Piefel}{piefel@informatik.hu-berlin.de}, +% \lstthanks{Michael~Piotrowski}{mxp@linguistik.uni-erlangen.de}, +% \lstthanks{Manfred~Piringer}{sz0490@rrze.uni-erlangen.de}, +% \lstthanks{Vincent~Poirriez}{Vincent.Poirriez@univ-valenciennes.fr}, +% \lstthanks{Adam~Prugel-Bennett}{apb@ecs.soton.ac.uk}, +% \lstthanks{Ralf~Quast}{rquast@hs.uni-hamburg.de}, +% \lstthanks{Aslak~Raanes}{araanes@ifi.ntnu.no}, +% \lstthanks{Venkatesh~Prasad~Ranganath}{vranganath@cox.net}, +% \lstthanks{Georg~Rehm}{Georg.Rehm@germanistik.uni-giessen.de}, +% \lstthanks{Fermin~Reig}{reig@ics.uci.edu}, +% \lstthanks{Detlef~Reimers}{dreimers@aol.com}, +% \lstthanks{Stephen~Reindl}{stephen.reindl@vodafone.com}, +% \lstthanks{Peter~Ruckdeschel}{Peter.Ruckdeschel@uni-bayreuth.de}, +% \lstthanks{Magne~Rudshaug}{magne@ife.no}, +% \lstthanks{Vespe~Savikko}{vespe@cs.tut.fi}, +% \lstthanks{Gunther~Schmidl}{gschmidl@gmx.at}, +% \lstthanks{Jochen~Schneider}{jschneider@ds3.etech.haw-hamburg.de}, +% \lstthanks{Martin~Steffen}{ms@informatik.uni-kiel.de}, +% \lstthanks{Andreas~Stephan}{Andreas.Stephan@victoria.de}, +% \lstthanks{Gabriel~Tauro}{gabriel@informatik.uni-jena.de}, +% \lstthanks{Winfried~Theis}{theis@statistik.uni-dortmund.de}, +% \lstthanks{Jens~T.~Berger~Thielemann}{jensthi@ifi.uio.no}, +% \lstthanks{Kalle~Tuulos}{kalle.tuulos@nic.fi}, +% \lstthanks{Gregory~Van~Vooren}{Gregory.VanVooren@rug.ac.be}, +% \lstthanks{Thorsten~Vitt}{vitt@informatik.hu-berlin.de}, +% \lstthanks{Herbert~Voss}{voss@perce.de} (big thankyou), ^^A beta tester +% \lstthanks{Herfried~Karl~Wagner}{hirf@gmx.at}, +% \lstthanks{Dominique~de~Waleffe}{ddw@miscrit.be}, +% \lstthanks{Michael~Weber}{mweber@informatik.hu-berlin.de}, +% \lstthanks{Sonja~Weidmann}{Sonja.Weidmann@gmx.de}, +% \lstthanks{Herbert~Weinhandl}{weinhand@grz08u.unileoben.ac.at}, +% \lstthanks{Michael~Wiese}{wiese@itwm.uni-kl.de}, +% \lstthanks{J\"orn~Wilms}{wilms@rocinante.colorado.edu}, +% \lstthanks{Kai~Wollenweber}{kai@ece.WPI.EDU}, +% \lstthanks{Ulrich~G.~Wortmann}{uliw@erdw.ethz.ch}, and +% \lstthanks{Timothy~Van~Zandt}{tvz@econ.insead.edu}. +% \end{quote} +% There are probably other people who contributed to this package. +% If I've missed your name, send an email. +% \end{advise} +% +% +% \part{Reference guide} +% +% +% \section{Main reference}\label{rMainReference} +% +% Your first training is completed. Now that you've left the User's guide, the +% friend telling you what to do has gone. Get more practice and become a +% journeyman!^^A :-) +% \begin{advise} +% \item Actually, the friend hasn't gone. There are still some advices, but +% only from time to time. +% \end{advise} +% +% +% \subsection{How to read the reference} +% +% Commands, keys and environments are presented as follows. +% \begin{syntax} +% \item[1.0,default,hints] \texttt{command}, \texttt{environment} or +% \keyname{key} with \meta{parameters} +% +% This field contains the explanation; here we describe the other fields. +% +% If present, the label in the left margin provides extra information: +% `\textit{addon}' indicates additionally introduced functionality, +% `\textit{changed}' a modified key, `\textit{data}' a command just +% containing data (which is therefore adjustable via |\renewcommand|), +% and so on. Some keys and functionality are `\emph{bug}'-marked or +% with a \dag-sign. These features might change in future or could be +% removed, so use them with care. +% +% If there is verbatim text touching the right margin, it is the +% predefined value. Note that some keys default to this value every +% listing, namely the keys which can be used on individual listings only. +% +% The label in the right margin is the current version number and marks +% newly introduced features. +% \end{syntax} +% Regarding the parameters, please keep in mind the following: +% \begin{enumerate} +% \item A list always means a comma separated list. You must put braces around +% such a list. Otherwise you'll get in trouble with the +% \packagename{keyval} package; it complains about an undefined key. +% \item You must put parameter braces around the whole value of a key if you +% use an \oarg{optional argument} of a key inside an optional +% \oarg{key=value list}: +% |\begin{lstlisting}[caption=|{\rstyle|{|}|[one]two|{\rstyle|}|}|]|. +% \item Brackets `|[ ]|' usually enclose optional arguments and must be typed +% in verbatim. Normal brackets `[ ]' always indicate an optional argument +% and must not be typed in. Thus |[*]| must be typed in exactly as is, +% but [|*|] just gets |*| if you use this argument. +% \item A vertical rule indicates an alternative, e.g.~^^A +% \meta{\alternative{true,false}} allows either \texttt{true} or +% \texttt{false} as arguments. +% \item If you want to enter one of the special characters |{}#%\|, this +% character must be escaped with a backslash. This means that you must +% write |\}| for the single character `right brace'---but of course not +% for the closing paramater character. +% \end{enumerate} +% +% +% \subsection{Typesetting listings}\label{rTypesettingListings} +% +% \begin{syntax} +% \item[0.19] \rcmdname\lstset\marg{key=value list} +% +% sets the values of the specified keys, see also section +% \ref{uTheKey=ValueInterface}. +% The parameters keep their values up to the end of the current group. +% In opposition, all optional \meta{key=value list}s below modify the +% parameters for single listings only. +% +% \item[0.18] \rcmdname\lstinline\oarg{key=value list}\meta{character}\meta{source code}\meta{same character} +% +% works like |\verb| but respects the active language and style. These +% listings use flexible columns except requested differently in the +% optional argument. You can write `|\lstinline!var i:integer;!|' and +% get `\lstinline!var i:integer;!'. +% +% Since the command first looks ahead for an optional argument, you must +% provide at least an empty one if you want to use |[| as +% \meta{character}. +% +% \dag\ An experimental implementation has been done to support the +% syntax |\lstinline|\oarg{key=value list}\marg{source code}. Try it if +% you want and report success and failure. A known limitation is that +% inside another argument the last source code token must not be an +% explicit space token---and, of course, using a listing inside another +% argument is itself experimental, see section \ref{rListingsInsideArguments}. +% +% \item[0.15,,changed] |\begin{|\texttt{\rstyle lstlisting}|}|\oarg{key=value list} +% +% \leavevmode\hspace*{-\leftmargini}|\end{|\texttt{\rstyle lstlisting}|}| +% +% typesets the code in between as a displayed listing. +% +% In contrast to the environment of the \packagename{verbatim} package, +% \LaTeX\ code on the same line and after the end of environment is +% typeset respectively executed. +% +% \item[0.1] \rcmdname\lstinputlisting\oarg{key=value list}\marg{file name} +% +% typesets the stand alone source code file as a displayed listing. +% \end{syntax} +% +% +% \subsection{Space and placement} +% +% \begin{syntax} +% \item[0.20,floatplacement,addon] \rkeyname{float}|=|[|*|]\meta{subset of \textup{\texttt{tbph}}}\syntaxor\rkeyname{float} +% +% makes sense on individual displayed listings only and lets them float. +% The argument controls where \LaTeX\ is \emph{allowed} to put the float: +% at the top or bottom of the current/next page, on a separate page, or +% here where the listing is. +% +% The optional star can be used to get a double-column float in a +% two-column document. +% +% \item[0.21,tbp] \rkeyname{floatplacement}|=|\meta{place specifiers} +% +% is used as place specifier if \keyname{float} is used without value. +% +% \item[0.21,\medskipamount] \rkeyname{aboveskip}|=|\meta{dimension} +% \item[0.21,\medskipamount] \rkeyname{belowskip}|=|\meta{dimension} +% +% define the space above and below displayed listings. +% +% \item[0.17,0pt,\dag] \rkeyname{lineskip}|=|\meta{dimension} +% +% specifies additional space between lines in listings. +% +% \item[0.18,c,\dag] \rkeyname{boxpos}|=|\meta{\alternative{b,c,t}} +% +% Sometimes the \packagename{listings} package puts a |\hbox| around a +% listing---or it couldn't be printed or even processed correctly. +% The key determines the vertical alignment to the surrounding material: +% bottom baseline, centered or top baseline. +% \end{syntax} +% +% +% \subsection{The printed range} +% +% \begin{syntax} +% \item[0.12,true,changed] \rkeyname{print}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{print} +% +% controls whether an individual displayed listing is typeset. Even if +% set false, the respective caption is printed and the label is defined. +% +% Note: If the package is loaded without the \texttt{draft} option, you +% can use this key together with |\lstset|. In the other case the key +% can only be used to typeset particular listings despite of the +% \texttt{draft} option. +% +% \item[0.1,1,renamed] \rkeyname{firstline}|=|\meta{number} +% \item[0.1,9999999,renamed] \rkeyname{lastline}|=|\meta{number} +% +% can be used on individual listings only. They determine the physical +% input lines used to print displayed listings. +% +% \item[0.20,false] \rkeyname{showlines}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{showlines} +% +% If true, the package prints empty lines at the end of listings. +% Otherwise these lines are dropped (but they count for line numbering). +% +% \item[1.0] \rkeyname{emptylines}|=|[|*|]\meta{number} +% +% sets the maximum of empty lines allowed. If there is a block of more +% than \meta{number} empty lines, only \meta{number} ones are printed. +% Without the optional star, line numbers can be disturb when blank +% lines are omitted; with the star, the lines keep their original +% numbers. +% +% \item[0.19,0] \rkeyname{gobble}|=|\meta{number} +% +% gobbles \meta{number} characters at the beginning of each +% \emph{environment} code line. This key has no effect on \cs{lstinline} +% or \cs{lstinputlisting}. +% +% Tabulators expand to \ikeyname{tabsize} spaces before they are gobbled. +% Code lines with less than \ikeyname{gobble} characters are considered +% empty, but never indent the end of environment by more characters. +% \end{syntax} +% +% +% \subsection{Languages and styles}\label{rLanguagesAndStyles} +% +% Please note that the arguments \meta{language}, \meta{dialect}, and +% \meta{style name} are case insensitive and that spaces have no effect. +% \begin{syntax} +% \item[0.18,{{}}] \rkeyname{style}|=|\meta{style name} +% +% activates the key=value list stored with |\lstdefinestyle|. +% +% \item[0.19] \rcmdname\lstdefinestyle\marg{style name}\marg{key=value list} +% +% stores the key=value list. +% +% \item[0.17,{{}}] \rkeyname{language}|=|\oarg{dialect}\meta{language} +% +% activates a (dialect of a) programming language. The `empty' default +% language detects no keywords, no comments, no strings, and so on. +% Without specifying \meta{dialect}, the package chooses a default +% dialect. +% +% Table \ref{uPredefinedLanguages} on page \pageref{uPredefinedLanguages} +% lists all languages and dialects provided by \texttt{lstdrvrs.dtx}. +% The predefined default dialects are underlined. +% +% \item[0.21] \rkeyname{alsolanguage}|=|\oarg{dialect}\meta{language} +% +% selects the (dialect of a) programming language additionally to the +% current active one. Note that some language definitions interfere with +% each other and are plainly incompatible. +% +% Take a look at the \ikeyname{classoffset} key in section +% \ref{rFigureOutTheAppearance} if you want to highlight the keywords +% of the languages differently. +% +% \item[0.19] \rkeyname{defaultdialect}|=|\oarg{dialect}\meta{language} +% +% defines \meta{dialect} as default dialect for \meta{language}. +% If you have defined a default dialect other than empty, for example +% |defaultdialect=[iama]fool|, you can't select the empty dialect, even +% not with |language=[]fool|. +% \end{syntax} +% +% Eventually here's a small list of language specific keys. +% \begin{syntax} +% \item[0.19,false,optional] \rkeyname{printpod}|=|\meta{\alternative{true,false}} +% +% prints or drops PODs in Perl. +% +% \item[0.20,true,\dag optional] \rkeyname{usekeywordsinside}|=|\meta{\alternative{true,false}} +% +% The package either use the first order keywords for HTML or prints all +% identifiers inside |<>| in keyword style. +% +% \item[0.20,true,optional] \rkeyname{makemacrouse}|=|\meta{\alternative{true,false}} +% +% Make specific: Macro use of identifiers, which are defined as first +% order keywords, also prints the surrounding |$(| and |)| in keyword +% style. e.g.~you could get +% \textbf{\textdollar(}\textbf{strip} \textdollar(BIBS)\textbf{)}. +% If deactivated you get +% \textdollar(\textbf{strip} \textdollar(BIBS)). +% \end{syntax} +% +% +% \subsection{Figure out the appearance}\label{rFigureOutTheAppearance} +% +% \begin{syntax} +% \item[0.18,{{}}] \rkeyname{basicstyle}|=|\meta{basic style} +% +% is selected at the beginning of each listing. You could use +% |\footnotesize|, |\small|, |\itshape|, |\ttfamily|, or something like +% that. The last token of \meta{basic style} must not read any following +% characters. +% +% \item[0.18,{{}}] \rkeyname{identifierstyle}|=|\meta{style} +% \item[0.11,\itshape] \rkeyname{commentstyle}|=|\meta{style} +% \item[0.12,{{}}] \rkeyname{stringstyle}|=|\meta{style} +% +% determine the style for non-keywords, comments, and strings. The +% \emph{last} token might be an one-parameter command like |\textbf| or +% |\underbar|. +% +% \item[0.11,\bfseries] \rkeyname{keywordstyle}|=|\oarg{number}\meta{style} +% \item[0.19,keywordstyle] \rkeyname{ndkeywordstyle}|=|\meta{style} +% +% are used to print keywords and second order keywords (if defined). +% The optional \meta{number} argument is the class number to which the +% style should be applied. +% |ndkeywordstyle=...| is equivalent to |keywordstyle=[2]...|. +% +% \item[1.0,0] \rkeyname{classoffset}|=|\meta{number} +% +% is added to all class numbers before the styles, keywords, identifiers, +% etc.~are assigned. The example below defines the keywords directly; +% you could do it indirectly by selection two different languages. +% \end{syntax} +%\ifcolor +% \begin{lstxsample} +% \lstset{classoffset=0, +% morekeywords={one,three,five},keywordstyle=\color{red}, +% classoffset=1, +% morekeywords={two,four,six},keywordstyle=\color{blue}, +% classoffset=0}% restore default +% \end{lstxsample} +%\else +% \begin{lstxsample} +% \lstset{classoffset=0, +% morekeywords={one,three,five},keywordstyle=\itshape, +% classoffset=1, +% morekeywords={two,four,six},keywordstyle=\bfseries}, +% classoffset=0}% restore default +% \end{lstxsample} +%\fi +% \begin{lstsample}{}{} +% \begin{lstlisting} +% one two three +% four five six +% \end{lstlisting} +% \end{lstsample} +% +% \begin{syntax} +% \item[0.20,keywordstyle,optional] \rkeyname{texcsstyle}|=|\meta{style} +% \item[0.20,keywordstyle,optional] \rkeyname{directivestyle}|=|\meta{style} +% +% determine the style of \TeX\ control sequences and directives. +% Note that these key are present only if you've chosen an appropriate +% language. +% +% \item[0.21] \rkeyname{emph}|=|\oarg{number}\marg{identifier list} +% \item[0.21] \rkeyname{moreemph}|=|\oarg{number}\marg{identifier list} +% \item[0.21] \rkeyname{deleteemph}|=|\oarg{number}\marg{identifier list} +% \item[0.21] \rkeyname{emphstyle}|=|\oarg{number}\marg{style} +% +% define, add and remove the \meta{identifier list} from `emphasize +% class \meta{number}' respectively define the style for that class. +% If you don't give an optional argument, the package assumes +% \meta{number}$\,=1$. +% +% These keys are described more detailed in section +% \ref{uEmphasizeIdentifiers}. +% +% \item[1.0] \rkeyname{delim}|=|[\texttt*[\texttt*]]\texttt[\meta{type}\texttt][\texttt[\meta{style}\texttt]]\meta{delimiter\textup(s\textup)} +% \item[1.0] \rkeyname{moredelim}|=|[\texttt*[\texttt*]]\texttt[\meta{type}\texttt][\texttt[\meta{style}\texttt]]\meta{delimiter\textup(s\textup)} +% \item[1.0] \rkeyname{deletedelim}|=|[\texttt*[\texttt*]]\texttt[\meta{type}\texttt]\meta{delimiter\textup(s\textup)} +% +% deletes all previously defined delimiters (but neither strings nor +% comments) and defines the user supplied delimiter, adds the specified +% delimiter, or removes it. +% +% In the first two cases \meta{style} is used to print the delimited +% code (and the delimiters). Here, \meta{style} could be something like +% |\bfseries| or |\itshape|, or it could refer to other styles via +% \texttt{keywordstyle}, \texttt{keywordstyle2}, \texttt{emphstyle}, +% etc. +% +% Supported types are \texttt{l} and \texttt{s}, see the comment keys in +% section \ref{uLanguageDefinitions} for an explanation. If you use the +% prefix \texttt i, i.e.~\texttt{il} or \texttt{is}, the delimiters are +% not printed, which is some kind of invisibility. +% +% If you use one optional star, the package will detect keywords, +% comments, and strings inside the delimited code. With both optional +% stars, aditionally the style is applied cumulative, see section +% \ref{uDelimiters}. +% \end{syntax} +% +% +% \subsection{Getting all characters right} +% +% \begin{syntax} +% \item[0.18,false] \rkeyname{extendedchars}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{extendedchars} +% +% allows or prohibits extended characters in listings, that means +% (national) characters of codes 128--255. If you use extended +% characters, you should load \packagename{fontenc} and/or +% \packagename{inputenc}, for example. +% +% \item[1.0,{{}}] \rkeyname{inputencoding}|=|\meta{encoding} +% +% determines the input encoding. The usage of this key requires the +% \packagename{inputenc} package; nothing happens if it's not loaded. +% +% \item[0.12,8] \rkeyname{tabsize}|=|\meta{number} +% +% sets tabulator stops at columns $\meta{number}+1$, $2\cdot\meta{number}+1$, $3\cdot\meta{number}+1$, and so on. +% Each tabulator in a listing moves the current column to the next +% tabulator stop. +% +% \item[0.20,false,renamed] \rkeyname{showtabs}|=|\meta{\alternative{true,false}} +% +% make tabulators visible or invisible. A visible tabulator looks like +% \lstinline[showtabs]! !, but that can be changed. If you choose +% invisible tabulators but visible spaces, tabulators are converted to +% an appropriate number of spaces. +% +% \item[0.20] \rkeyname{tab}|=|\meta{tokens} +% +% \meta{tokens} is used to print a visible tabulator. You might want to use |$\to$|, |$\mapsto$|, |$\dashv$| or something like that instead of the strange default definition. +% +% \item[0.20,false,renamed] \rkeyname{showspaces}|=|\meta{\alternative{true,false}} +% +% lets all blank spaces appear {\textvisiblespace} or as blank spaces. +% +% \item[0.12,true,renamed] \rkeyname{showstringspaces}|=|\meta{\alternative{true,false}} +% +% lets blank spaces in strings appear {\textvisiblespace} or as blank +% spaces. +% +% \item[0.19,\bigbreak] \rkeyname{formfeed}|=|\meta{tokens} +% +% Whenever a listing contains a form feed \meta{tokens} is executed. +% \end{syntax} +% +% +% \subsection{Line numbers}\label{rLineNumbers} +% +% \begin{syntax} +% \item[1.0,none] \rkeyname{numbers}|=|\meta{\alternative{none,left,right}} +% +% makes the package either print no line numbers, or put them on the +% left or the right side of a listing. +% +% \item[0.16,1,renamed] \rkeyname{stepnumber}|=|\meta{number} +% +% All lines with ``line number $\equiv 0$ modulo \meta{number}'' get a +% line number. +% If you turn line numbers on and off with \keyname{numbers}, the +% parameter \keyname{stepnumber} will keep its value. Alternatively you +% can turn them off via |stepnumber=0| and on with a nonzero number and +% keep the value of \keyname{numbers}. +% +% \item[0.16,{{}},renamed] \rkeyname{numberstyle}|=|\meta{style} +% +% determines the font and size of the numbers. +% +% \item[0.19,10pt,renamed] \rkeyname{numbersep}|=|\meta{dimension} +% +% is the distance between number and listing. +% +% \item[1.0,true] \rkeyname{numberblanklines}|=|\meta{\alternative{true,false}} +% +% If this is set to false, blank lines get no printed line number. +% +% \item[0.20,auto,{renamed,addon}] \rkeyname{firstnumber}|=|\meta{\alternative{auto,last,\normalfont\meta{number}}} +% +% \texttt{auto} lets the package choose the first number: a new listing +% starts with number one, a named listing continues the most recent +% same-named listing (see below), and a stand alone file begins with +% the number corresponding to the first input line. +% +% \texttt{last} continues the numbering of the most recent listing and +% \meta{number} sets it to the number. +% +% \item[1.0] \rkeyname{name}|=|\meta{name} +% +% names a listing. Displayed environment-listings with the same name +% share a line counter. +% +% \item[0.20,\arabic{lstnumber},{renamed,data}] \rcmdname\thelstnumber +% +% prints the lines' numbers. +% \end{syntax} +% We show an example on how to redefine |\thelstnumber|. But if you test it, +% you won't get the result shown on the left. +% \begin{lstxsample} +% \renewcommand*\thelstnumber{\oldstylenums{\the\value{lstnumber}}} +% \end{lstxsample} +% \begin{lstsample}{\lstset{stepnumber=-1}\label{rDecreasingLabels}}{} +% \begin{lstlisting}[numbers=left, +% firstnumber=753] +% begin { empty lines } +% +% +% +% +% +% +% end; { empty lines } +% \end{lstlisting} +% \end{lstsample} +% +% \begin{advise} +% \item +% The example shows a sequence $n,n+1,\ldots,n+7$ of 8 three-digit figures such that the sequence contains each digit $0,1,\ldots,9$. +% But 8 is not minimal with that property. +% Find the minimal number and prove that it is minimal. +% How many minimal sequences do exist? +% +% Now look at the generalized problem: +% Let $k\in\{1,\ldots,10\}$ be given. +% Find the minimal number $m\in\{1,\ldots,10\}$ such that there is a sequence $n,{n+1},\ldots,\allowbreak{n+m-1}$ of $m$ $k$-digit figures which contains each digit $\{0,\ldots,9\}$. +% Prove that the number is minimal. +% How many minimal sequences do exist? +% +% If you solve this problem with a computer, write a \TeX\ program! +% \end{advise} +% +% +% \subsection{Captions} +% +% In despite of \LaTeX\ standard behaviour, captions and floats are independent +% from each other here; you can use captions with non-floating listings. +% \begin{syntax} +% \item[0.21] \rkeyname{title}|=|\meta{title text} +% +% is used for a title without any numbering or label. +% +% \item[0.20] \rkeyname{caption}|={|\oarg{short}\meta{caption text}|}| +% +% The caption is made of \cs{lstlistingname} followed by a running +% number, a seperator, and \meta{caption text}. Either the caption text +% or, if present, \meta{short} will be used for the list of listings. +% +% \item[0.21] \rkeyname{label}|=|\meta{name} +% +% makes a listing referable via |\ref|\marg{name}. +% +% \item[0.16] \rcmdname\lstlistoflistings +% +% prints a list of listings. Each entry is with descending priority +% either the short caption, the caption, the file name or the name of the +% listing, see also the key \keyname{name} in section \ref{rLineNumbers}. +% +% \item[1.0] \rkeyname{nolol}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{nolol} +% +% If true, the listing does not make it into the list of listings. +% +% \item[0.16,Listings,data] \rcmdname\lstlistlistingname +% +% The header name for the list of listings. +% +% \item[0.20,Listing,data] \rcmdname\lstlistingname +% +% The caption label for listings. +% +% \item[0.20,\arabic{lstlisting},data] \rcmdname\thelstlisting +% +% prints the running number of the caption. +% +% \item[0.19,,re-introduced] \rcmdname\lstname +% +% prints the name of the current listing which is either the file name or +% the name defined by the \keyname{name} key. This command can be used to +% define a caption or title template, for example by +% |\lstset{caption=\lstname}|. +% +% \item[0.20,t] \rkeyname{captionpos}|=|\meta{subset of \textup{\texttt{tb}}} +% +% specifies the positions of the caption: top and/or bottom of the +% listing. +% +% \item[0.20,\smallskipamount] \rkeyname{abovecaptionskip}|=|\meta{dimension} +% \item[0.20,\smallskipamount] \rkeyname{belowcaptionskip}|=|\meta{dimension} +% +% is the vertical space above respectively below each caption. +% \end{syntax} +% +% +% \subsection{Margins and line shape}\label{rMarginsAndLineShape} +% +% \begin{syntax} +% \item[0.21,\linewidth] \rkeyname{linewidth}|=|\meta{dimension} +% +% defines the base line width for listings. The following three keys are +% taken into account additionally. +% +% \item[0.19,0pt,renamed] \rkeyname{xleftmargin}|=|\meta{dimension} +% \item[1.0,0pt] \rkeyname{xrightmargin}|=|\meta{dimension} +% +% The dimensions are used as extra margins on the left and right. Line +% numbers and frames both move respectively shrink or grow accordingly. +% +% \item[0.19,false,renamed] \rkeyname{resetmargins}|=|\meta{\alternative{true,false}} +% +% If true indention from list environments like \texttt{enumerate} or +% \texttt{itemize} is reset, i.e.~not used. +% +% \item[0.20,false] \rkeyname{breaklines}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{breaklines} +% +% activates or deactivates automatic line breaking of long lines. +% +% \item[0.20,{{}}] \rkeyname{prebreak}|=|\meta{tokens} +% \item[0.20,{{}}] \rkeyname{postbreak}|=|\meta{tokens} +% +% \meta{tokens} appear at the end of the current line respectively at the beginning of the next (broken part of the) line. +% +% You must not use dynamic space (in particular spaces) since internally we use |\discretionary|. +% However |\space| is redefined to be used inside \meta{tokens}. +% +% \item[0.20,20pt] \rkeyname{breakindent}|=|\meta{dimension} +% +% is the indention of the second, third, \ldots\ line of broken lines. +% +% \item[0.20,true] \rkeyname{breakautoindent}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{breakautoindent} +% +% activates or deactivates automatic indention of broken lines. This +% indention is used additionally to \ikeyname{breakindent}, see the +% example below. +% Visible spaces or visible tabulators might set this auto +% indention to zero. +% \end{syntax} +% In the following example we use tabulators to create long lines, but the +% verbatim part uses |tabsize=1|. +% \begin{lstxsample} +% \lstset{postbreak=\space, breakindent=5pt, breaklines} +% \end{lstxsample} +% \begin{lstsample}{\lstset{string=[d]",tabsize=6}}{\lstset{tabsize=1}\hfuzz=1in} +% \begin{lstlisting} +% "A long string is broken!" +% "Another long line." +% \end{lstlisting} +% +% \begin{lstlisting}[breakautoindent +% =false] +% { Now auto indention is off. } +% \end{lstlisting} +% \end{lstsample} +% +% +% \subsection{Frames}\label{rFrames} +% +% \begin{syntax} +% \item[1.0,none] \rkeyname{frame}|=|\meta{\alternative{none,leftline,topline,bottomline,lines,single,shadowbox}} +% +% draws either no frame, a single line on the left, at the top, at the +% bottom, at the top and bottom, a whole single frame, or a shadowbox. +% +% Note that \packagename{fancyvrb} supports the same frame types except +% \texttt{shadowbox}. The shadow color is \keyname{rulesepcolor}, see +% below. +% +% \item[0.19,{{}},changed] \rkeyname{frame}|=|\meta{subset of \textup{\texttt{trblTRBL}}} +% +% The characters \texttt{trblTRBL} are attached to lines at the top and +% bottom of a listing and to lines on the right and left. Upper case +% characters are used to draw double rules. So |frame=tlrb| draws a +% single frame and |frame=TL| double lines at the top and on the left. +% +% Note that frames usually reside outside the listing's space. +% +% \item[0.20,ffff] \rkeyname{frameround}|=|\meta{\alternative{t,f}}\meta{\alternative{t,f}}\meta{\alternative{t,f}}\meta{\alternative{t,f}} +% +% The four letters are attached to the top right, bottom right, bottom +% left and top left corner. In this order. \texttt{t} makes the +% according corner round. If you use round corners, the rule width is +% controlled via |\thinlines| and |\thicklines|. +% +% Note: The size of the quarter circles depends on \keyname{framesep} +% and is independent of the extra margins of a frame. The size is +% possibly adjusted to fit \LaTeX's circle sizes. +% +% \item[0.19,3pt,renamed] \rkeyname{framesep}|=|\meta{dimension} +% \item[0.19,2pt,renamed] \rkeyname{rulesep}|=|\meta{dimension} +% +% control the space between frame and listing and between double rules. +% +% \item[0.19,0.4pt,renamed] \rkeyname{framerule}|=|\meta{dimension} +% +% controls the width of the rules. +% +% \item[1.0,0pt] \rkeyname{framexleftmargin}|=|\meta{dimension} +% \item[1.0,0pt] \rkeyname{framexrightmargin}|=|\meta{dimension} +% \item[1.0,0pt] \rkeyname{framextopmargin}|=|\meta{dimension} +% \item[1.0,0pt] \rkeyname{framexbottommargin}|=|\meta{dimension} +% +% are the dimensions which are used additionally to \keyname{framesep} +% to make up the margin of a frame. +% +% \item[0.21,,changed] \rkeyname{backgroundcolor}|=|\meta{color command} +% \item[0.21,,{renamed,changed}] \rkeyname{rulecolor}|=|\meta{color command} +% \item[1.0] \rkeyname{fillcolor}|=|\meta{color command} +% \item[1.0] \rkeyname{rulesepcolor}|=|\meta{color command} +% +% specify the colour of the background, the rules, the space between +% `text box' and first rule, and of the space between two rules, +% respectively. +% Note that the value requires a |\color| command, for example +% \keyname{rulecolor}|=\color{blue}|. +% \end{syntax} +% \ikeyname{frame} does not work with |fancyvrb=true| or when the package +% internally makes a |\hbox| around the listing! And there are certainly more +% problems with other commands. Take the time to make a (bug) report. +%\ifcolor +% \begin{lstxsample} +% \lstset{framexleftmargin=5mm, frame=shadowbox, rulesepcolor=\color{blue}} +% \end{lstxsample} +%\else +% \lstset{framexleftmargin=5mm, frame=shadowbox} +%\fi +% \begin{lstsample}{}{} +% \begin{lstlisting}[numbers=left] +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% +% Do you want exotic frames? +% Try the following key if you want for example +% \begin{lstsample}{\lstset{frameshape={RYRYNYYYY}{yny}{yny}{RYRYNYYYY}}}{} +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% \begin{syntax} +% \item[0.20,,\dag] \rkeyname{frameshape}|=|\marg{top shape}\marg{left shape}\marg{right shape}\marg{bottom shape} +% +% gives you full control over the drawn frame parts. +% The arguments are not case sensitive. +% +% Both \meta{left shape} and \meta{right shape} are `left-to-right' +% \alternative{y,n} character sequences (or empty). Each |y| lets the +% package draw a rule, otherwise the rule is blank. These vertical rules +% are drawn `left-to-right' according to the specified shapes. +% The example above uses |yny|. +% +% \meta{top shape} and \meta{bottom shape} are `left-rule-right' +% sequences (or empty). The first `left-rule-right' sequence is attached +% to the most inner rule, the second to the next, and so on. +% Each sequence has three characters: `rule' is either |y| or |n|; +% `left' and `right' are |y|, |n| or |r| (which makes a corner round). +% The example uses |RYRYNYYYY| for both shapes: +% |RYR| describes the most inner (top and bottom) frame shape, |YNY| +% the middle, and |YYY| the most outer. +% \end{syntax} +% To summarize, the example above used +% \begin{verbatim} +% \lstset{frameshape={RYRYNYYYY}{yny}{yny}{RYRYNYYYY}}\end{verbatim} +% Note that you are not resticted to two or three levels. +% However you'll get in trouble if you use round corners when they are too big. +% +% +% \subsection{Indexing} +% +% \begin{syntax} +% \item[0.19] \rkeyname{index}|=|\oarg{number}\oarg{keyword classes}\marg{identifiers} +% \item[0.21] \rkeyname{moreindex}|=|\oarg{number}\oarg{keyword classes}\marg{identifiers} +% \item[0.21] \rkeyname{deleteindex}|=|\oarg{number}\oarg{keyword classes}\marg{identifiers} +% +% define, add and remove \meta{identifiers} and \meta{keyword classes} +% from the index class list \meta{number}. If you don't specify the +% optional number, the package assumes \meta{number} $=1$. +% +% Each appearance of the explicitly given identifiers and each appearance +% of the identifiers of the specified \meta{keyword classes} is indexed. +% For example, you could write |index=[1][keywords]| to index all +% keywords. Note that |[1]| is required here---otherwise we couldn't use +% the second optional argument. +% +% \item[0.19,\lstindexmacro] \rkeyname{indexstyle}|=|\oarg{number}\meta{tokens \textup(one-parameter command\textup)} +% +% \meta{tokens} actually indexes the identifiers for the list +% \meta{number}. In contrast to the style keys, \meta{tokens} +% \emph{must} read exactly one parameter, namely the identifier. +% Default definition is\icmdname{\lstindexmacro}\vspace*{-\itemsep} +% \begin{verbatim} +% \newcommand\lstindexmacro[1]{\index{{\ttfamily#1}}}\end{verbatim} +% \vspace*{-\itemsep}which you shouldn't modify. +% Define your own indexing commands and use them as argument to this key. +% \end{syntax} +% Section \ref{uIndexing} describes this feature in detail. +% +% +% \subsection{Column alignment}\label{rColumnAlignment} +% +% \begin{syntax} +% \item[1.0,{[c]fixed}] \rkeyname{columns}|=|\oarg{\alternative{c,l,r}}\meta{\alternative{fixed,flexible,fullflexible}} +% +% selects the respective column format, refer section +% \ref{uFixedAndFlexibleColumns}. +% +% The optional |c|, |l|, or |r| controls the horizontal orientation of +% smallest output units (keywords, identifiers, etc.). The arguments work +% as follows, where vertical bars visualize the effect: +% $\vert$\lstinline[columns={[c]fixed}]!listing!$\vert$, +% $\vert$\lstinline[columns={[l]fixed}]!listing!$\vert$, and +% $\vert$\lstinline[columns={[r]fixed}]!listing!$\vert$ +% in fixed column mode, +% $\vert$\lstinline[columns={[c]flexible}]!listing!$\vert$, +% $\vert$\lstinline[columns={[l]flexible}]!listing!$\vert$, and +% $\vert$\lstinline[columns={[r]flexible}]!listing!$\vert$ +% with flexible columns, and +% $\vert$\lstinline[columns={[c]fullflexible}]!listing!$\vert$, +% $\vert$\lstinline[columns={[l]fullflexible}]!listing!$\vert$, and +% $\vert$\lstinline[columns={[r]fullflexible}]!listing!$\vert$ +% with full flexible columns. +% +% \item[0.18,false] \rkeyname{flexiblecolumns}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{flexiblecolumns} +% +% selects the most recently selected flexible or fixed column format, +% refer to section \ref{uFixedAndFlexibleColumns}. +% +% \item[0.21,false,\dag] \rkeyname{keepspaces}|=|\meta{\alternative{true,false}} +% +% |keepspaces=true| tells the package not to drop spaces to fix column +% alignment and always converts tabulators to spaces. +% +% \item[0.16] \rkeyname{basewidth}|=|\meta{dimension}\syntaxor +% \item[0.18,{{0.6em,0.45em}}] \rkeyname{basewidth}|={|\meta{fixed}|,|\meta{flexible mode}|}| +% +% sets the width of a single character box for fixed and flexible column +% mode (both to the same value or individually). +% +% \item[0.20,false] \rkeyname{fontadjust}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{fontadjust} +% +% If true the package adjusts the base width every font selection. +% This makes sense only if \ikeyname{basewidth} is given in font specific +% units like `em' or `ex'---otherwise this boolean has no effect. +% +% After loading the package, it doesn't adjust the width every font +% selection: it looks at \ikeyname{basewidth} each listing and uses the +% value for the whole listing. This is possibly inadequate if the style +% keys in section \ref{rFigureOutTheAppearance} make heavy font size +% changes, see the example below. +% +% Note that this key might disturb the column alignment and might have an +% effect on the keywords' appearance! +% \end{syntax} +% \begin{lstsample}{\lstset{basicstyle=\normalsize}}{} +% \lstset{commentstyle=\scriptsize} +% \begin{lstlisting} +% { scriptsize font +% doesn't look good } +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% \begin{lstsample}{\lstset{basicstyle=\normalsize,commentstyle=\scriptsize}}{} +% \begin{lstlisting}[fontadjust] +% { scriptsize font +% looks better now } +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{lstlisting} +% \end{lstsample} +% +% +% \subsection{Escaping to \LaTeX}\label{rEscapingToLaTeX} +% +% \textbf{Note:} {\itshape Any escape to \LaTeX\ may disturb the column +% alignment since the package can't control the spacing there.} +% \begin{syntax} +% \item[0.18,false] \rkeyname{texcl}|=|\meta{\alternative{true,false}}\syntaxor\rkeyname{texcl} +% +% activates or deactivates \LaTeX\ comment lines. If activated, comment +% line delimiters are printed as usual, but the comment line text (up to +% the end of line) is read as \LaTeX\ code and typeset in comment style. +% \end{syntax} +% The example uses \Cpp\ comment lines (but doesn't say how to define them). +% Without |\upshape| we would get \textit{calculate} since the comment style +% is |\itshape|. +% \begin{lstsample}{\lstset{morecomment=[l]//}}{} +% \begin{lstlisting}[texcl] +% // \upshape calculate $a_{ij}$ +% A[i][j] = A[j][j]/A[i][j]; +% \end{lstlisting} +% \end{lstsample} +% +% \begin{syntax} +% \item[0.19,false] \rkeyname{mathescape}|=|\meta{\alternative{true,false}} +% +% activates or deactivates special behaviour of the dollar sign. +% If activated a dollar sign acts as \TeX's text math shift. +% +% This key is useful if you want to typeset formulas in listings. +% +% \item[0.19,{{}}] \rkeyname{escapechar}|=|\meta{character}\syntaxor\rkeyname{escapechar}|={}| +% +% If not empty the given character escapes the user to \LaTeX: all code +% between two such characters is interpreted as \LaTeX\ code. Note that +% \TeX's special characters must be entered with a preceding backslash, +% e.g.~|escapechar=\%|. +% +% \item[0.20,{{}}] \rkeyname{escapeinside}|=|\meta{character}\meta{character}\syntaxor\rkeyname{escapeinside}|={}| +% +% Is a generalization of \ikeyname{escapechar}. If the value is not +% empty, the package escapes to \LaTeX\ between the first and second +% character. +% +% \item[0.20,{{}}] \rkeyname{escapebegin}|=|\meta{tokens} +% \item[0.20,{{}}] \rkeyname{escapeend}|=|\meta{tokens} +% +% The tokens are executed at the beginning respectively at the end of +% each escape, in particular for \ikeyname{texcl}. +% See section \ref{uNationalCharacters} for an application. +% \end{syntax} +% +% \begin{lstsample}{\lstset{morecomment=[l]//}}{} +% \begin{lstlisting}[mathescape] +% // calculate $a_{ij}$ +% $a_{ij} = a_{jj}/a_{ij}$; +% \end{lstlisting} +% \end{lstsample} +% +% \begin{lstsample}{\lstset{morecomment=[l]//}}{} +% \begin{lstlisting}[escapechar=\%] +% // calc%ulate $a_{ij}$% +% %$a_{ij} = a_{jj}/a_{ij}$%; +% \end{lstlisting} +% \end{lstsample} +% +% \begin{lstsample}{\lstset{morecomment=[l]//}}{} +% \lstset{escapeinside=`'} +% \begin{lstlisting} +% // calc`ulate $a_{ij}$' +% `$a_{ij} = a_{jj}/a_{ij}$'; +% \end{lstlisting} +% \end{lstsample} +% In the first example the comment line up to $a_{ij}$ has been typeset by the +% \packagename{listings} package in comment style. The $a_{ij}$ itself is +% typeset in `\TeX\ math mode' without comment style. About the half +% comment line of the second example has been typeset by this package. +% The rest is in `\LaTeX\ mode'. +% +% To avoid problems with the current and future version of this package: +% \begin{enumerate} +% \item Don't use any command of the \packagename{listings} package when you +% have escaped to \LaTeX. +% \item Any environment must start and end inside the same escape. +% \item You might use |\def|, |\edef|, etc., but do not assume that the +% definitions are present later---except they are |\global|. +% \item |\if \else \fi|, groups, math shifts |$| and |$$|, \ldots\ must be +% balanced each escape. +% \item \ldots +% \end{enumerate} +% Expand that list yourself and mail me about new items. +% +% +% \subsection{Interface to \textsf{fancyvrb}} +% +% The \packagename{fancyvrb} package---fancy verbatims---from Timothy van Zandt +% provides macros for reading, writing and typesetting verbatim code. It has +% some remarkable features the \packagename{listings} package doesn't have. +% (Some are possible, but you must find somebody who implements them ; -- ). +% \begin{syntax} +% \item[0.19,,bug] \rkeyname{fancyvrb}|=|\meta{\alternative{true,false}} +% +% activates or deactivates the interface. If active, verbatim code is +% read by \packagename{fancyvrb} but typeset by \packagename{listings}, +% i.e.~with emphasized keywords, strings, comments, and so on. +% Internally we use a very special definition of |\FancyVerbFormatLine|. +% +% This interface works with |Verbatim|, |BVerbatim| and |LVerbatim|. +% But you shouldn't use \packagename{fancyvrb}'s \keyname{defineactive}. +% (As far as I can see it doesn't matter since it does nothing at all, +% but for safety \ldots) +% If \packagename{fancyvrb} and \packagename{listings} provide similar +% functionality, you should use \packagename{fancyvrb}'s. +% +% Bug (\keyname{commandchars}): If you use \packagename{fancyvrb}'s +% \keyname{commandchars}, the used commands must not take arguments from +% the verbatim code except the source code which is actually typeset. +% For example, |\textcolor{red}{keyword}| is illegal since |red| is (used +% to select the colour and) not typeset. There is an easy work-around: +% write |\newcommand*\myred{\textcolor{red}}| and use |\myred{keyword}| +% inside the verbatim code. +% \end{syntax} +% +% \iffancyvrb +% \begin{lstsample}{}{} +% \lstset{morecomment=[l]\ }% :-) +% \fvset{commandchars=\\\{\}} +% +% \begin{BVerbatim} +% First verbatim line. +% \fbox{Second} verbatim line. +% \end{BVerbatim} +% +% \par\vspace{72.27pt} +% +% \lstset{fancyvrb} +% \begin{BVerbatim} +% First verbatim line. +% \fbox{Second} verbatim line. +% \end{BVerbatim} +% \lstset{fancyvrb=false} +% \end{lstsample} +% The lines typeset by the \packagename{listings} package are wider since the +% default \ikeyname{basewidth} equals not the width of a single typewriter type +% character. Moreover note that the first space begins a comment as defined at +% the beginning of the example. +% \else +% \begin{center} +% \packagename{fancyvrb} seems to be unavailable on your platform, thus the +% example couldn't be printed here. +% \end{center} +% \fi +% +% +% \subsection{Environments}\label{rEnvironments} +% +% If you want to define your own pretty-printing environments, try the +% following command. The syntax comes from \LaTeX's |\newenvironment|. +% \begin{syntax} +% \item[0.19] \rcmdname\lstnewenvironment\\ +% \marg{name}\oarg{number}\oarg{opt.~default~arg.}\\ +% |{|\meta{starting code}|}|\\ +% |{|\meta{ending code}|}| +% \end{syntax} +% As a simple example we could just select a particular language. +% \begin{lstxsample} +% \lstnewenvironment{pascal} +% {\lstset{language=pascal}} +% {} +% \end{lstxsample} +% \begin{lstsample}{}{} +% \begin{pascal} +% for i:=maxint to 0 do +% begin +% { do nothing } +% end; +% \end{pascal} +% \end{lstsample} +% Doing other things is as easy, for example, using more keys and adding an +% optional argument to adjust settings each listing: +% \begin{verbatim} +%\lstnewenvironment{pascalx}[1][] +% {\lstset{language=pascal,numbers=left,numberstyle=\tiny,float,#1}} +% {}\end{verbatim} +% +% +% \subsection{Language definitions}\label{rLanguageDefinitions} +% +% You should first read section \ref{uLanguageDefinitions} for an introduction +% to language definitions. Otherwise you're probably unprepared for the full +% syntax of |\lstdefinelanguage|. +% \begin{syntax} +% \item[0.19] \rcmdname\lstdefinelanguage\syntaxnewline[\oarg{dialect}]\marg{language}\syntaxnewline[\oarg{base dialect}\marg{and base language}]\syntaxnewline\marg{key=value list}\syntaxnewline[\oarg{list of required aspects \textup(keywordcomments,texcs,etc.\textup)}] +% +% defines the (given dialect of the) programming language \meta{language}. +% If the language definition is based on another definition, you must +% specify the whole \oarg{base dialect}\marg{and base language}. Note +% that an empty \meta{base dialect} uses the default dialect! +% +% The last optional argument should specify all required aspects. This is +% a delicate point since the aspects are described in the developer's +% guide. You might use existing languages as templates. For example, +% ANSI C uses \aspectname{keywords}, \aspectname{comments}, +% \aspectname{strings} and \aspectname{directives}. +% +% \icmdname{\lst@definelanguage} has the same syntax and is used to +% define languages in the driver files. +% +% \begin{advise} +% \item Where should I put my language definition? +% \advisespace +% If you need the language for one particular document, put it into +% the preamble of that document. Otherwise create the local file +% `\texttt{lstlang0.sty}' or add the definition to that file, but use +% `|\lst@definelanguage|' instead of `|\lstdefinelanguage|'. +% However, you might want to send the definition to the address in +% section \ref{uSoftwareLicense}. Then it will be published under the +% \LaTeX\ Project Public License. +% \end{advise} +% +% \item[0.18] \rcmdname\lstalias\marg{alias}\marg{language} +% +% defines an alias for a programming language. Each \meta{alias} is +% redirected to the same dialect of \meta{language}. +% It's also possible to define an alias for one particular dialect only: +% +% \item[0.18] \rcmdname\lstalias\oarg{alias dialect}\marg{alias}\oarg{dialect}\marg{language} +% +% Here all four parameters are \emph{nonoptional} and an alias with empty +% \meta{dialect} will select the default dialect. Note that aliases +% can't be nested: The two aliases `|\lstalias{foo1}{foo2}|' and +% `|\lstalias{foo2}{foo3}|' redirect |foo1| \emph{not} to |foo3|. +% \end{syntax} +% All remaining keys in this section are intended to build language +% definitions. \emph{No other key should be used in such a definition!} +% +% +% \paragraph{Keywords} +% We begin with keyword building keys. Note: {\itshape If you want to enter +% {\upshape|\|, |{|, |}|, |%|, |#|} or {\upshape|&|} inside or as an argument +% here or below, you must do it with a preceding backslash!} +% \begin{syntax} +% \item[1.0,,{\dag bug}] \rkeyname{keywordsprefix}|=|\meta{prefix} +% +% All identifiers starting with \meta{prefix} will be printed as first +% order keywords. +% +% Bugs: Currently there are several limitations. +% (1) The prefix is always case sensitive. +% (2) Only one prefix can be defined at the same time. +% (3) If used `standalone', the key might work only after selecting a +% nonempty language (and switching back to the empty language if +% necessary). +% (4) The key does not respect the value of \keyname{classoffset} and +% has no optional class \meta{number} argument. +% +% \item[0.11] \rkeyname{keywords}|=|\oarg{number}\marg{list of keywords} +% \item[0.11] \rkeyname{morekeywords}|=|\oarg{number}\marg{list of keywords} +% \item[0.18] \rkeyname{deletekeywords}|=|\oarg{number}\marg{list of keywords} +% +% define, add to or remove the keywords from keyword list \meta{number}. +% The use of \keyname{keywords} is discouraged since it deletes all +% previously defined keywords in the list and is thus incompatible with +% the \keyname{alsolanguage} key. +% +% Please note the keys \ikeyname{alsoletter} and \ikeyname{alsodigit} +% below if you use unusual charaters in keywords. +% +% \item[0.19] \rkeyname{ndkeywords}|=|\marg{list of keywords} +% \item[0.19] \rkeyname{morendkeywords}|=|\marg{list of keywords} +% \item[0.19] \rkeyname{deletendkeywords}|=|\marg{list of keywords} +% +% define, add to or remove the keywords from keyword list 2. +% The use of \keyname{ndkeywords} is discouraged. +% +% \item[0.19,,optional] \rkeyname{texcs}|=|\marg{list of control sequences \textup(without backslashes\textup)} +% \item[0.20,,optional] \rkeyname{moretexcs}|=|\marg{list of control sequences \textup(without backslashes\textup)} +% \item[0.21,,optional] \rkeyname{deletetexcs}|=|\marg{list of control sequences \textup(without backslashes\textup)} +% +% Ditto for control sequences in \TeX\ and \LaTeX. +% +% \item[0.18,,optional] \rkeyname{directives}|=|\marg{list of compiler directives} +% \item[0.21,,optional] \rkeyname{moredirectives}|=|\marg{list of compiler directives} +% \item[0.21,,optional] \rkeyname{deletedirectives}|=|\marg{list of compiler directives} +% +% defines compiler directives in C, \Cpp, Objective-C, and POV. +% +% \item[0.14] \rkeyname{sensitive}|=|\meta{\alternative{true,false}} +% +% makes the keywords, control sequences, and directives case sensitive +% and insensitive, respectively. This key affects the keywords, control +% sequences, and directives only when a listing is processed. In all +% other situations they are case sensitive, for example, +% |deletekeywords={save,Test}| removes `save' and `Test', but neither +% `SavE' nor `test'. +% +% \item[0.19] \rkeyname{alsoletter}|=|\marg{character sequence} +% \item[0.19] \rkeyname{alsodigit}|=|\marg{character sequence} +% \item[0.19] \rkeyname{alsoother}|=|\marg{character sequence} +% +% All identifiers (keywords, directives, and such) begin with a letter +% and goes on with alpha-numeric characters (letters and digits). +% For example, if you write +% |keywords={one-two,\#include}|, +% the minus must become a digit and the sharp a letter since the +% keywords can't be detected otherwise. +% +% Table \ref{rStdCharTable} show the standard configuration of the +% \packagename{listings} package. The three keys overwrite the default +% behaviour. Each character of the sequence becomes a letter, digit +% and other, respectively. +% +% \item[0.20] \rkeyname{otherkeywords}|=|\marg{keywords} +% +% Each given `keyword' is printed in keyword style, but without changing +% the `letter', `digit' and `other' status of the characters. This key +% is designed to define keywords like |=>|, |->|, |-->|, |--|, |::|, and +% so on. If one keyword is a subsequence of another (like |--| and +% |-->|), you must specify the shorter first. +% +% \item[0.20,,{\dag optional}] \rkeyname{keywordsinside}|=|\meta{character}\meta{character}\syntaxor\rkeyname{keywordsinside}|={}| +% +% The first order keywords are active only between the first and second +% character. This key is used for HTML. +% \end{syntax} +% +% \begin{table}[tb] +% \caption{Standard character table}\label{rStdCharTable} +% \begin{tabular}{ll} +% class & characters\\ +% \noalign{\smallskip} +% letter & \texttt{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}\\ +% & \texttt{a b c d e f g h i j k l m n o p q r s t u v w x y z}\\ +% & \texttt{@ \textdollar\ } |_|\\ +% digit & \texttt{0 1 2 3 4 5 6 7 8 9}\\ +% other & \texttt{!\ " \#\ \%\ \&\ ' ( ) * + , - .\ / :\ ; < = > ?}\\ +% & {\catcode`\|=12\texttt{[ \char92\ ] \textasciicircum\ \char123\ | \char125\ \textasciitilde}}\\ +% space & chr(32)\\ +% tabulator & chr(9)\\ +% form feed & chr(12)\\ +% \noalign{\smallskip} +% \end{tabular} +% \par\noindent +% Note: Extended characters of codes 128--255 (if defined) are \emph{currently} +% letters. +% \end{table} +% +% +% \paragraph{Strings} +% \begin{syntax} +% \item[0.12] \rkeyname{string}|=|\oarg{\alternative{b,d,m,bd}}\marg{delimiter \textup(character\textup)} +% \item[0.21] \rkeyname{morestring}|=|\oarg{\alternative{b,d,m,bd}}\marg{delimiter} +% \item[0.21] \rkeyname{deletestring}|=|\oarg{\alternative{b,d,m,bd}}\marg{delimiter} +% +% define, add to or delete the delimiter from the list of string +% delimiters. Starting and ending delimiters are the same, i.e.~in the +% source code the delimiters must match each other. +% +% The optional argument is the type and controls how the delimiter itself +% is represented in a string or character literal: it is escaped by a +% |b|ackslash, |d|oubled (or both is allowed via |bd|) or it is +% `|m|atlabed'. +% The latter one is a special type for Ada and Matlab and possibly more +% languages where the string delimters are also used for other purposes. +% In general the delimiter is also doubled, but a string does not start +% after a letter, a right parenthesis, or a right bracket. +% \end{syntax} +% +% +% \paragraph{Comments} +% \begin{syntax} +% \item[0.13] \rkeyname{comment}|=|\oarg{type}\meta{delimiter\textup(s\textup)} +% \item[0.21] \rkeyname{morecomment}|=|\oarg{type}\meta{delimiter\textup(s\textup)} +% \item[0.21] \rkeyname{deletecomment}|=|\oarg{type}\meta{delimiter\textup(s\textup)} +% +% Ditto for comments, but some types require more than a single +% delimiter. The following overview uses \keyname{morecomment} as the +% only example. +% +% \item[0.13] \keyname{morecomment}|=[l]|\meta{delimiter} +% +% The delimiter starts a comment line, which in general starts with the +% delimiter and ends at end of line. If the character sequence |//| +% should start a comment line (like in \Cpp, Comal 80 or Java), +% |morecomment=[l]=//| is the correct declaration. For Matlab it +% would be |morecomment=[l]\%|---note the preceding backslash. +% +% \item[0.13] \keyname{morecomment}|=[s]|\marg{delimiter}\marg{delimiter} +% +% Here we have two delimiters. The second ends a comment starting with +% the first delimiter. If you require two such comments you can use this +% type twice. C, Java, PL/I, Prolog and SQL all define single comments +% via |morecomment=[s]{/*}{*/}|, and Algol does it with +% |morecomment=[s]{\#}{\#}|, which means that the sharp delimits both +% beginning and end of a single comment. +% +% \item[0.13] \keyname{morecomment}|=[n]|\marg{delimiter}\marg{delimiter} +% +% is similar to type |s|, but comments can be nested. Identical arguments +% are not allowed---think a while about it! +% Modula-2 and Oberon-2 use |morecomment=[n]{(*}{*)}|. +% +% \item[0.18,,changed] \keyname{morecomment}|=[f][]|\oarg{n=preceding columns}\meta{delimiter} +% +% The delimiter starts a comment line if and only if it appears on a +% fixed column-number, namely if it is in column $n$ (zero based). +% +% \item[0.17,,optional] \rkeyname{keywordcomment}|=|\marg{keywords} +% \item[0.21,,optional] \rkeyname{morekeywordcomment}|=|\marg{keywords} +% \item[0.21,,optional] \rkeyname{deletekeywordcomment}|=|\marg{keywords} +% +% A keyword comment begins with a keyword and ends with the same keyword. +% Consider |keywordcomment={comment,co}|. Then +% `\textbf{comment}\allowbreak\ldots\textbf{comment}' and +% `\textbf{co}\ldots\textbf{co}' are comments. +% +% \item[0.17,,optional] \rkeyname{keywordcommentsemicolon}|=|\marg{keywords}\marg{keywords}\marg{keywords} +% +% The definition of a `keyword comment semicolon' requires three keyword +% lists, e.g.~|{end}{else,end}{comment}|. A semicolon always ends such a +% comment. Any keyword of the first argument begins a comment and any +% keyword of the second argument ends it (and a semicolon also); +% a comment starting with any keyword of the third argument is terminated +% with the next semicolon only. In the example all possible comments are +% `\textbf{end}\ldots\textbf{else}', `\textbf{end}\ldots\textbf{end}' +% (does not start a comment again) and `\textbf{comment}\ldots;' and +% `\textbf{end}\ldots;'. +% Maybe a curious definition, but Algol and Simula use such comments. +% +% Note: The keywords here need not to be a subset of the defined +% keywords. They won't appear in keyword style if they aren't. +% +% \item[0.17,,optional] \rkeyname{podcomment}|=|\meta{\alternative{true,false}} +% +% activates or deactivates PODs---Perl specific. +% \end{syntax} +% +% +% \subsection{Installation}\label{rInstallation} +% +% \paragraph{Software installation} +% \begin{enumerate} +% \item Following the \TeX\ directory structure (TDS), you should put the files +% of the \packagename{listings} package into directories as follows: +% \begin{center} +% \begin{tabular}{lcl} +% \texttt{listings.dvi}&$\to$&\texttt{texmf/doc/latex/listings}\\ +% \texttt{listings.dtx}, \texttt{listings.ins},\\ +% \texttt{lstdrvrs.dtx}, +% \texttt{lstpatch.sty}&$\to$&\texttt{texmf/source/latex/listings} +% \end{tabular} +% \end{center} +% Note that you possibly don't have a patch file \texttt{lstpatch.sty}. +% If you don't use the TDS, simply adjust the directories below. +% \item Create the directory \texttt{texmf/tex/latex/listings} or remove all +% files except \texttt{lst}\meta{whatever}\texttt{0.sty} and +% \texttt{lstlocal.cfg} from that directory. +% \item Change the working directory to \texttt{texmf/source/latex/listings} +% and run \texttt{listings.ins} through \TeX. +% \item Move the generated files to \texttt{texmf/tex/latex/listings} if this +% is not already done. +% \begin{center} +% \begin{tabular}{lcl} +% \texttt{listings.sty}, \texttt{lstmisc.sty}, +% &&\qquad(kernel and add-ons)\\ +% \texttt{listings.cfg}, +% &&\qquad(configuration file)\\ +% \texttt{lstlang}\meta{number}\texttt{.sty}, +% &&\qquad(language drivers)\\ +% \texttt{lstpatch.sty}&$\to$&\texttt{texmf/tex/latex/listings} +% \end{tabular} +% \end{center} +% \item If your \TeX\ implementation uses a file name database, update it. +% \item If you receive a patch file later on, put it where +% \texttt{listings.sty} is (and update file name database). +% \end{enumerate} +% Note that \packagename{listings} requires at least version 1.10 of the +% \packagename{keyval} package included in the \packagename{graphics} bundle by +% David Carlisle. This bundle is available via ftp from +% \href{ftp://ftp.dante.de/tex-archive/macros/latex/required/graphics} +% {CTAN/macros/latex/required/graphics}. +% +% +% \paragraph{Software configuration} +% Read this only if you encounter problems with the standard configuration or +% if you want the package to suit foreign languages, for example. +% +% Never modify a file from the \packagename{listings} package, in particular +% not the configuration file. Each new installation or new version overwrites +% it. The software license allows modification, but I can't recommend it. +% It's better to create one or more of the files +% \begin{center} +% \begin{tabular}{lcl} +% \texttt{lstmisc0.sty} & for & local add-ons +% (see developer's guide),\\ +% \texttt{lstlang0.sty} & for & local language definitions +% (see \ref{rLanguageDefinitions}), and\\ +% \texttt{lstlocal.cfg} & as & local configuration file +% \end{tabular} +% \end{center} +% and put it/them to the other \packagename{listings} files. These three files +% are not touched by a new installation except you remove them. +% If \texttt{lstlocal.cfg} exists, it is loaded after \texttt{listings.cfg}. +% You might want to change one of the following parameters. +% \begin{syntax} +% \item[,,data] \rcmdname\lstaspectfiles\quad contains~\rlap{\texttt{\lstaspectfiles}} +% \item[,,data] \rcmdname\lstlanguagefiles\quad contains~\rlap{\texttt{\lstlanguagefiles}} +% +% The package uses the specified files to find add-ons and language +% definitions. +% \end{syntax} +% Moreover you might want to adjust +% \icmdname\lstlistlistingname, +% \icmdname\lstlistingname, +% \ikeyname{defaultdialect}, +% \icmdname\lstalias, or +% \icmdname\lstalias +% as described in earlier section. +% +% +% \section{Experimental features}\label{rExperimentalFeatures} +% +% This section describes the more or less unestablished parts of this package. +% It's unlikely that they are all removed (except it is stated explicitly), but +% they are liable to (heavy) changes and improvements. Such features have been +% \dag-marked in the last sections. So, if you find anything \dag-marked here, +% you should be very, very careful. +% +% +% \subsection{Listings inside arguments}\label{rListingsInsideArguments} +% +% There are some things to consider if you want to use |\lstinline| or the +% listing environment inside arguments. Since \TeX\ reads the argument before +% the `\lst-macro' is executed, this package can't do anything to preserve the +% input: spaces shrink to one space, the tabulator and the end of line are +% converted to spaces, \TeX's comment character is not printable, and so on. +% Hence, \emph{you} must work a bit more. You have to put a backslash in front +% of each of the following four characters: |\{}%|. Moreover you must protect +% spaces in the same manner if: (i) there are two or more spaces following each +% other or (ii) the space is the first character in the line. +% That's not enough: Each line must be terminated with a `line feed' |^^J|. +% And you can't escape to \LaTeX\ inside such listings! +% +% The easiest examples are with |\lstinline| since we need no line feed. +% \begin{verbatim} +%\footnote{\lstinline{var i:integer;} and +% \lstinline!protected\ \ spaces! and +% \fbox{\lstinline!\\\{\}\%!}}\end{verbatim} +% yields\lstset{language=Pascal}\footnote{\lstinline{var i:integer;} and +% \lstinline!protected\ \ spaces! and +% \fbox{\lstinline!\\\{\}\%!}} +% if the current language is Pascal. Note that this example shows another +% experimental feature: use of argument braces as delimiters. This is +% described in section \ref{rTypesettingListings}. +% +% And now an environment example: +% \begin{lstsample}{\lstset{language={}}}{} +% \fbox{% +% \begin{lstlisting}^^J +% \ !"#$\%&'()*+,-./^^J +% 0123456789:;<=>?^^J +% @ABCDEFGHIJKLMNO^^J +% PQRSTUVWXYZ[\\]^_^^J +% `abcdefghijklmno^^J +% pqrstuvwxyz\{|\}~^^J +% \end{lstlisting}} +% \end{lstsample} +% \begin{advise} +% \item You might wonder that this feature is still experimental. The reason: +% You shouldn't use listings inside arguments; it's not always safe. +% \end{advise} +% +% +% \subsection{\dag\ Export of identifiers}\label{rExportOfIdentifiers} +% +% It would be nice to export function or procedure names. In general that's a +% dream so far. The problem is that programming languages use various syntaxes +% for function and procedure declaration or definition. A general interface is +% completely out of the scope of this package---that's the work of a compiler +% and not of a pretty-printing tool. However, it is possible for particular +% languages: in Pascal each function or procedure definition and variable +% declaration is preceded by a particular keyword. +% Note that you must request the following keys with \texttt{procnames} option: +% |\usepackage[procnames]{listings}|. +% \begin{syntax} +% \item[0.19,{{}},{\dag renamed,optional}] \rkeyname{procnamekeys}|=|\marg{keywords} +% \item[0.21,,\dag optional] \rkeyname{moreprocnamekeys}|=|\marg{keywords} +% \item[0.21,,\dag optional] \rkeyname{deleteprocnamekeys}|=|\marg{keywords} +% +% each specified keyword indicates a function or procedure definition. +% Any identifier following such a keyword appears in `procname' style. +% For Pascal you might use\vspace{-.5\baselineskip} +% \begin{verbatim} +% procnamekeys={program,procedure,function}\end{verbatim} +% +% \item[0.19,keywordstyle,\dag optional] \rkeyname{procnamestyle}|=|\meta{style} +% +% defines the style in which procedure and function names appear. +% +% \item[0.19,false,\dag optional] \rkeyname{indexprocnames}|=|\meta{\alternative{true,false}} +% +% If activated, procedure and function names are also indexed. +% \end{syntax} +% \begin{TODO} +% The \aspectname{procnames} aspect is unsatisfactory (since unchanged for more +% than three years). It marks and indexes the function definitions so far, but +% it would be possible to mark also the following function calls, for example. +% A key could control whether function names are added to a special keyword +% class, which then appears in `procname' style. But should these names be +% added globally? There are good reasons for both. Of course, we would also +% need a key to reset the name list. +% \end{TODO} +% +% +% \subsection{\dag\ Hyper references}\label{rHyperReferences} +% +% This very small aspect must be requested via \texttt{hyper} option since it +% is experimental. One perspective for the future is to combine this aspect +% with \aspectname{procnames}. Then it should be possible to click on a +% function name and jump to its definition, for example. +% \begin{syntax} +% \item[0.21,,{\dag optional}] \rkeyname{hyperref}|=|\marg{identifiers} +% \item[0.21,,{\dag optional}] \rkeyname{morehyperref}|=|\marg{identifiers} +% \item[0.21,,{\dag optional}] \rkeyname{deletehyperref}|=|\marg{identifiers} +% +% Hyper references the specified identifiers (via \packagename{hyperref} +% package). A `click' on such an identifier jumps to the previous +% occurrence. +% +% \item[0.21,\hyper@@anchor,{\dag optional}] \rkeyname{hyperanchor}|=|\meta{two-parameter macro} +% \item[0.21,\hyperlink,{\dag optional}] \rkeyname{hyperlink}|=|\meta{two-parameter macro} +% +% The macros are used to set an hyper anchor and link, respectively. +% The defaults are suited for the \packagename{hyperref} package. +% \end{syntax} +% +% +% \subsection{Literate programming} +% +% We begin with an example and hide the crucial key=value list. +% \begin{lstsample}{\lstset{literate={:=}{{$\gets$}}1 {<=}{{$\leq$}}1 {>=}{{$\geq$}}1 {<>}{{$\neq$}}1}}{} +% \begin{lstlisting} +% var i:integer; +% +% if (i<=0) i := 1; +% if (i>=0) i := 0; +% if (i<>0) i := 0; +% \end{lstlisting} +% \end{lstsample} +% Funny, isn't it? We could write |i := 0| respectively i| |$\gets$| |0 +% instead, but that's not literate!^^A :-) +% Now you might want to know how this has been done. Have a \emph{close} +% look at the following key. +% \begin{syntax} +% \item[0.20,,\dag] \rkeyname{literate}|=|\meta{replacement item}\ldots\meta{replacement item} +% +% First note that there are no commas between the items. Each item +% consists of three arguments: +% \marg{replace}\marg{replacement text}\marg{length}. +% \meta{replace} is the original character sequence. +% Instead of printing these characters, we use \meta{replacement text}, +% which takes the width of \meta{length} characters in the output. +% +% Each `printing unit' in \meta{replacement text} \emph{must} be braced +% except it's a single character. For example, you must put braces +% around |$\leq$|. +% If you want to replace |<-1->| by |$\leftarrow1\rightarrow$|, the +% replacement item would be |{<-1->}{{$\leftarrow$}1{$\rightarrow$}}3|. +% Note the braces around the arrows. +% +% If one \meta{replace} is a subsequence of another \meta{replace}, you +% must use the shorter sequence first. For example, |{-}| must be used +% before |{--}| and this before |{-->}|. +% \end{syntax} +% In the example above I've used +% \begin{verbatim} +% literate={:=}{{$\gets$}}1 {<=}{{$\leq$}}1 {>=}{{$\geq$}}1 {<>}{{$\neq$}}1\end{verbatim} +% \begin{TODO} +% Of course, it's good to have keys for adding and removing single +% \meta{replacement item}s. Maybe the key(s) should work in the same fashion +% as the string and comment definitions, i.e.~one item per key=value. +% This way it would be easier to provide better auto-detection in case of a +% subsequence. +% \end{TODO} +% +% +% \subsection{\textsf{LGrind} definitions}\label{rLGrindDefinitions} +% +% Yes, it's a nasty idea to steal language definitions from other programs. +% Nevertheless, it's possible for the \packagename{LGrind} definition +% file---at least partially. Please note that this file must be found by +% \TeX. +% \begin{syntax} +% \item[0.21,,{optional}] \rkeyname{lgrindef}|=|\meta{language} +% +% scans the \texttt{lgrindef} language definition file for +% \meta{language} and activates it if present. Note that not all +% \packagename{LGrind} capabilities have a \packagename{listings} +% analogue. +% +% Note that `Linda' language doesn't work properly since it defines +% compiler directives with preceding `|#|' as keywords. +% +% \item[0.21,lgrindef.,{data,optional}] \rcmdname\lstlgrindeffile +% +% contains the (path and) name of the definition file. +% \end{syntax} +% +% +% \subsection{\dag\ Automatic formatting} +% +% \lstloadaspects{formats}^^A +% The automatic source code formatting is far away from being good. First of +% all, there are no general rules on how source code should be formatted. So +% `format definitions' must be flexible. This flexibility requires a complex +% interface, a powerful `format definition' parser, and lots of code lines +% behind the scenes. Currently, format definitions aren't flexible enough +% (possibly not the definitions but the results). A single `format item' has +% the form +% \begin{itemize}\item[] +% \meta{input chars}|=|\oarg{exceptional chars}\meta{pre}\oarg{\texttt{\string\string}}\meta{post} +% \end{itemize} +% Whenever \meta{input chars} aren't followed by one of the \meta{exceptional +% chars}, formatting is done according to the rest of the value. If |\string| +% isn't specified, the input characters aren't printed (except it's an +% identifier or keyword). Otherwise \meta{pre} is `executed' before printing +% the original character string and \meta{post} afterwards. These two are +% `subsets' of +% \begin{itemize} +% \item |\newline| ---ensuring a new line; +% \item |\space| ---ensuring a whitespace; +% \item |\indent| ---increasing indention; +% \item |\noindent| ---descreasing indention. +% \end{itemize} +% Now we can give an example.\lstaspectindex{\lstdefineformat}{}\lstaspectindex{format}{} +% \begin{lstxsample} +% \lstdefineformat{C}{% +% \{=\newline\string\newline\indent,% +% \}=\newline\noindent\string\newline,% +% ;=[\ ]\string\space} +% \end{lstxsample} +% \begin{lstsample}{\lstset{language={}}}{} +% \begin{lstlisting}[format=C] +% for (int i=0;i<10; i++){/* wait */}; +% \end{lstlisting} +% \end{lstsample} +% Not good. But there is a (too?) simple work-around: +% \begin{lstxsample} +% \lstdefineformat{C}{% +% \{=\newline\string\newline\indent,% +% \}=[;]\newline\noindent\string\newline,% +% \};=\newline\noindent\string\newline,% +% ;=[\ ]\string\space} +% \end{lstxsample} +% \begin{lstsample}{\lstset{language={}}}{} +% \begin{lstlisting}[format=C] +% for (int i=0;i<10; i++){/* wait */}; +% \end{lstlisting} +% \end{lstsample} +% Sometimes the problem is just to find a suitable format definition. +% Further formatting is complicated. +% Here are only three examples with increasing level of difficulty. +% \begin{enumerate} +% \item Insert horizontal space to separate function/procedure name and +% following parenthesis or to separate arguments of a function, +% e.g.~add the space after a comma (if inside function call). +% \item Smart breaking of long lines. Consider long `and/or' expressions. +% Formatting should follow the logical structure! +% \item Context sensitive formatting rules. It can be annoying if empty +% or small blocks take three or more lines in the output---think of +% scrolling down all the time. So it would be nice if the block +% formatting was context sensitive. +% \end{enumerate} +% Note that this is a very first and clumsy attempt to provide automatic +% formatting---clumsy since the problem isn't trivial. Any ideas are welcome. +% Implementations also. Eventually you should know that you must request format +% definitions at package loading, e.g.~via |\usepackage[formats]{listings}|. +% +% +% \section{Forthcoming ?} +% +% This section is rather rudimentary. It just lists some things I don't want +% to forget. +% +% First of all, I'd like to support even more languages, for example Maple, +% PostScript, Reduce, and so on. Fortunately my lifetime is limited, so other +% people may do that work. Please (e-)mail me your language definitions. +% +% Then, there are several ideas for the future. Some have already been stated +% as `to do's; some came from other people and are stated below; some more are +% far from being implemented, +% e.g.~\keyname{linerange}|=|\oarg{inter}\marg{line range list} +% which prints all lines in the range and executes \meta{inter} when omitting +% some code lines. The main problem here are frames and background colours; +% what should happen to them? In fact, the problem is how this can be coded. +% Another idea is to change the background colour (or the basic style) for +% particular code blocks. This, too, is not easy. +% +%^^A Auto-detect whether surplus space (from spaces and tabs) isn't needed to fix +%^^A alignment of wide character combinations like |==| or |<>|. +%^^A +%^^A Make package compatible to calc package. +%^^A +%^^A Rewrite \lst@LAS, \lst@DefDriver, \lst@Require to distinguish loading +%^^A of languages (which don't need base languages at once) and aspects +%^^A (which need required aspects to be loaded). +% +% \lsthelper{Vincent~Poirriez}{1999/11/18}{code examples inside caml comments}: +% Inside caml comments, |[| and |]| should print the code in +% between in basicstyle (or another newly introduced style). Nesting of these +% `code example delimiters' is allowed, e.g.~|(* [[x;y]] *)|. +% +% \lsthelper{Claus~Atzenbeck}{1999/12/03}{`extendedchars=false' doesn't issue +% warning when extended characters are used}: issue warning in final mode if +% \ikeyname{extendedchars}|=false| but extended chars are used. +% +% \lsthelper{Andreas~Matthias}{2000/01/04}{define header/footer to print +% the listing name}: Make the header/footer print the listing name. +% +% +% \part{Tips and tricks} +% +% Note: This part of the documentation is under construction. +% Section \ref{uHowTos} must be sorted by topic and ordered in some way. +% Moreover a new section `Examples' is planned, but not written. +% +% +% \section{Troubleshooting}\label{uTroubleshooting} +% +% If you're faced with a \packagename{listings}' package problem, there are +% some steps you should undergo before you make a bug report. First you should +% consult the reference guide whether the problem is already known. If not, +% create a \emph{minimal} file which reproduced the problem. Follow these +% instructions: +% \begin{enumerate} +% \item Start from the minimal file in section \ref{uAMinimalFile}. +% \item Add the \LaTeX\ code which causes the problem, but keep it short. +% In particular, keep the number of additional packages small. +% \item Remove some code from the file (and the according packages) until the +% problem disappears. Then you've found a crucial piece. +% \item Add this piece of code again and start over with step 3 until all code +% and all packages are substantial. +% \item You now have a minimal file. Send a bug report to the address on the +% first page of this documentation and include the minimal file together +% with the created \texttt{.log}-file. If you use a very special package +% (i.e.~not on CTAN), also include the package if its software license +% allows it. +% \end{enumerate} +% +% +% \section{How tos}\label{uHowTos} +% +% +% \subsubsection*{How to reference line numbers} +% You want to put |\label{|\meta{whatever}|}| into a \LaTeX\ escape which is +% inside a comment whose delimiters aren't printed? The compiler won't see the +% \LaTeX\ code since inside a comment, and the \packagename{listings} package +% won't print anything since the delimiters are dropped and |\label| doesn't +% produce any printable output. Well, your wish is granted. +% +% In Pascal, for example, you could make the package recognize the `special' +% comment delimiters |(*@| and |@*)| as begin-escape and end-escape sequences. +% Then you can use this special comment for |\label|s and other things. +% \begin{lstsample}{\lstset{numberstyle=\tiny,stepnumber=2,numbersep=5pt}}{} +% \lstset{escapeinside={(*@}{@*)}} +% +% \begin{lstlisting} +% for i:=maxint to 0 do +% begin +% { comment }(*@\label{comment}@*) +% end; +% \end{lstlisting} +% Line \ref{comment} shows a comment. +% \end{lstsample} +% \begin{advise} +% \item Can I use `|(*@|' and `|*)|' instead? +% \advisespace +% Yes. +% \item Can I use `|(*|' and `|*)|' instead? +% \advisespace +% Sure. If you want this. +% \item Can I use `|{@|' and `|@}|' instead? +% \advisespace +% No, never! The second delimiter is not allowed. The character `|@|' is +% defined to check whether the escape is over. But reading the lonely +% `end-argument' brace, \TeX\ encounters the error `\texttt{Argument of @ +% has an extra \char125}'. Sorry. +% \item Can I use `|{|' and `|}|' instead? +% \advisespace +% No. Again the second delimiter is not allowed. Here now \TeX\ would +% give you a `\texttt{Runaway argument}' error. Since `|}|' is defined to +% check whether the escape is over, it won't work as `end-argument' brace. +% \item And how can I use a comment line? +% \advisespace +% For example, write `|escapeinside={//*}{\^^M}|'. Here |\^^M| represents +% the end of line character. +% \end{advise} +% +% +% \subsubsection*{How to gobble characters} +% To make your \LaTeX\ code more readable, you might want to indent your +% \texttt{lstlisting} listings. This indention must be removed for +% pretty-printing. If you indent each code line by three characters, you can +% remove them via |gobble=3|: +% \begin{lstsample}{}{\lstset{showspaces}} +% \begin{lstlisting}[gobble=3] +% 1 for i:=maxint to 0 do +% 2 begin +% 3 { do nothing } +% 123end; +% +% Write('Case insensitive '); +% WritE('Pascal keywords.'); +% \end{lstlisting} +% \end{lstsample} +% Note that empty lines as well as the beginning and the end of the environment +% need not to respect the indention. But never indent the end by more than +% `\ikeyname{gobble}' characters. Moreover note that tabulators expand to +% |tabsize| spaces before we gobble. +% \begin{advise} +% \item Could I use `\ikeyname{gobble}' together with `|\lstinputlisting|'? +% \advisespace +% Yes, but it has no effect. +% +% \item Note that `\ikeyname{gobble}' can also be set via `|\lstset|'. +% \end{advise} +% +% +% \subsubsection*{How to include graphics} +% \lsthelper{Herbert~Weinhandl}{1999/09/06}{listings + eps} found a very easy +% way to include graphics in listings. Thanks for contributing this idea---an +% idea I never have had. +% +% Some programming languages allow the dollar sign to be part of an identifier. +% But except for intermediate function names or library functions, this +% character is most often unused. The \packagename{listings} package defines +% the \ikeyname{mathescape} key, which lets `|$|' escape to \TeX's math mode. +% This makes the dollar character an excellent candidate for our purpose here: +% use a package which can include a graphic, set \ikeyname{mathescape} true, +% and include the graphic between two dollar signs, which are inside a comment. +% +% The following example is originally from a header file I got from Herbert. +% For the presentation here I use the \texttt{lstlisting} environment and an +% excerpt from the header file. The |\includegraphics| command is from +% David Carlisle's \packagename{graphics} bundle. +% \begin{verbatim} +% \begin{lstlisting}[mathescape=true] +% /* +% $ \includegraphics[height=1cm]{defs-p1.eps} $ +% */ +% typedef struct { +% Atom_T *V_ptr; /* pointer to Vacancy in grid */ +% Atom_T *x_ptr; /* pointer to (A|B) Atom in grid */ +% } ABV_Pair_T; +% \end{lstlisting}\end{verbatim} +% The result looks pretty good. Unfortunately you can't see it. +% +% +% \subsubsection*{How to get closed frames on each page} +% The package supports closed frames only for listings which don't cross pages. +% If a listing is split on two pages, there is neither a bottom rule at the +% bottom of a page, nor a top rule on the following page. If you insist on +% these rules, you might want to use \texttt{framed.sty} by Donald Arseneau. +% Then you could write +% \begin{verbatim} +% \begin{framed} +% \begin{lstlisting} +% or \lstinputlisting{...} +% \end{lstlisting} +% \end{framed}\end{verbatim} +% The package also provides a \texttt{shaded} environment. If you use it, you +% shouldn't forget to define \texttt{shadecolor} with the \packagename{color} +% package. +% +% +% \subsubsection*{How to print national characters with $\Lambda$ and \packagename{listings}}\label{uNationalCharacters} +% +% Apart from typing in national characters directly, you can use the `escape' +% feature described in section \ref{rEscapingToLaTeX}. +% The keys \ikeyname{escapechar}, \ikeyname{escapeinside}, and \ikeyname{texcl} +% allow partial usage of \LaTeX\ code. +% +% Now, if you use $\Lambda$ (Lambda, the \LaTeX\ pendant to Omega) and want, +% for example, Arabic comment lines, you need not to write |\begin{arab}| +% \ldots\ |\end{arab}| each escaped comment line. This can be automated: +% \begin{verbatim} +% \lstset{escapebegin=\begin{arab},escapeend=\end{arab}} +% +% \begin{lstlisting}[texcl] +% // Replace text by Arabic comment. +% for (int i=0; i<1; i++) { }; +% \end{lstlisting}\end{verbatim} +% If your programming language doesn't have comment lines, you'll have to use +% \ikeyname{escapechar} or \ikeyname{escapeinside}: +% \begin{verbatim} +% \lstset{escapebegin=\begin{greek},escapeend=\end{greek}} +% +% \begin{lstlisting}[escapeinside=`'] +% /* `Replace text by Greek comment.' */ +% for (int i=0; i<1; i++) { }; +% \end{lstlisting}\end{verbatim} +% Note that the delimiters |`| and |'| are essential here. The example doesn't +% work without them. There is a more clever way if the comment delimiters of +% the programming language are single characters like the braces in Pascal: +% \begin{verbatim} +% \lstset{escapebegin=\textbraceleft\begin{arab}, +% escapeend=\end{arab}\textbraceright} +% +% \begin{lstlisting}[escapeinside=\{\}] +% for i:=maxint to 0 do +% begin +% { Replace text by Arabic comment. } +% end; +% \end{lstlisting}\end{verbatim} +% Please note that the `interface' to $\Lambda$ is completely untested. +% Reports are welcome! +% +% +% \subsubsection*{How to get bold typewriter type keywords} +% Many people asked for bold typewriter fonts since they aren't included in +% the \LaTeX\ standard distribution. Here now one answer on how to use them +% in spite of that. +% \begin{advise} +% \item Please note that I personally don't regard the following as a good +% solution. Such a bold typewriter type is too heavy. It would be better +% to use a light version of \texttt{cmtt} as basic font and \texttt{cmtt} +% or a \emph{slightly} heavier type for keywords. +% +% \item Why don't you tell us how to use the better solution? +% \advisespace +% A light version of \texttt{cmtt} doesn't exist. If it's once available, +% you can do a similar job as described below. +% \end{advise} +% First of all, you'll need Metafont source files for bold typewriter, e.g.~ +% \texttt{cmbtt8.mf}, \texttt{cmbtt9.mf} and \texttt{cmbtt10.mf} from +% \href{ftp://ftp.dante.de/tex-archive/fonts/cm/mf-extra/bold} +% {CTAN/fonts/cm/mf-extra/bold}. +% Secondly you have to create \texttt{.tfm}-files, i.e.~run the Metafont +% program on these sources. This is possibly done automatically when you use +% the fonts in a document. Finally you must tell \LaTeX\ that you've installed +% bold typewriter fonts. Just use +% \begin{verbatim} +% \DeclareFontShape{OT1}{cmtt}{bx}{n} +% {<5><6><7><8>cmbtt8% +% <9>cmbtt9% +% <10><10.95>cmbtt10% +% <12><14.4><17.28><20.74><24.88>cmbtt10% +% }{}\end{verbatim} +% in the preamble of your document. If you use these fonts often, you might +% want to make a local copy of \texttt{ot1cmtt.fd} and replace the declaration +% there. But note that you're not allowed to distributed the modified file +% under its original name! +% +% +% \subsubsection*{How to get the developer's guide} +% In the \emph{source directory} of the listings package, i.e.~where +% \texttt{listings.dtx} is, create the file \texttt{ltxdoc.cfg} with the +% following contents. +% \begin{verbatim} +% \AtBeginDocument{\AlsoImplementation}\end{verbatim} +% Then run \texttt{listings.dtx} through \LaTeX\ twice, run Makeindex, +% and one last time \LaTeX\ on \texttt{listings.dtx}. This creates the whole +% documentation including User's guide, Reference guide, Developer's guide, +% and Implementation. +% +% +% \makeatletter +% \def\index@prologue{\section*{Index}\markboth{Index}{Index}} +% \makeatother +%^^A \StopEventually{\lstcheckreference\setcounter{IndexColumns}{2}\PrintIndex} +% \StopEventually{\setcounter{IndexColumns}{2}\PrintIndex} +% +% +% \part{Developer's guide} +% +% First I must apologize for this developer's guide since some parts are not +% explained as good as possible. But note that you are in a pretty good shape: +% this developer's guide exists! ^^A :-) +% You might want to peak into section \ref{dPackageExtensions} before reading +% section \ref{dBasicConcepts}. +% +% +% \section{Basic concepts}\label{dBasicConcepts} +% +% The functionality of the \packagename{listings} package appears to be +% divided into two parts: on the one hand commands which actually typeset +% listings and on the other via |\lstset| adjustable parameters. Both could +% be implemented in terms of \lst-aspects, which are simply collections of +% public keys and commands and internal hooks and definitions. The package +% defines a couple of aspects, in particular the kernel, the main engine. +% Other aspects drive this engine, and language and style definitions tell +% the aspects how to drive. The relations between car, driver and assistant +% driver are exactly reproduced---and I'll be your driving instructor. +% +% +% \subsection{Package loading}\label{dPackageLoading} +% +% Each option in |\usepackage[|\meta{options}|]{listings}| loads an aspect or +% \emph{prevents} the package from loading it if the aspect name is +% \emph{preceded by an exclamation mark}. This mechanism was designed to clear +% up the dependencies of different package parts and to debug the package. For +% this reason there is another option: +% \begin{syntax} +% \item[0.21,,option] \texttt{noaspects}\leavevmode +% +% deletes the list of aspects to load. Note that, for example, the +% option lists |0.21,!labels,noaspects| and |noaspects| are essentially +% the same: the kernel is loaded and no other aspect. +% \end{syntax} +% This is especially useful for aspect-testing since we can load exactly the +% required parts. Note, however, that an aspect is loaded later if a predefined +% programming language requests it. One can load aspects also by hand: +% \begin{syntax} +% \item[0.20] |\lstloadaspects|\marg{comma separated list of aspect names} +% +% loads the specified aspects if they are not already loaded. +% \end{syntax} +% Here now is a list of all aspects and related keys and commands---in the hope +% that this list is complete. +% \begin{description} +% \hyphenpenalty=10000\relax \rightskip=0pt plus \linewidth\relax +% \item[\aspectname{strings}]\leavevmode +% +% \lstprintaspectkeysandcmds{strings} +% +% \item[\aspectname{comments}]\leavevmode +% +% \lstprintaspectkeysandcmds{comments} +% +% \item[\aspectname{pod}]\leavevmode +% +% \lstprintaspectkeysandcmds{pod} +% +% \item[\aspectname{escape}]\leavevmode +% +% \lstprintaspectkeysandcmds{escape} +% +% \item[\aspectname{writefile}] requires 1 |\toks|, 1 |\write| +% +% |\lst@BeginWriteFile|, |\lst@BeginAlsoWriteFile|, |\lst@EndWriteFile| +% +% \item[\aspectname{style}]\leavevmode +% +% empty style, \lstprintaspectkeysandcmds{style} +% +% \item[\aspectname{language}]\leavevmode +% +% empty language, \lstprintaspectkeysandcmds{language} +% +% \item[\aspectname{keywords}]\leavevmode +% +% \lstprintaspectkeysandcmds{keywords} +% +% \item[\aspectname{emph}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{emph} +% +% \item[\aspectname{html}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{html} +% +% \item[\aspectname{tex}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{tex} +% +% \item[\aspectname{directives}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{directives} +% +% \item[\aspectname{index}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{index} +% +% \item[\aspectname{procnames}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{procnames} +% +% \item[\aspectname{keywordcomments}] +% requires \aspectname{keywords}, \aspectname{comments} +% +% \lstprintaspectkeysandcmds{keywordcomments} +% +% \item[\aspectname{labels}] requires 2 |\count| +% +% \lstprintaspectkeysandcmds{labels} +% +% \item[\aspectname{lineshape}] requires 2 |\dimen| +% +% \lstprintaspectkeysandcmds{lineshape} +% +% \item[\aspectname{frames}] requires \aspectname{lineshape} +% +% \lstprintaspectkeysandcmds{frames} +% +% \item[\aspectname{make}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{make} +% +% \item[\aspectname{doc}] requires \aspectname{writefile} and 1 |\box| +% +% \lstprintaspectkeysandcmds{doc} +% +% \item[\aspectname{0.21}] defines old keys in terms of the new ones. +% \item[\aspectname{fancyvrb}] requires 1 |\box| +% +% \lstprintaspectkeysandcmds{fancyvrb} +% +% \item[\aspectname{lgrind}]\leavevmode +% +% \lstprintaspectkeysandcmds{lgrind} +% +% \item[\aspectname{hyper}] requires \aspectname{keywords} +% +% \lstprintaspectkeysandcmds{hyper} +% \end{description} +% The kernel allocates 6 |\count|, 4 |\dimen| and 1 |\toks|. +% Moreover it defines the following keys, commands, and environments: +% \begin{itemize}\item[] +% \hyphenpenalty=10000\relax \rightskip=0pt plus \linewidth\relax +% \lstprintaspectkeysandcmds{kernel}, \keyname{fancyvrb} +% \end{itemize} +% +% +% \subsection{How to define \lst-aspects}\label{dHowToDefineLstAspects} +% +% There are at least three ways to add new functionality: (a) you write an +% aspect of general interest, send it to me, and I'll just paste it into the +% implementation; (b) you write a `local' aspect not of general interest; or +% (c) you have an idea for an aspect and make me writing it. (a) and (b) are +% good choices.^^A :-) +% +% An aspect definition starts with |\lst@BeginAspect| plus arguments and ends +% with the next |\lst@EndAspect|. In particular, aspect definitions can't be +% nested. +% \begin{syntax} +% \item[0.20] |\lst@BeginAspect|[\oarg{list of required aspects}]\marg{aspect name} +% \item[0.20] |\lst@EndAspect| +% \end{syntax} +% The optional list is a comma separated list of required aspect names. +% The complete aspect is not defined in each of the following cases: +% \begin{enumerate} +% \item \meta{aspect name} is empty. +% \item The aspect is already defined. +% \item A required aspect is neither defined nor loadable via +% |\lstloadaspects|. +% \end{enumerate} +% Consequently you can't define a part of an aspect and later on another part. +% But it is possible to define aspect $A_1$ and later aspect $A_2$ which +% requires $A_1$. +% \begin{advise} +% \item Put local add-ons into `\texttt{lstmisc0.sty}'---this file is searched +% first by default. If you want to make add-ons for one particular +% document just replace the surrounding `|\lst@BeginAspect|' and +% `|\lst@EndAspect|' by `|\makeatletter|' and `|\makeatother|' and use +% the definitions in the preamble of your document. However, you have to +% load required aspects on your own. +% \end{advise} +% You can put any \TeX\ material in between the two commands, but note that +% definitions must be |\global| if you need them later---\LaTeX's |\newcommand| +% makes local definitions and can't be preceded by |\global|. So use the +% following commands, |\gdef|, and commands described in later sections. +% \begin{syntax} +% \item[0.20] |\lst@UserCommand|\meta{macro}\meta{parameter text}\marg{replacement text} +% +% The macro is (mainly) equivalent to |\gdef|. The purpose is to +% distinguish user commands and internal global definitions. +% +% \item[0.19] |\lst@Key|\marg{key name}\marg{init value}[\oarg{default value}]\marg{definition} +% \item[0.19] |\lst@Key|\marg{key name}|\relax|[\oarg{default value}]\marg{definition} +% +% defines a key using the \packagename{keyval} package from David +% Carlisle. \meta{definition} is the replacement text of a macro with +% one parameter. The argument is either the value from `key=value' or +% \meta{default value} if no `=value' is given. The helper macros +% |\lstKV@...| below might simplify \meta{definition}. +% +% The key is not initialized if the second argument is |\relax|. +% Otherwise \meta{init value} is the initial value given to the key. +% Note that we locally switch to |\globalsdefs=1| to ensure that +% initialization is not effected by grouping. +% +% \item[0.19] |\lst@AddToHook|\marg{name of hook}\marg{\TeX\ material} +% +% adds \TeX\ material at predefined points. Section \ref{dHooks} lists +% all hooks and where they are defined respectively executed. +% |\lst@AddToHook{A}{\csa}| before |\lst@AddToHook{A}{\csb}| +% \emph{does not} guarantee that |\csa| is executed before |\csb|. +% +% \item[0.20] |\lst@AddToHookExe|\marg{name of hook}\marg{\TeX\ material} +% +% also executes \meta{\TeX\ material} for initialization. You might use +% local variables---local in the sense of \TeX\ and/or usual programming +% languages---but when the code is executed for initialization all +% assignments are global: we set |\globaldefs| locally to one. +% +% \item[0.20] |\lst@UseHook|\marg{name of hook} +% +% executes the hook. +% \end{syntax} +% \begin{advise} +% \item Let's look at two examples. The first extends the package by adding +% some hook-material. If you want status messages, you might write +% \begin{verbatim} +% \lst@AddToHook{Init}{\message{\MessageBreak Processing listing ...}} +% \lst@AddToHook{DeInit}{\message{complete.\MessageBreak}}\end{verbatim} +% The second example introduces two keys to let the user control the +% messages. The macro |\lst@AddTo| is described in section +% \ref{dGeneralPurposeMacros}. +% \begin{verbatim} +% \lst@BeginAspect{message} +% \lst@Key{message}{Annoying message.}{\gdef\lst@message{#1}} +% \lst@Key{moremessage}\relax{\lst@AddTo\lst@message{\MessageBreak#1}} +% \lst@AddToHook{Init}{\typeout{\MessageBreak\lst@message}} +% \lst@EndAspect\end{verbatim} +% However, there are certainly aspects which are more useful. +% \end{advise} +% The following macros can be used in the \meta{definition} argument of the +% |\lst@Key| command to evaluate the argument. The additional prefix |KV| +% refers to the \packagename{keyval} package. +% \begin{syntax} +% \item[0.19] |\lstKV@SetIf|\marg{value}\meta{if macro} +% +% \meta{if macro} becomes |\iftrue| if the first character of +% \meta{value} equals |t| or |T|. Otherwise it becomes |\iffalse|. +% Usually you will use |#1| as \meta{value}. +% +% \item[1.0] \cs{lstKV@SwitchCases}\marg{value}\\ +% |{|\meta{string 1}|&|\meta{execute 1}|\\|\\ +% | |\meta{string 2}|&|\meta{execute 2}|\\|\\ +% \hbox to 3em{\hfill\vdots}\\ +% | |\meta{string $n$}|&|\meta{execute $n$}|}|\marg{else} +% +% Either execute \meta{else} or the \meta{value} matching part. +% +% \item[0.20] |\lstKV@TwoArg|\marg{value}\marg{subdefinition} +% \item[0.20] |\lstKV@ThreeArg|\marg{value}\marg{subdefinition} +% \item[0.20] |\lstKV@FourArg|\marg{value}\marg{subdefinition} +% +% \meta{subdefinition} is the replacement text of a macro with two, +% three, and four parameters. We call this macro with the arguments given +% by \meta{value}. Empty arguments are added if necessary. +% +% \item[0.19] |\lstKV@OptArg|\oarg{default arg.}\marg{value}\marg{subdefinition} +% +% |[|\meta{default arg.}|]| is \emph{not} optional. \meta{subdefinition} +% is the replacement text of a macro with parameter text |[##1]##2|. +% Note that the macro parameter character |#| is doubled since used +% within another macro. \meta{subdefinition} accesses these arguments +% via |##1| and |##2|. +% +% \meta{value} is usually the argument |#1| passed by the +% \packagename{keyval} package. If \meta{value} has no optional argument, +% \meta{default arg.} is inserted to provide the arguments to +% \meta{subdefinition}. +% +% \item[0.21] |\lstKV@XOptArg|\oarg{default arg.}\marg{value}\meta{submacro} +% +% Same as |\lstKV@OptArg| but the third argument \meta{submacro} is +% already a definition and not replacement text. +% +% \item[0.20] |\lstKV@CSTwoArg|\marg{value}\marg{subdefinition} +% +% \meta{value} is a \texttt comma \texttt separated list of one or two +% arguments. These are given to the subdefinition which is the +% replacement text of a macro with two parameters. An empty second +% argument is added if necessary. +% \end{syntax} +% \begin{advise} +% \item One more example. The key `\keyname{sensitive}' belongs to the aspect +% \aspectname{keywords}. Therefore it is defined in between +% `|\lst@BeginAspect{keywords}|' and `|\lst@EndAspect|', which is not shown +% here. +% \begin{verbatim} +% \lst@Key{sensitive}\relax[t]{\lstKV@SetIf{#1}\lst@ifsensitive} +% \lst@AddToHookExe{SetLanguage}{\let\lst@ifsensitive\iftrue}\end{verbatim} +% The last line is equivalent to +% \begin{verbatim} +% \lst@AddToHook{SetLanguage}{\let\lst@ifsensitive\iftrue} +% \global\let\lst@ifsensitive\iftrue\end{verbatim} +% We initialize the variable globally since the user might request an +% aspect in a group. Afterwards the variable is used locally---there is +% no |\global| in \meta{\TeX\ material}. Note that we could define and +% init the key as follows: +% \begin{verbatim} +% \lst@Key{sensitive}t[t]{\lstKV@SetIf{#1}\lst@ifsensitive} +% \lst@AddToHook{SetLanguage}{\let\lst@ifsensitive\iftrue}\end{verbatim} +%\end{advise} +% +% +% \subsection{Internal modes}\label{dInternalModes} +% +% You probably know \TeX's conditional commands |\ifhmode|, |\ifvmode|, +% |\ifmmode|, and |\ifinner|. They tell you whether \TeX\ is in (restricted) +% horizontal or (internal) vertical or in (nondisplay) mathematical mode. For +% example, true |\ifhmode| and true |\ifinner| indicate restricted horizontal +% mode, which means that you are in a |\hbox|. The typical user doesn't care +% about such modes; \TeX/\LaTeX\ manages all this. But since you're reading the +% developer's guide, we discuss the analogue for the \packagename{listings} +% package now. It uses modes to distinguish comments from strings, `comment +% lines' from `single comments', and so on. +% +% The package is in `no mode' before reading the source code. In the phase of +% initialization it goes to `processing mode'. Afterwards the mode depends on +% the actual source code. For example, consider the line +% \begin{verbatim} +% "string" // comment\end{verbatim} +% and assume \texttt{language=C++}. Reading the string delimiter, the package +% enters `string mode' and processes the string. The matching closing delimiter +% leaves the mode, i.e.\ switches back to the general `processing mode'. Coming +% to the two slashes, the package detects a comment line; it therefore enters +% `comment line mode' and outputs the slashes. Usually this mode lasts to the +% end of line. +% +% But with \texttt{textcl=true} the \aspectname{escape} aspect immediately +% leaves `comment line mode', interrupts the current mode sequence, and enters +% `\TeX\ comment line mode'. At the end of line we reenter the previous mode +% sequence `no mode' $\to$ 'processing mode'. This escape to \LaTeX\ works +% since `no mode' implies that \TeX's characters and catcodes are present, +% whereas `processing mode' means that \packagename{listings}' characters and +% catcodes are active. +% +% \begin{table}[htbp] +% \caption{Internal modes}\label{dDefinedInternalModes} +% \def\lsttabspace{\hspace*{1em}\hfill} +% \begin{tabular}{@{}lp{0.56\linewidth}@{}} +% aspect\lsttabspace\meta{mode name} & Usage/We are processing \ldots\\ +% \noalign{\smallskip} +% kernel\lsttabspace |\lst@nomode| & +% If this mode is active, \TeX's `character table' is present; the other +% implication is not true. Any other mode \emph{may} imply that catcodes +% and\nobreak/\allowbreak or definitions of characters are changed. +% \\ +% \lsttabspace |\lst@Pmode| & +% is a general processing mode. If active we are processing a listing, +% but haven't entered a more special mode. +% \\ +% \lsttabspace |\lst@GPmode| & +% general purpose mode for language definitions. +% \\ +% \aspectname{pod}\lsttabspace |\lst@PODmode| & +% \ldots~a POD---Perl specific. +% \\ +% \aspectname{escape}\lsttabspace |\lst@TeXLmode| & +% \ldots~a comment line, but \TeX's character table is present---except +% the EOL character, which is needed to terminate this mode. +% \\ +% \lsttabspace |\lst@TeXmode| & +% indicates that \TeX's character table is present (except one user +% specified character, which is needed to terminate this mode). +% \\ +% \aspectname{directives}\lsttabspace |\lst@CDmode| & +% indicates that the current line began with a compiler directive. +% \\ +% \aspectname{keywordcomments}\lsttabspace |\lst@KCmode| & +% \ldots~a keyword comment. +% \\ +% \lsttabspace |\lst@KCSmode| & +% \ldots~a keyword comment which can be terminated by a semicolon only. +% \\ +% \aspectname{html}\lsttabspace |\lst@insidemode| & +% Active if we are between \texttt{<} and \texttt{>}. +% \\ +% \aspectname{make}\lsttabspace |\lst@makemode| & +% Used to indicate a keyword. +% \end{tabular} +% \end{table} +% Table \ref{dDefinedInternalModes} lists all static modes and which aspects +% they belong to. Most features use dynamically created mode numbers, for +% example all strings and comments. Each aspect may define its own mode(s) +% simply by allocating it/\allowbreak them inside the aspect definition. +% \begin{syntax} +% \item[0.19] |\lst@NewMode|\meta{mode \textup(control sequence\textup)} +% +% defines a new static mode, which is a nonnegative integer assigned to +% \meta{mode}. \meta{mode} should have the prefix \texttt{lst@} and +% suffix \texttt{mode}. +% +% \item[0.21] |\lst@UseDynamicMode|\marg{token\textup(s\textup)} +% +% inserts a dynamic mode number as argument to the token(s). +% +% This macro cannot be used to get a mode number when an aspect is +% loaded or defined. It can only be used every listing in the process +% of initialization, e.g.~to define comments when the character table +% is selected. +% +% \item[0.19,,changed] |\lst@EnterMode|\meta{mode}\marg{start tokens} +% +% opens a group level, enters the mode, uses \meta{style} as the current +% style, and executes \meta{start tokens}. Note that the style and start +% tokens are read as one single argument and that there must be braces +% around the style. +% +% Use |\lst@modetrue| in \meta{start tokens} to prohibit future mode +% changes---except leaving the mode, of course. You must test yourself +% whether you're allowed to enter, see below. +% +% \item[0.19] |\lst@LeaveMode| +% +% returns to the previous mode by closing a group level if and only if +% the current mode isn't |\lst@nomode| already. You must test yourself +% whether you're allowed to leave a mode, see below. +% +%\iffalse +% \item[0.19] |\lst@LeaveAllModes| +% +% returns to |\lst@nomode|. +% This is some kind of emergency macro, so don't use it! +%\fi +% +% \item[0.19] |\lst@InterruptModes| +% \item[0.19] |\lst@ReenterModes| +% +% The first command returns to |\lst@nomode|, but saves the current mode +% sequence on a special stack. Afterwards the second macro returns to the +% previous mode. In between these commands you may enter any mode you +% want. In particular you can interrupt modes, enter some modes, and say +% `interrupt modes' again. Then two re-enters will take you back in front +% of the first `interrupt modes'. +% +% Remember that |\lst@nomode| implies that \TeX's character table is +% active. +% \end{syntax} +% Some variables show the internal state of processing. You are allowed to read +% them, but \emph{direct write access is prohibited}. Note: |\lst@ifmode| is +% \emph{not} obsolete since there is no relation between the boolean and the +% current mode. It will happen that we enter a mode without setting +% |\lst@ifmode| true, and we'll set it true without assigning any mode! +% \begin{syntax} +% \item[0.18,,counter] |\lst@mode| +% +% keeps the current mode number. Use |\ifnum\lst@mode=|\meta{mode name} +% to test against a mode. Don't modify the counter directly! +% +% \item[0.18,,boolean] |\lst@ifmode| +% +% No mode change is allowed if this boolean is true---except leaving the +% current mode. Use |\lst@modetrue| to modify this variable, but do it +% only in \meta{start tokens}. +% +% \item[1.0,,boolean] |\lst@ifLmode| +% +% Indicates whether the current mode ends at end of line. +% \end{syntax} +% +% +% \subsection{Hooks}\label{dHooks} +% +% Several problems arise if you want to define an aspect. +% You should and/or must +% (a) find additional functionality (of general interest) and implement it, +% (b) create the user interface, and +% (c) interface with the \packagename{listings} package, i.e.~find correct +% hooks and insert appropriate \TeX\ material. +% (a) is out of the scope of this developer's guide. The commands |\lstKV@...| +% in section \ref{dHowToDefineLstAspects} might help you with (b). Here now we +% describe all hooks of the \packagename{listings} package. +% +% All hooks are executed inside an overall group. This group starts somewhere +% near the beginning and ends somewhere at the end of each listing. Don't make +% any other assumptions on grouping. So define variables globally if it's +% necessary---and be alert of side effects if you don't use your own groups. +% \begin{syntax} +% \item \hookname{AfterBeginComment} +% +% is executed after the package has entered comment mode. +% The starting delimiter is usually typeset when the hook is called. +% +% \item \hookname{BoxUnsafe} +% +% Contains all material to deactivate all commands and registers which +% are possibly unsafe inside |\hbox|. It is used whenever the package +% makes a box around a listing and for \packagename{fancyvrb} support. +% +% \item \hookname{DeInit} +% +% Called at the very end of a listing but before closing the box from +% \hookname{BoxUnsafe} or ending a float. +% +% \item \hookname{DetectKeywords} +% +% This \hookname{Output} subhook is executed if and only if mode changes +% are allowed, i.e.~if and only if the package doesn't process a comment, +% string, and so on---see section \ref{dInternalModes}. +% +% \item \hookname{DisplayStyle} +% +% deactivates/activates features for displaystyle listings. +% +% \item \hookname{EmptyStyle} +% +% Executed to select the `empty' style---except the user has redefined +% the style. +% +% \item \hookname{EndGroup} +% +% Executed whenever the package closes a group, e.g.~at end of comment or +% string. +% +% \item \hookname{EOL} +% +% Called at each end of \emph{input} line, right before +% \hookname{InitVarsEOL}. +% +% \item \hookname{EveryLine} +% +% Executed at the beginning of each \emph{output} line, i.e.~more than +% once for broken lines. This hook must not change the horizontal or +% vertical position. +% +% \item \hookname{EveryPar} +% +% Executed once for each input line when the output starts. This hook +% must not change the horizontal or vertical position. +% +%^^A \item \hookname{ExcludeDelims} +%^^A +%^^A Executed by the \keyname{excludedelims} key before the excluded +%^^A delimiters are determined. +%^^A +% \item \hookname{ExitVars} +% +% Executed right before \hookname{DeInit}. +% +% \item \hookname{FontAdjust} +% +% adjusts font specific internal values (currently |\lst@width| only). +% +% \item \hookname{Init} +% +% Executed once each listing to initialize things before the character +% table is changed. It is called after \hookname{PreInit} and before +% \hookname{InitVars}. +% +% \item \hookname{InitVars} +% +% Called to init variables each listing. +% +% \item \hookname{InitVarsBOL} +% +% initializes variables at the beginning of each input line. +% +% \item \hookname{InitVarsEOL} +% +% updates variables at the end of each input line. +% +% \item \hookname{ModeTrue} +% +% executed by the package when mode changes become illegal. +% Here keyword detection is switched off for comments and strings. +% +% \item \hookname{OnEmptyLine} +% +% executed \emph{before} the package outputs an empty line. +% +% \item \hookname{OnNewLine} +% +% executed \emph{before} the package starts one or more new lines, +% i.e.~before saying |\par\noindent\hbox{}| (roughly speaking). +% +% \item \hookname{Output} +% +% Called before an identifier is printed. +% If you want a special printing style, modify |\lst@thestyle|. +% +% \item \hookname{OutputBox} +% +% used inside each output box. Currently it is only used to make the +% package work together with Lambda---hopefully. +% +% \item \hookname{OutputOther} +% +% Called before other character strings are printed. +% If you want a special printing style, modify |\lst@thestyle|. +% +% \item \hookname{PostOutput} +% +% Called after printing an identifier or any other output unit. +% +% \item \hookname{PostTrackKeywords} +% +% is a very special \hookname{Init} subhook to insert keyword tests and +% define keywords on demand. +% This hook is called after \hookname{TrackKeywords}. +% +% \item \hookname{PreInit} +% +% Called right before \hookname{Init} hook. +% +% \item \hookname{PreSet} +% +% Each typesetting command/environment calls this hook to initialize +% internals before any user supplied key is set. +% +% \item \hookname{SelectCharTable} +% +% is executed after the package has selected the standard character +% table. Aspects adjust the character table here and define string and +% comment delimiters, and such. +% +% \item \hookname{SetFormat} +% +% Called before internal assignments for setting a format are made. +% This hook determines which parameters are reset every format selection. +% +% \item \hookname{SetStyle} +% +% Called before internal assignments for setting a style are made. +% This hook determines which parameters are reset every style selection. +% +% \item \hookname{SetLanguage} +% +% Called before internal assignments for setting a language are made. +% This hook determines which parameters are reset every language +% selection. +% +% \item \hookname{TextStyle} +% +% deactivates/activates features for textstyle listings. +% +% \item \hookname{TrackKeywords} +% +% is a very special \hookname{Init} subhook to insert keyword tests and +% define keywords on demand. +% This hook is called before \hookname{PostTrackKeywords}. +% \end{syntax} +% +% +% \subsection{Character tables}\label{dCharacterTables} +% +% Now you know how a car looks like, and you can get a driving license if you +% take some practice. But you will have difficulties if you want to make heavy +% alterations to the car. So let's take a closer look and come to the most +% difficult part: the engine. We'll have a look at the big picture and fill in +% the details step by step. For our purpose it's good to override \TeX's +% character table. First we define a standard character table which contains +% \begin{itemize} +% \item letters: characters identifiers are out of, +% \item digits: characters for identifiers or numerical constants, +% \item spaces: characters treated as blank spaces, +% \item tabulators: characters treated as tabulators, +% \item form feeds: characters treated as form feed characters, and +% \item others: all other characters. +% \end{itemize} +% This character table is altered depending on the current programming language. +% We may define string and comment delimiters or other special characters. +% Table \ref{rStdCharTable} on page \pageref{rStdCharTable} shows the standard +% character table. It can be modified with the keys \keyname{alsoletter}, +% \keyname{alsodigit}, and \keyname{alsoother}. +% +% How do these `classes' work together? Let's say that the current character +% string is `|tr|'. Then letter `|y|' simply appends the letter and we get +% `|try|'. The next nonletter (and nondigit) causes the output of the +% characters. Then we collect all coming nonletters until reaching a letter +% again. This causes the output of the nonletters, and so on. Internally each +% character becomes active in the sense of \TeX\ and is defined to do the right +% thing, e.g.~we say +% \begin{verbatim} +% \def A{\lst@ProcessLetter A}\end{verbatim} +% where the first `|A|' is active and the second has letter catcode 11. +% The macro |\lst@ProcessLetter| gets one token and treats it as a letter. +% The following macros exist, where the last three get no explicit argument. +% \begin{syntax} +% \item[0.18] |\lst@ProcessLetter| \meta{spec.\ token} +% \item[0.18] |\lst@ProcessDigit| \meta{spec.\ token} +% \item[0.18] |\lst@ProcessOther| \meta{spec.\ token} +% \item[0.18] |\lst@ProcessTabulator| +% \item[0.18] |\lst@ProcessSpace| +% \item[0.20] |\lst@ProcessFormFeed| +% \end{syntax} +% \meta{spec.\ token} is supposed to do two things. Usually it expands to +% a printable version of the character. But if |\lst@UM| is equivalent to +% |\@empty|, \meta{spec.\ token} must expand to a \emph{character token}. +% For example, the sharp usually expands to |\#|, which is defined via +% |\chardef| and is not a character token. But if |\lst@UM| is equivalent to +% |\@empty|, the sharp expands to the character `|#|' (catcode 12). Note: +% \emph{Changes to} |\lst@UM| \emph{must be locally.} However, there should +% be no need to do such basic things yourself. The \packagename{listings} +% package provides advanced macros which use that feature, +% e.g.~|\lst@InstallKeywords| in section \ref{dKeywordsAndWorkingIdentifiers}. +% +% \begin{syntax} +% \item[0.18] |\lst@Def|\marg{character code}\meta{parameter text}\marg{definition} +% \item[0.18] |\lst@Let|\marg{character code}\meta{token} +% +% defines the specified character respectively assigns \meta{token}. +% The catcode table if not affected. Be careful if your definition has +% parameters: it is not safe to read more than one character ahead. +% Moreover, the argument can be \emph{arbitrary}; somtimes it's the next +% source code character, sometimes it's some code of the +% \packagename{listings} package, e.g.~|\relax|, |\@empty|, |\else|, +% |\fi|, and so on. Therefore don't use \TeX's ord-operator |`| on such +% an argument, e.g.~don't write |\ifnum`#1=65| to test against `|A|'. +% +% |\lst@Def| and |\lst@Let| are relatively slow. The real definition of +% the standard character table differs from the following example, but it +% could begin with +% \begin{verbatim} +% \lst@Def{9}{\lst@ProcessTabulator} +% \lst@Def{32}{\lst@ProcessSpace} +% \lst@Def{48}{\lst@ProcessDigit 0} +% \lst@Def{65}{\lst@ProcessLetter A}\end{verbatim} +% +%\iffalse +% \item[0.20] |\lst@activecharstrue| +% \item[0.20] |\lst@activecharsfalse| +% +% control whether selecting the character table also makes all characters +% active (standard/extended). This is usually true and therefore default. +% Only the \packagename{fancyvrb} interface sets it locally false. +%\fi +% \end{syntax} +% That's enough for the moment. Section \ref{dUsefulInternalDefinitions} +% presents advanced definitions to manipulate the character table, in +% particular how to add new comment or string types. +% +% +% \subsection{On the output} +% +% The \packagename{listings} package uses some variables to keep the output +% data. Write access is not recommended. Let's start with the easy ones. +% \begin{syntax} +% \item[0.17,,data] |\lst@lastother| +% +% equals \meta{spec.\ token} version of the last processed +% nonidentifier-character. Since programming languages redefine the +% standard character table, we use the original \meta{spec.\ token}. +% For example, if a double quote was processed last, |\lst@lastother| +% is not equivalent to the macro which enters and leaves string mode. +% It's equivalent to |\lstum@"|, where |"| belongs to the control +% sequence. Remember that \meta{spec.\ token} expands either to a +% printable or to a token character. +% +% |\lst@lastother| is equivalent to |\@empty| if such a character is not +% available, e.g.~at the beginning of a line. Sometimes an indentifier +% has already been printed after processing the last `other' character, +% i.e.~the character is far, far away. In this case |\lst@lastother| +% equals |\relax|. +% +% \item[0.17] |\lst@outputspace| +% +% Use this predefined \meta{spec.\ token} (obviously for character code +% 32) to test against |\lst@lastother|. +% +% \item[0.20] |\lstum@backslash| +% +% Use this predefined \meta{spec.\ token} (for character code 92) to test +% against |\lst@lastother|. In the replacement text for |\lst@Def| one +% could write |\ifx| |\lst@lastother| |\lstum@backslash| \ldots\ to test +% whether the last character has been a backslash. +% +% \item[0.20] |\lst@SaveOutputDef|\marg{character code}\meta{macro} +% +% Stores the \meta{spec.\ token} corresponding to \meta{character code} +% in \meta{macro}. This is the only safe way to get a correct meaning to +% test against |\lst@lastother|, for example +% |\lst@SaveOutputDef{"5C}\lstum@backslash|. +% +% You'll get a ``runaway argument'' error if \meta{character code} is not +% between 33 and 126 (inclusive). +% \end{syntax} +% Now let's turn to the macros dealing a bit more with the output data and +% state. +% \begin{syntax} +% \item[1.0] |\lst@XPrintToken| +% +% outputs the current character string and resets it. This macro keeps +% track of all variables described here. +% +% \item[0.18,,token] |\lst@token| +% +% contains the current character string. Each `character' usually +% expands to its printable version, but it must expand to a character +% token if |\lst@UM| is equivalent to |\@empty|. +% +% \item[0.12,,counter] |\lst@length| +% +% is the length of the current character string. +% +% \item[0.12,,dimension] |\lst@width| +% +% is the width of a single character box. +% +% \item[0.20,,global dimension] |\lst@currlwidth| +% +% is the width of so far printed line. +% +% \item[0.18,,global counter] |\lst@column| +% \item[0.12,,global counter] |\lst@pos| (nonpositive) +% +% |\lst@column|$-$|\lst@pos| is the length of the so far printed line. +% We use two counters since this simplifies tabulator handling: +% |\lst@pos| is a nonpositive representative of `length of so far +% printed line' modulo \keyname{tabsize}. +% It's usually not the biggest nonpositive representative. +% +% \item[0.20] |\lst@CalcColumn| +% +% |\@tempcnta| gets |\lst@column| $-$ |\lst@pos| $+$ |\lst@length|. +% This is the current column number minus one, or the current column +% number zero based. +% +% \item[0.18,,global dimension] |\lst@lostspace| +% +% equals `lost' space: desired current line width minus real line width. +% Whenever this dimension is positive the flexible column format can use +% this space to fix the column alignment. +% \end{syntax} +% +% +% \section{Package extensions}\label{dPackageExtensions} +% +% +% \subsection{Keywords and working identifiers}\label{dKeywordsAndWorkingIdentifiers} +% +% The \aspectname{keywords} aspect defines two main macros. Their respective +% syntax is shown on the left. On the right you'll find examples how the +% package actually defines some keys. +% \begin{syntax} +% \item[0.21] +% \cs{lst@InstallFamily} +% +% \marg{prefix}\syntaxfill \texttt k\\ +% \marg{name}\syntaxfill |{keywords}|\\ +% \marg{style name}\syntaxfill |{keywordstyle}|\\ +% \marg{style init}\syntaxfill |\bfseries|\\ +% \marg{default style name}\syntaxfill |{keywordstyle}|\\ +% \marg{working procedure}\syntaxfill |{}|\\ +% \meta{\alternative{l,o}}\syntaxfill |l|\\ +% \meta{\alternative{d,o}}\syntaxfill |d| +% +% installs either a keyword or `working' class of identifiers according +% to whether \meta{working procedure} is empty. +% +% The three keys \meta{name}, \keyname{more}\meta{name} and +% \keyname{delete}\meta{name}, and if not empty \meta{style name} are +% defined. The first order member of the latter one is initialized with +% \meta{style init} if not equivalent to |\relax|. If the user leaves a +% class style undefined, \meta{default style name} is used instead. +% Thus, make sure that this style is always defined. In the example, +% the first order keywordstyle is set to |\bfseries| and is the default +% for all other classes. +% +% If \meta{working procedure} is not empty, this code is executed when +% reaching such an (user defined) identifier. \meta{working procedure} +% takes exactly one argument, namely the class number to which the +% actual identifier belongs to. If the code uses variables and requires +% values from previous calls, you must define these variables +% |\global|ly. It's not sure whether working procedures are executed +% inside a (separate) group or not. +% +% \texttt l indicates a language key, i.e.~the lists are reset every +% language selection. \texttt o stands for `other' key. +% The keyword respectively working test is either installed at the +% \hookname{DetectKeyword} or \hookname{Output} hook according to +% \meta{\alternative{d,o}}. +% +% \item[0.20] +% \cs{lst@InstallKeywords} +% +% \marg{prefix}\syntaxfill \texttt{cs}\\ +% \marg{name}\syntaxfill |{texcs}|\\ +% \marg{style name}\syntaxfill |{texcsstyle}|\\ +% \marg{style init}\syntaxfill |\relax|\\ +% \marg{default style name}\syntaxfill |{keywordstyle}|\\ +% \marg{working procedure}\syntaxfill see below\\ +% \meta{\alternative{l,o}}\syntaxfill |l|\\ +% \meta{\alternative{d,o}}\syntaxfill |d| +% +% Same parameters, same functionality with one execption. The macro +% installs exactly one keyword class and not a whole family. Therefore +% the argument to \meta{working procedure} is constant (currently empty). +% +% The working procedure of the example reads as follows.\vspace*{-.5\baselineskip} +% \begin{verbatim} +% {\ifx\lst@lastother\lstum@backslash +% \let\lst@thestyle\lst@texcsstyle +% \fi}\end{verbatim} +%\vspace*{-.5\baselineskip} +% What does this procedure do? First of all it is called only if a +% keyword from the user supplied list (or language definition) is found. +% The procedure now checks for a preceding backslash and sets the output +% style accordingly. +% +%\iffalse +% \item[0.20] |\lst@InstallTest|\marg{prefix}\syntaxbreak +% |\lst@|\meta{name}|@list||\lst@|\meta{name}~|\lst@g|\meta{name}|@list||\lst@g|\meta{name}\syntaxbreak +% |\lst@g|\meta{name}|@sty|~\meta{\alternative{w,s}}\meta{\alternative{d,o}} +% +% installs a `working identifier' test or keyword style depending on +% \meta{\alternative{w,s}}. |\lst@g|\meta{name}|@sty| contains the +% working procedure or style macro. Note that the behaviour of the tests +% depends on the \texttt{savemem} option. +% The keyword respectively working test is either installed at the +% \hookname{DetectKeyword} or \hookname{Output} hook according to +% \meta{\alternative{d,o}}. +% +%^^A Either each call of this macro or each different \meta{prefix} inserts +%^^A another test (depending on the \texttt{savemem} option). +% +% |\lst@|\meta{name} contains the current identifier list and +% |\lst@|\meta{name}|@list| a `|\lst@|\meta{$n_i$}|\lst@g|\meta{$n_i$}' +% sequence of currently used classes. If no other classes are used, +% this equals |\lst@|\meta{name}|\lst@g|\meta{name}. The global versions +% |\lst@g|\ldots\ are used to keep track of the keywords. +% (This description needs improvement.) +%\fi +% \end{syntax} +% +% +% \subsection{Delimiters} +% +% We describe two stages: adding a new delimiter type to an existing class of +% delimiters and writing a new class. Each class has its name; currently exist +% \texttt{Comment}, \texttt{String}, and \texttt{Delim}. As you know, the +% latter and the first both provide the type \texttt l, but there is no string +% which starts with the given delimiter and ends at end of line. So we'll add +% it now! +% +% First of all we extend the list of string types by +% \begin{verbatim} +% \lst@AddTo\lst@stringtypes{,l}\end{verbatim} +% Then we must provide the macro which takes the user supplied delimiter and +% makes appropriate definitions. The command name consists of the prefix +% |\lst@|, the delimiter name, |DM| for using dynamic modes, and |@| followed +% by the type. +% \begin{verbatim} +% \gdef\lst@StringDM@l#1#2\@empty#3#4#5{% +% \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}}\end{verbatim} +% You can put these three lines into a \texttt{.sty}-file or surround them by +% |\makeatletter| and |\makeatother| in the preamble of a document. +% And that's all! +%{\makeatletter +%\lst@AddTo\lst@stringtypes{,l} +%\gdef\lst@StringDM@l#1#2\@empty#3#4#5{^^A +% \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} +%} +% \begin{lstsample}{}{} +% \lstset{string=[l]//} +% \begin{lstlisting} +% // This is a string. +% This isn't a string. +% \end{lstlisting} +% \end{lstsample} +% You want more details, of course. Let's begin with the arguments. +% \begin{itemize} +% \item The first argument \emph{after} |\@empty| is used to start the +% delimiter. It's provided by the delimiter class. +% \item The second argument \emph{after} |\@empty| is used to end the +% delimiter. It's also provided by the delimiter class. We didn't +% need it in the example, see the explanation below. +% \item The third argument \emph{after} |\@empty| is +% \marg{style}\meta{start tokens}. +% This with a preceding |\def\lst@currstyle| is used as argument to +% |\lst@EnterMode|. The delimiter class also provides it. In the +% example we `extended' |#5| by |\lst@Lmodetrue| (line mode true). +% The mode automatically ends at end of line, so we didn't need the +% end-delimiter argument. +% \end{itemize} +% And now for the other arguments. In case of dynamic modes, the first argument +% is the mode number. Then follow the user supplied delimiter(s) whose number +% must match the remaining arguments up to |\@empty|. For non-dynamic modes, +% you must either allocate a static mode yourself or use a predefined mode +% number. The delimiters then start with the first argument. +% +% Eventually let's look at the replacement text of the macro. The sequence +% |\lst@CArg #2\relax| puts two required arguments after |\lst@DefDelimB|. +% The syntax of the latter macro is +% \begin{syntax} +% \item[1.0] \cs{lst@DefDelimB} +% +% |{|\meta{1st}\meta{2nd}\marg{rest}|}|\syntaxfill |{//{}}|\\ +% \meta{save 1st}\syntaxfill |\lst@c/0|\\ +% \marg{execute}\syntaxfill|{}|\\ +% \marg{delim~exe~modetrue}\syntaxfill|{}|\\ +% \marg{delim~exe~modefalse}\syntaxfill|{}|\\ +% \meta{start-delimiter macro}\syntaxfill|#3|\\ +% \meta{mode number}\syntaxfill |{#1}|\\ +% |{|\marg{style}\meta{start tokens}|}|\syntaxfill |{#5\lst@Lmodetrue}| +% +% defines \meta{1st}\meta{2nd}\meta{rest} as starting-delimiter. +% \meta{execute} is executed when the package comes to \meta{1st}. +% \meta{delim~exe~modetrue} and \meta{delim~exe~modefalse} are +% executed only if the whole delimiter \meta{1st}\meta{2nd}\meta{rest} +% is found. Exactly one of them is called depending on |\lst@ifmode|. +% +% By default the package enters the mode if the delimiter is found +% \emph{and} |\lst@ifmode| is false. Internally we make an appropriate +% definition of |\lst@bnext|, which can be gobbled by placing +% |\@gobblethree| at the very end of \meta{delim exe modefalse}. +% One can provide an own definition (and gobble the default). +% +% \meta{save 1st} must be an undefined macro and is used internally to +% store the previous meaning of \meta{1st}. The arguments \meta{2nd} +% and/or \meta{rest} are empty if the delimiter has strictly less than +% three characters. All characters of \meta{1st}\meta{2nd}\meta{rest} +% must already be active (if not empty). +% That's not a problem since the macro |\lst@CArgX| does this job. +% +% \item[1.0] \cs{lst@DefDelimE} +% +% |{|\meta{1st}\meta{2nd}\marg{rest}|}|\\ +% \meta{save 1st}\\ +% \marg{execute}\\ +% \marg{delim~exe~modetrue}\\ +% \marg{delim~exe~modefalse}\\ +% \meta{end-delimiter macro}\\ +% \meta{mode number} +% +% Ditto for ending-delimiter with slight differences: +% \meta{delim~exe~modetrue} and \meta{delim~exe~modefalse} are executed +% depending on whether |\lst@mode| equals \meta{mode}. +% +% The package ends the mode if the delimiter is found and |\lst@mode| +% equals \meta{mode}. Internally we make an appropriate definition of +% |\lst@enext| (not |\lst@bnext|), which can be gobbled by placing +% |\@gobblethree| at the very end of \meta{delim exe modetrue}. +% +% \item[1.0] \cs{lst@DefDelimBE} +% +% followed by the same eight arguments as for |\lst@DefDelimB| and \ldots\\ +% \meta{end-delimiter macro} +% +% This is a combination of |\lst@DefDelimB| and |\lst@DefDelimE| for the +% case of starting and ending delimiter being the same. +% \end{syntax} +% We finish the first stage by examining two easy examples. +% \texttt d-type strings are defined by +% \begin{verbatim} +% \gdef\lst@StringDM@d#1#2\@empty#3#4#5{% +% \lst@CArg #2\relax\lst@DefDelimBE{}{}{}#3{#1}{#5}#4}\end{verbatim} +% (and an entry in the list of string types). +% Not a big deal. Ditto \texttt d-type comments: +% \begin{verbatim} +% \gdef\lst@CommentDM@s#1#2#3\@empty#4#5#6{% +% \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% +% \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}}\end{verbatim} +% Here we just need to use both |\lst@DefDelimB| and |\lst@DefDelimE|. +% \goodbreak +% +% So let's get to the second stage. For illustration, here's the definition of +% the \texttt{Delim} class. The respective first argument to the service macro +% makes it delete all delimiters of the class, add the delimiter, or delete +% the particular delimiter only. +% \begin{verbatim} +% \lst@Key{delim}\relax{\lst@DelimKey\@empty{#1}} +% \lst@Key{moredelim}\relax{\lst@DelimKey\relax{#1}} +% \lst@Key{deletedelim}\relax{\lst@DelimKey\@nil{#1}}\end{verbatim} +% The service macro itself calls another macro with appropriate arguments. +% \begin{verbatim} +% \gdef\lst@DelimKey#1#2{% +% \lst@Delim{}#2\relax{Delim}\lst@delimtypes #1% +% {\lst@BeginDelim\lst@EndDelim} +% i\@empty{\lst@BeginIDelim\lst@EndIDelim}}\end{verbatim} +% We have to look at those arguments. Above you can see the actual arguments +% for the \texttt{Delim} class, below are the \texttt{Comment} class ones. +% Note that the user supplied value covers the second and third line of +% arguments. +% \begin{syntax} +% \item[0.21,,changed] +% \cs{lst@Delim} +% +% \meta{default style macro}\syntaxfill \cs{lst@commentstyle}\\ \relax +% [\texttt*[\texttt*]]\texttt[\meta{type}\texttt][\texttt[\meta{style}\texttt][\texttt[\meta{type option}\texttt]]]\\ +% \meta{delimiter\textup(s\textup)}\cs{relax}\syntaxfill|#2|\cs{relax}\\ +% \marg{delimiter name}\syntaxfill|{Comment}|\\ +% \meta{delimiter types macro}\syntaxfill\texttt{\cs{lst@commenttypes}}\\ +% \alternative{\cs{@empty},\cs{@nil},\cs{relax}}\syntaxfill|#1|\\ +% \marg{begin- and end-delim macro}\syntaxfill|{|\cs{lst@BeginComment}\cs{lst@EndComment}|}|\\ +% \meta{extra prefix}\syntaxfill |i|\\ +% \meta{extra conversion}\syntaxfill |\@empty|\\ +% \marg{begin- and end-delim macro}\syntaxfill|{|\cs{lst@BeginIComment}\cs{lst@EndIComment}|}| +% +% Most arguments should be clear. We'll discuss the last four. Both +% \marg{begin- and end-delim macro} must contain exactly two control +% sequences, which are given to |\lst@|\meta{name}[|DM|]|@|\meta{type} +% to begin and end a delimiter. These are the arguments |#3| and |#4| in our +% first example of |\lst@StringDM@l|. Depending on whether the user chosen +% type starts with \meta{extra prefix}, the first two or the last control +% sequences are used. +% +% By default the package takes the delimiter(s), makes the characters active, +% and places them after |\lst@|\meta{name}[|DM|]|@|\meta{type}. If the user +% type starts with \meta{extra prefix}, \meta{extra conversion} might change +% the definition of |\lst@next| to choose a different conversion. The default +% is equivalent to |\lst@XConvert| with |\lst@false|. +% +% Note that \meta{type} never starts with \meta{extra prefix} since it is +% discarded. The functionality must be fully implemented by choosing a +% different \marg{begin- and end-delim macro} pair. +% \end{syntax} +% You might need to know the syntaxes of the \meta{begin- and end-delim macro}s. +% They are called as follows. +% \begin{syntax} +% \item[0.21] |\lst@Begin|\meta{whatever} +% +% \marg{mode} +% |{|\marg{style}\meta{start tokens}|}| +% \meta{delimiter}|\@empty| +% +% \item[0.21] |\lst@End|\meta{whatever} +% +% \marg{mode} +% \meta{delimiter}|\@empty| +% \end{syntax} +% The existing macros are internally defined in terms of |\lst@DelimOpen| and +% |\lst@DelimClose|, see the implementation. +% +% +% \subsection{Getting the kernel run} +% +% If you want new pretty-printing environments, you should be happy with +% section \ref{rEnvironments}. New commands like |\lstinline| or +% |\lstinputlisting| are more difficult. Roughly speaking you must follow +% these steps. +% \begin{enumerate} +% \item Open a group to make all changes local. +% \item \meta{Do whatever you want.} +% \item Call |\lsthk@PreSet| in any case. +% \item Now you \emph{might } want to (but need not) use |\lstset| to set some +% new values. +% \item \meta{Do whatever you want.} +% \item Execute |\lst@Init\relax| to finish initialization. +% \item \meta{Do whatever you want.} +% \item Eventually comes the source code, which is processed by the kernel. +% You must ensure that the characters are either not already read or all +% active. Moreover \emph{you} must install a way to detect the end of the +% source code. If you've reached the end, you must \ldots +% \item \ldots\ call |\lst@DeInit| to shutdown the kernel safely. +% \item \meta{Do whatever you want.} +% \item Close the group from the beginning. +% \end{enumerate} +% For example, consider the |\lstinline| command in case of being not inside an +% argument. Then the steps are as follows. +% \begin{enumerate} +% \item |\leavevmode\bgroup| opens a group. +% \item |\def\lst@boxpos{b}| `baseline' aligns the listing. +% \item |\lsthk@PreSet| +% \item |\lstset{flexiblecolumns,#1}| (|#1| is the user provided +% key=value list) +% \item |\lsthk@TextStyle| deactivates all features not safe here. +% \item |\lst@Init\relax| +% \item |\lst@Def{`#1}{\lst@DeInit\egroup}| installs the `end inline' +% detection, where |#1| is the next character after |\lstinline|. +% Moreover chr(13) is redefined to end the fragment in the same way but +% also issues an error message. +% \item Now comes the source code and \ldots +% \item \ldots\ |\lst@DeInit| (from |\lst@Def| above) ends the code snippet +% correctly. +% \item Nothing. +% \item |\egroup| (also from |\lst@Def|) closes the group. +% \end{enumerate} +% The real definition is different since we allow source code inside arguments. +% Read also section \ref{iTheInputCommand} if you really want to write +% pretty-printing commands. +% +% +% \section{Useful internal definitions}\label{dUsefulInternalDefinitions} +% +% This section requires an update. +% +% +% \subsection{General purpose macros}\label{dGeneralPurposeMacros} +% +% \begin{syntax} +% \item[0.19] |\lst@AddTo|\meta{macro}\marg{\TeX~material} +% +% adds \meta{\TeX~material} globally to the contents of \meta{macro}. +% +% \item[0.20] |\lst@Extend|\meta{macro}\marg{\TeX~material} +% +% calls |\lst@AddTo| after the first token of \meta{\TeX~material} is +% |\expand|ed|after|. For example, |\lst@Extend \a \b| merges the +% contents of the two macros and stores it globally in |\a|. +% +% \item[0.19] |\lst@lAddTo|\meta{macro}\marg{\TeX~material} +% \item[0.20] |\lst@lExtend|\meta{macro}\marg{\TeX~material} +% +% are local versions of |\lst@AddTo| and |\lst@Extend|. +% +% \item[0.18] |\lst@DeleteKeysIn|\meta{macro}\meta{macro \textup(keys to remove\textup)} +% +% Both macros contain a comma separated list of keys (or keywords). All +% keys appearing in the second macro are removed (locally) from the first. +% +% \item[0.19] |\lst@ReplaceIn|\meta{macro}\meta{macro \textup(containing replacement list\textup)} +% \item[0.20] |\lst@ReplaceInArg|\meta{macro}\marg{replacement list} +% +% The replacement list has the form $a_1b_1$\ldots$a_nb_n$, where each +% $a_i$ and $b_i$ is a character sequence (enclosed in braces if +% necessary) and may contain macros, but the first token of $b_i$ must +% not be equivalent to |\@empty|. Each sequence $a_i$ inside the first +% macro is (locally) replaced by $b_i$. +% The suffix |Arg| refers to the \emph{braced} second argument instead of +% a (nonbraced) macro. It's a hint that we get the `real' argument and +% not a `pointer' to the argument. +% +% \item[0.20] |\lst@IfSubstring|\marg{character sequence}\meta{macro}\marg{then}\marg{else} +% +% \meta{then} is executed if \meta{character sequence} is a substring of +% the contents of \meta{macro}. Otherwise \meta{else} is called. +% +% \item[0.12] |\lst@IfOneOf|\meta{character sequence}|\relax|\meta{macro}\marg{then}\marg{else} +% +% |\relax| terminates the first parameter here since it is faster than +% enclosing it in braces. \meta{macro} contains a comma separated list +% of identifiers. If the character sequence is one of these indentifiers, +% \meta{then} is executed, and otherwise \meta{else}. +% +% \item[0.21] |\lst@Swap|\marg{tok1}\marg{tok2} +% +% changes places of the following two tokens or arguments \emph{without} +% inserting braces. For example, |\lst@Swap{abc}{def}| expands to +% |defabc|. +% +% \item[0.18] |\lst@IfNextChars|\meta{macro}\marg{then}\marg{else} +% \item[0.19] |\lst@IfNextCharsArg|\marg{character sequence}\marg{then}\marg{else} +% +% Both macros execute either \meta{then} or \meta{else} according to +% whether the given character sequence respectively the contents of the +% given macro is found (after the three arguments). Note an important +% difference between these macros and \LaTeX's |\@ifnextchar|: +% We remove the characters behind the arguments until it is possible to +% decide which part must be executed. However, we save these characters +% in the macro |\lst@eaten|, so they can be inserted using \meta{then} or +% \meta{else}. +% +% \item[0.19] |\lst@IfNextCharActive|\marg{then}\marg{else} +% +% executes \meta{then} if next character is active, and \meta{else} +% otherwise. +% +% \item[0.20] |\lst@DefActive|\meta{macro}\marg{character sequence} +% +% stores the character sequence in \meta{macro}, but all characters +% become active. The string \emph{must not} contain a begin group, end +% group or escape character (|{}\|); it may contain a left brace, right +% brace or backslash with other meaning (= catcode). This command +% would be quite surplus if \meta{character sequence} is not already read +% by \TeX\ since such catcodes can be changed easily. It is explicitly +% allowed that the charcaters have been read, e.g.~in +% |\def\test{\lst@DefActive\temp{ABC}}|! +% +% Note that this macro changes |\lccode|s 0--9 without restoring them. +% +% \item[0.20] |\lst@DefOther|\meta{macro}\marg{character sequence} +% +% stores \meta{character sequence} in \meta{macro}, but all characters +% have catcode 12. Moreover all spaces are removed and control sequences +% are converted to their name without preceding backslash. For example, +% |\{ Chip \}| leads to |{Chip}| where all catcodes are 12---internally +% the primitive |\meaning| is used. +% +% \iffalse +% \item[0.19] |\lst@MakeActive|\marg{character sequence} +% +% stores the character sequence in |\lst@arg| and has the same +% restrictions as |\lst@DefActive|. If fact, the latter definition uses +% this macro here. +% \fi +% \end{syntax} +% +% +% \subsection{Character tables manipulated}\label{dCharacterTablesManipulated} +% +% \begin{syntax} +% \item[0.20] |\lst@SaveDef|\marg{character code}\meta{macro} +% +% Saves the current definition of the specified character in +% \meta{macro}. You should always save a character definition before you +% redefine it! And use the saved version instead of writing directly +% |\lst@Process|\ldots---the character could already be redefined and +% thus not equivalent to its standard definition. +% +% \item[0.20] |\lst@DefSaveDef|\marg{character code}\meta{macro}\meta{parameter text}\marg{definition} +% \item[0.20] |\lst@LetSaveDef|\marg{character code}\meta{macro}\meta{token} +% +% combine |\lst@SaveDef| and |\lst@Def| respectively |\lst@Let|. +% \end{syntax} +% Of course I shouldn't forget to mention \emph{where} to alter the character +% table. Hook material at \hookname{SelectCharTable} makes permanent changes, +% i.e.~it effects all languages. The following two keys can be used in any +% language definition and effects the particular language only. +% \begin{syntax} +% \item[0.20] |SelectCharTable=|\meta{\TeX\ code} +% \item[0.20] |MoreSelectCharTable=|\meta{\TeX\ code} +% +% uses \meta{\TeX\ code} (additionally) to select the character table. +% The code is executed after the standard character table is selected, +% but possibly before other aspects make more changes. Since previous +% meanings are always saved and executed inside the new definition, this +% should be harmless. +% \end{syntax} +% Here come two rather useless examples. Each point (full stop) will cause a +% message `|.|' on the terminal and in the |.log| file if language |useless| is +% active: +% \begin{verbatim} +% \lstdefinelanguage{useless} +% {SelectCharTable=\lst@DefSaveDef{46}% save chr(46) ... +% \lsts@point % ... in \lsts@point and ... +% {\message{.}\lsts@point}% ... use new definition +% }\end{verbatim} +% If you want to count points, you could write +% \begin{verbatim} +% \newcount\lst@points % \global +% \lst@AddToHook{Init}{\global\lst@points\z@} +% \lst@AddToHook{DeInit}{\message{Number of points: \the\lst@points}} +% \lstdefinelanguage[2]{useless} +% {SelectCharTable=\lst@DefSaveDef{46}\lsts@point +% {\global\advance\lst@points\@ne \lsts@point} +% }\end{verbatim} +% |% \global| indicates that the allocated counter is used globally. We zero +% the counter at the beginning of each listing, display a message about the +% current value at the end of a listing, and each processed point advances the +% counter by one. +% +% \begin{syntax} +% \item[0.21] |\lst@CArg|\meta{active characters}|\relax|\meta{macro} +% +% The string of active characters is split into \meta{1st}, \meta{2nd}, +% and \marg{rest}. If one doesn't exist, an empty argument is used. Then +% \meta{macro} is called with |{|\meta{1st}\meta{2nd}\marg{rest}|}| plus +% a yet undefined control sequence \meta{save 1st}. This macro is +% intended to hold the current definition of \meta{1st}, so \meta{1st} +% can be redefined without loosing information. +% +% \item[0.19] |\lst@CArgX|\meta{characters}|\relax|\meta{macro} +% +% makes \meta{characters} active before calling |\lst@CArg|. +% +% \item[0.21] |\lst@CDef{|\meta{1st}\meta{2nd}\marg{rest}|}|\meta{save 1st}\marg{execute}\marg{pre}\marg{post} +% +% should be used in connection with |\lst@CArg| or |\lst@CArgX|, i.e.~as +% \meta{macro} there. \meta{1st}, \meta{2nd}, and \meta{rest} must be +% active characters and \meta{save 1st} must be an undefined control +% sequence. +% +% Whenever the package reaches the character \meta{1st} (in a listing), +% \meta{execute} is executed. If the package detects the whole string +% \meta{1st}\meta{2nd}\meta{rest}, we additionally execute \meta{pre}, +% then the string, and finally \meta{post}. +% +% \item[0.21] |\lst@CDefX|\meta{1st}\meta{2nd}\marg{rest}\meta{save 1st}\marg{execute}\marg{pre}\marg{post} +% +% Ditto except that we execute \meta{pre} and \meta{post} without the +% original string if we reach \meta{1st}\meta{2nd}\meta{rest}. +% This means that the string is replaced by \meta{pre}\meta{post} (with +% preceding \meta{execute}). +% \end{syntax} +% As the final example, here's the definition of |\lst@DefDelimB|. +% \begin{verbatim} +% \gdef\lst@DefDelimB#1#2#3#4#5#6#7#8{% +% \lst@CDef{#1}#2% +% {#3}% +% {\let\lst@bnext\lst@CArgEmpty +% \lst@ifmode #4\else +% #5% +% \def\lst@bnext{#6{#7}{#8}}% +% \fi +% \lst@bnext}% +% \@empty}\end{verbatim} +% You got it? +% +% +% \part{Implementation} +% +% +% \CheckSum{10861} +%^^A +%^^A Don't index TeX-primitives. +%^^A +% \DoNotIndex{\advance,\afterassignment,\aftergroup,\batchmode,\begingroup} +% \DoNotIndex{\box,\catcode,\char,\chardef,\closeout,\copy,\count,\csname,\def} +% \DoNotIndex{\dimen,\discretionary,\divide,\dp,\edef,\else,\end,\endcsname} +% \DoNotIndex{\endgroup,\endinput,\endlinechar,\escapechar,\everypar} +% \DoNotIndex{\expandafter,\fi,\gdef,\global,\globaldefs,\hbadness,\hbox} +% \DoNotIndex{\hrulefill,\hss,\ht} +% \DoNotIndex{\if,\ifdim,\iffalse,\ifhmode,\ifinner,\ifnum,\ifodd,\iftrue} +% \DoNotIndex{\ifvoid,\ifx,\ignorespaces,\immediate,\input,\jobname,\kern} +% \DoNotIndex{\lccode,\leftskip,\let,\long,\lower,\lowercase,\meaning,\message} +% \DoNotIndex{\multiply,\muskip,\noexpand,\noindent,\openout,\par,\parfillskip} +% \DoNotIndex{\parshape,\parskip,\raise,\read,\relax,\rightskip,\setbox,\skip} +% \DoNotIndex{\string,\the,\toks,\uppercase,\vbox,\vcenter,\vrule,\vtop,\wd} +% \DoNotIndex{\write,\xdef} +% +%^^A +%^^A Don't index LaTeX's private definitions. +%^^A +% \DoNotIndex{\@@end,\@@par,\@M,\@arabic,\@circlefnt,\@currentlabel} +% \DoNotIndex{\@currenvir,\@depth,\@doendpe,\@dottedtocline,\@eha,\@ehc} +% \DoNotIndex{\@empty,\@firstofone,\@firstoftwo,\@float,\@for,\@getcirc} +% \DoNotIndex{\@gobble,\@gobbletwo,\@halfwidth,\@height,\@ifnextchar} +% \DoNotIndex{\@ifundefined,\@ignoretrue,\@makecaption,\@makeother,\@namedef} +% \DoNotIndex{\@ne,\@noligs,\@notprerr,\@onlypreamble,\@secondoftwo,\@spaces} +% \DoNotIndex{\@starttoc,\@totalleftmargin,\@undefined,\@whilenum} +% \DoNotIndex{\@wholewidth,\@width} +% \DoNotIndex{\c@chapter,\c@figure,\c@page,\end@float,\f@family,\filename@area} +% \DoNotIndex{\filename@base,\filename@ext,\filename@parse,\if@twoside} +% \DoNotIndex{\l@ngrel@x,\m@ne,\new@command,\nfss@catcodes,\tw@,\thr@@} +% \DoNotIndex{\z@,\zap@space} +% +%^^A +%^^A Don't index LaTeX's package definitions. +%^^A +% \DoNotIndex{\AtEndOfPackage} +% \DoNotIndex{\CurrentOption,\DeclareOption,\IfFileExists,\InputIfFileExists} +% \DoNotIndex{\MessageBreak,\NeedsTeXFormat,\PackageError,\PackageWarning} +% \DoNotIndex{\ProcessOptions,\ProvidesFile,\ProvidesPackage,\RequirePackage} +% +%^^A +%^^A Don't index LaTeX's public definitions. +%^^A +% \DoNotIndex{\abovecaptionskip,\active,\addcontentsline,\addtocounter,\begin} +% \DoNotIndex{\belowcaptionskip,\bfseries,\bgroup,\bigbreak,\chapter} +% \DoNotIndex{\contentsname,\do,\egroup,\footnotesize,\index,\itshape} +% \DoNotIndex{\linewidth,\llap,\makeatletter,\newbox,\newcommand,\newcount} +% \DoNotIndex{\newcounter,\newdimen,\newtoks,\newwrite,\nointerlineskip} +% \DoNotIndex{\normalbaselines,\normalfont,\numberline,\pretolerance,\protect} +% \DoNotIndex{\qquad,\refstepcounter,\removelastskip,\renewcommand,\rlap} +% \DoNotIndex{\small,\smallbreak,\smallskipamount,\smash,\space,\strut} +% \DoNotIndex{\strutbox,\tableofcontents,\textasciicircum,\textasciitilde} +% \DoNotIndex{\textasteriskcentered,\textbackslash,\textbar,\textbraceleft} +% \DoNotIndex{\textbraceright,\textdollar,\textendash,\textgreater,\textless} +% \DoNotIndex{\textunderscore,\textvisiblespace,\thechapter,\ttdefault} +% \DoNotIndex{\ttfamily,\typeout,\value,\vphantom} +% +%^^A +%^^A Don't index definitions from other packages. +%^^A +% \DoNotIndex{\MakePercentComment,\MakePercentIgnore} +% +%^^A +%^^A Don't index 0.19 definitions. +%^^A +% \DoNotIndex{\listlistingsname,\listoflistings,\lstbox,\lstbox@} +% \DoNotIndex{\lstlanguage@} +% +%^^A +%^^A Don't index 0.20 subdefinitions. +%^^A +% \DoNotIndex{\lst@ATH@,\lst@BOLGobble@,\lst@BOLGobble@@,\lst@CArg@,\lst@CArg@@} +% \DoNotIndex{\lst@CBC@,\lst@CBC@@,\lst@CCECUse@,\lst@CCPutMacro@,\lst@DefLang@} +% \DoNotIndex{\lst@DefLang@@,\lst@DefOther@,\lst@DeleteKeysIn@,\lst@Escape@} +% \DoNotIndex{\lstframe@,\lst@frameH@,\lst@frameL@,\lst@frameR@} +% \DoNotIndex{\lst@FillFixed@,\lst@FindAlias@,\lst@FVConvert@} +% \DoNotIndex{\lst@IfNextChars@,\lst@IfNextChars@@,\lst@InsideConvert@} +% \DoNotIndex{\lst@InstallKeywords@,\lst@Key@,\lst@KeywordTestI@} +% \DoNotIndex{\lst@MakeActive@,\lst@MakeMoreKeywords@} +% \DoNotIndex{\lst@RC@,\lst@RC@@,\lst@ReplaceIn@,\lst@ReplaceInput@} +% \DoNotIndex{\lst@ReportAllocs@,\lst@SKS@,\lst@SKS@@,\lst@UBC@} +% \DoNotIndex{\lst@WorkingTestI@,\lstalias@,\lstalias@@,\lstalso@} +% \DoNotIndex{\lstdefinestyle@,\lstenv@BOLGobble@@} +% \DoNotIndex{\lstenv@ProcessJ@,\lstinline@,\lstKV@OptArg@,\lstKV@SetIf@} +% \DoNotIndex{\lstlang@,\lstnewenvironment@,\lst@outputpos,\lstset@} +% +% +% \section{Overture} +% +% \paragraph{Registers} +% For each aspect, the required numbers of registers are listed in section +% \lstref{dPackageLoading}. Furthermore, the \packagename{keyval} package +% allocates one token register. The macros, boxes and counters +% |\@temp|\ldots|a|/|b|, the dimensions |\@tempdim|\ldots, and the macro +% |\@gtempa| are also used, see the index. +% +% \paragraph{Naming conventions} +% Let's begin with definitions for the user. All these public macros have +% lower case letters and contain |lst|. Private macros and variables use the +% following prefixes (not up-to-date?): +% \begin{itemize} +% \item |\lst@| for a general macro or variable, +% \item |\lstenv@| if it is defined for the listing environment, +% \item |\lsts@| for |s|aved character meanings, +% \item |\lsthk@|\meta{name of hook} holds hook material, +% \item |\lst|\meta{prefix}|@| for various kinds of keywords and working +% identifiers. +% \item |\lstlang@|\meta{language}|@|\meta{dialect} contains a language and +% \item |\lststy@|\meta{the style} contains style definition, +% \item |\lstpatch@|\meta{aspect} to patch an aspect, +% +% \item |\lsta@|\meta{language}|$|\meta{dialect} contains alias, +% \item |\lsta@|\meta{language} contains alias for all dialects of a language, +% \item |\lstdd@|\meta{language} contains default dialect of a language +% (if present). +% \end{itemize} +% To distinguish procedure-like macros from data-macros, the name of procedure +% macros use upper case letters with each beginning word, e.g.~|\lst@AddTo|. +% A macro with suffix |@| is the main working-procedure for another definition, +% for example |\lstinputlisting@| does the main work for |\lstinputlisting|. +% +% \paragraph{Preamble} +% All files generated from this \texttt{listings.dtx} will get a header. +% \begin{macrocode} +%% Please read the software license in listings.dtx or listings.dvi. +%% +%% (w)(c) 1996 -- 2002 Carsten Heinz and/or any other author +%% listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% Permission is granted to modify the listings package as well as +%% lstdrvrs.dtx. You are not allowed to distribute a modified version +%% of the package or lstdrvrs.dtx unless you change the file names and +%% provide the original files. In any case it is better to contact the +%% address below; other users will welcome removed bugs, new features, +%% and additional programming languages. +%% +%% The listings package is free software. +%% +%% However, if you distribute the package as part of a commercial +%% product or if you use the package to prepare a commercial document +%% (books, journals, and so on), I'd like to encourage you to make a +%% donation to the LaTeX3 fund. The size of this `license fee' should +%% depend on the value of the package for your product. For more +%% information about LaTeX see http://www.latex-project.org +%% +%% No matter whether you use the package for a commercial or +%% non-commercial document, please send me a copy of the document (.dvi, +%% .ps, .pdf, hardcopy, etc.) to support further development---it is +%% easier to introduce new features or simplify things if I see how the +%% package is used by other people. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +% \end{macrocode} +% +% \paragraph{Identification} +% All files will have same date and version. +% \begin{macrocode} +\def\filedate{2002/04/01} +\def\fileversion{1.0} +% \end{macrocode} +% What we need and who we are. +% \begin{macrocode} +%<*kernel> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{listings} + [\filedate\space\fileversion\space(Carsten Heinz)] +% \end{macrocode} +% \begin{macro}{\lst@CheckVersion} +% can be used by the various driver files to guarantee the correct version. +% \begin{macrocode} +\def\lst@CheckVersion#1{\edef\reserved@a{#1}% + \ifx\lst@version\reserved@a \expandafter\@gobble + \else \expandafter\@firstofone \fi} +% \end{macrocode} +% \begin{macrocode} +\let\lst@version\fileversion +% +% \end{macrocode} +% \end{macro} +% For example by the miscellaneous file +% \begin{macrocode} +%<*misc> +\ProvidesFile{lstmisc.sty} + [\filedate\space\fileversion\space(Carsten Heinz)] +\lst@CheckVersion\fileversion + {\typeout{^^J% + ***^^J% + *** This file requires `listings.sty' version \fileversion.^^J% + *** You have a serious problem, so I'm exiting ...^^J% + ***^^J}% + \batchmode \@@end} +% +% \end{macrocode} +% or by the dummy patch. +% \begin{macrocode} +%<*patch> +\ProvidesFile{lstpatch.sty} + [\filedate\space\fileversion\space(Carsten Heinz)] +\lst@CheckVersion\lst@version{} +% +% \end{macrocode} +% \begin{macrocode} +%<*doc> +\ProvidesPackage{lstdoc} + [\filedate\space\fileversion\space(Carsten Heinz)] +% +% \end{macrocode} +% +% \paragraph{Category codes} +% We define two macros to ensure correct catcodes when we input other files of +% the \packagename{listings} package. +% +% \begin{macro}{\lst@InputCatcodes} +% |@| and |"| become letters. Tabulators and EOLs are ignored; this avoids +% unwanted spaces---in the case I've forgotten a comment character. +% \begin{macrocode} +%<*kernel> +\def\lst@InputCatcodes{% + \makeatletter \catcode`\"12% + \catcode`\^^@\active + \catcode`\^^I9% + \catcode`\^^L9% + \catcode`\^^M9% + \catcode`\%14% + \catcode`\~\active} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@RestoreCatcodes} +% To load the kernel, we will change some catcodes and lccodes. We restore them +% at the end of package loading. \lsthelper{Dr.~Jobst~Hoffmann}{2000/11/17} +% {incompatibility with typehtml package} reported an incompatibility with the +% \packagename{typehtml} package, which is resolved by |\lccode`\/`\/| below. +% \begin{macrocode} +\def\lst@RestoreCatcodes#1{% + \ifx\relax#1\else + \noexpand\catcode`\noexpand#1\the\catcode`#1\relax + \expandafter\lst@RestoreCatcodes + \fi} +\edef\lst@RestoreCatcodes{% + \noexpand\lccode`\noexpand\/`\noexpand\/% + \lst@RestoreCatcodes\"\^^I\^^M\~\^^@\relax} +% \end{macrocode} +% Now we are ready for +% \begin{macrocode} +\lst@InputCatcodes +\AtEndOfPackage{\lst@RestoreCatcodes} +% +% \end{macrocode} +% \end{macro} +% +% \paragraph{Statistics} +% \begin{macro}{\lst@GetAllocs} +% \begin{macro}{\lst@ReportAllocs} +% are used to show the allocated registers. +% \begin{macrocode} +%<*info> +\def\lst@GetAllocs{% + \edef\lst@allocs{% + 0\noexpand\count\the\count10,1\noexpand\dimen\the\count11,% + 2\noexpand\skip\the\count12,3\noexpand\muskip\the\count13,% + 4\noexpand\box\the\count14,5\noexpand\toks\the\count15,% + 6\noexpand\read\the\count16,7\noexpand\write\the\count17}} +\def\lst@ReportAllocs{% + \message{^^JAllocs:}\def\lst@temp{none}% + \expandafter\lst@ReportAllocs@\lst@allocs,\z@\relax\z@,} +\def\lst@ReportAllocs@#1#2#3,{% + \ifx#2\relax \message{\lst@temp^^J}\else + \@tempcnta\count1#1\relax \advance\@tempcnta -#3\relax + \ifnum\@tempcnta=\z@\else + \let\lst@temp\@empty + \message{\the\@tempcnta \string#2,}% + \fi + \expandafter\lst@ReportAllocs@ + \fi} +\lst@GetAllocs +% \end{macrocode} +% \end{macro}\end{macro} +% \begingroup +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% \paragraph{Miscellaneous} +% \begin{macro}{\@lst} +% Just a definition to save memory space. +% \begin{macrocode} +%<*kernel> +\def\@lst{lst} +% +% \end{macrocode} +% \end{macro} +% +% +% \section{General problems} +% +% All definitions in this section belong to the kernel. +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% +% +%^^A \subsection{Quick `if parameter empty'} +%^^A +%^^A There are many situations where you have to look whether a macro parameter is empty. +%^^A We have at least two possibilities to test |#1|, for example: +%^^A \begin{center} +%^^A \begin{minipage}{0.35\linewidth} +%^^A \begin{verbatim} +%^^A\def\test{#1}% +%^^A\ifx \test\empty +%^^A % #1 is empty +%^^A\else +%^^A % #1 is not empty +%^^A\fi\end{verbatim} +%^^A \end{minipage} +%^^A \hskip2em\vrule\hskip2em +%^^A \begin{minipage}{0.35\linewidth} +%^^A \begin{verbatim} +%^^A\ifx \empty#1\empty +%^^A % #1 is empty +%^^A\else +%^^A % #1 is not empty +%^^A\fi\end{verbatim} +%^^A \end{minipage} +%^^A \end{center} +%^^A where |\empty| is defined by |\def\empty{}|, of course. +%^^A The left variant should be clear and works in any case. +%^^A The right-hand side works correct if and only if the first token of |#1| is +%^^A not equivalent to |\empty|. +%^^A This granted, the |\ifx| is true if and only if |#1| is empty (since |\empty| +%^^A left from |#1| is (not) compared with |\empty| on the right). +%^^A The two |\empty|s might be replaced by any other macro, which is not +%^^A equivalent to the first token of the argument. +%^^A But the definition of that macro shouldn't be too complex since this would +%^^A slow down the |\ifx|. +%^^A The right example needs about $45\%$ of the left's time. +%^^A Note that this \TeX{}nique lost its importance from version 0.18 on and that +%^^A other packages use |!| or |\relax| instead of |\empty|, for example. +%^^A +%^^A This \TeX nique is described in ``The \TeX book'' on page 376. +% +% +% \subsection{Substring tests}\label{iSubstringTests} +% +% \lstset{language=TeX,gobble=4,xleftmargin=20pt,columns=[l]fullflexible,mathescape,keywordstyle=\ttfamily,texcsstyle=\bfseries} +% \let\texverb\lstinline +% \lstnewenvironment{texcode}[1][]{\lstset{#1}}{} +% \lstset{keywords={def,key}} +% +% It's easy to decide whether a given character sequence is a substring of +% another string. For example, for the substring \texverb|def| we could say +% \begin{texcode} +% \def \lst@temp#1def#2\relax{% +% \ifx \@empty#2\@empty +% % "def" is not a substring +% \else +% % "def" is a substring +% \fi} +% +% \lst@temp $\meta{another\ string}$def\relax +% \end{texcode} +% When \TeX\ passes the arguments |#1| and |#2|, the second is empty if +% and only if \texverb|def| is not a substring. Without the additional +% \texverb|def\relax|, one would get a ``runaway argument'' error if +% \meta{another string} doesn't contain \texverb|def|. +% +% We use substring tests mainly in the special case of an identifier and a +% comma separated list of keys or keywords: +% \begin{texcode}[keywords=key] +% \def \lst@temp#1,key,#2\relax{% +% \ifx \@empty#2\@empty +% % `key' is not a keyword +% \else +% % `key' is a keyword +% \fi} +% +% \lst@temp,$\meta{list\ of\ keywords}$,key,\relax +% \end{texcode} +% This works very well and is quite fast. But we can reduce run time in the +% case that \texttt{key} is a keyword. Then |#2| takes the rest of the string, +% namely all keywords after \texttt{key}. +% Since \TeX\ inserts |#2| between the \texverb|\@empty|s, it must drop all of +% |#2| except the first character---which is compared with \texverb|\@empty|. +% We can redirect this rest to a third parameter: +% \begin{texcode}[keywords=key] +% \def \lst@temp#1,key,#2#3\relax{% +% \ifx \@empty#2% +% % "key" is not a keyword +% \else +% % "key" is a keyword +% \fi} +% +% \lst@temp,$\meta{list\ of\ keywords}$,key,\@empty\relax +% \end{texcode} +% That's a bit faster and an improvement for version 0.20. +% +% \begin{macro}{\lst@IfSubstring} +% The implementation should be clear from the discussion above. +% \begin{macrocode} +\def\lst@IfSubstring#1#2{% + \def\lst@temp##1#1##2##3\relax{% + \ifx \@empty##2\expandafter\@secondoftwo + \else \expandafter\@firstoftwo \fi}% + \expandafter\lst@temp#2#1\@empty\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@IfOneOf} +% Ditto. +% \begin{macrocode} +\def\lst@IfOneOf#1\relax#2{% + \def\lst@temp##1,#1,##2##3\relax{% + \ifx \@empty##2\expandafter\@secondoftwo + \else \expandafter\@firstoftwo \fi}% + \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax} +% \end{macrocode} +% \end{macro} +% \begin{REMOVED} +% One day, if there is need for a case insensitive key(word) test again, we +% can use two |\uppercase|s to normalize the first parameter: +% \begin{verbatim} +%\def\lst@IfOneOfInsensitive#1\relax#2{% +% \uppercase{\def\lst@temp##1,#1},##2##3\relax{% +% \ifx \@empty##2\expandafter\@secondoftwo +% \else \expandafter\@firstoftwo \fi}% +% \uppercase{% +% \expandafter\lst@temp\expandafter,#2,#1},\@empty\relax}\end{verbatim} +% Here we assume that macro |#2| already contains capital characters only, see +% the definition of |\lst@MakeMacroUppercase| at the very end of section +% \ref{iMakingTests}. If we \emph{must not} assume that, we could simply +% insert an |\expandafter| between the second |\uppercase| and the following +% brace. But this slows down the tests! +% \end{REMOVED} +% +% \begin{macro}{\lst@DeleteKeysIn} +% The submacro does the main work; we only need to expand the second +% macro---the list of keys to remove---and append the terminator |\relax|. +% \begin{macrocode} +\def\lst@DeleteKeysIn#1#2{% + \expandafter\lst@DeleteKeysIn@\expandafter#1#2,\relax,} +% \end{macrocode} +% `Replacing' the very last |\lst@DeleteKeysIn@| by |\lst@RemoveCommas| +% terminates the loop here. Note: The |\@empty| after |#2| ensures that this +% macro also works if |#2| is empty. +% \begin{macrocode} +\def\lst@DeleteKeysIn@#1#2,{% + \ifx\relax#2\@empty + \expandafter\@firstoftwo\expandafter\lst@RemoveCommas + \else + \ifx\@empty#2\@empty\else +% \end{macrocode} +% If we haven't reached the end of the list and if the key is not empty, we +% define a temporary macro which removes all appearances. +% \begin{macrocode} + \def\lst@temp##1,#2,##2{% + ##1% + \ifx\@empty##2\@empty\else + \expandafter\lst@temp\expandafter,% + \fi ##2}% + \edef#1{\expandafter\lst@temp\expandafter,#1,#2,\@empty}% + \fi + \fi + \lst@DeleteKeysIn@#1} +% \end{macrocode} +% \end{macro} +% \begin{OLDDEF} +% The following modification needs about $50\%$ more run time. +% It doesn't use |\edef| and thus also works with |\{| inside |#1|. +% However, we don't need that at the moment. +% \begin{verbatim} +% \def\lst@temp##1,#2,##2{% +% \ifx\@empty##2% +% \lst@lAddTo#1{##1}% +% \else +% \lst@lAddTo#1{,##1}% +% \expandafter\lst@temp\expandafter,% +% \fi ##2}% +% \let\@tempa#1\let#1\@empty +% \expandafter\lst@temp\expandafter,\@tempa,#2,\@empty\end{verbatim} +% \end{OLDDEF} +% +% \begin{macro}{\lst@RemoveCommas} +% The macro drops commas at the beginning and assigns the new value to |#1|. +% \begin{macrocode} +\def\lst@RemoveCommas#1{\edef#1{\expandafter\lst@RC@#1\@empty}} +\def\lst@RC@#1{\ifx,#1\expandafter\lst@RC@ \else #1\fi} +% \end{macrocode} +% \end{macro} +% \begin{OLDDEF} +% The following version works with |\{| inside the macro |#1|. +% \begin{verbatim} +%\def\lst@RemoveCommas#1{\expandafter\lst@RC@#1\@empty #1} +%\def\lst@RC@#1{% +% \ifx,#1\expandafter\lst@RC@ +% \else\expandafter\lst@RC@@\expandafter#1\fi} +%\def\lst@RC@@#1\@empty#2{\def#2{#1}}\end{verbatim} +% \end{OLDDEF} +% +% \begin{macro}{\lst@ReplaceIn} +% \begin{macro}{\lst@ReplaceInArg} +% These macros are similar to |\lst@DeleteKeysIn|, except that \ldots +% \begin{macrocode} +\def\lst@ReplaceIn#1#2{% + \expandafter\lst@ReplaceIn@\expandafter#1#2\@empty\@empty} +\def\lst@ReplaceInArg#1#2{\lst@ReplaceIn@#1#2\@empty\@empty} +% \end{macrocode} +% \ldots\space we replace |#2| by |#3| instead of |,#2,| by a single comma +% (which removed the key |#2| above). +% \begin{macrocode} +\def\lst@ReplaceIn@#1#2#3{% + \ifx\@empty#3\relax\else + \def\lst@temp##1#2##2{% + \ifx\@empty##2% + \lst@lAddTo#1{##1}% + \else + \lst@lAddTo#1{##1#3}\expandafter\lst@temp + \fi ##2}% + \let\@tempa#1\let#1\@empty + \expandafter\lst@temp\@tempa#2\@empty + \expandafter\lst@ReplaceIn@\expandafter#1% + \fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Flow of control} +% +% \begin{macro}{\@gobblethree} +% is defined if and only if undefined. +% \begin{macrocode} +\providecommand*\@gobblethree[3]{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@GobbleNil} +% \begin{macrocode} +\def\lst@GobbleNil#1\@nil{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Swap} +% is just this: +% \begin{macrocode} +\def\lst@Swap#1#2{#2#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@if} +% \begin{macro}{\lst@true} +% \begin{macro}{\lst@false} +% A general |\if| for temporary use. +% \begin{macrocode} +\def\lst@true{\let\lst@if\iftrue} +\def\lst@false{\let\lst@if\iffalse} +\lst@false +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@IfNextCharsArg} +% is quite easy: We define a macro and call |\lst@IfNextChars|. +% \begin{macrocode} +\def\lst@IfNextCharsArg#1{% + \def\lst@tofind{#1}\lst@IfNextChars\lst@tofind} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@IfNextChars} +% We save the arguments and start a loop. +% \begin{macrocode} +\def\lst@IfNextChars#1#2#3{% + \let\lst@tofind#1\def\@tempa{#2}\def\@tempb{#3}% + \let\lst@eaten\@empty \lst@IfNextChars@} +% \end{macrocode} +% Expand the characters we are looking for. +% \begin{macrocode} +\def\lst@IfNextChars@{\expandafter\lst@IfNextChars@@\lst@tofind\relax} +% \end{macrocode} +% Now we can refine |\lst@tofind| and append the input character |#3| to +% |\lst@eaten|. +% \begin{macrocode} +\def\lst@IfNextChars@@#1#2\relax#3{% + \def\lst@tofind{#2}\lst@lAddTo\lst@eaten{#3}% + \ifx#1#3% +% \end{macrocode} +% If characters are the same, we either call |\@tempa| or continue the test. +% \begin{macrocode} + \ifx\lst@tofind\@empty + \let\lst@next\@tempa + \else + \let\lst@next\lst@IfNextChars@ + \fi + \expandafter\lst@next + \else +% \end{macrocode} +% If the characters are different, we call |\@tempb|. +% \begin{macrocode} + \expandafter\@tempb + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@IfNextCharActive} +% We compare the character |#3| with its active version |\lowercase{~}|. +% Note that the right brace between |\ifx~| and |#3| ends the |\lowercase|. +% The |\endgroup| restores the |\lccode|. +% \begin{macrocode} +\def\lst@IfNextCharActive#1#2#3{% + \begingroup \lccode`\~=`#3\lowercase{\endgroup + \ifx~}#3% + \def\lst@next{#1}% + \else + \def\lst@next{#2}% + \fi \lst@next #3} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@for} +% A for-loop with expansion of the loop-variable. +% \begin{macrocode} +\def\lst@for#1\do#2{% + \def\lst@forbody##1{#2}% + \@for\lst@forvar:=#1\do + {\expandafter\lst@forbody\expandafter{\lst@forvar}}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Catcode changes}\label{iCatcodeChanges} +% +% A character gets its catcode right after reading it and \TeX\ has no +% primitive command to change attached catcodes. However, we can replace these +% characters by characters with same ASCII codes and different catcodes. +% It's not the same but suffices since the result is the same. +% Here we treat the very special case that all characters become active. +% If we want \texverb|\lst@arg| to contain an active version of the character +% |#1|, a prototype macro could be +% \begin{texcode} +% \def\lst@MakeActive#1{\lccode`\~=`#1\lowercase{\def\lst@arg{~}}} +% \end{texcode} +% The |\lowercase| changes the ASCII code of |~| to the one of |#1| since we +% have said that |~| is the lower case version of |#1|. +% Fortunately the |\lowercase| doesn't change the catcode, so we have an active +% version of |#1|. +% Note that |~| is usually active. +% +% \begin{macro}{\lst@MakeActive} +% We won't do this character by character. +% To increase speed we change nine characters at the same time (if nine +% characters are left). +% \begin{TODO} +% This was introduced when the delimiters were converted each listings. Now +% this conversion is done only each language selection. So we might want to +% implement a character by character conversion again to decrease the memory +% usage. +% \end{TODO} +% We get the argument, empty |\lst@arg| and begin a loop. +% \begin{macrocode} +\def\lst@MakeActive#1{% + \let\lst@temp\@empty \lst@MakeActive@#1% + \relax\relax\relax\relax\relax\relax\relax\relax\relax} +% \end{macrocode} +% There are nine |\relax|es since |\lst@MakeActive@| has nine parameters and we +% don't want any problems in the case that |#1| is empty. +% We need nine active characters now instead of a single |~|. +% We make these catcode changes local and define the coming macro |\global|. +% \begin{macrocode} +\begingroup +\catcode`\^^@=\active \catcode`\^^A=\active \catcode`\^^B=\active +\catcode`\^^C=\active \catcode`\^^D=\active \catcode`\^^E=\active +\catcode`\^^F=\active \catcode`\^^G=\active \catcode`\^^H=\active +% \end{macrocode} +% First we |\let| the next operation be |\relax|. +% This aborts our loop for processing all characters (default and possibly +% changed later). +% Then we look if we have at least one character. +% If this is not the case, the loop terminates and all is done. +% \begin{macrocode} +\gdef\lst@MakeActive@#1#2#3#4#5#6#7#8#9{\let\lst@next\relax + \ifx#1\relax + \else \lccode`\^^@=`#1% +% \end{macrocode} +% Otherwise we say that |^^@|=chr(0) is the lower case version of the first +% character. +% Then we test the second character. +% If there is none, we append the lower case |^^@| to |\lst@temp|. +% Otherwise we say that |^^A|=chr(1) is the lower case version of the second +% character and we test the next argument, and so on. +% \begin{macrocode} + \ifx#2\relax + \lowercase{\lst@lAddTo\lst@temp{^^@}}% + \else \lccode`\^^A=`#2% + \ifx#3\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A}}% + \else \lccode`\^^B=`#3% + \ifx#4\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B}}% + \else \lccode`\^^C=`#4% + \ifx#5\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C}}% + \else \lccode`\^^D=`#5% + \ifx#6\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D}}% + \else \lccode`\^^E=`#6% + \ifx#7\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E}}% + \else \lccode`\^^F=`#7% + \ifx#8\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F}}% + \else \lccode`\^^G=`#8% + \ifx#9\relax + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F^^G}}% +% \end{macrocode} +% If nine characters are present, we append (lower case versions of) nine +% active characters and call this macro again via redefining |\lst@next|. +% \begin{macrocode} + \else \lccode`\^^H=`#9% + \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F^^G^^H}}% + \let\lst@next\lst@MakeActive@ + \fi \fi \fi \fi \fi \fi \fi \fi \fi + \lst@next} +\endgroup +% \end{macrocode} +% This |\endgroup| restores the catcodes of chr(0)--chr(8), but not the +% catcodes of the characters inside |\lst@MakeActive@| since they are already +% read. +% +% Note: A conversion from an arbitrary `catcode--character code' table back to +% \TeX's catcodes is possible if we test against the character codes (either +% via |\ifnum| or |\ifcase|). +% But control sequences and begin and end group characters definitely need +% some special treatment. +% However I haven't checked the details. +% So just ignore this and don't bother me for this note. :\,--\,) +% \end{macro} +% +% \begin{macro}{\lst@DefActive} +% An easy application of |\lst@MakeActive|. +% \begin{macrocode} +\def\lst@DefActive#1#2{\lst@MakeActive{#2}\let#1\lst@temp} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DefOther} +% We use the fact that |\meaning| produces catcode 12 characters except spaces +% stay spaces. |\escapechar| is modified locally to suppress the output of an +% escape character. Finally we remove spaces via \LaTeX's |\zap@space|, which +% was proposed by \lsthelper{Rolf~Niepraschk}{1997/04/24}{use \zap@space}---not +% in this context, but that doesn't matter. +% \begin{macrocode} +\def\lst@DefOther#1#2{% + \begingroup \def#1{#2}\escapechar\m@ne \expandafter\endgroup + \expandafter\lst@DefOther@\meaning#1\relax#1} +\def\lst@DefOther@#1>#2\relax#3{\edef#3{\zap@space#2 \@empty}} +% \end{macrocode} +% \end{macro} +% +% +%\ifhyper +% \subsection{Applications to \ref*{iCatcodeChanges}}\label{iApplicationsTo} +%\else +% \subsection{Applications to \ref{iCatcodeChanges}}\label{iApplicationsTo} +%\fi +% +% If an environment is used inside an argument, the listing is already read and +% we can do nothing to preserve the catcodes. +% However, under certain circumstances the environment can be used inside an +% argument---that's at least what I've said in the User's guide. +% And now I have to work for it coming true. +% Moreover we define an analogous conversion macro for the +% \packagename{fancyvrb} mode. +% \begin{syntax} +% \item[0.19] |\lst@InsideConvert{|\meta{\TeX\ material \textup(already read\textup)}|}| +% +% \emph{appends} a verbatim version of the argument to |\lst@arg|, but all +% appended characters are active. Since it's not a character to character +% conversion, `verbatim' needs to be explained. All characters can be +% typed in as they are except |\|, |{|, |}| and |%|. If you want one of +% these, you must write |\\|, |\{|, |\}| and |\%| instead. +% If two spaces should follow each other, the second (third, fourth, +% \ldots) space must be entered with a preceding backslash. +% +% \item[0.19] |\lst@XConvert{|\meta{\TeX\ material \textup(already read\textup)}|}| +% +% \emph{appends} a `verbatim' version of the argument to |\lst@arg|. +% Here \TeX\ material is allowed to be put inside argument braces like +% |{(*}{*)}|. The contents of these arguments are converted, the braces +% stay as curly braces. +% +% If |\lst@if| is true, each second argument is treated differently. +% Only the first character (of the delimiter) becomes active. +% \end{syntax} +% +% \begin{macro}{\lst@InsideConvert} +% We call a submacro (similar to |\zap@space|) to preserve single spaces which +% are replaced by active spaces. +% \begin{macrocode} +\def\lst@InsideConvert#1{\lst@InsideConvert@#1 \@empty} +\begingroup \lccode`\~=`\ \relax \lowercase{% +% \end{macrocode} +% We make |#1| active and append these characters (plus an active space) to +% |\lst@arg|. +% If we haven't found the end |\@empty| of the input, we continue the process. +% \begin{macrocode} +\gdef\lst@InsideConvert@#1 #2{% + \lst@MakeActive{#1}% + \ifx\@empty#2% + \lst@lExtend\lst@arg{\lst@temp}% + \else + \lst@lExtend\lst@arg{\lst@temp~}% + \expandafter\lst@InsideConvert@ + \fi #2} +% \end{macrocode} +% Finally we end the |\lowercase| and close a group. +% \begin{macrocode} +}\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@XConvert} +% Check for an argument \ldots +% \begin{macrocode} +\def\lst@XConvert{\@ifnextchar\bgroup \lst@XConvertArg\lst@XConvert@} +% \end{macrocode} +% \ldots, convert the argument, add it together with group delimiters to +% |\lst@arg|, and we continue the conversion. +% \begin{macrocode} +\def\lst@XConvertArg#1{% + {\lst@false \let\lst@arg\@empty + \lst@XConvert#1\@nil + \global\let\@gtempa\lst@arg}% + \lst@lExtend\lst@arg{\expandafter{\@gtempa}}% + \lst@XConvertNext} +% \end{macrocode} +% Having no |\bgroup|, we look whether we've found the end of the input, and +% convert one token ((non)active character or control sequence) and continue. +% \begin{macrocode} +\def\lst@XConvert@#1{% + \ifx\@nil#1\else + \begingroup\lccode`\~=`#1\lowercase{\endgroup + \lst@lAddTo\lst@arg~}% + \expandafter\lst@XConvertNext + \fi} +\def\lst@XConvertNext{% + \lst@if \expandafter\lst@XConvertX + \else \expandafter\lst@XConvert \fi} +% \end{macrocode} +% Now we make only the first character active. +% \begin{macrocode} +\def\lst@XConvertX#1{% + \ifx\@nil#1\else + \lst@XConvertX@#1\relax + \expandafter\lst@XConvert + \fi} +\def\lst@XConvertX@#1#2\relax{% + \begingroup\lccode`\~=`#1\lowercase{\endgroup + \lst@XCConvertX@@~}{#2}} +\def\lst@XCConvertX@@#1#2{\lst@lAddTo\lst@arg{{#1#2}}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Driver file handling*} +% +% The \packagename{listings} package is split into several driver files, +% miscellaneous (= aspect) files, and one kernel file. +% All these files can be loaded partially and on demand---except the kernel +% which provides this functionality. +% \begin{syntax} +% \item[0.21] |\lst@Require|\marg{name}\marg{prefix}\marg{feature list}\meta{alias}\meta{file list macro} +% +% tries to load all items of \meta{feature list} from the files +% listed in \meta{file list macro}. +% Each item has the form [\oarg{sub}]\meta{feature}. +% |\lst@if| equals |\iftrue| if and only if all items were loadable. +% +% The macro \meta{alias} gets an item as argument and must define +% appropriate versions of |\lst@oalias| and |\lst@malias|. In fact +% the feature associated with these definitions is loaded. You can +% use \meta{alias}=|\lst@NoAlias| for no substitution. +% +% \meta{prefix} identifies the type internally and \meta{name} is used +% for messages. +% +% For example, |\lstloadaspects| uses the following arguments where |#1| +% is the list of aspects: |{aspects}|\allowbreak|a|\allowbreak +% |{#1}|\allowbreak|\lst@NoAlias|\allowbreak|\lstaspectfiles|. +% +% \item[0.20] |\lst@DefDriver|\marg{name}\marg{prefix}\meta{interface macro}|\if|\alternative{true,false} +% +% +% +% \item[0.21] |\lst@IfRequired|\oarg{sub}\marg{feature}\marg{then}\marg{else} +% +% is used inside a driver file by the aspect, language, or whatever +% else defining commands. \meta{then} is executed if and only if +% \oarg{sub}\marg{feature} has been requested via |\lst@Require|. +% Otherwise \meta{else} is executed---which is also the case for +% subsequent calls with the same \oarg{sub}\marg{feature}. +% +% \meta{then} and \meta{else} may use |\lst@prefix| (read access only). +% +% |\lst@BeginAspect| in section \ref{iAspectCommands} and |\lst@DefDriver| +% serve as examples. +% \end{syntax} +% +% \begin{macro}{\lst@Require} +% Initialize variables (if required items aren't empty), \ldots +% \begin{macrocode} +\def\lst@Require#1#2#3#4#5{% + \begingroup + \aftergroup\lst@true + \ifx\@empty#3\@empty\else + \def\lst@prefix{#2}\let\lst@require\@empty +% \end{macrocode} +% \ldots\space and for each nonempty item: determine alias and add it to +% |\lst@require| if it isn't loaded. +% \begin{macrocode} + \edef\lst@temp{\expandafter\zap@space#3 \@empty}% + \lst@for\lst@temp\do{% + \ifx\@empty##1\@empty\else \lstKV@OptArg[]{##1}{% + #4[####1]{####2}% + \@ifundefined{\@lst\lst@prefix @\lst@malias $\lst@oalias}% + {\edef\lst@require{\lst@require,\lst@malias $\lst@oalias}}% + {}}% + \fi}% +% \end{macrocode} +% Init things and input files if and as long as it is necessary. +% \begin{macrocode} + \global\let\lst@loadaspects\@empty + \lst@InputCatcodes + \ifx\lst@require\@empty\else + \lst@for{#5}\do{% + \ifx\lst@require\@empty\else + \InputIfFileExists{##1}{}{}% + \fi}% + \fi +% \end{macrocode} +% Issue error and call |\lst@false| (after closing the local group) if some +% items weren't loadable. +% \begin{macrocode} + \ifx\lst@require\@empty\else + \PackageError{Listings}{Couldn't load requested #1}% + {The following #1s weren't loadable:^^J\@spaces + \lst@require^^JThis may cause errors in the sequel.}% + \aftergroup\lst@false + \fi +% \end{macrocode} +% Request aspects. +% \begin{macrocode} + \ifx\lst@loadaspects\@empty\else + \lst@RequireAspects\lst@loadaspects + \fi + \fi + \endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@IfRequired} +% uses |\lst@IfOneOf| and adds some code to \meta{then} part: +% delete the now loaded item from the list and define +% |\lst|\meta{prefix}|@|\meta{feature}|$|\meta{sub}. +% \begin{macrocode} +\def\lst@IfRequired[#1]#2{% + \lst@NormedDef\lst@temp{[#1]#2}% + \expandafter\lst@IfRequired@\lst@temp\relax} +\def\lst@IfRequired@[#1]#2\relax#3{% + \lst@IfOneOf #2$#1\relax\lst@require + {\lst@DeleteKeysIn@\lst@require#2$#1,\relax,% + \global\expandafter\let + \csname\@lst\lst@prefix @#2$#1\endcsname\@empty + #3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@require} +% \begin{macrocode} +\let\lst@require\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@NoAlias} +% just defines |\lst@oalias| and |\lst@malias|. +% \begin{macrocode} +\def\lst@NoAlias[#1]#2{% + \lst@NormedDef\lst@oalias{#1}\lst@NormedDef\lst@malias{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LAS} +% \begin{macrocode} +\gdef\lst@LAS#1#2#3#4#5#6#7{% + \lst@Require{#1}{#2}{#3}#4#5% + #4#3% + \@ifundefined{lst#2@\lst@malias$\lst@oalias}% + {\PackageError{Listings}% + {#1 \ifx\@empty\lst@oalias\else \lst@oalias\space of \fi + \lst@malias\space undefined}% + {The #1 is not loadable. \@ehc}}% + {#6\csname\@lst#2@\lst@malias $\lst@oalias\endcsname #7}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@RequireAspects} +% \begin{macro}{\lstloadaspects} +% make use of the just developped definitions. +% \begin{macrocode} +\def\lst@RequireAspects#1{% + \lst@Require{aspect}{asp}{#1}\lst@NoAlias\lstaspectfiles} +\let\lstloadaspects\lst@RequireAspects +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lstaspectfiles} +% This macro is defined if and only if it's undefined yet. +% \begin{macrocode} +\@ifundefined{lstaspectfiles} + {\newcommand\lstaspectfiles{lstmisc0.sty,lstmisc.sty}}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DefDriver} +% Test the next character and reinsert the arguments. +% \begin{macrocode} +\gdef\lst@DefDriver#1#2#3#4{% + \@ifnextchar[{\lst@DefDriver@{#1}{#2}#3#4}% + {\lst@DefDriver@{#1}{#2}#3#4[]}} +% \end{macrocode} +% We set |\lst@if| locally true if the item has been requested. +% \begin{macrocode} +\gdef\lst@DefDriver@#1#2#3#4[#5]#6{% + \def\lst@name{#1}\let\lst@if#4% + \lst@NormedDef\lst@driver{\@lst#2@#6$#5}% + \lst@IfRequired[#5]{#6}{\begingroup \lst@true}% + {\begingroup}% + \lst@setcatcodes + \@ifnextchar[{\lst@XDefDriver{#1}#3}{\lst@DefDriver@@#3}} +% \end{macrocode} +% Note that |\lst@XDefDriver| takes optional `base' arguments, but eventually +% calls |\lst@DefDriver@@|. We define the item (in case of need), and +% |\endgroup| resets some catcodes and |\lst@if|, i.e.~|\lst@XXDefDriver| knows +% whether called by a public or internal command. +% \begin{macrocode} +\gdef\lst@DefDriver@@#1#2{% + \lst@if + \global\@namedef{\lst@driver}{#1{#2}}% + \fi + \endgroup + \@ifnextchar[\lst@XXDefDriver\@empty} +% \end{macrocode} +% We get the aspect argument, and (if not empty) load the aspects immediately +% if called by a public command or extend the list of required aspects or +% simply ignore the argument if the item leaves undefined. +% \begin{macrocode} +\gdef\lst@XXDefDriver[#1]{% + \ifx\@empty#1\@empty\else + \lst@if + \lstloadaspects{#1}% + \else + \@ifundefined{\lst@driver}{}% + {\xdef\lst@loadaspects{\lst@loadaspects,#1}}% + \fi + \fi} +% \end{macrocode} +% We insert an additional `also'key=value pair. +% \begin{macrocode} +\gdef\lst@XDefDriver#1#2[#3]#4#5{\lst@DefDriver@@#2{also#1=[#3]#4,#5}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Aspect commands}\label{iAspectCommands} +% +% This section contains commands used in defining `\lst-aspects'. +% \begin{macro}{\lst@UserCommand} +% is mainly equivalent to |\gdef|. +% \begin{macrocode} +%\let\lst@UserCommand\gdef +%\def\lst@UserCommand#1{\message{\string#1,}\gdef#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@BeginAspect} +% A straight-forward implementation: +% \begin{macrocode} +\newcommand*\lst@BeginAspect[2][]{% + \def\lst@curraspect{#2}% + \ifx \lst@curraspect\@empty + \expandafter\lst@GobbleAspect + \else +% \end{macrocode} +% If \meta{aspect name} is not empty, there are certain other conditions not to +% define the aspect (as described in section \ref{dHowToDefineLstAspects}). +% \begin{macrocode} +% \let\lst@next\@empty +% \def\lst@next{% +% \message{^^JDefine lst-aspect `#2':}\lst@GetAllocs}% + \lst@IfRequired[]{#2}% + {\lst@RequireAspects{#1}% + \lst@if\else \let\lst@next\lst@GobbleAspect \fi}% + {\let\lst@next\lst@GobbleAspect}% + \expandafter\lst@next + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EndAspect} +% finishes an aspect definition. +% \begin{macrocode} +\def\lst@EndAspect{% + \csname\@lst patch@\lst@curraspect\endcsname +% \lst@ReportAllocs + \let\lst@curraspect\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@GobbleAspect} +% drops all code up to the next |\lst@EndAspect|. +% \begin{macrocode} +\long\def\lst@GobbleAspect#1\lst@EndAspect{\let\lst@curraspect\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Key} +% The command simply defines the key. But we must take care of an optional +% parameter and the initialization argument |#2|. +% \begin{macrocode} +\def\lst@Key#1#2{% +% \message{#1,}% + \@ifnextchar[{\lstKV@def{#1}{#2}}% + {\def\lst@temp{\lst@Key@{#1}{#2}} + \afterassignment\lst@temp + \global\@namedef{KV@\@lst @#1}####1}} +% \end{macrocode} +% Now comes a renamed and modified copy from a \packagename{keyval} macro: +% We need global key definitions. +% \begin{macrocode} +\def\lstKV@def#1#2[#3]{% + \global\@namedef{KV@\@lst @#1@default\expandafter}\expandafter + {\csname KV@\@lst @#1\endcsname{#3}}% + \def\lst@temp{\lst@Key@{#1}{#2}}\afterassignment\lst@temp + \global\@namedef{KV@\@lst @#1}##1} +% \end{macrocode} +% We initialize the key if the first token of |#2| is not |\relax|. +% \begin{macrocode} +\def\lst@Key@#1#2{% + \ifx\relax#2\@empty\else + \begingroup \globaldefs\@ne + \csname KV@\@lst @#1\endcsname{#2}% + \endgroup + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@UseHook} +% is very, very, \ldots, very (hundreds of times) easy. +% \begin{macrocode} +\def\lst@UseHook#1{\csname\@lst hk@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@AddToHook} +% \begin{macro}{\lst@AddToHookExe} +% \begin{macro}{\lst@AddToHookAtTop} +% All use the same submacro. +% \begin{macrocode} +\def\lst@AddToHook{\lst@ATH@\iffalse\lst@AddTo} +\def\lst@AddToHookExe{\lst@ATH@\iftrue\lst@AddTo} +\def\lst@AddToHookAtTop{\lst@ATH@\iffalse\lst@AddToAtTop} +% \end{macrocode} +% If and only if the boolean value is true, the hook material is executed +% globally. +% \begin{macrocode} +\long\def\lst@ATH@#1#2#3#4{% + \@ifundefined{\@lst hk@#3}{% +% \message{^^Jnew hook `#3',^^J}% + \expandafter\gdef\csname\@lst hk@#3\endcsname{}}{}% + \expandafter#2\csname\@lst hk@#3\endcsname{#4}% + \def\lst@temp{#4}% + #1% \iftrue|false + \begingroup \globaldefs\@ne \lst@temp \endgroup + \fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@AddTo} +% Note that the definition is global! +% \begin{macrocode} +\long\def\lst@AddTo#1#2{% + \expandafter\gdef\expandafter#1\expandafter{#1#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@AddToAtTop} +% We need a couple of |\expandafter|s now. Simply note that we have\\ +% {\small\hspace*{2em}|\expandafter\gdef\expandafter#1\expandafter{\lst@temp| +% $\langle$\textit{contents of }|#1|$\rangle$|}|}\\ +% after the `first phase' of expansion. +% \begin{macrocode} +\def\lst@AddToAtTop#1#2{\def\lst@temp{#2}% + \expandafter\expandafter\expandafter\gdef + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\lst@temp#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@lAddTo} +% A local version of |\lst@AddTo| \ldots +% \begin{macrocode} +\def\lst@lAddTo#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Extend} +% \begin{macro}{\lst@lExtend} +% \ldots\space and here we expand the first token of the second argument first. +% \begin{macrocode} +\def\lst@Extend#1#2{% + \expandafter\lst@AddTo\expandafter#1\expandafter{#2}} +\def\lst@lExtend#1#2{% + \expandafter\lst@lAddTo\expandafter#1\expandafter{#2}} +% \end{macrocode} +% \begin{TODO} +% This should never be changed to +% \begin{verbatim} +% \def\lst@Extend#1{% +% \expandafter\lst@AddTo\expandafter#1\expandafter} +% \def\lst@lExtend#1{% +% \expandafter\lst@lAddTo\expandafter#1}\end{verbatim} +% The first is not equivalent in case that the second argument is a single +% (= non-braced) control sequence, and the second isn't in case of a braced +% second argument. +% \end{TODO} +% \end{macro} +% \end{macro} +% +% +% \subsection{Interfacing with \textsf{keyval}} +% +% The \packagename{keyval} package passes the value via the one and only +% paramater |#1| to the definition part of the key macro. The following +% commands may be used to analyse the value. Note that we need at least version +% 1.10 of the \packagename{keyval} package. Note also that the package removes +% a naming conflict with AMS classes---reported by \lsthelper{Ralf~Quast} +% {1998/01/08}{\keywords conflicts with AMS classes}. +% \begingroup +% \begin{macrocode} +\RequirePackage{keyval}[1997/11/10] +% \end{macrocode} +% \endgroup +% +% \begin{macro}{\lstKV@TwoArg} +% \begin{macro}{\lstKV@ThreeArg} +% \begin{macro}{\lstKV@FourArg} +% Define temporary macros and call with given arguments |#1|. We add empty +% arguments for the case that the user doesn't provide enough. +% \begin{macrocode} +\def\lstKV@TwoArg#1#2{\gdef\@gtempa##1##2{#2}\@gtempa#1{}{}} +\def\lstKV@ThreeArg#1#2{\gdef\@gtempa##1##2##3{#2}\@gtempa#1{}{}{}} +\def\lstKV@FourArg#1#2{\gdef\@gtempa##1##2##3##4{#2}\@gtempa#1{}{}{}{}} +% \end{macrocode} +% There's one question: What are the global definitions good for? |\lst@Key| +% might set |\globaldefs| to one and possibly calls this macro. That's the +% reason why we use global definitions here and below. +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lstKV@OptArg} +% We define the temporary macro |\@gtempa| and insert default argument if +% necessary. +% \begin{macrocode} +\def\lstKV@OptArg[#1]#2#3{% + \gdef\@gtempa[##1]##2{#3}\lstKV@OptArg@{#1}#2\@} +\def\lstKV@OptArg@#1{\@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[#1]}} +\def\lstKV@OptArg@@[#1]#2\@{\@gtempa[#1]{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstKV@XOptArg} +% Here |#3| is already a definition with at least two parameters whose first +% is enclosed in brackets. +% \begin{macrocode} +\def\lstKV@XOptArg[#1]#2#3{% + \global\let\@gtempa#3\lstKV@OptArg@{#1}#2\@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstKV@CSTwoArg} +% Just define temporary macro and call it. +% \begin{macrocode} +\def\lstKV@CSTwoArg#1#2{% + \gdef\@gtempa##1,##2,##3\relax{#2}% + \@gtempa#1,,\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstKV@SetIf} +% We simply test the lower case first character of |#1|. +% \begin{macrocode} +\def\lstKV@SetIf#1{\lstKV@SetIf@#1\relax} +\def\lstKV@SetIf@#1#2\relax#3{\lowercase{% + \expandafter\let\expandafter#3% + \csname if\ifx #1t}true\else false\fi\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstKV@SwitchCases} +% is implemented as a substring test. +% \begin{macrocode} +\def\lstKV@SwitchCases#1#2#3{% + \def\lst@temp##1\\#1&##2\\##3##4\@nil{% + \ifx\@empty##3% + #3% + \else + ##2% + \fi + }% + \lst@temp\\#2\\#1&\\\@empty\@nil} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstset} +% Finally this main user interface macro. +% We change catcodes for reading the argument. +% \begin{macrocode} +\lst@UserCommand\lstset{\begingroup \lst@setcatcodes \lstset@} +\def\lstset@#1{\endgroup \ifx\@empty#1\@empty\else\setkeys{lst}{#1}\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@setcatcodes} +% contains all catcode changes for |\lstset|. +% \begin{macrocode} +\def\lst@setcatcodes{\makeatletter \catcode`\"=12\relax} +% \end{macrocode} +% \begin{TODO} +% Change more catcodes? +% \end{TODO} +% \end{macro} +% +% +% \subsection{Internal modes} +% +% \begin{macro}{\lst@NewMode} +% We simply use |\chardef| for a mode definition. The counter |\lst@mode| +% mainly keeps the current mode number. But it is also used to advance the +% number in the macro |\lst@newmode|---we don't waste another counter. +% \begin{macrocode} +\def\lst@NewMode#1{% + \ifx\@undefined#1% + \lst@mode\lst@newmode\relax \advance\lst@mode\@ne + \xdef\lst@newmode{\the\lst@mode}% + \global\chardef#1=\lst@mode + \lst@mode\lst@nomode + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@mode} +% \begin{macro}{\lst@nomode} +% We allocate the counter and the first mode. +% \begin{macrocode} +\newcount\lst@mode +\def\lst@newmode{\m@ne}% init +\lst@NewMode\lst@nomode % init (of \lst@mode :-) +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@UseDynamicMode} +% For dynamic modes we must not use the counter |\lst@mode| (since possibly +% already valued). |\lst@dynamicmode| substitutes |\lst@newmode| and is a local +% definition here, \ldots +% \begin{macrocode} +\def\lst@UseDynamicMode{% + \@tempcnta\lst@dynamicmode\relax \advance\@tempcnta\@ne + \edef\lst@dynamicmode{\the\@tempcnta}% + \expandafter\lst@Swap\expandafter{\expandafter{\lst@dynamicmode}}} +% \end{macrocode} +% \ldots\ initialized each listing with the current `value' of |\lst@newmode|. +% \begin{macrocode} +\lst@AddToHook{InitVars}{\let\lst@dynamicmode\lst@newmode} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EnterMode} +% Each mode opens a group level, stores the mode number and execute mode +% specific tokens. Moreover we keep all these changes in mind (locally) and +% adjust internal variables if the user wants it. +% \begin{macrocode} +\def\lst@EnterMode#1#2{% + \bgroup \lst@mode=#1\relax #2% + \lst@FontAdjust + \lst@lAddTo\lst@entermodes{\lst@EnterMode{#1}{#2}}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{InitVars}{\let\lst@entermodes\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LeaveMode} +% We simply close the group and call |\lsthk@EndGroup| if and only if the +% current mode is not |\lst@nomode|. +% \begin{macrocode} +\def\lst@LeaveMode{% + \ifnum\lst@mode=\lst@nomode\else + \egroup \expandafter\lsthk@EndGroup + \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{EndGroup}{}% init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@InterruptModes} +% We put the current mode sequence on a stack and leave all modes. +% \begin{macrocode} +\def\lst@InterruptModes{% + \lst@Extend\lst@modestack{\expandafter{\lst@entermodes}}% + \lst@LeaveAllModes} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{InitVars}{\global\let\lst@modestack\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ReenterModes} +% If the stack is not empty, we leave all modes and pop the topmost element +% (which is the last element of |\lst@modestack|). +% \begin{macrocode} +\def\lst@ReenterModes{% + \ifx\lst@modestack\@empty\else + \lst@LeaveAllModes + \global\let\@gtempa\lst@modestack + \global\let\lst@modestack\@empty + \expandafter\lst@ReenterModes@\@gtempa\relax + \fi} +\def\lst@ReenterModes@#1#2{% + \ifx\relax#2\@empty +% \end{macrocode} +% If we've reached |\relax|, we've also found the last element: we execute |#1| +% and gobble |{#2}|=|{\relax}| after |\fi|. +% \begin{macrocode} + \gdef\@gtempa##1{#1}% + \expandafter\@gtempa + \else +% \end{macrocode} +% Otherwise we just add the element to |\lst@modestack| and continue the loop. +% \begin{macrocode} + \lst@AddTo\lst@modestack{{#1}}% + \expandafter\lst@ReenterModes@ + \fi + {#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LeaveAllModes} +% Leaving all modes means closing groups until the mode equals |\lst@nomode|. +% \begin{macrocode} +\def\lst@LeaveAllModes{% + \ifnum\lst@mode=\lst@nomode + \expandafter\lsthk@EndGroup + \else + \expandafter\egroup\expandafter\lst@LeaveAllModes + \fi} +% \end{macrocode} +% We need that macro to end a listing correctly. +% \begin{macrocode} +\lst@AddToHook{ExitVars}{\lst@LeaveAllModes} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Pmode} +% \begin{macro}{\lst@GPmode} +% The `processing' and the general purpose mode. +% \begin{macrocode} +\lst@NewMode\lst@Pmode +\lst@NewMode\lst@GPmode +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@modetrue} +% The usual macro to value a boolean except that we also execute a hook. +% \begin{macrocode} +\def\lst@modetrue{\let\lst@ifmode\iftrue \lsthk@ModeTrue} +\let\lst@ifmode\iffalse % init +\lst@AddToHook{ModeTrue}{}% init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ifLmode} +% Comment lines use a static mode. It terminates at end of line. +% \begin{macrocode} +\def\lst@Lmodetrue{\let\lst@ifLmode\iftrue} +\let\lst@ifLmode\iffalse % init +\lst@AddToHook{EOL}{\@whilesw \lst@ifLmode\fi \lst@LeaveMode} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Divers helpers} +% +% \begin{macro}{\lst@NormedDef} +% works like |\def| (without any parameters!) but normalizes the replacement +% text by making all characters lower case and stripping off spaces. +% \begin{macrocode} +\def\lst@NormedDef#1#2{\lowercase{\edef#1{\zap@space#2 \@empty}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@NormedNameDef} +% works like |\global\@namedef| (again without any parameters!) but normalizes +% both the macro name and the replacement text. +% \begin{macrocode} +\def\lst@NormedNameDef#1#2{% + \lowercase{\edef\lst@temp{\zap@space#1 \@empty}% + \expandafter\xdef\csname\lst@temp\endcsname{\zap@space#2 \@empty}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@GetFreeMacro} +% Initialize |\@tempcnta| and |\lst@freemacro|, \ldots +% \begin{macrocode} +\def\lst@GetFreeMacro#1{% + \@tempcnta\z@ \def\lst@freemacro{#1\the\@tempcnta}% + \lst@GFM@} +% \end{macrocode} +% \ldots\space and either build the control sequence or advance the counter and +% continue. +% \begin{macrocode} +\def\lst@GFM@{% + \expandafter\ifx \csname\lst@freemacro\endcsname \relax + \edef\lst@freemacro{\csname\lst@freemacro\endcsname}% + \else + \advance\@tempcnta\@ne + \expandafter\lst@GFM@ + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@gtempboxa} +% \begin{macrocode} +\newbox\lst@gtempboxa +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \end{macro} +% +% +% \section{Doing output} +% +% +% \subsection{Basic registers and keys} +% +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% +% \paragraph{The current character string} +% is kept in a token register and a counter holds its length. +% Here we define the macros to put characters into the output queue. +% +% \begin{macro}{\lst@token} +% \begin{macro}{\lst@length} +% are allocated here. Quite a useful comment, isn't it? +% \begin{macrocode} +\newtoks\lst@token \newcount\lst@length +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@ResetToken} +% \begin{macro}{\lst@lastother} +% The two registers get empty respectively zero at the beginning of each line. +% After receiving a report from \lsthelper{Claus~Atzenbeck}{1999/11/24}{HTML: +% output unit repeated after >}---I removed such a bug many times---I decided +% to reset these registers in the \hookname{EndGroup} hook, too. +% \begin{macrocode} +\def\lst@ResetToken{\lst@token{}\lst@length\z@} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{InitVarsBOL}{\lst@ResetToken \let\lst@lastother\@empty} +\lst@AddToHook{EndGroup}{\lst@ResetToken \let\lst@lastother\@empty} +% \end{macrocode} +% The macro |\lst@lastother| will be equivalent to the last `other' character, +% which leads us to |\lst@ifletter|. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@ifletter} +% indicates whether the token contains an identifier or other characters. +% \begin{macrocode} +\def\lst@lettertrue{\let\lst@ifletter\iftrue} +\def\lst@letterfalse{\let\lst@ifletter\iffalse} +\lst@AddToHook{InitVars}{\lst@letterfalse} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Append} +% puts the argument into the output queue. +% \begin{macrocode} +\def\lst@Append#1{\advance\lst@length\@ne + \lst@token=\expandafter{\the\lst@token#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@AppendOther} +% Depending on the current state, we first output the character string as an +% identifier. Then we save the `argument' via |\futurelet| and call the macro +% |\lst@Append| to do the rest. +% \begin{macrocode} +\def\lst@AppendOther{% + \lst@ifletter \lst@Output\lst@letterfalse \fi + \futurelet\lst@lastother\lst@Append} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@AppendLetter} +% We output a non-identifier string if necessary and call |\lst@Append|. +% \begin{macrocode} +\def\lst@AppendLetter{% + \lst@ifletter\else \lst@OutputOther\lst@lettertrue \fi + \lst@Append} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@SaveToken} +% \begin{macro}{\lst@RestoreToken} +% If a group end appears and ruins the character string, we can use these +% macros to save and restore the contents. |\lst@thestyle| is the current +% printing style and must be saved and restored, too. +% \begin{macrocode} +\def\lst@SaveToken{% + \global\let\lst@gthestyle\lst@thestyle + \xdef\lst@RestoreToken{\noexpand\lst@token{\the\lst@token}% + \noexpand\lst@length\the\lst@length\relax + \noexpand\let\noexpand\lst@thestyle + \noexpand\lst@gthestyle}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \paragraph{The current position} +% is either the dimension |\lst@currlwidth|, which is the horizontal position +% without taking the current character string into account, or it's the current +% column starting with number 0. This is |\lst@column| $-$ |\lst@pos| $+$ +% |\lst@length|. Moreover we have |\lst@lostspace| which is the difference +% between the current and the desired line width. We define macros to insert +% this lost space. +% +% \begin{macro}{\lst@currlwidth} +% \begin{macro}{\lst@column} +% \begin{macro}{\lst@pos} +% the current line width and two counters. +% \begin{macrocode} +\newdimen\lst@currlwidth % \global +\newcount\lst@column \newcount\lst@pos % \global +\lst@AddToHook{InitVarsBOL} + {\global\lst@currlwidth\z@ \global\lst@pos\z@ \global\lst@column\z@} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@CalcColumn} +% sets |\@tempcnta| to the current column. +% Note that |\lst@pos| will be nonpositive. +% \begin{macrocode} +\def\lst@CalcColumn{% + \@tempcnta\lst@column + \advance\@tempcnta\lst@length + \advance\@tempcnta-\lst@pos} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@lostspace} +% Whenever this dimension is positive we can insert space. A negative `lost +% space' means that the printed line is wider than expected. +% \begin{macrocode} +\newdimen\lst@lostspace % \global +\lst@AddToHook{InitVarsBOL}{\global\lst@lostspace\z@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@UseLostSpace} +% We insert space and reset it if and only if |\lst@lostspace| is positive. +% \begin{macrocode} +\def\lst@UseLostSpace{\ifdim\lst@lostspace>\z@ \lst@InsertLostSpace \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@InsertLostSpace} +% \begin{macro}{\lst@InsertHalfLostSpace} +% Ditto, but insert even if negative. |\lst@Kern| will be defined very soon. +% \begin{macrocode} +\def\lst@InsertLostSpace{% + \lst@Kern\lst@lostspace \global\lst@lostspace\z@} +\def\lst@InsertHalfLostSpace{% + \global\lst@lostspace.5\lst@lostspace \lst@Kern\lst@lostspace} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \paragraph{Column widths} +% Here we deal with the width of a single column, which equals the width of a +% single character box. Keep in mind that there are fixed and flexible column +% formats. +% +% \begin{macro}{\lst@width} +% \begin{lstkey}{basewidth} +% \keyname{basewidth} assigns the values to macros and tests whether they are +% negative. +% \begin{macrocode} +\newdimen\lst@width +\lst@Key{basewidth}{0.6em,0.45em}{\lstKV@CSTwoArg{#1}% + {\def\lst@widthfixed{##1}\def\lst@widthflexible{##2}% + \ifx\lst@widthflexible\@empty + \let\lst@widthflexible\lst@widthfixed + \fi + \def\lst@temp{\PackageError{Listings}% + {Negative value(s) treated as zero}% + \@ehc}% + \let\lst@error\@empty + \ifdim \lst@widthfixed<\z@ + \let\lst@error\lst@temp \let\lst@widthfixed\z@ + \fi + \ifdim \lst@widthflexible<\z@ + \let\lst@error\lst@temp \let\lst@widthflexible\z@ + \fi + \lst@error}} +% \end{macrocode} +% We set the dimension in a special hook. +% \begin{macrocode} +\lst@AddToHook{FontAdjust} + {\lst@width=\lst@ifflexible\lst@widthflexible + \else\lst@widthfixed\fi \relax} +% \end{macrocode} +% \end{lstkey} +% \end{macro} +% +% \begin{lstkey}{fontadjust} +% \begin{macro}{\lst@FontAdjust} +% This hook is controlled by a switch and is always executed at +% \hookname{InitVars}. +% \begin{macrocode} +\lst@Key{fontadjust}{false}[t]{\lstKV@SetIf{#1}\lst@iffontadjust} +\def\lst@FontAdjust{\lst@iffontadjust \lsthk@FontAdjust \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{InitVars}{\lsthk@FontAdjust} +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% +% \subsection{Low- and mid-level output} +% +% \paragraph{Doing the output} +% means putting the character string into a box register, updating all internal +% data, and eventually giving the box to \TeX. +% +% \begin{macro}{\lst@OutputBox} +% \begin{macro}{\lst@alloverstyle} +% The lowest level is the output of a box register. +% Here we use |\box#1| as argument to |\lst@alloverstyle|. +% \begin{macrocode} +\def\lst@OutputBox#1{\lst@alloverstyle{\box#1}} +% \end{macrocode} +% \begin{ALTERNATIVE} +% Instead of |\global\advance\lst@currlwidth| |\wd|\meta{box number} in +% both definitions |\lst@Kern| and |\lst@CalcLostSpaceAndOutput|, we could +% also advance the dimension here. But I decided not to do so since it +% simplifies possible redefinitions of |\lst@OutputBox|: we need not to care +% about |\lst@currlwidth|. +% \end{ALTERNATIVE} +% \begin{macrocode} +\def\lst@alloverstyle#1{#1}% init +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@Kern} +% has been used to insert `lost space'. +% It must not use |\@tempboxa| since that \ldots +% \begin{macrocode} +\def\lst@Kern#1{% + \setbox\z@\hbox{{\lst@currstyle{\kern#1}}}% + \global\advance\lst@currlwidth \wd\z@ + \lst@OutputBox\z@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CalcLostSpaceAndOutput} +% \ldots\space is used here. +% We keep track of |\lst@lostspace|, |\lst@currlwidth| and |\lst@pos|. +% \begin{macrocode} +\def\lst@CalcLostSpaceAndOutput{% + \global\advance\lst@lostspace \lst@length\lst@width + \global\advance\lst@lostspace-\wd\@tempboxa + \global\advance\lst@currlwidth \wd\@tempboxa + \global\advance\lst@pos -\lst@length +% \end{macrocode} +% Before |\@tempboxa| is output, we insert space if there is enough lost space. +% This possibly invokes |\lst@Kern| via `insert half lost space', which is the +% reason for why we mustn't use |\@tempboxa| above. By redefinition we prevent +% |\lst@OutputBox| from using any special style in |\lst@Kern|. +% \begin{macrocode} + \setbox\@tempboxa\hbox{\let\lst@OutputBox\box + \ifdim\lst@lostspace>\z@ \lst@leftinsert \fi + \box\@tempboxa + \ifdim\lst@lostspace>\z@ \lst@rightinsert \fi}% +% \end{macrocode} +% Finally we can output the new box. +% \begin{macrocode} + \lst@OutputBox\@tempboxa \lsthk@PostOutput} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{PostOutput}{}% init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@OutputToken} +% Now comes a mid-level definition. +% Here we use |\lst@token| to set |\@tempboxa| and eventually output the box. +% We take care of font adjustment and special output styles. +% Yet unknown macros are defined in the following subsections. +% \begin{macrocode} +\def\lst@OutputToken{% + \lst@TrackNewLines \lst@OutputLostSpace + \lst@CheckMerge + {\lst@thestyle{\lst@FontAdjust + \setbox\@tempboxa\lst@hbox + {\lsthk@OutputBox + \lst@lefthss + \expandafter\lst@FillOutputBox\the\lst@token\@empty + \lst@righthss}% + \lst@CalcLostSpaceAndOutput}}% + \lst@ResetToken} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{OutputBox}{}% init +% \end{macrocode} +% \end{macro} +% +% +% \paragraph{Delaying the output} +% means saving the character string somewhere and pushing it back when +% neccessary. We may also attach the string to the next output box without +% affecting style detection: both will be printed in the style of the upcoming +% output. We will call this `merging'. +% +% \begin{macro}{\lst@Delay} +% \begin{macro}{\lst@Merge} +% To delay or merge |#1|, we process it as usual and simply save the state +% in macros. For delayed characters we also need the currently `active' +% output routine. Both definitions first check whether there are already +% delayed or `merged' characters. +% \begin{macrocode} +\def\lst@Delay#1{% + \lst@CheckDelay + #1% + \lst@GetOutputMacro\lst@delayedoutput + \edef\lst@delayed{\the\lst@token}% + \edef\lst@delayedlength{\the\lst@length}% + \lst@ResetToken} +% \end{macrocode} +% \begin{macrocode} +\def\lst@Merge#1{% + \lst@CheckMerge + #1% + \edef\lst@merged{\the\lst@token}% + \edef\lst@mergedlength{\the\lst@length}% + \lst@ResetToken} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@MergeToken} +% Here we put the things together again. +% \begin{macrocode} +\def\lst@MergeToken#1#2{% + \advance\lst@length#2% + \lst@lExtend#1{\the\lst@token}% + \expandafter\lst@token\expandafter{#1}% + \let#1\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CheckDelay} +% We need to print delayed characters. The mode depends on the current output +% macro. If it equals the saved definition, we put the delayed characters in +% front of the character string (we merge them) since there has been no +% letter-to-other or other-to-letter leap. Otherwise we locally reset the +% current character string, merge this empty string with the delayed one, +% and output it. +% \begin{macrocode} +\def\lst@CheckDelay{% + \ifx\lst@delayed\@empty\else + \lst@GetOutputMacro\@gtempa + \ifx\lst@delayedoutput\@gtempa + \lst@MergeToken\lst@delayed\lst@delayedlength + \else + {\lst@ResetToken + \lst@MergeToken\lst@delayed\lst@delayedlength + \lst@delayedoutput}% + \let\lst@delayed\@empty + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CheckMerge} +% All this is easier for |\lst@merged|. +% \begin{macrocode} +\def\lst@CheckMerge{% + \ifx\lst@merged\@empty\else + \lst@MergeToken\lst@merged\lst@mergedlength + \fi} +% \end{macrocode} +% \begin{macrocode} +\let\lst@delayed\@empty % init +\let\lst@merged\@empty % init +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Column formats} +% +% It's time to deal with fixed and flexible column modes. +% A couple of open definitions are now filled in. +% +% \begin{macro}{\lst@column@fixed} +% switches to the fixed column format. The definitions here control how the +% output of the above definitions looks like. +% \begin{macrocode} +\def\lst@column@fixed{% + \lst@flexiblefalse + \lst@width\lst@widthfixed\relax + \let\lst@OutputLostSpace\lst@UseLostSpace + \let\lst@FillOutputBox\lst@FillFixed + \let\lst@hss\hss + \def\lst@hbox{\hbox to\lst@length\lst@width}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@FillFixed} +% Filling up a fixed mode box is easy. +% \begin{macrocode} +\def\lst@FillFixed#1{#1\lst@FillFixed@} +% \end{macrocode} +% While not reaching the end (|\@empty| from above), we insert dynamic space, +% output the argument and call the submacro again. +% \begin{macrocode} +\def\lst@FillFixed@#1{% + \ifx\@empty#1\else \lst@hss#1\expandafter\lst@FillFixed@ \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@column@flexible} +% The first flexible format. +% \begin{macrocode} +\def\lst@column@flexible{% + \lst@flexibletrue + \lst@width\lst@widthflexible\relax + \let\lst@OutputLostSpace\lst@UseLostSpace + \let\lst@FillOutputBox\@empty + \let\lst@hss\@empty + \let\lst@hbox\hbox} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@column@fullflexible} +% This column format inserts no lost space except at the beginning of a line. +% \begin{macrocode} +\def\lst@column@fullflexible{% + \lst@column@flexible + \def\lst@OutputLostSpace{\lst@ifnewline \lst@UseLostSpace\fi}% + \let\lst@leftinsert\@empty + \let\lst@rightinsert\@empty} +% \end{macrocode} +% \end{macro} +% +% So far the column formats. Now we define macros to use them. +% +% \begin{macro}{\lst@outputpos} +% This macro sets the `output-box-positioning' parameter (the old key +% \keyname{outputpos}). We test for |l|, |c| and |r|. +% The fixed formats use |\lst@lefthss| and |\lst@righthss|, whereas the +% flexibles need |\lst@leftinsert| and |\lst@rightinsert|. +% \begin{macrocode} +\def\lst@outputpos#1#2\relax{% + \def\lst@lefthss{\lst@hss}\let\lst@righthss\lst@lefthss + \let\lst@rightinsert\lst@InsertLostSpace + \ifx #1c% + \let\lst@leftinsert\lst@InsertHalfLostSpace + \else\ifx #1r% + \let\lst@righthss\@empty + \let\lst@leftinsert\lst@InsertLostSpace + \let\lst@rightinsert\@empty + \else + \let\lst@lefthss\@empty + \let\lst@leftinsert\@empty + \ifx #1l\else \PackageWarning{Listings}% + {Unknown positioning for output boxes}% + \fi + \fi\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ifflexible} +% indicates the column mode but does not distinguish between different fixed +% or flexible modes. +% \begin{macrocode} +\def\lst@flexibletrue{\let\lst@ifflexible\iftrue} +\def\lst@flexiblefalse{\let\lst@ifflexible\iffalse} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{columns} +% This is done here: check optional parameter and then build the control +% sequence of the column format. +% \begin{macrocode} +\lst@Key{columns}{[c]fixed}{\lstKV@OptArg[]{#1}{% + \ifx\@empty##1\@empty\else \lst@outputpos##1\relax\relax \fi + \expandafter\let\expandafter\lst@arg + \csname\@lst @column@##2\endcsname +% \end{macrocode} +% We issue a warning or save the definition for later. +% \begin{macrocode} + \lst@arg + \ifx\lst@arg\relax + \PackageWarning{Listings}{Unknown column format `##2'}% + \else + \lst@ifflexible + \let\lst@columnsflexible\lst@arg + \else + \let\lst@columnsfixed\lst@arg + \fi + \fi}} +% \end{macrocode} +% \begin{macrocode} +\let\lst@columnsfixed\lst@column@fixed % init +\let\lst@columnsflexible\lst@column@flexible % init +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{flexiblecolumns} +% Nothing else but a key to switch between the last flexible and fixed mode. +% \begin{macrocode} +\lst@Key{flexiblecolumns}\relax[t]{% + \lstKV@SetIf{#1}\lst@ifflexible + \lst@ifflexible \lst@columnsflexible + \else \lst@columnsfixed \fi} +% \end{macrocode} +% \end{lstkey} +% +% +% \subsection{New lines} +% +% \begin{macro}{\lst@newlines} +% This counter holds the number of `new lines' (cr+lf) we have to perform. +% \begin{macrocode} +\newcount\lst@newlines +\lst@AddToHook{InitVars}{\global\lst@newlines\z@} +\lst@AddToHook{InitVarsBOL}{\global\advance\lst@newlines\@ne} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@NewLine} +% This is how we start a new line: begin new paragraph and output an empty +% box. If low-level definition |\lst@OutputBox| just gobbles the box , we +% don't start a new line. This is used to drop the whole output. +% \begin{macrocode} +\def\lst@NewLine{% + \ifx\lst@OutputBox\@gobble\else + \par\noindent \hbox{}% + \fi + \global\advance\lst@newlines\m@ne + \lst@newlinetrue} +% \end{macrocode} +% Define |\lst@newlinetrue| and reset if after output. +% \begin{macrocode} +\def\lst@newlinetrue{\global\let\lst@ifnewline\iftrue} +\lst@AddToHookExe{PostOutput}{\global\let\lst@ifnewline\iffalse}% init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@TrackNewLines} +% If |\lst@newlines| is positive, we execute the hook and insert the +% new lines. +% \begin{macrocode} +\def\lst@TrackNewLines{% + \ifnum\lst@newlines>\z@ + \lsthk@OnNewLine + \lst@DoNewLines + \fi} +\lst@AddToHook{OnNewLine}{}% init +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{emptylines} +% \lsthelper{Adam~Prugel-Bennett}{2001/02/19}{spacing of empty lines} asked for +% such a key---if I didn't misunderstood him. We check for the optional star +% and set |\lst@maxempty| and switch. +% \begin{macrocode} +\lst@Key{emptylines}\maxdimen{% + \@ifstar{\lst@true\@tempcnta\@gobble#1\relax\lst@GobbleNil}% + {\lst@false\@tempcnta#1\relax\lst@GobbleNil}#1\@nil + \advance\@tempcnta\@ne + \edef\lst@maxempty{\the\@tempcnta\relax}% + \let\lst@ifpreservenumber\lst@if} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@DoNewLines} +% First we take care of |\lst@maxempty| and then of the remaining empty lines. +% \begin{macrocode} +\def\lst@DoNewLines{ + \@whilenum\lst@newlines>\lst@maxempty \do + {\lst@ifpreservenumber + \lsthk@OnEmptyLine + \global\advance\c@lstnumber\lst@advancelstnum + \fi + \global\advance\lst@newlines\m@ne}% + \@whilenum \lst@newlines>\@ne \do + {\lsthk@OnEmptyLine \lst@NewLine}% + \ifnum\lst@newlines>\z@ \lst@NewLine \fi} +\lst@AddToHook{OnEmptyLine}{}% init +% \end{macrocode} +% \end{macro} +% +% +% \subsection{High-level output} +% +% \begin{lstkey}{identifierstyle} +% A simple key. +% \begin{macrocode} +\lst@Key{identifierstyle}{}{\def\lst@identifierstyle{#1}} +\lst@AddToHook{EmptyStyle}{\let\lst@identifierstyle\@empty} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@GotoTabStop} +% Here we look whether the line already contains printed characters. +% If true, we output a box with the width of a blank space. +% \begin{macrocode} +\def\lst@GotoTabStop{% + \ifnum\lst@newlines=\z@ + \setbox\@tempboxa\hbox{\lst@outputspace}% + \setbox\@tempboxa\hbox to\wd\@tempboxa{{\lst@currstyle{\hss}}}% + \lst@CalcLostSpaceAndOutput +% \end{macrocode} +% It's probably not clear why it is sufficient to output a single space to go +% to the next tabulator stop. Just note that the space lost by this process is +% `lost space' in the sense above and therefore will be inserted before the +% next characters are output. +% \begin{macrocode} + \else +% \end{macrocode} +% Otherwise (no printed characters) we only need to advance |\lst@lostspace|, +% which is inserted by |\lst@OutputToken| above, and update the column. +% \begin{macrocode} + \global\advance\lst@lostspace \lst@length\lst@width + \global\advance\lst@column\lst@length \lst@length\z@ + \fi} +% \end{macrocode} +% Note that this version works also in flexible column mode. +% In fact, it's mainly the flexible version of \packagename{listings} 0.20. +% \begin{TODO} +% Use |\lst@ifnewline| instead of |\ifnum\lst@newlines=\z@|? +% \end{TODO} +% \end{macro} +% +% \begin{macro}{\lst@OutputOther} +% becomes easy with the previous definitions. +% \begin{macrocode} +\def\lst@OutputOther{% + \lst@CheckDelay + \ifnum\lst@length=\z@\else + \let\lst@thestyle\lst@currstyle + \lsthk@OutputOther + \lst@OutputToken + \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{OutputOther}{}% init +\let\lst@currstyle\relax % init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Output} +% We might use identifier style as default. +% \begin{macrocode} +\def\lst@Output{% + \lst@CheckDelay + \ifnum\lst@length=\z@\else + \ifx\lst@currstyle\relax + \let\lst@thestyle\lst@identifierstyle + \else + \let\lst@thestyle\lst@currstyle + \fi + \lsthk@Output + \lst@OutputToken + \fi + \let\lst@lastother\relax} +% \end{macrocode} +% Note that |\lst@lastother| becomes equivalent to |\relax| and not equivalent +% to |\@empty| as everywhere else. I don't know whether this will be important +% in the future or not. +% \begin{macrocode} +\lst@AddToHook{Output}{}% init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@GetOutputMacro} +% Just saves the output macro to be used. +% \begin{macrocode} +\def\lst@GetOutputMacro#1{% + \lst@ifletter \global\let#1\lst@Output + \else \global\let#1\lst@OutputOther\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@PrintToken} +% outputs the current character string in letter or nonletter mode. +% \begin{macrocode} +\def\lst@PrintToken{% + \lst@ifletter \lst@Output \lst@letterfalse + \else \lst@OutputOther \let\lst@lastother\@empty \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@XPrintToken} +% is a special definition to print also merged characters. +% \begin{macrocode} +\def\lst@XPrintToken{% + \lst@PrintToken \lst@CheckMerge + \ifnum\lst@length=\z@\else \lst@PrintToken \fi} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Dropping the whole output} +% +% \begin{macro}{\lst@BeginDropOutput} +% It's sometimes useful to process a part of a listing as usual, but to drop +% the output. This macro does the main work and gets one argument, namely the +% internal mode it enters. We save |\lst@newlines|, restore it |\aftergroup| +% and redefine one macro, namely |\lst@OutputBox|. After a bug report from +% \lsthelper{Gunther~Schmidl}{2002/02/27}{collapsing empty lines don't work +% with printpod=false} +% \begin{macrocode} +\def\lst@BeginDropOutput#1{% + \xdef\lst@BDOnewlines{\the\lst@newlines}% + \global\let\lst@BDOifnewline\lst@ifnewline + \lst@EnterMode{#1}% + {\lst@modetrue + \let\lst@OutputBox\@gobble + \aftergroup\lst@BDORestore}} +% \end{macrocode} +% Restoring the date is quite easy: +% \begin{macrocode} +\def\lst@BDORestore{% + \global\lst@newlines\lst@BDOnewlines + \global\let\lst@ifnewline\lst@BDOifnewline} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EndDropOutput} +% is equivalent to |\lst@LeaveMode|. +% \begin{macrocode} +\let\lst@EndDropOutput\lst@LeaveMode +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Writing to an external file} +% +% \begin{aspect}{writefile} +% Now it would be good to know something about character classes since we need +% to access the true input characters, for example a tabulator and not the +% spaces it `expands' to. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{writefile} +% \end{macrocode} +% +% \begin{macro}{\lst@WF} +% \begin{macro}{\lst@WFtoken} +% The contents of the token will be written to file. +% \begin{macrocode} +\newtoks\lst@WFtoken % global +\lst@AddToHook{InitVarsBOL}{\global\lst@WFtoken{}} +% \end{macrocode} +% \begin{macrocode} +\newwrite\lst@WF +\global\let\lst@WFifopen\iffalse % init +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@WFWriteToFile} +% To do this, we have to expand the contents and then expand this via |\edef|. +% Empty |\lst@UM| ensures that special characters (underscore, dollar, etc.) +% are written correctly. +% \begin{macrocode} +\gdef\lst@WFWriteToFile{% + \begingroup + \let\lst@UM\@empty + \expandafter\edef\expandafter\lst@temp\expandafter{\the\lst@WFtoken}% + \immediate\write\lst@WF{\lst@temp}% + \endgroup + \global\lst@WFtoken{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@WFAppend} +% Similar to |\lst@Append| but uses |\lst@WFtoken|. +% \begin{macrocode} +\gdef\lst@WFAppend#1{% + \global\lst@WFtoken=\expandafter{\the\lst@WFtoken#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@BeginWriteFile} +% \begin{macro}{\lst@BeginAlsoWriteFile} +% use different macros for |\lst@OutputBox| (not) to drop the output. +% \begin{macrocode} +\gdef\lst@BeginWriteFile{\lst@WFBegin\@gobble} +\gdef\lst@BeginAlsoWriteFile{\lst@WFBegin\lst@OutputBox} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@WFBegin} +% Here \ldots +% \begin{macrocode} +\begingroup \catcode`\^^I=11 +\gdef\lst@WFBegin#1#2{% + \begingroup + \let\lst@OutputBox#1% +% \end{macrocode} +% \ldots\space we have to update |\lst@WFtoken| and \ldots +% \begin{macrocode} + \def\lst@Append##1{% + \advance\lst@length\@ne + \expandafter\lst@token\expandafter{\the\lst@token##1}% + \ifx ##1\lst@outputspace \else + \lst@WFAppend##1% + \fi}% + \lst@lAddTo\lst@PreGotoTabStop{\lst@WFAppend{^^I}}% + \lst@lAddTo\lst@ProcessSpace{\lst@WFAppend{ }}% +% \end{macrocode} +% \ldots\space need different `EOL' and `DeInit' definitions to write the +% token register to file. +% \begin{macrocode} + \let\lst@DeInit\lst@WFDeInit + \let\lst@MProcessListing\lst@WFMProcessListing +% \end{macrocode} +% Finally we open the file if necessary. +% \begin{macrocode} + \lst@WFifopen\else + \immediate\openout\lst@WF=#2\relax + \global\let\lst@WFifopen\iftrue + \@gobbletwo\fi\fi + \fi} +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EndWriteFile} +% closes the file and restores original definitions. +% \begin{macrocode} +\gdef\lst@EndWriteFile{% + \immediate\closeout\lst@WF \endgroup + \global\let\lst@WFifopen\iffalse} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@WFMProcessListing} +% \begin{macro}{\lst@WFDeInit} +% write additionally |\lst@WFtoken| to external file. +% \begin{macrocode} +\global\let\lst@WFMProcessListing\lst@MProcessListing +\global\let\lst@WFDeInit\lst@DeInit +\lst@AddToAtTop\lst@WFMProcessListing{\lst@WFWriteToFile} +\lst@AddToAtTop\lst@WFDeInit{% + \ifnum\lst@length=\z@\else \lst@WFWriteToFile \fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \section{Character classes}\label{iCharacterClasses} +% +% In this section, we define how the basic character classes do behave, before +% turning over to the selection of character tables and how to specialize +% characters. +% +% +% \subsection{Letters, digits and others} +% +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% +% \begin{macro}{\lst@ProcessLetter} +% We put the letter, which is not a whitespace, into the output queue. +% \begin{macrocode} +\def\lst@ProcessLetter{\lst@whitespacefalse \lst@AppendLetter} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ProcessOther} +% Ditto. +% \begin{macrocode} +\def\lst@ProcessOther{\lst@whitespacefalse \lst@AppendOther} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ProcessDigit} +% A digit appends the character to the current character string. But we must +% use the right macro. This allows digits to be part of an identifier or +% a numerical constant. +% \begin{macrocode} +\def\lst@ProcessDigit{% + \lst@whitespacefalse + \lst@ifletter \expandafter\lst@AppendLetter + \else \expandafter\lst@AppendOther\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ifwhitespace} +% indicates whether the last processed character has been white space. +% \begin{macrocode} +\def\lst@whitespacetrue{\global\let\lst@ifwhitespace\iftrue} +\def\lst@whitespacefalse{\global\let\lst@ifwhitespace\iffalse} +\lst@AddToHook{InitVarsBOL}{\lst@whitespacetrue} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Whitespaces} +% +% Here we have to take care of two things: dropping empty lines at the end of +% a listing and the different column formats. Both use |\lst@lostspace|. Lines +% containing only tabulators and spaces should be viewed as empty. In order to +% achieve this, tabulators and spaces at the beginning of a line don't output +% any characters but advance |\lst@lostspace|. Whenever this dimension is +% positive we insert that space before the character string is output. Thus, +% if there are only tabulators and spaces, the line is `empty' since we +% haven't done any output. +% +% We have to do more for flexible columns. Whitespaces can fix the column +% alignment: if the real line is wider than expected, a tabulator is at least +% one space wide; all remaining space fixes the alignment. If there are two or +% more space characters, at least one is printed; the others fix the column +% alignment. +% +% +% \paragraph{Tabulators} +% are processed in three stages. You have already seen the last stage +% |\lst@GotoTabStop|. The other two calculate the necessary width and take care +% of visible tabulators and spaces. +% +% \begin{lstkey}{tabsize} +% We check for a legal argument before saving it. Default tabsize is 8 as +% proposed by \lsthelper{Rolf~Niepraschk}{1997/04/24}{tabsize=8}. +% \begin{macrocode} +\lst@Key{tabsize}{8} + {\ifnum#1>\z@ \def\lst@tabsize{#1}\else + \PackageError{Listings}{Strict positive integer expected}% + {You can't use `#1' as tabsize. \@ehc}% + \fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{showtabs} +% \begin{lstkey}{tab} +% Two more user keys for tab control. +% \begin{macrocode} +\lst@Key{showtabs}f[t]{\lstKV@SetIf{#1}\lst@ifshowtabs} +\lst@Key{tab}{\kern.06em\hbox{\vrule\@height.3ex}% + \hrulefill\hbox{\vrule\@height.3ex}} + {\def\lst@tab{#1}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@ProcessTabulator} +% A tabulator outputs the preceding characters, which decrements |\lst@pos| by +% the number of printed characters. +% \begin{macrocode} +\def\lst@ProcessTabulator{% + \lst@XPrintToken \lst@whitespacetrue +% \end{macrocode} +% Then we calculate how many columns we need to reach the next tabulator stop: +% we add |\lst@tabsize| until |\lst@pos| is strict positive. In other words, +% |\lst@pos| is the column modulo |tabsize| and we're looking for a positive +% representative. We assign it to |\lst@length| and reset |\lst@pos| in the +% submacro. +% \begin{macrocode} + \global\advance\lst@column -\lst@pos + \@whilenum \lst@pos<\@ne \do + {\global\advance\lst@pos\lst@tabsize}% + \lst@length\lst@pos + \lst@PreGotoTabStop} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@PreGotoTabStop} +% Visible tabs print |\lst@tab|. +% \begin{macrocode} +\def\lst@PreGotoTabStop{% + \lst@ifshowtabs + \lst@TrackNewLines + \setbox\@tempboxa\hbox to\lst@length\lst@width + {{\lst@currstyle{\hss\lst@tab}}}% + \lst@CalcLostSpaceAndOutput + \else +% \end{macrocode} +% If we are advised to keep spaces, we insert the correct number of them. +% \begin{macrocode} + \lst@ifkeepspaces + \@tempcnta\lst@length \lst@length\z@ + \@whilenum \@tempcnta>\z@ \do + {\lst@AppendOther\lst@outputspace + \advance\@tempcnta\m@ne}% + \lst@OutputOther + \else + \lst@GotoTabStop + \fi + \fi + \lst@length\z@ \global\lst@pos\z@} +% \end{macrocode} +% \end{macro} +% +% +% \paragraph{Spaces} +% are implemented as described at the beginning of this subsection. But first +% we define some user keys. +% +% \begin{macro}{\lst@outputspace} +% \begin{macro}{\lst@visiblespace} +% The first macro is a default definition, \ldots +% \begin{macrocode} +\def\lst@outputspace{\ } +\def\lst@visiblespace{\lst@ttfamily{\char32}\textvisiblespace} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{lstkey}{showspaces} +% \begin{lstkey}{keepspaces} +% \ldots\space which is modified on user's request. +% \begin{macrocode} +\lst@Key{showspaces}{false}[t]{\lstKV@SetIf{#1}\lst@ifshowspaces} +\lst@Key{keepspaces}{false}[t]{\lstKV@SetIf{#1}\lst@ifkeepspaces} +\lst@AddToHook{Init} + {\lst@ifshowspaces + \let\lst@outputspace\lst@visiblespace + \lst@keepspacestrue + \fi} +\def\lst@keepspacestrue{\let\lst@ifkeepspaces\iftrue} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@ProcessSpace} +% We look whether spaces fix the column alignment or not. In the latter case +% we append a space; otherwise \ldots +% \begin{macrocode} +\def\lst@ProcessSpace{% + \lst@ifkeepspaces + \lst@AppendOther\lst@outputspace + \else \ifnum\lst@newlines=\z@ +% \end{macrocode} +% \ldots\space we append a `special space' if the line isn't empty. +% \begin{macrocode} + \lst@AppendSpecialSpace + \else \ifnum\lst@length=\z@ +% \end{macrocode} +% If the line is empty, we check whether there are characters in the output +% queue. If there are no characters we just advance |\lst@lostspace|. +% Otherwise we append the space. +% \begin{macrocode} + \global\advance\lst@lostspace\lst@width + \global\advance\lst@pos\m@ne + \else + \lst@AppendSpecialSpace + \fi + \fi \fi + \lst@whitespacetrue} +% \end{macrocode} +% Note that this version works for fixed and flexible column output. +% \end{macro} +% +% \begin{macro}{\lst@AppendSpecialSpace} +% If there are at least two white spaces, we output preceding characters and +% advance |\lst@lostspace| to avoid alignment problems. Otherwise we append +% a space to the current character string. +% \begin{macrocode} +\def\lst@AppendSpecialSpace{% + \lst@ifwhitespace + \lst@PrintToken + \global\advance\lst@lostspace\lst@width + \global\advance\lst@pos\m@ne + \else + \lst@AppendOther\lst@outputspace + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \paragraph{Form feeds} +% has been introduced after communication with +% \lsthelper{Jan~Braun}{1998/04/27}{formfeed}. +% +% \begin{lstkey}{formfeed} +% let the user make adjustments. +% \begin{macrocode} +\lst@Key{formfeed}{\bigbreak}{\def\lst@formfeed{#1}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@ProcessFormFeed} +% Here we execute some macros according to whether a new line has already +% begun or not. No |\lst@EOLUpdate| is used in the else branch +% anymore---\lsthelper{Kalle~Tuulos}{2001/01/14}{form feed gobbles following +% output unit} sent the bug report. +% \begin{macrocode} +\def\lst@ProcessFormFeed{% + \lst@XPrintToken + \ifnum\lst@newlines=\z@ + \lst@EOLUpdate \lsthk@InitVarsBOL + \fi + \lst@formfeed + \lst@whitespacetrue} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Character tables}\label{iCharacterTables} +% +% +% \subsubsection{The standard table} +% +% The standard character table is selected by |\lst@SelectStdCharTable|, which +% expands to a token sequence +% \ldots|\def| |A{\lst@ProcessLetter| |A}|\ldots\space +% where the first A is active and the second has catcode 12. We use the +% following macros to build the character table. +% \begin{syntax} +% \item[0.19] |\lst@CCPut|\meta{class macro}\meta{$c_1$}\ldots\meta{$c_k$}|\z@| +% +% extends the standard character table by the characters with codes +% \meta{$c_1$}\ldots\meta{$c_k$} making each character use +% \meta{class macro}. All these characters must be printable via +% |\char|\meta{$c_i$}. +% +% \item[0.20] |\lst@CCPutMacro|\meta{class$_1$}\meta{$c_1$}\meta{definition$_1$}\ldots|\@empty\z@\@empty| +% +% also extends the standard character table: the character \meta{$c_i$} +% will use \meta{class$_i$} and is printed via \meta{definition$_i$}. +% These definitions must be \meta{spec. token}s in the sense of section +% \ref{dCharacterTables}. +% \end{syntax} +% +% \begin{macro}{\lst@Def} +% \begin{macro}{\lst@Let} +% For speed we won't use these helpers too often. +% \begin{macrocode} +\def\lst@Def#1{\lccode`\~=#1\lowercase{\def~}} +\def\lst@Let#1{\lccode`\~=#1\lowercase{\let~}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begingroup +% The definition of the space below doesn't hurt anything. But other aspects, +% for example \aspectname{lineshape} and \aspectname{formats}, redefine also +% the macro |\space|. Now, if \LaTeX\ calls |\try@load@fontshape|, the |.log| +% messages would show some strange things since \LaTeX\ uses |\space| in these +% messages. The following addition ensures that |\space| expands to a space +% and not to something different. This was one more bug reported by +% \lsthelper{Denis~Girou}{1999/09/16}{bad font info message with breaklines}. +% \begin{macrocode} +\lst@AddToAtTop{\try@load@fontshape}{\def\space{ }} +% \end{macrocode} +% \endgroup +% +% \begin{macro}{\lst@SelectStdCharTable} +% The first three standard characters. |\lst@Let| has been replaced by +% |\lst@Def| after a bug report from \lsthelper{Chris~Edwards}{2002/02/15} +% {tabulators show up with firstline>1}. +% \begin{macrocode} +\def\lst@SelectStdCharTable{% + \lst@Def{9}{\lst@ProcessTabulator}% + \lst@Def{12}{\lst@ProcessFormFeed}% + \lst@Def{32}{\lst@ProcessSpace}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CCPut} +% The first argument gives the character class, then follow the codes. +% \begin{macrocode} +\def\lst@CCPut#1#2{% + \ifnum#2=\z@ + \expandafter\@gobbletwo + \else + \lccode`\~=#2\lccode`\/=#2\lowercase{\lst@CCPut@~{#1/}}% + \fi + \lst@CCPut#1} +\def\lst@CCPut@#1#2{\lst@lAddTo\lst@SelectStdCharTable{\def#1{#2}}} +% \end{macrocode} +% Now we insert more standard characters. +% \begin{macrocode} +\lst@CCPut \lst@ProcessOther + {"21}{"22}{"27}{"28}{"29}{"2B}{"2C}{"2E}{"2F} + {"3A}{"3B}{"3D}{"3F}{"5B}{"5D}{"60} + \z@ +\lst@CCPut \lst@ProcessDigit + {"30}{"31}{"32}{"33}{"34}{"35}{"36}{"37}{"38}{"39} + \z@ +\lst@CCPut \lst@ProcessLetter + {"40}{"41}{"42}{"43}{"44}{"45}{"46}{"47} + {"48}{"49}{"4A}{"4B}{"4C}{"4D}{"4E}{"4F} + {"50}{"51}{"52}{"53}{"54}{"55}{"56}{"57} + {"58}{"59}{"5A} + {"61}{"62}{"63}{"64}{"65}{"66}{"67} + {"68}{"69}{"6A}{"6B}{"6C}{"6D}{"6E}{"6F} + {"70}{"71}{"72}{"73}{"74}{"75}{"76}{"77} + {"78}{"79}{"7A} + \z@ +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CCPutMacro} +% Now we come to a delicate point. The characters not inserted yet aren't +% printable (|_|, |$|, \ldots) or aren't printed well (|*|, |-|, \ldots) if we +% enter these characters. Thus we use proper macros to print the characters. +% Works perfectly. The problem is that the current character string is +% printable for speed, for example |_| is already replaced by a macro version, +% but the new keyword tests need the original characters. +% +% The solution: We define |\def _{\lst@ProcessLetter\lst@um_}| where the first +% underscore is active and the second belongs to the control sequence. +% Moreover we have |\def\lst@um_{\lst@UM _}| where the second underscore has +% the usual meaning. Now the keyword tests can access the original character +% simply by making |\lst@UM| empty. The default definition gets the following +% token and builds the control sequence |\lst@um_@|, which we'll define to +% print the character. Easy, isn't it?^^A ;-) +% +% The following definition does all this for us. The first parameter gives the +% character class, the second the character code, and the last the definition +% which actually prints the character. We build the names |\lst@um_| and +% |\lst@um_@| and give them to a submacro. +% \begin{macrocode} +\def\lst@CCPutMacro#1#2#3{% + \ifnum#2=\z@ \else + \begingroup\lccode`\~=#2\relax \lccode`\/=#2\relax + \lowercase{\endgroup\expandafter\lst@CCPutMacro@ + \csname\@lst @um/\expandafter\endcsname + \csname\@lst @um/@\endcsname /~}#1{#3}% + \expandafter\lst@CCPutMacro + \fi} +% \end{macrocode} +% The arguments are now |\lst@um_|, |\lst@um_@|, nonactive character, active +% character, character class and printing definition. We add |\def _{| +% |\lst@ProcessLetter| |\lst@um_}| to |\lst@SelectStdCharTable| (and similarly +% other special characters), define |\def\lst@um_{\lst@UM _}| and |\lst@um_@|. +% \begin{macrocode} +\def\lst@CCPutMacro@#1#2#3#4#5#6{% + \lst@lAddTo\lst@SelectStdCharTable{\def#4{#5#1}}% + \def#1{\lst@UM#3}% + \def#2{#6}} +% \end{macrocode} +% The default definition of |\lst@UM|: +% \begin{macrocode} +\def\lst@UM#1{\csname\@lst @um#1@\endcsname} +% \end{macrocode} +% And all remaining standard characters. +% \begin{macrocode} +\lst@CCPutMacro + \lst@ProcessOther {"23}\# + \lst@ProcessLetter{"24}\textdollar + \lst@ProcessOther {"25}\% + \lst@ProcessOther {"26}\& + \lst@ProcessOther {"2A}{\lst@ttfamily*\textasteriskcentered} + \lst@ProcessOther {"2D}{\lst@ttfamily{-{}}{$-$}} + \lst@ProcessOther {"3C}{\lst@ttfamily<\textless} + \lst@ProcessOther {"3E}{\lst@ttfamily>\textgreater} + \lst@ProcessOther {"5C}{\lst@ttfamily{\char92}\textbackslash} + \lst@ProcessOther {"5E}\textasciicircum + \lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}\textunderscore} + \lst@ProcessOther {"7B}{\lst@ttfamily{\char123}\textbraceleft} + \lst@ProcessOther {"7C}{\lst@ttfamily|\textbar} + \lst@ProcessOther {"7D}{\lst@ttfamily{\char125}\textbraceright} + \lst@ProcessOther {"7E}\textasciitilde + \lst@ProcessOther {"7F}- + \@empty\z@\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ttfamily} +% What is this ominous macro? It prints either the first or the second +% argument. In |\ttfamily| it ensures that |----| is typeset |----| and not +% $-$$-$$-$$-$ as in version 0.17. Bug encountered by +% \lsthelper{Dr.~Jobst~Hoffmann}{1998/03/30}{|\lst@minus| and |\ttfamily|}. +% Furthermore I added |\relax| after receiving an error report from +% \lsthelper{Magnus~Lewis-Smith}{1999/08/06}{! Bad character code (920).} +% \begin{macrocode} +\def\lst@ttfamily#1#2{\ifx\f@family\ttdefault#1\relax\else#2\fi} +% \end{macrocode} +% |\ttdefault| is defined |\long|, so the |\ifx| doesn't work since |\f@family| +% isn't |\long|! We go around this problem by redefining |\ttdefault| locally: +% \begin{macrocode} +\lst@AddToHook{Init}{\edef\ttdefault{\ttdefault}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ifactivechars} +% A simple switch. +% \begin{macrocode} +\def\lst@activecharstrue{\let\lst@ifactivechars\iftrue} +\def\lst@activecharsfalse{\let\lst@ifactivechars\iffalse} +\lst@activecharstrue +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@SelectCharTable} +% We select the standard character table and switch to active catcodes. +% \begin{macrocode} +\def\lst@SelectCharTable{% + \lst@SelectStdCharTable + \lst@ifactivechars + \catcode9\active \catcode12\active \catcode13\active + \@tempcnta=32\relax + \@whilenum\@tempcnta<128\do + {\catcode\@tempcnta\active\advance\@tempcnta\@ne}% + \fi + \lst@ifec \lst@DefEC \fi +% \end{macrocode} +% The following line and the according macros below have been added after a +% bug report from \lsthelper{Fr\'ed\'eric~Boulanger}{2001/02/27}{ligatures}. +% \begin{macrocode} + \let\do@noligs\lst@do@noligs \verbatim@nolig@list +% \end{macrocode} +% There are two ways to adjust the standard table: inside the hook or with +% |\lst@DeveloperSCT|. We use these macros and initialize the backslash if +% necessary. +% \begin{macrocode} + \lsthk@SelectCharTable + \lst@DeveloperSCT + \ifx\lst@Backslash\relax\else + \lst@LetSaveDef{"5C}\lsts@backslash\lst@Backslash + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{SelectCharTable} +% \begin{lstkey}{MoreSelectCharTable} +% The keys to adjust |\lst@DeveloperSCT|. +% \begin{macrocode} +\lst@Key{SelectCharTable}{}{\def\lst@DeveloperSCT{#1}} +\lst@Key{MoreSelectCharTable}\relax{\lst@lAddTo\lst@DeveloperSCT{#1}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{SetLanguage}{\let\lst@DeveloperSCT\@empty} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@do@noligs} +% To prevent ligatures, this macro inserts the token |\lst@NoLig| in front of +% |\lst@Process|\meta{whatever}\meta{spec.~token}. This is done by +% |\verbatim@nolig@list| for certain characters. Note that the submacro is +% a special kind of a local |\lst@AddToAtTop|. +% \begin{macrocode} +\def\lst@do@noligs#1{% + \begingroup \lccode`\~=`#1\lowercase{\endgroup + \lst@do@noligs@~}} +\def\lst@do@noligs#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\lst@NoLig#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@NoLig} +% When this extra macro is processed, it adds |\lst@nolig| to the output queue +% without increasing its length. For keyword detection this must expand to +% nothing if |\lst@UM| is empty. +% \begin{macrocode} +\def\lst@NoLig{\advance\lst@length\m@ne \lst@Append\lst@nolig} +\def\lst@nolig{\lst@UM\@empty}% +% \end{macrocode} +% But the usual meaning of |\lst@UM| builds the following control sequence, +% which prevents ligatures in the manner of \LaTeX's |\do@noligs|. +% \begin{macrocode} +\@namedef{\@lst @um@}{\leavevmode\kern\z@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@SaveOutputDef} +% To get the \meta{spec.~token} meaning of character |#1|, we look for |\def| +% `active character |#1|' in |\lst@SelectStdCharTable|, get the replacement +% text, strip off the character class via |\@gobble|, and assign the meaning. +% Note that you get a ``runaway argument'' error if an illegal \meta{character +% code}=|#1| is used. +% \begin{macrocode} +\def\lst@SaveOutputDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup + \def\lst@temp##1\def~##2##3\relax}{% + \global\expandafter\let\expandafter#2\@gobble##2\relax}% + \expandafter\lst@temp\lst@SelectStdCharTable\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstum@backslash} +% A commonly used character. +% \begin{macrocode} +\lst@SaveOutputDef{"5C}\lstum@backslash +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{National characters} +% +% \begin{lstkey}{extendedchars} +% The user key to activate extended characters 128--255. +% \begin{macrocode} +\lst@Key{extendedchars}{false}[t]{\lstKV@SetIf{#1}\lst@ifec} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@DefEC} +% Currently each character in the range 128--255 is treated as a letter. +% \begin{macrocode} +\def\lst@DefEC{% + \lst@CCECUse \lst@ProcessLetter + ^^80^^81^^82^^83^^84^^85^^86^^87^^88^^89^^8a^^8b^^8c^^8d^^8e^^8f% + ^^90^^91^^92^^93^^94^^95^^96^^97^^98^^99^^9a^^9b^^9c^^9d^^9e^^9f% + ^^a0^^a1^^a2^^a3^^a4^^a5^^a6^^a7^^a8^^a9^^aa^^ab^^ac^^ad^^ae^^af% + ^^b0^^b1^^b2^^b3^^b4^^b5^^b6^^b7^^b8^^b9^^ba^^bb^^bc^^bd^^be^^bf% + ^^c0^^c1^^c2^^c3^^c4^^c5^^c6^^c7^^c8^^c9^^ca^^cb^^cc^^cd^^ce^^cf% + ^^d0^^d1^^d2^^d3^^d4^^d5^^d6^^d7^^d8^^d9^^da^^db^^dc^^dd^^de^^df% + ^^e0^^e1^^e2^^e3^^e4^^e5^^e6^^e7^^e8^^e9^^ea^^eb^^ec^^ed^^ee^^ef% + ^^f0^^f1^^f2^^f3^^f4^^f5^^f6^^f7^^f8^^f9^^fa^^fb^^fc^^fd^^fe^^ff% + ^^00} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CCECUse} +% Reaching end of list (|^^00|) we terminate the loop. +% Otherwise we do the same as in |\lst@CCPut| if the character is not active. +% But if the character is active, we save the meaning before redefinition. +% \begin{macrocode} +\def\lst@CCECUse#1#2{% + \ifnum`#2=\z@ + \expandafter\@gobbletwo + \else + \ifnum\catcode`#2=\active + \lccode`\~=`#2\lccode`\/=`#2\lowercase{\lst@CCECUse@#1~/}% + \else + \lst@ifactivechars \catcode`#2=\active \fi + \lccode`\~=`#2\lccode`\/=`#2\lowercase{\def~{#1/}}% + \fi + \fi + \lst@CCECUse#1} +% \end{macrocode} +% We save the meaning as mentioned. Here we must also use the `|\lst@UM| +% construction' since extended characters could often appear in words = +% identifiers. Bug reported by \lsthelper{Denis~Girou}{1999/07/26} +% {incompatibility with inputenc}. +% \begin{macrocode} +\def\lst@CCECUse@#1#2#3{% + \expandafter\def\csname\@lst @EC#3\endcsname{\lst@UM#3}% + \expandafter\let\csname\@lst @um#3@\endcsname #2% + \edef#2{\noexpand#1% + \expandafter\noexpand\csname\@lst @EC#3\endcsname}} +% \end{macrocode} +% \lsthelper{Daniel~Gerigk}{2001/10/25}{extendedchars do not work} and +% \lsthelper{Heiko~Oberdiek}{2001/10/26}{extendedchars do not work: um@\#3@ +% must be @um\#3@} reported an error and a solution, respectively. +% \end{macro} +% +% +% \subsubsection{Catcode problems} +% +% \begin{macro}{\lst@nfss@catcodes} +% \lsthelper{Anders~Edenbrandt}{1997/04/22}{preload of .fd files} found a bug +% with \texttt{.fd}-files. Since we change catcodes and these files are read +% on demand, we must reset the catcodes before the files are input. We use a +% local redefinition of |\nfss@catcodes|. +% \begin{macrocode} +\lst@AddToHook{Init} + {\let\lsts@nfss@catcodes\nfss@catcodes + \let\nfss@catcodes\lst@nfss@catcodes} +% \end{macrocode} +% \begin{macrocode} +\def\lst@nfss@catcodes{% + \lst@makeletter + ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\relax + \@makeother 0\@makeother 1\@makeother 2\@makeother 3\@makeother 4% + \@makeother 5\@makeother 6\@makeother 7\@makeother 8\@makeother 9% + \@makeother =\lsts@nfss@catcodes} +% \end{macrocode} +% The investigation of a bug reported by \lsthelper{Christian~Gudrian} +% {2000/11/16}{problems with mathpple} showed that the equal sign needs +% to have `other' catcode, as assigned above. +% +% The name of |\lst@makeletter| is an imitation of \LaTeX's |\@makeother|. +% \begin{macrocode} +\def\lst@makeletter#1{% + \ifx\relax#1\else\catcode`#111\relax \expandafter\lst@makeletter\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\output} +% Another problem was first reported by \lsthelper{Marcin~Kasperski} +% {1999/04/28}{listings spoil toc}. It is also catcode related and +% \lsthelper{Donald~Arseneau}{1999/05/13}{comp.text.tex Re: delayed write and +% catcode changes} let me understand it. The point is that \TeX\ seems to use +% the \emph{currently} active catcode table when it writes non-|\immediate| +% |\write|s to file and not the catcodes involved when \emph{reading} the +% characters. +% So a section heading |\L a| was written |\La| if a listing was split on two +% pages since a non-standard catcode table was in use when writing |\La| to +% file, the previously attached catcodes do not matter. One more bug was that +% accents in page headings or footers were lost when a listing was split on +% two pages. \lsthelper{Denis~Girou}{1999/08/03}{Accents lost in heading if +% listing split on two pages} found this latter bug. A similar problem with +% the tilde was reported by \lsthelper{Thorsten~Vitt}{2001/06/25}{fancyhdr + +% listings crossing pages ==> ~ in header, not space}. +% +% The solution is a local redefinition of the output routine. We interrupt the +% current modes---in particular |\lst@Pmode| with modified catcode table---, +% call the original output routine and reenter the mode. This must be done +% with a little care. First we have to close the group which \TeX\ opens at +% the beginning of the output routine. A single |\egroup| gives an `unbalanced +% output routine' error. But |\expandafter\egroup| works. Again it was +% \lsthelper{Donald~Arseneau}{2001/01/10}{comp.text.tex Re: \output puzzle} +% who gave the explaination: The |\expandafter| set the token type of |\bgroup| +% to |backed_up|, which prevents \TeX's from recovering from an unbalanced +% output routine. \lsthelper{Heiko~Oberdiek}{2001/01/05}{comp.text.tex Re: +% \output puzzle} reported that |\csname| |egroup||\endcsname| does the trick, +% too. +% +% However, since \TeX\ checks the contents of |\box| 255 when we close the +% group (`output routine didn't use all of |\box| 255'), we have to save it +% temporaryly. +% \begin{macrocode} +\lst@AddToHook{Init} +{\edef\lst@OrgOutput{\the\output}% + \output{\global\setbox\lst@gtempboxa\box\@cclv + \expandafter\egroup +% \end{macrocode} +% Now we can interrupt the mode, but we have to save the current character +% string and the current style. +% \begin{macrocode} + \lst@SaveToken + \lst@InterruptModes +% \end{macrocode} +% We restore the contents, use the original output routine, and \ldots +% \begin{macrocode} + \setbox\@cclv\box\lst@gtempboxa + \bgroup\lst@OrgOutput\egroup +% \end{macrocode} +% \ldots\space open a group matching the |}| which \TeX\ inserts at the end of +% the output routine. We reenter modes and restore the character string and +% style |\aftergroup|. Moreover we need to reset |\pagegoal|---added after a +% bug report by \lsthelper{Jochen~Schneider}{2002/03/09}{de.comp.text.tex: +% Problem mit Listings-Paket 1.0-Beta; unmotivated pagebreak with preceding +% float}. +% \begin{macrocode} + \bgroup + \aftergroup\pagegoal\aftergroup\vsize + \aftergroup\lst@ReenterModes\aftergroup\lst@RestoreToken}} +% \end{macrocode} +% Note that this output routine isn't used too often. It is executed only if +% it's possible that a listing is split on two pages: if a listing ends at +% the bottom or begins at the top of a page, or if a listing is really split. +% \end{macro} +% +% +% \subsubsection{Adjusting the table} +% +% We begin with modifiers for the basic character classes. +% +% \begin{lstkey}{alsoletter} +% \begin{lstkey}{alsodigit} +% \begin{lstkey}{alsoother} +% The macros |\lst@also|\ldots\space will hold |\def|\meta{char}|{|\ldots|}| +% sequences, which adjusts the standard character table. +% \begin{macrocode} +\lst@Key{alsoletter}\relax{% + \lst@DoAlso{#1}\lst@alsoletter\lst@ProcessLetter} +\lst@Key{alsodigit}\relax{% + \lst@DoAlso{#1}\lst@alsodigit\lst@ProcessDigit} +\lst@Key{alsoother}\relax{% + \lst@DoAlso{#1}\lst@alsoother\lst@ProcessOther} +% \end{macrocode} +% This is done at \hookname{SelectCharTable} and every language selection +% the macros get empty. +% \begin{macrocode} +\lst@AddToHook{SelectCharTable} + {\lst@alsoother \lst@alsodigit \lst@alsoletter} +\lst@AddToHookExe{SetLanguage}% init + {\let\lst@alsoletter\@empty + \let\lst@alsodigit\@empty + \let\lst@alsoother\@empty} +% \end{macrocode} +% The service macro starts a loop and \ldots +% \begin{macrocode} +\def\lst@DoAlso#1#2#3{% + \lst@DefOther\lst@arg{#1}\let#2\@empty + \expandafter\lst@DoAlso@\expandafter#2\expandafter#3\lst@arg\relax} +\def\lst@DoAlso@#1#2#3{% + \ifx\relax#3\expandafter\@gobblethree \else +% \end{macrocode} +% \ldots\space while not reaching |\relax| we use the \TeX nique from +% |\lst@SaveOutputDef| to replace the class by |#2|. Eventually we append +% the new definition to |#1|. +% \begin{macrocode} + \begingroup \lccode`\~=`#3\relax \lowercase{\endgroup + \def\lst@temp##1\def~##2##3\relax{% + \edef\lst@arg{\def\noexpand~{\noexpand#2\expandafter + \noexpand\@gobble##2}}}}% + \expandafter\lst@temp\lst@SelectStdCharTable\relax + \lst@lExtend#1{\lst@arg}% + \fi + \lst@DoAlso@#1#2} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@SaveDef} +% \begin{macro}{\lst@DefSaveDef} +% \begin{macro}{\lst@LetSaveDef} +% These macros can be used in language definitions to make special changes. +% They save the definition and define or assign a new one. +% \begin{macrocode} +\def\lst@SaveDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~}} +\def\lst@DefSaveDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~\def~}} +\def\lst@LetSaveDef#1#2{% + \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~\let~}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% Now we get to the more powerful definitions. +% +% \begin{macro}{\lst@CDef} +% Here we unfold the first parameter \meta{1st}\marg{2nd}\marg{rest} and say +% that this input string is `replaced' by \meta{save 1st}\marg{2nd}^^A +% \marg{rest}---plus \meta{execute}, \meta{pre}, and \meta{post}. This main +% work is done by |\lst@CDefIt|. +% \begin{macrocode} +\def\lst@CDef#1{\lst@CDef@#1} +\def\lst@CDef@#1#2#3#4{\lst@CDefIt#1{#2}{#3}{#4#2#3}#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CDefX} +% drops the input string. +% \begin{macrocode} +\def\lst@CDefX#1{\lst@CDefX@#1} +\def\lst@CDefX@#1#2#3{\lst@CDefIt#1{#2}{#3}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CDefIt} +% is the main working procedure for the previous macros. It redefines the +% sequence |#1#2#3| of characters. At least |#1| must be active; the other two +% arguments might be empty, not equivalent to empty! +% \begin{macrocode} +\def\lst@CDefIt#1#2#3#4#5#6#7#8{% + \ifx\@empty#2\@empty +% \end{macrocode} +% For a single character we just execute the arguments in the correct order. +% You might want to go back to section \ref{dCharacterTablesManipulated} to +% look them up. +% \begin{macrocode} + \def#1{#6\def\lst@next{#7#4#8}\lst@next}% + \else \ifx\@empty#3\@empty +% \end{macrocode} +% For a two character sequence we test whether \meta{pre} and \meta{post} +% must be executed. +% \begin{macrocode} + \def#1##1{% + #6% + \ifx##1#2\def\lst@next{#7#4#8}\else + \def\lst@next{#5##1}\fi + \lst@next}% + \else +% \end{macrocode} +% We do the same for an arbitrary character sequence---except that we have to +% use |\lst@IfNextCharsArg| instead of |\ifx|\ldots|\fi|. +% \begin{macrocode} + \def#1{% + #6% + \lst@IfNextCharsArg{#2#3}{#7#4#8}% + {\expandafter#5\lst@eaten}}% + \fi \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CArgX} +% We make |#1#2| active and call |\lst@CArg|. +% \begin{macrocode} +\def\lst@CArgX#1#2\relax{% + \lst@DefActive\lst@arg{#1#2}% + \expandafter\lst@CArg\lst@arg\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CArg} +% arranges the first two arguments for |\lst@CDef|[|X|]. We get an undefined +% macro and use |\@empty\@empty\relax| as delimiter for the submacro. +% \begin{macrocode} +\def\lst@CArg#1#2\relax{% + \lccode`\/=`#1\lowercase{\def\lst@temp{/}}% + \lst@GetFreeMacro{lst@c\lst@temp}% + \expandafter\lst@CArg@\lst@freemacro#1#2\@empty\@empty\relax} +% \end{macrocode} +% Save meaning of \meta{1st}=|#2| in \meta{save 1st}=|#1| and call the macro +% |#6| with correct arguments. From version 1.0 on, |#2|, |#3| and |#4| +% (respectively empty arguments) are tied together with group braces. +% This allows us to save two arguments in other definitions, for example in +% |\lst@DefDelimB|. +% \begin{macrocode} +\def\lst@CArg@#1#2#3#4\@empty#5\relax#6{% + \let#1#2% + \ifx\@empty#3\@empty + \def\lst@next{#6{#2{}{}}}% + \else + \def\lst@next{#6{#2#3{#4}}}% + \fi + \lst@next #1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CArgEmpty} +% `executes' an |\@empty|-delimited argument. We will use it for the delimiters. +% \begin{macrocode} +\def\lst@CArgEmpty#1\@empty{#1} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Delimiters} +% +% Here we start with general definitions common to all delimiters. +% +% \begin{lstkey}{excludedelims} +% controls which delimiters are not printed in \meta{whatever}style. We just +% define |\lst@ifex|\meta{whatever} to be true. Such switches are set false +% in the \hookname{ExcludeDelims} hook and are handled by the individual +% delimiters. +% \begin{macrocode} +\lst@Key{excludedelims}\relax + {\lsthk@ExcludeDelims \lst@NormedDef\lst@temp{#1}% + \expandafter\lst@for\lst@temp\do + {\expandafter\let\csname\@lst @ifex##1\endcsname\iftrue}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@DelimPrint} +% And this macro might help in doing so. |#1| is |\lst@ifex|\meta{whatever} +% (plus |\else|) or just |\iffalse|, and |#2| will be the delimiter. The +% temporary mode change ensures that the characters can't end the current +% delimiter or start a new one. +% \begin{macrocode} +\def\lst@DelimPrint#1#2{% + #1% + \begingroup + \lst@mode\lst@nomode \lst@modetrue + #2\lst@XPrintToken + \endgroup + \lst@ResetToken + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DelimOpen} +% We print preceding characters and the delimiter, enter the appropriate mode, +% print the delimiter again, and execute |#3|. In fact, the arguments |#1| and +% |#2| will ensure that the delimiter is printed only once. +% \begin{macrocode} +\def\lst@DelimOpen#1#2#3#4#5#6\@empty{% + \lst@TrackNewLines \lst@XPrintToken + \lst@DelimPrint#1{#6}% + \lst@EnterMode{#4}{\def\lst@currstyle#5}% + \lst@DelimPrint{#1#2}{#6}% + #3} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DelimClose} +% is the same in reverse order. +% \begin{macrocode} +\def\lst@DelimClose#1#2#3\@empty{% + \lst@TrackNewLines \lst@XPrintToken + \lst@DelimPrint{#1#2}{#3}% + \lst@LeaveMode + \lst@DelimPrint{#1}{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@BeginDelim} +% \begin{macro}{\lst@EndDelim} +% These definitions are applications of |\lst@DelimOpen| and |\lst@DelimClose|: +% the delimiters have the same style as the delimited text. +% \begin{macrocode} +\def\lst@BeginDelim{\lst@DelimOpen\iffalse\else{}} +\def\lst@EndDelim{\lst@DelimClose\iffalse\else} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@BeginIDelim} +% \begin{macro}{\lst@EndIDelim} +% Another application: no delimiter is printed. +% \begin{macrocode} +\def\lst@BeginIDelim{\lst@DelimOpen\iffalse{}{}} +\def\lst@EndIDelim{\lst@DelimClose\iffalse{}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@DefDelims} +% This macro defines all delimiters and is therefore reset every language +% selection. +% \begin{macrocode} +\lst@AddToHook{SelectCharTable}{\lst@DefDelims} +\lst@AddToHookExe{SetLanguage}{\let\lst@DefDelims\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Delim} +% First we set default values: no |\lst@modetrue|, cumulative style, and no +% argument to |\lst@Delim|[|DM|]|@|\meta{type}. +% \begin{macrocode} +\def\lst@Delim#1{% + \lst@false \let\lst@cumulative\@empty \let\lst@arg\@empty +% \end{macrocode} +% These are the correct settings for the double-star-form, so we immediately +% call the submacro in this case. Otherwise we either just suppress cumulative +% style, or even indicate the usage of |\lst@modetrue| with |\lst@true|. +% \begin{macrocode} + \@ifstar{\@ifstar{\lst@Delim@{#1}}% + {\let\lst@cumulative\relax + \lst@Delim@{#1}}}% + {\lst@true\lst@Delim@{#1}}} +% \end{macrocode} +% The type argument is saved for later use. We check against the optional +% \meta{style} argument using |#1| as default, define |\lst@delimstyle| and +% look for the optional \meta{type option}, which is just saved in |\lst@arg|. +% \begin{macrocode} +\def\lst@Delim@#1[#2]{% + \gdef\lst@delimtype{#2}% + \@ifnextchar[\lst@Delim@sty + {\lst@Delim@sty[#1]}} +\def\lst@Delim@sty[#1]{% + \def\lst@delimstyle{#1}% + \ifx\@empty#1\@empty\else + \lst@Delim@sty@ #1\@nil + \fi + \@ifnextchar[\lst@Delim@option + \lst@Delim@delim} +\def\lst@Delim@option[#1]{\def\lst@arg{#1}\lst@Delim@delim} +% \end{macrocode} +% The definition of |\lst@delimstyle| depends on whether the first token is a +% control sequence. Here we possibly build |\lst@|\meta{style}. +% \begin{macrocode} +\def\lst@Delim@sty@#1#2\@nil{% + \if\relax\noexpand#1\else + \edef\lst@delimstyle{\expandafter\noexpand + \csname\@lst @\lst@delimstyle\endcsname}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Delim@delim} +% Eventually this macro is called. First we might need to delete a bunch of +% delimiters. If there is no delimiter, we might delete a subclass. +% \begin{macrocode} +\def\lst@Delim@delim#1\relax#2#3#4#5#6#7#8{% + \ifx #4\@empty \lst@Delim@delall{#2}\fi + \ifx\@empty#1\@empty + \ifx #4\@nil + \@ifundefined{\@lst @#2DM@\lst@delimtype}% + {\lst@Delim@delall{#2@\lst@delimtype}}% + {\lst@Delim@delall{#2DM@\lst@delimtype}}% + \fi + \else +% \end{macrocode} +% If the delimiter is not empty, we convert the delimiter and append it to +% |\lst@arg|. Ditto |\lst@Begin|\ldots, |\lst@End|\ldots, and the style and +% mode selection. +% \begin{macrocode} + \expandafter\lst@Delim@args\expandafter + {\lst@delimtype}{#1}{#5}#6{#7}{#8}#4% +% \end{macrocode} +% If the type is known, we either choose dynamic or static mode and use the +% contents of |\lst@arg| as arguments. All this is put into |\lst@delim|. +% \begin{macrocode} + \let\lst@delim\@empty + \expandafter\lst@IfOneOf\lst@delimtype\relax#3% + {\@ifundefined{\@lst @#2DM@\lst@delimtype}% + {\lst@lExtend\lst@delim{\csname\@lst @#2@\lst@delimtype + \expandafter\endcsname\lst@arg}}% + {\lst@lExtend\lst@delim{\expandafter\lst@UseDynamicMode + \csname\@lst @#2DM@\lst@delimtype + \expandafter\endcsname\lst@arg}}% +% \end{macrocode} +% Now, depending on the mode |#4| we either remove this particular delimiter or +% append it to all current ones. +% \begin{macrocode} + \ifx #4\@nil + \let\lst@temp\lst@DefDelims \let\lst@DefDelims\@empty + \expandafter\lst@Delim@del\lst@temp\@empty\@nil\@nil\@nil + \else + \lst@lExtend\lst@DefDelims\lst@delim + \fi}% +% \end{macrocode} +% An unknown type issues an error. +% \begin{macrocode} + {\PackageError{Listings}{Illegal type `\lst@delimtype'}% + {#2 types are #3.}}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Delim@args} +% Now let's look how we add the arguments to |\lst@arg|. First we initialize +% the conversion just to make all characters active. But if the first character +% of the type equals |#4|, \ldots +% \begin{macrocode} +\def\lst@Delim@args#1#2#3#4#5#6#7{% + \begingroup + \lst@false \let\lst@next\lst@XConvert +% \end{macrocode} +% \ldots\ we remove that character from |\lst@delimtype|, and |#5| might select +% a different conversion setting or macro. +% \begin{macrocode} + \@ifnextchar #4{\xdef\lst@delimtype{\expandafter\@gobble + \lst@delimtype}% + #5\lst@next#2\@nil + \lst@lAddTo\lst@arg{\@empty#6}% + \lst@GobbleNil}% +% \end{macrocode} +% Since we are in the `special' case above, we've also added the special +% |\lst@Begin|\ldots\space and |\lst@End|\ldots\space macros to |\lst@arg| +% (and |\@empty| as a brake for the delimiter). No special task must be done +% if the characters are not equal. +% \begin{macrocode} + {\lst@next#2\@nil + \lst@lAddTo\lst@arg{\@empty#3}% + \lst@GobbleNil}% + #1\@nil +% \end{macrocode} +% We always transfer the arguments to the outside of the group and append the +% style and mode selection if and only if we're not deleting a delimiter. +% Therefor we expand the delimiter style. +% \begin{macrocode} + \global\let\@gtempa\lst@arg + \endgroup + \let\lst@arg\@gtempa + \ifx #7\@nil\else + \expandafter\lst@Delim@args@\expandafter{\lst@delimstyle}% + \fi} +% \end{macrocode} +% Recall that the style is `selected' by |\def\lst@currstyle#5|, and this +% `argument' |#5| is to be added now. Depending on the settings at the very +% beginning, we use either |{\meta{style}}\lst@modetrue|---which selects the +% style and deactivates keyword detection---, or |{}\meta{style}|---which +% defines an empty style macro and executes the style for cumulative styles---, +% or |{\meta{style}|---which just defines the style macro. Note that we have to +% use two extra group levels below: one is discarded directly by |\lst@lAddTo| +% and the other by |\lst@Delim|[|DM|]|@|\meta{type}. +% \begin{macrocode} +\def\lst@Delim@args@#1{% + \lst@if + \lst@lAddTo\lst@arg{{{#1}\lst@modetrue}}% + \else + \ifx\lst@cumulative\@empty + \lst@lAddTo\lst@arg{{{}#1}}% + \else + \lst@lAddTo\lst@arg{{{#1}}}% + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Delim@del} +% To delete a particular delimiter, we iterate down the list of delimiters and +% compare the current item with the user supplied. +% \begin{macrocode} +\def\lst@Delim@del#1\@empty#2#3#4{% + \ifx #2\@nil\else + \def\lst@temp{#1\@empty#2#3}% + \ifx\lst@temp\lst@delim\else + \lst@lAddTo\lst@DefDelims{#1\@empty#2#3{#4}}% + \fi + \expandafter\lst@Delim@del + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Delim@delall} +% To delete a whole class of delimiters, we first expand the control sequence +% name, init some other data, and call a submacro to do the work. +% \begin{macrocode} +\def\lst@Delim@delall#1{% + \begingroup + \edef\lst@delim{\expandafter\string\csname\@lst @#1\endcsname}% + \lst@false \global\let\@gtempa\@empty + \expandafter\lst@Delim@delall@\lst@DefDelims\@empty + \endgroup + \let\lst@DefDelims\@gtempa} +% \end{macrocode} +% We first discard a preceding |\lst@UseDynamicMode|. +% \begin{macrocode} +\def\lst@Delim@delall@#1{% + \ifx #1\@empty\else + \ifx #1\lst@UseDynamicMode + \lst@true + \let\lst@next\lst@Delim@delall@do + \else + \def\lst@next{\lst@Delim@delall@do#1}% + \fi + \expandafter\lst@next + \fi} +% \end{macrocode} +% Then we can check whether (the following) |\lst@|\meta{delimiter name}\ldots\ +% matches the delimiter class given by |\lst@delim|. +% \begin{macrocode} +\def\lst@Delim@delall@do#1#2\@empty#3#4#5{% + \expandafter\lst@IfSubstring\expandafter{\lst@delim}{\string#1}% + {}% + {\lst@if \lst@AddTo\@gtempa\lst@UseDynamicMode \fi + \lst@AddTo\@gtempa{#1#2\@empty#3#4{#5}}}% + \lst@false \lst@Delim@delall@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DefDelimB} +% Here we put the arguments together to fit |\lst@CDef|. Note that the very +% last argument |\@empty| to |\lst@CDef| is a brake for |\lst@CArgEmpty| +% and |\lst@DelimOpen|. +% \begin{macrocode} +\gdef\lst@DefDelimB#1#2#3#4#5#6#7#8{% + \lst@CDef{#1}#2% + {#3}% + {\let\lst@bnext\lst@CArgEmpty + \lst@ifmode #4\else + #5% + \def\lst@bnext{#6{#7}{#8}}% + \fi + \lst@bnext}% + \@empty} +% \end{macrocode} +% After a bug report from \lsthelper{Vespe~Savikko}{2000/11/06}{bad output of +% doc-strings if HTML and Python are loaded} I added braces around |#7|. +% \end{macro} +% +% \begin{macro}{\lst@DefDelimE} +% The |\ifnum #7=\lst@mode| in the 5th line ensures that the delimiters +% match each other. +% \begin{macrocode} +\gdef\lst@DefDelimE#1#2#3#4#5#6#7{% + \lst@CDef{#1}#2% + {#3}% + {\let\lst@enext\lst@CArgEmpty + \ifnum #7=\lst@mode% + #4% + \let\lst@enext#6% + \else + #5% + \fi + \lst@enext}% + \@empty} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{Init}{\let\lst@bnext\relax \let\lst@enext\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DefDelimBE} +% This service macro will actually define all string delimiters. +% \begin{macrocode} +\gdef\lst@DefDelimBE#1#2#3#4#5#6#7#8#9{% + \lst@CDef{#1}#2% + {#3}% + {\let\lst@bnext\lst@CArgEmpty + \ifnum #7=\lst@mode + #4% + \let\lst@bnext#9% + \else + \lst@ifmode\else + #5% + \def\lst@bnext{#6{#7}{#8}}% + \fi + \fi + \lst@bnext}% + \@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@delimtypes} +% is the list of general delimiter types. +% \begin{macrocode} +\gdef\lst@delimtypes{s,l} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@StringKey} +% We just put together the arguments for |\lst@Delim|. +% \begin{macrocode} +\gdef\lst@DelimKey#1#2{% + \lst@Delim{}#2\relax + {Delim}\lst@delimtypes #1% + {\lst@BeginDelim\lst@EndDelim} + i\@empty{\lst@BeginIDelim\lst@EndIDelim}} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{delim} +% \begin{lstkey}{moredelim} +% \begin{lstkey}{deletedelim} +% all use |\lst@DelimKey|. +% \begin{macrocode} +\lst@Key{delim}\relax{\lst@DelimKey\@empty{#1}} +\lst@Key{moredelim}\relax{\lst@DelimKey\relax{#1}} +\lst@Key{deletedelim}\relax{\lst@DelimKey\@nil{#1}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@DelimDM@l} +% \begin{macro}{\lst@DelimDM@s} +% Nohting special here. +% \begin{macrocode} +\gdef\lst@DelimDM@l#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} +% \end{macrocode} +% \begin{macrocode} +\gdef\lst@DelimDM@s#1#2#3\@empty#4#5#6{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% + \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}} +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsubsection{Strings} +% +% \begin{aspect}{strings} +% Just starting a new aspect. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{strings} +% \end{macrocode} +% +% \begin{macro}{\lst@stringtypes} +% is the list of \ldots\space string types? +% \begin{macrocode} +\gdef\lst@stringtypes{d,b,m,bd,db} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@StringKey} +% We just put together the arguments for |\lst@Delim|. +% \begin{macrocode} +\gdef\lst@StringKey#1#2{% + \lst@Delim\lst@stringstyle #2\relax + {String}\lst@stringtypes #1% + {\lst@BeginString\lst@EndString}% + \@@end\@empty{}} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{string} +% \begin{lstkey}{morestring} +% \begin{lstkey}{deletestring} +% all use |\lst@StringKey|. +% \begin{macrocode} +\lst@Key{string}\relax{\lst@StringKey\@empty{#1}} +\lst@Key{morestring}\relax{\lst@StringKey\relax{#1}} +\lst@Key{deletestring}\relax{\lst@StringKey\@nil{#1}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{lstkey}{stringstyle} +% You shouldn't need comments on the following two lines, do you? +% \begin{macrocode} +\lst@Key{stringstyle}{}{\def\lst@stringstyle{#1}} +\lst@AddToHook{EmptyStyle}{\let\lst@stringstyle\@empty} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{showstringspaces} +% Thanks to \lsthelper{Knut~M\"uller}{1997/04/28}{\blankstringtrue} for +% reporting problems with |\blankstringtrue| (now |showstringspaces=false|). +% The problem has gone. +% \begin{macrocode} +\lst@Key{showstringspaces}t[t]{\lstKV@SetIf{#1}\lst@ifshowstringspaces} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@BeginString} +% Note that the tokens after |\lst@DelimOpen| are arguments! The only special +% here is that we switch to `keepspaces' after starting a string, if necessary. +% A bug reported by \lsthelper{Vespe~Savikko}{2000/09/27}{stringstyle used also +% on previous other characters} has gone due to the use of |\lst@DelimOpen|. +% \begin{macrocode} +\gdef\lst@BeginString{% + \lst@DelimOpen + \lst@ifexstrings\else + {\lst@ifshowstringspaces + \lst@keepspacestrue + \let\lst@outputspace\lst@visiblespace + \fi}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifexstrings\iffalse} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EndString} +% Again the two tokens following |\lst@DelimClose| are arguments. +% \begin{macrocode} +\gdef\lst@EndString{\lst@DelimClose\lst@ifexstrings\else} +% \end{macrocode} +% \end{macro} +% +% And now all the |\lst@StringDM@|\meta{type} definitions. +% +% \begin{macro}{\lst@StringDM@d} +% `d' means no extra work.; the first three arguments after |\lst@DefDelimBE| +% are left empty. The others are used to start and end the string. +% \begin{macrocode} +\gdef\lst@StringDM@d#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimBE{}{}{}#3{#1}{#5}#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@StringDM@b} +% The |\lst@ifletter|\ldots|\fi| has been inserted after bug reports by +% \lsthelper{Daniel~Gerigk}{2001/10/25}{improper strings in C++} and +% \lsthelper{Peter~Bartke}{2001/11/01}{improper strings in C++}. If the last +% other character is a backslash (4th line), we gobble the `end string' token +% sequence. +% \begin{macrocode} +\gdef\lst@StringDM@b#1#2\@empty#3#4#5{% + \let\lst@ifbstring\iftrue + \lst@CArg #2\relax\lst@DefDelimBE + {\lst@ifletter \lst@Output \lst@letterfalse \fi}% + {\ifx\lst@lastother\lstum@backslash + \expandafter\@gobblethree + \fi}{}#3{#1}{#5}#4} +% \end{macrocode} +% \begin{macrocode} +\global\let\lst@ifbstring\iffalse % init +% \end{macrocode} +% \lsthelper{Heiko~Heil}{2002/02/08}{string '\\' does not finish after the +% delimiter} reported problems with double backslashes. So: +% \begin{macrocode} +\lst@AddToHook{SelectCharTable}{% + \lst@ifbstring + \lst@CArgX \\\\\relax \lst@CDefX{}% + {\lst@ProcessOther\lstum@backslash + \lst@ProcessOther\lstum@backslash}% + {}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@StringDM@bd} +% \begin{macro}{\lst@StringDM@db} +% are just the same and the same as |\lst@StringDM@b|. +% \begin{macrocode} +\global\let\lst@StringDM@bd\lst@StringDM@b +\global\let\lst@StringDM@db\lst@StringDM@bd +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{macro}{\lst@StringDM@m} +% `M'atlabed is designed for programming languages where string delimiters are +% are also used for other purposes, like Matlab or Ada. Here we enter string +% mode only if the last character has not been a letter and has not been a +% right parenthesis or right bracket. The test for the latter one has been +% added after bug report from \lsthelper{Christian~Kindinger}{2002/03/??} +% {]' starts a string in Matlab}. +% \begin{macrocode} +\gdef\lst@StringDM@m#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimBE{}{}% + {\let\lst@next\@gobblethree + \lst@ifletter\else + \ifx\lst@lastother)\else \ifx\lst@lastother]\else + \let\lst@next\@empty + \fi \fi \fi + \lst@next}#3{#1}{#5}#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsubsection{Comments} +% +% \begin{aspect}{comments} +% That's what we are working on. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{comments} +% \end{macrocode} +% +% \begin{macro}{\lst@commenttypes} +% Via \keyname{comment} available comment types: \textbf line, \textbf fixed +% column, \textbf single, and \textbf nested and all with +% preceding \textbf i for invisible comments. +% \begin{macrocode} +\gdef\lst@commenttypes{l,f,s,n} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CommentKey} +% We just put together the arguments for |\lst@Delim|. +% \begin{macrocode} +\gdef\lst@CommentKey#1#2{% + \lst@Delim\lst@commentstyle #2\relax + {Comment}\lst@commenttypes #1% + {\lst@BeginComment\lst@EndComment}% + i\@empty{\lst@BeginInvisible\lst@EndInvisible}} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{comment} +% \begin{lstkey}{morecomment} +% \begin{lstkey}{deletecomment} +% The keys are easy since defined in terms of |\lst@CommentKey|. +% \begin{macrocode} +\lst@Key{comment}\relax{\lst@CommentKey\@empty{#1}} +\lst@Key{morecomment}\relax{\lst@CommentKey\relax{#1}} +\lst@Key{deletecomment}\relax{\lst@CommentKey\@nil{#1}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{lstkey}{commentstyle} +% Any hints necessary? +% \begin{macrocode} +\lst@Key{commentstyle}{}{\def\lst@commentstyle{#1}} +\lst@AddToHook{EmptyStyle}{\let\lst@commentstyle\itshape} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@BeginComment} +% \begin{macro}{\lst@EndComment} +% Once more the three tokens following |\lst@DelimOpen| are arguments. +% \begin{macrocode} +\gdef\lst@BeginComment{% + \lst@DelimOpen + \lst@ifexcomments\else + \lsthk@AfterBeginComment} +% \end{macrocode} +% Ditto. +% \begin{macrocode} +\gdef\lst@EndComment{\lst@DelimClose\lst@ifexcomments\else} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{AfterBeginComment}{} +\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifexcomments\iffalse} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@BeginInvisible} +% \begin{macro}{\lst@EndInvisible} +% Print preceding characters and begin dropping the output. +% \begin{macrocode} +\gdef\lst@BeginInvisible#1#2#3\@empty{% + \lst@TrackNewLines \lst@XPrintToken + \lst@BeginDropOutput{#1}} +% \end{macrocode} +% Don't print the delimiter and end dropping the output. +% \begin{macrocode} +\gdef\lst@EndInvisible#1\@empty{\lst@EndDropOutput} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Now we provide all |\lst@Comment|[|DM|]|@|\meta{type} macros. +% +% \begin{macro}{\lst@Comment@l} +% is easy---thanks to |\lst@CArg| and |\lst@DefDelimB|. Note that the +% `end comment' argument |#4| is not used here. +% \begin{macrocode} +\gdef\lst@CommentDM@l#1#2\@empty#3#4#5{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CommentDM@f} +% is slightly more work. First we provide the number of preceding columns. +% \begin{macrocode} +\gdef\lst@CommentDM@f#1{% + \@ifnextchar[{\lst@Comment@@f{#1}}% + {\lst@Comment@@f{#1}[0]}} +% \end{macrocode} +% We define the comment in the same way as above, but we enter comment mode +% if and only if the character is in column |#2| (counting from zero). +% \begin{macrocode} +\gdef\lst@Comment@@f#1[#2]#3\@empty#4#5#6{% + \lst@CArg #3\relax\lst@DefDelimB{}{}% + {\lst@CalcColumn + \ifnum #2=\@tempcnta\else + \expandafter\@gobblethree + \fi}% + #4{#1}{#6\lst@Lmodetrue}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CommentDM@s} +% Nothing special here. +% \begin{macrocode} +\gdef\lst@CommentDM@s#1#2#3\@empty#4#5#6{% + \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% + \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@CommentDM@n} +% We either give an error message or define the nested comment. +% \begin{macrocode} +\gdef\lst@CommentDM@n#1#2#3\@empty#4#5#6{% + \ifx\@empty#3\@empty\else + \def\@tempa{#2}\def\@tempb{#3}% + \ifx\@tempa\@tempb + \PackageError{Listings}{Identical delimiters}% + {These delimiters make no sense with nested comments.}% + \else + \lst@CArg #2\relax\lst@DefDelimB + {}% +% \end{macrocode} +% Note that the following |\@gobble| eats an |\else| from |\lst@DefDelimB|. +% \begin{macrocode} + {\ifnum\lst@mode=#1\relax \expandafter\@gobble \fi}% + {}#4{#1}{#6}% + \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}% + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsubsection{PODs} +% +% \begin{aspect}{pod} +% PODs are defined as a separate aspect. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{pod} +% \end{macrocode} +% +% \begin{lstkey}{printpod} +% \begin{lstkey}{podcomment} +% We begin with the user keys, which I introduced after communication with +% \lsthelper{Michael~Piotrowski}{1997/11/11}{printpod}. +% \begin{macrocode} +\lst@Key{printpod}{false}[t]{\lstKV@SetIf{#1}\lst@ifprintpod} +\lst@Key{podcomment}{false}[t]{\lstKV@SetIf{#1}\lst@ifpodcomment} +\lst@AddToHookExe{SetLanguage}{\let\lst@ifpodcomment\iffalse} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@PODmode} +% is the static mode for PODs. +% \begin{macrocode} +\lst@NewMode\lst@PODmode +% \end{macrocode} +% \end{macro} +% +% We adjust some characters if the user has selected |podcomment=true|. +% \begin{macrocode} +\lst@AddToHook{SelectCharTable} + {\lst@ifpodcomment + \lst@CArgX =\relax\lst@DefDelimB{}{}% +% \end{macrocode} +% The following code is executed if we've found an equality sign and haven't +% entered a mode (in fact if mode changes are allowed): We `begin drop output' +% and gobble the usual begin of comment sequence (via |\@gobblethree|) if PODs +% aren't be printed. Moreover we gobble it if the current column number is not +% zero---|\@tempcnta| is valued below. +% \begin{macrocode} + {\ifnum\@tempcnta=\z@ + \lst@ifprintpod\else + \def\lst@bnext{\lst@BeginDropOutput\lst@PODmode}% + \expandafter\expandafter\expandafter\@gobblethree + \fi + \else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@PODmode\lst@commentstyle +% \end{macrocode} +% If we come to |=|, we calculate the current column number (zero based). +% \begin{macrocode} + \lst@CArgX =cut\^^M\relax\lst@DefDelimE + {\lst@CalcColumn}% +% \end{macrocode} +% If there is additionally |cut|+EOL and if we are in |\lst@PODmode| but not in +% column one, we must gobble the `end comment sequence'. +% \begin{macrocode} + {\ifnum\@tempcnta=\z@\else + \expandafter\@gobblethree + \fi}% + {}% + \lst@EndComment\lst@PODmode + \fi} +% \end{macrocode} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Replacing input} +% +% \begingroup +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% \endgroup +% +% \begin{macro}{\lst@ReplaceInput} +% is defined in terms of |\lst@CArgX| and |\lst@CDefX|. +% \begin{macrocode} +\def\lst@ReplaceInput#1{\lst@CArgX #1\relax\lst@CDefX{}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{literate} +% \lsthelper{Jason~Alexander}{1999/03/10}{literate programming} asked for +% something like that. The key simply saves the argument. +% \begin{macrocode} +\lst@Key{literate}{}{\def\lst@literate{#1}} +\lst@AddToHook{SelectCharTable} + {\ifx\lst@literate\@empty\else + \expandafter\lst@Literate\lst@literate{}\relax\z@ + \fi} +% \end{macrocode} +% Internally we make use of the `replace input' feature. +% We print the preceding text, assign token and length, and output it. +% \begin{macrocode} +\def\lst@Literate#1#2#3{% + \ifx\relax#2\@empty\else + \lst@ReplaceInput{#1}% + {\lst@XPrintToken \lst@letterfalse + \lst@token{#2}\lst@length#3\relax + \lst@XPrintToken}% + \expandafter\lst@Literate + \fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@BeginDropInput} +% We deactivate all `process' macros. |\lst@modetrue| does this for all +% up-coming string delimiters, comments, and so on. +% \begin{macrocode} +\def\lst@BeginDropInput#1{% + \lst@EnterMode{#1}% + {\lst@modetrue + \let\lst@ifdropinput\iftrue + \let\lst@ProcessLetter\@gobble + \let\lst@ProcessDigit\@gobble + \let\lst@ProcessOther\@gobble + \let\lst@ProcessSpace\@empty + \let\lst@ProcessTabulator\@empty + \let\lst@ProcessFormFeed\@empty}} +\let\lst@ifdropinput\iffalse % init +% \end{macrocode} +% \end{macro} +% +% \begingroup +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Escaping to \LaTeX} +% +% \begin{aspect}{escape} +% We now define the \ldots\ damned \ldots\ the aspect has escaped! +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{escape} +% \end{macrocode} +% +% \begin{lstkey}{texcl} +% Communication with \lsthelper{J\"orn~Wilms}{1997/07/07}{\TeX\ comments} is +% responsible for this key. The definition and the first hooks are easy. +% \begin{macrocode} +\lst@Key{texcl}{false}[t]{\lstKV@SetIf{#1}\lst@iftexcl} +\lst@AddToHook{TextStyle}{\let\lst@iftexcl\iffalse} +\lst@AddToHook{EOL} + {\ifnum\lst@mode=\lst@TeXLmode + \expandafter\lst@escapeend + \expandafter\lst@LeaveAllModes + \expandafter\lst@ReenterModes + \fi} +% \end{macrocode} +% If the user wants \TeX\ comment lines, we print the comment separator and +% interrupt the normal processing. +% \begin{macrocode} +\lst@AddToHook{AfterBeginComment} + {\lst@iftexcl \lst@ifLmode \lst@ifdropinput\else + \lst@PrintToken + \lst@LeaveMode \lst@InterruptModes + \lst@EnterMode{\lst@TeXLmode}{\lst@modetrue\lst@commentstyle}% + \expandafter\expandafter\expandafter\lst@escapebegin + \fi \fi \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@NewMode\lst@TeXLmode +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@ActiveCDefX} +% Same as |\lst@CDefX| but we both make |#1| active and assign a new catcode. +% \begin{macrocode} +\gdef\lst@ActiveCDefX#1{\lst@ActiveCDefX@#1} +\gdef\lst@ActiveCDefX@#1#2#3{ + \catcode`#1\active\lccode`\~=`#1% + \lowercase{\lst@CDefIt~}{#2}{#3}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@Escape} +% gets four arguments all in all. The first and second are the `begin' and +% `end' escape sequences, the third is executed when the escape starts, and the +% fourth right before ending it. We use the same mechanism as for \TeX\ comment +% lines. The |\lst@ifdropinput| test has been added after a bug report by +% \lsthelper{Michael~Weber}{2002/03/26}{escape on lines < firstline corrupts +% output}. +% \begin{macrocode} +\gdef\lst@Escape#1#2#3#4{% + \lst@CArgX #1\relax\lst@CDefX + {}% + {\lst@ifdropinput\else + \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken + \lst@InterruptModes + \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}% +% \end{macrocode} +% Now we must define the character sequence to end the escape. +% \begin{macrocode} + \ifx\^^M#2% + \lst@CArg #2\relax\lst@ActiveCDefX + {}% + {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes}% + {\lst@MProcessListing}% + \else + \lst@CArg #2\relax\lst@ActiveCDefX + {}% + {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes + \lst@whitespacefalse}% + {}% + \fi + #3\lst@escapebegin + \fi}% + {}} +% \end{macrocode} +% The |\lst@whitespacefalse| above was added after a bug report from +% \lsthelper{Martin~Steffen}{2001/04/07}{mathescape drops subsequent space}. +% \begin{macrocode} +\lst@NewMode\lst@TeXmode +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{escapebegin} +% \begin{lstkey}{escapeend} +% The keys simply store the arguments. +% \begin{macrocode} +\lst@Key{escapebegin}{}{\def\lst@escapebegin{#1}} +\lst@Key{escapeend}{}{\def\lst@escapeend{#1}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{lstkey}{escapechar} +% The introduction of this key is due to a communication with \lsthelper +% {Rui~Oliveira}{1998/06/05}{escape characters}. We define |\lst@DefEsc| and +% execute it after selecting the standard character table. +% \begin{macrocode} +\lst@Key{escapechar}{} + {\ifx\@empty#1\@empty + \let\lst@DefEsc\relax + \else + \def\lst@DefEsc{\lst@Escape{#1}{#1}{}{}}% + \fi} +\lst@AddToHook{TextStyle}{\let\lst@DefEsc\@empty} +\lst@AddToHook{SelectCharTable}{\lst@DefEsc} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{escapeinside} +% Nearly the same. +% \begin{macrocode} +\lst@Key{escapeinside}{}{\lstKV@TwoArg{#1}% + {\let\lst@DefEsc\@empty + \ifx\@empty##1@empty\else \ifx\@empty##2\@empty\else + \def\lst@DefEsc{\lst@Escape{##1}{##2}{}{}}% + \fi\fi}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{mathescape} +% This is a switch and checked after character table selection. We use +% |\lst@Escape| with math shifts as arguments, but all inside |\hbox| +% to determine the correct width. +% \begin{macrocode} +\lst@Key{mathescape}{false}[t]{\lstKV@SetIf{#1}\lst@ifmathescape} +\lst@AddToHook{SelectCharTable} + {\lst@ifmathescape \lst@Escape{\$}{\$}% + {\setbox\@tempboxa=\hbox\bgroup$}% + {$\egroup \lst@CalcLostSpaceAndOutput}\fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \section{Keywords} +% +% +% \subsection{Making tests}\label{iMakingTests} +% +% \begin{aspect}{keywords} +% We begin a new and very important aspect. +% First of all we need to initialize some variables in order to work around a +% bug reported by \lsthelper{Beat~Birkhofer}{2001/06/15}{savemem doesn't work}. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{keywords} +% \end{macrocode} +% \begin{macrocode} +\global\let\lst@ifsensitive\iftrue % init +\global\let\lst@ifsensitivedefed\iffalse % init % \global +% \end{macrocode} +% All keyword tests take the following three arguments. +% \begin{macroargs} +% \item \meta{prefix} +% \item |\lst@|\meta{name}|@list| (a list of macros which contain the keywords) +% \item |\lst@g|\meta{name}|@sty| (global style macro) +% \end{macroargs} +% We begin with non memory-saving tests. +% \begingroup +% \begin{macrocode} +\lst@ifsavemem\else +% \end{macrocode} +% \endgroup +% +% \begin{macro}{\lst@KeywordTest} +% Fast keyword tests take advance of the |\lst@UM| construction in section +% \ref{iCharacterTables}. If |\lst@UM| is empty, all `use macro' characters +% expand to their original characters. Since |\lst|\meta{prefix}|@|\meta{keyword} +% will be equivalent to the appropriate style, we only need to build the control +% sequence |\lst|\meta{prefix}|@|\meta{current token} and assign it to +% |\lst@thestyle|. +% \begin{macrocode} +\gdef\lst@KeywordTest#1#2#3{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#1@\the\lst@token\endcsname + \endgroup + \ifx\@gtempa\relax\else + \let\lst@thestyle\@gtempa + \fi} +% \end{macrocode} +% Note that we need neither |#2| nor |#3| here. +% \end{macro} +% +% \begin{macro}{\lst@KEYWORDTEST} +% Case insensitive tests make the current character string upper case and give +% it to a submacro similar to |\lst@KeywordTest|. +% \begin{macrocode} +\gdef\lst@KEYWORDTEST{% + \uppercase\expandafter{\expandafter + \lst@KEYWORDTEST@\the\lst@token}\relax} +\gdef\lst@KEYWORDTEST@#1\relax#2#3#4{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#2@#1\endcsname + \endgroup + \ifx\@gtempa\relax\else + \let\lst@thestyle\@gtempa + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@WorkingTest} +% \begin{macro}{\lst@WORKINGTEST} +% The same except that |\lst|\meta{prefix}|@|\meta{current token} might be +% a working procedure; it is executed. +% \begin{macrocode} +\gdef\lst@WorkingTest#1#2#3{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#1@\the\lst@token\endcsname + \endgroup + \@gtempa} +% \end{macrocode} +% \begin{macrocode} +\gdef\lst@WORKINGTEST{% + \uppercase\expandafter{\expandafter + \lst@WORKINGTEST@\the\lst@token}\relax} +\gdef\lst@WORKINGTEST@#1\relax#2#3#4{% + \begingroup \let\lst@UM\@empty + \global\expandafter\let\expandafter\@gtempa + \csname\@lst#2@#1\endcsname + \endgroup + \@gtempa} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@DefineKeywords} +% Eventually we need macros which define and undefine +% |\lst|\meta{prefix}|@|\meta{keyword}. Here the arguments are +% \begin{macroargs} +% \item \meta{prefix} +% \item |\lst@|\meta{name} (a keyword list) +% \item |\lst@g|\meta{name}|@sty| +% \end{macroargs} +% We make the keywords upper case if necessary, \ldots +% \begin{macrocode} +\gdef\lst@DefineKeywords#1#2#3{% + \lst@ifsensitive + \def\lst@next{\lst@for#2}% + \else + \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}% + \fi + \lst@next\do +% \end{macrocode} +% \ldots\space iterate through the list, and make +% |\lst|\meta{prefix}|@|\meta{keyword} (if undefined) equivalent to +% |\lst@g|\meta{name}|@sty| which is possibly a working macro. +% \begin{macrocode} + {\expandafter\ifx\csname\@lst#1@##1\endcsname\relax + \global\expandafter\let\csname\@lst#1@##1\endcsname#3% + \fi}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@UndefineKeywords} +% We make the keywords upper case if necessary, \ldots +% \begin{macrocode} +\gdef\lst@UndefineKeywords#1#2#3{% + \lst@ifsensitivedefed + \def\lst@next{\lst@for#2}% + \else + \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}% + \fi + \lst@next\do +% \end{macrocode} +% \ldots\space iterate through the list, and `undefine' +% |\lst|\meta{prefix}|@|\meta{keyword} if it's equivalent to +% |\lst@g|\meta{name}|@sty|. +% \begin{macrocode} + {\expandafter\ifx\csname\@lst#1@##1\endcsname#3% + \global\expandafter\let\csname\@lst#1@##1\endcsname\relax + \fi}} +% \end{macrocode} +% Thanks to \lsthelper{Magnus~Lewis-Smith}{1999/09/08}{keywords do not +% undefine} a wrong |#2| in the replacement text could be changed to |#3|. +% \end{macro} +% +% \begingroup +% And now memory-saving tests. +% \begin{macrocode} +\fi +\lst@ifsavemem +% \end{macrocode} +% \endgroup +% +% \begin{macro}{\lst@IfOneOutOf} +% The definition here is similar to |\lst@IfOneOf|, but its second argument +% is a |\lst@|\meta{name}|@list|. Therefore we test a list of macros here. +% \begin{macrocode} +\gdef\lst@IfOneOutOf#1\relax#2{% + \def\lst@temp##1,#1,##2##3\relax{% + \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}% + \def\lst@next{\lst@IfOneOutOf@#1\relax}% + \expandafter\lst@next#2\relax\relax} +% \end{macrocode} +% We either execute the \meta{else} part or make the next test. +% \begin{macrocode} +\gdef\lst@IfOneOutOf@#1\relax#2#3{% + \ifx#2\relax + \expandafter\@secondoftwo + \else + \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax + \expandafter\lst@next + \fi} +\ifx\iffalse\else\fi +\gdef\lst@IOOOfirst#1\relax#2#3{\fi#2} +% \end{macrocode} +% The line |\ifx\iffalse\else\fi| balances the |\fi| inside |\lst@IOOOfirst|. +% \end{macro} +% +% \begin{macro}{\lst@IFONEOUTOF} +% As in |\lst@IFONEOF| we need two |\uppercase|s here. +% \begin{macrocode} +\gdef\lst@IFONEOUTOF#1\relax#2{% + \uppercase{\def\lst@temp##1,#1},##2##3\relax{% + \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}% + \def\lst@next{\lst@IFONEOUTOF@#1\relax}% + \expandafter\lst@next#2\relax} +\gdef\lst@IFONEOUTOF@#1\relax#2#3{% + \ifx#2\relax + \expandafter\@secondoftwo + \else + \uppercase + {\expandafter\lst@temp\expandafter,#2,#1,\@empty\relax}% + \expandafter\lst@next + \fi} +% \end{macrocode} +% Note: The third last line uses the fact that keyword lists (not the list +% of keyword lists) are already made upper case if keywords are insensitive. +% \end{macro} +% +% \begin{macro}{\lst@KWTest} +% is a helper for the keyword and working identifier tests. We expand the +% token and call |\lst@IfOneOf|. The tests below will append appropriate +% \meta{then} and \meta{else} arguments. +% \begin{macrocode} +\gdef\lst@KWTest{% + \begingroup \let\lst@UM\@empty + \expandafter\xdef\expandafter\@gtempa\expandafter{\the\lst@token}% + \endgroup + \expandafter\lst@IfOneOutOf\@gtempa\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@KeywordTest} +% \begin{macro}{\lst@KEYWORDTEST} +% are fairly easy now. Note that we don't need |#1|=\meta{prefix} here. +% \begin{macrocode} +\gdef\lst@KeywordTest#1#2#3{\lst@KWTest #2{\let\lst@thestyle#3}{}} +\global\let\lst@KEYWORDTEST\lst@KeywordTest +% \end{macrocode} +% For case insensitive tests we assign the insensitive version to +% |\lst@IfOneOutOf|. Thus we need no extra definition here. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@WorkingTest} +% \begin{macro}{\lst@WORKINGTEST} +% Ditto. +% \begin{macrocode} +\gdef\lst@WorkingTest#1#2#3{\lst@KWTest #2#3{}} +\global\let\lst@WORKINGTEST\lst@WorkingTest +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begingroup +% \begin{macrocode} +\fi +% \end{macrocode} +% \endgroup +% +% \begin{lstkey}{sensitive} +% is a switch, preset \texttt{true} every language selection. +% \begin{macrocode} +\lst@Key{sensitive}\relax[t]{\lstKV@SetIf{#1}\lst@ifsensitive} +\lst@AddToHook{SetLanguage}{\let\lst@ifsensitive\iftrue} +% \end{macrocode} +% We select case insensitive definitions if necessary. +% \begin{macrocode} +\lst@AddToHook{Init} + {\lst@ifsensitive\else + \let\lst@KeywordTest\lst@KEYWORDTEST + \let\lst@WorkingTest\lst@WORKINGTEST + \let\lst@IfOneOutOf\lst@IFONEOUTOF + \fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@MakeMacroUppercase} +% makes the contents of |#1| (if defined) upper case. +% \begin{macrocode} +\gdef\lst@MakeMacroUppercase#1{% + \ifx\@undefined#1\else \uppercase\expandafter + {\expandafter\def\expandafter#1\expandafter{#1}}% + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Installing tests} +% +% \begin{macro}{\lst@InstallTest} +% The arguments are +% \begin{macroargs} +% \item \meta{prefix} +% \item |\lst@|\meta{name}|@list| +% \item |\lst@|\meta{name} +% \item |\lst@g|\meta{name}|@list| +% \item |\lst@g|\meta{name} +% \item |\lst@g|\meta{name}|@sty| +% \item \alternative{w,s} (working procedure or style) +% \item \alternative{d,o} (\hookname{DetectKeywords} or \hookname{Output} hook) +% \end{macroargs} +% We just insert hook material. The tests will be inserted on demand. +% \begin{macrocode} +\gdef\lst@InstallTest#1#2#3#4#5#6#7#8{% + \lst@AddToHook{TrackKeywords}{\lst@TrackKeywords{#1}#2#4#6#7#8}% + \lst@AddToHook{PostTrackKeywords}{\lst@PostTrackKeywords#2#3#4#5}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{Init}{\lsthk@TrackKeywords\lsthk@PostTrackKeywords} +\lst@AddToHook{TrackKeywords}{}% init +\lst@AddToHook{PostTrackKeywords}{}% init +% \end{macrocode} +% We have to detect the keywords somewhere. +% \begin{macrocode} +\lst@AddToHook{Output}{\lst@ifkeywords \lsthk@DetectKeywords \fi} +\lst@AddToHook{DetectKeywords}{}% init +\lst@AddToHook{ModeTrue}{\let\lst@ifkeywords\iffalse} +\lst@AddToHook{Init}{\let\lst@ifkeywords\iftrue} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@InstallTestNow} +% actually inserts a test. +% \begin{macroargs} +% \item \meta{prefix} +% \item |\lst@|\meta{name}|@list| +% \item |\lst@g|\meta{name}|@sty| +% \item \alternative{w,s} (working procedure or style) +% \item \alternative{d,o} (\hookname{DetectKeywords} or \hookname{Output} hook) +% \end{macroargs} +% For example, |#4#5|=|sd| will add +% |\lst@KeywordTest{|\meta{prefix}|}| +% |\lst@|\meta{name}|@list| |\lst@g|\meta{name}|@sty| +% to the \hookname{DetectKeywords} hook. +% \begin{macrocode} +\gdef\lst@InstallTestNow#1#2#3#4#5{% + \@ifundefined{\string#2#1}% + {\global\@namedef{\string#2#1}{}% + \edef\@tempa{% + \noexpand\lst@AddToHook{\ifx#5dDetectKeywords\else Output\fi}% + {\ifx #4w\noexpand\lst@WorkingTest + \else\noexpand\lst@KeywordTest \fi + {#1}\noexpand#2\noexpand#3}}% +% \end{macrocode} +% If we are advised to save memory, we insert a test for each \meta{name}. +% Otherwise we install the tests according to \meta{prefix}. +% \begin{macrocode} + \lst@ifsavemem + \@tempa + \else + \@ifundefined{\@lst#1@if@ins}% + {\@tempa \global\@namedef{\@lst#1@if@ins}{}}% + {}% + \fi} + {}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@TrackKeywords} +% Now it gets a bit tricky. We expand the class list |\lst@|\meta{name}|@list| +% behind |\lst@TK@{|\meta{prefix}|}||\lst@g|\meta{name}|@sty| and use two +% |\relax|es as terminators. This will define the keywords of all the classes +% as keywords of type \meta{prefix}. More details come soon. +% \begin{macrocode} +\gdef\lst@TrackKeywords#1#2#3#4#5#6{% + \lst@false + \def\lst@arg{{#1}#4}% + \expandafter\expandafter\expandafter\lst@TK@ + \expandafter\lst@arg#2\relax\relax +% \end{macrocode} +% And nearly the same to undefine all out-dated keywords, which is necessary +% only if we don't save memory. +% \begin{macrocode} + \lst@ifsavemem\else + \def\lst@arg{{#1}#4#2}% + \expandafter\expandafter\expandafter\lst@TK@@ + \expandafter\lst@arg#3\relax\relax + \fi +% \end{macrocode} +% Finally we install the keyword test if keywords changed, in particular if +% they are defined the first time. Note that |\lst@InstallTestNow| inserts a +% test only once. +% \begin{macrocode} + \lst@if \lst@InstallTestNow{#1}#2#4#5#6\fi} +% \end{macrocode} +% Back to the current keywords. Global macros |\lst@g|\meta{id} contain +% globally defined keywords, whereas |\lst@|\meta{id} conatin the true +% keywords. This way we can keep track of the keywords: If keywords or +% \keyname{sensitive} changed, we undefine the old (= globally defined) +% keywords and define the true ones. The arguments of |\lst@TK@| are +% \begin{macroargs} +% \item \meta{prefix} +% \item |\lst@g|\meta{name}|@sty| +% \item |\lst@|\meta{id} +% \item |\lst@g|\meta{id} +% \end{macroargs} +% \begin{macrocode} +\gdef\lst@TK@#1#2#3#4{% + \ifx\lst@ifsensitive\lst@ifsensitivedefed + \ifx#3#4\else + \lst@true + \lst@ifsavemem\else + \lst@UndefineKeywords{#1}#4#2% + \lst@DefineKeywords{#1}#3#2% + \fi + \fi + \else + \ifx#3\relax\else + \lst@true + \lst@ifsavemem\else + \lst@UndefineKeywords{#1}#4#2% + \lst@DefineKeywords{#1}#3#2% + \fi + \fi + \fi +% \end{macrocode} +% We don't define and undefine keywords if we try to save memory. But we +% possibly need to make them upper case, which again wastes some memory. +% \begin{macrocode} + \lst@ifsavemem \ifx#3\relax\else + \lst@ifsensitive\else \lst@MakeMacroUppercase#3\fi + \fi \fi +% \end{macrocode} +% Reaching the end of the class list, we end the loop. +% \begin{macrocode} + \ifx#3\relax + \expandafter\@gobblethree + \fi + \lst@TK@{#1}#2} +% \end{macrocode} +% Here now we undefine the out-dated keywords. While not reaching the end of +% the global list, we look whether the keyword class |#4#5| is still in use or +% needs to be undefined. Our arguments are +% \begin{macroargs} +% \item \meta{prefix} +% \item |\lst@g|\meta{name}|@sty| +% \item |\lst@|\meta{name}|@list| +% \item |\lst@|\meta{id} +% \item |\lst@g|\meta{id} +% \end{macroargs} +% \begin{macrocode} +\gdef\lst@TK@@#1#2#3#4#5{% + \ifx#4\relax + \expandafter\@gobblefour + \else + \lst@IfSubstring{#4#5}#3{}{\lst@UndefineKeywords{#1}#5#2}% + \fi + \lst@TK@@{#1}#2#3} +% \end{macrocode} +% Keywords are up-to-date after \hookname{InitVars}. +% \begin{macrocode} +\lst@AddToHook{InitVars} + {\global\let\lst@ifsensitivedefed\lst@ifsensitive} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@PostTrackKeywords} +% After updating all the keywords, the global keywords and the global list +% become equivalent to the local ones. +% \begin{macrocode} +\gdef\lst@PostTrackKeywords#1#2#3#4{% + \lst@ifsavemem\else + \global\let#3#1% + \global\let#4#2% + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Classes and families} +% +% \begin{lstkey}{classoffset} +% just stores the argument in a macro. +% \begin{macrocode} +\lst@Key{classoffset}\z@{\def\lst@classoffset{#1}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@InstallFamily} +% Recall the parameters +% \begin{macroargs} +% \item \meta{prefix} +% \item \meta{name} +% \item \meta{style name} +% \item \meta{style init} +% \item \meta{default style name} +% \item \meta{working procedure} +% \item \alternative{l,o} (language or other key) +% \item \alternative{d,o} (\hookname{DetectKeywords} or \hookname{Output} hook) +% \end{macroargs} +% First we define the keys and the style key \meta{style name} if and only if +% the name is not empty. +% \begin{macrocode} +\gdef\lst@InstallFamily#1#2#3#4#5{% + \lst@Key{#2}\relax{\lst@UseFamily{#2}##1\relax\lst@MakeKeywords}% + \lst@Key{more#2}\relax + {\lst@UseFamily{#2}##1\relax\lst@MakeMoreKeywords}% + \lst@Key{delete#2}\relax + {\lst@UseFamily{#2}##1\relax\lst@DeleteKeywords}% + \ifx\@empty#3\@empty\else + \lst@Key{#3}{#4}{\lstKV@OptArg[\@ne]{##1}% + {\@tempcnta\lst@classoffset \advance\@tempcnta####1\relax + \@namedef{lst@#3\ifnum\@tempcnta=\@ne\else \the\@tempcnta + \fi}{####2}}}% + \fi + \expandafter\lst@InstallFamily@ + \csname\@lst @#2@data\expandafter\endcsname + \csname\@lst @#5\endcsname {#1}{#2}{#3}} +% \end{macrocode} +% Now we check whether \meta{working procedure} is empty. Accordingly we use +% \texttt working procedure or \texttt style in the `data' definition. +% The working procedure is defined right here if necessary. +% \begin{macrocode} +\gdef\lst@InstallFamily@#1#2#3#4#5#6#7#8{% + \gdef#1{{#3}{#4}{#5}#2#7}% + \long\def\lst@temp##1{#6}% + \ifx\lst@temp\@gobble + \lst@AddTo#1{s#8}% + \else + \lst@AddTo#1{w#8}% + \global\@namedef{lst@g#4@wp}##1{#6}% + \fi} +% \end{macrocode} +% Nothing else is defined here, all the rest is done on demand. +% \end{macro} +% +% \begin{macro}{\lst@UseFamily} +% We look for the optional class number, provide this member, \ldots +% \begin{macrocode} +\gdef\lst@UseFamily#1{% + \def\lst@family{#1}% + \@ifnextchar[\lst@UseFamily@{\lst@UseFamily@[\@ne]}} +\gdef\lst@UseFamily@[#1]{% + \@tempcnta\lst@classoffset \advance\@tempcnta#1\relax + \lst@ProvideFamily\lst@family +% \end{macrocode} +% \ldots\space and build the control sequences \ldots +% \begin{macrocode} + \lst@UseFamily@a + {\lst@family\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}} +\gdef\lst@UseFamily@a#1{% + \expandafter\lst@UseFamily@b + \csname\@lst @#1@list\expandafter\endcsname + \csname\@lst @#1\expandafter\endcsname + \csname\@lst @#1@also\expandafter\endcsname + \csname\@lst @g#1\endcsname} +% \end{macrocode} +% \ldots\space required for |\lst@MakeKeywords| and |#6|. +% \begin{macrocode} +\gdef\lst@UseFamily@b#1#2#3#4#5\relax#6{\lstKV@XOptArg[]{#5}#6#1#2#3#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ProvideFamily} +% provides the member `|\the\@tempcnta|' of the family |#1|. We do nothing if +% the member already exists. Otherwise we expand the data macro defined above. +% Note that we don't use the counter if it equals one. +% \begin{macrocode} +\gdef\lst@ProvideFamily#1{% + \@ifundefined{lst@#1\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}% + {\expandafter\expandafter\expandafter\lst@ProvideFamily@ + \csname\@lst @#1@data\endcsname + {\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}% + {}} +% \end{macrocode} +% Now we have the following arguments +% \begin{macroargs} +% \item \meta{prefix} +% \item \meta{name} +% \item \meta{style name} +% \item \meta{default style name} +% \item \alternative{l,o} (language or other key) +% \item \alternative{w,s} (working procedure or style) +% \item \alternative{d,o} (\hookname{DetectKeywords} or \hookname{Output} hook) +% \item |\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi| +% \end{macroargs} +% We define |\lst@g|\meta{name}\meta{number}|@sty| to call either +% |\lst@g|\meta{name}|@wp| with the number as argument or +% |\lst@|\meta{style name}\meta{number} where the number belongs to the control +% sequence. +% \begin{macrocode} +\gdef\lst@ProvideFamily@#1#2#3#4#5#6#7#8{% + \expandafter\xdef\csname\@lst @g#2#8@sty\endcsname + {\if #6w% + \expandafter\noexpand\csname\@lst @g#2@wp\endcsname{#8}% + \else + \expandafter\noexpand\csname\@lst @#3#8\endcsname + \fi}% +% \end{macrocode} +% We ensure the existence of the style macro. This is done in the +% \hookname{Init} hook by assigning the default style if necessary. +% \begin{macrocode} + \ifx\@empty#3\@empty\else + \edef\lst@temp{\noexpand\lst@AddToHook{Init}{% + \noexpand\lst@ProvideStyle\expandafter\noexpand + \csname\@lst @#3#8\endcsname\noexpand#4}}% + \lst@temp + \fi +% \end{macrocode} +% We call a submacro to do the rest. It requires some control sequences. +% \begin{macrocode} + \expandafter\lst@ProvideFamily@@ + \csname\@lst @#2#8@list\expandafter\endcsname + \csname\@lst @#2#8\expandafter\endcsname + \csname\@lst @#2#8@also\expandafter\endcsname + \csname\@lst @g#2#8@list\expandafter\endcsname + \csname\@lst @g#2#8\expandafter\endcsname + \csname\@lst @g#2#8@sty\expandafter\endcsname + {#1}#5#6#7} +% \end{macrocode} +% Now we have (except that \meta{number} is possibly always missing) +% \begin{macroargs} +% \item |\lst@|\meta{name}\meta{number}|@list| +% \item |\lst@|\meta{name}\meta{number} +% \item |\lst@|\meta{name}\meta{number}|@also| +% \item |\lst@g|\meta{name}\meta{number}|@list| +% \item |\lst@g|\meta{name}\meta{number} +% \item |\lst@g|\meta{name}\meta{number}|@sty| +% \item \meta{prefix} +% \item \alternative{l,o} (language or other key) +% \item \alternative{w,s} (working procedure or style) +% \item \alternative{d,o} (\hookname{DetectKeywords} or \hookname{Output} hook) +% \end{macroargs} +% Note that |#9| and `|#10|' are read by |\lst@InstallTest|. We initialize all +% required `variables' (at \hookname{SetLanguage}) and install the test (which +% definition is in fact also delayed). +% \begin{macrocode} +\gdef\lst@ProvideFamily@@#1#2#3#4#5#6#7#8{% + \gdef#1{#2#5}\global\let#2\@empty \global\let#3\@empty % init + \gdef#4{#2#5}\global\let#5\@empty % init + \if #8l\relax + \lst@AddToHook{SetLanguage}{\def#1{#2#5}\let#2\@empty}% + \fi + \lst@InstallTest{#7}#1#2#4#5#6} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@InstallKeywords} +% Now we take advance of the optional argument construction above. Thus, we +% just insert |[\@ne]| as \meta{number} in the definitions of the keys. +% \begin{macrocode} +\gdef\lst@InstallKeywords#1#2#3#4#5{% + \lst@Key{#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeKeywords}% + \lst@Key{more#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeMoreKeywords}% + \lst@Key{delete#2}\relax + {\lst@UseFamily{#2}[\@ne]##1\relax\lst@DeleteKeywords}% + \ifx\@empty#3\@empty\else + \lst@Key{#3}{#4}{\@namedef{lst@#3}{##1}}% + \fi + \expandafter\lst@InstallFamily@ + \csname\@lst @#2@data\expandafter\endcsname + \csname\@lst @#5\endcsname {#1}{#2}{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ProvideStyle} +% If the style macro |#1| is not defined, it becomes equivalent to |#2|. +% \begin{macrocode} +\gdef\lst@ProvideStyle#1#2{% + \ifx#1\@undefined \let#1#2% + \else\ifx#1\relax \let#1#2\fi\fi} +% \end{macrocode} +% \end{macro} +% +% Finally we define |\lst@MakeKeywords|, \ldots, |\lst@DeleteKeywords|. +% We begin with two helper. +% +% \begin{macro}{\lst@BuildClassList} +% After |#1| follows a comma separated list of keyword classes terminated by +% |,\relax,|, e.g.~|keywords2,emph1,\relax,|. For each \meta{item} in this +% list we \emph{append} the two macros |\lst@|\meta{item}|\lst@g|\meta{item} +% to |#1|. +% \begin{macrocode} +\gdef\lst@BuildClassList#1#2,{% + \ifx\relax#2\@empty\else + \ifx\@empty#2\@empty\else + \lst@lExtend#1{\csname\@lst @#2\expandafter\endcsname + \csname\@lst @g#2\endcsname}% + \fi + \expandafter\lst@BuildClassList\expandafter#1 + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DeleteClassesIn} +% deletes pairs of tokens, namely the arguments |#2#3| to the submacro. +% \begin{macrocode} +\gdef\lst@DeleteClassesIn#1#2{% + \expandafter\lst@DCI@\expandafter#1#2\relax\relax} +\gdef\lst@DCI@#1#2#3{% + \ifx#2\relax + \expandafter\@gobbletwo + \else +% \end{macrocode} +% If we haven't reached the end of the class list, we define a temporary macro +% which removes all appearances. +% \begin{macrocode} + \def\lst@temp##1#2#3##2{% + \lst@lAddTo#1{##1}% + \ifx ##2\relax\else + \expandafter\lst@temp + \fi ##2}% + \let\@tempa#1\let#1\@empty + \expandafter\lst@temp\@tempa#2#3\relax + \fi + \lst@DCI@#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@MakeKeywords} +% We empty some macros and make use of |\lst@MakeMoreKeywords|. +% Note that this and the next two definitions have the following arguments: +% \begin{macroargs} +% \item class list (in brackets) +% \item keyword list +% \item |\lst@|\meta{name}|@list| +% \item |\lst@|\meta{name} +% \item |\lst@|\meta{name}|@also| +% \item |\lst@g|\meta{name} +% \end{macroargs} +% \begin{macrocode} +\gdef\lst@MakeKeywords[#1]#2#3#4#5#6{% + \def#3{#4#6}\let#4\@empty \let#5\@empty + \lst@MakeMoreKeywords[#1]{#2}#3#4#5#6} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@MakeMoreKeywords} +% We append classes and keywords. +% \begin{macrocode} +\gdef\lst@MakeMoreKeywords[#1]#2#3#4#5#6{% + \lst@BuildClassList#3#1,\relax,% + \lst@DefOther\lst@temp{,#2}\lst@lExtend#4\lst@temp} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@DeleteKeywords} +% We convert the keyword arguments via |\lst@MakeKeywords| and remove the +% classes and keywords. +% \begin{macrocode} +\gdef\lst@DeleteKeywords[#1]#2#3#4#5#6{% + \lst@MakeKeywords[#1]{#2}\@tempa\@tempb#5#6% + \lst@DeleteClassesIn#3\@tempa + \lst@DeleteKeysIn#4\@tempb} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Main families and classes} +% +% +% \paragraph{Keywords} +% +% \begin{lstkey}{keywords} +% Defining the keyword family gets very, very easy. +% \begin{macrocode} +\lst@InstallFamily k{keywords}{keywordstyle}\bfseries{keywordstyle}{}ld +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{ndkeywords} +% Second order keywords use the same trick as |\lst@InstallKeywords|. +% \begin{macrocode} +\lst@Key{ndkeywords}\relax + {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@MakeKeywords}% +\lst@Key{morendkeywords}\relax + {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@MakeMoreKeywords}% +\lst@Key{deletendkeywords}\relax + {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@DeleteKeywords}% +\lst@Key{ndkeywordstyle}\relax{\@namedef{lst@keywordstyle2}{#1}}% +% \end{macrocode} +% \lsthelper{Dr.~Peter~Leibner}{1999/11/05}{undefined \lst@UseKeywords, +% Illegal parameter number (##1)} reported two bugs: |\lst@UseKeywords| and +% |##1| became |\lst@UseFamily| and |#1|. +% \end{lstkey} +% +% \begin{lstkey}{keywordsprefix} +% is implemented experimentally. The one and only prefix indicates its +% presence by making |\lst@prefixkeyword| empty. We can catch this information +% in the \keyname{Output} hook. +% \begin{macrocode} +\lst@Key{keywordsprefix}\relax{\lst@DefActive\lst@keywordsprefix{#1}} +\global\let\lst@keywordsprefix\@empty +\lst@AddToHook{SelectCharTable} + {\ifx\lst@keywordsprefix\@empty\else + \expandafter\lst@CArg\lst@keywordsprefix\relax + \lst@CDef{}% + {\lst@ifletter\else + \global\let\lst@prefixkeyword\@empty + \fi}% + {}% + \fi} +\lst@AddToHook{Init}{\global\let\lst@prefixkeyword\relax} +\lst@AddToHook{Output} + {\ifx\lst@prefixkeyword\@empty + \let\lst@thestyle\lst@gkeywords@sty + \global\let\lst@prefixkeyword\relax + \fi}% +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{otherkeywords} +% Thanks to \lsthelper{Bradford~Chamberlain}{2001/07/07}{otherkeywords={@,@^} +% does not work} we now iterate down the list of `other keywords' and make each +% active---instead of making the whole argument active. We append the active +% token sequence to |\lst@otherkeywords| to define each `other' keyword. +% \begin{macrocode} +\lst@Key{otherkeywords}{}{% + \let\lst@otherkeywords\@empty + \lst@for{#1}\do{% + \lst@MakeActive{##1}% + \lst@lExtend\lst@otherkeywords{% + \expandafter\lst@CArg\lst@temp\relax\lst@CDef + {}\lst@PrintOtherKeyword\@empty}}} +\lst@AddToHook{SelectCharTable}{\lst@otherkeywords} +% \end{macrocode} +% |\lst@PrintOtherkeyword| has been changed to |\lst@PrintOtherKeyword| after a +% bug report by \lsthelper{Peter~Bartke}{2001/11/06}{undefined control sequence +% \lst@PrintOtherkeyword}. +% \end{lstkey} +% +% \begin{macro}{\lst@PrintOtherKeyword} +% print preceding characters, prepare the output and typeset the argument in +% keyword style. +% \begin{macrocode} +\gdef\lst@PrintOtherKeyword#1\@empty{% + \lst@XPrintToken + \begingroup + \lst@modetrue \lsthk@TextStyle + \let\lst@ProcessDigit\lst@ProcessLetter + \let\lst@ProcessOther\lst@ProcessLetter + \lst@lettertrue + \lst@gkeywords@sty{#1\lst@XPrintToken}% + \endgroup} +% \end{macrocode} +% \begin{TODO} +% Which part of \hookname{TextStyle} hook is required? +% \end{TODO} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \paragraph{The emphasize family} +% +% \begin{aspect}{emph} +% is just one macro call here. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{emph} +\lst@InstallFamily e{emph}{emphstyle}{}{emphstyle}{}od +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \paragraph{\TeX\ control sequences} +% +% \begin{aspect}{tex} +% Here we check the last `other' processed token. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{tex} +% \end{macrocode} +% \begin{macrocode} +\lst@InstallKeywords{cs}{texcs}{texcsstyle}\relax{keywordstyle} + {\ifx\lst@lastother\lstum@backslash + \let\lst@thestyle\lst@texcsstyle + \fi} + ld +% \end{macrocode} +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \paragraph{Compiler directives} +% +% \begin{aspect}{directives} +% \begin{lstkey}{directives} +% First some usual stuff. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{directives} +% \end{macrocode} +% \begin{macrocode} +\lst@NewMode\lst@CDmode +\lst@AddToHook{EOL}{\ifnum\lst@mode=\lst@CDmode \lst@LeaveMode \fi} +\lst@InstallKeywords{d}{directives}{directivestyle}\relax{keywordstyle} + {\ifnum\lst@mode=\lst@CDmode + \let\lst@thestyle\lst@directivestyle + \fi} + ld +% \end{macrocode} +% If the user has defined directives, we redefine the character |#|. +% \begin{macrocode} +\lst@AddToHook{SelectCharTable} + {\ifx\lst@directives\@empty\else + \lst@DefSaveDef{`\#}\lsts@CCD + {\lst@CalcColumn + \lst@ifmode\else +% \end{macrocode} +% We enter `directive mode' (without setting |\lst@ifmode| true) only in the +% first column. +% \begin{macrocode} + \ifnum\@tempcnta=\z@ + \lst@EnterMode{\lst@CDmode}{}% + \fi + \fi + \ifnum\lst@mode=\lst@CDmode +% \end{macrocode} +% We print |#| in directive style if and only if we are in the first column. +% \begin{macrocode} + \ifnum\@tempcnta=\z@ + \lst@XPrintToken +% \end{macrocode} +% \begin{TODO} +% Is this |\lst@XPrintToken| necessary? First column should imply that the +% current character string is empty and that there are no delayed characters. +% \end{TODO} +% \begin{macrocode} + {\let\lst@currstyle\lst@directivestyle + \lsts@CCD\lst@PrintToken}% + \else \lsts@CCD + \fi + \else \lsts@CCD + \fi}% + \fi} +% \end{macrocode} +% We introduce a new string type (thanks to \lsthelper{R.~Isernhagen} +% {1999/11/12}{float isn't keyword in #include }), which \ldots +% \begin{macrocode} +\lst@AddTo\lst@stringtypes{,directive} +\gdef\lst@StringDM@directive#1#2#3\@empty{% + \lst@CArg #2\relax\lst@CDef + {}% +% \end{macrocode} +% \ldots\space is active only in |\lst@CDmode|: +% \begin{macrocode} + {\let\lst@bnext\lst@CArgEmpty + \ifnum\lst@mode=\lst@CDmode + \def\lst@bnext{\lst@BeginString{#1}}% + \fi + \lst@bnext}% + \@empty + \lst@CArg #3\relax\lst@CDef + {}% + {\let\lst@enext\lst@CArgEmpty + \ifnum #1=\lst@mode + \let\lst@bnext\lst@EndString + \fi + \lst@bnext}% + \@empty} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Restricted keywords} +% +% \begin{aspect}{html} +% Support HTML and others. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{html} +% \end{macrocode} +% +% \begin{lstkey}{keywordsinside} +% Allocate a new mode and start the key. +% \begin{macrocode} +\lst@NewMode\lst@insidemode +\lst@Key{keywordsinside}{}{\lstKV@TwoArg{#1} + {\let\lst@DefInside\@empty + \ifx\@empty##1\@empty\else \ifx\@empty##2\@empty\else + \def\lst@DefInside{% +% \end{macrocode} +% The redefinitions of the characters enter respectively leave the mode and +% execute the old meanings. +% \begin{macrocode} + \lst@DefSaveDef{`##1}\lsts@insideb + {\lst@ifmode\else \ifnum\lst@mode=\lst@insidemode\else + \lst@XPrintToken + \lst@EnterMode\lst@insidemode{}% + \fi\fi + \lsts@insideb}% + \lst@DefSaveDef{`##2}\lsts@insidee + {\ifnum\lst@mode=\lst@insidemode + \lsts@insidee \lst@XPrintToken\lst@LeaveMode + \else + \expandafter\lsts@insidee + \fi}}% + \fi\fi}} +% \end{macrocode} +% The redefinition is done via \hookname{SelectCharTable}. It is reset in +% \hookname{SetLanguage} since a bug report from \lsthelper{Richard~Hoefter} +% {2000/11/03}{no keyword detection in case of language=HTML,language=Java}. +% \begin{macrocode} +\lst@AddToHook{SelectCharTable}{\lst@DefInside} +\lst@AddToHook{SetLanguage}{\let\lst@DefInside\@empty} +% \end{macrocode} +% We reset |\lst@thestyle| if necessary. +% \begin{macrocode} +\lst@AddToHook{Output} + {\ifx\lst@DefInside\@empty\else \ifx\lst@thestyle\lst@gkeywords@sty + \ifnum\lst@mode=\lst@insidemode\else + \let\lst@thestyle\@empty + \fi + \fi\fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{usekeywordsinside} +% Here we set |\lst@thestyle| to keyword style if necessary. +% \begin{macrocode} +\lst@Key{usekeywordsinside}t[t]{\lstKV@SetIf{#1}\lst@ifusekeysinside} +\lst@AddToHook{Output} + {\ifnum\lst@mode=\lst@insidemode \lst@ifusekeysinside\else + \let\lst@thestyle\lst@gkeywords@sty + \fi\fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@BeginCDATA} +% This macro is used by the XML language definition. +% \begin{macrocode} +\gdef\lst@BeginCDATA#1\@empty{% + \lst@TrackNewLines \lst@PrintToken + \lst@EnterMode\lst@GPmode{}\let\lst@ifmode\iffalse + \lst@mode\lst@insidemode #1\lst@mode\lst@GPmode\relax\lst@modetrue} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Keyword comments} +% +% \begin{aspect}{keywordcomments} +% includes both comment types and is possibly split into this and |dkcs|. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords,comments]{keywordcomments} +% \end{macrocode} +% +% \begin{macro}{\lst@BeginKC} +% \begin{macro}{\lst@BeginKCS} +% Starting a keyword comment is easy, but \ldots +% \begin{macrocode} +\lst@NewMode\lst@KCmode \lst@NewMode\lst@KCSmode +\gdef\lst@BeginKC{% + \lst@ResetToken + \lst@BeginComment\lst@KCmode\lst@commentstyle\@empty} +\gdef\lst@BeginKCS{% + \lst@ResetToken + \lst@BeginComment\lst@KCSmode\lst@commentstyle\@empty} +% \end{macrocode} +% \ldots\space we must ensure that the comment starts after printing the +% comment delimiter since it could be a keyword. We assign |\lst@BeginKC|[|S|] +% to |\lst@KCpost|, which is executed and reset in \hookname{PostOutput}. +% \begin{macrocode} +\lst@AddToHook{PostOutput}{\lst@KCpost \global\let\lst@KCpost\@empty} +\global\let\lst@KCpost\@empty % init +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@EndKC} +% leaves the comment mode before the (temporaryly saved) comment delimiter is +% printed. +% \begin{macrocode} +\gdef\lst@EndKC{\lst@SaveToken \lst@LeaveMode \lst@RestoreToken} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{keywordcomment} +% The delimiters must be identical here, thus we use |\lst@KCmatch|. Note the +% last argument |o| to |\lst@InstallKeywords|: The working test is installed +% in the \hookname{Output} hook and not in \hookname{DetectKeywords}. +% Otherwise we couldn't detect the ending delimiter since keyword detection is +% done if and only if mode changes are allowed. +% \begin{macrocode} +\lst@InstallKeywords{kc}{keywordcomment}{}\relax{} + {\ifnum\lst@mode=\lst@KCmode + \edef\lst@temp{\the\lst@token}% + \ifx\lst@temp\lst@KCmatch + \lst@EndKC + \fi + \else + \lst@ifmode\else + \xdef\lst@KCmatch{\the\lst@token}% + \global\let\lst@KCpost\lst@BeginKC + \fi + \fi} + lo +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{keywordcommentsemicolon} +% The key simply stores the keywords. +% \begin{macrocode} +\lst@Key{keywordcommentsemicolon}{}{\lstKV@ThreeArg{#1}% + {\def\lst@KCAkeywordsB{##1}% + \def\lst@KCAkeywordsE{##2}% + \def\lst@KCBkeywordsB{##3}% + \def\lst@KCkeywords{##1##2##3}}} +% \end{macrocode} +% We define an appropriate semicolon if this keyword comment type is defined. +% Appropriate means that we leave any keyword comment mode if active. +% \lsthelper{Oldrich~Jedlicka}{2001/12/12}{keywordcomment(semicolon) fails} +% reported a bug and provided the fix, the two |\@empty|s. +% \begin{macrocode} +\lst@AddToHook{SelectCharTable} + {\ifx\lst@KCkeywords\@empty\else + \lst@DefSaveDef{`\;}\lsts@EKC + {\lst@XPrintToken + \ifnum\lst@mode=\lst@KCmode \lst@EndComment\@empty \else + \ifnum\lst@mode=\lst@KCSmode \lst@EndComment\@empty + \fi \fi + \lsts@EKC}% + \fi} +% \end{macrocode} +% The `working identifier' macros enter respectively leave comment mode. +% \begin{macrocode} +\gdef\lst@KCAWorkB{% + \lst@ifmode\else \global\let\lst@KCpost\lst@BeginKC \fi} +\gdef\lst@KCBWorkB{% + \lst@ifmode\else \global\let\lst@KCpost\lst@BeginKCS \fi} +\gdef\lst@KCAWorkE{\ifnum\lst@mode=\lst@KCmode \lst@EndKC \fi} +% \end{macrocode} +% Now we install the tests and initialize the given macros. +% \begin{macrocode} +\lst@ProvideFamily@@ + \lst@KCAkeywordsB@list\lst@KCAkeywordsB \lst@KC@also + \lst@gKCAkeywordsB@list\lst@gKCAkeywordsB \lst@KCAWorkB + {kcb}owo % prefix, other key, working procedure, Output hook +\lst@ProvideFamily@@ + \lst@KCAkeywordsE@list\lst@KCAkeywordsE \lst@KC@also + \lst@gKCAkeywordsE@list\lst@gKCAkeywordsE \lst@KCAWorkE + {kce}owo +\lst@ProvideFamily@@ + \lst@KCBkeywordsB@list\lst@KCBkeywordsB \lst@KC@also + \lst@gKCBkeywordsB@list\lst@gKCBkeywordsB \lst@KCBWorkB + {kcs}owo +% \end{macrocode} +% \end{lstkey} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Export of identifiers} +% +% \begin{aspect}{index} +% \begin{macro}{\lstindexmacro} +% One more `keyword' class. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{index} +\lst@InstallFamily w{index}{indexstyle}\lstindexmacro{indexstyle} + {\csname\@lst @indexstyle#1\expandafter\endcsname + \expandafter{\the\lst@token}} + od +\lst@UserCommand\lstindexmacro#1{\index{{\ttfamily#1}}} +\lst@EndAspect +% +% \end{macrocode} +% \end{macro} +% \end{aspect} +% +% \begin{aspect}{procnames} +% \begin{lstkey}{procnamestyle} +% \begin{lstkey}{procnamekeys} +% \begin{lstkey}{indexprocnames} +% The `idea' here is the usage of a global |\lst@ifprocname|, indicating a +% preceding `procedure keyword'. All the other is known stuff. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{procnames} +\gdef\lst@procnametrue{\global\let\lst@ifprocname\iftrue} +\gdef\lst@procnamefalse{\global\let\lst@ifprocname\iffalse} +\lst@AddToHook{Init}{\lst@procnamefalse} +\lst@AddToHook{DetectKeywords} + {\lst@ifprocname + \let\lst@thestyle\lst@procnamestyle + \lst@ifindexproc \csname\@lst @gindex@sty\endcsname \fi + \lst@procnamefalse + \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{procnamestyle}{}{\def\lst@procnamestyle{#1}} +\lst@Key{indexprocnames}{false}[t]{\lstKV@SetIf{#1}\lst@ifindexproc} +\lst@AddToHook{Init}{\lst@ifindexproc \lst@indexproc \fi} +\gdef\lst@indexproc{% + \@ifundefined{lst@indexstyle1}% + {\@namedef{lst@indexstyle1}##1{}}% + {}} +% \end{macrocode} +% The default definition of |\lst@indexstyle| above has been moved outside the +% hook after a bug report from \lsthelper{Ulrich~G.~Wortmann}{2002/01/22} +% {procnames doesn't work}. +% \begin{macrocode} +\lst@InstallKeywords w{procnamekeys}{}\relax{} + {\global\let\lst@PNpost\lst@procnametrue} + od +\lst@AddToHook{PostOutput}{\lst@PNpost\global\let\lst@PNpost\@empty} +\global\let\lst@PNpost\@empty % init +\lst@EndAspect +% +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{aspect} +% +% +% \section{More aspects and keys} +% +% \begin{lstkey}{basicstyle} +% \begin{lstkey}{inputencoding} +% There is no better place to define these keys, I think. +% \begin{macrocode} +%<*kernel> +\lst@Key{basicstyle}\relax{\def\lst@basicstyle{#1}} +\lst@Key{inputencoding}\relax{\def\lst@inputenc{#1}} +\lst@AddToHook{Init} + {\lst@basicstyle + \ifx\lst@inputenc\@empty\else + \@ifundefined{inputencoding}{}% + {\inputencoding\lst@inputenc}% + \fi} +\lst@AddToHookExe{EmptyStyle} + {\let\lst@basicstyle\@empty + \let\lst@inputenc\@empty} +% +% \end{macrocode} +% Michael Niedermair asked for a key like \keyname{inputencoding}. +% \end{lstkey} +% \end{lstkey} +% +% +% \subsection{Styles and languages} +% +% \begin{aspect}{style} +% We begin with style definition and selection. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{style} +% \end{macrocode} +% +% \begin{macro}{\lststylefiles} +% This macro is defined if and only if it's undefined yet. +% \begin{macrocode} +\@ifundefined{lststylefiles} + {\lst@UserCommand\lststylefiles{lststy0.sty}}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstdefinestyle} +% \begin{macro}{\lst@definestyle} +% \begin{macro}{\lst@DefStyle} +% are defined in terms of |\lst@DefStyle|, which is defined via +% |\lst@DefDriver|. +% \begin{macrocode} +\lst@UserCommand\lstdefinestyle{\lst@DefStyle\iftrue} +\lst@UserCommand\lst@definestyle{\lst@DefStyle\iffalse} +\gdef\lst@DefStyle{\lst@DefDriver{style}{sty}\lstset} +% \end{macrocode} +% The `empty' style calls the initial empty hook \hookname{EmptyStyle}. +% \begin{macrocode} +\global\@namedef{lststy@$}{\lsthk@EmptyStyle} +\lst@AddToHook{EmptyStyle}{}% init +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{lstkey}{style} +% is an application of |\lst@LAS|. We just specify the hook and an empty +% argument as `pre' and `post' code. +% \begin{macrocode} +\lst@Key{style}\relax{% + \lst@LAS{style}{sty}{[]{#1}}\lst@NoAlias\lststylefiles + \lsthk@SetStyle + {}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{SetStyle}{}% init +% \end{macrocode} +% \end{lstkey} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% \begin{aspect}{language} +% Now we deal with commands used in defining and selecting programming +% languages, in particular with aliases. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{language} +% \end{macrocode} +% +% \begin{macro}{\lstlanguagefiles} +% This macro is defined if and only if it's undefined yet. +% \begin{macrocode} +\@ifundefined{lstdriverfiles} + {\lst@UserCommand\lstlanguagefiles{lstlang0.sty}}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstdefinelanguage} +% \begin{macro}{\lst@definelanguage} +% \begin{macro}{\lst@DefLang} +% are defined in terms of |\lst@DefLang|, which is defined via +% |\lst@DefDriver|. +% \begin{macrocode} +\lst@UserCommand\lstdefinelanguage{\lst@DefLang\iftrue} +\lst@UserCommand\lst@definelanguage{\lst@DefLang\iffalse} +\gdef\lst@DefLang{\lst@DefDriver{language}{lang}\lstset} +% \end{macrocode} +% Now we can provide the `empty' language. +% \begin{macrocode} +\lstdefinelanguage{}{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{lstkey}{language} +% \begin{lstkey}{alsolanguage} +% is mainly an application of |\lst@LAS|. +% \begin{macrocode} +\lst@Key{language}\relax{\lstKV@OptArg[]{#1}% + {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles + \lsthk@SetLanguage + {\lst@FindAlias[##1]{##2}% + \let\lst@language\lst@malias + \let\lst@dialect\lst@oalias}}} +% \end{macrocode} +% Ditto, we simply don't execute |\lsthk@SetLanguage|. +% \begin{macrocode} +\lst@Key{alsolanguage}\relax{\lstKV@OptArg[]{#1}% + {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles + {}% + {\lst@FindAlias[##1]{##2}% + \let\lst@language\lst@malias + \let\lst@dialect\lst@oalias}}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{SetLanguage}{}% init +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lstalias} +% Now we concentrate on aliases and default dialects. +% |\lsta@|\meta{language}|$|\meta{dialect} and |\lsta@|\meta{language} contain +% the aliases of a particular dialect respectively a complete language. +% We'll use a |$|-character to separate a language name from its dialect. +% \begin{macrocode} +\lst@UserCommand\lstalias{\@ifnextchar[\lstalias@\lstalias@@} +\gdef\lstalias@[#1]#2[#3]#4{\lst@NormedNameDef{lsta@#2$#1}{#4$#3}} +\gdef\lstalias@@#1#2{\lst@NormedNameDef{lsta@#1}{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{defaultdialect} +% We simply store the dialect. +% \begin{macrocode} +\lst@Key{defaultdialect}\relax + {\lstKV@OptArg[]{#1}{\lst@NormedNameDef{lstdd@##2}{##1}}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@FindAlias} +% Now we have to find a language. First we test for a complete language alias, +% then we set the default dialect if necessary. +% \begin{macrocode} +\gdef\lst@FindAlias[#1]#2{% + \lst@NormedDef\lst@oalias{#1}% + \lst@NormedDef\lst@malias{#2}% + \@ifundefined{lsta@\lst@malias}{}% + {\edef\lst@malias{\csname\@lst a@\lst@malias\endcsname}}% +% \end{macrocode} +% \begin{macrocode} + \ifx\@empty\lst@oalias \@ifundefined{lstdd@\lst@malias}{}% + {\edef\lst@oalias{\csname\@lst dd@\lst@malias\endcsname}}% + \fi +% \end{macrocode} +% Now we are ready for an alias of a single dialect. +% \begin{macrocode} + \edef\lst@temp{\lst@malias $\lst@oalias}% + \@ifundefined{lsta@\lst@temp}{}% + {\edef\lst@temp{\csname\@lst a@\lst@temp\endcsname}}% +% \end{macrocode} +% Finally we again set the default dialect---for the case of a dialect alias. +% \begin{macrocode} + \expandafter\lst@FindAlias@\lst@temp $} +\gdef\lst@FindAlias@#1$#2${% + \def\lst@malias{#1}\def\lst@oalias{#2}% + \ifx\@empty\lst@oalias \@ifundefined{lstdd@\lst@malias}{}% + {\edef\lst@oalias{\csname\@lst dd@\lst@malias\endcsname}}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@RequireLanguages} +% This definition will be equivalent to |\lstloadlanguages|. We requested the +% given list of languages and load additionally required aspects. +% \begin{macrocode} +\gdef\lst@RequireLanguages#1{% + \lst@Require{language}{lang}{#1}\lst@FindAlias\lstlanguagefiles + \ifx\lst@loadaspects\@empty\else + \lst@RequireAspects\lst@loadaspects + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstloadlanguages} +% is the same as |\lst@RequireLanguages|. +% \begin{macrocode} +\global\let\lstloadlanguages\lst@RequireLanguages +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Format definitions*} +% +% \begin{aspect}{formats} +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{formats} +% \end{macrocode} +% +% \begin{macro}{\lstformatfiles} +% This macro is defined if and only if it's undefined yet. +% \begin{macrocode} +\@ifundefined{lstformatfiles} + {\lst@UserCommand\lstformatfiles{lstfmt0.sty}}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstdefineformat} +% \begin{macro}{\lst@defineformat} +% \begin{macro}{\lst@DefFormat} +% are defined in terms of |\lst@DefFormat|, which is defined via +% |\lst@DefDriver|. +% \begin{macrocode} +\lst@UserCommand\lstdefineformat{\lst@DefFormat\iftrue} +\lst@UserCommand\lst@defineformat{\lst@DefFormat\iffalse} +\gdef\lst@DefFormat{\lst@DefDriver{format}{fmt}\lst@UseFormat} +% \end{macrocode} +% We provide the `empty' format. +% \begin{macrocode} +\lstdefineformat{}{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{lstkey}{format} +% is an application of |\lst@LAS|. We just specify the hook as `pre' and an +% empty argument as `post' code. +% \begin{macrocode} +\lst@Key{format}\relax{% + \lst@LAS{format}{fmt}{[]{#1}}\lst@NoAlias\lstformatfiles + \lsthk@SetFormat + {}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{SetFormat}{\let\lst@fmtformat\@empty}% init +% \end{macrocode} +% \end{lstkey} +% +% +% \paragraph{Helpers} +% Our goal is to define the yet unkown |\lst@UseFormat|. This definition +% will parse the user supplied format. We start with some general macros. +% +% \begin{macro}{\lst@fmtSplit} +% splits the content of the macro |#1| at |#2| in the preceding characters +% |\lst@fmta| and the following ones |\lst@fmtb|. |\lst@if| is false if and +% only if |#1| doesn't contain |#2|. +% \begin{macrocode} +\gdef\lst@fmtSplit#1#2{% + \def\lst@temp##1#2##2\relax##3{% + \ifnum##3=\z@ + \ifx\@empty##2\@empty + \lst@false + \let\lst@fmta#1% + \let\lst@fmtb\@empty + \else + \expandafter\lst@temp#1\relax\@ne + \fi + \else + \def\lst@fmta{##1}\def\lst@fmtb{##2}% + \fi}% + \lst@true + \expandafter\lst@temp#1#2\relax\z@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@IfNextCharWhitespace} +% is defined in terms of |\lst@IfSubstring|. +% \begin{macrocode} +\gdef\lst@IfNextCharWhitespace#1#2#3{% + \lst@IfSubstring#3\lst@whitespaces{#1}{#2}#3} +% \end{macrocode} +% And here come all white space characters. +% \begin{macrocode} +\begingroup +\catcode`\^^I=12\catcode`\^^J=12\catcode`\^^M=12\catcode`\^^L=12\relax% +\lst@DefActive\lst@whitespaces{\ ^^I^^J^^M}% add ^^L +\global\let\lst@whitespaces\lst@whitespaces% +\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtIfIdentifier} +% tests the first character of |#1| +% \begin{macrocode} +\gdef\lst@fmtIfIdentifier#1{% + \ifx\relax#1\@empty + \expandafter\@secondoftwo + \else + \expandafter\lst@fmtIfIdentifier@\expandafter#1% + \fi} +% \end{macrocode} +% against the `letters' |_|, |@|, |A|,\ldots,|Z| and |a|,\ldots,|z|. +% \begin{macrocode} +\gdef\lst@fmtIfIdentifier@#1#2\relax{% + \let\lst@next\@secondoftwo + \ifnum`#1=`_\else + \ifnum`#1<64\else + \ifnum`#1<91\let\lst@next\@firstoftwo\else + \ifnum`#1<97\else + \ifnum`#1<123\let\lst@next\@firstoftwo\else + \fi \fi \fi \fi \fi + \lst@next} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtIfNextCharIn} +% is required for the optional \meta{exceptional characters}. +% The implementation is easy---refer section \ref{iSubstringTests}. +% \begin{macrocode} +\gdef\lst@fmtIfNextCharIn#1{% + \ifx\@empty#1\@empty \expandafter\@secondoftwo \else + \def\lst@next{\lst@fmtIfNextCharIn@{#1}}% + \expandafter\lst@next\fi} +\gdef\lst@fmtIfNextCharIn@#1#2#3#4{% + \def\lst@temp##1#4##2##3\relax{% + \ifx \@empty##2\expandafter\@secondoftwo + \else \expandafter\@firstoftwo \fi}% + \lst@temp#1#4\@empty\relax{#2}{#3}#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtCDef} +% We need derivations of |\lst@CDef| and |\lst@CDefX|: we have to test the +% next character against the sequence |#5| of exceptional characters. +% These tests are inserted here. +% \begin{macrocode} +\gdef\lst@fmtCDef#1{\lst@fmtCDef@#1} +\gdef\lst@fmtCDef@#1#2#3#4#5#6#7{% + \lst@CDefIt#1{#2}{#3}% + {\lst@fmtIfNextCharIn{#5}{#4#2#3}{#6#4#2#3#7}}% + #4% + {}{}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtCDefX} +% The same but `drop input'. +% \begin{macrocode} +\gdef\lst@fmtCDefX#1{\lst@fmtCDefX@#1} +\gdef\lst@fmtCDefX@#1#2#3#4#5#6#7{% + \let#4#1% + \ifx\@empty#2\@empty + \def#1{\lst@fmtIfNextCharIn{#5}{#4}{#6#7}}% + \else \ifx\@empty#3\@empty + \def#1##1{% + \ifx##1#2% + \def\lst@next{\lst@fmtIfNextCharIn{#5}{#4##1}% + {#6#7}}% + \else + \def\lst@next{#4##1}% + \fi + \lst@next}% + \else + \def#1{% + \lst@IfNextCharsArg{#2#3}% + {\lst@fmtIfNextCharIn{#5}{\expandafter#4\lst@eaten}% + {#6#7}}% + {\expandafter#4\lst@eaten}}% + \fi \fi} +% \end{macrocode} +% \end{macro} +% +% +% \paragraph{The parser} +% applies |\lst@fmtSplit| to cut a format definition into items, items into +% `input' and `output', and `output' into `pre' and 'post'. This should be +% clear if you are in touch with format definitions. +% +% \begin{macro}{\lst@UseFormat} +% Now we can start with the parser. +% \begin{macrocode} +\gdef\lst@UseFormat#1{% + \def\lst@fmtwhole{#1}% + \lst@UseFormat@} +\gdef\lst@UseFormat@{% + \lst@fmtSplit\lst@fmtwhole,% +% \end{macrocode} +% We assign the rest of the format definition, \ldots +% \begin{macrocode} + \let\lst@fmtwhole\lst@fmtb + \ifx\lst@fmta\@empty\else +% \end{macrocode} +% \ldots\space split the item at the equal sign, and work on the item. +% \begin{macrocode} + \lst@fmtSplit\lst@fmta=% + \ifx\@empty\lst@fmta\else +% \end{macrocode} +% \begin{TODO} +% Insert |\let\lst@arg\@empty| |\expandafter\lst@XConvert\lst@fmtb\@nil| +% |\let\lst@fmtb\lst@arg|. +% \end{TODO} +% \begin{macrocode} + \expandafter\lstKV@XOptArg\expandafter[\expandafter]% + \expandafter{\lst@fmtb}\lst@UseFormat@b + \fi + \fi +% \end{macrocode} +% Finally we process the next item if the rest is not empty. +% \begin{macrocode} + \ifx\lst@fmtwhole\@empty\else + \expandafter\lst@UseFormat@ + \fi} +% \end{macrocode} +% We make |\lst@fmtc| contain the preceding characters as a braced argument. +% To add more arguments, we first split the replacement tokens at the control +% sequence |\string|. +% \begin{macrocode} +\gdef\lst@UseFormat@b[#1]#2{% + \def\lst@fmtc{{#1}}\lst@lExtend\lst@fmtc{\expandafter{\lst@fmta}}% + \def\lst@fmtb{#2}% + \lst@fmtSplit\lst@fmtb\string +% \end{macrocode} +% We append an empty argument or |\lst@fmtPre| with `|\string|-preceding' +% tokens as argument. We do the same for the tokens after |\string|. +% \begin{macrocode} + \ifx\@empty\lst@fmta + \lst@lAddTo\lst@fmtc{{}}% + \else + \lst@lExtend\lst@fmtc{\expandafter + {\expandafter\lst@fmtPre\expandafter{\lst@fmta}}}% + \fi + \ifx\@empty\lst@fmtb + \lst@lAddTo\lst@fmtc{{}}% + \else + \lst@lExtend\lst@fmtc{\expandafter + {\expandafter\lst@fmtPost\expandafter{\lst@fmtb}}}% + \fi +% \end{macrocode} +% Eventually we extend |\lst@fmtformat| appropriately. Note that |\lst@if| +% still indicates whether the replacement tokens contain |\string|. +% \begin{macrocode} + \expandafter\lst@UseFormat@c\lst@fmtc} +% \end{macrocode} +% \begin{macrocode} +\gdef\lst@UseFormat@c#1#2#3#4{% + \lst@fmtIfIdentifier#2\relax + {\lst@fmtIdentifier{#2}% + \lst@if\else \PackageWarning{Listings}% + {Cannot drop identifier in format definition}% + \fi}% + {\lst@if + \lst@lAddTo\lst@fmtformat{\lst@CArgX#2\relax\lst@fmtCDef}% + \else + \lst@lAddTo\lst@fmtformat{\lst@CArgX#2\relax\lst@fmtCDefX}% + \fi + \lst@DefActive\lst@fmtc{#1}% + \lst@lExtend\lst@fmtformat{\expandafter{\lst@fmtc}{#3}{#4}}}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{SelectCharTable}{\lst@fmtformat} +\global\let\lst@fmtformat\@empty +% \end{macrocode} +% \end{macro} +% +% +% \paragraph{The formatting} +% +% \begin{macro}{\lst@fmtPre} +% \begin{macrocode} +\gdef\lst@fmtPre#1{% + \lst@PrintToken + \begingroup + \let\newline\lst@fmtEnsureNewLine + \let\space\lst@fmtEnsureSpace + \let\indent\lst@fmtIndent + \let\noindent\lst@fmtNoindent + #1% + \endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtPost} +% \begin{macrocode} +\gdef\lst@fmtPost#1{% + \global\let\lst@fmtPostOutput\@empty + \begingroup + \def\newline{\lst@AddTo\lst@fmtPostOutput\lst@fmtEnsureNewLine}% + \def\space{\aftergroup\lst@fmtEnsurePostSpace}% + \def\indent{\lst@AddTo\lst@fmtPostOutput\lst@fmtIndent}% + \def\noindent{\lst@AddTo\lst@fmtPostOutput\lst@fmtNoindent}% + \aftergroup\lst@PrintToken + #1% + \endgroup} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{Init}{\global\let\lst@fmtPostOutput\@empty} +\lst@AddToHook{PostOutput} + {\lst@fmtPostOutput \global\let\lst@fmtPostOutput\@empty} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtEnsureSpace} +% \begin{macro}{\lst@fmtEnsurePostSpace} +% \begin{macrocode} +\gdef\lst@fmtEnsureSpace{% + \lst@ifwhitespace\else \expandafter\lst@ProcessSpace \fi} +\gdef\lst@fmtEnsurePostSpace{% + \lst@IfNextCharWhitespace{}{\lst@ProcessSpace}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{lstkey}{fmtindent} +% \begin{macro}{\lst@fmtIndent} +% \begin{macro}{\lst@fmtNoindent} +% \begin{macrocode} +\lst@Key{fmtindent}{20pt}{\def\lst@fmtindent{#1}} +\newdimen\lst@fmtcurrindent +\lst@AddToHook{InitVars}{\global\lst@fmtcurrindent\z@} +\gdef\lst@fmtIndent{\global\advance\lst@fmtcurrindent\lst@fmtindent} +\gdef\lst@fmtNoindent{\global\advance\lst@fmtcurrindent-\lst@fmtindent} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{lstkey} +% +% \begin{macro}{\lst@fmtEnsureNewLine} +% \begin{macrocode} +\gdef\lst@fmtEnsureNewLine{% + \global\advance\lst@newlines\@ne + \global\advance\lst@newlinesensured\@ne + \lst@fmtignoretrue} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToAtTop\lst@DoNewLines{% + \ifnum\lst@newlines>\lst@newlinesensured + \global\advance\lst@newlines-\lst@newlinesensured + \fi + \global\lst@newlinesensured\z@} +\newcount\lst@newlinesensured % global +\lst@AddToHook{Init}{\global\lst@newlinesensured\z@} +% \end{macrocode} +% \begin{macrocode} +\gdef\lst@fmtignoretrue{\let\lst@fmtifignore\iftrue} +\gdef\lst@fmtignorefalse{\let\lst@fmtifignore\iffalse} +\lst@AddToHook{InitVars}{\lst@fmtignorefalse} +\lst@AddToHook{Output}{\lst@fmtignorefalse} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@fmtUseLostSpace} +% \begin{macrocode} +\gdef\lst@fmtUseLostSpace{% + \lst@ifnewline \kern\lst@fmtcurrindent \global\lst@lostspace\z@ + \else + \lst@OldOLS + \fi} +\lst@AddToHook{Init} + {\lst@true + \ifx\lst@fmtformat\@empty \ifx\lst@fmt\@empty \lst@false \fi\fi + \lst@if + \let\lst@OldOLS\lst@OutputLostSpace + \let\lst@OutputLostSpace\lst@fmtUseLostSpace + \let\lst@ProcessSpace\lst@fmtProcessSpace + \fi} +% \end{macrocode} +% \begin{TODO} +% This `lost space' doesn't use |\lst@alloverstyle| yet! +% \end{TODO} +% \end{macro} +% +% \begin{macro}{\lst@fmtProcessSpace} +% \begin{macrocode} +\gdef\lst@fmtProcessSpace{% + \lst@ifletter + \lst@Output + \lst@fmtifignore\else + \lst@AppendOther\lst@outputspace + \fi + \else \lst@ifkeepspaces + \lst@AppendOther\lst@outputspace + \else \ifnum\lst@newlines=\z@ + \lst@AppendSpecialSpace + \else \ifnum\lst@length=\z@ + \global\advance\lst@lostspace\lst@width + \global\advance\lst@pos\m@ne + \else + \lst@AppendSpecialSpace + \fi + \fi \fi \fi + \lst@whitespacetrue} +% \end{macrocode} +% \end{macro} +% +% +% \paragraph{Formatting identifiers} +% +% \begin{macro}{\lst@fmtIdentifier} +% We install a (keyword) test for the `format identifiers'. +% \begin{macrocode} +\lst@InstallTest{f} + \lst@fmt@list\lst@fmt \lst@gfmt@list\lst@gfmt + \lst@gfmt@wp + wd +\gdef\lst@fmt@list{\lst@fmt\lst@gfmt}\global\let\lst@fmt\@empty +\gdef\lst@gfmt@list{\lst@fmt\lst@gfmt}\global\let\lst@gfmt\@empty +% \end{macrocode} +% The working procedure expands |\lst@fmt$|\meta{string} (and defines +% |\lst@PrintToken| to do nothing). +% \begin{macrocode} +\gdef\lst@gfmt@wp{% + \begingroup \let\lst@UM\@empty + \let\lst@PrintToken\@empty + \csname\lst@ @fmt$\the\lst@token\endcsname + \endgroup} +% \end{macrocode} +% This control sequence is probably defined as `working identifier'. +% \begin{macrocode} +\gdef\lst@fmtIdentifier#1#2#3#4{% + \lst@DefOther\lst@fmta{#2}\edef\lst@fmt{\lst@fmt,\lst@fmta}% + \@namedef{\lst@ @fmt$\lst@fmta}{#3#4}} +% \end{macrocode} +% |\lst@fmt$|\meta{identifier} expands to a |\lst@fmtPre|/|\lst@fmtPost| +% sequence defined by |#2| and |#3|. +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% +% \subsection{Line numbers} +% +% \begin{aspect}{labels} +% \lsthelper{Rolf~Niepraschk}{1997/04/24}{line numbers} asked for line numbers. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{labels} +% \end{macrocode} +% +% \begin{lstkey}{numbers} +% Depending on the argument we define |\lst@PlaceNumber| to print the line +% number. +% \begin{macrocode} +\lst@Key{numbers}{none}{% + \let\lst@PlaceNumber\@empty + \lstKV@SwitchCases{#1}% + {none&\\% + left&\def\lst@PlaceNumber{\llap{\normalfont + \lst@numberstyle{\thelstnumber}\kern\lst@numbersep}}\\% + right&\def\lst@PlaceNumber{\rlap{\normalfont + \kern\linewidth \kern\lst@numbersep + \lst@numberstyle{\thelstnumber}}}% + }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{numberstyle} +% \begin{lstkey}{numbersep} +% \begin{lstkey}{stepnumber} +% \begin{lstkey}{numberblanklines} +% Definition of the keys. +% \begin{macrocode} +\lst@Key{numberstyle}{}{\def\lst@numberstyle{#1}} +\lst@Key{numbersep}{10pt}{\def\lst@numbersep{#1}} +\lst@Key{stepnumber}{1}{\def\lst@stepnumber{#1\relax}} +\lst@AddToHook{EmptyStyle}{\let\lst@stepnumber\@ne} +\lst@Key{numberblanklines}{true}[t] + {\lstKV@SetIf{#1}\lst@ifnumberblanklines} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{lstkey}{firstnumber} +% We select the first number according to the argument. +% \begin{macrocode} +\lst@Key{firstnumber}{auto}{% + \lstKV@SwitchCases{#1}% + {auto&\let\lst@firstnumber\@undefined\\% + last&\let\lst@firstnumber\c@lstnumber + }{\def\lst@firstnumber{#1\relax}}} +\lst@AddToHook{PreSet}{\let\lst@advancenumber\z@} +\lst@AddToHook{PreInit} + {\ifx\lst@firstnumber\@undefined + \let\lst@firstnumber\lst@firstline + \fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@SetFirstNumber} +% \begin{macro}{\lst@SaveFirstNumber} +% \lsthelper{Boris~Veytsman}{1998/03/25}{continue line numbering: a.c b.c a.c} +% proposed to continue line numbers according to listing names. We define the +% label number of the first printing line here. A bug reported by +% \lsthelper{Jens~Schwarzer}{2001/05/29}{wrong line numbering of lstlisting +% with first>1} has been removed by replacing |\@ne| by |\lst@firstline|. +% \begin{macrocode} +\gdef\lst@SetFirstNumber{% + \ifx\lst@firstnumber\@undefined + \@tempcnta 0\csname\@lst no@\lst@intname\endcsname\relax + \ifnum\@tempcnta=\z@ \@tempcnta\lst@firstline + \else \lst@nololtrue \fi + \advance\@tempcnta\lst@advancenumber + \edef\lst@firstnumber{\the\@tempcnta\relax}% + \fi} +% \end{macrocode} +% The current label is stored in|\lstno@|\meta{name}. If the name is empty, +% we use a space instead, which leaves |\lstno@| undefined. +% \begin{macrocode} +\gdef\lst@SaveFirstNumber{% + \expandafter\xdef + \csname\@lst no\ifx\lst@intname\@empty @ \else @\lst@intname\fi + \endcsname{\the\c@lstnumber}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c@lstnumber} +% This counter keeps the current label number. We use it as current label to +% make line numbers referenced by |\ref|. This was proposed by +% \lsthelper{Boris~Veytsman}{1998/03/25}{make line numbers referenced via +% \label and \ref}. We now use |\refstepcounter| to do the job---thanks to a +% bug report from \lsthelper{Christian~Gudrian}{2000/11/13}{\ref{lst:line} +% jumps to top of listing and not to the line}. +% \begin{macrocode} +\newcounter{lstnumber}% \global +\global\c@lstnumber\@ne % init +\renewcommand*\thelstnumber{\@arabic\c@lstnumber} +\lst@AddToHook{EveryPar} + {\global\advance\c@lstnumber\lst@advancelstnum + \global\advance\c@lstnumber\m@ne \refstepcounter{lstnumber}% + \lst@SkipOrPrintLabel}% +\global\let\lst@advancelstnum\@ne +% \end{macrocode} +% Note that the counter advances \emph{before} the label is printed and not +% afterwards. Otherwise we have wrong references---reported by +% \lsthelper{Gregory~Van~Vooren}{1999/06/04}{reference one unit too large}. +% \begin{macrocode} +\lst@AddToHook{Init}{\def\@currentlabel{\thelstnumber}} +% \end{macrocode} +% The label number is initialized and we ensure correct line numbers for +% continued listings. +% \begin{macrocode} +\lst@AddToHook{InitVars} + {\global\c@lstnumber\lst@firstnumber + \global\advance\c@lstnumber\lst@advancenumber + \global\advance\c@lstnumber-\lst@advancelstnum + \ifx \lst@firstnumber\c@lstnumber + \global\advance\c@lstnumber-\lst@advancelstnum + \fi} +\lst@AddToHook{ExitVars} + {\global\advance\c@lstnumber\lst@advancelstnum} +% \end{macrocode} +% \lsthelper{Walter~E.~Brown}{2001/05/22}{pdftex 3.14159-14f warning: +% destination with the same identifier} reported problems with pdftex and +% \packagename{hyperref}. A bad default of |\theHlstlabel| was the reason. +% \lsthelper{Heiko~Oberdiek}{2001/11/08}{pdftex warning: destination with +% the same identifier} found another bug which was due to the localization +% of |\lst@neglisting|. He also provided the following fix, replacing +% |\thelstlisting| with the |\ifx| \ldots\ |\fi| construction. +% \begin{macrocode} +\AtBeginDocument{% + \def\theHlstnumber{\ifx\lst@@caption\@empty \lst@neglisting + \else \thelstlisting \fi + .\thelstnumber}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@skipnumbers} +% There are more things to do. We calculate how many lines must skip their +% label. The formula is +% $$|\lst@skipnumbers|= +% \textrm{\emph{first printing line}}\bmod|\lst@stepnumber|.$$ +% Note that we use a nonpositive representative for |\lst@skipnumbers|. +% \begin{macrocode} +\newcount\lst@skipnumbers % \global +\lst@AddToHook{Init} + {\ifnum \z@>\lst@stepnumber + \let\lst@advancelstnum\m@ne + \edef\lst@stepnumber{-\lst@stepnumber}% + \fi + \ifnum \z@<\lst@stepnumber + \global\lst@skipnumbers\lst@firstnumber + \global\divide\lst@skipnumbers\lst@stepnumber + \global\multiply\lst@skipnumbers-\lst@stepnumber + \global\advance\lst@skipnumbers\lst@firstnumber + \ifnum\lst@skipnumbers>\z@ + \global\advance\lst@skipnumbers -\lst@stepnumber + \fi +% \end{macrocode} +% If |\lst@stepnumber| is zero, no line numbers are printed: +% \begin{macrocode} + \else + \let\lst@SkipOrPrintLabel\relax + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@SkipOrPrintLabel} +% But default is this. We use the fact that |\lst@skipnumbers| is nonpositive. +% The counter advances every line and if that counter is zero, we print a line +% number and decrement the counter by |\lst@stepnumber|. +% \begin{macrocode} +\gdef\lst@SkipOrPrintLabel{% + \ifnum\lst@skipnumbers=\z@ + \global\advance\lst@skipnumbers-\lst@stepnumber\relax + \lst@PlaceNumber + \fi + \global\advance\lst@skipnumbers\@ne} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{OnEmptyLine}{% + \lst@ifnumberblanklines\else \ifnum\lst@skipnumbers=\z@ + \global\advance\lst@skipnumbers-\lst@stepnumber\relax + \fi\fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Line shape and line breaking} +% +% \begin{macro}{\lst@parshape} +% We define a default version of |\lst@parshape| for the case that the +% \aspectname{lineshape} aspect is not loaded. We use this parshape every line +% (in fact every paragraph). Furthermore we must repeat the parshape if we +% close a group level---or the shape is forgotten. +% \begin{macrocode} +%<*kernel> +\def\lst@parshape{\parshape\@ne \z@ \linewidth} +\lst@AddToHookAtTop{EveryLine}{\lst@parshape} +\lst@AddToHookAtTop{EndGroup}{\lst@parshape} +% +% \end{macrocode} +% \end{macro} +% +% \begin{aspect}{lineshape} +% Our first aspect in this section. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{lineshape} +% \end{macrocode} +% +% \begin{lstkey}{xleftmargin} +% \begin{lstkey}{xrightmargin} +% \begin{lstkey}{resetmargins} +% \begin{lstkey}{linewidth} +% Usual stuff. +% \begin{macrocode} +\lst@Key{xleftmargin}{\z@}{\def\lst@xleftmargin{#1}} +\lst@Key{xrightmargin}{\z@}{\def\lst@xrightmargin{#1}} +\lst@Key{resetmargins}{false}[t]{\lstKV@SetIf{#1}\lst@ifresetmargins} +% \end{macrocode} +% The margins become zero if we make an exact box around the listing. +% \begin{macrocode} +\lst@AddToHook{BoxUnsafe}{\let\lst@xleftmargin\z@ + \let\lst@xrightmargin\z@} +\lst@AddToHook{TextStyle}{% + \let\lst@xleftmargin\z@ \let\lst@xrightmargin\z@ + \let\lst@ifresetmargins\iftrue} +% \end{macrocode} +% Added above hook after bug report from \lsthelper{Magnus~Lewis-Smith} +%{1999/08/06}{|\lstinline| indented} and \lsthelper{Jos\'e~Romildo~Malaquias} +%{2000/08/22}{|\lstinline| indented (resetmargins)} respectively. +% \begin{macrocode} +\lst@Key{linewidth}\linewidth{\def\lst@linewidth{#1}} +\lst@AddToHook{PreInit}{\linewidth\lst@linewidth\relax} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@parshape} +% The definition itself is easy. +% \begin{macrocode} +\gdef\lst@parshape{% + \parshape\@ne \@totalleftmargin \linewidth} +% \end{macrocode} +% We calculate the line width and (inner/outer) indent for a listing. +% \begin{macrocode} +\lst@AddToHook{Init} + {\lst@ifresetmargins + \advance\linewidth\@totalleftmargin + \advance\linewidth\rightmargin + \@totalleftmargin\z@ + \fi + \advance\linewidth-\lst@xleftmargin + \advance\linewidth-\lst@xrightmargin + \advance\@totalleftmargin\lst@xleftmargin\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{lineskip} +% The introduction of this key is due to communication with +% \lsthelper{Andreas~Bartelt}{1997/09/11}{problem with redefed \parskip; +% \lstlineskip introduced}. Version 1.0 implements this feature by +% redefining |\baselinestretch|. +% \begin{macrocode} +\lst@Key{lineskip}{\z@}{\def\lst@lineskip{#1\relax}} +\lst@AddToHook{Init} + {\parskip\z@ + \ifdim\z@=\lst@lineskip\else + \@tempdima\baselineskip + \advance\@tempdima\lst@lineskip + \divide\@tempdima\strip@pt\baselineskip\relax + \edef\baselinestretch{\strip@pt\@tempdima}% + \selectfont + \fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{breaklines} +% \begin{lstkey}{breakindent} +% \begin{lstkey}{breakautoindent} +% \begin{lstkey}{prebreak} +% \begin{lstkey}{postbreak} +% As usual we have no problems in announcing more keys. +% \begin{macrocode} +\lst@Key{breaklines}{false}[t]{\lstKV@SetIf{#1}\lst@ifbreaklines} +\lst@Key{breakindent}{20pt}{\def\lst@breakindent{#1}} +\lst@Key{breakautoindent}{t}[t]{\lstKV@SetIf{#1}\lst@ifbreakautoindent} +\lst@Key{prebreak}{}{\def\lst@prebreak{#1}} +\lst@Key{postbreak}{}{\def\lst@postbreak{#1}} +% \end{macrocode} +% We assign some different macros and (if necessary) suppress ``underfull +% |\hbox|'' messages (and use different pretolerance): +% \begin{macrocode} +\lst@AddToHook{Init} + {\lst@ifbreaklines + \hbadness\@M \pretolerance\@M +% \end{macrocode} +% We use the normal parshape and the calculated |\lst@breakshape| (see below). +% \begin{macrocode} + \def\lst@parshape{\parshape\tw@ \@totalleftmargin\linewidth + \lst@breakshape}% + \else + \let\lst@discretionary\@empty + \fi} +\lst@AddToHook{OnNewLine} + {\lst@ifbreaklines \lst@breakNewLine \fi} +% \end{macrocode} +% \end{lstkey}\end{lstkey}\end{lstkey}\end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@discretionary} +% \begin{macro}{\lst@spacekern} +% Here comes the whole magic: We set a discretionary break after each `output +% unit'. However we redefine |\space| to be used inside |\discretionary| and +% use \hookname{EveryLine} hook. +% \begin{macrocode} +\gdef\lst@discretionary{% + \discretionary{\let\space\lst@spacekern\lst@prebreak}% + {\llap{\lsthk@EveryLine \kern\lst@breakcurrindent}% + \let\space\lst@spacekern\lst@postbreak}{}} +\lst@AddToHook{PostOutput}{\lst@discretionary} +\gdef\lst@spacekern{\kern\lst@width} +% \end{macrocode} +% \begin{ALTERNATIVE} +% |\penalty\@M \hskip\z@ plus 1fil \penalty0\hskip\z@ plus-1fil| \emph{before} +% each `output unit' (i.e.~before |\hbox{...}| in the output macros) also break +% the lines as desired. But we wouldn't have |prebreak| and |postbreak|. +% \end{ALTERNATIVE} +% \end{macro}\end{macro} +% +% \begin{macro}{\lst@breakNewLine} +% We use \keyname{breakindent}, and additionally the current line indention +% (coming from white spaces at the beginning of the line) if `auto indent' is +% on. +% \begin{macrocode} +\gdef\lst@breakNewLine{% + \@tempdima\lst@breakindent\relax + \lst@ifbreakautoindent \advance\@tempdima\lst@lostspace \fi +% \end{macrocode} +% Now we calculate the margin and line width of the wrapped part \ldots +% \begin{macrocode} + \@tempdimc-\@tempdima \advance\@tempdimc\linewidth + \advance\@tempdima\@totalleftmargin +% \end{macrocode} +% \ldots\space and store it in |\lst@breakshape|. +% \begin{macrocode} + \xdef\lst@breakshape{\noexpand\lst@breakcurrindent \the\@tempdimc}% + \xdef\lst@breakcurrindent{\the\@tempdima}} +% \end{macrocode} +% \begin{TODO} +% We could speed this up by allocating two global dimensions. +% \end{TODO} +% \end{macro} +% +% \begin{macro}{\lst@breakshape} +% \lsthelper{Andreas~Deininger}{2000/08/25}{`breaklines,first>1' leads to +% ``undefined control sequence'' error} reported a problem which is resolved +% by providing a default break shape. +% \begin{macrocode} +\gdef\lst@breakshape{\@totalleftmargin \linewidth} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@breakProcessOther} +% is the same as |\lst@ProcessOther| except that it also outputs the current +% token string. This inserts a potential linebreak point. +% Only the closing parenthesis uses this macro yet. +% \begin{macrocode} +\gdef\lst@breakProcessOther#1{\lst@ProcessOther#1\lst@OutputOther} +\lst@AddToHook{SelectCharTable} + {\lst@ifbreaklines \lst@Def{`)}{\lst@breakProcessOther)}\fi} +% \end{macrocode} +% A bug reported by \lsthelper{Gabriel~Tauro}{2001/04/18}{unexpected `)' if +% the character appears before first printed line} has been removed by using +% |\lst@ProcessOther| instead of |\lst@AppendOther|. +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Frames} +% +% \begin{aspect}{frames} +% Another aspect. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[lineshape]{frames} +% \end{macrocode} +% +% \begin{lstkey}{framexleftmargin} +% \begin{lstkey}{framexrightmargin} +% \begin{lstkey}{framextopmargin} +% \begin{lstkey}{framexbottommargin} +% These keys just save the argument. +% \begin{macrocode} +\lst@Key{framexleftmargin}{\z@}{\def\lst@framexleftmargin{#1}} +\lst@Key{framexrightmargin}{\z@}{\def\lst@framexrightmargin{#1}} +\lst@Key{framextopmargin}{\z@}{\def\lst@framextopmargin{#1}} +\lst@Key{framexbottommargin}{\z@}{\def\lst@framexbottommargin{#1}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{lstkey}{backgroundcolor} +% \lsthelper{Ralf~Imh\"auser}{2000/01/08}{coloured background} inspired the +% key \keyname{backgroundcolor}. All keys save the argument, and \ldots +% \begin{macrocode} +\lst@Key{backgroundcolor}{}{\def\lst@bkgcolor{#1}} +\lst@Key{fillcolor}{}{\def\lst@fillcolor{#1}} +\lst@Key{rulecolor}{}{\def\lst@rulecolor{#1}} +\lst@Key{rulesepcolor}{}{\def\lst@rulesepcolor{#1}} +% \end{macrocode} +% \ldots\space some have default settings if they are empty. +% \begin{macrocode} +\lst@AddToHook{Init}{% + \ifx\lst@fillcolor\@empty + \let\lst@fillcolor\lst@bkgcolor + \fi + \ifx\lst@rulesepcolor\@empty + \let\lst@rulesepcolor\lst@fillcolor + \fi} +% \end{macrocode} +% \end{lstkey} +% +% \begin{lstkey}{rulesep} +% \begin{lstkey}{framerule} +% \begin{lstkey}{framesep} +% \begin{lstkey}{frameshape} +% Another set of keys, which mainly save their respective argument. +% \keyname{frameshape} capitalizes all letters, and checks whether at least one +% round corner is specified. Eventually we define |\lst@frame| to be empty if +% and only if there is no frameshape. +% \begin{macrocode} +\lst@Key{rulesep}{2pt}{\def\lst@rulesep{#1}} +\lst@Key{framerule}{.4pt}{\def\lst@framerulewidth{#1}} +\lst@Key{framesep}{3pt}{\def\lst@frametextsep{#1}} +\lst@Key{frameshape}{}{% + \let\lst@xrulecolor\@empty + \lstKV@FourArg{#1}% + {\uppercase{\def\lst@frametshape{##1}}% + \uppercase{\def\lst@framelshape{##2}}% + \uppercase{\def\lst@framershape{##3}}% + \uppercase{\def\lst@framebshape{##4}}% + \let\lst@ifframeround\iffalse + \lst@IfSubstring R\lst@frametshape{\let\lst@ifframeround\iftrue}{}% + \lst@IfSubstring R\lst@framebshape{\let\lst@ifframeround\iftrue}{}% + \def\lst@frame{##1##2##3##4}}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{lstkey}{frameround} +% \begin{lstkey}{frame} +% We have to do some conversion here. +% \begin{macrocode} +\lst@Key{frameround}\relax + {\uppercase{\def\lst@frameround{#1}}% + \expandafter\lstframe@\lst@frameround ffff\relax} +\global\let\lst@frameround\@empty +% \end{macrocode} +% In case of an verbose argument, we use the |trbl|-subset replacement. +% \begin{macrocode} +\lst@Key{frame}\relax{% + \let\lst@xrulecolor\@empty + \lstKV@SwitchCases{#1}% + {none&\let\lst@frame\@empty\\% + leftline&\def\lst@frame{l}\\% + topline&\def\lst@frame{t}\\% + bottomline&\def\lst@frame{b}\\% + lines&\def\lst@frame{tb}\\% + single&\def\lst@frame{trbl}\\% + shadowbox&\def\lst@frame{tRBl}% + \def\lst@xrulecolor{\lst@rulesepcolor}% + \def\lst@rulesep{\lst@frametextsep}% + }{\def\lst@frame{#1}}% + \expandafter\lstframe@\lst@frameround ffff\relax} +% \end{macrocode} +% Adding |t|, |r|, |b|, and |l| in case of their upper case versions makes +% later tests easier. +% \begin{macrocode} +\gdef\lstframe@#1#2#3#4#5\relax{% + \lst@IfSubstring T\lst@frame{\edef\lst@frame{t\lst@frame}}{}% + \lst@IfSubstring R\lst@frame{\edef\lst@frame{r\lst@frame}}{}% + \lst@IfSubstring B\lst@frame{\edef\lst@frame{b\lst@frame}}{}% + \lst@IfSubstring L\lst@frame{\edef\lst@frame{l\lst@frame}}{}% +% \end{macrocode} +% We now check top and bottom frame rules, \ldots +% \begin{macrocode} + \let\lst@frametshape\@empty \let\lst@framebshape\@empty + \lst@frameCheck + ltr\lst@framelshape\lst@frametshape\lst@framershape #4#1% + \lst@frameCheck + LTR\lst@framelshape\lst@frametshape\lst@framershape #4#1% + \lst@frameCheck + lbr\lst@framelshape\lst@framebshape\lst@framershape #3#2% + \lst@frameCheck + LBR\lst@framelshape\lst@framebshape\lst@framershape #3#2% +% \end{macrocode} +% \ldots\space look for round corners \ldots +% \begin{macrocode} + \let\lst@ifframeround\iffalse + \lst@IfSubstring R\lst@frametshape{\let\lst@ifframeround\iftrue}{}% + \lst@IfSubstring R\lst@framebshape{\let\lst@ifframeround\iftrue}{}% +% \end{macrocode} +% and define left and right frame shape. +% \begin{macrocode} + \let\lst@framelshape\@empty \let\lst@framershape\@empty + \lst@IfSubstring L\lst@frame + {\def\lst@framelshape{YY}}% + {\lst@IfSubstring l\lst@frame{\def\lst@framelshape{Y}}{}}% + \lst@IfSubstring R\lst@frame + {\def\lst@framershape{YY}}% + {\lst@IfSubstring r\lst@frame{\def\lst@framershape{Y}}{}}} +% \end{macrocode} +% Now comes the macro used to define top and bottom frame shape. +% It extends the macro |#5|. +% The last two arguments show whether left and right corners are round. +% |#4| and |#6| are temporary macros. +% |#1#2#3| are the three characters we test for. +% \begin{macrocode} +\gdef\lst@frameCheck#1#2#3#4#5#6#7#8{% + \lst@IfSubstring #1\lst@frame + {\if #7T\def#4{R}\else \def#4{Y}\fi}% + {\def#4{N}}% + \lst@IfSubstring #3\lst@frame + {\if #8T\def#6{R}\else \def#6{Y}\fi}% + {\def#6{N}}% + \lst@IfSubstring #2\lst@frame{\edef#5{#5#4Y#6}}{}} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\lst@frameMakeVBox} +% \begin{macrocode} +\gdef\lst@frameMakeBoxV#1#2#3{% + \setbox#1\hbox{% + \color@begingroup \lst@rulecolor + \llap{\setbox\z@\hbox{\vrule\@width\z@\@height#2\@depth#3% + \lst@frameL}% + \rlap{\lst@frameBlock\lst@rulesepcolor{\wd\z@}% + {\ht\z@}{\dp\z@}}% + \box\z@ + \ifx\lst@framelshape\@empty + \kern\lst@frametextsep\relax + \else + \lst@frameBlock\lst@fillcolor\lst@frametextsep{#2}{#3}% + \fi + \kern\lst@framexleftmargin}% + \rlap{\kern-\lst@framexleftmargin + \@tempdima\linewidth + \advance\@tempdima\lst@framexleftmargin + \advance\@tempdima\lst@framexrightmargin + \lst@frameBlock\lst@bkgcolor\@tempdima{#2}{#3}% + \ifx\lst@framershape\@empty + \kern\lst@frametextsep\relax + \else + \lst@frameBlock\lst@fillcolor\lst@frametextsep{#2}{#3}% + \fi + \setbox\z@\hbox{\vrule\@width\z@\@height#2\@depth#3% + \lst@frameR}% + \rlap{\lst@frameBlock\lst@rulesepcolor{\wd\z@}% + {\ht\z@}{\dp\z@}}% + \box\z@}% + \color@endgroup}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameBlock} +% \begin{macrocode} +\gdef\lst@frameBlock#1#2#3#4{% + \color@begingroup + #1% + \setbox\z@\hbox{\vrule\@height#3\@depth#4% + \ifx#1\@empty \@width\z@ \kern#2\relax + \else \@width#2\relax \fi}% + \box\z@ + \color@endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameR} +% typesets right rules. +% We only need to iterate through |\lst@framershape|. +% \begin{macrocode} +\gdef\lst@frameR{% + \expandafter\lst@frameR@\lst@framershape\relax + \kern-\lst@rulesep} +\gdef\lst@frameR@#1{% + \ifx\relax#1\@empty\else + \if #1Y\lst@framevrule \else \kern\lst@framerulewidth \fi + \kern\lst@rulesep + \expandafter\lst@frameR@b + \fi} +\gdef\lst@frameR@b#1{% + \ifx\relax#1\@empty + \else + \if #1Y\color@begingroup + \lst@xrulecolor + \lst@framevrule + \color@endgroup + \else + \kern\lst@framerulewidth + \fi + \kern\lst@rulesep + \expandafter\lst@frameR@ + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameL} +% Ditto left rules. +% \begin{macrocode} +\gdef\lst@frameL{% + \kern-\lst@rulesep + \expandafter\lst@frameL@\lst@framelshape\relax} +\gdef\lst@frameL@#1{% + \ifx\relax#1\@empty\else + \kern\lst@rulesep + \if#1Y\lst@framevrule \else \kern\lst@framerulewidth \fi + \expandafter\lst@frameL@ + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameH} +% This is the central macro used to draw top and bottom frame rules. +% The first argument is either |T| or |B| and the second contains the shape. +% We use |\@tempcntb| as size counter. +% \begin{macrocode} +\gdef\lst@frameH#1#2{% + \global\let\lst@framediml\z@ \global\let\lst@framedimr\z@ + \setbox\z@\hbox{}\@tempcntb\z@ + \expandafter\lst@frameH@\expandafter#1#2\relax\relax\relax + \@tempdimb\lst@frametextsep\relax + \advance\@tempdimb\lst@framerulewidth\relax + \@tempdimc-\@tempdimb + \advance\@tempdimc\ht\z@ + \advance\@tempdimc\dp\z@ + \setbox\z@=\hbox{% + \lst@frameHBkg\lst@fillcolor\@tempdimb\@firstoftwo + \if#1T\rlap{\raise\dp\@tempboxa\box\@tempboxa}% + \else\rlap{\lower\ht\@tempboxa\box\@tempboxa}\fi + \lst@frameHBkg\lst@rulesepcolor\@tempdimc\@secondoftwo + \advance\@tempdimb\ht\@tempboxa + \if#1T\rlap{\raise\lst@frametextsep\box\@tempboxa}% + \else\rlap{\lower\@tempdimb\box\@tempboxa}\fi + \rlap{\box\z@}% + }} +\gdef\lst@frameH@#1#2#3#4{% + \ifx\relax#4\@empty\else + \lst@frameh \@tempcntb#1#2#3#4% + \advance\@tempcntb\@ne + \expandafter\lst@frameH@\expandafter#1% + \fi} +\gdef\lst@frameHBkg#1#2#3{% + \setbox\@tempboxa\hbox{% + \kern-\lst@framexleftmargin + #3{\kern-\lst@framediml\relax}{\@tempdima\z@}% + \ifdim\lst@framediml>\@tempdimb + #3{\@tempdima\lst@framediml \advance\@tempdima-\@tempdimb + \lst@frameBlock\lst@rulesepcolor\@tempdima\@tempdimb\z@}% + {\kern-\lst@framediml + \advance\@tempdima\lst@framediml\relax}% + \fi + #3{\@tempdima\z@ + \ifx\lst@framelshape\@empty\else + \advance\@tempdima\@tempdimb + \fi + \ifx\lst@framershape\@empty\else + \advance\@tempdima\@tempdimb + \fi}% + {\ifdim\lst@framedimr>\@tempdimb + \advance\@tempdima\lst@framedimr\relax + \fi}% + \advance\@tempdima\linewidth + \advance\@tempdima\lst@framexleftmargin + \advance\@tempdima\lst@framexrightmargin + \lst@frameBlock#1\@tempdima#2\z@ + #3{\ifdim\lst@framedimr>\@tempdimb + \@tempdima-\@tempdimb + \advance\@tempdima\lst@framedimr\relax + \lst@frameBlock\lst@rulesepcolor\@tempdima\@tempdimb\z@ + \fi}{}% + }} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameh} +% This is the low-level macro used to draw top and bottom frame rules. +% It \emph{adds} one rule plus corners to box 0. +% The first parameter gives the size of the corners and the second is either +% |T| or |B|. +% |#3#4#5| is a left-to-right description of the frame and is in +% $\{$\texttt{Y,N,R}$\}\times\{$\texttt{Y,N}$\}\times\{$\texttt{Y,N,R}$\}$. +% We move to the correct horizontal position, set the left corner, the +% horizontal line, and the right corner. +% \begin{macrocode} +\gdef\lst@frameh#1#2#3#4#5{% + \lst@frameCalcDimA#1% + \lst@ifframeround \@getcirc\@tempdima \fi +% \end{macrocode} +% \begin{macrocode} + \setbox\z@\hbox{% + \begingroup + \setbox\z@\hbox{% + \kern-\lst@framexleftmargin + \color@begingroup + \ifnum#1=\z@ \lst@rulecolor \else \lst@xrulecolor \fi +% \end{macrocode} +% |\lst@frameCorner| gets four arguments: +% |\llap|, |TL| or |BL|, the corner type $\in\{$\texttt{Y,N,R}$\}$, and the +% size |#1|. +% \begin{macrocode} + \lst@frameCornerX\llap{#2L}#3#1% + \ifdim\lst@framediml<\@tempdimb + \xdef\lst@framediml{\the\@tempdimb}% + \fi + \begingroup + \if#4Y\else \let\lst@framerulewidth\z@ \fi + \@tempdima\lst@framexleftmargin + \advance\@tempdima\lst@framexrightmargin + \advance\@tempdima\linewidth + \vrule\@width\@tempdima\@height\lst@framerulewidth \@depth\z@ + \endgroup + \lst@frameCornerX\rlap{#2R}#5#1% + \ifdim\lst@framedimr<\@tempdimb + \xdef\lst@framedimr{\the\@tempdimb}% + \fi + \color@endgroup}% +% \end{macrocode} +% \begin{macrocode} + \if#2T\rlap{\raise\dp\z@\box\z@}% + \else\rlap{\lower\ht\z@\box\z@}\fi + \endgroup + \box\z@}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameCornerX} +% typesets a single corner and returns |\@tempdimb|, the width of the corner. +% \begin{macrocode} +\gdef\lst@frameCornerX#1#2#3#4{% + \setbox\@tempboxa\hbox{\csname\@lst @frame\if#3RR\fi #2\endcsname}% + \@tempdimb\wd\@tempboxa + \if #3R% + #1{\box\@tempboxa}% + \else + \if #3Y\expandafter#1\else + \@tempdimb\z@ \expandafter\vphantom \fi + {\box\@tempboxa}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameCalcDimA} +% calculates an all over width; used by |\lst@frameh| and |\lst@frameInit|. +% \begin{macrocode} +\gdef\lst@frameCalcDimA#1{% + \@tempdima\lst@rulesep + \advance\@tempdima\lst@framerulewidth + \multiply\@tempdima#1\relax + \advance\@tempdima\lst@frametextsep + \advance\@tempdima\lst@framerulewidth + \multiply\@tempdima\tw@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameInit} +% First we look which frame types we have on the left and on the right. +% We speed up things if there are no vertical rules. +% \begin{macrocode} +\lst@AddToHook{Init}{\lst@frameInit} +\newbox\lst@framebox +\gdef\lst@frameInit{% + \ifx\lst@framelshape\@empty \let\lst@frameL\@empty \fi + \ifx\lst@framershape\@empty \let\lst@frameR\@empty \fi + \def\lst@framevrule{\vrule\@width\lst@framerulewidth\relax}% +% \end{macrocode} +% We adjust values to round corners if necessary. +% \begin{macrocode} + \lst@ifframeround + \lst@frameCalcDimA\z@ \@getcirc\@tempdima + \@tempdimb\@tempdima \divide\@tempdimb\tw@ + \advance\@tempdimb -\@wholewidth + \edef\lst@frametextsep{\the\@tempdimb}% + \edef\lst@framerulewidth{\the\@wholewidth}% +% \end{macrocode} +% \begin{macrocode} + \lst@frameCalcDimA\@ne \@getcirc\@tempdima + \@tempdimb\@tempdima \divide\@tempdimb\tw@ + \advance\@tempdimb -\tw@\@wholewidth + \advance\@tempdimb -\lst@frametextsep + \edef\lst@rulesep{\the\@tempdimb}% + \fi +% \end{macrocode} +% \begin{macrocode} + \lst@frameMakeBoxV\lst@framebox{\ht\strutbox}{\dp\strutbox}% + \def\lst@framelr{\copy\lst@framebox}% +% \end{macrocode} +% Finally we typeset the rules (+ corners). +% We possibly need to insert negative |\vskip| to remove space between +% preceding text and top rule. +% \begin{TODO} +% Use |\vspace| instead of |\vskip|? +% \end{TODO} +% \begin{macrocode} + \ifx\lst@frametshape\@empty\else + \lst@frameH T\lst@frametshape + \ifvoid\z@\else + \par\lst@parshape + \@tempdima-\baselineskip \advance\@tempdima\ht\z@ + \ifdim\prevdepth<\@cclvi\p@\else + \advance\@tempdima\prevdepth + \fi + \ifdim\@tempdima<\z@ + \vskip\@tempdima\vskip\lineskip + \fi + \noindent\box\z@\par + \lineskiplimit\maxdimen \lineskip\z@ + \fi + \lst@frameSpreadV\lst@framextopmargin + \fi} +% \end{macrocode} +% |\parshape\lst@parshape| ensures that the top rules correctly indented. +% The bug was reported by \lsthelper{Marcin~Kasperski}{1999/04/28}{top rules +% indented right inside itemize}. +% +% We typeset left and right rules every line. +% \begin{macrocode} +\lst@AddToHook{EveryLine}{\lst@framelr} +\global\let\lst@framelr\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameExit} +% The rules at the bottom. +% \begin{macrocode} +\lst@AddToHook{DeInit} + {\ifx\lst@framebshape\@empty\else \lst@frameExit \fi} +\gdef\lst@frameExit{% + \lst@frameSpreadV\lst@framexbottommargin + \lst@frameH B\lst@framebshape + \ifvoid\z@\else + \everypar{}\par\lst@parshape\nointerlineskip\noindent\box\z@ + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameSpreadV} +% sets rules for vertical spread. +% \begin{macrocode} +\gdef\lst@frameSpreadV#1{% + \ifdim\z@=#1\else + \everypar{}\par\lst@parshape\nointerlineskip\noindent + \lst@frameMakeBoxV\z@{#1}{\z@}% + \box\z@ + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@frameTR} +% \begin{macro}{\lst@frameBR} +% \begin{macro}{\lst@frameBL} +% \begin{macro}{\lst@frameTL} +% These macros make a vertical and horizontal rule. +% The implicit argument |\@tempdima| gives the size of two corners and is +% provided by |\lst@frameh|. +% \begin{macrocode} +\gdef\lst@frameTR{% + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@ + \kern-\lst@framerulewidth + \raise\lst@framerulewidth\hbox{% + \vrule\@width\lst@framerulewidth\@height\z@\@depth.5\@tempdima}} +\gdef\lst@frameBR{% + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@ + \kern-\lst@framerulewidth + \vrule\@width\lst@framerulewidth\@height.5\@tempdima\@depth\z@} +\gdef\lst@frameBL{% + \vrule\@width\lst@framerulewidth\@height.5\@tempdima\@depth\z@ + \kern-\lst@framerulewidth + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@} +\gdef\lst@frameTL{% + \raise\lst@framerulewidth\hbox{% + \vrule\@width\lst@framerulewidth\@height\z@\@depth.5\@tempdima}% + \kern-\lst@framerulewidth + \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro} +% +% \begin{macro}{\lst@frameRoundT} +% \begin{macro}{\lst@frameRoundB} +% are helper macros to typeset round corners. We set height and depth to +% the visible parts of the circle font. +% \begin{macrocode} +\gdef\lst@frameRoundT{% + \setbox\@tempboxa\hbox{\@circlefnt\char\@tempcnta}% + \ht\@tempboxa\lst@framerulewidth + \box\@tempboxa} +\gdef\lst@frameRoundB{% + \setbox\@tempboxa\hbox{\@circlefnt\char\@tempcnta}% + \dp\@tempboxa\z@ + \box\@tempboxa} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@frameRTR} +% \begin{macro}{\lst@frameRBR} +% \begin{macro}{\lst@frameRBL} +% \begin{macro}{\lst@frameRTL} +% The round corners. +% \begin{macrocode} +\gdef\lst@frameRTR{% + \hb@xt@.5\@tempdima{\kern-\lst@framerulewidth + \kern.5\@tempdima \lst@frameRoundT \hss}} +\gdef\lst@frameRBR{% + \hb@xt@.5\@tempdima{\kern-\lst@framerulewidth + \advance\@tempcnta\@ne \kern.5\@tempdima \lst@frameRoundB \hss}} +\gdef\lst@frameRBL{% + \advance\@tempcnta\tw@ \lst@frameRoundB + \kern-.5\@tempdima} +\gdef\lst@frameRTL{% + \advance\@tempcnta\thr@@\lst@frameRoundT + \kern-.5\@tempdima} +% \end{macrocode} +% \end{macro}\end{macro}\end{macro}\end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Macro use for make} +% +% \begin{aspect}{make} +% \begin{macro}{\lst@makemode} +% \begin{macro}{\lst@ifmakekey} +% If we've entered the special mode for Make, we save whether the last +% identifier has been a first order keyword. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{make} +% \end{macrocode} +% \begin{macrocode} +\lst@NewMode\lst@makemode +\lst@AddToHook{Output}{% + \ifnum\lst@mode=\lst@makemode + \ifx\lst@thestyle\lst@gkeywords@sty + \lst@makekeytrue + \fi + \fi} +% \end{macrocode} +% \begin{macrocode} +\gdef\lst@makekeytrue{\let\lst@ifmakekey\iftrue} +\gdef\lst@makekeyfalse{\let\lst@ifmakekey\iffalse} +\global\lst@makekeyfalse % init +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{lstkey}{makemacrouse} +% adjusts the character table if necessary +% \begin{macrocode} +\lst@Key{makemacrouse}f[t]{\lstKV@SetIf{#1}\lst@ifmakemacrouse} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@MakeSCT} +% If `macro use' is on, the opening |$(| prints preceding characters, enters +% the special mode and merges the two characters with the following output. +% +% \begin{macrocode} +\gdef\lst@MakeSCT{% + \lst@ifmakemacrouse + \lst@ReplaceInput{$(}{% + \lst@PrintToken + \lst@EnterMode\lst@makemode{\lst@makekeyfalse}% + \lst@Merge{\lst@ProcessOther\$\lst@ProcessOther(}}% +% \end{macrocode} +% The closing parenthesis tests for the mode and either processes |)| as usual +% or outputs it right here (in keyword style if a keyword was between |$(| and +% |)|). +% \begin{macrocode} + \lst@ReplaceInput{)}{% + \ifnum\lst@mode=\lst@makemode + \lst@PrintToken + \begingroup + \lst@ProcessOther)% + \lst@ifmakekey + \let\lst@currstyle\lst@gkeywords@sty + \fi + \lst@OutputOther + \endgroup + \lst@LeaveMode + \else + \expandafter\lst@ProcessOther\expandafter)% + \fi}% +% \end{macrocode} +% If \keyname{makemacrouse} is off then both |$(| are just `others'. +% \begin{macrocode} + \else + \lst@ReplaceInput{$(}{\lst@ProcessOther\$\lst@ProcessOther(}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \section{Typesetting a listing} +% +% \begingroup +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% \endgroup +% \begin{macro}{\lst@lineno} +% \begin{lstkey}{print} +% \begin{lstkey}{firstline} +% \begin{lstkey}{lastline} +% The `current line' counter and three keys. +% \begin{macrocode} +\newcount\lst@lineno % \global +\lst@AddToHook{InitVars}{\global\lst@lineno\@ne} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{print}{true}[t]{\lstKV@SetIf{#1}\lst@ifprint} +\lst@Key{firstline}\relax{\def\lst@firstline{#1\relax}} +\lst@Key{lastline}\relax{\def\lst@lastline{#1\relax}} +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{PreSet} + {\let\lst@firstline\@ne \def\lst@lastline{9999999\relax}} +% \end{macrocode} +% \end{lstkey}\end{lstkey}\end{lstkey}\end{macro} +% +% \begin{lstkey}{nolol} +% is just a key here. We'll use it below, of course. +% \begin{macrocode} +\lst@Key{nolol}{false}[t]{\lstKV@SetIf{#1}\lst@ifnolol} +\def\lst@nololtrue{\let\lst@ifnolol\iftrue} +\let\lst@ifnolol\iffalse % init +% \end{macrocode} +% \end{lstkey} +% +% +% \subsection{Floats, boxes and captions} +% +% \begin{lstkey}{captionpos} +% \begin{lstkey}{abovecaptionskip} +% \begin{lstkey}{belowcaptionskip} +% \begin{lstkey}{label} +% \begin{lstkey}{title} +% \begin{lstkey}{caption} +% Some keys and \ldots +% \begin{macrocode} +\lst@Key{captionpos}{t}{\def\lst@captionpos{#1}} +\lst@Key{abovecaptionskip}\smallskipamount{\def\lst@abovecaption{#1}} +\lst@Key{belowcaptionskip}\smallskipamount{\def\lst@belowcaption{#1}} +% \end{macrocode} +% \lsthelper{Rolf~Niepraschk}{2000/01/10}{key: title} proposed \keyname{title}. +% \begin{macrocode} +\lst@Key{label}\relax{\def\lst@label{#1}} +\lst@Key{title}\relax{\def\lst@title{#1}\let\lst@caption\relax} +\lst@Key{caption}\relax{\lstKV@OptArg[{#1}]{#1}% + {\def\lst@caption{##2}\def\lst@@caption{##1}}% + \let\lst@title\@empty} +\lst@AddToHookExe{TextStyle} + {\let\lst@caption\@empty \let\lst@@caption\@empty + \let\lst@title\@empty \let\lst@label\@empty} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% \end{lstkey} +% +% \begin{macro}{\thelstlisting} +% \begin{macro}{\lstlistingname} +% \ldots\space and how the caption numbers look like. I switched to +% |\@ifundefined| (instead of |\ifx| |\@undefined|) after an error report from +% \lsthelper{Denis~Girou}{1999/07/26}{incompatible if hyperref loaded before +% listings}. +% \begin{macrocode} +\@ifundefined{thechapter} + {\newcounter{lstlisting} + \renewcommand\thelstlisting{\@arabic\c@lstlisting}} + {\newcounter{lstlisting}[chapter] + \renewcommand\thelstlisting + {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@lstlisting}} +% \end{macrocode} +% \begin{macrocode} +\lst@UserCommand\lstlistingname{Listing} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@MakeCaption} +% Before defining this macro, we ensure that some other control sequences +% exist---\lsthelper{Adam~Prugel-Bennett}{2001/02/19}{\abovecaptionskip +% undefined in slides.cls} reported problems with the slides document class. +% In particular we allocate above- and belowcaption skip registers and define +% |\@makecaption|, which is an exact copy of the definition in the article +% class. To respect the LPPL: you should have a copy of this class on your +% \TeX\ system or you can obtain a copy from the CTAN, e.g.~from the ftp-server +% \texttt{ftp.dante.de}. +% \begin{macrocode} +\@ifundefined{abovecaptionskip} +{\newskip\abovecaptionskip + \newskip\belowcaptionskip + \long\def\@makecaption#1#2{% + \vskip\abovecaptionskip + \sbox\@tempboxa{#1: #2}% + \ifdim \wd\@tempboxa >\hsize + #1: #2\par + \else + \global \@minipagefalse + \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}% + \fi + \vskip\belowcaptionskip}% +}{} +% \end{macrocode} +% We |\refstepcounter| the listing counter if and only if |\lst@@caption| is +% not empty. Otherwise we ensure correct hyper-references, +% see |\lst@HRefStepCounter| below. We do this once a listing, namely at the +% top. +% \begin{macrocode} +\def\lst@MakeCaption#1{% + \ifx #1t% + \ifx\lst@@caption\@empty\expandafter\lst@HRefStepCounter \else + \expandafter\refstepcounter + \fi {lstlisting}% + \ifx\lst@label\@empty\else \label{\lst@label}\fi + \fi +% \end{macrocode} +% We make a caption if and only if the caption is not empty and the user +% requested a caption at |#1| $\in\{\mathtt t,\mathtt b\}$. To disallow +% pagebreaks between caption (or title) and a listing, we redefine the +% primitive |\vskip| locally to insert |\nobreak|s. Note that we allow +% pagebreaks in front of a `top-caption' and after a `bottom-caption'. +% \begin{TODO} +% This redefinition is a brute force method. Is there a better one? +% \end{TODO} +% \begin{macrocode} + \ifx\lst@caption\@empty\else + \lst@IfSubstring #1\lst@captionpos + {\begingroup \let\@@vskip\vskip + \def\vskip{\afterassignment\lst@vskip \@tempskipa}% + \def\lst@vskip{\nobreak\@@vskip\@tempskipa\nobreak}% + \par\normalsize\normalfont + \ifx #1t\allowbreak \fi + \ifx\lst@title\@empty + \expandafter\@makecaption + \else + \expandafter\lst@maketitle + \fi + {\noindent\lstlistingname + \ifx\lst@@caption\@empty\else~\thelstlisting\fi}% + \lst@caption + \ifx #1b\allowbreak \fi + \endgroup}{}% + \fi} +% \end{macrocode} +% I've inserted |\normalsize| after a bug report from +% \lsthelper{Andreas~Matthias}{2000/01/04}{caption affected by basicstyle} +% and moved it in front of |\@makecaption| after receiving another from +% \lsthelper{Sonja~Weidmann}{2000/02/01}{listings and caption packages +% not compatible}. +% \end{macro} +% +% \begin{macro}{\lst@maketitle} +% This definition depends on the existence of the \packagename{caption} +% package. The default gobbles the delimiter and ignores spaces. Note that +% this definition isn't compatible with all packages and classes. +% \begin{macrocode} +\def\lst@maketitle#1#2{\@makecaption\lst@title@dropdelim\lst@title} +\def\lst@title@dropdelim#1{\ignorespaces} +% \end{macrocode} +% For \packagename{caption2} we modify the caption style locally and make this +% style \ldots +% \begin{macrocode} +\AtBeginDocument{% +\@ifundefined{caption@make}{}{% +\def\lst@maketitle#1#2{% + \begingroup + \captionstyle{lsttitle}\@makecaption{}\lst@title + \endgroup} +% \end{macrocode} +% \ldots\space print only the title = caption text. +% \begin{macrocode} +\newcaptionstyle{lsttitle}{\caption@make{lsttitle}}% +\def\caption@@@lsttitle{\captiontext\par}% +}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@HRefStepCounter} +% This macro sets the listing number to a negative value since the user +% shouldn't refer to such a listing. If the \packagename{hyperref} package +% is present, we use `lstlisting' (argument from above) to hyperref to. +% The groups have been added to prevent other packages (namely +% \packagename{tabularx}) from reading the locally changed counter +% and writing it back globally. Thanks to \lsthelper{Michael~Niedermair} +% {2001/09/18}{strange numbering of listings} for the report. Unfortunately +% this localization led to another bug, see |\theHlstnumber|. +% \begin{macrocode} +\def\lst@HRefStepCounter#1{% + \begingroup + \c@lstlisting\lst@neglisting + \advance\c@lstlisting\m@ne \xdef\lst@neglisting{\the\c@lstlisting}% + \ifx\hyper@refstepcounter\@undefined\else + \hyper@refstepcounter{#1}% + \fi + \endgroup} +\gdef\lst@neglisting{\z@}% init +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{boxpos} +% \begin{macro}{\lst@boxtrue} +% sets the vertical alignment of the (possibly) used box respectively indicates +% that a box is used. +% \begin{macrocode} +\lst@Key{boxpos}{c}{\def\lst@boxpos{#1}} +% \end{macrocode} +% \begin{macrocode} +\def\lst@boxtrue{\let\lst@ifbox\iftrue} +\let\lst@ifbox\iffalse +% \end{macrocode} +% \end{macro}\end{lstkey} +% +% \begin{lstkey}{float} +% \begin{lstkey}{floatplacement} +% Matthias Zenger asked for double-column floats, so I've inserted some code. +% We first check for a star \ldots +% \begin{macrocode} +\lst@Key{float}\relax[\lst@floatplacement]{% + \def\lst@next{\@ifstar{\let\lst@beginfloat\@dblfloat + \let\lst@endfloat\end@dblfloat + \lst@KFloat}% + {\let\lst@beginfloat\@float + \let\lst@endfloat\end@float + \lst@KFloat}} + \edef\lst@float{#1}% + \expandafter\lst@next\lst@float\relax} +% \end{macrocode} +% \ldots\ and define |\lst@float|. +% \begin{macrocode} +\def\lst@KFloat#1\relax{% + \ifx\@empty#1\@empty + \let\lst@float\lst@floatplacement + \else + \def\lst@float{#1}% + \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{floatplacement}{tbp}{\def\lst@floatplacement{#1}} +\lst@AddToHook{PreSet}{\let\lst@float\relax} +\lst@AddToHook{TextStyle}{\let\lst@float\relax} +% \end{macrocode} +% The float type |\ftype@lstlisting| is set according to whether the +% \packagename{float} package is loaded and whether \texttt{figure} and +% \texttt{table} floats are defined. This is done at |\begin{document}| to +% make the code independent of the order of package loading. +% \begin{macrocode} +\AtBeginDocument{% +\@ifundefined{c@float@type}% + {\edef\ftype@lstlisting{\ifx\c@figure\@undefined 1\else 4\fi}} + {\edef\ftype@lstlisting{\the\c@float@type}% + \addtocounter{float@type}{\value{float@type}}}% +} +% \end{macrocode} +% \end{lstkey} +% \end{lstkey} +% +% +% \subsection{Init and EOL} +% +% \begin{lstkey}{aboveskip} +% \begin{lstkey}{belowskip} +% We define and initialize these keys and prevent extra spacing for `inline' +% listings (in particular if \packagename{fancyvrb} interface is active, +% problem reported by \lsthelper{Denis~Girou}{1999/08/03}{wrong spacing}). +% \begin{macrocode} +\lst@Key{aboveskip}\medskipamount{\def\lst@aboveskip{#1}} +\lst@Key{belowskip}\medskipamount{\def\lst@belowskip{#1}} +\lst@AddToHook{TextStyle} + {\let\lst@aboveskip\z@ \let\lst@belowskip\z@} +% \end{macrocode} +% \end{lstkey}\end{lstkey} +% +% \begin{lstkey}{everydisplay} +% \begin{macro}{\lst@ifdisplaystyle} +% Some things depend on display-style listings. +% \begin{macrocode} +\lst@Key{everydisplay}{}{\def\lst@EveryDisplay{#1}} +\lst@AddToHook{TextStyle}{\let\lst@ifdisplaystyle\iffalse} +\lst@AddToHook{DisplayStyle}{\let\lst@ifdisplaystyle\iftrue} +\let\lst@ifdisplaystyle\iffalse +% \end{macrocode} +% \end{macro} +% \end{lstkey} +% +% \begin{macro}{\lst@Init} +% Begin a float if requested. +% \begin{macrocode} +\def\lst@Init#1{% + \begingroup + \ifx\lst@float\relax\else + \edef\@tempa{\noexpand\lst@beginfloat{lstlisting}[\lst@float]}% + \expandafter\@tempa + \fi +% \end{macrocode} +% In restricted horizontal \TeX\ mode we switch to |\lst@boxtrue|. +% In that case we make appropriate box(es) around the listing. +% \begin{macrocode} + \ifhmode\ifinner \lst@boxtrue \fi\fi + \lst@ifbox + \lsthk@BoxUnsafe + \hbox to\z@\bgroup + $\if t\lst@boxpos \vtop + \else \if b\lst@boxpos \vbox + \else \vcenter \fi\fi + \bgroup \par\noindent + \else + \lst@ifdisplaystyle + \lst@EveryDisplay + \par\penalty-50\relax + \vspace\lst@aboveskip + \fi + \fi +% \end{macrocode} +% Moved |\vspace| after |\par|---or we can get an empty line atop listings. +% Bug reported by \lsthelper{Jim~Hefferon}{1999/08/27}{empty line before +% listings with |\lstinputlisting|}. +% +% Now make the top caption. +% \begin{macrocode} + \normalbaselines + \abovecaptionskip\lst@abovecaption\relax + \belowcaptionskip\lst@belowcaption\relax + \lst@MakeCaption t% +% \end{macrocode} +% Some initialization. +% I removed |\par\nointerlineskip| |\normalbaselines| after bug report from +% \lsthelper{Jim~Hefferon}{1999/08/23}{bad vertical space after lstlisting}. +% He reported the same problem as Aidan Philip Heerdegen (see below), but I +% immediately saw the bug here since Jim used |\parskip|$\,\neq0$. +% \begin{macrocode} + \lsthk@PreInit \lsthk@Init + \lst@ifdisplaystyle + \global\let\lst@ltxlabel\@empty + \if@inlabel + \lst@ifresetmargins + \leavevmode + \else + \xdef\lst@ltxlabel{\the\everypar}% + \lst@AddTo\lst@ltxlabel{% + \global\let\lst@ltxlabel\@empty + \everypar{\lsthk@EveryLine\lsthk@EveryPar}}% + \fi + \fi + \everypar\expandafter{\lst@ltxlabel + \lsthk@EveryLine\lsthk@EveryPar}% + \else + \everypar{}\let\lst@NewLine\@empty + \fi + \lsthk@InitVars \lsthk@InitVarsBOL +% \end{macrocode} +% The end of line character chr(13)=|^^M| controls the processing, see the +% definition of |\lst@MProcessListing| below. +% The argument |#1| is either |\relax| or |\lstenv@backslash|. +% \begin{macrocode} + \lst@Let{13}\lst@MProcessListing + \let\lst@Backslash#1% + \lst@EnterMode{\lst@Pmode}{\lst@SelectCharTable}} +% \end{macrocode} +% Note: From version 0.19 on `listing processing' is implemented as an internal +% mode, namely a mode with special character table. +% \begin{macrocode} +\lst@AddToHook{InitVars} + {\rightskip\z@ \leftskip\z@ \parfillskip=\z@ plus 1fil + \let\par\@@par} +\lst@AddToHook{EveryLine}{}% init +\lst@AddToHook{EveryPar}{}% init +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{showlines} +% lets the user control whether empty lines at the end of a listing are +% printed. But you know that if you've read the User's guide. +% \begin{macrocode} +\lst@Key{showlines}f[t]{\lstKV@SetIf{#1}\lst@ifshowlines} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@DeInit} +% Output the remaining characters and update all things. First I missed to +% to use |\lst@ifdisplaystyle| here, but then \lsthelper{KP~Gores}{2001/07/11} +% {\csname{par} after each \lstinline} reported a problem. +% \begin{macrocode} +\def\lst@DeInit{% + \lst@XPrintToken \lst@EOLUpdate + \global\advance\lst@newlines\m@ne + \lst@ifshowlines + \lst@DoNewLines + \else + \setbox\@tempboxa\vbox{\lst@DoNewLines}% + \fi + \lst@ifdisplaystyle \par\removelastskip \fi + \everypar{}\lsthk@ExitVars \lsthk@DeInit +% \end{macrocode} +% Making the bottom caption. +% \begin{macrocode} + \lst@MakeCaption b% +% \end{macrocode} +% Close the boxes if necessary and make a rule to get the right width. +% I added the |\par\nointerlineskip| (and removed |\nointerlineskip| later +% again) after receiving a bug report from \lsthelper{Aidan~Philip~Heerdegen} +% {1999/07/23}{wrong vertical spacing}. |\everypar{}| is due to a bug report +% from \lsthelper{Sonja~Weidmann}{2000/02/01}{listings and caption packages +% not compatible}. +% \begin{macrocode} + \lst@ifbox + \egroup $\hss \egroup + \vrule\@width\lst@maxwidth\@height\z@\@depth\z@ + \else + \lst@ifdisplaystyle + \par\penalty-50\vspace\lst@belowskip + \fi + \fi +% \end{macrocode} +% End the float if necessary. +% \begin{macrocode} + \ifx\lst@float\relax\else + \expandafter\lst@endfloat + \fi + \endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@maxwidth} +% is to be allocated, initialized and updated. +% \begin{macrocode} +\newdimen\lst@maxwidth % \global +\lst@AddToHook{InitVars}{\global\lst@maxwidth\z@} +\lst@AddToHook{InitVarsEOL} + {\ifdim\lst@currlwidth>\lst@maxwidth + \global\lst@maxwidth\lst@currlwidth + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EOLUpdate} +% What do you think this macro does? +% \begin{macrocode} +\def\lst@EOLUpdate{\lsthk@EOL \lsthk@InitVarsEOL} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@MProcessListing} +% This is what we have to do at EOL while processing a listing. +% We output all remaining characters and update the variables. +% We call |\lst@EndProcessListing| if the next line number is greater than the +% last printing line. +% Finally we gobble characters to come to the beginning of the next line. +% \begin{macrocode} +\def\lst@MProcessListing{% + \lst@XPrintToken \lst@EOLUpdate \lsthk@InitVarsBOL + \global\advance\lst@lineno\@ne + \ifnum \lst@lineno>\lst@lastline + \expandafter\lst@EndProcessListing + \else + \expandafter\lst@BOLGobble + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@EndProcessListing} +% Default definition is |\endinput|. +% This works for |\lstinputlisting|. +% \begin{macrocode} +\let\lst@EndProcessListing\endinput +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{gobble} +% The key sets the number of characters to gobble each line. +% \begin{macrocode} +\lst@Key{gobble}{0}{\def\lst@gobble{#1}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lst@BOLGobble} +% If the number is positive, we set a temporary counter and start a loop. +% \begin{macrocode} +\def\lst@BOLGobble{% + \ifnum\lst@gobble>\z@ + \@tempcnta\lst@gobble\relax + \expandafter\lst@BOLGobble@ + \fi} +% \end{macrocode} +% A nonpositive number terminates the loop (by not continuing). +% Note: This is not the macro just used in |\lst@BOLGobble|. +% \begin{macrocode} +\def\lst@BOLGobble@@{% + \ifnum\@tempcnta>\z@ + \expandafter\lst@BOLGobble@ + \fi} +% \end{macrocode} +% If we gobble a backslash, we have to look whether this backslash ends an +% environment. Whether the coming characters equal e.g.~|end{lstlisting}|, +% we either end the environment or insert all just eaten characters after the +% `continue loop' macro. +% \begin{macrocode} +\def\lstenv@BOLGobble@@{% + \lst@IfNextChars\lstenv@endstring{\lstenv@End}% + {\advance\@tempcnta\m@ne \expandafter\lst@BOLGobble@@\lst@eaten}} +% \end{macrocode} +% Now comes the loop: if we read |\relax|, EOL or FF, the next operation is +% exactly the same token. +% \begin{macrocode} +\def\lst@BOLGobble@#1{% + \let\lst@next#1% + \ifx \lst@next\relax\else + \ifx \lst@next\lst@MProcessListing\else + \ifx \lst@next\lst@ProcessFormFeed\else +% \end{macrocode} +% Otherwise we use one of the two submacros. +% \begin{macrocode} + \ifx \lst@next\lstenv@backslash + \let\lst@next\lstenv@BOLGobble@@ + \else + \let\lst@next\lst@BOLGobble@@ +% \end{macrocode} +% Now we really gobble characters. A tabulator decreases the temporary counter +% by |\lst@tabsize| (and deals with remaining amounts, if necessary), \ldots +% \begin{macrocode} + \ifx #1\lst@ProcessTabulator + \advance\@tempcnta-\lst@tabsize\relax + \ifnum\@tempcnta<\z@ + \lst@length-\@tempcnta \lst@PreGotoTabStop + \fi +% \end{macrocode} +% \ldots\space whereas any other character decreases the counter by one. +% \begin{macrocode} + \else + \advance\@tempcnta\m@ne + \fi + \fi \fi \fi \fi + \lst@next} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{List of listings} +% +% \begin{lstkey}{name} +% \begin{macro}{\lstname} +% \begin{macro}{\lst@name} +% \begin{macro}{\lst@intname} +% Each pretty-printing command values |\lst@intname| before setting any keys. +% \begin{macrocode} +\lst@Key{name}\relax{\def\lst@intname{#1}} +\lst@AddToHookExe{PreSet}{\global\let\lst@intname\@empty} +\lst@AddToHook{PreInit}{% + \let\lst@arg\lst@intname \lst@ReplaceIn\lst@arg\lst@filenamerpl + \global\let\lst@name\lst@arg \global\let\lstname\lst@name} +% \end{macrocode} +% Use of |\lst@ReplaceIn| removes a bug first reported by +% \lsthelper{Magne~Rudshaug}{1998/01/09}{_ and list of listings}. +% Here is the replacement list. +% \begin{macrocode} +\def\lst@filenamerpl{_\textunderscore $\textdollar -\textendash} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{lstkey} +% +% \begin{macro}{\l@lstlisting} +% prints one `lol' line. +% \begin{macrocode} +\def\l@lstlisting#1#2{\@dottedtocline{1}{1.5em}{2.3em}{#1}{#2}} +% \end{macrocode} +% We make a `lol' entry if the name is neither empty nor a single space. +% But we test |\lst@|(|@|)|caption| and |\lst@ifnolol| first. +% \begin{macrocode} +\lst@AddToHook{Init} + {\lst@ifnolol\else + \ifx\lst@@caption\@empty + \ifx\lst@caption\@empty + \ifx\lst@intname\@empty \else \def\lst@temp{ }% + \ifx\lst@intname\lst@temp \else + \addcontentsline{lol}{lstlisting}\lst@name + \fi\fi + \fi + \else + \addcontentsline{lol}{lstlisting}% + {\protect\numberline{\thelstlisting}\lst@@caption}% + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstlistlistingname} +% contains simply the header name. +% \begin{macrocode} +\lst@UserCommand\lstlistlistingname{Listings} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstlistoflistings} +% We make local adjustments and call |\tableofcontents|. This way, +% redefinitions of that macro (e.g.~without any |\MakeUppercase| inside) +% also take effect on the list of listings. +% \begin{macrocode} +\lst@UserCommand\lstlistoflistings{\bgroup + \let\contentsname\lstlistlistingname + \let\lst@temp\@starttoc \def\@starttoc##1{\lst@temp{lol}}% + \tableofcontents \egroup} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Inline listings}\label{iInlineListings} +% +% \begin{macro}{\lstinline} +% In addition to |\lsthk@PreSet|, we use |boxpos=b| and flexiblecolumns. +% I've inserted |\leavevmode| after bug report from \lsthelper{Michael~Weber} +% {1999/12/16}{wrong spacing in list environments}. \lsthelper{Olivier~Lecarme} +% {2001/07/30}{inconsistent `break' when \lstinline is used inside caption} +% reported a problem which has gone after removing |\let| |\lst@newlines| +% |\@empty| (now |\lst@newlines| is a counter!). Unfortunately I don't know +% the reason for inserting this code some time ago! At the end of the macro we +% check the delimiter. +% \begin{macrocode} +\newcommand\lstinline[1][]{% + \leavevmode\bgroup % \hbox\bgroup --> \bgroup + \def\lst@boxpos{b}% + \lsthk@PreSet\lstset{flexiblecolumns,#1}% + \lsthk@TextStyle + \@ifnextchar\bgroup{\afterassignment\lst@InlineG \let\@let@token}% + \lstinline@} +\def\lstinline@#1{% + \lst@Init\relax + \lst@IfNextCharActive{\lst@InlineM#1}{\lst@InlineJ#1}} +\lst@AddToHook{TextStyle}{}% init +% \end{macrocode} +% \begin{macrocode} +\lst@AddToHook{SelectCharTable}{\lst@inlinechars} +\global\let\lst@inlinechars\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@InlineM} +% \begin{macro}{\lst@InlineJ} +% treat the cases of `normal' inlines and inline listings inside an argument. +% In the first case the given character ends the inline listing and EOL within +% such a listing immediately ends it and produces an error message. +% \begin{macrocode} +\def\lst@InlineM#1{\gdef\lst@inlinechars{% + \lst@Def{`#1}{\lst@DeInit\egroup\global\let\lst@inlinechars\@empty}% + \lst@Def{13}{\lst@DeInit\egroup \global\let\lst@inlinechars\@empty + \PackageError{Listings}{lstinline ended by EOL}\@ehc}}% + \lst@inlinechars} +% \end{macrocode} +% In the other case we get all characters up to |#1|, make these characters +% active, execute (typeset) them and end the listing (all via temporary macro). +% That's all about it. +% \begin{macrocode} +\def\lst@InlineJ#1{% + \def\lst@temp##1#1{% + \let\lst@arg\@empty \lst@InsideConvert{##1}\lst@arg + \lst@DeInit\egroup}% + \lst@temp} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\lst@InlineG} +% is experimental. +% \begin{macrocode} +\def\lst@InlineG{% + \lst@Init\relax + \lst@IfNextCharActive{\lst@InlineM\}}% + {\let\lst@arg\@empty \lst@InlineGJ}} +\def\lst@InlineGJ{\futurelet\@let@token\lst@InlineGJTest} +\def\lst@InlineGJTest{% + \ifx\@let@token\egroup + \afterassignment\lst@InlineGJEnd + \expandafter\let\expandafter\@let@token + \else + \ifx\@let@token\@sptoken + \let\lst@next\lst@InlineGJReadSp + \else + \let\lst@next\lst@InlineGJRead + \fi + \expandafter\lst@next + \fi} +\def\lst@InlineGJEnd{\lst@arg\lst@DeInit\egroup} +\def\lst@InlineGJRead#1{% + \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% + \lst@InlineGJ} +\def\lst@InlineGJReadSp#1{% + \lccode`\~=`\ \lowercase{\lst@lAddTo\lst@arg~}% + \lst@InlineGJ#1} +% \end{macrocode} +% \begin{macrocode} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The input command}\label{iTheInputCommand} +% +% \begin{macro}{\lstinputlisting} +% inputs the listing or asks the user for a new file name. +% \begin{macrocode} +\newcommand\lstinputlisting[2][]{% + \def\lst@set{#1}% + \IfFileExists{#2}% + {\lst@InputListing{#2}}% + {\filename@parse{#2}% + \edef\reserved@a{\noexpand\lst@MissingFileError + {\filename@area\filename@base}% + {\ifx\filename@ext\relax tex\else\filename@ext\fi}}% + \reserved@a}% + \@doendpe \@newlistfalse \ignorespaces} +% \end{macrocode} +% We use |\@doendpe| to remove indention at the beginning of the next +% line---except there is an empty line after |\lstinputlisting|. Bug was +% reported by \lsthelper{David~John~Evans}{1999/06/08}{indention after +% listings} and \lsthelper{David~Carlisle}{1999/06/08}{LaTeX `display +% environment' code} pointed me to the solution. +% \end{macro} +% +% \begin{macro}{\lst@MissingFileError} +% is a derivation of \LaTeX's |\@missingfileerror|: +% \begin{macrocode} +\def\lst@MissingFileError#1#2{% + \typeout{^^J! Package Listings Error: File `#1.#2' not found.^^J^^J% + Type X to quit or to proceed,^^J% + or enter new name. (Default extension: #2)^^J}% + \message{Enter file name: }% + {\endlinechar\m@ne \global\read\m@ne to\@gtempa}% +% \end{macrocode} +% Typing |x| or |X| exits. +% \begin{macrocode} + \ifx\@gtempa\@empty \else + \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi + \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi +% \end{macrocode} +% In all other cases we try the new file name. +% \begin{macrocode} + \filename@parse\@gtempa + \edef\filename@ext{% + \ifx\filename@ext\relax#2\else\filename@ext\fi}% + \edef\reserved@a{\noexpand\IfFileExists % + {\filename@area\filename@base.\filename@ext}% + {\noexpand\lst@InputListing % + {\filename@area\filename@base.\filename@ext}}% + {\noexpand\lst@MissingFileError + {\filename@area\filename@base}{\filename@ext}}}% + \expandafter\reserved@a % + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@ifdraft} +% makes use of |\lst@ifprint|. +% \begin{macrocode} +\let\lst@ifdraft\iffalse +\DeclareOption{draft}{\let\lst@ifdraft\iftrue} +\lst@AddToHook{PreSet} + {\lst@ifdraft + \let\lst@ifprint\iffalse + \@gobbletwo\fi\fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@InputListing} +% The one and only argument is the file name, but we have the `implicit' +% argument |\lst@set|. Note that |\lst@Init| takes |\relax| as argument. +% \begin{macrocode} +\def\lst@InputListing#1{% + \begingroup + \lsthk@PreSet \gdef\lst@intname{#1}% + \expandafter\lstset\expandafter{\lst@set}% + \lsthk@DisplayStyle + \lst@Init\relax \let\lst@gobble\z@ + \lst@SkipToFirst + \lst@ifprint \def\lst@next{\input{#1}}% + \else \let\lst@next\@empty \fi + \lst@next + \lst@DeInit + \endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@SkipToFirst} +% The end of line character either processes the listing or is responsible for +% dropping lines up to first printing line. +% \begin{macrocode} +\def\lst@SkipToFirst{% + \ifnum \lst@lineno<\lst@firstline +% \end{macrocode} +% We drop the input and redefine the end of line characters. +% \begin{macrocode} + \lst@BeginDropInput\lst@Pmode + \lst@Let{13}\lst@MSkipToFirst + \lst@Let{10}\lst@MSkipToFirst + \else + \expandafter\lst@BOLGobble + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@MSkipToFirst} +% We just look whether to drop more lines or to leave the mode which restores +% the definition of chr(13) and chr(10). +% \begin{macrocode} +\def\lst@MSkipToFirst{% + \global\advance\lst@lineno\@ne + \ifnum \lst@lineno=\lst@firstline + \lst@LeaveMode \global\lst@newlines\z@ + \lsthk@InitVarsBOL + \expandafter\lst@BOLGobble + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The environment} +% +% +% \subsubsection{Low-level processing} +% +% \begin{macro}{\lstenv@DroppedWarning} +% gives a warning if characters have been dropped. +% \begin{macrocode} +\def\lstenv@DroppedWarning{% + \ifx\lst@dropped\@undefined\else + \PackageWarning{Listings}{Text dropped after begin of listing}% + \fi} +\let\lst@dropped\@undefined % init +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@Process} +% We execute `|\lstenv@ProcessM|' or |\lstenv@ProcessJ| according to whether we +% find an active EOL or a nonactive |^^J|. +% \begin{macrocode} +\begingroup \lccode`\~=`\^^M\lowercase{% +\gdef\lstenv@Process#1{% + \ifx~#1% +% \end{macrocode} +% We make no extra |\lstenv@ProcessM| definition since there is nothing to do +% at all if we've found an active EOL. +% \begin{macrocode} + \lstenv@DroppedWarning \let\lst@next\lst@SkipToFirst + \else\ifx^^J#1% + \lstenv@DroppedWarning \let\lst@next\lstenv@ProcessJ + \else + \let\lst@dropped#1\let\lst@next\lstenv@Process + \fi \fi + \lst@next} +}\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@ProcessJ} +% Now comes the horrible scenario: a listing inside an argument. We've +% already worked in section \ref{iApplicationsTo} for this. Here we must get +% all characters up to `end environment'. We distinguish the cases `command +% fashion' and `true environment'. +% \begin{macrocode} +\def\lstenv@ProcessJ{% + \let\lst@arg\@empty + \ifx\@currenvir\lstenv@name + \expandafter\lstenv@ProcessJEnv + \else +% \end{macrocode} +% The first case is pretty simple: The code is terminated by +% |\end|\meta{name of environment}. Thus we expand that control sequence +% before defining a temporary macro, which gets the listing and does all +% the rest. Back to the definition of |\lstenv@ProcessJ| we call the +% temporary macro after expanding |\fi|. +% \begin{macrocode} + \expandafter\def\expandafter\lst@temp\expandafter##1% + \csname end\lstenv@name\endcsname + {\lst@InsideConvert{##1}\lstenv@ProcessJ@}% + \expandafter\lst@temp + \fi} +% \end{macrocode} +% We must append an active backslash and the `end string' to |\lst@arg|. So all +% (in fact most) other processing won't notice that the code has been inside +% an argument. But the EOL character is chr(10)=|^^J| now and not chr(13). +% \begin{macrocode} +\begingroup \lccode`\~=`\\\lowercase{% +\gdef\lstenv@ProcessJ@{% + \lst@lExtend\lst@arg + {\expandafter\ \expandafter~\lstenv@endstring}% + \catcode10=\active \lst@Let{10}\lst@MProcessListing +% \end{macrocode} +% We execute |\lst@arg| to typeset the listing. +% \begin{macrocode} + \lst@SkipToFirst \lst@arg} +}\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@ProcessJEnv} +% The `true environment' case is more complicated. We get all characters up to +% an |\end| and the following argument. If that equals |\lstenv@name|, we have +% found the end of environment and start typesetting. +% \begin{macrocode} +\def\lstenv@ProcessJEnv#1\end#2{\def\lst@temp{#2}% + \ifx\lstenv@name\lst@temp + \lst@InsideConvert{#1}% + \expandafter\lstenv@ProcessJ@ + \else +% \end{macrocode} +% Otherwise we append the characters including the eaten |\end| and the eaten +% argument to current |\lst@arg|. And we look for the end of environment again. +% \begin{macrocode} + \lst@InsideConvert{#1\\end\{#2\}}% + \expandafter\lstenv@ProcessJEnv + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@backslash} +% Coming to a backslash we either end the listing or process a backslash and +% insert the eaten characters again. +% \begin{macrocode} +\def\lstenv@backslash{% + \lst@IfNextChars\lstenv@endstring + {\lstenv@End}% + {\expandafter\lsts@backslash \lst@eaten}}% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@End} +% This macro has just been used and terminates a listing environment: +% We call the `end environment' macro using |\end| or as a command. +% \begin{macrocode} +\def\lstenv@End{% + \ifx\@currenvir\lstenv@name + \edef\lst@next{\noexpand\end{\lstenv@name}}% + \else + \def\lst@next{\csname end\lstenv@name\endcsname}% + \fi + \lst@next} +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{\cs{lstnewenvironment}} +% +% \begin{macro}{\lstnewenvironment} +% Now comes the main command. We define undefined environments only. On the +% parameter text |#1#2#| (in particular the last sharp) see the paragraph +% following example 20.5 on page 204 of `The \TeX book'. +% \begin{macrocode} +\lst@UserCommand\lstnewenvironment#1#2#{% + \@ifundefined{#1}% + {\let\lst@arg\@empty + \lst@XConvert{#1}\@nil + \expandafter\lstnewenvironment@\lst@arg{#1}{#2}}% + {\PackageError{Listings}{Environment `#1' already defined}\@eha + \@gobbletwo}} +\def\@tempa#1#2#3{% +\gdef\lstnewenvironment@##1##2##3##4##5{% + \begingroup +% \end{macrocode} +% A lonely `end environment' produces an error. +% \begin{macrocode} + \global\@namedef{end##2}{\lstenv@Error{##2}}% +% \end{macrocode} +% The `main' environment macro defines the environment name for later use and +% calls a submacro getting all arguments. We open a group and make EOL active. +% This ensures |\@ifnextchar[| not to read characters of the listing---it reads +% the active EOL instead. +% \begin{macrocode} + \global\@namedef{##2}{\def\lstenv@name{##2}% + \begingroup \catcode\active=\active \csname##2@\endcsname}% +% \end{macrocode} +% The submacro is defined via |\new@command|. We misuse |\l@ngrel@x| to make +% the definition |\global| and refine \LaTeX's |\@xargdef|. +% \begin{macrocode} + \let\l@ngrel@x\global + \let\@xargdef\lstenv@xargdef + \expandafter\new@command\csname##2@\endcsname##3% +% \end{macrocode} +% First we execute |##4|=\meta{begin code}. Then follows the definition of +% the terminating string (|end{lstlisting}| or |endlstlisting|, for example): +% \begin{macrocode} + {\lsthk@PreSet ##4% + \ifx\@currenvir\lstenv@name + \def\lstenv@endstring{#1#2##1#3}% + \else + \def\lstenv@endstring{#1##1}% + \fi +% \end{macrocode} +% We redefine (locally) `end environment' since ending is legal now. +% Note that the redefinition also works inside a \TeX\ comment line. +% \begin{macrocode} + \@namedef{end##2}{\lst@DeInit ##5\endgroup + \@doendpe \@ignoretrue}% +% \end{macrocode} +% |\@doendpe| again removes the indention problem. +% Finally we start the processing. +% \begin{macrocode} + \lsthk@DisplayStyle + \lst@Init\lstenv@backslash + \let\lst@EndProcessListing\lstenv@SkipToEnd + \lst@ifprint + \expandafter\expandafter\expandafter\lstenv@Process + \else + \expandafter\lstenv@SkipToEnd + \fi + \lst@insertargs}% + \endgroup}% +} +\let\lst@arg\@empty \lst@XConvert{end}\{\}\@nil +\expandafter\@tempa\lst@arg +\let\lst@insertargs\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@xargdef} +% This is a derivation of \LaTeX's |\@xargdef|. We expand the submacro's name, +% use |\gdef| instead of |\def|, and hard code a kind of |\@protected@testopt|. +% \begin{macrocode} +\def\lstenv@xargdef#1{ + \expandafter\lstenv@xargdef@\csname\string#1\endcsname#1} +\def\lstenv@xargdef@#1#2[#3][#4]#5{% + \@ifdefinable#2{% + \gdef#2{% + \ifx\protect\@typeset@protect + \expandafter\lstenv@testopt + \else + \@x@protect#2% + \fi + #1% + {#4}}% + \@yargdef + #1% + \tw@ + {#3}% + {#5}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@testopt} +% The difference between this macro and |\@testopt| is that we temporaryly +% reset the catcode of the EOL character |^^M| to read the optional argument. +% \begin{macrocode} +\long\def\lstenv@testopt#1#2{% + \@ifnextchar[{\catcode\active5\relax \lstenv@testopt@#1}% + {#1[{#2}]}} +\def\lstenv@testopt@#1[#2]{% + \catcode\active\active + #1[#2]} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@SkipToEnd} +% We use the temporary definition +% \begin{itemize}\item[] +% |\long\def\lst@temp##1\|\meta{content of \textup{\cs{lstenv@endstring}}}|{\lstenv@End}| +% \end{itemize} +% which gobbles all characters up to the end of environment and finishes it. +% \begin{macrocode} +\begingroup \lccode`\~=`\\\lowercase{% +\gdef\lstenv@SkipToEnd{% + \long\expandafter\def\expandafter\lst@temp\expandafter##\expandafter + 1\expandafter~\lstenv@endstring{\lstenv@End}% + \lst@temp} +}\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstenv@Error} +% is called by a lonely `end environment'. +% \begin{macrocode} +\def\lstenv@Error#1{\PackageError{Listings}{Extra \string\end#1}% + {I'm ignoring this, since I wasn't doing a \csname#1\endcsname.}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@TestEOLChar} +% Here we test for the two possible EOL characters. +% \begin{macrocode} +\begingroup \lccode`\~=`\^^M\lowercase{% +\gdef\lst@TestEOLChar#1{% + \def\lst@insertargs{#1}% + \ifx ~#1\@empty \else + \ifx^^J#1\@empty \else + \global\let\lst@intname\lst@insertargs + \let\lst@insertargs\@empty + \fi \fi} +}\endgroup +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{lstlisting} +% The awkward work is done, the definition is quite easy now. We test whether +% the user has given the name argument, set the keys, and deal with +% continued line numbering. +% \begin{macrocode} +\lstnewenvironment{lstlisting}[2][] + {\lst@TestEOLChar{#2}% + \lstset{#1}% + \csname\@lst @SetFirstNumber\endcsname} + {\csname\@lst @SaveFirstNumber\endcsname} +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \end{environment} +% +% +% \section{Documentation support} +% +% \begin{syntax} +% \item[0.19] +% |\begin{lstsample}|\marg{point list}\marg{left}\marg{right} +% +% \leavevmode\hspace*{-\leftmargini}|\end{lstsample}| +% +% Roughly speaking all material in between this environment is executed +% `on the left side' and typeset verbatim on the right. \meta{left} is +% executed before the left side is typeset, and similarly \meta{right} +% before the right-hand side. +% +% \meta{point list} is used as argument to the \keyname{point} key. +% This is a special key used to highlight the keys in the examples. +% +% \item[1.0] +% |\begin{lstxsample}|\marg{point list} +% +% \leavevmode\hspace*{-\leftmargini}|\end{lstxsample}| +% +% The material in between is (a) added to the left side of the next +% \texttt{lstsample} environment and (b) typeset verbatim using the +% whole line width. +% +% \item[0.21] |\newdocenvironment|\marg{name}\marg{short name}\marg{begin code}\marg{end code} +% +% The \meta{name} environment can be used in the same way as `macro'. +% The provided(!) definitions +% |\Print|\meta{short name}|Name| +% and |\SpecialMain|\meta{short name}|Index| +% control printing in the margin and indexing as the defaults +% |\PrintMacroName| and |\SpecialMainIndex| do. +% +% This command is used to define the `aspect' and `lstkey' environments. +% +%\item[0.21] \texttt{macroargs} environment +% +% This `enumerate' environment uses as labels `|#1| =', `|#2| =', +% and so on. +% +% \item \texttt{TODO} environment +% \item \texttt{ALTERNATIVE} environment +% \item \texttt{REMOVED} environment +% \item \texttt{OLDDEF} environment +% +% These environments enclose comments on `to do's', alternatives and +% removed or old definitions. +% +% \item[0.21] |\lstscanlanguages|\meta{list macro}\marg{input files}\marg{don't input} +% +% scans \marg{input files}$\setminus$\marg{don't input} for language +% definitions. The available languages are stored in \meta{list macro} +% using the form \meta{language}|(|\meta{dialtect}|),|. +% +% \item[0.21] |\lstprintlanguages|\meta{list macro} +% +% prints the languages in two column format. +% \end{syntax} +% and a lot of more simple commands. +% +% +% \subsection{Required packages} +% +% Most of the `required' packages are optional. +% \begin{macrocode} +%<*doc> +\let\lstdoc@currversion\fileversion +\RequirePackage[writefile]{listings}[2002/04/01] +\newif\iffancyvrb \IfFileExists{fancyvrb.sty}{\fancyvrbtrue}{} +\newif\ifcolor \IfFileExists{color.sty}{\colortrue}{} +\newif\ifhyper \@ifundefined{pdfoutput}{} + {\IfFileExists{hyperref.sty}{\hypertrue}{}} +\newif\ifalgorithmic \IfFileExists{algorithmic.sty}{\algorithmictrue}{} +\iffancyvrb \RequirePackage{fancyvrb}\fi +\ifhyper \RequirePackage[colorlinks]{hyperref}\else + \def\href#1{\texttt}\fi +\ifcolor \RequirePackage{color}\fi +\ifalgorithmic \RequirePackage{algorithmic}\fi +\RequirePackage{nameref} +\renewcommand\ref{\protect\T@ref} +\renewcommand\pageref{\protect\T@pageref} +% \end{macrocode} +% +% +% \subsection{Environments for notes} +% +% \begin{macro}{\lst@BeginRemark} +% \begin{macro}{\lst@EndRemark} +% We begin with two simple definitions \ldots +% \begin{macrocode} +\def\lst@BeginRemark#1{% + \begin{quote}\topsep0pt\let\small\footnotesize\small#1:} +\def\lst@EndRemark{\end{quote}} +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{environment}{TODO} +% \begin{environment}{ALTERNATIVE} +% \begin{environment}{REMOVED} +% \begin{environment}{OLDDEF} +% \ldots\space used to define some environments. +% \begin{macrocode} +\newenvironment{TODO} + {\lst@BeginRemark{To do}}{\lst@EndRemark} +\newenvironment{ALTERNATIVE} + {\lst@BeginRemark{Alternative}}{\lst@EndRemark} +\newenvironment{REMOVED} + {\lst@BeginRemark{Removed}}{\lst@EndRemark} +\newenvironment{OLDDEF} + {\lst@BeginRemark{Old definition}}{\lst@EndRemark} +% \end{macrocode} +% \end{environment}\end{environment}\end{environment}\end{environment} +% +% \begin{environment}{advise} +% \begin{macro}{\advisespace} +% The environment uses |\@listi|. +% \begin{macrocode} +\def\advise{\par\list\labeladvise + {\advance\linewidth\@totalleftmargin + \@totalleftmargin\z@ + \@listi + \let\small\footnotesize \small\sffamily + \parsep \z@ \@plus\z@ \@minus\z@ + \topsep6\p@ \@plus1\p@\@minus2\p@ + \def\makelabel##1{\hss\llap{##1}}}} +\let\endadvise\endlist +% \end{macrocode} +% \begin{macrocode} +\def\advisespace{\hbox{}\qquad} +\def\labeladvise{$\to$} +% \end{macrocode} +% \end{macro} +% \end{environment} +% +% \begin{environment}{syntax} +% \begin{macro}{\syntaxbreak} +% \begin{macro}{\syntaxnewline} +% \begin{macro}{\syntaxor} +% This environment uses |\list| with a special |\makelabel|, \ldots +% \begin{macrocode} +\newenvironment{syntax} + {\list{}{\itemindent-\leftmargin + \def\makelabel##1{\hss\lst@syntaxlabel##1,,,,\relax}}} + {\endlist} +% \end{macrocode} +% \ldots\ which is defined here. The comma separated items are placed as +% needed. +% \begin{macrocode} +\def\lst@syntaxlabel#1,#2,#3,#4\relax{% + \llap{\scriptsize\itshape#3}% + \def\lst@temp{#2}% + \expandafter\lst@syntaxlabel@\meaning\lst@temp\relax + \rlap{\hskip-\itemindent\hskip\itemsep\hskip\linewidth + \llap{\ttfamily\lst@temp}\hskip\labelwidth + \def\lst@temp{#1}% + \ifx\lst@temp\lstdoc@currversion#1\fi}} +\def\lst@syntaxlabel@#1>#2\relax + {\edef\lst@temp{\zap@space#2 \@empty}} +% \end{macrocode} +% \begin{macrocode} +\newcommand*\syntaxnewline{\newline\hbox{}\kern\labelwidth} +\newcommand*\syntaxor{\qquad or\qquad} +\newcommand*\syntaxbreak + {\hfill\kern0pt\discretionary{}{\kern\labelwidth}{}} +\let\syntaxfill\hfill +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{environment} +% +% \begin{macro}{\alternative} +% iterates down the list and inserts vertical rule(s). +% \begin{macrocode} +\def\alternative#1{\lst@true \alternative@#1,\relax,} +\def\alternative@#1,{% + \ifx\relax#1\@empty + \expandafter\@gobble + \else + \ifx\@empty#1\@empty\else + \lst@if \lst@false \else $\vert$\fi + \textup{\texttt{#1}}% + \fi + \fi + \alternative@} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Extensions to \textsf{doc}} +% +% \begin{macro}{\m@cro@} +% We need a slight modification of \packagename{doc}'s internal macro. +% The former argument |#2| has become |#3|. This change is not marked below. +% The second argument is now \meta{short name}. +% \begin{macrocode} +\long\def\m@cro@#1#2#3{\endgroup \topsep\MacroTopsep \trivlist + \edef\saved@macroname{\string#3}% + \def\makelabel##1{\llap{##1}}% + \if@inlabel + \let\@tempa\@empty \count@\macro@cnt + \loop \ifnum\count@>\z@ + \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat + \edef\makelabel##1{\llap{\vtop to\baselineskip + {\@tempa\hbox{##1}\vss}}}% + \advance \macro@cnt \@ne + \else \macro@cnt\@ne \fi + \edef\@tempa{\noexpand\item[% + #1% + \noexpand\PrintMacroName + \else +% \end{macrocode} +% The next line has been modified. +% \begin{macrocode} + \expandafter\noexpand\csname Print#2Name\endcsname % MODIFIED + \fi + {\string#3}]}% + \@tempa + \global\advance\c@CodelineNo\@ne + #1% + \SpecialMainIndex{#3}\nobreak + \DoNotIndex{#3}% + \else +% \end{macrocode} +% Ditto. +% \begin{macrocode} + \csname SpecialMain#2Index\endcsname{#3}\nobreak % MODIFIED + \fi + \global\advance\c@CodelineNo\m@ne + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\macro} +% \begin{macro}{\environment} +% These two definitions need small adjustments due to the modified |\m@cro@|. +% \begin{macrocode} +\def\macro{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \iftrue {Macro}}% MODIFIED +\def\environment{\begingroup + \catcode`\\12 + \MakePrivateLetters \m@cro@ \iffalse {Env}}% MODIFIED +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{macro}{\newdocenvironment} +% This command simply makes definitions similar to `environment' and provides +% the printing and indexing commands. +% \begin{macrocode} +\def\newdocenvironment#1#2#3#4{% + \@namedef{#1}{#3\begingroup \catcode`\\12\relax + \MakePrivateLetters \m@cro@ \iffalse {#2}}% + \@namedef{end#1}{#4\endmacro}% + \@ifundefined{Print#2Name}{\expandafter + \let\csname Print#2Name\endcsname\PrintMacroName}{}% + \@ifundefined{SpecialMain#2Index}{\expandafter + \let\csname SpecialMain#2Index\endcsname\SpecialMainIndex}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{aspect} +% \begin{macro}{\PrintAspectName} +% \begin{macro}{\SpecialMainAspectIndex} +% The environment and its `print' and `index' commands. +% \begin{macrocode} +\newdocenvironment{aspect}{Aspect}{}{} +\def\PrintAspectName#1{} +\def\SpecialMainAspectIndex#1{% + \@bsphack + \index{aspects:\levelchar\protect\aspectname{#1}\encapchar main}% + \@esphack} +% \end{macrocode} +% \end{macro}\end{macro}\end{environment} +% +% \begin{environment}{lstkey} +% \begin{macro}{\PrintKeyName} +% \begin{macro}{\SpecialMainKeyIndex} +% One more environment with its `print' and `index' commands. +% \begin{macrocode} +\newdocenvironment{lstkey}{Key}{}{} +\def\PrintKeyName#1{\strut\keyname{#1}\ } +\def\SpecialMainKeyIndex#1{% + \@bsphack + \index{keys\levelchar\protect\keyname{#1}\encapchar main}% + \@esphack} +% \end{macrocode} +% \end{macro}\end{macro}\end{environment} +% +% \begin{macro}{\labelargcount} +% \begin{environment}{macroargs} +% We just allocate a counter and use \LaTeX's |\list| to implement this +% environment. +% \begin{macrocode} +\newcounter{argcount} +\def\labelargcount{\texttt{\#\arabic{argcount}}\hskip\labelsep$=$} +% \end{macrocode} +% \begin{macrocode} +\def\macroargs{\list\labelargcount + {\usecounter{argcount}\leftmargin=2\leftmargin + \parsep \z@ \@plus\z@ \@minus\z@ + \topsep4\p@ \@plus\p@ \@minus2\p@ + \itemsep\z@ \@plus\z@ \@minus\z@ + \def\makelabel##1{\hss\llap{##1}}}} +\def\endmacroargs{\endlist\@endparenv} +% \end{macrocode} +% \end{environment}\end{macro} +% +% +% \subsection{The \texttt{lstsample} environment} +% +% \begin{environment}{lstsample} +% We store the verbatim part and write the source code also to file. +% \begin{macrocode} +\lst@RequireAspects{writefile} +% \end{macrocode} +% \begin{macrocode} +\newbox\lst@samplebox +\lstnewenvironment{lstsample}[3][] + {\global\let\lst@intname\@empty + \gdef\lst@sample{#2}% + \setbox\lst@samplebox=\hbox\bgroup + \setkeys{lst}{language={},style={},tabsize=4,gobble=5,% + basicstyle=\small\ttfamily,basewidth=0.51em,point={#1}} + #3% + \lst@BeginAlsoWriteFile{\jobname.tmp}} + {\lst@EndWriteFile\egroup +% \end{macrocode} +% Now |\lst@samplebox| contains the verbatim part. +% If it's too wide, we use atop and below instead of left and right. +% \begin{macrocode} + \ifdim \wd\lst@samplebox>.5\linewidth + \begin{center}% + \hbox to\linewidth{\box\lst@samplebox\hss}% + \end{center}% + \lst@sampleInput + \else + \begin{center}% + \begin{minipage}{0.45\linewidth}\lst@sampleInput\end{minipage}% + \qquad + \begin{minipage}{0.45\linewidth}% + \hbox to\linewidth{\box\lst@samplebox\hss}% + \end{minipage}% + \end{center}% + \fi} +% \end{macrocode} +% The new keyword class \keyname{point}. +% \begin{macrocode} +\lst@InstallKeywords{p}{point}{pointstyle}\relax{keywordstyle}{}ld +% \end{macrocode} +% \end{environment} +% +% \begin{environment}{lstxsample} +% Omitting |\lst@EndWriteFile| leaves the file open. +% \begin{macrocode} +\lstnewenvironment{lstxsample}[1][] + {\begingroup + \setkeys{lst}{belowskip=-\medskipamount,language={},style={},% + tabsize=4,gobble=5,basicstyle=\small\ttfamily,% + basewidth=0.51em,point={#1}} + \lst@BeginAlsoWriteFile{\jobname.tmp}} + {\endgroup + \endgroup} +% \end{macrocode} +% \end{environment} +% +% \begin{macro}{\lst@sampleInput} +% inputs the `left-hand' side. +% \begin{macrocode} +\def\lst@sampleInput{% + \MakePercentComment\catcode`\^^M=10\relax + \small\lst@sample + {\setkeys{lst}{SelectCharTable=\lst@ReplaceInput{\^\^I}% + {\lst@ProcessTabulator}}% + \leavevmode \input{\jobname.tmp}}\MakePercentIgnore} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Miscellaneous} +% +% \paragraph{Sectioning and cross referencing} +% We begin with a redefinition paragraph. +% \begin{macrocode} +\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}% + {1.25ex \@plus1ex \@minus.2ex}% + {-1em}% + {\normalfont\normalsize\bfseries}} +% \end{macrocode} +% We introduce |\lstref| which prints section number together with its name. +% \begin{macrocode} +\def\lstref#1{\emph{\ref{#1} \nameref{#1}}} +% \end{macrocode} +% Moreover we adjust the table of contents. +% \begin{macrocode} +\def\@part[#1]#2{\addcontentsline{toc}{part}{#1}% + {\parindent\z@ \raggedright \interlinepenalty\@M + \normalfont \huge \bfseries #2\markboth{}{}\par}% + \nobreak\vskip 3ex\@afterheading} +\renewcommand*\l@section[2]{% + \addpenalty\@secpenalty + \addvspace{.25em \@plus\p@}% + \setlength\@tempdima{1.5em}% + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \endgroup} +\renewcommand*\l@subsection{\@dottedtocline{2}{0pt}{2.3em}} +\renewcommand*\l@subsubsection{\@dottedtocline{3}{0pt}{3.2em}} +% \end{macrocode} +% +% \paragraph{Indexing} +% The `user' commands. |\rstyle| is defined below. +% \begin{macrocode} +\newcommand\ikeyname[1]{% + \lstkeyindex{#1}{}% + \lstaspectindex{#1}{}% + \keyname{#1}} +\newcommand\ekeyname[1]{% + \@bsphack + \lstkeyindex{#1}{\encapchar usage}% + \lstaspectindex{#1}{\encapchar usage}% + \@esphack} +\newcommand\rkeyname[1]{% + \@bsphack + \lstkeyindex{#1}{\encapchar main}% + \lstaspectindex{#1}{\encapchar main}% + \@esphack{\rstyle\keyname{#1}}} +% \end{macrocode} +% \begin{macrocode} +\newcommand\icmdname[1]{% + \@bsphack + \lstaspectindex{#1}{}% + \@esphack\texttt{\string#1}} +\newcommand\rcmdname[1]{% + \@bsphack + \lstaspectindex{#1}{\encapchar main}% + \@esphack\texttt{\rstyle\string#1}} +% \end{macrocode} +% One of the two yet unknown `index'-macros is empty, the other looks up +% the aspect name for the given argument. +% \begin{macrocode} +\def\lstaspectindex#1#2{% + \global\@namedef{lstkandc@\string#1}{}% + \@ifundefined{lstisaspect@\string#1} + {\index{unknown\levelchar + \protect\texttt{\protect\string\string#1}#2}}% + {\index{\@nameuse{lstisaspect@\string#1}\levelchar + \protect\texttt{\protect\string\string#1}#2}}% +} +\def\lstkeyindex#1#2{% +% \index{key\levelchar\protect\keyname{#1}#2}% +} +% \end{macrocode} +% The key/command to aspect relation is defined near the top of this file using +% the following command. In future the package should read this information +% from the aspect files. +% \begin{macrocode} +\def\lstisaspect[#1]#2{% + \global\@namedef{lstaspect@#1}{#2}% + \lst@AddTo\lst@allkeysandcmds{,#2}% + \@for\lst@temp:=#2\do + {\ifx\@empty\lst@temp\else + \global\@namedef{lstisaspect@\lst@temp}{#1}% + \fi}} +\gdef\lst@allkeysandcmds{} +% \end{macrocode} +% This relation is also good to print all keys and commands of a particular +% aspect \ldots +% \begin{macrocode} +\def\lstprintaspectkeysandcmds#1{% + \lst@true + \expandafter\@for\expandafter\lst@temp + \expandafter:\expandafter=\csname lstaspect@#1\endcsname\do + {\lst@if\lst@false\else, \fi \texttt{\lst@temp}}} +% \end{macrocode} +% \ldots\ or to check the reference. Note that we've defined +% |\lstkandc@|\meta{name} in |\lstaspectindex|. +% \begin{macrocode} +\def\lstcheckreference{% + \@for\lst@temp:=\lst@allkeysandcmds\do + {\ifx\lst@temp\@empty\else + \@ifundefined{lstkandc@\lst@temp} + {\typeout{\lst@temp\space not in reference guide?}}{}% + \fi}} +% \end{macrocode} +% +% \paragraph{Unique styles} +% \begin{macrocode} +\newcommand*\lst{\texttt{lst}} +\newcommand*\Cpp{C\texttt{++}} +\let\keyname\texttt +\let\keyvalue\texttt +\let\hookname\texttt +\newcommand*\aspectname[1]{{\normalfont\sffamily#1}} +% \end{macrocode} +% \begin{macrocode} +\DeclareRobustCommand\packagename[1]{% + {\leavevmode\text@command{#1}% + \switchfontfamily\sfdefault\rmdefault + \check@icl #1\check@icr + \expandafter}}% +\def\switchfontfamily#1#2{% + \begingroup\xdef\@gtempa{#1}\endgroup + \ifx\f@family\@gtempa\fontfamily#2% + \else\fontfamily#1\fi + \selectfont} +% \end{macrocode} +% The color mainly for keys and commands in the reference guide. +% \begin{macrocode} +\ifcolor + \definecolor{darkgreen}{rgb}{0,0.6,0} + \def\rstyle{\color{darkgreen}} +\else + \let\rstyle\empty +\fi +% \end{macrocode} +% +% \paragraph{Commands for credits and helpers} +% \begin{macrocode} +\gdef\lst@emails{} +\newcommand*\lstthanks[2] + {#1\lst@AddTo\lst@emails{,#1,<#2>}% + \ifx\@empty#2\@empty\typeout{Missing email for #1}\fi} +\newcommand*\lsthelper[3] + {{\let~\ #1}% + \lst@IfOneOf#1\relax\lst@emails + {}{\typeout{^^JWarning: Unknown helper #1.^^J}}} +% \end{macrocode} +% +% \paragraph{Languages and styles} +% \begin{macrocode} +\lstdefinelanguage[doc]{Pascal}{% + morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,% + do,downto,else,end,false,file,for,function,get,goto,if,in,% + integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% + procedure,put,read,readln,real,record,repeat,reset,rewrite,set,% + text,then,to,true,type,unpack,until,var,while,with,write,writeln},% + sensitive=false,% + morecomment=[s]{(*}{*)},% + morecomment=[s]{\{}{\}},% + morestring=[d]{'}} +% \end{macrocode} +% \begin{macrocode} +\lstdefinestyle{} + {basicstyle={},% + keywordstyle=\bfseries,identifierstyle={},% + commentstyle=\itshape,stringstyle={},% + numberstyle={},stepnumber=1,% + pointstyle=\pointstyle} +\def\pointstyle{% + {\let\lst@um\@empty \xdef\@gtempa{\the\lst@token}}% + \expandafter\lstkeyindex\expandafter{\@gtempa}{}% + \expandafter\lstaspectindex\expandafter{\@gtempa}{}% + \rstyle} +\lstset{defaultdialect=[doc]Pascal,language=Pascal,style={}} +% \end{macrocode} +% +% +% \subsection{Scanning languages} +% +% \begin{macro}{\lstscanlanguages} +% We modify some internal definitions and input the files. +% \begin{macrocode} +\def\lstscanlanguages#1#2#3{% + \begingroup + \def\lst@DefDriver@##1##2##3##4[##5]##6{% + \lst@false + \lst@lAddTo\lst@scan{##6(##5),}% + \begingroup + \@ifnextchar[{\lst@XDefDriver{##1}##3}{\lst@DefDriver@@##3}}% + \def\lst@XXDefDriver[##1]{}% + \lst@InputCatcodes + \def\lst@dontinput{#3}% + \let\lst@scan\@empty + \lst@for{#2}\do{% + \lst@IfOneOf##1\relax\lst@dontinput + {}% + {\InputIfFileExists{##1}{}{}}}% + \global\let\@gtempa\lst@scan + \endgroup + \let#1\@gtempa} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstprintlanguages} +% |\do| creates a box of width 0.5|\linewidth| or |\linewidth| depending +% on how wide the argument is. This leads to `two column' output. +% The other main thing is sorting the list and begin with the output. +% \begin{macrocode} +\def\lstprintlanguages#1{% + \def\do##1{\setbox\@tempboxa\hbox{##1\space\space}% + \ifdim\wd\@tempboxa<.5\linewidth \wd\@tempboxa.5\linewidth + \else \wd\@tempboxa\linewidth \fi + \box\@tempboxa\allowbreak}% + \begin{quote} + \par\noindent + \hyphenpenalty=\@M \rightskip=\z@\@plus\linewidth\relax + \lst@BubbleSort#1% + \expandafter\lst@NextLanguage#1\relax(\relax),% + \end{quote}} +% \end{macrocode} +% We get and define the current language and \ldots +% \begin{macrocode} +\def\lst@NextLanguage#1(#2),{% + \ifx\relax#1\else + \def\lst@language{#1}\def\lst@dialects{(#2),}% + \expandafter\lst@NextLanguage@ + \fi} +% \end{macrocode} +% \ldots\space gather all available dialect of this language (note that the +% list has been sorted) +% \begin{macrocode} +\def\lst@NextLanguage@#1(#2),{% + \def\lst@temp{#1}% + \ifx\lst@temp\lst@language + \lst@lAddTo\lst@dialects{(#2),}% + \expandafter\lst@NextLanguage@ + \else +% \end{macrocode} +% or begin to print this language with all its dialects. Therefor we sort the +% dialects +% \begin{macrocode} + \do{\lst@language + \ifx\lst@dialects\lst@emptydialect\else + \expandafter\lst@NormedDef\expandafter\lst@language + \expandafter{\lst@language}% + \space(% + \lst@BubbleSort\lst@dialects + \expandafter\lst@PrintDialects\lst@dialects(\relax),% + )% + \fi}% + \def\lst@next{\lst@NextLanguage#1(#2),}% + \expandafter\lst@next + \fi} +\def\lst@emptydialect{(),} +% \end{macrocode} +% and print the dialect with appropriate commas in between. +% \begin{macrocode} +\def\lst@PrintDialects(#1),{% + \ifx\@empty#1\@empty empty\else + \lst@PrintDialect{#1}% + \fi + \lst@PrintDialects@} +\def\lst@PrintDialects@(#1),{% + \ifx\relax#1\else + , \lst@PrintDialect{#1}% + \expandafter\lst@PrintDialects@ + \fi} +% \end{macrocode} +% Here we take care of default dialects. +% \begin{macrocode} +\def\lst@PrintDialect#1{% + \lst@NormedDef\lst@temp{#1}% + \expandafter\ifx\csname\@lst dd@\lst@language\endcsname\lst@temp + \texttt{\underbar{#1}}% + \else + \texttt{#1}% + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Bubble sort} +% +% \begin{macro}{\lst@IfLE} +% \meta{string 1}|\relax\@empty|\meta{string 2}|\relax\@empty|\marg{then}\meta{else}. +% If \meta{string 1} $\leq$ \meta{string 2}, we execute \meta{then} and +% \meta{else} otherwise. +% Note that this comparision is case insensitive. +% \begin{macrocode} +\def\lst@IfLE#1#2\@empty#3#4\@empty{% + \ifx #1\relax + \let\lst@next\@firstoftwo + \else \ifx #3\relax + \let\lst@next\@secondoftwo + \else + \lowercase{\ifx#1#3}% + \def\lst@next{\lst@IfLE#2\@empty#4\@empty}% + \else + \lowercase{\ifnum`#1<`#3}\relax + \let\lst@next\@firstoftwo + \else + \let\lst@next\@secondoftwo + \fi + \fi + \fi \fi + \lst@next} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@BubbleSort} +% is in fact a derivation of bubble sort. +% \begin{macrocode} +\def\lst@BubbleSort#1{% + \ifx\@empty#1\else + \lst@false +% \end{macrocode} +% We `bubble sort' the first, second, \ldots\ elements and \ldots +% \begin{macrocode} + \expandafter\lst@BubbleSort@#1\relax,\relax,% +% \end{macrocode} +% \ldots\space then the second, third, \ldots\ elements until no elemets have +% been swapped. +% \begin{macrocode} + \expandafter\lst@BubbleSort@\expandafter,\lst@sorted + \relax,\relax,% + \let#1\lst@sorted + \lst@if + \def\lst@next{\lst@BubbleSort#1}% + \expandafter\expandafter\expandafter\lst@next + \fi + \fi} +\def\lst@BubbleSort@#1,#2,{% + \ifx\@empty#1\@empty + \def\lst@sorted{#2,}% + \def\lst@next{\lst@BubbleSort@@}% + \else + \let\lst@sorted\@empty + \def\lst@next{\lst@BubbleSort@@#1,#2,}% + \fi + \lst@next} +% \end{macrocode} +% But the bubbles rise only one step per call. Putting the elements at their +% top most place would be inefficient (since \TeX\ had to read much more +% parameters in this case). +% \begin{macrocode} +\def\lst@BubbleSort@@#1,#2,{% + \ifx\relax#1\else + \ifx\relax#2% + \lst@lAddTo\lst@sorted{#1,}% + \expandafter\expandafter\expandafter\lst@BubbleSort@@@ + \else + \lst@IfLE #1\relax\@empty #2\relax\@empty + {\lst@lAddTo\lst@sorted{#1,#2,}}% + {\lst@true \lst@lAddTo\lst@sorted{#2,#1,}}% + \expandafter\expandafter\expandafter\lst@BubbleSort@@ + \fi + \fi} +\def\lst@BubbleSort@@@#1\relax,{} +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \end{macro} +% +% +% \section{Interfaces to other programs} +% +% +% \subsection{0.21 compatibility} +% +% \begin{aspect}{0.21} +% Some keys have just been renamed. +% \begin{macrocode} +%<*0.21> +\lst@BeginAspect{0.21} +% \end{macrocode} +% +% \begin{macrocode} +\lst@Key{labelstyle}{}{\def\lst@numberstyle{#1}} +\lst@Key{labelsep}{10pt}{\def\lst@numbersep{#1}} +\lst@Key{labelstep}{0}{% + \ifnum #1=\z@ \KV@lst@numbers{none}% + \else \KV@lst@numbers{left}\fi + \def\lst@stepnumber{#1\relax}} +\lst@Key{firstlabel}\relax{\def\lst@firstnumber{#1\relax}} +\lst@Key{advancelabel}\relax{\def\lst@advancenumber{#1\relax}} +\let\c@lstlabel\c@lstnumber +\lst@AddToHook{Init}{\let\thelstnumber\thelstlabel} +\newcommand*\thelstlabel{\@arabic\c@lstlabel} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{first}\relax{\def\lst@firstline{#1\relax}} +\lst@Key{last}\relax{\def\lst@lastline{#1\relax}} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{framerulewidth}{.4pt}{\def\lst@framerulewidth{#1}} +\lst@Key{framerulesep}{2pt}{\def\lst@rulesep{#1}} +\lst@Key{frametextsep}{3pt}{\def\lst@frametextsep{#1}} +\lst@Key{framerulecolor}{}{\lstKV@OptArg[]{#1}% + {\ifx\@empty##2\@empty + \let\lst@rulecolor\@empty + \else + \ifx\@empty##1\@empty + \def\lst@rulecolor{\color{##2}}% + \else + \def\lst@rulecolor{\color[##1]{##2}}% + \fi + \fi}} +\lst@Key{backgroundcolor}{}{\lstKV@OptArg[]{#1}% + {\ifx\@empty##2\@empty + \let\lst@bkgcolor\@empty + \else + \ifx\@empty##1\@empty + \def\lst@bkgcolor{\color{##2}}% + \else + \def\lst@bkgcolor{\color[##1]{##2}}% + \fi + \fi}} +\lst@Key{framespread}{\z@}{\def\lst@framespread{#1}} +\lst@AddToHook{PreInit} + {\@tempdima\lst@framespread\relax \divide\@tempdima\tw@ + \edef\lst@framextopmargin{\the\@tempdima}% + \let\lst@framexrightmargin\lst@framextopmargin + \let\lst@framexbottommargin\lst@framextopmargin + \advance\@tempdima\lst@xleftmargin\relax + \edef\lst@framexleftmargin{\the\@tempdima}} +% \end{macrocode} +% \lsthelper{Harald~Harders}{1998/03/30}{inner- and outerspread} had the idea +% of two spreads (inner and outer). We either divide the dimension by two or +% assign the two dimensions to inner- and outerspread. +% \begin{macrocode} +\newdimen\lst@innerspread \newdimen\lst@outerspread +\lst@Key{spread}{\z@,\z@}{\lstKV@CSTwoArg{#1}% + {\lst@innerspread##1\relax + \ifx\@empty##2\@empty + \divide\lst@innerspread\tw@\relax + \lst@outerspread\lst@innerspread + \else + \lst@outerspread##2\relax + \fi}} +\lst@AddToHook{BoxUnsafe}{\lst@outerspread\z@ \lst@innerspread\z@} +\lst@Key{wholeline}{false}[t]{\lstKV@SetIf{#1}\lst@ifresetmargins} +\lst@Key{indent}{\z@}{\def\lst@xleftmargin{#1}} +\lst@AddToHook{PreInit} + {\lst@innerspread=-\lst@innerspread + \lst@outerspread=-\lst@outerspread + \ifodd\c@page \advance\lst@innerspread\lst@xleftmargin + \else \advance\lst@outerspread\lst@xleftmargin \fi + \ifodd\c@page + \edef\lst@xleftmargin{\the\lst@innerspread}% + \edef\lst@xrightmargin{\the\lst@outerspread}% + \else + \edef\lst@xleftmargin{\the\lst@outerspread}% + \edef\lst@xrightmargin{\the\lst@innerspread}% + \fi} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{defaultclass}\relax{\def\lst@classoffset{#1}} +\lst@Key{stringtest}\relax{}% dummy +\lst@Key{outputpos}\relax{\lst@outputpos#1\relax\relax} +% \end{macrocode} +% \begin{macrocode} +\lst@Key{stringspaces}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowstringspaces} +\lst@Key{visisblespaces}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowspaces} +\lst@Key{visibletabs}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowtabs} +% \end{macrocode} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{\textsf{fancyvrb}} +% +% \lsthelper{Denis~Girou}{1998/07/26}{fancyvrb} asked whether +% \packagename{fancyvrb} and \packagename{listings} could work together. +% This is still the second attempt. +% +% \begin{lstkey}{fancyvrb} +% We set the boolean and call a submacro. +% \begin{macrocode} +%<*kernel> +\lst@Key{fancyvrb}\relax[t]{% + \lstKV@SetIf{#1}\lst@iffancyvrb + \lstFV@fancyvrb} +\ifx\lstFV@fancyvrb\@undefined + \gdef\lstFV@fancyvrb{\lst@RequireAspects{fancyvrb}\lstFV@fancyvrb} +\fi +% +% \end{macrocode} +% \end{lstkey} +% +% \begin{aspect}{fancyvrb} +% We end the job if \packagename{fancyvrb} is not present. +% \begin{macrocode} +%<*misc> +\lst@BeginAspect{fancyvrb} +% \end{macrocode} +% \begin{macrocode} +\@ifundefined{FancyVerbFormatLine} + {\typeout{^^J% + ***^^J% + *** `listings.sty' needs `fancyvrb.sty' right now.^^J% + *** Please ensure its availability and try again.^^J% + ***^^J}% + \batchmode \@@end}{} +% \end{macrocode} +% +% \begin{macro}{\lstFV@fancyvrb} +% We assign the correct |\FancyVerbFormatLine| macro. +% \begin{macrocode} +\gdef\lstFV@fancyvrb{% + \lst@iffancyvrb + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine\else + \let\lstFV@FVFL\FancyVerbFormatLine + \let\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \fi + \else + \ifx\lstFV@FVFL\@undefined\else + \let\FancyVerbFormatLine\lstFV@FVFL + \let\lstFV@FVFL\@undefined + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstFV@VerbatimBegin} +% We initialize things if necessary. +% \begin{macrocode} +\gdef\lstFV@VerbatimBegin{% + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \lsthk@TextStyle \lsthk@BoxUnsafe + \lsthk@PreSet + \lst@activecharsfalse + \let\normalbaselines\relax +% \end{macrocode} +% \begin{TODO} +% Is this |\let| bad? +% \end{TODO} +% I inserted |\lst@ifresetmargins|\ldots|\fi| after a bug report from +% \lsthelper{Peter~Bartke}{1999/11/18}{wrong fancyvrb frame}. +% \begin{macrocode} + \lst@Init\relax + \lst@ifresetmargins \advance\linewidth-\@totalleftmargin \fi + \everypar{}\global\lst@newlines\z@ + \lst@mode\lst@nomode \let\lst@entermodes\@empty + \lst@InterruptModes +% \end{macrocode} +% \lsthelper{Rolf~Niepraschk}{1998/11/25}{ligatures problem} reported a bug +% concerning ligatures to \lsthelper{Denis~Girou}{1998/11/27}{use |\@noligs|}. +% \begin{macrocode} +%% D.G. modification begin - Nov. 25, 1998 + \let\@noligs\relax +%% D.G. modification end + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lstFV@VerbatimEnd} +% A box and macro must exist after |\lst@DeInit|. +% We store them globally. +% \begin{macrocode} +\gdef\lstFV@VerbatimEnd{% + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \global\setbox\lstFV@gtempboxa\box\@tempboxa + \global\let\@gtempa\FV@ProcessLine + \lst@mode\lst@Pmode + \lst@DeInit + \let\FV@ProcessLine\@gtempa + \setbox\@tempboxa\box\lstFV@gtempboxa + \fi} +% \end{macrocode} +% \begin{macrocode} +\newbox\lstFV@gtempboxa +% \end{macrocode} +% \end{macro} +% +% \noindent +% We insert |\lstFV@VerbatimBegin| and |\lstFV@VerbatimEnd| where necessary. +% \begin{macrocode} +\lst@AddTo\FV@VerbatimBegin\lstFV@VerbatimBegin +\lst@AddToAtTop\FV@VerbatimEnd\lstFV@VerbatimEnd +\lst@AddTo\FV@LVerbatimBegin\lstFV@VerbatimBegin +\lst@AddToAtTop\FV@LVerbatimEnd\lstFV@VerbatimEnd +\lst@AddTo\FV@BVerbatimBegin\lstFV@VerbatimBegin +\lst@AddToAtTop\FV@BVerbatimEnd\lstFV@VerbatimEnd +% \end{macrocode} +% +% \begin{macro}{\lstFV@FancyVerbFormatLine} +% `@' terminates the argument of |\lst@FVConvert|. +% Moreover |\lst@ReenterModes| and |\lst@InterruptModes| encloses some code. +% This ensures that we have same group level at the beginning and at the end of +% the macro---even if the user begins but doesn't end a comment, which means +% one open group. +% Furthermore we use |\vtop| and reset |\lst@newlines| to allow line breaking. +% \begin{macrocode} +\gdef\lstFV@FancyVerbFormatLine#1{% + \let\lst@arg\@empty \lst@FVConvert#1\@nil + \global\lst@newlines\z@ + \vtop{\leavevmode\lst@parshape + \lst@ReenterModes + \lst@arg \lst@PrintToken\lst@EOLUpdate\lsthk@InitVarsBOL + \lst@InterruptModes}} +% \end{macrocode} +% The |\lst@parshape| inside |\vtop| is due to a bug report from +% \lsthelper{Peter~Bartke}{1999/11/18}{wrong par indention with fancyvrb}. +% \end{macro} +% +% \begin{macro}{\lst@FVConvert} +% Since |\@ifnextchar\bgroup| might fail, we have to use |\ifcat| here. +% Bug reported by \lsthelper{Denis~Girou}{1999/07/26}{fancyvrb=true + `second +% commandchar' other than \{ doesn't work}. +% However we don't gobble space tokens as |\@ifnextchar| does. +% \begin{macrocode} +\gdef\lst@FVConvert{\futurelet\@let@token\lst@FVConvert@@} +\gdef\lst@FVConvert@@{% + \ifcat\noexpand\@let@token\bgroup \expandafter\lst@FVConvertArg + \else \expandafter\lst@FVConvert@ \fi} +% \end{macrocode} +% Coming to such a catcode${}={}$1 character we convert the argument and add +% it together with group delimiters to |\lst@arg|. +% We also add |\lst@PrintToken|, which prints all collected characters before +% we forget them. +% Finally we continue the conversion. +% \begin{macrocode} +\gdef\lst@FVConvertArg#1{% + {\let\lst@arg\@empty + \lst@FVConvert#1\@nil + \global\let\@gtempa\lst@arg}% + \lst@lExtend\lst@arg{\expandafter{\@gtempa\lst@PrintToken}}% + \lst@FVConvert} +% \end{macrocode} +% Having no |\bgroup|, we look whether we've found the end of the input, and +% convert one token ((non)active character or control sequence) and continue. +% \begin{macrocode} +\gdef\lst@FVConvert@#1{% + \ifx \@nil#1\else + \if\relax\noexpand#1% + \lst@lAddTo\lst@arg{\lst@OutputLostSpace\lst@PrintToken#1}% + \else + \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% + \fi + \expandafter\lst@FVConvert + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{Omega support} +% +% \begingroup +% $\Omega$ support looks easy---I hope it works at least in some cases. +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% \begin{macrocode} +\@ifundefined{ocp}{} + {\lst@AddToHook{OutputBox}% + {\let\lst@ProcessLetter\@firstofone + \let\lst@ProcessDigit\@firstofone + \let\lst@ProcessOther\@firstofone}} +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{\textsf{LGrind}} +% +% \begin{aspect}{lgrind} +% \begin{macro}{\lst@LGGetNames} +% is used to extract the language names from |\lst@arg| (the +% \packagename{LGrind} definition). +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords,comments,strings,language]{lgrind} +% \end{macrocode} +% \begin{macrocode} +\gdef\lst@LGGetNames#1:#2\relax{% + \lst@NormedDef\lstlang@{#1}\lst@ReplaceInArg\lstlang@{|,}% + \def\lst@arg{:#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LGGetValue} +% returns in |\lst@LGvalue| the value of capability |#1| given by the list +% |\lst@arg|. If |#1| is not found, we have |\lst@if|=|\iffalse|. +% Otherwise it is true and the ``cap=value'' pair is removed from the list. +% First we test for |#1| and +% \begin{macrocode} +\gdef\lst@LGGetValue#1{% + \lst@false + \def\lst@temp##1:#1##2##3\relax{% + \ifx\@empty##2\else \lst@LGGetValue@{#1}\fi} + \expandafter\lst@temp\lst@arg:#1\@empty\relax} +% \end{macrocode} +% remove the pair if necessary. +% \begin{macrocode} +\gdef\lst@LGGetValue@#1{% + \lst@true + \def\lst@temp##1:#1##2:##3\relax{% + \@ifnextchar=\lst@LGGetValue@@{\lst@LGGetValue@@=}##2\relax + \def\lst@arg{##1:##3}}% + \expandafter\lst@temp\lst@arg\relax} +\gdef\lst@LGGetValue@@=#1\relax{\def\lst@LGvalue{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LGGetComment} +% stores the comment delimiters (enclosed in braces) in |#2| if comment of type +% |#1| is present and not a comment line. Otherwise |#2| is empty. +% \begin{macrocode} +\gdef\lst@LGGetComment#1#2{% + \let#2\@empty + \lst@LGGetValue{#1b}% + \lst@if + \let#2\lst@LGvalue + \lst@LGGetValue{#1e}% + \ifx\lst@LGvalue\lst@LGEOL + \edef\lstlang@{\lstlang@,commentline={#2}}% + \let#2\@empty + \else + \edef#2{{#2}{\lst@LGvalue}}% + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LGGetString} +% does the same for string delimiters, but it doesn't `return' any value. +% \begin{macrocode} +\gdef\lst@LGGetString#1#2{% + \lst@LGGetValue{#1b}% + \lst@if + \let#2\lst@LGvalue + \lst@LGGetValue{#1e}% + \ifx\lst@LGvalue\lst@LGEOL + \edef\lstlang@{\lstlang@,morestringizer=[l]{#2}}% + \else +% \end{macrocode} +% we must check for |\e|, i.e.~whether we have to use \texttt doubled or +% \texttt backslashed stringizer. +% \begin{macrocode} + \ifx #2\lst@LGvalue + \edef\lstlang@{\lstlang@,morestringizer=[d]{#2}}% + \else + \edef\lst@temp{\lst@LGe#2}% + \ifx \lst@temp\lst@LGvalue + \edef\lstlang@{\lstlang@,morestringizer=[b]{#2}}% + \else + \PackageWarning{Listings}% + {String #2...\lst@LGvalue\space not supported}% + \fi + \fi + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LGDefLang} +% defines the language given by |\lst@arg|, the definition part, and +% |\lst@language@|, the language name. First we remove unwanted stuff from +% |\lst@arg|, e.g.~we replace |:\ :| by |:|. +% \begin{macrocode} +\gdef\lst@LGDefLang{% + \lst@LGReplace + \let\lstlang@\empty +% \end{macrocode} +% Get the keywords and values of friends. +% \begin{macrocode} + \lst@LGGetValue{kw}% + \lst@if + \lst@ReplaceInArg\lst@LGvalue{{ },}% + \edef\lstlang@{\lstlang@,keywords={\lst@LGvalue}}% + \fi +% \end{macrocode} +% \begin{macrocode} + \lst@LGGetValue{oc}% + \lst@if + \edef\lstlang@{\lstlang@,sensitive=f}% + \fi +% \end{macrocode} +% \begin{macrocode} + \lst@LGGetValue{id}% + \lst@if + \edef\lstlang@{\lstlang@,alsoletter=\lst@LGvalue}% + \fi +% \end{macrocode} +% Now we get the comment delimiters and use them as single or double comments +% according to whether there are two or four delimiters. +% Note that |\lst@LGGetComment| takes care of comment lines. +% \begin{macrocode} + \lst@LGGetComment a\lst@LGa + \lst@LGGetComment c\lst@LGc + \ifx\lst@LGa\@empty + \ifx\lst@LGc\@empty\else + \edef\lstlang@{\lstlang@,singlecomment=\lst@LGc}% + \fi + \else + \ifx\lst@LGc\@empty + \edef\lstlang@{\lstlang@,singlecomment=\lst@LGa}% + \else + \edef\lstlang@{\lstlang@,doublecomment=\lst@LGc\lst@LGa}% + \fi + \fi +% \end{macrocode} +% Now we parse the stringizers. +% \begin{macrocode} + \lst@LGGetString s\lst@LGa + \lst@LGGetString l\lst@LGa +% \end{macrocode} +% We test for the continuation capability and +% \begin{macrocode} + \lst@LGGetValue{tc}% + \lst@if + \edef\lstlang@{\lstlang@,lgrindef=\lst@LGvalue}% + \fi +% \end{macrocode} +% define the language. +% \begin{macrocode} + \expandafter\xdef\csname\@lst LGlang@\lst@language@\endcsname + {\noexpand\lstset{\lstlang@}}% +% \end{macrocode} +% Finally we inform the user of all ignored capabilities. +% \begin{macrocode} + \lst@ReplaceInArg\lst@arg{{: :}:}\let\lst@LGvalue\@empty + \expandafter\lst@LGDroppedCaps\lst@arg\relax\relax + \ifx\lst@LGvalue\@empty\else + \PackageWarningNoLine{Listings}{Ignored capabilities for + \space `\lst@language@' are\MessageBreak\lst@LGvalue}% + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LGDroppedCaps} +% just drops a previous value and appends the next capabilty name to +% |\lst@LGvalue|. +% \begin{macrocode} +\gdef\lst@LGDroppedCaps#1:#2#3{% + \ifx#2\relax + \lst@RemoveCommas\lst@LGvalue + \else + \edef\lst@LGvalue{\lst@LGvalue,#2#3}% + \expandafter\lst@LGDroppedCaps + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\lst@LGReplace} +% \begin{macro}{\lst@LGe} +% We replace `escaped \verb!:^$|!' by catcode 11 versions, and other strings +% by some kind of short versions (which is necessary to get the above +% definitions work). +% \begin{macrocode} +\begingroup +\catcode`\/=0 +\lccode`\z=`\:\lccode`\y=`\^\lccode`\x=`\$\lccode`\v=`\| +\catcode`\\=12\relax +/lowercase{% +/gdef/lst@LGReplace{/lst@ReplaceInArg/lst@arg + {{\:}{z }{\^}{y}{\$}{x}{\|}{v}{ \ }{ }{:\ :}{:}{\ }{ }{\(}({\)})}} +/gdef/lst@LGe{\e} +} +/endgroup +% \end{macrocode} +% \end{macro}\end{macro} +% +% \begin{macro}{\lst@LGRead} +% reads one language definition and defines the language if the correct one +% is found. +% \begin{macrocode} +\gdef\lst@LGRead#1\par{% + \lst@LGGetNames#1:\relax + \def\lst@temp{endoflanguagedefinitions}% + \ifx\lstlang@\lst@temp + \let\lst@next\endinput + \else + \expandafter\lst@IfOneOf\lst@language@\relax\lstlang@ + {\lst@LGDefLang \let\lst@next\endinput}% + {\let\lst@next\lst@LGRead}% + \fi + \lst@next} +% \end{macrocode} +% \end{macro} +% +% \begin{lstkey}{lgrindef} +% We only have to request the language and +% \begin{macrocode} +\lst@Key{lgrindef}\relax{% + \lst@NormedDef\lst@language@{#1}% + \begingroup + \@ifundefined{lstLGlang@\lst@language@}% + {\everypar{\lst@LGRead}% + \catcode`\\=12\catcode`\{=12\catcode`\}=12\catcode`\%=12% + \catcode`\#=14\catcode`\$=12\catcode`\^=12\catcode`\_=12\relax + \input{\lstlgrindeffile}% + }{}% + \endgroup +% \end{macrocode} +% select it or issue an error message. +% \begin{macrocode} + \@ifundefined{lstLGlang@\lst@language@}% + {\PackageError{Listings}% + {LGrind language \lst@language@\space undefined}% + {The language is not loadable. \@ehc}}% + {\lsthk@SetLanguage + \csname\@lst LGlang@\lst@language@\endcsname}} +% \end{macrocode} +% \end{lstkey} +% +% \begin{macro}{\lstlgrindeffile} +% contains just the file name. +% \begin{macrocode} +\@ifundefined{lstlgrindeffile} + {\lst@UserCommand\lstlgrindeffile{lgrindef.}}{} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \subsection{\textsf{hyperref}} +% +% \begin{aspect}{hyper} +% \begin{macrocode} +%<*misc> +\lst@BeginAspect[keywords]{hyper} +% \end{macrocode} +% +% \begin{lstkey}{hyperanchor} +% \begin{lstkey}{hyperlink} +% determine the macro to set an anchor and a link, respectively. +% \begin{macrocode} +\lst@Key{hyperanchor}\hyper@@anchor{\let\lst@hyperanchor#1} +\lst@Key{hyperlink}\hyperlink{\let\lst@hyperlink#1} +% \end{macrocode} +% \end{lstkey}\end{lstkey} +% Again, the main thing is a special working procedure. First we extract the +% contents of |\lst@token| and get a free macro name for this current character +% string (using prefix |lstHR@| and a number as suffix). Then we make this +% free macro equivalent to |\@empty|, so it is not used the next time. +% \begin{macrocode} +\lst@InstallKeywords{h}{hyperref}{}\relax{} + {\begingroup + \let\lst@UM\@empty \xdef\@gtempa{\the\lst@token}% + \endgroup + \lst@GetFreeMacro{lstHR@\@gtempa}% + \global\expandafter\let\lst@freemacro\@empty +% \end{macrocode} +% |\@tempcnta| is the suffix of the free macro. We use it here to refer to +% the last occurence of the same string. To do this, we redefine the output +% macro |\lst@alloverstyle| to set an anchor \ldots +% \begin{macrocode} + \@tempcntb\@tempcnta \advance\@tempcntb\m@ne + \edef\lst@alloverstyle##1{% + \let\noexpand\lst@alloverstyle\noexpand\@empty + \noexpand\smash{\raise\baselineskip\hbox + {\noexpand\lst@hyperanchor{lst.\@gtempa\the\@tempcnta}% + {\relax}}}% +% \end{macrocode} +% \ldots\space and a link to the last occurence (if there is any). +% \begin{macrocode} + \ifnum\@tempcnta=\z@ ##1\else + \noexpand\lst@hyperlink{lst.\@gtempa\the\@tempcntb}{##1}% + \fi}% + } + od +% \end{macrocode} +% +% \begin{macrocode} +\lst@EndAspect +% +% \end{macrocode} +% \end{aspect} +% +% +% \section{Epilogue} +% +% \begingroup +% \begin{macrocode} +%<*kernel> +% \end{macrocode} +% Each option adds the aspect name to |\lst@loadaspects| or removes it from that data macro. +% \begin{macrocode} +\DeclareOption*{\expandafter\lst@ProcessOption\CurrentOption\relax} +\def\lst@ProcessOption#1#2\relax{% + \ifx #1!% + \lst@DeleteKeysIn\lst@loadaspects{#2}% + \else + \lst@lAddTo\lst@loadaspects{,#1#2}% + \fi} +% \end{macrocode} +% The following aspects are loaded by default. +% \begin{macrocode} +\@ifundefined{lst@loadaspects} + {\def\lst@loadaspects{strings,comments,escape,style,language,% + keywords,labels,lineshape,frames,emph,index}% + }{} +% \end{macrocode} +% We load the patch file, \ldots +% \begin{macrocode} +\InputIfFileExists{lstpatch.sty}{}{} +% \end{macrocode} +% \ldots\ process the options, \ldots +% \begin{macrocode} +\let\lst@ifsavemem\iffalse +\DeclareOption{savemem}{\let\lst@ifsavemem\iftrue} +\DeclareOption{noaspects}{\let\lst@loadaspects\@empty} +\ProcessOptions +% \end{macrocode} +% \ldots\ and load the aspects. +% \begin{macrocode} +\lst@RequireAspects\lst@loadaspects +\let\lst@loadaspects\@empty +% \end{macrocode} +% If present we select the empty style and language. +% \begin{macrocode} +\lst@UseHook{SetStyle}\lst@UseHook{EmptyStyle} +\lst@UseHook{SetLanguage}\lst@UseHook{EmptyLanguage} +% \end{macrocode} +% Finally we load the configuration files. +% \begin{macrocode} +\InputIfFileExists{listings.cfg}{}{} +\InputIfFileExists{lstlocal.cfg}{}{} +%\lst@ReportAllocs +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \section{History} +% \begingroup\small +% Only major changes are listed here. Introductory version numbers of commands +% and keys are in the sources of the guides, which makes this history fairly +% short. +% \renewcommand\labelitemi{--} +% \begin{itemize} +% \item[0.1] from 1996/03/09 +% \item test version to look whether package is possible or not +% \item[0.11] from 1996/08/19 +%\iffalse +% \item additional blank option (= language) +%\fi +% \item improved alignment +% \item[0.12] from 1997/01/16 +% \item nearly `perfect' alignment +% \item[0.13] from 1997/02/11 +%\iffalse +% \item additional languages: Eiffel, Fortran 90, Modula-2, Pascal XSC +%\fi +% \item load on demand: language specific macros moved to driver files +% \item comments are declared now and not implemented for each language again +% (this makes the \TeX\ sources easier to read) +% \item[0.14] from 1997/02/18 +% \item User's guide rewritten, Implementation guide uses macro environment +% \item (non) case sensitivity implemented and multiple string types, +% i.e.~Modula-2 handles both string types: quotes and double quotes +%\iffalse +% \item comment declaration is user-accessible +% \item package compatible to \verb!german.sty! +%\fi +% \item[0.15] from 1997/04/18 +%\iffalse +% \item additional languages: Java, Turbo Pascal +%\fi +% \item package renamed from \packagename{listing} to \packagename{listings} +% since the first already exists +% \item[0.16] from 1997/06/01 +%\iffalse +% \item changed `$<$' to `$>$' in |\lst@SkipToFirst| +% \item bug removed: |\lst@Init| must be placed before |\lst@SkipToFirst| +%\fi +% \item listing environment rewritten +% \item[0.17] from 1997/09/29 +%\iffalse +% \item |\spreadlisting| works correct now (e.g.~page numbers don't move right) +%\fi +% \item speed up things (quick `if parameter empty', all |\long| except one +% removed, faster \verb!\lst@GotoNextTabStop!, etc.) +% \item improved alignment of wide other characters (e.g.~$==$) +%\iffalse +% \item many new languages: Ada, Algol, Cobol, Comal 80, Elan, Fortran 77, +% Lisp, Logo, Matlab, Oberon, Perl, PL/I, Simula, SQL, \TeX +%\fi +% \item[pre-0.18] from 1998/03/24 (unpublished) +%\iffalse +% \item bug concerning |\labelstyle| (becomes \keyname{numberstyle}) removed +% (now oldstylenum example works) +%\fi +% \item experimental implementation of character classes +% \item[0.19] from 1998/11/09 +% \item character classes and new \lst-aspects seem to be good +% \item user interface uses \packagename{keyval} package +% \item \packagename{fancyvrb} support +% \item[0.20] from 1999/07/12 +% \item new keyword detection mechanism +% \item new aspects: \aspectname{writefile}, \aspectname{breaklines}, +% captions, \aspectname{html} +%\iffalse +% \item improved \packagename{fancyvrb} support +%\fi +% \item all aspects reside in a single file and the language drivers in +% currently two files +% \item[0.21] 2000/08/23 +% \item completely new User's guide +% \item experimental format definitions +% \item keyword classes replaced by families +% \item dynamic modes +% \item[1.0$\beta$] 2001/09/21 +% \item keynames synchronized with \packagename{fancyvrb} +% \item \aspectname{frames} aspect extended +% \item new output concept (delaying and merging) +% \item[1.0] 2002/04/01 +% \item update of all documentation sections including Developer's guide +% \item delimiters unified +% \end{itemize} +% \endgroup +% +% +% \Finale +% +\endinput diff --git a/docs/packages/listings/listings.ins b/docs/packages/listings/listings.ins index 291af06bda..2100f5de34 100644 --- a/docs/packages/listings/listings.ins +++ b/docs/packages/listings/listings.ins @@ -1,77 +1,95 @@ %% -%% Installation file: Listings package for LaTeX2e -%% (w)(c) 1996-1998 Carsten Heinz +%% This file generates files required to use the listings package. +%% At your command prompt write %% -\def\batchfile{listings.ins} -% -% just do these things -% -\input{docstrip} +%% tex listings.ins +%% +%% +%% (w)(c) 1996--1999,2002 Carsten Heinz +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Permission is granted to change this file. You are not allowed to +%% distribute any changed version of this file unless you rename it. +%% +\input docstrip +\preamble +\endpreamble + +\usedir{tex/latex/listings} \keepsilent \askforoverwritefalse % -% define the preamble -% -\preamble - -(w)(c) 1996-1998 Carsten Heinz - -Please read the software license in listings.dtx or listings.dvi. - -This file is distributed freely. You are not allowed to take money for -the distribution of this file, except for a nominal charge for copying -etc.. - -This file is free for any non-commercial use. Commercial use needs (i) -explicit permission of the author of this package and (ii) the payment -of a license fee. This fee is to be determined in each instance by the -commercial user and the package author and is to be payed as donation -to the LaTeX3 project. - -This file is distributed without any warranty, express or implied, as -to merchantability or fitness for any particular purpose. - -Permission is granted to change this file. You are not allowed to -distribute any changed version this file, neither under the same name -nor under a different one. - -\endpreamble - - -% -% unpack the listings package +% generate base package % \generate{ - \file{listings.sty} {\from{listings.dtx}{kernel}} - \file{lst017.sty} {\from{listings.dtx}{0.17}} - \file{lstfvrb.sty} {\from{listings.dtx}{fancyvrb}} -} - - -% -% create installation and configuration file if lstdrvrs.dtx exists -% -\IfFileExists{lstdrvrs.dtx}{\generate{ + \file{listings.sty}{\from{listings.dtx}{kernel}} + \file{lstmisc.sty}{\from{listings.dtx}{misc,0.21}} + \file{lstdoc.sty}{\from{listings.dtx}{doc}} \file{lstdrvrs.ins}{\from{lstdrvrs.dtx}{install}} \file{listings.cfg}{\from{lstdrvrs.dtx}{config}} -}} - +} % -% unpack drivers if possible +% generate dummy patch if necessary % -\InputIfFileExists{lstdrvrs.ins}{}{} +\newif\ifdummypatch +\def\lstinsIfFileExists#1#2#3{% + \openin\inputcheck #1\relax + \ifeof\inputcheck\else + \closein\inputcheck + #2% + \@@input #1 + #3% + \fi} +\def\ProvidesFile#1[#2]{\def\lstpatch{#2}\endinput} +\def\lstinsCheckVersion#1 #2{% + \ifx #2v\dummypatchtrue \expandafter\lstinsGobbleNil \fi + \afterassignment\lstinsCheckVersion@ \count\z@#2} +\def\lstinsCheckVersion@.{% + \afterassignment\lstinsGobbleNil \count\tw@} +\def\lstinsGobbleNil#1\@nil{% + \ifdummypatch\else + \edef\patchversion{\the\count\z@.\the\count\tw@}% + \ifx\lstversion\patchversion\else + \dummypatchtrue + \fi + \fi} +\Msg{checking listings version ...} +\lstinsIfFileExists{listings.sty} + {\def\NeedsTeXFormat#1{\endinput}} + {\let\lstversion\fileversion + \lstinsIfFileExists{lstpatch.sty}% + {\let\fileversion\@undefined}% + {\ifx\fileversion\@undefined + \expandafter\lstinsCheckVersion\lstpatch\@nil + \fi}% + } + +\ifdummypatch + \generate{\file{lstpatch.sty}{\from{listings.dtx}{patch}}} +\fi % -% print user's advice +% generate language driver files % +\batchinput{lstdrvrs.ins} + + \Msg{*} -\Msg{* Move all `.sty' and `.cfg' files into a folder searched by TeX.} +\Msg{* You probably need to move all created `.sty' and `.cfg'} +\Msg{* files into a directory searched by TeX.} \Msg{*} -\Msg{* Run the `.dtx' file through LaTeX2e to get the documentation.} +\Msg{* And don't forget to refresh your filename database} +\Msg{* if your TeX distribution uses such a database.} \Msg{*} -\endinput +\endbatchfile + diff --git a/docs/packages/listings/lstdrvrs.dtx b/docs/packages/listings/lstdrvrs.dtx index 9102ff9ca5..1c853a1678 100644 --- a/docs/packages/listings/lstdrvrs.dtx +++ b/docs/packages/listings/lstdrvrs.dtx @@ -10,9 +10,8 @@ %<*driver> \documentclass{ltxdoc} -\EnableCrossrefs +\EnableCrossrefs \CodelineIndex -\OldMakeindex \begin{document} \DocInput{lstdrvrs.dtx} @@ -21,11 +20,6 @@ % \fi % % -% \providecommand\lsthelper[4]{#1\ifx\empty#2\empty\typeout{^^JWarning: #1 has unknown email^^J}\else\space\texttt{<#2>}{}\fi} -% \ifx\TODO\undefined -% \newenvironment{TODO}{\begin{quote}\footnotesize To do:}{\end{quote}} -% \fi -% % \DoNotIndex{\[,\{,\},\],\1,\2,\3,\4,\5,\6,\7,\8,\9,\0} % \DoNotIndex{\`,\,,\!,\#,\$,\&,\',\(,\),\+,\.,\:,\;,\<,\=,\>,\?,\_} % \DoNotIndex{\askforoverwritefalse,\askforoverwritetrue,\batchfile} @@ -34,134 +28,100 @@ % \DoNotIndex{\keepsilent,\lccode,\let,\lowercase,\preamble,\relax} % \DoNotIndex{\undefined} % -% \DoNotIndex{\lst@DriverLocation,\lst@SCmode,} -% \DoNotIndex{\lst@eaten,\lst@EnterMode,\lst@ifmode,\lst@IfNextCharsArg} -% \DoNotIndex{\lst@keywords,\lst@LeaveMode,\lst@mode,\lst@NewMode} -% \DoNotIndex{\lst@PrintToken, alsodigit=,\lstalsoletter, alsoother=} -% \DoNotIndex{\lstCC@@BeginComment,\lstCC@CommentE,\lstCC@TestCArg} -% \DoNotIndex{\lstCC@Def,\lstCC@ProcessOther,\lstCC@ProcessPOD} -% \DoNotIndex{\lstCC@SpecialUseAfter} -% \DoNotIndex{\lstset,\lststorekeywords} % -% \DoNotIndex{\lstkeys@cobol,\lstkeys@cobol@eightyfive,\lstkeys@fortran} -% \DoNotIndex{\lstkeys@tex@commoncs,\lstkeys@tex@latexcs} -% \DoNotIndex{\lstkeys@tex@primitives} -% -% -% \title{Driver files for Listings.dtx 0.19\\ {\large by Carsten Heinz and individual authors:}} -% \author{Kai Below\and Detlev Dr\"oge\and Christian Haul\and J\"urgen Heim\and Detlef Reimers\and Dominique de Waleffe\and Kai Wollenweber} +% \title{Language, Style and Format drivers\\ for \textsf{Listings 1.0}\\ {\large by Carsten Heinz and individual authors:}} +% \author{\InputIfFileExists{lstdrvrs.tmp}{}{}} % \date{} % % \maketitle % +% \newwrite\authors \immediate\openout\authors lstdrvrs.tmp\relax +% \gdef\lstthanks#1#2#3{#1\global\let\lstthanks\lstthanksb\lstwrite{#1}} +% \gdef\lstthanksb#1#2#3{#1\lstwrite{\string\and\space#1}} +% \gdef\lstwrite#1{\begingroup\let~\space\def\"{\string\"}\def\'{\string\'}\immediate\write\authors{#1}\endgroup} +% +% \newcommand*\lsthelper[4]{#1} +% % % \section{Installation and configuration} % % \begingroup % \begin{macrocode} +%% (w)(c) 1996/1997/1998/1999/2000/2001/2002 Carsten Heinz and/or any +%% other author listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +% \end{macrocode} +% \endgroup +% +% \begingroup +% \begin{macrocode} %<*install> -% -% do these things if not already done -% -\ifx\keepsilent\undefined % - \input{docstrip} - \keepsilent - \askforoverwritefalse -\fi -\def\batchfile{lstdrvrs.ins} - -% -% define preamble -% +\input docstrip \preamble - -(w)(c) 1996,1997,1998 Carsten Heinz and/or any other author mentioned -elsewhere in this file. - -This file is distributed freely. You are not allowed to take money for -the use or distribution of this file, except for a nominal charge for -copying etc.. - -This file is distributed without any warranty, express or implied, as -to merchantability or fitness for any particular purpose. - -Permission is granted to change this file. You are not allowed to -distribute any changed version this file, neither under the same name -nor under a different one. - \endpreamble -% -% generate all language drivers -% -\generate{ - \file{lstalgol.sty} {\from{listings.dtx}{keywordcomments} - \from{lstdrvrs.dtx}{algol}} - \file{lstc.sty} {\from{listings.dtx}{c} - \from{lstdrvrs.dtx}{c,objective-c,c++}} - \file{lstperl.sty} {\from{listings.dtx}{perl} - \from{lstdrvrs.dtx}{perl}} - \file{lstsimula.sty} {\from{listings.dtx}{keywordcomments} - \from{lstdrvrs.dtx}{simula}} - \file{lsttex.sty} {\from{listings.dtx}{tex} - \from{lstdrvrs.dtx}{tex}} -% - \file{lstada.sty} {\from{lstdrvrs.dtx}{ada}} - \file{lstcobol.sty} {\from{lstdrvrs.dtx}{cobol}} - \file{lstedu.sty} {\from{lstdrvrs.dtx}{comal,elan,logo}} - \file{lstcsh.sty} {\from{lstdrvrs.dtx}{csh}} - \file{lstdelphi.sty} {\from{lstdrvrs.dtx}{delphi}} - \file{lsteiffel.sty} {\from{lstdrvrs.dtx}{eiffel}} - \file{lsteuphoria.sty}{\from{lstdrvrs.dtx}{euphoria}} - \file{lstfortran.sty} {\from{lstdrvrs.dtx}{fortran}} - \file{lsthtml.sty} {\from{lstdrvrs.dtx}{html}} - \file{lstidl.sty} {\from{lstdrvrs.dtx}{idl}} - \file{lstjava.sty} {\from{lstdrvrs.dtx}{java}} +\ifToplevel{ +\usedir{tex/latex/listings} +\keepsilent +\askonceonly } + \generate{ - \file{lstlisp.sty} {\from{lstdrvrs.dtx}{lisp}} - \file{lstmatlab.sty} {\from{lstdrvrs.dtx}{matlab}} - \file{lstmercury.sty} {\from{lstdrvrs.dtx}{mercury}} - \file{lstmodula.sty} {\from{lstdrvrs.dtx}{modula}} - \file{lstoberon.sty} {\from{lstdrvrs.dtx}{oberon}} - \file{lstpascal.sty} {\from{lstdrvrs.dtx}{pascal}} - \file{lstpli.sty} {\from{lstdrvrs.dtx}{pli}} - \file{lstprolog.sty} {\from{lstdrvrs.dtx}{prolog}} - \file{lstsql.sty} {\from{lstdrvrs.dtx}{sql}} - \file{lstvhdl.sty} {\from{lstdrvrs.dtx}{vhdl}} + \file{lstlang1.sty}{\from{lstdrvrs.dtx}{lang1}} + \file{lstlang2.sty}{\from{lstdrvrs.dtx}{lang2}} + \file{lstlang3.sty}{\from{lstdrvrs.dtx}{lang3}} } -\end + + +\ifToplevel{ +\Msg{*} +\Msg{* You probably need to move all created `.sty' and `.cfg'} +\Msg{* files into a directory searched by TeX.} +\Msg{*} +\Msg{* Run `lstdrvrs.dtx' through LaTeX2e to get the documentation.} +\Msg{*} +} + +\endbatchfile % % \end{macrocode} +% \endgroup % % \begingroup % \begin{macrocode} %<*config> % \end{macrocode} % \endgroup -% Configuration starts with locations of some language drivers. +% We mainly define default dialects. % \begin{macrocode} -\lst@DriverLocation{C++}{lstc} -\lst@DriverLocation{Modula-2}{lstmodula} -\lst@DriverLocation{Oberon-2}{lstoberon} -\lst@DriverLocation{PL/I}{lstpli} -% \end{macrocode} -% \begin{macrocode} -\lst@DriverLocation{Comal 80}{lstedu} -\lst@DriverLocation{Elan}{lstedu} -\lst@DriverLocation{Logo}{lstedu} -% \end{macrocode} -% Then we define default dialects. -% \begin{macrocode} -\lstset{defaultdialect=[68]Algol} -\lstset{defaultdialect=[ANSI]C} -\lstset{defaultdialect=[1985]Cobol} -\lstset{defaultdialect=[ANSI]C++} -\lstset{defaultdialect=[95]Fortran} -\lstset{defaultdialect=[Standard]Pascal} -\lstset{defaultdialect=[67]Simula} -\lstset{defaultdialect=[plain]TeX} +\ProvidesFile{listings.cfg}[2002/04/01 v1.0 listings configuration] +\def\lstlanguagefiles + {lstlang0.sty,lstlang1.sty,lstlang2.sty,lstlang3.sty} +\lstset{defaultdialect=[R/3 6.10]ABAP, + defaultdialect=[95]Ada, + defaultdialect=[68]Algol, + defaultdialect=[ANSI]C, + defaultdialect=[light]Caml, + defaultdialect=[1985]Cobol, + defaultdialect=[ISO]C++, + defaultdialect=[95]Fortran, + defaultdialect=[3.0]Mathematica, + defaultdialect=[OMG]OCL, + defaultdialect=[Standard]Pascal, + defaultdialect=[67]Simula, + defaultdialect=[plain]TeX, + defaultdialect=[97]VRML} +\lstalias[]{TclTk}[tk]{tcl} % \end{macrocode} % \begingroup % \begin{macrocode} @@ -169,12 +129,133 @@ nor under a different one. % \end{macrocode} % \endgroup % +% \begin{macrocode} +%<+lang1>\ProvidesFile{lstlang1} +%<+lang2>\ProvidesFile{lstlang2} +%<+lang3>\ProvidesFile{lstlang3} +%<-config> [2002/07/31 v1.0d listings language file] +% \end{macrocode} +% % % \section{Language drivers} % -% You should read section 'Overture' in the \texttt{listings.dtx} documentation. -% |\lstPre@| and |\lstSCT| are explained there. -% '\texttt{???}' still indicates things I don't know. +% +% \subsection{Abap} +% +% \lstthanks{Knut Lickert}{knut.lickert@gmx.de}{2000/08/01,2001/12/29} added +% support for Abap.\footnote{In this section `I' is Knut Lickert.} +% +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% Abap definition by Knut Lickert +%% +% \end{macrocode} +% +% There are some other new commands in release 6.10. +% They will follow later, but up to now I don't work +% with 6.10. +% +% \begin{macrocode} +%%%%knut>>>>>new +\lst@definelanguage[R/3 6.10]{ABAP}[R/3 4.6C]{ABAP}% + {morekeywords={try,endtry},% + }[keywords,comments,strings] +%%%%knut<<<<}{{$\rightarrow$}}1{=>}{{$\Rightarrow$}}1,%knut + }[keywords,comments,strings] +% \end{macrocode} +% Yes there are also some more releases in R/3 (2.1\ldots), but I +% know them not really. So let's start with R/3~3.1. +% \begin{macrocode} +\lst@definelanguage[R/3 3.1]{ABAP}[R/2 5.0]{ABAP}{}% +% \end{macrocode} +% As I remember all this commands exists in R/2. Many commands are +% new in R/2~5.0 (compared with R/2 4.3). But as I am not using +% R/2~4.3 any more, I start with R/2~5.0. +% \begin{macrocode} +\lst@definelanguage[R/2 5.0]{ABAP}% + {sensitive=f,% + procnamekeys={report,program,form,function},% + morekeywords={*,add,after,alias,analyzer,and,append,area,assign,at,% + authority-check,before,binary,blank,break-point,calendar,call,% + case,change,changing,check,clear,cnt,co,collect,commit,common,% + component,compute,condense,cos,cp,cs,currency-conversion,% + cursor,data,database,dataset,decimals,define,delete,dequeue,% + describe,detail,dialog,directory,div,divide,do,documentation,% + during,dynpro,else,end-of-page,end-of-selection,endat,endcase,% + enddo,endfor,endform,endif,endloop,endmodule,endselect,% + endwhile,enqueue,exceptions,exit,exp,export,exporting,extract,% + field,field-groups,field-symbols,find,for,form,format,free,% + from,function,generating,get,giving,hide,id,if,import,% + importing,in,incl,include,initial,initialization,input,insert,% + interrupt,into,is,language,leave,like,line,lines,line-count, + line-selection,list-processing,load,local,log,logfile,loop,% + margin,mark,mask,memory,menue,message,mod,modify,module,move,% + move-text,multiply,na,new,new-line,new-page,no-gaps,np,ns,% + number,obligatory,occurs,of,on,or,others,output,parameter,% + parameters,parts,perform,pf-status,places,position,process,% + raise,raising,ranges,read,refresh,refresh-dynpro,reject,remote,% + replace,report,reserve,reset,restart,run,screen,scroll,search,% + segments,select,select-options,selection-screen,set,shift,sin,% + single,sqrt,start-of-selection,statement,structure,submit,% + subtract,summary,summing,suppress,system,table,tables,task,% + text,time,to,top-of-page,trace,transaction,transfer,% + transfer-dynpro,translate,type,unpack,update,user-command,% + using,value,when,where,while,window,with,workfile,write,},% + morecomment=[l]",% + morecomment=[f][0]*,% + morestring=[d]'% + }[keywords,comments,strings,procnames] +% \end{macrocode} +% This section for R/2~4.3 is not really maintained. It is just what I remember +% of the past. +% \begin{macrocode} +\lst@definelanguage[R/2 4.3]{ABAP}[R/2 5.0]{ABAP}% + {deletekeywords={function,importing,exporting,changing,exceptions,% + raise,raising}% + }[keywords,comments,strings] +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{ACSL} +% +% This language was provided by \lstthanks{Andreas~Matthias}{amat@kabsi.at} +% {2000/03/21}. I'm sorry for forgetting to add this language for a long time. +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +%% +%% ACSL definition (c) 2000 by Andreas Matthias +%% +\lst@definelanguage{ACSL}[90]{Fortran}% + {morekeywords={algorithm,cinterval,constant,derivative,discrete,% + dynamic,errtag,initial,interval,maxterval,minterval,% + merror,xerror,nsteps,procedural,save,schedule,sort,% + table,terminal,termt,variable},% + sensitive=false,% + morecomment=[l]!% + }[keywords, comments]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup % % % \subsection{Ada} @@ -187,26 +268,36 @@ nor under a different one. % {\copyright} 1991 Addison-Wesley Publishing Company, Inc.; % ISBN 0-201-56539-0. % \end{itemize} +% \lstthanks{Torsten~Neuer}{tneuer@inwise.de}{1998/11/23} added support for +% Ada 95. I changed the definition to reduce the required string memory. % \begingroup % \begin{macrocode} -%<*ada> +%<*lang1> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage{Ada}% - {keywords={abort,abs,accept,access,all,and,array,at,begin,body,% +%% +%% Ada 95 definition (c) Torsten Neuer +%% +\lst@definelanguage[95]{Ada}[83]{Ada}% + {morekeywords={abstract,aliased,protected,requeue,tagged,until}}% +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage[83]{Ada}% + {morekeywords={abort,abs,accept,access,all,and,array,at,begin,body,% case,constant,declare,delay,delta,digits,do,else,elsif,end,entry,% exception,exit,for,function,generic,goto,if,in,is,limited,loop,% mod,new,not,null,of,or,others,out,package,pragma,private,% procedure,raise,range,record,rem,renames,return,reverse,select,% separate,subtype,task,terminate,then,type,use,when,while,with,% xor},% - sensitive=false,% - commentline={--},% - stringizer=[m]{"'}% percent not defined as stringizer so far - }% + sensitive=f,% + morecomment=[l]--,% + morestring=[m]",% percent not defined as stringizer so far + morestring=[m]'% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -229,12 +320,12 @@ nor under a different one. % The definition of Algol 68 doesn't support comments enclosed by \rlap{/}c. % \begingroup % \begin{macrocode} -%<*algol> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[68]{Algol}% +\lst@definelanguage[68]{Algol}% % ??? should 'i' be a keyword - {keywords={abs,and,arg,begin,bin,bits,bool,by,bytes,case,channel,% + {morekeywords={abs,and,arg,begin,bin,bits,bool,by,bytes,case,channel,% char,co,comment,compl,conj,divab,do,down,elem,elif,else,empty,% end,entier,eq,esac,exit,false,fi,file,flex,for,format,from,ge,% goto,gt,heap,if,im,in,int,is,isnt,le,leng,level,loc,long,lt,lwb,% @@ -242,190 +333,525 @@ nor under a different one. overab,par,plusab,plusto,pr,pragmat,prio,proc,re,real,ref,repr,% round,sema,shl,short,shorten,shr,sign,skip,string,struct,then,% timesab,to,true,union,up,upb,void,while},% - sensitive=false,% ??? - singlecomment={\#}{\#},% + sensitive=f,% ??? + morecomment=[s]{\#}{\#},% keywordcomment={co,comment}% - }% + }[keywords,comments,keywordcomments]% % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[60]{Algol}% - {keywords={array,begin,Boolean,code,comment,div,do,else,end,false,% - for,goto,if,integer,label,own,power,procedure,real,step,string,% - switch,then,true,until,value,while},% - sensitive=false,% ??? - doublekeywordcommentsemicolon={end}{else,end}{comment}% - }% -% +\lst@definelanguage[60]{Algol}% + {morekeywords={array,begin,Boolean,code,comment,div,do,else,end,% + false,for,goto,if,integer,label,own,power,procedure,real,step,% + string,switch,then,true,until,value,while},% + sensitive=f,% ??? + keywordcommentsemicolon={end}{else,end}{comment}% + }[keywords,keywordcomments]% +% % \end{macrocode} % \endgroup % % -% \subsection{C, C++ and Objective-C} +% \subsection{Assembler} +% +% Credits go to \lstthanks{Andrew Zabolotny}{zap@cobra.ru}{2002/07/05}. +% \begingroup +% \begin{macrocode} +%<*lang3> +%% +%% x86masm definition (c) 2002 Andrew Zabolotny +%% +\lst@definelanguage[x86masm]{Assembler}% + {morekeywords={al,ah,ax,eax,bl,bh,bx,ebx,cl,ch,cx,ecx,dl,dh,dx,edx,% + si,esi,di,edi,bp,ebp,sp,esp,cs,ds,es,ss,fs,gs,cr0,cr1,cr2,cr3,% + db0,db1,db2,db3,db4,db5,db6,db7,tr0,tr1,tr2,tr3,tr4,tr5,tr6,tr7,% + st,aaa,aad,aam,aas,adc,add,and,arpl,bound,bsf,bsr,bswap,bt,btc,% + btr,bts,call,cbw,cdq,clc,cld,cli,clts,cmc,cmp,cmps,cmpsb,cmpsw,% + cmpsd,cmpxchg,cwd,cwde,daa,das,dec,div,enter,hlt,idiv,imul,in,% + inc,ins,int,into,invd,invlpg,iret,ja,jae,jb,jbe,jc,jcxz,jecxz,% + je,jg,jge,jl,jle,jna,jnae,jnb,jnbe,jnc,jne,jng,jnge,jnl,jnle,% + jno,jnp,jns,jnz,jo,jp,jpe,jpo,js,jz,jmp,lahf,lar,lea,leave,lgdt,% + lidt,lldt,lmsw,lock,lods,lodsb,lodsw,lodsd,loop,loopz,loopnz,% + loope,loopne,lds,les,lfs,lgs,lss,lsl,ltr,mov,movs,movsb,movsw,% + movsd,movsx,movzx,mul,neg,nop,not,or,out,outs,pop,popa,popad,% + popf,popfd,push,pusha,pushad,pushf,pushfd,rcl,rcr,rep,repe,% + repne,repz,repnz,ret,retf,rol,ror,sahf,sal,sar,sbb,scas,seta,% + setae,setb,setbe,setc,sete,setg,setge,setl,setle,setna,setnae,% + setnb,setnbe,setnc,setne,setng,setnge,setnl,setnle,setno,setnp,% + setns,setnz,seto,setp,setpe,setpo,sets,setz,sgdt,shl,shld,shr,% + shrd,sidt,sldt,smsw,stc,std,sti,stos,stosb,stosw,stosd,str,sub,% + test,verr,verw,wait,wbinvd,xadd,xchg,xlatb,xor,fabs,fadd,fbld,% + fbstp,fchs,fclex,fcom,fcos,fdecstp,fdiv,fdivr,ffree,fiadd,ficom,% + fidiv,fidivr,fild,fimul,fincstp,finit,fist,fisub,fisubr,fld,fld1,% + fldl2e,fldl2t,fldlg2,fldln2,fldpi,fldz,fldcw,fldenv,fmul,fnop,% + fpatan,fprem,fprem1,fptan,frndint,frstor,fsave,fscale,fsetpm,% + fsin,fsincos,fsqrt,fst,fstcw,fstenv,fstsw,fsub,fsubr,ftst,fucom,% + fwait,fxam,fxch,fxtract,fyl2x,fyl2xp1,f2xm1},% + morekeywords=[2]{.align,.alpha,assume,byte,code,comm,comment,.const,% + .cref,.data,.data?,db,dd,df,dosseg,dq,dt,dw,dword,else,end,endif,% + endm,endp,ends,eq,equ,.err,.err1,.err2,.errb,.errdef,.errdif,% + .erre,.erridn,.errnb,.errndef,.errnz,event,exitm,extrn,far,% + .fardata,.fardata?,fword,ge,group,gt,high,if,if1,if2,ifb,ifdef,% + ifdif,ife,ifidn,ifnb,ifndef,include,includelib,irp,irpc,label,% + .lall,le,length,.lfcond,.list,local,low,lt,macro,mask,mod,.model,% + name,ne,near,offset,org,out,page,proc,ptr,public,purge,qword,.% + radix,record,rept,.sall,seg,segment,.seq,.sfcond,short,size,% + .stack,struc,subttl,tbyte,.tfcond,this,title,type,.type,width,% + word,.xall,.xcref,.xlist},% + alsoletter=.,alsodigit=?,% + sensitive=f,% + morestring=[b]",% + morestring=[b]',% + morecomment=[l];% + }[directives,keywords,comments,strings] +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Basic} +% +% Credits go to \lstthanks{Robert Frank}{rf7@ukc.ac.uk}{2002/07/05}. +% \begingroup +% \begin{macrocode} +%<*lang1> +%% +%% Visual Basic definition (c) 2002 Robert Frank +%% +\lst@definelanguage[Visual]{Basic} + {morekeywords={Abs,Array,Asc,AscB,AscW,Atn,Avg,CBool,CByte,CCur,% + CDate,CDbl,Cdec,Choose,Chr,ChrB,ChrW,CInt,CLng,Command,Cos,% + Count,CreateObject,CSng,CStr,CurDir,CVar,CVDate,CVErr,Date,% + DateAdd,DateDiff,DatePart,DateSerial,DateValue,Day,DDB,Dir,% + DoEvents,Environ,EOF,Error,Exp,FileAttr,FileDateTime,FileLen,% + Fix,Format,FreeFile,FV,GetAllStrings,GetAttr,% + GetAutoServerSettings,GetObject,GetSetting,Hex,Hour,IIf,% + IMEStatus,Input,InputB,InputBox,InStr,InstB,Int,Integer,IPmt,% + IsArray,IsDate,IsEmpty,IsError,IsMissing,IsNull,IsNumeric,% + IsObject,LBound,LCase,Left,LeftB,Len,LenB,LoadPicture,Loc,LOF,% + Log,Ltrim,Max,Mid,MidB,Min,Minute,MIRR,Month,MsgBox,Now,NPer,% + NPV,Oct,Partition,Pmt,PPmt,PV,QBColor,Rate,RGB,Right,RightB,Rnd,% + Rtrim,Second,Seek,Sgn,Shell,Sin,SLN,Space,Spc,Sqr,StDev,StDevP,% + Str,StrComp,StrConv,String,Switch,Sum,SYD,Tab,Tan,Time,Timer,% + TimeSerial,TimeValue,Trim,TypeName,UBound,Ucase,Val,Var,VarP,% + VarType,Weekday,Year},% functions + morekeywords=[2]{Accept,Activate,Add,AddCustom,AddFile,AddFromFile,% + AddFromTemplate,AddItem,AddNew,AddToAddInToolbar,% + AddToolboxProgID,Append,AppendChunk,Arrange,Assert,AsyncRead,% + BatchUpdate,BeginTrans,Bind,Cancel,CancelAsyncRead,CancelBatch,% + CancelUpdate,CanPropertyChange,CaptureImage,CellText,CellValue,% + Circle,Clear,ClearFields,ClearSel,ClearSelCols,Clone,Close,Cls,% + ColContaining,ColumnSize,CommitTrans,CompactDatabase,Compose,% + Connect,Copy,CopyQueryDef,CreateDatabase,CreateDragImage,% + CreateEmbed,CreateField,CreateGroup,CreateIndex,CreateLink,% + CreatePreparedStatement,CreatePropery,CreateQuery,% + CreateQueryDef,CreateRelation,CreateTableDef,CreateUser,% + CreateWorkspace,Customize,Delete,DeleteColumnLabels,% + DeleteColumns,DeleteRowLabels,DeleteRows,DoVerb,Drag,Draw,Edit,% + EditCopy,EditPaste,EndDoc,EnsureVisible,EstablishConnection,% + Execute,ExtractIcon,Fetch,FetchVerbs,Files,FillCache,Find,% + FindFirst,FindItem,FindLast,FindNext,FindPrevious,Forward,% + GetBookmark,GetChunk,GetClipString,GetData,GetFirstVisible,% + GetFormat,GetHeader,GetLineFromChar,GetNumTicks,GetRows,% + GetSelectedPart,GetText,GetVisibleCount,GoBack,GoForward,Hide,% + HitTest,HoldFields,Idle,InitializeLabels,InsertColumnLabels,% + InsertColumns,InsertObjDlg,InsertRowLabels,InsertRows,Item,% + KillDoc,Layout,Line,LinkExecute,LinkPoke,LinkRequest,LinkSend,% + Listen,LoadFile,LoadResData,LoadResPicture,LoadResString,% + LogEvent,MakeCompileFile,MakeReplica,MoreResults,Move,MoveData,% + MoveFirst,MoveLast,MoveNext,MovePrevious,NavigateTo,NewPage,% + NewPassword,NextRecordset,OLEDrag,OnAddinsUpdate,OnConnection,% + OnDisconnection,OnStartupComplete,Open,OpenConnection,% + OpenDatabase,OpenQueryDef,OpenRecordset,OpenResultset,OpenURL,% + Overlay,PaintPicture,Paste,PastSpecialDlg,PeekData,Play,Point,% + PopulatePartial,PopupMenu,Print,PrintForm,PropertyChanged,Pset,% + Quit,Raise,RandomDataFill,RandomFillColumns,RandomFillRows,% + rdoCreateEnvironment,rdoRegisterDataSource,ReadFromFile,% + ReadProperty,Rebind,ReFill,Refresh,RefreshLink,RegisterDatabase,% + Reload,Remove,RemoveAddInFromToolbar,RemoveItem,Render,% + RepairDatabase,Reply,ReplyAll,Requery,ResetCustom,% + ResetCustomLabel,ResolveName,RestoreToolbar,Resync,Rollback,% + RollbackTrans,RowBookmark,RowContaining,RowTop,Save,SaveAs,% + SaveFile,SaveToFile,SaveToolbar,SaveToOle1File,Scale,ScaleX,% + ScaleY,Scroll,Select,SelectAll,SelectPart,SelPrint,Send,% + SendData,Set,SetAutoServerSettings,SetData,SetFocus,SetOption,% + SetSize,SetText,SetViewport,Show,ShowColor,ShowFont,ShowHelp,% + ShowOpen,ShowPrinter,ShowSave,ShowWhatsThis,SignOff,SignOn,Size,% + Span,SplitContaining,StartLabelEdit,StartLogging,Stop,% + Synchronize,TextHeight,TextWidth,ToDefaults,TwipsToChartPart,% + TypeByChartType,Update,UpdateControls,UpdateRecord,UpdateRow,% + Upto,WhatsThisMode,WriteProperty,ZOrder},% methods + morekeywords=[3]{AccessKeyPress,AfterAddFile,AfterChangeFileName,% + AfterCloseFile,AfterColEdit,AfterColUpdate,AfterDelete,% + AfterInsert,AfterLabelEdit,AfterRemoveFile,AfterUpdate,% + AfterWriteFile,AmbienChanged,ApplyChanges,Associate,% + AsyncReadComplete,AxisActivated,AxisLabelActivated,% + AxisLabelSelected,AxisLabelUpdated,AxisSelected,% + AxisTitleActivated,AxisTitleSelected,AxisTitleUpdated,% + AxisUpdated,BeforeClick,BeforeColEdit,BeforeColUpdate,% + BeforeConnect,BeforeDelete,BeforeInsert,BeforeLabelEdit,% + BeforeLoadFile,BeforeUpdate,ButtonClick,ButtonCompleted,% + ButtonGotFocus,ButtonLostFocus,Change,ChartActivated,% + ChartSelected,ChartUpdated,Click,ColEdit,Collapse,ColResize,% + ColumnClick,Compare,ConfigChageCancelled,ConfigChanged,% + ConnectionRequest,DataArrival,DataChanged,DataUpdated,DblClick,% + Deactivate,DeviceArrival,DeviceOtherEvent,DeviceQueryRemove,% + DeviceQueryRemoveFailed,DeviceRemoveComplete,DeviceRemovePending,% + DevModeChange,Disconnect,DisplayChanged,Dissociate,% + DoGetNewFileName,Done,DonePainting,DownClick,DragDrop,DragOver,% + DropDown,EditProperty,EnterCell,EnterFocus,Event,ExitFocus,% + Expand,FootnoteActivated,FootnoteSelected,FootnoteUpdated,% + GotFocus,HeadClick,InfoMessage,Initialize,IniProperties,% + ItemActivated,ItemAdded,ItemCheck,ItemClick,ItemReloaded,% + ItemRemoved,ItemRenamed,ItemSeletected,KeyDown,KeyPress,KeyUp,% + LeaveCell,LegendActivated,LegendSelected,LegendUpdated,% + LinkClose,LinkError,LinkNotify,LinkOpen,Load,LostFocus,% + MouseDown,MouseMove,MouseUp,NodeClick,ObjectMove,% + OLECompleteDrag,OLEDragDrop,OLEDragOver,OLEGiveFeedback,% + OLESetData,OLEStartDrag,OnAddNew,OnComm,Paint,PanelClick,% + PanelDblClick,PathChange,PatternChange,PlotActivated,% + PlotSelected,PlotUpdated,PointActivated,PointLabelActivated,% + PointLabelSelected,PointLabelUpdated,PointSelected,% + PointUpdated,PowerQuerySuspend,PowerResume,PowerStatusChanged,% + PowerSuspend,QueryChangeConfig,QueryComplete,QueryCompleted,% + QueryTimeout,QueryUnload,ReadProperties,Reposition,% + RequestChangeFileName,RequestWriteFile,Resize,ResultsChanged,% + RowColChange,RowCurrencyChange,RowResize,RowStatusChanged,% + SelChange,SelectionChanged,SendComplete,SendProgress,% + SeriesActivated,SeriesSelected,SeriesUpdated,SettingChanged,% + SplitChange,StateChanged,StatusUpdate,SysColorsChanged,% + Terminate,TimeChanged,TitleActivated,TitleSelected,% + TitleActivated,UnboundAddData,UnboundDeleteRow,% + UnboundGetRelativeBookmark,UnboundReadData,UnboundWriteData,% + Unload,UpClick,Updated,Validate,ValidationError,WillAssociate,% + WillChangeData,WillDissociate,WillExecute,WillUpdateRows,% + WithEvents,WriteProperties},% VB-events + morekeywords=[4]{AppActivate,Base,Beep,Call,Case,ChDir,ChDrive,% + Const,Declare,DefBool,DefByte,DefCur,DefDate,DefDbl,DefDec,% + DefInt,DefLng,DefObj,DefSng,DefStr,Deftype,DefVar,DeleteSetting,% + Dim,Do,Else,ElseIf,End,Enum,Erase,Event,Exit,Explicit,FileCopy,% + For,ForEach,Friend,Function,Get,GoSub,GoTo,If,Implements,Kill,% + Let,LineInput,Lock,Lset,MkDir,Name,Next,OnError,On,Option,% + Private,Property,Public,Put,RaiseEvent,Randomize,ReDim,Rem,% + Reset,Resume,Return,RmDir,Rset,SavePicture,SaveSetting,% + SendKeys,SetAttr,Static,Sub,Then,Type,Unlock,Wend,While,Width,% + With,Write},% statements + sensitive=false, + keywordcomment=rem,% + MoreSelectCharTable=\def\lst@BeginKC@{% chmod + \lst@ResetToken + \lst@BeginComment\lst@GPmode{{\lst@commentstyle}% + \lst@Lmodetrue\lst@modetrue}\@empty}% + morecomment=[l]{'}, + morecomment=[s]{/*}{*/}, + morestring=[b]", + }[keywords,comments,strings,keywordcomments] +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Clean} % +% Thanks to \lstthanks{Jos\'e~Romildo~Malaquias}{romildo@iceb.ufop.br}{2000/08/08}. +% \lsthelper{Markus~Pahlow}{pahlowm@mar.dfo-mpo.gc.ca}{2001/10/12}{missing comma} +% found a missing comma % \begingroup % \begin{macrocode} -%<*c> -% \end{macrocode} -% \begin{macrocode} -\lstdefinelanguage[ANSI]{C}% - {keywords={auto,break,case,char,const,continue,default,do,double,% - else,enum,extern,float,for,goto,if,int,long,register,return,% - short,signed,sizeof,static,struct,switch,typedef,union,unsigned,% - void,volatile,while},% - sensitive=true,% - singlecomment={/*}{*/},% - stringizer=[b]{"},% - cdirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% - include,pragma,undef,warning}% - }% -% \end{macrocode} -% \begin{macrocode} -% +%<*lang3> +%% +%% Clean definition (c) 1999 Jos\'e Romildo Malaquias +%% +%% +%% Clean 1.3 : some standard functional language: pure, lazy, +%% polymorphic type system, modules, type classes, +%% garbage collection, functions as first class citizens +%% +\lst@definelanguage{Clean}% + {otherkeywords={:,::,=,:==,=:,=>,->,<-,<-:,\{,\},\{|,|\},\#,\#!,|,\&,% + [,],!,.,\\\\,;,_},% + morekeywords={from,definition,implementation,import,module,system,% + case,code,if,in,let,let!,of,where,with,infix,infixl,infixr},% + morendkeywords={True,False,Start,Int,Real,Char,Bool,String,World,% + File,ProcId},% + sensitive,% + morecomment=[l]//,% missing comma: Markus Pahlow + morecomment=[n]{/*}{*/},% + morestring=[b]"% + }[keywords,comments,strings]% +% % \end{macrocode} % \endgroup % +% +% \subsection{Corba IDL} +% +% This language definition is due to \lstthanks{Jens~T.~Berger~Thielemann} +% {jensthi@ifi.uio.no}{1999/11/28}. % \begingroup % \begin{macrocode} -%<*c++> +%<*lang2> +%% +%% Corba IDL definition (c) 1999 Jens T. Berger Thielemann +%% +%% +\lst@definelanguage[CORBA]{IDL}% + {morekeywords={any,attribute,boolean,case,char,const,context,default,% + double,enum,exception,fixed,float,in,inout,interface,long,module,% + native,Object,octet,oneway,out,raises,readonly,sequence,short,% + string,struct,switch,typedef,union,unsigned,void,wchar,wstring,% + FALSE,TRUE},% + sensitive,% + moredirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% + include,pragma,undef,warning},% + morecomment=[l]//,% + morecomment=[s]{/*}{*/},% + morestring=[b]"% + }[keywords,comments,strings]% +% % \end{macrocode} +% \endgroup +% +% +% \subsection{C, C++, et al} +% +% \begingroup % \begin{macrocode} -\lstdefinedrvlanguage[ANSI]{C++}% - {language=[ANSI]C,% - morekeywords={asm,bad_cast,bad_typeid,bool,catch,class,const_cast,% - delete,dynamic_cast,false,friend,inline,namespace,new,operator,% - private,protected,public,reinterpret_cast,static_cast,template,% - this,throw,true,try,type_info,typeid,using,virtual,xalloc,% - __multiple_inheritance,__single_inheritance,% - __virtual_inheritance},% - commentline={//}% +%<*lang1> +% \end{macrocode} +% For compatibility the `ANSI' language is defined in terms of ISO. +% \begin{macrocode} +\lst@definelanguage[ANSI]{C++}[ISO]{C++}{}% +% \end{macrocode} +% \lstthanks{Michael Piefel}{piefel@informatik.hu-berlin.de}{2001/11/21} +% suggested some more changes and added GNU C++. +% \begin{macrocode} +\lst@definelanguage[GNU]{C++}[ISO]{C++}% + {morekeywords={__attribute__,__extension__,__restrict,__restrict__,% + typeof,__typeof__},% }% % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[Visual]{C++}% - {language=[ANSI]C++,% - morekeywords={__asm,__based,__cdecl,__declspec,dllexport,% +\lst@definelanguage[Visual]{C++}[ISO]{C++}% + {morekeywords={__asm,__based,__cdecl,__declspec,dllexport,% dllimport,__except,__fastcall,__finally,__inline,__int8,__int16,% __int32,__int64,naked,__stdcall,thread,__try,__leave},% }% % \end{macrocode} % \begin{macrocode} -% -% \end{macrocode} -% \endgroup -% -% Objective-C is due to \lsthelper{Detlev Dr\"oge}{droege@informatik.uni-koblenz.de}{1997/11/04}{Objective-C}. -% I've only done some conversion. -% \begingroup -% \begin{macrocode} -%<*objective-c> -% \end{macrocode} -% \begin{macrocode} -%% (c) 1997 Detlev Droege -\lstdefinedrvlanguage[Objective]{C}% - {language=[ANSI]C,% - morekeywords={bycopy,id,in,inout,oneway,out,self,super,% - @class,@defs,@encode,@end,@implementation,@interface,@private,% - @protected,@protocol,@public,@selector},% - commentline={//},% - cdirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% - include,import,pragma,undef,warning}% +\lst@definelanguage[ISO]{C++}[ANSI]{C}% + {morekeywords={and,and_eq,asm,bad_cast,bad_typeid,bitand,bitor,bool,% + catch,class,compl,const_cast,delete,dynamic_cast,explicit,export,% + false,friend,inline,mutable,namespace,new,not,not_eq,operator,or,% + or_eq,private,protected,public,reinterpret_cast,static_cast,% + template,this,throw,true,try,typeid,type_info,typename,using,% + virtual,wchar_t,xor,xor_eq},% }% % \end{macrocode} % \begin{macrocode} -% +% +% \end{macrocode} +% \endgroup +% +% Objective-C is due to \lstthanks{Detlev~Dr\"oge} +%{droege@informatik.uni-koblenz.de}{1997/11/04}. +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +%% +%% Objective-C definition (c) 1997 Detlev Droege +%% +%% +\lst@definelanguage[Objective]{C}[ANSI]{C} + {morekeywords={bycopy,id,in,inout,oneway,out,self,super,% + @class,@defs,@encode,@end,@implementation,@interface,@private,% + @protected,@protocol,@public,@selector},% + moredirectives={import}% + }% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage[ANSI]{C}% + {morekeywords={auto,break,case,char,const,continue,default,do,double,% + else,enum,extern,float,for,goto,if,int,long,register,return,% + short,signed,sizeof,static,struct,switch,typedef,union,unsigned,% + void,volatile,while},% + sensitive,% + morecomment=[s]{/*}{*/},% + morecomment=[l]//,% nonstandard + morestring=[b]",% + morestring=[b]',% + moredirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% + include,pragma,undef,warning}% + }[keywords,comments,strings,directives]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% Thanks go to \lstthanks{Martin~Brodbeck}{Martin.Brodbeck@gmx.de}{2002/03/17}. +% \begin{macrocode} +%% +%% C-Sharp definition (c) 2002 Martin Brodbeck +%% +\lst@definelanguage[Sharp]{C}% + {morekeywords={abstract,base,bool,break,byte,case,catch,char,checked,% + class,const,continue,decimal,default,delegate,do,double,else,% + enum,event,explicit,extern,false,finally,fixed,float,for,foreach,% + goto,if,implicit,in,int,interface,internal,is,lock,long,% + namespace,new,null,object,operator,out,override,params,private,% + protected,public,readonly,ref,return,sbyte,sealed,short,sizeof,% + static,string,struct,switch,this,throw,true,try,typeof,uint,% + ulong,unchecked,unsafe,ushort,using,virtual,void,while},% + sensitive,% + morecomment=[s]{/*}{*/},% + morecomment=[l]//,% + morestring=[b]" + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Caml and Objective Caml} +% +% \lstthanks{Patrick~Cousot}{Patrick.Cousot@wanadoo.fr}{1999/01/09} mailed me +% the definition. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% (Objective) Caml definition (c) 1999 Patrick Cousot +%% +%% +%% Objective CAML and Caml light are freely available, together with a +%% reference manual, at URL ftp.inria.fr/lang/caml-light for the Unix, +%% Windows and Macintosh OS operating systems. +%% +\lst@definelanguage[Objective]{Caml}[light]{Caml} + {deletekeywords={not,prefix,value,where},% + morekeywords={assert,asr,class,closed,constraint,external,false,% + functor,include,inherit,land,lazy,lor,lsl,lsr,lxor,method,mod,% + module,new,open,parser,private,sig,struct,true,val,virtual,when},% + }% +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage[light]{Caml} + {morekeywords={and,as,begin,do,done,downto,else,end,exception,for,% + fun,function,if,in,let,match,mutable,not,of,or,prefix,rec,then,% + to,try,type,value,where,while,with},% + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[b]",% + moredirectives={open,close,include}% + }[keywords,comments,strings,directives]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{Cobol} % -% Keywords are not marked if their names are broken by EOL, for example DEBUG- CONTENTS. -% Sometimes portions of a string are not printed as a string. -% This happens if the double quote is not doubled to insert a quote, e.g.\ |""bad" cobol"| won't be printed correctly. +% Keywords are not marked if their names are broken by EOL, for example DEBUG- +% CONTENTS. Sometimes portions of a string are not printed as a string. +% This happens if the double quote is not doubled to insert a quote, +% e.g.~|""bad" cobol"| won't be printed correctly. % \begingroup % \begin{macrocode} -%<*cobol> +%<*lang2> % \end{macrocode} -% We store some keywords: % \begin{macrocode} -\lststorekeywords\lstkeys@cobol{ACCEPT,ACCESS,ADD,ADVANCING,AFTER,ALL,% - ALPHABETIC,ALSO,ALTER,ALTERNATE,AND,ARE,AREA,AREAS,ASCENDING,% - ASSIGN,AT,AUTHOR,BEFORE,BINARY,BLANK,BLOCK,BOTTOM,BY,CALL,CANCEL,% - CD,CF,CH,CHARACTER,CHARACTERS,CLOCK-UNITS,CLOSE,COBOL,CODE,% - CODE-SET,COLLATING,COLUMN,COMMA,COMMUNICATION,COMP,COMPUTE,% - CONFIGURATION,CONTAINS,CONTROL,CONTROLS,CONVERTING,COPY,CORR,% - CORRESPONDING,COUNT,CURRENCY,DATA,DATE,DATE-COMPILED,DATE-WRITTEN,% - DAY,DE,DEBUG-CONTENTS,DEGUB-ITEM,DEBUG-LINE,DEBUG-NAME,DEBUG-SUB1,% - DEBUG-SUB2,DEBUG-SUB3,DEBUGGING,DECIMAL-POINT,DECLARATIVES,DELETE,% - DELIMITED,DELIMITER,DEPENDING,DESCENDING,DESTINATION,DETAIL,% - DISABLE,DISPLAY,DIVIDE,DIVISION,DOWN,DUPLICATES,DYNAMIC,EGI,ELSE,% - EMI,ENABLE,END,END-OF-PAGE,ENTER,ENVIRONMENT,EOP,EQUAL,ERROR,ESI,% - EVERY,EXCEPTION,EXIT,EXTEND,FD,FILE,FILE-CONTROL,FILLER,FINAL,% - FIRST,FOOTING,FOR,FROM,GENERATE,GIVING,GO,GREATER,GROUP,HEADING,% - HIGH-VALUE,HIGH-VALUES,I-O,I-O-CONTROL,IDENTIFICATION,IF,IN,INDEX,% - INDEXED,INDICATE,INITIAL,INITIATE,INPUT,INPUT-OUTPUT,INSPECT,% - INSTALLATION,INTO,INVALID,IS,JUST,JUSTIFIED,KEY,LABEL,LAST,LEADING,% - LEFT,LENGTH,LESS,LIMIT,LIMITS,LINAGE,LINAGE-COUNTER,LINE,% - LINE-COUNTER,LINES,LINKAGE,LOCK,LOW-VALUE,LOW-VALUES,MEMORY,MERGE,% - MESSAGE,MODE,MODULES,MOVE,MULTIPLE,MULTIPLY,NATIVE,NEGATIVE,NEXT,% - NO,NOT,NUMBER,NUMERIC,OBJECT-COMPUTER,OCCURS,OF,OFF,OMITTED,ON,% - OPEN,OPTIONAL,OR,ORGANIZATION,OUTPUT,OVERFLOW,PAGE,PAGE-COUNTER,% - PERFORM,PF,PH,PIC,PICTURE,PLUS,POINTER,POSITION,PRINTING,POSITIVE,% - PRINTING,PROCEDURE,PROCEDURES,PROCEED,PROGRAM,PROGRAM-ID,QUEUE,% - QUOTE,QUOTES,RANDOM,RD,READ,RECEIVE,RECORD,RECORDING,RECORDS,% - REDEFINES,REEL,REFERENCES,RELATIVE,RELEASE,REMAINDER,REMOVAL,% - RENAMES,REPLACING,REPORT,REPORTING,REPORTS,RERUN,RESERVE,RESET,% - RETURN,REVERSED,REWIND,REWRITE,RF,RH,RIGHT,ROUNDED,RUN,SAME,SD,% - SEARCH,SECTION,SECURITY,SEGMENT,SEGMENT-LIMIT,SELECT,SEND,SENTENCE,% - SEPARATE,SEQUENCE,SEQUENTIAL,SET,SIGN,SIZE,SORT,SORT-MERGE,SOURCE,% - SOURCE-COMPUTER,SPACE,SPACES,SPECIAL-NAMES,STANDARD,START,STATUS,% - STOP,STRING,SUB-QUEUE-1,SUB-QUEUE-2,SUB-QUEUE-3,SUBTRACT,SUM,% - SYMBOLIC,SYNC,SYNCHRONIZED,TABLE,TALLYING,TAPE,TERMINAL,TERMINATE,% - TEXT,THAN,THROUGH,THRU,TIME,TIMES,TO,TOP,TRAILING,TYPE,UNIT,% - UNSTRING,UNTIL,UP,UPON,USAGE,USE,USING,VALUE,VALUES,VARYING,WHEN,% - WITH,WORDS,WORKING-STORAGE,WRITE,ZERO,ZEROES,ZEROS}% -\lststorekeywords\lstkeys@cobol@eightyfive{ALPHABET,ALPHABETIC-LOWER,% - ALPHABETIC-UPPER,ALPHANUMERIC,ALPHANUMERIC-EDITED,ANY,CLASS,COMMON,% - CONTENT,CONTINUE,DAY-OF-WEEK,END-ADD,END-CALL,END-COMPUTE,% - END-DELETE,END-DIVIDE,END-EVALUATE,END-IF,END-MULTIPLY,END-PERFORM,% - END-READ,END-RECEIVE,END-RETURN,END-REWRITE,END-SEARCH,END-START,% - END-STRING,END-SUBTRACT,END-UNSTRING,END-WRITE,EVALUATE,EXTERNAL,% - FALSE,GLOBAL,INITIALIZE,NUMERIC-EDITED,ORDER,OTHER,PACKED-DECIMAL,% - PADDING,PURGE,REFERENCE,RELOAD,REPLACE,STANDARD-1,STANDARD-2,TEST,% - THEN,TRUE}% -% \end{macrocode} -% Now define the languages: -% \begin{macrocode} -\lstdefinedrvlanguage[1985]{Cobol}% - {keywords={\lstkeys@cobol,\lstkeys@cobol@eightyfive},% - sensitive=false,% ??? - fixedcommentline=[6]{*},% - stringizer=[d]{"}% ??? doubled +\lst@definelanguage[ibm]{Cobol}[1985]{Cobol}% + {morekeywords={ADDRESS,BEGINNING,COMP-3,COMP-4,COMPUTATIONAL,% + COMPUTATIONAL-3,COMPUTATIONAL-4,DISPLAY-1,EGCS,EJECT,ENDING,% + ENTRY,GOBACK,ID,MORE-LABELS,NULL,NULLS,PASSWORD,RECORDING,% + RETURN-CODE,SERVICE,SKIP1,SKIP2,SKIP3,SORT-CONTROL,SORT-RETURN,% + SUPPRESS,TITLE,WHEN-COMPILED},% }% % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[1974]{Cobol}% - {keywords={\lstkeys@cobol},% - sensitive=false,% ??? - fixedcommentline=[6]{*},% - stringizer=[d]{"}% ??? doubled +\lst@definelanguage[1985]{Cobol}[1974]{Cobol}% + {morekeywords={ALPHABET,ALPHABETIC-LOWER,ALPHABETIC-UPPER,% + ALPHANUMERIC,ALPHANUMERIC-EDITED,ANY,CLASS,COMMON,CONTENT,% + CONTINUE,DAY-OF-WEEK,END-ADD,END-CALL,END-COMPUTE,END-DELETE,% + END-DIVIDE,END-EVALUATE,END-IF,END-MULTIPLY,END-PERFORM,END-READ,% + END-RECEIVE,END-RETURN,END-REWRITE,END-SEARCH,END-START,% + END-STRING,END-SUBTRACT,END-UNSTRING,END-WRITE,EVALUATE,EXTERNAL,% + FALSE,GLOBAL,INITIALIZE,NUMERIC-EDITED,ORDER,OTHER,% + PACKED-DECIMAL,PADDING,PURGE,REFERENCE,RELOAD,REPLACE,STANDARD-1,% + STANDARD-2,TEST,THEN,TRUE},% }% % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[ibm]{Cobol}% - {keywords={\lstkeys@cobol,\lstkeys@cobol@eightyfive,% - ADDRESS,BEGINNING,COMP-3,COMP-4,COMPUTATIONAL,COMPUTATIONAL-3,% - COMPUTATIONAL-4,DISPLAY-1,EGCS,EJECT,ENDING,ENTRY,GOBACK,ID,% - MORE-LABELS,NULL,NULLS,PASSWORD,RECORDING,RETURN-CODE,SERVICE,% - SKIP1,SKIP2,SKIP3,SORT-CONTROL,SORT-RETURN,SUPPRESS,TITLE,% - WHEN-COMPILED},% - sensitive=false,% ??? - fixedcommentline=[6]{*},% - stringizer=[d]{"}% ??? doubled - }% -% \end{macrocode} +\lst@definelanguage[1974]{Cobol}% + {morekeywords={ACCEPT,ACCESS,ADD,ADVANCING,AFTER,ALL,ALPHABETIC,ALSO,% + ALTER,ALTERNATE,AND,ARE,AREA,AREAS,ASCENDING,ASSIGN,AT,AUTHOR,% + BEFORE,BINARY,BLANK,BLOCK,BOTTOM,BY,CALL,CANCEL,CD,CF,CH,% + CHARACTER,CHARACTERS,CLOCK-UNITS,CLOSE,COBOL,CODE,CODE-SET,% + COLLATING,COLUMN,COMMA,COMMUNICATION,COMP,COMPUTE,CONFIGURATION,% + CONTAINS,CONTROL,CONTROLS,CONVERTING,COPY,CORR,CORRESPONDING,% + COUNT,CURRENCY,DATA,DATE,DATE-COMPILED,DATE-WRITTEN,DAY,DE,% + DEBUG-CONTENTS,DEGUB-ITEM,DEBUG-LINE,DEBUG-NAME,DEBUG-SUB1,% + DEBUG-SUB2,DEBUG-SUB3,DEBUGGING,DECIMAL-POINT,DECLARATIVES,% + DELETE,DELIMITED,DELIMITER,DEPENDING,DESCENDING,DESTINATION,% + DETAIL,DISABLE,DISPLAY,DIVIDE,DIVISION,DOWN,DUPLICATES,DYNAMIC,% + EGI,ELSE,EMI,ENABLE,END,END-OF-PAGE,ENTER,ENVIRONMENT,EOP,EQUAL,% + ERROR,ESI,EVERY,EXCEPTION,EXIT,EXTEND,FD,FILE,FILE-CONTROL,% + FILLER,FINAL,FIRST,FOOTING,FOR,FROM,GENERATE,GIVING,GO,GREATER,% + GROUP,HEADING,HIGH-VALUE,HIGH-VALUES,I-O,I-O-CONTROL,% + IDENTIFICATION,IF,IN,INDEX,INDEXED,INDICATE,INITIAL,INITIATE,% + INPUT,INPUT-OUTPUT,INSPECT,INSTALLATION,INTO,INVALID,IS,JUST,% + JUSTIFIED,KEY,LABEL,LAST,LEADING,LEFT,LENGTH,LESS,LIMIT,LIMITS,% + LINAGE,LINAGE-COUNTER,LINE,LINE-COUNTER,LINES,LINKAGE,LOCK,% + LOW-VALUE,LOW-VALUES,MEMORY,MERGE,MESSAGE,MODE,MODULES,MOVE,% + MULTIPLE,MULTIPLY,NATIVE,NEGATIVE,NEXT,NO,NOT,NUMBER,NUMERIC,% + OBJECT-COMPUTER,OCCURS,OF,OFF,OMITTED,ON,OPEN,OPTIONAL,OR,% + ORGANIZATION,OUTPUT,OVERFLOW,PAGE,PAGE-COUNTER,PERFORM,PF,PH,PIC,% + PICTURE,PLUS,POINTER,POSITION,PRINTING,POSITIVE,PRINTING,% + PROCEDURE,PROCEDURES,PROCEED,PROGRAM,PROGRAM-ID,QUEUE,QUOTE,% + QUOTES,RANDOM,RD,READ,RECEIVE,RECORD,RECORDING,RECORDS,REDEFINES,% + REEL,REFERENCES,RELATIVE,RELEASE,REMAINDER,REMOVAL,RENAMES,% + REPLACING,REPORT,REPORTING,REPORTS,RERUN,RESERVE,RESET,RETURN,% + REVERSED,REWIND,REWRITE,RF,RH,RIGHT,ROUNDED,RUN,SAME,SD,SEARCH,% + SECTION,SECURITY,SEGMENT,SEGMENT-LIMIT,SELECT,SEND,SENTENCE,% + SEPARATE,SEQUENCE,SEQUENTIAL,SET,SIGN,SIZE,SORT,SORT-MERGE,% + SOURCE,SOURCE-COMPUTER,SPACE,SPACES,SPECIAL-NAMES,STANDARD,START,% + STATUS,STOP,STRING,SUB-QUEUE-1,SUB-QUEUE-2,SUB-QUEUE-3,SUBTRACT,% + SUM,SYMBOLIC,SYNC,SYNCHRONIZED,TABLE,TALLYING,TAPE,TERMINAL,% + TERMINATE,TEXT,THAN,THROUGH,THRU,TIME,TIMES,TO,TOP,TRAILING,TYPE,% + UNIT,UNSTRING,UNTIL,UP,UPON,USAGE,USE,USING,VALUE,VALUES,VARYING,% + WHEN,WITH,WORDS,WORKING-STORAGE,WRITE,ZERO,ZEROES,ZEROS},% + alsodigit=-%, + sensitive=f,% ??? + morecomment=[f][commentstyle][6]*,% + morestring=[d]"% ??? doubled + }[keywords,comments,strings]% +% \end{macrocode} +% \texttt{commentstyle} (not the surrounding brackets) have been added after +% a bug report by \lsthelper{Stephen Reindl}{Stephen.Reindl@vodafone.de} +% {2002/05/28}{no commentstyle in Cobol}. % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -443,47 +869,50 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*comal> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage{Comal 80}% - {keywords={AND,AUTO,CASE,DATA,DEL,DIM,DIV,DO,ELSE,ENDCASE,ENDIF,% +\lst@definelanguage{Comal 80}% + {morekeywords={AND,AUTO,CASE,DATA,DEL,DIM,DIV,DO,ELSE,ENDCASE,ENDIF,% ENDPROC,ENDWHILE,EOD,EXEC,FALSE,FOR,GOTO,IF,INPUT,INT,LIST,LOAD,% MOD,NEW,NEXT,NOT,OF,OR,PRINT,PROC,RANDOM,RENUM,REPEAT,RND,RUN,% SAVE,SELECT,STOP,TAB,THEN,TRUE,UNTIL,WHILE,ZONE},% - sensitive=false,% ??? - commentline={//},% - stringizer={"}% - }% + sensitive=f,% ??? + morecomment=[l]//,% + morestring=[d]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % % % \subsection{C-Shell} % -% This language is due to \lsthelper{Kai Below}{below@tu-harburg.de}{1998/09/21}{csh}, but he pointed out that some keywords are probably missing. +% This language is from \lstthanks{Kai~Below}{below@tu-harburg.de}{1998/09/21}, +% but he pointed out that some keywords are probably missing. % \begingroup % \begin{macrocode} -%<*csh> +%<*lang1> % \end{macrocode} % \begin{macrocode} -%% (c) 1998 Kai Below -\lstdefinelanguage{csh} - {keywords={alias,awk,cat,echo,else,end,endif,endsw,exec,exit,% +%% +%% csh definition (c) 1998 Kai Below +%% +\lst@definelanguage{csh} + {morekeywords={alias,awk,cat,echo,else,end,endif,endsw,exec,exit,% foreach,glob,goto,history,if,logout,nice,nohup,onintr,repeat,sed,% set,setenv,shift,source,switch,then,time,while,umask,unalias,% unset,wait,while,@,env,argv,child,home,ignoreeof,noclobber,% noglob,nomatch,path,prompt,shell,status,verbose,print,printf,% sqrt,BEGIN,END},% - commentline={\#},% - stringizer={"}% - } + morecomment=[l]\#,% + morestring=[d]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -491,13 +920,15 @@ nor under a different one. % \subsection{Delphi} % % I took the data from Delphi 1.0 (?) online help. +% \lstthanks{Christian~Gudrian}{chrigu@kawo1.rwth-aachen.de}{2001/08/16} +% provided the `double slash' comment. % \begingroup % \begin{macrocode} -%<*delphi> +%<*lang2> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{Delphi}% - {keywords={and,as,asm,array,begin,case,class,const,constructor,% +\lst@definelanguage{Delphi}% + {morekeywords={and,as,asm,array,begin,case,class,const,constructor,% destructor,div,do,downto,else,end,except,exports,file,finally,% for,function,goto,if,implementation,in,inherited,inline,% initialization,interface,is,label,library,mod,nil,not,object,of,% @@ -507,42 +938,45 @@ nor under a different one. absolute,abstract,assembler,at,cdecl,default,dynamic,export,% external,far,forward,index,name,near,nodefault,on,override,% private,protected,public,published,read,resident,storedDir,% - virtual,write,% - Abs,AddExitProc,Addr,AllocMem,AnsiCompareStr,AnsiCompareText,% - AnsiLowerCase,AnsiUpperCase,Append,AppendStr,ArcTan,AssignCrt,% - Assigned,AssignFile,BlockRead,BlockWrite,Break,ChangeFileExt,% - ChDir,Chr,CloseFile,ClrEol,ClrScr,Concat,Continue,Copy,Cos,CSeg,% - CursorTo,Date,DateTimeToFileDate,DateTimeToStr,DateTimeToString,% - DateToStr,DayOfWeek,Dec,DecodeDate,DecodeTime,Delete,DeleteFile,% - DiskFree,DiskSize,Dispose,DisposeStr,DoneWinCrt,DSeg,EncodeDate,% - EncodeTime,Eof,Eoln,Erase,Exclude,Exit,Exp,ExpandFileName,% - ExtractFileExt,ExtractFileName,ExtractFilePath,FileAge,FileClose,% - FileDateToDateTime,FileExists,FileGetAttr,FileGetDate,FileOpen,% - FilePos,FileRead,FileSearch,FileSeek,FileSetAttr,FileSetDate,% - FileSize,FillChar,FindClose,FindFirst,FindNext,FloatToDecimal,% - FloatToStrF,FloatToStr,FloatToText,FloatToTextFmt,Flush,% - FmtLoadStr,FmtStr,Format,FormatBuf,FormatDateTime,FormatFloat,% - Frac,Free,FreeMem,GetDir,GetMem,GotoXY,Halt,Hi,High,Inc,Include,% - InitWinCrt,Insert,Int,IntToHex,IntToStr,IOResult,IsValidIdent,% - KeyPressed,Length,Ln,Lo,LoadStr,Low,LowerCase,MaxAvail,MemAvail,% - MkDir,Move,New,NewStr,Now,Odd,Ofs,Ord,ParamCount,ParamStr,Pi,Pos,% - Pred,Ptr,Random,Randomize,Read,ReadBuf,ReadKey,Readln,ReAllocMem,% - Rename,RenameFile,Reset,Rewrite,RmDir,Round,RunError,ScrollTo,% - Seek,SeekEof,SeekEoln,Seg,SetTextBuf,Sin,SizeOf,SPtr,Sqr,Sqrt,% - SSeg,Str,StrCat,StrComp,StrCopy,StrDispose,StrECopy,StrEnd,% - StrFmt,StrLCat,StrIComp,StrLComp,StrLCopy,StrLen,StrLFmt,% - StrLIComp,StrLower,StrMove,StrNew,StrPas,StrPCopy,StrPos,StrScan,% - StrRScan,StrToDate,StrToDateTime,StrToFloat,StrToInt,StrToIntDef,% + virtual,write},% + morendkeywords={Abs,AddExitProc,Addr,AllocMem,AnsiCompareStr,% + AnsiCompareText,AnsiLowerCase,AnsiUpperCase,Append,AppendStr,% + ArcTan,AssignCrt,Assigned,AssignFile,BlockRead,BlockWrite,Break,% + ChangeFileExt,ChDir,Chr,CloseFile,ClrEol,ClrScr,Concat,Continue,% + Copy,Cos,CSeg,CursorTo,Date,DateTimeToFileDate,DateTimeToStr,% + DateTimeToString,DateToStr,DayOfWeek,Dec,DecodeDate,DecodeTime,% + Delete,DeleteFile,DiskFree,DiskSize,Dispose,DisposeStr,% + DoneWinCrt,DSeg,EncodeDate,EncodeTime,Eof,Eoln,Erase,Exclude,% + Exit,Exp,ExpandFileName,ExtractFileExt,ExtractFileName,% + ExtractFilePath,FileAge,FileClose,FileDateToDateTime,FileExists,% + FileGetAttr,FileGetDate,FileOpen,FilePos,FileRead,FileSearch,% + FileSeek,FileSetAttr,FileSetDate,FileSize,FillChar,FindClose,% + FindFirst,FindNext,FloatToDecimal,FloatToStrF,FloatToStr,% + FloatToText,FloatToTextFmt,Flush,FmtLoadStr,FmtStr,Format,% + FormatBuf,FormatDateTime,FormatFloat,Frac,Free,FreeMem,GetDir,% + GetMem,GotoXY,Halt,Hi,High,Inc,Include,InitWinCrt,Insert,Int,% + IntToHex,IntToStr,IOResult,IsValidIdent,KeyPressed,Length,Ln,Lo,% + LoadStr,Low,LowerCase,MaxAvail,MemAvail,MkDir,Move,New,NewStr,% + Now,Odd,Ofs,Ord,ParamCount,ParamStr,Pi,Pos,Pred,Ptr,Random,% + Randomize,Read,ReadBuf,ReadKey,Readln,ReAllocMem,Rename,% + RenameFile,Reset,Rewrite,RmDir,Round,RunError,ScrollTo,Seek,% + SeekEof,SeekEoln,Seg,SetTextBuf,Sin,SizeOf,SPtr,Sqr,Sqrt,SSeg,% + Str,StrCat,StrComp,StrCopy,StrDispose,StrECopy,StrEnd,StrFmt,% + StrLCat,StrIComp,StrLComp,StrLCopy,StrLen,StrLFmt,StrLIComp,% + StrLower,StrMove,StrNew,StrPas,StrPCopy,StrPos,StrScan,StrRScan,% + StrToDate,StrToDateTime,StrToFloat,StrToInt,StrToIntDef,% StrToTime,StrUpper,Succ,Swap,TextToFloat,Time,TimeToStr,% TrackCursor,Trunc,Truncate,TypeOf,UpCase,UpperCase,Val,WhereX,% WhereY,Write,WriteBuf,WriteChar,Writeln},% - sensitive=false,% - doublecomment={(*}{*)}{\{}{\}},% - stringizer=[d]{'}% - }% + sensitive=f,% + morecomment=[s]{(*}{*)},% + morecomment=[s]{\{}{\}},% + morecomment=[l]{//},% 2001 Christian Gudrian + morestring=[d]'% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -558,11 +992,11 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*eiffel> +%<*lang2> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{Eiffel}% - {keywords={alias,all,and,as,BIT,BOOLEAN,CHARACTER,check,class,% +\lst@definelanguage{Eiffel}% + {morekeywords={alias,all,and,as,BIT,BOOLEAN,CHARACTER,check,class,% creation,Current,debug,deferred,do,DOUBLE,else,elseif,end,% ensure,expanded,export,external,false,feature,from,frozen,if,% implies,indexing,infix,inherit,inspect,INTEGER,invariant,is,% @@ -570,14 +1004,16 @@ nor under a different one. REAL,redefine,rename,require,rescue,Result,retry,select,% separate,STRING,strip,then,true,undefine,unique,until,variant,% when,xor},% - sensitive=true,% - commentline={--},% - stringizer={"},% - stringtest=false% - }% + sensitive,% + morecomment=[l]--,% + morestring=[d]",% + }[keywords,comments,strings]% % \end{macrocode} +% The key=value \texttt{stringtest=false} has been removed after a bug +% report from \lsthelper{Xavier~Cr\'egut}{cregut@enseeiht.fr}{2002/09/09} +% {stringtest no more part of package}. % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -593,16 +1029,16 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*elan> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage{Elan}% - {keywords={ABS,AND,BOOL,CAND,CASE,CAT,COLUMNS,CONCR,CONJ,CONST,COR,% - DECR,DEFINES,DET,DIV,DOWNTO,ELIF,ELSE,END,ENDIF,ENDOP,ENDPACKET,% - ENDPROC,ENDREP,ENDSELECT,FALSE,FI,FILE,FOR,FROM,IF,INCR,INT,INV,% - LEAVE,LENGTH,LET,MOD,NOT,OF,OP,OR,OTHERWISE,PACKET,PROC,REAL,REP,% - REPEAT,ROW,ROWS,SELECT,SIGN,STRUCT,SUB,TEXT,THEN,TRANSP,TRUE,% - TYPE,UNTIL,UPTO,VAR,WHILE,WITH,XOR,% +\lst@definelanguage{Elan}% + {morekeywords={ABS,AND,BOOL,CAND,CASE,CAT,COLUMNS,CONCR,CONJ,CONST,% + COR,DECR,DEFINES,DET,DIV,DOWNTO,ELIF,ELSE,END,ENDIF,ENDOP,% + ENDPACKET,ENDPROC,ENDREP,ENDSELECT,FALSE,FI,FILE,FOR,FROM,IF,% + INCR,INT,INV,LEAVE,LENGTH,LET,MOD,NOT,OF,OP,OR,OTHERWISE,PACKET,% + PROC,REAL,REP,REPEAT,ROW,ROWS,SELECT,SIGN,STRUCT,SUB,TEXT,THEN,% + TRANSP,TRUE,TYPE,UNTIL,UPTO,VAR,WHILE,WITH,XOR,% maxint,sign,abs,min,max,random,initializerandom,subtext,code,% replace,text,laenge,pos,compress,change,maxreal,smallreal,floor,% pi,e,ln,log2,log10,sqrt,exp,tan,tand,sin,sind,cos,cosd,arctan,% @@ -611,45 +1047,48 @@ nor under a different one. close,complexzero,complexone,complexi,complex,realpart,imagpart,% dphi,phi,vector,norm,replace,matrix,idn,row,column,sub,% replacerow,replacecolumn,replaceelement,transp,errorsstop,stop},% - sensitive=true,% - stringizer=[d]{"}% - }% + sensitive,% + morestring=[d]"% + }[keywords,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % % % \subsection{Euphoria} % -% \lsthelper{Detlef Reimers}{dreimers@aol.com}{1998/08/30}{Euphoria} sent me the language definition. -% I've done the conversion to listings 0.19. +% \lstthanks{Detlef~Reimers}{dreimers@aol.com}{1998/08/30} sent me the language +% definition. % \begingroup % \begin{macrocode} -%<*euphoria> +%<*lang2> % \end{macrocode} % \begin{macrocode} -%% (c) 1998 Detlef Reimers -\lstdefinelanguage{Euphoria}% +%% +%% Euphoria definition (c) 1998 Detlef Reimers +%% +\lst@definelanguage{Euphoria}% % for Euphoria 2.0, Rapid Deployment Software, Kanada - {keywords={abort,and,and_bits,append,arctan,atom,by,call,call_proc,% - call_func,c_proc,c_func,clear_screen,close,command_line,compare,% - constant,cos,do,date,else,elsif,end,exit,find,floor,for,function,% - getc,getenv,get_key,gets,global,get_pixel,if,include,integer,% - length,log,match,machine_func,machine_proc,mem_copy,mem_set,not,% - not_bits,or,object,open,or_bits,procedure,puts,position,prepend,% - print,printf,power,peek,poke,pixel,poke4,peek4s,peek4u,return,% - rand,repeat,remainder,routine_id,sequence,sqrt,sin,system,% - sprintf,then,type,to,time,trace,tan,while,with,without,xor,% - xor_bits},% - sensitive=true,% - commentline={--},% - stringizer=[d]{'"}% - }% + {morekeywords={abort,and,and_bits,append,arctan,atom,by,call,% + call_proc,call_func,c_proc,c_func,clear_screen,close,% + command_line,compare,constant,cos,do,date,else,elsif,end,exit,% + find,floor,for,function,getc,getenv,get_key,gets,global,% + get_pixel,if,include,integer,length,log,match,machine_func,% + machine_proc,mem_copy,mem_set,not,not_bits,or,object,open,% + or_bits,procedure,puts,position,prepend,print,printf,power,peek,% + poke,pixel,poke4,peek4s,peek4u,return,rand,repeat,remainder,% + routine_id,sequence,sqrt,sin,system,sprintf,then,type,to,time,% + trace,tan,while,with,without,xor,xor_bits},% + sensitive,% + morecomment=[l]--,% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -671,80 +1110,148 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*fortran> +%<*lang1> % \end{macrocode} -% The common Fortran 90 and 77 'keywords': +% \lsthelper{Denis Girou}{Denis.Girou@idris.fr}{1998/07/26}{Fortran 95=90} +% proposed to have Fortran 95 and Fortran 90 to be equivalent. % \begin{macrocode} -\lststorekeywords\lstkeys@fortran{ACCESS,ASSIGN,BACKSPACE,BLANK,% - BLOCK,CALL,CHARACTER,CLOSE,COMMON,COMPLEX,CONTINUE,DATA,DIMENSION,% - DIRECT,DO,DOUBLE,ELSE,END,ENTRY,EOF,EQUIVALENCE,ERR,EXIST,EXTERNAL,% - FILE,FMT,FORM,FORMAT,FORMATTED,FUNCTION,GO,TO,IF,IMPLICIT,INQUIRE,% - INTEGER,INTRINSIC,IOSTAT,LOGICAL,NAMED,NEXTREC,NUMBER,OPEN,OPENED,% - PARAMETER,PAUSE,PRECISION,PRINT,PROGRAM,READ,REAL,REC,RECL,% - RETURN,REWIND,SEQUENTIAL,STATUS,STOP,SUBROUTINE,THEN,TYPE,% - UNFORMATTED,UNIT,WRITE}% +\lst@definelanguage[90]{Fortran}[95]{Fortran}{} % \end{macrocode} -% As proposed by \lsthelper{J\"orn Wilms}{wilms@rocinante.colorado.edu}{1997/07/07}{Fortran with \lstsensitivefalse} keywords are \emph{not} case sensitive. -% There is no \cs{lstfixedcommentline} in Fortran 90 since otherwise CONTAINS could start a comment. -% This problem was reported by \lsthelper{Magne Rudshaug}{magne@ife.no}{1998/01/09}{no fixedcommentline= in Fortran 90}. +% There is no |morecomment=[f]| in Fortran 90 since otherwise CONTAINS could +% start a comment. This problem was reported by \lsthelper{Magne Rudshaug} +% {magne@ife.no}{1998/01/09}{no morecomment=[f] in Fortran 90}. % Moreover the keyword INCLUDE is due to him. % \begin{macrocode} -\lstdefinedrvlanguage[95]{Fortran}% - {keywords={\lstkeys@fortran,ACTION,ADVANCE,ALLOCATE,ALLOCATABLE,% - ASSIGNMENT,CASE,CONTAINS,CYCLE,DEALLOCATE,DEFAULT,DELIM,EXIT,% - INCLUDE,IN,NONE,IN,OUT,INTENT,INTERFACE,IOLENGTH,KIND,LEN,MODULE,% - NAME,NAMELIST,NMT,NULLIFY,ONLY,OPERATOR,OPTIONAL,OUT,PAD,POINTER,% - POSITION,PRIVATE,PUBLIC,READWRITE,RECURSIVE,RESULT,SELECT,% - SEQUENCE,SIZE,STAT,TARGET,USE,WHERE,WHILE,BLOCKDATA,% - DOUBLEPRECISION,ELSEIF,ENDBLOCKDATA,ENDDO,ENDFILE,ENDFUNCTION,% - ENDIF,ENDINTERFACE,ENDMODULE,ENDPROGRAM,ENDSELECT,ENDSUBROUTINE,% - ENDTYPE,ENDWHERE,GOTO,INOUT,SELECTCASE},% - sensitive=false,%% not Fortran standard %% 1997 J\"orn Wilms - commentline={!},% no fixed comment line: 1998 Magne Rudshaug - stringizer={"}% +\lst@definelanguage[95]{Fortran}[77]{Fortran}% + {deletekeywords=SAVE,% + morekeywords={ACTION,ADVANCE,ALLOCATE,ALLOCATABLE,ASSIGNMENT,CASE,% + CONTAINS,CYCLE,DEALLOCATE,DEFAULT,DELIM,EXIT,INCLUDE,IN,NONE,IN,% + OUT,INTENT,INTERFACE,IOLENGTH,KIND,LEN,MODULE,NAME,NAMELIST,NMT,% + NULLIFY,ONLY,OPERATOR,OPTIONAL,OUT,PAD,POINTER,POSITION,PRIVATE,% + PUBLIC,READWRITE,RECURSIVE,RESULT,SELECT,SEQUENCE,SIZE,STAT,% + TARGET,USE,WHERE,WHILE,BLOCKDATA,DOUBLEPRECISION,ELSEIF,% + ENDBLOCKDATA,ENDDO,ENDFILE,ENDFUNCTION,ENDIF,ENDINTERFACE,% + ENDMODULE,ENDPROGRAM,ENDSELECT,ENDSUBROUTINE,ENDTYPE,ENDWHERE,% + GOTO,INOUT,SELECTCASE},% + deletecomment=[f],% no fixed comment line: 1998 Magne Rudshaug + morecomment=[l]!% }% % \end{macrocode} -% \lsthelper{Denis Girou}{Denis.Girou@idris.fr}{1998/07/26}{Fortran 95=90} proposed to have Fortran 95 and Fortran 90 to be equivalent. +% As proposed by \lsthelper{J\"orn Wilms}{wilms@rocinante.colorado.edu} +% {1997/07/07}{Fortran with \lstsensitivefalse} keywords are \emph{not} case +% sensitive. % \begin{macrocode} -\lstdefinedrvlanguage[90]{Fortran}{language=[95]Fortran} +\lst@definelanguage[77]{Fortran}% + {morekeywords={ACCESS,ASSIGN,BACKSPACE,BLANK,BLOCK,CALL,CHARACTER,% + CLOSE,COMMON,COMPLEX,CONTINUE,DATA,DIMENSION,DIRECT,DO,DOUBLE,% + ELSE,END,ENTRY,EOF,EQUIVALENCE,ERR,EXIST,EXTERNAL,FILE,FMT,FORM,% + FORMAT,FORMATTED,FUNCTION,GO,TO,IF,IMPLICIT,INQUIRE,INTEGER,% + INTRINSIC,IOSTAT,LOGICAL,NAMED,NEXTREC,NUMBER,OPEN,OPENED,% + PARAMETER,PAUSE,PRECISION,PRINT,PROGRAM,READ,REAL,REC,RECL,% + RETURN,REWIND,SEQUENTIAL,STATUS,STOP,SUBROUTINE,THEN,TYPE,% + UNFORMATTED,UNIT,WRITE,SAVE},% + sensitive=f,%% not Fortran standard %% + morecomment=[f]*,% + morecomment=[f]C,% + morecomment=[f]c,% + morestring=[d]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[77]{Fortran}% - {keywords={\lstkeys@fortran,SAVE},% - sensitive=false,%% not Fortran standard %% - fixedcommentline={*Cc},% - stringizer={"}% - }% -% \end{macrocode} -% \begin{macrocode} -% +% % \end{macrocode} % \endgroup % % -% \subsection{IDL} +% \subsection{Haskell} % -% The definition is due to \lsthelper{J\"urgen Heim}{heim@astro.uni-tuebingen.de}{1998/07/27}{IDL}. -% I've done the conversion to version 0.19. +% Thanks to \lstthanks{Peter~Bartke}{bartke@inf.fu-berlin.de}{1999/11/18} for +% providing the new definition. % \begingroup % \begin{macrocode} -%<*idl> +%<*lang2> % \end{macrocode} % \begin{macrocode} -%% (c) 1998 Juergen Heim -\lstdefinelanguage{IDL}% - {keywords={and,begin,case,common,do,else,end,endcase,endelse,% - endfor,endif,endrep,endwhile,eq,for,function,ge,goto,gt,if,le,lt,% - mod,ne,not,of,on_ioerror,or,pro,repeat,return,then,until,while,% - xor,on_error,openw,openr,openu,print,printf,printu,plot,read,% - readf,readu,writeu,stop},% - sensitive=false,% - commentline={;},% - stringizer=[d]{'}% - }% +%% +%% Haskell98 as implemented in Hugs98. See http://www.haskell.org +%% All keywords from Prelude and Standard Libraries +%% (c) 1999 Peter Bartke +%% +\lst@definelanguage{Haskell}% + {otherkeywords={=>},% + morekeywords={abstype,if,then,else,case,class,data,default,deriving,% + hiding,if,in,infix,infixl,infixr,import,instance,let,module,% + newtype,of,qualified,type,where,do,AbsoluteSeek,AppendMode,% + Array,BlockBuffering,Bool,BufferMode,Char,Complex,Double,Either,% + FilePath,Float,Int,Integer,IO,IOError,Ix,LineBuffering,Maybe,% + Ordering,NoBuffering,ReadMode,ReadWriteMode,ReadS,RelativeSeek,% + SeekFromEnd,SeekMode,ShowS,StdGen,String,Void,Bounded,Enum,Eq,% + Eval,ExitCode,exitFailure,exitSuccess,Floating,Fractional,% + Functor,Handle,HandlePosn,IOMode,Integral,List,Monad,MonadPlus,% + MonadZero,Num,Numeric,Ord,Random,RandomGen,Ratio,Rational,Read,% + Real,RealFloat,RealFrac,Show,System,Prelude,EQ,False,GT,Just,% + Left,LT,Nothing,Right,WriteMode,True,abs,accum,accumArray,% + accumulate,acos,acosh,all,and,any,ap,appendFile,applyM,% + approxRational,array,asTypeOf,asin,asinh,assocs,atan,atan2,atanh,% + bounds,bracket,bracket_,break,catch,catMaybes,ceiling,chr,cis,% + compare,concat,concatMap,conjugate,const,cos,cosh,curry,cycle,% + decodeFloat,delete,deleteBy,deleteFirstsBy,denominator,% + digitToInt,div,divMod,drop,dropWhile,either,elem,elems,elemIndex,% + elemIndices,encodeFloat,enumFrom,enumFromThen,enumFromThenTo,% + enumFromTo,error,even,exitFailure,exitWith,exp,exponent,fail,% + filter,filterM,find,findIndex,findIndices,flip,floatDigits,% + floatRadix,floatRange,floatToDigits,floor,foldl,foldM,foldl1,% + foldr,foldr1,fromDouble,fromEnum,fromInt,fromInteger,% + fromIntegral,fromJust,fromMaybe,fromRat,fromRational,% + fromRealFrac,fst,gcd,genericLength,genericTake,genericDrop,% + genericSplitAt,genericIndex,genericReplicate,getArgs,getChar,% + getContents,getEnv,getLine,getProgName,getStdGen,getStdRandom,% + group,groupBy,guard,hClose,hFileSize,hFlush,hGetBuffering,% + hGetChar,hGetContents,hGetLine,hGetPosn,hIsClosed,hIsEOF,hIsOpen,% + hIsReadable,hIsSeekable,hIsWritable,hLookAhead,hPutChar,hPutStr,% + hPutStrLn,hPrint,hReady,hSeek,hSetBuffering,hSetPosn,head,% + hugsIsEOF,hugsHIsEOF,hugsIsSearchErr,hugsIsNameErr,% + hugsIsWriteErr,id,ioError,imagPart,index,indices,init,inits,% + inRange,insert,insertBy,interact,intersect,intersectBy,% + intersperse,intToDigit,ioeGetErrorString,ioeGetFileName,% + ioeGetHandle,isAlreadyExistsError,isAlreadyInUseError,isAlpha,% + isAlphaNum,isAscii,isControl,isDenormalized,isDoesNotExistError,% + isDigit,isEOF,isEOFError,isFullError,isHexDigit,isIEEE,% + isIllegalOperation,isInfinite,isJust,isLower,isNaN,% + isNegativeZero,isNothing,isOctDigit,isPermissionError,isPrefixOf,% + isPrint,isSpace,isSuffixOf,isUpper,isUserError,iterate,ixmap,% + join,last,lcm,length,lex,lexDigits,lexLitChar,liftM,liftM2,% + liftM3,liftM4,liftM5,lines,listArray,listToMaybe,log,logBase,% + lookup,magnitude,makePolar,map,mapAccumL,mapAccumR,mapAndUnzipM,% + mapM,mapM_,mapMaybe,max,maxBound,maximum,maximumBy,maybe,% + maybeToList,min,minBound,minimum,minimumBy,mkPolar,mkStdGen,% + mplus,mod,msum,mzero,negate,next,newStdGen,not,notElem,nub,nubBy,% + null,numerator,odd,openFile,or,ord,otherwise,partition,phase,pi,% + polar,pred,print,product,properFraction,putChar,putStr,putStrLn,% + quot,quotRem,random,randomIO,randomR,randomRIO,randomRs,randoms,% + rangeSize,read,readDec,readFile,readFloat,readHex,readInt,readIO,% + readList,readLitChar,readLn,readParen,readOct,readSigned,reads,% + readsPrec,realPart,realToFrac,recip,rem,repeat,replicate,return,% + reverse,round,scaleFloat,scanl,scanl1,scanr,scanr1,seq,sequence,% + sequence_,setStdGen,show,showChar,showEFloat,showFFloat,% + showFloat,showGFloat,showInt,showList,showLitChar,showParen,% + showSigned,showString,shows,showsPrec,significand,signum,sin,% + sinh,snd,sort,sortBy,span,split,splitAt,sqrt,stderr,stdin,stdout,% + strict,subtract,succ,sum,system,tail,tails,take,takeWhile,tan,% + tanh,toEnum,toInt,toInteger,toLower,toRational,toUpper,transpose,% + truncate,try,uncurry,undefined,unfoldr,union,unionBy,unless,% + unlines,until,unwords,unzip,unzip3,unzip4,unzip5,unzip6,unzip7,% + userError,when,words,writeFile,zero,zip,zip3,zip4,zip5,zip6,zip7,% + zipWith,zipWithM,zipWithM_,zipWith3,zipWith4,zipWith5,zipWith6,% + zipWith7},% + sensitive,% + morecomment=[l]--,% + morecomment=[n]{\{-}{-\}},% + morestring=[b]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -755,12 +1262,12 @@ nor under a different one. % In particular this is true for the defined keywords. % \begingroup % \begin{macrocode} -%<*html> +%<*lang1> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{HTML}% - {keywords={A,ADDRESS,APPLET,B,BASE,BASEFONT,BIG,BLOCKQUOTE,BODY,BR,% - CENTER,CITE,CODE,DFN,DIR,DIV,DOCTYPE,EM,FONT,FORM,HEAD,HR,% +\lst@definelanguage{HTML}% + {morekeywords={A,ADDRESS,APPLET,B,BASE,BASEFONT,BIG,BLOCKQUOTE,BODY,% + BR,CENTER,CITE,CODE,DFN,DIR,DIV,DOCTYPE,EM,FONT,FORM,HEAD,HR,% H1,H2,H3,H4,H5,H6,HTML,I,IMG,INPUT,ISINDEX,KBD,LI,LINK,LISTING,% MAP,META,MENU,P,PLAINTEXT,PRE,OL,SAMP,SCRIPT,SELECT,SMALL,STRIKE,% STRING,SUB,SUP,STYLE,TABLE,TEXTAREA,TITLE,TT,U,UL,VAR,XMP,% @@ -769,81 +1276,60 @@ nor under a different one. height,href,hspace,ismap,link,maxlength,method,multiple,name,% noshade,nowrap,rel,rev,rows,rowspan,selected,shape,size,src,text,% title,type,usemap,valign,value,vlink,vspace,width},% - sensitive=false,% - stringizer={"}% ??? doubled - }% + keywordsinside=<>, + sensitive=f,% + morestring=[d]",% ??? doubled +% \end{macrocode} +% Now we take care of comments. +% We don't enter comment mode if we aren't inside |<>|. +% \begin{macrocode} + MoreSelectCharTable=% + \lst@CArgX--\relax\lst@DefDelimB{}{}% + {\ifnum\lst@mode=\lst@insidemode\else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@commentmode{{\lst@commentstyle}}% + \lst@CArgX--\relax\lst@DefDelimE{}{}{}% + \lst@EndComment\lst@commentmode + }[keywords,comments,strings,html]% +% \end{macrocode} +% \lsthelper{Peter~Biechele}{peter.biechele@physik.uni-freiburg.de} +% {1999/07/01}{! Missing $\}$ inserted} reported a problem which was due to +% missing |\@empty| in value of |SelectCharTable|. And after receiving a bug +% report from \lsthelper{Jochen Schneider}{jschneider@ds3.etech.haw-hamburg.de} +% {2002/04/05}{use of \lst@thestyle doesn't match its definition} I converted +% the version 0.21 contents of |MoreSelectCharTable| to version 1.0. +% \begin{macrocode} +% % \end{macrocode} % \endgroup % -% \begin{macro}{\lstPre@html} -% We don't detect keywords all over a HTML document: we 'undefine' them first. -% \begin{macrocode} -\gdef\lstPre@html{% - \let\lstkeys@html\lst@keywords % - \let\lst@keywords\@empty} -% \end{macrocode} -% \end{macro} % -% \begin{macro}{\lst@HTMLmode} -% They will be active (exactly) in HTML mode. -% \begin{macrocode} -\lst@NewMode\lst@HTMLmode % -% \end{macrocode} -% \end{macro} +% \subsection{IDL} % -% \begin{macro}{\lstSCT@html} -% Coming to the delimiter |<|, we define the keywords again and execute the old meaning of |<|. -% \begin{macrocode} -\gdef\lstSCT@html{% - \lccode`\~=`\<\lowercase{\let\lsts@HTMLb~}% - \lstCC@Def{`\<}{% - \lst@ifmode\else % - \lst@EnterMode{\lst@HTMLmode}% - {\let\lst@keywords\lstkeys@html}% - \fi % - \lsts@HTMLb} -% \end{macrocode} -% |>| undefines the keywords again (since we leave HTML mode including an |\egroup|). -% \begin{macrocode} - \lccode`\~=`\>\lowercase{\let\lsts@HTMLe~}% - \lstCC@Def{`\>}{% - \ifnum\lst@mode=\lst@HTMLmode % - \lsts@HTMLe \lst@PrintToken \lst@LeaveMode % - \else % - \expandafter\lsts@HTMLe % - \fi}% -% \end{macrocode} -% \begin{TODO} -% You shouldn't think that here's anything to do. -% The definition shouldn't be changed to\vspace*{-\baselineskip} -% \begin{verbatim} -%\lstCC@Def{`\>}{% -% \lsts@HTMLe % -% \ifnum\lst@mode=\lst@HTMLmode % -% \lst@PrintToken \lst@LeaveMode % -% \fi}%\end{verbatim} -% If |\lst@HTMLe| (= old |>|) gets any arguments, it's really not the same. -% However, this is not true for HTML (I think), but in some time someone might need arguments \ldots -% \end{TODO} -% Now we take care of comments. -% The minus is redefined to look ahead for another minus, but we enter comment mode only if we are in HTML mode. -% \begin{macrocode} - \lccode`\~=`\-\lowercase{\let\lsts@HTMLc~}% - \lstCC@Def{`\-}##1{% - \let\lstCC@bnext\relax % - \ifnum\lst@mode=\lst@HTMLmode \ifnum`##1=`\-% - \def\lstCC@bnext{\lstCC@@BeginComment\lst@SCmode}% - \fi \fi % - \lstCC@bnext \lsts@HTMLc ##1}% -% \end{macrocode} -% Finally we define |--| to end the comment. -% \begin{macrocode} - \lstCC@TestCArg--\@empty\relax\lstCC@CommentE{SC}\lst@SCmode} -% \end{macrocode} -% \end{macro} +% The definition is from \lstthanks{J\"urgen~Heim} +% {heim@astro.uni-tuebingen.de}{1998/07/27}. % \begingroup % \begin{macrocode} -% +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% IDL definition (c) 1998 Juergen Heim +%% +\lst@definelanguage{IDL}% + {morekeywords={and,begin,case,common,do,else,end,endcase,endelse,% + endfor,endif,endrep,endwhile,eq,for,function,ge,goto,gt,if,le,lt,% + mod,ne,not,of,on_ioerror,or,pro,repeat,return,then,until,while,% + xor,on_error,openw,openr,openu,print,printf,printu,plot,read,% + readf,readu,writeu,stop},% + sensitive=f,% + morecomment=[l];,% + morestring=[d]'% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % @@ -853,29 +1339,60 @@ nor under a different one. % Got data from \texttt{http://java.sun.com}. % \begingroup % \begin{macrocode} -%<*java> +%<*lang1> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{Java}% - {keywords={abstract,boolean,break,byte,case,catch,char,class,const,% - continue,default,do,double,else,extends,final,finally,float,for,% - goto,if,implements,import,instanceof,int,interface,long,native,% - new,null,package,private,protected,public,return,short,static,% - super,switch,synchronized,this,throw,throws,transient,try,void,% - volatile,while,true,false},% - sensitive=true,% - commentline={//},% - singlecomment={/*}{*/},% - stringizer=[b]{"}% ??? backslashed - }% +\lst@definelanguage{Java}% + {morekeywords={abstract,boolean,break,byte,case,catch,char,class,% + const,continue,default,do,double,else,extends,false,final,% + finally,float,for,goto,if,implements,import,instanceof,int,% + interface,label,long,native,new,null,package,private,protected,% + public,return,short,static,super,switch,synchronized,this,throw,% + throws,transient,true,try,void,volatile,while},% + sensitive,% + morecomment=[l]//,% + morecomment=[s]{/*}{*/},% + morestring=[b]",% + morestring=[b]',% + }[keywords,comments,strings]% % \end{macrocode} +% \lsthelper{Herbert Voss}{Herbert.Voss@alumni.TU-Berlin.de}{2002/07/30} +% {missing keyword label} added the keyword \texttt{label}. % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % % -% \subsection{Lisp} +% \subsection{ksh} +% +% Thanks to \lstthanks{Jeffrey Ratcliffe}{Jeffrey.Ratcliffe@m.eads.net} +% {2002/02/21} for this language definition. +% \begingroup +% \begin{macrocode} +%<*lang3> +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage{ksh} + {morekeywords={alias,awk,cat,echo,else,elif,fi,exec,exit,% + for,in,do,done,select,case,esac,while,until,function,% + time,export,cd,eval,fc,fg,kill,let,pwd,read,return,rm,% + glob,goto,history,if,logout,nice,nohup,onintr,repeat,sed,% + set,setenv,shift,source,switch,then,umask,unalias,% + unset,wait,@,env,argv,child,home,ignoreeof,noclobber,% + noglob,nomatch,path,prompt,shell,status,verbose,print,printf,% + sqrt,BEGIN,END},% + morecomment=[l]\#,% + morestring=[d]",% + morestring=[d]'% + }[keywords,comments,strings]% +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Lisp, AutoLisp} % % Most data are from % \begin{itemize} @@ -885,17 +1402,18 @@ nor under a different one. % Copyright 1990 by Digital Equipment Corporation; % ISBN 1-55558-042-4. % \end{itemize} -% Thanks to \lsthelper{Aslak Raanes}{araanes@ifi.ntnu.no}{1997/11/24}{single comment in Lisp} for the single comment. -% The keywords are the 'one-word' functions and macros of Common Lisp, i.e.\ words not containing a minus. -% But I left out the \texttt{caaaar}, \ldots{} functions. +% Thanks to \lsthelper{Aslak Raanes}{araanes@ifi.ntnu.no}{1997/11/24}{single +% comment in Lisp} for the `single comment' delimiters. The keywords are the +% `one-word' functions and macros of Common Lisp, i.e.~words not containing a +% minus. But I left out the \texttt{caaaar}, \ldots{} functions. % If anyone types them in, I'd like to get them. % \begingroup % \begin{macrocode} -%<*lisp> +%<*lang2> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{Lisp}% - {keywords={abort,abs,acons,acos,acosh,adjoin,alphanumericp,alter,% +\lst@definelanguage{Lisp}% + {morekeywords={abort,abs,acons,acos,acosh,adjoin,alphanumericp,alter,% append,apply,apropos,aref,arrayp,ash,asin,asinh,assoc,atan,atanh,% atom,bit,boole,boundp,break,butlast,byte,catenate,ceiling,cerror,% char,character,characterp,choose,chunk,cis,close,clrhash,coerce,% @@ -932,15 +1450,124 @@ nor under a different one. incf,iterate,labels,let,locally,loop,macrolet,mapping,or,pop,% producing,prog,psetf,psetq,push,pushnew,remf,return,rotatef,% setf,shiftf,step,time,trace,typecase,unless,untrace,when},% - sensitive=true,% ??? - alsodigit={-},% - commentline={;},% - singlecomment={\#|}{|\#},% 1997 Aslak Raanes - stringizer=[b]{"}% - }% + sensitive,% ??? + alsodigit=-,% + morecomment=[l];,% + morecomment=[s]{\#|}{|\#},% 1997 Aslak Raanes + morestring=[b]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% +% \end{macrocode} +% \endgroup +% +% +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \lstthanks{Stefan Lagotzki}{info@lagotzki.de}{2001/10/28} warned me to +% define this as a lisp dialect \ldots +% \begin{macrocode} +%% +%% AutoLISP/VisualLISP - Stefan Lagotzki, info@lagotzki.de +%% +\lst@definelanguage[Auto]{Lisp}% + {morekeywords={abs,acad_colordlg,acad_helpdlg,acad_strlsort,% + action_tile,add_list,alert,alloc,and,angle,angtof,angtos,append,% + apply,arx,arxload,arxunload,ascii,assoc,atan,atof,atoi,atom,% + atoms-family,autoarxload,autoload,Boole,boundp,caddr,cadr,car,% + cdr,chr,client_data_tile,close,command,cond,cons,cos,cvunit,% + defun,defun-q,defun-q-list-ref,defun-q-list-set,dictadd,dictnext,% + dictremove,dictrename,dictsearch,dimx_tile,dimy_tile,distance,% + distof,done_dialog,end_image,end_list,entdel,entget,entlast,% + entmake,entmakex,entmod,entnext,entsel,entupd,eq,equal,*error*,% + eval,exit,exp,expand,expt,fill_image,findfile,fix,float,foreach,% + function,gc,gcd,get_attr,get_tile,getangle,getcfg,getcname,% + getcorner,getdist,getenv,getfiled,getint,getkword,getorient,% + getpoint,getreal,getstring,getvar,graphscr,grclear,grdraw,grread,% + grtext,grvecs,handent,help,if,initdia,initget,inters,itoa,lambda,% + last,layoutlist,length,list,listp,load,load_dialog,log,logand,% + logior,lsh,mapcar,max,mem,member,menucmd,menugroup,min,minusp,% + mode_tile,namedobjdict,nentsel,nentselp,new_dialog,not,nth,% + null,numberp,open,or,osnap,polar,prin1,princ,print,progn,prompt,% + quit,quote,read,read-char,read-line,redraw,regapp,rem,repeat,% + reverse,rtos,set,set_tile,setcfg,setenv,setfunhelp,setq,% + setvar,setview,sin,slide_image,snvalid,sqrt,ssadd,ssdel,ssget,% + ssgetfirst,sslength,ssmemb,ssname,ssnamex,sssetfirst,startapp,% + start_dialog,start_image,start_list,strcase,strcat,strlen,subst,% + substr,tablet,tblnext,tblobjname,tblsearch,term_dialog,terpri,% + textbox,textpage,textscr,trace,trans,type,unload_dialog,untrace,% + vector_image,ver,vl-acad-defun,vl-acad-undefun,vl-arx-import,% + vl-bb-ref,vl-bb-set,vl-catch-all-apply,% + vl-catch-all-error-message,vl-catch-all-error-p,vl-cmdf,vl-consp,% + vl-directory-files,vl-doc-export,vl-doc-import,vl-doc-ref,% + vl-doc-set,vl-every,vl-exit-with-error,vl-exit-with-value,% + vl-file-copy,vl-file-delete,vl-file-directory-p,vl-file-rename,% + vl-file-size,vl-file-systime,vl-filename-base,% + vl-filename-directory,vl-filename-extension,vl-filename-mktemp,% + vl-get-resource,vl-list*,vl-list->string,% + vl-list-exported-functions,vl-list-length,vl-list-loaded-vlx,% + vl-load-all,vl-load-com,vl-load-reactors,vl-member-if,% + vl-member-if-not,vl-position,vl-prin1-to-string,% + vl-princ-to-string,vl-propagate,vl-registry-delete,% + vl-registry-descendents,vl-registry-read,vl-registry-write,% + vl-remove,vl-remove-if,vl-remove-if-not,vl-some,vl-sort,% + vl-sort-i,vl-string->list,vl-string-elt,vl-string-left-trim,% + vl-string-mismatch,vl-string-position,vl-string-right-trim,% + vl-string-search,vl-string-subst,vl-string-translate,% + vl-string-trim,vl-symbol-name,vl-symbol-value,vl-symbolp,% + vl-unload-vlx,vl-vbaload,vl-vbarun,vl-vlx-loaded-p,vlax-3D-point,% + vlax-add-cmd,vlax-create-object,vlax-curve-getArea,% + vlax-curve-getDistAtParam,vlax-curve-getDistAtPoint,% + vlax-curve-getEndParam,vlax-curve-getEndPoint,% + vlax-curve-getParamAtDist,vlax-curve-getParamAtPoint,% + vlax-curve-getPointAtDist,vlax-curve-getPointAtParam,% + vlax-curve-getStartParam,vlax-curve-getStartPoint,% + vlax-curve-isClosed,vlax-curve-isPeriodic,vlax-curve-isPlanar,% + vlax-curve-getClosestPointTo,% + vlax-curve-getClosestPointToProjection,vlax-curve-getFirstDeriv,% + vlax-curve-getSecondDeriv,vlax-dump-object,% + vlax-ename->vla-object,vlax-erased-p,vlax-for,% + vlax-get-acad-object,vlax-get-object,vlax-get-or-create-object,% + vlax-get-property,vlax-import-type-library,vlax-invoke-method,% + vlax-ldata-delete,vlax-ldata-get,vlax-ldata-list,vlax-ldata-put,% + vlax-ldata-test,vlax-make-safearray,vlax-make-variant,% + vlax-map-collection,vlax-method-applicable-p,% + vlax-object-released-p,vlax-product-key,% + vlax-property-available-p,vlax-put-property,vlax-read-enabled-p,% + vlax-release-object,vlax-remove-cmd,vlax-safearray-fill,% + vlax-safearray-get-dim,vlax-safearray-get-element,% + vlax-safearray-get-l-bound,vlax-safearray-get-u-bound,% + vlax-safearray-put-element,vlax-safearray-type,% + vlax-safearray->list,vlax-tmatrix,vlax-typeinfo-available-p,% + vlax-variant-change-type,vlax-variant-type,vlax-variant-value,% + vlax-vla-object->ename,vlax-write-enabled-p,vlisp-compile,% + vlr-acdb-reactor,vlr-add,vlr-added-p,vlr-beep-reaction,% + vlr-command-reactor,vlr-current-reaction-name,vlr-data,% + vlr-data-set,vlr-deepclone-reactor,vlr-docmanager-reactor,% + vlr-dwg-reactor,vlr-dxf-reactor,vlr-editor-reactor,% + vlr-insert-reactor,vlr-linker-reactor,vlr-lisp-reactor,% + vlr-miscellaneous-reactor,vlr-mouse-reactor,vlr-notification,% + vlr-object-reactor,vlr-owner-add,vlr-owner-remove,vlr-owners,% + vlr-pers,vlr-pers-list,vlr-pers-p,vlr-pers-release,% + vlr-reaction-names,vlr-reaction-set,vlr-reactions,vlr-reactors,% + vlr-remove,vlr-remove-all,vlr-set-notification,% + vlr-sysvar-reactor,vlr-toolbar-reactor,vlr-trace-reaction,% + vlr-type,vlr-types,vlr-undo-reactor,vlr-wblock-reactor,% + vlr-window-reactor,vlr-xref-reactor,vports,wcmatch,while,% + write-char,write-line,xdroom,xdsize,zerop},% + alsodigit=->,% + otherkeywords={1+,1-},% + sensitive=false,% + morecomment=[l];,% + morecomment=[l];;,% + morestring=[b]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % @@ -951,12 +1578,12 @@ nor under a different one. % Help me! % \begingroup % \begin{macrocode} -%<*logo> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage{Logo}% +\lst@definelanguage{Logo}% % ??? {end,unix} also keywords - {keywords={and,atan,arctan,both,break,bf,bl,butfirst,butlast,% + {morekeywords={and,atan,arctan,both,break,bf,bl,butfirst,butlast,% cbreak, close,co,continue,cos,count,clearscreen,cs,debquit,% describe,diff,difference,ed,edit,either,emptyp,equalp,er,erase,% errpause,errquit,fifp,filefprint,fifty,fileftype,fip,fileprint,% @@ -977,25 +1604,82 @@ nor under a different one. scrunch,seth,setheading,setscrun,setscrunch,setxy,shownp,st,% showturtle,towardsxy,clean,wipeclean,xcor,ycor,tur,turtle,% display,dpy},% - sensitive=false% ??? - }% + sensitive=f% ??? + }[keywords]% % \end{macrocode} % \begin{macrocode} -% +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Make} +% +% \lstthanks{Rolf~Niepraschk}{niepraschk@ptb.de}{2000/01/10} sent me the new +% definitions. \lstthanks{Markus~Pahlow}{pahlowm@mar.dfo-mpo.gc.ca}{2001/10/12} +% found a missing comma and added some keywords, which improve the highlighting +% with |makemacrouse=true| (but I haven't tested this). +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% Make definitions (c) 2000 Rolf Niepraschk +%% +\lst@definelanguage[gnu]{make}% + {morekeywords={SHELL,MAKE,MAKEFLAGS,$@,$\%,$<,$?,$^,$+,$*,% + @,^,<,\%,+,?,*,% Markus Pahlow + export,unexport,include,override,define,ifdef,ifneq,ifeq,else,% + endif,vpath,subst,patsubst,strip,findstring,filter,filter-out,% + sort,dir,notdir,suffix,basename,addsuffix,addprefix,join,word,% + words,firstword,wildcard,shell,origin,foreach,% + @D,@F,*D,*F,\%D,\%F, % \end{macrocode} % \endgroup % % % \subsection{Matlab} % -% I took the keywords from \texttt{http://www.utexas.edu/math/Matlab/Manual} , but I removed the keywords |i|, |j| and |tmp| --- the change was proposed by \lsthelper{Kai Below}{below@tu-harburg.de}{1998/09/21}{Matlab: keywords i,j,tmp removed}. +% I took the keywords from \texttt{http://www.utexas.edu/math/Matlab/Manual}, +% but I removed the keywords |i|, |j| and |tmp|---the change was proposed by +% \lsthelper{Kai Below}{below@tu-harburg.de}{1998/09/21}{Matlab: keywords +% i,j,tmp removed}. % \begingroup % \begin{macrocode} -%<*matlab> +%<*lang1> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{matlab}% - {keywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% +\lst@definelanguage{Matlab}% + {morekeywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% all,angle,ans,any,asec,asech,asin,asinh,atan,atan2,atanh,auread,% auwrite,axes,axis,balance,bar,bessel,besselk,bessely,beta,% betainc,betaln,blanks,bone,break,brighten,capture,cart2pol,% @@ -1061,39 +1745,292 @@ nor under a different one. viewmtx,waitforbuttonpress,waterfall,wavread,wavwrite,what,% whatsnew,which,while,white,whitebg,who,whos,wilkinson,wk1read,% wk1write,xlabel,xor,ylabel,zeros,zlabel,zoom},% - sensitive=true,% - commentline={\%},% - stringizer=[m]{'}% + sensitive,% + morecomment=[l]\%,% + morestring=[m]'% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Mathematica} +% +% \lstthanks{Michael Wiese}{wiese@itwm.uni-kl.de}{1999/02/25} typed in all the +% keywords! +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +%% +%% Mathematica definitions (c) 1999 Michael Wiese +%% +\lst@definelanguage[3.0]{Mathematica}[1.0]{Mathematica}% + {morekeywords={Abort,AbortProtect,AbsoluteDashing,AbsolutePointSize,% + AbsoluteThickness,AbsoluteTime,AccountingFormAiry,AiPrime,AiryBi,% + AiryBiPrime,Alternatives,AnchoredSearch,AxesEdge,AxesOrigin,% + AxesStyle,Background,BetaRegularized,BoxStyle,C,CheckAbort,% + Circle,ClebschGordan,CMYKColor,ColorFunction,ColorOutput,Compile,% + Compiled,CompiledFunction,ComplexExpand,ComposeList,Composition,% + ConstrainedMax,ConstrainedMin,Contexts,ContextToFilename,% + ContourLines,Contours,ContourShading,ContourSmoothing,% + ContourStyle,CopyDirectory,CopyFile,CosIntegral,CreateDirectory,% + Cuboid,Date,DeclarePackage,DefaultColor,DefaultFont,Delete,% + DeleteCases,DeleteDirectory,DeleteFile,Dialog,DialogIndent,% + DialogProlog,DialogSymbols,DigitQ,Directory,DirectoryStack,Disk,% + Dispatch,DownValues,DSolve,Encode,Epilog,Erfc,Evaluate,% + ExponentFunction,FaceGrids,FileByteCount,FileDate,FileNames,% + FileType,Find,FindList,FixedPointList,FlattenAt,Fold,FoldList,% + Frame,FrameLabel,FrameStyle,FrameTicks,FromCharacterCode,% + FromDate,FullGraphics,FullOptions,GammaRegularized,% + GaussianIntegers,GraphicsArray,GraphicsSpacing,GridLines,% + GroebnerBasis,Heads,HeldPart,HomeDirectory,Hue,IgnoreCases,% + InputStream,Install,InString,IntegerDigits,InterpolatingFunction,% + InterpolatingPolynomial,Interpolation,Interrupt,InverseFunction,% + InverseFunctions,JacobiZeta,LetterQ,LinearProgramming,ListPlay,% + LogGamma,LowerCaseQ,MachineNumberQ,MantissaExponent,MapIndexed,% + MapThread,MatchLocalNames,MatrixExp,MatrixPower,MeshRange,% + MeshStyle,MessageList,Module,NDSolve,NSolve,NullRecords,% + NullWords,NumberFormat,NumberPadding,NumberSigns,OutputStream,% + PaddedForm,ParentDirectory,Pause,Play,PlayRange,PlotRegion,% + PolygonIntersections,PolynomialGCD,PolynomialLCM,PolynomialMod,% + PostScript,PowerExpand,PrecisionGoal,PrimePi,Prolog,% + QRDecomposition,Raster,RasterArray,RealDigits,Record,RecordLists,% + RecordSeparators,ReleaseHold,RenameDirectory,RenameFile,% + ReplaceHeldPart,ReplacePart,ResetDirectory,Residue,% + RiemannSiegelTheta,RiemannSiegelZ,RotateLabel,SameTest,% + SampleDepth,SampledSoundFunction,SampledSoundList,SampleRate,% + SchurDecomposition,SessionTime,SetAccuracy,SetDirectory,% + SetFileDate,SetPrecision,SetStreamPosition,Shallow,SignPadding,% + SinIntegral,SixJSymbol,Skip,Sound,SpellingCorrection,% + SphericalRegion,Stack,StackBegin,StackComplete,StackInhibit,% + StreamPosition,Streams,StringByteCount,StringConversion,% + StringDrop,StringInsert,StringPosition,StringReplace,% + StringReverse,StringTake,StringToStream,SurfaceColor,% + SyntaxLength,SyntaxQ,TableAlignments,TableDepth,% + TableDirections,TableHeadings,TableSpacing,ThreeJSymbol,TimeUsed,% + TimeZone,ToCharacterCode,ToDate,ToHeldExpression,TokenWords,% + ToLowerCase,ToUpperCase,Trace,TraceAbove,TraceBackward,% + TraceDepth,TraceDialog,TraceForward,TraceOff,TraceOn,% + TraceOriginal,TracePrint,TraceScan,Trig,Unevaluated,Uninstall,% + UnsameQ,UpperCaseQ,UpValues,ViewCenter,ViewVertical,With,Word,% + WordSearch,WordSeparators},% + morendkeywords={Stub,Temporary,$Aborted,$BatchInput,$BatchOutput,% + $CreationDate,$DefaultFont,$DumpDates,$DumpSupported,$Failed,% + $Input,$Inspector,$IterationLimit,$Language,$Letters,$Linked,% + $LinkSupported,$MachineEpsilon,$MachineID,$MachineName,% + $MachinePrecision,$MachineType,$MaxMachineNumber,$MessageList,% + $MessagePrePrint,$MinMachineNumber,$ModuleNumber,$NewMessage,% + $NewSymbol,$Notebooks,$OperatingSystem,$Packages,$PipeSupported,% + $PreRead,$ReleaseNumber,$SessionID,$SoundDisplayFunction,% + $StringConversion,$StringOrder,$SyntaxHandler,$TimeUnit,% + $VersionNumber}% }% % \end{macrocode} % \begin{macrocode} -% +\lst@definelanguage[1.0]{Mathematica}% + {morekeywords={Abs,Accuracy,AccurayGoal,AddTo,AiryAi,AlgebraicRules,% + AmbientLight,And,Apart,Append,AppendTo,Apply,ArcCos,ArcCosh,% + ArcCot,ArcCoth,ArcCsc,ArcCsch,ArcSec,ArcSech,ArcSin,ArcSinh,% + ArcTan,ArcTanh,Arg,ArithmeticGeometricMean,Array,AspectRatio,% + AtomQ,Attributes,Axes,AxesLabel,BaseForm,Begin,BeginPackage,% + BernoulliB,BesselI,BesselJ,BesselK,BesselY,Beta,Binomial,Blank,% + BlankNullSequence,BlankSequence,Block,Boxed,BoxRatios,Break,Byte,% + ByteCount,Cancel,Cases,Catch,Ceiling,CForm,Character,Characters,% + ChebyshevT,ChebyshevU,Check,Chop,Clear,ClearAll,ClearAttributes,% + ClipFill,Close,Coefficient,CoefficientList,Collect,ColumnForm,% + Complement,Complex,CompoundExpression,Condition,Conjugate,% + Constants,Context,Continuation,Continue,ContourGraphics,% + ContourPlot,Cos,Cosh,Cot,Coth,Count,Csc,Csch,Cubics,Cyclotomic,% + D,Dashing,Decompose,Decrement,Default,Definition,Denominator,% + DensityGraphics,DensityPlot,Depth,Derivative,Det,DiagonalMatrix,% + DigitBlock,Dimensions,DirectedInfinity,Display,DisplayFunction,% + Distribute,Divide,DivideBy,Divisors,DivisorSigma,Do,Dot,Drop,Dt,% + Dump,EdgeForm,Eigensystem,Eigenvalues,Eigenvectors,Eliminate,% + EllipticE,EllipticExp,EllipticF,EllipticK,EllipticLog,EllipticPi,% + EllipticTheta,End,EndPackage,EngineeringForm,Environment,Equal,% + Erf,EulerE,EulerPhi,EvenQ,Exit,Exp,Expand,ExpandAll,% + ExpandDenominator,ExpandNumerator,ExpIntegralE,ExpIntegralEi,% + Exponent,Expression,ExtendedGCD,FaceForm,Factor,FactorComplete,% + Factorial,Factorial2,FactorInteger,FactorList,FactorSquareFree,% + FactorSquareFreeList,FactorTerms,FactorTermsList,FindMinimum,% + FindRoot,First,Fit,FixedPoint,Flatten,Floor,FontForm,For,Format,% + FormatType,FortranForm,Fourier,FreeQ,FullDefinition,FullForm,% + Function,Gamma,GCD,GegenbauerC,General,Get,Goto,Graphics,% + Graphics3D,GrayLevel,Greater,GreaterEqual,Head,HermiteH,% + HiddenSurface,Hold,HoldForm,Hypergeometric0F1, Hypergeometric1F1,% + Hypergeometric2F1,HypergeometricU,Identity,IdentityMatrix,If,Im,% + Implies,In,Increment,Indent,Infix,Information,Inner,Input,% + InputForm,InputString,Insert,Integer,IntegerQ,Integrate,% + Intersection,Inverse,InverseFourier,InverseJacobiSN,% + InverseSeries,JacobiAmplitude,JacobiP,JacobiSN,JacobiSymbol,Join,% + Label,LaguerreL,Last,LatticeReduce,LCM,LeafCount,LegendreP,% + LegendreQ,LegendreType,Length,LerchPhi,Less,LessEqual,Level,% + Lighting,LightSources,Limit,Line,LinearSolve,LineBreak,List,% + ListContourPlot,ListDensityPlot,ListPlot,ListPlot3D,Literal,Log,% + LogicalExpand,LogIntegral,MainSolve,Map,MapAll,MapAt,MatchQ,% + MatrixForm,MatrixQ,Max,MaxBend,MaxMemoryUsed,MemberQ,% + MemoryConstrained,MemoryInUse,Mesh,Message,MessageName,Messages,% + Min,Minors,Minus,Mod,Modulus,MoebiusMu,Multinomial,N,NameQ,Names,% + NBernoulliB,Needs,Negative,Nest,NestList,NIntegrate,% + NonCommutativeMultiply,NonConstants,NonNegative,Normal,Not,% + NProduct,NSum,NullSpace,Number,NumberForm,NumberPoint,NumberQ,% + NumberSeparator,Numerator,O,OddQ,Off,On,OpenAppend,OpenRead,% + OpenTemporary,OpenWrite,Operate,Optional,Options,Or,Order,% + OrderedQ,Out,Outer,OutputForm,PageHeight,PageWidth,% + ParametricPlot,ParametricPlot3D,Part,Partition,PartitionsP,% + PartitionsQ,Pattern,Permutations,Plot,Plot3D,PlotDivision,% + PlotJoined,PlotLabel,PlotPoints,PlotRange,PlotStyle,Pochhammer,% + Plus,Point,PointSize,PolyGamma,Polygon,PolyLog,PolynomialQ,% + PolynomialQuotient,PolynomialRemainder,Position,Positive,Postfix,% + Power,PowerMod,PrecedenceForm,Precision,PreDecrement,Prefix,% + PreIncrement,Prepend,PrependTo,Prime,PrimeQ,Print,PrintForm,% + Product,Protect,PseudoInverse,Put,PutAppend,Quartics,Quit,% + Quotient,Random,Range,Rational,Rationalize,Raw,Re,Read,ReadList,% + Real,Rectangle,Reduce,Remove,RenderAll,Repeated,RepeatedNull,% + Replace,ReplaceAll,ReplaceRepeated,Rest,Resultant,Return,Reverse,% + RGBColor,Roots,RotateLeft,RotateRight,Round,RowReduce,Rule,% + RuleDelayed,Run,RunThrough,SameQ,Save,Scaled,Scan,ScientificForm,% + Sec,Sech,SeedRandom,Select,Sequence,SequenceForm,Series,% + SeriesData,Set,SetAttributes,SetDelayed,SetOptions,Shading,Share,% + Short,Show,Sign,Signature,Simplify,Sin,SingularValues,Sinh,% + Skeleton,Slot,SlotSequence,Solve,SolveAlways,Sort,% + SphericalHarmonicY,Splice,Sqrt,StirlingS1,StirlingS2,String,% + StringBreak,StringForm,StringJoin,StringLength,StringMatchQ,% + StringSkeleton,Subscript,Subscripted,Subtract,SubtractForm,Sum,% + Superscript,SurfaceGraphics,Switch,Symbol,Table,TableForm,TagSet,% + TagSetDelayed,TagUnset,Take,Tan,Tanh,ToString,TensorRank,TeXForm,% + Text,TextForm,Thickness,Thread,Through,Throw,Ticks,% + TimeConstrained,Times,TimesBy,Timing,ToExpression,Together,% + ToRules,ToString,TotalHeight,TotalWidth,Transpose,TreeForm,TrueQ,% + Unequal,Union,Unique,Unprotect,Unset,Update,UpSet,UpSetDelayed,% + ValueQ,Variables,VectorQ,ViewPoint,WeierstrassP,% + WeierstrassPPrime,Which,While,WorkingPrecision,Write,WriteString,% + Xor,ZeroTest,Zeta},% + morendkeywords={All,Automatic,Catalan,ComplexInfinity,Constant,% + Degree,E,EndOfFile,EulerGamma,False,Flat,GoldenRatio,HoldAll,% + HoldFirst,HoldRest,I,Indeterminate,Infinity,Listable,Locked,% + Modular,None,Null,OneIdentity,Orderless,Pi,Protected,% + ReadProtected,True,$CommandLine,$Context,$ContextPath,$Display,% + $DisplayFunction,$Echo,$Epilog,$IgnoreEOF,$Line,$Messages,% + $Output,$Path,$Post,$Pre,$PrePrint,$RecursionLimit,$System,% + $Urgent,$Version},% + sensitive,% + morecomment=[s]{(*}{*)},% + morestring=[d]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{Mercury} % -% \lsthelper{Dominique de Waleffe}{ddw@miscrit.be}{1997/11/24}{Mercury} mailed me these data. +% \lstthanks{Dominique~de~Waleffe}{ddw@miscrit.be}{1997/11/24} mailed me the +% data and \lstthanks{Ralph~Becket}{rbeck@microsoft.com}{2001/05/01} extended +% the definition. % \begingroup % \begin{macrocode} -%<*mercury> +%<*lang2> % \end{macrocode} % \begin{macrocode} -%% (c) 1997 Dominique de Waleffe -\lstdefinelanguage{Mercury}% -% ??? add :: -> --> ---> :- as keywords - {keywords={pred,type,module,end_module,import_module,mode,% - pragma,func,lambda,det,semidet,erroneous,multi,true,fail,is,in,% - out,di,uo,ui,interface,implementation},% - sensitive=false,% - commentline={\%},% - singlecomment={/*}{*/},% - stringizer=[bd]{"'}% - }% +%% +%% Mercury definition (c) 1997 Dominique de Waleffe +%% Extended (c) 2001 Ralph Becket +%% +\lst@definelanguage{Mercury}% + {otherkeywords={::,->,-->,--->,:-,==,=>,<=,<=>},% + morekeywords={module,include_module,import_module,interface,% + end_module,implementation,mode,is,failure,semidet,nondet,det,% + multi,erroneous,inst,in,out,di,uo,ui,type,typeclass,instance,% + where,with_type,pred,func,lambda,impure,semipure,if,then,else,% + some,all,not,true,fail,pragma,memo,no_inline,inline,loop_check,% + minimal_model,fact_table,type_spec,terminates,does_not_terminate,% + check_termination,promise_only_solution,unsafe_promise_unique,% + source_file,obsolete,import,export,c_header_code,c_code,% + foreign_code,foreign_proc,may_call_mercury,will_not_call_mercury,% + thread_safe,not_thread_safe},% + sensitive=t,% + morecomment=[l]\%,% + morecomment=[s]{/*}{*/},% + morestring=[bd]",% + morestring=[bd]'% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Miranda} +% +% Thanks to \lsthelper{Peter~Bartke}{bartke@inf.fu-berlin.de}{1999/01/30}{} +% for providing the definition. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% Miranda definition (c) 1998 Peter Bartke +%% +%% Miranda: pure lazy functional language with polymorphic type system, +%% garbage collection and functions as first class citizens +%% +\lst@definelanguage{Miranda}% + {morekeywords={abstype,div,if,mod,otherwise,readvals,show,type,where,% + with,bool,char,num,sys_message,False,True,Appendfile,Closefile,% + Exit,Stderr,Stdout,System,Tofile,\%include,\%export,\%free,% + \%insert,abs,and,arctan,cjustify,code,concat,const,converse,cos,% + decode,digit,drop,dropwhile,entier,error,exp,filemode,filter,% + foldl,foldl1,foldr,foldr1,force,fst,getenv,hd,hugenum,id,index,% + init,integer,iterate,last,lay,layn,letter,limit,lines,ljustify,% + log,log10,map,map2,max,max2,member,merge,min,min2,mkset,neg,% + numval,or,pi,postfix,product,read,rep,repeat,reverse,rjustify,% + scan,seq,showfloat,shownum,showscaled,sin,snd,sort,spaces,sqrt,% + subtract,sum,system,take,takewhile,tinynum,tl,transpose,undef,% + until,zip2,zip3,zip4,zip5,zip6,zip},% + sensitive,% + morecomment=[l]||,% + morestring=[b]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{ML} +% +% Thanks to \lstthanks{Torben~Hoffmann}{toho@it.dtu.dk}{1999/02/18} for +% providing the definition. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% ML definition (c) 1999 Torben Hoffmann +%% +\lst@definelanguage{ML}% + {morekeywords={abstype,and,andalso,as,case,do,datatype,else,end,% + eqtype,exception,fn,fun,functor,handle,if,in,include,infix,% + infixr,let,local,nonfix,of,op,open,orelse,raise,rec,sharing,sig,% + signature,struct,structure,then,type,val,with,withtype,while},% + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[d]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % @@ -1111,48 +2048,255 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*modula> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{Modula-2}% - {keywords={AND,ARRAY,BEGIN,BY,CASE,CONST,DIV,DO,ELSE,ELSIF,END,EXIT,% - EXPORT,FOR,FROM,IF,IMPLEMENTATION,IMPORT,IN,MOD,MODULE,NOT,OF,% - OR,POINTER,PROCEDURE,QUALIFIED,RECORD,REPEAT,RETURN,SET,THEN,% +\lst@definelanguage{Modula-2}% + {morekeywords={AND,ARRAY,BEGIN,BY,CASE,CONST,DIV,DO,ELSE,ELSIF,END,% + EXIT,EXPORT,FOR,FROM,IF,IMPLEMENTATION,IMPORT,IN,MOD,MODULE,NOT,% + OF,OR,POINTER,PROCEDURE,QUALIFIED,RECORD,REPEAT,RETURN,SET,THEN,% TYPE,UNTIL,VAR,WHILE,WITH,ABS,BITSET,BOOLEAN,CAP,CARDINAL,CHAR,% CHR,DEC,EXCL,FALSE,FLOAT,HALT,HIGH,INC,INCL,INTEGER,LONGCARD,% LONGINT,LONGREAL,MAX,MIN,NIL,ODD,ORD,PROC,REAL,SIZE,TRUE,TRUNC,% - VAL},% - sensitive=true,% - nestedcomment={(*}{*)},% - stringizer=[d]{'"}% - }% + VAL,DEFINITION,LOOP},% added keywords due to Peter Bartke 99/07/22 + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} +% \endgroup +% +% +% \subsection{NASTRAN} +% +% \begingroup +% \begin{macrocode} +%<*lang3> +% \end{macrocode} +% The definition is from \lsthelper{Jeffrey Ratcliffe} +% {Jeffrey.Ratcliffe@m.eads.net}{2002/02/21}{}---except the +% \texttt{MoreSelectCharTable} part which simulates the keyword +% \texttt{BEGIN BULK}. +% \begin{macrocode} +\lst@definelanguage{NASTRAN} + {morekeywords={ENDDATA},% + morecomment=[l]$,% + MoreSelectCharTable=% + \lst@CArgX BEGIN\ BULK\relax\lst@CDef{}% + {\lst@ifmode\else \ifnum\lst@length=\z@ + \lst@EnterMode{\lst@GPmode}{\lst@modetrue + \let\lst@currstyle\lst@gkeywords@sty}% + \fi \fi}% + {\ifnum\lst@mode=\lst@GPmode + \lst@XPrintToken \lst@LeaveMode + \fi}% + }[keywords,comments]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup % % % \subsection{Oberon-2} % % \begingroup % \begin{macrocode} -%<*oberon> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage{Oberon-2}% - {keywords={ARRAY,BEGIN,BOOLEAN,BY,CASE,CHAR,CONST,DIV,DO,ELSE,% +\lst@definelanguage{Oberon-2}% + {morekeywords={ARRAY,BEGIN,BOOLEAN,BY,CASE,CHAR,CONST,DIV,DO,ELSE,% ELSIF,END,EXIT,FALSE,FOR,IF,IMPORT,IN,INTEGER,IS,LONGINT,% LONGREAL,LOOP,MOD,MODULE,NIL,OF,OR,POINTER,PROCEDURE,REAL,RECORD,% REPEAT,RETURN,SET,SHORTINT,THEN,TO,TRUE,TYPE,UNTIL,VAR,WHILE,% WITH,ABS,ASH,CAP,CHR,COPY,DEC,ENTIER,EXCL,HALT,INC,INCL,LEN,LONG,% MAX,MIN,NEW,ODD,ORD,SHORT,SIZE},% - sensitive=true,% - nestedcomment={(*}{*)},% - stringizer=[d]{'"}% - }% + sensitive,% + morecomment=[n]{(*}{*)},% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{OCL} +% +% This definition is based on chapter 7 of the OMG UML standard version 1.3: +% \begin{itemize} +% \item +% \textsc{OMG}: +% \textbf{OMG Unified Modeling Language Specification}; +% {\copyright} 1999 OMG; +% Available at \texttt{ftp://ftp.omg.org/pub/docs/ad/99-06-08.pdf}. +% \end{itemize}% +% This language is due to \lstthanks{Achim~D.~Brucker} +% {brucker@informatik.uni-freiburg.de}{2000/08/14}. +% +% \begingroup +% \begin{macrocode} +%<*lang3> +% \end{macrocode} +% \begin{macrocode} +%% +%% OCL definition (c) 2000 Achim D. Brucker +%% +%% +%% You are allowed to use, modify and distribute this code either under +%% the terms of the LPPL (version 1.0 or later) or the GPL (version 2.0 +%% or later). +%% +% \end{macrocode} +% First we define are very decorative style. In the OMG standard only the +% boolean (infix (?)) operations are highlighted, but I think all OCL-defined +% operations should be highlighted, because they are \emph{guaranteed} to be +% side-effect-free (in OCL only side effect free evaluations or path +% expressions are allowed). +% \begin{macrocode} +\lst@definelanguage[decorative]{OCL}[OMG]{OCL} + {otherkeywords={@pre},% + morendkeywords={name,attributes,associatoinEnds,operations,% + supertypes,allSupertypes,allInstances,oclIsKindOf,oclIsTypeOf,% + oclAsType,oclInState,oclIsNew,evaluationType,abs,floor,round,max,% + min,div,mod,size,concat,toUpper,toLower,substring,includes,% + excludes,count,includesAll,exludesAll,isEmpty,notEmpty,sum,% + exists,forAll,isUnique,sortedBy,iterate,union,intersection,% + including,excluding,symmetricDifference,select,reject,collect,% + asSequence,asBag,asSequence,asSet,append,prepend,subSequence,at,% + first,last,true,false,isQuery}% + }% +% \end{macrocode} +% Remark: "isQuery" is not real OCL, but a important attribute of the +% underlying UML model. +% +% The dialect called \texttt{OMG} is a very spare version. If you use +% this variant with bold style for first and second order keywords you +% get the look and feel of the OMG standard. First order keywords are the +% OCL context declarations (see section 7.3 of the OMG standard): +% \begin{macrocode} +\lst@definelanguage[OMG]{OCL}% + {morekeywords={context,pre,inv,post},% +% \end{macrocode} +% Second order keywords are the operation which are defined for type +% Boolean (see pages 7-34/35 of the OMG standard) and the let-operation +% (in principle these are the infix operations): +% \begin{macrocode} + ndkeywords={or,xor,and,not,implies,if,then,else,endif},% +% \end{macrocode} +% Third order keywords are the basic data types as declared in section 7.4 of +% the OMG standard: +% \begin{macrocode} + morerdkeywords={Boolean,Integer,Real,String,Set,Sequence,Bag,% + OclType,OclAny,OclExpression,Enumeration,Collection,},% + sensitive=t,% + morecomment=[l]--,% + morestring=[d]'% + }[keywords,rdkeywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Octave} +% +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% As you can read below the definition is due to \lsthelper{Ulrich G. Wortmann} +% {uliw@erdw.ethz.ch}{2002/02/18}{}. +% \begin{macrocode} +%% +%% Octave definition (c) 2001,2002 Ulrich G. Wortmann +%% +%% +\lst@definelanguage{Octave}% + {morekeywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% + all,angle,ans,any,asec,asech,asin,asinh,atan,atan2,atanh,auread,% + auwrite,axes,axis,balance,bar,bessel,besselk,bessely,beta,% + betainc,betaln,blanks,bone,break,brighten,capture,cart2pol,% + cart2sph,caxis,cd,cdf2rdf,cedit,ceil,chol,cla,clabel,clc,clear,% + clf,clock,close,colmmd,Colon,colorbar,colormap,ColorSpec,colperm,% + comet,comet3,compan,compass,computer,cond,condest,conj,contour,% + contour3,contourc,contrast,conv,conv2,cool,copper,corrcoef,cos,% + cosh,cot,coth,cov,cplxpair,cputime,cross,csc,csch,csvread,% + csvwrite,cumprod,cumsum,cylinder,date,dbclear,dbcont,dbdown,% + dbquit,dbstack,dbstatus,dbstep,dbstop,dbtype,dbup,ddeadv,ddeexec,% + ddeinit,ddepoke,ddereq,ddeterm,ddeunadv,deblank,dec2hex,deconv,% + del2,delete,demo,det,diag,diary,diff,diffuse,dir,disp,dlmread,% + dlmwrite,dmperm,dot,drawnow,echo,eig,ellipj,ellipke,else,elseif,% + end,engClose,engEvalString,engGetFull,engGetMatrix,engOpen,% + engOutputBuffer,engPutFull,engPutMatrix,engSetEvalCallback,% + engSetEvalTimeout,engWinInit,eps,erf,erfc,erfcx,erfinv,% + errorbar,etime,etree,eval,exist,exp,expint,expm,expo,eye,fclose,% + feather,feof,ferror,feval,fft,fft2,fftshift,fgetl,fgets,figure,% + fill,fill3,filter,filter2,find,findstr,finite,fix,flag,fliplr,% + flipud,floor,flops,fmin,fmins,fopen,for,format,fplot,fprintf,% + fread,frewind,fscanf,fseek,ftell,full,function,funm,fwrite,fzero,% + gallery,gamma,gammainc,gammaln,gca,gcd,gcf,gco,get,getenv,% + getframe,ginput,global,gplot,gradient,gray,graymon,grid,griddata,% + gtext,hadamard,hankel,help,hess,hex2dec,hex2num,hidden,hilb,hist,% + hold,home,hostid,hot,hsv,hsv2rgb,if,ifft,ifft2,imag,image,% + imagesc,Inf,info,input,int2str,interp1,interp2,interpft,inv,% + invhilb,isempty,isglobal,ishold,isieee,isinf,isletter,isnan,% + isreal,isspace,issparse,isstr,jet,keyboard,kron,lasterr,lcm,% + legend,legendre,length,lin2mu,line,linspace,load,log,log10,log2,% + loglog,logm,logspace,lookfor,lower,ls,lscov,lu,magic,matClose,% + matDeleteMatrix,matGetDir,matGetFp,matGetFull,matGetMatrix,% + matGetNextMatrix,matGetString,matlabrc,matlabroot,matOpen,% + matPutFull,matPutMatrix,matPutString,max,mean,median,menu,mesh,% + meshc,meshgrid,meshz,mexAtExit,mexCallMATLAB,mexdebug,% + mexErrMsgTxt,mexEvalString,mexFunction,mexGetFull,mexGetMatrix,% + mexGetMatrixPtr,mexPrintf,mexPutFull,mexPutMatrix,mexSetTrapFlag,% + min,more,movie,moviein,mu2lin,mxCalloc,mxCopyCharacterToPtr,% + mxCopyComplex16ToPtr,mxCopyInteger4ToPtr,mxCopyPtrToCharacter,% + mxCopyPtrToComplex16,mxCopyPtrToInteger4,mxCopyPtrToReal8,% + mxCopyReal8ToPtr,mxCreateFull,mxCreateSparse,mxCreateString,% + mxFree,mxFreeMatrix,mxGetIr,mxGetJc,mxGetM,mxGetN,mxGetName,% + mxGetNzmax,mxGetPi,mxGetPr,mxGetScalar,mxGetString,mxIsComplex,% + mxIsFull,mxIsNumeric,mxIsSparse,mxIsString,mxIsTypeDouble,% + mxSetIr,mxSetJc,mxSetM,mxSetN,mxSetName,mxSetNzmax,mxSetPi,% + mxSetPr,NaN,nargchk,nargin,nargout,newplot,nextpow2,nnls,nnz,% + nonzeros,norm,normest,null,num2str,nzmax,ode23,ode45,orient,orth,% + pack,pascal,patch,path,pause,pcolor,pi,pink,pinv,plot,plot3,% + pol2cart,polar,poly,polyder,polyeig,polyfit,polyval,polyvalm,% + pow2,print,printopt,prism,prod,pwd,qr,qrdelete,qrinsert,quad,% + quad8,quit,quiver,qz,rand,randn,randperm,rank,rat,rats,rbbox,% + rcond,real,realmax,realmin,refresh,rem,reset,reshape,residue,% + return,rgb2hsv,rgbplot,rootobject,roots,rose,rosser,rot90,rotate,% + round,rref,rrefmovie,rsf2csf,save,saxis,schur,sec,sech,semilogx,% + semilogy,set,setstr,shading,sign,sin,sinh,size,slice,sort,sound,% + spalloc,sparse,spaugment,spconvert,spdiags,specular,speye,spfun,% + sph2cart,sphere,spinmap,spline,spones,spparms,sprandn,sprandsym,% + sprank,sprintf,spy,sqrt,sqrtm,sscanf,stairs,startup,std,stem,% + str2mat,str2num,strcmp,strings,strrep,strtok,subplot,subscribe,% + subspace,sum,surf,surface,surfc,surfl,surfnorm,svd,symbfact,% + symmmd,symrcm,tan,tanh,tempdir,tempname,terminal,text,tic,title,% + toc,toeplitz,trace,trapz,tril,triu,type,uicontrol,uigetfile,% + uimenu,uiputfile,unix,unwrap,upper,vander,ver,version,view,% + viewmtx,waitforbuttonpress,waterfall,wavread,wavwrite,what,% + whatsnew,which,while,white,whitebg,who,whos,wilkinson,wk1read,% + stderr,stdout,plot,set,endif,wk1write,xlabel,xor,ylabel,zeros,% + zlabel,zoom,endwhile,endfunction},% + sensitive=f,% + morecomment=[l]\#,% + morecomment=[l]\#\#,% + morestring=[m]',% + morestring=[m]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % @@ -1161,25 +2305,14 @@ nor under a different one. % % \begingroup % \begin{macrocode} -%<*pascal> +%<*lang1> % \end{macrocode} +% Thanks to \lsthelper{Andreas Stephan}{Andreas.Stephan@victoria.de}{1998/04/07} +% {alpha, byte, pack, unpack} for reporting non-keywords alpha, byte, pack and +% unpack. % \begin{macrocode} -\lstdefinelanguage[Standard]{Pascal}% - {keywords={alfa,and,array,begin,boolean,byte,case,char,const,div,do,% - downto,else,end,false,file,for,function,get,goto,if,in,integer,% - label,maxint,mod,new,not,of,or,pack,packed,page,program,put,% - procedure,read,readln,real,record,repeat,reset,rewrite,set,text,% - then,to,true,type,unpack,until,var,while,with,write,writeln},% - sensitive=false,% - doublecomment={(*}{*)}{\{}{\}},% - stringizer=[d]{'}% - }% -% \end{macrocode} -% Thanks to \lsthelper{Andreas Stephan}{astepha@wmpi04.math.uni-wuppertal.de}{1998/04/07}{alpha, byte, pack, unpack} for reporting non-keywords alpha, byte, pack and unpack. -% \begin{macrocode} -\lstdefinedrvlanguage[XSC]{Pascal}% - {language=[Standard]Pascal,% - deletekeywords={alfa,byte,pack,unpack},% 1998 Andreas Stephan +\lst@definelanguage[XSC]{Pascal}[Standard]{Pascal} + {deletekeywords={alfa,byte,pack,unpack},% 1998 Andreas Stephan morekeywords={dynamic,external,forward,global,module,nil,operator,% priority,sum,type,use,dispose,mark,page,release,cimatrix,% cinterval,civector,cmatrix,complex,cvector,dotprecision,imatrix,% @@ -1188,15 +2321,13 @@ nor under a different one. ord,pos,pred,round,rval,sign,substring,succ,trunc,ub,ubound}% }% % \end{macrocode} -% % \begin{macrocode} -\lstdefinedrvlanguage[Borland6]{Pascal}% - {language=[Standard]Pascal,% - morekeywords={asm,constructor,destructor,implementation,inline,% - interface,nil,object,shl,shr,string,unit,uses,xor,% - Abs,Addr,ArcTan,Chr,Concat,Copy,Cos,CSeg,DiskFree,DiskSize,% - DosExitCode,DosVersion,DSeg,EnvCount,EnvStr,Eof,Eoln,Exp,% - FExpand,FilePos,FileSize,Frac,FSearch,GetBkColor,GetColor,% +\lst@definelanguage[Borland6]{Pascal}[Standard]{Pascal} + {morekeywords={asm,constructor,destructor,implementation,inline,% + interface,nil,object,shl,shr,string,unit,uses,xor},% + morendkeywords={Abs,Addr,ArcTan,Chr,Concat,Copy,Cos,CSeg,DiskFree,% + DiskSize,DosExitCode,DosVersion,DSeg,EnvCount,EnvStr,Eof,Eoln,% + Exp,FExpand,FilePos,FileSize,Frac,FSearch,GetBkColor,GetColor,% GetDefaultPalette,GetDriverName,GetEnv,GetGraphMode,GetMaxMode,% GetMaxX,GetMaxY,GetModeName,GetPaletteSize,GetPixel,GetX,GetY,% GraphErrorMsg,GraphResult,Hi,ImageSize,InstallUserDriver,% @@ -1229,23 +2360,38 @@ nor under a different one. }% % \end{macrocode} % \begin{macrocode} -% +\lst@definelanguage[Standard]{Pascal}% + {morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,% + do,downto,else,end,false,file,for,function,get,goto,if,in,% + integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% + put,procedure,read,readln,real,record,repeat,reset,rewrite,set,% + text,then,to,true,type,unpack,until,var,while,with,write,% + writeln},% + sensitive=f,% + morecomment=[s]{(*}{*)},% + morecomment=[s]{\{}{\}},% + morestring=[d]'% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{Perl} % -% I got the data from \texttt{http://www.perl.com}. -% But I wish to thank \lsthelper{Herbert~Weinhandl}{weinhand@grz08u.unileoben.ac.at}{}{} for the book 'Learning Perl'. +% I got the data from \texttt{http://www.perl.com}. But I wish to thank +% \lsthelper{Herbert~Weinhandl}{weinhand@grz08u.unileoben.ac.at}{}{} for the +% book `Learning Perl'. % \begingroup % \begin{macrocode} -%<*perl> +%<*lang1> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage{Perl}% - {keywords={abs,accept,alarm,atan2,bind,binmode,bless,caller,chdir,% - chmod,chomp,chop,chown,chr,chroot,close,closedir,connect,% +\lst@definelanguage{Perl}% + {morekeywords={abs,accept,alarm,atan2,bind,binmode,bless,caller,% + chdir,chmod,chomp,chop,chown,chr,chroot,close,closedir,connect,% continue,cos,crypt,dbmclose,dbmopen,defined,delete,die,do,dump,% each,else,elsif,endgrent,endhostent,endnetent,endprotoent,% endpwent,endservent,eof,eval,exec,exists,exit,exp,fcntl,fileno,% @@ -1269,29 +2415,540 @@ nor under a different one. telldir,tie,tied,time,times,tr,truncate,uc,ucfirst,umask,undef,% unless,unlink,unpack,unshift,untie,until,use,utime,values,vec,% wait,waitpid,wantarray,warn,while,write,y},% - sensitive=true,% - commentline={\#},% - stringizer=[b]{"'}% - }% + sensitive,% + morecomment=[l]\#,% + morestring=[b]",% + morestring=[b]',% + MoreSelectCharTable=% + \lst@ReplaceInput{\$\#}{\lst@ProcessOther\$\lst@ProcessOther\#}% + }[keywords,comments,strings]% % \end{macrocode} -% \endgroup -% -% \begin{macro}{\lstSCT@perl} -% We define the 'POD character' |=| and say that after a dollor sign the sharp is nothing else than |\lstCC@ProcessOther\#|. -% In all other cases the comment line indicator is untouched! % \begin{macrocode} -\gdef\lstSCT@perl{% - \lccode`\~=`\=\lowercase{\let\lsts@POD~\let~}\lstCC@ProcessPOD % - \lstCC@SpecialUseAfter{$}{\#}{\lstCC@ProcessOther\#}}% -% \end{macrocode} -% \end{macro} -% \begingroup -% \begin{macrocode} -% +% % \end{macrocode} % \endgroup % % +% \subsection{PHP} +% +% \lstthanks{Luca Balzerani}{lou@latoserver.it}{2002/04/06} sent me this +% language definition. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% PHP definition by Luca Balzerani, +%% +\lst@definelanguage{PHP}% + {morekeywords={% + abs,acos,acosh,addcslashes,addslashes,apache_child_terminate,% + apache_note,apache_setenv,array_change_key_case,array_chunk,% + array_diff,array_fill,array_filter,array_flip,array_intersect,% + array_keys,array_map,array_merge_recursive,array_merge,% + array_pad,array_pop,array_push,array_rand,array_reduce,% + array_search,array_shift,array_slice,array_splice,array_sum,% + array_unshift,array_values,array_walk,array,arsort,ascii2ebcdic,% + asinh,asort,aspell_check_raw,aspell_check,aspell_new,% + assert_options,assert,atan,atan2,atanh,base_convert,% + base64_encode,basename,bcadd,bccomp,bcdiv,bcmod,bcmul,bcpow,% + bcsqrt,bcsub,bin2hex,bind_textdomain_codeset,bindec,% + bzclose,bzcompress,bzdecompress,bzerrno,bzerror,bzerrstr,% + bzopen,bzread,bzwrite,cal_days_in_month,cal_from_jd,cal_info,% + call_user_func_array,call_user_func,call_user_method_array,% + ccvs_add,ccvs_auth,ccvs_command,ccvs_count,ccvs_delete,% + ccvs_init,ccvs_lookup,ccvs_new,ccvs_report,ccvs_return,% + ccvs_sale,ccvs_status,ccvs_textvalue,ccvs_void,ceil,chdir,% + checkdnsrr,chgrp,chmod,chop,chown,chr,chroot,chunk_split,% + clearstatcache,closedir,closelog,com_addref,com_get,com_invoke,% + com_load_typelib,com_load,com_propget,com_propput,com_propset,% + com_set,compact,connection_aborted,connection_status,% + constant,convert_cyr_string,copy,cos,cosh,count_chars,count,% + cpdf_add_outline,cpdf_arc,cpdf_begin_text,cpdf_circle,cpdf_clip,% + cpdf_closepath_fill_stroke,cpdf_closepath_stroke,cpdf_closepath,% + cpdf_curveto,cpdf_end_text,cpdf_fill_stroke,cpdf_fill,% + cpdf_finalize,cpdf_global_set_document_limits,cpdf_import_jpeg,% + cpdf_moveto,cpdf_newpath,cpdf_open,cpdf_output_buffer,% + cpdf_place_inline_image,cpdf_rect,cpdf_restore,cpdf_rlineto,% + cpdf_rotate_text,cpdf_rotate,cpdf_save_to_file,cpdf_save,% + cpdf_set_action_url,cpdf_set_char_spacing,cpdf_set_creator,% + cpdf_set_font_directories,cpdf_set_font_map_file,cpdf_set_font,% + cpdf_set_keywords,cpdf_set_leading,cpdf_set_page_animation,% + cpdf_set_text_matrix,cpdf_set_text_pos,cpdf_set_text_rendering,% + cpdf_set_title,cpdf_set_viewer_preferences,% + cpdf_setdash,cpdf_setflat,cpdf_setgray_fill,cpdf_setgray_stroke,% + cpdf_setlinecap,cpdf_setlinejoin,cpdf_setlinewidth,% + cpdf_setrgbcolor_fill,cpdf_setrgbcolor_stroke,cpdf_setrgbcolor,% + cpdf_show,cpdf_stringwidth,cpdf_stroke,cpdf_text,cpdf_translate,% + crack_closedict,crack_getlastmessage,crack_opendict,crc32,% + crypt,ctype_alnum,ctype_alpha,ctype_cntrl,ctype_digit,% + ctype_lower,ctype_print,ctype_punct,ctype_space,ctype_upper,% + curl_close,curl_errno,curl_error,curl_exec,curl_getinfo,% + curl_setopt,curl_version,current,cybercash_base64_decode,% + cybercash_decr,cybercash_encr,cybermut_creerformulairecm,% + cybermut_testmac,cyrus_authenticate,cyrus_bind,cyrus_close,% + cyrus_query,cyrus_unbind,date,dba_close,dba_delete,dba_exists,% + dba_firstkey,dba_insert,dba_nextkey,dba_open,dba_optimize,% + dba_replace,dba_sync,dbase_add_record,dbase_close,dbase_create,% + dbase_get_record_with_names,dbase_get_record,dbase_numfields,% + dbase_open,dbase_pack,dbase_replace_record,dblist,dbmclose,% + dbmexists,dbmfetch,dbmfirstkey,dbminsert,dbmnextkey,dbmopen,% + dbplus_add,dbplus_aql,dbplus_chdir,dbplus_close,dbplus_curr,% + dbplus_errno,dbplus_find,dbplus_first,dbplus_flush,% + dbplus_freelock,dbplus_freerlocks,dbplus_getlock,% + dbplus_info,dbplus_last,dbplus_lockrel,dbplus_next,dbplus_open,% + dbplus_rchperm,dbplus_rcreate,dbplus_rcrtexact,dbplus_rcrtlike,% + dbplus_restorepos,dbplus_rkeys,dbplus_ropen,dbplus_rquery,% + dbplus_rsecindex,dbplus_runlink,dbplus_rzap,dbplus_savepos,% + dbplus_setindexbynumber,dbplus_sql,dbplus_tcl,dbplus_tremove,% + dbplus_undoprepare,dbplus_unlockrel,dbplus_unselect,% + dbplus_xlockrel,dbplus_xunlockrel,dbx_close,dbx_compare,% + dbx_error,dbx_query,dbx_sort,dcgettext,dcngettext,debugger_off,% + decbin,dechex,decoct,define_syslog_variables,define,defined,% + delete,dgettext,die,dio_close,dio_fcntl,dio_open,dio_read,% + dio_stat,dio_truncate,dio_write,dirname,disk_free_space,% + diskfreespace,dl,dngettext,domxml_add_root,domxml_attributes,% + domxml_dumpmem,domxml_get_attribute,domxml_new_child,% + domxml_node_set_content,domxml_node_unlink_node,domxml_node,% + domxml_set_attribute,domxml_version,dotnet_load,doubleval,each,% + easter_days,ebcdic2ascii,echo,empty,end,ereg_replace,ereg,% + eregi,error_log,error_reporting,escapeshellarg,escapeshellcmd,% + exec,exit,exp,explode,expm1,extension_loaded,extract,ezmlm_hash,% + fbsql_autocommit,fbsql_change_user,fbsql_close,fbsql_commit,% + fbsql_create_blob,fbsql_create_clob,fbsql_create_db,% + fbsql_database_password,fbsql_database,fbsql_db_query,% + fbsql_drop_db,fbsql_errno,fbsql_error,fbsql_fetch_array,% + fbsql_fetch_field,fbsql_fetch_lengths,fbsql_fetch_object,% + fbsql_field_flags,fbsql_field_len,fbsql_field_name,% + fbsql_field_table,fbsql_field_type,fbsql_free_result,% + fbsql_hostname,fbsql_insert_id,fbsql_list_dbs,fbsql_list_fields,% + fbsql_next_result,fbsql_num_fields,fbsql_num_rows,% + fbsql_pconnect,fbsql_query,fbsql_read_blob,fbsql_read_clob,% + fbsql_rollback,fbsql_select_db,fbsql_set_lob_mode,% + fbsql_start_db,fbsql_stop_db,fbsql_tablename,fbsql_username,% + fclose,fdf_add_template,fdf_close,fdf_create,fdf_get_file,% + fdf_get_value,fdf_next_field_name,fdf_open,fdf_save,fdf_set_ap,% + fdf_set_file,fdf_set_flags,fdf_set_javascript_action,% + fdf_set_status,fdf_set_submit_form_action,fdf_set_value,feof,% + fgetc,fgetcsv,fgets,fgetss,file_exists,file,fileatime,filectime,% + fileinode,filemtime,fileowner,fileperms,filepro_fieldcount,% + filepro_fieldtype,filepro_fieldwidth,filepro_retrieve,% + filepro,filesize,filetype,floatval,flock,floor,flush,fopen,% + fputs,fread,frenchtojd,fribidi_log2vis,fscanf,fseek,fsockopen,% + ftell,ftok,ftp_cdup,ftp_chdir,ftp_connect,ftp_delete,ftp_exec,% + ftp_fput,ftp_get,ftp_login,ftp_mdtm,ftp_mkdir,ftp_nlist,% + ftp_put,ftp_pwd,ftp_quit,ftp_rawlist,ftp_rename,ftp_rmdir,% + ftp_size,ftp_systype,ftruncate,func_get_arg,func_get_args,% + function_exists,fwrite,get_browser,get_cfg_var,% + get_class_vars,get_class,get_current_user,get_declared_classes,% + get_defined_functions,get_defined_vars,get_extension_funcs,% + get_included_files,get_loaded_extensions,get_magic_quotes_gpc,% + get_meta_tags,get_object_vars,get_parent_class,% + get_resource_type,getallheaders,getcwd,getdate,getenv,% + gethostbyname,gethostbynamel,getimagesize,getlastmod,getmxrr,% + getmyinode,getmypid,getmyuid,getprotobyname,getprotobynumber,% + getrusage,getservbyname,getservbyport,gettext,gettimeofday,% + gmdate,gmmktime,gmp_abs,gmp_add,gmp_and,gmp_clrbit,gmp_cmp,% + gmp_div_q,gmp_div_qr,gmp_div_r,gmp_div,gmp_divexact,gmp_fact,% + gmp_gcdext,gmp_hamdist,gmp_init,gmp_intval,gmp_invert,% + gmp_legendre,gmp_mod,gmp_mul,gmp_neg,gmp_or,gmp_perfect_square,% + gmp_pow,gmp_powm,gmp_prob_prime,gmp_random,gmp_scan0,gmp_scan1,% + gmp_sign,gmp_sqrt,gmp_sqrtrem,gmp_strval,gmp_sub,gmp_xor,% + gregoriantojd,gzclose,gzcompress,gzdeflate,gzencode,gzeof,% + gzgetc,gzgets,gzgetss,gzinflate,gzopen,gzpassthru,gzputs,gzread,% + gzseek,gztell,gzuncompress,gzwrite,header,headers_sent,hebrev,% + hexdec,highlight_file,highlight_string,htmlentities,% + hw_array2objrec,hw_changeobject,hw_children,hw_childrenobj,% + hw_connect,hw_connection_info,hw_cp,hw_deleteobject,% + hw_docbyanchorobj,hw_document_attributes,hw_document_bodytag,% + hw_document_setcontent,hw_document_size,hw_dummy,hw_edittext,% + hw_errormsg,hw_free_document,hw_getanchors,hw_getanchorsobj,% + hw_getchildcoll,hw_getchildcollobj,hw_getchilddoccoll,% + hw_getobject,hw_getobjectbyquery,hw_getobjectbyquerycoll,% + hw_getobjectbyqueryobj,hw_getparents,hw_getparentsobj,% + hw_getremote,hw_getremotechildren,hw_getsrcbydestobj,hw_gettext,% + hw_identify,hw_incollections,hw_info,hw_inscoll,hw_insdoc,% + hw_insertdocument,hw_insertobject,hw_mapid,hw_modifyobject,% + hw_new_document,hw_objrec2array,hw_output_document,hw_pconnect,% + hw_root,hw_setlinkroot,hw_stat,hw_unlock,hw_who,hypot,% + ibase_blob_cancel,ibase_blob_close,ibase_blob_create,% + ibase_blob_get,ibase_blob_import,ibase_blob_info,% + ibase_close,ibase_commit,ibase_connect,ibase_errmsg,% + ibase_fetch_object,ibase_fetch_row,ibase_field_info,% + ibase_free_result,ibase_num_fields,ibase_pconnect,ibase_prepare,% + ibase_rollback,ibase_timefmt,ibase_trans,icap_close,% + icap_delete_calendar,icap_delete_event,icap_fetch_event,% + icap_list_events,icap_open,icap_rename_calendar,icap_reopen,% + icap_store_event,iconv_get_encoding,iconv_set_encoding,iconv,% + ifx_blobinfile_mode,ifx_byteasvarchar,ifx_close,ifx_connect,% + ifx_create_blob,ifx_create_char,ifx_do,ifx_error,ifx_errormsg,% + ifx_fieldproperties,ifx_fieldtypes,ifx_free_blob,ifx_free_char,% + ifx_get_blob,ifx_get_char,ifx_getsqlca,ifx_htmltbl_result,% + ifx_num_fields,ifx_num_rows,ifx_pconnect,ifx_prepare,ifx_query,% + ifx_update_blob,ifx_update_char,ifxus_close_slob,% + ifxus_free_slob,ifxus_open_slob,ifxus_read_slob,ifxus_seek_slob,% + ifxus_write_slob,ignore_user_abort,image2wbmp,% + imagearc,imagechar,imagecharup,imagecolorallocate,imagecolorat,% + imagecolorclosestalpha,imagecolorclosesthwb,% + imagecolorexact,imagecolorexactalpha,imagecolorresolve,% + imagecolorset,imagecolorsforindex,imagecolorstotal,% + imagecopy,imagecopymerge,imagecopymergegray,imagecopyresampled,% + imagecreate,imagecreatefromgd,imagecreatefromgd2,% + imagecreatefromgif,imagecreatefromjpeg,imagecreatefrompng,% + imagecreatefromwbmp,imagecreatefromxbm,imagecreatefromxpm,% + imagedashedline,imagedestroy,imageellipse,imagefill,% + imagefilledellipse,imagefilledpolygon,imagefilledrectangle,% + imagefontheight,imagefontwidth,imageftbbox,imagefttext,% + imagegd,imagegd2,imagegif,imageinterlace,imagejpeg,imageline,% + imagepalettecopy,imagepng,imagepolygon,imagepsbbox,% + imagepsextendfont,imagepsfreefont,imagepsloadfont,% + imagepstext,imagerectangle,imagesetbrush,imagesetpixel,% + imagesetthickness,imagesettile,imagestring,imagestringup,% + imagesy,imagetruecolortopalette,imagettfbbox,imagettftext,% + imagewbmp,imap_8bit,imap_alerts,imap_append,imap_base64,% + imap_body,imap_bodystruct,imap_check,imap_clearflag_full,% + imap_createmailbox,imap_delete,imap_deletemailbox,imap_errors,% + imap_fetch_overview,imap_fetchbody,imap_fetchheader,% + imap_get_quota,imap_getmailboxes,imap_getsubscribed,imap_header,% + imap_headers,imap_last_error,imap_listmailbox,% + imap_mail_compose,imap_mail_copy,imap_mail_move,imap_mail,% + imap_mime_header_decode,imap_msgno,imap_num_msg,imap_num_recent,% + imap_ping,imap_popen,imap_qprint,imap_renamemailbox,imap_reopen,% + imap_rfc822_parse_headers,imap_rfc822_write_address,% + imap_search,imap_set_quota,imap_setacl,imap_setflag_full,% + imap_status,imap_subscribe,imap_thread,imap_uid,imap_undelete,% + imap_utf7_decode,imap_utf7_encode,imap_utf8,implode,% + in_array,include_once,include,ingres_autocommit,ingres_close,% + ingres_connect,ingres_fetch_array,ingres_fetch_object,% + ingres_field_length,ingres_field_name,ingres_field_nullable,% + ingres_field_scale,ingres_field_type,ingres_num_fields,% + ingres_pconnect,ingres_query,ingres_rollback,ini_alter,% + ini_get,ini_restore,ini_set,intval,ip2long,iptcembed,iptcparse,% + ircg_disconnect,ircg_fetch_error_msg,ircg_get_username,% + ircg_ignore_add,ircg_ignore_del,ircg_is_conn_alive,ircg_join,% + ircg_lookup_format_messages,ircg_msg,ircg_nick,% + ircg_nickname_unescape,ircg_notice,ircg_part,ircg_pconnect,% + ircg_set_current,ircg_set_file,ircg_set_on_die,ircg_topic,% + is_array,is_bool,is_dir,is_double,is_executable,is_file,% + is_int,is_integer,is_link,is_long,is_null,is_numeric,is_object,% + is_real,is_resource,is_scalar,is_string,is_subclass_of,% + is_writable,is_writeable,isset,java_last_exception_clear,% + jddayofweek,jdmonthname,jdtofrench,jdtogregorian,jdtojewish,% + jdtounix,jewishtojd,join,jpeg2wbmp,juliantojd,key,krsort,ksort,% + ldap_8859_to_t61,ldap_add,ldap_bind,ldap_close,ldap_compare,% + ldap_count_entries,ldap_delete,ldap_dn2ufn,ldap_err2str,% + ldap_error,ldap_explode_dn,ldap_first_attribute,% + ldap_first_reference,ldap_free_result,ldap_get_attributes,% + ldap_get_entries,ldap_get_option,ldap_get_values_len,% + ldap_list,ldap_mod_add,ldap_mod_del,ldap_mod_replace,% + ldap_next_attribute,ldap_next_entry,ldap_next_reference,% + ldap_parse_result,ldap_read,ldap_rename,ldap_search,% + ldap_set_rebind_proc,ldap_sort,ldap_start_tls,ldap_t61_to_8859,% + leak,levenshtein,link,linkinfo,list,localeconv,localtime,log,% + log1p,long2ip,lstat,ltrim,mail,% + mailparse_msg_create,mailparse_msg_extract_part_file,% + mailparse_msg_free,mailparse_msg_get_part_data,% + mailparse_msg_get_structure,mailparse_msg_parse_file,% + mailparse_rfc822_parse_addresses,mailparse_stream_encode,% + max,mb_convert_encoding,mb_convert_kana,mb_convert_variables,% + mb_decode_numericentity,mb_detect_encoding,mb_detect_order,% + mb_encode_numericentity,mb_http_input,mb_http_output,% + mb_language,mb_output_handler,mb_parse_str,% + mb_send_mail,mb_strcut,mb_strimwidth,mb_strlen,mb_strpos,% + mb_strwidth,mb_substitute_character,mb_substr,mcal_append_event,% + mcal_create_calendar,mcal_date_compare,mcal_date_valid,% + mcal_day_of_year,mcal_days_in_month,mcal_delete_calendar,% + mcal_event_add_attribute,mcal_event_init,mcal_event_set_alarm,% + mcal_event_set_class,mcal_event_set_description,% + mcal_event_set_recur_daily,mcal_event_set_recur_monthly_mday,% + mcal_event_set_recur_none,mcal_event_set_recur_weekly,% + mcal_event_set_start,mcal_event_set_title,mcal_expunge,% + mcal_fetch_event,mcal_is_leap_year,mcal_list_alarms,% + mcal_next_recurrence,mcal_open,mcal_popen,mcal_rename_calendar,% + mcal_snooze,mcal_store_event,mcal_time_valid,mcal_week_of_year,% + mcrypt_cfb,mcrypt_create_iv,mcrypt_decrypt,mcrypt_ecb,% + mcrypt_enc_get_block_size,mcrypt_enc_get_iv_size,% + mcrypt_enc_get_modes_name,mcrypt_enc_get_supported_key_sizes,% + mcrypt_enc_is_block_algorithm,mcrypt_enc_is_block_mode,% + mcrypt_encrypt,mcrypt_generic_deinit,mcrypt_generic_end,% + mcrypt_generic,mcrypt_get_block_size,mcrypt_get_cipher_name,% + mcrypt_get_key_size,mcrypt_list_algorithms,mcrypt_list_modes,% + mcrypt_module_get_algo_block_size,% + mcrypt_module_get_supported_key_sizes,% + mcrypt_module_is_block_algorithm,mcrypt_module_is_block_mode,% + mcrypt_module_self_test,mcrypt_ofb,md5_file,md5,% + metaphone,method_exists,mhash_count,mhash_get_block_size,% + mhash_keygen_s2k,mhash,microtime,min,ming_setcubicthreshold,% + ming_useswfversion,mkdir,mktime,move_uploaded_file,% + msession_count,msession_create,msession_destroy,% + msession_find,msession_get_array,msession_get,msession_getdata,% + msession_list,msession_listvar,msession_lock,msession_plugin,% + msession_set_array,msession_set,msession_setdata,% + msession_uniq,msession_unlock,msql_affected_rows,msql_close,% + msql_create_db,msql_createdb,msql_data_seek,msql_dbname,% + msql_dropdb,msql_error,msql_fetch_array,msql_fetch_field,% + msql_fetch_row,msql_field_seek,msql_fieldflags,msql_fieldlen,% + msql_fieldtable,msql_fieldtype,msql_free_result,msql_freeresult,% + msql_list_fields,msql_list_tables,msql_listdbs,msql_listfields,% + msql_num_fields,msql_num_rows,msql_numfields,msql_numrows,% + msql_query,msql_regcase,msql_result,msql_select_db,% + msql_tablename,msql,mssql_bind,mssql_close,mssql_connect,% + mssql_execute,mssql_fetch_array,mssql_fetch_assoc,% + mssql_fetch_field,mssql_fetch_object,mssql_fetch_row,% + mssql_field_name,mssql_field_seek,mssql_field_type,% + mssql_get_last_message,mssql_guid_string,mssql_init,% + mssql_min_message_severity,mssql_next_result,mssql_num_fields,% + mssql_pconnect,mssql_query,mssql_result,mssql_rows_affected,% + mt_getrandmax,mt_rand,mt_srand,muscat_close,muscat_get,% + muscat_setup_net,muscat_setup,mysql_affected_rows,% + mysql_close,mysql_connect,mysql_create_db,mysql_data_seek,% + mysql_db_query,mysql_drop_db,mysql_errno,mysql_error,% + mysql_fetch_array,mysql_fetch_assoc,mysql_fetch_field,% + mysql_fetch_object,mysql_fetch_row,mysql_field_flags,% + mysql_field_name,mysql_field_seek,mysql_field_table,% + mysql_free_result,mysql_get_client_info,mysql_get_host_info,% + mysql_get_server_info,mysql_insert_id,mysql_list_dbs,% + mysql_list_tables,mysql_num_fields,mysql_num_rows,% + mysql_query,mysql_result,mysql_select_db,mysql_tablename,% + natcasesort,natsort,ncurses_addch,ncurses_addchnstr,% + ncurses_addnstr,ncurses_addstr,ncurses_assume_default_colors,% + ncurses_attron,ncurses_attrset,ncurses_baudrate,ncurses_beep,% + ncurses_bkgdset,ncurses_border,ncurses_can_change_color,% + ncurses_clear,ncurses_clrtobot,ncurses_clrtoeol,% + ncurses_curs_set,ncurses_def_prog_mode,ncurses_def_shell_mode,% + ncurses_delay_output,ncurses_delch,ncurses_deleteln,% + ncurses_doupdate,ncurses_echo,ncurses_echochar,ncurses_end,% + ncurses_erasechar,ncurses_filter,ncurses_flash,ncurses_flushinp,% + ncurses_halfdelay,ncurses_has_colors,ncurses_has_ic,% + ncurses_has_key,ncurses_hline,ncurses_inch,ncurses_init_color,% + ncurses_init,ncurses_insch,ncurses_insdelln,ncurses_insertln,% + ncurses_instr,ncurses_isendwin,ncurses_keyok,ncurses_killchar,% + ncurses_move,ncurses_mvaddch,ncurses_mvaddchnstr,% + ncurses_mvaddnstr,ncurses_mvaddstr,ncurses_mvcur,% + ncurses_mvgetch,ncurses_mvhline,ncurses_mvinch,ncurses_mvvline,% + ncurses_napms,ncurses_newwin,ncurses_nl,ncurses_nocbreak,% + ncurses_nonl,ncurses_noqiflush,ncurses_noraw,ncurses_putp,% + ncurses_raw,ncurses_refresh,ncurses_resetty,ncurses_savetty,% + ncurses_scr_init,ncurses_scr_restore,ncurses_scr_set,% + ncurses_slk_attr,ncurses_slk_attroff,ncurses_slk_attron,% + ncurses_slk_clear,ncurses_slk_color,ncurses_slk_init,% + ncurses_slk_refresh,ncurses_slk_restore,ncurses_slk_touch,% + ncurses_standout,ncurses_start_color,ncurses_termattrs,% + ncurses_typeahead,ncurses_ungetch,ncurses_use_default_colors,% + ncurses_use_extended_names,ncurses_vidattr,ncurses_vline,% + next,ngettext,nl_langinfo,nl2br,notes_body,notes_copy_db,% + notes_create_note,notes_drop_db,notes_find_note,% + notes_list_msgs,notes_mark_read,notes_mark_unread,% + notes_search,notes_unread,notes_version,number_format,ob_clean,% + ob_end_flush,ob_flush,ob_get_contents,ob_get_length,% + ob_gzhandler,ob_iconv_handler,ob_implicit_flush,ob_start,% + ocicancel,ocicollappend,ocicollassign,ocicollassignelem,% + ocicollmax,ocicollsize,ocicolltrim,ocicolumnisnull,% + ocicolumnprecision,ocicolumnscale,ocicolumnsize,ocicolumntype,% + ocicommit,ocidefinebyname,ocierror,ociexecute,ocifetch,% + ocifetchstatement,ocifreecollection,ocifreecursor,ocifreedesc,% + ociinternaldebug,ociloadlob,ocilogoff,ocilogon,ocinewcollection,% + ocinewdescriptor,ocinlogon,ocinumcols,ociparse,ociplogon,% + ocirollback,ocirowcount,ocisavelob,ocisavelobfile,% + ocisetprefetch,ocistatementtype,ociwritelobtofile,octdec,% + odbc_binmode,odbc_close_all,odbc_close,odbc_columnprivileges,% + odbc_commit,odbc_connect,odbc_cursor,odbc_do,odbc_error,% + odbc_exec,odbc_execute,odbc_fetch_array,odbc_fetch_into,% + odbc_fetch_row,odbc_field_len,odbc_field_name,odbc_field_num,% + odbc_field_scale,odbc_field_type,odbc_foreignkeys,% + odbc_gettypeinfo,odbc_longreadlen,odbc_next_result,% + odbc_num_rows,odbc_pconnect,odbc_prepare,odbc_primarykeys,% + odbc_procedures,odbc_result_all,odbc_result,odbc_rollback,% + odbc_specialcolumns,odbc_statistics,odbc_tableprivileges,% + opendir,openlog,openssl_csr_export_to_file,openssl_csr_export,% + openssl_csr_sign,openssl_error_string,openssl_free_key,% + openssl_get_publickey,openssl_open,openssl_pkcs7_decrypt,% + openssl_pkcs7_sign,openssl_pkcs7_verify,% + openssl_pkey_export,openssl_pkey_new,openssl_private_decrypt,% + openssl_public_decrypt,openssl_public_encrypt,openssl_seal,% + openssl_verify,openssl_x509_check_private_key,% + openssl_x509_export_to_file,openssl_x509_export,% + openssl_x509_parse,openssl_x509_read,ora_bind,ora_close,% + ora_columnsize,ora_columntype,ora_commit,ora_commitoff,% + ora_do,ora_error,ora_errorcode,ora_exec,ora_fetch_into,% + ora_getcolumn,ora_logoff,ora_logon,ora_numcols,ora_numrows,% + ora_parse,ora_plogon,ora_rollback,ord,overload,ovrimos_close,% + ovrimos_connect,ovrimos_cursor,ovrimos_exec,ovrimos_execute,% + ovrimos_fetch_row,ovrimos_field_len,ovrimos_field_name,% + ovrimos_field_type,ovrimos_free_result,ovrimos_longreadlen,% + ovrimos_num_rows,ovrimos_prepare,ovrimos_result_all,% + ovrimos_rollback,pack,parse_ini_file,parse_str,parse_url,% + pathinfo,pclose,pdf_add_annotation,pdf_add_bookmark,% + pdf_add_locallink,pdf_add_note,pdf_add_outline,pdf_add_pdflink,% + pdf_add_weblink,pdf_arc,pdf_arcn,pdf_attach_file,pdf_begin_page,% + pdf_begin_template,pdf_circle,pdf_clip,pdf_close_image,% + pdf_close_pdi,pdf_close,pdf_closepath_fill_stroke,% + pdf_closepath,pdf_concat,pdf_continue_text,pdf_curveto,% + pdf_end_page,pdf_end_pattern,pdf_end_template,pdf_endpath,% + pdf_fill,pdf_findfont,pdf_get_buffer,pdf_get_font,% + pdf_get_fontsize,pdf_get_image_height,pdf_get_image_width,% + pdf_get_minorversion,pdf_get_parameter,pdf_get_pdi_parameter,% + pdf_get_value,pdf_initgraphics,pdf_lineto,pdf_makespotcolor,% + pdf_new,pdf_open_ccitt,pdf_open_file,pdf_open_gif,% + pdf_open_image,pdf_open_jpeg,pdf_open_memory_image,% + pdf_open_pdi,pdf_open_png,pdf_open_tiff,pdf_open,% + pdf_place_pdi_page,pdf_rect,pdf_restore,pdf_rotate,pdf_save,% + pdf_set_border_color,pdf_set_border_dash,pdf_set_border_style,% + pdf_set_duration,pdf_set_font,pdf_set_horiz_scaling,% + pdf_set_info_creator,pdf_set_info_keywords,pdf_set_info_subject,% + pdf_set_info,pdf_set_leading,pdf_set_parameter,pdf_set_text_pos,% + pdf_set_text_rise,pdf_set_transition,pdf_set_value,% + pdf_setcolor,pdf_setdash,pdf_setflat,pdf_setfont,% + pdf_setgray_stroke,pdf_setgray,pdf_setlinecap,pdf_setlinejoin,% + pdf_setmatrix,pdf_setmiterlimit,pdf_setpolydash,% + pdf_setrgbcolor_stroke,pdf_setrgbcolor,pdf_show_boxed,% + pdf_show,pdf_skew,pdf_stringwidth,pdf_stroke,pdf_translate,% + pfpro_init,pfpro_process_raw,pfpro_process,pfpro_version,% + pg_cancel_query,pg_client_encoding,pg_close,pg_cmdtuples,% + pg_connection_busy,pg_connection_reset,pg_connection_status,% + pg_copy_to,pg_dbname,pg_end_copy,pg_errormessage,% + pg_escape_string,pg_exec,pg_fetch_array,pg_fetch_object,% + pg_fieldisnull,pg_fieldname,pg_fieldnum,pg_fieldprtlen,% + pg_fieldtype,pg_freeresult,pg_get_result,pg_getlastoid,pg_host,% + pg_last_notice,pg_lo_close,pg_lo_seek,pg_lo_tell,pg_loclose,% + pg_loexport,pg_loimport,pg_loopen,pg_loread,pg_loreadall,% + pg_lowrite,pg_numfields,pg_numrows,pg_options,pg_pconnect,% + pg_put_line,pg_request_cancel,pg_result_error,pg_result_status,% + pg_send_query,pg_set_client_encoding,pg_trace,pg_tty,pg_untrace,% + php_sapi_name,php_uname,phpcredits,phpinfo, +% \end{macrocode} +% \endgroup +% +% % \subsection{PL/I} % % Found the data in @@ -1304,11 +2961,11 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*pli> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage{PL/I}% - {keywords={ABS,ATAN,AUTOMATIC,AUTO,ATAND,BEGIN,BINARY,BIN,BIT,% +\lst@definelanguage{PL/I}% + {morekeywords={ABS,ATAN,AUTOMATIC,AUTO,ATAND,BEGIN,BINARY,BIN,BIT,% BUILTIN,BY,CALL,CHARACTER,CHAR,CHECK,COLUMN,COL,COMPLEX,CPLX,% COPY,COS,COSD,COSH,DATA,DATE,DECIMAL,DEC,DECLARE,DCL,DO,EDIT,% ELSE,END,ENDFILE,ENDPAGE,ENTRY,EXP,EXTERNAL,EXT,FINISH,FIXED,% @@ -1320,29 +2977,111 @@ nor under a different one. RETURNS,ROUND,SIN,SIND,SINH,SIZE,SKIP,SQRT,STATIC,STOP,STRING,% SUBSTR,SUM,SYSIN,SYSPRINT,TAN,TAND,TANH,THEN,TO,UNDERFLOW,UFL,% VARYING,WHILE,WRITE,ZERODIVIDE,ZDIV},% - sensitive=false,% - singlecomment={/*}{*/},% - stringizer={'}% - }% + sensitive=f,% + morecomment=[s]{/*}{*/},% + morestring=[d]'% + }[keywords,comments,strings]% % \end{macrocode} % \begin{macrocode} -% +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{POV-Ray} +% +% \lstthanks{Berthold~H\"ollmann}{bhoel@starship.python.net}{1999/04/15} sent +% me the definition. But I removed |blankstring=false| and +% |flexiblecolumns=true| from the driver since they have nothing to do with a +% language definition. +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +%% +%% POV definition (c) 1999 Berthold H\"ollmann +%% +%% +\lst@definelanguage{POV}% + {morekeywords={abs,absorption,acos,acosh,adaptive,adc_bailout,agate,% + agate_turb,all,alpha,ambient,ambient_light,angle,aperture,append,% + arc_angle,area_light,array,asc,asin,asinh,assumed_gamma,atan,% + atan2,atanh,average,background,bezier_spline,bicubic_patch,% + black_hole,blob,blue,blur_samples,bounded_by,box,boxed,bozo,% + break,brick,brick_size,brightness,brilliance,bumps,bump_map,% + bump_size,camera,case,caustics,ceil,checker,chr,clipped_by,clock,% + clock_delta,color,color_map,colour,colour_map,component,% + composite,concat,cone,confidence,conic_sweep,control0,control1,% + cos,cosh,count,crackle,crand,cube,cubic,cubic_spline,cubic_wave,% + cylinder,cylindrical,debug,declare,default,defined,degrees,% + density,density_file,density_map,dents,difference,diffuse,% + dimensions,dimension_size,direction,disc,distance,% + distance_maximum,div,eccentricity,else,emission,end,error,% + error_bound,exp,extinction,fade_distance,fade_power,falloff,% + falloff_angle,false,fclose,file_exists,filter,finish,fisheye,% + flatness,flip,floor,focal_point,fog,fog_alt,fog_offset,fog_type,% + fopen,frequency,gif,global_settings,gradient,granite,% + gray_threshold,green,height_field,hexagon,hf_gray_16,hierarchy,% + hollow,hypercomplex,if,ifdef,iff,ifndef,image_map,include,int,% + interior,interpolate,intersection,intervals,inverse,ior,irid,% + irid_wavelength,jitter,julia_fractal,lambda,lathe,leopard,% + light_source,linear_spline,linear_sweep,local,location,log,% + looks_like,look_at,low_error_factor,macro,mandel,map_type,marble,% + material,material_map,matrix,max,max_intersections,max_iteration,% + max_trace_level,media,media_attenuation,media_interaction,merge,% + mesh,metallic,min,minimum_reuse,mod,mortar,nearest_count,no,% + normal,normal_map,no_shadow,number_of_waves,object,octaves,off,% + offset,omega,omnimax,on,once,onion,open,orthographic,panoramic,% + perspective,pgm,phase,phong,phong_size,pi,pigment,pigment_map,% + planar,plane,png,point_at,poly,polygon,poly_wave,pot,pow,ppm,% + precision,prism,pwr,quadratic_spline,quadric,quartic,quaternion,% + quick_color,quick_colour,quilted,radial,radians,radiosity,radius,% + rainbow,ramp_wave,rand,range,ratio,read,reciprocal,% + recursion_limit,red,reflection,reflection_exponent,refraction,% + render,repeat,rgb,rgbf,rgbft,rgbt,right,ripples,rotate,roughness,% + samples,scale,scallop_wave,scattering,seed,shadowless,sin,% + sine_wave,sinh,sky,sky_sphere,slice,slope_map,smooth,% + smooth_triangle,sor,specular,sphere,spherical,spiral1,spiral2,% + spotlight,spotted,sqr,sqrt,statistics,str,strcmp,strength,strlen,% + strlwr,strupr,sturm,substr,superellipsoid,switch,sys,t,tan,tanh,% + text,texture,texture_map,tga,thickness,threshold,tightness,tile2,% + tiles,torus,track,transform,translate,transmit,triangle,% + triangle_wave,true,ttf,turbulence,turb_depth,type,u,% + ultra_wide_angle,undef,union,up,use_color,use_colour,use_index,% + u_steps,v,val,variance,vaxis_rotate,vcross,vdot,version,vlength,% + vnormalize,vrotate,v_steps,warning,warp,water_level,waves,while,% + width,wood,wrinkles,write,x,y,yes,z},% + moredirectives={break,case,debug,declare,default,else,end,fclose,% + fopen,local,macro,read,render,statistics,switch,undef,version,% + warning,write},% + sensitive,% + morecomment=[l]//,% + morecomment=[s]{/*}{*/},% + morestring=[d]",% + }[keywords,directives,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{Prolog} % -% \lsthelper{Dominique de Waleffe}{ddw@miscrit.be}{1997/11/24}{Prolog} mailed me the data for Prolog. -% He took the keywords from the \textsf{LGrind} language definition file. +% \lsthelper{Dominique~de~Waleffe}{ddw@miscrit.be}{1997/11/24}{Prolog} mailed +% me the data for Prolog. He took the keywords from the \textsf{LGrind} +% language definition file. % \begingroup % \begin{macrocode} -%<*prolog> +%<*lang2> % \end{macrocode} % \begin{macrocode} -%% (c) 1997 Dominique de Waleffe -\lstdefinelanguage{Prolog}% - {keywords={op,mod,abort,ancestors,arg,ascii,ask,assert,asserta,% +%% +%% Prolog definition (c) 1997 Dominique de Waleffe +%% +\lst@definelanguage{Prolog}% + {morekeywords={op,mod,abort,ancestors,arg,ascii,ask,assert,asserta,% assertz,atom,atomic,char,clause,close,concat,consult,ed,ef,em,% eof,fail,file,findall,write,functor,getc,integer,is,length,% listing,load,name,nl,nonvar,not,numbervars,op,or,pp,prin,print,% @@ -1350,14 +3089,86 @@ nor under a different one. retract,retractall,save,see,seeing,seen,sh,skip,statistics,% subgoal_of,system,tab,tell,telling,time,told,trace,true,unload,% untrace,var,write},% + sensitive=f,% + morecomment=[l]\%,% + morecomment=[s]{/*}{*/},% + morestring=[bd]",% + morestring=[bd]'% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Python} +% +% \lstthanks{Michael~Weber}{mweber@informatik.hu-berlin.de}{1998/12/21} sent me +% the definition. He got data from \textsc{Mark Lutz}: \textbf{Programming +% Python}; O'Reilly 1996; ISBN 1-56592-197-6. +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +%% +%% Python definition (c) 1998 Michael Weber +%% +%% +\lst@definelanguage{Python}% + {morekeywords={access,and,break,class,continue,def,del,elif,else,% + except,exec,finally,for,from,global,if,import,in,is,lambda,not,% + or,pass,print,raise,return,try,while},% + sensitive=true,% + morecomment=[l]\#,% + morecomment=[s]{'''}{'''},% used for documentation text + morecomment=[s]{"""}{"""},% added by Philipp Matthias Hahn + morestring=[b]',% + morestring=[b]"% + }% +% \end{macrocode} +% \lsthelper{Philipp Matthias Hahn}{pmhahn@titan.lahn.de}{2002/04/18}{} +% added the third comment. \lsthelper{eRreuR}{rogspr@newdeal.ch}{2002/05/28} +% {probl\`eme avec "listings" et le langage Python} found a bug using Python +% and \lsthelper{Nicolas Markey}{markey@lsv.ens-cachan.fr}{2002/05/29} +% {listings and Python} informed me about the corresponding thread on +% \texttt{fr.comp.text.tex} and provided the fix---adding \texttt{[b]} to +% both \texttt{morestring} declarations. +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{SHELXL} +% +% Thanks to \lstthanks{Aidan~Philip~Heerdegen}{Aidan.Heerdegen@anu.edu.au} +% {1999/07/09} for mailing this definition. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% SHELXL definition (c) 1999 Aidan Philip Heerdegen +%% +%% +\lst@definelanguage{SHELXL}% + {morekeywords={TITL,CELL,ZERR,LATT,SYMM,SFAC,DISP,UNIT,LAUE,% + REM,MORE,TIME,END,HKLF,OMIT,SHEL,BASF,TWIN,EXTI,SWAT,% + MERG,SPEC,RESI,MOVE,ANIS,AFIX,HFIX,FRAG,FEND,EXYZ,EADP,% + EQIV,OMIT,CONN,PART,BIND,FREE,DFIX,BUMP,SAME,SADI,CHIV,% + FLAT,DELU,SIMU,DEFS,ISOR,SUMP,L.S.,CGLS,SLIM,BLOC,DAMP,% + WGHT,FVAR,BOND,CONF,MPLA,RTAB,LIST,ACTA,SIZE,TEMP,WPDB,% + FMAP,GRID,PLAN,MOLE},% sensitive=false,% - commentline={\%},% - singlecomment={/*}{*/},% - stringizer=[bd]{"'}% + alsoother=_,% Makes the syntax highlighting ignore the underscores + morecomment=[l]{! },% }% % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % @@ -1373,59 +3184,60 @@ nor under a different one. % \end{itemize} % \begingroup % \begin{macrocode} -%<*simula> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinelanguage[67]{Simula}% - {keywords={activate,after,array,at,before,begin,boolean,character,% - class,comment,delay,detach,do,else,end,external,false,for,go,% - goto,if,in,inner,inspect,integer,is,label,name,new,none,notext,% - otherwise,prior,procedure,qua,reactivate,real,ref,resume,simset,% - simulation,step,switch,text,then,this,to,true,until,value,% - virtual,when,while},% - sensitive=false,% - doublekeywordcommentsemicolon=% - {end}{else,end,otherwise,when}{comment},% - stringizer={"'}% - }% +\lst@definelanguage[IBM]{Simula}[DEC]{Simula}{}% % \end{macrocode} -% % \begin{macrocode} -\lstdefinedrvlanguage[CII]{Simula}% - {language=[67]Simula,% - morekeywords={and,equiv,exit,impl,not,or,stop}% - }% -% \end{macrocode} -% -% \begin{macrocode} -\lstdefinedrvlanguage[DEC]{Simula}% - {language=[67]Simula,% - morekeywords={and,eq,eqv,ge,gt,hidden,imp,le,long,lt,ne,not,% +\lst@definelanguage[DEC]{Simula}[67]{Simula}% + {morekeywords={and,eq,eqv,ge,gt,hidden,imp,le,long,lt,ne,not,% options,or,protected,short}% }% % \end{macrocode} -% % \begin{macrocode} -\lstdefinedrvlanguage[IBM]{Simula}{language=[DEC]Simula} +\lst@definelanguage[CII]{Simula}[67]{Simula}% + {morekeywords={and,equiv,exit,impl,not,or,stop}}% % \end{macrocode} % \begin{macrocode} -% +\lst@definelanguage[67]{Simula}% + {morekeywords={activate,after,array,at,before,begin,boolean,% + character,class,comment,delay,detach,do,else,end,external,false,% + for,go,goto,if,in,inner,inspect,integer,is,label,name,new,none,% + notext,otherwise,prior,procedure,qua,reactivate,real,ref,resume,% + simset,simulation,step,switch,text,then,this,to,true,until,value,% + virtual,when,while},% + sensitive=f,% + keywordcommentsemicolon={end}{else,end,otherwise,when}{comment},% + morestring=[d]",% + morestring=[d]'% + }[keywords,keywordcomments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{SQL} % -% Data come from \lsthelper{Christian Haul}{haul@dvs1.informatik.tu-darmstadt.de}{1998/01/09}{SQL}. +% Data come from \lstthanks{Christian~Haul} +% {haul@dvs1.informatik.tu-darmstadt.de}{1998/01/09}. +% \lstthanks{Neil Conway}{nconway@klamath.dyndns.org}{2002/07/06} added some +% keywords. % \begingroup % \begin{macrocode} -%<*sql> +%<*lang1> % \end{macrocode} % \begin{macrocode} -%% (c) 1998 by Christian Haul -\lstdefinelanguage{sql}% - {keywords={ABSOLUTE,ACTION,ADD,ALLOCATE,ALTER,ARE,ASSERTION,AT,% - BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,% +%% +%% SQL definition (c) 1998 Christian Haul +%% +%% and (c) 2002 Neil Conway +%% +\lst@definelanguage{SQL}% + {morekeywords={ABSOLUTE,ACTION,ADD,ALLOCATE,ALTER,ARE,AS,ASSERTION,% + AT,BETWEEN,BIT,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,% CATALOG,CHAR,CHAR_LENGTH,CHARACTER_LENGTH,CLUSTER,COALESCE,% COLLATE,COLLATION,COLUMN,CONNECT,CONNECTION,CONSTRAINT,% CONSTRAINTS,CONVERT,CORRESPONDING,CREATE,CROSS,CURRENT_DATE,% @@ -1434,76 +3246,300 @@ nor under a different one. DISCONNECT,DOMAIN,DROP,ELSE,END,EXEC,EXCEPT,EXCEPTION,EXECUTE,% EXTERNAL,EXTRACT,FALSE,FIRST,FLOAT,FOREIGN,FROM,FULL,GET,GLOBAL,% GRAPHIC,HAVING,HOUR,IDENTITY,IMMEDIATE,INDEX,INITIALLY,INNER,% - INPUT,INSENSITIVE,INT,INTEGER,INTERSECT,INTERVAL,ISOLATION,JOIN,% - KEY,LAST,LEADING,LEFT,LEVEL,LOCAL,LOWER,MATCH,MINUTE,MONTH,NAMES,% - NATIONAL,NATURAL,NCHAR,NEXT,NO,NOT,NULL,NULLIF,OCTET_LENGTH,ON,% - ONLY,ORDERED,OUTER,OUTPUT,OVERLAPS,PAD,PARTIAL,POSITION,PREPARE,% - PRESERVE,PRIMARY,PRIOR,READ,RELATIVE,RESTRICT,REVOKE,RIGHT,ROWS,% - SCROLL,SECOND,SELECT,SESSION,SESSION_USER,SIZE,SMALLINT,SPACE,% - SQLSTATE,SUBSTRING,SYSTEM_USER,TABLE,TEMPORARY,THEN,TIME,% - TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,TRAILING,TRANSACTION,% - TRANSLATE,TRANSLATION,TRIM,TRUE,UNIQUE,UNKNOWN,UPPER,USAGE,USING,% - VALUE,VARCHAR,VARGRAPHIC,VARYING,WHEN,WHERE,WRITE,YEAR,ZONE},% - sensitive=true,% - commentline={--},% - singlecomment={/*}{*/},% - stringizer={'"}% + INPUT,INSENSITIVE,INSERT,INT,INTO,INTEGER,INTERSECT,INTERVAL,% + ISOLATION,JOIN,KEY,LAST,LEADING,LEFT,LEVEL,LIMIT,LOCAL,LOWER,% + MATCH,MINUTE,MONTH,NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NOT,NULL,% + NULLIF,OCTET_LENGTH,ON,ONLY,ORDER,ORDERED,OUTER,OUTPUT,OVERLAPS,% + PAD,PARTIAL,POSITION,PREPARE,PRESERVE,PRIMARY,PRIOR,READ,% + RELATIVE,RESTRICT,REVOKE,RIGHT,ROWS,SCROLL,SECOND,SELECT,SESSION,% + SESSION_USER,SIZE,SMALLINT,SPACE,SQLSTATE,SUBSTRING,SYSTEM_USER,% + TABLE,TEMPORARY,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,% + TIMEZONE_MINUTE,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,% + TRUE,UNIQUE,UNKNOWN,UPPER,USAGE,USING,VALUE,VALUES,VARCHAR,% + VARGRAPHIC,VARYING,WHEN,WHERE,WRITE,YEAR,ZONE},% + sensitive,% + morecomment=[l]--,% + morecomment=[s]{/*}{*/},% + morestring=[d]',% + morestring=[d]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% +% \subsection{Tcl/Tk} +% +% Tcl/Tk is a very dynamic language. A statical analysis might not be +% adequate. Nevertheless the following definitions produce the desired +% result for my programs with a minimum of ``misses''. +% +% Data come from +% \begin{itemize} +% \item +% \textsc{Welch, Brent B.}: +% \textbf{Practical Programming in Tcl and Tk}; +% {\copyright} 1997 Prentice Hall, Inc.; +% ISBN 0-13-616830-2. +% \item +% \textsc{Ousterhout, John K.}: +% \textbf{Tcl and the Tk Toolkit}; +% {\copyright} 1997 Addison-Wesley Publishing Company; +% ISBN 0-201-6337-X. +% \end{itemize} +% \lstthanks{Gerd~Neugebauer}{gerd.neugebauer@gmx.de}{2000/09/16} added support +% for Tcl/Tk. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% Tcl/Tk definition (c) Gerd Neugebauer +%% +\lst@definelanguage[tk]{tcl}[]{tcl}% + {morekeywords={activate,add,separator,radiobutton,checkbutton,% + command,cascade,all,bell,bind,bindtags,button,canvas,canvasx,% + canvasy,cascade,cget,checkbutton,config,configu,configur,% + configure,clipboard,create,arc,bitmap,image,line,oval,polygon,% + rectangle,text,textwindow,curselection,delete,destroy,end,entry,% + entrycget,event,focus,font,actual,families,measure,metrics,names,% + frame,get,grab,current,release,status,grid,columnconfigure,% + rowconfigure,image,image,create,bitmap,photo,delete,height,types,% + widt,names,index,insert,invoke,itemconfigure,label,listbox,lower,% + menu,menubutton,message,move,option,add,clear,get,readfile,pack,% + photo,place,radiobutton,raise,scale,scroll,scrollbar,search,see,% + selection,send,stdin,stdout,stderr,tag,bind,text,tk,tkerror,% + tkwait,window,variable,visibility,toplevel,unknown,update,winfo,% + class,exists,ismapped,parent,reqwidth,reqheight,rootx,rooty,% + width,height,wm,aspect,client,command,deiconify,focusmodel,frame,% + geometry,group,iconbitmap,iconify,iconmask,iconname,iconposition,% + iconwindow,maxsize,minsize,overrideredirect,positionfrom,% + protocol,sizefrom,state,title,transient,withdraw,xview,yview,% + yposition,% + -accelerator,-activebackground,-activeborderwidth,% + -activeforeground,-after,-anchor,-arrow,-arrowshape,-aspect,% + -async,-background,-before,-bg,-bigincrement,-bitmap,-bordermode,% + -borderwidth,-button,-capstyle,-channel,-class,-closeenough,% + -colormap,-column,-columnspan,-command,-confine,-container,% + -count,-cursor,-data,-default,-detail,-digits,-direction,% + -displayof,-disableforeground,-elementborderwidth,-expand,% + -exportselection,-extend,-family,-fg,-file,-fill,-focus,-font,% + -fontmap,-foreground,-format,-from,-gamma,-global,-height,% + -highlightbackground,-highlightcolor,-highlightthickness,-icon,% + -image,-in,-insertbackground,-insertborderwidth,-insertofftime,% + -insertontime,-imsertwidth,-ipadx,-ipady,-joinstyle,-jump,% + -justify,-keycode,-keysym,-label,-lastfor,-length,-maskdata,% + -maskfile,-menu,-message,-mode,-offvalue,-onvalue,-orient,% + -outlien,-outlinestipple,-overstrike,-override,-padx,-pady,% + -pageanchor,-pageheight,-pagewidth,-pagey,-pagey,-palette,% + -parent,-place,-postcommand,-relheight,-relief,-relwidth,-relx,% + -rely,-repeatdelay,-repeatinterval,-resolution,-root,-rootx,% + -rooty,-rotate,-row,-rowspan,-screen,-selectcolor,-selectimage,% + -sendevent,-serial,-setgrid,-showvalue,-shrink,-side,-size,% + -slant,-sliderlength,-sliderrelief,-smooth,-splinesteps,-state,% + -sticky,-stipple,-style,-subsample,-subwindow,-tags,-takefocus,% + -tearoff,-tearoffcommand,-text,-textvariable,-tickinterval,-time,% + -title,-to,-troughcolor,-type,-underline,-use,-value,-variable,% + -visual,-width,-wrap,-wraplength,-x,-xscrollcommand,-y,% + -bgstipple,-fgstipple,-lmargin1,-lmargin2,-rmargin,-spacing1,% + -spacing2,-spacing3,-tabs,-yscrollcommand,-zoom,% + activate,add,addtag,bbox,cget,clone,configure,coords,% + curselection,debug,delete,delta,deselect,dlineinfo,dtag,dump,% + entrycget,entryconfigure,find,flash,fraction,get,gettags,handle,% + icursor,identify,index,insert,invoke,itemcget,itemconfigure,mark,% + moveto,own,post,postcascade,postscript,put,redither,ranges,% + scale,select,show,tag,type,unpost,xscrollcommand,xview,% + yscrollcommand,yview,yposition}% }% % \end{macrocode} % \begin{macrocode} -% +\lst@definelanguage[]{tcl}% + {alsoletter={.:,*=&-},% + morekeywords={after,append,array,names,exists,anymore,donesearch,% + get,nextelement,set,size,startsearch,auto_mkindex,binary,break,% + case,catch,cd,clock,close,concat,console,continue,default,else,% + elseif,eof,error,eval,exec,-keepnewline,exit,expr,fblocked,% + fconfigure,fcopy,file,atime,dirname,executable,exists,extension,% + isdirectory,isfile,join,lstat,mtime,owned,readable,readlink,% + rootname,size,stat,tail,type,writable,-permissions,-group,-owner,% + -archive,-hidden,-readonly,-system,-creator,-type,-force,% + fileevent,flush,for,foreach,format,gets,glob,global,history,if,% + incr,info,argsbody,cmdcount,commands,complete,default,exists,% + globals,level,library,locals,patchlevel,procs,script,tclversion,% + vars,interp,join,lappend,lindex,linsert,list,llength,lrange,% + lreplace,lsearch,-exact,-regexp,-glob,lsort,-ascii,-integer,% + -real,-dictionary,-increasing,-decreasing,-index,-command,load,% + namespace,open,package,forget,ifneeded,provide,require,unknown,% + vcompare,versions,vsatisfies,pid,proc,puts,-nonewline,pwd,read,% + regexp,-indices,regsub,-all,-nocaserename,return,scan,seek,set,% + socket,source,split,string,compare,first,index,last,length,match,% + range,tolower,toupper,trim,trimleft,trimright,subst,switch,tell,% + time,trace,variable,vdelete,vinfo,unknown,unset,uplevel,upvar,% + vwait,while,acos,asin,atan,atan2,ceil,cos,cosh,exp,floor,fmod,% + hypot,log,log10,pow,sin,sinh,sqrt,tan,tanh,abs,double,int,round% + },% + morestring=[d]",% + MoreSelectCharTable=% + \lst@CArgX\#\relax\lst@DefDelimB{}{}% + {\ifx\lst@lastother\lstum@backslash + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@commentmode + {{\lst@commentstyle}\lst@Lmodetrue}% + }[keywords,comments,strings]% +% \end{macrocode} +% And after receiving a bug report from \lsthelper{Vitaly A. Repin} +% {vitaly@radio.hop.stu.neva.ru}{2002/04/08}{undefined control sequence +% \lst@CommentB} I converted the version 0.21 contents of |MoreSelectCharTable| +% to version 1.0. +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{Statistical languages} +% +% These languages have been added by \lstthanks{Winfried~Theis} +% {theis@statistik.uni-dortmund.de}{2000/09/05}. \lstthanks{Robert~Denham} +% {Robert.Denham@dnr.qld.gov.au}{2001/05/03} contributed the additional +% string delimiter |'|. +% \begingroup +% \begin{macrocode} +%<*lang3> +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage{S}[]{R}{} +\lst@definelanguage[PLUS]{S}[]{R}{} +\lst@definelanguage{R}% + {keywords={abbreviate,abline,abs,acos,acosh,action,add1,add,% + aggregate,alias,Alias,alist,all,anova,any,aov,aperm,append,apply,% + approx,approxfun,apropos,Arg,args,array,arrows,as,asin,asinh,% + atan,atan2,atanh,attach,attr,attributes,autoload,autoloader,ave,% + axis,backsolve,barplot,basename,besselI,besselJ,besselK,besselY,% + beta,binomial,body,box,boxplot,break,browser,bug,builtins,bxp,by,% + c,C,call,Call,case,cat,category,cbind,ceiling,character,char,% + charmatch,check,chol,chol2inv,choose,chull,class,close,cm,codes,% + coef,coefficients,co,col,colnames,colors,colours,commandArgs,% + comment,complete,complex,conflicts,Conj,contents,contour,% + contrasts,contr,control,helmert,contrib,convolve,cooks,coords,% + distance,coplot,cor,cos,cosh,count,fields,cov,covratio,wt,CRAN,% + create,crossprod,cummax,cummin,cumprod,cumsum,curve,cut,cycle,D,% + data,dataentry,date,dbeta,dbinom,dcauchy,dchisq,de,debug,% + debugger,Defunct,default,delay,delete,deltat,demo,de,density,% + deparse,dependencies,Deprecated,deriv,description,detach,% + dev2bitmap,dev,cur,deviance,off,prev,,dexp,df,dfbetas,dffits,% + dgamma,dgeom,dget,dhyper,diag,diff,digamma,dim,dimnames,dir,% + dirname,dlnorm,dlogis,dnbinom,dnchisq,dnorm,do,dotplot,double,% + download,dpois,dput,drop,drop1,dsignrank,dt,dummy,dump,dunif,% + duplicated,dweibull,dwilcox,dyn,edit,eff,effects,eigen,else,% + emacs,end,environment,env,erase,eval,equal,evalq,example,exists,% + exit,exp,expand,expression,External,extract,extractAIC,factor,% + fail,family,fft,file,filled,find,fitted,fivenum,fix,floor,for,% + For,formals,format,formatC,formula,Fortran,forwardsolve,frame,% + frequency,ftable,ftable2table,function,gamma,Gamma,gammaCody,% + gaussian,gc,gcinfo,gctorture,get,getenv,geterrmessage,getOption,% + getwd,gl,glm,globalenv,gnome,GNOME,graphics,gray,grep,grey,grid,% + gsub,hasTsp,hat,heat,help,hist,home,hsv,httpclient,I,identify,if,% + ifelse,Im,image,\%in\%,index,influence,measures,inherits,install,% + installed,integer,interaction,interactive,Internal,intersect,% + inverse,invisible,IQR,is,jitter,kappa,kronecker,labels,lapply,% + layout,lbeta,lchoose,lcm,legend,length,levels,lgamma,library,% + licence,license,lines,list,lm,load,local,locator,log,log10,log1p,% + log2,logical,loglin,lower,lowess,ls,lsfit,lsf,ls,machine,Machine,% + mad,mahalanobis,make,link,margin,match,Math,matlines,mat,matplot,% + matpoints,matrix,max,mean,median,memory,menu,merge,methods,min,% + missing,Mod,mode,model,response,mosaicplot,mtext,mvfft,na,nan,% + names,omit,nargs,nchar,ncol,NCOL,new,next,NextMethod,nextn,% + nlevels,nlm,noquote,NotYetImplemented,NotYetUsed,nrow,NROW,null,% + numeric,\%o\%,objects,offset,old,on,Ops,optim,optimise,optimize,% + options,or,order,ordered,outer,package,packages,page,pairlist,% + pairs,palette,panel,par,parent,parse,paste,path,pbeta,pbinom,% + pcauchy,pchisq,pentagamma,persp,pexp,pf,pgamma,pgeom,phyper,pico,% + pictex,piechart,Platform,plnorm,plogis,plot,pmatch,pmax,pmin,% + pnbinom,pnchisq,pnorm,points,poisson,poly,polygon,polyroot,pos,% + postscript,power,ppoints,ppois,predict,preplot,pretty,Primitive,% + print,prmatrix,proc,prod,profile,proj,prompt,prop,provide,% + psignrank,ps,pt,ptukey,punif,pweibull,pwilcox,q,qbeta,qbinom,% + qcauchy,qchisq,qexp,qf,qgamma,qgeom,qhyper,qlnorm,qlogis,qnbinom,% + qnchisq,qnorm,qpois,qqline,qqnorm,qqplot,qr,Q,qty,qy,qsignrank,% + qt,qtukey,quantile,quasi,quit,qunif,quote,qweibull,qwilcox,% + rainbow,range,rank,rbeta,rbind,rbinom,rcauchy,rchisq,Re,read,csv,% + csv2,fwf,readline,socket,real,Recall,rect,reformulate,regexpr,% + relevel,remove,rep,repeat,replace,replications,report,require,% + resid,residuals,restart,return,rev,rexp,rf,rgamma,rgb,rgeom,R,% + rhyper,rle,rlnorm,rlogis,rm,rnbinom,RNGkind,rnorm,round,row,% + rownames,rowsum,rpois,rsignrank,rstandard,rstudent,rt,rug,runif,% + rweibull,rwilcox,sample,sapply,save,scale,scan,scan,screen,sd,se,% + search,searchpaths,segments,seq,sequence,setdiff,setequal,set,% + setwd,show,sign,signif,sin,single,sinh,sink,solve,sort,source,% + spline,splinefun,split,sqrt,stars,start,stat,stem,step,stop,% + storage,strstrheight,stripplot,strsplit,structure,strwidth,sub,% + subset,substitute,substr,substring,sum,summary,sunflowerplot,svd,% + sweep,switch,symbol,symbols,symnum,sys,status,system,t,table,% + tabulate,tan,tanh,tapply,tempfile,terms,terrain,tetragamma,text,% + time,title,topo,trace,traceback,transform,tri,trigamma,trunc,try,% + ts,tsp,typeof,unclass,undebug,undoc,union,unique,uniroot,unix,% + unlink,unlist,unname,untrace,update,upper,url,UseMethod,var,% + variable,vector,Version,vi,warning,warnings,weighted,weights,% + which,while,window,write,\%x\%,x11,X11,xedit,xemacs,xinch,xor,% + xpdrows,xy,xyinch,yinch,zapsmall,zip},% + otherkeywords={!,!=,~,$,*,\&,\%/\%,\%*\%,\%\%,<-,<<-,_,/},% + alsoother={._$},% + sensitive,% + morecomment=[l]\#,% + morestring=[d]",% + morestring=[d]'% 2001 Robert Denham + }% +% \end{macrocode} +% \lsthelper{Benjamin Janson}{benjamin.janson@gmx.de}{2002/07/09} +% {prockeywords undefined} got a \texttt{prockeywords undefined} error, +% which was removed by \lsthelper{Heiko Oberdiek}{oberdiek@uni-freiburg.de} +% {2002/07/10}{prockeywords -> procnamekeys}. +% \begin{macrocode} +\lst@definelanguage{SAS}% + {procnamekeys={proc},% + morekeywords={DATA,AND,OR,NOT,EQ,GT,LT,GE,LE,NE,INFILE,INPUT,DO,BY,% + TO,SIN,COS,OUTPUT,END,PLOT,RUN,LIBNAME,VAR,TITLE,FIRSTOBS,OBS,% + DELIMITER,DLM,EOF,ABS,DIM,HBOUND,LBOUND,MAX,MIN,MOD,SIGN,SQRT,% + CEIL,FLOOR,FUZZ,INT,ROUND,TRUNC,DIGAMMA,ERF,ERFC,EXP,GAMMA,% + LGAMMA,LOG,LOG2,LOG10,ARCOS,ARSIN,ATAN,COSH,SINH,TANH,TAN,% + POISSON,PROBBETA,PROBBNML,PROBCHI,PROBF,PROBGAM,PROBHYPR,% + PROBNEGB,PROBNORM,PROBT,BETAINV,CINV,FINV,GAMINV,PROBIT,TINV,CSS,% + CV,KURTOSIS,MEAN,NMISS,RANGE,SKEWNESS,STD,STDERR,SUM,USS,NORMAL,% + RANBIN,RANCAU,RANEXP,RANGAM,RANNOR,RANPOI,RANTBL,RANTRI,RANUNI,% + UNIFORM,IF,THEN,ELSE,WHILE,UNTIL,DROP,KEEP,LABEL,DEFAULT,ARRAY,% + MERGE,CARDS,CARDS4,PUT,SET,UPDATE,ABORT,DELETE,DISPLAY,LIST,% + LOSTCARD,MISSING,STOP,WHERE,ARRAY,DROP,KEEP,WINDOW,LENGTH,RENAME,% + RETAIN,MEANS,UNIVARIATE,SUMMARY,TABULATE,CORR,FREQ,FOOTNOTE,NOTE,% + SHOW},% + otherkeywords={!,!=,~,$,*,\&,_,/,<,>=,=<,>},% + morestring=[d]'% + }[keywords,comments,strings,procnames]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{\TeX} % -% I extracted the data from |plain.tex| and |latex.ltx|. +% I extracted the data from |plain.tex|, |latex.ltx|, and |size10.clo|. +% \lsthelper{Dr.~Peter~Leibner}{leibner@sta.siemens.de}{1999/11/08}{missing +% keywords in definition of \LaTeX} reported that some keywords are missing +% and also added a couple. % \begingroup % \begin{macrocode} -%<*tex> +%<*lang3> % \end{macrocode} % \begin{macrocode} -\lstdefinedrvlanguage[plain]{tex}% - {texcs={\lstkeys@tex@primitives,\lstkeys@tex@commoncs,% - advancepageno,beginsection,bf,bffam,bye,cal,cleartabs,columns,% - dosupereject,endinsert,eqalign,eqalignno,fiverm,fivebf,fivei,% - fivesy,folio,footline,hang,headline,it,itemitem,itfam,leqalignno,% - magnification,makefootline,makeheadline,midinsert,mit,mscount,% - nopagenumbers,normalbottom,of,oldstyle,pagebody,pagecontents,% - pageinsert,pageno,plainoutput,preloaded,proclaim,rm,settabs,% - sevenbf,seveni,sevensy,sevenrm,sl,slfam,supereject,tabalign,tabs,% - tabsdone,tabsyet,tenbf,tenex,teni,tenit,tenrm,tensl,tensy,tentt,% - textindent,topglue,topins,topinsert,tt,ttfam,ttraggedright,% - vfootnote},% - sensitive=true,% - alsoother={0123456789},% - commentline={\%}% - }% -% \end{macrocode} -% -% \begin{macrocode} -\lstdefinedrvlanguage[primitive]{tex}% - {texcs={\lstkeys@tex@primitives},% - sensitive=true,% - alsoother={0123456789},% - commentline={\%}% - }% -% \end{macrocode} -% -% \begin{macrocode} -\lstdefinedrvlanguage[latex]{tex}% - {texcs={\lstkeys@tex@primitives,\lstkeys@tex@latexcs},% - sensitive=true,% - alsoother={0123456789},% - commentline={\%}% - }% -% \end{macrocode} -% -% \begin{macrocode} -\lstdefinedrvlanguage[allatex]{tex}% - {texcs={\lstkeys@tex@primitives,\lstkeys@tex@latexcs, - AtBeginDocument,AtBeginDvi,AtEndDocument,AtEndOfClass,% +\lst@definelanguage[AlLaTeX]{TeX}[LaTeX]{TeX}% + {moretexcs={AtBeginDocument,AtBeginDvi,AtEndDocument,AtEndOfClass,% AtEndOfPackage,ClassError,ClassInfo,ClassWarning,% ClassWarningNoLine,CurrentOption,DeclareErrorFont,% DeclareFixedFont,DeclareFontEncoding,DeclareFontEncodingDefaults,% @@ -1525,213 +3561,300 @@ nor under a different one. ProvidesPackage,ProvideTextCommand,RequirePackage,% RequirePackageWithOptions,SetMathAlphabet,SetSymbolFont,% TextSymbolUnavailable,UseTextAccent,UseTextSymbol},% - keywords={array,center,displaymath,document,enumerate,eqnarray,% + morekeywords={array,center,displaymath,document,enumerate,eqnarray,% equation,flushleft,flushright,itemize,list,lrbox,math,minipage,% - picture,sloppypar,tabbing,tabular,trivlist,verbatim},% - sensitive=true,% - alsoother={0123456789},% - commentline={\%}% + picture,sloppypar,tabbing,tabular,trivlist,verbatim}% }% % \end{macrocode} +% \begin{macrocode} +\lst@definelanguage[LaTeX]{TeX}[common]{TeX}% + {moretexcs={a,AA,aa,addcontentsline,addpenalty,addtocontents,% + addtocounter,addtolength,addtoversion,addvspace,alph,Alph,and,% + arabic,array,arraycolsep,arrayrulewidth,arraystretch,author,% + baselinestretch,begin,bezier,bfseries,bibcite,bibdata,bibitem,% + bibliography,bibliographystyle,bibstyle,bigskip,boldmath,% + botfigrule,bottomfraction,Box,caption,center,CheckCommand,circle,% + citation,cite,cleardoublepage,clearpage,cline,columnsep,% + columnseprule,columnwidth,contentsline,dashbox,date,dblfigrule,% + dblfloatpagefraction,dblfloatsep,dbltextfloatsep,dbltopfraction,% + defaultscriptratio,defaultscriptscriptratio,depth,Diamond,% + displaymath,document,documentclass,documentstyle,doublerulesep,% + em,emph,endarray,endcenter,enddisplaymath,enddocument,% + endenumerate,endeqnarray,endequation,endflushleft,endflushright,% + enditemize,endlist,endlrbox,endmath,endminipage,endpicture,% + endsloppypar,endtabbing,endtabular,endtrivlist,endverbatim,% + enlargethispage,ensuremath,enumerate,eqnarray,equation,% + evensidemargin,extracolsep,fbox,fboxrule,fboxsep,filecontents,% + fill,floatpagefraction,floatsep,flushbottom,flushleft,flushright,% + fnsymbol,fontencoding,fontfamily,fontseries,fontshape,fontsize,% + fontsubfuzz,footnotemark,footnotesep,footnotetext,footskip,frac,% + frame,framebox,fussy,glossary,headheight,headsep,height,hline,% + hspace,I,include,includeonly,index,inputlineno,intextsep,% + itemindent,itemize,itemsep,iterate,itshape,Join,kill,label,% + labelsep,labelwidth,LaTeX,LaTeXe,leadsto,lefteqn,leftmargin,% + leftmargini,leftmarginii,leftmarginiii,leftmarginiv,leftmarginv,% + leftmarginvi,leftmark,lhd,lim,linebreak,linespread,linethickness,% + linewidth,list,listfiles,listfiles,listparindent,lrbox,% + makeatletter,makeatother,makebox,makeglossary,makeindex,% + makelabel,MakeLowercase,MakeUppercase,marginpar,marginparpush,% + marginparsep,marginparwidth,markboth,markright,math,mathbf,% + mathellipsis,mathgroup,mathit,mathrm,mathsf,mathsterling,mathtt,% + mathunderscore,mathversion,mbox,mdseries,mho,minipage,% + multicolumn,multiput,NeedsTeXFormat,newcommand,newcounter,% + newenvironment,newfont,newhelp,newlabel,newlength,newline,% + newmathalphabet,newpage,newsavebox,newtheorem,nobreakspace,% + nobreakspace,nocite,nocorr,nocorrlist,nofiles,nolinebreak,% + nonumber,nopagebreak,normalcolor,normalfont,normalmarginpar,% + numberline,obeycr,oddsidemargin,oldstylenums,onecolumn,oval,% + pagebreak,pagenumbering,pageref,pagestyle,paperheight,paperwidth,% + paragraphmark,parbox,parsep,partopsep,picture,poptabs,pounds,% + protect,pushtabs,put,qbezier,qbeziermax,r,raggedleft,raisebox,% + ref,refstepcounter,renewcommand,renewenvironment,restorecr,% + reversemarginpar,rhd,rightmargin,rightmark,rmfamily,roman,Roman,% + rootbox,rule,samepage,sbox,scshape,secdef,section,sectionmark,% + selectfont,setcounter,settodepth,settoheight,settowidth,sffamily,% + shortstack,showoutput,showoverfull,sloppy,sloppypar,slshape,% + smallskip,sqsubset,sqsupset,SS,stackrel,stepcounter,stop,stretch,% + subparagraphmark,subsectionmark,subsubsectionmark,sum,% + suppressfloats,symbol,tabbing,tabbingsep,tabcolsep,tabular,% + tabularnewline,textasciicircum,textasciitilde,textbackslash,% + textbar,textbf,textbraceleft,textbraceright,textbullet,% + textcircled,textcompwordmark,textdagger,textdaggerdbl,textdollar,% + textellipsis,textemdash,textendash,textexclamdown,textfloatsep,% + textfraction,textgreater,textheight,textit,textless,textmd,% + textnormal,textparagraph,textperiodcentered,textquestiondown,% + textquotedblleft,textquotedblright,textquoteleft,textquoteright,% + textregistered,textrm,textsc,textsection,textsf,textsl,% + textsterling,textsuperscript,texttrademark,texttt,textunderscore,% + textup,textvisiblespace,textwidth,thanks,thefootnote,thempfn,% + thempfn,thempfootnote,thepage,thepage,thicklines,thinlines,% + thispagestyle,title,today,topfigrule,topfraction,topmargin,% + topsep,totalheight,tracingfonts,trivlist,ttfamily,twocolumn,% + typein,typeout,unboldmath,unitlength,unlhd,unrhd,upshape,usebox,% + usecounter,usefont,usepackage,value,vector,verb,verbatim,vline,% + vspace,width,% + normalsize,small,footnotesize,scriptsize,tiny,large,Large,LARGE,% + huge,Huge}% + }% +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage[plain]{TeX}[common]{TeX}% + {moretexcs={advancepageno,beginsection,bf,bffam,bye,cal,cleartabs,% + columns,dosupereject,endinsert,eqalign,eqalignno,fiverm,fivebf,% + fivei,fivesy,folio,footline,hang,headline,it,itemitem,itfam,% + leqalignno,magnification,makefootline,makeheadline,midinsert,mit,% + mscount,nopagenumbers,normalbottom,of,oldstyle,pagebody,% + pagecontents,pageinsert,pageno,plainoutput,preloaded,proclaim,rm,% + settabs,sevenbf,seveni,sevensy,sevenrm,sl,slfam,supereject,% + tabalign,tabs,tabsdone,tabsyet,tenbf,tenex,teni,tenit,tenrm,% + tensl,tensy,tentt,textindent,topglue,topins,topinsert,tt,ttfam,% + ttraggedright,vfootnote}% + }% +% \end{macrocode} +% The following language is only a helper. +% \begin{macrocode} +\lst@definelanguage[common]{TeX}[primitive]{TeX} + {moretexcs={active,acute,ae,AE,aleph,allocationnumber,allowbreak,% + alpha,amalg,angle,approx,arccos,arcsin,arctan,arg,arrowvert,% + Arrowvert,ast,asymp,b,backslash,bar,beta,bgroup,big,Big,bigbreak,% + bigcap,bigcirc,bigcup,bigg,Bigg,biggl,Biggl,biggm,Biggm,biggr,% + Biggr,bigl,Bigl,bigm,Bigm,bigodot,bigoplus,bigotimes,bigr,Bigr,% + bigskip,bigskipamount,bigsqcup,bigtriangledown,bigtriangleup,% + biguplus,bigvee,bigwedge,bmod,bordermatrix,bot,bowtie,brace,% + braceld,bracelu,bracerd,braceru,bracevert,brack,break,breve,% + buildrel,bullet,c,cap,cases,cdot,cdotp,cdots,centering,% + centerline,check,chi,choose,circ,clubsuit,colon,cong,coprod,% + copyright,cos,cosh,cot,coth,csc,cup,d,dag,dagger,dashv,ddag,% + ddagger,ddot,ddots,deg,delta,Delta,det,diamond,diamondsuit,dim,% + displaylines,div,do,dospecials,dot,doteq,dotfill,dots,downarrow,% + Downarrow,downbracefill,egroup,eject,ell,empty,emptyset,endgraf,% + endline,enskip,enspace,epsilon,equiv,eta,exists,exp,filbreak,% + flat,fmtname,fmtversion,footins,footnote,footnoterule,forall,% + frenchspacing,frown,gamma,Gamma,gcd,ge,geq,gets,gg,goodbreak,% + grave,H,hat,hbar,heartsuit,hglue,hideskip,hidewidth,hom,% + hookleftarrow,hookrightarrow,hphantom,hrulefill,i,ialign,iff,Im,% + imath,in,inf,infty,int,interdisplaylinepenalty,% + interfootnotelinepenalty,intop,iota,item,j,jmath,joinrel,jot,% + kappa,ker,l,L,lambda,Lambda,land,langle,lbrace,lbrack,lceil,% + ldotp,ldots,le,leavevmode,leftarrow,Leftarrow,leftarrowfill,% + leftharpoondown,leftharpoonup,leftline,leftrightarrow,% + Leftrightarrow,leq,lfloor,lg,lgroup,lhook,lim,liminf,limsup,line,% + ll,llap,lmoustache,ln,lnot,log,longleftarrow,Longleftarrow,% + longleftrightarrow,Longleftrightarrow,longmapsto,longrightarrow,% + Longrightarrow,loop,lor,lq,magstep,magstep,magstephalf,mapsto,% + mapstochar,mathhexbox,mathpalette,mathstrut,matrix,max,maxdimen,% + medbreak,medskip,medskipamount,mid,min,models,mp,mu,multispan,% + nabla,narrower,natural,ne,nearrow,neg,negthinspace,neq,newbox,% + newcount,newdimen,newfam,newif,newinsert,newlanguage,newmuskip,% + newread,newskip,newtoks,newwrite,next,ni,nobreak,nointerlineskip,% + nonfrenchspacing,normalbaselines,normalbaselineskip,% + normallineskip,normallineskiplimit,not,notin,nu,null,nwarrow,o,O,% + oalign,obeylines,obeyspaces,odot,oe,OE,offinterlineskip,oint,% + ointop,omega,Omega,ominus,ooalign,openup,oplus,oslash,otimes,% + overbrace,overleftarrow,overrightarrow,owns,P,parallel,partial,% + perp,phantom,phi,Phi,pi,Pi,pm,pmatrix,pmod,Pr,prec,preceq,prime,% + prod,propto,psi,Psi,qquad,quad,raggedbottom,raggedright,rangle,% + rbrace,rbrack,rceil,Re,relbar,Relbar,removelastskip,repeat,% + rfloor,rgroup,rho,rhook,rightarrow,Rightarrow,rightarrowfill,% + rightharpoondown,rightharpoonup,rightleftharpoons,rightline,rlap,% + rmoustache,root,rq,S,sb,searrow,sec,setminus,sharp,showhyphens,% + sigma,Sigma,sim,simeq,sin,sinh,skew,slash,smallbreak,smallint,% + smallskip,smallskipamount,smash,smile,sp,space,spadesuit,sqcap,% + sqcup,sqrt,sqsubseteq,sqsupseteq,ss,star,strut,strutbox,subset,% + subseteq,succ,succeq,sum,sup,supset,supseteq,surd,swarrow,t,tan,% + tanh,tau,TeX,theta,Theta,thinspace,tilde,times,to,top,tracingall,% + triangle,triangleleft,triangleright,u,underbar,underbrace,% + uparrow,Uparrow,upbracefill,updownarrow,Updownarrow,uplus,% + upsilon,Upsilon,v,varepsilon,varphi,varpi,varrho,varsigma,% + vartheta,vdash,vdots,vec,vee,vert,Vert,vglue,vphantom,wedge,% + widehat,widetilde,wlog,wp,wr,xi,Xi,zeta}% + }% +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage[primitive]{TeX}% + {moretexcs={above,abovedisplayshortskip,abovedisplayskip,aftergroup,% + abovewithdelims,accent,adjdemerits,advance,afterassignment,atop,% + atopwithdelims,badness,baselineskip,batchmode,begingroup,% + belowdisplayshortskip,belowdisplayskip,binoppenalty,botmark,box,% + boxmaxdepth,brokenpenalty,catcode,char,chardef,cleaders,closein,% + closeout,clubpenalty,copy,count,countdef,cr,crcr,csname,day,% + deadcycles,def,defaulthyphenchar,defaultskewchar,delcode,% + delimiter,delimiterfactor,delimitershortfall,dimen,dimendef,% + discretionary,displayindent,displaylimits,displaystyle,% + displaywidowpenalty,displaywidth,divide,doublehyphendemerits,dp,% + edef,else,emergencystretch,end,endcsname,endgroup,endinput,% + endlinechar,eqno,errhelp,errmessage,errorcontextlines,% + errorstopmode,escapechar,everycr,everydisplay,everyhbox,everyjob,% + everymath,everypar,everyvbox,exhyphenpenalty,expandafter,fam,fi,% + finalhypendemerits,firstmark,floatingpenalty,font,fontdimen,% + fontname,futurelet,gdef,global,globaldefs,halign,hangafter,% + hangindent,hbadness,hbox,hfil,hfill,hfilneg,hfuzz,hoffset,% + holdinginserts,hrule,hsize,hskip,hss,ht,hyphenation,hyphenchar,% + hyphenpenalty,if,ifcase,ifcat,ifdim,ifeof,iffalse,ifhbox,ifhmode,% + ifinner,ifmmode,ifnum,ifodd,iftrue,ifvbox,ifvmode,ifvoid,ifx,% + ignorespaces,immediate,indent,input,insert,insertpenalties,% + interlinepenalty,jobname,kern,language,lastbox,lastkern,% + lastpenalty,lastskip,lccode,leaders,left,lefthyphenmin,leftskip,% + leqno,let,limits,linepenalty,lineskip,lineskiplimits,long,% + looseness,lower,lowercase,mag,mark,mathaccent,mathbin,mathchar,% + mathchardef,mathchoice,mathclose,mathcode,mathinner,mathop,% + mathopen,mathord,mathpunct,mathrel,mathsurround,maxdeadcycles,% + maxdepth,meaning,medmuskip,message,mkern,month,moveleft,% + moveright,mskip,multiply,muskip,muskipdef,newlinechar,noalign,% + noboundary,noexpand,noindent,nolimits,nonscript,nonstopmode,% + nulldelimiterspace,nullfont,number,omit,openin,openout,or,outer,% + output,outputpenalty,over,overfullrule,overline,overwithdelims,% + pagedepth,pagefilllstretch,pagefillstretch,pagefilstretch,% + pagegoal,pageshrink,pagestretch,pagetotal,par,parfillskip,% + parindent,parshape,parskip,patterns,pausing,penalty,% + postdisplaypenalty,predisplaypenalty,predisplaysize,pretolerance,% + prevdepth,prevgraf,radical,raise,read,relax,relpenalty,right,% + righthyphenmin,rightskip,romannumeral,scriptfont,% + scriptscriptfont,scriptscriptstyle,scriptspace,scriptstyle,% + scrollmode,setbox,setlanguage,sfcode,shipout,show,showbox,% + showboxbreadth,showboxdepth,showlists,showthe,skewchar,skip,% + skipdef,spacefactor,spaceskip,span,special,splitbotmark,% + splitfirstmark,splitmaxdepth,splittopskip,string,tabskip,% + textfont,textstyle,the,thickmuskip,thinmuskip,time,toks,toksdef,% + tolerance,topmark,topskip,tracingcommands,tracinglostchars,% + tracingmacros,tracingonline,tracingoutput,tracingpages,% + tracingparagraphs,tracingrestores,tracingstats,uccode,uchyph,% + underline,unhbox,unhcopy,unkern,unpenalty,unskip,unvbox,unvcopy,% + uppercase,vadjust,valign,vbadness,vbox,vcenter,vfil,vfill,% + vfilneg,vfuzz,voffset,vrule,vsize,vskip,vsplit,vss,vtop,wd,% + widowpenalty,write,xdef,xleaders,xspaceskip,year},% + sensitive,% + alsoother={0123456789$_},% + morecomment=[l]\%% + }[keywords,tex,comments]% +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} % \endgroup % -% \begin{macro}{\lstkeys@tex@primitives} -% \begin{macro}{\lstkeys@tex@commoncs} -% \begin{macro}{\lstkeys@tex@latexcs} -% Now come all control sequences. -% The second macro holds the common control sequences of plain \TeX\ and \LaTeX. -% \begin{macrocode} -\lststorekeywords\lstkeys@tex@primitives{above,abovedisplayshortskip,% - abovedisplayskip,abovewithdelims,accent,adjdemerits,advance,% - afterassignment,aftergroup,atop,atopwithdelims,badness,% - baselineskip,batchmode,begingroup,belowdisplayshortskip,% - belowdisplayskip,binoppenalty,botmark,box,boxmaxdepth,% - brokenpenalty,catcode,char,chardef,cleaders,closein,closeout,% - clubpenalty,copy,count,countdef,cr,crcr,csname,day,deadcycles,def,% - defaulthyphenchar,defaultskewchar,delcode,delimiter,% - delimiterfactor,delimitershortfall,dimen,dimendef,discretionary,% - displayindent,displaylimits,displaystyle,displaywidowpenalty,% - displaywidth,divide,doublehyphendemerits,dp,else,emergencystretch,% - end,endcsname,endgroup,endinput,endlinechar,eqno,errhelp,% - errmessage,errorcontextlines,errorstopmode,escapechar,everycr,% - everydisplay,everyhbox,everyjob,everymath,everypar,everyvbox,% - exhyphenpenalty,expandafter,fam,fi,finalhypendemerits,firstmark,% - floatingpenalty,font,fontdimen,fontname,futurelet,gdef,global,% - globaldefs,halign,hangafter,hangindent,hbadness,hbox,hfil,hfill,% - hfilneg,hfuzz,hoffset,holdinginserts,hrule,hsize,hskip,hss,ht,% - hyphenation,hyphenchar,hyphenpenalty,if,ifcase,ifcat,ifdim,ifeof,% - iffalse,ifhbox,ifhmode,ifinner,ifmmode,ifnum,ifodd,iftrue,ifvbox,% - ifvmode,ifvoid,ifx,ignorespaces,immediate,indent,input,insert,% - insertpenalties,interlinepenalty,jobname,kern,language,lastbox,% - lastkern,lastpenalty,lastskip,lccode,leaders,left,lefthyphenmin,% - leftskip,leqno,let,limits,linepenalty,lineskip,lineskiplimits,long,% - looseness,lower,lowercase,mag,mark,,mathaccent,mathbin,mathchar,% - mathchardef,mathchoice,mathclose,mathcode,mathinner,mathop,% - mathopen,mathord,mathpunct,mathrel,mathsurround,maxdeadcycles,% - maxdepth,meaning,medmuskip,message,mkern,month,moveleft,moveright,% - mskip,multiply,muskip,muskipdef,newlinechar,noalign,noboundary,% - noexpand,noindent,nolimits,nonscript,nonstopmode,% - nulldelimiterspace,nullfont,number,omit,openin,openout,or,outer,% - output,outputpenalty,over,overfullrule,overline,overwithdelims,% - pagedepth,pagefilllstretch,pagefillstretch,pagefilstretch,pagegoal,% - pageshrink,pagestretch,pagetotal,par,parfillskip,parindent,% - parshape,parskip,patterns,pausing,penalty,postdisplaypenalty,% - predisplaypenalty,predisplaysize,pretolerance,prevdepth,prevgraf,% - radical,raise,read,relax,relpenalty,right,righthyphenmin,rightskip,% - romannumeral,scriptfont,scriptscriptfont,scriptscriptstyle,% - scriptspace,scriptstyle,scrollmode,setbox,setlanguage,sfcode,% - shipout,show,showbox,showboxbreadth,showboxdepth,showlists,showthe,% - skewchar,skip,skipdef,spacefactor,spaceskip,span,special,% - splitbotmark,splitfirstmark,splitmaxdepth,splittopskip,string,% - tabskip,textfont,textstyle,the,thickmuskip,thinmuskip,time,toks,% - toksdef,tolerance,topmark,topskip,tracingcommands,tracinglostchars,% - tracingmacros,tracingonline,tracingoutput,tracingpages,% - tracingparagraphs,tracingrestores,tracingstats,uccode,uchyph,% - underline,unhbox,unhcopy,unkern,unpenalty,unskip,unvbox,unvcopy,% - uppercase,vadjust,valign,vbadness,vbox,vcenter,vfil,vfill,vfilneg,% - vfuzz,voffset,vrule,vsize,vskip,vsplit,vss,vtop,wd,widowpenalty,% - write,xdef,xleaders,xspaceskip,year}% -% \end{macrocode} -% \begin{macrocode} -\lststorekeywords\lstkeys@tex@commoncs{active,acute,ae,AE,aleph,% - allocationnumber,allowbreak,alpha,amalg,angle,approx,arccos,arcsin,% - arctan,arg,arrowvert,Arrowvert,ast,asymp,b,backslash,bar,beta,% - bgroup,big,Big,bigbreak,bigcap,bigcirc,bigcup,bigg,Bigg,biggl,% - Biggl,biggm,Biggm,biggr,Biggr,bigl,Bigl,bigm,Bigm,bigodot,bigoplus,% - bigotimes,bigr,Bigr,bigskip,bigskipamount,bigsqcup,bigtriangledown,% - bigtriangleup,biguplus,bigvee,bigwedge,bmod,bordermatrix,bot,% - bowtie,brace,braceld,bracelu,bracerd,braceru,bracevert,brack,break,% - breve,buildrel,bullet,c,cap,cases,cdot,cdotp,cdots,centering,% - centerline,check,chi,choose,circ,clubsuit,colon,cong,coprod,% - copyright,cos,cosh,cot,coth,csc,cup,d,dag,dagger,dashv,ddag,% - ddagger,ddot,ddots,deg,delta,Delta,det,diamond,diamondsuit,dim,% - displaylines,div,do,dospecials,dot,doteq,dotfill,dots,downarrow,% - Downarrow,downbracefill,egroup,eject,ell,empty,emptyset,endgraf,% - endline,enskip,enspace,epsilon,equiv,eta,exists,exp,filbreak,flat,% - fmtname,fmtversion,footins,footnote,footnoterule,forall,% - frenchspacing,frown,gamma,Gamma,gcd,ge,geq,gets,gg,goodbreak,grave,% - H,hat,hbar,heartsuit,hglue,hideskip,hidewidth,hom,hookleftarrow,% - hookrightarrow,hphantom,hrulefill,i,ialign,iff,Im,imath,in,inf,% - infty,int,interdisplaylinepenalty,interfootnotelinepenalty,intop,% - iota,item,j,jmath,joinrel,jot,kappa,ker,l,L,lambda,Lambda,land,% - langle,lbrace,lbrack,lceil,ldotp,ldots,le,leavevmode,leftarrow,% - Leftarrow,leftarrowfill,leftharpoondown,leftharpoonup,leftline,% - leftrightarrow,Leftrightarrow,leq,lfloor,lg,lgroup,lhook,lim,% - liminf,limsup,line,ll,llap,lmoustache,ln,lnot,log,longleftarrow,% - Longleftarrow,longleftrightarrow,Longleftrightarrow,longmapsto,% - longrightarrow,Longrightarrow,loop,lor,lq,magstep,magstep,% - magstephalf,mapsto,mapstochar,mathhexbox,mathpalette,mathstrut,% - matrix,max,maxdimen,medbreak,medskip,medskipamount,mid,min,models,% - mp,mu,multispan,nabla,narrower,natural,ne,nearrow,neg,negthinspace,% - neq,newbox,newcount,newdimen,newfam,newif,newinsert,newlanguage,% - newmuskip,newread,newskip,newtoks,newwrite,next,ni,nobreak,% - nointerlineskip,nonfrenchspacing,normalbaselines,% - normalbaselineskip,normallineskip,normallineskiplimit,not,notin,nu,% - null,nwarrow,o,O,oalign,obeylines,obeyspaces,odot,oe,OE,% - offinterlineskip,oint,ointop,omega,Omega,ominus,ooalign,openup,% - oplus,oslash,otimes,overbrace,overleftarrow,overrightarrow,owns,P,% - parallel,partial,perp,phantom,phi,Phi,pi,Pi,pm,pmatrix,pmod,Pr,% - prec,preceq,prime,prod,propto,psi,Psi,qquad,quad,raggedbottom,% - raggedright,rangle,rbrace,rbrack,rceil,Re,relbar,Relbar,% - removelastskip,repeat,rfloor,rgroup,rho,rhook,rightarrow,% - Rightarrow,rightarrowfill,rightharpoondown,rightharpoonup,% - rightleftharpoons,rightline,rlap,rmoustache,root,rq,S,sb,searrow,% - sec,setminus,sharp,showhyphens,sigma,Sigma,sim,simeq,sin,sinh,skew,% - slash,smallbreak,smallint,smallskip,smallskipamount,smash,smile,sp,% - space,spadesuit,sqcap,sqcup,sqrt,sqsubseteq,sqsupseteq,ss,star,% - strut,strutbox,subset,subseteq,succ,succeq,sum,sup,supset,supseteq,% - surd,swarrow,t,tan,tanh,tau,TeX,theta,Theta,thinspace,tilde,times,% - to,top,tracingall,triangle,triangleleft,triangleright,u,underbar,% - underbrace,uparrow,Uparrow,upbracefill,updownarrow,Updownarrow,% - uplus,upsilon,Upsilon,v,varepsilon,varphi,varpi,varrho,varsigma,% - vartheta,vdash,vdots,vec,vee,vert,Vert,vglue,vphantom,wedge,% - widehat,widetilde,wlog,wp,wr,xi,Xi,zeta}% -% \end{macrocode} -% \begin{macrocode} -\lststorekeywords\lstkeys@tex@latexcs{a,AA,aa,addcontentsline,% - addpenalty,addtocontents,addtocounter,addtolength,addtoversion,% - addvspace,alph,Alph,and,arabic,array,arraycolsep,arrayrulewidth,% - arraystretch,author,baselinestretch,begin,bezier,bfseries,bibcite,% - bibdata,bibitem,bibliography,bibliographystyle,bibstyle,boldmath,% - botfigrule,bottomfraction,Box,caption,center,CheckCommand,circle,% - citation,cite,cleardoublepage,clearpage,cline,columnsep,% - columnseprule,columnwidth,contentsline,dashbox,date,dblfigrule,% - dblfloatpagefraction,dblfloatsep,dbltextfloatsep,dbltopfraction,% - defaultscriptratio,defaultscriptscriptratio,depth,Diamond,% - displaymath,document,documentclass,documentstyle,doublerulesep,em,% - emph,endarray,endcenter,enddisplaymath,enddocument,endenumerate,% - endeqnarray,endequation,endflushleft,endflushright,enditemize,% - endlist,endlrbox,endmath,endminipage,endpicture,endsloppypar,% - endtabbing,endtabular,endtrivlist,endverbatim,enlargethispage,% - ensuremath,enumerate,eqnarray,equation,evensidemargin,extracolsep,% - fbox,fboxrule,fboxsep,filecontents,fill,floatpagefraction,floatsep,% - flushbottom,flushleft,flushright,fnsymbol,fontencoding,fontfamily,% - fontseries,fontshape,fontsize,fontsubfuzz,footnotemark,footnotesep,% - footnotetext,footskip,frac,frame,framebox,fussy,glossary,% - headheight,headsep,height,hline,hspace,I,include,includeonly,index,% - inputlineno,intextsep,itemindent,itemize,itemsep,iterate,itshape,% - Join,kill,label,labelsep,labelwidth,LaTeX,LaTeXe,leadsto,lefteqn,% - leftmargin,leftmargini,leftmarginii,leftmarginiii,leftmarginiv,% - leftmarginv,leftmarginvi,leftmark,lhd,linebreak,linespread,% - linethickness,linewidth,list,listfiles,listfiles,listparindent,% - lrbox,makeatletter,makeatother,makebox,makeglossary,makeindex,% - makelabel,MakeLowercase,MakeUppercase,marginpar,marginparpush,% - marginparsep,marginparwidth,markboth,markright,math,mathbf,% - mathellipsis,mathgroup,mathit,mathsf,mathsterling,mathtt,% - mathunderscore,mathversion,mbox,mdseries,mho,minipage,multicolumn,% - multiput,NeedsTeXFormat,newcommand,newcounter,newenvironment,% - newfont,newhelp,newlabel,newlength,newline,newmathalphabet,newpage,% - newsavebox,newtheorem,nobreakspace,nobreakspace,nocite,nocorr,% - nocorrlist,nofiles,nolinebreak,nonumber,nopagebreak,normalcolor,% - normalfont,normalmarginpar,numberline,obeycr,oddsidemargin,% - oldstylenums,onecolumn,oval,pagebreak,pagenumbering,pageref,% - pagestyle,paperheight,paperwidth,paragraphmark,parbox,parsep,% - partopsep,picture,poptabs,pounds,protect,pushtabs,put,qbezier,% - qbeziermax,r,raggedleft,raisebox,ref,refstepcounter,renewcommand,% - renewenvironment,restorecr,reversemarginpar,rhd,rightmargin,% - rightmark,rmfamily,roman,Roman,rootbox,rule,samepage,sbox,scshape,% - secdef,sectionmark,selectfont,setcounter,settodepth,settoheight,% - settowidth,sffamily,shortstack,showoutput,showoverfull,sloppy,% - sloppypar,slshape,sqsubset,sqsupset,SS,stackrel,stepcounter,stop,% - stretch,subparagraphmark,subsectionmark,subsubsectionmark,% - suppressfloats,symbol,tabbing,tabbingsep,tabcolsep,tabular,% - tabularnewline,textasciicircum,textasciitilde,textbackslash,% - textbar,textbf,textbraceleft,textbraceright,textbullet,textcircled,% - textcompwordmark,textdagger,textdaggerdbl,textdollar,textellipsis,% - textemdash,textendash,textexclamdown,textfloatsep,textfraction,% - textgreater,textheight,textit,textless,textmd,textnormal,% - textparagraph,textperiodcentered,textquestiondown,textquotedblleft,% - textquotedblright,textquoteleft,textquoteright,textregistered,% - textrm,textsc,textsection,textsf,textsl,textsterling,% - textsuperscript,texttrademark,texttt,textunderscore,textup,% - textvisiblespace,textwidth,thanks,thefootnote,thempfn,thempfn,% - thempfootnote,thepage,thepage,thicklines,thinlines,thispagestyle,% - title,today,topfigrule,topfraction,topmargin,topsep,totalheight,% - tracingfonts,trivlist,ttfamily,twocolumn,typein,typeout,unboldmath,% - unitlength,unlhd,unrhd,upshape,usebox,usecounter,usefont,% - usepackage,value,vector,verb,verbatim,vline,vspace,width}% -% \end{macrocode} -% \end{macro}\end{macro}\end{macro} +% +% \subsection{VBScript} +% +% \lstthanks{Sonja~Weidmann}{Sonja.Weidmann@sap.com}{2000/01/10}{VBScript} +% sent me this language definition. % \begingroup % \begin{macrocode} -% +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% VBScript definition (c) 2000 Sonja Weidmann +%% +\lst@definelanguage{VBScript}% + {morekeywords={Call,Case,Const,Dim,Do,Each,Else,End,Erase,Error,Exit,% + Explicit,For,Function,If,Loop,Next,On,Option,Private,Public,% + Randomize,ReDim,Rem,Select,Set,Sub,Then,Wend,While,Abs,Array,Asc,% + Atn,CBool,CByte,CCur,CDate,CDbl,Chr,CInt,CLng,Cos,CreateObject,% + CSng,CStr,Date,DateAdd,DateDiff,DatePart,DateSerial,DateValue,% + Day,Exp,Filter,Fix,FormatCurrency,FormatDateTime,FormatNumber,% + FormatPercent,GetObject,Hex,Hour,InputBox,InStr,InStrRev,Int,% + IsArray,IsDate,IsEmpty,IsNull,IsNumeric,IsObject,Join,LBound,% + LCase,Left,Len,LoadPicture,Log,LTrim,Mid,Minute,Month,MonthName,% + MsgBox,Now,Oct,Replace,RGB,Right,Rnd,Round,RTrim,ScriptEngine,% + ScriptEngineBuildVersion,ScriptEngineMajorVersion,% + ScriptEngineMinorVersion,Second,Sgn,Sin,Space,Split,Sqr,StrComp,% + StrReverse,String,Tan,Time,TimeSerial,TimeValue,Trim,TypeName,% + UBound,UCase,VarType,Weekday,WeekdayName,Year, And,Eqv,Imp,Is,% + Mod,Not,Or,Xor,Add,BuildPath,Clear,Close,Copy,CopyFile,% + CopyFolder,CreateFolder,CreateTextFile,Delete,DeleteFile,% + DeleteFolder,Dictionary,Drive,DriveExists,Drives,Err,Exists,File,% + FileExists,FileSystemObject,Files,Folder,FolderExists,Folders,% + GetAbsolutePathName,GetBaseName,GetDrive,GetDriveName,% + GetExtensionName,GetFile,GetFileName,GetFolder,% + GetParentFolderName,GetSpecialFolder,GetTempName,Items,Keys,Move,% + MoveFile,MoveFolder,OpenAsTextStream,OpenTextFile,Raise,Read,% + ReadAll,ReadLine,Remove,RemoveAll,Skip,SkipLine,TextStream,Write,% + WriteBlankLines,WriteLine,Alias,Archive,CDROM,Compressed,% + Directory,Fixed,ForAppending,ForReading,ForWriting,Hidden,Normal,% + RAMDisk,ReadOnly,Remote,Removable,System,SystemFolder,% + TemporaryFolder,TristateFalse,TristateTrue,TristateUseDefault,% + Unknown,Volume,WindowsFolder,vbAbortRetryIgnore,% + vbApplicationModal,vbArray,vbBinaryCompare,vbBlack,vbBlue,% + vbBoolean,vbByte,vbCr,vbCrLf,vbCritical,vbCurrency,vbCyan,% + vbDataObject,vbDate,vbDecimal,vbDefaultButton1,vbDefaultButton2,% + vbDefaultButton3,vbDefaultButton4,vbDouble,vbEmpty,vbError,% + vbExclamation,vbFirstFourDays,vbFirstFullWeek,vbFirstJan1,% + vbFormFeed,vbFriday,vbGeneralDate,vbGreen,vbInformation,% + vbInteger,vbLf,vbLong,vbLongDate,vbLongTime,vbMagenta,vbMonday,% + vbNewLine,vbNull,vbNullChar,vbNullString,vbOKC,ancel,vbOKOnly,% + vbObject,vbObjectError,vbQuestion,vbRed,vbRetryCancel,vbSaturday,% + vbShortDate,vbShortTime,vbSingle,vbString,vbSunday,vbSystemModal,% + vbTab,vbTextCompare,vbThursday,vbTuesday,vbUseSystem,% + vbUseSystemDayOfWeek,vbVariant,vbVerticalTab,vbWednesday,vbWhite,% + vbYellow,vbYesNo,vbYesNoCancel},% + sensitive=f,% + morecomment=[l]',% + morestring=[d]"% + }[keywords,comments,strings]% +% \end{macrocode} +% \begin{macrocode} +% % \end{macrocode} % \endgroup % % % \subsection{VHDL} % -% This language is due to \lsthelper{Kai Wollenweber}{kai@ece.wpi.edu}{1997/11/04}{VHDL}. -% I've done conversion to \textsf{listings} 0.19 only. -% \lsthelper{Gaurav Aggarwal}{gaurav@ics.uci.edu}{1998/04/02}{\lstsensitivefalse} reported that VHDL is case insensitive. +% This language is due to \lstthanks{Kai~Wollenweber}{kai@ece.wpi.edu} +% {1997/11/04}{VHDL}. I've done conversion to version 0.19 only. +% \lsthelper{Gaurav Aggarwal}{gaurav@ics.uci.edu}{1998/04/02}{sensitive=f} +% reported that VHDL is case insensitive. % \begingroup % \begin{macrocode} -%<*vhdl> +%<*lang1> % \end{macrocode} % \begin{macrocode} -%% (c) 1997 Kai Wollenweber -\lstdefinelanguage{VHDL}% - {keywords={ALL,ARCHITECTURE,ABS,AND,ASSERT,ARRAY,AFTER,ALIAS,% +%% +%% VHDL definition (c) 1997 Kai Wollenweber +%% +\lst@definelanguage{VHDL}% + {morekeywords={ALL,ARCHITECTURE,ABS,AND,ASSERT,ARRAY,AFTER,ALIAS,% ACCESS,ATTRIBUTE,BEGIN,BODY,BUS,BLOCK,BUFFER,CONSTANT,CASE,% COMPONENT,CONFIGURATION,DOWNTO,ELSE,ELSIF,END,ENTITY,EXIT,% FUNCTION,FOR,FILE,GENERIC,GENERATE,GUARDED,GROUP,IF,IN,INOUT,IS,% @@ -1741,21 +3864,119 @@ nor under a different one. RETURN,REGISTER,REJECT,SIGNAL,SUBTYPE,SLL,SRL,SLA,SRA,SEVERITY,% SELECT,THEN,TYPE,TRANSPORT,TO,USE,UNITS,UNTIL,VARIABLE,WHEN,WAIT,% WHILE,XOR,XNOR},% - sensitive=false,% 1998 Gaurav Aggarwal - commentline={--},% - stringizer=[d]{"}% - }% + sensitive=f,% 1998 Gaurav Aggarwal + morecomment=[l]--,% + morestring=[d]{"}% + }[keywords,comments,strings]% +% \end{macrocode} +% The VHDL-AMS dialect has been added by \lstthanks{Steffen~Klupsch} +% {steffen@vlsi.informatik.tu-darmstadt.de}{2001/10/05}. +% \begin{macrocode} +%% +%% VHDL-AMS definition (c) Steffen Klupsch +%% +\lst@definelanguage[AMS]{VHDL}[]{VHDL}% + {morekeywords={ACROSS,ARRAY,BREAK,DISCONNECT,NATURE,NOISE,PORT,% + PROCEDURAL,QUANTITY,SHARED,SPECTRUM,SUBNATURE,TERMINAL,THROUGH,% + TOLERANCE,UNAFFACTED,UNITS}} % \end{macrocode} % \begin{macrocode} -% +% % \end{macrocode} % \endgroup % % -% \setcounter{IndexColumns}{2} -% \PrintIndex +% \subsection{VRML} +% +% This language is due to \lstthanks{Oliver~Baum}{oli.baum@web.de}{2001/07/10} +% {VRML}. +% \begingroup +% \begin{macrocode} +%<*lang2> +% \end{macrocode} +% \begin{macrocode} +%% +%% VRML definition (c) 2001 Oliver Baum +%% +\lst@definelanguage[97]{VRML} + {morekeywords={DEF,EXTERNPROTO,FALSE,IS,NULL,PROTO,ROUTE,TO,TRUE,USE,% + eventIn,eventOut,exposedField,field,Introduction,Anchor,% + Appearance,AudioClip,Background,Billboard,Box,Collision,Color,% + ColorInterpolator,Cone,Coordinate,CoordinateInterpolator,% + Cylinder,CylinderSensor,DirectionalLight,ElevationGrid,Extrusion,% + Fog,FontStyle,Group,ImageTexture,IndexedFaceSet,IndexedLineSet,% + Inline,LOD,Material,MovieTexture,NavigationInfo,Normal,% + NormalInterpolator,OrientationInterpolator,PixelTexture,% + PlaneSensor,PointLight,PointSet,PositionInterpolator,% + ProximitySensor,ScalarInterpolator,Script,Shape,Sound,Sphere,% + SphereSensor,SpotLight,Switch,Text,TextureCoordinate,% + TextureTransform,TimeSensor,TouchSensor,Transform,Viewpoint,% + VisibilitySensor,WorldInfo},% + morecomment=[l]\#,% bug: starts comment in the first column + morestring=[b]"% + }[keywords,comments,strings] +% \end{macrocode} +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +% \subsection{XML} +% +% This is my first attempt to support XML. It is from 2000/07/18. +% \begingroup +% \begin{macrocode} +%<*lang1> +% \end{macrocode} +% \begin{macrocode} +\lst@definelanguage{XML}% + {keywords={,CDATA,DOCTYPE,ATTLIST,termdef,ELEMENT,EMPTY,ANY,ID,% + IDREF,IDREFS,ENTITY,ENTITIES,NMTOKEN,NMTOKENS,NOTATION,% + INCLUDE,IGNORE,SYSTEM,PUBLIC,NDATA,PUBLIC,% + PCDATA,REQUIRED,IMPLIED,FIXED,%%% preceded by # + xml,xml:space,xml:lang,version,standalone,default,preserve},% + alsoother=$,% + alsoletter=:,% + keywordsinside=<>,% + morestring=[d]",% ??? doubled + morestring=[d]',% ??? doubled + MoreSelectCharTable=% + \lst@CArgX--\relax\lst@DefDelimB{}{}% + {\ifnum\lst@mode=\lst@insidemode\else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@commentmode{{\lst@commentstyle}}% + \lst@CArgX--\relax\lst@DefDelimE{}{}{}% + \lst@EndComment\lst@commentmode + \lst@CArgX[CDATA[\relax\lst@CDef{}% + {\ifnum\lst@mode=\lst@insidemode + \expandafter\lst@BeginCDATA + \else \expandafter\lst@CArgEmpty + \fi}% + \@empty + \lst@CArgX]]\relax\lst@CDef{}% + {\ifnum\lst@mode=\lst@GPmode + \expandafter\lst@EndComment + \else \expandafter\lst@CArgEmpty + \fi}% + \@empty + }[keywords,comments,strings,html]% +% \end{macrocode} +% And after receiving a bug report from \lsthelper{Michael Niedermair} +% {m.g.n@gmx.de}{2002/04/07}{undefined control sequence \lst@commentmode} I +% converted the version 0.21 contents of |MoreSelectCharTable| to version 1.0. +% \begin{macrocode} +% +% \end{macrocode} +% \endgroup +% +% +%^^A \setcounter{IndexColumns}{2} +%^^A \PrintIndex % % % \Finale % \endinput + diff --git a/docs/packages/listings/lstdrvrs.ins b/docs/packages/listings/lstdrvrs.ins index c769e690fa..7b01ba631f 100644 --- a/docs/packages/listings/lstdrvrs.ins +++ b/docs/packages/listings/lstdrvrs.ins @@ -6,89 +6,45 @@ %% %% lstdrvrs.dtx (with options: `install') %% -%% (w)(c) 1996-1998 Carsten Heinz -%% -%% Please read the software license in listings.dtx or listings.dvi. -%% -%% This file is distributed freely. You are not allowed to take money for -%% the distribution of this file, except for a nominal charge for copying -%% etc.. -%% -%% This file is free for any non-commercial use. Commercial use needs (i) -%% explicit permission of the author of this package and (ii) the payment -%% of a license fee. This fee is to be determined in each instance by the -%% commercial user and the package author and is to be payed as donation -%% to the LaTeX3 project. -%% -%% This file is distributed without any warranty, express or implied, as -%% to merchantability or fitness for any particular purpose. -%% -%% Permission is granted to change this file. You are not allowed to -%% distribute any changed version this file, neither under the same name -%% nor under a different one. -%% -\ifx\keepsilent\undefined % - \input{docstrip} - \keepsilent - \askforoverwritefalse -\fi -\def\batchfile{lstdrvrs.ins} - +%% (w)(c) 1996/1997/1998/1999/2000/2001/2002 Carsten Heinz and/or any +%% other author listed elsewhere in this file. +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% This file is completely free and comes without any warranty. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +\input docstrip \preamble - -(w)(c) 1996,1997,1998 Carsten Heinz and/or any other author mentioned -elsewhere in this file. - -This file is distributed freely. You are not allowed to take money for -the use or distribution of this file, except for a nominal charge for -copying etc.. - -This file is distributed without any warranty, express or implied, as -to merchantability or fitness for any particular purpose. - -Permission is granted to change this file. You are not allowed to -distribute any changed version this file, neither under the same name -nor under a different one. - \endpreamble -\generate{ - \file{lstalgol.sty} {\from{listings.dtx}{keywordcomments} - \from{lstdrvrs.dtx}{algol}} - \file{lstc.sty} {\from{listings.dtx}{c} - \from{lstdrvrs.dtx}{c,objective-c,c++}} - \file{lstperl.sty} {\from{listings.dtx}{perl} - \from{lstdrvrs.dtx}{perl}} - \file{lstsimula.sty} {\from{listings.dtx}{keywordcomments} - \from{lstdrvrs.dtx}{simula}} - \file{lsttex.sty} {\from{listings.dtx}{tex} - \from{lstdrvrs.dtx}{tex}} - \file{lstada.sty} {\from{lstdrvrs.dtx}{ada}} - \file{lstcobol.sty} {\from{lstdrvrs.dtx}{cobol}} - \file{lstedu.sty} {\from{lstdrvrs.dtx}{comal,elan,logo}} - \file{lstcsh.sty} {\from{lstdrvrs.dtx}{csh}} - \file{lstdelphi.sty} {\from{lstdrvrs.dtx}{delphi}} - \file{lsteiffel.sty} {\from{lstdrvrs.dtx}{eiffel}} - \file{lsteuphoria.sty}{\from{lstdrvrs.dtx}{euphoria}} - \file{lstfortran.sty} {\from{lstdrvrs.dtx}{fortran}} - \file{lsthtml.sty} {\from{lstdrvrs.dtx}{html}} - \file{lstidl.sty} {\from{lstdrvrs.dtx}{idl}} - \file{lstjava.sty} {\from{lstdrvrs.dtx}{java}} +\ifToplevel{ +\usedir{tex/latex/listings} +\keepsilent +\askonceonly } \generate{ - \file{lstlisp.sty} {\from{lstdrvrs.dtx}{lisp}} - \file{lstmatlab.sty} {\from{lstdrvrs.dtx}{matlab}} - \file{lstmercury.sty} {\from{lstdrvrs.dtx}{mercury}} - \file{lstmodula.sty} {\from{lstdrvrs.dtx}{modula}} - \file{lstoberon.sty} {\from{lstdrvrs.dtx}{oberon}} - \file{lstpascal.sty} {\from{lstdrvrs.dtx}{pascal}} - \file{lstpli.sty} {\from{lstdrvrs.dtx}{pli}} - \file{lstprolog.sty} {\from{lstdrvrs.dtx}{prolog}} - \file{lstsql.sty} {\from{lstdrvrs.dtx}{sql}} - \file{lstvhdl.sty} {\from{lstdrvrs.dtx}{vhdl}} + \file{lstlang1.sty}{\from{lstdrvrs.dtx}{lang1}} + \file{lstlang2.sty}{\from{lstdrvrs.dtx}{lang2}} + \file{lstlang3.sty}{\from{lstdrvrs.dtx}{lang3}} } -\end + +\ifToplevel{ +\Msg{*} +\Msg{* You probably need to move all created `.sty' and `.cfg'} +\Msg{* files into a directory searched by TeX.} +\Msg{*} +\Msg{* Run `lstdrvrs.dtx' through LaTeX2e to get the documentation.} +\Msg{*} +} + +\endbatchfile + [2002/07/31 v1.0d listings language file] \endinput %% %% End of file `lstdrvrs.ins'. diff --git a/docs/packages/listings/lstpatch.sty b/docs/packages/listings/lstpatch.sty index 8173d86af8..df942c9704 100644 --- a/docs/packages/listings/lstpatch.sty +++ b/docs/packages/listings/lstpatch.sty @@ -1,69 +1,464 @@ -%% -%% 1998/11/23: First patch for listings.sty -%% -%% (c) 1998 Carsten Heinz -%% -\def\lstlanguage@[#1]#2{% - \lst@LocateLanguage[#1]{#2}% - \@ifundefined{\lst@requested}% - {{\catcode`\^^M=9\catcode`\"=12\makeatletter % - \input{\lst@driver.sty}}}{}% - \@ifundefined{\lst@requested}% - {\PackageError{Listings}% - {\ifx\@empty\lst@dialect@\else \lst@dialect@\space of \fi % - \lst@language@\space undefined}{The driver file is not - loadable or doesn't support the language.^^J% - Type to proceed without changing the language.}}% - {\lsthk@SetLanguage % - \csname\lst@requested\endcsname % -%% modification of -% \def\lst@language{#1}\lst@Normalize\lst@language % -% \def\lst@dialect{#2}\lst@Normalize\lst@dialect}} - \def\lst@language{#2}\lst@Normalize\lst@language % - \def\lst@dialect{#1}\lst@Normalize\lst@dialect}} -%% end modification -% -%% load .fd files -\lst@AddToHook{BeforeSelectCharTable} - {\setbox\@tempboxa\hbox{\lst@labelstyle \lst@loadfd}} -%% end load .fd files -% -%% move \let\lst@lastother\relax to end of macros -\def\lst@Output{% - \ifnum\lst@length=\z@\else % - \lst@NewLine \lst@UseLostSpace % - \hbox to \lst@length\lst@width{% - \lst@lefthss % - \lsthk@Output \lst@thestyle{% - \expandafter\lst@FillOutputBox\the\lst@token\relax}% - \lst@righthss}% - \global\advance\lst@pos -\lst@length % - \lst@token{}\lst@length\z@ % - \fi % - \let\lst@lastother\relax} -\def\lst@OutputFlexible{% - \ifnum\lst@length=\z@\else % - \lst@NewLine \lst@UseLostSpace % - \setbox\@tempboxa\hbox{% - \lsthk@Output \lst@thestyle{\the\lst@token}}% - \lst@CalcLostSpaceAndOutput % - \fi % - \let\lst@lastother\relax} -%% end move \let\lst@lastother\relax to end of macros -% -%% correct bug of \lst@Aspect{texcs}{\def\lst@texcs{#1}} -\let\lstS@Aspect\lst@Aspect -\def\lst@Aspect#1{\def\@tempa{#1}\def\@tempb{texcs}% - \ifx\@tempa\@tempb % - \expandafter\lst@AspectTeX % - \fi % - \lstS@Aspect{#1}} -\def\lst@AspectTeX#1#2#3{% - \@ifundefined{KV@lst@#2}% - {\let\lst@ifnew\iftrue}{\let\lst@ifnew\iffalse}% - \lst@ifnew % - \else % - \expandafter\@gobblefour % - \fi % - \lstdefine@key{lst}{#2}{\edef\lst@texcs{##1}}} -%% end correct bug of \lst@Aspect{texcs}{\def\lst@texcs{#1}} +%% +%% This is file `lstpatch.sty', generated manually. +%% +%% Please read the software license in listings.dtx or listings.dvi. +%% +%% (w)(c) 2002 Carsten Heinz +%% +%% This file is distributed under the terms of the LaTeX Project Public +%% License from CTAN archives in directory macros/latex/base/lppl.txt. +%% Either version 1.0 or, at your option, any later version. +%% +%% Send comments and ideas on the package, error reports and additional +%% programming languages to . +%% +%% This patch file will remove the following bugs from the listings package. +%% Each item contains the bug finder with date of report and first bug fix +%% version, a short description of the problem, and the reason for the bug +%% in parenthesis. +%% +%% 1) Jochen Schneider, 2002/04/03, 1.0a (2002/04/05) +%% +%% undefined control sequence \lst@CommentB with HTML, XML, tcl +%% (I didn't renamed them to \lst@DefDelimB|E) +%% +%% 2) Michael Niedermair, 2002/04/07, 1.0b +%% +%% undefined control sequence \lst@commentmode with XML +%% (mode not defined any more) +%% +%% 3) Carsten Heinz, 2002/04/08, 1.0b +%% +%% bad PODs (investigating bugs 1 and 2) +%% (definition doesn't use 1.0 style) +%% +%% 4) Peter Bartke, 2002/04/10, 1.0b +%% +%% various problems with fancyvrb interface: string ".5" at beginning +%% of first line when using lineskip; ditto "perhaps a missing \item +%% error"; wrong placed characters , and - when using fancyvrb +%% (bad use of \strip@pt; TeX is not in vertical mode when leaving +%% Verbatim; bad `noligs' handling) +%% +%% 5) Rolf Niepraschk, 2002/04/12, 1.0b +%% +%% \RequirePackage is missing keywordstyle when near the top of a page +%% (\lst@lastother not saved away across page breaks) +%% +%% 6) Peter Ruckdeschel, 2002/04/12, 1.0b +%% Timothy Van Zandt analyzed and fixed the bug +%% +%% incompatibility with seminar class +%% (bad assignment of \lst@do@noligs in \lst@SelectCharTable) +%% +%% 7) Rene H. Larsen, 2002/04/12, 1.0b +%% +%% \lstinputlistings and texcl conflict +%% (^^M not active to reenter modes) +%% +%% 8) Carsten Heinz, 2002/04/15, 1.0b (2002/04/15) +%% +%% gobble doesn't always work (investigating problem with VTeX) +%% (\lst@BOLGobble@ must test against \lst@Process{FormFeed|Tabulator}X) +%% +%% 9) Peter Bartke, 2002/04/17, 1.0c +%% +%% TeX capacity exceeded with fancyvrb +%% (\let\lst@entermodes\@empty must stay in \lstFV@VerbatimBegin) +%% +%% 10) Svend Tollak Munkejord, 2002/04/17, 1.0c +%% Heiko Oberdiek analyzed and fixed the bug +%% +%% package incompatible with Lucida .fd files +%% (parentheses have active catcodes when reading the file) +%% +%% 11) Carsten Hamm, 2002/04/19, 1.0c (2002/04/24) +%% +%% wrong frame rules with breaklines and xleftmargin>0pt +%% (missing \kern-\lst@xleftmargin in \lst@discretionary) +%% +%% 12) Michael Niedermair, 2002/05/14, 1.0d +%% +%% backgroundcolor take effect on bottom captions +%% (wrong order of \everypar{} and \lsthk@ExitVars in \lst@DeInit) +%% +%% 13) Georg Rehm, 2002/05/14, 1.0d +%% +%% bad baselineskip with captionpos=b +%% (missing \normalbaselines) +%% +%% 14) Herfried Karl Wagner, 2002/05/11, 1.0d +%% +%% undefined control sequence \lst@entermodes +%% (\output called before first \lst@EnterMode) +%% +%% 15) Peter K\"oller, 2002/05/24, 1.0d +%% +%% XML keywords don't have keywordstyle +%% (missing \ifx... in implementation of contentsstyle) +%% +%% 16) Stephen Reindl, 2002/05/28, 1.0d +%% +%% \inaccessible using Cobol +%% (\lst@Delim@option didn't enclose option in []) +%% +%% 17) Stephen Reindl, 2002/06/04, 1.0d (2002/06/12) +%% +%% frames not deactivated for text style listings +%% +%% 18) Carsten Heinz, 2002/07/27, 1.0e (2002/07/31) +%% +%% broken keywordcomments +%% (\lst@KCpost inside group level 2; bad \lst@BeginComment call) +%% +%% 19) Kris Luyten, 2002/07/30, 1.0f (2002/08/03) +%% +%% Undefined control sequence \lst@thestyle +%% (undefined \lst@directives after _loading_ C) +%% +%% 20) Kris Luyten, 2002/08/03, 1.0g (2002/08/06) +%% +%% Undefined control sequence \lst@thestyle +%% (side effect of 19-bugfix on \lst@ProvideFamily) +%% +%% 21) Venkatesh Prasad Ranganath, 2002/08/31, 1.0h +%% +%% Undefined control sequence \thelstnumber with 0.21-option +%% (\let must be changed to a \def inition) +%% +%% 22) Fermin Reig, 2002/09/04, 1.0h (2002/09/09) +%% +%% Bad top frame inside figure+centering +%% (reset of leftskip, rightskip and parfillskip comes too late) +%% +%% 23) Hermann H\"uttler, 2002/10/05, 1.0i (2002/10/13) +%% +%% C++-string "... \\" does not end with second double quote +%% (missing \let\lst@lastother\@empty in old fix) +%% +%% +%% Moreover the following functionality is added. +%% +%% a) option "final" (Rolf Niepraschk, Enrico Straube) +%% +%% b) keys "fvcmdparams" and "morefvcmdparams" (Denis Girou) +%% +%% c) key "contentstyle" (Peter K\"oller) +%% +%% d) key "numberfirstline" (Georg Rehm) +%% +%% +\ProvidesFile{lstpatch.sty}[2002/10/13 1.0i (Carsten Heinz)] +\lst@CheckVersion{1.0} +{\typeout{^^J% + ***^^J% + *** This is a patch for `listings.sty' version 1.0, but^^J% + *** you're using version \lst@version.^^J% + ***^^J + *** Patch file not loaded.^^J% + ***^^J}% + \endinput +} +% +% 1) Define the missing control sequences. (Not needed any more.) +\def\lstpatch@comments{% + \global\let\lst@CommentB\lst@DefDelimB + \global\let\lst@CommentE\lst@DefDelimE} +% +% 2) Define \lst@commentmode. +\lst@NewMode\lst@commentmode +% +% 3) Introduce \lst@ifxpodcomment as master-clause and define 1.0 style +% contents for SelectCharTable. +\def\lstpatch@pod{% +\lst@Key{podcomment}{false}[t]{\lstKV@SetIf{##1}\lst@ifxpodcomment}% +\lst@AddToHookExe{SetLanguage}{\let\lst@ifxpodcomment\iffalse}% +\lst@AddToHook{SelectCharTable}% + {\lst@ifxpodcomment + \lst@CArgX =\relax\lst@DefDelimB{}{}% + {\ifnum\@tempcnta=\z@ + \lst@ifprintpod\else + \def\lst@bnext{\lst@BeginDropOutput\lst@PODmode}% + \expandafter\expandafter\expandafter\@gobblethree + \fi + \else + \expandafter\@gobblethree + \fi}% + \lst@BeginComment\lst@PODmode{{\lst@commentstyle}}% modified + \lst@CArgX =cut\^^M\relax\lst@DefDelimE + {\lst@CalcColumn}% + {\ifnum\@tempcnta=\z@\else + \expandafter\@gobblethree + \fi}% + {}% + \lst@EndComment\lst@PODmode + \fi}% +} +% +% 4) Redefine lineskip like podcomment above and don't use \strip@pt +% together with \divide. +\def\lstpatch@lineshape{% +\lst@Key{lineskip}{\z@}{\def\lst@xlineskip{##1\relax}} +\lst@AddToHook{Init} + {\ifdim\z@=\lst@xlineskip\else + \@tempdima\baselineskip + \advance\@tempdima\lst@xlineskip + \multiply\@tempdima\@cclvi + \divide\@tempdima\baselineskip\relax + \multiply\@tempdima\@cclvi + \edef\baselinestretch{\strip@pt\@tempdima}% + \selectfont + \fi}% +% 11) Add \kern-\lst@xleftmargin. +\gdef\lst@discretionary{% + \discretionary{\let\space\lst@spacekern\lst@prebreak}% + {\llap{\lsthk@EveryLine + \kern\lst@breakcurrindent\kern-\lst@xleftmargin}% + \let\space\lst@spacekern\lst@postbreak}{}}% +} +% Back to 4): Insert \par for vertical mode. +\def\lstpatch@fancyvrb{% +\gdef\lstFV@VerbatimEnd{% + \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine + \global\setbox\lstFV@gtempboxa\box\@tempboxa + \global\let\@gtempa\FV@ProcessLine + \lst@mode\lst@Pmode + \lst@DeInit + \let\FV@ProcessLine\@gtempa + \setbox\@tempboxa\box\lstFV@gtempboxa + \par % modified + \fi}% +% 9) Redefined \lstFV@VerbatimBegin removed. +% b) Refine conversion definitions to either work as usual or to ... +\gdef\lst@FVConvert{\@tempcnta\z@ \lst@FVConvertO@}% +\gdef\lst@FVConvertO@{% + \ifcase\@tempcnta \expandafter + \futurelet\expandafter\@let@token\expandafter\lst@FVConvert@@ + \else +% append arguments as they are. + \expandafter\lst@FVConvertO@a + \fi}% +\gdef\lst@FVConvertO@a##1{% + \lst@lAddTo\lst@arg{{##1}}\advance\@tempcnta\m@ne + \lst@FVConvertO@}% +% Here, ... +\gdef\lst@FVConvert@##1{% + \ifx \@nil##1\else + \if\relax\noexpand##1% + \lst@lAddTo\lst@arg{\lst@OutputLostSpace\lst@PrintToken##1}% +% ... actually here, we check for commands with arguments and set the +% value of \@tempcnta as required. + \def\lst@temp####1,##1####2,####3####4\relax{% + \ifx####3\@empty \else \@tempcnta####2\relax \fi}% + \expandafter\lst@temp\lst@FVcmdparams,##1\z@,\@empty\relax + \else + \lccode`\~=`##1\lowercase{\lst@lAddTo\lst@arg~}% + \fi + \expandafter\lst@FVConvertO@ + \fi} +% Eventually we define user keys to adjust \lst@FVcmdparams. The base +% set of commands and parameter numbers was provided by Denis Girou. +\lst@Key{fvcmdparams}% +% D.G. suggestion begin - 2002/05/31 + {\overlay\@ne}% +% D.G. suggestion end + {\def\lst@FVcmdparams{,##1}}% +\lst@Key{morefvcmdparams}\relax{\lst@lAddTo\lst@FVcmdparams{,##1}}% +} +% +% 5) Extend \lst@SaveToken to save \lst@lastother. +\def\lst@SaveToken{% + \global\let\lst@gthestyle\lst@thestyle + \global\let\lst@glastother\lst@lastother + \xdef\lst@RestoreToken{\noexpand\lst@token{\the\lst@token}% + \noexpand\lst@length\the\lst@length\relax + \noexpand\let\noexpand\lst@thestyle + \noexpand\lst@gthestyle + \noexpand\let\noexpand\lst@lastother + \noexpand\lst@glastother}% +} +% +% 6) Assign \lst@do@noligs to \do. +\def\lst@SelectCharTable{% + \lst@SelectStdCharTable + \lst@ifactivechars + \catcode9\active \catcode12\active \catcode13\active + \@tempcnta=32\relax + \@whilenum\@tempcnta<128\do + {\catcode\@tempcnta\active\advance\@tempcnta\@ne}% + \fi + \lst@ifec \lst@DefEC \fi + \let\do\lst@do@noligs \verbatim@nolig@list % modified + \lsthk@SelectCharTable + \lst@DeveloperSCT + \ifx\lst@Backslash\relax\else + \lst@LetSaveDef{"5C}\lsts@backslash\lst@Backslash + \fi} +% 4)+6) And we need correct versions of \lst@do@noligs[@]. +\def\lst@do@noligs#1{% + \begingroup \lccode`\~=`#1\lowercase{\endgroup + \lst@do@noligs@~}} +\def\lst@do@noligs@#1{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter\lst@NoLig#1}} +% +% 7) Make ^^M active. +\def\lst@InputListing#1{% + \begingroup + \lsthk@PreSet \gdef\lst@intname{#1}% + \expandafter\lstset\expandafter{\lst@set}% + \lsthk@DisplayStyle + \catcode\active=\active % added + \lst@Init\relax \let\lst@gobble\z@ + \lst@SkipToFirst + \lst@ifprint \def\lst@next{\input{#1}}% + \else \let\lst@next\@empty \fi + \lst@next + \lst@DeInit + \endgroup} +% +% 8) Replace \lst@Process{FormFeed|Tabulator}. +\def\lst@ProcessFormFeedX{\lst@ProcessFormFeed} +\def\lst@ProcessTabulatorX{\lst@ProcessTabulator} +\def\lst@BOLGobble@#1{% + \let\lst@next#1% + \ifx \lst@next\relax\else + \ifx \lst@next\lst@MProcessListing\else + \ifx \lst@next\lst@ProcessFormFeedX\else + \ifx \lst@next\lstenv@backslash + \let\lst@next\lstenv@BOLGobble@@ + \else + \let\lst@next\lst@BOLGobble@@ + \ifx #1\lst@ProcessTabulatorX + \advance\@tempcnta-\lst@tabsize\relax + \ifnum\@tempcnta<\z@ + \lst@length-\@tempcnta \lst@PreGotoTabStop + \fi + \else + \advance\@tempcnta\m@ne + \fi + \fi \fi \fi \fi + \lst@next} +% +% 10) Add some \@makeother to \lst@nfss@catcodes. +\def\lst@nfss@catcodes{% + \lst@makeletter + ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\relax + \@makeother (\@makeother )\@makeother ,\@makeother :\@makeother &% + \@makeother 0\@makeother 1\@makeother 2\@makeother 3\@makeother 4% + \@makeother 5\@makeother 6\@makeother 7\@makeother 8\@makeother 9% + \@makeother =\lsts@nfss@catcodes} +% +% 12) and 13) Deactivate \everypar and use normal baseline parameters. +\lst@AddToHook{DeInit}{\everypar{}\normalbaselines} +% +% 14) Define \lst@entermodes. +\let\lst@entermodes\@empty +% +% 16) Insert [ and ] in replacement text. +\def\lst@Delim@option[#1]{\def\lst@arg{[#1]}\lst@Delim@delim} +% +% 17) Just empty `frame' and top, right, bottom, and left shape. +\lst@AddToHook{TextStyle} + {\let\lst@frame\@empty + \let\lst@frametshape\@empty + \let\lst@framershape\@empty + \let\lst@framebshape\@empty + \let\lst@framelshape\@empty} +% +% 18) Execute \lst@BeginKC and \lst@BeginKCS outside the two groups. +% Modify third argument to \lst@BeginComment to work properly. +\def\lstpatch@keywordcomments{% +\gdef\lst@BeginKC{\aftergroup\aftergroup\aftergroup\lst@BeginKC@}% +\gdef\lst@BeginKC@{% + \lst@ResetToken + \lst@BeginComment\lst@KCmode{{\lst@commentstyle}\lst@modetrue}\@empty}% +\gdef\lst@BeginKCS{\aftergroup\aftergroup\aftergroup\lst@BeginKCS@}% +\gdef\lst@BeginKCS@{% + \lst@ResetToken + \lst@BeginComment\lst@KCSmode{{\lst@commentstyle}\lst@modetrue}\@empty}% +\gdef\lst@EndKC{\lst@SaveToken \lst@LeaveMode \lst@RestoreToken + \let\lst@thestyle\lst@identifierstyle \lsthk@Output}% renew style selection +} +% +% 19) Init \lst@directives. +\def\lstpatch@directives{% + \global\let\lst@directives\@empty} +% +% 20) Use new prefix for a family -- the now initialized \lst@directives +% clashes with the default. +\def\lstpatch@keywords{% +\gdef\lst@ProvideFamily##1{% + \@ifundefined{lstfam@##1\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}% + {\@namedef{lstfam@##1\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}{}% + \expandafter\expandafter\expandafter\lst@ProvideFamily@ + \csname\@lst @##1@data\endcsname + {\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}% + {}}% +} +% 21) Define \thelstnumber every listing via \def. +\@namedef{lstpatch@021}{% + \lst@AddToHook{Init}{\def\thelstnumber{\thelstlabel}}% +} +% 22) Reset the registers in PreInit hook +\lst@AddToHook{PreInit} + {\rightskip\z@ \leftskip\z@ \parfillskip\z@ plus 1fil} +% +% 23) Add \let\lst@lastother\@empty +\lst@AddToHook{SelectCharTable}{% + \lst@ifbstring + \lst@CArgX \\\\\relax \lst@CDefX{}% + {\lst@ProcessOther\lstum@backslash + \lst@ProcessOther\lstum@backslash + \let\lst@lastother\@empty}% + {}% + \fi} +% +% a) Just declare the option. +\DeclareOption{final}{\let\lst@ifdraft\iffalse} +% +% c) Define contentstyle and use it. +\def\lstpatch@html{% +\lst@Key{contentstyle}{}{\def\lst@contentstyle{##1}}% +\lst@AddToHook{Init}% + {\ifx\lst@DefInside\@empty\else + \let\lst@tagstyle\lst@identifierstyle + \let\lst@identifierstyle\lst@contentstyle + \fi}% +\lst@AddToHook{Output}% + {\ifnum\lst@mode=\lst@insidemode +% 15) Check for keywordstyle. + \ifx\lst@thestyle\lst@gkeywords@sty\else + \lst@ifusekeysinside \let\lst@thestyle\lst@tagstyle + \else \let\lst@thestyle\lst@gkeywords@sty \fi + \fi\fi}% +\lst@AddToHook{OutputOther}% + {\lst@ifmode\else \ifnum\lst@mode=\lst@insidemode\else + \ifx\lst@DefInside\@empty\else + \let\lst@thestyle\lst@contentstyle + \fi + \fi\fi}% +} +% +% d) Define key and adjust \lst@SkipOrPrintLabel. +\def\lstpatch@labels{% +\lst@Key{numberfirstline}{f}[t]{\lstKV@SetIf{##1}\lst@ifnumberfirstline}% +\gdef\lst@numberfirstlinefalse{\let\lst@ifnumberfirstline\iffalse} +\gdef\lst@SkipOrPrintLabel{% + \ifnum\lst@skipnumbers=\z@ + \global\advance\lst@skipnumbers-\lst@stepnumber\relax + \lst@PlaceNumber + \lst@numberfirstlinefalse + \else + \lst@ifnumberfirstline + \lst@PlaceNumber + \lst@numberfirstlinefalse + \fi + \fi + \global\advance\lst@skipnumbers\@ne}% +} +%% +\endinput +%% +%% End of file `lstpatch.sty'. \ No newline at end of file