2  INTRODUCTION  SCANTEX §1

1. Introduction. This program takes a TEX file generated by and strips out the sections which have not been changed, outputting the changed sections to a second, greatly reduced TEX file. The index, section names, and table of contents are dropped as well.

The program uses a few features of the Modula-2 compiler used in its development (Logitech MS-DOS) that may need to be changed in other installations. System-dependent portions of can be identified by looking at the entries for ‘system dependencies’ in the index below.

The “banner line” defined here should be changed whenever is modified. define banner ≡ ´ ␣ ␣ ␣ ␣ ´

2. The program begins with a fairly normal header, made up of pieces that will mostly be filled in later. The TEX input comes from file TeX file and the new TEX output goes to file out TeX file. Unlike Pascal, Modula-2 does not require the constant, type, and variable sections to be placed here in the program header in a rigidly specified order, but we will do it anyway, since makes it so easy. module scan TeX ; ⟨ Import List 4 ⟩

const ⟨ Constants in the outer block 5 ⟩ type ⟨ Types in the outer block 6 ⟩ var ⟨ Globals in the outer block 7 ⟩

3. This procedure initializes the module. procedure initialize;

var ⟨ Local variables for initialization 15 ⟩ begin

⟨ Set initial values 8 ⟩

⟨ Initialize the file system 16 ⟩; end initialize;

4. A few macro definitions for low-level output instructions are introduced here. All of the terminal-oriented commands in the remainder of the module will be stated in terms of simple primitives. The boxes signify words that must not be forced to uppercase when the program is , since Modula-2 is case-sensitive.

define pr char ≡ \underline{\overline{␣ ␣}} (∗ library procedure to output a character ∗) define pr string ≡ \underline{\overline{␣ ␣}} (∗ library procedure to output a string ∗) define rd string ≡ \underline{\overline{␣ ␣}} (∗ library procedure to input a string ∗) define pr card ≡ \underline{\overline{␣ ␣}} (∗ library procedure to output a cardinal number ∗) define new line ≡ \underline{\overline{␣ ␣}} (∗ a new line ∗) define print string (#) ≡ pr string (#) (∗ put a given string to the terminal ∗) define read string (#) ≡ rd string (#) (∗ read a given string from the terminal ∗) define print cardinal (#) ≡ pr card (#, 1) (∗ put a given cardinal to the terminal, in decimal notation,

using only as many digit positions as necessary ∗)

