diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/statrep |
Initial commit
Diffstat (limited to 'macros/latex/contrib/statrep')
21 files changed, 8866 insertions, 0 deletions
diff --git a/macros/latex/contrib/statrep/LICENSE b/macros/latex/contrib/statrep/LICENSE new file mode 100644 index 0000000000..f8b699e6eb --- /dev/null +++ b/macros/latex/contrib/statrep/LICENSE @@ -0,0 +1,415 @@ +The LaTeX Project Public License +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +LPPL Version 1.3c 2008-05-04 + +Copyright 1999 2002-2008 LaTeX3 Project + Everyone is allowed to distribute verbatim copies of this + license document, but modification of it is not allowed. + + +PREAMBLE +======== + +The LaTeX Project Public License (LPPL) is the primary license under +which the LaTeX kernel and the base LaTeX packages are distributed. + +You may use this license for any work of which you hold the copyright +and which you wish to distribute. This license may be particularly +suitable if your work is TeX-related (such as a LaTeX package), but +it is written in such a way that you can use it even if your work is +unrelated to TeX. + +The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE', +below, gives instructions, examples, and recommendations for authors +who are considering distributing their works under this license. + +This license gives conditions under which a work may be distributed +and modified, as well as conditions under which modified versions of +that work may be distributed. + +We, the LaTeX3 Project, believe that the conditions below give you +the freedom to make and distribute modified versions of your work +that conform with whatever technical specifications you wish while +maintaining the availability, integrity, and reliability of +that work. If you do not see how to achieve your goal while +meeting these conditions, then read the document `cfgguide.tex' +and `modguide.tex' in the base LaTeX distribution for suggestions. + + +DEFINITIONS +=========== + +In this license document the following terms are used: + + `Work' + Any work being distributed under this License. + + `Derived Work' + Any work that under any applicable law is derived from the Work. + + `Modification' + Any procedure that produces a Derived Work under any applicable + law -- for example, the production of a file containing an + original file associated with the Work or a significant portion of + such a file, either verbatim or with modifications and/or + translated into another language. + + `Modify' + To apply any procedure that produces a Derived Work under any + applicable law. + + `Distribution' + Making copies of the Work available from one person to another, in + whole or in part. Distribution includes (but is not limited to) + making any electronic components of the Work accessible by + file transfer protocols such as FTP or HTTP or by shared file + systems such as Sun's Network File System (NFS). + + `Compiled Work' + A version of the Work that has been processed into a form where it + is directly usable on a computer system. This processing may + include using installation facilities provided by the Work, + transformations of the Work, copying of components of the Work, or + other activities. Note that modification of any installation + facilities provided by the Work constitutes modification of the Work. + + `Current Maintainer' + A person or persons nominated as such within the Work. If there is + no such explicit nomination then it is the `Copyright Holder' under + any applicable law. + + `Base Interpreter' + A program or process that is normally needed for running or + interpreting a part or the whole of the Work. + + A Base Interpreter may depend on external components but these + are not considered part of the Base Interpreter provided that each + external component clearly identifies itself whenever it is used + interactively. Unless explicitly specified when applying the + license to the Work, the only applicable Base Interpreter is a + `LaTeX-Format' or in the case of files belonging to the + `LaTeX-format' a program implementing the `TeX language'. + + + +CONDITIONS ON DISTRIBUTION AND MODIFICATION +=========================================== + +1. Activities other than distribution and/or modification of the Work +are not covered by this license; they are outside its scope. In +particular, the act of running the Work is not restricted and no +requirements are made concerning any offers of support for the Work. + +2. You may distribute a complete, unmodified copy of the Work as you +received it. Distribution of only part of the Work is considered +modification of the Work, and no right to distribute such a Derived +Work may be assumed under the terms of this clause. + +3. You may distribute a Compiled Work that has been generated from a +complete, unmodified copy of the Work as distributed under Clause 2 +above, as long as that Compiled Work is distributed in such a way that +the recipients may install the Compiled Work on their system exactly +as it would have been installed if they generated a Compiled Work +directly from the Work. + +4. If you are the Current Maintainer of the Work, you may, without +restriction, modify the Work, thus creating a Derived Work. You may +also distribute the Derived Work without restriction, including +Compiled Works generated from the Derived Work. Derived Works +distributed in this manner by the Current Maintainer are considered to +be updated versions of the Work. + +5. If you are not the Current Maintainer of the Work, you may modify +your copy of the Work, thus creating a Derived Work based on the Work, +and compile this Derived Work, thus creating a Compiled Work based on +the Derived Work. + +6. If you are not the Current Maintainer of the Work, you may +distribute a Derived Work provided the following conditions are met +for every component of the Work unless that component clearly states +in the copyright notice that it is exempt from that condition. Only +the Current Maintainer is allowed to add such statements of exemption +to a component of the Work. + + a. If a component of this Derived Work can be a direct replacement + for a component of the Work when that component is used with the + Base Interpreter, then, wherever this component of the Work + identifies itself to the user when used interactively with that + Base Interpreter, the replacement component of this Derived Work + clearly and unambiguously identifies itself as a modified version + of this component to the user when used interactively with that + Base Interpreter. + + b. Every component of the Derived Work contains prominent notices + detailing the nature of the changes to that component, or a + prominent reference to another file that is distributed as part + of the Derived Work and that contains a complete and accurate log + of the changes. + + c. No information in the Derived Work implies that any persons, + including (but not limited to) the authors of the original version + of the Work, provide any support, including (but not limited to) + the reporting and handling of errors, to recipients of the + Derived Work unless those persons have stated explicitly that + they do provide such support for the Derived Work. + + d. You distribute at least one of the following with the Derived Work: + + 1. A complete, unmodified copy of the Work; + if your distribution of a modified component is made by + offering access to copy the modified component from a + designated place, then offering equivalent access to copy + the Work from the same or some similar place meets this + condition, even though third parties are not compelled to + copy the Work along with the modified component; + + 2. Information that is sufficient to obtain a complete, + unmodified copy of the Work. + +7. If you are not the Current Maintainer of the Work, you may +distribute a Compiled Work generated from a Derived Work, as long as +the Derived Work is distributed to all recipients of the Compiled +Work, and as long as the conditions of Clause 6, above, are met with +regard to the Derived Work. + +8. The conditions above are not intended to prohibit, and hence do not +apply to, the modification, by any method, of any component so that it +becomes identical to an updated version of that component of the Work as +it is distributed by the Current Maintainer under Clause 4, above. + +9. Distribution of the Work or any Derived Work in an alternative +format, where the Work or that Derived Work (in whole or in part) is +then produced by applying some process to that format, does not relax or +nullify any sections of this license as they pertain to the results of +applying that process. + +10. a. A Derived Work may be distributed under a different license + provided that license itself honors the conditions listed in + Clause 6 above, in regard to the Work, though it does not have + to honor the rest of the conditions in this license. + + b. If a Derived Work is distributed under a different license, that + Derived Work must provide sufficient documentation as part of + itself to allow each recipient of that Derived Work to honor the + restrictions in Clause 6 above, concerning changes from the Work. + +11. This license places no restrictions on works that are unrelated to +the Work, nor does this license place any restrictions on aggregating +such works with the Work by any means. + +12. Nothing in this license is intended to, or may be used to, prevent +complete compliance by all parties with all applicable laws. + + +NO WARRANTY +=========== + +There is no warranty for the Work. Except when otherwise stated in +writing, the Copyright Holder provides the Work `as is', without +warranty of any kind, either expressed or implied, including, but not +limited to, the implied warranties of merchantability and fitness for a +particular purpose. The entire risk as to the quality and performance +of the Work is with you. Should the Work prove defective, you assume +the cost of all necessary servicing, repair, or correction. + +In no event unless required by applicable law or agreed to in writing +will The Copyright Holder, or any author named in the components of the +Work, or any other party who may distribute and/or modify the Work as +permitted above, be liable to you for damages, including any general, +special, incidental or consequential damages arising out of any use of +the Work or out of inability to use the Work (including, but not limited +to, loss of data, data being rendered inaccurate, or losses sustained by +anyone as a result of any failure of the Work to operate with any other +programs), even if the Copyright Holder or said author or said other +party has been advised of the possibility of such damages. + + +MAINTENANCE OF THE WORK +======================= + +The Work has the status `author-maintained' if the Copyright Holder +explicitly and prominently states near the primary copyright notice in +the Work that the Work can only be maintained by the Copyright Holder +or simply that it is `author-maintained'. + +The Work has the status `maintained' if there is a Current Maintainer +who has indicated in the Work that they are willing to receive error +reports for the Work (for example, by supplying a valid e-mail +address). It is not required for the Current Maintainer to acknowledge +or act upon these error reports. + +The Work changes from status `maintained' to `unmaintained' if there +is no Current Maintainer, or the person stated to be Current +Maintainer of the work cannot be reached through the indicated means +of communication for a period of six months, and there are no other +significant signs of active maintenance. + +You can become the Current Maintainer of the Work by agreement with +any existing Current Maintainer to take over this role. + +If the Work is unmaintained, you can become the Current Maintainer of +the Work through the following steps: + + 1. Make a reasonable attempt to trace the Current Maintainer (and + the Copyright Holder, if the two differ) through the means of + an Internet or similar search. + + 2. If this search is successful, then enquire whether the Work + is still maintained. + + a. If it is being maintained, then ask the Current Maintainer + to update their communication data within one month. + + b. If the search is unsuccessful or no action to resume active + maintenance is taken by the Current Maintainer, then announce + within the pertinent community your intention to take over + maintenance. (If the Work is a LaTeX work, this could be + done, for example, by posting to comp.text.tex.) + + 3a. If the Current Maintainer is reachable and agrees to pass + maintenance of the Work to you, then this takes effect + immediately upon announcement. + + b. If the Current Maintainer is not reachable and the Copyright + Holder agrees that maintenance of the Work be passed to you, + then this takes effect immediately upon announcement. + + 4. If you make an `intention announcement' as described in 2b. above + and after three months your intention is challenged neither by + the Current Maintainer nor by the Copyright Holder nor by other + people, then you may arrange for the Work to be changed so as + to name you as the (new) Current Maintainer. + + 5. If the previously unreachable Current Maintainer becomes + reachable once more within three months of a change completed + under the terms of 3b) or 4), then that Current Maintainer must + become or remain the Current Maintainer upon request provided + they then update their communication data within one month. + +A change in the Current Maintainer does not, of itself, alter the fact +that the Work is distributed under the LPPL license. + +If you become the Current Maintainer of the Work, you should +immediately provide, within the Work, a prominent and unambiguous +statement of your status as Current Maintainer. You should also +announce your new status to the same pertinent community as +in 2b) above. + + +WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE +====================================================== + +This section contains important instructions, examples, and +recommendations for authors who are considering distributing their +works under this license. These authors are addressed as `you' in +this section. + +Choosing This License or Another License +---------------------------------------- + +If for any part of your work you want or need to use *distribution* +conditions that differ significantly from those in this license, then +do not refer to this license anywhere in your work but, instead, +distribute your work under a different license. You may use the text +of this license as a model for your own license, but your license +should not refer to the LPPL or otherwise give the impression that +your work is distributed under the LPPL. + +The document `modguide.tex' in the base LaTeX distribution explains +the motivation behind the conditions of this license. It explains, +for example, why distributing LaTeX under the GNU General Public +License (GPL) was considered inappropriate. Even if your work is +unrelated to LaTeX, the discussion in `modguide.tex' may still be +relevant, and authors intending to distribute their works under any +license are encouraged to read it. + +A Recommendation on Modification Without Distribution +----------------------------------------------------- + +It is wise never to modify a component of the Work, even for your own +personal use, without also meeting the above conditions for +distributing the modified component. While you might intend that such +modifications will never be distributed, often this will happen by +accident -- you may forget that you have modified that component; or +it may not occur to you when allowing others to access the modified +version that you are thus distributing it and violating the conditions +of this license in ways that could have legal implications and, worse, +cause problems for the community. It is therefore usually in your +best interest to keep your copy of the Work identical with the public +one. Many works provide ways to control the behavior of that work +without altering any of its licensed components. + +How to Use This License +----------------------- + +To use this license, place in each of the components of your work both +an explicit copyright notice including your name and the year the work +was authored and/or last substantially modified. Include also a +statement that the distribution and/or modification of that +component is constrained by the conditions in this license. + +Here is an example of such a notice and statement: + + %% pig.dtx + %% Copyright 2005 M. Y. Name + % + % This work may be distributed and/or modified under the + % conditions of the LaTeX Project Public License, either version 1.3 + % of this license or (at your option) any later version. + % The latest version of this license is in + % http://www.latex-project.org/lppl.txt + % and version 1.3 or later is part of all distributions of LaTeX + % version 2005/12/01 or later. + % + % This work has the LPPL maintenance status `maintained'. + % + % The Current Maintainer of this work is M. Y. Name. + % + % This work consists of the files pig.dtx and pig.ins + % and the derived file pig.sty. + +Given such a notice and statement in a file, the conditions +given in this license document would apply, with the `Work' referring +to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being +generated from `pig.dtx' using `pig.ins'), the `Base Interpreter' +referring to any `LaTeX-Format', and both `Copyright Holder' and +`Current Maintainer' referring to the person `M. Y. Name'. + +If you do not want the Maintenance section of LPPL to apply to your +Work, change `maintained' above into `author-maintained'. +However, we recommend that you use `maintained', as the Maintenance +section was added in order to ensure that your Work remains useful to +the community even when you can no longer maintain and support it +yourself. + +Derived Works That Are Not Replacements +--------------------------------------- + +Several clauses of the LPPL specify means to provide reliability and +stability for the user community. They therefore concern themselves +with the case that a Derived Work is intended to be used as a +(compatible or incompatible) replacement of the original Work. If +this is not the case (e.g., if a few lines of code are reused for a +completely different task), then clauses 6b and 6d shall not apply. + + +Important Recommendations +------------------------- + + Defining What Constitutes the Work + + The LPPL requires that distributions of the Work contain all the + files of the Work. It is therefore important that you provide a + way for the licensee to determine which files constitute the Work. + This could, for example, be achieved by explicitly listing all the + files of the Work near the copyright notice of each file or by + using a line such as: + + % This work consists of all files listed in manifest.txt. + + in that place. In the absence of an unequivocal list it might be + impossible for the licensee to determine what is considered by you + to comprise the Work and, in such a case, the licensee would be + entitled to make reasonable conjectures as to which files comprise + the Work. diff --git a/macros/latex/contrib/statrep/README b/macros/latex/contrib/statrep/README new file mode 100644 index 0000000000..0baed44361 --- /dev/null +++ b/macros/latex/contrib/statrep/README @@ -0,0 +1,186 @@ +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 diff --git a/macros/latex/contrib/statrep/doc/images/Thumbs.db b/macros/latex/contrib/statrep/doc/images/Thumbs.db Binary files differnew file mode 100644 index 0000000000..feb1fb04eb --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/Thumbs.db diff --git a/macros/latex/contrib/statrep/doc/images/default.png b/macros/latex/contrib/statrep/doc/images/default.png Binary files differnew file mode 100644 index 0000000000..8bfff57cc5 --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/default.png diff --git a/macros/latex/contrib/statrep/doc/images/example_output.png b/macros/latex/contrib/statrep/doc/images/example_output.png Binary files differnew file mode 100644 index 0000000000..010af4c137 --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/example_output.png diff --git a/macros/latex/contrib/statrep/doc/images/htmlblue.png b/macros/latex/contrib/statrep/doc/images/htmlblue.png Binary files differnew file mode 100644 index 0000000000..a67acf037a --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/htmlblue.png diff --git a/macros/latex/contrib/statrep/doc/images/journal.png b/macros/latex/contrib/statrep/doc/images/journal.png Binary files differnew file mode 100644 index 0000000000..b012f55cac --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/journal.png diff --git a/macros/latex/contrib/statrep/doc/images/listing.png b/macros/latex/contrib/statrep/doc/images/listing.png Binary files differnew file mode 100644 index 0000000000..d81f91cefc --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/listing.png diff --git a/macros/latex/contrib/statrep/doc/images/sasuniv1.png b/macros/latex/contrib/statrep/doc/images/sasuniv1.png Binary files differnew file mode 100644 index 0000000000..00389bd602 --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/sasuniv1.png diff --git a/macros/latex/contrib/statrep/doc/images/statistical.png b/macros/latex/contrib/statrep/doc/images/statistical.png Binary files differnew file mode 100644 index 0000000000..f6f5c7a06c --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/statistical.png diff --git a/macros/latex/contrib/statrep/doc/images/vm1.png b/macros/latex/contrib/statrep/doc/images/vm1.png Binary files differnew file mode 100644 index 0000000000..e126ac6c6b --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/vm1.png diff --git a/macros/latex/contrib/statrep/doc/images/vm2.png b/macros/latex/contrib/statrep/doc/images/vm2.png Binary files differnew file mode 100644 index 0000000000..274ebcb3a7 --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/vm2.png diff --git a/macros/latex/contrib/statrep/doc/images/vm3.png b/macros/latex/contrib/statrep/doc/images/vm3.png Binary files differnew file mode 100644 index 0000000000..1f57fbe067 --- /dev/null +++ b/macros/latex/contrib/statrep/doc/images/vm3.png diff --git a/macros/latex/contrib/statrep/doc/quickstart.tex b/macros/latex/contrib/statrep/doc/quickstart.tex new file mode 100644 index 0000000000..4cf527ff1c --- /dev/null +++ b/macros/latex/contrib/statrep/doc/quickstart.tex @@ -0,0 +1,176 @@ +\documentclass{article} +\usepackage{statrep} +\usepackage{parskip,xspace} +\newcommand*{\Statrep}{\mbox{\textsf{StatRep}}\xspace} +\newcommand*{\Code}[1]{\texttt{\textbf{#1}}} +\newcommand*{\cs}[1]{\texttt{\textbf{\textbackslash#1}}} +\setcounter{secnumdepth}{0} +\title{Example and Tutorial for the \Statrep Package} +\author{Tim Arnold and Warren F. Kuhfeld\\SAS Institute Inc., Cary, NC} +\date{April 25, 2012} +\begin{document} +\maketitle +\section{Introduction} +This article provides an example and a +tutorial that show how to use the \Statrep \LaTeX\ package. +For complete details +see the \emph{\Statrep User's Guide} that accompanies the +package (\Code{statrepmanual.pdf}). The package is available +for download at \texttt{http://support.sas.com/StatRepPackage}. + +When you use the \Statrep \LaTeX\ package, you use the following +four-step process to create an executable document that +enables you to ensure that your research results are reproducible: +\begin{enumerate} +\item Create your \LaTeX\ document so that it contains your text, +data, and SAS code. + +\item Compile your document with pdf\LaTeX\ to generate the SAS +program. + +\item Execute the SAS program to capture your output. For each +code block in your document, SAS creates a SAS Output Delivery System (ODS) +document that contains the resulting output. + +For each output request in your document, SAS replays the +specified output objects to external files. All your +requested output is generated and captured when you execute +the generated SAS program. + +\item Recompile your \LaTeX\ document. In this step, the +requested outputs are embedded in the resulting final PDF document. + +You might need to repeat this step so that \LaTeX\ can measure the +listing outputs to ensure that they are framed appropriately. +\end{enumerate} + +\section{Step 1: Create Your \LaTeX\ Document} +This article provides you with an example \LaTeX\ document +already created as in step 1. + +The purpose of the \Code{Datastep} environment is to read in data. +It produces no output. + +The SAS statements in the \Code{Datastep} environment create a new data set +called \Code{Wine}. The \Code{first=} and \Code{last=} options specify that +only a portion of the data set be displayed. + +...descriptive text that introduces data... + +\begin{Datastep}[first=5, last=3] +data Wine; + input WineType $ VisitLength @@; + datalines; +white 80 white 98 white 115 white 89 white 103 +white 91 white 119 white 31 white 109 white 95 +white 71 white 105 white 66 white 141 white 79 +white 113 white 69 white 120 white 87 red 93 +red 87 red 106 red 76 red 121 red 143 +red 81 red 97 red 74 red 107 red 112 +red 67 red 107 red 72 red 116 red 99 +red 104 red 91 red 132 red 78 red 107 +red 101 red 92 +; +\end{Datastep} + +The purpose of the \Code{Sascode} environment is to generate output. +The statements in the following \Code{Sascode} environment perform an +analysis that uses the ANOVA procedure (PROC ANOVA). +You use the \Code{store=} option so that +later in your document +you can refer to output that is created in the \Code{Sascode} +environment. +In this example, all output that is generated by the analysis is stored in the ODS document +\Code{wineA}. + +...descriptive text that introduces the analysis... + +\begin{Sascode}[store=wineA] +ods graphics on; +proc anova data=Wine; + class WineType; + model VisitLength = WineType; +run; +ods graphics off; +\end{Sascode} +The \cs{Listing} and \cs{Graphic} tags specify the output to be displayed. +The purpose of the \cs{Listing} tag is to display tabular output and notes. +The purpose of the \cs{Graphic} tag is to display graphical output. + +...descriptive text that introduces output... + +The \cs{Listing} tag selects three output tables from the \Code{wineA} ODS document: +\Code{ClassLevels}, \Code{NObs}, and \Code{OverallANOVA} + +\Listing[store=wineA, + objects=ClassLevels NObs OverallANOVA, + caption={Analysis of Variance for Visit Length}]{tsta} + +The \cs{Graphic} tag selects the \Code{BoxPlot} +graph from the \Code{wineA} ODS document. + +...descriptive text that introduces the graph... + +\Graphic[store=wineA, + objects=BoxPlot, +caption={Box Plots for Visit Length}]{tstb} + + +\section{Step 2: Compile Your Document} + +You can compile your document as follows from the command line: +\begin{verbatim} + pdflatex quickstart.tex +\end{verbatim} + +If you use a \LaTeX-aware editor, such as \TeX works, you can use it to +compile your document. + +In either case, when you compile your document, the +\Statrep system produces a PDF file and generates a SAS program. + +\textbf{Note:} The requested output is missing after the first compile step. +(This is normal at this step.) + +\section{Step 3: Execute the SAS Program} + +Open the generated SAS program \Code{quickstart\_SR.sas} in a +SAS session. From the SAS main menu, select +\textsf{Run}$\rightarrow$\textsf{Submit}. + +In this step, SAS generates the results that are requested in your document. +By default, tabular output files are created in the `lst' subdirectory and +graphic output files are created in the `png' subdirectory. + +\section{Step 4: Recompile Your \LaTeX\ Document} + +The last step is to recompile your document with pdf\LaTeX. +As in the first compilation, you can use a \LaTeX-aware editor such +as \TeX works, or you can use the \Code{pdflatex} command in a terminal window. + +In this recompilation step, the outputs that are captured by the SAS program +are included in the final PDF document. + +\section{Conclusion} + +When you generate +the SAS program by compiling your document with pdf\LaTeX, +the \Statrep package does the following: +\begin{itemize} +\item The lines in the \Code{Datastep} environment are passed unchanged to the program. +\item The lines in the \Code{Sascode} environment are parsed for line commands and passed +to the program. +\item Each \cs{Listing} tag selects the specified notes and tables. + +\item Each \cs{Graphic} tag selects the specified graphs. + +\end{itemize} + +When you execute the generated SAS program, the output that is +specified in the \cs{Listing} and \cs{Graphic} +tags is automatically captured. + +When you recompile your \LaTeX\ document, the \cs{Listing} and \cs{Graphic} tags +insert the requested SAS results and page breaks are handled automatically. + +\end{document} diff --git a/macros/latex/contrib/statrep/doc/statrep.pdf b/macros/latex/contrib/statrep/doc/statrep.pdf Binary files differnew file mode 100644 index 0000000000..bf87bbf8ab --- /dev/null +++ b/macros/latex/contrib/statrep/doc/statrep.pdf diff --git a/macros/latex/contrib/statrep/doc/statrepmanual.pdf b/macros/latex/contrib/statrep/doc/statrepmanual.pdf Binary files differnew file mode 100644 index 0000000000..8960bc852e --- /dev/null +++ b/macros/latex/contrib/statrep/doc/statrepmanual.pdf diff --git a/macros/latex/contrib/statrep/doc/statrepmanual.tex b/macros/latex/contrib/statrep/doc/statrepmanual.tex new file mode 100644 index 0000000000..723fbb6a5d --- /dev/null +++ b/macros/latex/contrib/statrep/doc/statrepmanual.tex @@ -0,0 +1,2978 @@ +\documentclass[article,oneside]{memoir} +\usepackage[T1]{fontenc} +\usepackage{mathptmx,upquote,alltt} +\IfFileExists{helvet.sty}{\usepackage[scaled=0.92]{helvet}}{\relax} +\IfFileExists{couriers.sty}{\usepackage[scaled=0.95]{couriers}}{\relax} +\usepackage{float,graphicx,xspace,framed,xcolor} +\definecolor{shadecolor}{rgb}{0.97,0.97,0.97} +\definecolor{lightblue}{rgb}{0.93,0.95,1.0} +\definecolor{darkblue}{rgb}{0,0,0.6} +\definecolor{darkred}{rgb}{0.6,0,0} +\setlength{\parindent}{0pt} +\nonzeroparskip +\usepackage[ + bookmarks=true, + hyperindex = true, + pdfpagemode = useoutlines, + pdfpagelabels = true, + plainpages = false, + colorlinks = true, + linkcolor=darkblue, + filecolor=darkblue, + citecolor=darkblue, + urlcolor=darkblue, +]{hyperref} +\usepackage{attachfile} +\usepackage{memhfixc} +\raggedbottom +\hyphenation{StatRep} +\chapterstyle{article} +\DeclareTextFontCommand{\Code}{\ttfamily} +\newcommand*{\StatRep}{\textsf{StatRep}\xspace} +\newcolumntype{P}[1]{>{\raggedright\arraybackslash}p{#1}} +\setlength{\FrameSep}{1pt} +\title{The \StatRep System for Reproducible Research} +\author{Tim Arnold and Warren F. Kuhfeld\\SAS Institute Inc.} +\makeindex +\begin{document} +\maketitle +\tableofcontents*%\listoftables\listoffigures +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\part{User's Guide} +\chapter{Synopsis} +The \StatRep system consists of a \LaTeX\ package and a suite of SAS macros that +support SAS users who want to create documents with reproducible results. + +The \LaTeX\ package 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 +(\Code{Datastep} and \Code{Sascode}) display SAS code. +The two tags (\cs{Listing} and \cs{Graphic}) display SAS output. + +The generated SAS program includes calls to the \StatRep macros that use the SAS +Output Delivery System (ODS) document to capture the output as external files. +These SAS macros are included in the package file \Code{statrep\_macros.sas}. + +The \StatRep package is available at \url{http://support.sas.com/StatRepPackage} + +By default, \StatRep displays SAS output tables as generated by the ODS Listing +destination; that is, the output tables are displayed as plain text. However, you can +specify that \StatRep display \LaTeX\ outputs, generated by SAS, instead +(see appendix \ref{latexoutput} for details). + +You can use \StatRep with a standalone SAS installation on your PC, or you can use it +in conjunction with \textbf{SAS Studio} and \textbf{SAS University Edition} +(see appendix \ref{sasstudio} for details). + +Bundled with the \StatRep package is the \Code{longfigure} package for +multipage figures. +You can use the \Code{lonfigure} package in other \LaTeX\ documents. + +The \StatRep system was designed to be flexible enough to support serious publishing systems. +It can handle many different situations and it is very customizable. +This document +covers all aspects of \StatRep; however, for most users, the \textit{User's Guide} portion +will suffice. For those who need more advanced techniques and customization, please see the +\textit{Reference Manual}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Introduction} + +At the end of a research project, one of the most difficult tasks remains: documentation. +The task is especially difficult with computational research because you +must ensure that the displayed program code works as expected and exactly produces the +displayed output. + +The \StatRep package, a single-source document system, +is an open-source software project that you can use for your own research documentation +to ensure that the results you display can easily be reproduced by your readers. +The \StatRep package is based on the \LaTeX\ typesetting system. You write your paper using +both the usual \LaTeX\ markup and the customizations and SAS macros that this package provides. +The system reads the code and markup from the single source (your document) and creates a +SAS program. This automatically generated SAS program produces the results that are displayed +in your document. + +Comparable projects such as Sweave (Leisch 2002) and SASweave (Lenth 2007) +address the problem of reproducibility through the use of a special intermediate language. +Although similar in spirit to those systems, \StatRep differs in that it is a +normal \LaTeX\ package; no special steps are needed to create the \LaTeX\ +file or the SAS program. In addition, \StatRep provides both a complete, customizable system for +automatic handling of multiple outputs and page breaking and an easy-to-use, +flexible method for output selection. + +When you use the \StatRep \LaTeX\ package, you follow a four-step process to +create an executable document that enables you to create +reproducible research results: +\begin{enumerate} +\item Create your \LaTeX\ source file so that it contains your text, data, and SAS code. + +\item Compile the document with pdf\LaTeX. You can use a LaTeX-aware + editor such as \TeX works, or you can use the command-line command \Code{pdflatex}. + This step generates the SAS program that is needed to produce the results. + If the name of your document is \textit{myarticle.tex}, the name of the generated SAS + program is \textit{myarticle\_SR.sas} by default. + +\item Execute the SAS program to capture your output. + +During execution of the SAS program, for each code block in your document, +SAS creates a SAS Output Delivery System (ODS) document that contains the resulting output. +For more information about ODS documents, see the +\textit{SAS Output Delivery System User's Guide}. +For each output request (the included \cs{Listing} and \cs{Graphic} tags) in your document, SAS replays the specified output objects +to external files. All of your requested output is generated and captured when you +execute the generated SAS program. + +\item Recompile the document with pdfLaTeX. This step compiles your + document to PDF, this time including the SAS results + that are generated in the preceding step. + + In some cases listing outputs may not be framed properly after this step. + If your listing outputs are not framed properly, repeat this step so that + LaTeX can remeasure the listing outputs. + +\end{enumerate} + +When you need to make a change in your data or SAS code, you make the change in +one place (the \LaTeX\ source file) and repeat steps 2 through 4. +Your changes are automatically displayed in your code and in your results. +You perform the steps only as needed---when you change your data or code. + +You can share your \LaTeX\ source with colleagues and be sure that your results +are reproducible. Any SAS user can reproduce your analysis with your \LaTeX\ document +and the supplemental files that are described in this manual. + +\section{Requirements for the \StatRep Package} +\index{package!requirements} +To use the \StatRep package, you need SAS 9.2 or later, +the \LaTeX\ typesetting system +(the pdf\LaTeX\ typesetting engine must be version 1.30 or later), and the \StatRep package itself. + +For complete step-by-step instructions for installation, see appendix \ref{install}. + +\section{Package Usage} +\index{package!usage} + To use the \StatRep package, include it in your document preamble after you + declare the \Code{documentclass}. + Figure \ref{fig:usage} displays an example of how you can use the \StatRep package. + +\begin{figure}[H] +\begin{shaded} +\begin{verbatim} +\documentclass{book} +\usepackage[figname=output,resetby=chapter]{statrep} +\end{verbatim}% +\end{shaded} +\caption{Example of Using the \StatRep Package}\label{fig:usage} +\end{figure} + + The \StatRep package supports the following options:\index{package!options} + \begin{itemize} + \item \Code{color} specifies color support for SAS output tables. + This option is only used in conjunction with + the ODS LaTeX tagset (see appendix \ref{latexoutput}). + + \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.\index{figure names}\index{figname option} + + \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.\index{resetby= option} + \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, which + is provided with the \StatRep package. + The \Code{longfigure} package + supports display and page breaking within a stream of outputs, and it can be + used independently of the \StatRep package. See chapter{longfigure} for +more information. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Getting Started}\label{gs} + +This section provides a simple example of how you can use the \StatRep package +to produce a document with reproducible results. +You can follow along with the actual code: extract this +\textattachfile[color=0 0 0.6]{example.tex}{example \LaTeX\ file} that +contains the code in this section if your PDF viewer supports file annotations. + + Two code environments + (\Code{Datastep}, shown in Figure \ref{fig:d1}, and + \Code{Sascode}, shown in Figure \ref{fig:s1}) + and two output tags + (\cs{Listing} and \cs{Graphic}, shown in Figure \ref{fig:slg}) + are used to generate a SAS program that produces + the necessary output files. + + The code from the \Code{Datastep} environment is passed unchanged to the + generated SAS program.\index{Datastep environment} +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Datastep} +proc format; + value $sex 'F' = 'Female' 'M' = 'Male'; +data one; + set sashelp.class; + format sex $sex.; +run; +\end{Datastep} +\end{verbatim} +\end{snugshade} +\caption{Example of \texttt{Datastep} Environment}\label{fig:d1} +\end{figure} + + The code in the \Code{Sascode} environment is parsed by the \StatRep package before it is + written to the generated SAS program.\index{Sascode environment} + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[store=class] +proc reg; + model weight = height age; +run; +\end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Example of \texttt{Sascode} Environment}\label{fig:s1} +\end{figure} + + The \cs{Listing} and \cs{Graphic} tags convey information to \LaTeX\ and to SAS. + The tags specify the names of the output files to insert into the document + and the captions for the output. + Additionally, the tags specify the names of the output files to + create and they can specify which + ODS objects to capture. In this example, no objects are specified so all + objects are captured. + \index{Listing tag}\index{Graphic tag}% + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\Listing[store=class, + caption={Regression Analysis}]{rega} + +\Graphic[store=class, scale=0.9, + caption={Graphs for Regression Analysis}]{regb} +\end{verbatim} +\end{snugshade} +\caption{Example of \texttt{Listing} and \texttt{Graphic} Tags}\label{fig:slg} +\end{figure} + + Figure \ref{fig:sgp} shows the SAS code that is generated + from the preceding \LaTeX\ source when you compile the document. + +\begin{figure}[H] +\begin{framed} +\begin{snugshade} +{\hfil\emph{generated from }\textbf{Datastep Block}\hfil} +\begin{verbatim} +proc format; + value $sex 'F' = 'Female' 'M' = 'Male'; +data one; + set sashelp.class; + format sex $sex.; +run; +\end{verbatim} +\end{snugshade} +\begin{snugshade} +{\hfil\emph{generated from }\textbf{Sascode Block}\hfil} +\begin{verbatim} +%output(class) +proc reg; + model weight = height age; +run; +%endoutput(class) +\end{verbatim} +\end{snugshade} +\begin{snugshade} +{\hfil\emph{generated from }\textbf{Listing \& Graphic Tags}\hfil} +\begin{verbatim} +%write(rega,store=class,type=listing) + +%write(regb,store=class,type=graphic) +\end{verbatim} +\end{snugshade} +\end{framed} +\caption{Generated SAS Code}\label{fig:sgp} +\end{figure} + + When you generate the SAS program by compiling your \LaTeX\ document, + the lines in the \Code{Datastep} environment are passed unchanged to the program + and + the lines in the \Code{Sascode} + environment are wrapped between two SAS macros (\Code{\%output} and \Code{\%endoutput}), + whose definitions accompany this package (\texttt{statrep\_macros.sas}). + \index{statrep\_macros.sas}\index{SAS macros!output}\index{SAS macros!endoutput} + The macros and their options are discussed in detail in section \ref{macros}. + + The \cs{Listing} tag results in a call to the \Code{\%write} macro that selects all notes and tables from the ODS document.\index{SAS macros!write} + The \cs{Graphic} tag results in a call to the \Code{\%write} macro that selects all graphs from the ODS document. + + When you execute the generated SAS program that is displayed + in Figure \ref{fig:sgp}, the SAS results created in the \Code{Sascode} block are contained + in the ODS document \Code{class}. The \Code{\%write} macro writes the requested results from the ODS document + to the specified + external files. + + When you compile your \LaTeX\ document again, the \cs{Listing} and \cs{Graphic} tags + insert the requested SAS results, handling page breaks automatically. + + The first listing in the example document is shown in Figure \ref{exfig}. +\definecolor{shadecolor}{rgb}{0.93,0.95,1.0} + +\begin{figure}[H] +\caption{Example listing output}\label{exfig} +\begin{snugshade} +\centering +\includegraphics[width=0.8\textwidth]{images/example_output} +\end{snugshade} +\end{figure} + +\definecolor{shadecolor}{rgb}{0.97,0.97,0.97} + +By default, \StatRep generates listing output from the +SAS ODS Listing destination. The preceding figure provides an example +of how the SAS output is displayed in your LaTeX document. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Syntax} + + The \StatRep package provides two environments and two tags that work + together to display your SAS code and results and generate the SAS program + that produces those results. + + The environments: + \begin{itemize} + \item The \Code{Datastep} environment contains SAS code blocks that produce no output. + Its purpose is to read in data. + \item The \Code{Sascode} environment contains SAS code that generates output to be + captured. It supports line-based commands to identify + code lines that should only be displayed, only passed to the generated program, + or both displayed and passed to the generated program. + \end{itemize} + + The tags: + \begin{itemize} + \item The \cs{Listing} tag provides information to the generated program about + which tabular SAS output should be captured. + It also provides information to \LaTeX\ about how that output should be displayed. + \item The \cs{Graphic} tag provides information to the generated program about + which graphical SAS output should be captured. + It also provides information to \LaTeX\ about how that output should be displayed. + \end{itemize} + + The environments and tags are described in detail in the following sections. + +\section{Code Environments} + +\subsection{Datastep Environment}\index{Datastep environment} + +The purpose of the \Code{Datastep} environment is to read in data. +It produces no SAS results. + + The \Code{Datastep} contents are passed unchanged to the generated program. + The \Code{Datastep} block is indented by three spaces in the PDF file. + You can adjust the amount that the block is indented; see + section \ref{custom} for details. The block indent is provided automatically so that + your data and program lines can begin in the first column in your \LaTeX\ source. + + Because you begin the \Code{Datastep} data lines in the + first column, formatted or column input statements will work correctly when + pasted into a SAS session.\index{copy and paste}\index{interactive SAS session} + + + Although the purpose of the \Code{Datastep} environment is to read in data, + \index{reading data}% + it can contain any SAS code that does not generate output + to be captured. Additional statements typically include + TITLE and OPTIONS statements and PROC FORMAT steps. See Figure \ref{fig:sd2} + on page \pageref{fig:sd2} for an example. + + +Table \ref{dsopt} summarizes the \Code{Datastep} environment options. +\index{Datastep environment!options} +\index{program option}\index{display option}\index{first= option}\index{last= option}% +\index{fontsize= option} + +\begin{table}[H] +\caption{Commonly Used \Code{Datastep} Environment Options}\label{dsopt} +\begin{tabular}{lP{3.75in}} +\hline +\textbf{Option} & \textbf{Action} \\ +\hline + & By default, all lines are displayed and written to the program. +\\[0.5\baselineskip] +\Code{program} & + Specifies that all lines in the environment + be written to the generated program only + (that is, no lines are displayed). This option is useful when you need + to produce a data set that is not central to the topic being + discussed and does not need to be displayed. +\\[0.5\baselineskip] +\Code{display} & + Specifies that all lines in the environment be displayed + only (that is, no lines are written to the program). This option is + useful when you need to show code fragments that will not run as is or + example code that is not needed + for later output generation. A \Code{Datastep} environment that specifies + the \Code{display} option is similar to a plain \Code{verbatim} environment except + that it is automatically indented when displayed. +\\[0.5\baselineskip] +\Code{first=\textit{n}} & + Specifies that the first \textit{n} lines + in the environment be displayed. The option affects only the displayed + code block. + This option is useful when you have many data lines that do not need to be + displayed, but that must be available to the program. + After the \textit{n}th line is displayed, the following + text line is written in the displayed code block: + \par\texttt{... more data lines ...}\par% + You can specify different text to be used; + see section \ref{custom} for details. +\\[0.5\baselineskip] +\Code{last=\textit{m}} & + Specifies that the last \textit{m} lines + in the environment be displayed. The option affects only the displayed + code block. + This option is used in conjunction with the \Code{first=} option to show + the ending lines of the \Code{Datastep} environment. Without the \Code{first=} + option, the \Code{last=} option has no effect. +\\[0.5\baselineskip] +\Code{fontsize=} & Specifies the \LaTeX\ font size used to display the + code block. For exampe, \Code{fontsize=small} or \Code{fontsize=footnotesize}. +\\ +\hline + +\end{tabular} +\end{table} + +See the section \titleref{dsex} for an example. + + \subsection{Sascode Environment}\index{Sascode environment} + +The purpose of the \Code{Sascode} environment is to generate output. +In addition to the environment options, it supports +line commands that enable you to specify certain lines as display-only or program-only. + + The \Code{Sascode} environment is parsed for line commands, and the appropriate lines are + passed to the program and displayed. The displayed code block is indented by three spaces. + You can adjust the amount the block should be indented; see section \ref{custom} for + details.\index{display option} The block indent is provided + automatically so that your program lines can begin in the first column in your \LaTeX\ source. + + Because all line commands are valid SAS statements, + you can copy \Code{Sascode} blocks and paste them directly + into a SAS session.\index{copy and paste}\index{interactive SAS session} + +Table \ref{scopt} summarizes the \Code{Sascode} environment options. +\index{Sascode environment!options}\index{store= option}\index{program option}% +\index{display option}\index{fontsize= option}% + +\begin{table}[H] +\caption{Commonly Used \Code{Sascode} Environment Options}\label{scopt} +\begin{tabular}{lP{3.75in}} +\hline +\textbf{Option} & \textbf{Action} \\ +\hline +& By default, all lines are displayed and written to the program. \\[0.5\baselineskip] +\Code{store=} & + Specifies the name of the ODS document to contain the SAS output. +\\[0.5\baselineskip] + +\Code{program} & Specifies that all lines in the environment + be written to the program only + (that is, no lines are displayed). This option is useful when you need + to execute code that is not central to the topic being discussed and need not + be displayed. +\\[0.5\baselineskip] +\Code{display} & + Specifies that all lines in the environment + be displayed only (that is, no lines are written to the program). + This option is + useful when you need to show example code + fragments that will not run as is or that are not needed + for later output generation. A \Code{Sascode} environment that specifies + the \Code{display} option is similar to a plain \Code{verbatim} environment except + that it is automatically indented when displayed. +\\[0.5\baselineskip] +\Code{fontsize=} & + specifies the \LaTeX\ font size used to display the + code block (for example, \Code{fontsize=small} or \Code{fontsize=footnotesize}). +\\ +\hline +\end{tabular} +\end{table} + +The \Code{Sascode} environment also supports +a finer degree of control with line-based commands to identify lines that should +be only displayed or only passed to the generated program. + +Table \ref{lcmd} summarizes the line commands you can use in the \Code{Sascode} environment. +\index{Sascode environment!line commands} +\index{program line command}\index{display line command} + +\begin{table}[H] +\caption{\Code{Sascode} Line Commands}\label{lcmd} +\begin{tabular}{lP{3.5in}} +\hline +\textbf{Option} & \textbf{Action} \\ +\hline + \Code{\%* program} \textit{n} \Code{;} & The next \textit{n} lines are only written to + the program and not displayed.\\[0.5\baselineskip] + \Code{\%* display} \textit{n} \Code{;} & The next \textit{n} lines are only displayed + and not written to the program.\\[0.5\baselineskip] + \Code{\%*;} \textit{code line} & The current line is only written to the + program and not displayed.\\ +\hline +\end{tabular} +\end{table} + + The \Code{Sascode} environment is parsed for line commands before being written + to the generated program file. + +See the sections \titleref{scex} and \titleref{scexlc} for examples. + + + By using a combination of environment options and line commands, you have + complete control over the displayed code and the generated program contents. + +\section{Outputs} + \index{SAS ODS outputs}\index{Listing tag}\index{Graphic tag} +The \cs{Listing} and \cs{Graphic} tags specify the outputs to be displayed. +The purpose of the \cs{Listing} tag is to display tabular output and notes. +The purpose of the \cs{Graphic} tag is to display graphical output. + + All figures are centered. If the figure width is narrower than the text block, the + figure is centered with respect to the text block. Otherwise, the figure is + centered with respect to the page. + + The \cs{Listing} and \cs{Graphic} tags support a set of options and have one + mandatory argument, which specifies the filename prefix for the output + to be generated and displayed. + The prefix must be unique; otherwise the output from one example will + overwrite another. + + Furthermore, the prefix must not end in a numeral so that the prefix name does not interfere + with SAS-generated output file names. + 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 options supported by the \cs{Listing} and \cs{Graphic} tags are used by + the \StatRep \LaTeX\ package and by the \StatRep SAS macros. + + The following table lists all options. Subsequent tables provide descriptions + for each option and how it is used in LaTeX and in SAS. +\begin{table}[H] +\caption{Master List of Output Tag Options} + \begin{tabular}{lll} + \toprule + \textbf{Option Name} & \textbf{Used by} & \textbf{Output Tag}\\ + \midrule +\Code{caption=} & LaTeX & Listing, Graphic \\ +\Code{dest=} & LaTeX, SAS & Listing \\ +\Code{dpi=} & SAS & Graphic \\ +\Code{firstobj=} & SAS & Listing, Graphic \\ +\Code{fontsize=} & LaTeX & Listing (ODS Listing destination) \\ +\Code{height=} & SAS & Graphic \\ +\Code{lastobj=} & SAS & Listing, Graphic \\ +\Code{linesize=} & LaTeX, SAS & Listing (ODS Listing destination) \\ +\Code{objects=} & SAS & Listing, Graphic \\ +\Code{options=} & SAS & Listing, Graphic \\ +\Code{pagesize=} & SAS & Listing \\ +\Code{pattern=} & SAS & Listing, Graphic \\ +\Code{scale=} & LaTeX & Graphic \\ +\Code{store=} & LaTeX, SAS & Listing, Graphic \\ +\Code{style=} & SAS & Listing (ODS LaTeX destination), Graphic \\ +\Code{type=} & SAS & Listing, Graphic \\ +\Code{width=} & LaTeX, SAS & Graphic \\ +\bottomrule +\end{tabular} +\end{table} + + \subsection{Options Used by the \textsf{StatRep} \LaTeX\ Package} + \index{Listing tag!options}\index{Graphic tag!options} + The following options are used by the \StatRep \LaTeX\ package. + \index{caption= option}\index{fontsize= option}\index{linesize= option}% + \index{scale= option}\index{store= option}\index{width= option} + + \begin{description} + \item[\Code{caption=}] specifies the caption to use for an output. + + \item[\Code{dest=}] specifies the ODS destination to use for generating the output. + The default value is \Code{listing}. The other possible value is \Code{latex}, which + specifies that Listing output be generated and displayed as LaTeX tables. + + \item[\Code{fontsize=}] specifies the \LaTeX\ font size to use to display an output + (for example, \Code{fontsize=small} or \Code{fontsize=footnotesize}). + + \item[\Code{linesize=}] specifies the line size used to generate and display + \Code{Listing} output. By default, the value is 80 columns. + This specification lasts for the duration of this step. The current line size is + restored at the end. + Typical values are \Code{80}, \Code{96}, or \Code{120}. + + For extremely wide output tables, you can use the \Code{linesize} and \Code{fontsize} + options together (for example, \Code{linesize=120} and \Code{fontsize=scriptsize}). + The \Code{linesize} option affects how SAS captures the table. The \Code{fontsize} + option specifies how \LaTeX\ displays the table.\index{linesize= option}% + \index{fontsize= option}\index{wide output} + + \item[\Code{scale=}] specifies a factor by which to scale a \Code{Graphic} image. + For example, specify \Code{scale=0.5} to scale the image to half its original size, + or specify \Code{scale=2} to scale it to double its original size. + + \item[\Code{store=}] specifies the name of the ODS document that is created in a + \Code{Sascode} environment. When you specify the \Code{store=} option, + the \StatRep package adds the appropriate SAS macro calls to the + generated program. + + \item[width=] specifies the width to generate and display \Code{Graphic} output + The default is 6.4 inches, which is the standard width for ODS graphs. + + \end{description} + + \subsection{Options Passed to the \textsf{StatRep} SAS Macros}\label{sasopts} + \index{SAS macro options} +The \Code{store=}, \Code{linesize=}, and \Code{width=} options described in the previous +section are passed to the \StatRep SAS macros. +\index{dpi= option}\index{firstobj= option}\index{height= option}\index{lastobj= option} +\index{linesize= option}\index{objects= option}\index{options= option} +In addition, the following options are passed to the \StatRep SAS macros: + \begin{description} + + \item[\Code{dest=}] specifies the ODS destination to use for generating the output. + The default value is \Code{listing}. The other possible value is \Code{latex}, which + specifies that Listing output be generated and displayed as LaTeX tables. + + \item[\Code{dpi=}] specifies dots per inch (DPI) to use in generating graphs. + The default is \Code{dpi=300}. A typical alternative is \Code{dpi=100}. + + \item[\Code{firstobj=}] specifies the first data object to capture in an output stream. + All objects after and including the specified object + are displayed, up to the final object + (or optionally up to the object specified in \Code{lastobj=}). + You can use \Code{options=skipfirst} to begin with the object after the one specified in \Code{firstobj=}. + See section \ref{selection} for details. + + \item[\Code{height=}] specifies the height of graphs. The default is 0.75 times the width. + + \item[\Code{lastobj=}] specifies the last data object to capture in an output stream. + All objects starting with the first object + (or optionally the object specified in \Code{firstobj=}) are displayed up to and + including the specified object. + You can use \Code{options=skiplast} to end with the object before the one specified in \Code{lastobj=}. + +\item[\Code{linesize=}] specifies the line size used to generate and display + \Code{Listing} output. By default, the value is 80 columns. + This specification lasts for the duration of this step. The current line size is + restored at the end. + Typical values are \Code{80}, \Code{96}, or \Code{120}. + + \item[\Code{objects=}] specifies a space-separated list of ODS objects to capture + in an output stream. + The names that are used for selection come from the ODS document. + If you specify \Code{objects=}, then you can also specify object breaking rules + (where page breaks can occur). See section \ref{selection} for details. + + \item[\Code{options=}] specifies binary options. Specify one value or a space-separated + list of values (for example, \Code{options=skipfirst skiplast}). + You can specify the following values (the default is \Code{options=autopage}): + + \begin{description} + \item[\Code{autopage}] specifies that the first \cs{Listing} + command or \Code{\%write} macro start a new output stream with + titles, procedure titles, and so on. + Page breaks also occur at other places where the procedure + explicitly sets a page break. The \Code{autopage} value is the default. + See also the \Code{nopage} and \Code{newpage} values. + \index{autopage option} + + \item[\Code{graph}] specifies that only graphs be selected. + You can alternatively specify \Code{type=graph}.\index{graph option} + + \item[\Code{list}] specifies that the contents of the ODS document be listed + in the SAS log. This value does not run PROC DOCUMENT to replay the output.\index{list option} + + \item[\Code{newpage}] specifies that SAS force a new page for the first object. + \index{newpage option} + + \item[\Code{nopage}] suppresses page breaks.\index{nopage option} + + \item[\Code{onebox}] groups all tables, notes, reports, and so on into a + single piece of SAS output. You cannot specify this option to group graphs. + See section \ref{selection} for more information about grouping.\index{onebox option} + + \item[\Code{skipfirst}] modifies the \Code{firstobj=} option so that the first object in the + list is not selected. This enables you to select all objects after the one + specified in \Code{firstobj=}.\index{skipfirst option} + + \item[\Code{skiplast}] modifies the \Code{lastobj=} option so that the last object + in the list is not selected. This enables you to select all objects before + the one specified in \Code{lastobj=}.\label{skiplast}\index{skiplast option} + + \item[\Code{table}] selects all objects + (tables, notes, reports, and so on) except graphs. You can + alternatively specify \Code{type=listing}.\index{table option} + + \end{description} + + \item[\Code{pagesize=}] specifies the page size. The default is the page size currently in effect. + This specification lasts for the + duration of this step. The current page size is restored at the end.\index{pagesize= option} + + If you have not changed the page size, the default page size set by the \StatRep + package is 500. This large page size is the default so that output is generated with + minimal new pages caused by page boundaries. For large tables, you can specify a smaller + page size to force more page breaks. See section \ref{custom} for information about + how to change the \StatRep default. See section \ref{large} for information about how + to use the \Code{pagesize=} option with large tables. + + \item[\Code{pattern=}] provides an optional and additional selection criterion. + Specify part of a path (for example, a group name).\index{pattern= option} + Only objects whose name includes the specified value are selected. + + \item[\Code{store=}] specifies the name of the ODS document that is created in a + \Code{Sascode} environment. When you specify the \Code{store=} option, + the \StatRep package adds the appropriate SAS macro calls to the + generated program.\index{store= option} + + \item[\Code{style=}] specifies the ODS style to use in generating output. + The default is \mbox{\Code{style=Statistical}}. You can change the default style + (for example, to \Code{HTMLBlue}) by inserting the following line into a \Code{Sascode} + or \Code{Datastep} environment:\index{style= option} + +\begin{snugshade} +\begin{verbatim} + *; %let defaultstyle=HTMLBlue; +\end{verbatim} +\end{snugshade} + + This option affects ODS graphs only when used in a \cs{Graphic} tag. + You can specify this option in the \Code{\%output} macro to set the style + for GRSEG graphs (graphs that are produced by legacy SAS/GRAPH + procedures such as the GPLOT, GMAP, and GCHART procedures). + GRSEG graphs are stored in catalogs + and cannot be changed after they are generated. In contrast, + style, DPI, and so on for ODS graphis can be changed after the graph is initially created. + See section \ref{grseg} for more information. + + \item[\Code{type=\emph{listing}|\emph{graph}}] specifies that only listings or + only graphs be selected. + You can alternatively specify \Code{options=table} or \Code{options=graph}. + \item[\Code{width=}] specifies the width to generate and display \Code{Graphic} output + The default is 6.4 inches, which is the standard width for ODS graphs. + + \end{description} + +\chapter{Examples} +\section{Using the Datastep Environment}\label{dsex} +\index{Datastep environment} + Figure \ref{fig:sd2} displays an example \Code{Datastep} environment. The left margin for + the environment is in the first column, which is where the data lines themselves begin. + This ensures that the variables will be read correctly. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Datastep}[first=9, last=3] +title 'Probit Analysis, Newspaper Survey'; +proc format; + value subscrib 1 = 'accept' 0 = 'reject'; +run; +data news; + input sex $ 1-6 age 12-13 subs 18 ; + datalines; +Female 35 0 +Male 45 1 +Female 51 0 +Male 54 1 +Female 35 0 +Female 48 0 +Male 46 1 +Female 46 1 +Male 38 1 +Male 49 1 +Male 50 1 +Female 47 0 +Female 39 0 +Female 45 0 +Male 39 1 +Female 39 0 +Female 52 1 +Male 58 1 +Female 32 0 +Female 35 0 +; +\end{Datastep} +\end{verbatim} +\end{snugshade} +\caption{\texttt{Datastep} Environment with Options}\label{fig:sd2} +\end{figure} + + In Figure \ref{fig:sd2}, the options to the \Code{Datastep} environment specify that only a portion + of the code block be displayed. All lines in the environment are written to the + generated program. + + The option \Code{first=9} specifies that the displayed code + block contain the TITLE, the PROC FORMAT code, and the DATA step block through the + second line of data (the first nine input lines). After these lines, the + following text is displayed:\par\texttt{... more data lines ...} + + The option \Code{last=3} specifies that the displayed code block + will contain the last three lines of the environment. + + Figure \ref{fig:sd3} shows the display resulting from the preceding +\Code{Datastep} environment. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + title 'Probit Analysis, Newspaper Survey'; + proc format; + value subscrib 1 = 'accept' 0 = 'reject'; + run; + data news; + input sex $ 1-6 age 12-13 subs 18 ; + datalines; + Female 35 0 + Male 45 1 + + ... more data lines ... + + Female 32 0 + Female 35 0 + ; +\end{verbatim} +\end{snugshade} +\caption{Displayed \texttt{Datastep} Environment with Options}\label{fig:sd3} +\end{figure} + + +\section{Using the Sascode Environment}\label{scex}\index{Sascode environment} +Figure \ref{sb} displays an example \Code{Sascode} environment. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[store=mdoc] +proc reg data=h38 plots=predictions(X=Year); + model Population = Year Yearsq; +quit; +\end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Sascode Block}\label{sb} +\end{figure} + The code displayed in Figure \ref{sb} contains SAS code that +performs a regression analysis. Because no line commands are given, +the code block is written as-is to the generated SAS program, as shown +in Figure \ref{figsb}. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +%output(mdoc); +proc reg data=h38 plots=predictions(X=Year); + model Population = Year Yearsq; +quit; +%endoutput(mdoc); +\end{verbatim} +\end{snugshade} +\caption{Generated Code from Sascode Block }\label{figsb} +\end{figure} + +\section{Using the Sascode Environment with Line Commands}\label{scexlc} +\index{Sascode environment!line commands} +Figure \ref{sblc} displays an example + \Code{Sascode} environment that contains line commands. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[store=mdoc] + * program 2; +libname mylib 'c:/mylibs'; +filename in1 'h38.ssp'; + * display 2; +libname mylib 'path to your library directory'; +filename in1 'path to data directory/h38.ssp'; +proc reg data=mylib.h38 plots=predictions(X=Year); + model Population = Year Yearsq; +quit; +\end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Sascode Block with Line Commands}\label{sblc} +\end{figure} + The code displayed in Figure \ref{sblc} contains + two line commands that delineate two + specifications for the \Code{libname} and \Code{filename} SAS statements. + The line command \Code{\mbox{\%* program 2;}} specifies that the location-specific + definitions be passed to the generated program, + as shown in Figure \ref{fig:gsblc}. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + output(mdoc); +libname mylib 'c:/mylibs'; +filename in1 'h38.ssp'; +proc reg data=mylib.h38 plots=predictions(X=Year); + model Population = Year Yearsq; +quit; + endoutput(mdoc); +\end{verbatim} +\end{snugshade} +\caption{Generated Code from Sascode Block with Line Commands}\label{fig:gsblc} +\end{figure} + + The line command \Code{\%* display 2;} in Figure \ref{sblc} + specifies that the generic version + of the \Code{libname} and \Code{filename} statements be displayed, + as shown in Figure \ref{dsblc}. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + libname mylib 'path to your library directory'; + filename in1 'path to data directory/h38.ssp'; + proc reg data=mylib.h38 plots=predictions(X=Year); + model Population = Year Yearsq; + quit; +\end{verbatim} +\end{snugshade} +\caption{Displayed Code from Sascode Block with Line Commands}\label{dsblc} +\end{figure} + +\section{Selecting ODS Objects by Default}\label{odsdefault} +\index{ODS object selection} + + When you use the \cs{Graphic} tag, all graph objects are automatically selected. + When you use the \cs{Listing} tag, all non-graph objects such as tables and notes + are automatically selected. When you use the \Code{\%write} macro, you can specify + the \Code{options=graph} option to select graphs or the \Code{options=table} to + select tables and notes. + + The following statements select all of the tables for the \cs{Listing} + display and all of the graphs for the \cs{Graphic} display: + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[store=docgs1] +ods graphics on; +proc corresp data=PhD short; + var y1973-y1978; + id Science; +run; +\end{Sascode} + +\Listing[store=docgs1, + caption={Inertia and Chi-Square Decomposition}]{crsi1a} + +\Graphic[store=docgs1, + caption={Correspondence Analysis of Ph.D. Data}]{crsi1b} +\end{verbatim} +\end{snugshade} +\caption{Object Selection with the \cs{Listing} and \cs{Graphic} Tags}\label{optionoption} +\end{figure} + + The log information tables display the selected objects for each + block of output. + + The first information table corresponds to the ODS selection that is produced + by the \cs{Listing} tag. All ODS objects of type `Table' are + selected (more precisely, all objects that are not of type `Graph'). + Each object is contained in its own selection group, so + a page break might occur between any of the tables. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + Objects Type Status Group + + Corresp.Inertias Table Selected 1 + Corresp.Rows.RowCoors Table Selected 2 + Corresp.Columns.ColCoors Table Selected 3 + Corresp.Configuration.ConfigPlot Graph . +\end{verbatim} +\end{snugshade} +\caption{SAS Log Information Table from the Listing Tag}\label{loglstinfo} +\end{figure} + + The second information table corresponds to the ODS selection that is produced + by the \cs{Graphic} tag. The single ODS object of type `Graph' is + selected. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + Objects Type Status Group + + Corresp.Inertias Table . + Corresp.Rows.RowCoors Table . + Corresp.Columns.ColCoors Table . + Corresp.Configuration.ConfigPlot Graph Selected 1 +\end{verbatim} +\end{snugshade} +\caption{SAS Log Information Table from the Graphic Tag}\label{loggraphinfo} +\end{figure} + + +\section{Specifying and Capturing ODS Objects by Name} +\index{ODS object selection} + To capture particular ODS objects or ODS group output, you + must specify the appropriate names in the \cs{Listing} tag, + the \cs{Graphic} tag, or the \Code{\%write} macro. + The options that support specific ODS names are + the \Code{pattern=}, + \Code{firstobj=}, \Code{lastobj=}, or \Code{objects=} options. + + If an object appears more than once in a particular ODS document + (which typically means in one \Code{Sascode} block), you must specify additional + name levels to differentiate the objects. The log information table + displays the fully qualified ODS names; you use the information from + the log to specify the appropriate name for the ODS objects to capture. + + For example, if there are multiple residual panels, + you must specify the additional level to select a particular + ODS object. + +\begin{snugshade} +\begin{verbatim} + objects=residualplot +\end{verbatim} +\end{snugshade} +\begin{snugshade} +\begin{verbatim} + objects=residualplot\#2 +\end{verbatim} +\end{snugshade} + + \textbf{Note:} When you have a pound character (\#) in a pattern or object name, + you must escape it in \LaTeX\ tags. The pound character is a special \LaTeX\ control + character and must be escaped with a backslash. + In other words, specify \Code{Group\textbackslash{}\#2} instead of + \Code{Group\#2} in a \LaTeX\ tag. + Do not escape the \# when you use the \Code{\%write} macro. + + Comparisons are not case sensitive. For example, if you specify \Code{pattern=fit}, + the following objects will be selected if they occur in the output stream: +\begin{snugshade} +\begin{verbatim} +Fit.Population.ANOVA +MODEL1.Fit.Population.ANOVA +Reg.MODEL1.Fit.Population.ANOVA +reg#1.model1#1.fit#1.population#1.anova#1 +reg#1.model1.fit.population#1.anova#1 +reg.model1.fit.population.anova +\end{verbatim} +\end{snugshade} + + Typically\footnote{When deciding on names to specify, be sure to consult the table of names + from the ODS document that appears in the SAS log. It contains the proper pattern + of \# characters. See Figure \ref{loginfo} for an example.}, + you need only to specify the last level of an ODS name. + For example, for one model and one ANOVA table, + all of the following specifications for the ANOVA object are equivalent. + +\begin{snugshade} +\begin{verbatim} + anova + ANOVA + ANOVA\#1 + Fit.Population.ANOVA + MODEL1.Fit.Population.ANOVA + Population.ANOVA + Reg.MODEL1.Fit.Population.ANOVA + reg.model1.fit.population.anova + reg\#1.model1.fit.population\#1.anova\#1 + reg\#1.model1\#1.fit\#1.population\#1.anova\#1 +\end{verbatim} +\end{snugshade} + + When you run the SAS program that is generated by the \StatRep package, + the SAS log contains a table with information about each ODS object. + For example, Figure \ref{capturelist} shows a \Code{Sascode} environment that + is parsed and written to the generated SAS program when the \LaTeX\ document + is compiled. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[store=Ex31] +proc probit data=news; + class subs sex; + model subs=sex age / d=logistic itprint; +run; +\end{Sascode} + +\Listing[store=Ex31, + objects=ClassLevels IterHistory ModelInfo + LastGrad LastHess ParameterEstimates, + caption={Logistic Regression of Subscription Status}]{prb31a} + +\end{verbatim} +\end{snugshade} +\caption{Example of Capturing Listing Output}\label{capturelist} +\end{figure} + +The \cs{Listing} tag results in a call to the \Code{\%write} macro in the +automatically generated SAS program. When you execute the program, +the \Code{\%write} macro generates the log information table shown in +Figure \ref{loginfo}. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + Objects Type Status Group + + Probit.IterHistory Table Selected 1 + Probit.ModelInfo Table Selected 2 + Probit.NObs Table . + Probit.ClassLevels Table Selected 3 + Probit.ParmInfo Table . + Probit.ResponseProfile Table . + Probit.Note Note . + Probit.LastGrad Table Selected 4 + Probit.LastHess Table Selected 5 + Probit.ConvergenceStatus Table . + Probit.Type3Analysis Table . + Probit.ParameterEstimates Table Selected 6 +\end{verbatim} +\end{snugshade} +\caption{SAS Log Information Table}\label{loginfo} +\end{figure} + + The table of information displays the fully qualified name for each + generated ODS object, its type, whether it is selected, and its + selection group. + + Page breaks can occur only between + selection groups. You can control the grouping + as described in the section \ref{pagebreak} on page \pageref{pagebreak}. + For example, if you specify +\Code{LastGrad LastHess} as \Code{<LastGrad LastHess>}, + the two tables would be in the same group. + + The order in which objects are created is determined by the + order in which they are generated, not the order in which they are + specified in the \Code{objects=} option. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\part{Reference Manual} +\chapter{Overview} + +The preceding pages should provide the information to use the package +in most scenarios. For more in-depth descriptions and methods for +customization, see the following chapters. + +\begin{description} +\item[Customizing \StatRep] describes several hooks for customizing +the package and setting system-wide defaults. +\item[About the Program Preamble] provides an overview of how the \StatRep +package works with the SAS macros; a special file (the program preamble) +provides a method of communication between the two. +\item[Two Methods of Writing] describes how you can bypass the automatic +code generation and use the \StatRep SAS macros directly. +\item[\StatRep SAS Macros] describe in detail each SAS macro in the +\StatRep package. You can use these macros yourself for maximum flexibility +in creating a custom \StatRep document. +\item[ODS Object Selection] describes how you can use options in the +\cs{Listing} and \cs{Graphic} tag to specify exactly what output you want +to display. +\item[ODS Graphics] describes differences between ODS graphics and +GRSEG graphics. +\end{description} + +\chapter{Customizing \StatRep}\label{custom} + \index{customizing}\index{configuration} + + You can modify the configuration file \Code{statrep.cfg} to change +the following settings used by the \StatRep package. + See section \ref{secdefaults} for more information about macro variable defaults. + + \begin{description} + \item[\cs{SRcaptionfont}] specifies the font for the output captions. + The default is \cs{sffamily} (\textsf{sans serif}). + \index{caption font} + + \item[\cs{SRcaptioncontinuedfont}] specifies the font for the \Code{continued} name + for outputs that break across pages. + The default is \cs{sffamily}\cs{itshape} (\textsf{\textit{sans serif, italic}}). + + \item[\cs{SRcontinuedname}] specifies the name that indicates that an output + block is continued. The name is used when an output stream breaks across a page. + The default is \Code{continued}. + + \item[\cs{SRdefaultdests}] specifies the default ODS Destination for tabular + outputs. The default is \Code{listing}. You can specify \Code{latex} to produce + SAS-generated LaTeX tabular output. See appendix \ref{latexoutput} for details. + \index{LaTeX output} + + \item[\cs{SRdpi}] specifies the default dots per inch (DPI) for SAS to use in generating + graphical output. The default is \Code{300}. + \index{dpi} + + \item[\cs{SRgraphicdir}] specifies the name of the directory that contains the SAS + generated graphical output files. The default is \Code{png}. + \index{graphic directory} + + \item[\cs{SRgraphtype}] specifies the format of the SAS + generated graphical output. You can specify either + \Code{png} or \Code{pdf}. The default is \Code{png}. + \index{graphics type}\index{PNG graphics}\index{PDF graphics} + + \item[\cs{SRlatexdir}] specifies the name of the directory that contains the + SAS generated LaTeX tabular output. The default is \Code{tex}. + See appendix \ref{latexoutput} for details. + + \item[\cs{SRlatexstyle}] specifies the ODS style for SAS to use to generate + LaTeX tabular output. The default is \Code{statrep}, a monochromatic style based + on the \Code{statistical} ODS style. + See appendix \ref{latexoutput} for details. + + \item[\cs{SRodsgraphopts}] specifies a string that is passed as + ODS GRAPHICS statement options. For a complete explanation of all available options, + see the documentation of the ODS GRAPHICS statement in + \textit{SAS Output Delivery System: User's Guide}. + \index{ODS graphics options} + + \item[\cs{SRintertext}] specifies the text to insert in + \Code{Datastep} environments that specify + the \Code{first=} option. The default is \Code{\mbox{... more data lines ...}} + + \item[\cs{SRlinesize}] specifies the default line size to use in generating tabular + output and centering it for display. The default is \Code{80}. + \index{output width}\index{linesize} + + \item[\cs{SRlistingdir}] specifies the name of the directory that contains the SAS + generated listing (tabular) output files. The default is \Code{lst}. + + \item[\cs{SRmacropath}] specifies the path to the location of the + SAS macros that are bundled with the \Code{StatRep} package. + \index{SAS macro location} + For example, if you installed the \Code{statrep\_macros.sas} file to a directory named + \Code{C:\textbackslash mymacros}, + then define macro \cs{SRmacropath} as follows: + \begin{verbatim} + \def\SRmacropath{c:/mymacros/statrep_macros.sas} + \end{verbatim} + + Use the forward slash in the definition + as the directory name delimiter instead of the backslash, which is a special + character in \LaTeX. If you want to use a backslash character (\textbackslash), you + must insert it with the \LaTeX\ command, \cs{@backslashchar}. + + The default value is the current path. That is, the default + definition for the \cs{SRmacropath} macro is the filename itself, \Code{statrep\_macros.sas}. + + \item[\cs{SRmacroinclude}] specifies the line used in the generated SAS program to + include the SAS macros that are bundled with the \Code{StatRep} package. + The default is\\\Code{\%include }\cs{SRmacropath}~\Code{/nosource;} + + \item[\cs{SRpagesize}] specifies the default page size for SAS to use in generating + tabular output. The default is \Code{500}. + + + \item[\cs{SRparindent}] specifies the amount of space to indent + \Code{Datastep} and \Code{Sascode} environments. + The argument is a dimension. + The default is \Code{3em} and is measured according to the font currently in use. + + \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 macro (from \Code{statrep\_macros.sas}) + that removes the contents of the listing and graphic directories to ensure + that the generated graphs and listings from the SAS program are current. + The directories are created with + each SAS run that includes the macros themselves (via \Code{x} commands). +\begin{snugshade} +\begin{verbatim} + %hostdel; +\end{verbatim} +\end{snugshade} + + \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{SRstyle}] specifies the default ODS style for SAS to use to generate + graphical output. The default is \Code{Statistical}. + \index{ODS output style} + + \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 \Code{sr.tmp}. + + \item[\cs{SRverbfont}] specifies the font to use for code within \Code{Datastep} and + \Code{Sascode} blocks. The default is \cs{ttfamily}\cs{bfseries} + (\texttt{\textbf{typewriter text, bold}}). + \index{verbatim font} + + \end{description} + + \chapter{About the Program Preamble} + +The \StatRep package automatically writes a preamble to the generated program and a preamble file. + +The preamble settings are split into two parts to support users who prefer to +manually write the calls to the \StatRep macros and work interactively between the +\LaTeX\ source document and a SAS session. For this use, you can include the external +preamble file once in your SAS session and all the necessary settings are made for you. + +If you do not manually write calls to the \StatRep macros (you use the default, automated method), +there is nothing you need to do---your generated program contains the lines that specify your settings. + +The preamble in the generated program includes the preamble file and deletes the contents of the +output directories (\Code{lst}, \Code{tex}, and \Code{png}, by default) so that obsolete files are +not included in the document. +Figure \ref{fig:pgmpreamble} shows an example of the preamble lines +that are written to the generated program. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +/* + This file is auto-generated by the statrep package. + Do not edit this file or your changes will be lost. + Edit the LaTeX file instead. + + See the statrep package documentation and the file + statrep.cfg for information on these settings. + */ + + +%include "report_SR_preamble.sas" /nosource; +/* Remove all output files. */ +%hostdel; + +/* Start program with a null title. */ +title; +\end{verbatim} +\end{snugshade} +\caption{Generated SAS Program Preamble}\label{fig:pgmpreamble} +\end{figure} + + The external preamble file sets defaults, includes + the output-capture macros, and creates the output directories if they do not exist. + You can customize the preamble; see section \ref{custom} for details. + Figure \ref{fig:preamble} shows the default file preamble. +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +/* + This file is auto-generated by the statrep package. + Do not edit this file or your changes will be lost. + Edit the LaTeX file instead. + + See the statrep package documentation and the file + statrep.cfg for information on these settings. + */ + + +/* Set and invoke macro variable defaults. */ +%let defaultlinesize=80; +%let defaultpagesize=500; +%let defaultdpi=300; +%let defaultstyle=statistical; +%let listingdir=lst; +%let graphicdir=png; +%let graphtype=png; +%let odsgraphopts=; +%let latexdir=tex; +%let latexstyle=statrep; +%let defaultdests=listing; + +options nodate nonumber +ls=&defaultlinesize ps=&defaultpagesize +formchar='|----|+|---+=|-/\<>*'; + +ods graphics on; +/* Include SAS macro definitions. */ +%include "statrep_macros.sas" /nosource; + +\end{verbatim} +\end{snugshade} +\caption{Generated Preamble File}\label{fig:preamble} +\end{figure} + +\chapter{Two Methods of Writing} + To maximize flexibility, the \StatRep package provides two methods of writing code in your +\LaTeX\ document. + +When you create your \LaTeX\ document, you can use either the automatic method described in +chapter \ref{gs} (in which the SAS macro calls are generated automatically) or a manual +method (in which you write the \Code{\%output}, \Code{\%endoutput}, and \Code{\%write} macros yourself). + +In the automatic method, each \Code{Sascode} code block generates an \Code{\%output} macro call at the beginning +of the block and an \Code{\%endoutput} macro call at the end of the block. +Each \cs{Listing} and \cs{Graphic} tag generates the \Code{\%write} +macro to replay the selected output objects to external files. + +In the manual method, you decide where and when to make the macro calls. +It is only in this respect that the method is manual: the +\StatRep package still generates your SAS program and displays your code and results. + +The \StatRep package uses + the SAS macro comment (\Code{\%* \emph{comment} ;}) to provide line + commands within a \Code{Sascode} + block. Furthermore, any line of code that begins with a null macro + comment (\Code{\%*;}) + is written to the SAS program and is not displayed. + +You can use the manual method when you want to do one or more of the following: +\begin{itemize} +\item capture specialized or complicated output +\item capture print output with SAS 9.2 (see the \Code{\%startlist} macro in section \ref{startlist}) +\item capture output from the SAS log (see the \Code{\%startlog} macro in section \ref{startlog}) +\item work interactively when writing (you can interactively develop or debug a + certain section of your document by copying code from + your \LaTeX\ document and pasting it into a SAS session) +\end{itemize} + + You can use either method, and you can +mix the methods in a single document. The manual method is provided for cases in which the +automatic method is too inflexible. By using the line commands in a \Code{Sascode} environment, +you are free to write your program as you want, while retaining control of the code that is +displayed in your final PDF document. + + Continuing with example shown in Figure \ref{fig:d1} and Figure \ref{fig:s1}, + you can write the code yourself within your + \LaTeX\ document as shown in Figure \ref{fig:manual} + and obtain the identical code display and capture. + +\begin{figure}[H] +\begin{framed} +\begin{snugshade} +{\hfil\textit{Datastep is identical}\hfil} +\begin{verbatim} +\begin{Datastep} +proc format; + value $sex 'F' = 'Female' 'M' = 'Male'; +data one; + set sashelp.class; + format sex $sex.; +run; +\end{Datastep} +\end{verbatim} +\end{snugshade} +\begin{snugshade} +{\hfil\textit{\texttt{\%output} added manually}\hfil} +\begin{verbatim} +\begin{Sascode} + *; %output(class) +proc reg; + model weight = height age; +run; +\end{verbatim} +\end{snugshade} +\begin{snugshade} +{\hfil\textit{\texttt{\%write} macros added manually}\hfil} +\begin{verbatim} + *; %write(rega, type=listing) + *; %write(regb, type=graphic) +\end{Sascode} +\end{verbatim} +\end{snugshade} +\begin{snugshade} +{\hfil\textit{Listing and Graphic tags only caption and insert output}\hfil} +\begin{verbatim} +\Listing[caption={Regression Analysis}]{rega} +\Graphic[caption={Graphs for Regression Analysis}]{regb} +\end{verbatim} +\end{snugshade} +\end{framed} +\caption{Using the SAS Macros Manually}\label{fig:manual} +\end{figure} + + The \Code{Datastep} environment in Figure \ref{fig:manual} is identical to that shown in the + Figure \ref{fig:d1}. However, the \Code{Sascode} + environment makes an explicit call to the \Code{\%output} macro to create + the ODS document that contains all the results from the code block. + Because this line begins with the null SAS macro comment (\Code{\%*;}), the line + is passed directly to the generated SAS program and is not displayed. + + The \Code{\%endoutput} macro is not necessary when you are processing + only one ODS document. It is implicitly specified by the first \Code{\%write} macro. + + Next are two explicit calls to the \Code{\%write} macro, which + specify the ODS objects to capture and the ODS document that the objects + should be taken from. + Both \Code{\%write} macros use the minimum number of options. + The first \Code{\%write} macro selects all + notes and tables from the last ODS document created. The second \Code{\%write} macro + selects all graphs from the last ODS document created. + Because the \Code{store=} option is omitted in both cases, + output from the most recently created ODS document is displayed. + + Finally, the \cs{Listing} and \cs{Graphic} tags request the outputs. + In + this method, you do not place the options that are related to SAS in the + the \cs{Listing} and \cs{Graphic} tags. You need to + specify only the caption and filename prefix. + + + To summarize, the \Code{Datastep} environment is handled identically in either method, + the \Code{Sascode} environment can optionally produce the \Code{\%output} and \Code{\%endoutput} macros, + and the \cs{Listing} and \cs{Graphic} tags can optionally produce the \Code{\%write} macros. + +\chapter{\StatRep SAS Macros}\label{macros} +\index{SAS macros} + SAS programs created by the \StatRep package + run SAS macros to capture output. The macros depend on the ODS document. + The ODS document is a destination or repository for the results + (tables, notes, titles, and graphs) + that come from SAS procedures. Each procedure step is run only once, + and the results are captured in an ODS document. + Then the parts of the ODS document are replayed using PROC DOCUMENT. + + When \StatRep encounters a \Code{Sascode} environment, + it generates a macro call to create an ODS document from the environment. + When \StatRep encounters a \cs{Listing} or \cs{Graphic} tag, + it generates a macro call to replay output from that ODS document into an external file. + + For the output that is generated in each \Code{Sascode} block, the SAS macros provide you + with a list of all + of the objects in the ODS document and a table that displays + the objects selected for display. You can + review this list in the SAS log. + It is important to check these lists to ensure that either all output + is included somewhere or any omissions are deliberate. + + The following macros are defined: + \begin{itemize} + \item The \Code{\%output} and \Code{\%endoutput} macros open and close an ODS document, respectively. + When you use \StatRep to automatically generate your program, these macros are called at the + beginning and end of a \Code{Sascode} block, respectively. + You can manually call the macros at any time within + a \Code{Sascode} block by prefixing the call with a null SAS macro comment (\Code{\%*;}). + \index{SAS macros!output}\index{SAS macros!endoutput} + + \item The \Code{\%write} macro writes ODS objects that are contained in an ODS document to + one or more external files. + When you use \StatRep to automatically generate your program, this macro is called when + a \cs{Listing} or \cs{Graphic} tag is encountered. You can manually call the macro + at any time within a \Code{Sascode} block by prefixing the call with a null + SAS macro comment (\Code{\%*;}). + \index{SAS macros!write} + + \item The \Code{\%startlist} and \Code{\%endlist} macros capture printed content + (for example, a PROC PRINT or DATA step) to an external file. To use these macros, + you must manually call the macro + within a \Code{Sascode} block and prefix the call with a null + SAS macro comment (\Code{\%*;}). + \index{SAS macros!startlist}\index{SAS macros!endlist} + + \item The \Code{\%startlog} and \Code{\%endlog} macros capture content from the + SAS log to an external file. To use these macros, + you must manually call the macro + within a \Code{Sascode} block and prefix the call with a null + SAS macro comment (\Code{\%*;}). + \index{SAS macros!startlog}\index{SAS macros!endlog} + \end{itemize} + + + \section{The \texttt{\%output} and \texttt{\%endoutput} Macros}\label{outputmacro} + The \Code{Sascode} environment writes the \Code{\%output} and \Code{\%endoutput} macros to + the generated program + whenever the \Code{store=} option is specified. + However, you can call the macros + yourself by omitting the \Code{store=} option in the \Code{Sascode} environment and + call the macros within the \Code{Sascode} environment. Each call must be prefixed + with a null SAS macro comment (\Code{\%*;}). + \index{SAS macros!output}\index{SAS macros!endoutput} + + The \Code{\%output} macro supports two other options (\Code{style=} and \Code{dpi=}) that are used to + set parameters for GRSEG graphs. These options are not supported in the + \Code{Sascode} environment options. If you want to change the style or DPI for + GRSEG graphs, you must call the \Code{\%output} and \Code{\%endoutput} macros manually. + + The following options are supported by the \Code{\%output} macro: + \begin{description} + \item[\Code{store=}] specifies the name of the ODS document. + This name is used in the \Code{store=} option in the \cs{Listing} and \cs{Graphic} tags + or in the \Code{\%write macro}. + + \item[\Code{style=}] specifies the style used for GRSEG graphs. + The default is \Code{HTMLBlue}. See section \ref{grseg} for details. + + \item[\Code{dpi=}] specifies the dots per inch (DPI) setting used for GRSEG graphs. + The default is 300 DPI. See section \ref{grseg} for details. + \end{description} + + + \section{The \texttt{\%write} Macro} + The \Code{\%write} macro supports the same key-value options as the \cs{Listing} and + \cs{Graphic} tags support. + The \StatRep package generates the \Code{\%write} macro in the SAS program + file whenever the \Code{store=} option is specified in the output tag. + However, you can call the macros + yourself by omitting the \Code{store=} option in the \cs{Listing} or \cs{Graphic} + tag and call the macro within a \Code{Sascode} environment. Each call must be prefixed + with a null SAS macro comment (\Code{\%*;}). + \index{SAS macros!write} +See the section \titleref{sasopts} for more information about the options used in the +\cs{Listing} and \cs{Graphic} tags that are passed to the \Code{\%write} macro. + + +\vspace*{1em}\noindent\textbf{Note:} If you use the macros interactively, be aware that +these macros open and close ODS destinations, +enable and disable ODS Graphics, and change ODS options. Output capture uses the +LISTING destination, and when the \Code{\%write} macro finishes, only the +LISTING destination remains open. +If you need other ODS destinations for your work, you need to reset them +when you are done with a section of output capture. For example, +if you are using the HTML destination +in the SAS windowing environment, then you need to +close the LISTING destination and reopen the HTML destination when you finish +capturing output. + + \section{The \texttt{\%startlist} and \texttt{\%endlist} Macros}\label{startlist} + + The \Code{\%startlist} and \Code{\%endlist} macros capture printed information + from the ODS listing destination. The macros are used when + you create output with a procedure that does not support ODS. + They are also used when you use the + \Code{DATA \_NULL\_} and \Code{PUT \_ODS\_} SAS statements to + manually capture output. + \index{SAS macros!startlist}\index{SAS macros!endlist} + + These macros are not automatically generated by the \StatRep package. + You must call them + manually within a \Code{Sascode} environment (with each call preceded + by a null SAS macro comment). + + In SAS 9.2, PROC PRINT is not fully integrated into the ODS document, + unless you specify PROC PRINT with no options. + If you specify PROC PRINT + with options, you must use the \Code{\%startlist} and \Code{\%endlist} + macros to capture output. + + If you use PROC PRINT in SAS 9.3 or later, + you can use the \Code{\%output} and \Code{\%write} macros as you would with + any SAS procedure. + + The \Code{\%startlist} macro has one mandatory argument, the filename prefix + of the file to contain + the output. The argument is also used + in the \cs{Listing} tag to insert the output. + + The \Code{\%startlist} macro supports the following options after + the filename argument, separated with a comma (,): + \begin{description} + \item[\Code{linesize=}] specifies the line size. + The default is the line size currently in effect. + This specification lasts for the duration of this step. + The current line size is restored at the end. + When you specify the \Code{linesize=} option in the \Code{\%startlist} + macro, be sure to make the same specification + in the \cs{Listing} tag you use to insert the output. + + \item[\Code{pagesize=}] specifies the size of the output page. + The default is the page size currently in effect. + This specification lasts for the duration of this step. + The current page size is restored at the end. + This option is useful for breaking up long listings into smaller parts to allow for page breaks. + If a listing output spans more than one SAS page, + the output is automatically split into parts and the page breaks + can occur only between parts of output. + For more information about capturing large outputs, see section \ref{large}. + \end{description} + + \section{The \texttt{\%startlog} and \texttt{\%endlog} Macros}\label{startlog} + + The \Code{\%startlog} and \Code{\%endlog} macros capture SAS notes + or error messages from the SAS log. They also capture output + from some SAS/IML functions that write to the SAS log rather than using ODS. + \index{SAS macros!startlog}\index{SAS macros!endlog} + + These macros are not automatically generated by the \StatRep package. + To capture content from the SAS log, you must call these macros + manually within a \Code{Sascode} environment (with each call preceded + by a null SAS macro comment). + + The \Code{\%startlog} macro has one mandatory argument, the filename prefix + of the file to contain the output. The argument is also used in the \cs{Listing} + tag to insert the output. + + The \Code{\%endlog} macro supports the following options, + separated by a comma (,): + + \begin{description} + \item[\Code{code=}] specifies whether program code in the SAS log is included. + By default, code is captured (\Code{code=1}). Set \Code{code=0} to exclude code. + \item[\Code{range=}] specifies a Boolean expression to select + certain observations. For example, you can specify \Code{range=\_n\_ <= 5 } + to select the first five lines. You can specify + \Code{range=not index(line, 'ERROR')} to select all lines that do not contain the string + `ERROR'. Selection must be based on \Code{\_n\_} or the variable \Code{line}, which + contains a single line of the log. + \end{description} + + \section{Macro Variable Defaults}\label{secdefaults} + \index{macro variables}\index{default settings}\index{package!defaults} + \index{SAS macros!variables} + + The SAS macro defaults are set globally in the file \Code{statrep.cfg}. + See section \ref{custom} for details. You can also reset the + defaults within your document by specifying new settings in a \Code{Sascode} + environment. + + Table \ref{defaults} shows the description and default values for each + macro variable. + + \begin{table}[H] + \centering\caption{Default Values for Macro Variables}\label{defaults} + \begin{tabular}{llP{2.5in}} + \textbf{Macro Variable} & \textbf{Default} & \textbf{Description}\\ + \hline + \Code{defaultlinesize} & 80 & Line size for tabular ODS output\\ + \Code{defaultpagesize} & 500 & Page size for tabular ODS output\\ + \Code{defaultstyle} & Statistical & ODS style for graphical output \\ + \Code{defaultdpi} & 300 & Dots per inch (DPI) for graphical output\\ + \Code{graphtype} & png & graphics file format ('png' or 'pdf')\\ + \Code{odsgraphopts} & & string containing ODS graphics options\\ + \Code{defaultdests} & listing & \texttt{listing} or \texttt{latex} tabular output\\ + \Code{latexstyle} & statrep & ODS Style for SAS-generated LaTeX output\\ + \hline + \end{tabular} + \end{table} + + You can edit the \Code{statrep.cfg} file\index{customizing}\index{statrep.cfg} + \index{configuration}% + to globally reset the defaults, or you can specify commands to change the default anywhere + in your document. For example, the following lines change all of the macro variable + default settings for the duration of the program. The \Code{program} option specifies + that the code be written only to the generated program and not displayed. + + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} + \begin{Sascode}[program] + %let defaultlinesize=96; + %let defaultpagesize=50; + %let defaultstyle=statistical; + %let defaultdpi=100; + %let graphtype=pdf; + %let odsgraphopts=antialiasmax=10000; + \end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Reset SAS Macro Defaults within Document with SAS}\label{reset} +\end{figure} + + When you change the \Code{defaultlinesize} in the \Code{statrep.cfg} file, the same value + is automatically used by SAS and by the \StatRep package. + When you change the \Code{defaultlinesize} inside your document, + you change the line size used by SAS in generating + outputs; You must also set the line size in the \cs{Listing} tag to match. + + The setting of \Code{defaultpagesize=500} produces a large + virtual page so that SAS does not break ODS objects into smaller pieces. + When a stream of outputs is typeset, page breaks can occur only between ODS objects or + when SAS forces a page break inside an ODS table. + + The macro options and default macro variables work as follows: + If an option is specified in a macro, its value is used regardless of + the specification in the default macro variables. + If an option is not specified in a macro, the default macro variables provide + the values. + + In summary, a direct option specification in a macro takes precedence over the default + settings, and you can change the default settings by resetting the + default macro variables + in your document or by editing the \Code{statrep.cfg} file. + + \chapter{ODS Object Selection}\label{selection} +To select and display ODS objects, you specify options in the \cs{Listing} tag, \cs{Graphic} + tag, or the \Code{\%write} macro. +\label{optionopt} +By default, when you omit object selection options, the \Code{\%write} macro selects all ODS objects, +the \cs{Listing} tag selects all ODS tables and notes, and the \cs{Graphic} tag selects all ODS graphs. +\index{ODS object selection} + Table \ref{tabselect} summarizes how you select ODS objects. + \begin{table}[H] + \centering\caption{ODS Object Selection Options}\label{tabselect} + \begin{tabular}{lP{3.75in}} + \textbf{Option} & \textbf{Action}\\ + \hline + \Code{options=table} & Select all tables and notes\\ + \Code{options=graph} & Select all graphs \\ + \Code{pattern=} \textit{pattern} & +Select all objects with a name matching a pattern. +When an ODS object name has more than two levels, + the middle level name is a group name. You can specify the \Code{pattern=} option + to select all ODS objects in the specified ODS group. + More generally, you can specify any pattern to select all objects + whose path contains the pattern.\\ + \Code{firstobj=} & Specifies the first object in the output stream to capture. + The specified and subsequent objects are captured.\\ + \Code{lastobj=} & Specifies the last object in the output stream to capture. +The first object in the stream to capture is the first object produced by the +\Code{Sascode} code block or the object specified in the \Code{firstobj=} option.\\ + \Code{objects=} option & Specifies a space-separated list of objects to capture.\\ + \hline + \end{tabular} + \end{table} + + The \Code{firstobj=} and \Code{lastobj=} options can be modified with the option + \Code{options=skiplast} and \Code{options=skipfirst}. For more information about + how to use these options, + see page \pageref{skiplast}. + + \section{Page Breaks}\label{pagebreak} + By default, a page break can occur between any two objects in the output stream. + However, you can use left and right angle brackets, \Code{<>}, to delineate a + set of objects in which to suppress breaks. + You use the symbols in the \Code{objects=} option list in + a \cs{Listing} tag, a \cs{Graphic} tag, or a \Code{\%write} macro. + + + For example, you can use the symbols to prevent a break between a + ``Parameter Estimates'' table and the ``Fit Statistics'' table that follows it + with the following option: + \Code{objects = < ParameterEstimates FitStatistics >} + + After the \Code{<} symbol, breaking is suppressed until the \Code{>} symbol is encountered. + After the \Code{>} symbol, a break is introduced and normal breaking continues. + + In summary: + \begin{itemize} + \item You can use the \Code{<>} symbols in pairs to keep ODS objects together. + \item You can use the \Code{>} symbol (unpaired with a matching \Code{<}) to create a break between tables. + \item You can use the \Code{<} symbol (unpaired with a matching \Code{>}) to suppress all breaks. + \end{itemize} + + A break is always allowed before and after a graph. + + See page \pageref{skiplast} for an alternate method of controlling breaks + with the \Code{options=nopage} and \Code{options=onebox} options. + + \chapter{ODS Graphics} + \index{ODS graphics} + + In SAS 9.3 and later, ODS Graphics is enabled by default in the SAS windowing environment. + ODS Graphics is not enabled by default in batch mode and in the SAS windowing environment in SAS 9.2. + When ODS Graphics is not enabled by default, you can enable ODS Graphics by specifying the following statement: + +\begin{snugshade} +\begin{verbatim} + ods graphics on; +\end{verbatim} +\end{snugshade} + + +You can enable ODS Graphics in \StatRep for all steps by providing this code block at the +beginning of your LaTeX document: + +\begin{snugshade} +\begin{verbatim} + \begin{Sascode}[program] + ods graphics on; + \end{Sascode} +\end{verbatim} +\end{snugshade} + + \section{ODS Graphics and GRSEG Graphics} + \label{grseg} + \index{ODS graphics}\index{GRSEG graphics} + When you create a graph with ODS Graphics, the style and dots per inch (DPI) can be changed + after the graph is created. The style and DPI are set when the + graph is written to the external file. This enables you to specify the options + in the \cs{Graphic} tag or in the \Code{\%write} macro. + + On the other hand, when you create a GRSEG graph, the style and DPI + are set when the graph is created. That is why you must specify the options + in the \Code{\%output} macro. See section \ref{outputmacro} for details + about the \Code{\%output} macro options. + + Table \ref{tabgraph} summarizes the methods you can use to modify the + style and DPI settings when you create a graph. + + \begin{table}[H] + \centering + \caption{Methods to Change Graph Properties}\label{tabgraph} + \begin{tabular}{lcc} + \textbf{Method} & \textbf{ODS Graph} & \textbf{GRSEG Graph} \\ + \hline + \cs{Graphic} tag options & Yes & No \\ + \Code{\%write} macro options & Yes & No \\ + \Code{\%output} macro options & No & Yes \\ + Reset global default & Yes & Yes \\ + \hline + \end{tabular} + \end{table} + + The \cs{Graphic} tag, the \Code{\%write} macro, and the + \Code{\%output} macro have \Code{style=} and \Code{dpi=} options. For more information + about these options, see section \ref{sasopts}. + Also, see section \ref{secdefaults} for details about + using the SAS macro variables to reset global defaults. + + For GRSEG graphs, there are only two choices for DPI: 300 (the default) and 96. + When the DPI is set to anything other than 300, + then 96 is automatically used instead for GRSEG graphs. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\chapter{Advanced Examples} + + +\section{Capturing PRINT Output}\index{SAS macros!startlist}\index{SAS macros!endlist} + Figure \ref{printoutput} shows simple use of the \Code{\%startlist} and \Code{\%endlist} + macros. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode} + *; %startlist(myprtlabel); + proc print data=sashelp.class(obs=10) noobs; + run; + *; %endlist; +\end{Sascode} + +\Listing[caption={Mass Analysis}]{myprtlabel} +\end{verbatim} +\end{snugshade} +\caption{Capturing Print Output with the \texttt{\%startlist} and +\texttt{\%endlist} Macros}\label{printoutput} +\end{figure} + + The \Code{\%startlist} macro opens the ODS listing destination for writing. + The PRINT procedure code is executed, and the \Code{\%endlist} macro closes the ODS destinations. + The result is an output file called \Code{myprtlabel.lst}, which is + inserted into the document with the \cs{Listing} tag. + + The following section describes how to use the \Code{\%startlist} and \Code{\%endlist} + macros to capture and display part of a table. + + +\section{Capturing Large Tables}\label{large} + + The \StatRep package automatically takes care of all page breaks in the output. + Pages are allowed to break between groups of ODS objects or wherever there is a new page + in the listing output. + + In some cases, an ODS object is too large to fit on a page. + There are two ways to handle such large tables: + \begin{itemize} + \item Set the page size to a smaller size so that a single ODS object is broken into pieces + by using the SAS system option to control the size of the output parts. + By default, a large page size is + in effect (\Code{defaultpagesize=500}) and each table appears + as a complete output block. However, when you have tables that are + too long to fit on a page (that is, single ODS objects that will not fit on a page), + you must specify a smaller page size + (for example, \Code{pagesize=50}). + The tables will automatically split using the normal SAS + rules for splitting tables. + + \item Save the ODS object to a SAS data set and manipulate the data set + so that it contains only part of the original output. Use PROC PRINT + or DATA step statements to generate and capture the modified data set. + + \end{itemize} + + Figure \ref{odsdataset} shows an + example of using a SAS data set to manipulate + the ODS object resulting from a problem that is very + slow to converge. The output from this step includes a long iteration + history table. + The goal is to display only the first few and last few lines of + the iteration history table. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[store=doc] +proc prinqual data=X n=1 maxiter=2000 + plots=transformation out=results; + *; ods output mtv=m convergencestatus=c; + title 'Linearize the Scatter Plot'; + transform spline(X1-X3 / nknots=9); +run; +\end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Capturing Output to an ODS Output Data Set}\label{odsdataset} +\end{figure} + + Any arbitrary SAS statement can be sent to the generated program by preceding + it with a null SAS macro comment (\%*;). + With the output generated and the ODS document \Code{doc} created, + the \Code{Sascode} block shown in Figure \ref{odsmanip} is passed directly + to the generated program and not displayed. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode}[program] +%startlist(prqdb) +title3 'The PRINQUAL Procedure'; +title5 'PRINQUAL MTV Algorithm Iteration History'; +title6 ' '; + +data _null_; + set m(rename=(variance=rsquare)); + if _n_ le 13 or _n_ gt 1669; + if 11 le _n_ le 13 then do; + iternum = .; avechange = ._; criterionchange = ._; + maxchange = ._; rsquare = ._; + end; + file print ods=(template='Stat.Transreg.MTV'); + put _ods_; +run; +title; + +data _null_; + set c; + file print; + put @8 reason; +run; +%endlist; +\end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Manipulating the ODS Output Data Set for Printing}\label{odsmanip} +\end{figure} + + The \Code{\%startlist} macro opens the file \Code{prqdb} + to contain the printed results of the code block. + The DATA step reads, manipulates, and prints the data set \Code{m} + that was just created by PROC PRINQUAL, and the printed content is written to the + output file \Code{prqdb.lst}, which is shown in Figure \ref{odsmanipresult}. + +\begin{figure}[H] +\footnotesize +\begin{snugshade} +\begin{verbatim} + Linearize the Scatter Plot + + The PRINQUAL Procedure + + PRINQUAL MTV Algorithm Iteration History + + Iteration Average Maximum Proportion Criterion + Number Change Change of Variance Change Note + ------------------------------------------------------------------------- + 1 0.15125 0.93453 0.92376 + 2 0.04589 0.14682 0.98030 0.05653 + 3 0.03154 0.10125 0.98626 0.00596 + 4 0.02258 0.06890 0.98890 0.00265 + 5 0.01682 0.04777 0.99028 0.00137 + 6 0.01297 0.03782 0.99106 0.00078 + 7 0.01032 0.03029 0.99154 0.00048 + 8 0.00851 0.02514 0.99186 0.00032 + 9 0.00722 0.02124 0.99209 0.00023 + 10 0.00625 0.01871 0.99226 0.00017 + . + . + . + 1670 0.00001 0.00005 0.99371 0.00000 + 1671 0.00001 0.00005 0.99371 0.00000 + 1672 0.00001 0.00005 0.99371 0.00000 Converged + + Algorithm converged. +\end{verbatim} +\end{snugshade} +\caption{Result of Printing ODS Output Data Set}\label{odsmanipresult} +\end{figure} + + + Similarly, Figure \ref{printods} creates an output data set in the first step. + The second step reads in the data set and uses PROC PRINT to display + the first 10 rows of a table. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode} + title2 'Binary Table'; + + *---Perform Multiple Correspondence Analysis---; + proc corresp data=Cars binary; + *; ods output rowcoors=rc; + ods select RowCoors; + tables Origin Size Type Income Home Marital Sex; + run; +\end{Sascode} +\begin{Sascode}[program] +%startlist(crse1n) +proc print data=rc(obs=10) noobs label; + label label = '00'x; + title4 'The CORRESP Procedure'; + title6 'Row Coordinates'; +run; +%endlist; +\end{Sascode} +\end{verbatim} +\end{snugshade} +\caption{Capturing PROC PRINT Output from an ODS Data Set}\label{printods} +\end{figure} + +\section{Capturing Log Output} + \index{SAS macros!startlog}\index{SAS macros!endlog} + + The SAS/IML example shown in Figure \ref{logout} illustrates + the use of the macros that capture log output. In this example, the goal is to + display SAS/IML error messages\footnote{The example code generates an error because + of a variable scoping issue. + Module \Code{Mod7} is called from module \Code{Mod8}. Therefore, the variables + available to \Code{Mod7} are those defined in the scope of \Code{Mod8}. + Because no variable named \Code{x} is in the scope of \Code{Mod8}, + an error occurs on the PRINT statement in \Code{Mod7}. + An error would not occur if \Code{Mod7} was called from the main scope, + because \Code{x} is defined at main scope.}. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode} + *; %startlog(psmodb) +proc iml; + x = 123; + + start Mod7; + print "In Mod7:" x; + finish; + + start Mod8(p); + print "In Mod8:" p; + run Mod7; + finish; + run Mod8(x); + + *; %endlog; +\end{Sascode} +\Listing[caption={Error Message When a Variable is + Not Defined in a Module}]{psmodb} +\end{verbatim} +\end{snugshade} +\caption{Capturing Log Output}\label{logout} +\end{figure} + + The captured log output is shown in Figure \ref{logcomplete}. + + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +1599 +proc iml; +NOTE: IML Ready +1600 + x = 123; +1601 + +1602 + start Mod7; +1603 + print "In Mod7:" x; +1604 + finish; +NOTE: Module MOD7 defined. +1605 + +1606 + start Mod8(p); +1607 + print "In Mod8:" p; +1608 + run Mod7; +1609 + finish; +NOTE: Module MOD8 defined. +1610 + +1611 + run Mod8(x); +ERROR: Matrix x has not been set to a value. + + statement : PRINT at line 1603 column 7 + traceback : module MOD7 at line 1603 column 7 + module MOD8 at line 1608 column 7 + +NOTE: Paused in module MOD7. +NOTE: Exiting IML. +NOTE: The SAS System stopped processing this step because of errors. +\end{verbatim} +\end{snugshade} +\caption{Complete Log Output Capture}\label{logcomplete} +\end{figure} + + The \Code{\%startlog} macro opens the specified file for writing, the IML + procedure code is executed, and the \Code{\%endlog} macro closes the file. + + To omit the PROC IML code from the captured log output, + specify the \Code{code=0} option in the \Code{\%endlog} macro as follows: + +\begin{snugshade} +\begin{verbatim} + %*; %endlog(code=0); +\end{verbatim} +\end{snugshade} + + With the \Code{code=0} option specified, the captured log output is + displayed as shown in Figure \ref{lognoproc}. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +NOTE: IML Ready +NOTE: Module MOD7 defined. +NOTE: Module MOD8 defined. +ERROR: Matrix x has not been set to a value. + + statement : PRINT at line 1651 column 7 + traceback : module MOD7 at line 1651 column 7 + module MOD8 at line 1656 column 7 + +NOTE: Paused in module MOD7. +NOTE: Exiting IML. +NOTE: The SAS System stopped processing this step because of errors. +\end{verbatim} +\end{snugshade} +\caption{Log Output Capture: Procedure Code Omitted}\label{lognoproc} +\end{figure} + + You can further refine the captured log output with the + \Code{range=} option in the \Code{\%endlog} macro as follows: + +\begin{snugshade} +\begin{verbatim} + %*; %endlog(code=0, range=_n_ > 6 and _n_ le 24); +\end{verbatim} +\end{snugshade} + With the both options specified, the captured log output is displayed as + shown in Figure \ref{logabbrev}. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +NOTE: Module MOD7 defined. +NOTE: Module MOD8 defined. +ERROR: Matrix x has not been set to a value. + + statement : PRINT at line 1722 column 7 + traceback : module MOD7 at line 1722 column 7 + module MOD8 at line 1727 column 7 + +NOTE: Paused in module MOD7. +\end{verbatim} +\end{snugshade} +\caption{Abbreviated Log Output Capture: Procedure Code Omitted}\label{logabbrev} +\end{figure} + + The \Code{range=\_n\_ > 6 and \_n\_ le 24} option specifies that only the lines between 6 and 24 + be included in the captured output. + The value of \Code{\_n\_} refers to the original line numbers before any filtering is done. + + +\section{Capturing Output with Interactive Procedures} + You can use the \StatRep package to capture output from interactive procedures. +Figure \ref{interact} shows how to capture output from the interactive + IML procedure. It displays three \Code{Sascode} environments with \cs{Listing} + outputs interleaved. + +\begin{figure}[H] +\begin{snugshade} +\begin{verbatim} +\begin{Sascode} + *; %output(doc) + proc iml; + x = 1; + print x; +\end{Sascode} + +\Listing[caption={x = 1}]{x1a} + +\begin{Sascode} + x = 2; + print x; +\end{Sascode} + +\Listing[caption={x = 2}]{x2a} + +\begin{Sascode} + x = 3; + print x; + *; %write(x1a, objects=x) + *; %write(x2a, objects=x#2) + *; %write(x3a, objects=x#3) +\end{Sascode} + +\Listing[caption={x = 3}]{x3a} +\end{verbatim} +\end{snugshade} +\caption{Capture Output with an Interactive Procedure}\label{interact} +\end{figure} + + When you need to interleave \Code{Sascode} blocks to make a single ODS + document, as in Figure \ref{interact}, you cannot rely on the \StatRep package to + automatically write the macros. You must write the output capture macros manually. + + When the \StatRep package automatically writes the macros, there is a + one-to-one correspondence between a \Code{Sascode} block and an ODS document. + The interactive procedure terminates when the ODS document is closed. + + Figure \ref{interact} uses three \Code{Sascode} blocks to create a single ODS document. + The contents of that ODS document are displayed in three separate listings. + The ODS document is created by the \Code{\%output(doc)} statement in the first + \Code{Sascode} environment, and it is closed by the first \Code{\%write} + macro in the third \Code{Sascode} environment. + The three \Code{\%write} macros create the output for the + three output listings. + The fact that two of the \cs{Listing} lines come before any of the output is + created does not pose a problem. + +\section{Capturing and Displaying Numerical Results in Text} + +This example shows how you can capture SAS output values and display them in text. +For example, suppose you want to capture the R-square values from a PROC REG +step and a PROC GLM step and then display those values +(but not display the steps) in your document. + +Use the following steps to capture the values and display them in text: + +\begin{enumerate} +\item In your document source file, anywhere before you want to display the + captured values, include the following command to + input a \LaTeX\ file (named\newline\texttt{myconstants.tex} in this example) + to contain the \LaTeX\ definitions of the captured values: +\begin{snugshade} +\begin{verbatim} + \input{myconstants} +\end{verbatim} +\end{snugshade} + +The \texttt{myconstants.tex} file is actually generated in step 3, +but you can include the preceding command before the file is generated +because the SAS output capture program will create the file and write +the definitions before pdf\LaTeX\ generates the final PDF file. + +\item Include one or more procedure steps, such as the following + PROC REG and PROC GLM steps, which produce tables of fit statistics + that are named \texttt{fsr} and \texttt{fsg}, respectively: +\begin{snugshade} +\begin{verbatim} + \begin{Sascode} + proc reg data=sashelp.class; + model weight = height; + %*;ods output fitstatistics=fsr; + run; quit; + + proc glm data=sashelp.class; + class sex; + model weight = sex | height; + %*;ods output fitstatistics=fsg; + run; quit; + \end{Sascode} +\end{verbatim} +\end{snugshade} + +Include a null macro comment at the beginning of the ODS OUTPUT statement +in each step to cause the step to be run in the capture program but not be +displayed in the text. + +\item Near the end of your document source file, include code such as the + following to generate the \texttt{myconstants.tex} file, extract the + R-square values from the \texttt{fsr} and \texttt{fsg} tables of fit statistics that were + generated in step 2, and write those values to \texttt{myconstants.tex}. + The \texttt{Sascode} environment option, \texttt{program}, + runs the code without displaying it in the text. +\begin{snugshade} +\begin{verbatim} + \begin{Sascode}[program] + data _null_; + file 'myconstants.tex' termstr=nl; + set fsr(keep=label2 nvalue2 where=(label2='R-Square')); + put '\def \regrsq{' nvalue2 6.4 '}'; + set fsg(keep=rsquare); + put '\def \glmrsq{' rsquare 6.4 '}'; + run; + \end{Sascode} +\end{verbatim} +\end{snugshade} + +\item Include the tags that are contained + in the \texttt{myconstants.tex} file when you want to display + the values of those tags, as follows: +\begin{snugshade} +\begin{verbatim} + The R-square values are \regrsq\ and \qlmrsq, respectively. +\end{verbatim} +\end{snugshade} + Include a backslash after the tag when you need to include a space after the value. +\end{enumerate} + +When you execute the generated SAS program, SAS writes the +following tags in the \texttt{myconstants.tex} file: +\begin{snugshade} +\begin{verbatim} + \def \regrsq{0.7705} + \def \glmrsq{0.7930} +\end{verbatim} +\end{snugshade} + +When pdf\LaTeX\ processes the file, it replaces the +\verb+\regrsq+ and \verb+\glmrsq+ tags with the values that were +written to the \texttt{myconstants.tex} file and produces the +following: +\begin{snugshade} + The R-square values are 0.7705 and 0.7930, respectively. +\end{snugshade} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\appendix +\part{Appendix} +%\chapter{Appendix} + +\chapter{Installation and Requirements}\label{install}\index{installing} +You can install the \StatRep package by downloading \Code{statrep.zip} from \url{support.sas.com/StatRepPackage}. + +Table \ref{ziptable} shows the contents: +\begin{table}[H] +\caption{Contents of the \Code{statrep.zip} File}\label{ziptable} +\begin{tabular}{ll} +\hline +\textbf{Filename} & \textbf{Description}\\ +\Code{doc/statrepmanual.pdf} & The \textit{\StatRep User's Guide} (this manual)\\ +\Code{doc/quickstart.tex} & A template and tutorial sample \LaTeX\ file\\ +\Code{sas/statrep\_macros.sas} & The \StatRep SAS macros \\ +\Code{sas/statrep\_tagset.sas} & The \StatRep SAS tagset for LaTeX tabular output \\ +\Code{statrep.ins} & The \LaTeX\ package installer file\\ +\Code{statrep.dtx} & The \LaTeX\ package itself\\ +\hline +\end{tabular} +\end{table} + +Unzip the file \Code{statrep.zip} to a temporary directory and +perform the following steps: + +\section{Step 1: Install the StatRep SAS Macros} + + Copy the file \Code{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 + \Code{C:\textbackslash{}mymacros} and copy the file into that directory. + +\section{Step 2: Install the StatRep LaTeX Package} + + These instructions show how to install the StatRep package + in your \LaTeX\ distribution for your personal use. + + \begin{enumerate}[a)] + \item + \textbf{Mik\TeX\ users}: If you do not have a directory for your own + packages, choose a directory name to contain your packages + (for example, c:\textbackslash{}localtexmf). + + In the following instructions, this directory is referred to as the + "root directory". + + \textbf{\TeX{}Live users}: + 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: + \url{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=what-TDS} + + Determine the location that LaTeX uses to load packages. At a + command-line prompt, enter the following command:\\ + \texttt{kpsewhich -var-value=TEXMFHOME} + + The command returns the root directory name in which LaTeX can + find your personally installed packages. + + In the following instructions, this directory is referred to as the + "root directory". + + \item + Create the directory if it does not exist, and create the additional + subdirectories \Code{tex/latex/statrep}. + Your directory tree will have the following structure: +\begin{verbatim} + --------------- + root directory/ + tex/ + latex/ + statrep/ +\end{verbatim} + \item + Copy the files \Code{statrep.dtx}, \Code{statrep.ins}, \Code{statrepmanual.pdf}, + and \Code{statrepmanual.tex} to + the \Code{statrep} subdirectory. Your directory tree will have the following structure: +\begin{verbatim} + --------------- + root directory/ + tex/ + latex/ + statrep/ + statrep.dtx + statrep.ins + statrepmanual.pdf + statrepmanual.tex + --------------- +\end{verbatim} + \item + Change to the \Code{statrep} directory and enter the following command:\\ + \texttt{pdftex statrep.ins} + + The command creates several files, one of which is the configuration + file, \Code{statrep.cfg}. + + \textbf{Mik\TeX\ users}: + Add the root directory name from Step 2a according to these instructions + for installing packages for MikTeX + (\textit{Register a user-managed TEXMF directory}): + \url{http://docs.miktex.org/manual/localadditions.html} + +\end{enumerate} + +\section{Step 3: Tell the StatRep Package the Location of the StatRep SAS Macros} + + Edit the \Code{statrep.cfg} file that was generated in Step 2d so that the macro + \cs{SRmacropath} contains + the correct location of the macro file from step 1. For example, if + you copied the \Code{statrep\_macros.sas} file to a directory named + \Code{C:\textbackslash{}mymacros}, + then you define macro \cs{SRmacropath} as follows: + \begin{verbatim} + \def\SRmacropath{c:/mymacros/statrep_macros.sas} + \end{verbatim} + + Use the forward slash + as the directory name delimiter instead of the backslash, which is a special + character in LaTeX. + + You can now test and experiment with the package. Create a working + directory, and copy the file \Code{quickstart.tex} into it. + + To generate the quick-start document: +\begin{enumerate} +\item Compile the document with pdf\LaTeX. You can use a \LaTeX-aware + editor such as \TeX works, or use the command-line command \Code{pdflatex}. + This step generates the SAS program that is needed to produce the results. + +\item 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 quick-start document. + + +\item Recompile the document with pdf\LaTeX. This step compiles the + quick-start document to PDF, this time including the SAS results + that were generated in the preceding step. + + In some cases listing outputs may not be framed properly after this step. + If your listing outputs are not framed properly, repeat this step so that + LaTeX can remeasure the listing outputs. + +\end{enumerate} + You can make changes to the file with a \LaTeX-aware editor + or with any plain-text editor such as \textsf{NotePad} or \textsf{emacs}. + +If you ever want to uninstall the \StatRep package, +delete the \Code{statrep} directory that you created +in the installation step 2d and remove the SAS macro file \Code{statrep\_macros.sas} +that you copied in installation step 1. + Mik\TeX\ users must additionally update the filename database.\\ + \Code{(MikTeX Options dialog: General-> Refresh FNDB)} + +\chapter{The \texttt{longfigure} Package}\label{longfigure}\index{longfigure package} + + + The \Code{longfigure} package uses and relabels components of the + well-known \Code{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 \Code{longtable} package defines a \Code{longtable} environment, + which produces tables that can be broken by \TeX's standard page-breaking algorithm. + Similarly, the \Code{longfigure} package defines a \Code{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 \Code{longfigure} package differs from the \Code{longtable} package in the following ways: + \begin{itemize} + \item The \Code{longfigure} package supports two additional key-value options: + \begin{itemize} + \item The \Code{figname=} option specifies the counter for numbering + \Code{longfigure} environments. + You can specify any string; the default is \Code{figure}. + When you specify a \Code{figname=} value for which no counter already exists, the + \Code{longfigure} package loads the \Code{tocloft} package and creates the counter. + \index{figname option} + + \item The \Code{resetby=} option specifies a counter (for example, + \Code{resetby=chapter}) such + that output numbering is reset each time the counter value changes. + If a counter is specified that does not exist, the \Code{tocloft} package is + loaded to create the new counter. + \index{tocloft package}% + For information about how the lists are typeset, + \index{list of outputs, creating}% + see the \Code{tocloft} package documentation. + \end{itemize} + \item The counters and macros that start with \cs{LT} in the \Code{longtable} package + are renamed to start with \cs{LF} in the \Code{longfigure} pacakge to avoid + namespace conflicts when the two packages are used together. + The generic macros that are defined in the \Code{longtable} package + (\cs{endfirsthead}, \cs{endhead}, \cs{endfoot}, and \cs{endlastfoot}) are + also renamed with \cs{LF} as a prefix in the \Code{longfigure} package. + + \item The \cs{LF@name} macro is based on the \cs{fnum@table} macro from + the \Code{longtable} package. The \cs{LF@name} macro returns the capitalized + counter name and value. For example, if the counter is \Code{figure} and the + macro is processing the second \Code{longfigure}, the \cs{LF@name} macro + would contain the value ``Figure 2.'' + + \end{itemize} + You can use the \Code{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: + +\begin{verbatim} + \listoffigures +\end{verbatim} + + + The default counter used to display figures is the \Code{figure} counter, + but you can specify a different counter. For example, if you want your + figures to be labeled as ``Display,'' specify \Code{figname=display} when you + load the \Code{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: + +\begin{verbatim} + \listofdisplay +\end{verbatim} + + \textbf{Note:} If you specify a counter that does not exist, + an auxiliary file with extension \Code{.lft} is created to contain the information + needed to create the list. + + If you want to use more advanced features of the \Code{tocloft} package, + load it before you load the \Code{longfigure} package so that the \Code{longfigure} + package sees that the counters specified by the \Code{figname=} and \Code{resetby=} + options are already defined and does not attempt to create them. + + +\section{Example} + The following lines produce a single figure that contains three images and + one tabular environment. Each element is a row of the \Code{longfigure} environment. + Page breaks can occur between rows. + +\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} + + In this example, the \Code{\{c\}} argument in the \cs{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. +%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%% + +\chapter{The ODS \StatRep LaTeX Tagset}\label{latexoutput} +\index{ODS LaTeX output}\index{LaTeX output} +The \StatRep package provides limited support for +SAS-generated LaTeX output\footnote{Since SAS 9.1, SAS\textsuperscript{\textregistered} +has provided an experimental LaTeX tagset.\index{statrep tagset} +The \texttt{statrep} tagset is a simplified version of that experimental tagset.}. + +Three corresponding configuration variables are available. You can change them +in the file \texttt{statrep.cfg} or in your LaTeX document. +For complete details about the configuration file, see +the section \ref{custom}. + +The variables are as follows: + +\begin{itemize} +\item \cs{SRdefaultdests} specifies the type of ODS output to generate. +The default is \texttt{listing}, which corresponds to the ODS Listing destination. +\item \cs{SRlatexstyle} specifies the ODS style for SAS-generated LaTeX tables. +The default is \texttt{statrep}, which is a monochromatic style based on the +SAS ODS LaTeX tagset. +\item \cs{SRlatexdir} specifies the name of the subdirectory into which +SAS writes the LaTeX output files. +The default is \texttt{tex}. +\end{itemize} + +To enable the use of LaTeX output in \StatRep, follow these steps. +\begin{enumerate} + +\item Change your \StatRep configuration or in your LaTeX document. +The \cs{SRdefaultdests} setting +selects the default output type; it can have the value \texttt{latex} +or \texttt{listing}. The default value is \texttt{listing}. +You can change the value in the \texttt{statrep.cfg} configuration file as follows: + +\begin{verbatim} + \def\SRdefaultdests{latex} +\end{verbatim} + +Alternatively, you can change the value in your LaTeX document +after the \StatRep package is loaded and before your document begins: + +\begin{verbatim} + \documentclass{article} + \usepackage{statrep} + \def\SRdefaultdests{latex} + \begin{document} +\end{verbatim} + +\item Run the included SAS program \Code{statrep\_tagsets.sas}\index{statrep tagset} +before you generate the SAS output for your document. This program creates +a \texttt{statrep} tagset and a \texttt{statrep} ODS style. +When you run the program to generate the output for your document, +SAS must be able to find the \texttt{statrep} tagset in order to produce LaTeX +tabular output that is compatible with the \StatRep package. + +For details on installing and storing tagsets see this SAS\textsuperscript{\textregistered} Note: +\url{http://support.sas.com/kb/32/394.html} + +\end{enumerate} + +\section{How It Works} + +When you first compile your document with \texttt{pdflatex}, the SAS +program to produce the requested outputs is generated. + +When you run the program, SAS checks the type of output requested, +which is controlled with the \cs{SRdefaultdests} setting. +If the output type is \texttt{latex}, +LaTeX output is written to a subdirectory named \texttt{tex}. +If the output type is \texttt{listing}, +ODS Listing output is written to a subdirectory named \texttt{lst}. + + +When you recompile your document with \texttt{pdflatex}, the +\cs{Listing} tag displays the requested output objects, +insuring that your outputs are displayed properly with automatic page breaking. + +\section{Customization} + +\begin{description} +\item[ODS Style] You can specify an ODS style for your LaTeX output with the \cs{SRlatexstyle} +setting. The default is \texttt{statrep}, a monochrome style that is generated by the +SAS program \Code{statrep\_tagsets.sas}.\index{statrep tagset} +Examples of different styles are provided in the section \titleref{styleexamples}. + +If you specify an ODS style that uses color, specify the \texttt{color} option +when you load the \StatRep package. + +\begin{verbatim} +\documentclass{article} +\usepackage[color]{statrep} +\end{verbatim} + +The style setting for LaTeX tables cannot be changed within a document. +That is, you cannot mix ODS LaTeX styles within a document.\index{mixing LaTeX styles} +If you change the style within your document, the last +style specified is used for all LaTeX outputs. + +\item[Mixing Output Types] You can mix output types with the \texttt{dest=} +option on the \cs{Listing} tag.\index{mixing output types} +The option overrides the global \cs{SRdefaultdests} setting. + +For example, if your \cs{SRdefaultdests} is set to \texttt{latex}, you can +specify that a particular \cs{Listing} output to be in listing format by +specifying \texttt{dest=listing} in the \cs{Listing} tag options, as follows: + +\begin{verbatim} +\Listing[store=mydoc, dest=listing, caption={Results}]{outa} +\end{verbatim} + +\item[Output Directory Name] You can change the name of the directory into which +SAS writes the outputs with the \cs{SRlatexdir} variable. The default +subdirectory name is \Code{tex}. + +\end{description} + +\section{Caution} + +In some cases the LaTeX tagset produces tables that are too wide +to fit in the text block. In some cases, you can shift the table to +the left so the table will fit on the page. You can shift the table +with the \cs{LFleft} command. + +The following example moves the left margin of the +output 1 inch to the left of its normal location +(the start of the text block). +The output is then typeset and the margin is set back to its default value of 0. + +\begin{verbatim} + \LFleft=-1in + \Listing[store=mydoc, caption={Results}]{outa} + \LFleft=0in +\end{verbatim} + +In some cases, the table will not fit on the page at all. +The only solution in those cases is to change back to the +\texttt{listing} output destination, modifying the fontsize and linesize +as needed. + +Some ODS styles may not work with the LaTeX tagset. For example, +some styles specify fonts that are available to SAS but not to LaTeX. + +\section{Style Examples}\label{styleexamples} + +\begin{figure}[H] +\caption{Listing Output} +\includegraphics{images/listing} +\end{figure} +\begin{figure}[H] +\caption{LaTeX Output, default style} +\includegraphics{images/default} +\end{figure} +\begin{figure}[H] +\caption{LaTeX Output, \texttt{statistical} style} +\includegraphics{images/statistical} +\end{figure} +\begin{figure}[H] +\caption{LaTeX Output, \texttt{journal} style} +\includegraphics{images/journal} +\end{figure} +\begin{figure}[H] +\caption{LaTeX Output, \texttt{htmlblue} style} +\includegraphics{images/htmlblue} +\end{figure} + + +\chapter{\StatRep with SAS Studio or SAS University Edition}\label{sasstudio} +\index{SAS Studio}\index{University Edition}\index{SAS University Edition} +\index{web interface} + +You can use \StatRep with the SAS Studio web-based interface and SAS University Edition. +You can find more information on these applications here: +\begin{description} +\item[SAS Studio] is a web application for SAS that you access through your web browser. +\url{http://support.sas.com/software/products/sasstudio/} + +\item[SAS University Edition] +is free and includes the SAS products Base SAS, SAS/STAT, SAS/IML, SAS/ACCESS Interface to PC Files, and SAS Studio. +\url{http://support.sas.com/software/products/university-edition/index.html} +\end{description} + +With a web interface, there is no concept of a \emph{current directory}, +so you must let SAS know where your files are located. +In order to use \StatRep, SAS needs to know the following locations: + +\begin{itemize} +\item the directory that contains your LaTeX file. +\item the full path to the file \texttt{statrep\_macros.sas}. +\item the location of the \StatRep ODS tagset, if you prefer LaTeX output (instead of Listing output). +See the previous chapter for details on how to create and use this tagset. +\end{itemize} + +With SAS University Edition, you run a virtual machine on your local computer so you can +create a shared folder that SAS can access.\index{virtual machine} +For SAS Studio folder locations, see the following section for details. + +\section{SAS Studio Folders} +\index{SAS Studio} +Other than SAS University Edition, there are three 3 types of installations for SAS Studio: +\begin{itemize} +\item SAS Studio Single User +\item SAS Studio Basic (Windows or UNIX) +\item SAS Studio Mid-Tier (Enterprise Edition) +\end{itemize} + +For Single User, \textit{My Folders} is your home directory on your local machine and the folders list will also include folders for your desktop, documents folder, and mapped drives. + +For both Enterprise and Basic edition, the path for \textit{My Folders} is the home directory on the remote SAS server. That is, the file system in the \textit{Folders} accordion is not your local machine; +it is the location of the remote server. + +On Windows, you can add a \textit{Folder Shortcut} back to your local computer. +The shortcut must be accessible by the remote server. +On UNIX, you can add a \textit{Folder Shortcut} to your home directory. + +You may need to ask your local SAS administrator about how to create a folder shortcut to your local +files. + +\section{SAS University Edition: Creating a Shared Folder} +\index{University Edition}\index{SAS University Edition}\index{virtual machine} +Suppose you have a directory called \texttt{mydocs} that contains your LaTeX file. +You create a shared folder in the virtual machine as shown in the following screenshot: + +\includegraphics[width=\textwidth]{images/vm1} + +When you select \texttt{Shared Folders} and click to add a new path, +enter the information (path and name) as shown in the following screenshot: + +\includegraphics[width=\textwidth]{images/vm2} + +The \texttt{Folder Path} is the absolute path to the directory and the +folder name is the last part of that path. +The name is a short-hand name that is used later in your code. +Make sure to select \texttt{Auto-mount} if you want to use the folder in later SAS sessions (as you probably will). +The result of entering the information is shown in the following screenshot. + +\includegraphics[width=\textwidth]{images/vm3} + +When you start SAS Studio, the \texttt{Folder} panel shows your new shared folder as a \emph{Folder Shortcut}. +SAS will know this folder by the full name \texttt{/folders/myshortcuts/mydocs}, +which means you can use that name to assign filerefs and libnames as you normally would in any SAS program. + +Notice the \texttt{Folder} panel in the following screenshot. +You can disregard most of the code in the program editor window, +but do notice the first line that references the new shared folder. + +\includegraphics[width=\textwidth]{images/sasuniv1} + +The LIBNAME statement in the code window assigns the \texttt{mytempl} libref to your shared folder. + +\section{The Bridge Between LaTeX and SAS} + +Now you have your working directory and SAS knows that there is such a location. +The final step is to define a bridge between your LaTeX document and SAS. + +You connect the two by defining a LaTeX tag called \verb+\SRrootdir+, which contains the +path to your shared folder as displayed in the following LaTeX code: + +\begin{verbatim} + \documentclass{article} + \usepackage[margin=1in]{geometry} + \usepackage[color]{statrep} + \def\SRrootdir{/folders/myshortcuts/mydocs} + \def\SRmacropath{/folders/myshortcuts/mydocs/statrep_macros.sas} + \begin{document} +\end{verbatim} + +This document preamble performs the following: +\begin{itemize} +\item Specifies that the document use the \texttt{article} class. +\item Loads the \texttt{geometry} package and specifies 1 inch margins on all sides. +\item Loads the \texttt{statrep} package and specifies that outputs can include color. +\item Defines the \verb+\SRrootdir+ path (the path to the working directory) as the shared folder you created in the previous steps. +\item Defines the \verb+\SRmacropath+ that contains the full path and file name of the \texttt{statrep\_macros.sas} file +that is part of the \StatRep package. +This example shows that it is in the same directory as the LaTeX file, but you can put the macros anywhere you like, +as long as SAS can find the file (that is, as long as the macros are in a shared folder) +\end{itemize} + +With this preamble, you can start writing your content; when \StatRep automatically generates the SAS program to create your output, +the paths you have defined here are used so SAS can find the macros it needs and so it can write the requested outputs to your working directory. + +From this point on, you use \StatRep just as you would normally. + + +\printindex +\end{document}
\ No newline at end of file diff --git a/macros/latex/contrib/statrep/sas/statrep_macros.sas b/macros/latex/contrib/statrep/sas/statrep_macros.sas new file mode 100644 index 0000000000..3681c4b653 --- /dev/null +++ b/macros/latex/contrib/statrep/sas/statrep_macros.sas @@ -0,0 +1,1523 @@ + /*---------------------------------------------*/ + /* The WRITE macro displays one or more pieces */ + /* of output (tables, notes, graphs, and so */ + /* on) that were captured into an ODS document */ + /* by the OUTPUT macro. */ + /*---------------------------------------------*/ +%macro write(fname, /* is a required keyword that specifies the */ + /* first level of the output file name. This */ + /* name will appear at the end of the \Listing */ + /* or \Graphic tag in the LaTeX file. The */ + /* following examples show where the fname */ + /* keyword, in this case 'crsi1a', is */ + /* specified in the WRITE macro and in the */ + /* \Listing tag: */ + /* */ + /* %*;%write(crsi1a, objects=inertias) */ + /* \Listing[caption={... caption ...}]{crsi1a} */ + /* */ + dest=, /* specifies destination: latex or listing. */ + /* Null uses the defaultdests macro. */ + /* */ + width=, /* specifies the width of graphs. */ + /* Example: WIDTH=5.4in. */ + height=, /* specifies the height of graphs. */ + /* Example: HEIGHT=4in. */ + /* */ + dpi=, /* specifies DPI (dots per inch) for ODS */ + /* Graphics. You typically would not use this */ + /* option except when you would otherwise run */ + /* out of memory. The default is 300 DPI, and */ + /* a reasonable alternative for ODS graphs */ + /* with large file sizes is 100 DPI. More */ + /* details follow. */ + /* */ + /* This option controls the DPI for ODS */ + /* Graphics. Use the DPI= option in the */ + /* OUTPUT macro to control the DPI for GRSEG */ + /* graphics. */ + /* */ + /* If DPI= is specified, that DPI is used. */ + /* If DPI= is not specified, and if a macro */ + /* variable DefaultDPI is defined, its value */ + /* is used as the DPI. If DPI= is not */ + /* specified and the macro variable DefaultDPI */ + /* is not defined or if its value is null, */ + /* then the default DPI, 300, is used. */ + /* */ + /* In other words, the default DPI is 300. */ + /* However, you can set the default DPI to */ + /* (say) 100 by putting the following at the */ + /* top of your first Sascode block, beginning */ + /* in column 1: */ + /* */ + /* %*;%let defaultdpi=100; */ + /* */ + /* Since the %LET statement is preceded by a */ + /* null macro comment (%*;) beginning in */ + /* column 1, it will not show up in the */ + /* SAS code listing, but it will affect the */ + /* capture program and change the default */ + /* DPI for the duration of the running of the */ + /* program. You can change the default DPI at */ + /* any time with a %LET statement. */ + /* */ + /* With GRSEG graphics, 100 DPI is not */ + /* available, so this specification creates */ + /* graphs at 96 DPI. */ + /* */ + store=, /* specifies the name of the ODS document */ + /* that is created by the OUTPUT macro. This */ + /* is the ODS document that the WRITE macro */ + /* will process. By default, when null, the */ + /* current document from the last OUTPUT macro */ + /* is used. If you are processing the last */ + /* document created, you can omit specifying */ + /* the STORE= option. To use some other */ + /* document, specify STORE=documentlabel. */ + /* */ + pattern=, /* provides an optional additional selection */ + /* criterion. Specify part of a path, for */ + /* example, a group name. Then only objects */ + /* whose name includes this group name are */ + /* used. Comparisons are not case sensitive. */ + /* The macro looks for an appearance of the */ + /* PATTERN=value anywhere in the path. For */ + /* example, PATTERN=fit, will match */ + /* "Reg.m2.Fit.Population.ParameterEstimates" */ + /* and anything else with "fit" in it */ + /* including paths that contain "fitplot", */ + /* "fitness", "outfit" and so on. */ + /*---------------------------------------------*/ + firstobj=, /* specifies the first data object. */ + lastobj=, /* specifies the last data object. */ + objects=, /* specifies the list of data objects. */ + /* */ + /* To specify which objects go into a section */ + /* of output, specify one of the following */ + /* combinations: */ + /* * FIRSTOBJ=, */ + /* * LASTOBJ=, */ + /* * FIRSTOBJ= and LASTOBJ=, */ + /* * OBJECTS=, */ + /* * none of the above. */ + /* */ + /* If FIRSTOBJ= is specified and LASTOBJ= is */ + /* not specified, then the last object is the */ + /* last object produced by the procedure. If */ + /* LASTOBJ= is specified and FIRSTOBJ= is not */ + /* specified, then the default first object is */ + /* the first object produced by the procedure. */ + /* If OBJECTS= is specified, then only objects */ + /* in that list are used. If none of these */ + /* options is specified then, all objects are */ + /* used. */ + /* */ + /* The term "object" used in this */ + /* discussion refers to notes, tables, and */ + /* graphs. Specify the first or last object */ + /* or list of objects (tables, notes, graphs). */ + /* All object name comparisons are case */ + /* insensitive. */ + /* */ + /* All selections are based on paths instead */ + /* of label paths. You can specify the last m */ + /* levels of the path. Assuming that you have */ + /* one model and one ANOVA table, any of the */ + /* following specifications for the ANOVA */ + /* object are equivalent, along with many */ + /* other possibilities: */ + /* */ + /* Reg.MODEL1.Fit.Population.ANOVA */ + /* reg.model1.fit.population.anova */ + /* reg#1.model1#1.fit#1.population#1.anova#1 */ + /* reg#1.model1.fit.population#1.anova#1 */ + /* MODEL1.Fit.Population.ANOVA */ + /* Fit.Population.ANOVA */ + /* Population.ANOVA */ + /* ANOVA */ + /* ANOVA#1 */ + /* */ + /* Typically, you need to specify only the */ + /* last level. If an object appears more than */ + /* once, then you might need to specify more */ + /* levels. The #n notation is allowed, even */ + /* in cases where it does not work in an ODS */ + /* SELECT statement. You must specify a name, */ + /* using the #n notation that matches the name */ + /* (or the last few levels of the name) as it */ + /* appears in the ODS document. For example, */ + /* if there are multiple residual panels, you */ + /* can specify OBJECTS=residualplot and */ + /* OBJECTS=residualplot#2. The object list */ + /* produced by the macro will show every place */ + /* that a #2 or #n (n > 1) is required. */ + /* */ + /* If you run a procedure more than once for */ + /* this ODS document, then you need #2 on the */ + /* procedure name for the second group. For */ + /* example, here are the fully-qualified names */ + /* from a set of two PROC REG runs: */ + /* */ + /* Reg.MODEL1.Fit.Fail.NObs */ + /* Reg.MODEL1.Fit.Fail.ANOVA */ + /* Reg.MODEL1.Fit.Fail.FitStatistics */ + /* Reg.MODEL1.Fit.Fail.ParameterEstimates */ + /* Reg#2.MODEL1.Fit.Fail.NObs */ + /* Reg#2.MODEL1.Fit.Fail.ANOVA */ + /* Reg#2.MODEL1.Fit.Fail.FitStatistics */ + /* Reg#2.MODEL1.Fit.Fail.ParameterEstimates */ + /* */ + /* The order in which objects come out is */ + /* determined by the order in which they are */ + /* generated, not the order in which they are */ + /* specified in the OBJECTS= option. */ + /* */ + /* If you specify OBJECTS=, then you can also */ + /* specify where page breaks can occur. By */ + /* default, breaks might occur between the */ + /* bottom of a table and the top of the note */ + /* or table that comes after it. If you want */ + /* anything different to occur, use left and */ + /* right angled brackets, <>, to start and end */ + /* a new group and suppress normal page */ + /* breaking in between. After a <, no default */ + /* page breaking occurs until a > is hit. A */ + /* page break occurs at the > and then in the */ + /* default places after that. You can use */ + /* "< list >" in pairs (for example, "<ANOVA */ + /* FitStatistics>" to keep certain objects */ + /* together. You can instead use > to cause */ + /* page breaks in addition to the default page */ + /* breaks. You can also use < to designate */ + /* page breaks and suppress all default page */ + /* breaking. A break always occurs before and */ + /* after a graph regardless of what <> */ + /* specification you use. */ + /*---------------------------------------------*/ + pagesize=, /* specifies the page size. The default is */ + /* the page size currently in effect. This */ + /* specification lasts for the duration of */ + /* this step. The current page size is */ + /* restored at the end. */ + linesize=, /* specifies the line size. The default is */ + /* the line size currently in effect. This */ + /* specification lasts for the duration of */ + /* this step. The current line size is */ + /* restored at the end. */ + /* */ + options=, /* specifies one or more binary options: */ + /* */ + /* LIST - do not run PROC DOCUMENT for */ + /* each group of objects. Just */ + /* list the contents of the */ + /* document. */ + /* */ + /* TABLE - (or TABLES) selects only tables */ + /* and notes (more specifically, */ + /* anything but graphs). */ + /* */ + /* GRAPH - only selects graphs. */ + /* */ + /* NOPAGE - no page breaks at the top of */ + /* tables. */ + /* */ + /* NEWPAGE - forces a page break on the first */ + /* object. */ + /* */ + /* AUTOPAGE - same page breaks that the */ + /* procedure makes. There is a */ + /* page break on the first object */ + /* and where the proc forces a new */ + /* page. AUTOPAGE is the default. */ + /* */ + /* ONEBOX - is used with the \Listing tag */ + /* and specifies that only one */ + /* block of tables is made. This */ + /* option strips out all '<>' */ + /* characters from the OBJECTS= */ + /* list and adds a '<' to the */ + /* beginning of the list. With */ + /* FIRSTOBJ= or LASTOBJ= or no */ + /* OBJECTS= list, the effect is the */ + /* same even though the mechanism */ + /* is different. If anything other */ + /* than only tables or a single */ + /* graph is input, an error is */ + /* issued along with the object */ + /* list. */ + /* */ + /* SKIPFIRST- deletes the first object that */ + /* would otherwise be selected. */ + /* Typical usage is with FIRST= */ + /* to select every object after the */ + /* one that was named. */ + /* */ + /* SKIPLAST - deletes the last object that */ + /* would otherwise be selected. */ + /* Typical usage is with LAST= to */ + /* select every object before the */ + /* one that was named. */ + /* */ + /* Example: OPTIONS=TABLE ONEBOX. */ + /* */ + style=, /* specifies the ODS style for ODS Graphics. */ + /* Use the STYLE= option in the OUTPUT macro */ + /* to control the style for GRSEG graphics. */ + /* If STYLE= is specified, that style is used. */ + /* If STYLE= is not specified, and if a macro */ + /* variable DefaultStyle is defined, its value */ + /* is used as the style. If STYLE= is not */ + /* specified and the macro variable */ + /* DefaultStyle is not defined or if its value */ + /* is null, then the default style (which is */ + /* the HTMLBLUE style) is used. */ + /* */ + /* In other words, the default style is the */ + /* HTMLBLUE style. However, you can set the */ + /* default style to (say) LISTING by putting */ + /* the following line at the top of your first */ + /* Sascode block, beginning in column 1: */ + /* */ + /* %*;%let defaultstyle=listing; */ + /* */ + /* Since this line begins with a null macro */ + /* comment (%*;) that begins in column 1, it */ + /* will not show up in the SAS code listing, */ + /* but it will affect the capture program and */ + /* change the default style for the duration */ + /* of the running of the program. */ + /* */ + type=);; /* specifies the type of objects to select. */ + /* \Listing specifies TYPE=LISTING, which is */ + /* an alias for OPTIONS=TABLE. */ + /* \Graphic specifies TYPE=GRAPH, which is an */ + /* alias for OPTIONS=GRAPH. */ + /*---------------------------------------------*/ + +%local i j k flow error savenote holdlast allobjflag firstflag onlylist + lastflag rangeflag objflag ngroups h onebox isgraph savesize + left tyw stw grw abnormal selecttype savetime kl kh jl jh ls + pagebreak gdevice skipfirst skiplast; + +%let abnormal = 0; +%let error = 0; +%let savenote = %sysfunc(getoption(notes)); +%let savetime = %sysfunc(getoption(stimer)); +%let savesize = ls=%sysfunc(getoption(ls)) ps=%sysfunc(getoption(ps)); +%let holdlast = &syslast; +%let graphtype = %qlowcase(&graphtype); +%if %nrbquote(&graphtype) ne pdf %then %let graphtype = png; + +options nostimer %if &pagesize ne %then ps=&pagesize; + %if &linesize ne %then ls=&linesize;; + +%if %symexist(adsflow) %then %let flow = %lowcase(&adsflow); + +* Set the default style using STYLE= and a DefaultStyle macro variable.; +%if &style eq %then %let style = &defaultstyle; + +* Set the default DPI using DPI= and a DefaultDPI macro variable.; +%if &dpi eq %then %let dpi = &defaultDPI; + +%let gdevice = %substr(png300, 1, 3 * (1 + (&dpi eq 300))); +%if %nrbquote(&graphtype) eq pdf %then %let gdevice = pdf; + +* Find out what is in the document. Store the list in a SAS data set.; +%if %symexist(documentlabel) %then %do; + %if %nrbquote(&store) eq %then %let store = &documentLabel; + %end; + +%if %nrbquote(&store) eq %then %do; + %put ERROR: No ODS document available.; + %let error = 1; + %goto veryend; + %end; +%else %put NOTE: Processing document &store..; + +%if not %index(&flow, notes) %then %do; options nonotes; %end; + +ods document close; run; +ods _all_ close; + +proc document name=&store; + ods output properties=_ads_doclist(where=(not (type eq "Dir" or + (type =: 'R' and index(type, 'p.'))))); + list / details levels=all; + run; quit; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto veryend; +ods listing; + +data _null_; + call symputx('ls', getoption('ls'), 'L'); + if 0 then set _ads_doclist nobs=nprts; + if nprts eq 0 then do; + put "ERROR: Document &store does not exist."; + call symputx('error', '1', 'L'); + end; + + length fname $ 40 c $ 1; + fname = symget('fname'); + c = substr(fname, length(fname), 1); + if '0' le c le '9' then do; + put 'ERROR: The name ' fname 'is invalid. It must not end in a numeral.'; + call symputx('error', '1', 'L'); + end; + if _error_ then call symputx('error', '1', 'L'); + stop; + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto veryend; + +* Basic option setting, checking, and processing.; +data _null_; + length c $ 1 c2 $ 2 firstobj lastobj options type $ 200 objects $ 32500; + + w = symget('width'); + if w = ' ' then w = '6.4in'; + h = symget('height'); + if h = ' ' then + call symputx('h', trim(put(0.75 * input(translate(lowcase(w), ' ', + 'incm'), 12.), best12.)) || substr(w, length(w) - 1, 2), 'L'); + else call symputx('h', trim(h), 'L'); + + options = lowcase(symget('defaultdests')); + options = compbl(options); + call symputx('defaultdests', options, 'G'); + i = index(options, 'listing'); if i then substr(options, i, 7) = ' '; + i = index(options, 'latex'); if i then substr(options, i, 5) = ' '; + + if options ne ' ' then do; + put 'ERROR: %LET ' "DEFAULTDESTS=&defaultdests is invalid."; + put 'WARNING: Choose from: listing latex.'; + call symputx('error', '1', 'L'); + end; + + options = lowcase(symget('dest')); + options = compbl(options); + + if not (options eq ' ' or options eq 'listing' or options eq 'latex') then do; + put "ERROR: DESTS=&dest is invalid."; + put 'WARNING: Choose from: listing latex.'; + call symputx('error', '1', 'L'); + end; + if options eq ' ' then options = symget('defaultdests'); + call symputx('dest', options, 'L'); + + * Flag which options were specified.; + + type = lowcase(symget('type')); + options = lowcase(symget('options')); + + tx = index(type , 'tables'); if tx then substr(type , tx, 6) = ' '; + tt = index(type , 'table'); if tt then substr(type , tt, 5) = ' '; + tl = index(type , 'listing'); if tl then substr(type , tl, 7) = ' '; + t1 = index(type , 'graphics'); if t1 then substr(type , t1, 8) = ' '; + t2 = index(type , 'graphic'); if t2 then substr(type , t2, 7) = ' '; + t3 = index(type , 'graphs'); if t3 then substr(type , t3, 6) = ' '; + t4 = index(type , 'graph'); if t4 then substr(type , t4, 5) = ' '; + no = index(options, 'nopage'); if no then substr(options, no, 6) = ' '; + nw = index(options, 'newpage'); if nw then substr(options, nw, 7) = ' '; + ap = index(options, 'autopage'); if ap then substr(options, ap, 8) = ' '; + li = index(options, 'listing'); if li then substr(options, li, 7) = ' '; + ls = index(options, 'list'); if ls then substr(options, ls, 4) = ' '; + ty = index(options, 'tables'); if ty then substr(options, ty, 6) = ' '; + ta = index(options, 'table'); if ta then substr(options, ta, 5) = ' '; + ob = index(options, 'onebox'); if ob then substr(options, ob, 6) = ' '; + g1 = index(options, 'graphics'); if g1 then substr(options, g1, 8) = ' '; + g2 = index(options, 'graphic'); if g2 then substr(options, g2, 7) = ' '; + g3 = index(options, 'graphs'); if g3 then substr(options, g3, 6) = ' '; + g4 = index(options, 'graph'); if g4 then substr(options, g4, 5) = ' '; + sf = index(options, 'skipfirst'); if sf then substr(options, sf, 9) = ' '; + sl = index(options, 'skiplast'); if sl then substr(options, sl, 8) = ' '; + + if options ne ' ' then do; + options = compbl(options); + put 'WARNING: WRITE macro OPTIONS=' options 'is invalid and is ignored.'; + end; + + if type ne ' ' then do; + type = compbl(type); + put 'WARNING: WRITE macro TYPE=' type 'is invalid and is ignored.'; + end; + + table = ta or ty or li or tt or tx or tl; + graph = g1 or g2 or g3 or g4 or t1 or t2 or t3 or t4; + + if no then call symputx('pagebreak', 'nopage'); + else if nw then call symputx('pagebreak', 'newpage'); + else call symputx('pagebreak', 'autopage'); + + call symputx('onlylist', ls ne 0, 'L'); + call symputx('onebox', ob, 'L'); + call symputx('isgraph', graph, 'L'); + call symputx('selecttype', ob or table or graph, 'L'); + call symputx('skipfirst', sf ne 0, 'L'); + call symputx('skiplast', sl ne 0, 'L'); + + if table and graph then do; + put "ERROR: TYPE=&type and OPTIONS=&options conflict."; + put "ERROR: Both tables and graphs were selected."; + call symputx('error', '1', 'L'); + end; + + * Process object names.; + firstobj = symget('firstobj'); + lastobj = symget('lastobj'); + objects = lowcase(symget('objects')); + if ob then objects = '<' || compbl(translate(objects, ' ', '<>')); + + call symputx('ngroups', '0', 'L'); + call symputx('pattern', lowcase(symget('pattern')), 'L'); + call symputx('firstobj', lowcase(firstobj), 'L'); + call symputx('lastobj', lowcase(lastobj), 'L'); + call symputx('objects', objects, 'L'); + + if (firstobj ne ' ' or lastobj ne ' ') and objects ne ' ' then do; + put 'ERROR: OBJECTS= may not be specified with FIRSTOBJ= and LASTOBJ=.'; + call symputx('error', '1', 'L'); + end; + + * Remove extra spaces and funkiness around < and >.; + if objects ne ' ' then do; + objects = ' ' || compbl(objects); + + * Get rid of trailing open brackets.; + done = 0; + do i = 1 to 32500 until(done); + l = length(objects); + if substr(objects, l, 1) eq '<' then substr(objects, l, 1) = ' '; + else done = 1; + end; + + * Get rid of multiple contiguous brackets.; + c = ' '; + done = 0; + do i = 1 to 32500 until(done); + if i gt length(objects) then done = 1; + else do; + c2 = substr(objects, i, 1); + if (c eq '<' and c2 eq '<') or + (c eq '>' and c2 eq '>') then substr(objects, i, 1) = ' '; + c2 = substr(objects, i, 1); + if not (c2 eq ' ' or c2 eq '<' or c2 eq '>') then c = ' '; + else if c2 eq '<' or c2 eq '>' then c = c2; + end; + end; + objects = ' ' || compbl(objects); + + * Move brackets next to names. + For example, change '< name' to '<name' and 'name >' to 'name>'.; + done = 0; + do i = 1 to 32500 until(done); + if i gt length(objects) then done = 1; + else do; + c2 = substr(objects, i, 2); + if c2 eq '< ' then substr(objects, i, 2) = ' <'; + if c2 eq ' >' then substr(objects, i, 2) = '> '; + c2 = substr(objects, i, 1); + if c2 eq '<' then do; + c = substr(objects, i - 1, 1); + if c ne ' ' then objects = substr(objects, 1, i - 1) || + ' <' || substr(objects, i + 1); + i + 1; + end; + else if c2 eq '>' then do; + c = substr(objects, i + 1, 1); + if c ne ' ' then objects = substr(objects, 1, i - 1) || + '> ' || substr(objects, i + 1); + i + 1; + end; + end; + end; + + * Get rid of null bracket groups.; + done = 0; + do i = 1 to 32500 until(done); + if i gt length(objects) then done = 1; + else do; + c2 = substr(objects, i, 2); + if c2 eq '<>' then substr(objects, i, 2) = ' '; + end; + end; + objects = compbl(left(objects)); + + * Get rid of leading close brackets.; + if objects =: '>' then objects = substr(objects, 2); + + call symputx('objects', left(compbl(objects)), 'L'); + end; + + call symputx('allobjflag', (firstobj eq ' ' and lastobj eq ' ' and + objects eq ' '), 'L'); + call symputx('firstflag', (firstobj eq ' ' and lastobj ne ' '), 'L'); + call symputx('lastflag' , (firstobj ne ' ' and lastobj eq ' '), 'L'); + call symputx('rangeflag', (firstobj ne ' ' and lastobj ne ' '), 'L'); + call symputx('objflag' , (objects ne ' '), 'L'); + + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto veryend; + +data _ads_doclist(drop=i p); + set _ads_doclist; + + /*-------------Translate: Special characters not shown------------- + English German Spanish French Italian + Batch Batch Batch Traitement par lots Batch + Crosstab Kreuztabelle TablaCruzada Table a double entr*e Campi incr. + Dir Dir Dir Rép. Dir + File file Archivo Fichier File + Graph Grafik Gr*fico Graphique Grafico + Note Hinweis Nota Note Nota + Report Bericht Informe Rapport Report + Table Tabelle Tabla Tableau Tabella + Text Text Texto Texte Testo + Tree Baum *rbol Arbre Struttura + */ + + if trim(type) in ('Hinweis', 'Nota') then type = 'Note'; + else if type =: 'Kreuz' or type =: 'Tabla' or type =: 'Campi' or + index(trim(type), 'double') then type = 'Crosstab'; + else if type =: 'Tab' then type = 'Table'; + else if type =: 'Gra' then type = 'Graph'; + else if type =: 'Traite' then type = 'Batch'; + else if type =: 'Te' then type = 'Text'; + else if type =: 'Fi' or type =: 'fi' or type =: 'Archi' then type = 'File'; + else if trim(type) in ('Bericht', 'Informe', 'Rapport') then type ='Report'; + else if trim(type) in ('Baum', 'Arbre', 'Struttura') or index(type, 'rbol') + then type ='Tree'; + + ObjNum = _n_; + * The variable ourpath is used for group subsetting and display in the SAS log. + It is not used for actual selection (beyond group selection).; + ourpath = substr(translate(path, '.', '\'), 2); + do i = 1 to length(ourpath) until(p eq 0); + p = index(ourpath, '#1.'); + if p then substr(ourpath, p, 3) = '. '; + end; + ourpath = compress(ourpath, ' '); + p = length(ourpath) - 1; + if substr(ourpath, p, 2) eq '#1' then substr(ourpath, p, 2) = ' '; + + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +* Get object names specified in FIRSTOBJ=, LAST=, and OBJECTS= for error checking.; +%if not &allobjflag %then %do; + data _ads_objects(keep=object); + length l $ 32500 object $ 200; + l = symget('firstobj') || ' ' || symget('lastobj') || ' ' || symget('objects'); + do i = 1 to 32500 until(object eq ' '); + object = scan(l, i, ' <>'); + if object ne ' ' then output; + end; + + if _error_ then call symputx('error', '1', 'L'); + run; + + %if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + + * Make sure every specified name is referenced.; + data _null_; + set _ads_objects; + length object holdobj $ 200; + holdobj = object; + + * Store object name with pounds and such to match document.; + %ads_expand_obj(object, holdobj) + + match = 0; + do i = 1 to nprts until(match); + set _ads_doclist nobs=nprts point=i; + + * If object has n levels, store in pathpart the last n levels from path.; + %ads_extr_path(pathpart, path, holdobj) + match = (pathpart eq object); + end; + if not match then do; + put 'ERROR: Object ' holdobj 'not found.'; + call symputx('error', '1', 'L'); + end; + + if _error_ then call symputx('error', '1', 'L'); + run; + + %if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + %end; + +* Extract the relevant tables and notes from the list.; +data _ads_select(keep=path type left right object ourpath label pagebreak); + length objlist $ 32500 fullqualobj object firstlist lastlist $ 200; + retain object firstlist lastlist objlist ' ' inflag 0 objind 1; + set _ads_doclist; + + if type eq 'Report' and label =: 'Data Set ' and path =: '\Print' + then label = substr(label, 10); + else do; + label = ' '; + if type eq 'Report' then type = 'rpt'; + end; + + left = 0; right = 0; fullqualobj = ' '; + + if _n_ eq 1 then do; + firstlist = symget('firstobj'); + lastlist = symget('lastobj'); + objlist = symget('objects'); + end; + + * Perform preliminary subsetting based on group patterns.; + %if %nrbquote(&pattern) ne %then %do; + if index(lowcase(ourpath), "&pattern"); + %end; + + righttype = 1; + if &selecttype then righttype = (( &isgraph and type eq 'Graph') or + (not &isgraph and type ne 'Graph')); + + %* Are only the last ones selected (FIRSTOBJ= specified)?; + %if &lastflag and not &allobjflag %then %do; + %ads_extr_path(pathpart, path, firstlist) + %ads_expand_obj(fullqualobj, firstlist) + if pathpart eq fullqualobj then inflag = 1; + if inflag and righttype then output; + %end; + + %* Are only the first ones selected (LASTOBJ= specified)?; + %else %if &firstflag and not &allobjflag %then %do; + if _n_ eq 1 then inflag = 1; + %ads_extr_path(pathpart, path, lastlist) + %ads_expand_obj(fullqualobj, lastlist) + if inflag and righttype then output; + if pathpart eq fullqualobj then inflag = 0; + %end; + + %* Is a range being selected (FIRSTOBJ= and LASTOBJ= specified)?; + %else %if &rangeflag and not &allobjflag %then %do; + %ads_extr_path(pathpart, path, firstlist) + %ads_expand_obj(fullqualobj, firstlist) + if pathpart eq fullqualobj then inflag = 1; + %ads_extr_path(pathpart, path, lastlist) + %ads_expand_obj(fullqualobj, lastlist) + if inflag and righttype then output; + if pathpart eq fullqualobj then inflag = 0; + %end; + + %* Is a list being selected (OBJECTS= specified)?; + %else %if &objflag and not &allobjflag %then %do; + do i = 1 to 32500 until(object eq ' '); + object = scan(objlist, i, ' '); + + if object ne ' ' then do; + + * For an object has n levels, + store in pathpart the last n levels from the path.; + %ads_extr_path(pathpart, path, object) + + left = 0; right = 0; + if substr(object, 1, 1) eq '<' then do; + left = 1; + object = substr(object, 2); + end; + if substr(object, length(object), 1) eq '>' then do; + right = 1; + object = substr(object, 1, length(object) - 1); + end; + + * Store the object name with pounds and such to match the document.; + %ads_expand_obj(fullqualobj, object) + + if fullqualobj eq pathpart then do; + if righttype then output; + object = ' '; + end; + end; + end; + %end; + + %* Is everything selected?; + %else %do; + if righttype then output; + %end; + + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + + +* Omit the first or last object from the selection list with SKIPFIRST or SKIPLAST.; +%if &skipfirst or &skiplast %then %do; + data _ads_select; + set _ads_select end=eof; + + %if &skipfirst %then %do; if _n_ = 1 then delete; %end; + %if &skiplast %then %do; if eof then delete; %end; + + if _error_ then call symputx('error', '1', 'L'); + run; + + %if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + %end; + +* Set page breaks.; +data _ads_select(keep=path type left right object ourpath group label pagebreak); + set _ads_select end=eof; + retain Group 1 oldgroup anyleft 0; + if type in ('Graph', 'Report', 'rpt') then do; + left = 1; right = 1; + if type eq 'Graph' then ngraphs + 1; + end; + if left then do; + group = oldgroup + (not &onebox); + if &onebox and group eq 0 then group = 1; + anyleft = 1; + end; + oldgroup = group; + output; + if right then anyleft = 0; + + other + (type in ('Note', 'Report', 'rpt')); + tabtype = (type in ('Table', 'Tree', 'Batch', 'Crosstab', 'Text')); + if tabtype then ntabs + 1; + if right or (not anyleft and tabtype) then group = oldgroup + (not &onebox); + + if eof and &onebox and &isgraph and ((ntabs + other) or ngraphs ne 1) then do; + put 'ERROR: The Graphic tag must select ' + 'only one graph and nothing ' "else in document &store.."; + call symputx('onlylist', '1', 'L'); + call symputx('abnormal', '1', 'L'); + end; + + if eof and &onebox and not &isgraph and ((ntabs + other) lt 1 or ngraphs) + then do; + put 'ERROR: The Listing tag must select tables and no graphs ' + "in document &store.."; + call symputx('onlylist', '1', 'L'); + call symputx('abnormal', '1', 'L'); + end; + + if not &onlylist and eof and + not &onebox and (ntabs + other) and ngraphs then do; + put 'ERROR: You may request either tables or graphs but not both ' + "in document &store.."; + call symputx('onlylist', '1', 'L'); + call symputx('abnormal', '1', 'L'); + end; + + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +%if %index(&flow, print) %then %do; + proc print; var path type group object; run; + proc print; var ourpath type group object; run; + %end; + +* Check for objects that match multiple document pieces.; +%if not &allobjflag %then %do; + proc sort data=_ads_select out=_ads_objects; + by object; + run; + + %if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + + data _null_; + set _ads_objects; + by object; + if object ne ' ' and not (first.object and last.object) then do; + put 'ERROR: Multiple matches. Object ' object + 'matches ' ourpath +(-1)'.'; + call symputx('error', '1', 'L'); + end; + if _error_ then call symputx('error', '1', 'L'); + run; + + %if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + %end; + +* Clear out titles, subtitles, and footnotes as necessary. Build rendering code.; +options nosource; + +data _null_; + length list $ 32500; + retain list ' ' forcepage &&__New_&store; + set _ads_select end=end; + by group; + if _n_ eq 1 then call execute("proc document name=&store;"); + + list = trim(list) || ' or _path_ = "' || trim(path) || '"'; + + %if &pagebreak eq autopage %then %do; /* default */ + first = pagebreak; + if type ne 'Graph' then do; + first = (first or forcepage); + forcepage = 0; + end; + %end; + %else %if &pagebreak eq nopage %then %do; + first = 0; + %end; + %else %do; /* new page */ + first = ((_n_ eq 1) or pagebreak); + %end; + + if first and type ne 'Graph' then put 'Note: New page for ' path; + + if first then call execute("obfootn " || path || ';'); + else if end then call execute('obtitle ' || path || '; obstitle ' || + path || '; run; quit;'); + else call execute('obfootn ' || path || '; obstitle ' || path || + '; obtitle ' || path || ';'); + + if last.group then do; + list = substr(list, 5); + call symputx('_list' || left(put(group, 5.)), trim(list), 'L'); + call symputx('_gtype' || left(put(group, 5.)), put(type, $1.), 'L'); + call symputx('ngroups', group, 'L'); + if type eq 'Report' then + call symputx('_data' || left(put(group, 5.)), trim(label), 'L'); + list = ' '; + end; + + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +options source &savenote; + +%let __new_&store = 0; + +%if &onebox and &ngroups ne 1 and not &abnormal %then %do; + %if &isgraph %then %let i = Graphic; + %else %let i = Listing; + %put ERROR: There must be exactly one group of objects with &i..; + %let onlylist = 1; + %let abnormal = 1; + %end; + +* Render each group of data objects.; +%if not &onlylist %then %do; + ods _all_ close; + ods graphics / reset=index imagename=""; + + %let kl = 0; %let kh = 0; + %do i = 1 %to &ngroups; + + %if %symexist(_list&i) %then %do; + %if &kl eq 0 %then %let jl = ; %else %let jl = &kl; + %if &kh eq 0 %then %let jh = ; %else %let jh = &kh; + %let kl = %eval(&kl + 1); + %let kh = %eval(&kh + 1); + + %if &&_gtype&i eq G %then %do; /* if graph replay */ + %if %nrbquote(&graphtype) eq pdf %then %do; + %if (%nrbquote(&sysver) < 9.3) %then %do; + %put WARNING: ODS PDF Graphics are unavailable in SAS 9.2; + %put WARNING: Generating PNG format in "png" directory.; + %let graphtype=png; + %let graphicdir=png; + %end; + %end; + + ods listing style=&style image_dpi=&dpi gpath="&graphicdir"; + ods graphics / reset=index imagename="&fname&jl" &odsgraphopts + %if %nrbquote(&width) ne %then width=&width; + %if %nrbquote(&height) ne %then height=&height; + %if %nrbquote(&graphtype) eq pdf %then outputfmt=pdf;; + + %if %sysprod(graph) = 1 %then %do; + goptions dev=&gdevice fileonly gsfname=gsasfile gsfmode=replace + hsize= + %if %nrbquote(&width) ne %then &width; + %else 6.4in; + vsize=&h border; + %end; + filename gsasfile "&graphicdir/&fname&jl..&graphtype"; + %put NOTE: Writing Graph file: &graphicdir/&fname&jl..&graphtype; + %end; + %else %do; + %if %index(&dest, listing) %then %do; + ods listing file="&listingdir/_tmp"; + %end; + %if %index(&dest, latex) %then %do; + ods tagsets.statrep style=&latexstyle + file="&latexdir/&fname&jh..tex" (notop nobot) + stylesheet="&rootdir/sas.sty" + newfile=output ; + %end; + %end; + %if not %index(&flow, notes) %then %do; options nonotes; %end; + proc document name=&store; + replay ^(where=(&&_list&i)) / levels=all; + run; quit; + %if &syserr > 4 %then %let error = 1; + %if &error %then %goto endit; + options &savenote; + %if &&_gtype&i eq G %then %do; /* if graph replay */ + filename gsasfile "&graphicdir/_tmp.&graphtype"; + %end; + ods _all_ close; + ods graphics / reset=index imagename="" reset=width reset=height; + %if &&_gtype&i ne G and /* if not graph */ + %index(&dest, listing) %then %do; + /* break up big listing files */ + options nonotes; + data _null_; + retain kl &jl; + length fn $ 200; + infile "&listingdir/_tmp" lrecl=%eval(&ls+1) pad; + input line $char%eval(&ls+1).; + page = substr(line, 1, 1) eq '0C'x; + if _n_ eq 1 or page then do; + fn = "&listingdir/&fname"; + if page then line = substr(line, 2); + if kl then fn = compress(fn || put(kl, 5.) || '.lst'); + else fn = compress(fn || '.lst'); + kl + 1; + call symputx('kl', kl, 'L'); + put 'Note: Writing Listing file : ' fn; + end; + file x filevar=fn nopad; + l = length(line); + put line $varying. l; + if _error_ then call symputx('error', '1', 'L'); + run; + %if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + options &savenote; + %end; + %end; + %end; + ods listing; +%end; + +%if &ngroups eq 0 %then %do; + %put ERROR: No objects selected.; + %let error = 1; + %goto endit; + %end; + +%if not %index(&flow, notes) %then %do; options nonotes; %end; + +proc sort data=_ads_doclist; by path; run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +proc sort data=_ads_select; by path; run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +data _ads_doclist; + merge _ads_doclist(in=dl) _ads_select(keep=path group in=s); + by path; + if s then Status = 'Selected'; + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +proc sort data=_ads_doclist; by objnum; run; + +%if &syserr > 4 %then %let error = 1; %if &error %then %goto endit; + +%endit:; + +* Get some formatting information for rendering the document contents list.; +data _null_; + set _ads_doclist end=eof; + left = max(left, length(ourpath)); + tyw = max(tyw, length(type)); + if eof then do; + left + 1; tyw + 1; stw = 9; grw = 5; + atright = min(&ls - tyw - stw - grw - 1, left + 3); + call symputx('atright', atright, 'L'); + call symputx('tyw', tyw, 'L'); + call symputx('stw', stw, 'L'); + call symputx('grw', grw, 'L'); + end; + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; + +* Render the document contents list, wrapping the path if necessary.; +data _null_; + length p $ 500; + status = ' '; group = .; + file log; + set _ads_doclist; + ghead = 'Group'; thead = 'Type'; shead = 'Status'; + if _n_ eq 1 then put / 'Objects' + @&atright thead $&tyw.. + @%eval(&atright+&tyw) shead $&stw.. + @%eval(&atright+&tyw+&stw) ghead $&grw.. /; + do j = 1 to 100 while(ourpath ne ' '); + do l = &atright - 2 to &atright / 2 by -1 + while(not (substr(ourpath, l, 1) in ('.', ' '))); + end; + p = substr(ourpath, 1, l); + if j eq 1 then + put p $%eval(&atright-2). +1 type $&tyw.. status $&stw.. group 3.; + else put p $%eval(&atright-2).; + ourpath = substr(ourpath, l + 1); + end; + if _error_ then call symputx('error', '1', 'L'); + run; + +%if &syserr > 4 %then %let error = 1; + +%veryend:; + +* Clean up.; +%if not %index(&flow, notes) %then %do; options nonotes; %end; +proc datasets nolist; delete _ads_select _ads_doclist _ads_objects; run; quit; + +%if &syserr > 4 %then %let error = 1; + +%let syslast = &holdlast; +%if &error or &abnormal %then %put ERROR: Macro write ended abnormally.; +run; + +filename __f1 "&listingdir/_tmp"; +filename __f2 "&graphicdir/_tmp.&graphtype"; +data _null_; rc = fdelete('__f1'); rc = fdelete('__f2'); run; + +options obs=max nosyntaxcheck &savenote &savetime &savesize; +%mend; + +*------------------------------------------------------------------------; + + /*---------------------------------------------*/ + /* The OUTPUT macro opens an ODS document and */ + /* captures output until it encounters an */ + /* ENDOUTPUT macro or a WRITE macro. */ + /*---------------------------------------------*/ +%macro output(label, /* is a required keyword that specifies the */ + /* ODS document name. This is used in the */ + /* STORE= option in the WRITE macro and in */ + /* \Listing and \Graphic tags. */ + /* */ + style=, /* specifies the ODS style for GRSEG graphics. */ + /* Use the STYLE= option in the WRITE macro to */ + /* control the style for ODS Graphics. If */ + /* STYLE= is specified, that style is used. */ + /* If STYLE= is not specified, and if a macro */ + /* variable DefaultStyle is defined, its value */ + /* is used as the style. If STYLE= is not */ + /* specified and the macro variable */ + /* DefaultStyle is not defined or if its value */ + /* is null, then the default style (which is */ + /* the HTMLBLUE style) is used. */ + /* */ + /* In other words, the default style is the */ + /* HTMLBLUE style. However, you can set the */ + /* default style to (say) LISTING by putting */ + /* the following line at the top of your first */ + /* Sascode block, beginning in column 1: */ + /* */ + /* %*;%let defaultstyle=listing; */ + /* */ + /* Since this line begins with a null macro */ + /* comment (%*;) in column 1, it will not show */ + /* up in the SAS code listing, but it will */ + /* affect the capture program and change the */ + /* default style for the duration of the */ + /* running of the program. */ + /* */ + dpi=);; /* specifies DPI (dots per inch) for GRSEG */ + /* graphics. You typically would not use this */ + /* except when you would otherwise run out of */ + /* memory. The default is 300 DPI, and a */ + /* reasonable alternative for GRSEG graphs */ + /* with a large file size is 96 DPI. More */ + /* details follow. */ + /* */ + /* With GRSEG graphics, you do not have */ + /* continuous control over DPI as you do with */ + /* ODS Graphics. With the macro default DPI */ + /* of 300, you get 300 DPI. Otherwise, you */ + /* get the device default of 96 DPI. */ + /* */ + /* This option controls the DPI for GRSEG */ + /* graphics. Use the DPI= option in the WRITE */ + /* macro to control the style for ODS */ + /* Graphics. If DPI= is specified, that DPI */ + /* is used. If DPI= is not specified, and if */ + /* a macro variable DefaultDPI is defined, its */ + /* value is used as the DPI. If DPI= is not */ + /* specified and the macro variable DefaultDPI */ + /* is not defined or if its value is null, */ + /* then the default DPI (300) is used. */ + /* */ + /* In other words, the default DPI is 300. */ + /* However, you can set the default DPI for */ + /* GRSEG graphics to 96 by putting the */ + /* following line at the top of your first */ + /* Sascode block, beginning in column 1: */ + /* */ + /* %*;%let defaultdpi=100; */ + /* */ + /* This is not a typo. If you set the default */ + /* DPI to anything other than 300, you get 96 */ + /* DPI with GRSEG graphics and the specified */ + /* value with ODS Graphics. With ODS */ + /* Graphics, the values of 300 and 100 are */ + /* most commonly used. */ + /* */ + /* Since the %LET statement is preceded by a */ + /* null macro comment (%*;) in column 1, it */ + /* will not show up in the SAS code listing, */ + /* but it will affect the capture program and */ + /* change the default DPI for the duration of */ + /* the running of the program. You can change */ + /* DPI at any time with one of these */ + /* statements. */ + /*---------------------------------------------*/ + +%local log lst savenote gdevice; + +* Set the default style using STYLE= and a DefaultStyle macro variable; +%if &style eq %then %let style = &defaultstyle; + +* Set the default DPI using DPI= and a DefaultDPI macro variable; +%if &dpi eq %then %let dpi = &defaultDPI; + +%let graphtype = %qlowcase(&graphtype); +%if %nrbquote(&graphtype) ne pdf %then %let graphtype = png; +%let gdevice = %substr(png300, 1, 3 * (1 + (&dpi eq 300))); +%if %nrbquote(&graphtype) eq pdf %then %let gdevice = pdf; + +%if not (&dpi eq 96 or &dpi eq 100 or &dpi eq 300) + %then %put NOTE: DPI=96 will be used for GRSEG graphics.; + +%let savenote = %sysfunc(getoption(notes)); +%if %sysfunc(symexist(_ads_debug)) %then %do; + %let log = 0; + %let lst = 0; + %let _ads_debug = %lowcase(&_ads_debug); + %if %index(&_ads_debug, flowall) %then %do; + %let log = 1; + %let lst = 1; + %end; + %else %if %index(&_ads_debug, flowlog) %then %let log = 1; + %else %if %index(&_ads_debug, flowlst) %then %let lst = 1; + %if &log or &lst %then %do; + ods listing; + data _null_; + %if &log %then %do; put "Begin Sascode block ""&label""."; %end; + %if &lst %then %do; + file print; + put _page_; + put "Begin Sascode block ""&label""."; + %end; + run; + %end; + %end; + +run; quit; + +options nonotes; +libname mydir '.'; +options nodate nonumber obs=max nosyntaxcheck; +%global documentlabel; + +ods _all_ close; +ods document close; + +data _null_; call symputx("__New_&label", '1', 'G'); run; + +proc datasets nolist nowarn; + delete gseg(memtype=catalog); + run; quit; + +proc datasets nolist nowarn library=sasuser; + delete __&label(memtype=catalog); + run; quit; + +* Select the style for GRSEG graphics.; +ods listing style=&style file="&listingdir/_tmp"; +ods listing select none; +filename __f "&listingdir/_tmp"; +data _null_; rc = fdelete('__f'); run; + +* Set the global label, and open the ODS Document.; +%let documentLabel = &label; +ods document name = &label(write) cat=sasuser.__&label; + +* Specify 300 DPI for GRSEG graphics (gdevice = png or png300).; +%if %sysprod(graph) = 1 %then %do; + goptions dev=&gdevice fileonly gsfname=gsasfile gsfmode=replace border; +%end; +filename gsasfile "&graphicdir/_tmp.&graphtype"; +options &savenote; +%mend; + +*------------------------------------------------------------------------; + + /*---------------------------------------------*/ + /* The ENDOUTPUT macro ends output capture. */ + /*---------------------------------------------*/ +%macro endoutput(label);;/* specifies the ODS document name. This is */ + /* used only to display program flow */ + /* information in the SAS log when the macro */ + /* variable _ads_debug is defined. */ + /*---------------------------------------------*/ + +run; quit; +options obs=max nosyntaxcheck; +ods document close; + +%local log lst; + +%if %sysfunc(symexist(_ads_debug)) %then %do; + %let log = 0; + %let lst = 0; + %let _ads_debug = %lowcase(&_ads_debug); + %if %index(&_ads_debug, flowall) %then %do; + %let log = 1; + %let lst = 1; + %end; + %else %if %index(&_ads_debug, flowlog) %then %let log = 1; + %else %if %index(&_ads_debug, flowlst) %then %let lst = 1; + %if &log or &lst %then %do; + ods listing; + data _null_; + %if &log %then %do; put "End Sascode block ""&label""."; %end; + %if &lst %then %do; + file print; + put "End Sascode block ""&label""."; + put _page_; + %end; + run; + %end; + %end; +ods _all_ close; +%mend; + +*------------------------------------------------------------------------; + + /*---------------------------------------------*/ + /* The STARTLIST macro starts the capture of */ + /* listing output. Use this macro when you */ + /* want to program your own output capture */ + /* (for example, when you want to show only */ + /* part of a table). */ + /*---------------------------------------------*/ +%macro startlist(fname, /* is a required keyword that specifies the */ + /* first level of the output file name. This */ + /* name will appear at the end of the \Listing */ + /* tag. */ + /* */ + pagesize=, /* specifies page size. The default is the */ + /* page size currently in effect. This */ + /* specification lasts for the duration of */ + /* this step. The current page size is */ + /* restored at the end. */ + linesize=);;/* specifies line size. The default is the */ + /* line size currently in effect. This */ + /* specification lasts for the duration of */ + /* this step. The current line size is */ + /* restored at the end. */ + /*---------------------------------------------*/ + +%global _ads_printfname _ads_savesize; +%let _ads_printfname = &fname; +%let _ads_savesize = ls=%sysfunc(getoption(ls)) ps=%sysfunc(getoption(ps)); +quit; +ods _all_ close; +ods document close; +options nodate nonumber %if &pagesize ne %then ps=&pagesize; + %if &linesize ne %then ls=&linesize;; +ods listing file="&listingdir/_tmp"; +%mend; + + /*---------------------------------------------*/ +%macro endlist;; /* The ENDLIST macro ends the capture of */ + /* listing output. */ + /*---------------------------------------------*/ +%local ls savenote; +run; +ods _all_ close; +%let ls = %sysfunc(getoption(ls)); +%let savenote = %sysfunc(getoption(notes)); + +options nonotes; +data _null_; + retain kl 0; + length fn $ 40; + infile "&listingdir/_tmp" lrecl=%eval(&ls+1) pad; + input line $char%eval(&ls+1).; + page = substr(line, 1, 1) eq '0C'x; + if _n_ eq 1 or page then do; + ext = 'lst';; + fn = ext || "/&_ads_printfname"; + if page then line = substr(line, 2); + if kl then fn = compress(fn || put(kl, 5.) || '.' || ext); + else fn = compress(fn || '.' || ext); + kl + 1; + put 'Note: Writing Print file: ' fn; + end; + file x filevar=fn nopad; + l = length(line); + put line $varying. l; + run; + +options &savenote &_ads_savesize; + +filename __f "&listingdir/_tmp"; +data _null_; rc = fdelete('__f'); run; +%mend; + +*------------------------------------------------------------------------; + + /*---------------------------------------------*/ + /* The STARTLOG macro starts the capture of */ + /* the SAS log. */ + /*---------------------------------------------*/ +%macro startlog(fname);; /* is a required keyword that specifies the */ + /* first level of the output file name. This */ + /* name will appear at the end of the \Listing */ + /* tag. */ + /*---------------------------------------------*/ +%global __fname __ls; +%let __fname=&fname; +%let __ls = %sysfunc(getoption(ls)); + +options nostimer nosource2 nosource; +proc printto log="&listingdir/__tmp" new; run; +%mend; + + + /*---------------------------------------------*/ + /* The ENDLOG macro ends the capture of the */ + /* SAS log. */ + /*---------------------------------------------*/ +%macro endlog(store=1, /* set STORE=0 to capture messages only and */ + /* not code. */ + range=1);; /* Specify a Boolean expression to select only */ + /* certain observations. Examples: */ + /* RANGE=_n_ < 5, */ + /* RANGE=not index(line, 'ERROR'). */ + /*---------------------------------------------*/ + +%local savenote; +%let savenote = %sysfunc(getoption(stimer)) %sysfunc(getoption(source2)) + %sysfunc(getoption(source)); + +proc printto log=log; run; + +options stimer source2 source; + +data _null_; + infile "&listingdir/__tmp" lrecl=%eval(&__ls+4) pad; + input line $char&__ls..; + if anycntrl(line) = 0; + %if &store %then %do; + if index(line, '%endlog') = 0; + %end; + %else %do; + if not (n(input(scan(line, 1, ' +'), ?? 12.)) and + compress(line, ' 0123456789') =: '+'); + %end; + if ⦥ + file "&listingdir/&__fname..lst" lrecl=%eval(&__ls+4); + put line $char&__ls..; + run; + +filename __f "&listingdir/__tmp"; +data _null_; rc = fdelete('__f'); run; + +options &savenote; +%mend; + +*------------------------------------------------------------------------; + +* This utility macro stores in the out macro variable the + object name with pounds and such to match the name in the document.; +%macro ads_expand_obj(out, in); + length _w $ 200; + &out = ' '; + do _j = 1 to 32500 until(_w = ' '); + _w = scan(&in, _j, '.'); + if _w ne ' ' then do; + if not index(_w, '#') then _w = trim(_w) || '#1'; + &out = trim(&out) || '\' || _w; + end; + end; + &out = substr(&out, 3); + %mend; + +* This utility macro stores in the out macro variable the last n levels + (for an object with n levels) from the path.; +%macro ads_extr_path(out, path, object); + _levs = 1 + length(&object) - length(compress(&object, '.')); + call scan(&path, -_levs, _p, _len, '\'); + &out = lowcase(substr(&path, max(_p, 1))); + if substr(&out, 1, 1) eq '\' then &out = substr(&out, 2); + %mend; + +*------------------------------------------------------------------------; + +* 'this macro creates a directory if needed and deletes files with the +given extension to insure the directory exists and is empty of output files.; + +%macro cleandir(droot, dname, ext); + %local saveopts; + %let saveopts = %sysfunc(getoption(notes)); + options nonotes; + data _null_; + length ext $ 5 ; + droot = symget('droot'); + dname = symget('dname'); + ext = cats('.', upcase(symget('ext'))); + dpath = cats(droot, '/', dname); + + rc = filename('dref', droot); + rc = fexist('dref'); + if rc eq 0 then do; + put 'ERROR: Directory ' droot 'not found.'; + stop; + end; + + rc = filename('dref', dpath); + rc = fexist('dref'); + if rc eq 0 then do; + dpath = dcreate(dname, droot); + rc2 = filename('dreff', dpath); + rc2 = fexist('dreff'); + if rc2 eq 0 then do; + put 'ERROR: Directory ' dpath 'not created.'; + stop; + end; + else do; + put 'Note: Directory ' dpath 'created.'; + end; + end; + else do; + rc = filename('dreff', dpath); + did = dopen('dreff'); + if rc or not did then do; + put 'ERROR: Directory ' dpath 'not found.'; + stop; + end; + do i = 1 to dnum(did); /* Loops through entire directory */ + file = dread(did, i); + if index(upcase(file), ext) then do; /* file ends in dot extension */ + rc = filename('fref', cats(dpath, '/', file)); + rc = fdelete('fref'); + end; + end; + rc = dclose(did); + end; + run; + options &saveopts; +%mend cleandir; + + diff --git a/macros/latex/contrib/statrep/sas/statrep_tagset.sas b/macros/latex/contrib/statrep/sas/statrep_tagset.sas new file mode 100644 index 0000000000..819157c07d --- /dev/null +++ b/macros/latex/contrib/statrep/sas/statrep_tagset.sas @@ -0,0 +1,566 @@ +proc template; + define style styles.StatRep; + parent = styles.statistical; + class colors / + 'link2' = cx0000FF + 'link1' = cx800080 + 'docbg' = cxFFFFFF + 'contentbg' = cxFFFFFF + 'systitlebg' = cxFFFFFF + 'titlebg' = cxFFFFFF + 'proctitlebg' = cxFFFFFF + 'headerbg' = cxFFFFFF + 'captionbg' = cxFFFFFF + 'captionfg' = cx000000 + 'bylinebg' = cxFFFFFF + 'notebg' = cxFFFFFF + 'tablebg' = cxFFFFFF + 'batchbg' = cxFFFFFF + 'systitlefg' = cx000000 + 'titlefg' = cx000000 + 'proctitlefg' = cx000000 + 'bylinefg' = cx000000 + 'notefg' = cx000000; + class Header / + color = cx000000 + backgroundcolor = cxFFFFFF + bordercolor = cxB0B7BB + bordercollapse = collapse; + class RowHeader / + color = cx000000 + backgroundcolor = cxFFFFFF + bordercolor = cxB0B7BB + bordercollapse = collapse; + class Footer / + color = cx000000 + backgroundcolor = cxFFFFFF + bordercolor = cxB0B7BB + bordercollapse = collapse; + class RowFooter / + color = cx000000 + backgroundcolor = cxFFFFFF + bordercolor = cxB0B7BB + bordercollapse = collapse; + class batch / + borderwidth = 0px; + class Data / + font = fonts('DocFont') + backgroundcolor = _undef_ + bordercolor = cx919191 + bordercollapse = collapse; + class DataEmphasis / + font = fonts('DocFont') + backgroundcolor = _undef_ + bordercolor = cx919191 + bordercollapse = collapse; + end; +run; + +proc template; +define tagset Tagsets.StatRep; + notes "This is the StatRep LaTeX definition"; + + define event initialize; + trigger set_options; + end; + + define event set_options; + set $options["junk" ] "junk" /if ^$options; + unset $cell_align; + + do /if cmp( $options["CELL_ALIGN"], "yes"); + set $cell_align "True"; + done; + + end; + + define event title_format_section; + put value; + end; + + define event cell_is_empty; + put " "; + end; + + define event list; + start: + put "\begin{itemize}" NL; + + finish: + put "\end{itemize}" NL; + end; + + define event list_item; + put "\item "; + end; + + define event list_entry; + put "\item "; + end; + + define event image; + put "\sasgraph{"; + put BASENAME /if ^exists( NOBASE); + put URL; + put "}" NL; + end; + + define event line; + put "\rule{\linewidth}{" colwidth; + put "pt}" NL; + end; + + define event text; + start: + put "\par " NL; + end; + + define event paragraph; + start: + put VALUE; + put NL; + put NL; + end; + + define event preformat; + start: + put "\verb?" NL; + + finish: + put "?" NL; + end; + + define event center; + start: + put "\begin{center}" NL; + + finish: + put "\end{center}" NL; + end; + + define event styles; + start: + put NL; + put "\RequirePackage[T1]{fontenc}" NL; + put "\RequirePackage{times}" NL; + put "\RequirePackage{fancyvrb}" NL; + put "\RequirePackage{array}" NL; + put "\RequirePackage{graphicx}" NL; + put NL; + put "\newbox\sas@fig" NL; + put "\newlength\sas@figwidth" NL; + put NL; + put "\newif\ifsas@color" NL; + put "\sas@colorfalse" NL; + put NL; + put "\DeclareOption{color}{\sas@colortrue}" NL; + put "\ProcessOptions" NL; + put NL; + + finish: + put %nrstr("%% Set cell padding") NL; + put "\renewcommand{\arraystretch}{1.3}" NL NL; + put %nrstr("%% Headings") NL; + put %nrstr("\newcommand{\sasheading}[3][c]{{%%") NL; + put %nrstr(" \if#1r\flushright\else\if#1l\flushleft\else\centering\fi\fi%%") NL; + put %nrstr(" {\csname sasS#2\endcsname #3}\mbox{}\\[0.1\baselineskip]%%") NL; + put %nrstr(" \if#1r\endflushright\else\if#1l\endflushleft\else\fi\fi%%") NL; + put "}}" NL; + put NL; + put "\newcommand{\sasbyline}[2][c]{\sasheading[#1]{byline}{#2}}" NL; + put "\newcommand{\sassystemtitle}[2][c]{\sasheading[#1]{systemtitle}{#2}}" NL; + put "\newcommand{\sassystemfooter}[2][c]{\sasheading[#1]{systemfooter}{#2}}" NL; + put "\newcommand{\sasproctitle}[2][c]{\sasheading[#1]{proctitle}{#2}}" NL; + put "\newcommand{\sascaption}[2][l]{\marginpar[#1]{\fbox{\parbox{0.7in}{\sasScaption{#2}}}}}" NL; + put NL; + put %nrstr("%% Declare new verbatim type") NL; + put %nrstr("\DefineVerbatimEnvironment{sasverbatim}{BVerbatim}%%") NL; + put " {fontsize=\footnotesize," NL; + put " commandchars=\\\{\}," NL; + put " formatcom=\sasSbatch}" NL; + put NL; + put %nrstr("%% Declare new column types") NL; + put "\newcolumntype{S}[2]{>{\csname sasS#1\endcsname}#2}" NL; + put "\newcolumntype{d}{r}" NL; + put NL; + put %nrstr("%% Set warning box style") NL; + put "\newlength\notewidth" NL; + put "\setlength\notewidth{4in}" NL; + put "\newcommand*{\saswarn}[2][c]{\sasmsg{warn}{#1}{#2}}" NL; + put "\newcommand*{\saserror}[2][c]{\sasmsg{error}{#1}{#2}}" NL; + put "\newcommand*{\sasnote}[2][c]{\sasmsg{note}{#1}{#2}}" NL; + put "\newcommand*{\sasfatal}[2][c]{\sasmsg{fatal}{#1}{#2}}" NL; + put %nrstr("\newcommand*{\sasmsg}[3]{%%") NL; + put %nrstr(" \ifsas@color\let\columncolor\undefined\fi%%") NL; + put %nrstr(" \begin{center}%%") NL; + put %nrstr(" \begin{tabular}{ll}\hline%%") NL; + put %nrstr(" \multicolumn{1}{|S{#1banner}{p{0.7in}}|}{#1} & %%") NL; + put %nrstr(" \multicolumn{1}{|S{#1content}{p{\notewidth}}|}{#3{\newline}}\\\hline%%") NL; + put %nrstr(" \end{tabular}%%") NL; + put %nrstr(" \end{center}%%") NL; + put %nrstr(" \ifsas@color\let\columncolor\sascolumncolor\fi%%") NL; + put "}" NL; + put NL; + put "\ifsas@color\RequirePackage{colortbl}\fi" NL; + put NL; + put %nrstr("%% Hack colortbl to allow \columncolor in macros") NL; + put "\let\CT@extract@org\CT@extract" NL; + put "\def\CT@extract{\futurelet\CT@NEXT\CT@extract@next}" NL; + put %nrstr("\def\CT@extract@next{%%") NL; + put " \ifx\CT@NEXT\csname" NL; + put %nrstr(" \@ReturnAfterFi{%%") NL; + put " \expandafter\expandafter\expandafter" NL; + put %nrstr(" }%%") NL; + put " \fi" NL; + put " \CT@extract@org" NL; + put "}" NL; + put "\long\def\@ReturnAfterFi#1\fi{\fi#1}" NL; + put "" NL; + put "\ifsas@color" NL; + put "" NL; + put " \newcommand{\foreground}[1]{\color[rgb]{#1}}" NL; + put " \newcommand{\sascolumncolor}[2][]{}" NL; + put " \let\columncolor\sascolumncolor" NL; + put " \newcommand{\documentforeground}[1]{\AtBeginDocument{\color[rgb]{#1}}}" NL; + put " \newcommand{\documentbackground}[1]{\AtBeginDocument{\pagecolor[rgb]{#1}}}" NL; + put " \def\sastable{\let\columncolor\undefined\tabular}" NL; + put " \def\endsastable{\endtabular\let\columncolor\sascolumncolor}" NL; + put " \def\stackedcell{\bgroup\renewcommand{\arraystretch}{1}\tabular}" NL; + put " \def\endstackedcell{\endtabular\egroup}" NL; + put NL; + put "\else" NL; + put NL; + put " \providecommand{\foreground}[1]{}" NL; + put " \providecommand{\color}[2][]{}" NL; + put " \newcommand{\sascolumncolor}[2][]{}" NL; + put " \let\columncolor\sascolumncolor" NL; + put " \newcommand{\documentforeground}[1]{}" NL; + put " \newcommand{\documentbackground}[1]{}" NL; + put " \def\sastable{\tabular}" NL; + put " \def\endsastable{\endtabular}" NL; + put " \def\stackedcell{\bgroup\renewcommand{\arraystretch}{1}\tabular}" NL; + put " \def\endstackedcell{\endtabular\egroup}" NL; + put "" NL; + put "\fi" NL; + put NL; + put %nrstr("%%\let\sasgraph\includegraphics") NL; + put %nrstr("%% Scale graphics so they always fit on the page") NL; + put %nrstr("\newcommand\sasgraph[2][]{%%") NL; + put %nrstr(" \savebox{\sas@fig}{\includegraphics[#1]{#2}}%%") NL; + put %nrstr(" \settowidth{\sas@figwidth}{\usebox{\sas@fig}}%%") NL; + put %nrstr(" \ifthenelse{\lengthtest{\sas@figwidth > \textwidth}}{%%") NL; + put %nrstr(" \resizebox{0.95\textwidth}{!}{\usebox{\sas@fig}}}{%%") NL; + put " \usebox{\sas@fig}}" NL; + put "}" NL; + put NL; + end; + + define event style_class; + start: + put "\def\sasS" lowcase(HTMLCLASS) %nrstr("{%%") NL; + put " " FONT_SIZE %nrstr("%%") NL /if exists( FONT_SIZE); + put " " FONT_WEIGHT %nrstr("%%") NL /if exists( FONT_WEIGHT); + put " " FONT_STYLE %nrstr("%%") NL /if exists( FONT_STYLE); + put " " FONT_FACE %nrstr("%%") NL /if exists( FONT_FACE); + put " \color[rgb]{" FOREGROUND %nrstr("}%%") NL /if exists( foreground); + put " \columncolor[rgb]{" BACKGROUND %nrstr("}%%") NL /if exists( background); + set $foreground foreground /if cmp( htmlclass, "body"); + set $background background /if cmp( htmlclass, "body"); + + finish: + put "}" NL; + end; + + define event caption; + start: + set $sascaption "true"; + block table; + block row; + block colspecs; + block colspec_entry; + put "\sascaption["; + put "l" /if cmp( TYPE, "L"); + put "r" /if cmp( TYPE, "R"); + put "b" /if cmp( TYPE, "B"); + put "t" /if cmp( TYPE, "T"); + put "]{"; + + finish: + put "}" NL; + unblock table; + unblock row; + unblock colspecs; + unblock colspec_entry; + set $sascaption "false"; + end; + + define event table; + start: + put NL; + put NL; + put "\begin{sastable}"; + + trigger alignment; + + finish: + put "\end{sastable}" NL; + put NL; + end; + + define event verbatim_text; + put VALUE; + put NL; + end; + + define event verbatim_container; + start: + put NL; + put NL; + put "\begin{center}" NL /if cmp( just, "c"); + put "\begin{sasverbatim}" NL; + + finish: + put "\end{sasverbatim}" NL; + put "\end{center}" NL /if cmp( just, "c"); + put NL; + end; + + define event alignment; + start: + put "[c]" /if cmp( just, "c"); + put "[c]" /if cmp( just, "d"); + put "[r]" /if cmp( just, "r"); + put "[l]" /if cmp( just, "l"); + flush; + end; + + define event colspecs; + start: + put "{"; + + finish: + put "}\hline" NL; + end; + + define event colspec_entry; + put just /if ^cmp( just, "d"); + put "r" /if cmp( just, "d"); + end; + + define event row; + + finish: + put NL "\\\hline" NL; + end; + + define event rowspanfillsep; + put %nrstr(" & ") NL; + end; + + define event rowspancolspanfill; + put " "; + put "\multicolumn{"; + put colspan; + put "1" /if ^exists( colspan); + put "}"; + put "{|S{"; + put lowcase(HTMLCLASS); + put "data" /if ^htmlclass; + put "}{"; + put just; + put "}|}{~}"; + end; + + define event header; + start: + + trigger data; + + finish: + + trigger data; + end; + + define event data; + start: + put VALUE /if cmp( $sascaption, "true"); + break /if cmp( $sascaption, "true"); + put %nrstr(" & ") NL /if ^cmp( COLSTART, "1"); + put " "; + put "\multicolumn{"; + put colspan; + put "1" /if ^colspan; + put "}"; + put "{"; + put "|" /if ^$instacked; + put "S{"; + put lowcase(HTMLCLASS); + put "}{"; + put just; + put "}"; + put "|" /if ^$instacked; + put "}"; + put "{"; + put tranwrd(VALUE,"-","$-$") /if contains( lowcase(HTMLCLASS), "data"); + put VALUE /if ^contains( lowcase(HTMLCLASS), "data"); + + finish: + break /if cmp( $sascaption, "true"); + put "}"; + end; + + define event data_note; + start: + + trigger data; + + finish: + + trigger data; + end; + + define event stacked_cell; + start: + put NL; + put "\begin{stackedcell}"; + + trigger alignment; + + finish: + put "\end{stackedcell}" NL; + end; + + define event stacked_value; + start: + unset $instacked; + set $instacked "true"; + + trigger data; + + finish: + + trigger data; + unset $instacked; + end; + + define event stacked_value_header; + start: + + trigger stacked_value; + + finish: + + trigger stacked_value; + end; + + define event stacked_cell_colspecs; + start: + put "{"; + + finish: + put "}" NL; + end; + + define event stacked_cell_colspec_entry; + put just /if ^cmp( just, "d"); + put "r" /if cmp( just, "d"); + end; + + define event stacked_cell_row; + + finish: + put NL "\\" NL; + end; + + define event put_value; + put VALUE; + end; + + define event put_value_cr; + put VALUE NL; + end; + + define event byline; + put NL; + put "\sasbyline"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event proc_title; + put "\sasproctitle"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event note; + put "\sasnote"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event Error; + put "\saserror"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event Warn; + put "\saswarn"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event Fatal; + put "\sasfatal"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event system_title; + put "\sassystemtitle"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + define event system_footer; + put "\sassystemfooter"; + + trigger alignment; + put "{"; + put VALUE; + put "}" NL; + end; + + image_formats = "png,pdf"; + split = " {\newline} "; + nobreakspace = "~"; + mapsub = %nrstr("/\%%/\$/\&/\{/\}/\~/\^/\#/{\textunderscore}/{\textbackslash}/"); + map = %nrstr("%%$&{}~^#_\"); + output_type = "latex"; + stacked_columns = OFF; + embedded_stylesheet; + private; +end; +run; diff --git a/macros/latex/contrib/statrep/statrep.dtx b/macros/latex/contrib/statrep/statrep.dtx new file mode 100644 index 0000000000..38f90f325b --- /dev/null +++ b/macros/latex/contrib/statrep/statrep.dtx @@ -0,0 +1,2960 @@ +% \iffalse meta-comment +%<*internal> +\iffalse +%</internal> +%<*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 +%</readme> +%<*internal> +\fi +\def\nameofplainTeX{plain} +\ifx\fmtname\nameofplainTeX\else + \expandafter\begingroup +\fi +%</internal> +%<*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. <tim.arnold@sas.com> + +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}}} +%</install> +%<install>\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 +%</internal> +%<*statrep> +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{statrep}[2015/09/15 v1.07 The statrep package] +%</statrep> +%<*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} +%</driver> +%\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 +%</example> +% \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 +%</statrep> +%<*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 +%</cfg> +%<*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 +%</statrep> +%\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 +%</example> +% \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 +%</example> +% \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 +%</example> +% \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 +%</example> +% \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 +%</longfigure> +% \fi +%\Finale +%\endinput diff --git a/macros/latex/contrib/statrep/statrep.ins b/macros/latex/contrib/statrep/statrep.ins new file mode 100644 index 0000000000..9e6502629c --- /dev/null +++ b/macros/latex/contrib/statrep/statrep.ins @@ -0,0 +1,62 @@ +%% +%% This is file `statrep.ins', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% statrep.dtx (with options: `install') +%% ---------------------------------------------------------------- +%% 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 +%% ---------------------------------------------------------------- +\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. <tim.arnold@sas.com> + +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 +%% Copyright (C) 2015 by SAS Institute Inc. <tim.arnold@sas.com> +%% +%% 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 +%% +%% End of file `statrep.ins'. |