summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/statrep
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/statrep
Initial commit
Diffstat (limited to 'macros/latex/contrib/statrep')
-rw-r--r--macros/latex/contrib/statrep/LICENSE415
-rw-r--r--macros/latex/contrib/statrep/README186
-rw-r--r--macros/latex/contrib/statrep/doc/images/Thumbs.dbbin0 -> 48127 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/default.pngbin0 -> 20727 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/example_output.pngbin0 -> 33784 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/htmlblue.pngbin0 -> 27614 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/journal.pngbin0 -> 20905 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/listing.pngbin0 -> 19317 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/sasuniv1.pngbin0 -> 158101 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/statistical.pngbin0 -> 21958 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/vm1.pngbin0 -> 85523 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/vm2.pngbin0 -> 90837 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/images/vm3.pngbin0 -> 72565 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/quickstart.tex176
-rw-r--r--macros/latex/contrib/statrep/doc/statrep.pdfbin0 -> 418742 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/statrepmanual.pdfbin0 -> 625258 bytes
-rw-r--r--macros/latex/contrib/statrep/doc/statrepmanual.tex2978
-rw-r--r--macros/latex/contrib/statrep/sas/statrep_macros.sas1523
-rw-r--r--macros/latex/contrib/statrep/sas/statrep_tagset.sas566
-rw-r--r--macros/latex/contrib/statrep/statrep.dtx2960
-rw-r--r--macros/latex/contrib/statrep/statrep.ins62
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
new file mode 100644
index 0000000000..feb1fb04eb
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/Thumbs.db
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/default.png b/macros/latex/contrib/statrep/doc/images/default.png
new file mode 100644
index 0000000000..8bfff57cc5
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/default.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/example_output.png b/macros/latex/contrib/statrep/doc/images/example_output.png
new file mode 100644
index 0000000000..010af4c137
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/example_output.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/htmlblue.png b/macros/latex/contrib/statrep/doc/images/htmlblue.png
new file mode 100644
index 0000000000..a67acf037a
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/htmlblue.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/journal.png b/macros/latex/contrib/statrep/doc/images/journal.png
new file mode 100644
index 0000000000..b012f55cac
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/journal.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/listing.png b/macros/latex/contrib/statrep/doc/images/listing.png
new file mode 100644
index 0000000000..d81f91cefc
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/listing.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/sasuniv1.png b/macros/latex/contrib/statrep/doc/images/sasuniv1.png
new file mode 100644
index 0000000000..00389bd602
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/sasuniv1.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/statistical.png b/macros/latex/contrib/statrep/doc/images/statistical.png
new file mode 100644
index 0000000000..f6f5c7a06c
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/statistical.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/vm1.png b/macros/latex/contrib/statrep/doc/images/vm1.png
new file mode 100644
index 0000000000..e126ac6c6b
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/vm1.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/vm2.png b/macros/latex/contrib/statrep/doc/images/vm2.png
new file mode 100644
index 0000000000..274ebcb3a7
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/vm2.png
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/images/vm3.png b/macros/latex/contrib/statrep/doc/images/vm3.png
new file mode 100644
index 0000000000..1f57fbe067
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/images/vm3.png
Binary files differ
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
new file mode 100644
index 0000000000..bf87bbf8ab
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/statrep.pdf
Binary files differ
diff --git a/macros/latex/contrib/statrep/doc/statrepmanual.pdf b/macros/latex/contrib/statrep/doc/statrepmanual.pdf
new file mode 100644
index 0000000000..8960bc852e
--- /dev/null
+++ b/macros/latex/contrib/statrep/doc/statrepmanual.pdf
Binary files differ
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 &range;
+ 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'.