define print ln(#) ≡ pr string (#); new line;

(∗ put a given string to the terminal, followed by a new line ∗)

define print char (#) ≡ pr char (#) (∗ put a given character to the terminal ∗) ⟨ Import List 4 ⟩ ≡

from \underline{\overline{␣ ␣}} import pr string , rd string , pr char , pr card , new line;

See also sections 10 and 11. This code is used in section 2.

§5  SCANTEX  INTRODUCTION 3

5. Let’s define a few constants. ⟨ Constants in the outer block 5 ⟩ ≡

buf size = 1000; (∗ maximum length of input line ∗)

file name len = 200; (∗ length of a file name ∗)

This code is used in section 2.

6. A global variable called history will contain one of four values at the end of every run: spotless means that no unusual messages were printed; harmless message means that a message of possible interest was printed but no real errors were detected; error message means that at least one error was found; fatal message means that the program terminated abnormally. The value of history does not influence the behavior of the program; it is simply computed for the convenience of systems that might want to use such information.

We don’t really have to worry about errors too much in this particular program because the input is machine-generated (by ). The error likeliest to occur is failure during file opens.

define mark harmless ≡

if history = spotless then

history ← harmless message; end ;

define mark error ≡ history ← error message

define mark fatal ≡ history ← fatal message

define err print (#) ≡ print ln(#); mark error ; ⟨ Types in the outer block 6 ⟩ ≡

error level = (spotless , harmless message, error message, fatal message);

This code is used in section 2.

7. ⟨ Globals in the outer block 7 ⟩ ≡ history : error level ; (∗ how bad was this run? ∗)

See also sections 12 and 18. This code is used in section 2.

8. ⟨ Set initial values 8 ⟩ ≡ history ← spotless ;

See also section 17. This code is used in section 3.

9. Some implementations may wish to pass the value of the history variable to the operating system so that it can be used to govern whether or not other programs are started. The doscall procedure passes a program status value back to DOS. We use fatal error to terminate the program abnormally.

define print fatal message ≡ print string (´ ␣ ␣ ␣ ␣´ ); print ln(´ ␣ ␣ ´ ) define fatal error (#) ≡ mark fatal ; print ln(#); print fatal message; doscall (˝ 4C, history );

⟨ Terminate program, converting history to program exit status 9 ⟩ ≡

doscall (˝ 4C, history );

This code is used in section 24.

10. If we are going to use doscall from the Logitech library we have to import it from the module system. ⟨ Import List 4 ⟩ +≡

4  FILE HANDLING  SCANTEX §11

from system import doscall ; 11. File Handling. Here we define the symbols for use with file handling.

define lookup ≡ \underline{\overline{␣ ␣}} (∗ library procedure to open a file ∗) define close ≡ \underline{\overline{␣ ␣}} (∗ library procedure to close a file ∗) define failure(#) ≡ (#. \underline{\overline{}}≠ \underline{\overline{}}) (∗ last file operation sucessful ? ∗) define abort if open error (#) ≡

if failure(#) then

print string (´ ␣ ␣ ␣´ ); fatal error (filename); end ;

define open input file(#) ≡ lookup(#, filename, false); abort if open error (#) define open output file(#) ≡ lookup(#, filename, true); abort if open error (#) define close file(#) ≡ close(#); define end file ≡ \underline{\overline{}} define null char ≡ \underline{\overline{␣ ␣}} define end of line(#) ≡ (ch = eol ) define end of file(#) ≡ (#.end file) define read char ≡ \underline{\overline{␣ ␣}} define write char ≡ \underline{\overline{␣ ␣}} define input char (#) ≡ read char (#, ch); define output char (#) ≡ write char (#, ch) define read ln(#) ≡

while ¬end of line(#) do

input char (#); end ;

define write ln(#) ≡ write char (#, eol ); define text file ≡ \underline{\overline{␣ ␣}}

⟨ Import List 4 ⟩ +≡ from \underline{\overline{␣ ␣}} import lookup, \underline{\overline{}}, read char , write char , text file, close; from ascii import eol , null char ;

12. Input goes into an array called buffer . ⟨ Globals in the outer block 7 ⟩ +≡ buffer : array [0 . . buf size] of char ; TeX file, out TeX file: text file;

§13  SCANTEX  FILE HANDLING 5

13. The input ln procedure brings the next line of input from the specified file into the buffer array and returns the value true, unless the file has already been entirely read, in which case it returns false. Under normal conditions, we will never reach true end of file, for reasons discussed in later sections, but we will handle it anyway. Trailing blanks are ignored and the global variable limit is set to the length of the line. The value of limit must be strictly less than buf size. procedure input ln(var f : text file): boolean; (∗ inputs a line or returns false ∗)

var final limit : [0 . . buf size]; (∗ limit without trailing blanks ∗) ch: char ; (∗ current input character ∗) line pres : boolean; (∗ temporary result of procedure ∗)

begin limit ← 0; final limit ← 0; if end of file(f) then line pres ← false

else input char (f); while ¬end of line(f) do if ch = null char then

return false

end ;

buffer [limit ] ← ch; inc(limit ); if buffer [limit − 1] ≠ ´ ␣´ then

final limit ← limit end ; if limit = buf size then

read ln(f); dec(limit ); err print (´ ␣ ␣ ␣ ␣ ´ ); return true; end ; input char (f);

end ;

read ln(f); limit ← final limit ; line pres ← true; end ; return line pres ;

end input ln;

14. The output ln procedure writes the next line of output from the buffer array to the specified file. procedure output ln(var f : text file); (∗ outputs a line ∗)

var ch: char ; (∗ current output character ∗)

temp: [0 . . buf size]; begin

if limit > 0 then

for temp ← 0 to limit − 1 do

ch ← buffer [temp]; output char (f); end ; end ; write ln(f);

end output ln;

15. We define filename local to the initalization procedure because it is used only during file open. ⟨ Local variables for initialization 15 ⟩ ≡ filename: array [0 . . file name len − 1] of char ;

This code is used in section 3.

16. In this section we open both of the files.

define next file(#) ≡ filename[0] ← ´ ␣´ ; print ln(#); read string (filename); new line;

print ln(filename); new line;

⟨ Initialize the file system 16 ⟩ ≡ next file(´ ␣ ´ ); open input file(TeX file); next file(´ ␣ ␣ ´ ); open output file(out TeX file);

This code is used in section 3.

17. Here we initialize most of the variables. The output enabled flag is initialized to true so that the lines in the header of the -generated TEX file, known as “limbo text”, are picked up in addition to the changed sections. ⟨ Set initial values 8 ⟩ +≡

TeX line ← 0; out TeX line ← 0; limit ← 0; buffer [0] ← ´ ␣´ ; input has ended ← false; output enabled ← true;

18. ⟨ Globals in the outer block 7 ⟩ +≡ TeX line: cardinal ; (∗ the number of the current line in the main TEX file ∗) out TeX line: cardinal ; (∗ the number of the line in the output TEX file ∗) limit : [0 . . buf size]; (∗ the last character position occupied in the buffer ∗) input has ended : boolean; (∗ there is no more input ∗) output enabled : boolean; (∗ we are copying input lines to output ∗)

§19  SCANTEX  MAIN INPUT LOOP 7

19. Main Input Loop. This is the main processing loop of . We simply read lines until end of file. The get line procedure will determine the setting of the output enabled flag. If set, we copy the line to the output file. ⟨ Read the input 19 ⟩ ≡

while ¬input has ended do get line;

if output enabled then

output ln(out TeX file); inc(out TeX line); end ;

end ;

This code is used in section 24.

20. The get line procedure is called to read in the next line and scan it. We will output an “I’m alive!” dot to the terminal every 100 input lines and a new line every 2000. procedure get line; (∗ inputs the next line ∗)

var keep looking : boolean; temp index : cardinal ; begin

input has ended ← ¬input ln(TeX file);

if input has ended then

output enabled ← false; return ; else

inc(TeX line);

if (TeX line mod 100) = 0 then print char (´ ´ ); if (TeX line mod 2000) = 0 then

new line; end ; end ; ⟨ Scan the line 21 ⟩; buffer [limit ] ← ´ ␣´ ;

end ; end get line;

8  MAIN INPUT LOOP  SCANTEX §21

21. In this section we determine whether the current line is the beginning of a section (‘ ’ or ‘ ’ at beginning of line, followed immediately by a section number) and, if so, whether the section has been modified (‘ ’ following the number). We update the output enabled flag according. Additionally, the index section (‘ ’) is considered end of file. If it is detected, we set the flag input has ended to terminate the program and set output enabled to false to keep the command from being copied to the output file.

define numeric digit at (#) ≡ ((buffer [#] ≤ ´ ´ ) ∧ (buffer [#] ≥ ´ ´ ))

define third char matches (#) ≡ (buffer [temp index + 2] = #)

define second char matches (#) ≡ (buffer [temp index + 1] = #) ∧ third char matches

define char matches (#) ≡ (buffer [temp index ] = #)

define three chars match(#) ≡ char matches (#) ∧ second char matches ⟨ Scan the line 21 ⟩ ≡

temp index ← 1;

if (limit > 3) ∧ (buffer [0] = ´ ´ ) then

if (char matches (´ ´ ) ∨ char matches (´ ´ )) ∧ numeric digit at (2) then

⟨ Search for ‘ ’; set output enabled if found 22 ⟩; elsif three chars match(´ ´ )(´ ´ )(´ ´ ) then

output enabled ← false; input has ended ← true; end ;

end ;

This code is used in section 20.

22. Starting at the first digit of the section number, search for ‘ ’, which indicates that this is a changed section. Discontinue the search if ‘ ’is found or the current position is no longer a numeric digit, which means we have moved past the section number without finding it. ⟨ Search for ‘ ’; set output enabled if found 22 ⟩ ≡

output enabled ← false; keep looking ← true; temp index ← 3;

while (¬output enabled ) ∧ keep looking do output enabled ← three chars match(´ ´ )(´ ´ )(´ ´ ); keep looking ← numeric digit at (temp index ); inc(temp index );

end ;

This code is used in section 21.

23. The command to generate the table of contents (‘ ’) is normally the last line in a TEX file generated

by  . Part of its function is to terminate TEX gracefully by generating a ‘  ’ command or equivalent
after generating the contents. Since we are dropping the ‘  ’ command, we must issue the ‘  ’ command

directly, just before closing the input and output files. ⟨ Add ‘ ’ command to end of output and close both files 23 ⟩ ≡

buffer [0] ← ´ ´ ; buffer [1] ← ´ ´ ; buffer [2] ← ´ ´ ; buffer [3] ← ´ ´ ; limit ← 4; output ln(out TeX file); inc(out TeX line); close file(TeX file); close file(out TeX file);

This code is used in section 24.

§24  SCANTEX  MAIN PROGRAM 9

24. Main Program. This is the main program. begin

print ln(banner ); initialize; ⟨ Read the input 19 ⟩; ⟨ Add ‘ ’ command to end of output and close both files 23 ⟩; ⟨ Print statistics about line counts 26 ⟩; ⟨ Print the job history 25 ⟩; ⟨ Terminate program, converting history to program exit status 9 ⟩;

end scan TeX .

25. Here we simply report the history to the user. ⟨ Print the job history 25 ⟩ ≡

case history of

spotless : print ln(´ ␣ ␣ ␣ ´ ) | harmless message: print string (´ ␣ ␣ ␣ ␣´ );

print ln(´ ␣ ␣ ´ ) | error message: print string (´ ␣ ␣ ␣ ␣ ␣ ␣´ );

print ln(´ ␣ ␣ ´ ) | fatal message: print fatal message

end ; (∗ there are no other cases ∗)

This code is used in section 24.

26. ⟨ Print statistics about line counts 26 ⟩ ≡ new line; print ln(´ ␣ ␣ ´ ); print cardinal (TeX line); print ln(´ ␣ ␣ ␣ ␣ ␣ ´ ); print cardinal (out TeX line); print ln(´ ␣ ␣ ␣ ␣ ␣ ´ );

This code is used in section 24.

10  INDEX  SCANTEX §27

27. Index.

abort if open error : \underline{11}. ascii : 11. banner : \underline{1}, 24. boolean: 13, 18, 20. buf size: \underline{5}, 12, 13, 14, 18. buffer : \underline{12}, 13, 14, 17, 20, 21, 23. cardinal : 18, 20. ch: 11, \underline{13}, \underline{14}. char : 12, 13, 14, 15. char matches : \underline{21}. close: \underline{11}. close file: \underline{11}, 23. dec: 13. doscall : 9, \underline{10}. end file: \underline{11}. end of file: \underline{11}, 13. end of line: \underline{11}, 13. eol : \underline{11}. err print : \underline{6}, 13. error level : \underline{6}, 7. error message: \underline{6}, 25. f: \underline{13}, \underline{14}. failure: \underline{11}. false: 11, 13, 17, 20, 21, 22. fatal error : \underline{9}, 11. fatal message: \underline{6}, 25. file name len: \underline{5}, 15. filename: 11, \underline{15}, 16. : 11. final limit : \underline{13}. get line: 19, \underline{20}. harmless message: \underline{6}, 25. history : 6, \underline{7}, 8, 9, 25. inc: 13, 19, 20, 22, 23. initialize: \underline{3}, 24. : 4. : 13. input char : \underline{11}, 13. input has ended : 17, \underline{18}, 19, 20, 21. input ln: \underline{13}, 20. keep looking : \underline{20}, 22. limit : 13, 14, 17, \underline{18}, 20, 21, 23. line pres : \underline{13}. Logitech: 1, 10. lookup: \underline{11}. mark error : \underline{6}. mark fatal : \underline{6}, 9. mark harmless : \underline{6}. Modula-2: 1, 2, 4. MS-DOS: 1, 9, 10. new line: \underline{4}, 16, 20, 26. next file: \underline{16}. null char : \underline{11}, 13. numeric digit at : \underline{21}, 22. open input file: \underline{11}, 16. open output file: \underline{11}, 16. out TeX file: 2, \underline{12}, 16, 19, 23. out TeX line: 17, \underline{18}, 19, 23, 26. output char : \underline{11}, 14. output enabled : 17, \underline{18}, 19, 20, 21, 22. output ln: \underline{14}, 19, 23. pr card : \underline{4}. pr char : \underline{4}. pr string : \underline{4}. print cardinal : \underline{4}, 26. print char : \underline{4}, 20. print fatal message: \underline{9}, 25. print ln: \underline{4}, 6, 9, 16, 24, 25, 26. print string : \underline{4}, 9, 11, 25. rd string : \underline{4}. read char : \underline{11}. read ln: \underline{11}, 13. read string : \underline{4}, 16. scan TeX : \underline{2}, 24. second char matches : \underline{21}. spotless : \underline{6}, 8, 25. system: 10. system dependencies: \underline{1}, 2, 4, 9, 10, 11, 13. temp: \underline{14}. temp index : \underline{20}, 21, 22. TeX file: 2, \underline{12}, 16, 20, 23. TeX line: 17, \underline{18}, 20, 26. text file: \underline{11}, 12, 13, 14. third char matches : \underline{21}. three chars match: \underline{21}, 22. true: 11, 13, 17, 21, 22. : 11. write char : \underline{11}. write ln: \underline{11}, 14.

§27  SCANTEX  NAMES OF THE SECTIONS 11

⟨ Add ‘ ’ command to end of output and close both files 23 ⟩ Used in section 24. ⟨ Constants in the outer block 5 ⟩ Used in section 2. ⟨ Globals in the outer block 7, 12, 18 ⟩ Used in section 2.

⟨ Import List 4, 10, 11 ⟩ Used in section 2.

⟨ Initialize the file system 16 ⟩ Used in section 3. ⟨ Local variables for initialization 15 ⟩ Used in section 3. ⟨ Print statistics about line counts 26 ⟩ Used in section 24.

⟨ Print the job history 25 ⟩ Used in section 24. ⟨ Read the input 19 ⟩ Used in section 24. ⟨ Scan the line 21 ⟩ Used in section 20.

⟨ Search for ‘ ’; set output enabled if found 22 ⟩ Used in section 21.

⟨ Set initial values 8, 17 ⟩ Used in section 3.

⟨ Terminate program, converting history to program exit status 9 ⟩ Used in section 24. ⟨ Types in the outer block 6 ⟩ Used in section 2.

The SCANTEX processor

(Version 1.0)

Section Page

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 File Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 4 Main Input Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 7 Main Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 9 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 10