The newclude LaTeX package

A new system for including files (Frankenstein’s backbone)

          Matt Swift <swift@alum.mit.edu>

Version: 2 Date: 1999/11/02

Documentation revision: 1999/11/02

Abstract

Newclude is a backwards-compatible reimplementation of the L^{A}TEX system for including files. The princpal new features are: (1) the restriction that \clearpages must surround an included file is removed, (2) the restriction that \includes cannot be nested is removed, and (3) the provision of hooks executed before and after the contents of an included file. Newclude accomplishes the first two by using a single aux file instead of many.

Still in development, but already useful in many situations, are new commands that include partial contents of independent L^{A}TEX files, which can also be processed on their own (that is, files that contain \documentclass, \begin{document}, etc.). Newclude absorbs and supersedes the former package includex.

Contents

I Discussion 3

1 Introduction 3 2 Usage 3 3 Experimental features 5 4 Options 6

4.1 Simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 4.2 Tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 4.3 Allocate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

5 Programmers’ interface 8 6 How to play nicely with newclude 8

II Implementation 10

7 Version control 10 8 Review of the kernel’s inclusion system 10 9 Discussion of newclude’s inclusion system 11 10 Package initialization 11 11 Simple 12 12 Common 13 13 Experimental common 14 14 Tag 17

14.1 Writing to \@auxout . . . . . . . . . . . . . . . . . . . . . . . . . . 17 14.2 Kernel redefinitions . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 14.3 Checkpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 14.4 Including . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

15 Allocate 23 15.0.1 Wheels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 15.0.2 Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . . . 24 15.0.3 Static allocation . . . . . . . . . . . . . . . . . . . . . . . . 25 15.0.4 Dynamic allocation . . . . . . . . . . . . . . . . . . . . . . . 26 15.0.5 Including . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 15.0.6 Checkpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 15.0.7 Wheels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 16 Benign packages 29

3

Part I

Discussion

1 Introduction

Let us call a file that might be included into another document with a command in the \include family a part. When a part is actually included during a particular processing run, let us call it an included part, and when it is not included, let us call it an unincluded part. Notice that an unincluded part is not the same as a file that was never a candidate for inclusion with a command in the \include family.

The newclude package adds these features to the standard LaTeX inclusion system:

  1. Hooks \AtBeginInclude and \AtEndInclude are provided.

2. Optional arguments to \include and friends override current values of

     \AtBeginInclude and \AtEndInclude.

3. \include* is like \include but with arbitrary commands rather than \clearpages surrounding the part.

4. \include and friends can be nested.

  5. \includeall cancels the effect of \includeonly.

6. \IfAllowed ⟨filename⟩ is a new conditional that branches, depending on what has been declared in an \includeonly.

7. Commands \includedoc etc. include a part that can be processed independently. These features are in development.

Newclude accepts three mutually-exclusive package options, with tag the default when no package option is given.

Loading newclude with the simple option provides only features 1 and 2. If you don’t use either of these new features, the standard L^{A}TEX and newclude inclusion systems will behave identically except in some unusual and benign odd cases relating the the parsing of the new optional arguments to \include, which are discussed below in that command’s documentation.

The options tag and allocate each implement all the above features with a different method. Each method introduces different discrepancies from standard L^{A}TEX which are discussed below in sections 4.2 and 4.3. If I discover how to make one method never inferior to the other, I will remove the other option from the package.

2 Usage

\include \include [⟨prehook⟩]{⟨filename⟩}[⟨posthook⟩] behaves like standard L^{A}TEX’s

\AtBeginInclude
\AtEndInclude

\include except that it can be nested and the contents of the two hook arguments, when they are given, are inserted at the beginning and end of the part whenever it is included, overriding the current values of \AtBeginInclude and

\AtEndInclude.

Warning: Right square braces (]s) in the optional arguments must be surrounded by curly braces to avoid confusing the argument parser.

