summaryrefslogtreecommitdiff
path: root/support/tex-it
diff options
context:
space:
mode:
Diffstat (limited to 'support/tex-it')
-rw-r--r--support/tex-it/CHANGES274
-rw-r--r--support/tex-it/COPYING280
-rw-r--r--support/tex-it/README98
-rw-r--r--support/tex-it/chkscr.pl42
-rw-r--r--support/tex-it/texit.pl2686
-rw-r--r--support/tex-it/texit.tex672
-rw-r--r--support/tex-it/texitrc.os259
-rw-r--r--support/tex-it/texitrc.unx157
8 files changed, 4268 insertions, 0 deletions
diff --git a/support/tex-it/CHANGES b/support/tex-it/CHANGES
new file mode 100644
index 0000000000..ab46c667d2
--- /dev/null
+++ b/support/tex-it/CHANGES
@@ -0,0 +1,274 @@
+$Id: CHANGES 1.6 1993/12/30 17:27:16 norm Exp $
+
+This file documents the changes to TeXit:
+
+Version 1.35:
+
+- $DEFAULTLATEXFORMAT added to specify default LaTeX variant (it could be
+ a LaTeX file, a LaTeX+NFSS file, a LaTeX+NFSS2 file, an AMS LaTeX file,
+ or ...
+
+- Added support for LaTeX2e
+
+- Added an option to allow the TEXINPUTS path to be specified differently
+ for different formats. Right now, for example, TEXINPUTS2E will be used
+ in place of TEXINPUTS when formatting LaTeX2e documents.
+
+- Running under X11, TeXit will change the title bar and the icon title
+ to reflect the action being performed. For long jobs, this makes it
+ easy to tell if the iconified TeXit process has finished. If you want
+ this functionality, you must set $SETXTITLE=1; in your .texitrc file.
+
+Version 1.34:
+
+- Reorganized the initialization code for the format file names, printable
+ names, and parsing routines.
+
+- Added support for finding the position of the first error in a TeX log.
+ The '%E' in a command (the editing command, for example) is replaced
+ by the name of the file containing the error and `%e' is replaced by the
+ line number of the error.
+
+- TeXit verifies that TeX will be able to find the format file that you've
+ requested. This will help users with non-standard format file names track
+ down problems quickly.
+
+- Parsing the LaTeX log has been extended to add dependencies for bibliography
+ style files and bibliography databases.
+
+- The environment variables that contain the paths for searching for biblio
+ files and format files are stored in $ENV_TEXINPUTS, $ENV_BIBINPUTS, and
+ $ENV_TEXFMTS. These should be changed in your .texitrc file to reflect
+ the correct environment variables.
+
+- The Local-Variables and other format-file clues no longer override the
+ values established by a % Format:, % Master:, or % Mode: line in the
+ document.
+
+- Error messages for unrecognized warnings in LaTeX now use the format
+ "filename: line-number: warning" if the line number occurs in the
+ message, otherwise the format "filename: warning" is used.
+
+- If you define $DEFAULT_PRINTER, it will be the default printer queue if
+ you do not specify one.
+
+- Made STDOUT unbuffered
+
+- Print %done message while parsing LOG file. For very large log files,
+ earlier versions of TeXit gave the impression that they were hung...
+
+- If a raw input filename is given (one with no path component), then
+ TeXit will search for the file in the $ENV_TEXINPUTS path.
+
+Version 1.33:
+
+- Parsing the log files now notices which files are \input and adds them
+ to the dependency list for the document. You no longer have to list
+ all of the included files in the rules section of your document.
+
+- Now prints a summary of unrecognized LaTeX warning messages. Some trivial
+ messages are ignored (moved Marginpars, NFSS font substitutions, etc.). The
+ "NFSS2 Info: ***" messages _are_ displayed.
+
+- Added a show status subroutine and a default command for it: [?] status.
+ This can be used to view the list of files that TeXit things your document
+ depends on (? dep), the rules TeXit is using (? rules) or the value of
+ an Perl variable (? <varname>). "? ?" summarizes the show status syntax.
+ It's basically a debugging option...
+
+- Added an -nfss2ltx option for the NFSS2.
+
+Version 1.32:
+
+- Never publicly released
+
+Version 1.31:
+
+- Never publicly released
+
+Version 1.30:
+
+- Parsing LaTeX log files now notices that a BBL file is missing. This
+ handles \nocite{*}. Using \nocite{} doesn't produce a citation missing
+ warning so simply checking for the warning could miss a document that
+ had a \nocite but no \cites.
+
+- Parsing the log files now determines which files are included (styles
+ or \input, etc.) and adds them to the list of dependencies
+ after the first TeX run.
+
+- Added a [?] option to show the current status of TeXit. This is really
+ kindof a debugging option, but it does let you see a short summary of the
+ dependencies or rules of a document as well as any Perl variable defined
+ in TeXit.
+
+- When parsing LaTeX files, TeXit now records unrecognized warnings (identified
+ by the word "Warning:") and summarizes them at the end of processing. The
+ %WARNINGS array should be used for this purpose if you want to support it
+ in other formats.
+
+Version 1.29:
+
+- Added the &cleanup_files subroutine to simplify adding files to be erased
+ in TeXit rules.
+
+- Updated the documentation. It's still not great, but it's better.
+
+Version 1.28:
+
+- Added call to &dependent_files_are_newer() in each &interpret_<format>_log.
+ It was a stupid oversight to have forgotten.
+
+- Removed spurious carriage return after print options.
+
+- Changed TEXCMD{}s to use "%t" instead of "%s". This was necessary to fix
+ some weirdness with TeX paths. TeX always stores the DVI file in the
+ current directory and strips off the last extension _given_ so I've made
+ the filename passed to TeX consistent, the ".tex" is always left on if it
+ was ever present. This makes it easier to figure out what the names of
+ auxilliary files will be.
+
+- Added 'find_on_path' subroutine which looks for a file on a colon or
+ semi-colon seperated path name. Used in my .texitrc file, for example.
+
+- Made lots of changes to my .texitrc file to emphasis the fact that the
+ .texitrc file isn't a Perl file (it's read by require_hack) and to show
+ some examples that users have requested from me.
+
+- Added "n files deleted." message to cleanup.
+
+Version 1.27:
+
+- Added -clean option and $CLEANPROMPT variable to control whether or
+ not you are prompted for confirmation before cleaning up files.
+ If you use the '-clean' option, you will not be prompted.
+
+- Made -once call cleanup before exiting if $CLEANONEXIT is true and
+ $CLEANPROMPT is false.
+
+- Fixed bug that caused files with extensions other than ".tex" not to be
+ processed correctly.
+
+- Added default extensions list for cleaning up TeXinfo files.
+
+- Removed "dvi" from the default list of extensions to remove when cleaning
+ up files. You can add it back in with a .texitrc file or a TeXit rule
+ in your document.
+
+- Added 'lot', 'lof', and 'toc' to the list of cleanup extensions for LaTeX
+
+- Added check for multiply defined references in LaTeX. TeXit retries
+ once to fix the references (since they may have been fixed, but still
+ persist in the AUX file) and then gives up. It'll never succeed so
+ why keep trying?
+
+- Added support for a list of rules that are format-dependent. A list of
+ rules named "@$TEXFORMAT_rules" is executed before your document rules.
+ The list "@default_rules" is executed before those. So, for example,
+ if you are processing a LaTeX document, first @default_rules get executed,
+ then @latex_rules, then the rules defined by your document.
+
+ Check out the rules defined in ``texitrc.unx'' for an example of some
+ rules for LaTeX documents.
+
+- Added parsing and interpretation for the Texinfo format
+
+- Reworked the &dependencies_changed() code to run seperate subroutines for
+ parsing and analyzing the log file. Plain TeX, LaTeX, and Texinfo are
+ currently supported, but it's much easier to add other formats now.
+
+- Changed the way &dependson() works. It now builds a list of files that
+ TeXit checks automatically. This is an improvement because earlier
+ versions of TeXit couldn't check the dependencies of your document when
+ you simply pressed Enter at the TeXit prompt.
+
+- New feature: $CMDPROMPT{key} keys that begin with "!" are valid but they
+ are not printed in the prompt string.
+
+- New feature: if $DVIQUERY{type} is set, TeXit will prompt the user for
+ DVI driver options. The $DVIQUERY{type} string is the prompt. These
+ options are appended (with a space) to any previous options.
+
+- New feature: if $PRINTQUERY{Q} is set, TeXit will prompt the user for
+ printer options. See above.
+
+- New feature: if defined, the setting of $PRINTCONFIRM{Q} overrides the
+ global setting of $CONFIRMPRINT. It should be "yes", "no", "0", or "1".
+
+- Added name of file being processed to the "Again?" prompt.
+
+Version 1.26:
+
+- Changed name of %formats array to %format.
+- Added %formatname array to get the printable name of the format.
+
+ %format{"latex"} = "lplain"
+ %formatname{"latex"} = "LaTeX"
+
+- $DEFAULTFORMAT is now "plain". TeXit can usually figure out that a
+ file is LaTeX, so it makes more sense to assume a document that cannot
+ be deduced is Plain.
+- Added $CLEANONEXIT flag. If $CLEANONEXIT is set, TeXit will ask if you
+ want to delete auxilliary files on your way out.
+- Added symbolic names for all the standard prompts. This makes it easier
+ to delete them, or add them to the AUTOCMD list...
+- Added %DEFAULTCMD to customize an blank response at the prompt. If you
+ simply press enter w/o entering an option, TeXit pretends that you entered
+ "$DEFAULTCMD{key}". In this context, "key" is the _last_ choice that you
+ entered. For example, to make "View" the default choice after running
+ TeX, set:
+
+ $DEFAULTCMD{$TeXReply} = $ViewReply;
+
+- Added %AUTOCMD to chain commands together. If $AUTOCMD{key} is set,
+ TeXit runs "$AUTOCMD{key}" after running whatever "key" refered to w/o
+ returning to the prompt. For example, to add a new choice "[T]ex and View"
+ which runs TeX and then automatically runs View, use:
+
+ $TeXandViewReply = "[T]eX & View";
+ $CMDPROMPT{$TeXandViewReply} = $CMDPROMPT{$TeXReply};
+ $CMDTEST{$TeXandViewReply} = $CMDTEST{$TeXReply};
+ $AUTOCMD{$TeXandViewReply} = $ViewReply;
+ $AUTOOPT{$TeXandViewReply} = "";
+
+ The array %AUTOOPT holds options that should be used for the automatic
+ command.
+- Added $AUTOMAX to control chaining. TeXit will never perform more than
+ $AUTOMAX automatic commands. This prevents infinite loops.
+- Added $TEXERROR to indicate what return code from TeX is a fatal error.
+ Some implementations of TeX (notably emTeX) return a non-zero error code
+ when non-fatal errors occur. TeXit assumes that if the return code from
+ TeX is less than $TEXERROR, the error doesn't count.
+- Made $TEXCMD an associative array so that different formats can
+ have different command strings. $TEXCMD{"default"} is now the default.
+- Made analagous change to $TEXOPTS.
+- Added warning message when TeXit can't figure out the format
+- No longer escape backslashes in rules. This means that you have to
+ use "\\" where "\" used to suffice. Advantage: you can now refer to
+ Perl variables in your rules (prefix them with one backslash).
+- Added %S, %T, and %D meta-symbols in commands. They have the same
+ meaning as %s, %t and %d but forward slashes are translated into
+ backslashes before substitution. This is so they can be passed to
+ DOS and OS/2 programs which expect pathnames to be delimited with
+ backslashes.
+- Improved handling of return codes from programs.
+- Print warning if return code is non-zero
+- Parse LaTeX log file for "foiltex" and "slitex" formats
+- Print rules before evaluating them in $VERBOSE mode
+- Automatically recognize the "foiltex" format
+- No longer run BibTeX if the AUX file is missing
+- Made it possible for prompt keys [x] to be any non-whitespace char
+ instead of only letters.
+- Added -menu option. If -menu is used, TeX is not run before displaying
+ the menu for the first time.
+- Reworked the logic for running BibTeX. Now only run BibTeX if there
+ are new missing citations. This means BibTeX is usually only run once
+ rather than twice.
+
+Version 1.25
+
+ Never released
+
+Version 1.24
+
+ Initial release
diff --git a/support/tex-it/COPYING b/support/tex-it/COPYING
new file mode 100644
index 0000000000..c7aea1896f
--- /dev/null
+++ b/support/tex-it/COPYING
@@ -0,0 +1,280 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/support/tex-it/README b/support/tex-it/README
new file mode 100644
index 0000000000..aedbdd40b5
--- /dev/null
+++ b/support/tex-it/README
@@ -0,0 +1,98 @@
+README for TeXit v1.35.
+
+This is just a slightly altered version of the first README file (for
+version 1.24). See the CHANGES file for a list of new features.
+
+TeXit is a Perl script for running TeX. It has the following features:
+
+ 1) TeXit examines the log file produced by TeX and tries to determine
+ when TeX needs to be run again in order to resolve references
+ and citations.
+
+ 2) TeXit is smart enough to run BibTeX, if necessary and can easily
+ be told to run MakeIndex if necessary.
+
+ 3) After your document has been formatted, TeXit provides a menu that
+ offers other options including: BibTeXing, Viewing, Viewing with
+ Ghostview, Printing, and Cleanup. Cleanup deletes the extra files
+ that get created when you run TeX (aux, log, ilg, blg, etc.).
+
+ 4) TeXit remains "smart" about your document. If you run BibTeX, for
+ example, TeXit automatically reruns TeX.
+
+ 5) TeXit has lots of hooks for customization. You can easily add new
+ printer queues, new printer types, and new commands without editing
+ the body of the script. It's all done with init files.
+
+ For example, here's how I add a "query printer" command to the
+ menu:
+
+ # Adding a query printer option...
+ $CMDPROMPT{"[q]uery printer"} = '&run("lpq -P%o", $opts); $REASK;';
+ $CMDTEST{"[q]uery printer"} = '';
+
+ (Allright, I admit it's a bit ugly to read, but it's nicer than
+ having to modify the script!)
+
+ 6) You can add "TeXit rules" to a document to indicate that the document
+ has unusual dependencies. These rules are added in TeX comments at
+ the bottom of your document (like Emacs `Local Variables' if you're
+ familiar with them). For example, the following rule tells
+ TeXit about your index:
+
+ % &makeindex('-o driver.ind driver.idx')
+ % if &missing('driver.ind') || &changed('driver.idx');
+
+ When processing a document that contains this rule, TeXit will
+ automatically re-run TeX if the file "driver.ind" does not exist
+ or if "driver.idx" changes during a TeX run.
+
+ This next rule handles a diagram created with TreeTeX. If "texittr.tlo"
+ changes or "texittr.tli" doesn't exist, TeXit will run the command
+ indicated (which asynchronously runs a command on another workstation
+ because TreeTeX doesn't build right for the workstation I usually use)
+ and then wait for "texittr.tli" to spring into existence.
+
+ % &run('treetex texittr'), &waitfor('texittr.tli')
+ % if &changed('texittr.tlo') || &missing('texittr.tli');
+
+ Since this document creates some extra files, I push those onto the
+ cleanup list so that TeXit will delete them when I'm done:
+
+ % push(@cleanup_files, ('texittr.tli','texittr.tlo')) #
+ % if $first_time;
+
+ 7) The script is heavily commented and the author is pretty friendly about
+ answering questions (even if I do say so myself ;-)
+
+ 8) I've banged out a few pages of documentation. Hopefully the docs make
+ it easier to use rather than harder, although I admit I was up pretty
+ late writing them and I don't really have the time to do it well just
+ at the moment.
+
+ 9) It's free.
+
+A lot of the features in TeXit were inspired by features in AUC-TeX. Even
+though AUC-TeX does most of these things, I find TeXit handy. For one thing,
+my machine at home is way too slow to run AUC-TeX, but it runs TeXit pretty
+well (after Perl finishes compiling it, anyway ;-).
+
+Lots of people have retreived it and I haven't had any complaints, so I
+gather it works pretty well.
+
+Obviously, you have to have Perl installed on your system to use this script.
+Perl is pretty cool in its own right, so I recommend you go out and get it
+if you don't already have it.
+
+If you are interested in trying out TeXit, you can get it by anonymous ftp
+from: ibis.cs.umass.edu:/pub/norm/tex/texit/*.
+
+If you try it, please let me know how you like it, or even if you like it. ;-)
+
+ Be seeing you...
+ norm
+---
+Norman Walsh | University of Massachusetts, Amherst, MA 01003
+<walsh@cs.umass.edu> | CMPSCI Dept., LGRC A210 | Standard disclaimer applies
+
+
diff --git a/support/tex-it/chkscr.pl b/support/tex-it/chkscr.pl
new file mode 100644
index 0000000000..b37c52f72a
--- /dev/null
+++ b/support/tex-it/chkscr.pl
@@ -0,0 +1,42 @@
+#!/usr/local/bin/perl
+
+$prevline = "";
+@badlines = ();
+$prevbad = 0;
+while (<>) {
+ chop;
+
+ push (@badlines, $_) if $prevbad;
+ $prevbad = 0;
+ next if /\s*#/;
+ next if /.*\}\s*$/;
+ next if /.*\{\s*$/;
+ next if /.*,\s*$/;
+ next if /^\s*$/;
+
+ if (!/.*;\s*$/) {
+ push (@badlines, $_);
+ $prevbad = 1;
+ }
+}
+
+$even = 0;
+foreach $line (@badlines) {
+ if ($even) {
+ $ok = 0;
+ if ($line =~ /.*;\s*$/ && $line =~ /^\s*if/) {
+ $ok = 1;
+ }
+ if (! $ok) {
+ print "---\n";
+ print $prevline, "\n";
+ print $line, "\n";
+ }
+
+ $even = 0;
+ } else {
+ $even = 1;
+ $prevline = $line;
+ }
+}
+
diff --git a/support/tex-it/texit.pl b/support/tex-it/texit.pl
new file mode 100644
index 0000000000..8c4c428e8a
--- /dev/null
+++ b/support/tex-it/texit.pl
@@ -0,0 +1,2686 @@
+#! /usr/local/bin/perl -- # -*-Perl-*-
+
+########################################################################
+# TeXit: a Perl script for running TeX.
+#
+# Copyright (C) 1993 by Norman Walsh. <norm@ora.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# Comments, questions, suggestions, and even flames welcome.
+#
+# See "display_usage" at the bottom of this file for information
+# about how to use TeXit.
+########################################################################
+
+($VERSION = '$Revision: 1.36 $ ') =~ s/.*: (\d+.\d+).*/$1/;
+print "This is TeXit v$VERSION. ";
+print "Copyright (C) 1993 by Norman Walsh.\n";
+
+($revision, $patchlevel) = &perl_version_info();
+
+if ($revision lt "4.0.1.7" ||
+ ($revision eq "4.0.1.7" && $patchlevel < 35)) {
+ print "***********************************",
+ "***********************************\n";
+ print " WARNING: Your Perl is old. TeXit may or may not work.\n";
+ print " In particular, options may not be interpreted correctly.\n";
+ print "***********************************",
+ "***********************************\n";
+}
+
+########################################################################
+# Load standard library routines for handling abbreviations. I use
+# this for the command line options.
+#
+require "abbrev.pl";
+
+########################################################################
+# Initialize associative arrays of format information.
+#
+# &setup_format (common-name, printable-name, parser-name, format-name);
+#
+# Where:
+#
+# common-name : The (unique) internal (to TeXit) name of the format
+# printable-name : What we tell the user this format is called
+# parser-name : Which "parse_<parser-name>_log" routine gets called
+# format-name : What is the '&<format-name>' filename of this format
+#
+&setup_format ("amslatex", "AMSLaTeX", "latex", "lplain", "" );
+&setup_format ("amstex", "AMSTeX", "default", "amstex", "" );
+&setup_format ("foiltex", "FoilTeX", "latex", "fltplain", "" );
+&setup_format ("lamstex", "LAMSTeX", "default", "lamstex", "" );
+&setup_format ("latex", "LaTeX", "latex", "lplain", "" );
+&setup_format ("lollipop", "Lollipop", "default", "lollipop", "" );
+&setup_format ("nfss2ltx", "LaTeX (NFSS2)", "latex", "nfss2ltx", "" );
+&setup_format ("plain", "Plain TeX", "default", "plain", "" );
+&setup_format ("slitex", "SliTeX", "latex", "splain", "" );
+&setup_format ("texinfo", "Texinfo", "texinfo", "plain", "" );
+&setup_format ("latex2e", "LaTeX2e", "latex", "latex2e", "2E" );
+
+########################################################################
+# Global defaults. These should be set to reasonable values when the
+# script is installed. The values below are reasonable for many Unix
+# installations.
+#
+# To override these defaults, when TeXit begins, it loads each of the
+# following files, if they exist:
+#
+# A system-wide init file (if configured to do so)
+# ~/.texitrc (.texitrc in the users home directory)
+# /path/.texitrc (/path is the path of the tex file being processed)
+# foo (for each "-initfile foo" specified on the command line)
+#
+# They are loaded in that order and each can over-ride the values of
+# the preceding. Or any of the defaults shown below:
+#
+$TEXITRC = ".texitrc"; # Filename for init files ~/.texitrc ...
+
+$DEFAULTFORMAT = "plain"; # Default format to use...
+$DEFAULTLATEXFORMAT = "latex"; # Default LaTeX format to use...
+$VERBOSE = 0; # Lots of messages...
+$TEXITFASTEXIT = 1; # Empty line at prompt == quit
+$ONCE = 0; # Run once, no prompting? (-once)
+$GOTOMENU = 0; # Go right to menu? (-menu)
+$CONFIRMPRINT = 1; # Ask before printing?
+$CLEANONEXIT = 0; # Cleanup automatically on exit?
+$CLEANPROMPT = 1; # Should we ask first? (-clean)
+$SETXTITLE = 0; # Should we alter the X11 title/icon name?
+
+%DEPENDSON = (); # what does the DVI file depend on?
+
+%WARNINGS = (); # are there any warnings parse_<format>_log
+ # didn't recognize?
+%DEFAULTCMD = (); # no default commands
+%AUTOCMD = (); # no automatic commands
+$AUTOMAX = 1; # how many automatic commands can occur
+ # in a row?
+
+$TEXERROR = 1; # Return code from TEX that indicates an
+ # an error. Under emTeX, make this 2.
+ # emTeX returns 1 for overfull boxes, etc.
+ # which arent really errors.
+$ERRORLINE = 0; # What line did the TeX error occur on...
+$ERRORFILE = ""; # What file was being processed...
+%Parens = ();
+$ParenLevel = 0;
+
+$ENV_TEXINPUTS = "TEXINPUTS"; # Name of TEXINPUTS environment variable
+$ENV_BIBINPUTS = "BIBINPUTS"; # Name of BIBINPUTS environment variable
+$ENV_TEXFMTS = "TEXFORMATS";# Name of TEXFORMATS environment variable
+
+$TEXRETRIES = 4; # How many retries before we give up?
+
+$TEXHEADERSIZE = 20; # number of lines at the top of each
+ # document that TeXit searches for
+ # formatting clues.
+
+$QuitReply = "e[x]it"; # To leave TeXit
+$TeXReply = "[t]ex"; # To run TeX
+$CleanupReply = "[c]leanup"; # To cleanup files
+$BibTeXReply = "[b]ibtex"; # To run BibTeX
+$GhostviewReply= "[g]hostview";# To run Ghostview
+$PrintReply = "[p]rint"; # To print
+$ViewReply = "[v]iew"; # To view
+$StatusReply = "[?]status"; # To get a status report from TeXit
+
+$TEX = "virtex"; # TeX, the program
+$BIBTEX = "bibtex"; # BibTeX
+$MAKEINDEX = "makeindex"; # MakeIndex
+$VIEW = "xdvi"; # A previewer
+$GSVIEW = "ghostview"; # Ghostview, another previewer
+
+# The following commands are used to run each of the above programs.
+# See the 'run' subroutine for a description of the %-variable
+# substitution that is performed. Also, note that Perl $VARIABLE
+# substitution is performed too.
+#
+# The $TEXCMDs are stored in an associative array because not all
+# format files can be run with the same command line.
+#
+$TEXCMD{"default"} = '$TEX "%F %o \\input{%t}"';
+$TEXCMD{"plain"} = '$TEX "%F %o \\input %t"';
+$TEXCMD{"texinfo"} = '$TEX "%F %o \\input %t"';
+$BIBTEXCMD = '$BIBTEX %o %s';
+$MAKEINDEXCMD = '$MAKEINDEX %o %s';
+$VIEWCMD = '$VIEW %o %d';
+$GSVIEWCMD = '$GSVIEW %o %s.ps';
+
+# Default options for each of the above commands. These options
+# are _always_ used (where %o occurs in the command) if they are
+# set, so choose wisely. They come before any additional options
+# specified at the TeXit prompt.
+#
+$TEXOPTS{"default"} = "";
+$BIBTEXOPTS = "";
+$MAKEINDEXOPTS = "";
+$VIEWOPTS = "";
+$GSVIEWOPTS = "";
+
+########################################################################
+# Printer initialization. It works like this: the user selects a
+# printer queue "Q". Then $PRQUEUE{"Q"} determines the printer _type_.
+# Ordinarily, the user never knows about the type, but it is used
+# to lookup the DVI driver and printer commands. In particular:
+#
+# $PRQUEUE{"Q"} = "TYPE"
+#
+# $DVICMD{"TYPE"} = DVI driver command (with substitutions)
+# $DVIOPT{"TYPE"} = Default options for driver
+# $DVIQUERY{"TYPE"} = Ask for additional DVI options?
+# If $DVIQUERY{"TYPE"} is defined, TeXit will ask
+# the user for additional dvi driver options (using
+# the value of $DVIQUERY{"TYPE"} as the prompt).
+# These options are added to any options entered
+# at the prompt.
+#
+# $PRINTCMD{"Q"} = How to print resulting file (with substitution)
+# $PRINTOPT{"Q"} = Default options for driver
+# $PRINTQUERY{"Q"} = Ask for additional printer options? See above.
+# $PRINTCONFIRM{"Q"}= Yes or No? Overrides $CONFIRMPRINT...
+#
+# Ordinarily, all of the above variables should be set for each queue
+# and it is an error for them to be unset. However, the following
+# exception is made: if the $PRINTCMD{"Q"} isn't set, then the file
+# is run through a DVI driver but is not printed.
+#
+# Note: Ghostview is implemented this way, but it is also hard coded
+# later on as an option in it's own right because we can be a little
+# more intelligent about it.
+#
+# It would clearly have been possible to do configuration in other
+# ways, in particular by using a single print command with different
+# printer options ("lpr -P%p" for example). But that has disadvantages
+# too and it doesn't save much time or space.
+#
+$PRQUEUE{"Local"} = "ps"; # A 'local' printer
+$PRQUEUE{"File"} = "ps"; # Just save the PS file
+$PRQUEUE{"ghostview"} = "ps"; # Ghostview
+
+$PRINTCMD{"Local"} = 'lpr %o %s.ps';
+$PRINTOPT{"Local"} = "";
+
+$PRINTCMD{"File"} = "";
+$PRINTOPT{"File"} = "";
+
+$PRINTCMD{"ghostview"} = '$GSVIEW %o %s.ps';
+$PRINTOPT{"ghostview"} = "";
+
+$DVICMD{"ps"} = 'dvips %o %d';
+$DVIOPT{"ps"} = "";
+
+########################################################################
+# The $CleanupReply option looks for a list of files to delete in the
+# list "@cleanup_files". These are usually set by perl commands in the
+# document since there aren't any default _files_ to delete.
+#
+# It also looks for a list of extensions in the list "@cleanup_<format>"
+# If the file <texbasefile>.<ext> exists, it is deleted during cleanup
+#
+@cleanup_files = ();
+@cleanup_plain = ('log');
+@cleanup_texinfo = ('log', 'aux', 'cp','fn','ky','pg','toc','tp','vr');
+@cleanup_latex = ('log', 'aux', 'blg', 'ilg', 'lot', 'lof', 'toc');
+@cleanup_nfss2ltx = ('log', 'aux', 'blg', 'ilg', 'lot', 'lof', 'toc');
+@cleanup_latex2e = ('log', 'aux', 'blg', 'ilg', 'lot', 'lof', 'toc');
+
+########################################################################
+# The system default, user default, and directory default initfiles
+# have to be kept around until we're ready to load them. That's what
+# the @TEXITINIT list is for. Ordinarily this is initialized empty.
+# But if you always want to load a system-wide init file, perhaps
+# "/usr/local/lib/texitrc" then you can initialize TEXITINIT to
+# include that file.
+#
+@TEXITINIT = ();
+
+# Unfortunately, we want to run the system default files before the
+# files specified with -initfile on the command line, but we don't
+# find out what the name of the directory default is until after we've
+# parsed the command line. To circumvent this problem, we store
+# initfiles from the command line in a seperate array.
+#
+@TEXITCMDLINE = (); # leave this empty
+
+########################################################################
+# Locate the user-default init file and store it on the TEXITINIT list.
+# Some installations might not have a HOME environment variable to
+# contain the home directory, so we let them specify a TEXIT env. var.
+# instead.
+#
+$_ = $ENV{"TEXIT"};
+$_ = $ENV{"HOME"} if $_ eq "";
+$_ .= "/" if $_ && $_ !~ /.*\/$/;
+$texitrc = $_ . $TEXITRC;
+print "Looking for user-init file: $texitrc\n" if $VERBOSE;
+unshift(@TEXITINIT, $texitrc) if -r $texitrc;
+
+########################################################################
+# make STDOUT unbuffered so we can print messages w/o newlines in them
+#
+select(STDOUT); $| = 1;
+
+########################################################################
+# Get ready to parse the arguments...
+#
+# The associative array "cmdlineopts" is built to hold all of the
+# possible, unambiguous command line options. It will later be used
+# to get back the full name (i.e. $cmdlineopts{"ini"} = "initfile").
+#
+{
+ local (@formatlist) = keys (%format);
+ %cmdlineopts = ();
+ &abbrev (*cmdlineopts,
+ 'initfile', 'verbose', 'once', 'menu', 'clean',
+ 'bibtex', 'makeindex', 'tex',
+ @formatlist);
+}
+
+# Build the case statement for parsing the options. This code builds
+# an associative array and 'eval's it to get the cases. It's a little
+# obscure, but it works.
+#
+# If a valid option is not found in the case statement, it is assumed
+# to be the name of a format file. This saves a whole bunch of cases.
+# Note: the lines inbetween &case and ENDCASE _are not_ evaluated
+# by the Perl compiler at compile time...they are 'eval'ed at runtime.
+#
+&case (*casefoo,<<'ENDCASE');
+ initfile $texitrc = $ARGV[0] || "no file"; shift;
+ verbose $VERBOSE = 1;
+ once $ONCE = 1;
+ menu $GOTOMENU = 1;
+ clean $CLEANPROMPT = 0;
+ tex $runtexfirst = 1;
+ bibtex $runbibtexfirst = 1;
+ makeindex $runmakeindexfirst = 1;
+ENDCASE
+
+# make sure a few things are undefined
+undef ($TEXFORMAT);
+undef ($texitrc);
+undef ($runtexfirst);
+undef ($runbibtexfirst);
+undef ($runmakeindexfirst);
+
+# Now look at the arguments, keep scanning through them as long as
+# they begin with a hyphen. Anything after that has to be a filename
+#
+while ($ARGV[0] =~ /^-(.*)/ && shift) {
+ ($option = $1) =~ tr/A-Z/a-z/;
+ $option = $cmdlineopts{$option}; # find long opt
+ die "Unrecognized or ambiguous option: -$1.\n"
+ if $option eq "";
+
+ if (defined($casefoo{$option})) {
+ # Ok, it's one of the arms of the case statement
+ eval $casefoo{$option};
+ if (defined($texitrc)) {
+ # The only arm that isn't self-contained is the -initfile arm.
+ # For that option, we have to check for the initfile and save
+ # it for later.
+ die "You forgot the file name after \"-$1\".\n"
+ if $texitrc eq "no file";
+
+ die "Initfile does not exist: $texitrc\n"
+ if ! -r $texitrc;
+
+ print "Looking for -initfile: $texitrc\n" if $VERBOSE;
+ unshift(@TEXITCMDLINE, $texitrc);
+ undef ($texitrc);
+ }
+ } else {
+ # It's not one of the arms of the case, so it must be a format.
+ $TEXFORMAT = $option;
+ }
+}
+
+########################################################################
+# What's left on the command line must be the name of the file that
+# contains the document to process. Anything else must be options to
+# TeX. Make sure they begin with an escape (you can put \relax
+# in front if you need to). Note: this verifies that the user
+# escaped the shell command line correctly.
+#
+$texfile = $ARGV[0] || &display_usage(); # display_usage doesn't return
+shift;
+
+if (defined($ARGV[0])) {
+ local ($texescape, $printescape);
+ $texescape = "\\\\";
+ $texescape = "@" if $TEXFORMAT eq "texinfo";
+ eval "\$printescape = \"$texescape\"";
+ if ($ARGV[0] !~ /^$texescape.*/) {
+ print "TeX options must begin with a \"$printescape\". ";
+ die "Use ${printescape}relax if necessary.\n";
+ }
+
+ $CMDLINEOPTS = join (" ", @ARGV);
+}
+
+########################################################################
+# Locate the requested TeX file. It's either in the current (or
+# specified) directory or no path was specified and it's on the
+# TEXINPUTS path.
+#
+$qualifiedtexfile = &cleanup_texfilename($texfile);
+if (! -e $qualifiedtexfile) {
+ if ($texfile !~ /[\/\\]/) { # no path...
+ $qualifiedtexfile = &find_on_path("$ENV{$ENV_TEXINPUTS}",
+ "$texfile");
+ $qualifiedtexfile = &find_on_path("$ENV{$ENV_TEXINPUTS}",
+ "$texfile" . ".tex")
+ if $qualifiedtexfile eq "";
+
+ die "Cannot find \"$texfile[.tex]\" on $ENV_TEXINPUTS path.\n"
+ if $qualifiedtexfile eq "";
+
+ $texfile = $qualifiedtexfile;
+ } else {
+ die "Cannot find \"$texfile[.tex]\".\n";
+ }
+} else {
+ $texfile = $qualifiedtexfile;
+}
+
+########################################################################
+# Maybe the file has an emacs-style "local variables" definition that
+# describes the file. Here, we only care about the local variables
+# "TeX-master" and "mode". These are the same variables AUC-TeX uses.
+# The TeX-master file means that _this_ file is some sub-part of a
+# larger document. The larger document is pointed to by TeX-master.
+# The "mode" is what format this is in (Plain TeX, LaTeX, ... etc.)
+#
+# Alternatively, if you don't use Emacs, you can get the same logic
+# out of TeXit by putting:
+#
+# % Master: file
+# % Mode: format % or Format: format
+#
+# somewhere near the top (within the first $TEXHEADERSIZE lines) of
+# your document. In this case, the line must begin with a percent
+# sign and there must be nothing else on the line. The Master: and
+# Mode: commands must each appear on a line of their own. If you
+# specify both a Master: and a TeX-master in the local variables, the
+# TeX-master will win (simply because it comes later in the file).
+# The same goes for mode:.
+#
+# Other than that, TeXit tries to be smart about what format to use,
+# looking for things that are clues to the format. Unfortunately,
+# TeXit is easy to fool, so you may need a -<format> on the command
+# line sometimes.
+#
+&get_local_vars ($texfile);
+
+# If this file has a master, load the local vars from the master file
+# as well...these override variables from the initial file, but that's
+# probably for the best anyway...
+#
+# TeX-master = "t" is special, it means _this_ file is the master file
+# (i.e. it's `true' that this is the master file).
+#
+# If there isn't a master file, then $texfile is the master.
+#
+$texmaster = $texvars{"TeX-master"};
+if (defined($texmaster) && $texmaster ne "t") {
+ $texmaster = &cleanup_texfilename($texmaster);
+ print "Processing $texfile ... superceded by master file.\n";
+ die "Cannot read master file: $texmaster" if (! -r $texmaster);
+ &get_local_vars ($texmaster);
+} else {
+ $texmaster = $texfile;
+}
+
+if ($texvars{"mode"} eq "") {
+ if ($TEXFORMAT eq "") {
+ print "\nI can't figure out what format this file uses, ",
+ "and you didn't say, so \nI'm going to guess that ",
+ "it's a \"$formatname{$DEFAULTFORMAT}\" file. Use ",
+ "the \"-format\" \noption if this is a bad guess.\n\n";
+
+ $texvars{"mode"} = $DEFAULTFORMAT;
+ } else {
+ $texvars{"mode"} = $TEXFORMAT;
+ }
+}
+
+########################################################################
+# Split the master filename up into a path, name, and extension
+#
+($TEXFILEPATH,$TEXFILENAME,$TEXFILEEXT) = &splitfn($texmaster,".tex");
+$DEPENDSON{$texmaster} = 1;
+
+########################################################################
+# Build up the default array of commands.
+#
+# Prompt with "key" if $CMDPROMPT{key} exists and the test $CMDTEST{key}
+# succeeds. A null test succeeds by default. The string enclosed in
+# square brackets in the key is what the user has to enter to select
+# that option.
+#
+# TeXit `eval's $CMDPROMPT{key} if the user selects the option "key".
+#
+# Use single quotes when building the command to be evaluated _and_
+# the test so that $VAR substitution isn't performed prematurely!
+#
+# The commands to run tex, cleanup the directory, and quit are used
+# elsewhere. Change the definitions of $xxxReply to make them different.
+# But don't change what they _mean_!!!
+#
+
+$RETEX = "last ASKLOOP";
+$REASK = "next ASKLOOP";
+
+$CMDPROMPT{$TeXReply} = '$RETEX';
+$CMDPROMPT{$CleanupReply} = '&cleanup("$opts"); $REASK';
+$CMDPROMPT{$QuitReply} = 'print "Thank you for using TeXit!\n\n";exit(0)';
+$CMDPROMPT{$StatusReply} = '&showstatus("$opts"); $REASK';
+
+$CMDTEST{$TeXReply} = '';
+$CMDTEST{$CleanupReply} = '&files_to_cleanup()';
+$CMDTEST{$QuitReply} = '';
+$CMDTEST{$StatusReply} = '';
+
+# It would be ok to change these...
+#
+$CMDPROMPT{$BibTeXReply} = '&bibtexcmd("$opts"); $RETEX';
+$CMDPROMPT{$GhostviewReply} = '&ghostviewcmd("$opts"); $REASK';
+$CMDPROMPT{$PrintReply} = '&printcmd("$opts"); $REASK';
+$CMDPROMPT{$ViewReply} = '&viewcmd("$opts"); $REASK';
+
+$CMDTEST{$BibTeXReply} = '"$BIBTEX" && -r &auxfile("aux")';
+$CMDTEST{$GhostviewReply} = '"$GSVIEW" && -r &auxfile("dvi")';
+$CMDTEST{$PrintReply} = '"%PRQUEUE" && -r &auxfile("dvi")';
+$CMDTEST{$ViewReply} = '"$VIEW" && -r &auxfile("dvi")';
+
+########################################################################
+# Look for a directory-local init file. Then load all the init files
+# that we've found. Load the global one, then the user-global one,
+# then the directory-local one then all the user specified ones, in
+# order.
+#
+# Note: init files are just bits of Perl code so they can really do
+# anything you want. But they have to be legal Perl. Usually they
+# just set some global vars.
+#
+# Yes, "require_hack" is ugly. But read the comments in that routine
+# and you'll see why it was necessary.
+#
+$texitrc = $TEXFILEPATH . $TEXITRC;
+print "Looking for local init file: $texitrc\n" if $VERBOSE;
+unshift (@TEXITINIT, $texitrc) if -r $texitrc;
+
+while (@TEXITINIT) {
+ $texitrc = pop(@TEXITINIT);
+ if (-r $texitrc) {
+ &require_hack ($texitrc);
+ } else {
+ warn "Can't read initfile: $texitrc\n";
+ }
+}
+
+while (@TEXITCMDLINE) {
+ $texitrc = pop(@TEXITCMDLINE);
+ if (-r $texitrc) {
+ &require_hack ($texitrc);
+ } else {
+ warn "Can't read initfile: $texitrc\n";
+ }
+}
+
+undef($texitrc);
+
+########################################################################
+# Now that all the initialization code has been run, build up an
+# abbreviation list for the printer queues.
+#
+{
+ local ($queue,@prlist);
+
+ foreach $queue (keys %PRQUEUE) {
+ unshift(@prlist, $queue);
+ }
+
+ %pr_queue_names = ();
+ &abbrev (*pr_queue_names, @prlist);
+}
+
+########################################################################
+# Pick a format. Tell the user if we don't agree about the format
+# they demanded. Shift the format to lowercase for using as a key in
+# the %format associative array.
+#
+# Bail out if we can't find the format in the %format.
+#
+print "Processing $TEXFILEPATH$TEXFILENAME.$TEXFILEEXT ... ";
+if ($TEXFORMAT ne "" && $TEXFORMAT ne $texvars{"mode"}) {
+ print "it looks like a $formatname{$texvars{mode}} file to me,\n";
+ print "but you said it was a $formatname{$TEXFORMAT} file. ";
+ print "Suit yourself.\n";
+} elsif ($TEXFORMAT eq "") {
+ print "it looks like a $formatname{$texvars{mode}} file to me.\n";
+ if ($texvars{"mode"} eq "latex" && $DEFAULTLATEXFORMAT) {
+ $TEXFORMAT = $DEFAULTLATEXFORMAT;
+ print "(Using $formatname{$TEXFORMAT} variant of LaTeX.)\n";
+ }
+} else {
+ print "using $formatname{$TEXFORMAT}, like you said.\n";
+}
+
+$TEXFORMAT = $texvars{"mode"} if $TEXFORMAT eq "";
+$TEXFORMAT =~ tr/A-Z/a-z/;
+
+die "Don't know what format file to use for \"$TEXFORMAT\".\n"
+ if $format{$TEXFORMAT} eq "";
+
+########################################################################
+# Let's make sure we can process this format...
+#
+{
+ local ($path) = $ENV{$ENV_TEXFMTS} || "/usr/local/lib/tex/formats";
+ local ($formatfile) = $format{$TEXFORMAT} . ".fmt";
+ local ($formatpath) = &find_on_path($path, $formatfile);
+
+ if ($formatpath eq "") {
+ print "\nCan't find the format file for ";
+ print "$formatname{$TEXFORMAT} on the $ENV_TEXFMTS path.\n";
+ die "Can't continue without \"$formatfile\".\n";
+ }
+}
+
+# If the user has specified an alternate inputs environment for this
+# format, temporarily set the environment for TeX...
+if ($altinputenv{$TEXFORMAT}
+ && $ENV{"$ENV_TEXINPUTS$altinputenv{$TEXFORMAT}"}) {
+ $ENV{"$ENV_TEXINPUTS"} = $ENV{"$ENV_TEXINPUTS$altinputenv{$TEXFORMAT}"};
+ print "Adjusting $ENV_TEXINPUTS environment variable for this format.\n";
+}
+
+########################################################################
+# Evaluate the PLC commands for this document.
+#
+# PLC commands are bits of Perl that usually look something like this:
+#
+# % &makeindex('-o driver.ind driver.idx')
+# % if &missing('driver.ind') || &changed('driver.idx');
+# % &bibtex('driver') if &newer('jigsaw.bib','driver.bbl');
+#
+# This says run MakeIndex if "driver.ind" is missing or "driver.idx"
+# changes over the course of a TeX run. And run BibTeX if the
+# bibliography file is newer than the BBL file (it'll also get run
+# automatically if any citations are unresolved).
+#
+# $first_time is true now so that &missing, &dependson, &changed, and
+# &newer all return false regardless of the condition tested. This
+# way we can initialize some globals before we run TeX for the first
+# time (to see if files change on the first run, for example).
+#
+# VERBOSE is forced off temporarily so that no stupid messages are
+# printed, even if the user wants them. Note the dynamic scoping
+# nature of Perl.
+#
+
+{
+ local ($VERBOSE) = 0;
+ local ($first_time) = 1;
+ local ($line, @the_rules);
+
+ @the_rules = @default_rules;
+ foreach $line (@the_rules) {
+ eval $line;
+ die "Invalid rule in \@default_rules: $line\n" if $@;
+ }
+
+ eval "\@the_rules = \@${TEXFORMAT}_rules";
+ foreach $line (@the_rules) {
+ eval $line;
+ die "Invalid rule in \@${TEXFORMAT}_rules: $line\n" if $@;
+ }
+
+ foreach $line (@PLCRULES) {
+ eval $line;
+ die "Invalid PLC rule: $line\n" if $@;
+ }
+}
+
+{
+ # Now print out the rules, if the user wants to see them...
+
+ local ($line, @the_rules);
+
+ if ($VERBOSE && @default_rules) {
+ print "Default rules:\n";
+ foreach $line (@default_rules) {
+ print " $line\n";
+ }
+ print "\n";
+ }
+
+ eval "\@the_rules = \@${TEXFORMAT}_rules";
+ if ($VERBOSE && @the_rules) {
+ print "$TEXFORMAT rules:\n";
+ foreach $line (@the_rules) {
+ print " $line\n";
+ }
+ print "\n";
+ }
+
+ if ($VERBOSE && @PLCRULES) {
+ print "Your document defined the following rules:\n";
+ foreach $line (@PLCRULES) {
+ print " $line\n";
+ }
+ print "\n";
+ }
+}
+
+########################################################################
+# If the user asked us to run MakeIndex or BibTeX first, run them now.
+#
+if ($runbibtexfirst) {
+ if (-r &auxfile("aux")) {
+ &bibtexcmd("");
+ } else {
+ print "There's no AUX file to run BibTeX against.\n";
+ }
+}
+undef($runbibtexfirst);
+
+if ($runmakeindexfirst) {
+ if (-r &auxfile("idx")) {
+ &makeindexcmd("");
+ } else {
+ print "There's no IDX file to run MakeIndex against.\n";
+ }
+}
+undef($runmakeindexfirst);
+
+########################################################################
+# Ok, now it's time to run TeX. Run TeX repeatedly until an error
+# occurs, the dependencies don't change or we've tried more than four
+# times. If it doesn't work in four tries, it never will.
+#
+$opts = ""; # user specified options after the prompt
+$changed = 0; # did the file change on this run?
+$runcount = 0; # how many times have we run TeX in a row?
+
+# Think about BibTeX: every time we run it, it changes the BBL file and
+# potentially causes us to decide to run TeX again. But if the list of
+# missing citations doesn't change after the first run, running again
+# won't help. So we keep track of the missing citations between runs
+# and only run BibTeX when it changes.
+#
+%missingcites = (); # last missing cite list
+
+# If not -menu, assume we'll TeX first...
+#
+$changed = !$GOTOMENU;
+
+# If the tex file and the dvi file and the log file all exist, maybe
+# we don't actually have to run TeX first...maybe the user just wants
+# to print or preview or something and they're used to typing "texit".
+#
+if (!$GOTOMENU && !$runtexfirst) { # if the user doesn't insist...
+ $changed = &dependencies_changed ()
+ if (-r $texmaster && -r &auxfile("dvi") && -r &auxfile("log"));
+ %missingcites = (); # the results from an old log don't count
+}
+undef($runtexfirst);
+
+$autocount = 0; # No automatic commands yet...
+$lastcmd = $TeXReply; # assume we ran tex...
+TEXLOOP: for(;;) { # don't stop till the user says quit.
+ if ($changed) {
+ $ERRORLINE = 0; # No errors occurred...
+ $ERRORFILE = ""; #
+ $rc = &texcmd($opts); # run TeX
+ # If the return code is less than TEXERROR, set it to zero.
+ # This canonicalizes the test for success when running a program
+ $rc = 0 if $rc < $TEXERROR;
+
+ # 9 Sep 93: the former test at this location failed to handle
+ # a document that _required_ four tries to process correctly.
+ $changed = 0;
+ $changed = 1 if $rc == 0 && &dependencies_changed ();
+ next TEXLOOP if $changed && $runcount < $TEXRETRIES;
+ } else {
+ $rc = 0;
+ }
+
+ if ($rc != 0) {
+ warn "TeX failed. All bets are off.\n\n";
+ ($ERRORFILE, $ERRORLINE) = &find_error_line();
+ }
+
+ if ($runcount >= $TEXRETRIES && $changed) {
+ print "\nI've tried $TEXRETRIES times and it still ";
+ print "isn't right...I give up.\n\n";
+ exit 1 if $ONCE;
+ } else {
+ if ($ONCE) {
+ &cleanup("") if $CLEANONEXIT && !$CLEANPROMPT && !$rc;
+ exit $rc;
+ }
+ }
+
+ $changed = 1; # assume it'll change before we get back to top...
+
+ ASKLOOP: for (;;) {
+ # User can change anything while we're sitting at the prompt, so
+ # reset runcount and citation list.
+ $runcount = 0;
+ %missingcites = ();
+
+ &set_x_titles("TeXit");
+
+ if ($rc == 0
+ && $AUTOCMD{$lastcmd} ne ""
+ && $CMDPROMPT{$AUTOCMD{$lastcmd}} ne ""
+ && $autocount < $AUTOMAX) {
+ $cmd = $AUTOCMD{$lastcmd};
+ $opts = "";
+ $autocount++;
+ } else {
+ $rc = 0;
+ $autocount = 0;
+ ($cmd, $opts) = &get_command();
+ }
+
+ if ($cmd eq "") {
+ $cmd = $QuitReply;
+ $cmd = $DEFAULTCMD{$lastcmd} if $DEFAULTCMD{$lastcmd} ne "";
+ $cmd = "redo" if !$TEXITFASTEXIT && $DEFAULTCMD{$lastcmd} eq "";
+
+ # Unless the last thing we did was cleanup, re-running TeX
+ # supercedes other commands if the DVI file is gone or any
+ # dependent files are newer...
+ if ($lastcmd ne $CleanupReply) {
+ if (! -r &auxfile("dvi")) {
+ print "\n", &auxfile("dvi"), " disappeared.\n";
+ $cmd = $TeXReply;
+ } elsif (&dependent_files_are_newer()) {
+ print "\nA file that the document ",
+ "depends on has changed.\n";
+ $cmd = $TeXReply;
+ }
+ }
+ }
+
+ next if $cmd eq "redo";
+
+ # Special case for $QuitReply if CLEANONEXIT is true:
+ #
+ if ($cmd eq $QuitReply && $CLEANONEXIT) {
+ $AUTOCMD{$CleanupReply} = $QuitReply; # exit w/o asking next
+ $CLEANONEXIT = 0; # Prevent reexecution of this code...
+ $cmd = $CleanupReply;
+ $opts = "";
+ }
+
+ if (($cmd eq $QuitReply) && $SETXTITLE) {
+ local ($host, $cwd);
+ chop($host = `hostname`);
+ chop($cwd = `pwd`);
+ &set_xterm_title("$host: $cwd");
+ &set_xicon_title("$host");
+ }
+
+ $lastcmd = $cmd;
+
+ # Ok, now it's time to 'eval' the command.
+ #
+ # First, copy it and protect any quotations in it from premature
+ # replacement. Note: the user has to protect backslashes by
+ # escaping them (i.e. in order to get "\" use "\\"). This is
+ # necessary so that the user can use a backslash to protect
+ # dollar signs for variable assignment.
+ #
+ # Then eval it once to do $-var substitution.
+ #
+ # Then eval it again to really do the work...
+ #
+ $thecmd = $CMDPROMPT{$cmd};
+ $thecmd =~ s/\"/\\"/g; # protect double quotes
+ eval "\$thecmd = \"$thecmd\"";
+ eval ( $thecmd );
+ die "Invalid command defined for $cmd: $CMDPROMPT{$cmd}\n" if $@;
+ }
+}
+
+########################################################################
+# These subroutines execute the expected commands. They are here, with
+# nice names, so that the PLC commands can use them and be easy to read.
+# Internally, different routines are used so that %-var substitution is
+# preformed. Note that it _isn't_ preformed here.
+#
+# &tex("foo") ==> $TEX foo
+#
+sub tex {
+ local ($opts) = @_;
+ local ($exopts);
+
+ $exopts = join(" ",$TEXOPTS{$TEXFORMAT},$CMDLINEOPTS,$opts);
+
+ &run($TEX . $exopts, "");
+}
+
+sub bibtex {
+ local ($opts) = @_;
+
+ &run($BIBTEX . " " . $BIBTEXOPTS . " " . $opts, "");
+}
+
+sub makeindex {
+ local ($opts) = @_;
+
+ &run($MAKEINDEX . " " . $MAKEINDEXOPTS . " " . $opts, "");
+}
+
+########################################################################
+# These are the subroutines used internally where all we want to pass
+# in are the _additional_ options.
+#
+# &texcmd("foo") => $TEXCMD with $TEXOPTS and "foo" inserted as options
+# and all other %-var substitution performed.
+#
+sub texcmd {
+ local ($opts) = @_;
+ local ($rc, $extex, $exopt);
+
+ $extex = $TEXCMD{"default"};
+ $extex = $TEXCMD{$TEXFORMAT} if $TEXCMD{$TEXFORMAT} ne "";
+ $exopt = join (" ", $TEXOPTS{$TEXFORMAT}, $CMDLINEOPTS, $opts);
+
+ $rc = &run ($extex, $exopt);
+ $runcount++;
+ $rc;
+}
+
+sub bibtexcmd {
+ local ($opts) = @_;
+ local ($rc);
+
+ if (! -r &auxfile("aux")) {
+ print "Cannot run BibTeX, no AUX file." if $VERBOSE;
+ $rc = -1;
+ } else {
+ $rc = &run ($BIBTEXCMD, $BIBTEXOPTS . " " . $opts);
+ }
+
+ $rc;
+}
+
+sub makeindexcmd {
+ local ($opts) = @_;
+
+ &run($MAKEINDEXCMD, $MAKEINDEXOPTS . " " . $opts);
+}
+
+sub viewcmd {
+ local ($opts) = @_;
+
+ &run ($VIEWCMD, $VIEWOPTS . " " . $opts);
+}
+
+sub printcmd {
+ local ($opts) = @_;
+ local ($queueopt, $dviuseropts, $prtuseropts);
+ local ($rc, $type);
+ local ($dvicmd, $dviopt, $prtcmd, $prtopt);
+ local ($doit,$queue);
+ local ($confirm) = $CONFIRMPRINT;
+
+ $queueopt = "";
+
+ # parse the user-specified options for a printer queue and options
+ if ($opts =~ /^\s*(\S+)\s*(.*)$/) {
+ $queueopt = $1;
+ $opts = $2;
+ }
+
+ # if the queue name starts with "-" or "/", assume that it's an option,
+ # not a queue name...
+ if ($queueopt =~ /^(-|\/)/) {
+ $opts = "$queueopt $opts";
+ $queueopt = "";
+ }
+
+ # if no queue is specified, use the default printer queue
+ $queueopt = $DEFAULT_PRINTER if $queueopt eq "";
+
+ if ($queueopt eq "") {
+ print "You must specify a printer queue (use \"p <printer>\").\n";
+ return(0);
+ }
+
+ # Special case, if the queue is "?", list the queues we know about.
+ if ($queueopt eq "?") {
+ &print_long_list("\nThe following queues are available: ",
+ sort(keys(%PRQUEUE)));
+ print "\n";
+ return (0);
+ }
+
+ $queue = $pr_queue_names{$queueopt};
+
+ if (!defined ($PRQUEUE{$queue})) {
+ warn "There is no printer queue named \"$queueopt\".\n";
+ return 0;
+ }
+
+ ($dviuseropts, $prtuseropts) = split (/\|/, $opts);
+
+ $type = $PRQUEUE{$queue};
+
+ if (!defined ($DVICMD{$type})) {
+ warn "There is no DVI driver for \"$type\" printers.\n";
+ return 0;
+ }
+
+ $dvicmd = $DVICMD{$type};
+ $dviopt = $DVIOPT{$type};
+
+ if ($DVIQUERY{$type} ne "") {
+ print $DVIQUERY{$type};
+ $_ = scalar (<STDIN>);
+ $dviuseropts .= " " . $_;
+ }
+
+ $prtcmd = $PRINTCMD{$queue};
+ $prtopt = $PRINTOPT{$queue};
+
+ $rc = &run ($dvicmd, $dviopt . " " . $dviuseropts);
+
+ warn "DVI driver failed.\n" if $rc;
+
+ $doit = ($prtcmd ne ""); # really print it...
+
+ if (defined($PRINTCONFIRM{$queue})) {
+ undef $confirm;
+ $confirm = 0 if "0" =~ /^$PRINTCONFIRM{$queue}/i;
+ $confirm = 0 if "no" =~ /^$PRINTCONFIRM{$queue}/i;
+ $confirm = 0 if "false" =~ /^$PRINTCONFIRM{$queue}/i;
+ $confirm = 1 if "1" =~ /^$PRINTCONFIRM{$queue}/i;
+ $confirm = 1 if "yes" =~ /^$PRINTCONFIRM{$queue}/i;
+ $confirm = 1 if "true" =~ /^$PRINTCONFIRM{$queue}/i;
+ if (! defined($confirm)) {
+ print "\nI don't know what `$PRINTCONFIRM{$queue}' means, ";
+ print "I'll assume that it means ";
+ print "`yes'.\n" if $CONFIRMPRINT;
+ print "`no'.\n" if !$CONFIRMPRINT;
+ $confirm = $CONFIRMPRINT;
+ }
+ }
+
+ # Wait! If the driver failed or there's a queue other than
+ # Ghostview selected, ask and make sure.
+ #
+ if ($rc || ($doit && ($queue ne "ghostview") && $confirm)) {
+ print "Really print to $queue? ";
+ $_ = scalar (<STDIN>); chop;
+ $doit = 0 if !/^y/i;
+ }
+
+ if ($doit) {
+ if ($PRINTQUERY{$queue} ne "") {
+ print $PRINTQUERY{$queue};
+ $_ = scalar (<STDIN>);
+ $prtuseropts .= " " . $_;
+ }
+ $rc = &run ($prtcmd, $prtopt . " " . $prtuseropts);
+ } else {
+ print "Print command aborted.\n" if ($prtcmd ne "");
+ $rc = -1;
+ }
+
+ $rc;
+}
+
+########################################################################
+# Ghostview is a little special. The print commands always have to
+# run the DVI driver because they don't know what kind of file might
+# be produced, but with Ghostview, we know that it'll be the master
+# document name with '.ps' on the end. So, if that exists and is
+# newer than the DVI file, don't bother running the DVI driver again.
+#
+# Note also that Ghostview knows what type it is, so the type doesn't
+# have to be in the printer queue. This means you can remove the
+# Ghostview printer from the queue list even if you don't have any
+# other PS printers.
+#
+# Oh, also, we always run the DVI driver again if the user entered
+# DVI driver options at the prompt...
+#
+sub ghostviewcmd {
+ local ($opts) = @_;
+ local ($queue, $dviuseropts, $prtuseropts);
+ local ($rc, $type);
+ local ($dvicmd, $dviopt, $prtcmd, $prtopt);
+ local ($doit);
+ local ($psfile) = &auxfile("ps");
+
+ ($dviuseropts, $prtuseropts) = split (/\|/, $opts);
+
+ $type = "ps";
+
+ if (!defined ($DVICMD{$type})) {
+ warn "There is no DVI driver for \"$type\" output.\n";
+ return 0;
+ }
+
+ $dvicmd = $DVICMD{$type};
+ $dviopt = $DVIOPT{$type};
+
+ if ((! -r $psfile || (&mtime($psfile) < &mtime(&auxfile("dvi"))))
+ || $dviuseropts ne "") {
+ $rc = &run ($dvicmd, $dviopt . " " . $dviuseropts);
+ } else {
+ print "\nPostScript file already exists.\n";
+ $rc = 0;
+ }
+
+ $doit = 1;
+ if ($rc) {
+ warn "DVI driver failed.\n";
+ print "Preview anyway? ";
+ $_ = scalar (<STDIN>); chop;
+ $doit = 1 if /^y/i;
+ }
+
+ if ($doit) {
+ $rc = &run ($GSVIEWCMD, $GSVIEWOPTS . " " . $prtuseropts);
+ }
+
+ $rc;
+}
+
+########################################################################
+# Add new files to the @cleanup_files array. This call makes sure that
+# duplicate filenames are not added. It simplifies the TeXit rules
+# for extending the list of files to clean up. Simply saying:
+#
+# push(@cleanup_files, 'one', 'two');
+#
+# is a bad idea because it'll add "one" and "two" each time the document
+# is processed. On the other hand, expecting users to type the rule:
+#
+# push(@cleanup_files, 'one', 'two') if $first_time;
+#
+# is unrealistic. So now they can just call cleanup_files...
+#
+sub cleanup_files {
+ local (@newfiles) = @_;
+ local ($file, $files, $newfile, $add);
+
+ $add = 1;
+ foreach $newfile (@newfiles) {
+ foreach $file (@cleanup_files) {
+ $add = 0;
+ last if $file eq $newfile;
+ $add = 1;
+ }
+ push (@cleanup_files, $newfile) if ($add);
+ }
+}
+
+########################################################################
+# Go out there and find all the files that have to be cleaned up.
+# Return them in a list.
+#
+sub files_to_cleanup {
+ local ($opts) = @_;
+ local (%thefiles);
+ local ($file, @filelist, $ext, @extlist);
+
+ @filelist = ();
+
+ # throw them all in an associative array first to
+ # avoid duplicates.
+ foreach $file (@cleanup_files) {
+ $file =~ s/\\/\//; # \ -> /
+ $file = $TEXFILEPATH . $file if $file !~ /\//;
+ $thefiles{$file} = 1;
+ }
+
+ # find the list of extensions in "@cleanup_<format>".
+ eval "\@extlist = \@cleanup_$TEXFORMAT";
+ if (@extlist) {
+ local ($file);
+ foreach $ext (@extlist) {
+ $file = &auxfile($ext);
+ $thefiles{$file} = 1;
+ }
+ }
+
+ # now put them in a regular array
+ foreach $file (keys %thefiles) {
+ if (-e $file) {
+ unshift(@filelist, $file);
+ }
+ }
+
+ # return that array
+
+ @filelist;
+}
+
+########################################################################
+# Delete any files that have to be cleaned up...
+#
+sub cleanup {
+ local ($opts) = @_;
+ local (@filelist, $_);
+
+ @filelist = &files_to_cleanup();
+
+ # if there are any files to be deleted, ask the user to confirm
+ # and then blow 'em away...
+ if (@filelist) {
+ &print_long_list ("\nDelete: ", sort @filelist);
+ print "\n";
+ if ($CLEANPROMPT) {
+ print "Really delete these files? ";
+ $_ = scalar (<STDIN>); chop;
+ } else {
+ $_ = "yes";
+ }
+
+ if (/^y/i) {
+ print "\n", unlink(@filelist), " files deleted.\n";
+ } else {
+ print "\nCleanup aborted.\n";
+ }
+
+ print "\n";
+ }
+}
+
+########################################################################
+# The workhorse. This routine takes a command string and an options
+# string. The command string is subjected to the following
+# interpolation:
+#
+# IN ORDER TO HANDLE SOME TEX WEIRDNESS WITH FILENAMES, THIS MACRO ASSUMES
+# THAT YOU PASSED '%t' TO THE TEX PROGRAM, IF YOU PASS '%s', THIS CODE
+# WILL MAKE INCORRECT SUBSTITUTIONS FOR SOME VARIABLES!
+#
+# 1) It is "eval"ed so that Perl variables in the
+# string are replaced with their values, i.e.
+# "$TEX foo" -> "virtex foo" if $TEX="virtex".
+#
+# 2) %-substitution is performed. The following
+# substitutions are currently supported:
+#
+# %F = format name (&lplain)
+# %s = base document name (myfile)
+# [ this used to mean /path/file w/o an extension, it now
+# means the name of the DVI file w/o the .dvi extension ]
+# %t = tex document name (/path/file.tex)
+# %d = dvi document name (myfile.dvi)
+# %e = error line, if there was one, otherwise 0
+# %E = file containing error, if there was one
+# %o = the options passed into run
+#
+# %S, %T, and %D are the same as %s, %t, and %d except that
+# pathname components are seperated by backslashes. This is a
+# hack for MS-DOS and OS/2.
+#
+# TeX has some funny rules about path names:
+#
+# - The DVI file always goes in the current directory,
+# the path is ignored.
+#
+# - To form the dvi filename, TeX strips off the last extension that
+# *you* provide and appends .dvi. For example:
+#
+# You say: You mean: Dvi file:
+# ------------- ------------ ------------
+# test.foo test.foo.tex test.dvi
+# test.foo test.foo test.dvi
+# test.foo.tex test.foo.tex test.foo.dvi
+# test.foo.bar test.foo.bar test.foo.dvi
+#
+sub run {
+ local ($cmd,$opts) = @_;
+ local ($format) = "&" . $format{$TEXFORMAT};
+ local ($texbase, $dvifile, $texfile);
+ local ($Texbase, $Dvifile, $Texfile);
+ local ($rc,$title);
+
+ $texfile = $TEXFILEPATH . $TEXFILENAME . "." . $TEXFILEEXT;
+ $texbase = $TEXFILENAME;
+ $dvifile = &auxfile ("dvi");
+
+ ($Texbase = $texbase) =~ s#/#\\#g;
+ ($Texfile = $texfile) =~ s#/#\\#g;
+ ($Dvifile = $dvifile) =~ s#/#\\#g;
+
+ # $cmd may be of the form "$TEX ..." and we want to
+ # expand the definition of $TEX, etc.
+ $cmd =~ s/\\/\\\\/g; # protect \'s
+ $cmd =~ s/\"/\\\"/g; # protect "'s
+ eval "\$cmd = \"$cmd\"";
+
+ # Now substitute for `%' options...
+ $cmd =~ s/\%F/$format/g;
+ $cmd =~ s/\%s/$texbase/g;
+ $cmd =~ s/\%t/$texfile/g;
+ $cmd =~ s/\%d/$dvifile/g;
+ $cmd =~ s/\%S/$Texbase/g;
+ $cmd =~ s/\%T/$Texfile/g;
+ $cmd =~ s/\%D/$Dvifile/g;
+ $cmd =~ s/\%e/$ERRORLINE/g if $ERRORLINE;
+ $cmd =~ s/\%E/$ERRORFILE/g if $ERRORLINE;
+ $cmd =~ s/\%o/$opts/g;
+
+ $cmd =~ s/\s+/ /g; # remove extranous whitespace, (display hack).
+
+ $title = (split(/\s/, $cmd))[0];
+ &set_xterm_title("TeXit: $title");
+ &set_xicon_title("$title");
+
+ print "\n$cmd\n";
+ $rc = system "$cmd";
+
+ if ($rc > 0) {
+ local (@parms);
+ @parms = split (/\s+/, $cmd);
+ print "\nNote: $parms[0] ended with return code $rc.\n";
+ }
+
+ $rc;
+}
+
+########################################################################
+# Gets a command from the user by building a prompt up from the
+# %CMDPROMPT and %CMDTEST arrays. A particular entry is only allowed
+# if an eval of it's %CMDTEST returns true.
+#
+# &get_command() returns a two element list. The first element is
+# index into the %CMDPROMPT array, the second element is any additional
+# arguments supplied by the user.
+#
+sub get_command {
+ local (%commands, $_, $options);
+ local ($promptstring, $promptprefix);
+ local ($line, $thetest, $result);
+
+ %commands = ();
+ $promptstring = "";
+ $promptprefix = "Again? ";
+ $line = $promptprefix;
+
+ # look for a stupid configuration error where a CMDTEST has
+ # gotten misspelled.
+ foreach $cmdname (keys %CMDTEST) {
+ die "$cmdname is defined as a CMDTEST but not as a CMDPROMPT.\n"
+ if !defined($CMDPROMPT{$cmdname});
+ }
+
+ foreach $cmdname (sort keys %CMDPROMPT) {
+ $thetest = $CMDTEST{$cmdname};
+ $result = 1;
+ if ($thetest ne "") {
+ eval "\$result = $thetest";
+ die "Bad CMDTEST: $thetest\n" if $@;
+ }
+
+ if ($result) {
+ local ($cmdkey) = $cmdname;
+ $cmdkey =~ s/^.*\[(.*)\].*$/$1/;
+ die "No command string in square brackets: $cmdname\n"
+ if $cmdkey eq "";
+ die "Duplicate command: $cmdname = $commands{$cmdkey}\n"
+ if defined($commands{$cmdkey});
+ $commands{$cmdkey} = $cmdname;
+ if ($cmdname !~ /^!.*/) {
+ if (length($line . $cmdname) < 60) {
+ $line .= $cmdname . ", ";
+ } else {
+ $promptstring .= $line . "\n";
+ $line = " " x length($promptprefix) . $cmdname . ", ";
+ }
+ }
+ }
+ }
+
+ $line =~ s/(.*),\s*$/$1/; # remove the last ", "...
+ $promptstring .= $line . ": ";
+
+ for (;;) {
+ ($cmdkey, $options) = ("", "");
+ print "\nProcessing: $TEXFILEPATH$TEXFILENAME.$TEXFILEEXT\n",
+ $promptstring;
+ $_ = scalar(<STDIN>); chop;
+ ($cmdkey, $options) = ($1, $2) if /\s*(\S+)\s*(.*)/;
+ last if $commands{$cmdkey} ne "" || $_ eq "";
+ print "\nI don't understand the command: $cmdkey\n\n";
+ }
+
+ ($commands{$cmdkey}, $options);
+}
+
+########################################################################
+# Parse the TeX file looking for a local variables section. Build
+# the associative array "%texvars" to hold the variables.
+#
+sub get_local_vars {
+ local($texfile) = @_;
+ local(@parms, $in_locals, $near_top, $in_plc, $plc_line);
+
+ open (TEXFILE, $texfile) || die "Can't read $texfile.\n";
+
+ $in_locals = 0; # have we found the start of the local vars?
+ $in_plc = 0; # are we in the PLC commands?
+ $near_top = $TEXHEADERSIZE; # are we in the "header" area?
+
+ @PLCRULES = (); # throw away any rules we've already found
+
+ while (<TEXFILE>) {
+ chop;
+
+ if ($near_top) {
+ $texvars{"TeX-master"} = $1 if /\%+\s*master:\s*(\S+)\s*$/i;
+ $texvars{"mode"} = $1 if /\%+\s*format:\s*(\S+)\s*$/i;
+ $texvars{"mode"} = $1 if /\%+\s*mode:\s*(\S+)\s*$/i;
+
+ if (!defined($texvars{"mode"})) {
+ $texvars{"mode"} = "latex" if (/^\\documentstyle/);
+ $texvars{"mode"} = "latex2e" if (/^\\documentclass/);
+ $texvars{"mode"} = "slitex" if (/^\\documentstyle.*\{slides\}/);
+ $texvars{"mode"} = "foiltex" if (/^\\documentstyle.*\{foils\}/);
+ $texvars{"mode"} = "amstex" if (/^\\document\s*$/);
+ $texvars{"mode"} = "lollipop" if (/^\\Define\w+:\w+/);
+ $texvars{"mode"} = "texinfo" if (/^\@node/);
+ $texvars{"mode"} = "texinfo" if (/^\@ifinfo/);
+ $texvars{"mode"} = "texinfo" if (/input texinfo/);
+ }
+
+ $near_top--;
+ }
+
+ $in_locals = 0 if $in_locals && /End:\s*$/;
+
+ if ($in_locals) {
+ local($_) = $_;
+ s/^\W*//; # remove leading whitespace
+ @parms = split(/[: \t\"\']+/);
+ $var = $parms[0];
+ shift(@parms);
+ $val = join(" ",@parms);
+ $texvars{$var} = $val if !defined($texvars{$var});
+ }
+
+ # the [V] makes sure Emacs doesn't get confused when editing
+ # texit.pl
+ $in_locals = 1 if /Local [V]ariables:\s*$/;
+
+ if ($in_plc && /End\s+TeXit\s+rules:\s*$/) {
+ push (@PLCRULES, $plc_line) if $plc_line ne "";
+ undef($plc_line);
+ $in_plc = 0;
+ }
+
+ if ($in_plc) {
+ local ($line) = $_;
+ local ($lastline) = /.*;\s*$/; # ends with a semicolon?
+ $line =~ s/\s*\%*\s*(.*)/$1/; # trim leading whitespace
+ $line =~ s/(.*)([^\\])(\#)(.*)$/$1$2/; # trim trailing comments
+ $line = "" if $line =~ /^\#/; # _only_ a comment?
+ $plc_line .= $line . " " if $line ne "";
+ if ($lastline) {
+ push (@PLCRULES, $plc_line);
+ $plc_line = "";
+ }
+ }
+
+ $in_plc = 1 if /Start\s+TeXit\s+rules:\s*$/;
+ }
+
+ warn "Unended local variables section?\n" if $in_locals;
+ die "Unended TeXit rules section!\n" if $in_plc;
+
+ close (TEXFILE);
+}
+
+########################################################################
+# Cleanup the TeX filename. Add the extension ".tex" if it doesn't
+# already have an extension.
+#
+sub cleanup_texfilename {
+ local($texfile) = @_;
+ local($path,$base,$ext) = &splitfn($texfile,".tex");
+
+ $ext = "tex" if ($ext eq "");
+
+ $path . $base . "." . $ext;
+}
+
+########################################################################
+# Break a filename into it's path, basename, and extension components.
+# The path returned always ends with a slash. "./" is returned if the
+# file has no path. If the filename passed in does not exist, the
+# default extension passed in is tried (actually, is assumed to be
+# correct).
+#
+sub splitfn {
+ local ($filename, $defext) = @_;
+ local ($path, $basename, $ext) = ("", "", "");
+
+ $filename =~ tr/\\/\//; # translate \ into /
+
+ $filename = $filename . $defext if ! -r $filename;
+
+ if ($filename =~ /\//) {
+ ($path = $filename) =~ s/\/[^\/]*$//;
+ ($basename = $filename) =~ s/.*\///;
+ }
+ else {
+ $path = ".";
+ $basename = $filename;
+ }
+
+ if ($basename =~ /\./) {
+ ($ext = $basename) =~ s/.*\.//;
+ $basename =~ s/\.[^.]*$//;
+ }
+
+ ($path . "/",$basename,$ext);
+}
+
+########################################################################
+# Print a %done message when scanning LOGFILE
+#
+sub percent_done {
+ local ($logfile) = @_;
+
+ if ($logfile) {
+ $LOGSIZE = -s $logfile;
+ $LOGPERC = 0;
+ $LOGPREV = 0;
+ } else {
+ $LOGPERC = int (tell(LOGFILE) / $LOGSIZE * 100.0);
+ printf "Parsing log file...%d%% done\r", $LOGPERC
+ if $LOGPERC > $LOGPREV;
+ $LOGPREV = $LOGPERC;
+ }
+}
+
+########################################################################
+# Search the log file looking for the (first) line that contains an
+# error.
+#
+sub find_error_line {
+ local ($logfile) = &auxfile("log");
+ local ($prevtext, $curfile, $paren, $rest, $temp);
+ local ($line) = 0;
+
+ &init_parse_log_filenames();
+
+ $curfile = "";
+
+ if (-r $logfile) {
+ &percent_done($logfile);
+ open (LOGFILE, $logfile);
+ while (<LOGFILE>) {
+ chop;
+ &percent_done();
+
+ ($paren, $rest, $temp) = &parse_log_filenames($_);
+ while ($paren eq "(" || $paren eq ")") {
+ $curfile = $temp;
+ ($paren, $rest, $temp) = &parse_log_filenames($rest);
+ }
+
+ if ($prevtext =~ /^! .*$/
+ && /^l\.([0-9]+) /) {
+ $line = $1;
+ }
+
+ last if $line;
+
+ $prevtext = $_;
+ }
+ close (LOGFILE);
+ }
+
+ ($curfile, $line);
+}
+
+########################################################################
+# Look through the log file for warnings.
+#
+sub parse_default_log {
+ # only looks for new dependency files...
+ local ($paren, $rest, $tempfile, $curfile);
+ local ($logfile) = &auxfile("log");
+
+ &init_parse_log_filenames();
+
+ if (-r $logfile) {
+ &percent_done ($logfile);
+ open (LOGFILE, $logfile);
+ while (<LOGFILE>) {
+ chop;
+ &percent_done ();
+
+ ($paren, $rest, $tempfile) = &parse_log_filenames($_);
+ while ($paren eq "(" || $paren eq ")") {
+ $curfile = $tempfile;
+ printf("Adding dependency for `%s'.\n", $curfile)
+ if !defined($DEPENDSON{$curfile}) && $VERBOSE;
+ $DEPENDSON{$curfile} = 1;
+ ($paren, $rest, $tempfile) = &parse_log_filenames($rest);
+ }
+ }
+ }
+ close (LOGFILE);
+}
+
+########################################################################
+# Look through the log file for the LaTeX warnings.
+#
+sub parse_latex_log {
+ local ($newbib, $misbib, $newref, $badref, $badfont) = (0, 0, 0, 0, 0);
+ local ($hastoc, $haslof, $haslot) = (0, 0, 0);
+ local ($font, $reference, $citation);
+ local ($inputfile, $warning);
+ local ($logfile) = &auxfile("log");
+ local ($auxfile) = &auxfile("aux");
+ local ($paren, $rest, $curfile, $tempfile);
+
+ # These are global values.
+ undef (%citelist); # undefined citations
+ undef (%reflist); # undefined references
+ undef (%fontlist); # NFSS substituted fonts
+ undef (%refmultlist); # multiply defined references
+ undef (%WARNINGS); # Unrecognized warning messages
+
+ &init_parse_log_filenames();
+
+ if (-r $logfile) {
+ &percent_done ($logfile);
+ open (LOGFILE, $logfile);
+ while (<LOGFILE>) {
+ chop;
+ &percent_done ();
+
+ $warning = 0;
+
+ ($paren, $rest, $tempfile) = &parse_log_filenames($_);
+ while ($paren eq "(" || $paren eq ")") {
+ $curfile = $tempfile;
+ printf("Adding dependency for `%s'.\n", $curfile)
+ if !defined($DEPENDSON{$curfile}) && $VERBOSE;
+ $DEPENDSON{$curfile} = 1;
+ ($paren, $rest, $tempfile) = &parse_log_filenames($rest);
+ }
+
+ if (/LaTeX Warning: Citation/) {
+ $newbib = 1;
+ ($citation = $_) =~ s/.*`(.*)'.*/$1/; # '`
+ $citelist{$citation} = 1;
+ $warning = 1;
+ }
+
+ if (/LaTeX Warning: Reference/) {
+ ($reference = $_) =~ s/.*\`(.*)\'.*/$1/;
+ $reflist{$reference} = 1;
+ $badref = 1;
+ $warning = 1;
+ }
+
+ if (/LaTeX Warning: Label `(.*)' multiply defined/) { # '`
+ $refmultlist{$1} = 1;
+ $badref = 1;
+ $warning = 1;
+ }
+
+ if (/Warning: Font\/shape.*undefined/) {
+ ($font = $_) =~ s/.*\`(\S+)\s*\'.*/$1/;
+ $fontlist{$font} = 1;
+ $badfont = 1;
+ $warning = 1;
+ }
+
+ if (/Warning: Font\/shape.*not available/) {
+ ($font = $_) =~ s/.*\`(\S+)\s*\'.*/$1/;
+ $fontlist{$font} = 1;
+ $badfont = 1;
+ $warning = 1;
+ }
+
+ if (/LaTeX Warning: Label\(s\) may have changed/) {
+ $newref = 1;
+ $warning = 1;
+ }
+
+ # LaTeX2e
+ if (/LaTeX Warning: There are unresolved references./) {
+ $warning = 1;
+ }
+
+ if (/LaTeX Warning: Marginpar on page .* moved./
+ || /Warning: Using `.*' instead on input line [0-9]+./ # '`
+ || /Warning: Using external font `.*' instead on input/ # '`
+ || /Warning: Substituting `.*' instead on input/) { # '`
+ $warning = 1; # don't bother to show these warnings.
+ }
+
+ if ((/Warning:/ && !$warning)
+ || /NFSS Info: \*\*\*/) {
+ $WARNINGS{$_} = $curfile;
+ }
+
+ if (/No file .*\.bbl\./) {
+ $misbib = 1;
+ }
+
+ # see if the file should have TOC, LOF, and LOT files...
+ $hastoc = 1 if /tf\@toc/;
+ $haslof = 1 if /tf\@lof/;
+ $haslot = 1 if /tf\@lot/;
+ }
+ close (LOGFILE);
+ }
+
+ if (-r $auxfile) {
+ open (AUXFILE, $auxfile);
+ while (<AUXFILE>) {
+ chop;
+
+ if (/\\bibstyle\{(.+)\}/) {
+ local ($name, $fullname);
+ $name = $1 . ".bst";
+ $fullname = &find_on_path($ENV{"$ENV_TEXINPUTS"}, $name);
+ if ($fullname ne ""
+ && -r $fullname
+ && !defined($DEPENDSON{$fullname})) {
+ printf("Adding dependency for `%s'.\n", $fullname)
+ if !defined($DEPENDSON{$fullname}) && $VERBOSE;
+ $DEPENDSON{$fullname} = 1;
+ }
+ }
+
+ if (/\\bibdata\{(.+)\}/) {
+ local (@filelist, $fullname, $name);
+
+ @filelist = split(/,/, $1);
+ while (($name = shift @filelist)) {
+ $name = $name . ".bib";
+ $fullname = &find_on_path($ENV{"$ENV_BIBINPUTS"}, $name);
+ if ($fullname ne ""
+ && -r $fullname
+ && !defined($DEPENDSON{$fullname})) {
+ printf("Adding dependency for `%s'.\n", $fullname)
+ if !defined($DEPENDSON{$fullname}) && $VERBOSE;
+ $DEPENDSON{$fullname} = 1;
+ }
+ }
+ }
+ }
+ close (AUXFILE);
+ }
+
+ ($newbib, $misbib, $newref, $badref, $badfont, $hastoc, $haslof, $haslot);
+}
+
+########################################################################
+# Look through the log file for the Texinfo warnings.
+#
+sub parse_texinfo_log {
+ local ($newref, $badref) = (0, 0);
+ local ($logfile) = &auxfile("log");
+ local ($ref);
+ local ($paren, $rest, $tempfile, $curfile);
+
+ undef (%reflist); # undefined references
+
+ &init_parse_log_filenames();
+
+ if (-r $logfile) {
+ &percent_done ($logfile);
+ open (LOGFILE, $logfile);
+ while (<LOGFILE>) {
+ chop;
+ &percent_done ();
+
+ ($paren, $rest, $tempfile) = &parse_log_filenames($_);
+ while ($paren eq "(" || $paren eq ")") {
+ $curfile = $tempfile;
+ printf("Adding dependency for `%s'.\n", $curfile)
+ if !defined($DEPENDSON{$curfile}) && $VERBOSE;
+ $DEPENDSON{$curfile} = 1;
+ ($paren, $rest, $tempfile) = &parse_log_filenames($rest);
+ }
+
+ if (/Undefined cross reference \`(.*)\'./) {
+ $badref = 1;
+ $ref = $1;
+ $ref = $1 if $ref =~ /(.*)-[^\-]*/;
+ $reflist{$ref} = 1;
+ }
+
+ $newref = 1
+ if /Cross reference values unknown; you must run TeX again./;
+ }
+ close (LOGFILE);
+ }
+
+ ($newref, $badref);
+}
+
+########################################################################
+# This routine aids in the parsing of log files be locating filenames
+# within the log. Filenames included in a document always appear as
+# '(filename...' in the log.
+#
+# NOTE: if unbalanced parenthesis occur in the log file (because someone
+# printed them in a \typeout command or some such), all bets are
+# off!
+#
+# FURTHER NOTE: this routine returns the top of the filename stack
+# whenever a close paren is seen, so you will get the
+# same files more than once...
+#
+# This routine uses the global variables %ParenLevel and %Parens which
+# it initializes appropriately...
+#
+# **********************************************************************
+# THIS ROUTINE IS NOT RE-ENTRANT! IT REQUIRES STATE SAVED ACROSS CALLS!
+# **********************************************************************
+#
+sub init_parse_log_filenames {
+ %Parens = ();
+ $ParenLevel = 0;
+}
+
+sub parse_log_filenames {
+ local ($rest) = @_;
+ local ($paren, $curfile);
+ local (@result) = ();
+
+ undef ($curfile);
+
+ while ($rest =~ /^[^()]*(\(|\))(.*)/) {
+ $paren = $1;
+ $rest = $2;
+
+ ($curfile = $rest) =~ s/\s*(\S+)/$1/; # leading whitesp
+ $curfile =~ s/^([^() ]+).*/$1/; # trailing ( and )
+
+ if ($paren eq "(") {
+ $ParenLevel++;
+ if (-r $curfile) {
+ $Parens{$ParenLevel} = $curfile;
+ } else {
+ $Parens{$ParenLevel} = '*';
+ }
+ } else {
+ $ParenLevel--;
+ $curfile = $Parens{$ParenLevel};
+ }
+
+ last if -r $curfile;
+
+ undef ($curfile);
+ }
+
+ if ($curfile) {
+ @result = ("$paren", "$rest", "$curfile");
+ }
+
+ @result;
+}
+
+########################################################################
+# This routine is called after each run of TeX to see if TeX needs to
+# be run again. TeX needs to be run twice when documents contain
+# cross references, lists of tables, or other things which cannot be
+# completely determined in a single pass. Sometimes TeX needs to be
+# run three times.
+#
+# Since different formats print different messages in the log file,
+# there is no universal way to determine if TeX needs to be run again.
+#
+# This routine calls "&parse_FORMAT_log()" to extract information from
+# the log file and "&interpret_FORMAT_log()" to decide what to do with
+# the information. "&parse_FORMAT_log()" should return a list, this
+# list is passed to "&interpret_FORMAT_log()".
+#
+# FORMAT = $parsename{$TEXFORMAT}.
+#
+# Currently only "default" and "latex" FORMATs exist. The default
+# format just looks to see if the DVI file still exists or if the
+# master file is newer than the DVI file.
+#
+# The latex format does a lot more.
+#
+# If you write new &parse_FORMAT_log()/&interpret_FORMAT_log() routines,
+# remember to do the same checking that &interpret_default_log() does
+# and remember to run the users PLC commands at an appropriate place.
+# Copying and modifying the latex versions is probably the best way
+# to start.
+#
+sub dependencies_changed {
+ local (@parselist, $sub);
+
+ $changed = 0;
+
+ eval "\@parselist = &parse_$parsename{$TEXFORMAT}_log();";
+ eval "\$changed = &interpret_$parsename{$TEXFORMAT}_log(\@parselist);";
+
+ $changed;
+}
+
+########################################################################
+# Called by the interpret_FORMAT_routines, this function returns
+# true if the dvi file is missing or the master document is more
+# recent than the dvi file...
+#
+sub document_is_newer {
+ local ($changed) = 0;
+
+ if (! -r &auxfile("dvi")) {
+ print &auxfile("dvi"), " is missing.\n" if $VERBOSE;
+ $changed = 1;
+ } elsif (&mtime(&auxfile("dvi")) < &mtime($texmaster)) {
+ print "$texmaster is newer than ", &auxfile("dvi"), ".\n"
+ if $VERBOSE;
+ $changed = 1;
+ }
+
+ $changed;
+}
+
+########################################################################
+# Called by the interpret_FORMAT_routines, this function runs the
+# @default_rules, @FORMAT_rules, and user rules...
+# Input: $changed
+# Output: new value of $changed
+#
+sub run_rules {
+ local ($changed) = @_;
+ local ($line, @the_rules);
+
+ @the_rules = @default_rules;
+ foreach $line (@the_rules) {
+ print "Rule: $line\n" if $VERBOSE;
+ eval $line;
+ die "Invalid rule: $line\n" if $@;
+ }
+
+ eval "\@the_rules = \@${TEXFORMAT}_rules";
+ foreach $line (@the_rules) {
+ print "Rule: $line\n" if $VERBOSE;
+ eval $line;
+ die "Invalid rule: $line\n" if $@;
+ }
+
+ foreach $line (@PLCRULES) {
+ print "Rule: $line\n" if $VERBOSE;
+ eval $line;
+ die "Invalid rule: $line\n" if $@;
+ }
+
+ $changed;
+}
+
+########################################################################
+# Input: the list of values returned by parse_default_log().
+# Output: prints informative messages.
+# Returns: 1 if TeX should be run again...
+#
+sub interpret_default_log {
+ local ($changed) = 0;
+
+ $changed = &document_is_newer();
+ $changed = &run_rules($changed);
+ $changed = 1 if &dependent_files_are_newer();
+
+ print "\nAs far as I can tell, the document is up to date.\n"
+ if !$changed;
+
+ $changed;
+}
+
+########################################################################
+# Input: the list of values returned by parse_latex_log().
+# Output: prints informative messages.
+# Returns: 1 if TeX should be run again...
+#
+sub interpret_latex_log {
+ local ($newbib, $misbib, $newref, $badref, $badfont,
+ $hastoc, $haslof, $haslot) = @_;
+ local ($changed) = 0;
+ local ($warning);
+
+ $changed = &document_is_newer();
+
+ # If the document should have TOC, LOF, or LOT files but they
+ # don't actually exist, then the document has to be TeX'd
+ # again.
+ if (($hastoc && ! -r &auxfile("toc"))
+ || ($haslof && ! -r &auxfile("lof"))
+ || ($haslot && ! -r &auxfile("lot"))) {
+ $changed = 1;
+ print "Table of contents disappeared.\n"
+ if $hastoc && ! -r &auxfile("toc");
+ print "List of figures disappeared.\n"
+ if $haslof && ! -r &auxfile("lof");
+ print "List of tables disappeared.\n"
+ if $haslot && ! -r &auxfile("lot");
+ }
+
+ # If there are unknown citations...
+ if ($newbib) {
+ local ($wasdiff) = 0;
+
+ &print_long_list ("Missing citations: ", keys(%citelist));
+
+ # calculate the intersection between the currently missing
+ # citations and the ones that were missing last time. If they
+ # are different, run BibTeX. Since missingcites begins empty,
+ # this will force BibTeX to be run at least once if there are
+ # any missing citations.
+ {
+ local (%mark, @diff, $_);
+ grep($mark{$_}++, keys(%missingcites));
+ @diff = grep(!$mark{$_}, keys(%citelist));
+ if (@diff) {
+ $rc = &bibtexcmd ("");
+ print "\n";
+ $changed = 1;
+ $wasdiff = 1;
+ }
+ }
+
+ if (%missingcites) {
+ print "Bibliography database(s) may be incomplete.\n";
+ if (! $wasdiff) {
+ print "The same citations are missing. ",
+ "Running BibTeX again won't help.\n";
+ }
+ }
+ print "\n";
+
+ %missingcites = %citelist;
+ }
+
+ if ($misbib && ! $newbib) {
+ $rc = &bibtexcmd("");
+ print "\n";
+ }
+
+ # If there are unknown references...
+ if ($badref) {
+ if (%reflist) {
+ &print_long_list ("Missing references: ",
+ keys(%reflist));
+ print "\n";
+ }
+ if (%refmultlist) {
+ &print_long_list ("Multiply defined references: ",
+ keys(%refmultlist));
+ print "\n";
+ # Retry once if the error is found on the first pass
+ # because the error persists in the AUX file through
+ # one run after the user fixes the problem.
+ $newref = 0 if $runcount > 1;
+ }
+ }
+
+ # Just FYI about substituted fonts...
+ if ($badfont) {
+ &print_long_list ("FYI: substituted fonts: ",
+ keys(%fontlist));
+ print "\n";
+ }
+
+ # If there are Warnings that TeXit doesn't understand...
+ if (%WARNINGS) {
+ print "\nThe following (unrecognized) warnings appear ",
+ "in the log file:\n";
+ foreach $warning (keys %WARNINGS) {
+ if ($warning =~ /input line ([0-9]+)./) {
+ printf "%s: %d: %s\n", $WARNINGS{$warning}, $1, $warning;
+ } else {
+ print $WARNINGS{$warning}, ": ", $warning, "\n";
+ }
+ }
+ }
+
+ # The file has changed if there are new references...
+ $changed = $changed || $newref;
+
+ $changed = &run_rules($changed);
+ $changed = 1 if &dependent_files_are_newer();
+
+ if (!$changed) {
+ if ($newbib || $badref) {
+ print "\nThe document is still incorrect, ";
+ print "but TeXing again won't help.\n";
+ print "Some citations cannot be found. "
+ if $newbib;
+ print "Some references cannot be found or cannot be resolved."
+ if $badref;
+ print "\n\n";
+ } else {
+ print "\nAs far as I can tell, the document is up to date.\n";
+ }
+ } else {
+ print "\n";
+ }
+
+ $changed;
+}
+
+########################################################################
+# Input: the list of values returned by parse_texinfo_log().
+# Output: prints informative messages.
+# Returns: 1 if TeX should be run again...
+#
+sub interpret_texinfo_log {
+ local ($newref, $badref) = @_;
+ local ($changed) = 0;
+
+ # If there are unknown references...
+ if ($badref) {
+ if (%reflist) {
+ print "\n";
+ &print_long_list ("Missing references: ",
+ keys(%reflist));
+ print "\n";
+ }
+ }
+
+ $changed = &document_is_newer() || $newref;
+ $changed = &run_rules($changed);
+ $changed = 1 if &dependent_files_are_newer();
+
+ if (!$changed) {
+ if ($badref) {
+ print "The document is still incorrect, ";
+ print "but TeXing again won't help.\n";
+ print "Some references cannot be found or cannot be resolved."
+ if $badref;
+ print "\n\n";
+ } else {
+ print "As far as I can tell, the document is up to date.\n";
+ }
+ }
+
+ $changed;
+}
+
+########################################################################
+# Input: an extension, `ext'
+# Output: the filename $TEXFILEPATH . $TEXFILENAME . `.ext'
+# Note: auxilliary files are always placed in the current directory,
+# the path is ignored. This is a change from v1.27 to be more
+# compatible with TeX.
+#
+sub auxfile {
+ local($ext) = @_;
+ local($dot);
+
+ $dot = "";
+ $dot = "." if $ext ne "" && $ext !~ /^\./;
+
+ $TEXFILENAME . $dot . $ext;
+}
+
+########################################################################
+# Input: none
+# Output: true if any file in %DEPENDSON is newer than DVI file
+#
+sub dependent_files_are_newer {
+ local($file, $rerun);
+
+ $rerun = 0;
+ if (-r &auxfile("dvi")) {
+ foreach $file (keys %DEPENDSON) {
+ if (-r $file) {
+ if (&mtime(&auxfile("dvi")) < &mtime($file)) {
+ print "$file newer than DVI file? Yes.\n"
+ if $VERBOSE;
+ $rerun = 1;
+ } else {
+ print "$file newer than DVI file? No.\n"
+ if $VERBOSE;
+ }
+ } else {
+ print "$file newer than DVI file? No (doesn't exist).\n"
+ if $VERBOSE;
+ }
+ }
+ }
+
+ $rerun;
+}
+
+########################################################################
+# Input: list of files
+# Output: None. Sets the %DEPENDSON list...
+#
+sub dependson {
+ local(@filelist) = @_;
+ local($file);
+
+ foreach $file (@filelist) {
+ $DEPENDSON{$file} = 1;
+ }
+}
+
+########################################################################
+# Input: list of files
+# Output: true if any file is missing
+#
+sub missing {
+ local(@filelist) = @_;
+ local($missing, $file);
+
+ $missing = 0;
+
+ foreach $file (@filelist) {
+ if (defined($ifmissing{$file})) {
+ if (! -r $file) {
+ print "Missing: $file? Yes.\n" if $VERBOSE;
+ $missing = 1;
+ } else {
+ print "Missing: $file? No.\n" if $VERBOSE;
+ }
+ } else {
+ $ifmissing{$file} = 1;
+ }
+ }
+
+ $missing && (!$first_time);
+}
+
+########################################################################
+# Input: list of files
+# Output: waits until they all exist (and are readable)
+#
+sub waitfor {
+ local(@filelist) = @_;
+ local(@missing, $file);
+
+ @missing = ();
+
+ foreach $file (@filelist) {
+ push (@missing, $file) if (! -r $file);
+ }
+
+ if ($VERBOSE && @missing) {
+ &print_long_list ("\nWaiting for: ",@filelist);
+ print "\n";
+ }
+
+ foreach $file (@missing) {
+ while (! -r $file) {
+ sleep 1;
+ }
+ }
+}
+
+########################################################################
+# Input: list of files
+# Output: true if any file has changed. A file has changed if its
+# checksum is different from the preceding call. Files that
+# are missing both times are currently the same.
+#
+sub changed {
+ local(@filelist) = @_;
+ local($changed, $savecheck, $file);
+
+ $changed = 0;
+
+ foreach $file (@filelist) {
+ if (defined($ifchanged{$file})) {
+ $savecheck = &checksum($file);
+ if ($ifchanged{$file} != $savecheck) {
+ print "Changed: $file? Yes.\n" if $VERBOSE;
+ $ifchanged{$file} = $savecheck;
+ $changed = 1;
+ } else {
+ print "Changed: $file? No.\n" if $VERBOSE;
+ }
+ } else {
+ $ifchanged{$file} = &checksum($file);
+ }
+ }
+
+ $changed && (!$first_time);
+}
+
+########################################################################
+# Calculate a checksum for a file.
+#
+sub checksum {
+ local($file) = @_;
+ local($/, $checksum);
+
+ undef $/;
+
+ if (-r $file) {
+ open (CHECKSUM, $file);
+ $checksum = unpack("%32C*", <CHECKSUM>);
+ close (CHECKSUM);
+ } else {
+ $checksum = "none";
+ }
+
+ $checksum;
+}
+
+########################################################################
+# Input: two lists of files. The lists must be quoted strings so that
+# they can be seperated easily. The two strings are split on
+# "/, /" so they _can_ include multiple files.
+# Output: true if _any_ of the first list of files is newer than _any_
+# of the second list of files _or_ any of the second list of
+# files is missing.
+#
+sub newer {
+ local ($newfile, $oldfile) = @_;
+ local (@newfiles,@oldfiles);
+ local ($file, $missing, $newer);
+
+ @newfiles = split(/[, ]/, $newfile);
+ @oldfiles = split(/[, ]/, $oldfile);
+
+ die "Bad call to &newer(). No files in `new' list.\n"
+ if !@newfiles;
+ die "Bad call to &newer(). No files in `old' list.\n"
+ if !@oldfiles;
+
+ $newer = 0;
+
+ # Find the oldest old file. All must exist.
+ undef $oldfile;
+ foreach $file (@oldfiles) {
+ $newer = 1, $missing = $file, last if ! -r $file;
+ $oldfile = $file
+ if (! $oldfile || (&mtime($file) < &mtime($oldfile)));
+ }
+
+ # Find the newest new file.
+ undef $newfile;
+ foreach $file (@newfiles) {
+ $newfile = $file
+ if (-r $file
+ && (! $newfile || (&mtime($file) > &mtime($newfile))));
+ }
+
+ warn "None of the `new' files exist: @newfiles\n"
+ if ! $newfile;
+
+ $newer = $newer
+ || ($newfile && (&mtime($newfile) > &mtime($oldfile)));
+
+ if ($newer) {
+ if ($oldfile) {
+ print "$newfile newer than $oldfile? Yes.\n"
+ if $VERBOSE;
+ } else {
+ print "$missing doesn't exist, so $newfile is newer.\n"
+ if $VERBOSE;
+ }
+ } else {
+ print "$newfile newer than $oldfile? No.\n"
+ if $VERBOSE;
+ }
+
+ $newer && (!$first_time);
+}
+
+########################################################################
+# This routine prints a message followed by a potentially long list of
+# items, seperated by spaces. It will never allow "word wrap" to occur
+# in the middle of a word. There has to be a better way, using Perl's
+# report generation to do this, but I haven't looked yet.
+#
+sub print_long_list {
+ local ($message,@thelist) = @_;
+ local ($line) = $message;
+ local ($item, $displaystring) = ("", "");
+
+ foreach $item (@thelist) {
+ if (length($line . $item) < 73) {
+ $line .= $item . ", ";
+ } else {
+ $displaystring .= $line . "\n";
+ $line = $item . ", ";
+ }
+ }
+
+ $line =~ s/(.*),\s*$/$1/; # remove the last ", "...
+ $displaystring .= $line . "\n";
+
+ print $displaystring;
+}
+
+########################################################################
+# Shows the current status of TeXit. This is kindof a debugging option
+# and kindof a 'satisfy my curiousity' option. It isn't really very
+# complete yet.
+sub showstatus {
+ local($opts) = @_;
+
+ print "\n";
+
+ if ($opts eq "?" || $opts eq "") {
+ print "Status options:\n";
+ print " rules = rules\n";
+ print " dep = document dependencies\n";
+ print " <var> = value of Perl variable <var>\n";
+ } elsif ($opts eq "rules") {
+ local ($line, @the_rules);
+
+ @the_rules = @default_rules;
+ foreach $line (@the_rules) {
+ print "Default rule: $line\n";
+ }
+
+ eval "\@the_rules = \@${TEXFORMAT}_rules";
+ foreach $line (@the_rules) {
+ print "$TEXFORMAT rule: $line\n";
+ }
+
+ foreach $line (@PLCRULES) {
+ print "Document rule: $line\n";
+ }
+ } elsif ($opts eq "dep") {
+ local ($line);
+
+ print "This document depends on the following files:\n";
+ foreach $line (keys %DEPENDSON) {
+ print "\t$line\n";
+ }
+ } else {
+ local ($arg, $svalue, %pvalue, @avalue, $line, $isdef);
+
+ $isdef = 0;
+
+ eval "\$arg = defined(\$$opts);";
+ if ($arg) {
+ eval "\$svalue = \$$opts;";
+ print "\$$opts = $svalue\n";
+ $isdef = 1;
+ }
+
+ eval "\$arg = defined(\%$opts);";
+ if ($arg) {
+ print "\%$opts:\n";
+ eval "\%pvalue = \%$opts;";
+ foreach $line (keys %pvalue) {
+ print "$line = $pvalue{$line}\n";
+ }
+ $isdef = 1;
+ }
+
+ eval "\$arg = defined(\@$opts);";
+ if ($arg) {
+ print "\@$opts:\n";
+ eval "\@avalue = \@$opts;";
+ foreach $line (@avalue) {
+ print "$line\n";
+ }
+ $isdef = 1;
+ }
+
+ if (! $isdef) {
+ print "$opts is undefined.\n";
+ }
+ }
+}
+
+########################################################################
+# Setup the $format{}, $formatname{}, and $parsename{} associative
+# arrays for finding the format file name, printable name, and parser
+# name for each format.
+sub setup_format {
+ local ($common_name, $printable_name,
+ $parser_name, $format_name, $alt_inputenv) = @_;
+
+ $format{$common_name} = $format_name;
+ $formatname{$common_name} = $printable_name;
+ $parsename{$common_name} = $parser_name;
+ $altinputenv{$common_name} = $alt_inputenv;
+}
+
+########################################################################
+# Builds an associative array for a pascal-like case statement. This
+# is a bit obscure and relies on Perl's ability to evaluate strings
+# that look like code at runtime.
+sub case {
+ local(*assoc,$_) = @_;
+ for (split(/\n/)) {
+ /^\s*(\S+)\s+(.*)/;
+ for (eval $1) {
+ $assoc{$_} = $2;
+ }
+ }
+}
+
+########################################################################
+# Return Perl version info...
+#
+sub perl_version_info {
+ local($savestar) = $*;
+
+ $* = 1;
+
+ $] =~ /^.*Revision: ([\d.]+) .*\nPatch level: (\d+).*$/;
+ $revision = $1;
+ $patchlevel = $2;
+
+ $* = $savestar;
+
+ ($revision, $patchlevel);
+}
+
+########################################################################
+# This hack gets around problems with MS-DOS and OS/2 ports of Perl.
+# Some ports get confused when presented with "require d:/path/file"
+# because they think "d:/path/file" should appear somewhere in @INC
+# because it doesn't begin with a slash. Sigh. This code isn't as
+# nice as "require" but it works...
+#
+sub require_hack {
+ local($file) = @_;
+ local($line);
+
+ print "Loading init file: $file\n" if $VERBOSE;
+
+ $line = "";
+ open (INIT, $file);
+ while (<INIT>) {
+ $line = $line . $_;
+ if (/;\s*$/) {
+ eval $line;
+ die "Error in init file: $file at line $..\n" if $@;
+ $line = "";
+ }
+ }
+ close (INIT);
+
+ die "Missing \";\" at end of init file: $file.\n"
+ if ($line !~ /^\s*$/);
+}
+
+########################################################################
+# This hack gets around problems with (at least) the OS/2 port of Perl.
+# The OS/2 port (maybe the MS-DOS port?) have one _hell_ of an annoying
+# bug. The test "-M file" returns a large positive number instead of
+# a negative number for files that are newer than the start-time of the
+# script (someone probably did an unsigned computation where a signed
+# computation was required...) The result is that -M file1 > -M file2
+# if file2 existed when the script began and file1 did not. Really
+# bad.
+#
+# Caveat, on a working system:
+#
+# -M file1 > -M file2 ==> &mtime(file1) < &mtime(file2)
+#
+sub mtime {
+ local ($file) = @_;
+ local ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
+ $atime, $mtime, $ctime, $blksize, $blocks);
+
+ if (-r $file) {
+ ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
+ $atime, $mtime, $ctime, $blksize, $blocks) = stat($file);
+ } else {
+ $mtime = -1;
+ }
+
+ $mtime;
+}
+
+########################################################################
+# This helpful little routine locates a file on a path. The path can
+# be ":" or ";" delimited. If the file is found, it's fully qualified
+# name is returned, otherwise the null string is returned. If the
+# input path contains "/" or "\" then either it is returned (if the file
+# specified exists) or the empty string is returned, the path _is not_
+# searched.
+#
+sub find_on_path {
+ local($path, $file) = @_;
+ local($dir, $filename);
+
+ $filename = "";
+
+ if ($file =~ /\/|\\/) {
+ $filename = $file if -e $file;
+ } else {
+ foreach $dir (split(/;|:/,$path)) {
+ $dir =~ s/\\/\//g;
+ $filename = $dir . "/" . $file;
+ last if -e $filename;
+ $filename = "";
+ }
+ }
+ $filename;
+}
+
+########################################################################
+# Sometimes it is helpful to have a .texitrc file (especially in a
+# working directory) update the paths used by TeX. These two routines
+# are a big help...
+#
+sub del_from_path {
+ local($path,$dir) = @_;
+ local(@paths,$outpath,$curdir,$place);
+
+ @paths = split(/$PATHSEP/,$path);
+
+ $outpath = "";
+ for ($place = 0; $place <= $#paths; $place++) {
+ $curdir = @paths[$place];
+ $outpath = sprintf("%s$PATHSEP%s", $outpath, $curdir)
+ if $curdir && $curdir ne $dir;
+ }
+
+ $outpath = $1 if $outpath =~ /^$PATHSEP+([^$PATHSEP].*)$/;
+ $outpath = $1 if $outpath =~ /^(.*[^$PATHSEP])$PATHSEP+$/;
+
+ $outpath;
+}
+
+sub add_to_path {
+ local($path,$dir,$front) = @_;
+ local(@paths,$outpath,$curdir,$place);
+
+ $path = &del_from_path($path,$dir); # remove it if it's already there
+
+ if ($front) {
+ $path = $dir . $PATHSEP . $path;
+ } else {
+ $path = $path . $PATHSEP . $dir;
+ }
+
+ $path;
+}
+
+########################################################################
+# For texit running under X11, this routine changes the title to reflect
+# what's going on now...works for the iconized xterm too!
+#
+sub set_xterm_title {
+ local ($title) = @_;
+
+ print STDOUT "]2;$title" if $SETXTITLE;
+}
+
+sub set_xicon_title {
+ local ($title) = @_;
+
+ print STDOUT "]1;$title" if $SETXTITLE;
+}
+
+sub set_x_titles {
+ local ($title) = @_;
+ &set_xterm_title ($title);
+ &set_xicon_title ($title);
+}
+
+########################################################################
+# I'm sure this could be improved...but real docs should be written
+# anyway so there's no need to go overboard here. That's my excuse,
+# in any event.
+#
+sub display_usage {
+ local (@formatlist, $item);
+
+ print "#" x 72, "\n";
+ print <<'EOF';
+Usage: texit <options> texfile[.tex]
+Where <options> may be:
+ -<format> process `texfile' using the named format.
+ -once process document once and exit. Returns 0
+ if the document seems ok after processing.
+ -clean suppress prompt message when cleaning up files.
+ -menu skip the initial run of TeX and go straight to the menu.
+ -verbose display additional status messages.
+ -initfile init load the file "init" during initialization.
+ -tex force an initial run of TeX, even if it doesn't
+ seem necessary.
+ -bibtex start by running BibTeX (instead of TeX).
+ -makeindex start by running MakeIndex.
+
+TeXit tries to figure out the format of your document, so you don't
+have to specify it. Of course, you have to specify it if TeXit guesses
+wrong. Better yet, stick in an Emacs-style local var section to define
+the format or a "% Format: format" line at the top of your document.
+
+You only have to specify enough of the option string to make it
+unambiguous (e.g. "-v" is good enough for -verbose).
+
+EOF
+
+ foreach $item (keys %format) {
+ unshift(@formatlist, $item) if !defined($casefoo{$item});
+ }
+
+ &print_long_list("TeXit recognizes the following format names: ",
+ sort(@formatlist));
+ print "#" x 72, "\n";
+ exit 2;
+}
+
diff --git a/support/tex-it/texit.tex b/support/tex-it/texit.tex
new file mode 100644
index 0000000000..0c13b51cd0
--- /dev/null
+++ b/support/tex-it/texit.tex
@@ -0,0 +1,672 @@
+\documentstyle{article}
+%
+% If you don't have Anthony Bloesch's ``treetex.sty'' file, just remove
+% that style option. The ``right thing'' will happen when you process
+% the document.
+
+%% #!/usr/local/bin/perl
+%% dependency on format file names...
+
+\partopsep=0pt
+\topsep=0pt
+\parindent=0pt
+\parskip=\baselineskip
+
+\def\desctree{%
+Consider a \LaTeX\footnote{There's nothing special about \LaTeX\ in this
+example, it's just convienient to select the \LaTeX\ format because it has
+support for bibliographies and indices built in. Similar arguments can be
+made about other formats with different arrangements of supporting files.}
+document composed of a main file, \verb|main.tex|, and two included files,
+\verb|chap1.tex| and \verb|chap2.tex|. Assume that the document has a
+bibliography and an index (\verb|main.bbl| and \verb|main.ind|). The
+bibliography is constructed from \verb|myrefs.bib| by Bib\TeX and the index is
+constructed by MakeIndex from the \verb|main.idx| file produced by \TeX{}ing
+the document.
+}
+
+\def\maketree{%
+Consider a \LaTeX\footnote{There's nothing special about \LaTeX\ in this
+example, it's just convienient to select the \LaTeX\ format because it has
+support for bibliographies and indices built in. Similar arguments can be
+made about other formats with different arrangements of supporting files.}
+document composed of several files as shown in the diagram below. Assume that
+the bibliography (\verb|main.bbl|) is constructed from \verb|myrefs.bib| by
+Bib\TeX and the index is constructed by MakeIndex from the \verb|main.idx|
+file produced by \TeX{}ing the document.
+
+\begin{center}
+ \def\treefbox##1{\fbox{{\tt ##1}}}
+ \begin{tree}{texittr}
+ \rootnode{\treefbox{main.tex}}
+ \treenode{nodeA}{root}{\treefbox{chap1.tex}}
+ \treenode{nodeB}{root}{\treefbox{chap2.tex}}
+ \treenode{nodeC}{root}{\treefbox{main.bbl}}
+ \treenode{nodeD}{root}{\treefbox{main.ind}}
+ \treenode{nodeE}{nodeC}{\treefbox{myrefs.bib}}
+ \treenode{nodeF}{nodeE}{\treefbox{plain.bst}}
+ \treenode{nodeG}{nodeD}{\treefbox{main.idx}}
+ \end{tree}
+\end{center}
+}
+
+% if you include the ``treetex'' style, you can have a nice drawing
+% in your document.
+\makeatletter
+\@ifundefined{tree}{\let\drawdoc\desctree}{\let\drawdoc\maketree}
+% something else while I've got the @ right...
+\def\@listI{\leftmargin\leftmargini \parsep 4\p@ plus2\p@ minus\p@
+\topsep 0\p@ plus0\p@ minus0\p@
+\itemsep 4\p@ plus2\p@ minus\p@}
+\makeatother
+
+\title{TeXit \\ An intelligent script for running \TeX %
+ \\ \ \\ {\small Version 1.29}}
+\author{Norman Walsh \\ {\tt walsh@cs.umass.edu}}
+\date{August 16, 1993}
+
+\begin{document}
+
+\maketitle
+
+\section{What is TeXit?}
+
+TeXit is a Perl script designed to automate the task of processing documents
+with \TeX. It runs \TeX\ with the correct format and tries to intelligently
+determine when \TeX\ needs to be run a second, or even third, time in order
+to get correctly typeset output.
+
+`Out of the box', TeXit is configured to recognize \LaTeX, Plain \TeX, and
+Texinfo files, but it can easily be extended to other formats. One of the
+nice features of TeXit is that you can provide document-specific ``rules'' to
+determine how many times \TeX\ needs to be run.
+
+By the way, I tried to make a ``minimal'' TeXit and decided it wasn't worth
+it. The difference in startup speed was too small to justify the expense
+of maintaining two versions. Honest.
+
+This document describes TeXit, but you should also look at the
+``\verb|texit.pl|'' file. I tried to put informative comments next to all of
+the variables that you might want to change. If you do want to change them,
+{\em do it in an initialization file} (see Section~\ref{sec:init}). {\bf Don't
+change the script!}
+
+\section{Legal Mumbo-Jumbo}
+
+TeXit is distributed under the terms of the GNU General Public License,
+version 2 or later.
+
+Use at your own risk. I take no responsibility for {\it any\/} problems
+you have, whether or not they are caused by TeXit. On the other hand,
+if you do have problems, I'll be as helpful as I can ;-)
+
+\section{What Does It Do?}
+
+\drawdoc
+
+Such a document forms a tree-like graph\footnote{It's tree-like because you
+can't have a cycle in the ``main branches'' (i.e. the included files) but it's
+also a graph because there can be cross references between any two nodes.}.
+
+In the worst case, getting this document to print correctly requires
+{\em eight\/} steps!
+
+\begin{enumerate}
+ \item Run \LaTeX\ (this generates \verb|main.idx| and \verb|main.aux|).
+ \item Run \LaTeX\ again to satisfy any cross references.
+ \item Run Bib\TeX\ (this generates \verb|main.bbl|).
+ \item Run MakeIndex (this generates \verb|main.ind|).
+ \item Run \LaTeX\ (this builds the ``final document''). Except that
+ the bibliography citations have changed a page break so the references
+ are wrong.
+ \item Run \LaTeX\ again to satisfy any cross references.
+ \item Run MakeIndex since the index may be wrong.
+ \item Run \LaTeX\ to build the final document.
+\end{enumerate}
+
+As if that weren't enough to warrant the aid of a script to do the dirty
+work, you might also like to setup \TeX\ as a compiler from within your
+editor, but you want to run \LaTeX\ on ``\verb|main.tex|'' even if you
+happen to be editing ``\verb|chap02.tex|''.
+
+TeXit can handle all of these problems.
+
+\subsection{Finding the Right File}
+
+When TeXit processes a file, the first thing it looks for is some indication
+that the file it was given is part of some larger document. If it discovers
+that this is the case, it abandons the current file in favor of the ``master''
+file.
+
+There are two ways that you can indicate that a file is part of a larger
+document:
+
+\begin{itemize}
+ \item Place ``\verb|% master: main.tex|'' on a line by itself near the
+ top of your document. This identifies ``\verb|main.tex|'' as
+ the master file.
+ \item Include ``\verb|% TeX-master: main.tex|'' in an Emacs ``Local
+ Variables'' section at the bottom of your file. If you don't
+ use Emacs, don't worry about this.
+\end{itemize}
+
+\subsection{Finding the Right Format}
+
+Next, TeXit needs to determine what format to use. You can force TeXit
+to select a particular mode with the ``\verb|-|{\em format\/}'' command-line
+switch, or by inserting a command in your document:
+
+\begin{itemize}
+ \item Place ``\verb|% mode: latex|'' or ``\verb|% format: latex|'' on a
+ line by itself near the top of your document. This identifies
+ ``\verb|latex|'' as the format to use. TeXit figures out the
+ actual format file name, you just tell it in English. Running TeXit
+ without any arguments will give you a list of formats.
+ \item Include \verb|% mode: latex| in an Emacs ``Local
+ Variables'' section at the bottom of your file. If you don't
+ use Emacs, don't worry about this.
+\end{itemize}
+
+If you don't specify a format, TeXit assumes that the document is Plain \TeX\
+unless it finds one of the following:
+
+\begin{itemize}
+\item ``\verb|\documentstyle[|{\em any options\/}\verb|]{slides}|''
+ indicates Sli\TeX.
+
+\item ``\verb|\documentstyle[|{\em any options\/}\verb|]{foils}|''
+ indicates Foil\TeX.
+
+\item ``\verb|\documentsytle|''
+ indicates \LaTeX.
+
+\item ``\verb|\document |{\em something\/}''
+ indicates AMS\TeX.
+
+\item ``\verb|\Define|{\em xxx\/}\verb|:|{\em yyy\/}''
+ indicates Lollipop.
+
+\item ``\verb|@node|'' or ``\verb|@ifinfo|'' or ``\verb|input texinfo|''
+ indicates Texinfo.
+\end{itemize}
+
+TeXit only searches the first \verb|$TEXHEADERSIZE| lines for these commands.
+With the exception of ``\verb|input texinfo|'', they must occur at the
+very beginning of a line to be recognized.
+
+After processing your document, TeXit looks at the log file and re-runs \TeX\
+if the references have changed or the citations have changed. TeXit provides
+support for \LaTeX\ and Texinfo logs at the moment. Other formats will be
+added upon request.
+
+\section{More Power!\protect\footnote{grunt, Grunt, GRUNT! ;-) This is a
+poor joke. It'll only make sense if you're familiar with the television
+sit-com {\em Home Improvement}.}}
+
+You can extend TeXit by adding ``rules'' to your documents. Rules tell
+TeXit how the various pieces of your document are related. It is similar
+to ``make'' in many regards, but it is a little better than make for \TeX\
+documents since it can examine the contents as well as the time-stamp
+of a file.
+
+Rules are added by placing a ``rules'' section in your main document file.
+For example, this document has the following rules:
+
+% hackery here so that the first line isn't noticed by TeXit...
+\verb| % Start TeXit |\verb|rules:|
+\vskip-\baselineskip\vskip-\parskip
+\begin{verbatim}
+ % &cleanup_files ('texittr.tli','texittr.tlo');
+ %
+ % # it doesn't really have this rule, I just wanted to make the
+ % # example more interesting
+ % &bibtex('texit') if &newer('myrefs.bib')
+ % || &missing('texit.bbl');
+ %
+ % &run(treetex texittr'),
+ % &waitfor('texittr.tli') if &changed('texittr.tlo')
+ % || &missing('texittr.tli');
+ %
+ % &dependson('texittr.tli');
+ % End TeXit rules:
+\end{verbatim}
+
+The ``\verb|Start TeXit rules:|'' and ``\verb|End TeXit rules:|'' lines are
+markers. They are required. Leading ``\%'' signs and whitespace are ignored.
+Note: if you are using a \TeX\ format that uses some other comment character,
+you'll have to protect the rules in some other way. You can't simply use any
+comment character that you want.
+
+The catch is that your rules have to be valid Perl statements. I've
+tried to make most of the common things easy to add by hiding them in
+functions. If you use the syntax shown, everything will be ok.
+
+TeXit rules can extend over over multiple lines, but some care must be taken.
+When TeXit is parsing the rules, it assumes that any line that {\em ends\/}
+with a semi-colon ends the rule. Trailing Perl comments (unescaped ``\#''
+marks) are trimmed off. This allows you to build up a compound statement like
+this:
+
+\begin{verbatim}
+ % if ($some_conditional) {
+ % do_this ; # use perl comment to hide the semicolon
+ % and_this ; # (make sure you hide each one)
+ % } ;
+\end{verbatim}
+
+Rules can ``do anything'' since they're written in Perl. Use care: don't
+change any of TeXit's variables! The rules for a document are evaluated
+{\em every\/} time the document is processed. If you want some rules to
+be evaluated only once, you can test against ``\verb|$first_time|''. This
+variable will only be true once, right before the document is processed
+for the first time.
+
+The following variables are defined before the rules are executed:
+
+\begin{itemize}
+ \item \verb|$TEXFILEPATH|
+
+ The pathname of the master file (it always ends in a slash and
+ is equal to ``./'' if the file has no other path).
+
+ \item \verb|$TEXFILENAME|
+
+ The base name of the master file (no path, no extension).
+
+ \item \verb|$TEXFILEEXT|
+
+ The extension of the master file.
+
+ \item \verb|$TEXFORMAT|
+
+ The english name of the format that TeXit decided to use.
+\end{itemize}
+
+\section{A Short Lesson in Rules}
+
+If you aren't a Perl aficionado, the following guidelines will help you write
+right rules. But be warned, not every statement in this section is the whole
+truth.
+
+Most rules have the form:
+
+\begin{center}
+ \verb|&|{\it command}\verb|(|{\it arguments}\verb|) if |%
+ {\it predicates}\verb|;|
+\end{center}
+
+The following commands are available:
+
+\begin{itemize}
+ \item \verb|&bibtex('|{\it arguments}\verb|')|
+
+ Runs the BibTeX program with the arguments specified.
+
+ \item \verb|&tex('|{\it arguments}\verb|')|
+
+ Runs the \TeX\ program with the arguments specified.
+
+ \item \verb|&makeindex('|{\it arguments}\verb|')|
+
+ Runs the MakeIndex program with the arguments specified.
+
+ \item \verb|&run('|{\it command arguments}\verb|')|
+
+ The most general form, this command runs whatever you pass
+ it, just as if you typed it at the shell prompt.
+
+ \item \verb|&waitfor('|{\it file1}\verb|', '|%
+ {\it file2}\verb|',|\ldots\verb|)|
+
+ Waits until all the files specified exist. Use care, this can
+ cause TeXit to ``hang'' forever. I added this condition so that
+ I could run commands asynchronously on another machine and make
+ TeXit pause until they were done.
+
+ \item \verb|&auxfile("ext")|
+
+ Returns the name of the auxilliary file with the extension
+ ``ext''. This allows you to test for files, like the DVI file:
+
+ For example, the test ``\verb|-r &auxfile("dvi")|'' returns true
+ if the DVI file is readable.
+
+ \item \verb|&cleanup_files('|{\it file1}\verb|', '|%
+ {\it file2}\verb|',| \ldots\verb|)|
+
+ This command adds ``{\it file1\/}'', ``{\it file2}'', etc., to the
+ list of files that should be deleted by the cleanup choice.
+
+\end{itemize}
+
+The following predicates are available:
+
+\begin{itemize}
+ \item \verb|$first_time|
+
+ TeXit runs all of your rules once before running \TeX\ for the
+ first time. During that one run, the \verb|&first_run| predicate
+ will be true. All of the other predicates return false during
+ the first run.
+
+ \item \verb|&dependson('|{\it file1}\verb|', '|%
+ {\it file2}\verb|',| \ldots\verb|)|
+
+ Tells TeXit that the DVI file for your document depends on
+ all of the files listed. If any of these files are newer than
+ the DVI file, \TeX\ will be run again.
+
+ TeXit evaluates your rules in the order they are written. Make
+ sure that all of your \verb|&dependson| rules occur last.
+
+ \item \verb|&missing('|{\it file1}\verb|', '|%
+ {\it file2}\verb|',| \ldots\verb|)|
+
+ Returns true if any of the files specified are missing (i.e.
+ unreadable by your effective userid).
+
+ \item \verb|&changed('|{\it file1}\verb|', '|%
+ {\it file2}\verb|',| \ldots\verb|)|
+
+ Returns true if any of the files specified have changed since the
+ last time \TeX\ was run. TeXit saves a checksum of each file across
+ runs of \TeX\ and compares the checksums.
+
+ \item \verb|&newer('|{\it nfile1, nfile2, \ldots}\verb|', '|%
+ {\it ofile1, ofile2, \ldots}\verb|')|
+
+ Returns true if any of the ``{\it nfiles}'' are newer than any
+ of the ``{\it ofiles}'' or if any of the ``{\it ofiles}'' don't
+ exist.
+
+ Note the different calling sequence for this predicate. You must
+ pass only two elements to this function: {\em put the list of files
+ in quotes!} This is different than all the other predicates, I know.
+ Sorry about that.
+\end{itemize}
+
+\section{Built in Commands}
+
+When TeXit finishes processing your document, it presents the ``Again?''
+prompt. You should respond to the ``Again?'' prompt with the letter(s) in
+square brackets for the command that you want to issue. For example, to run
+the ``\verb|[p]rint|'' command, reply ``p''. You can insert a space and
+additional options. For example ``p -Pdept1'' runs the print command with the
+additional options ``-Pdept1''. How (or if) that argument is interpreted
+depends on the command.
+
+By default, TeXit is configured to supply the following commands:
+
+\begin{itemize}
+ \item \verb|[b]ibtex|, \verb|[g]hostview|, \verb|[t]ex|, \verb|[v]iew|
+
+ Runs BibTeX, Ghostview, \TeX, or your previewer, respectively.
+
+ \item \verb|[p]rint|
+
+ Runs a printer. You {\em must\/} specify the name of the printer
+ queue as an option. Use ``p ?'' to get a list of queues. Additional
+ options, after the queue name, are passed to either the DVI driver
+ or the print command: options before a ``\verb+|+'' go to the DVI
+ driver, options after go the print command.
+
+ For example, the following command ``\verb+p dept1 -p1 -l1|-K2+''
+ prints your job to the ``dept1'' printer queue. The DVI driver
+ sees the options ``-p1 -l1'' and the printer command sees the
+ options ``-K2''.
+
+ \item \verb|[c]leanup|
+
+ Deletes auxilliary files (log, aux, etc.). This can be configured
+ in document rules and/or \verb|.texitrc| files.
+
+ \item \verb|e[x]it|
+
+ Exits TeXit.
+\end{itemize}
+
+Section~\ref{sec:examples} illustrates how you can add your own commands.
+
+\section{Other Initialization}
+\label{sec:init}
+
+The first thing TeXit does after parsing your command line arguments and
+finding out what document you want to process is load initialization files.
+These files typically set variables like \verb|$TEXRETRIES| and
+\verb|$TEXHEADERSIZE|. If they exist, the following scripts are loaded (in
+this order):
+
+\begin{itemize}
+ \item Some global configuration file
+
+ Support for this option requires editing the script. I don't expect it
+ to be done very often.
+
+ \item \verb|~/.texitrc|
+
+ The script file found in your home directory. TeXit finds your home
+ directory by looking for the ``\verb|TEXIT|'' environment
+ variable and the ``\verb|HOME|'' environment variable. It uses whichever
+ it finds first.
+
+ You really should set one or the other. If neither is set, your
+ home directory effectively becomes the current directory. Probably
+ not what you had in mind.
+
+ \item \verb|$TEXFILEPATH/.texitrc|
+
+ The script file in the same directory as your \TeX\ master document
+ file.
+
+ \item \verb|-initfile |{\it ifile}
+
+ Finally, any init files that you specify as options are loaded. If you
+ specify more than one, they are loaded in the order specified.
+\end{itemize}
+
+\section{Some Examples}
+\label{sec:examples}
+
+This section demonstrates some customizations performed in ``\verb|.texitrc|''
+files. These examples should help you figure out how to do some of the
+customizations you're likely to want. You can alway send me email if you
+want help with a particular customization.
+
+\subsection{Adding a new command}
+
+Let's add the \verb|dvitty| program as a new command. First, define
+the program name and the command. These could be combined, but it's
+better not to for reasons that will become clear in a moment.
+
+\begin{verbatim}
+ $DVITTY = "/usr/local/bin/dvi2tty";
+ $DVITTYCMD = "$DVITTY %o %d";
+\end{verbatim}
+
+Table~\ref{tab:percentsubst} shows all of the \%-substitutions that
+you can include in the command.
+
+\begin{table}
+ \begin{center}
+ \begin{tabular}{|l|l|}
+ \hline
+ \verb|%F| & The format file name \\
+ \verb|%s| & The base name of the \TeX\ master file \\
+ \verb|%t| & The \TeX\ master file with its extension \\
+ \verb|%d| & The DVI file\\
+ \verb|%o| & Any options added to the command by the user\\
+ \verb|%D| & The DVI file with ``/'' translated to ``$\backslash$''. \\
+ \verb|%S| & The base name with ``/'' translated to ``$\backslash$''. \\
+ \verb|%T| & The master file with its extension and with ``/'' translated to ``$\backslash$''. \\
+ \hline
+ \end{tabular}
+ \caption{Percent substitutions performed by TeXit.}
+ \label{tab:percentsubst}
+ \end{center}
+\end{table}
+
+The next thing that you need to do is tell TeXit to present this as an option
+to the user. In order to do this, you must define two more commands:
+\verb|$CMDPROMPT{|{\it cmd-name}\verb|}| and \verb|$CMDTEST{|{\it
+cmd-name}\verb|}|. The ``{\it cmd-name}'' is the prompt-string that
+will be displayed to the user. Some portion of that string must be in square
+brackets. That portion is what the user must enter to run the choice. The
+\verb|$CMDPROMPT| is the Perl string that is evaluated if the user
+selects that command and the \verb|$CMDTEST| string is evaluated before the
+prompt is displayed to see if that command is allowed now. Both of these
+strings should be defined in {\em single quotes\/} so that Perl doesn't
+do any interpolation when it's defining the command. The \verb|$CMDPROMPT|
+string should end with either ``\verb|$RETEX|'' or ``\verb|$REASK|'' depending
+on whether you want to re-run \TeX\ or redisplay the prompt.
+
+Here's how \verb|dvitty| is defined:
+
+\begin{verbatim}
+ $CMDPROMPT{"dvi2[tty]"} = '&run($DVITTYCMD, "$opts"); $REASK;';
+ $CMDTEST{"dvi2[tty]"}
+ = '"$DVITTY" && -x "$DVITTY" && -r &auxfile("dvi")';
+\end{verbatim}
+
+These commands indicate that:
+
+\begin{itemize}
+ \item TeXit should add ``\verb|dvi2[tty]|'' to the prompt.
+ \item The user must respond ``\verb|tty|'' to select this option.
+ \item The option is only available if \verb|$DVITTY| is defined and
+ executable and the DVI file exists.
+ \item If selected, TeXit should run the \verb|$DVITTYCMD| with any
+ options the user specified (always stored in ``\verb|$opts|'')
+ and then redisplay the prompt.
+\end{itemize}
+
+Another example: adding a printer queue command. This one's done
+a bit sloppily, but it works.
+
+\begin{verbatim}
+ $CMDPROMPT{"[q]uery printer"}
+ = '&run("lpq -P%o", "$opts"); $REASK;';
+ $CMDTEST{"[q]uery printer"} = '';
+\end{verbatim}
+
+\subsection{Adding a New Printer}
+
+Assuming that the program ``\verb|dvi2bam|'' translates DVI files into output
+for the Bambleweenie 2000 printer (translating ``file.dvi'' to ``file.bbw''),
+the following commands add the ``\verb|neato|'' printer to TeXit.
+
+\begin{verbatim}
+ $DVIBAM = "/usr/local/bin/dvi2bam";
+ $DVIBAMCMD = "$DVIBAM %o %d";
+
+ $PRQUEUE{"neato"} = "bamble";
+ $PRINTCMD{"neato"} = "lpr %o %s.bbw";
+ $PRINTOPT{"neato"} = "-Pneato";
+
+ $DVICMD{"bamble"} = $DVIBAMCMD;
+ $DVIOPT{"bamble"} = "";
+\end{verbatim}
+
+Adding a new printer, ``\verb|myprinter|'', of the same type is a simple
+matter:
+
+\begin{verbatim}
+ $PRQUEUE{"myprinter"} = "bamble";
+ $PRINTCMD{"myprinter"} = "lpr %o %s.bbw";
+ $PRINTOPT{"myprinter"} = "-Pmyprinter";
+\end{verbatim}
+
+\subsection{Removing a Command}
+
+To remove a command, undefine one of the things that its ``\verb|$CMDTEST|''
+string tests. For example, to remove Ghostview:
+
+\begin{verbatim}
+ undef($GSVIEW);
+\end{verbatim}
+
+This is why you should always put a simple command-defined type test in
+your ``\verb|$CMDTEST|'' strings.
+
+To completely remove a command, delete its entries in the \verb|$CMDTEST|
+{\em and\/} \verb|$CMDPROMPT| arrays. If you only delete its entry
+in the \verb|$CMDTEST| array, the command will always be available (a
+null test is true by default). If you only delete its entry in the
+\verb|$CMDPROMPT| array, you will get a runtime error (this is intentional,
+it helps catch typos in the array definitions).
+
+\begin{verbatim}
+ delete $CMDPROMPT{"[b]ibtex"};
+ delete $CMDTEST{"[b]ibtex"};
+\end{verbatim}
+
+\subsection{Removing a Printer}
+
+To remove a printer, delete its ``\verb|$PRQUEUE|'' entry. For example,
+the following command removes the ``Local'' printer:
+
+\begin{verbatim}
+ delete $PRQUEUE{"Local"};
+\end{verbatim}
+
+\subsection{Other Examples}
+
+Look in the \verb|.texitrc| files supplied with TeXit for more ideas
+and examples.
+
+\section{Running under OS/2}
+
+The following file, ``\verb|texit.cmd|'' demonstrates how \verb|texit.pl|
+can be run under OS/2. This sort of hackery might not be necessary if you
+put \verb|texit.pl| in the Perl library path, but I don't because
+the compiled-in path is \verb|c:\perl\lib| which I'm unwilling to use.
+I could recompile Perl, I suppose, but on my 386SX box that'd probably
+take about a year and a half. Not to mention all the disk space I don't
+have. Actually, there's a bug in this port that I would like
+to fix, but I won't be able to do that for a while.
+
+The tricks are:
+
+\begin{itemize}
+ \item You have to get the whole pathname to Perl and OS/2 only
+ passes the path of the command you typed (so if it's on your PATH, it
+ only gets ``\verb|texit|''.
+
+ \item Having put the pathname on the ``extproc'' line, you have to do
+ a ``shift'' to get rid of the name that OS/2 put on the command line.
+
+ \item In order for Perl to find the file ``\verb|require|''d,
+ it must be on the \verb|@INC| path. (You see, it begins with a
+ drive letter (not a ``/'') so Perl thinks it has to look
+ for the file. The bug. Sigh.)
+\end{itemize}
+
+\begin{verbatim}
+ extproc perl -x e:/emtex/texit.cmd
+ #! perl
+ shift; # get rid of TEXIT.CMD shoved on by OS/2
+ push (@INC, "e:/emtex"); # add emtex to search path
+ push (@INC, "e:/Perl/lib"); # perl path
+ require "texit.pl"
+\end{verbatim}
+
+\section{Questions, Suggestions, or Flames?}
+
+I know this documentation is incomplete (and badly written). I'll try to
+answer any questions that you ask and entertain any suggestions that you might
+have (no matter {\em how\/} entertaining I think they are ;-).
+
+In my own defense, I {\em did\/} put lots of comments in the script. It
+shouldn't be too inscrutable.
+
+\end{document}
+
+
+% Start TeXit rules:
+% &cleanup_files ('texittr.tli','texittr.tlo');
+%
+%# &run('treetex texittr'), &waitfor('texittr.tli')
+%# if &changed('texittr.tlo') || &missing('texittr.tli');
+%
+% &dependson('texittr.tli');
+% End TeXit rules:
+
diff --git a/support/tex-it/texitrc.os2 b/support/tex-it/texitrc.os2
new file mode 100644
index 0000000000..267d254df3
--- /dev/null
+++ b/support/tex-it/texitrc.os2
@@ -0,0 +1,59 @@
+# This is my .texitrc for OS/2 using emTeX
+
+# I like to delete a lot more files...
+#
+@cleanup_latex = ('dvi', 'aux','log','blg','ilg','ind','idx','bbl');
+
+# emTeX returns error code 1 for overfull boxes and other non-fatal
+# errors, so set $TEXERROR to 2.
+#
+$TEXERROR = 2;
+
+# Prompt me to delete files when I'm done using TeXit...
+#
+$CLEANONEXIT = 1;
+
+$TEX = "tex386"; # The emTeX executables...
+$MAKEINDEX = "makeindx";
+$VIEW = "v.cmd"; # Batch file to view DVI with DVISCR
+
+$TEXCMD{"default"} = '$TEX %F %o \\input{%s}';
+$TEXCMD{"plain"} = '$TEX %F %o \\input %s';
+$TEXCMD{"texinfo"} = '$TEX %F %o \\input %s';
+$VIEWCMD = '$VIEW %D %o';
+
+$DEFAULTFORMAT = "plain"; # Run Plain TeX by default
+
+%PRQUEUE = (); # Delete all default printers
+
+$PRQUEUE{"Local"} = "pcl"; # Add Local PCL printer (LaserJet)
+$PRQUEUE{"File"} = "pcl"; # Print to file is a PCL printer too
+
+$DVICMD{"pcl"} = 'lj3.btm %D %o'; # lj3.btm is a batch file to run dvihplj
+$DVIOPT{"pcl"} = "";
+
+$PRINTCMD{"Local"} = 'copy /b %S.pcl %o lpt1';
+$PRINTOPT{"Local"} = "";
+
+$PRINTCMD{"File"} = "";
+$PRINTOPT{"File"} = "";
+
+# Delete Ghostview...
+delete $CMDPROMPT{$GhostviewReply};
+delete $CMDTEST{$GhostviewReply};
+
+# Default action when hitting Enter after TeXing is Viewing...
+$DEFAULTCMD{$TeXReply} = $ViewReply;
+
+# Add a new command which runs TeX and then automatically runs View...
+$TeXandViewReply = "[T]eX & View";
+$CMDPROMPT{$TeXandViewReply} = $CMDPROMPT{$TeXReply};
+$CMDTEST{$TeXandViewReply} = $CMDTEST{$TeXReply};
+$AUTOCMD{$TeXandViewReply} = $ViewReply;
+$AUTOOPT{$TeXandViewReply} = "";
+
+# Add a run-any-command option...
+$RunCommand = "[!] run command";
+$CMDPROMPT{$RunCommand} = '&run("$opts",""); $REASK;';
+$CMDTEST{$RunCommand} = "";
+
diff --git a/support/tex-it/texitrc.unx b/support/tex-it/texitrc.unx
new file mode 100644
index 0000000000..1296c99db8
--- /dev/null
+++ b/support/tex-it/texitrc.unx
@@ -0,0 +1,157 @@
+########################################################################;
+## PLEASE REMEMBER THAT THIS ISN'T REALLY A PERL FILE. IT'S ACTUALLY ##;
+## READ AND "EVAL"ED ON A LINE BY LINE BASIS. THE EVALUATOR ACCUM- ##;
+## ULATES LINES UNTIL IT FINDS ONE THAT ENDS IN A SEMICOLON. USE ##;
+## COMMENT CHARACTERS TO PROTECT SEMICOLONS IN COMPOUND STATEMENTS AND##;
+## SEMICOLONS AT THE END OF COMMENTS TO AVOID ACCUMULATING A BUNCH OF ##;
+## COMMENTS INTO A STATEMENT. MOST OF THE TIME, PERL SEEMS TO "DO THE##;
+## RIGHT THING", BUT IT DOESN'T HURT TO BE CAREFUL. ##;
+########################################################################;
+## SEE THE COMMENT FOR THE 'require_hack' SUBROUTINE IN texit.pl FOR ##;
+## AN EXPLANATION OF THIS UNFORTUNATE BEHAVIOR. IT REALLY ISN'T MY ##;
+## FAULT, HONEST! ##;
+########################################################################;
+# ;
+# The .texitrc file that I use on my Unix box at work ;
+# ;
+# I like to delete a lot more files... ;
+
+@cleanup_latex = ('aux','log','blg','ilg','ind','idx','bbl','ps');
+
+@latex_rules = (
+ '$changed = 1 if &changed($TEXFILEPATH . $TEXFILENAME . ".bbl");',
+ '$changed = 1 if &changed($TEXFILEPATH . $TEXFILENAME . ".toc");',
+ '$changed = 1 if &changed($TEXFILEPATH . $TEXFILENAME . ".lot");',
+ '$changed = 1 if &changed($TEXFILEPATH . $TEXFILENAME . ".lof");'
+);
+
+# Ask me about deleting those files on exit.. ;
+$CLEANONEXIT = 1;
+
+# Add some local printers...some PostScript, a PostScript @ 600dpi ;
+# and a special printer to demonstrate how TeXit can be setup to ask ;
+# for options. ;
+# ;
+$PRQUEUE{"oos"} = "ps";
+$PRQUEUE{"joshua"} = "ps";
+$PRQUEUE{"xerox1"} = "ps";
+$PRQUEUE{"woper"} = "ps600";
+$PRQUEUE{"qtest"} = "psq";
+
+$DVICMD{"psq"} = $DVICMD{"ps"};
+$DVIOPT{"psq"} = $DVIOPT{"ps"};
+$DVIQUERY{"psq"} = "Additional DVI options? ";
+
+$DVICMD{"ps600"} = "dvips %o %d";
+$DVIOPT{"ps600"} = "-Pwoper";
+
+$PRINTCMD{"oos"} = "lpr %o %s.ps";
+$PRINTOPT{"oos"} = "-Poos";
+
+$PRINTCMD{"joshua"} = "lpr %o %s.ps";
+$PRINTOPT{"joshua"} = "-Pjoshua";
+
+$PRINTCMD{"xerox1"} = "lpr %o %s.ps";
+$PRINTOPT{"xerox1"} = "-Pxerox1 -K2";
+
+$PRINTCMD{"woper"} = "lpr %o %s.ps";
+$PRINTOPT{"woper"} = "-Pwoper";
+
+$PRINTCMD{"qtest"} = $PRINTCMD{"oos"};
+$PRINTOPT{"qtest"} = $PRINTOPT{"oos"};
+$PRINTQUERY{"qtest"}= "Additional lpr options? ";
+$PRINTCONFIRM{"qtest"} = "no";
+
+# Rather than having two options, dvitty and Xdvi, let's switch between ;
+# them based on the terminal type...actually, just as an example, let's ;
+# make the test even more complicated: ;
+# ;
+# - run xdvi if TERM=xterm ;
+# - run dvgt if we're on a Sparc and not an xterm ;
+# - run dvi2tty if we're not on a Sparc or an xterm ;
+# ;
+# This code assumes that your login script sets $HOSTTYPE and $TERM... ;
+# ;
+if ($ENV{"TERM"} eq "xterm") {
+ $VIEWCMD = '$VIEW %o %d >/dev/null 2>1 &'; # run xdvi in the background...
+} elsif ($ENV{"HOSTTYPE"} eq "sparc") {
+ $VIEW = "dvigt"; # avoid end of expr
+} else {
+ $VIEW = "dvi2tty"; # avoid end of expr
+};
+
+# Let's make sure we can find the previewer and turn off the option if ;
+# we can't. Print a warning message in that case too... ;
+# ;
+if (&find_on_path ($ENV{"PATH"}, $VIEW) eq "") {
+ print "*** Can't find previewer ($VIEW) on path. "; #
+ print "Viewing disabled. ***\n"; #
+ delete $CMDTEST{$ViewReply}; #
+ delete $CMDPROMPT{$ViewReply}; #
+};
+
+# Uncomment this code if you _always_ want a choice for dvi2tty instead ;
+# of using the switch above. For example, if you want dvi2tty as a choice ;
+# even if you are running on an Xterm. ;
+# ;
+#$DVITTY = "/exp/rcf/share/tex/bin/dvi2tty";
+#$DVITTYCMD = "$DVITTY %o %d";
+#$DvittyReply = "dvi2[tty]";
+#$CMDPROMPT{$DvittyReply} = '&run("$DVITTYCMD", "$opts"); $REASK;';
+#$CMDTEST{$DvittyReply} = '"$DVITTY" && -x "$DVITTY" && -r &auxfile("dvi")';
+
+# Setting up dvips as a command...;
+#$DVIPS = "/usr/local/bin/dvips";
+#$DVIPSCMD = "$DVIPS -o %s.ps %d";
+#$DvipsReply = "dvi[ps]";
+#$CMDPROMPT{$DvipsReply} = '&run("$DVIPSCMD", "$opts"); $REASK;';
+#$CMDTEST{$DvipsReply} = '"$DVIPS" && -x "$DVIPS" && -r &auxfile("dvi")';
+
+# Adding a query printer option...;
+#
+$LpqReply = "[q]uery printer";
+$CMDPROMPT{$LpqReply} = '&run("lpq -P%o", $opts); $REASK;';
+$CMDTEST{$LpqReply} = '';
+
+# Delete Ghostview... ;
+# ;
+delete $CMDPROMPT{$GhostviewReply};
+delete $CMDTEST{$GhostviewReply};
+
+# Default action when hitting Enter after TeXing is Viewing... ;
+# ;
+$DEFAULTCMD{$TeXReply} = $ViewReply;
+
+# Add a new command which runs TeX and then automatically runs View... ;
+# ;
+$TeXandViewReply = "[T]eX & View";
+$CMDPROMPT{$TeXandViewReply} = $CMDPROMPT{$TeXReply};
+$CMDTEST{$TeXandViewReply} = $CMDTEST{$TeXReply};
+$AUTOCMD{$TeXandViewReply} = $ViewReply;
+$AUTOOPT{$TeXandViewReply} = "";
+
+# let ! run any command, but don't bother to show the prompt...The fact ;
+# that there are two !'s in this example is coincidence, they are ;
+# unrelated. ;
+# ;
+$RunCommand = "![!] run command";
+$CMDPROMPT{$RunCommand} = '&run("$opts",""); $REASK;';
+$CMDTEST{$RunCommand} = '';
+
+# Add an edit command. This is kind of funky because we want to edit ;
+# the master TeX file if no option is given, but edit the file specified;
+# if a file is given... ;
+# We get the editor from the "EDITOR" environment variable or use emacs.;
+# This option is hidden because I never use it (the joys of an Xterm, ;
+# I guess ;-). It's included just because it's an interesting example. ;
+# ;
+$EditCommand = "![e]dit a file";
+$EDITOR = $ENV{"EDITOR"};
+$EDITOR = "emacs" if $EDITOR eq "";
+$CMDPROMPT{$EditCommand} =
+ 'if ("\$opts" eq "") {
+ &run("\$EDITOR %o &",
+ \$TEXFILEPATH . \$TEXFILENAME . "." . \$TEXFILEEXT); #
+ } else {
+ &run("\$EDITOR %o &", "\$opts"); } ';
+$CMDTEST{$EditCommand} = "";