% \iffalse meta-comment %<*internal> \iffalse % %<*readme> ABOUT The StatRep package is a LaTeX package that provides two environments and two tags that work together to display your SAS code and results and to generate the SAS program that produces those results. The two environments (Datastep and Sascode) display SAS code. The two tags (Listing and Graphic) display SAS output. The generated SAS program includes calls to macros that use the SAS Output Delivery System (ODS) document to capture the output as external files. These SAS macros are included in this package (statrep_macros.sas). The package is available in two locations: * http://support.sas.com/StatRepPackage * http://mirror.ctan.org/macros/latex/contrib/statrep/ The distribution(statrep.zip) consists of the following files: README.txt (this file) statrep_macros.sas SAS macro file statrep_tagset.sas SAS tagset and style for LaTeX tabular output statrepmanual.pdf StatRep Package User's Guide (pdf) statrepmanual.tex StatRep Package User's Guide (source) quickstart.tex Example and tutorial LaTeX file statrep.dtx Package source file statrep.ins Install file (for MikTeX Users) INSTALL Unzip the file statrep.zip to a temporary directory and perform the following steps: Step 1: Install the StatRep SAS Macros Copy the file statrep_macros.sas to a local directory. If you have a folder where you keep your personal set of macros, copy the file there. Otherwise, create a directory such as C:\mymacros and copy the file into that directory. Step 2: Install the StatRep LaTeX Package If you are working with the MikTeX distribution on Windows and it is configured to download and install packages automatically, you can skip this step. Otherwise, see these instructions for installing packages for MikTeX: http://docs.miktex.org/manual/localadditions.html The following instructions show how to install the StatRep package in the TeXLive LaTeX distribution for your personal use. If you maintain a system-wide LaTeX distribution and you want to make StatRep available to all users, see more detailed information about how to install LaTeX packages at http://www.tex.ac.uk/cgi-bin/texfaq2html?label=what-TDS a) Determine the location that LaTeX uses to load packages. From a command-line prompt, give the following command: kpsewhich -var-value=TEXMFHOME The command will return the root directory name in which LaTeX can find your personally installed packages. b) Create the directory if it does not exist and create the additional subdirectories tex/latex/statrep Your directory tree will have the following structure: --------------- root directory/ (given by kpsewhich command in 2a) tex/ latex/ statrep/ d) Copy the files statrep.dtx, statrepmanual.pdf, and statrepmanual.tex to the statrep subdirectory. Your directory tree will have the following structure: --------------- root directory/ (given by kpsewhich command in 2a) tex/ latex/ statrep/ statrep.dtx statrepmanual.pdf statrepmanual.tex --------------- e) Change to the statrep directory and give the following command: pdflatex statrep.dtx The command creates several files, one of which is the configuration file, statrep.cfg. Step 3: Let the StatRep Package Know the Location of the StatRep SAS Macros Edit the statrep.cfg file generated in Step 2d so that the macro SRmacropath contains the correct location of the macro file from step 1. For example, if you copied the statrep_macros.sas file to a directory named 'C:\mymacros', then you define macro \SRmacropath as follows: \def\SRmacropath{c:/mymacros/statrep_macros.sas} Note the use of the forward slash in the definition. Use the forward slash as the directory name delimiter instead of the backslash, which is a special character in LaTeX. EXPLORE You can now test and experiment with the package. Create a working directory and copy the file quickstart.tex into it. To generate the quickstart document: 1) Compile the document with pdfLaTeX. You can use a LaTeX-aware editor such as TeXworks or use the command-line command 'pdflatex'. This step generates the SAS program that is needed to produce the results. 2) Execute the SAS program quickstart_SR.sas, which was automatically created in the preceding step. This step generates the SAS results that are requested in the quickstart document. 3) Recompile the document with pdfLaTeX. This step compiles the quickstart document to PDF, this time including the SAS results that are generated in the preceding step. You might need to repeat this step so that LaTeX can re- measure the listing outputs to ensure that they are framed properly. Notes: You can make changes to the file with a LaTeX-aware editor or with any plain-text editor such as NotePad or emacs. You can read the StatRep User's Guide for complete usage details. It is included in the file statrepmanual.pdf that you copied in the installation step 2d. UNINSTALL To uninstall the package, delete the statrep directory that you created in the installation step 2d and remove the SAS macro file statrep_macros.sas that you copied in Installation step 1. NOTE StatRep now includes limited support for SAS ODS LaTeX output. See the StatRep User's Guide for details. LICENSE statrep.dtx statrep_macros.sas statrep_tagset.sas statrepmanual.tex Copyright (c) 2015 SAS Institute Inc. Permission is granted to copy, distribute, and/or modify this software under the terms of the LaTeX Project Public License (LPPL), version 1.3. This software is provided by SAS Institute Inc. as a service to its users. It is provided 'as is', without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantibility and fitness for a particular purpose. See http://www.latex-project.org/lppl.txt for the details of that license. This work has the LPPL maintenance status 'maintained'. The Current Maintainer of this work is Tim Arnold (tim dot arnold at sas dot com). REQUIREMENTS pdfLaTeX typesetting engine 1.30 or later LaTeX packages verbatim, graphicx, xkeyval, calc, ifthen SAS 9.2 or later See the StatRep User's Guide, included with this package, for complete details. This work consists of the files: README (this file) statrep_macros.sas statrep_tagset.sas statrepmanual.tex statrepmanual.pdf quickstart.tex statrep.dtx statrep.ins statrep.pdf statrep.sty statrep.cfg % %<*internal> \fi \def\nameofplainTeX{plain} \ifx\fmtname\nameofplainTeX\else \expandafter\begingroup \fi % %<*install> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble ---------------------------------------------------------------- StatRep --- A LaTeX package to generate documentation and a SAS program that generates the SAS results used in the source document. The package helps to support reproducible research. E-mail: tim.arnold@sas.com ---------------------------------------------------------------- \endpreamble \postamble Copyright (C) 2015 by SAS Institute Inc. This work consists of the files statrep.dtx, statrep_macros.sas, statrep_tagset.sas statrepmanual.tex, quickstart.tex and the derived files statrep.ins, statrep.cfg, statrep.sty, longfigure.sty, statrep.pdf, statrep_macros.sas, statrepmanual.pdf \endpostamble \generate{\file{statrep.sty}{\from{statrep.dtx}{statrep,cfg}}} \generate{\file{statrep.cfg}{\from{statrep.dtx}{cfg}}} \generate{\file{longfigure.sty}{\from{statrep.dtx}{longfigure}}} % %\endbatchfile %<*internal> \generate{\file{statrep.ins}{\from{statrep.dtx}{install}} } \nopreamble\nopostamble \generate{\file{README.}{\from{statrep.dtx}{readme}}} \ifx\fmtname\nameofplainTeX \expandafter\endbatchfile \else \expandafter\endgroup \fi % %<*statrep> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{statrep}[2015/09/15 v1.07 The statrep package] % %<*driver> \documentclass[11pt]{ltxdoc} \usepackage[T1]{fontenc} \usepackage{float} \restylefloat{figure} \usepackage{tocloft} \usepackage[lined,boxed,linesnumbered]{algorithm2e} \usepackage{parskip} \usepackage{xspace} \usepackage{framed} \usepackage{xcolor} \definecolor{shadecolor}{rgb}{0.8,0.9,1} \definecolor{lightblue}{rgb}{0.93,0.95,1.0} \definecolor{darkblue}{rgb}{0,0,0.6} \usepackage{mathptmx} \usepackage{upquote} \usepackage[numbered]{hypdoc} \usepackage{statrep} \newcommand*{\Statrep}{\textsf{StatRep}\xspace} \newcommand*{\Sasoption}{\marginpar{\hfill\emph{SAS option}}} \DeclareTextFontCommand{\Code}{\ttfamily\bfseries} \uchyph=0 \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{statrep.dtx} \end{document} % %\fi %\def\filename{statrep.dtx} %\def\fileversion{1.07} %\def\filedate{\today} %\CheckSum{2172} %\StopEventually{\PrintChanges\PrintIndex} % % \CharacterTable % {Upper-case \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 % Lower-case \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 % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % % %\changes{v1.0}{2011/11/15}{Initial version} %\changes{v1.01}{2012/05/23}{Updated README for MikTeX users} %\changes{v1.02}{2014/06/16}{Added options for graphtype and odsgraphopts} %\changes{v1.03}{2014/06/19}{Added support for PDF graphics} %\changes{v1.04}{2014/09/08}{Fixed ligatures appearing in Listings} %\changes{v1.05}{2014/10/27}{Added support SAS-generated LaTeX table output} %\changes{v1.06}{2015/01/15}{Added support for root directory specification} %\changes{v1.07}{2015/09/15}{Fixed bug with losing margins after an output} %\GetFileInfo{statrep.sty} % % %\DoNotIndex{\.,\@auxout,\@height,\^,\addcontentsline,\addvspace,\arabic,\bfseries} %\DoNotIndex{\boolean,\DeclareOptionX,\do,\dospecials,\hskip,\hoffset,\insert,\label} %\DoNotIndex{\LaTeX,\leftskip,\loop,\ProcessOptionsX,\real,\repeat,\stepcounter} %\DoNotIndex{\@@Function,\@@endpbox,\@@startpbox,\@Function,\@M,\@Mi,\@acol} %\DoNotIndex{\%,\@@endpbox,\@@startpbox,\@M,\@Mi,\@acol,\@arraycr} %\DoNotIndex{\@arrayparboxrestore,\@arstrut,\@arstrutbox,\@cclv,\@classiv} %\DoNotIndex{\@classz,\@colht,\@colroom,\@depth,\@ehc,\@endpbox,\@finalstrut} %\DoNotIndex{\@firstofone,\@footnotetext,\@getpen,\@gobble,\@gtempa,\@ifnextchar} %\DoNotIndex{\@ifstar,\@ifundefined,\@let@token,\@lowpenalty,\@makecol,\@makeother,\@medpenalty} %\DoNotIndex{\@mkpream,\@mparbottom,\@ne,\@outputpage,\@preamble,\@sharp,\@spaces} %\DoNotIndex{\@startpbox,\@tabacol,\@tabarray,\@tabclassiv,\@tabclassz,\@tabularcr} %\DoNotIndex{\@testopt,@twocolumntrue,\@undefined,\@width,\@xargarraycr,\@xdblarg} %\DoNotIndex{\@yargarraycr,\\,\^,\2,\9,\advance,\aftergroup,\arabic\arrayrulewidth} %\DoNotIndex{\arraystretch,\begin,\begingroup,\bgroup,\bigskipamount,\bgroup} %\DoNotIndex{\bigskipamount,\box,\break,\c@footnote,\c@LF@chunks,\c@LFchunksize,\c@page} %\DoNotIndex{\cloeout,\col@number,\col@sep,\copy,\count@,\cr,\crcr,\csname,\def} %\DoNotIndex{\define@boolkeys,\define@cmdkeys,\dimen@,\dimen@ii,\doublerulesep} %\DoNotIndex{\dp,\edef,\egroup,\else,\end,\endcsname,\endgraf,\endgroup,\endinput} %\DoNotIndex{\endLFfirsthead,\endLFfoot,\endLFhead,\endLFlastfoot,,\equal,\everycr} %\DoNotIndex{\expandafter,\extrarowheight,\fi,\fill,\footins,\footnotetext,\futurelet} %\DoNotIndex{\gdef,\global,\halign,\hbadness,\hbox,\hfil,\hfill,\hline,\hrule} %\DoNotIndex{\hsize,\ht,\if,\if@filesw,\if@twocolumn,\ifcase,\ifdim,\ifhbox,\ifhmode,\iffalse,\ifnum} %\DoNotIndex{\ifthenelse,\ifvoid,\ifx,\immediate,\isert,\itemsep,\itshape,\kern,\kill} %\DoNotIndex{\lastbox,\leaders,\let,\LF@@hl,\LF@@hline,\LF@@save@row,\LF@@tabarray} %\DoNotIndex{\LF@array,\LF@argtabularcr,\LF@bchunk,\LF@blank@row,\LF@build@blank,\LF@cols,\LF@crcr} %\DoNotIndex{\LF@def@row,\LF@echunk,\LF@end@hd@ft,\LF@end@pen,\LF@endpbox,\LF@entry} %\DoNotIndex{\LF@entry@chop,\LF@entry@write,\LF@err,\LF@final@warn,\LF@get@widths} %\DoNotIndex{\LF@kill,\LF@lastfoot,\LF@LL@FM@cr,\LF@max@sel,\LF@mcol,\LF@n@fcols} %\DoNotIndex{\LF@no@pgbk,\LF@nofcols,\LF@ntabularcr,\LF@old@row,\LF@output,\LF@p@ftn} %\DoNotIndex{\LF@p@ftntext,\LF@rebox,\LF@rows,\LF@save@row,\LF@sep,\LF@setprevdepth} %\DoNotIndex{\LF@startpbox,\LF@t@bularcr,\LF@tabularcr,\LF@warn,\LF@xtabularcr} %\DoNotIndex{\LFchunksize,\LFlistoffalse,\LFlistoftrue,\LFoutfile,\LFpost,\LFpre} %\DoNotIndex{\LFright,\LF@samefalse,\LF@sametrue,\LFupcase,\lineskip,\m@ne,\m@th} %\DoNotIndex{\MakeUppercase,\mathchardef,\maxdepth,\maxdimen,\MessageBreak,\multicols} %\DoNotIndex{\multicolumn,\multispan,\newbox,\newcommand,\newcount,\newcounter,\newdimen} %\DoNotIndex{\newenvironment,\newif,\newlength,\newpage,\newsavebox,\newskip,\newtoks} %\DoNotIndex{\newwrite,\noalign,\nobreak,\noexpand,\noindent,\nopagebreak,\number} %\DoNotIndex{\numberline,\omit,\or,\output,\outputpenalty,\pagebreak,\pagegoal,\pagetotal} %\DoNotIndex{\par,\parbox,\parsep,\parskip,\partopsep,\penalty,\prevdepth,\protect} %\DoNotIndex{\ProvidesPackage,\relax,\renewcommand,\romannumeral,\saswfk,\sbox,\savebox} %\DoNotIndex{\selectfont,\setboolean,\setbox,\setcounter,\setlength,\setlongfigures,\settowidth} %\DoNotIndex{\sffamily,\space,\strutbox,\tabcolsep,\tabskip,\tabularnewline,\the} %\DoNotIndex{\thetable,\topsep,\ttfamily,\tw@,\unhbox,\unskip,\unvbox,\vbox,\vfil} %\DoNotIndex{\vrule,\vsize,\vskip,\vspace,\vsplit,\vfuzz,\vss,\vtop,\wd,\write,\x,\xdef} %\DoNotIndex{\z@} %\DoNotIndex{\@empty,\@tempa,\@tempboxa,\@tempdima,\@twocolumntrue,\baselineskip} %\DoNotIndex{\c@LF@tables,\detokenize,\hss,\LF@c@ption,\LF@capti@n,\LF@firsthead} %\DoNotIndex{\LF@foot,\LF@head,\LF@hline\LF@make@row,\LF@name,\LF@start,\LFcounter} %\DoNotIndex{\LFProcessOptions,\RequirePackage,\string,\SR@outkey,\SR@outval,\usebox} % %\title{The \textsf{statrep} package\thanks{This document corresponds %to \textsf{statrep}~\fileversion, last revised \filedate.}} %\author{Tim Arnold and Warren F. Kuhfeld\\SAS Institute Inc.\\\texttt{tim.arnold@sas.com}\\\texttt{warren.kuhfeld@sas.com}} %\date{\filedate} %\maketitle %\iffalse %<*statrep> %\fi % \tableofcontents\listoffigures % \section{About This Document} % This document uses the following aids for presenting information. % \begin{itemize} % \item The verbatim font (\Code{example text}) is used for names of variables, % macros, and environments. % % \item Hyperlinks are displayed in \textcolor{red}{red}. % \item Figures are displayed with a light blue background. %\item Macro names are given in the margin near where the macro is defined or described. % \item The index contains terms with pointers to the code lines. % \end{itemize} % \section{\Statrep Usage} % \index{statrep package|usage} % To use the \Statrep package, add the \cs{usepackage} command to your document preamble after you % declare the \Code{documentclass}. % % Figure \ref{fig:usage} shows an example of using the \Statrep package and % specifying two of its three options. % \iffalse %<*example> % \fi %\begin{figure}[H] %\begin{snugshade} \begin{verbatim} \documentclass{book} \usepackage[figname=output,resetby=chapter]{statrep} \end{verbatim} %\end{snugshade} %\caption{Example of Using the \Statrep Package}\label{fig:usage} %\end{figure} % \iffalse % % \fi % % The \Statrep package supports the following options: % \begin{itemize} % \item \Code{generate} specifies whether a SAS program % is generated at compile time. \index{generate option} % It can have a value of \Code{true} or \Code{false}; the default is \Code{true}. % % \item \Code{figname=} specifies the name of a \LaTeX\ counter % that is used for numbering outputs\index{figname option}. % The default is \Code{figure}. If you specify a value for the \Code{figname} % option for which no counter exists, % a counter is created. % % \item \Code{resetby=} specifies that the counter for output numbering be reset with % each change in the specified counter value. For example, if \Code{resetby=chapter}, % all output numbering is reset when the chapter value changes. See section % \ref{longfigure} for details. Also, refer to the \Code{tocloft} package documentation % for information about how the lists are typeset.\index{list of outputs, creating}% % \end{itemize} % % The options \Code{figname=} and \Code{resetby=} are not used directly by the \Statrep % package but are passed to the \Code{longfigure} package. % % The |longfigure| package is provided with the \Statrep package. It % supports display and page breaking within a stream of outputs, and it can be % used independently of the \Statrep package. It supports the options |figname=| % and |resetby=|. For complete details about the implementation of the |longfigure| package, % see section \ref{longfigure}. % % % In Figure \ref{fig:usage}, the specified options label the included output as % appropriately numbered \Code{Output}s and enable a \textit{List of Outputs} to be generated. % To generate a \textit{List of Outputs}, add the \cs{listofoutput} % command at the point in your document where you want % the \textit{List of Outputs} to appear. % If you specify \Code{figname=display}, add the \cs{listofdisplay} command % where you want the \textit{List of Displays} to appear. % % If you load the \Statrep package with no options, % the outputs are labeled as figures and you can display the \textit{List of Figures} % with the command \cs{listoffigures}. % % % For more information about how to use the \Statrep package, see the \Statrep User's Guide % (\texttt{statrepmanual.pdf}) that accompanies the \Statrep distribution. % % \section{\Statrep Implementation} % % \subsection{Required Packages} % The \Statrep package requires the following \LaTeX\ packages. Each package is available % in a relatively recent \TeX{}Live distribution (2005 or later). % % \begin{macrocode} \RequirePackage{verbatim} \RequirePackage{graphicx} \RequirePackage{xkeyval} \RequirePackage{calc} \RequirePackage{ifthen} % \end{macrocode} % \begin{itemize} % \item The |verbatim| package provides the foundation for the \Statrep package. % \item The |graphicx| package enables inclusion of images and is used by the \cs{Graphic} tag. % \item The |xkeyval|, |calc|, and |ifthen| packages provide programming capabilities that are % used throughout the \Statrep package. % \end{itemize} % % \begin{macrocode} \newif\ifSR@generate\SR@generatetrue \DeclareOptionX{generate}[true]{\@nameuse{SR@generate#1}} \DeclareOptionX{color}[true]{% \IfFileExists{sas.sty} {\PassOptionsToPackage{\CurrentOption}{sas}} {\relax} } \DeclareOptionX{figname}{\PassOptionsToPackage{\CurrentOption}{longfigure}} \DeclareOptionX{resetby}{\PassOptionsToPackage{\CurrentOption}{longfigure}} \ProcessOptionsX \IfFileExists{sas.sty} {\RequirePackage{sas}} {\relax} \RequirePackage{longfigure} % \end{macrocode} % % Declare an option for \texttt{color}; Pass the value to the \texttt{sas} % package if it exists, otherwise do nothing. This option has no effect if % the ODS Listing destination is used. It applies only to SAS-generated % LaTeX tabular output. % % The file \texttt{sas.sty} is loaded if it exists. The file is created by a SAS ODS % tagset that is experimental; the tagset generates SAS output as LaTeX tables. More % information on this experimental support can be found in the User's Guide (appendix). % % % \subsection{Programming Utilities}\label{utilities} % The programming helpers described in this section are used % throughout the package: % % \begin{macrocode} \ifSR@generate\def\SR@writepgm{\immediate\write} \else\let\SR@writepgm\@gobbletwo \fi % \end{macrocode} % \DescribeMacro{\SR@generate} % \cs{SR@generate} is a Boolean switch that is created and defined to have a % default value of |true|. The switch is used to provide alternative definitions of % a utility macro \cs{SR@writepgm}. % \DescribeMacro{\SR@writepgm} % If the switch remains true, \cs{SR@writepgm} is defined as % \cs{immediate}\cs{write}; % otherwise, it is defined to remove its two arguments (\cs{@gobbletwo}). % % The effect of these alternative definitions is as follows. % When you do not override the default (by default, |generate| is true), % the macro writes to a file stream that represents the generated program file. % Otherwise, the macro is defined to remove its two arguments (therefore, it is effectively % a null operation). % % The following two commands set the tolerance for bad boxes, orphans, and widows: % \begin{macrocode} \newcommand*{\dosloppy}{\setlength{\hfuzz}{\maxdimen}\hbadness\maxdimen} \newcommand*{\unsloppy}{\setlength{\hfuzz}{0.3pt}\hbadness 1414} % \end{macrocode} % % \DescribeMacro{\dosloppy} % \DescribeMacro{\unsloppy} % The |dosloppy| macro is intended to be used when you knowingly violate % typesetting rules, such as when you must write extremely % wide outputs. For such situations, set the tolerance % high with |dosloppy| and set it back to normal with |unsloppy|. These settings % do not change \LaTeX's line-breaking algorithms or line penalties; they suppress % the overfull box (\cs{hfuzz}) and underfull box (\cs{hbadness}) warnings in the log. % The system uses theses commands when it insert outputs. % See the % \cs{SR@set@outmargin} macro in section \ref{insert} for % details. % % The following definitions are used to calculate and set the output % stream of listings or figures. See section \ref{insert} for details. % \begin{macrocode} \newlength{\SR@scratchlength} \newlength{\SR@verbwidth} \newsavebox{\SR@filebox} \newcommand*{\SR@firsthead}{} \newcommand*{\SR@conthead}{} \newcommand*{\SR@endfoot}{} % \end{macrocode} % The following variables aid in constructing the two verbatim environments % provided in the \Statrep package: % \begin{macrocode} \newcounter{SR@currentline}\setcounter{SR@currentline}{0} \newcounter{SR@displayline}\setcounter{SR@displayline}{0} \newcounter{SR@programline}\setcounter{SR@programline}{0} \newcounter{SR@startinglastline}\setcounter{SR@startinglastline}{0} \newcounter{SR@totallines}\setcounter{SR@totallines}{0} \newcounter{SR@multifilecount}\setcounter{SR@multifilecount}{0} \newboolean{SR@multifile}\setboolean{SR@multifile}{false} % \end{macrocode} % \begin{itemize} % \item |SR@currentline| contains the current line number of the % |verbatim| environment that is being processed. % % \item |SR@displayline| contains the number of lines to display. % The number can be specified as a line command inside a |Sascode| environment. % % \item |SR@programline| contains the number of lines to write to the % generated program. % The number can be specified as a line command inside a |Sascode| environment. % % \item |SR@startinglastline| contains the line number that begins the bottom block % of an abbreviated displayed |Datastep| environment. This counter is used % when the |last=| option is specified in the |Datastep| environment. % % \item |SR@totallines| contains the total number of lines in the % |verbatim| environment. % % \item |SR@multifilecount| counter is used to step through and insert % a set of output files that are generated by SAS. % % % \item |SR@multifile| is a Boolean switch that is used in the algorithm that % inserts the stream of outputs. See section \ref{insert} for complete details. % \end{itemize} % % \begin{macrocode} \begingroup\catcode`\#=12\gdef\SR@hashchar{#}\endgroup % \end{macrocode} % \DescribeMacro{\SR@hashchar} % The \cs{SR@hashchar} macro is used in writing options that are specified in the % \cs{Listing} and \cs{Graphic} macros. Options that specify SAS ODS % object names % can contain a hash character. In the \LaTeX\ source, the normal % hash character (|#|) must be escaped (|\#|). When the string is written % to the generated program, the escaping backslash must be removed. % The definition resets the category code inside a group so that % the change will not affect other definitions. Then the \cs{SR@hashchar} % macro is globally defined as an unescaped hash character. % % The \cs{SR@hashchar} macro is used in the \cs{SR@write@outoptions} macro. % See section \ref{output} for details. % % \DescribeMacro{SR@ keys} % The following |SR@| family of keys is used in the |Datastep| and |Sascode| environments % and the \cs{Listing} and \cs{Graphic} macros. % \begin{macrocode} \define@boolkeys{SR}[SR@]{display,program,continued}[true]{} \define@cmdkeys{SR}[SR@]{caption,first,last}{} \define@cmdkeys{SR}[SR@]{fontsize,scale,label}{} % \end{macrocode} % The keys are used for two purposes: One set of keys is used by the \Statrep % package to typeset the environments or outputs that are defined in the package. % Another set of keys is used to communicate with SAS; the keys are passed through % directly to the generated program. There is some overlap between the two % set of keys. For example, the |width| key is used by the \Statrep package % to typeset the output that is specified in a \cs{Graphic} tag and is used by SAS % to generate the image. % % The following keys are used only by the \Statrep package: % \index{display option|usage}\index{program option|usage}\index{first option|usage} % \index{caption option|usage}\index{continued option|usage}\index{last option|usage} % \index{fontsize option|usage}\index{scale option|usage} % \begin{itemize} % \item |display| is a Boolean key that specifies that a |Sascode| or |Datastep| block % should only be displayed. % \item |program| is a Boolean key that specifies that a |Sascode| or |Datastep| block % should only be written to the program file. % % \item |continued| is a Boolean key that specifies whether the output is a % continuation of a preceding output block. % % \item |caption=| specifies the caption to use for a |Listing| or |Graphic| output. % % \item |first=| specifies the number of top lines to display in a |Datastep| environment. % \item |last=| specifies the number of bottom lines to display in a |Datastep| environment. % \item |fontsize=| specifies the \LaTeX\ font size to use in displaying output % or code environment (for example, |small| or |footnotesize|). % \item |scale=| specifies a factor by which to scale a |Graphic| image. % For example, specify |scale=0.5| to scale the image to half its original size, % or specify |scale=2| to scale it to double its original size. % \item |label=| is used internally by the \Statrep package to generate a label % for \cs{Graphic} and \cs{Listing} elements. % \end{itemize} % % The following keys are used both by the \Statrep package and by SAS: % \index{store option|usage}\index{linesize option|usage}\index{width option|usage} % \begin{itemize} % \item |store=| specifies the name of the ODS document store to be created in a % |Sascode| environment. When this key is specified, the \Statrep package % writes the appropriate SAS program lines to the generated program. When this % key is not specified, the \Statrep package assumes that the author has written % the SAS macro calls into the |Sascode| blocks. % % \item |linesize=| specifies the line size that is used to generate and % typeset |Listing| output. Typical values are |80|, |96|, or |120|. % % \item |width=| specifies the width to generate or display |Graphic| output. % % \item |dest=| specifies the SAS ODS destination to use for tabular output. % The possible values are |listing| and |latex|. The |listing| option includes verbatim % text-based tables from the ODS LISTING destination. The |latex| option includes % LaTeX tabular environments that use the |sas| package (generated during the SAS run). % \end{itemize} % \begin{macrocode} \define@cmdkeys{SR}[SR@]{store,linesize,width,dest}{} % \end{macrocode} % The remaining keys are defined and accepted by the \cs{Listing} and \cs{Graphic} % macros, but are passed on to the generated SAS program. The following keys are % used only by SAS: % \begin{macrocode} \define@cmdkeys{SR}[SR@]{type,style,dpi}{} \define@cmdkeys{SR}[SR@]{firstobj,lastobj}{} \define@cmdkeys{SR}[SR@]{objects,pattern,options}{} \define@cmdkeys{SR}[SR@]{height,pagesize}{} % \end{macrocode} % % \index{type option|usage}\index{height option|usage} % \index{objects option|usage}\index{pattern option|usage}\index{style option|usage} % \index{dpi option|usage}\index{pagesize option|usage}\index{firstobj option|usage} % \index{lastobj option|usage} % \begin{itemize} % \item |style=| specifies the ODS style to use in generating output. % \item |dpi=| specifies how many dots per inch (DPI) to use in generating a graph. % % \item |firstobj=| specifies the first object's name to capture in an output stream. % \item |lastobj=| specifies the last object's name to capture in an output stream. % \item |objects=| specifies a space-separated list of object names to capture. % \item |pattern=| specifies a name-matching pattern to select objects to capture. % % \item |options=| specifies other options for generating output. % \item |height=| specifies the height of a generated graph (for example, |height=5.4in|). % \item |pagesize=| specifies page size for output. % \item |type=| specifies the type of output stream to initiate (|graphic| or |listing|). % If the automatic program generation capability is in effect % (that is, the |store=| option is specified), % the \cs{Listing} and \cs{Graphic} tags automatically generate the appropriate % value for this key. % % \end{itemize} % % \DescribeMacro{\presetkeys} % When any environment or command uses the keys, it first calls the following % |presetkeys| macro, which provides default values for each key: % \begin{macrocode} \presetkeys{SR}{% display = false, program = false, continued = false, caption = \@empty, first = 0, last = 0, fontsize = \@empty, scale = \@empty, label = \@empty, store = \@empty, linesize = \@empty, width = \@empty, type = \@empty, style = \@empty, dpi = \@empty, dest = \@empty, firstobj = \@empty, lastobj = \@empty, objects = \@empty, pattern = \@empty, options = \@empty, height = \@empty, pagesize = \@empty}{} % \end{macrocode} % \subsection{Customizable Settings} %\iffalse % %<*cfg> %\fi % \index{customizing|usage} % The definitions in this section can be overridden by settings in the external file % |statrep.cfg|.\index{statrep.cfg|usage} % % \DescribeMacro{\SRmacropath} % \cs{SRmacropath} specifies the path to the location of the % SAS macros that are bundled with the \Statrep package. You can define % the path by using forward slashes (/) instead of backslashes (\textbackslash) % as the directory % name delimiter. If you do use backslashes, you % must insert a backslash character into this argument by using the % \cs{@backslashchar} command. % The default value is the current % directory. That is, the definition for the path to the macro file % is the filename itself, |statrep_macros.sas|. % \begin{macrocode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Edit this line to point to the location of the StatRep macros. \def\SRmacropath{statrep_macros.sas} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \end{macrocode} %% The following statements define line size, page size, graphic resolution, %% and also specify the default ODS output style: % \DescribeMacro{\SRlinesize}\DescribeMacro{\SRpagesize} % \DescribeMacro{\SRdpi}\DescribeMacro{\SRstyle}\DescribeMacro{\SRodsgraphopts} % \DescribeMacro{\SRlatexstyle} %\changes{v1.06}{2015/01/15}{Added rootdir for SAS/Studio support.} % \begin{macrocode} \def\SRrootdir{.} \def\SRlinesize{80} \def\SRpagesize{500} \def\SRdpi{300} \def\SRstyle{statistical} \def\SRlatexstyle{statrep} \def\SRodsgraphopts{} % \end{macrocode} % The following statements define system options used in the generated SAS program% % \begin{itemize} % \item \cs{SRlinesize} specifies the default linesize to use for listing output. % \item \cs{SRpagesize} specifies the default pagesize to use for listing output. % \item \cs{SRdpi} specifies the default DPI setting to use for GRSEG and ODS graphics. % \item \cs{SRstyle} specifies the default ODS output style to use for ODS graphics. % \item \cs{SRlatexstyle} specifies the ODS output style to use for LaTeX tabular output. % The default is |statrep|, which is provided in the supplmental file % |statrep_tagset.sas|. % \end{itemize} % \begin{macrocode} \def\SRgraphicdir{\SRrootdir/png} \def\SRgraphtype{png} \def\SRlistingdir{\SRrootdir/lst} \def\SRlatexdir{\SRrootdir/tex} \def\SRdefaultdests{listing} % \end{macrocode} % \DescribeMacro{\SRgraphicdir}\DescribeMacro{\SRgraphtype}\DescribeMacro{\SRlistingdir} % \DescribeMacro{\SRdefaultdests}\DescribeMacro{\SRlatexdir} % \begin{itemize} % \item \cs{SRgraphicdir} specifies the name of the directory that contains the % graphic output files that are generated by SAS. The default is |png|. % \item \cs{SRgraphtype} specifies the type of graphics file that SAS will generate. % The choices are |png| and |pdf|. The default is |png|. % \item \cs{SRlistingdir} specifies the name of the directory that contains the % listing (tabular) output files that are generated by SAS. The default is |lst|. % \item \cs{SRlatexdir} specifies the name of the directory that contains the % LaTeX (tabular) output files that are generated by SAS. The default is |tex|. % \item \cs{SRdefaultdests} specifies the ODS destination to use for tabular output. % The possible values are |listing| and |latex|. The default is |listing|. % \end{itemize} %\changes{v1.01}{2012/05/23}{Changed SRsasprogramline to call hostdel SAS macro} %\changes{v1.06}{2015/01/15}{Changed hostdel macro to cleandir for SAS/Studio support.} % \begin{macrocode} \def\SRprogramname{\jobname_SR.sas} \def\SRpreamblename{\jobname_SR_preamble.sas} \def\SRmacroinclude{\@percentchar include "\SRmacropath" /nosource;} \def\SRsasprogramline{% \@percentchar cleandir(\SRrootdir, tex, tex);^^J% \@percentchar cleandir(\SRrootdir, png, png);^^J% \@percentchar cleandir(\SRrootdir, lst, lst);^^J% }% % \end{macrocode} % \DescribeMacro{\SRprogramname} % \DescribeMacro{\SRmacroinclude}\DescribeMacro{\SRprogramline} % \begin{itemize} % \item \cs{SRprogramname} specifies the filename for the generated SAS % program. The default is \cs{jobname\_SR.sas}, where \cs{jobname} is usually % the stem name of the \LaTeX\ source file. % \item \cs{SRmacroinclude} specifies the line used in the generated SAS program to % include the SAS macros that are bundled with the \Statrep package. % The default is |%include|~\cs{SRmacropath}~/|nosource;|. % \item \cs{SRprogramline} specifies the first lines to include in % the generated SAS program % after the \cs{SRmacroinclude} line. The following default value calls a SAS % macro that removes the contents of the listing, tex, and graphic directories. % The directories are created with % each SAS run that includes the macros themselves (via x commands). % \end{itemize} % % \begin{macrocode} \def\SRparindent{3em} \def\SRintertext{... more data lines ...} \def\SRtempfilename{sr.tmp} \def\SRcontinuedname{continued} \def\SRcaptionfont{\sffamily} \def\SRcaptioncontinuedfont{\sffamily\itshape} \def\SRverbfont{\ttfamily\bfseries} % \end{macrocode} % \DescribeMacro{\SRparindent} % \DescribeMacro{\SRintertext}\DescribeMacro{\tempfilename} % \begin{itemize} % \item \cs{SRparindent} specifies the amount of space to indent % |Datastep| and |Sascode| environments. % The argument is a dimension. % The default is |3em| and is measured according to the font % currently in use. % \item \cs{SRintertext} specifies the text to insert in abbreviated % |Datastep| environments (that is, |Datastep| environments that specify % the |first=| option). % \item \cs{SRtempfilename} specifies the name of a temporary file that is % used as a scratch file in the current working directory. % The default is |sr.tmp|. % % \DescribeMacro{\SRcontinuedname}\DescribeMacro{\SRcaptionfont} % \DescribeMacro{\SRcaptioncontinuedfont}\DescribeMacro{\SRverbfont} % \item \cs{SRcontinuedname} specifies the name that indicates that an output % block is continued. This helper is used when an output stream breaks across a page. % The default is |continued|. % \item \cs{SRcaptionfont} specifies the font to use for the output captions. % The default is \cs{sffamily} (\textsf{sans serif}). % % \item \cs{SRcaptioncontinuedfont} specifies the font to use for the |continued| name % for outputs that break across pages. % The default is \cs{sffamily}\cs{itshape} (\textsf{\textit{sans serif, italic}}). % % \item \cs{SRverbfont} specifies the font to use for code within |Datastep| and % |Sascode| blocks. The default is \cs{ttfamily}\cs{bfseries} % ({\bfseries\texttt{typewriter text, bold}}). % % \end{itemize} % %\iffalse % %<*statrep> %\fi % If the file |statrep.cfg| exists, the following statements load it so that you can override % the preceding definitions: % \begin{macrocode} \InputIfFileExists{statrep.cfg} {\PackageInfo{statrep}{Reading custom configuration file statrep.cfg}} {\PackageInfo{statrep}{No custom configuration file found (statrep.cfg).% Using defaults.}} % \end{macrocode} % Two output streams are created: % \begin{macrocode} \newwrite\SR@program@stream \newwrite\SR@tempfile@stream % \end{macrocode} % The stream \cs{SR@program@stream} represents the % generated SAS program. The stream \cs{SR@tempfile@stream} represents a % temporary stream and is used to write the SAS program preamble and % to construct each |Datastep| environment. % % The following lines define boilerplate text that is included in the % preamble SAS file and the capture-program SAS file: % \begin{macrocode} \def\SR@preambletext{/*^^J This file is auto-generated by the statrep package.^^J Do not edit this file or your changes will be lost.^^J Edit the LaTeX file instead.^^J ^^J See the statrep package documentation and the file^^J statrep.cfg for information on these settings.^^J */^^J ^^J } % \end{macrocode} % The following statements open the temporary stream by using the filename % |\SR@preamblename| and write the default settings into the preamble file. % The temporary file is then closed. % \begin{macrocode} \def\SR@write@preamble{ \immediate\openout\SR@tempfile@stream\SRpreamblename% \SR@writepgm\SR@tempfile@stream{\SR@preambletext} \SR@writepgm\SR@tempfile@stream{/* Set and invoke macro variable defaults. */} \SR@writepgm\SR@tempfile@stream{\@percentchar let rootdir=\SRrootdir;} \SR@writepgm\SR@tempfile@stream{\@percentchar let defaultstyle=\SRstyle;} \SR@writepgm\SR@tempfile@stream{\@percentchar let latexstyle=\SRlatexstyle;} \SR@writepgm\SR@tempfile@stream{\@percentchar let graphtype=\SRgraphtype;} \SR@writepgm\SR@tempfile@stream{\@percentchar let graphicdir=\SRgraphicdir;} \SR@writepgm\SR@tempfile@stream{\@percentchar let listingdir=\SRlistingdir;} \SR@writepgm\SR@tempfile@stream{\@percentchar let latexdir=\SRlatexdir;} \SR@writepgm\SR@tempfile@stream{\@percentchar let defaultlinesize=\SRlinesize;} \SR@writepgm\SR@tempfile@stream{\@percentchar let defaultpagesize=\SRpagesize;} \SR@writepgm\SR@tempfile@stream{\@percentchar let defaultdpi=\SRdpi;} \SR@writepgm\SR@tempfile@stream{\@percentchar let odsgraphopts=\SRodsgraphopts;} \SR@writepgm\SR@tempfile@stream{\@percentchar let defaultdests=\SRdefaultdests;} \SR@writepgm\SR@tempfile@stream{} \SR@writepgm\SR@tempfile@stream{options nodate nonumber} \SR@writepgm\SR@tempfile@stream{ls=&defaultlinesize ps=&defaultpagesize} \SR@writepgm\SR@tempfile@stream{formchar='|----|+|---+=|-/\@backslashchar<>*';} \SR@writepgm\SR@tempfile@stream{} \SR@writepgm\SR@tempfile@stream{ods graphics on;} \SR@writepgm\SR@tempfile@stream{/* Include SAS macro definitions. */} \SR@writepgm\SR@tempfile@stream{\SRmacroinclude} \SR@writepgm\SR@tempfile@stream{} \immediate\closeout\SR@tempfile@stream % \end{macrocode} % The following statements begin writing the generated SAS program |\SRprogramname|. % They open the |\SR@program@stream|, write lines to include the preamble file, % and do the preliminary work necessary before each run of the capture program. % % The preamble is written to a separate file and not directly into the capture % program so that users who copy and paste code from the \LaTeX\ source to a SAS % session can include only the preamble in their SAS session. % \begin{macrocode} \immediate\openout\SR@program@stream\SRprogramname \SR@writepgm\SR@program@stream{\SR@preambletext} \SR@writepgm\SR@program@stream{\@percentchar include "\SRrootdir/\SRpreamblename" /nosource;} \SR@writepgm\SR@program@stream{/* Remove all output files. */} \SR@writepgm\SR@program@stream{\SRsasprogramline} \SR@writepgm\SR@program@stream{} \SR@writepgm\SR@program@stream{/* Start program with a null title. */} \SR@writepgm\SR@program@stream{title;} \SR@writepgm\SR@program@stream{} } % \end{macrocode} % \DescribeMacro{\SR@write@preamble} % The \cs{SR@write@preamble} macro opens the |\SR@tempfile@stream| stream and % writes the preamble for the SAS program to be generated. The preamble is constructed % from the preceding configurable macros (for example, |\SRlinesize|, |\SRdpi|). % You can modify the preamble in the |statrep.cfg| file. % % \begin{macrocode} \AtBeginDocument{\SR@write@preamble} \AtEndDocument{\immediate\closeout\SR@program@stream} % \end{macrocode} % At the beginning of the document, the \cs{SR@program@stream} stream is % opened and the program file preamble (that is, the initial definitions % described previously) is written to the program file. % At the end of the document, the \cs{SR@programout} stream is closed. % % \subsection{Code Environments} % % The \Statrep package depends on the |verbatim| package to handle its code environments. % The |verbatim| package provides programming hooks for redefining commands that are % used to process % |verbatim| environments. By redefining some of the commands that are called by the |verbatim| % package, the \Statrep package can preprocess and postprocess code blocks as needed. % % The |verbatim| package defines the following macros as hooks for processing % |verbatim| environments: % \begin{itemize} % \item \cs{verbatim@addtoline} adds its argument to the character buffer. % \item \cs{verbatim@processline} typesets the characters that accumulate in the buffer. % \end{itemize} % % By redefining these macros, the \Statrep package can control % the reading, processing, and writing % of the |verbatim| environment. % The |Datastep| environment redefines \cs{verbatim@processline} at the beginning % and the end of the code block. % The |Sascode| environment redefines \cs{verbatim@addtoline} by inserting several % line-processing steps before adding characters to the character buffer. % % \subsubsection{Datastep Environment} % % Three macros are defined to set up the |Datastep| environment: % \begin{macrocode} \def\SR@datastep@writefile#1{% \setcounter{SR@totallines}{0}% \@bsphack\immediate\openout\SR@tempfile@stream#1% \let\do\@makeother\dospecials\catcode`\^^M\active% % \def\verbatim@processline{% \addtocounter{SR@totallines}{1}% \SR@writepgm\SR@tempfile@stream{\the\verbatim@line}% }% \verbatim@start% } % \end{macrocode} % \DescribeMacro{\SR@datastep@writefile} % The |SR@datastep@writefile| macro is used at the beginning of the % |Datastep| environment. It resets category codes, opens a temporary file, and % redefines \cs{verbatim@processline} % to count the lines in the environment and write the code block to a temporary file. % % The logic in the \cs{SR@datastep@writefile} macro is taken from an example in the |verbatim| % package documentation (Sch\"opf, Raichle, and Rowley 2001). % \begin{macrocode} \def\SR@enddatastep@writefile{\immediate\closeout\SR@tempfile@stream\@esphack} % \end{macrocode} % \DescribeMacro{\SR@enddatastep@writefile} % The \cs{SR@enddatastep@writefile} macro closes the temporary file. % \begin{macrocode} \newcommand{\SR@datastep@writeprogramline}{% \SR@writepgm\SR@program@stream{\the\verbatim@line}} % \end{macrocode} % \DescribeMacro{\SR@datastep@writeprogramline} % % The \cs{SR@datastep@writeprogramline} macro writes a line from the code block to the % generated program. It is used % when the code block is not specified as display-only. % The |Datastep| environment begins by redefining the \cs{verbatim@processline} macro % to write the code block to a temporary file. It also keeps a count of the total number % of lines in the block. % It ends by again redefining the \cs{verbatim@processline} macro, this time % to process lines from the temporary file according to options that are specified in the % |Datastep| environment. % % Figure \ref{dsscheme} shows how a |Datastep| environment is % processed. The names in \textcolor{darkblue}{blue} represent macros that are called % by the |verbatim| package, even though the macro contents might have been redefined. % \index{Datastep schematic|usage} % \begin{figure}[H] % \begin{snugshade} % \begin{picture}(400,170) % \put(20,100){\texttt{Datastep}} % \put(55,120){\textit{\textbf{Begin environment}}} % \put(55,70){\textit{\textbf{End environment}}} % % % \put(55,140){\textit{SR@datastep@writefile}} % \put(55,138){\vector(1,0){90}} % \put(165,145){\color{darkblue}\textit{verbatim@processline}} % \put(165,135){\textit{(count lines)}} % \put(230,138){\vector(1,0){50}} % \put(285,140){\textit{Temporary file}} % % % \put(55,55){\color{darkblue}\textit{verbatim@processline}} % \put(55,40){\textit{Process option keys for display}} % \put(55,30){(see \textit{Algorithm \ref{algo1}})} % \put(55,52){\vector(1,0){210}} % \put(285,52){\color{darkblue}\textit{verbatiminput}} % \put(255,40){\textit{(from temporary file)}} % \end{picture} % \end{snugshade} % \caption{Processing Schematic for the \texttt{Datastep} Environment}\label{dsscheme} % \end{figure} % \begin{macrocode} \def\@Datastep[#1]{% \setkeys{SR}{#1}% \SR@datastep@writefile{\SRtempfilename}% } \newenvironment{Datastep}{% \catcode`\^^M=\active \@ifnextchar[{\catcode`\^^M=5\@Datastep}{\catcode`\^^M=5\@Datastep[]} } % \end{macrocode} % % \begin{environment}{Datastep} % The beginning of the |Datastep| environment sets the key-value options that are % specified for the environment and calls the \Statrep macro \cs{SR@datastep@writefile}. % % If you specify a |Datastep| environment with no options, and you place a comment % character at the beginning of the first line % of the environment, that line is hidden from % the display. \LaTeX\ looks for the first ``real'' character of the environment and does % not see the commented line. To account for this possiblity, the \cs{@Datastep} % command is used internally to begin the real environment. At the initialization % of the |Datastep| environment, the category code for the end-of-line character % is changed to \emph{active}. If the environment has options, processing continues % as normal (\cs{@Datastep} is called directly). If the environment has no options, % a blank set of brackets is inserted into the stream and the \cs{@Datastep} is % then called. Thus, if you specify a |Datastep| environment with no options, % \LaTeX\ knows not to continue looking for the end of the command because the % empty brackets represent an empty set of options. % \begin{macrocode} {% \SR@enddatastep@writefile\endgraf% % \end{macrocode} % The end of the |Datastep| environment performs the following tasks: % \begin{enumerate} % \item calls \cs{SR@enddatastep@writefile} to close the temporary file % \item redefines \cs{verbatim@processline} to handle line processing % \item includes the temporary file that uses those redefined macros % \end{enumerate} % If the block should only be written to the program and not displayed, redefine % \cs{verbatim@processline} to \cs{SR@datastep@writeprogramline} (defined previously) % to write % a line to the generated program file. Then process the temporary file. % \begin{macrocode} \ifSR@program\def\verbatim@processline{\SR@datastep@writeprogramline}% \else% % \end{macrocode} % Otherwise, the code block is to be displayed. % \begin{macrocode} \ifthenelse{\equal{\SR@fontsize}{\@empty}}% {\relax}% {\@nameuse{\SR@fontsize}}% \setcounter{SR@currentline}{0}% \setcounter{SR@startinglastline}{\theSR@totallines-\SR@last-1}% % \end{macrocode} % Set the font size to be used in the display. Set the |SR@currentline| % counter to 0. Set |SR@startinglastline| to the total number of lines % in the environment minus the number of bottom lines to display. % % \DescribeMacro{\verbatim@processline} % Redefine the \cs{verbatim@processline} macro to account for options % that are specified to the % environment and read in the temporary file. % \begin{macrocode} \def\verbatim@processline{% % \end{macrocode} % If the code block is not display-only, write each line to the program file % by using the \cs{SR@datastep@writeprogramline} macro, defined previously. % \begin{macrocode} \ifSR@display\else\SR@datastep@writeprogramline\fi% % \end{macrocode} % The remainder of the macro logic is described in Algorithm \ref{algo1} on % page \pageref{algo1}. % % Supporting the |last=| option in the |Datastep| environment is the only % reason for the complexity of writing to a temporary file and % retrieving the lines from the file. % To know how to display the last \emph{n} lines, \Statrep must know the total % number of lines in the code block. % So it writes the code block to the temporary file and keeps % a tally of the number of lines as it writes each line. % % A horizontal skip of length \cs{SRparindent} is added % to the beginning of each \cs{the}\cs{verbatimline} line that is displayed. % % A \cs{par} is also appended to each \cs{the}\cs{verbatimline}: % In a |verbatim| environment, % \index{verbatim environment|usage} the entire block is typeset as a list of one item, % and within that item, each line is a paragraph. The following statements append a % \cs{par} to each % \cs{the}\cs{verbatimline} to end the paragraph: % \changes{1.05}{2014/10/15}{Added leavevmode; otherwise, interaction with geometry package} % \changes{1.05}{2014/10/16}{Added braces around par lines; otherwise, interaction with tocloft package} % \begin{macrocode} \ifnum\SR@first>0% \ifnum\theSR@currentline<\SR@first% {\leavevmode\hskip\SRparindent\the\verbatim@line\par}% \else% \ifnum\theSR@currentline=\SR@first% {\leavevmode\par\hskip\SRparindent\SRintertext\par}% \else% \ifnum\SR@last>0% \ifnum\theSR@currentline=\theSR@startinglastline{\leavevmode\par}\fi% \ifnum\theSR@currentline>\theSR@startinglastline% {\leavevmode\hskip\SRparindent\the\verbatim@line\par}% \fi% \fi% \fi% \fi% \else% {\leavevmode\hskip\SRparindent\the\verbatim@line\par}% \fi% \addtocounter{SR@currentline}{1}% }% \fi% % \end{macrocode} % The following algorithm describes how this redefined version of the % \cs{verbatim@processline} macro processes each line. % % \index{Datastep processing|usage} % \begin{algorithm}[H] % \For{each line in block}{ % \uIf{block is not display only} % {write data line \;} % \uIf{first=\textsf{n} is specified} % { % \uIf{currentline < \textsf{n}}{display line\;} % \uElseIf{currentline = \textsf{n}}{write the value of \cs{SRintertext}\;} % \uElseIf{last=\textsf{m} is specified}{ % \uIf{currentline = (totallines - \textsf{m})}{start new line\;} % \uElseIf{currentline > (totallines - \textsf{m})}{display line\;} % } % } % \uElse{display line\;} % } % \caption{\texttt{Datastep} Environment: \cs{verbatim@processline} Macro}\label{algo1} % \end{algorithm} % % When all settings are configured, and when subsidiary macros and the % \cs{verbatim@processline} macro are redefined, % the following statement reads in the temporary file that was created at the % beginning of the |Datastep| % environment. The file is read by using the |verbatim| package macro % \cs{verbatiminput}. That macro then calls \cs{verbatim@processline}, which the % \Statrep package has just redefined. % % \begin{macrocode} \verbatiminput{\SRtempfilename}% % \end{macrocode} % The code block has now been displayed and written to the program file as specified % by the options in the |Datastep| environment. However, there is still % cleanup left to do. % % The following statements determine whether the block was displayed: % if it was not displayed, they % retrieve all vertical space that is associated with the environment: % \begin{macrocode} \ifSR@program \setlength{\SR@scratchlength}{-2\topsep-\partopsep-2\parskip-\baselineskip} \vspace*{\SR@scratchlength}% \fi% % \end{macrocode} % If the block is written to the program file, the following statements output a blank line after % this |Datastep| environment in the program file: % \begin{macrocode} \ifSR@display\else% \SR@writepgm\SR@program@stream{}% \fi% } % \end{macrocode} % \end{environment} % % % \subsubsection{Sascode Environment} % The following macros are defined to set up the |Sascode| environment: % % \begin{itemize} % \item \cs{SR@sascode@addtoline} resets category codes and calls \cs{SR@sascode@filter}. % \item \cs{SR@sascode@filter} acts as a filter. It processes lines with line commands % and passes other lines to \cs{SR@sascode@writeline}. % \item \cs{SR@sascode@writeline} writes the lines into the character buffer that is used % by the |verbatim| package. It also writes lines to the generated program file. % \end{itemize} % % The |Sascode| environment uses this sequence of macros by % replacing the |verbatim| package macro \cs{verbatim@addtoline} with the % \cs{SR@sascode@addtoline} macro. % % The following statements start a group to safely change the category % code for the \% character to % \emph{other}. Within this group, the \% character can be used in other definitions % because its category code is no longer the comment category code (normally category % code 14). % \index{category codes|usage} % \begin{macrocode} \begingroup \catcode`\%12 % \end{macrocode} % \DescribeMacro{\SR@sascode@addtoline} % The following statements call the \cs{SR@sascode@addtoline} macro, % reset category codes, and call % \cs{SR@sascode@filter} with two arguments: the original category code of the % \% character and the verbatim line itself. The original category code for the \% % character is sent so that it can be returned to its original state after % \cs{SR@sascode@filter} is called. % \begin{macrocode} \gdef\SR@sascode@addtoline{\catcode`\%12 \expandafter\relax \expandafter\SR@sascode@filter \expandafter{\number\catcode`\% }} % \end{macrocode} % After expansion, the following command is left, where \textit{n} is the original % category code of the \% character:\\ % |\relax\SR@sascode@filter|~\textit{n}\\ % That is, the macro first % redefines the category code of the \% character and calls the % \cs{SR@sascode@filter} macro with the original category code of the % \% character as its first argument. % % \DescribeMacro{\SR@sascode@filter} % The \cs{SR@sascode@filter} macro does the work of filtering the % code block for line commands. See Algorithm \ref{algo2} for details. % % This macro is the reason \Statrep requires the use of % pdf\LaTeX: the PDF primitive \cs{pdfmatch} is essential to the macro. % % \DescribeMacro{\pdfmatch} % The \cs{pdfmatch}\marg{pattern}\marg{string} % command implements pattern matching (using the syntax of % POSIX regular expressions). % The first argument is a regular expression pattern and the second % argument is a string. The command expands % to --1 if the pattern is invalid, to 0 if no match is found, and to 1 if a match % is found. % The primitive was introduced in pdfTEX 1.30.0 (Thanh et al. 2009). % The result of \cs{pdfmatch} is stored in an array. % % \DescribeMacro{\pdflastmatch} % The \cs{pdflastmatch}\marg{integer}\marg{expandable} returns the % match that corresponds to \marg{integer} provided by the \cs{pdfmatch} % command. Entry 0 contains the full match, and further % entries contain submatches (captured group) that correspond to the subpatterns % of the match. % % The regular expression argument must be escaped for use in \LaTeX. % For example, consider the task to capture the integer in the following % expression:\\ % |%* program 4;|\\ % A typical regular expression to capture the integer 4 is defined as follows:\\ % |^%\*\s*program\s*([0-9]+);| % % To use the expression in \LaTeX, it must be escaped so that % the pattern becomes\\ % |^%\string\*\space*program\space*([0-9]+);| % % That is, \cs{*} becomes \cs{string}\cs{*} and \cs{s}* becomes \cs{space}*. % % The second argument is detokenized so that it represents a string of characters % for use in the \cs{pdfmatch} macro. % % The effect of the \cs{SR@sascode@filter} macro is that every line that % contains a line command is parsed, the appropriate line counters are % set, and the line is skipped. % % Algorithm \ref{algo2} describes how the \cs{SR@sascode@filter} processes % each line of the |Sascode| block. % % \index{Sascode processing|usage} % \begin{algorithm}[H] % \For {each line in block}{ % \eIf{line begins with \texttt{\%*} (column 1)}{ % \uIf{line matches \texttt{\%*} program n\; }{set program counter} % \uElseIf{line matches \texttt{\%*} display n\; }{set display counter} % \uElseIf{line matches \texttt{\%*} \; }{write line to program\;} % \Else{display and write to program (valid SAS macro comment)} % } % {pass line onward to \cs{SR@sascode@writeline}\;} % } % \caption{\texttt{Sascode} Environment: \texttt{SR@sascode@filter} Macro}\label{algo2} % \end{algorithm} % \begin{macrocode} \gdef\SR@sascode@filter#1#2{ \ifnum\pdfmatch{^%\string\*} {\detokenize{#2}}=1 \ifnum\pdfmatch{^%\string\*\space*program\space*([0-9]+);} {\detokenize{#2}}=1 \setcounter{SR@programline} {\expandafter\strip@prefix\pdflastmatch 1} \catcode`\%#1\@tempswafalse\verbatim@line{} \else \ifnum\pdfmatch{^%\string\*\space*display\space*([0-9]+);} {\detokenize{#2}}=1 \setcounter{SR@displayline} {\expandafter\strip@prefix\pdflastmatch 1} \catcode`\%#1\@tempswafalse\verbatim@line{} \else \ifnum\pdfmatch{^%\string\*\space*;(.*)$} {\detokenize{#2}}=1 \SR@writepgm\SR@program@stream{\expandafter\strip@prefix\pdflastmatch 1} \catcode`\%#1\@tempswafalse\verbatim@line{} \else \catcode`\%#1\SR@sascode@writeline{#2} \fi \fi \fi \else \catcode`\%#1\SR@sascode@writeline{#2} \fi } \endgroup % \end{macrocode} % The \cs{begingroup} that started the definition block for \cs{SR@sascode@addtoline} % and \cs{SR@sascode@filter} is closed with \cs{endgroup}. % % In the \cs{SR@sascode@filter} macro, the Boolean switch % \cs{tempswa} must be set to false for skipped lines because of how % the |verbatim| package uses the switch. % In the % \cs{verbatim@processline} macro, the switch determines % whether to insert a line ending. That is, it decides whether % a new verbatim environment is % starting (\verb+\@tempswatrue+). This decision determines whether % to end % a paragraph. Lines are equivalent to paragraphs inside a verbatim environment. % % Because the |Sascode| environment redefines the \cs{verbatim@addtoline} macro % and not the \cs{verbatim@processline} macro from the |verbatim| package, the % |Sascode| environment must set the \cs{tempswa} switch so that it is set appropriately % when the |verbatim| package invokes \cs{verbatim@processline}. % In this % way, the % \cs{tempswafalse} macro ensures that the displayed verbatim environment does % not have blank lines in places where a line command was used. % % The \cs{SR@sascode@filter} macro passes all lines that are not line commands % to the \cs{SR@sascode@writeline} macro. Lines that begin with the % special line command, the null SAS macro comment (\%*;), are written directly to % the generated program file after stripping the macro comment. % % The final \textbf{else} statement is executed % when neither the program counter nor the display counter is set. % % \DescribeMacro{\SR@sascode@writeline} % The \cs{SR@sascode@writeline} macro tests whether line counters are set % and writes each line to its appropriate destination (the display or the % generated program file or both). See Algorithm \ref{algo3} for a description % of the macro's behavior. % % Note the use of \cs{SRparindent} to indent the code lines so that the |Sascode| % environment display matches the |Datastep| environment display. % \begin{macrocode} \newcommand{\SR@sascode@writeline}[1]{% \ifSR@program% \SR@writepgm\expandafter\SR@program@stream{\detokenize{#1}}% \@tempswafalse% \else% \ifSR@display% \verbatim@line\expandafter{\the\verbatim@line\hskip\SRparindent#1}% \else% \ifnum\theSR@programline>0% \SR@writepgm\expandafter\SR@program@stream{\detokenize{#1}}% \addtocounter{SR@programline}{-1}% \@tempswafalse% \else% \ifnum\theSR@displayline>0% \verbatim@line\expandafter{\the\verbatim@line\hskip\SRparindent#1}% \addtocounter{SR@displayline}{-1}% \else% \SR@writepgm\expandafter\SR@program@stream{\detokenize{#1}}% \verbatim@line\expandafter{\the\verbatim@line\hskip\SRparindent#1}% \fi% \fi% \fi% \fi% } % \end{macrocode} % Algorithm \ref{algo3} describes how the \cs{SR@sascode@writeline} macro % processes each line that is received from the \cs{SR@sascode@filter} macro. % % \index{Sascode processing|usage} % \begin{algorithm}[H] % \For {each line received}{ % \uIf{program only}{write line to program file} % \uElseIf{display only}{display line} % \uElseIf{Program counter set} % {write line to program file\; % decrement \cs{SR@program} counter\;} % \uElseIf{Display counter set} % {display line\; % decrement \cs{SR@display} counter\;} % \Else{write line to program file\; % display line\;} % } % \caption{\texttt{Sascode} Environment: \texttt{SR@sascode@writeline} Macro}\label{algo3} % \end{algorithm} % % Figure \ref{fig:sascode} shows how a |Sascode| environment is % processed. The names in \textcolor{darkblue}{blue} represent macros that are called % by the |verbatim| package, even though the macro contents might have been % redefined. % \index{Sascode schematic|usage} % \begin{figure}[H] % \begin{snugshade} % \begin{picture}(400,200) % \put(150,175){\texttt{Sascode}} % \put(167,170){\vector(0,-1){30}} % \put(60,130){{\color{darkblue}\texttt{verbatim@addtoline}} => \texttt{SR@sascode@addtoline}} % % \put(200,120){\textit{\small initialize catcode}} % \put(200,110){\textit{\small in order to define}} % \put(200,100){\textit{\small and call\ldots}} % % \put(200, 75){\textit{\small filter lines, }} % \put(200, 65){\textit{\small process line commands,}} % \put(200, 55){\textit{\small and call\ldots}} % % \put(200, 30){\textit{\small send line into standard}} % \put(200, 20){\texttt{\small \textcolor{darkblue}{verbatim@line}} \textit{\small buffer}} % \put(188,125){\vector(0,-1){30}} % \put(175,85){\texttt{SR@sascode@filter}} % \put(188,80){\vector(0,-1){30}} % \put(175,40){\texttt{SR@sascode@writeline}} % % \put(80,125){\color{darkblue}\vector(0,-1){90}} % \put(60,25){\color{darkblue}\texttt{verbatim}} % \put(85,15){\color{darkblue}\small \textit{typeset standard}} % \put(85,5){\small\color{darkblue}\texttt{verbatim@line} \textit{\small buffer}} % % % \end{picture} % \end{snugshade} % \caption{Processing Schematic for the \texttt{Sascode} Environment}\label{fig:sascode} % \end{figure} % % \begin{environment}{Sascode} % The |Sascode| environment first sets the values for the optional keys. % If the environment is to be written to the generated program, the appropriate % keys are processed and passed to the program. % % If you do not use the |store=| key, \Statrep assumes that you are writing % your own SAS macros to output the ODS document and write the outputs. If you do % use the key, the macros are written automatically. % % The central point of the code for processing the |Sascode| environment is to % redirect the |verbatim| package macro, % \cs{verbatim@addtoline}, to the \Statrep package macro,\cs{SR@sascode@addtoline}. % This redirection begins the workflow % shown in Figure \ref{fig:sascode}. The processing steps are as follows: % \index{Sascode processing|usage} % \begin{enumerate} % \item The |verbatim| package macro calls \cs{verbatim@addtoline}. % \item The \cs{verbatim@addtoline} macro redirects to \cs{SR@sascode@addtoline}. % \item The \cs{SR@sascode@addtoline} macro sets category codes and calls \cs{SR@sascode@filter}. % \item The \cs{SR@sascode@filter} macro processes line commands and % calls \cs{SR@sascode@writeline}. % \item The \cs{SR@sascode@writeline} macro % parses and processes the lines. It writes the appropriate lines to % the generated program file. % It also writes the appropriate lines into the \cs{verbatim@line} buffer, which % is processed by the |verbatim| package macro \cs{verbatim}. % \end{enumerate} % % If you specify a |Sascode| environment with no options, and you place % a comment character at the beginning of the first line, that line is hidden from % the display. \LaTeX\ looks for the first ``real'' character of the environment and does % not see the commented line. To account for this possiblity, the \cs{@Sascode} % command is used internally to begin the real environment. At the initialization % of the |Sascode| environment, the category code for the end-of-line character % is changed to \emph{active}. If the environment has options, processing continues % as normal (\cs{@Sascode} is called directly). If the environment has no options, % an empty set of brackets is inserted into the stream and \cs{@Sascode} is % then called. Thus, if you specify a |Sascode| environment with no options, % \LaTeX\ knows not to continue looking for the end of the command because the % empty brackets represent an empty set of options. % \begin{macrocode} \def\@Sascode[#1]{% \setkeys{SR}{#1}% \ifSR@display\else% \ifthenelse{\equal{\SR@store}{\@empty}}% {\relax}% {\SR@writepgm\SR@program@stream{\@percentchar output(\SR@store)}% \PackageInfo{statrep}{Processing Sascode block \SR@store}}% \fi% \ifthenelse{\equal{\SR@fontsize}{\@empty}}% {\relax}% {\@nameuse{\SR@fontsize}}% \setcounter{SR@programline}{0}% \setcounter{SR@displayline}{0}% \let\verbatim@addtoline\SR@sascode@addtoline% \verbatim} \newenvironment{Sascode}{% \catcode`\^^M=\active \@ifnextchar[{\catcode`\^^M=5\@Sascode}{\catcode`\^^M=5\@Sascode[]} } % \end{macrocode} % The end of the |Sascode| environment performs the last steps that are needed % and does some cleanup. % The following statements remove vertical space that is caused by the end % of the |Sascode| environment and write the |%endoutput| macro % contents to the generated program file: % \begin{macrocode} {\endverbatim% \setlength{\SR@scratchlength}{-2\topsep-\partopsep-2\parskip} \vspace*{\SR@scratchlength}% \ifSR@program\vspace*{-\baselineskip}\fi % \ifSR@display\else% \ifthenelse{\equal{\SR@store}{\@empty}}% {\relax}% {\SR@writepgm\SR@program@stream{\@percentchar endoutput(\SR@store)}% \SR@writepgm\SR@program@stream{}}% \fi% } % \end{macrocode} % \end{environment} % % \subsection{Handling the SAS Output}\label{output} % % The \cs{Listing} and \cs{Graphic} tags support options that are used % in the generated program and in output display. % % There are three possible cases for an output request: % \begin{itemize} % \item The output is of type |graphic|. % \item The output is of type |listing| and destination |listing|. % \item The output is of type |listing| and destination |latex|. % \end{itemize} % % When the |store=| option % is used in the tags, a line is written to the |%write| macro that passes % a subset of the options in the tag to the generated program. The tags also insert % the stream of specified outputs in the displayed document. % % Graphical output is inserted as specified in the \cs{Graphic} tag, % captioned, and centered. % % Listing output is inserted in the same way, but the output is framed when % the destination is |listing|; when the destination is |latex|, the output % (which is in the form of LaTeX tabular environments) is not framed. % % The frame for the |listing| destination % is created with the help of the |longfigure| package and the % \cs{hline} command. % If the ODS destination is LaTeX, the resulting output blocks are put into % a minipage of \cs{textwidth} width and are not framed. % % The following helper macros are used only in writing to the generated program: % \begin{description} % \item[\cs{SR@write@outoptions}] is called when the |store=| option is specified in % the output tag. The command parses the options that are specified in the output tag % for program-related options % and writes the appropriate SAS macro to the generated program. % \item[\cs{SR@set@outoptions}] creates a string of |key=value| pairs that are used % in the generated SAS macro. % \item[\cs{SR@final@outoptions}] accumulates each |key=value| pair into one string. % \item[\cs{SR@outkeyval}] tests each key to determine whether to add the key and % its value to the final option string. % \end{description} % % % \DescribeMacro{\SR@write@outoptions} % If the |store=| option is specified in a \cs{Listing} or \cs{Graphic} tag, % the \cs{SR@write@outoptions} macro is called. % Otherwise, nothing is written to the generated % SAS program. % For each line that is written, use the macro \cs{SR@hashchar} to write out % an unescaped hash character (|#|) when an escaped hash % character (|\#|) is read.\index{hashchar|usage}\index{\#|usage} % See section \ref{utilities} for information about the \cs{SR@hashchar} macro. % \begin{macrocode} \def\SR@write@outoptions{ \SR@set@outoptions \let\#\SR@hashchar \SR@writepgm\SR@program@stream{% \@percentchar write(\SR@label,store=\SR@store \SR@final@outoptions) } % \end{macrocode} % % After the program line is written, a blank line is output to the program: % \begin{macrocode} \SR@writepgm\SR@program@stream{} } % \end{macrocode} % The following statements define the \cs{SR@set@outoptions} macro. % \DescribeMacro{\SR@set@outoptions} % This macro % resets the \cs{SR@final@outoptions} % definition and calls \cs{SR@outkeyval} for the keys that can be passed % through to the generated SAS program. This processing is necessary % so that keys with \cs{@empty} values are not passed to the generated % program. % \begin{macrocode} \newcommand*{\SR@set@outoptions}{% \global\edef\SR@final@outoptions{} \SR@outkeyval{height}\SR@outkeyval{objects}\SR@outkeyval{pattern} \SR@outkeyval{style}\SR@outkeyval{dpi}\SR@outkeyval{options} \SR@outkeyval{pagesize}\SR@outkeyval{linesize}\SR@outkeyval{width} \SR@outkeyval{dest}\SR@outkeyval{type}\SR@outkeyval{firstobj}\SR@outkeyval{lastobj} } % \end{macrocode} % Recall that all keys are set to \cs{@empty} with the \cs{presetkeys} macro. % If the value has not been changed from the default, the following statements % omit it from % the \cs{SR@final@outoptions} macro definition. % % \DescribeMacro{\SR@outkeyval} % The \cs{SR@outkeyval} macro expands % \cs{SR@final@outoptions} to a string of |key=value| pairs. % With each call to the \cs{SR@outkeyval} macro, the argument is checked % to determine whether it is empty. If it is not empty, the argument is expanded and % added to the \cs{SR@final@outoptions} value. % \begin{macrocode} \newcommand*{\SR@outkeyval}[1]{% \def\SR@outkey{#1} \edef\SR@outval{\csname SR@#1\endcsname} \ifx\@empty\SR@outval \else \edef\SR@final@outoptions{\SR@final@outoptions,\SR@outkey=\SR@outval} \fi } % \end{macrocode} % % The following macros are used to display the SAS generated output. % \begin{description} % \item[\cs{Listing}] inserts a stream of listing outputs. % \begin{description} % \item[\cs{Boxlisting}] boxes a single listing. % \end{description} % \item[\cs{Graphic}] inserts a stream of graphical outputs. % \begin{description} % \item[\cs{Boxgraphic}] boxes a single graphic. % \end{description} % \item[\cs{SR@insert}] begins the output insertion process. % \begin{description} % \item[\cs{SR@set@outheadings}] sets the heading for a |longfigure|. % \item[\cs{SR@set@outmargin}] sets the left margin for centering a |longfigure|. % \end{description} % \end{description} % % \subsubsection{Note on Widths} % If the output is a listing and the destination is |listing|, the output % will be inserted as verbatim type input. The width is calculated by the linesize and % the output centered by adjusting the \cs{LFleft} margin. The width calculation is % done once, at the \cs{Listing} command itself. % % If the output is a graphic, the output is put into a box at whatever |scale| or % |width| the user specified. The width of that box is calculated and the % output centered by adjusting the \cs{LFleft} margin. The width calculation cannot % be done at the \cs{Graphic} command since the output must be measured first. % It is in the \cs{Boxgraphic} macro that the calculation takes place, which means it % happens for each graphic in the output stream. Only the first graphic has an effect; % it is only the first graphic in the stream that affects the \cs{LFleft} margin. % This is an inefficiency. % % If the output is a listing and the destination is |latex|, the output cannot be % measured at all. The output is put into a minipage of |textwidth| width and the % \cs{LFleft} margin is untouched. The user can therefore set \cs{LFleft} before the % \cs{Listing} tag to shift the output if needed. % % \subsubsection{The \cs{Listing} Macro}\label{listing} %\index{output labels|usage} % \begin{macro}{\Listing} % The \cs{Listing} macro sets the options that are specified in the tag and % automatically creates a label by using % its \marg{argument}, which serves also as the name of % the output file (without an extension). % \begin{macrocode} \newcommand{\Listing}[2][]{% \setkeys{SR}{#1,type=listing,label=#2}% \ifthenelse{\equal{\SR@store}{\@empty}}% {\relax}% {\SR@write@outoptions}% % \end{macrocode} % The |type=| option is automatically specified as |listing|; this option % is passed to the generated SAS program. % If the |store=| option is specified, the \cs{SR@write@outoptions} macro is invoked % to write the appropriate SAS macro to the generated file. % \begin{macrocode} \ifthenelse{\equal{\SR@dest}{\@empty}}% {\def\SR@dest{\SRdefaultdests}}% {\relax}% % \end{macrocode} % If no value was given for the |dest=| option, set \cs{SR@dest} to the % default value (specified globally as \cs{SRdest}). Now we are guaranteed % to have a value for \cs{SR@dest} (used in the \cs{Boxlisting} and % \cs{SR@insert} macros). % % The next block only pertains to the situation where we have a % verbatim listing output from ODS Listing destination. We need to find % the width of the output, which is done by calculating the width of a single % character in the specified font and multiplying that value by the number % of characters per line (linesize). This line length is saved in the % value \cs{SR@scratchlength} and used to center the output. % \begin{macrocode} \ifthenelse{\equal{\SR@dest}{listing}}% % The following statements set the font size: % \begin{macrocode} {\ifthenelse{\equal{\SR@fontsize}{\@empty}}% {\def\SR@fontsize{normalsize}}% {\relax}% % \end{macrocode} % The following statements set \cs{SR@scratchlength} to the width of a % single character (\textasciitilde) by using the % current font size and the verbatim font: % \begin{macrocode} \settowidth{\SR@scratchlength}{\@nameuse\SR@fontsize% \SRverbfont\selectfont~}% % \end{macrocode} % % The following statements control the line size for ODS Listing output: % \begin{macrocode} \ifthenelse{\equal{\SR@linesize}{\@empty}}% {\def\SR@linesize{\SRlinesize}}{\relax}% % \end{macrocode} % The value for the key \cs{SR@linesize} is set to \cs{@empty} with each % invocation of the \cs{Listing} command. If no value is specified % for \cs{SR@linesize}, the following statements set it to the specified default % value for line size \cs{SRlinesize}. This default is set to 80 by the % \Statrep package; you can set the line size in the |statrep.cfg| file. % % The |linesize=| key corresponds to the line size that the SAS program uses to % generate the tabular output. By default it is set to 80; other typical values % are 96 and 120. % % The following statements set \cs{SR@verbwidth} to the width % of \cs{SR@linesize} number of columns, % with each column as wide as \cs{SR@scratchlength}. The result represents the % width of the contents of a SAS listing output. % % \begin{macrocode} \setlength{\SR@verbwidth}{(\SR@linesize\SR@scratchlength)}% % \end{macrocode} % Finally, the following statements % add 2\cs{tabcolsep} and 2\cs{arrayrulewidth} to that width. % The result represents the total width of a \cs{Listing} output and % is used in the \cs{SR@insert} macro to center the output.\footnote{A listing % output stream gets its width once, at the beginning of the stream. A graphic % gets the width for each graphic file in its stream. Only the first % measurement is used to calculate the graphic width % (that is, only the first graphic file width is used).} % \begin{macrocode} \setlength{\SR@scratchlength}{\SR@verbwidth+2\tabcolsep+ 2\arrayrulewidth}% }% end if dest is listing {\relax}% do nothing if dest is latex. % \end{macrocode} % With \cs{SR@verbwidth} calculated, \cs{SR@insert} is called to insert the \cs{Listing}. % When the Listing is being set, the value for the left margin of the longfigure is % calculated. After the Listing is finished, reset the value back to its default, 0. % \begin{macrocode} \SR@insert{#2}% \setlength{\LFleft}{0in}% } % \end{macrocode} % \end{macro} % \subsubsection{The \cs{Graphic} Macro} % The \cs{Graphic} macro sets the options that are specified in the tag and % automatically creates a label by using % its \marg{argument}, which also serves as the name of % the output file (without an extension). % \begin{macrocode} \newcommand{\Graphic}[2][]{% \setkeys{SR}{#1,type=graphic, label=#2}% \ifthenelse{\equal{\SR@store}{\@empty}}% {\relax}% {\SR@write@outoptions}% \SR@insert{#2}% \setlength{\LFleft}{0in}% } % \end{macrocode} % \begin{macro}{\Graphic} % The |type=| option is automatically specified as |graphic|; this option % is passed to the generated SAS program. % If the |store=| option is specified, the \cs{SR@write@outoptions} macro is invoked % to write the appropriate SAS macro to the generated file. % % Finally, \cs{SR@insert} is called to insert the \cs{Graphic}. % When the Graphic is being set, the value for the left margin of the longfigure is % calculated. After the Graphic is finished, reset the value back to its default, 0. % \end{macro} % % \subsubsection{The \cs{Boxlisting} Macro} % If the \cs{SRdest} value has been set for this % listing, the value for \cs{SR@dest} now contains the value (see the Listing code above). % % If the current destination is |listing|, the \cs{Boxlisting} macro % creates a box that contains the verbatim content % of an external listing file. Put the content of the specified file % into a box as verbatim input. If the file doesn't exist, place a marker in the document. % % If the current destination is |latex|, the \cs{Boxlisting} macro puts % the contents of the specified file into a minipage and then into the box. % % \begin{macrocode} \newcommand*{\Boxlisting}[1]{% \ifthenelse{\equal{\SR@dest}{listing}}% {\global\def\SR@insertname{lst/#1.lst}% \IfFileExists{\SR@insertname}% {% \savebox{\SR@filebox}{% \def\verbatim@font{% \@nameuse{\SR@fontsize}% \SRverbfont% \hyphenchar\font\m@ne% \@noligs% }% \parbox{\SR@verbwidth}{% \vspace*{0.25\baselineskip}% \noindent\verbatiminput{\SR@insertname}% \vspace*{0.25\baselineskip}}% }% }% {\savebox{\SR@filebox}{\fbox{Missing File \SR@insertname}}% \global\def\SR@insertname{\@empty}}% }% {\global\def\SR@insertname{tex/#1.tex}% \IfFileExists{\SR@insertname}% {% \savebox{\SR@filebox}{% \begin{minipage}{\textwidth}% \vspace{0.25\baselineskip}% \centering\input{\SR@insertname}% \vspace{0.25\baselineskip}% \end{minipage}% }% }% {\savebox{\SR@filebox}{\centering\fbox{Missing File \SR@insertname}}% \global\def\SR@insertname{\@empty}% }% }% \global\setbox\SR@filebox=\box\SR@filebox% \PackageInfo{statrep}{Processing output \SR@insertname}% } % \end{macrocode} % % \begin{macro}{\Boxlisting} % \changes{1.04}{2014/09/08}{Added noligs to verbatim font definition} % The \cs{Boxlisting} macro takes a single argument, the \marg{filename} % of the listing output to be boxed (the filename without the extension). % If the file exists, the macro places the content of the file % (using \cs{verbatiminput}) into a box of \cs{SR@verbwidth}, % which is calculated % as described in section \ref{listing}. % White space at the top and bottom of the box is % inserted (0.25\cs{baselineskip}). % % The \cs{verbatim@font} is set to the user-defined \cs{SR@fontsize} (from the % options on the Listing tag) and the \cs{SRverbfont} in the configuration. Furthermore, % ligatures and the hyphenation character are both turned off. If you omit this % step, ligatures will appear in the listing output (the case which prompted this % bug-fix was a dashed line; the emdash ligature was applied to each pair of dashes). % % Note that \cs{SR@verbwidth} is the width that is used to create the \cs{parbox} % that contains the output. \cs{SR@scratchlength} is used to center % the output in a later step. % \cs{SR@scratchlength} represents the width of the output plus the surrounding frame. % % If the file does not exist, \cs{SR@insertname} is defined to be % \cs{@empty} and \cs{SR@filebox} is defined to be a box with % the contents |Missing File|. % \end{macro} % \subsubsection{The \cs{Boxgraphic} Macro} % The \cs{Boxgraphic} macro creates a box that contains the content of an external % graphic file. % \begin{macrocode} \newcommand*{\Boxgraphic}[1]{% \IfFileExists{png/#1.\SRgraphtype}% {\global\def\SR@insertname{png/#1.\SRgraphtype}}% {\global\def\SR@insertname{\@empty}}% \ifthenelse{\equal{\SR@insertname}{\@empty}}% {\savebox{\SR@filebox}{\fbox{ Missing File png/#1.\SRgraphtype}}}% {% \ifthenelse{\equal{\SR@scale}{\@empty}}% {\ifthenelse{\equal{\SR@width}{\@empty}}% {\savebox{\SR@filebox}{\includegraphics{\SR@insertname}}}% {\savebox{\SR@filebox}{\includegraphics[width=\SR@width]% {\SR@insertname}}}}% {\savebox{\SR@filebox}{\includegraphics[scale=\SR@scale]% {\SR@insertname}}}% }% \global\setbox\SR@filebox=\box\SR@filebox% \PackageInfo{statrep}{Processing graphic \SR@insertname}% \setlength{\SR@scratchlength}{\wd\SR@filebox+2\tabcolsep}% }% % \end{macrocode} % \begin{macro}{\Boxgraphic} % The \cs{Boxgraphic} macro takes a single argument, the \marg{filename} % of the graphic output to be boxed (the filename without the extension). % \index{png graphics|usage} % \index{pdf graphics|usage} % % The macro first checks whether the file exists. % If it does, it sets the global variable \cs{SR@insertname} to the full name. % If the file does not exist, % \cs{SR@insertname} is defined to be \cs{@empty}. % % If the global variable \cs{SR@insertname} is empty, % then \cs{SR@filebox} is defined to be a framed box with % the contents |Missing File|. % % Otherwise, we use % the \cs{includegraphics} macro from the |graphicx| package to place % the image. % % If the |width=| or |scale=| option was specified, the option is passed % to the \cs{includegraphics} macro. % % Finally, \cs{SR@scratchlength} is set to the width of the graphic % (now contained in \cs{SR@filebox}) + 2\cs{tabcolsep}. % The result represents the total width of a \cs{Graphic} output and % is used in the \cs{SR@insert} macro to center the output. % \end{macro} % % \subsubsection{The \cs{SR@insert} Macro}\label{insert} % % The \cs{SR@insert} macro sets headings and footers for a |longfigure|, % begins the |longfigure| environment, and calls the appropriate macro to % display an % output stream by using \cs{Boxlisting} or \cs{Boxgraphic}. % The |longfigure| package is described in detail in section \ref{longfigure}. % \begin{macro}{SR@filebox} % Two helper macros are necessary to set up for the \cs{SR@insert} % command: % \begin{description} % \item[\cs{SR@set@outheadings}] sets the headings on the output. % \item[\cs{SR@set@outmargin}] sets the left margin to center the output. % \end{description} % \end{macro} % % \DescribeMacro{\SR@set@outheadings} % The \cs{SR@set@outheadings} macro sets the contents of the |longfigure|'s first heading, % its ``continued'' heading, and the footer. If the content is a \cs{Listing} and the % destination is |listing|, % the |longfigure| is framed (the headings and footers include an % \cs{hline} command). % % \begin{macrocode} \def\SR@set@outheadings{% % \end{macrocode} % The following statements define three macros for typing shortcuts: % \begin{macrocode} \def\SR@@caption{\caption{\SRcaptionfont\SR@caption}}% \def\SR@@captioncontinued{\caption{\SRcaptioncontinuedfont\SRcontinuedname}}% \def\SR@@captionskip{\\*[0.5\baselineskip]}% % \end{macrocode} % % The following statements define a set of \cs{SR@@} macros that are % used as calculators for the actual macros used % at the time of typesetting: % \begin{macrocode} \ifthenelse{\equal{\SR@dest}{listing}}% {\def\SR@@firsthead{\hline\endLFfirsthead}% \def\SR@@conthead{\hline\endLFhead}% \def\SR@@endfoot{\hline\endLFfoot}}% % {\def\SR@@firsthead{\endLFfirsthead}% \def\SR@@conthead{\endLFhead}% \def\SR@@endfoot{\endLFfoot}}% %%% % \end{macrocode} % If the \cs{SR@dest} is |listing|, \cs{hline} commands are used for the heading % and footer of the |longfigure|. % % The following statements set initial values for the heading % and footer based on the preceding definitions: % \begin{macrocode} %%% \renewcommand*{\SR@firsthead}{\SR@@firsthead}% \renewcommand*{\SR@conthead}{\SR@@conthead}% \renewcommand*{\SR@endfoot}{\SR@@endfoot}% % \end{macrocode} % \begin{macrocode} \ifthenelse{\equal{\SR@caption}{\@empty}}% {% CAPTION NOT GIVEN \addtocounter{\LFcounter}{-1}% \ifSR@continued% \renewcommand*{\SR@conthead}{\SR@@captioncontinued% \SR@@captionskip\SR@@conthead}% \fi% }% % \end{macrocode} % If a caption has not been specified, the % first heading is empty. If the |longfigure| is a continuation % (\cs{SR@continued} is true), the contination heading is set and % the |longfigure| counter \cs{LFcounter} is decremented. % Decrementing \cs{LFcounter} anticipates the automatic incrementing of the counter by the % |longfigure| environment in the |longfigure| package. % Thus, \textit{continued} |longfigure|s retain the number % of the preceding |longfigure| environment. % \begin{macrocode} {% CAPTION GIVEN \renewcommand*{\SR@firsthead}{\SR@@caption\label{\SR@label}% \SR@@captionskip\SR@@firsthead}% \renewcommand*{\SR@conthead}{\SR@@captioncontinued% \SR@@captionskip\SR@@conthead}% } } % \end{macrocode} % If a caption has been specified, both the first heading and the continued % heading are set appropriately. % % \index{output processing|usage} % \DescribeMacro{\SR@set@outmargin} % The \cs{SR@set@outmargin} macro sets the |longfigure| parameter |LFleft| based % on the output dimensions. The output width is set in the % \cs{Listing} (|listing| destination), % or \cs{Boxgraphic} macros. The length % parameter \cs{SR@scratchlength} contains the output width. % \index{output centering|usage}% % \begin{macrocode} \def\SR@set@outmargin{% \ifdim\SR@scratchlength>\textwidth% \dosloppy% \setlength{\LFleft}{(\paperwidth-\SR@scratchlength)/\real{2.0}}% \addtolength{\LFleft}{-1in}% \addtolength{\LFleft}{-\hoffset}% \addtolength{\LFleft}{-\leftskip}% \ifodd\c@page\addtolength{\LFleft}{-\oddsidemargin}% \else\addtolength{\LFleft}{-\evensidemargin}% \fi% \else% \setlength{\LFleft}{(\textwidth-\SR@scratchlength)/\real{2.0}}% \fi% } % \end{macrocode} % If the width of the output is narrower than the text block, it is centered % with respect to the text block. % \[ % \mathsf{LFleft} = \frac{\mathtt{textwidth} - \mathtt{outputwidth}}{2} % \] % If the width of the output is wider than the textblock, it is centered with % respect to the page. The position of the left-hand edge of % the page from the text block is calculated. % The text block margin is the sum of the following: % \begin{itemize} % \item the standard \TeX\ margin (1 inch) % \item \cs{hoffset} % \item \cs{leftskip} % \item the margin specified in the document design % \end{itemize} % To move to the left edge of the page, move left % by the total amount of margin:\\ % 1 inch + \cs{hoffset} + \cs{leftskip} + \textit{document margin} % % Therefore, to center with respect to the page, add horizontal space equal to half % the difference between the paper width and the output width. That is: % \[ % \mathsf{LFleft} = -(\mathrm{TeX margin}+\mathtt{hoffset} + \mathtt{leftskip} + \mathtt{margin}) +\frac{\mathtt{paperwidth}-\mathtt{outputwidth}}{2} % \] % The first term (encompassed in parentheses) moves to the left edge of the page; % the second and last term adds the % horizontal space necessary to center the output. For example, using % |letterpaper|, an output width of 5.75 inches, and a side margin % of 1.5 inch, and assuming \cs{hoffset} and \cs{leftskip} have their default % values of zero width, % the left margin is set as follows: % \[ % \mathrm{LFleft} = - (1 + 1.5) + \frac{8.5-5.75}{2} = -1.125 % \] % The \cs{LFleft} margin is set to |-1.125|, which is 1.125 inches to the left of the % normal text block margin. % % For documents with unequal margins on even-numbered and odd-numbered pages, % take the page number into % account before subtracting the side margin. The \cs{ifodd} macro, provided % by the |ifthen| package, checks whether the page number is odd or even. % % Note: The \cs{dosloppy} command is used only when the output is wider than % the text block.\index{dosloppy|usage} % % \begin{macro}{\SR@insert} % The \cs{SR@insert} macro inserts an output stream into the document. % % The following statements set the heading for the output and box the % first output in the stream: % \begin{macrocode} \newcommand{\SR@insert}[1]{% \SR@set@outheadings% \ifthenelse{\equal{\SR@type}{listing}}{\Boxlisting{#1}}{\Boxgraphic{#1}}% \ifthenelse{\equal{\SR@dest}{latex}}% {\relax}% {\SR@set@outmargin}% % \end{macrocode} % % The width of a \cs{Listing} output is calculated in the \cs{Listing} macro. % The width of a \cs{Graphic} output is calculated in the \cs{Boxgraphic} macro. % Therefore, after boxing an output, the \cs{SR@scratchlength} contains the % width of the output regardless of type. With that information, the margins % that are required for centering are set. This does not apply to outputs with % |dest=latex|. % % The following statements determine whether an output file exists that matches % the argument specified in the output tag; and if so, they % set the Boolean switch |SR@multifile| to |true| and display the resulting % boxed output: % \begin{macrocode} \ifthenelse{\equal{\SR@insertname}{\@empty}}% {\setboolean{SR@multifile}{false}}% {\setboolean{SR@multifile}{true}}% % \end{macrocode} % \changes{v1.07}{2015/09/15}{encapsulates longfigure with bgroup/egroup} % The following statements center a listing or a graphic and % put a vertical line on each side of a listing (|listing| destination). % No horizontal or vertical lines (no box) are drawn for graphics or % outputs using the |latex| destination. % \begin{macrocode} \ifthenelse{\equal{\SR@dest}{listing}}% {\bgroup\longfigure{|c|}}{\bgroup\longfigure{c}}% \SR@firsthead\SR@conthead\SR@endfoot% \usebox{\SR@filebox}% % \end{macrocode} % The following statements begin the input loop, inserting output files that % match the specified stem pattern until % there are no matching files:\index{output insertion|usage} % \begin{macrocode} \setcounter{SR@multifilecount}{1}% \whiledo{\boolean{SR@multifile}}{% \ifthenelse{\equal{\SR@type}{listing}}% {\Boxlisting{#1\arabic{SR@multifilecount}}}% {\Boxgraphic{#1\arabic{SR@multifilecount}}}% \ifthenelse{\equal{\SR@insertname}{\@empty}}% {\setboolean{SR@multifile}{false}}% {\\[0.5\baselineskip]\usebox{\SR@filebox}% \stepcounter{SR@multifilecount}% \setboolean{SR@multifile}{true}}% }% \endlongfigure\egroup% \unsloppy% } % \end{macrocode} % The logic of the preceding statements is depicted in Algorithm \ref{malgo}. % % \begin{algorithm}[H] % \While{multiple files is True} % {\eIf{type=listing}{Boxlisting}{Boxgraphic} % \eIf{file exists}{insert contents, increment counter}{multiple files is False} % } % \caption{Input Loop for the Output Stream}\label{malgo} % \end{algorithm} % % When SAS generates a set of files from one ODS selection, it follows a % pattern. The first file that is generated is identical to the filename. The next % file that is generated has the same name with a ``1'' appended to it, the next file % has the same name with a ``2'' appended, and so on. % The preceding statements input the original file; the following statements test for % the existence of a file that has a name with the next digit in the % sequence appended. The \cs{SR@multifilecount} counter contains the % digit. With each inserted file, the counter is incremented. % % When no file matches the pattern (the % \cs{SR@insertname} macro is \cs{@empty}), the Boolean switch % \cs{SR@multifile} is set to false and the loop is ended. % % The \cs{unsloppy} macro is called when the stream insertion is finished % to undo the effects of a \cs{dosloppy} command, which is called when % the width of the output is greater than the width of % the textblock. Invoking the \cs{unsloppy} macro % multiple times has the same effect as calling it once; that is, even if % \cs{dosloppy} is never called, calling \cs{unsloppy} causes no problem. % % \end{macro} %\iffalse % %\fi %<*longfigure> % \section{\textsf{\small longfigure} Usage} % \label{longfigure} % \index{longfigure package|usage} % % The |longfigure| package uses and relabels components of the % well-known |longtable| package, written by David Carlisle, to % provide a table-like environment that can display a stream % of subfigures as a single figure that can break across pages. % % The |longtable| package defines a |longtable| environment, % which produces tables that can be broken by \TeX's standard page-breaking algorithm. % Similarly, the |longfigure| package defines a |longfigure| environment, which produces % figures that can be broken by \TeX's standard page-breaking algorithm. % The internal structure of a long figure is similar to a long table. % Rows might contain (for example) tables or graphics. Page breaks % can occur only between rows. % % The |longfigure| package differs from the |longtable| package in the following ways: % \begin{itemize} % \item The |longfigure| package supports two additional key-value options: % \begin{itemize} % \item The |figname=| option specifies the counter for numbering |longfigure| environments. % You can specify any string; the default is |figure|. % When you specify a |figname=| value for which no counter already exists, the % |longfigure| package loads the |tocloft| package and creates the counter. % \index{figname option|usage} % % \item The |resetby=| option specifies a counter (for example, |resetby=chapter|) such % that output numbering is reset each time the counter value changes. % If a counter is specified that does not exist, the |tocloft| package is % loaded to create the new counter. % \index{tocloft package|usage}% % For information about how the lists are typeset, % \index{list of outputs, creating|usage}% % see the |tocloft| package documentation. % \end{itemize} % \item The counters and macros that start with \cs{LT} in the |longtable| package % are renamed to start with \cs{LF} in the |longfigure| pacakge to avoid % namespace conflicts when the two packages are used together. % The generic macros that are defined in the |longtable| package % (\cs{endfirsthead}, \cs{endhead}, \cs{endfoot}, and \cs{endlastfoot}) are % also renamed with \cs{LF} as a prefix in the |longfigure| package. % % \item The \cs{LF@name} macro is based on the \cs{fnum@table} macro from % the |longtable| package. The \cs{LF@name} macro returns the capitalized % counter name and value. For example, if the counter is |figure| and the % macro is processing the second |longfigure|, the \cs{LF@name} macro % would contain the value ``Figure 2.'' % % \end{itemize} % You can use the |longfigure| package defaults to produce a \emph{List of Figures} % by inserting the following tag in your document at the point where you want % the list to appear: % \iffalse %<*example> % \fi \begin{verbatim} \listoffigures \end{verbatim} % \iffalse % % \fi % % The default counter used to display figures is the |figure| counter, % but you can specify a different counter. For example, if you want your % figures to be labeled as ``Display,'' specify |figname=display| when you % load the |longfigure| package; to display a \emph{List of Displays}, insert the following % command in your document at the point where you want the list to appear: % \iffalse %<*example> % \fi \begin{verbatim} \listofdisplay \end{verbatim} % \iffalse % % \fi % \textbf{Note:} If you specify a counter that does not exist, % an auxiliary file with extension |.lft| is created to contain the information % needed to create the list. % % If you want to use more advanced features of the |tocloft| package, % load it before you load the |longfigure| package so that the |longfigure| % package sees that the counters specified by the |figname=| and |resetby=| % options are already defined and does not attempt to create them. % % %\subsection{Example} % The following lines produce a single figure that contains three images and % one tabular environment. Each element is a row of the |longfigure| environment. % Page breaks can occur between rows. %% \iffalse %<*example> % \fi \begin{verbatim} \documentclass{book} \usepackage{graphicx} \usepackage{longfigure} \begin{document} \begin{longfigure}{c} \caption{My Long Figure}\label{mlfig}\\ \includegraphics[width=3in]{myfig1}\\ \includegraphics[width=3in]{myfig2}\\ \includegraphics[width=3in]{myfig3}\\ \begin{tabular}{ll} one & two \\ three & four\\ \end{tabular} \end{longfigure} \end{document} \end{verbatim} % \iffalse % % \fi % In this example, the |{c}| argument in the |\begin{longfigure}| command % specifies only a single centered column. You can also specify multiple columns and, % if needed, use the \cs{multicolumn} command for more flexibility. % % The following lines display another example that specifies a 'continued' heading % when the figure breaks over a page. It also displays a double horizontal line at the % end of the figure. % \iffalse %<*example> % \fi \begin{verbatim} \documentclass{book} \usepackage{graphicx} \usepackage{longfigure} \begin{document} \begin{longfigure}{c} \caption{My Long Figure}\label{mlfig2}\\ \hline\endLFfirsthead \caption{continued}\\ \hline\endLFhead \hline\endLFfoot \hline\hline\endLFlastfoot \includegraphics[width=3in]{myfig1}\\ \includegraphics[width=3in]{myfig2}\\ \includegraphics[width=3in]{myfig3}\\ \begin{tabular}{ll} one & two \\ three & four\\ \end{tabular} \end{longfigure} \end{document} \end{verbatim} % \iffalse % % \fi % \section{Implementation} % % This section describes the implementation of the |longfigure| package. % The comments describe only the changes from the |longtable| package code. % For complete details about the logic and usage of the |longtable| environment, % see Carlisle (2004). %\iffalse %<*longfigure> %\fi % \begin{macrocode} \ProvidesPackage{longfigure}[2014/01/06 longfigure] % \end{macrocode} % The following statement loads the |xkeyval| package for declaring % and processing package options: % \begin{macrocode} \RequirePackage{xkeyval} % \end{macrocode} % The following statement defines a new command, \cs{LFcounter}, to % contain the string |figure|. % Later code tests whether a counter with that name exists. % \begin{macrocode} \newcommand*{\LFcounter}{figure} % \end{macrocode} % % The following statement defines a new command, \cs{LFreset}, to contain % the name of the counter within which the |longfigure| number should reset. % If no value is specified, the long figures are numbered consecutively % through the document. % \begin{macrocode} \newcommand*{\LFreset}{\@empty} % \end{macrocode} % \subsection{Options} % The \cs{LFcounter} and \cs{LFreset} commands support the % package options |figname=| and |resetby=| as follows: % \begin{macrocode} \DeclareOptionX{figname}[figure]{\renewcommand*{\LFcounter}{#1}} \DeclareOptionX{resetby}{\renewcommand*{\LFreset}{#1}} % \end{macrocode} % The following statements further define the options % that the |longtable| package defines: % \begin{macrocode} \DeclareOptionX{set}{} \DeclareOptionX{final}{} \DeclareOptionX{errorshow}{\def\LF@warn{\PackageInfo{longfigure}}} \DeclareOptionX{pausing}{\def\LF@warn#1{\LF@err{#1}{This is not really an error}}} \ProcessOptionsX % \end{macrocode} % The following statements process the options: % \begin{macrocode} \def\LFProcessOptions#1{ \@ifundefined{c@#1}{% \RequirePackage{tocloft} \def\LFuc##1##2{\MakeUppercase{##1}{##2}} \expandafter\def\csname list#1name\endcsname{List of \LFuc#1s} \ifx\@empty\LFreset% \newlistof{#1}{lft}{\csname list#1name\endcsname} \else \newlistof[\LFreset]{#1}{lft}{\csname list#1name\endcsname} \fi }{}% } \expandafter\LFProcessOptions\expandafter{\LFcounter} % \end{macrocode} % If a counter is specified that does not exist, its name (\cs{c@}\textit{countername}) % is undefined and the |longfigure| package loads the |tocloft| package in order to % use its commands to create the new counters and list. % % Thus, the |tocloft| package is required only when a new counter % is specified, % \index{tocloft package|usage}% % and this automatic loading takes place only if the counter that is specified % in the package options is not defined. % % You can load the |tocloft| package before loading the |longfigure| package % and retain all of the flexibility that the |tocloft| package offers. % However, you must define the new counters yourself by using the % \cs{newlistof} command in the |tocloft| package, % and you must define the new list to use an auxiliary |lft| file where % its auxiliary information is written. % \index{tocloft package|usage}% % % \subsection{Utilities} % \DescribeMacro{\strcfstr} % The following macro, \cs{strcfstr}, checks whether two strings, which are % provided as arguments, are equal (Wilson, 2001). % A new boolean \cs{ifLF@same} contains the result of the test. % \begin{macrocode} \newif\ifLF@same \newcommand{\strcfstr}[2]{% \LF@samefalse \begingroup\def\2{#2} \ifx\2#1\endgroup\LF@sametrue \else\endgroup \fi } % \end{macrocode} % \DescribeMacro{\LFupcase} % The following macro, \cs{LFupcase}, uppercases the first letter of % a string (Lazarides, 2010): % \begin{macrocode} \def\LFupcase#1{% \def\x##1##2{% \MakeUppercase{##1}{##2}}\x#1% } % \end{macrocode} % The following macro, \cs{LF@name}, creates a string to provide a label and number for % an output. Analogous to the \cs{fnum@table} macro in the |longtable| package, % it contains the capitalized version of the counter name and the counter % number (for example, |Figure~3|). % \begin{macrocode} \def\LF@name{\expandafter\LFupcase% \expandafter{\LFcounter}~% \expandafter\csname the\LFcounter\endcsname}% % \end{macrocode} % The remainder of this package follows the |longtable| package % almost identically, except that macros, skips, counters, and so on % use an \cs{LF} prefix instead of the \cs{LT} prefix that the |longtable| package uses. % % \begin{macrocode} \def\LF@err{\PackageError{longfigure}} \def\LF@warn{\PackageWarning{longfigure}} \def\LF@final@warn{% \AtEndDocument{% \LF@warn{\LFcounter \@width s have changed. Rerun \LaTeX\.\@gobbletwo}}% \global\let\LF@final@warn\relax} % \newskip\LFleft \LFleft=\fill \newskip\LFright \LFright=\fill \newskip\LFpre \LFpre=\bigskipamount \newskip\LFpost \LFpost=\bigskipamount \newcount\LFchunksize \LFchunksize=20 \let\c@LFchunksize\LFchunksize \newdimen\LFcapwidth \LFcapwidth=4in \newbox\LF@head \newbox\LF@firsthead \newbox\LF@foot \newbox\LF@lastfoot \newcount\LF@cols \newcount\LF@rows \newcounter{LF@tables} \newcounter{LF@chunks}[LF@tables] % \newtoks\LF@p@ftn \mathchardef\LF@end@pen=30000 \def\longfigure{% \par \ifx\multicols\@undefined \else \ifnum\col@number>\@ne \@twocolumntrue \fi \fi \if@twocolumn \LF@err{longfigure not in 1-column mode}\@ehc \fi \begingroup \@ifnextchar[\LF@array{\LF@array[x]}} \def\LF@array[#1]#2{% \refstepcounter{\LFcounter}\stepcounter{LF@tables}% \if l#1% \LFleft\z@ \LFright\fill \else\if r#1% \LFleft\fill \LFright\z@ \else\if c#1% \LFleft\fill \LFright\fill \fi\fi\fi \let\LF@mcol\multicolumn \let\LF@@tabarray\@tabarray \let\LF@@hl\hline \def\@tabarray{% \let\hline\LF@@hl \LF@@tabarray}% \let\\\LF@tabularcr\let\tabularnewline\\% \def\newpage{\noalign{\break}}% \def\pagebreak{\noalign{\ifnum`}=0\fi\@testopt{\LF@no@pgbk-}4}% \def\nopagebreak{\noalign{\ifnum`}=0\fi\@testopt\LF@no@pgbk4}% \let\hline\LF@hline \let\kill\LF@kill\let\caption\LF@caption \@tempdima\ht\strutbox \let\@endpbox\LF@endpbox \ifx\extrarowheight\@undefined \let\@acol\@tabacol \let\@classz\@tabclassz \let\@classiv\@tabclassiv \def\@startpbox{\vtop\LF@startpbox}% \let\@@startpbox\@startpbox \let\@@endpbox\@endpbox \let\LF@LL@FM@cr\@tabularcr \else \advance\@tempdima\extrarowheight \col@sep\tabcolsep \let\@startpbox\LF@startpbox\let\LF@LL@FM@cr\@arraycr \fi \setbox\@arstrutbox\hbox{\vrule \@height \arraystretch \@tempdima \@depth \arraystretch \dp \strutbox \@width \z@}% \let\@sharp##\let\protect\relax \begingroup \@mkpream{#2}% \xdef\LF@bchunk{% \global\advance\c@LF@chunks\@ne \global\LF@rows\z@\setbox\z@\vbox\bgroup \LF@setprevdepth \tabskip\LFleft \noexpand\halign to\hsize\bgroup \tabskip\z@ \@arstrut \@preamble \tabskip\LFright \cr}% \endgroup \expandafter\LF@nofcols\LF@bchunk&\LF@nofcols \LF@make@row \m@th\let\par\@empty \everycr{}\lineskip\z@\baselineskip\z@ \LF@bchunk} \def\LF@no@pgbk#1[#2]{\penalty #1\@getpen{#2}\ifnum`{=0\fi}} \def\LF@start{% \let\LF@start\endgraf \endgraf\penalty\z@\vskip\LFpre \dimen@\pagetotal \advance\dimen@ \ht\ifvoid\LF@firsthead\LF@head\else\LF@firsthead\fi \advance\dimen@ \dp\ifvoid\LF@firsthead\LF@head\else\LF@firsthead\fi \advance\dimen@ \ht\LF@foot \dimen@ii\vfuzz \vfuzz\maxdimen \setbox\tw@\copy\z@ \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox \setbox\tw@\vbox{\unvbox\tw@}% \vfuzz\dimen@ii \advance\dimen@ \ht \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi \advance\dimen@\dp \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi \advance\dimen@ -\pagegoal \ifdim \dimen@>\z@\vfil\break\fi \global\@colroom\@colht \ifvoid\LF@foot\else \advance\vsize-\ht\LF@foot \global\advance\@colroom-\ht\LF@foot \dimen@\pagegoal\advance\dimen@-\ht\LF@foot\pagegoal\dimen@ \maxdepth\z@ \fi \ifvoid\LF@firsthead\copy\LF@head\else\box\LF@firsthead\fi\nobreak \output{\LF@output}} \def\endlongfigure{% \crcr \noalign{% \let\LF@entry\LF@entry@chop \xdef\LF@save@row{\LF@save@row}}% \LF@echunk \LF@start \unvbox\z@ \LF@get@widths \if@filesw {\let\LF@entry\LF@entry@write\immediate\write\@auxout{% \gdef\expandafter\noexpand \csname LF@\romannumeral\c@LF@tables\endcsname {\LF@save@row}}}% \fi \ifx\LF@save@row\LF@@save@row \else \LF@warn{Column \@width s have changed\MessageBreak in table \thetable}% \LF@final@warn \fi \endgraf\penalty -\LF@end@pen \endgroup \global\@mparbottom\z@ \pagegoal\vsize \endgraf\penalty\z@\addvspace\LFpost \ifvoid\footins\else\insert\footins{}\fi} \def\LF@nofcols#1&{% \futurelet\@let@token\LF@n@fcols} \def\LF@n@fcols{% \advance\LF@cols\@ne \ifx\@let@token\LF@nofcols \expandafter\@gobble \else \expandafter\LF@nofcols \fi} \def\LF@tabularcr{% \relax\iffalse{\fi\ifnum0=`}\fi \@ifstar {\def\crcr{\LF@crcr\noalign{\nobreak}}\let\cr\crcr \LF@t@bularcr}% {\LF@t@bularcr}} \let\LF@crcr\crcr \let\LF@setprevdepth\relax \def\LF@t@bularcr{% \global\advance\LF@rows\@ne \ifnum\LF@rows=\LFchunksize \gdef\LF@setprevdepth{% \prevdepth\z@\global \global\let\LF@setprevdepth\relax}% \expandafter\LF@xtabularcr \else \ifnum0=`{}\fi \expandafter\LF@LL@FM@cr \fi} \def\LF@xtabularcr{% \@ifnextchar[\LF@argtabularcr\LF@ntabularcr} \def\LF@ntabularcr{% \ifnum0=`{}\fi \LF@echunk \LF@start \unvbox\z@ \LF@get@widths \LF@bchunk} \def\LF@argtabularcr[#1]{% \ifnum0=`{}\fi \ifdim #1>\z@ \unskip\@xargarraycr{#1}% \else \@yargarraycr{#1}% \fi \LF@echunk \LF@start \unvbox\z@ \LF@get@widths \LF@bchunk} \def\LF@echunk{% \crcr\LF@save@row\cr\egroup \global\setbox\@ne\lastbox \unskip \egroup} \def\LF@entry#1#2{% \ifhmode\@firstofone{&}\fi\omit \ifnum#1=\c@LF@chunks \else \kern#2\relax \fi} \def\LF@entry@chop#1#2{% \noexpand\LF@entry {\ifnum#1>\c@LF@chunks 1}{0pt% \else #1}{#2% \fi}} \def\LF@entry@write{% \noexpand\LF@entry^^J% \@spaces} \def\LF@kill{% \LF@echunk \LF@get@widths \expandafter\LF@rebox\LF@bchunk} \def\LF@rebox#1\bgroup{% #1\bgroup \unvbox\z@ \unskip \setbox\z@\lastbox} \def\LF@blank@row{% \xdef\LF@save@row{\expandafter\LF@build@blank \romannumeral\number\LF@cols 001 }} \def\LF@build@blank#1{% \if#1m% \noexpand\LF@entry{1}{0pt}% \expandafter\LF@build@blank \fi} \def\LF@make@row{% \global\expandafter\let\expandafter\LF@save@row \csname LF@\romannumeral\c@LF@tables\endcsname \ifx\LF@save@row\relax \LF@blank@row \else {\let\LF@entry\or \if!% \ifcase\expandafter\expandafter\expandafter\LF@cols \expandafter\@gobble\LF@save@row \or \else \relax \fi !% \else \aftergroup\LF@blank@row \fi}% \fi} \let\setlongfigures\relax \def\LF@get@widths{% \setbox\tw@\hbox{% \unhbox\@ne \let\LF@old@row\LF@save@row \global\let\LF@save@row\@empty \count@\LF@cols \loop \unskip \setbox\tw@\lastbox \ifhbox\tw@ \LF@def@row \advance\count@\m@ne \repeat}% \ifx\LF@@save@row\@undefined \let\LF@@save@row\LF@save@row \fi} \def\LF@def@row{% \let\LF@entry\or \edef\@tempa{% \ifcase\expandafter\count@\LF@old@row \else {1}{0pt}% \fi}% \let\LF@entry\relax \xdef\LF@save@row{% \LF@entry \expandafter\LF@max@sel\@tempa \LF@save@row}} \def\LF@max@sel#1#2{% {\ifdim#2=\wd\tw@ #1% \else \number\c@LF@chunks \fi}% {\the\wd\tw@}} \def\LF@hline{% \noalign{\ifnum0=`}\fi \penalty\@M \futurelet\@let@token\LF@@hline} \def\LF@@hline{% \ifx\@let@token\hline \global\let\@gtempa\@gobble \gdef\LF@sep{\penalty-\@medpenalty\vskip\doublerulesep}% \else \global\let\@gtempa\@empty \gdef\LF@sep{\penalty-\@lowpenalty\vskip-\arrayrulewidth}% \fi \ifnum0=`{\fi}% \multispan\LF@cols \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr \noalign{\LF@sep}% \multispan\LF@cols \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr \noalign{\penalty\@M}% \@gtempa} % \end{macrocode} % \subsection{Captioning} % You can easily change how a long figure is captioned by % redefining the \cs{LF@makecaption} macro after loading the |longfigure| package. % The following statements show the default definition of the % \cs{LF@makecaption}: % % \begin{macrocode} \def\LF@caption{% \noalign\bgroup \@ifnextchar[{\egroup\LF@c@ption\@firstofone}\LF@capti@n} % \end{macrocode} % The \cs{LF@caption} command begins the process. % If it includes an optional argument, it calls \cs{LF@c@ption}; otherwise % it calls \cs{LF@capti@n}, which then calls \cs{LF@c@ption}. % \begin{macrocode} \def\LF@c@ption#1[#2]#3{% \LF@makecaption#1\LF@name{#3}% \def\@tempa{#2}% \ifx\@tempa\@empty\else % \end{macrocode} % If a list of long figures is requested, the following code uses the % previously defined \cs{strcfstr} macro and \cs{ifLF@same} boolean % to determine the name of the counter and set the output file to % contain the |longfigure| information. % % The code writes to one of the following files. % \begin{itemize} % \item If the counter is |figure|, write to the |lof| file. % \item If the counter is |table|, write to the |lot| file. % \item Otherwise, write to |lft|, a file created here for this purpose. % \end{itemize} % % \begin{macrocode} {\let\\\space \strcfstr{\LFcounter}{figure} \ifLF@same\def\LFoutfile{lof}\else \strcfstr{\LFcounter}{table} \ifLF@same\def\LFoutfile{lot}\else \def\LFoutfile{lft}\fi\fi \addcontentsline{\LFoutfile}{\LFcounter} {\expandafter\protect\expandafter\numberline\expandafter% {\expandafter\csname the\LFcounter\endcsname}{#2}}}% \fi } % \end{macrocode} % The \cs{LF@c@ption} macro ends the process when it calls the % \cs{LF@makecaption} macro, which typesets the caption. % \begin{macrocode} \def\LF@capti@n{% \@ifstar {\egroup\LF@c@ption\@gobble[]}% {\egroup\@xdblarg{\LF@c@ption\@firstofone}}} % \end{macrocode} % % If you want to redefine how the |longfigure| is captioned, % you need to override the following macro. % The first argument is the name of the counter % (for example, |Figure|), the second argument is the number of the counter, and the % third argument is the caption itself. % \begin{macrocode} \def\LF@makecaption#1#2#3{% \LF@mcol\LF@cols c{\hbox to\z@{\hss\parbox[t]\LFcapwidth{% \sbox\@tempboxa{#1{#2: }#3}% \ifdim\wd\@tempboxa>\hsize #1{#2: }#3% \else \hbox to\hsize{\hfil\box\@tempboxa\hfil}% \fi \endgraf\vskip\baselineskip}% \hss}}} \def\LF@output{% \ifnum\outputpenalty <-\@Mi \ifnum\outputpenalty > -\LF@end@pen \LF@err{floats and marginpars not allowed in a longfigure}\@ehc \else \setbox\z@\vbox{\unvbox\@cclv}% \ifdim \ht\LF@lastfoot>\ht\LF@foot \dimen@\pagegoal \advance\dimen@-\ht\LF@lastfoot \ifdim\dimen@<\ht\z@ \setbox\@cclv\vbox{\unvbox\z@\copy\LF@foot\vss}% \@makecol \@outputpage \setbox\z@\vbox{\box\LF@head}% \fi \fi \global\@colroom\@colht \global\vsize\@colht \vbox {\unvbox\z@\box\ifvoid\LF@lastfoot\LF@foot\else \LF@lastfoot\fi}% \fi \else \setbox\@cclv\vbox{\unvbox\@cclv\copy\LF@foot\vss}% \@makecol \@outputpage \global\vsize\@colroom \copy\LF@head\nobreak \fi} \def\LF@end@hd@ft#1{% \LF@echunk \ifx\LF@start\endgraf \LF@err {Longfigure head or foot not at start of table}% {Increase LFchunksize}% \fi \setbox#1\box\z@ \LF@get@widths \LF@bchunk} % \end{macrocode} % The following four macros do not have an \cs{LT} prefix in the |longtable| package, % but they must be redefined to have an \cs{LF} prefix in order to avoid a namespace clash; % \begin{macrocode} \def\endLFfirsthead{\LF@end@hd@ft\LF@firsthead} \def\endLFhead{\LF@end@hd@ft\LF@head} \def\endLFfoot{\LF@end@hd@ft\LF@foot} \def\endLFlastfoot{\LF@end@hd@ft\LF@lastfoot} % \def\LF@startpbox#1{% \bgroup \let\@footnotetext\LF@p@ftntext \setlength\hsize{#1}% \@arrayparboxrestore \vrule \@height \ht\@arstrutbox \@width \z@} \def\LF@endpbox{% \@finalstrut\@arstrutbox \egroup \the\LF@p@ftn \global\LF@p@ftn{}% \hfil} \def\LF@p@ftntext#1{% \edef\@tempa{\the\LF@p@ftn\noexpand\footnotetext[\the\c@footnote]}% \global\LF@p@ftn\expandafter{\@tempa{#1}}}% % \end{macrocode} % \subsection{References} % % Carlisle, D. 2004. % \emph{The longtable Package}. % Included in the ``Comprehensive \TeX\ Archive Network.'' \url{http://ctan.org}. % % Lazarides, Y. 2010. % \TeX stackexchange, online forum. \url{http://tex.stackexchange.com/questions/7992}. % % Sch\"opf, R, B. Raichle, and C. Rowley. 2001. % \emph{A New Implementation of \LaTeX's \texttt{verbatim} and \texttt{verbatim*} Environments}. % Originally appeared in TUGboat 1990, 11(2), 284--296. % % Thanh, H., S. Rahtz, H. Hagen, and H. Henkel. 2009. % ``The pdf\TeX\ User's Manual,'' Revision 655, corresponding to pdf\TeX\ 1.40.11. % \url{www.tug.org/applications/pdftex}. % % Wilson, P. 2001. % \emph{Glisterings}. In TUGboat 22(4), 339--340. % % % \iffalse % % \fi %\Finale %\endinput