Warning: A left square brace ([) that immediately follows an \include command’s mandatory ⟨filename⟩ argument (after optional whitespace) will be considered to delimit the beginning of the ⟨posthook⟩ argument. If you want an actual left brace character in this position, you must precede it with something that will terminate TEX’s search for an optional argument, such as \relax, , or a paragraph division (explicit or implicit).

The commands \AtBeginInclude ⟨tokens⟩ and \AtEndInclude ⟨tokens⟩ are analagous to standard L^{A}TEX’s commands \AtBeginDocument ⟨tokens⟩ and \AtEndDocument ⟨tokens⟩.

FIX: multiple instances concatenate?

FIX give name to what’s held by atbegininclude so that an override can mention it

When the optional argument ⟨prehook⟩ is given to \include, its contents will be used instead of whatever has been specified with \AtBeginInclude, for that one inclusion. Likewise, ⟨posthook⟩ will be used in place of whatever has been specified with \AtEndInclude for that one inclusion.

For example, putting the \chapter declaration in the ⟨prehook⟩ argument allows the chapter name, and, optionally, a corresponding L^{A}TEX label, to be kept in the including file, rather than the included file:

 \include [\chapter{Whales}
           \label{ch:whales}]
          {big-cetecea}

The ⟨posthook⟩ argument can be used, for example, to delimit or undo declarations made in the ⟨prehook⟩ or the included file: FIX: better example, since these coudl simple appear before/after the \include without ill effect.

 \include [\begingroup\larger] % this part in larger type
          {manifesto}
          [\endgroup]

\include* \include*[⟨prehook⟩]{⟨filename⟩}[⟨posthook⟩] is like \include but omits

\IncludeSurround
\DefaultIncludeSurround

the usual \clearpages that surround an included part, replacing them with

\IncludeSurround, which defaults to \DefaultIncludeSurround. The contents

of \IncludeSurround are inserted before the ⟨prehook⟩ or whatever has been specified with \AtBeginInclude, and after the ⟨posthook⟩ or whatever has been

specified with \AtEndInclude.

Warning: A space gets inserted after an \include* unless it is suppressed by a immediately following. Combined with trailing spaces in the included file, this may lead to unwanted spaces. For this reason, \DefaultIncludeSurround is initialized to \par. When the user must explicitly change \IncludeSurround to achieve totally smooth flow from main file to included file, they are more likely to consult this documentation if they spot a problem. Package and class writers should take this difficulty into account when changing \DefaultIncludeSurround.

\includeonly The \includeonly command is reimplemented, but its usage and behavior is

the same as the standard L^{A}TEX version.

\includeall The \includeall command cancels the effect of any \includeonly command presently in effect.

If you write an \includeonly so that each file appears on its own line, it is particularly easy to add and remove files to include by commenting out their lines, but it becomes laborious to comment out the entire \includeonly command. It’s easy, however, to uncomment a single \includeall command when you want to process the entire document. (Or \includeall could be inserted from the command line that invokes L^{A}TEX, and so on.)

3 Experimental features

\includeenv \includeenv[⟨prehook⟩]{⟨filename⟩}{⟨environment name⟩}{⟨instance⟩}[⟨posthook⟩]

\includeenv *[⟨prehook⟩]{⟨filename⟩}{⟨environment name⟩}{⟨instance⟩}[⟨posthook⟩]

\includeenv includes the contents of a single L^{A}TEX environment that appears in ⟨filename⟩. The environment is specified by giving its name (⟨environment⟩) and an instance of that environment in the file (⟨instance⟩). Presently, ⟨instance⟩ is ignored, so that it will always be the contents of the first occurrence in ⟨filename⟩ of a L^{A}TEX environment with the name ⟨environment⟩ that will be included. In the future, the ⟨instance⟩ argument may be used to specify the nth instance of the environment within the file, or further specify the environment to be extracted in some other way.

FIX: right now they’re required; skip text up to documentclass OR the target, then branch?

   Good preamble syntactic sugar: \let\TheMarkupDeclarations\begin

To do: You can insert a \usepackage into the main aux file and have it loaded properly. If we discover a \usepackage that is not a formatting package, one strategy is to insert a corresponding \usepackage into the (main) aux file and then bail after the preamble.

To do: You can’t skip verbatim text via macro argument processing and sugar. this means that a major reimplementation of skipping using verbatim methods will have to be done.

The included file is permitted (but not required) to have its own \documentclass

command and \begin{document} . . . \end{document} pair. \includeenv ex-

tracts the specified environment by processing the preamble if one exists, skipping text up until the beginning of the specified environment, processing the contents of the environment, and skipping the rest of the included part.

   Notice that while a \begin{document} . . . \end{document} pair may not

technically delimit a L^{A}TEX environment, you may nevertheless (because it looks exactly like an environment) set ⟨environment⟩ to document to extract the contents of the document “environment” of ⟨filename⟩.

Consider the following issues when you are tempted to use this command. Maybe the \usepackage you are about to disregard is necessary to processing the part’s contents. Maybe it conflicts with a package already loaded at top level. Maybe both! The same holds of course for the defining commands like \newcommand that one expects to find in a package.

A deep problem with the design of a L^{A}TEX source file exists with respect to the function of the preamble. The preamble contains declarations that determine how the document below will be formatted. Unfortunately, there is no way to make the distinction between:

1. declarations that signal that certain markup will appear in the document that are either not defined in the L^{A}TEX kernel or are used with a different syntax

2. declarations that describe how a certain instance of the document should be formatted

Examples in the first category are \usepackage{url} and FIX%example, and examples in the second are \usepackage{times} and FIX. When you want to include the document or a part of it in another document, it is absolutely necessary to make this distinction so that declarations in category (1) can be processed and declarations in category (2) can be ignored.

Adopting a convention on the use of the preamble can overcome this design problem, but it will not fix the problem for legacy files whose preambles do not obey the convention. Legacy files that contain category (1) declarations in their preambles must either be altered or specifically accommodated with additional commands.

   The convention I suggest is to \usepackage{preamble}. \beginmarkup

\endmarkup. FIX. Can we arrange to load

When \includeenv encounters a \usepackage command in the included part, it looks at the packages in the argument of \usepackage and issues a warning if the package is not already loaded and does not appear on a list of packages known whose use falls entirely within category (2). (See the

\DeclareFormattingPackage command below.)

The \documentclass command is of course also a category (1) declaration. Presently, if \includeenv detects that the arguments to an included \documentclass command differ from the arguments of the \documentclass command of the including document, it will issue a warning, and continue. In the future, I hope to make this behavior smarter by having \includeenv take specific actions for specific combinations of arguments. For example, if the included document’s class implies the use of markup not defined in the parent’s class, an appropriate action would be to define the missing markup commands. A document of class report and a document of class article, on the other hand, do not (I don’t think) declare different markup, so that there should be no warning in this case.

\includeenv* \includeenv* is analogous to \include*, that is, it surrounds the included

part with \IncludeSurround rather than \clearpage.

\includedoc \includedoc[⟨prehook⟩]{⟨file name⟩}[⟨posthook⟩] is shorthand for \includeenv \includedoc* [⟨prehook⟩]{⟨filename⟩}{⟨document ⟩}{⟨⟩}[⟨posthook⟩].

   \includedoc* is analogous to \includeenv*.

4 Options

4.1 Simple

If the simple option is given, the only new feature provided is the hooks (features 1 and 2 above). As with standard L^{A}TEX, \clearpages surround an \include and nesting \includes gives an error. Newclude will only behave differently than standard L^{A}TEX command scans for possible optional arguments will make a different.

4.2 Tag

The tag option causes L^{A}TEX to use just one aux file. This option, which is the default, works well. I am aware of the following two differences from the kernel’s including system:

1. If the L^{A}TEX process is stopped during the processing of a part, all information normally stored in an aux file from that point in the document forward is lost. In the kernel’s system, processing the document twice more would recover any aux information previously generated for parts.

If L^{A}TEX is always invoked in \nonstopmode (e.g., by AUC-TEX), then this difference is only going to occur when there are catastrophic errors that cause even \nonstopmode to terminate processing.

2. Other packages and classes that redefine kernel commands that write to \@auxout will cause problems.

The first difference must be accepted. The second difference can be removed on a case by case basis, by specifically coding compatibility with such packages and classes. I intend to do this. Here is a list of such packages and classes known to me:

⟨none so far⟩ If you discover any more for this list, please write me!

It’s also very easy to revise the other package to be compatible with newclude as it is now. See section 6 below, which includes a list of relevant kernel commands.

4.3 Allocate

The second way (the allocate option) represents my first attempt at a solution, and until I am sure it has no advantages over tag under any circumstances, it will continue to be an option.

The allocate option causes L^{A}TEX to dynamically allocate TEX output streams to each part as they are needed. Streams are allocated when processing of the part begins, and are reclaimed after the ejection of the last page to which the part has contributed. Like the old system, a separate aux file is created for each part. The limitation of this implementation is that TEX only possesses 16 output streams.

Each of the commands \tableofcontents, \listoffigures, \listoftables,

\makeglossary, and \makeindex causes L^{A}TEX to use one output stream. The remainder (minus any streams required by packages and classes) are available for the including system. If n streams are available, the level of nesting possible is n − 1 minus the maximum number of parts that occur on the same page. For example, if 10 streams are available and the parts never appear on the same page (the old behavior required by the \clearpages), then 8 levels of nesting are possible (which is 8, not 7 more than with the old system). The maximum number of parts that may contribute the to same page is calculated with the same equation. Note: TEX’s page-breaking algorithm looks ahead until it has more than enough material to fill one page. You must count all the new aux files that are opened during a look-ahead as contributing to the page in question, even if some of the later ones do not actually contribute to the page after the break is chosen.

The allocate solution is itself implemented in two ways. The system either reserves a fixed number of output streams from the start, or will dynamically claim and free them as needed. The dynamic solution is the default. I do not see much use for the static solution at present. If the dynamic system claims streams that are later required, then it is simply a question of whether newclude or the other feature is going to signal an error about having no more streams to allocate.

5 Programmers’ interface

\IfAllowed \IfAllowed {⟨part name⟩}{⟨true⟩}{⟨false⟩} executes ⟨true⟩ if ⟨part-name⟩ is on the list of files to be included and ⟨false⟩ otherwise. If there is no list, executes ⟨true⟩.

\IncludeName \IncludeName expands to the name of the part currently being processed. In

the toplevel source file, it will expand to \jobname.

\ParentName \ParentName expands to the name of the part that includes the part currently being processed. In the toplevel source file, expanding \ParentName will generate a warning and expand to \jobname (which is also what \IncludeName expands to).

FIX: root source file? toplevel? master? principle source? glossary!

\DeclareFormattingPackage      \DeclareFormattingPackage {⟨package name⟩} declares ⟨package name⟩ to

be a package that only makes formatting declarations, that is, the effect of using it falls entirely within category (2). If a formatting package occurs in a \usepackage declaration in the preamble of a part included by \includeenv, no warning will be given. An example of a formatting package is the times package. No facility is provided to distinguish the case when a package is used with or without certain package options, so do not declare a package as a formatting package unless it is so regardless of the options it is passed.

If you send me the names of formatting packages, I will include them in the next release of newclude. Meanwhile, you may declare them in newclude.cfg. Do the same for your local formatting packages if you wish. It does no harm to declare a package as a formatting package more than once.

\ifSkipPreamble
\SkipPreambletrue
\SkipPreamblefalse

\Disable {⟨tokens⟩} provides a way to ignore additional commands when

\Disable
\DisableAll

using \includeenv and friends. If you want to cause the macro \foo which takes no arguments to be entirely ignored in parts, issue the command \Disable{\let\ foo\relax} any time before including the parts you want to affect. If \foo takes one mandatory argument, write \let\foo\Gobble instead. If \foo takes one optional and one mandatory, write \let\foo\GobbleOM. And so on. For other examples, see the gobbling commands in the moredefs package (which newclude requires), or write your own.

The arguments to \Disable are accumulated and executed by the command \DisableAll, which is executed inside a group that contains a part when it is included.

There is no way to undo the effect of issuing a \Disable command.

6 How to play nicely with newclude

To adapt a package or class for use with the tag option of newclude:

  1. replace \immediate\write\@auxout with \@writeaux
  2. replace \protected@write\@auxout with \protected@writeaux

3. add

\providecommand\@writeaux {%
  \immediate\write\@auxout
}
\providecommand\protected@writeaux {%
  \protected@write\@auxout
}

Part II

Implementation

7 Version control

\fileinfo \DoXUsepackagE \HaveECitationS \fileversion \filedate \docdate \PPOptArg These definitions must be the first ones in the file.
 1 \def\fileinfo{A new system for including files (Frankenstein's backbone)}
 2 \def\DoXPackageS {}
 3 \def\fileversion{v2}
 4 \def\filedate{1999/11/02}
 5 \def\docdate{1999/11/02}
 6 \edef\PPOptArg {%
 7 \filedate\space \fileversion\space \fileinfo
 8 }

If we’re loading this file from a \ProcessDTXFile command (see the compsci package), then \JusTLoaDInformatioN will be defined; othewise we assume it is not (that’s why the FunkY NamE).

If we’re loading from \ProcessDTXFile, we want to load the packages listed in \DoXPackageS (needed to typeset the documentation for this file) and then bail out. Otherwise, we’re using this file in a normal way as a package, so do nothing. \DoXPackageS, if there are any, are declared in the dtx file, and, if you’re reading the typeset documentation of this package, would appear just above. (It’s OK to call \usepackage with an empty argument or \relax, by the way.)

 9 \makeatletter% A special comment to help create bst files.  Don't change!
10 \@ifundefined{JusTLoaDInformatioN} {%
11 }{% ELSE (we know the compsci package is already loaded, too)
12 \UndefineCS\JusTLoaDInformatioN
13 \SaveDoXVarS
14 \eExpand\csname DoXPackageS\endcsname\In {%use \csname in case it's undefined
15  \usepackage{#1}%
16 }%
17 \RestoreDoXVarS
18 \makeatother
19 \endinput
20 }% A special comment to help create bst files.  Don't change!

Now we check for L^{A}TEX2e and declare the LaTeX package.

21 \NeedsTeXFormat{LaTeX2e}
22 \ProvidesPackage{newclude}[\PPOptArg]

8 Review of the kernel’s inclusion system

One aux file is written to disk for the principle source and one for each of the included parts. The reason to have a separate ones for the parts is so that information from the last time the part was included is retained in subsequent runs even when the part is excluded by \includeonly. Suppose a part is processed once, and on a subsequent run its name is removed from the \includeonly list. This run will still read in the part’s aux file, since the aux file of any part that was \included during the last run is always read. But the information therein is not going to be regenerated in this run, since the part will not be processed. The main aux file is created anew with each run, so this information would be lost if it resided there.

To handle writing these multiple aux files, the kernel uses two of TEX’s output streams. When a routine writes to an auxiliary file, it writes to \@auxout, which is \let to either \@mainaux, the aux file for the principle source, or \@partaux the aux file for all the parts each in turn.

When encountering an \include command, but before deciding whether or not to actually load the part, the kernel writes a command to \@mainaux that will load the part’s aux file. The main aux file is loaded by \document, so that all aux files are read in every time the principle source is processed.

If a part is actually loaded, a checkpoint is written to the part’s aux file consisting of a snapshot of the counters (a record of the values of all L^{A}TEX counters). On the next run, if the part is not actually loaded, the information in its aux file has nevertheless already been processed by \document. Processing the checkpoint causes a macro to be defined that when invoked restores the counter state. When \include does not actually load a part it calls this checkpoint macro instead to alter the present counter state.

This system has pitfalls as well as benefits. It is useful to keep the bibliography, citations, cross references, and page numbers up to date in certain situations, but the results can be confusing sometimes, because checkpoints are not documented. (Perhaps this is remedied in the 2d edition of the L^{A}TEX manual.) How, besides reading the code, or finding out the hard way, is anyone supposed to guess that rearranging two “deactivated” \include statements in a principle source will bring havoc on the page numbers?

9 Discussion of newclude’s inclusion system

The simple removal of the \clearpages that surround an included part would cause a problem involving the delayed action of \write commands. Suppose a part ending with a \write command ends halfway down a page, and another \write occurs in the principle source immediately (or soon) after the inclusion. The first must be written to \@partaux and the second to \@mainaux. If we close \@partaux while the first \write is still pending, that is, before the current page has been shipped out, then the \write will be destined for a closed stream and therefore go to the log file and terminal. The \clearpages solve this by flushing all pending \writes. Then we can close \@partaux immediately and

reopen \@mainaux.

Successful removal of the \clearpages can be accomplished either by having the entire document use just one auxiliary file, or by allocating additional output streams so that it becomes possible to avoid closing \@partaux until after the current page is shipped out when all the \write’s to it have been completed.

10 Package initialization

23 \RequirePackage{moredefs}
24 \InitCS\sc@t@a
25 \DeclareOption{simple} {%

26 \input{simple.sto}
27 \let\sc@t@a\endinput

28 }

29 %^^A\DeclareOption{group} {%
30 %^^A  \AtEndOfPackage {\input{group.sto}}
31 %^^A}
32 \DeclareOption{tag} {%
33 \AtEndOfPackage {\input{tag.sto}}

34 }

35 \DeclareOption{allocate} {%
36 \AtEndOfPackage {\input{allocate.sto}}

37 }

38 \DeclareBooleanOptions{dynamic}{static}
39 \ExecuteOptions{tag}
40 \ProcessOptions

If the simple option has been given, end right here.

41 \sc@t@a

11 Simple

The above option processing causes the file simple.sto to be loaded when the simple is given. After it is loaded, processing stops. When the simple option is not given, newclude package code continues in section 12.

The simple option adds the optional argument to \include, and does nothing else.

\include I’m not really sure why the \relax is there; I’m imitating the kernel’s command.

42 \defcommand\include {%
43 \relax
44 \ifnum\@auxout=\@partaux
45  \@latex@error{\string\include\space cannot be nested}\@eha
46 \else
47  \expandafter\@include
48 \fi

49 }

\@include
50 \defcommand\@include [2][] {%
51 \clearpage
52 \if@filesw
53  \immediate\write\@mainaux{\string\@input{#2.aux}}%
54 \fi
55 \@tempswatrue
56 \if@partsw
57  \@tempswafalse
58  \edef\reserved@b{#2}%
59  \@for\reserved@a:=\@partlist\do
60  {\ifx\reserved@a\reserved@b\@tempswatrue\fi}%
61 \fi
62 \if@tempswa
63  \let\@auxout\@partaux
64  \if@filesw
65  \immediate\openout\@partaux #2.aux

66  \immediate\write\@partaux{\relax}%
67  \fi

All we did was change #1 to #2 and add the next line.

68  #1%
69  \@input@{#2.tex}%
70  \clearpage
71  \@writeckpt{#2}%
72  \if@filesw
73  \immediate\closeout\@partaux
74  \fi
75 \else
76  \@nameuse{cp@#2}%
77 \fi
78 \let\@auxout\@mainaux

79 }

12 Common

The code in this section is common to the tag and allocate options.

\nc@t@a \nc@t@b \nc@t@c \nc@toks@a Scratch variables.
80 \ReserveCS\nc@t@a
81 \ReserveCS\nc@t@b
82 \ReserveCS\nc@t@c
83 \newtokens\nc@toks@a
\IncludeSurround
\DefaultIncludeSurround
84 \newcommand\DefaultIncludeSurround {%
85 \par

86 }

87 \newlet\IncludeSurround\DefaultIncludeSurround

\c@IncludeDepth With nested \includes, we need some way for the various ones to distinguish themselves, so we keep track of the nested depth with the IncludeDepth counter.

88 \newcounter{IncludeDepth} % starts at 0

\IfAllowed \includeonly \includeall I think it’s more efficient to define a macro for each included part on the list than it is to search through the list possibly twice for each one. Other opinions on making this whole thing more efficient?

We are using the usual L^{A}TEX trick of undefined control sequences comparing equally with \relax. Empty control sequences are not the same. Should be followed by ⟨true clause⟩ then ⟨false clause⟩.

89 \newcommand\IfAllowed [1] {%
90 \@firstoftwo

91 }

92 \newcommand\includeall {%
93 \let\includeonly\Gobble

94 }

95 \defcommand\includeonly [1] {%
96 \@partswtrue
97 %  \DTypeout{INCLUDEONLY}%

 98 \edef\@partlist {\zap@space#1 \@empty}%
 99 \@for\nc@t@a:=\@partlist \do {%
100  \InitName*{nc@part@\nc@t@a}%

101 }%

102 \defcommand\IfAllowed [1] {% args: part-name
103  \@ifundefined{nc@part@##1} {%
104 %        \DTypeout{##1 NOTALLOWED}%
105  \let\nc@t@c\@secondoftwo
106  }{% ELSE
107 %      \DTypeout{##1 ALLOWED}%
108  \let\nc@t@c\@firstoftwo

109 }%

110  \nc@t@c

111 }%

112 %  \DTypeout{ENDINCLUDEONLY}%

113 }

\include \include* This is the principle user command. The scratch variable \nc@t@b contains what really surrounds the included file.

114 \def\include {%
115 \@ifstar {%
116  \let\nc@t@b\IncludeSurround
117  \nc@include
118  }{% ELSE
119  \let\nc@t@b\clearpage
120  \nc@include

121 }% 122 }

13 Experimental common

\Disable \DisableAll This allows the disabling hacks.

123 \ReserveCS\DisableAll
124 \newcommand\Disable [1] {%
125 \g@addto@macro\DisableAll{#1}%

126 }

We start with considering how to quit inputting a file. The idea is to make the \end{document} command of the part call \endinput. But there is a hitch that characters on the line after the \end{document} get inserted when you don’t want them to. To beat that limitation, we have to do some work.

\nc@radical@shutdown We will add a bunch of commands to this macro, with the idea of \catcodeing everything and its brother to a comment. This would be a brute force method!

127 \ReserveCS\nc@radical@shutdown

First log a message that we’re about to do some crazy things. In case something goes wrong, this might help.

128 \addto@macro\nc@radical@shutdown {%
129 \MonsterInfo{newclude}
130  {\protect\nc@radical@shutdown\space beginning}}

Now we start adding \catcode commands. These first two should be redundant; but just in case someone changed things. …

131 \addto@macro\nc@radical@shutdown{\catcode`\%=14}    % 14 = comment
132 \addto@macro\nc@radical@shutdown{\catcode`\^=7}     % 7 = superscript

\nc@disable@char Next, we define a command we weill use in a loop in a moment.

133 \newcommand\nc@disable@char[1] {%
134 \addto@macro\nc@radical@shutdown
135  {\catcode`#1=14}}  % 14 = comment

The following list contains every keyboard char except these three, which are treated specially: %#. The first is already a comment, and we handle the second in a moment. Each character in the following list is \catcoded to a comment:

136 \@tfor\sc@t@a:=abcdefghijklmnopqrstuvwxyz%
137  ABCDEFGHIJKLMNOPQRSTUVWXYZ%
138  ~!@$&*()_+-=[]|/?.,<>%
139  1234567890%
140  `'";:%
141  \^\\\{\}\ % this is really the chars "^\{}" and space
142  \do {\expandafter\nc@disable@char\sc@t@a}

We add # separately, because it’s tricky or impossible to put it into the list we just used.

143 \nc@disable@char\#

We end the macro with \endinput. This has to come after all the previous, otherwise, TEX goes ahead and reads to the end of the line immediately, with regular catcodes. This is a good theory, I’m not sure it’s necessary.

144 \addto@macro\nc@radical@shutdown{\endinput}
\nc@radical@shutdown@aftergroup We need to use \nc@radical@shutdown this way.
145 \newcommand\nc@radical@shutdown@aftergroup {%
146 \aftergroup\nc@radical@shutdown

147 }

\includedoc
\includedoc*
148 \newcommand\includedoc {%
149 \md@check@star
150 \Expand \sc@star@nothing\In {%
151  \IncludeEnv##1{document}{}%

152 }% 153 }

\includedocskip
\includedocskip*
154 \newcommand\includedocskip {%
155 \md@check@star
156 \Expand \sc@star@nothing\In {%
157  \IncludeEnvSkip##1{document}{}%

158 }% 159 }

\IncludeEnv
\nc@includeenv
\nc@@includeenv

160 \newcommand\IncludeEnv [2] {% args: environment instance

161 \md@check@star
162 \@ifnextchar [ {%           ^^A for Emacs: ]
163  \nc@includeenv{#1}{#2}%
164  }{% ELSE
165  \nc@includeenv{#1}{#2}[]%

166 }% 167 }

168 \NewName{nc@includeenv} {#1#2[#3]} {% args: environment instance [prehook]
169 \@ifnextchar [ {%      ^^A for Emacs: ]
170  \nc@@includeenv {#1}{#2}{#3}%
171  }{% ELSE
172  \nc@@includeenv {#1}{#2}{#3}[]%

173 }% 174 }

175 \NewName{nc@@includeenv} {#1#2#3[#4]} {% args: environment instance prehook [posthook]
176 \begingroup
177  \DisableAll
178  \let\documentclass\GobbleOM
179  \let\usepackage\GobbleOM
180  \expandafter\def\csname end#1\endcsname {%
181  \makeatletter
182  % POSTHOOK
183  \nc@radical@shutdown@aftergroup

184 }%

185  \expandafter\def\csname #1\endcsname {} % PREHOOK
186 \endgroup
187 \par
188 \Expand \sc@star@nothing\In {%
189  \include##1{#2}%

190 }% 191 }

192 \NewName {nc@@includeenvskip} {#1#2#3[#4]} {% args: environment instance prehook [posthook]
193 \begingroup
194  \DisableAll
195  \expandafter\def\csname end#1\endcsname {%
196  \makeatletter
197  % POSTHOOK
198  \nc@radical@shutdown@aftergroup

199 }%

200  \expandafter\def\csname #1\endcsname {} % PREHOOK
201  \long\def\documentclass ##1\begin{document}{%
202  \begingroup
203  \def\@currenvir{document}%

204 }

205 \endgroup
206 \par
207 #1%

208 }

14 Tag

The code in this section is processed when the tag package option is given (or, because the tag option is the default, when no package options are given.)

14.1 Writing to \@auxout

To do: Might I need to do \let\protect\@unexpandable@protect instead of
\noexpand, in the def of \\protected@writeaux?
\nc@writeaux@main \nc@protected@writeaux@main The main versions are exactly the same as what they replaced.
209 \newcommand\nc@writeaux@main {%
210 \immediate\write\@auxout

211 }

212 \newcommand\nc@protected@writeaux@main {%
213 \protected@write\@auxout

214 }

\nc@writeaux@aux \nc@protected@writeaux@aux When you remove the \immediate, you have to expand whatever’s in the argument

at the time you invoke \write. \IncludeName and \@percentchar, and other

exandables in #2 will get expanded now. The \@percentchar and the ^^Js are there because lines written to \@auxout must be on lines by themselves to satisfy BibTEX. The ^^Js write newlines, and the \@percentchar eliminates a newline when the aux file is read in again later. Accommodating BibTEX requires special consideration several times below as well.

215 \newcommand\nc@writeaux@aux [1] {% args: write-text
216 \eExecute {%
217  \write\@auxout{\string\@auxtag{\IncludeName}{\@percentchar^^J#1^^J}}%

218 }% 219 }

220 \newcommand\nc@protected@writeaux@aux [2] {% args: init-hook write-text
221 \protected@write\@auxout{#1}{\string\@auxtag{\IncludeName}{\@percentchar^^J#2^^J}}%

222 }

\@writeaux \@protected@writeaux We start with the main versions. We don’t reserve the control sequences \@writeaux and \protected@writeaux because the hack to adapt other packages might have already defined it with \providecommand.

223 \let\@writeaux\nc@writeaux@main
224 \let\protected@writeaux\nc@protected@writeaux@main

14.2 Kernel redefinitions

\@bibitem \@lbibitem \label \@citex \bibliography \nocite \addtocontents These are simple redefinitions of kernel functions. The changes are the substitutions for the writing commands described above.

225 \defcommand*\@bibitem [1] {%
226 \item
227 \if@filesw
228  \@writeaux{\string\bibcite{#1}{\the\value{\@listctr}}}%
229 \fi
230 \ignorespaces

231 }

232 \DefName*{@lbibitem} {[#1]#2} {%

233 \item[\@biblabel{#1}\hfill]%
234 \if@filesw
235  \begingroup
236  \let\protect\noexpand
237  \@writeaux{\string\bibcite{#2}{#1}}%
238  \endgroup
239 \fi
240 \ignorespaces

241 }

242 \defcommand*\label [1] {%
243 \@bsphack
244 \protected@writeaux{}{\string\newlabel{#1}{{\@currentlabel}{\thepage}}}%
245 \@esphack

246 }

247 \defcommand\addtocontents [2] {%
248 \protected@writeaux

249 {

250  \let\label\Gobble
251  \let\index\Gobble
252  \let\glossary\Gobble

253 }

254  {\string\@writefile{#1}{#2}}%

255 }

256 \DefName*{@citex} {[#1]#2} {%
257 \let\@citea\@empty
258 \@cite {%
259  \@for\@citeb:=#2\do {%
260  \@citea
261  \def\@citea{,\penalty\@m\ }%
262  \edef\@citeb{\expandafter\@firstofone\@citeb}%
263  \if@filesw
264  \@writeaux{\string\citation{\@citeb}}%
265  \fi
266  \@ifundefined{b@\@citeb} {%
267 \mbox{\reset@font\bfseries ?}%
268 \G@refundefinedtrue
269 \@latex@warning
270  {Citation `\@citeb' on page \thepage \space undefined}%
271 }{% ELSE
272  \hbox{\csname b@\@citeb\endcsname}%

273 }% 274 }%

275 }{#1}% second arg to \@cite

276 }

277 \defcommand*\bibliography [1] {%
278 \if@filesw
279  \@writeaux{\string\bibdata{#1}}%
280 \fi
281 \@input@{\jobname.bbl}%

282 }

283 \defcommand*\bibliographystyle [1] {%
284 \ifx\@begindocumenthook\@undefined\else
285  \expandafter\AtBeginDocument
286 \fi

287 {\if@filesw
288  \@writeaux{\string\bibstyle{#1}}%
289 \fi}%

290 }

291 \defcommand*\nocite [1] {%
292 \@bsphack
293 \@for\@citeb:=#1\do {%
294  \edef\@citeb{\expandafter\@firstofone\@citeb}%
295  \if@filesw
296  \@writeaux{\string\citation{\@citeb}}%
297  \fi
298  \@ifundefined{b@\@citeb} {%
299 \G@refundefinedtrue
300  \@latex@warning{Citation `\@citeb' undefined}%
301  }{}%

302 }%

303 \@esphack

304 }

14.3 Checkpoints

\@writeckpt \@wckptelt The \@charlb, \@charrb, and \@percentchar stuff is to satisfy BibTEX (see

above).

305 \defcommand*\@writeckpt [1] {%
306 \if@filesw
307  \write\@auxout{\string\@setckpt{#1}\@charlb\@percentchar}%
308  {\let\@elt\@wckptelt
309  \cl@@ckpt}%
310  \write\@auxout{\@charrb}%
311 \fi

312 }

313 \defcommand\@wckptelt [1] {%
314 \write\@auxout{\string\setcounter{#1}{\the\@nameuse{c@#1}}}%

315 }

14.4 Including

\IncludeName
\ParentName
\nc@includename@<N>

316 \newcommand\IncludeName {%
317 \@nameuse{nc@includename@\theIncludeDepth}%

318 }

319 \newcommand\ParentName {%
320 \ifnum\value{IncludeDepth}= 0
321  \jobname
322  \FrankenWarning{newclude}{Requested name of parent of principle source}%
323 \else

The incrementation of the IncludeDepth counter is local to the group.

324  \begingroup
325  \advance\c@IncludeDepth by \m@one
326  \@nameuse{nc@includename@\theIncludeDepth}%
327  \endgroup
328 \fi

330 \NewName {nc@includename@0} {} {\jobname}
\nc@include \nc@@include To do: dox
331 \newcommand\nc@include [2][] {% args: hook filename
332 \@ifnextchar [ {%]
333  \nc@@include{#1}{#2}%
334  }{% ELSE
335  \nc@@include{#1}{#2}[]%

336 }% 337 }

338 \NewName{nc@@include}{#1#2[#3]} {% args: prehook filename posthook
339 \IfAllowed{#2} {%
340  \nc@t@b           % surround the \include with something
341  \stepcounter{IncludeDepth}%
342  \DefName*{nc@includename@\theIncludeDepth} {} {#2}%
343  \let\@writeaux\nc@writeaux@aux
344  \let\protected@writeaux\nc@protected@writeaux@aux

Now execute the text of the optional argument to \include.

345  #1%
346  \@input@{#2.tex}%
347  #3%
348  \@writeckpt{#2}%
349  \let\@writeaux\nc@writeaux@main
350  \let\protected@writeaux\nc@protected@writeaux@main

We mustn’t restore the counter before we have finished using it.

351  \addtocounter{IncludeDepth}{\m@ne}%
352  \nc@t@b           % surround the \include with something
353  }{% ELSE

If the file is not allowed, we don’t load it and do two things instead. We execute the part’s checkpoint, then we write out the part’s auxcommands and checkpoint again. We must handle the case when the auxcommands isn’t defined; but the checkpoint will always be defined.

354  \@ifundefined{cp@#2} {%
355 %        \DTypeout{No information on part [#2]!}%
356  }{% ELSE
357  \@nameuse{cp@#2}%
358  \if@filesw%
359  \nc@write@auxcommands{#2}%
360  \nc@write@ckpt{#2}%
361  \fi%                                                  if@filesw
362  }%                                                      if@undefined
363 }%                                                        IfAllowed

364 }%

\nc@write@auxcommands \nc@write@ckpt To do: dox

\meaning produces catcode 12’s for all chars except spaces which are 10. Begin making definitions with \catcode`\^^M=12 (other).

365 \begingroup
366 \catcode`\^^M=12 %% double percents mean they're there only because of the catcode

367 %%

368 \Global\DefName*{nc@write@auxcommands} {#1} {% args: partname
369 \@ifundefined{nc@auxcommands@#1} {%
370  }{% ELSE
371  \write\@auxout{\string\@auxtag{#1}\@charlb\@percentchar}%
372  \EExpand*\csname nc@auxcommands@#1\endcsname\In {%
373  \edef\nc@t@a {%
374  \expandafter\strip@prefix\meaning ##1%

375 }% 376 }%

377  \edef\nc@t@a {\expandafter\nc@strip@M\nc@t@a\@nil}%
378 %    \DTypeout{The auxcommands: \meaning\nc@t@a}%
379  \begingroup %%
380  \catcode`\^^M=12 % other
381  \nc@for\nc@t@b:=\nc@t@a\do {%
382 %  \DTypeout{auxcommand ITEM: \meaning\nc@t@b}%
383 \EExpand\nc@t@b\In {%
384 \write\@auxout{##1}%

385 }% 386 }%

387  \endgroup %%
388  \write\@auxout{\@charrb}%

389 }%

390 }%%
391 \Global\DefName*{nc@write@ckpt} {#1} {% args: partname
392 \write\@auxout{\string\@setckpt{#1}\@charlb\@percentchar}%
393 \EExpand*\csname cp@#1\endcsname\In {%
394  \edef\nc@t@a {%
395  \expandafter\strip@prefix\meaning ##1%

396 }% 397 }%

398 \edef\nc@t@a {\expandafter\nc@strip@M\nc@t@a\@nil}%
399 \begingroup %%
400  \catcode`\^^M=12 % other
401  \nc@for\nc@t@b:=\nc@t@a\do {%
402 %      \DTypeout{checkpoint ITEM: \meaning\nc@t@b}%
403  \EExpand\nc@t@b\In {%
404 \write\@auxout{##1}%

405 }% 406 }%

407 \endgroup %%
408 \write\@auxout{\@charrb}%
409 }%%

\nc@for \nc@forloop \nc@iforloop \nc@for is like the kernel’s \@for but divides its list at ^^M_{12} instead of ,.

410 \Global\NewName{nc@for} {#1:=#2\do#3} {% FIX (what?)
411 \expandafter   \def %%
412  \expandafter \@fortmp %%
413  \expandafter {#2}%
414 \ifx\@fortmp\@empty \else %%
415  \expandafter\nc@forloop#2^^M\@nil^^M\@nil\@@#1{#3}%
416 \fi %%
417 }%%
418 \Global\NewName{nc@forloop} {#1^^M#2^^M#3\@@#4#5} {%
419 \def#4{#1}%

420 \ifx #4\@nnil \else %%
421  #5%
422  \def#4{#2}%
423  \ifx #4\@nnil \else %%
424  #5%
425  \nc@iforloop #3\@@#4{#5}%
426  \fi %%
427 \fi %%
428 }%%
429 \Global\NewName{nc@iforloop} {#1^^M#2\@@#3#4} {%
430 \def#3{#1}%
431 \ifx #3\@nnil %%
432  \expandafter\@fornoop %%
433 \else %%
434  #4%
435  \relax %%
436  \expandafter\nc@iforloop %%
437 \fi %%
438 #2\@@#3{#4}%
439 }%%

\nc@strip@M This strips a final ^^M_{12} from its argument. To do: I think this could be built in to \nc@for.

440 \Global\NewName{nc@strip@M} {#1^^M\@nil} {#1}%%

Finish making definitions with \catcode`\^^M=12.

441 \endgroup

\@auxtag \@@auxtag We both execute and save. To do: efficiency? check only once, then redefine auxtag? To do: dox . I could use \EExpand\In for clarity, but I go for efficiency on this crucial macro. Begin making definitions with \catcode`\^^M=12 (other).

442 \begingroup
443 \catcode`\^^M\active %% double percents mean they're there only because of the catcode

444 %%

445 \Global\NewName*{@auxtag} {#1} {% args: partname
446 \begingroup %%
447  \catcode`\^^M\active %%
448  \@@auxtag{#1}%
449 }%%
450 \Global\NewName*{@@auxtag} {#1#2} {% args: partname auxcommands
451  \@ifundefined {nc@auxcommands@#1} {%
452 \nc@toks@a={#2}%
453  }{% ELSE
454  \expandafter   \nc@toks@a %%
455 \expandafter \expandafter %%
456 \expandafter {\csname nc@auxcommands@#1\endcsname#2}%

457 }%

458  \expandafter\xdef\csname nc@auxcommands@#1\endcsname{\the\nc@toks@a}%
459  #2%
460 \endgroup %%
461 }%%

\@setckpt \@@setckpt To do: dox
462 \Global\DefName*{@setckpt} {#1} {% args: partname
463 \begingroup %%
464  \catcode`\^^M\active %%
465  \@@setckpt{#1}%
466 }%%

Finish making definitions with \catcode`\^^M=12.

467 \endgroup

The \endgroup terminates the change in catcode.

468 \newcommand*\@@setckpt [2] {% args: partname checkpoint
469  \expandafter\gdef\csname cp@#1\endcsname{#2}%
470 \endgroup

471 }

What this does is effectively remove all the tags. The end of document hook is processed before the closing processing of the aux files, during which checking for things like undefined references is done. At this point we do not need the tags.

472 \AtEndDocument {%
473 \let\@auxtag\@secondoftwo

474 }

15 Allocate

The code in this section is processed when the allocate package option is given.

Warning: This code has not been well tested yet. The output routine of L^{A}TEX is very complicated, and unforseen problems might arise.

\NextAux The macro \NextAux changes \@auxout to a new stream if one is available, and

\DynamicAux
\StaticAux

gives an error otherwise. The macro is implemented in dynamic and static ways which can be selected with \DynamicAux and \StaticAux{⟨number of streams⟩}. The number of streams can be from 2 to 16. The dynamic implementation is the default; I do not see much use for the static implementation at present. The static option is the equivalent of the declaration \StaticAux{10}. The dynamic selects the dynamic implementation.

\StaticAux can be invoked after \DynamicAux, but not the other way around (at least, the streams allocated by \StaticAux are not recovered). Macros which use \NextAux do not have to know whether the implementation is static or dynamic.

15.0.1 Wheels

The output streams are manipulated with the help of a data structure I call a wheel.

A wheel has 0 or more spokes and can be rolled. Each spoke is a TEX token, probably a control sequence name, and has an internal name. You can access the spoke at the 12 o’clock or “top” position of a wheel. In computerese, a wheel is a circularly linked list of tokens, and the operation of rolling moves a pointer along it in a certain direction by one element.

Wheels and operations on wheels are local.

\InitWheel You make a wheel either with \InitWheel {⟨\csname⟩}, which makes

\DefWheel

⟨\csname⟩ a wheel with no spokes, or \DefWheel {⟨\csname⟩}{⟨spokes⟩}, which makes a wheel with ⟨spokes⟩ for spokes. The first spoke in ⟨spokes⟩ is the top, the second will be top after one roll, and the first will be top again after n rolls, if there are n spokes.

\Roll Wheels are rolled by \Roll {⟨wheel⟩}. Spokes can be added to a wheel with

\Top
\AddSpokes

\AddSpokes{⟨wheel⟩}{⟨spokes⟩}. When n spokes are added, the previous top will be at the top after n rolls. \Top {⟨wheel⟩} expands eventually to the top spoke, which then can further expand, and so on.

\IfTop \IfTop{⟨wheel⟩}{⟨spoke⟩}{⟨true clause⟩}{⟨false clause⟩} compares the top of ⟨wheel⟩ with ⟨spoke⟩ using \ifx, and executes either ⟨true clause⟩ or ⟨false clause⟩ as appropriate. (The newclude package doesn’t actually use this command; it’s provided to “round out” the wheel data structure.)

Warning: Don’t put more than one token as the second argument to \IfTop.

15.0.2 Preliminaries

We require the afterpage package. The intuitive justification is that \writes are delayed until the current page is shipped out. We need to keep an output stream open until its last \write has been actually handled; after that, the stream can be made available again.

475 \RequirePackage{afterpage}

\nc@aux@wheel We use the wheel structure to handle both the static case and the dynamic case. The spokes of the wheel are macros \nc@auxout@⟨n⟩. Their first-level expansion is ⟨n⟩, a positive integer from 0 to 15. Each spoke has two corresponding macros. \nc@auxout@⟨n⟩@stream is a stream name allocated by \newwrite. \nc@auxout@⟨n⟩@inuse is a global boolean which is true iff the corresponding stream is currently in use.

476 \InitWheel\nc@aux@wheel

\nc@count We need an internal counter. Notice that the stream numbers used in the auxwheel start at 0, so the stream associated with with the numeral 4 is the fifth stream.

477 \newcounter{nc@count}

\nc@aux@wheel@size \nc@aux@wheel@size is a pseudo-counter that holds the present size of the aux wheel. In the static case it never changes and is set only for consistency.

478 \ReserveCS\nc@aux@wheel@size
\NextAux
479 \ReserveCS\NextAux

The kernel allocates two streams for the include system, \@mainaux and \@partaux. The auxwheel is initialized with these two streams. The first, corresponding to the principle source, is always marked in use.

To do: Reserve the stream names.

480 \newboolean{@nc@auxout@1@inuse@}

481

482 \ReserveName{nc@auxout@1}
483 \NewName*{nc@auxout@1} {} {1}

484

485 \ReserveName{nc@auxout@1@stream}
486 \expandafter\let\csname nc@auxout@1@stream\endcsname\@partaux

\nc@init@aux@wheel We initialize the wheel with the first spoke.

487 \newcommand\nc@init@aux@wheel {%
488 \EExpand\csname nc@auxout@1\endcsname\In {%
489  \AddSpokes\nc@aux@wheel##1%

490 } 491 }

15.0.3 Static allocation

\StaticAux nonpositive numbers are treated the same as 1.

To do: bounds check; the counter’s max should be one less than the number, since we have stream 0.

492 \newcommand\StaticAux [1] {%
493 \def\nc@aux@wheel@size {#1}
494 \setcounter{nc@count}{2}
495 \nc@init@aux@wheel
496 \@whilenum \value{nc@count} <= \nc@aux@wheel@size
497  \do {%

First define the macros that make up the wheel itself to be their spoke numbers.

498  \eExpand*\thenc@count\In {%
499  \NewName*{nc@auxout@\thenc@count} {} {%
500  ##1%

501 }% 502 }

Next allocate the corresponding stream.

503  \EExpand\csname nc@auxout@\thenc@count@stream\endcsname\In {%
504  \@nameuse{newwrite}##1%

505 }

Next create the corresponding flag (they start false).

506  \provideboolean{@nc@auxout@\thenc@count @inuse@}

Now add the spoke itself.

507  \EExpand\csname nc@auxout@\thenc@count\endcsname\In {%
508  \ReserveCS#1%
509  \AddSpokes\nc@aux@wheel##1%

510 }

511  \stepcounter{nc@count}

512 }

513 \def\NextAux {%
514  \Roll\nc@aux@wheel
515  \@nameuse{if@nc@auxout@\Top\nc@aux@wheel @inuse@}%
516  \MonsterError{newclude} {%
517  You can't nest \protect\include this deeply!%

518 }%

519  \else
520  \Elet\@auxout\csname nc@auxout@\Top\nc@aux@wheel @stream\endcsname
521  \fi

522 }% 523 }

15.0.4 Dynamic allocation

\DynamicAux
\nc@addnewauxstream
524 \newcommand\DynamicAux {%
525 \def\nc@aux@wheel@size {1}
526 \nc@init@aux@wheel
527 \def\NextAux {%
528  \Roll\nc@aux@wheel
529  \@nameuse{if@nc@auxout@\Top\nc@aux@wheel @inuse@}%
530  \nc@addnewauxstream
531  \fi

Either the top spoke was not in use, or we have added a fresh spoke at the top – so the top spoke represents what we want.

532  \Elet\@auxout\csname nc@auxout@\Top\nc@aux@wheel @stream\endcsname
533  \typeout{NextAux has just set auxout to stream
534  \the\csname nc@auxout@\Top\nc@aux@wheel @stream\endcsname.
535  We are using spoke number
536  \csname nc@auxout@\Top\nc@aux@wheel\endcsname.}

537 }% 538 }

It works out that the new spoke should have a spoke number one greater than the current wheel size. We use the nc@count counter to find this number.

539 \newcommand\nc@addnewauxstream {%
540 \setcounter{nc@count}{\nc@aux@wheel@size}%
541 \stepcounter{nc@count}%
542 \typeout{Allocating another spoke (spoke number \thenc@count)}%

First we add the spoke itself, then initialize the corresponding objects.

543 \EExpand*\csname nc@auxout@\thenc@count\endcsname\In {%
544  \AddSpokes\nc@aux@wheel##1%

545 }%

546 \EExpand*\thenc@count\In {%
547  \DefName*{nc@auxout@##1} {} {##1}%
548  \provideboolean{@nc@auxout@##1@inuse@}%
549  \def\nc@aux@wheel@size {##1}%
550  \EExpand*\csname nc@auxout@##1@stream\endcsname\In {%
551  \@nameuse{newwrite}####1%

552 }% 553 }% 554 }

555 \DynamicAux

15.0.5 Including

\nc@include The only way I see how to set the inuse flag to false at the proper time is to use the afterpage package. What I would really like is to \write something with side effects.

556 \newcommand\nc@include [2][] {%
557 \if@filesw
558  \immediate\write\@mainaux{\string\@input{#2.aux}}%
559 \fi
560 \@tempswatrue
561 \if@partsw

562  \@tempswafalse
563  \edef\reserved@b{#2}%
564  \@for\reserved@a:=\@partlist\do
565  {\ifx\reserved@a\reserved@b\@tempswatrue\fi}%
566 \fi
567 \if@tempswa
568  \stepcounter{IncludeDepth}%

\nc@t@c is going to preserve the current aux stream number to restore \@auxout, in case there is a nested \include.

569  \edef\nc@t@c {%
570  \the\@auxout

571 }%

572  \if@filesw
573  \NextAux
574  \openout\@auxout #2.aux
575  \write\@auxout{\relax}%
576  \expandafter\global
577  \csname @nc@auxout@\Top\nc@aux@wheel @inuse@true\endcsname

\nc@include@finish@<N> The next line defines the macro \nc@include@finish@⟨n⟩ to close the output stream that is presently open. We have an interesting task here of getting certain unique information to macros after the \@input when we might end up recursing during the \@input. To do this, we immediately expand the variables we need and store them in a macro which will not be altered by a recursion of \include. We have set up the IncludeDepth counter to allow us to define such a macro, which is unique to this instance of \include.

Warning: The macro names \nc@include@finish@⟨n⟩ where ⟨n⟩ is an integer are overwritten, that is, they are not allocated in a safe way.

The following lines are intended to make this definition, where <D> represents the current value of IncludeDepth, <P> represents the spoke number of the current top of \nc@aux@wheel, and <S> represents the stream number for the current part, i.e., the current value of \@auxout, and <X> represents the stream number that was current before \include got called (this is saved in \nc@t@c).

   \def\nc@include@finish@<D> {%
     \closeout<S>%
     \global\chardef\@auxout=<X>%
     \afterpage{\global\@nc@auxout@<P>@inuse@false}
   }
578  \EExpand\theIncludeDepth\In {%                   ##1
579  \EExpand\the\@auxout\In {%                       ####1
580  \DefName{nc@include@finish@##1} {} {%
581  \closeout####1%
582  \global\chardef\@auxout=\nc@t@c
583  \typeout{Restored auxout to stream number
584  \nc@t@c \space (old: \the\@auxout)}
585  \typeout{executing afterpage}%
586  \EExpand\csname @nc@auxout@\Top\nc@aux@wheel
587  @inuse@false\endcsname\In {% ########1
588  \afterpage{%
589  \typeout{Finishing.  auxout is now \the\@auxout;  current spoke

590  is \csname nc@auxout@\Top\nc@aux@wheel\endcsname\space
591  with stream number
592  \the\csname nc@auxout@\Top\nc@aux@wheel @stream\endcsname

593 }%

594  \global########1%
595  }%                                                 Afterpage
596  }%                                                   EExpand
597  }%                                                     DefName
598  }}%                                                      EExpand
599  \fi %                                                      \if@filesw
600  \nc@t@b           % surround the \include with something

Now execute the text of the optional argument to \include. Notice that if we change to a new aux file, we should do it before the optional argument. This is important so that sectioning commands will appear in the right order. If the sectioning command were to write to \@mainaux, then it would come after the whole included aux file, instead of before it.

601  #1%
602  \@input@{#2.tex}%
603  \@writeckpt{#2}%
604  \if@filesw
605  \csname nc@include@finish@\theIncludeDepth\endcsname
606  \fi
607  \nc@t@b           % surround the \include with something

We mustn’t restore the counter before we have finished using it.

608  \addtocounter{IncludeDepth}{\m@ne}%

If the file is excluded by the \includeonly command, we don’t load it and execute the file’s checkpoint instead.

609 \else
610  \@nameuse{cp@#2}%
611 \fi

612 }

15.0.6 Checkpoints

\@writeckpt \@wckptelt We must redefine the macros which write the checkpoints. \@auxout is substituted for \@partaux; I think this change should be in the kernel anyway! And we remove

 the \immediates.
613 \defcommand\@writeckpt [1] {%
614 \if@filesw
615  \write\@auxout{\string\@setckpt{#1}\@charlb}%
616  \begingroup
617  \let\@elt\@wckptelt
618  \cl@@ckpt
619  \endgroup
620  \write\@auxout{\@charrb}%
621 \fi

622 }

623 \defcommand\@wckptelt [1] {%
624 \protected@write\@auxout{}{\string\setcounter{#1}{\the\@nameuse{c@#1}}}%

625 }

15.0.7 Wheels

\InitWheel \Roll \IfTop \Top \AddSpokes A wheel is implemented as a macro. The tokens of its first-level expansion are the spokes, the top being the first.

626 \newcommand\InitWheel [1] {% args: wheel
627 \InitCS#1%

628 }

629 \newcommand\Roll [1] {% args: wheel
630 \edef #1{%
631  \expandafter\nc@roll #1\nc@llor

632 }% 633 }

634 \ReserveCS\nc@llor
635 \NewNameDef{nc@roll} {#1\nc@llor} {%
636 \@cdr#1\@nil\@car#1\@nil

637 }

638 \newcommand\Top [1] {% args: wheel
639 \E@car #1\@nil

640 }

641 \newcommand\IfTop [4] {% args: wheel token true false
642 \EExpand#1\In {%
643  \edef\nc@t@b {%
644  \expandafter\noexpand\@car##1\@nil

645 }% 646 }%

At this point, the first-level expansion of \nc@t@b is a single token, the top of the wheel. We \let \nc@t@a to this token.

647 \Elet\nc@t@a\nc@t@b
648 \let\nc@t@b #2%
649 \ifx\nc@t@a\nc@t@b
650  \expandafter\@firstoftwo
651 \else
652  \expandafter\@secondoftwo
653 \fi

654 }

655 \newcommand\AddSpokes [2] {% args: wheel spokes
656 \EExpand#1\In {%
657  \def #1{#2##1}%

658 }% 659 }

16 Benign packages

\DeclareFormattingPackage
\nc@formatting@packages
660 \newcommand\DeclareFormattingPackage [1] {%
661 \addto@macro\nc@formatting@packages{,#1}%

662 }

663 \newcommand\nc@formatting@packages {times,helvetic}

Index

Numbers written in italic refer to the page where the corresponding entry is described; numbers underlined refer to the code line of the definition; numbers in roman refer to the code lines where the entry is used.

Symbols

\# . . . . . . . . . . . . . . 143 \% . . . . . . . . . . . . . . 131 \@@ 415, 418, 425, 429, 438 \@@auxtag . . . . . . . . \underline{442}

\@@setckpt . . . . . . . \underline{462}

\@auxout . 44, 63, 78, 210, 213, 217, 221, 307, 310, 314, 371, 384, 388, 392, 404, 408, 520, 532, 570, 574, 575, 579, 582, 584, 589, 615, 620, 624

\@auxtag . . . . . 217,

221, 371, \underline{442}, 473

\@begindocumenthook 284

\@bibitem . . . . . . . . \underline{225}

\@biblabel . . . . . . . 233

\@bsphack …. 243, 292 \@car . . . . . . . . 636, 644 \@cdr . . . . . . . . . . . . 636 \@charlb . . . . . . . . .

. 307, 371, 392, 615 \@charrb . . . . . . . . .

. 310, 388, 408, 620 \@cite . . . . . . . 258, 275 \@citea … 257, 260, 261 \@citeb . . . . . . 259,

262, 264, 266, 270, 272, 293, 294, 296, 298, 300

\@citex . . . . . . . . . . \underline{225}

\@currentlabel . . . . 244
\@currenvir . . . . . . . 203

\@eha . . . . . . . . . . . . 45 \@elt . . . . . . . . 308, 617 \@empty … 98, 257, 414 \@esphack …. 245, 303

\@firstofone . . 262, 294
\@firstoftwo 90, 108, 650

\@for 59, 99, 259, 293, 564 \@fornoop . . . . . . . . 432 \@fortmp . . . . . 412, 414

\@ifnextchar . . . . . .

…. 162, 169, 332 \@ifstar . . . . . . . . . 115

                          \@ifundefined . . . . .

. . 10, 103, 266, 298, 354, 369, 451

\@include . . . . . . 47, \underline{50} \@input . . . . . . . 53, 558 \@input@ 69, 281, 346, 602

                          \@latex@error . . . . . 45
                          \@latex@warning 269, 300
                          \@lbibitem . . . . . . . \underline{225}

\@listctr . . . . . . . . 228 \@m . . . . . . . . . . . . . 261 \@mainaux . . 53, 78, 558

                          \@nameuse . . . . . 76,

314, 317, 326, 357, 504, 515, 529, 551, 610, 624

\@nil . 377, 398, 415,

440, 636, 639, 644 \@nnil …. 420, 423, 431

                          \@partaux . . . . . 44,

63, 65, 66, 73, 486 \@partlist 59, 98, 99, 564

                          \@partswtrue . . . . . . 96
                          \@percentchar . 217,

221, 307, 371, 392

                          \@protected@writeaux

. . . . . . . . . . . \underline{223}

                          \@secondoftwo . . . . .

…. 105, 473, 652

                          \@setckpt . . . . . . . .

. 307, 392, \underline{462}, 615

                          \@tempswafalse . 57, 562
                          \@tempswatrue . . . . .

. . 55, 60, 560, 565 \@tfor . . . . . . . . . . . 136

                          \@undefined . . . . . . . 284
                          \@wckptelt . . . \underline{305}, \underline{613}
                          \@whilenum . . . . . . . 496
                          \@writeaux   \underline{223}, 228,

237, 264, 279, 288, 296, 343, 349

                          \@writeckpt . . . . 71,

\underline{305}, 348, 603, \underline{613}

                          \@writefile . . . . . . . 254

\\ . . . . . . . . . . . . . . 141 \{ . . . . . . . . . . . . . . 141 \} . . . . . . . . . . . . . . 141 \^132, 141, 366, 380,

400, 443, 447, 464

\␣ . . . . . . . . . . 141, 261

A \active … 443, 447, 464

                                                   \AddSpokes . . . . 24,

489, 509, 544, \underline{626}

                                                   \addto@macro 128, 131,

132, 134, 144, 661

                                                   \addtocontents . . . . \underline{225}
                                                   \addtocounter . 351, 608

\advance . . . . . . . . . 325

                                                   \aftergroup . . . . . . . 146
                                                   \afterpage . . . . . . . 588
                                                   \AtBeginDocument . . 285
                                                   \AtBeginInclude . . . . 3
                                                   \AtEndDocument . . . . 472
                                                   \AtEndInclude . . . . . . 3
                                                   \AtEndOfPackage . . .

. . . . . . . 30, 33, 36

B \begin . . . . . . . . . . . 201

                                                   \begingroup 176, 193,

202, 235, 324, 365, 379, 399, 442, 446, 463, 616

\bfseries . . . . . . . . 267 \bibcite . . . . . 228, 237 \bibdata . . . . . . . . . 279

                                                   \bibliography . . . . . \underline{225}
                                                   \bibliographystyle . 283

\bibstyle . . . . . . . . 288

C

                                                   \c@IncludeDepth   \underline{88}, 325

\catcode . . 131, 132, 135, 366, 380, 400, 443, 447, 464

\chardef . . . . . . . . . 582 \citation …. 264, 296 \cl@@ckpt …. 309, 618

                                                   \clearpage . 51, 70, 119

\closeout . . . . . 73, 581 \csname . . . . . . . 14,

180, 185, 195, 200, 272, 372, 393, 456, 458, 469, 486, 488, 503, 507, 520, 532, 534, 536, 543, 550, 577, 586, 590, 592, 605

D

\DeclareBooleanOptions

. . . . . . . . . . . . 38

\DeclareFormattingPackage

. . . . . . . . . 8, \underline{660}

\DeclareOption . . . .

…. 25, 29, 32, 35 \def . . 1–5, 114, 180,

185, 195, 200, 201, 203, 261, 411, 419, 422, 430, 493, 513, 525, 527, 549, 657

\DefaultIncludeSurround

. . . . . . . . . . 4, \underline{84}

\defcommand . . . . . . .

42, 50, 95, 102, 225, 242, 247, 277, 283, 291, 305, 313, 613, 623

\DefName . . . . . 232, 256, 342, 368, 391, 462, 547, 580

\DefWheel . . . . . . . . 23 \Disable . . . . . . . 8, \underline{123}

\DisableAll . . . . . . .

. . 8, \underline{123}, 177, 194 \do …. 59, 99, 142,

259, 293, 381, 401, 410, 497, 564

\docdate . . . . . . . . . . \underline{1}

\documentclass 178, 201
\DoXPackageS . . . . . . . 2
\DoXUsepackagE . . . . . \underline{1}
\DTypeout . . . . . 97,

104, 107, 112, 355, 378, 382, 402

\DynamicAux . . . . 23, \underline{524}

E

\E@car . . . . . . . . . . . 639 \edef . . . . . 6, 58, 98,

262, 294, 373, 377, 394, 398, 563, 569, 630, 643 \eExecute . . . . . . . . 216 \EExpand . . 372, 383,

393, 403, 488, 503, 507, 543, 546, 550, 578, 579, 586, 642, 656

\eExpand . . . . . . 14, 498 \Elet . . . . . 520, 532, 647 \else 46, 75, 284, 323,

414, 420, 423, 433, 519, 609, 651

\endcsname . . . . 14,

180, 185, 195, 200, 272, 372, 393, 456, 458, 469, 486, 488, 503, 507, 520, 532, 534, 536, 543, 550, 577, 587, 590, 592, 605

\endgroup . . . . 186,

205, 238, 327, 387, 407, 441, 460, 467, 470, 619

\endinput . . 19, 27, 144

\ExecuteOptions . . . 39

\Expand … 150, 156, 188

\expandafter . . . . . .

. . 47, 142, 180, 185, 195, 200, 262, 285, 294, 374, 377, 395, 398, 411–413, 415, 432, 436, 454–456, 458, 469, 486, 576, 631, 644, 650, 652

F

\fi 48, 54, 60, 61, 67, 74, 77, 229, 239, 265, 280, 286, 289, 297, 311, 328, 361, 416, 426, 427, 437, 521, 531, 559, 565, 566, 599, 606, 611, 621, 653

\filedate . . . . . . . . . \underline{1} \fileinfo . . . . . . . . . \underline{1}

\fileversion . . . . . . . \underline{1}
\FrankenWarning . . . 322

G

\g@addto@macro . . . . 125

                   \G@refundefinedtrue

. . . . . . . . 268, 299 \gdef . . . . . . . . . . . . 469 \Global … 368, 391,

410, 418, 429, 440, 445, 450, 462

\global … 576, 582, 594 \glossary . . . . . . . . 252 \Gobble …. 93, 250–252 \GobbleOM …. 178, 179

H

                   \HaveECitationS . . . . \underline{1}

\hbox . . . . . . . . . . . . 272 \hfill . . . . . . . . . . . 233

I

                   \if@filesw 52, 64, 72,

227, 234, 263, 278, 287, 295, 306, 358, 557, 572, 599, 604, 614

                   \if@partsw . . . . 56, 561
                   \if@tempswa . . . . 62, 567
                   \IfAllowed . . 8, \underline{89}, 339

\ifnum . . . . . . . . 44, 320

                   \ifSkipPreamble . . . . 8

\IfTop . . . . . . . . 24, \underline{626} \ifx 60, 284, 414, 420,

423, 431, 565, 649

                   \ignorespaces . 230, 240
                   \immediate . . . . 53,

65, 66, 73, 210, 558 \In 14, 150, 156, 188,

372, 383, 393, 403, 488, 498, 503, 507, 543, 546, 550, 578, 579, 587, 642, 656

\include …. 3, \underline{42}, \underline{114}, 189, 340, 352, 517, 600, 607

\include* . . . . . . 4, \underline{114}

                   \includeall . . . . . . 4, \underline{89}
                   \includedoc . . . . . 6, \underline{148}
                   \includedoc* . . . . 6, \underline{148}
                   \includedocskip . . . \underline{154}
                   \includedocskip* . . \underline{154}
                   \IncludeEnv . . . 151, \underline{160}
                   \includeenv . . . . . . . . 5
                   \includeenv* . . . . . . . 6
                   \IncludeEnvSkip . . . 157
                   \IncludeName . . . . . .

. . 8, 217, 221, \underline{316}

\includeonly . . . . . 4, \underline{89}
\IncludeSurround . .

. . . . . . . 4, \underline{84}, 116 \index . . . . . . . . . . . 251 \InitCS . . . . . . . 24, 627 \InitName . . . . . . . . 100

\InitWheel 23, 476, \underline{626}

\input … 26, 30, 33, 36 \item . . . . . . . . 226, 233

J

\jobname . . 281, 321, 330

\JusTLoaDInformatioN 12

L

\label . . . . . . . . . . . \underline{225} \let . . . . . . . . 27, 63,

78, 93, 105, 108, 116, 119, 178, 179, 223, 224, 236, 250–252, 257, 308, 343, 344, 349, 350, 473, 486, 617, 648

\long . . . . . . . . . . . . 201

M

\m@ne . . . . . . . . 351, 608 \m@one . . . . . . . . . . . 325

\makeatletter 9, 181, 196
\makeatother . . . . . . 18

\mbox . . . . . . . . . . . . 267

\md@check@star . . . .

…. 149, 155, 161 \meaning . . . . . 374,

378, 382, 395, 402

\MonsterError . . . . . 516
\MonsterInfo . . . . . . 129

N

\nc@@include . . . . . . \underline{331}
\nc@@includeenv . . . \underline{160}
\nc@addnewauxstream  \underline{524}
\nc@aux@wheel . . . . .

. \underline{476}, 489, 509, 514, 515, 520, 528, 529, 532, 534, 536, 544, 577, 586, 590, 592

\nc@aux@wheel@size .

…. \underline{478}, 493, 496, 525, 540, 549

\nc@count . . . . . . . . \underline{477}

\nc@disable@char . . \underline{133}

\nc@for … 381, 401, \underline{410}

\nc@forloop . . . . . . . \underline{410}
\nc@formatting@packages

. . . . . . . . . . . \underline{660}

\nc@iforloop . . . . . . \underline{410}
\nc@include . . . . . . .

. 117, 120, \underline{331}, \underline{556}

\nc@includeenv . . . . \underline{160}
\nc@init@aux@wheel .

…. \underline{487}, 495, 526 \nc@llor . . 631, 634, 635

\nc@protected@writeaux@aux

. . . . . . . . \underline{215}, 344

\nc@protected@writeaux@main

…. \underline{209}, 224, 350

\nc@radical@shutdown

. . . . . . . . \underline{127}, 146

\nc@radical@shutdown@aftergroup

…. \underline{145}, 183, 198 \nc@roll . . . . . . . . . 631

\nc@strip@M 377, 398, \underline{440}

\nc@t@a . . . . . \underline{80}, 99, 100, 373, 377, 378, 381, 394, 398, 401, 647, 649

\nc@t@b . . . . . . . \underline{80}, 116, 119, 340, 352, 381–383, 401–403, 600, 607, 643, 647–649

\nc@t@c \underline{80}, 105, 108,

110, 569, 582, 584

\nc@toks@a . . . . . . .

. \underline{80}, 452, 454, 458

\nc@write@auxcommands

. . . . . . . . 359, \underline{365}

\nc@write@ckpt 360, \underline{365}
\nc@writeaux@aux . .

. . . . . . . . \underline{215}, 343

\nc@writeaux@main .

…. \underline{209}, 223, 349

\NeedsTeXFormat . . . 21
\newboolean . . . . . . . 480
\newcommand . . . . . . .

84, 89, 92, 124, 133, 145, 148, 154, 160, 209, 212, 215, 220, 316, 319, 331, 468, 487, 492, 524, 539, 556, 626, 629, 638, 641, 655, 660, 663

\newcounter . . . . 88, 477

\newlabel . . . . . . . . 244 \newlet . . . . . . . . . . 87 \NewName 168, 175, 192,

330, 338, 410, 418, 429, 440, 445, 450, 483, 499

\NewNameDef . . . . . . . 635
\newtokens . . . . . . . 83

\NextAux . . . . . . 23,

\underline{479}, 513, 527, 573 \nocite . . . . . . . . . . \underline{225} \noexpand …. 236, 644

O

\openout . . . . . . 65, 574

P

\par . . . . . . 85, 187, 206

\ParentName . . . . . 8, \underline{316}

\penalty . . . . . . . . . 261 \PPOptArg . . . . . . . \underline{1}, 22

\ProcessOptions . . . 40

\protect . . 130, 236, 517

\protected@write . .

…. 213, 221, 624

\protected@writeaux

. . . . . . . . 224, 244, 248, 344, 350

\provideboolean 506, 548
\ProvidesPackage . . 22

R

\relax . . 43, 66, 435, 575

\RequirePackage 23, 475
\ReserveCS . . . . . . .

80–82, 123, 127, 478, 479, 508, 634

\reserved@a . . . . . . .

. . 59, 60, 564, 565

\reserved@b . . . . . . .

. . 58, 60, 563, 565

\ReserveName . . 482, 485
\reset@font . . . . . . . 267
\RestoreDoXVarS . . . 17

\Roll . . 24, 514, 528, \underline{626}

S

\SaveDoXVarS . . . . . . 13
\sc@star@nothing . .

…. 150, 156, 188 \sc@t@a . . . . . . . . . .

24, 27, 41, 136, 142

\setcounter . . . . . . .

. 314, 494, 540, 624

\SkipPreamblefalse . . 8
\SkipPreambletrue . . 8

\space . . . . . . 7, 45,

130, 270, 584, 590

\StaticAux . . . . 23, \underline{492}
\stepcounter . . . . . .

. 341, 511, 541, 568 \string . 45, 53, 217,

221, 228, 237, 244, 254, 264, 279, 288, 296, 307, 314, 371, 392, 558, 615, 624

\strip@prefix . 374, 395

T

\the . . 228, 314, 458, 534, 570, 579, 584, 589, 592, 624

                   \theIncludeDepth 317,

326, 342, 578, 605

                   \thenc@count . . . . . .

. 498, 499, 506, 507, 542, 543, 546

                   \thenc@count@stream 503

\thepage . . . . . 244, 270 \Top . . . . . . . 24, 515,

520, 529, 532, 534, 536, 577, 586, 590, 592, \underline{626}

\typeout . . . . . 533, 542, 583, 585, 589

U

                   \UndefineCS . . . . . . . 12
                   \usepackage . . . . 15, 179

V \value …. 228, 320, 496

W \write 53, 66, 210, 217,

307, 310, 314, 371, 384, 388, 392, 404, 408, 558, 575, 615, 620

X \xdef . . . . . . . . . . . . 458

Z

                                             \zap@space . . . . . . . 98