Google
 

Trailing-Edge - PDP-10 Archives - BB-5255D-BM - 4-sources/runoff.mac
There are 18 other files named runoff.mac in the archive. Click here to see a list.
;<3-UTILITIES>RUNOFF.MAC.3,  8-Nov-77 10:50:55, EDIT BY KIRSCHEN
;MORE COPYRIGHT UPDATING...
;<3-UTILITIES>RUNOFF.MAC.2, 26-Oct-77 11:19:06, EDIT BY KIRSCHEN
;UPDATE COPYRIGHT FOR RELEASE 3
;<2-UTILITIES>RUNOFF.MAC.3,  8-Apr-77 11:51:42, EDIT BY HURLEY
;<2-UTILITIES>RUNOFF.MAC.2,  8-Apr-77 11:50:11, EDIT BY HURLEY
;MAKE RUNOFF ASSEMBLE WITH RELEASE 2 MACREL AND MACRO 52
;<1B-UTILITIES>RUNOFF.MAC.4, 23-Jun-76 16:39:21, EDIT BY HURLEY
;<1B-UTILITIES>RUNOFF.MAC.3, 23-Jun-76 15:49:47, EDIT BY HURLEY
;<1B-UTILITIES>RUNOFF.MAC.2, 23-Jun-76 15:40:25, EDIT BY HURLEY
	TITLE	RUNOFF - PROGRAM TO FORMAT DOCUMENTATION - %11(247)
	SUBTTL	R CLEMENTS/RCC/CHP/PFC/DAL 16-DEC-75



RNFWHO==0		;DEC DEVELOPMENT
RNFVER==11		;MAJOR VERSION
RNFMIN==0		;MINOR VERSION
RNFEDT==251		;EDIT NUMBER


;+
;.AUTOPARAGRAPH.FLAG INDEX.FLAG CAPITAL.LOWER CASE
;.TITLE ^PROGRAM ^LOGIC ^MANUAL FOR ^^RUNOFF\\
;.FIGURE 10.CENTER;^^RUNOFF\\
;.SKIP 1.CENTER;^PROGRAM ^LOGIC ^MANUAL
;.SKIP 1.CENTER;^VERSION 10
;.SKIP -20.CENTER;<ABSTRACT
;.SKIP 1

;<RUNOFF IS A PROGRAM WHICH FORMATS A FILE OF DOCUMENTATION.
;^THE FILE MUST BE A SPECIAL FORMAT CONSISTING OF FREE FORMAT
;TEXT MIXED WITH SPECIAL CONTROL LINES, WHICH START WITH PERIOD.


;.PAGE;^^
;***COPYRIGHT 1970, 1971, 1972, 1973, 1974, 1975, 1976 DIGITAL EQUIPMENT CORP., MAYNARD,MASS.***
;-\\
;       	TABLE OF CONTENTS FOR RUNOFF
;
;
;                          SECTION                            PAGE
;    1. REVISION HISTORY......................................   6
;    2. DEFINITIONS...........................................   7
;    3. IMPURE STORAGE........................................  12
;    4. INITIALIZATION........................................  13
;    5. INPUT SECTION.........................................  27
;    6. DOT COMMAND SCANNER...................................  33
;    7. DOT COMMANDS..........................................  49
;    8. CHAPTER AND SECTION OPERATIONS........................  67
;    9. VARIABLE AND IF OPERATIONS............................  69
;   10. INDEX OPERATIONS......................................  72
;   11. FOOTNOTE OPERATIONS...................................  78
;   12. OUTPUT SECTION........................................  80
;   13. TYPESET TRANSLATION LOGIC.............................  96
;   14. HANDY-DANDY SUBROUTINES...............................  99
;   15. INPUT CHARACTER PROCESSORS............................ 115
;   16. ERROR MESSAGE HANDLING................................ 121
;+.LEFT MARGIN 5.RIGHT MARGIN 55
;.SKIP 3


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976, 1977, 1978 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;.LEFT MARGIN 0.RIGHT MARGIN 60

;.PAGE.SUBTITLE ^TABLE OF ^CONTENTS
;.CENTER;^TABLE OF ^CONTENTS
;.NOFILL.NOAUTOP.LM10.TAB STOPS 15,18.SKIP 2

;1.	^GENERAL ^INFORMATION
;2.	^DEFAULT ^PARAMETERS
;3.	^REVISION ^HISTORY
;4.	^DEFINITIONS
;		^A^CS
;		^FLAGS
;		^CHARACTERS
;		^MACROS
;5.	^IMPURE ^STORAGE
;6.	^TERMINAL ^COMMAND ^SCANNING
;7.	^TEXT ^INPUT ^LOGIC
;8.	^DOT ^COMMAND ^SCANNER
;9.	^DOT ^COMMAND ^PROCESSORS
;10.	^CHAPTER AND ^SECTION ^OPERATIONS
;11.	^VARIABLE AND ^IF ^OPERATIONS
;12.	^INDEXING
;13.	^FOOTNOTES
;14.	^OUTPUT PROCESSING
;15.	^TYPESET ^OUTPUT ^LOGIC
;16.	^HANDY ^SUBROUTINES
;17.	^INPUT ^CHARACTER ^PROCESSING
;18.	^ERROR ^MESSAGE ^HANDLING

;.FILL.AUTOP.LM0.TS5,8
;.CHAPTER GENERAL INFORMATION
;-
	SYN	IFE,IF

IF TOPS-10,<
	SEARCH	JOBDAT,C,SCNMAC
%%JOBD==%%JOBD
%%C==%%C
%%SCNM==%%SCNM
> ;END TOPS-10
IF TOPS-20,<
	SEARCH	SCNM20,MACTEN,MACSYM,MONSYM
	.JBHRL==115		;SIZE OF HISEG
	.JBFF==121		;FIRST FREE
	.JBVER==137		;WHERE TO PUT VERSION #
> ;END TOPS-20

	.REQUE	SYS:SCAN11
	.REQUE	SYS:WILD11
	.REQUE	SYS:HELPER
%%%SCN==:11
%%%WLD==:11
	SALL

;+
;^ASSEMBLY INSTRUCTIONS:^^
;
;	.LOAD OPSYS+RUNOFF
;	  W\\HERE ^^OPSYS.MAC\\ CONTAINS EITHER:^^
;.B;		^^TOPS==10	;FOR TOPS-10
;.C;-OR-
;		^^TOPS==20	;FOR TOPS-20
;.B 2;
;
;- \\ ^THEN <SSAVE THE PROGRAM AND PLACE IT ON <SYS:.
;THIS MACRO IS USED TO FORCE A PAGE OVERFLOW WITH COMMENT
;TO HAVE LISTINGS MATCH THE PROPOSED CODING STANDARD.
;
;IT IS INVOKED WHENEVER A PAGE OVERFLOW WOULD HAVE HAPPENED.
;
;
;ACCORDING TO THE PROPOSED STANDARD, ALL SOURCE FOR A ROUTINE
;MUST OCCUR ON ONE PAGE. HOWEVER, IT IS IMPORTANT FOR THE
;USER TO FIND "SENTENCE" BREAKS TO FORM THE OVERFLOW (EJECT)
;POINTS. WHENEVER OVERFLOW OCCURS, A COMMENT
;TO THAT EFFECT SHOULD APPEAR IN THE LISTING. ALL THIS IS
;ACCOMPLISHED BY THE USER INCLUDING THE MACRO "CONT." IN HIS
;SOURCE AT THE POINT OF THE OVERFLOW. NO BLANKS SHOULD PRECEED
;OR FOLLOW THE MACRO.

	DEFINE	CONT.<LALL

			   PAGE	;(CONTINUED ON NEXT PAGE)
			   SALL	;(CONTINUED FROM PREVIOUS PAGE)
>
	TWOSEG

	LOC	.JBVER
	VRSN.	RNF
	RELOC


;+
;.CHAPTER DEFAULT PARAMETERS
;
;^THE FOLLOWING PARAMETERS CAN PROBABLY BE REDEFINED:^^
;.TS20.LM20.P-20,0.SK.SELECT D
;D+

ND AD.CAS,CASEUPPER	;INITIAL CASE DEFAULT
ND AD.CON,0	;/CONTROL DEFAULT
ND AD.UND,"_"	;/UNDERLINE CHARACTER DEFAULT
ND ADSUND,"-"	;UNDERLINE CHARACTER IF /UNDERLINE:SEPARATE
ND BARWID,3	;WIDTH OF BAR AREA
ND CHAPTB,^D12	;BLANK BEFORE CHAPTER (IF LENGTH IS 64)
ND CHAPTC,1	;BLANK BEFORE CHAPTER TITLE
ND CHAPTD,3	;BLANK AFTER CHAPTER TITLE
ND HEADLB,3	;BLANK BEFORE .HL
ND HEADLC,1	;BLANK AFTER .HL1-2
ND HEADLT,4	;EXTRA TEST PAGE ON .HL
ND HRMRG,^D72	;INITIAL RIGHT MARGIN FOR .HLP FILES
ND HWPLN,^D66	;HARDWARE PAGE LENGTH
ND ILMRG,0	;INITIAL LEFT MARGIN
ND ILPGNO,1	;INITIAL PAGE NUMBER
ND INDEXD,CHAPTD	;SPACING AFTER INDEX HEADER
ND IPARIN,5	;INITIAL PARAGRAPH INDENT
ND IPARTP,2	;INITIAL PARAGRAPH .TEST PAGE
ND IPARVS,-1	;INITIAL PARAGRAPH VERTICAL SPACING
ND L0LMAR,^D9	;INITIAL LEFT MARGIN ON .LIST
ND LESPAC,2	;HORIZ. SPACE AFTER "." IN LIST ELEMENT NUMBER
ND LFSPAC,1	;LIST FINAL SPACE
ND LSLMAR,^D4	;LEFT MARGIN FOR EMBEDDED .LIST
ND LPTLEN,^D60	;SPOOLED HARDWARE PAGE LENGTH
ND NASPAC,1	;SPACING AFTER "NOTE"
ND NFSPAC,2	;SPACING AFTER NOTE (FINAL SPACE)
ND NHSPAC,2	;SPACING BEFORE NOTE
ND NPMARG,^D15	;NOTES PRIMARY MARGIN CHANGE
ND NSMARG,4	;NOTES SECONDARY MARGIN CHANGE
ND NSPACG,1	;NOTES SPACING
ND PD.TYP,TYPCAT	;/TYPESET DEFAULTS :CAT
ND RHDSPA,2	;RUNNING HEAD (TITLE) SPACING AFTER
ND SINDIN,2	;INDENT FOR SUB-INDEX
ND SPARIN,0	;PARAGRAPH INDENT IF .SD COMMAND
ND TYPSWD,^D36	;WIDTH OF TYPESETTER
				CONT.
;D.SELECT _;
;+
; AD.BAR,"|"	;BAR CHARACTER
; PD.BAR,"\"	;BAR CHARACTER IF /BAR
; AD.DWN,0	;VERTICAL SPACING BEFORE TITLE
; PD.DWN,5	;VERTICAL SPACING BEFORE TITLE IF /DOWN
; AD.HDR,HEADMIXED ;INITIAL HEADER DEFAULT
; PD.HDR,HEADUPPER ;HEADER DEFAULT IF /HEADER
; AD.LPP,58	;LINES PER PAGE
; PD.LPP,64	;LINES PER PAGE IF /LINES
; AD.OVR,0	;HORIZONTAL SPACING BEFORE LEFT BORDER
; PD.OVR,^D20	;HORIZONTAL SPACING BEFORE LEFT BORDER IF /OVER
; AD.SPC,1	;INITIAL SPACING
; PD.SPC,2	;INITIAL SPACING IF /SPACING
; AD.UNL,UNDRLINE	;/UNDERLINE MODE DEFAULT
; PD.UNL,UNDRCHARACTER	;/UNDERLINE MODE DEFAULT IF /UNDERLINE
; AD.WID,^D60	;INITIAL WIDTH
; PD.WID,^D70	;INITIAL WIDTH IF /WIDTH
;-

DM BAR,177,"|","\"	;/BAR:CH
DM DWN,^D60,0,5		;/DOWN:N
DM HDR,,HEADMIXED,HEADUPPER	;/HEADER:X
DM LPP,^D100000,^D58,^D64	;/LINES:N
DM OVR,^D70,0,^D20	;/OVER:N
DM SPC,5,1,2		;/SPACING:N
DM UNL,77,UNDRLINE,UNDRCHARACTER ;/UNDERLINE: TYPE
DM WID,^D100000,^D60,^D70	;/WIDTH:N

;+.LM0.P0,-1
;\\ ^THE FOLLOWING PARAMETERS CAN NOT BE CHANGED WITHOUT
;RISKING FURTHER DEBUGGING:		^^
;.LM20.P-20,0.SK.SELECT D
;D+

IF TOPS-10,<
ND LN$DRB,6	;MAX DIRECTORY DEPTH (UFD+SFDS)
ND LN$ENT,11	;LENGTH OF EXTENDED ENTER BLOCK
ND LN$LKP,7	;LENGTH OF EXTENDED LOOKUP BLOCK
> ;END TOPS-10
IF TOPS-20,<
ND LN$DRB,0	;NO SFD'S ON TOPS-20
ND LN$ENT,^D30	;ENTER STRING
ND LN$LKP,^D30	;LOOKUP STRING
>
ND LN$IDX,^D60	;MAX/5 LENGTH OF NAME IN INDEX
ND LN$LIN,^D100	;MAX/5 LINE LENGTH
ND LN$MJP,5	;LENGTH OF NOTE/LIST PUSH DOWN LIST
ND LN$MJS,4	;LENGTH OF ENTRY ON NOTE/LIST PUSH DOWN LIST
ND LN$PDL,200	;PUSH DOWN LIST LENGTH
ND LN$RNG,^D20	;NUMBER OF /IRANGE/ORANGE PAIRS
ND LN$SEC,6	;MAX DEPTH OF SECTION LOGIC
ND LN$TAB,40	;MAX NUMBER OF TAB STOPS
ND LN$TEC,^D20	;MAX/5 CHARS IN END COMMANDS
ND LN$TTL,^D50	;MAX/5 TITLE LENGTH
ND LN$UND,^D100	;MAX NUMBER UNDERLINES IN A LINE
ND LN$VAR,^D20	;MAX NUMBER OF VARIABLES
ND LN$IFS,^D32	;MAX NUMBER OF NESTED .IF'S   [244]

;D.SELECT _;
;&.FILL;\\
	SUBTTL	REVISION HISTORY

;+
;.CHAPTER REVISION HISTORY
;.SK2
;.LM5.P -5,0.TS 5.UC.AUTOTABLE.NOFLAGS

;#7a -- and previous versions are lost in the dark ages. Work
;     started  on  #10  during  fall, 1971.  Work was resumed
;     after edit 11.
;a.  Change to use twoseg.
;b.  !  and ?  followed by space are treated like .  followed
;     by space.
;c.  All commands may be abbreviated.
;d.  Add new commands:  CENTRE  (=  CENTER),  I  (=INDEX),  P
;     (=PARAGRAPH),  X  (=SUBINDEX), PAGE SIZE (=PAPER SIZE),
;     UPPER CASE (=^^), LOWER CASE (=\\).
;e.  Add SUBINDEX command.  Same as INDEX  except  subindices
;     indicated by >.
;f.  Warn of indents to the left of 0.
;g.  Add  defensive  code  to  footnote  routine  to  recover
;     instead of halt.
;h.  .PAGE clears current line before changing page width and
;     counts as a break.
;i.  Ring bell in PAUSE mode between pages.
;j.  Avoid blank pages.
;k.  Handle multiple lines of INDEX.
;l.  Defend against footnote within a footnote.
;m.  Defend correctly against !  when not in footnote.
;n.  Around footnotes, preserve (and clear)  indentation  and
;     case lock, preserve (and set) JUSTIFY and FILL.
;o.  INDICATE core usage within [].
;p.  TYPE number of pages at end.
;q.  Warn and disregard strange control characters in file.
;r.  Suppress the leading and trailing form  feed  on  output
;     except in PAUSE mode.
;s.  Clear out any final footnotes at EOF.
;t.  "PAGE" in page header is now UPPER/LOWER case.
;(12) Convert  to  use  C,  SCNMAC,  SCAN,  and  WILD.   This
;     includes  full  wild-card  and path usage on both input
;     and output.
;RUNOFF pushed through PGMFMT.
;Default spacing is single, default case is UPPER.
;Default output is LPT:same.<MAGIC>[-]
;Default input is DSK:.RNX[-] (file  is  previous  or  output
;     file). where RNX=RNO+RND+RNP+RNC+<nul> in that order.
;Convert all messages to lower case.  Improve several of them
;     in the process.
;Use LF-VT-FF instead of CR as end of line.
;Detect comments after non-text commands;  junk as error.
				CONT.
;(13) Add /HEADER:X and .HEADER  X  (X=UPPER,LOWER,MIXED)  to
;     control case of "PAGE n" (default is MIXED).
;Detect illegal negative arguments in commands (NUMBER,  LEFT
;     MARGIN,  TEST  PAGE,  SKIP,  BLANK,  TAB STOPS, CENTER,
;     FOOTNOTE).
;Keep Center within PAGE SIZE.
;(10-6912) Fix multiple case indexing correctly.
;Include SUBPAGE in error messages.
;Correct SUBPAGE logic to allow .PAGE inside .SUBPAGE.
;Warn if too many SUBPAGES (gt 26).
;Include SUBPAGES in INDEX.
;(10-6710) Put out sets of pages in INDEX with hyphens.
;Add .LITERAL n and .END LITERAL commands.
;Make !  be comment character, and  ;   be  multiple  command
;     separator (except for TITLE, SUBTITLE, and INDEX).
;Fix error messages to print actual commands
;Include input page and line in error messages.
;Initialize FOOTNOTE case to /CASE:X setting as  modified  by
;     .UPPER CASE and .LOWER CASE.

;14   Implement .SCWLD for full output wildcarding.
;15   Implement > in SUBINDEX.  also ;.
;16   Recognize multiple tab and space in AUTOPARAGRAPH.
;17   Fix bug which kept .X > from printing main entry.
;20   Handle RUNOFF and RUN xxx () commands.
;21   Add .AUTOPARAGRAPH and .NO AUTOPARAGRAPH.
;22   Add /NOAUTOPARAGRAPH/nopause/NOSIMULATE.
;23   Make .<CR> and .<SPACE> be break.  In particular,  note
;     that . ;text is a new line.
;24   Add default extension .RNH to produce .HLP.
;25   Add .NOPAGING, reset by .PAGING.  This  is  default  if
;     .RNH input.
;26   Add .COMMENT.
;27   Add optional  second  argument  to  .PARAGRAPH  to  set
;     vertical paragraph spacing.  -1 sets <SPAC+1>/2
;30   Add /SEQUENCE/NOSEQUENCE to list  input  file  sequence
;     numbers to left of output.
;31   Add .SUBTTL (identical to .SUBTITLE).
;32   Allow sequence .PAGE;.TITLE to work.
;33   Add .FIRSTTITLE to cause PAGE 1 to be titled.
;34   Add .SELECT, .NOSELECT, /SELECT/NOSELECT,  and  default
;     selection on source files.
;35   Correct /PAUSE bug to pause on first page.
;36   Suppress informational typeouts if output to TTY:
;37   Change output device default to DSK:
;40   Add file name to page count message.
;41   Add .NO XXX for .NOXXX.
;42   Treat :  and ;  like !  ?  and .
;43   Add .PERIOD .NOPERIOD  to  defeat  the  .?!:;   special
;     handling.
				CONT.
;44   Change internal EOF code to -1.
;45   Have .CENTER suppress trailing unquoted spaces.
;46   On .CENTER, treat TAB as a space.
;47   If CCL mode, type  "RUNOFF:   "  before  file  in  page
;     count.
;50   Correct core messages to round up.
;51   Convert to the error message standard.
;52   Allow  multiple  spaces  and  tabs  between  words   in
;     commands.
;53   Allow null numbers on .PARAGRAPH, .TAB STOPS.
;54   Fix .CENTER to work correctly at top of page.
;55   In .AUTOPARAGRAPH mode,  a  blank  line  causes  a  new
;     paragraph.
;56   Use the current .SPACING in the INDEX.
;57   Preset .TAB STOPS 9,17,25,...
;60   Allow  relative  specifications  on  .CENTER,  .NUMBER,
;     .LEFT MARGIN, .RIGHT MARGIN, .PAGE SIZE.
;61   Add .LEFT and .RIGHT.
;62   Only consider .:;!?  as  needing  double  space  if  it
;     comes after two consecutive alphabetics.
;63   Treat spaces before last tab on line  as  non-expanding
;     (quoted).
;64   /SEPARATE line for underline;  default /UND to -.
;65   Change  command  entry  point  names  for  consistency.
;     Change names of LH(F) to L.XXXX.
;66   Add defensive code on all buffers with error E$$IBO.
;67   If source file, then default output to .PLM.
;70   Negative argument to BLANK/SKIP is from bottom of page.
;71   Place  underlined  items  before  identically   spelled
;     ununderlined ones.
;72   Add .FLAGS/.NOFLAGS commands.
;73   Default RIGHT MARGIN to 72 if .HLP.
;74   Default INDEX casing is UPPER for first  character  and
;     LOWER for rest.  This is altered by any case controls.
;75   Start FOOTNOTE in case lock of text at definition.
;76   Add .FIGURE DEFER n.
;77   Add _ control character, .CONTROL, /CONTROL.
;100  Add .FLAG CAPITALIZE <.
;101  Add .FLAG INDEX >.
;102  Add .NOHEADER.
;103  Add 1-2 letter abbreviations for each command.
;104  Add .LS, .NOTE, .END, .SD.
;105  Add optional third argument to .P  for  automatic  test
;     page.
;106  Notice <LF><FF> as not a blank line.
;107  Add /DOWN, /OVER.
;110  Don't justify an exactly full line with no spaces.
;111  Detect absence of command.
;112  Fix the bug in routine which causes spaces before  tabs
;     to be quoted.
				CONT.
;113  Add  CHAPTER  and   HEADER   commands   for   automatic
;     sectioning.
;114  Fix bugs in < and . logic within text.
;115  Allow "." (current form) as statement separator  except
;     in comments.
;116  Flag capital and index take up to  the  next  space  or
;     linefeed.
;117  Add SPARIN and set it on .SD command.
;120  Fix .NOTE to agree with DEC standard.
;121  Fix many minor bugs in above edits.
;122  Centralize start of all error messages.
;123  Change to use C, SCNMAC as universal files.
;124  .CH update title, .HL1 update subtitle.
;125  If .RM is greater than page width, expand page width.
;126  Add .NST.
;127  Fix bugs in implicit skip logic  which  caused  missing
;     headings.
;130  Introduce internal mode of defaulting capitalization.
;131  Check indent against right margin.
;132  Add .AUTOTABLE.
;133  Include chapter numbers in page numbering.
;134  Add  .DO  INDEX  and  "INDEX-"  in  paging  of  chapter
;     documents.
;135  Add .LIST ELEMENT.
;136  Make "n" optional in .LITERAL.
;137  Add long names for HL, SD, LS.
;140  Add /VARIANT, .VARIABLE, etc.
;141  Add options to .NUMBER.
;142  Add .APPENDIX.
;143  Add /DRAFT.
;144  Add /IRANGE, /ORANGE.
;145  Add /TYPESET.
;146  Clear indent on page/section/paragraph style commands.
;147  Detect illegal commands inside footnote.
;150  Add .NUMBER LEVEL and .NUMBER LIST.
;151  (10-13004) If ^\, etc., use last;  make ^  followed  by
;     lower case force upper (just one character).
;152  Change  /OVER  to   /RIGHT;    consolidate   /UNDERLINE
;     switches.
;153  Cancel edit 62 as a bad idea.
;154  Add /LINES to set initial page length.
;155  Add .RNE makes .ERR, .RNS makes .STD.
;156  Have angle flags toggle settings.
;157  (QAR 2220) Allow /UNDERLINE:NONE and /UNDER:arg:arg and
;     /NOUNDERLINE.
;160  Clean up /ORANGE.
;161  Decrease NIA errors.  Issue as warnings.
;162  Add /TYPESET:CAT.
;163  Add .TYPESET.
;164  Fix literal tab bug and wild open bug.
				CONT.
;165  (QAR 2632) Allow period in text type commands.
;166  Fix bug which lost line if footnote defined at  end  of
;     page.
;167  (QAR 2453) Ignore autopar, autotab if no fill.
;170  (QAR 2537) Preserve AC B in routine FIN.
;171  (QAR 2473) Don't clear indent on test page.
;172  (QAR 2473) Allow .NUMBER PAGE 0.
;173  (QAR 2480) Add .END LIST.
;174  (QAR 2483) Underline quoted spaces when underlining.
;175  (QAR  2486)  Speed  up  output  by  removing   unneeded
;     carriage returns.
;176  (QAR 2487) Discard extra space on line overflow when no
;     fill.
;177  (QAR 2488) Improve justify with no fill.
;200  (QAR 2489)  Move  indent  reset  to  handle  CJL  error
;     better.
;201  (QAR 2491) More error tests:  .I and .P to left of left
;     edge, have .LM update .P if needed.
;202  (QAR 2493) Clear typein before waiting on /PAUSE.
;203  (QAR 2494) When output to TTY:/PAUSE, suppress echo.
;204  (QAR 2499) Return core after print index.
;205  (QAR 2633) Update lines this page more reliably.
;206  Support routine .OSDFS.
;207  Add extensions .RNB and .RNM;  add more languages.
;210  Handle .END LITERAL if in lower case.
;211  (QAR 2635) Add BAR feature.
;212  Add .END FOOTNOTE.
;213  (QAR 2727) Fix relative .NUMBER.
;214  (QAR 2726) TSTPAG was off by 1.
;215  Remove bug of not double space after  period  at  input
;     eol.
;216  Remove bug in /SEQ if file not sequenced.
;217  Add command .NOSPACE.
;220  Remove bug in /VARIANT table lookup.
;221  Add /NUMBER/PAGING/WIDTH.
;222  (QAR 2784) Don't clear indent on .TP.
;223  (QAR 2785) Remove spurious JEC on .FLAG.
;224  (QAR 2786) Detect .ENDIF after blank line.
;225  Allow subindexes to match shorter form.
;226  (QAR 2845) Allow .PG.NM x to work.
;227  (QAR 2845) Add /CRETURN.
;230  (QAR 2845) Add .END SELECT.
;231  .NT at top of page lost page heading.
;232  Blank lines in .LT lost page heading.
;.B;.C;VERSION 10(232) RELEASED
;.B
;233 CONVERT TO RUN ON TOPS-20
;234	RUNOFF DOES NOT JUSTIFY CORRECTLY WHEN THE TITLE OF A HEADER
;	(.HL3 OR GREATER) IS UNDERLINED. [SPR 10-17960]
;235	NOT ENOUGH SPACE ALLOCATED FOR /IRANGE AND /ORANGE. 3 WORDS
;	ARE STORED BUT ONLY 2 ALLOCATED.
;236	IF A CENTERED LINE CONTAINS SPACES QUOTED WITH UNDERLINE (TO
;	GET THE SPACES UNDERLINED ON THE PRINTOUT), THE LINE IS NOT
;	CENTERED CORRECTLY. [SPR 10-17868]
;237	ALLOW RUNOFF TO HANDLE BACKSPACE IN THE SOURCE TEXT (TO ALLOW
;	OVERSTRIKES). RUNOFF WILL NOW JUSTIFY LINES WITH BACKSPACES
;	ASSUMING THAT THE BACKSPACE TAKES -1 PRINT POSITION. [SPR 10-17551]
;240	PUT HEADER ON CONTINUATION PAGE OF INDEX [SPR 10-16812]
;241	MAKE .DO INDEX WORK EVEN IF DOCUMENT HAS NO CHAPTERS. [SPRS
;	10-16842 AND 10-17089]
;242	HANDLE QUOTED CHARACTERS IN INDEXED ITEMS CORRECTLY. [SPRS
;	10-17188 AND 10-17522]
;243	CHANGE RUNOFF SO THAT TYPING JUST THE WORD "RUNOFF" ON SYSTEMS
;	WITH A RUNOFF COMMAND PRINTS A * INSTEAD OF RNFNFS ERROR.
;244	NESTED .IF CONDITIONALS DO NOT WORK PROPERLY. [SPR 10-16797]
;245	/SELECT SWITCH FAILS [SPR 10-16820]
;246	ILL. MEM. REF. USING .NOHEADER/.HEADER [SPR 10-16454]
;247	CORRECT 244
	SUBTTL	DEFINITIONS

;.FLAGS.LM 0.NOAUTOT.UPPER CASE
;.CHAPTER DEFINITIONS
;.HL1 AC DEFINITIONS
;.NOFILL.TS16;.P0,-1
;-

;AC'S

;&.END SELECT

F=0		;FLAGS
A=1		;WORK
B=2
C=3
D=4
X=5
CH=6
C2=7		;MUST STAY 7
S1=10
S2=11	
N=12
N1=13

PA=15		;POP ARGS

P=17		;STACK

				;&
;+.HL1 FLAGS
;.HL2 FLAGS IN <LH OF F

;.NOFILL.END SELECT

L.PJUS==(1B0)		;.JUSTIFY
L.JUST==(1B1)		;.JUSTIFY BUT NOT .NO FILL
L.TJUS==(1B2)		;JUSTIFY THIS LINE
L.FILL==(1B3)		;.FILL
L.NFSP==(1B4)		;NO FREE SPACE
L.FOOT==(1B5)		;ON IF PROCESSING FROM FOOTNOTE STRING
L.GCIN==(1B6)		;ON IF CHARS IN GCINP TO READ
L.ESOL==(1B7)		;EXTRA SPACES ON LEFT
L.INDX==(1B8)		;INDEX THIS WORD
L.CAPS==(1B9)		;CAPITALIZE THIS WORD
L.ULMS==(1B10)		;ON IF UNDERLINE SHIFT-LOCKED ON
L.UMOD==(1B11)		;ON IF UNDERLINE GETS DONE IN ONE PASS
L.USUP==(1B12)		;ON IF USER HAS SUPPRESSED UNDERLINING
L.UBSP==(1B13)		;ON IF UNDERLINING WITH BACKSPACE (ASCII)
L.ULIN==(1B14)		;ON IF UNDERLINING TAKES A SECOND LINE
L.SUPO==(1B15)		;SUPPRESS OUTPUT BECAUSE OF /RANGE
L.IDXC==(1B16)		;IN INDEX, INDICATES L.IDXD SIGNIFICANT
L.IDXD==(1B17)		;IN INDEX, OLD ENTRY COMES FIRST
			;&
			;+

;.HL2 FLAGS IN <RH OF F

;.NOFILL.END SELECT

R.FSEQ==1B18		;SEQUENCE NUMBER BEING DISCARDED ON INPUT
R.LCWV==1B19		;LAST CHAR INPUT WAS VERT. MOTION
R.SPPR==1B20		;LEADING SPACE IMPLIES PARAGRAPH
R.AUTB==1B21		;.AUTOTABLE MODE
R.PGSQ==1B22		;SEQUENCE OF PAGES DURING INDEX PRINTING
R.CCOM==1B23		;READING A COMMAND (DUPLICATE INTO BUFFER)
R.SEQU==1B24		;/SEQUENCE
R.QNIC==1B25		;QUOTE NEXT INPUT
R.ALCC==1B26		;ALLOW ALL CONTROL CHARS
R.SLCT==1B27		;SELECT MODE
R.SLLK==1B28		;LOOK FOR SELECTION PREFIX
R.SLRG==1B29		;IN +- SELECTION RANGE
R.NPER==1B30		;.NO PERIOD
R.MULN==1B31		;GOING FOR MULTIPLE NUMBERS
R.NNUL==1B32		;LAST NUMBER WAS NOT NULL
;;SPARE	1B33
R.NFLA==1B34		;SUPPRESS ALL FLAG CHARACTERS EXCEPT .!
R.FRCC==1B35		;CASE CONTROLLED BY USER
;&
;+

;.HL2 OTHER FLAGS (NOT IN F)

;.NOFLAGS.NOFILL.END SELECT

LCHPVT==1B18		;PREVENT CHARACTER RECOGNITION (FOLLOWS _)
APPXFL==1B23		;IN CHAPTER NUMBER, APPENDIX
			;&
;+
;.FLAGS.HL1 OTHER DEFINITIONS
;.HL2 MISCELLANEOUS SYMBOLS

;.NOFLAGS.NOFILL.END SELECT

CNVTOK==-12		;CONVERT TO K FROM WORDS
INFIN==377777		;INFINITY
PGWID==^D18		;PAGE WIDTH IN INDEX TABLE
PGMASK==<1_PGWID>-1	;PAGE MASK IN INDEX TABLE
SPWID==5		;SUB-PAGE WIDTH IN INDEX TABLE
SPMASK==<1_SPWID>-1	;SUB-PAGE MASK IN INDEX TABLE
CHWID==^D36-PGWID-SPWID	;CHAPTER WIDTH IN INDEX TABLE
CHMASK==<1_CHWID>-1	;CHAPTER MASK IN INDEX TABLE
IFE APPXFL&CHMASK,<PRINTX ? CHAPTER MASK DOESN'T INCLUDE APPENDIX FLAG>
ULCAS==40		;DIFFERENCE BETWEEN CASES
CCUCAS==100		;DIFFERENCE BETWEEN CONTROL AND UPPER
CHRMSK==177		;ASCII CHARACTER MASK
IFN LCHPVT&CHRMSK,<PRINTX ? CHRMSK INCLUDES LCHPVT>
			;&
;+
;.FLAGS

;.HL2 CHARACTERS FOR <CREF

;.NOFLAGS.NOFILL.END SELECT

C.SIFI==1		;SUBINDEX FLAG IN INTERNAL STRING STORAGE
C.QUTI==2		;INTERNAL QUOTE IN STORAGE
C.ULS==3		;UNDERLINE CHARACTER IN INTERNAL STORAGE
C.TAT==4		;TYPESET END OF MACRO ARG IN INTERNAL STORAGE
C.FLGS==" "-3		;HIGHEST INTERNAL FLAG CHARACTER

C.QTS==" "-2		;QUOTED SPACE (INTERNAL FOR #)
C.NXS==" "-1		;NON-EXPANDABLE SPACE (INTERNAL)

C.GRPH==" "		;LOWEST GRAPHIC
C.SPC==" "
C.EXCL=="!"		;EXCLAMATION (AS PUNCT, NOT FOOTNOTE CUE)
C.EFNT=="!"		;END OF FOOTNOTE
C.COMT=="!"		;COMMENT FLAG
C.QS=="#"		;QUOTED (NONEXPANDABLE) SPACE IN INPUT FILE
C.ULI=="&"		;UNDERLINE COMMAND IN INPUT DATA
C.PLUS=="+"		;PLUS IN NUMBERS
C.CMA==","		;COMMA SEPARATOR IN ARGUMENT LISTS
C.HYPH=="-"		;HYPHEN IN SECTION HEADERS
C.MINS=="-"		;MINUS IN NUMBERS
C.CNT=="."		;CONTROL PREFIX
C.PD=="."		;PERIOD. FOR SPECIAL SPACING AFTER PERIOD
C.COLN==":"		;COLON IN TEXT
C.SEMI==";"		;SEMICOLON
C.SEMC==";"		;SEMICOLON IN TEXT
C.CAP=="<"		;CAPITALIZE NEXT WORD
C.IND==">"		;INDEX NEXT WORD
C.SIF==">"		;SUBINDEX FLAG IN INPUT
C.QM=="?"		;QUESTION MARK
C.DN=="\"		;LOWER CASE INDICATOR
C.UP=="^"		;UPPER CASE INDICATOR
C.QNC=="_"		;QUOTE NEXT CHARACTER
			;&
;+
;.FLAGS

;.HL2 SOFTWARE CHANNELS

;.NOFLAGS.NOFILL.END SELECT

F.FIN==1		;COMMAND FILE INPUT
F.FOUT==2		;COMMAND FILE OUTPUT
			;&
;&.FLAGS.FILL

DEFINE	IFEOF$($LOC),<	JUMPL	CH,$LOC>	;CREF EOF TESTS
;+
;.AUTOP.LOWER CASE

;.HL2 MACROS

; <MSG$ IS FOLLOWED BY THE THREE LETTER ERROR CODE,
;ONE OF THE INDICATORS <ERR, <WRN, OR <INF FOR WHICH CLASS
;OF MESSAGE, AN OPTIONAL ^S TO SAVE ALL ACCUMULATORS,
;AND THE MESSAGE TEXT.  ^IT WILL FORCE OUT ANY <TTY
;BUFFERS, ISSUE THE FILE NAME IF NOT YET DONE,
;THEN ISSUE THE MESSAGE CORRECTLY PREFIXED.
;-

	DEFINE	MSG$(CODE$,LEVEL$,SAVEF$,TEXT$),<XLIST
E$$'CODE$:
IFIDN <SAVEF$><S>,<	SAVE$ <A,B,C,D>	>
	MOVE	A,[''CODE$'',,[ASCIZ \TEXT$\] ]
	LIST
	PUSHJ	P,LEVEL$'MSG
	XLIST
IFIDN <SAVEF$><S>,<	RSTR$ <D,C,B,A>	>
	LIST>

;+
;<ILCM$ IS FOLLOWED BY THE THREE LETTER ERROR CODE,
;AND THEN THE TEXT OF THE MESSAGE.  ^IT ISSUES
;THE MESSAGE WITH  THE STANDARD PREFIX AS A
;FATAL ERROR MESSAGE.  ^IT THEN FOLLOWS THE
;MESSAGE WITH THE CURRENT COMMAND AND THE
;PAGE LOCATION OF THE ERROR.  ^FINALLY, IT JUMPS
;TO END OF COMMAND PROCESSING.
;-

	DEFINE	ILCM$(CODE$,TEXT$),<XLIST
E$$'CODE$:
	MOVE	A,[''CODE$'',,[ASCIZ \TEXT$: "\] ]
	LIST
	JRST	ILCMSG
>
				CONT.
;+
;<SAVE$ _<LIST_> PUSHS THE LIST OF LOCATIONS
;ONTO THE STACK.
;-

	DEFINE	SAVE$	(LIST$),<
	XLIST
IRP (LIST$),<	PUSH	P,LIST$	>
	LIST
>


;+
;<RSTR$ _<LIST_> POPS THE LIST OF LOCATIONS FROM THE STACK.
;-

	DEFINE	RSTR$	(LIST$),<
	XLIST
IRP (LIST$),<	POP	P,LIST$	>
	LIST
>
	SUBTTL	IMPURE STORAGE

;+
;.TS8,16,24.UPPER CASE
;.CHAPTER IMPURE STORAGE
;-.NOFILL.NOFLAGS.END SELECT

;LOCATIONS WHICH ARE SET AT START-UP TIME AND NEVER CLEARED
CCLF1:	BLOCK	1		;1 IF CCL ENTRY, 0 IF NORMAL
INICOR:	BLOCK	1		;SIZE OF CORE BEFORE ANY EXPANSION
INIFF:	BLOCK	1		;INITIAL SETTING OF .JBFF


;SCAN BLOCKS

SCNFWA:!		;START OF SCAN BLOCKS
SCNLOC:	BLOCK	1		;POINTER TO LAST INPUT SCAN BLOCK
SCNPTR:	BLOCK	1		;WILD-CARD SCAN POINTER
SINCOR:	BLOCK	1		;LH=.JBFF, RH=.JBREL AT START OF FILE
SCNFIR:	BLOCK	1		;START OF SCAN PARAMETER AREA
FINI:	BLOCK	1		;INITIAL F SETTING
FINIM:	BLOCK	1		;MASK FOR FINI
SCNNVR:	BLOCK	1		;/VARIABLE COUNT
SCNVAR:	BLOCK	LN$VAR		;/VARIABLE LIST
SCNNIR:	BLOCK	1		;/IRANGE COUNT
SCNIRG:	BLOCK	3*LN$RNG	;/IRANGE FROM:TO PAIRS
SCNNOR:	BLOCK	1		;/ORANGE COUNT
SCNORG:	BLOCK	3*LN$RNG	;/ORANGE FROM:TO PAIRS
				;(0) FROM PAGE,,LINE
				;(1)  TO  PAGE,,LINE
				;(2) START CHAPTER,,END CHAPTER

SCMFWA:!		;START OF SCAN SWITCHES
SCNBAR:	BLOCK	1		;/BAR SWITCH
SCNCAS:	BLOCK	1		;/CASE SWITCH
SCNCRT:	BLOCK	1		;/CRETURN SWITCH
SCNDRF:	BLOCK	1		;/DRAFT SWITCH
SCNDWN: BLOCK	1		;/DOWN SWITCH
SCNHDR:	BLOCK	1		;/HEADER SWITCH
SCNLPP:	BLOCK	1		;/LINES SWITCH
SCNNMB:	BLOCK	1		;/NUMBER SWITCH
SCNOVR: BLOCK	1		;/OVER SWITCH
SCNPAG:	BLOCK	1		;/PAGING SWITCH
SCNPAU:	BLOCK	1		;/PAUSE SWITCH
SCNPER:	BLOCK	1		;/PERIOD SWITCH
SCNSEL:	BLOCK	1		;/SELECT SWITCH VALU
SCNSIM:	BLOCK	1		;/SIMULATE SWITCH
SCNSPG:	BLOCK	1		;/SPACING SWITCH
SCNTYP:	BLOCK	1		;/TYPESET
SCNWID:	BLOCK	1		;/WIDTH SWITCH
ULCHO:	BLOCK	1		;/UNDERLINE CHARACTER
ULTYPE:	BLOCK	1		;TYPE OF UNDERLINE
SCMLWA==.-1		;END OF SCAN SWITCHES
				CONT.
SCNOUT:	BLOCK	.FXLEN		;OUTPUT PARAMETER BLOCK
OPNBLK:	BLOCK	3		;INPUT OPEN BLOCK
SCNLWA==.-1
FILFWA:!		;START OF AREA TO CLEAR BEFORE EACH FILE
RMARG:	BLOCK	1		;RIGHT MARGIN
PRMRG:	BLOCK	1		;RIGHT PAGE-SIZE
LMARG:	BLOCK	1		;LEFT MARGIN
FILCAS:	BLOCK	1		;INITIAL CASE MODE
CAS:	BLOCK	1		;0 OR 40 TO CONVERT TO LOWER CASE
PAGENO:	BLOCK	1		;PAGE NUMBER FOR OUTPUT FILE
FRCPAR:	BLOCK	1		;FLAG TO FORCE PARAGRAPH
PARIND:	BLOCK	1		;INDENTING FOR PARAGRAPHS
PARSPC:	BLOCK	1		;VERT SPAC FOR PARAGRAPHS
PARTPG:	BLOCK	1		;TEST PAGE FOR PARAGRAPHS
LASLS:	BLOCK	1		;DEPTH OF LAST .LIST COMMAND
LSTCNT:	BLOCK	LN$MJP+1	;COUNT AT THAT DEPTH
NSPNG:	BLOCK	1		;SPACING
LINEC:	BLOCK	1
SUBPGE:	BLOCK	1		;0 OR 1+SUBPAGE WE ARE IN
FILHDR:	BLOCK	1		;.HEADER CASE
FILOVR: BLOCK	1		;SPACES IN FROM /OVER
FILOVT: BLOCK	1		;TABS IN FROM /OVER
FLNUMB:	BLOCK	1		;.NONUMBERING
FLTITL:	BLOCK	1		;TITLE ON NEXT PAGE
FLNOPG:	BLOCK	1		;.NOPAGING
FLNHDR:	BLOCK	1		;.NOHEADER
FLSOPG:	BLOCK	1		;FLAG SOMETHING ON PAGE

FILNVR:	BLOCK	1		;NUMBER OF VARIABLES
FILVAR:	BLOCK	LN$VAR		;VARIABLE NAMES
FILVVR:	BLOCK	LN$VAR		;VARIABLE VALUES (-LN$VAR=FALSE)
FILFVR:	BLOCK	LN$VAR		;VARIABLE DRAFT FLAGS (IF,,IFN)
IFSTKP:	BLOCK	1		;[244] STACK POINTER FOR IF STACK
IFSTK:	BLOCK	3*LN$IFS	;[244] IF STACK
VRSKIP:	BLOCK	1		;CURRENT VARIABLE INDEX
FLSKIP:	BLOCK	1		;ASCIZ LISTING FLAGS (/DRAFT)
IFSKIP:	BLOCK	1		;-1 TO SKIP INPUT

MJSPDL:	BLOCK	1		;PD POINTER TO MJSPDB
MJSPDB:	BLOCK	LN$MJP*LN$MJS	;PD STORAGE FOR NOTE/LS
SECNUM:	BLOCK	LN$SEC		;SECTION NUMBERS (FIRST IS CHAPTER)
LASHL:	BLOCK	1		;LEVEL OF LAST .HL OR .CH
CENPOS:	BLOCK	1		;SAVED VALUE FOR CENTERING
CENTTL:	BLOCK	1		;-1 OR COUNT DOWN OF TITLE IN CENTER
SMINSC:	BLOCK	1		;FLAG SOMETHING IN THIS SECTION


TABTAB:	BLOCK	LN$TAB		;TAB SETTINGS
NTABS:	BLOCK	1

NLPG:	BLOCK	1		;PAGE LENGTH
PNLPG:	BLOCK	1		;PAGE SIZE
				CONT.
; GLOBAL VARIABLES

PLIST:	BLOCK	LN$PDL+1

INIFBF:	BLOCK	1		;FIRST VALUE LOADED INTO FOOTBF
FOOTBF:	BLOCK	1		;ADDRESS OF FOOTNOTE BUFFER (SET AT INITIALIZATION)
FOOTC:	BLOCK	1		;FOOTNOTE COUNT
FOOTP1:	BLOCK	1
FOOTP2:	BLOCK	1
FOOTP3:	BLOCK	1
FOOTP4:	BLOCK	1

FOOTWB:	BLOCK	LN$LIN		;LINE HOLDING BUFFER AROUND FOOTNOTE OUTPUTTER
FOOTS1:	BLOCK	1		;POINTERS TO FOOTWB
FOOTS2:	BLOCK	1		; ..

ICBUF:	BLOCK	LN$IDX		;STORAGE FOR INDEXED ITEM
ICBFE=.-1
ICBUFC:	BLOCK	1		;UP COUNTER ON ICBUF
ICBUFP:	BLOCK	1		;BYTE POINTER TO ICBUF
SUBIDX:	BLOCK	1		;DISTINGUISHES SUBINDEX COMMAND
XFIRST:	BLOCK	1		;ADDRESS OF ALPHABETICALLY FIRST ITEM
XTOP:	BLOCK	1		;TOP OF INDEX STORAGE
XBOT:	BLOCK	1		;BOTTOM OF INDEX STORAGE
OIXC:	BLOCK	1		;CURRENT ITEM IN OUTPUT INDEX
OIXL:	BLOCK	1		;INITIAL LETTER IN OUTPUT INDEX
AUTIDX:	BLOCK	1		;-1 IF > INDEXING

PAGECT:	BLOCK	1		;COUNT OF REAL PAGES OUTPUT
LINECT:	BLOCK	1		;COUNT OF LINES ON CURRENT PAGE OUTPUT
DIDSOM:	BLOCK	1		;NON-ZERO IF LINE OUT SINCE LAST PAUSE
INDCT:	BLOCK	1		;INDENTATION
NIACNT:	BLOCK	1		;COUNT OF NIA WARNINGS SINCE LM
DEFFIG:	BLOCK	1		;DEFERRED FIGURE SIZE
LITCNT:	BLOCK	1		;LITERAL LINE COUNTER

BARSW:	BLOCK	1		;BAR ENABLED
BARON:	BLOCK	1		;BAR ON
BARNPY:	BLOCK	1		;BAR WAS ON AT START OF LINE
				CONT.

LKPBLK:	BLOCK	LN$LKP		;LOOKUP BLOCK FOR INPUT FILE
INEXT:	BLOCK	1		;INPUT EXTENSION
OPNOUT:	BLOCK	3		;OPEN BLOCK FOR OUTPUT
ENTBLK:	BLOCK	LN$ENT		;ENTER BLOCK FOR OUTPUT FILE
DEFEXT:	BLOCK	1		;DEFAULT EXTENSION FOR OUTPUT
H.FOUT:	BLOCK	3		;BUFFER HEADER FOR OUTPUT

; GENERAL


TT1:	BLOCK	1
TT2:	BLOCK	1
TT5:	BLOCK	1
TT6:	BLOCK	1
LCH:	BLOCK	1
PSTRP:	BLOCK	2

INSEQP:	BLOCK	1		;POINTER TO INPUT SEQUENCE NUMBER
INSEQN:	BLOCK	1		;CURRENT INPUT SEQUENCE NUMBER
INSEQL:	BLOCK	1		;INPUT SEQUENCE NUMBER OF LAST LINE
INLINE:	BLOCK	1		;INPUT LINE COUNT THIS PAGE
INPAGE:	BLOCK	1		;INPUT PAGE COUNT
THISEQ:	BLOCK	1		;SEQUENCE AT START OF THIS OUTPUT LINE
THISLN:	BLOCK	1		;LINE COUNT AT START OF OUTPUT LINE
THISPG:	BLOCK	1		;PAGE COUNT AT START OF OUTPUT LINE

INEOFP:	BLOCK	1		;INPUT END OF FILE STRING POINTER

SELPFX:	BLOCK	1		;SELECT PREFIX      ;;KEEP
SELSNG:	BLOCK	1		;SELECT SINGLE LINE ;; IN
SELSTR:	BLOCK	1		;SELECT START RANGE ;;THIS
SELSTP:	BLOCK	1		;SELECT STOP RANGE  ;;ORDER
ESLCTF:	BLOCK	1		;-1 IF AFTER .END SELECT
SLINBF:	BLOCK	50		;.END SELECT BUFFER
SLINBL==.-SLINBF
SLIN:	BLOCK	4		;POINTERS TO SLINBF

TTISOT:	BLOCK	1		;-1 IF OUTPUT TO TTY:
ISDFLN:	BLOCK	1		;-1 IF ISSUED FILE NAME

AFTRNC:	BLOCK	1		;IF NON-ZERO, ADDRESS OF STRING TO
				; OUTPUT AFTER NEXT CHARACTER
TYPMUL:	BLOCK	1		;SPACING MULTIPLIER IF TYPESETTING
TYPDIV:	BLOCK	1		;SPACING DIVISOR IF TYPESETTING
FLTYPC:	BLOCK	1		;FLAG THAT IN .TYPESET COMMAND
FLTYPR:	BLOCK	1		;0=NO FACE CHANGE,
				;  -1=FACE CHANGE, +1=TEXT AFTER FACE CHANGE
FLTYPS:	BLOCK	1		;-1=SUPPRESS NEXT STARTING SPACE
FOUTCH:	BLOCK	1		;ADDRESS OF ROUTINE TO OUTPUT CHAR
				CONT.
IF TOPS-20,<

;TOPS-20 STORAGE
DFIEXT:	BLOCK	1		;DEFAULT INPUT EXTENSION
PMAPZ:!				;CLEARED FOR EACH OUTPUT FILE
PMAPF:	BLOCK	1		;NUMBER OF PAGES PMAP'ED
BYTECT:	BLOCK	1		;OUTPUT FILE BYTE COUNT
PMAPPG:	BLOCK	1		;PROCESS PAGE FOR START OF WINDOW
BYTEPT:	BLOCK	1		;BYTE POINTER TO WINDOW
WINCNT:	BLOCK	1		;ROOM LEFT IN WINDOW
FILEPG:	BLOCK	1		;FILE PAGE NUMBER TO START NEXT WINDOW
PMAPEZ==.-1			;LAST WORD CLEARED
> ;TOPS-20
				CONT.
; LINE TEMPS


LNINCT:	BLOCK	1		;COUNT OF CHARACTERS IN LINBF
LINBK:	BLOCK	1
SPCNT:	BLOCK	1		;COUNT OF SPACES IN LINBF
LSTSP:	BLOCK	1		;CHARACTER ADDRESS OF LAST SPACE IN LINBF
LINNSC:	BLOCK	1		;COUNT OF NON-SPACING CHARS IN LINBF

LNIN1:	BLOCK	1		;INPUT POINTERS TO LINBF
LNIN2:	BLOCK	1		; ..
LOUT1:	BLOCK	1		;OUTPUT POINTERS TO LINBF
LOUT2:	BLOCK	1		; ..

LINBF:	BLOCK	LN$LIN		;LINE BUFFER

GCINP:	BLOCK	1		;RE-EAT POINTERS
GCIN2:	BLOCK	1		; ..
GCSCH:	BLOCK	1		;SAVED CHARACTER (-1=NONE)
LINDCX:	BLOCK	1		;ADDRESS OF ROUTINE IN LINDCW

CMSTP:	BLOCK	1
CMST2:	BLOCK	1

CMBF:	BLOCK	10
ECMBF=.-1
CMEBFP:	BLOCK	4		;READ/WRITE/FIRST/LAST+1 CHAR POINT TO CMEBF
CMEBF:	BLOCK	6		;LAST COMMAND
CMEBFL==.-CMEBF

RINCHR:	BLOCK	1		;ROUTINE TO READ CHAR
ADRECM:	BLOCK	1		;END ADDRESS MATCH
TECBFP:	BLOCK	4		;READ/WRITE/FIRST/LAST+4 CHAR PNTR TO TECBF
TECBF:	BLOCK	LN$TEC		;END COMMAND TEMP STRING BUFFER

TTLP1:	BLOCK	1		;TITLES
TTLP2:	BLOCK	1
TTLBUF:	BLOCK	LN$TTL
STTLP1:	BLOCK	1		;SUB TITLES
STTLP2:	BLOCK	1
STTLBF:	BLOCK	LN$TTL
DOSTTL:	BLOCK	1		;INCLUDE SUBTITLE
				CONT.
EXSP1:	BLOCK	1
EXSP2:	BLOCK	1
ULMCH:	BLOCK	1

NSPCH:	BLOCK	1
LSTNSP:	BLOCK	1
ULPOS:	BLOCK	1
CPOS:	BLOCK	1
ULPT1:	BLOCK	1
ULPBF:	BLOCK	LN$UND		;COLUMNS TO BE UNDERLINED

CCTABL:!		;PARRALLELS FLASTD
CC.CAP:	BLOCK	1		;.FLAG CAPITALIZE	<
CC.CON:	BLOCK	1		;.FLAG CONTROL		.
CC.END:	BLOCK	1		;.FLAG ENDFOOTNOTE	!
CC.IND:	BLOCK	1		;.FLAG INDEX		>
CC.LOW:	BLOCK	1		;.FLAG LOWERCASE	\
CC.QUO:	BLOCK	1		;.FLAG QUOTE		_
CC.SPA:	BLOCK	1		;.FLAG SPACE		#
CC.SUB:	BLOCK	1		;.FLAG SUBINDEX		>
CC.UND:	BLOCK	1		;.FLAG UNDERLINE	&
CC.UPP:	BLOCK	1		;.FLAG UPPERCASE	^
CCTEND==.-1


FILLWA==.-1		;END OF STORAGE CLEARED EACH FILE
			;&

	RELOC	400000		;END OF VARIABLES
	SUBTTL	INITIALIZATION

;+
;.AUTOPA.FLAGS.TS8,16,24,32,,,,,,,,.LM0.P0,-1.FILL.LOWER CASE
;.CHAPTER TERMINAL COMMAND SCANNING
;-

RUNOFF:	TDZA	A,A		;NON-CCL ENTRY
	MOVEI	A,1		;CCL ENTRY
	MOVEM	A,CCLF1		;STORE FOR LATER
	RESET			;CLEAR ALL I/O
IF TOPS-10,<
	HRRZ	A,.JBREL	;GET FIRST-TIME CORE SIZE
	MOVEM	A,INICOR
> ;END TOPS-10
	HRRZ	A,.JBFF		;GET INITIAL .JBFF
	MOVEM	A,INIFF		;SAVE FOR LATER
	STORE	17,0,16,0	;CLEAR ALL ACS
	MOVE	P,[IOWD LN$PDL,PLIST]	;STACK
	MOVE	A,[2,,[ IOWD 1,['RUNOFF']
			CCLF1,,'RNO']]
CISCAN:	PUSHJ	P,.ISCAN##	;INITIALIZE COMMAND SCANNER  [243]
				CONT.
;BACK HERE AFTER EACH COMMAND IS COMPLETE
RUNOF0:	MOVE	A,[11,,[IOWD SWTL,SWTN
			SWTD,,SWTM
			0,,SWTP
			-1
			SCNCLA,,0
			SCNAIN,,SCNAOT
			0
			0
			0,,SCNSWT]]
	PUSHJ	P,.TSCAN##	;SCAN THE LINE
	SKIPN	A,SCNLOC	;IS THERE A FILE? [243]
	JRST	CISCAN		;RESTART RUNOFF (NOTE C(A)=0) [243]
	MOVE	A,[3,,[IOWD SWTL,SWTN
			SWTD,,SWTM
			0,,SWTP]]
	PUSHJ	P,.OSCAN##	;GET OPTIONS IF ANY
	JRST	RUNOFS		;GO PROCESS IT

;ROUTINE TO CLEAR SCAN RESULTS
SCNCLA:	STORE	A,SCNFWA,SCNLWA,0	;CLEAR AREA
	STORE	A,SCMFWA,SCMLWA,-1	;AND SWITCHES
	MOVE	A,INIFF		;RESTORE .JBFF
	MOVEM	A,.JBFF		; ..
IF TOPS-10,<
	MOVE	A,INICOR	;RESTORE .JBREL
	CAME	A,.JBREL	; ..
	CORE	A,		; ..
	  JFCL			; (NICE TRY)
> ;END TOPS-10
	POPJ	P,		;RETURN
;ROUTINE TO STORE MULTI-VALUED SWITCHES

SCNSWT:	TLZ	B,-1		;CLEAR POINTER TO LEAVE INDEX
	JUMPG	B,SCNRNG	;IF NOT /VARIANT, JUMP

;HERE WHEN SWITCH IS /VARIANT

	AOS	A,SCNNVR	;INCREMENT COUNT
	CAIN	A,LN$VAR+1	;SEE IF TOO MANY
E$$TMV:	JRST	[MOVEI A,'TMV'	;YES--GIVE UP
		 PJSP  B,SCNERR
		 ASCIZ \Too many /VARIANTS\]
E$$VVZ:	JUMPE	C2,[MOVEI A,'VVZ'
		    PJSP  B,SCNERR
		    ASCIZ \/VARIANT value zero\]
	MOVEM	C2,SCNVAR-1(A)	;NO--STORE AWAY
	POPJ	P,		;RETURN, INDICATING DONE

;HERE IF /IRANGE OR /ORANGE

SCNRNG:	CAILE	B,2		;SEE IF NOT /IR OR /OR
	JRST	SCNUND		;RIGHT--GO TRY SOMETHING ELSE
	MOVEI	D,SCNNIR	;POINT TO /IRANGE
	CAIN	B,2		;SEE IF /ORANGE
	MOVEI	D,SCNNOR	;YES--POINT TO IT
	AOS	A,(D)		;INCREMENT COUNT
	CAIN	A,LN$RNG+1	;SEE IF OVERFLOW YET
E$$TMR:	JRST	[MOVEI A,'TMR'	;YES--GIVE UP
		 PJSP  B,SCNERR
		 ASCIZ \Too many RANGES\]
	IMULI	A,3		;MULTIPLY COUNT BY 3
	ADDI	D,-2(A)		;POINT TO START OF TRIPLET
	MOVE	A,.NMUL##	;GET FROM
	MOVEM	A,(D)		;STORE
	MOVE	A,.NMUL+1	;GET TO
	MOVEM	A,1(D)		;STORE
	MOVE	A,.NMUL+2	;GET CHAPTERS
	MOVEM	A,2(D)		;STORE
	POPJ	P,		;RETURN
;HERE IF /UNDERLINE

SCNUND:	HLRE	A,C2		;GET UNDERLINE CHARACTER
	JUMPL	A,SCNUN1	;NOT SPECIFIED--PROCEED
	SKIPLE	ULCHO		;SEE IF PREVIOUSLY SET
	CAMN	A,ULCHO		;YES--SEE IF SAME
	SKIPA			;OK
	JRST	E.DSI##		;NO--ERROR
	MOVEM	A,ULCHO		;OK--STORE
SCNUN1:	HRRE	A,C2		;GET UNDERLINE TYPE
	JUMPL	A,SCNUN2	;NOT SPECIFIED--ALL DONE
	SKIPL	ULTYPE		;SEE IF PREVIOUSLY SET
	CAMN	A,ULTYPE	;YES--SEE IF SAME
	SKIPA			;OK
	JRST	E.DSI##		;NO--ERROR
	MOVEM	A,ULTYPE	;OK--STORE TYPE

;HERE WHEN DONE WITH ARG, IF COLON, DO AGAIN

SCNUN2:	CAIE	S1,":"		;SEE IF COLON
	POPJ	P,		;RETURN
	PUSHJ	P,SWUNDR	;YES--GET ANOTHER ARG
	JRST	SCNUND		;AND GO STORE IT
;ROUTINE TO SCAN THE /UNDERLINE SWITCH
;VALUES ARE:
;	/UNDERLINE:"CHARACTER"
;	/UNDERLINE:OCTAL		BOTH SET UNDERLINE CHARACTER
;
;	/UNDERLINE:KEYWORD	SETS TYPE OF UNDERLINING

SWUNDR:	PUSHJ	P,TCHOO	;GET CHARACTER OR OCTAL VALUE
	  JRST	[JUMPE C2,SWUND4 ;IF 0, INDICATE /UNDER:0
		 HRLO  C2,C2	;RETURN THE
		 POPJ  P,]	; ANSWER NUMBER

	PUSHJ	P,.SIXSC##	;MUST BE KEYWORD
	MOVE	A,[IOWD UNDR.L,UNDR.T]
	PUSHJ	P,.NAME##	;LOOK IN TABLE OF KEYS
	  JRST	SWUND3		;NOT FOUND--GO SEE WHY
	SUBI	A,UNDR.T-1	;FOUND--REMOVE OFFSET
	TLZ	A,-1		;CLEAR JUNK
	CAIN	A,UNDRNONE	;SEE IF NONE
	JRST	SWUND4		;YES--INDICATE THAT
	HRROI	C2,(A)		;SET IN ANSWER
	POPJ	P,		; AND RETURN

SWUND3:	CAME	C2,['0     ']	;SEE IF :0
	JUMPN	C2,E.UKK##	;IF NOT AND NOT BLANK, ERROR
SWUND4:	HRROI	C2,0		;IF SO, RETURN 0
	POPJ	P,		;RETURN

;SWITCH HANDLER FOR OCTAL OR QUOTED CHARACTER

SWCHOO:	PUSHJ	P,TCHOO		;GET IT
	  POPJ	P,		;SOMETHING
	MOVEI	C2,0		;IGNORE
	POPJ	P,		; NULL

;ROUTINE TO GET OCTAL OR QUOTED CHARACTER

TCHOO:	PUSHJ	P,.TIAUC##	;GET FIRST CHARACTER
	CAIE	S1,""""		;SEE IF QUOTED CHARACTER
	JRST	SWCHO1		;NO--TRY SOMETHING ELSE
	PUSHJ	P,.TISQT##	;YES--SET QUOTE
	SKIPN	.QUOTE##	;SEE IF STILL QUOTED
	JRST	E.SVR##		;NO--INDICATE SWITCH VALUE REQUIRED
	MOVE	C2,S1		;RETURN THE ANSWER CHARACTER
	MOVEI	A,.TFCHR##	;INDICATE SINGLE
	MOVEM	A,.LASWD##	; CHARACTER FORMAT
	PJRST	.TIAUC##	;GET SEPARATOR AND RETURN

SWCHO1:	CAIL	S1,"0"		;SEE IF
	CAILE	S1,"7"		; OCTAL
	JRST	CPOPJ1		;NOT FOUND
	PUSHJ	P,.OCTNC##	;YES--GET OCTAL NUMBER
	CAILE	C2,177		;SEE IF VALID CHARACTER
	JRST	E.SVTL##	;NO--INDICATE ERROR
	POPJ	P,		;RETURN VALUE
;ROUTINE TO SCAN A RANGE VALUE
;FORM IS A/B-C:D/E-F WHERE A,C,D,F ARE DECIMAL NUMBERS OR ^ OR *
; A/B-C IS FROM, D/E-F IS TO ON THE RANGE
; A,D ARE LINE NUMBERS, C,F ARE PAGE NUMBERS
; B,E ARE CHAPTER NUMBERS OR APPENDIX LETTERS OR "INDEX"
;IF B,E ARE OMITTED, SO CAN FOLLOWING -
;IF D/E-F ARE ABSENT, COLON CAN BE OMITTED AND THEY ARE END OF FILE
;IF A/B-C ARE ABSENT, MEANS FROM START OF FILE
;IF F IS MISSING, SAME AS C
;IF C IS MISSING, SAME AS 1
;IF A IS MISSING, SAME AS 1
;IF D IS MISSING, SAME AS END OF PAGE (777777 INTERNALLY)
;^ IS SAME AS 1 (I.E., BEGINNING)
;* IS SAME AS 777777 (I.E., END)

SWRNGE:	SAVE$	<X,CH>		;SAVE P1, P2
	PUSHJ	P,.TIAUC##	;GET NEXT CHARACTER
	PUSHJ	P,.TICQT##	;SET QUOTE IF APPROPRIATE
	SETZB	X,CH		;CLEAR FROM AND TO
	PUSHJ	P,DECPGC	;GET A
	HRLZ	X,C2		;SAVE AWAY
	MOVEI	C2,0		;CLEAR ACCUMULATOR
	CAIN	S1,"/"		;SEE IF PAGE NEXT
	SKIPN	.QUOTE##	;YES--LEGAL ONLY IF QUOTED
	SKIPA			;NO--SKIP
	PUSHJ	P,DECHAP	;YES--GET IT
	HRR	X,C2		;SAVE AWAY
	HLLOM	C2,.NMUL+2	;SET START CHAPTER (END CH=INF)
	CAIE	S1,":"		;SEE IF TO SPECIFIED
	JRST	SWRNG1		;NO--SKIP OVER
	PUSHJ	P,DECPAG	;YES--GET D
	HRLZ	CH,C2		;SAVE AWAY
	MOVEI	C2,0		;CLEAR ACCUMULATOR
	CAIN	S1,"/"		;SEE IF PAGE NEXT
	SKIPN	.QUOTE##	;YES--LEGAL ONLY IF QUOTED
	SKIPA			;NO--SKIP
	PUSHJ	P,DECHAP	;YES--GET IT
	HRR	CH,C2		;SAVE AWAY
	TLNE	C2,-1		;SEE IF CHAPTER SET
	HLRM	C2,.NMUL+2	;YES--SAVE AWAY
SWRNG1:	SKIPN	CH		;SEE IF TO SPECIFIED
	SETOM	CH		;NO--DEFAULT TO MAX
				;A DEFAULTS TO 0
	TRNN	X,-1		;SEE IF C
	HRRI	X,1		;NO--DEFAULT TO /1
	TLNN	CH,-1		;SEE IF D
	TLO	CH,-1		;NO--DEFAULT TO END OF PAGE
	TRNN	CH,-1		;SEE IF F
	HRR	CH,X		;NO--DEFAULT TO C
	MOVEM	X,.NMUL##	;STORE FROM
	MOVEM	CH,.NMUL+1	;STORE TO
	RSTR$	<CH,X>		;RESTORE P2, P1
	POPJ	P,		;AND FINISH PROCESSING
;ROUTINE TO GET CHAPTER AND PAGE NUMBER
;RETURNS CHAPTER,,PAGE IN C2

DECHAP:	PUSHJ	P,.TIAUC##	;GET FIRST CHARACTER
	CAIL	S1,"A"		;SEE IF ALPHA
	CAILE	S1,"Z"		; ..
	JRST	DECHP3		;NO--HANDLE NUMERIC
	MOVEI	C2,0		;YES--APPENDIX
DECHP1:	CAIL	S1,"A"		;SEE IF STILL ALPHA
	CAILE	S1,"Z"		; ..
	JRST	DECHP2		;NO--EXIT LOOP
	IMULI	C2,^D26		;YES--ADVANCE RADIX
	ADDI	C2,1-"A"(S1)	;INCLUDE THIS DIGIT--OFFSET BY 1
	PUSHJ	P,.TIAUC##	;GET NEXT CHARACTER
	JRST	DECHP1		;LOOP
DECHP2:	CAME	C2,[^D4361706]	;"INDEX"
	TROA	C2,APPXFL	;APPENDIX--SET FLAG
	SETOM	C2		;INDEX--SET CODE
	JRST	DECHP4		;GO FINISH UP

DECHP3:	PUSHJ	P,DECPGC	;GET DECIMAL CHAPTER
	CAIE	S1,"-"		;SEE IF WAS CHAPTER
	JRST	DECHP5		;NO--IS PAGE
DECHP4:	PUSH	P,C2		;SAVE CHAPTER
	MOVEI	C2,0		;CLEAR PAGE
	CAIN	S1,"-"		;SEE IF PAGE COMING
	PUSHJ	P,DECPAG	;YES--GET IT
	POP	P,A		;RESTORE CHAPTER
	HRL	C2,A		;ENTER IN RESULT
DECHP5:	POPJ	P,		;RETURN VALUE

;ROUTINE TO GET POSITION
; DECIMAL OR ^ FOR 1 OR * FOR END (777777)
;RETURNS VALUE IN C2

DECPAG:	PUSHJ	P,.TIAUC##	;GET FIRST CHARACTER
DECPGC:	CAIN	S1,"*"		;SEE IF END
	JRST	DECPG1		;YES--GO HANDLE
	CAIE	S1,"^"		;SEE IF START
	PJRST	.DECNC##	;NO--HANDLE DECIMAL
	SKIPA	C2,[1]		;YES--SET "1"
DECPG1:	MOVEI	C2,-1		;END--SET "777777"
	PJRST	.TIAUC##	;GET BREAK AND RETURN
;ROUTINE TO ALLOCATE OUTPUT SPEC AREA
SCNAOT:	MOVEI	A,SCNOUT	;POINT TO AREA
	MOVEI	B,.FXLEN	;AND LENGTH
	POPJ	P,		;RETURN

;ROUTINE TO ALLOCATE INPUT SPEC AREA
SCNAIN:	MOVE	B,.JBFF		;GET START OF FREE CORE
	SUBI	B,.FXLEN	;OFFSET FOLLOWING ADDI
	SKIPN	A,SCNLOC	;SEE IF ALREADY SOME
	MOVE	A,B		;NO--POINT TO START OF FREE CORE
	ADDI	A,.FXLEN	;POINT TO START OF AREA
	MOVEM	A,SCNLOC	;UPDATE MEMORY
	MOVEI	B,.FXLEN(A)	;DETERMINE NEW START OF FREE SPACE
	MOVEM	B,.JBFF		;SAVE FOR OTHERS
IF TOPS-10,<
	CAMG	B,.JBREL	;SEE IF IT FITS IN CORE
	JRST	SCNAIG		;YES--PROCEED
	MOVEI	C,(B)		;NO--GET MORE
	CORE	C,		;FROM MONITOR
> ;END TOPS-10
IF TOPS-20,<
	CAIL	B,RUNOFF	;LOWSEG UP TO HISEG
> ;TOPS-20
	  JRST	E$$TMI		;WELL--NICE TRY
SCNAIG:	HRLZ	C,A		;CLEAR AREA
	HRRI	C,1(A)		; ..
	SETZM	(A)		; ..
	BLT	C,(B)		; ..
	MOVEI	B,.FXLEN	;INDICATE LENGTH
	POPJ	P,		;RETURN

E$$TMI:	MOVEI	A,'TMI'		;NOT ENOUGH CORE
	MOVEI	B,[ASCIZ \Insufficient core for command\]

;HERE ON ALL SCANNING ERRORS
SCNERR:	HRLI	A,'RNF'		;INCLUDE RUNOFF PREFIX
	HRLI	B,"?"		;INDICATE FATAL ERROR
	PUSHJ	P,.ERMSG##	;ISSUE ERROR MESSAGE
	PJRST	.FMSGE##	;GO RESTART COMMAND

;HERE TO PROCESS /SELECT

SCNASQ:	PUSHJ	P,.SWASQ##	;[245]READ SWITCH
	MOVE	C2,.NMUL##	;[245]PUT ANSWER IN N
	POPJ	P,0		;[245]RETURN TO SCAN
	;SWITCH CONTROL TABLES

	DEFINE	SWTCHS,<
SN AUTOPARAGRAPH,<POINTR (FINI,R.SPPR)>,FS.NUE!FS.NFS
SP BAR,SCNBAR,SWCHOO,BAR,FS.NUE!FS.NFS
SL CASE,SCNCAS,CASE,CASELOWER,FS.NUE!FS.NFS
SN CONTROL,<POINTR (FINI,R.ALCC)>,FS.NUE!FS.NFS
SN CRETURN,SCNCRT,FS.NUE!FS.NFS
SP DOWN,SCNDWN,.SWDEC##,DWN,FS.NUE!FS.NFS
SN DRAFT,SCNDRF,FS.NUE!FS.NFS
SL HEADER,SCNHDR,HEAD,HEADUPPER,FS.NUE!FS.NFS
SP IRANGE,1,SWRNGE,VAR,FS.LRG!FS.VRQ!FS.NFS
SP LINES,SCNLPP,.SWDEC##,LPP,FS.NUE!FS.NFS
SS NOBAR,SCNBAR,0,FS.NUE!FS.NFS
SS NOSELECT,SCNSEL,1,FS.NUE!FS.NFS
SS NOUNDERLINE,ULTYPE,UNDRNONE,FS.NUE!FS.NFS
SN NUMBERING,SCNNMB,FS.NUE!FS.NFS
SP ORANGE,2,SWRNGE,VAR,FS.LRG!FS.VRQ!FS.NFS
SN PAGING,SCNPAG,FS.NUE!FS.NFS
SN PAUSE,SCNPAU,FS.NUE!FS.NFS
SN PERIOD,SCNPER,FS.NUE!FS.NFS
SP RIGHT,SCNOVR,.SWDEC##,OVR,FS.NUE!FS.NFS
SP SELECT,SCNSEL,SCNASQ,,FS.NUE!FS.NFS,	;[245]
SN SEQUENCE,<POINTR (FINI,R.SEQU)>,FS.NUE!FS.NFS
SN SIMULATE,SCNSIM,FS.NUE!FS.NFS
SP SPACING,SCNSPG,.SWDEC##,SPC,FS.NUE!FS.NFS
SL TYPESET,SCNTYP,TYP,PD.TYP,FS.NUE!FS.NFS
SP UNDERLINE,3,SWUNDR,UNL,FS.NFS
SP VARIANT,,.SWSIX##,VAR,FS.VRQ!FS.NFS
SP WIDTH,SCNWID,.SWDEC##,WID,FS.NUE!FS.NFS
>

PD.VAR==0
MX.VAR==1


;KEY WORD LISTS

KEYS (CASE,<LOWER,UPPER>)
KEYS (HEAD,<UPPER,MIXED,LOWER>)
KEYS (TYP,<LPT,CAT,TXT>)
KEYS (UNDR,<BACKSPACE,CHARACTER,LINE,SEPARATE,NONE>)
;NOW BUILD THE TABLES
	DOSCAN	(SWT)
;HERE WHEN SCAN COMPLETED
RUNOFS:
IF TOPS-10,<
	MOVSI	A,'DSK'		;GET DEFAULT OUTPUT DEVICE
	SKIPN	SCNOUT+.FXDEV	;SEE IF NEEDED
	MOVEM	A,SCNOUT+.FXDEV	;YES--FILL IN DEFAULT
> ;END TOPS-10
	MOVEI	A,AD.DWN	;GET DEFAULT FOR DOWN
	SKIPGE	SCNDWN		;SEE IF VALUE SET FOR DOWN
	MOVEM	A,SCNDWN	;WASN'T,MOVE IN DEFAULT
	SKIPLE	SCNDRF		;SEE IF /DRAFT
	JRST	[MOVEI A,R.SEQU	;YES--SEE IF /SEQUENCE
		 TDNN  A,FINIM	;  OR /NOSEQUENCE
		 IORM  A,FINI	;NO--SET /SEQUENCE
		 JRST  .+1]	; AND PROCEED

;LOOP OVER INPUT SPECS
	SKIPN	SCNLOC		;SEE IF ANY INPUT
	PUSHJ	P,SCNAIN	;NO--MAKE A BLANK AREA
	MOVE	X,INIFF		;GET INITIAL AREA
	MOVEM	X,SCNFIR	;SET AS START OF SCAN AREA
INDEFL:	MOVE	A,X		;POINT TO SPEC			[206]
	MOVEI	B,.FXLEN	;INDICATE LENGTH		[206]
	PUSHJ	P,.OSDFS##	;APPLY DEFAULTS FROM SWITCH.INI	[206]
IF TOPS-10,<
	MOVSI	B,'DSK'		;GET DEFAULT DEVICE
	SKIPN	.FXDEV(X)	;SEE IF NEEDED
	MOVEM	B,.FXDEV(X)	;YES--FILL IN DEFAULT
	MOVE	B,SCNOUT+.FXNAM	;GET OUTPUT FILE NAME IF ANY
	MOVE	C,SCNOUT+.FXNMM	;GET OUTPUT FILE NAME WILD CARD
	CAME	X,INIFF		;SEE IF FIRST SPEC
	MOVE	B,.FXNAM-.FXLEN(X)  ;NO--DEFAULT TO PREVIOUS
	CAME	X,INIFF		; ..
	MOVE	C,.FXNMM-.FXLEN(X)  ; ..
	SKIPN	.FXNAM(X)	;SEE IF FILE NAME GIVEN
	MOVEM	C,.FXNMM(X)	;NO--FILL IN DEFAULT
	SKIPN	.FXNAM(X)	; ..
	MOVEM	B,.FXNAM(X)	; ..
	HLLO	B,EXTTAB	;GET DEFAULT EXTENSION
	SKIPN	.FXEXT(X)	;SEE IF ANYTHING TYPED
	MOVEM	B,.FXEXT(X)	;NO--FILL IN DEFAULT
> ;END TOPS-10
	ADDI	X,.FXLEN	;ADVANCE TO NEXT SPEC
	CAMG	X,SCNLOC	;SEE IF ALL DONE
	JRST	INDEFL		;NO--GO DO NEXT ONE

IF TOPS-10,<
	MOVE	A,.JBREL	;GET CORE
	HRL	A,.JBFF		;AND FREE STORAGE
> ;END TOPS-10
IF TOPS-20,<
	HRLZ	A,.JBFF		;GET FIRST FREE
> ;TOPS-20
	MOVEM	A,SINCOR	;SAVE FOR MAIN LOOP
				CONT.
;BACK HERE AFTER EACH FILE PROCESSED
RUNOF1:	MOVE	A,SINCOR	;GET ORIGINAL CORE
	HLRZM	A,.JBFF		;RESTORE FREE CORE
IF TOPS-10,<
	TLZ	A,-1		;CLEAR TO CORE SIZE
	CAME	A,.JBREL	; ..
	CORE	A,		;RESTORE IT
	  JFCL			;NICE TRY.
> ;END TOPS-10

	MOVSI	F,L.JUST!L.PJUS!L.FILL
	SKIPGE	A,ULTYPE	;GET TYPE OF UNDERLINING
	MOVEI	A,AD.UNL	;  FILL IN DEFAULT
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	MOVEI	A,UNDRCH	;YES--SET /UNDERLINE:CHARACTER
	XCT	[TLO F,L.USUP		;/UNDERLINE:NO
		 TLO F,L.UBSP!L.UMOD	;/UNDERLINE:BACKSPACE
		 TLO F,L.UMOD		;/UNDERLINE:CHARACTER (NON-SPACING)
		 JFCL			;/UNDERLINE:LINE (OVERPRINT)
		 TLO F,L.ULIN		;/UNDERLINE:SEPARATE (LINE)
		 TLO F,L.USUP](A)	;/UNDERLINE:NONE
IFN AD.CON< TRO	F,R.ALCC>	;SET /CONTROLS IF DEFAULT
	ANDCM	F,FINIM		;CLEAR SPECIFIED SWITCHES
	IOR	F,FINI		;INCLUDE OTHER COMMAND FLAGS
	SKIPN	SCNPER		;SEE IF /NOPERIOD
	TRO	F,R.NPER	;YES--SET INITIALLY TO IGNORE THEM

	STORE	A,FILFWA,FILLWA,0	;CLEAR FILE AREA
					CONT.
	MOVE	A,[4,,[ SCNFIR,,SCNLOC
			OPNBLK,,LKPBLK
			.FXLEN,,LN$LKP
			1B0+F.FIN_^D18+SCNPTR]]
	PUSHJ	P,.LKWLD##	;PERFORM WILD-CARD LOOKUP (SEARCH)
	  JRST	RUNOF0		;NOT DISK--SEE IF DONE OR OTHER DEVICE

IF TOPS-10,<
	MOVE	X,SCNPTR	;GET INDEX
	MOVE	C2,B		;SAVE DEVICE TYPE FOR LATER
	JUMPE	A,RDERR3	;ERROR IF NO SUCH DEVICE

	OPEN	F.FIN,OPNBLK	;OPEN CHANNEL
	  JRST	RDERR1		;CAN'T GET DEVICE
	INBUF	F.FIN,0		;GET DEFAULT BUFFER RING
	MOVE	CH,LKPBLK+.RBPPN	;SAVE DIRECTORY
	MOVSI	S1,-EXTN	;POINT TO DEFAULT EXTENSION TABLE
;BACK HERE IF FILE NOT FOUND AND NEW DEFAULT BEING TRIED
SETUP2:	MOVEI	A,0		;SET FOR EXTENDEDLOOKUP
	SKIPL	C2		;SET OFFSET OF 0 IF DISK
	MOVEI	A,2		;OR 2 IF NOT
	MOVEM	CH,LKPBLK+.RBPPN	;RESTORE DIRECTORY
	LOOKUP	F.FIN,LKPBLK(A)	;LOOKUP FILE
	  JRST	RDERR2		;CAN'T GET AT FILE
> ;END TOPS-10
IF TOPS-20,<
	SKIPE	OPNBLK		;ANY JFN ASSIGNED?
	JRST	SETU2X		;YES--GO USE IT
	MOVSI	S1,-EXTN	;NO--POINTER TO DEFAULTS
SETU2A:	MOVE	B,[POINT 6,EXTTAB(S1)]
	MOVE	C,[POINT 7,DFIEXT]
	MOVEI	D,3
SETU2B:	ILDB	A,B		;GET A BYTE
	ADDI	A," "-' '	;CONVERT TO ASCII
	IDPB	A,C		;STORE IN BUFFER
	SOJG	D,SETU2B	;LOOP OVER EXTENSION
	MOVEI	A,GTJFNB	;POINT TO GTJFN BLOCK
	HRROI	B,LKPBLK	;MAIN STRING POINTER
	GTJFN			;TRY TO FIND FILE
	  JRST	SETU2C		;LOST
	MOVEM	A,OPNBLK	;REMEMBER THE ANSWER
	HRRZ	B,SCNPTR	;POINTER TO SCAN BLOCK
	MOVEM	A,.FXJFN(B)	;SAVE FOR .SCWLD
	TLNE	A,770000	;ANY WILD CARDS?
	GNJFN			;YES--DO FIEST STEP
	  JFCL
	JRST	SETU2X		;USE JFN
SETU2C:	AOBJN	S1,SETU2A	;LOOP OVER ALL EXTS
	MSG$	FNF,ERR,,<INPUT FILE NOT FOUND >
	MOVEI	A,LKPBLK
	PUSHJ	P,.TSTRG##	;GIVE FILE NAME
	PUSHJ	P,.CLRBF##	;CLEAR INPUT BUFFER
	PUSHJ	P,.TCRLF##	;START NEW LINE
	JRST	RUNOF0		;START OVER
SETU2X:
> ;END TOPS-20
	PUSHJ	P,.CHKTM##	;CHECK /BEFORE/SINCE
	  JRST	SETER4		;FAIL--GO TRY ANOTHER
IF TOPS-20,<
	PUSHJ	P,.DTOPN##	;OPEN THE DATA FILE
>
				CONT.
;NOW THE PRIMARY OUTPUT FILE

SETUP3:	MOVSI	N,-EXTN		;NOW FIND CORRESPONDING OUT EXT
IF TOPS-10,<
	HLLZ	B,LKPBLK+.RBEXT	;JUST THE EXT
> ;END TOPS-10
IF TOPS-20,<
	HRROI	A,.STEMP##	;WHERE TO PUT ANSWER
	HRRZ	B,OPNBLK	;JFN
	MOVX	C,<1B11>	;JUST DO EXTENSION
	JFNS			;CONVERT TO ASCII
	MOVE	A,[POINT 6,B]	;POINTER FOR SIXBIT
	MOVE	C,[POINT 7,.STEMP##]
	MOVEI	N1,3		;MAX LENGTH
	SETZB	B,INEXT		;CLEAR ANSWER
SETU30:	ILDB	D,C		;GET A BYTE
	JUMPE	D,SETU3C	;NOT 3 CHARS
	SUBI	D," "-' '	;MAKE SIXBIT
	IDPB	D,A		;SAVE
	SOJG	N1,SETU30	;DO 3 CHARS
	ILDB	D,C		;GET FORTH CHAR
	JUMPN	D,SETU3C	;MUST BE ZERO FOR 3 CHAR EXT
> ;END TOPS-20
	MOVEM	B,INEXT		;SAVE INPUT EXTENSION
SETU3A:	HLLZ	C,EXTTAB(N)	;CHECK INPUT EXT
	CAMN	B,C		;INPUT IN TABLE?
	JRST	SETU3D		;YES.
	AOBJN	N,SETU3A	;NOT THAT ONE. TRY THEM ALL
	MOVSI	N1,-NSLEXT	;NOT FOUND--TRY SOURCE FILES
SETU3B:	HLLZ	C,SELEXT(N1)	;GET SAMPLE
	CAME	B,C		;CHECK
	AOBJN	N1,SETU3B	;NO--TRY NEXT
	JUMPGE	N1,SETU3C	;DEFAULT IF UNKNOWN
	MOVS	N,PLMEXT	;YES--SET TO .PLM
	JRST	SETU3E		;AND PROCEED
SETU3C:	SUBI	N,1		;NOT FOUND--USE LAST ENTRY
SETU3D:	MOVS	N,EXTTAB(N)	;FOUND. GET OUT EXT FOR IT.
SETU3E:	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	[ANDI  N,77	;YES--SAVE LAST CHAR OF INPUT
		 TRO   N,'TP '	;INCLUDE .TP?
		 HRLZS N	;POSITION TO LH
		 JRST  .+1]	;AND PROCEED
	HLLOM	N,DEFEXT	;SAVE FOR .SCWLD
	MOVE	A,[4,,[SCNPTR,,[SCNOUT]
			OPNBLK,,OPNOUT
			LKPBLK,,ENTBLK
			DEFEXT,,LN$ENT]]
	PUSHJ	P,.SCWLD##	;SETUP OUTPUT WILDCARDS
	  JRST	SETER4		;GIVE UP IF IMPOSSIBLE
IF TOPS-10,<
	MOVSI	C,H.FOUT
	MOVEM	C,OPNOUT+2	;SET BUFFER ADDRESS
	OPEN	F.FOUT,OPNOUT
	  JRST	WRERR1		;CANT GET OUTPUT DEVICE
	OUTBUF	F.FOUT,0	;ALLOCATE DEFAULT OUTPUT BUFFERS
				CONT.
	MOVE	A,LKPBLK+.RBVER	;GET VERSION OF INPUT
	SKIPN	ENTBLK+.RBVER	;UNLESS SET,
	MOVEM	A,ENTBLK+.RBVER	;STORE FOR OUTPUT
	SKIPG	A,LKPBLK+.RBSIZ	;GET ACTUAL INPUT SIZE
	MOVEI	A,0		;(IGNORE IF .LE. 0)
	LSH	A,-7		;CONVERT TO BLOCKS
	SKIPN	ENTBLK+.RBEST	;UNLESS SET,
	MOVEM	A,ENTBLK+.RBEST	;SAVE AS ESTIMATED LENGTH
	MOVEI	A,0		;SET FOR EXTENDED
	SKIPL	B		;IF NOT DISK
	MOVEI	A,2		;CHANGE TO SHORT
	ENTER	F.FOUT,ENTBLK(A)  ;ENTER FILE
	  JRST	WRERR2		;IF ERROR, GO GIVE UP

	MOVEI	A,F.FOUT	;POINT TO OUTPUT CHANNEL
	DEVNAM	A,		;GET PHYSICAL NAME
	  MOVE	A,OPNOUT+1	;(OLD MONS, GET LOG NAME)
	GETLIN	B,		;GET TTY NAME
	CAMN	A,B		;SEE IF THE SAME
	SETOM	TTISOT		;YES--SET FLAG TO SUPPRESS INFO MESSAGES
	MOVEI	A,F.FOUT	;POINT TO CHANNEL		[203]
	DEVCHR	A,		;GET CHARACTERISTICS		[203]
	TXNE	A,DV.TTY	;SEE IF A TTY			[203]
	SETSTS	F.FOUT,IO.SUP	;YES--SUPPRESS ECHO		[203]
> ;END TOPS-10
IF TOPS-20,<
	HRRZ	A,OPNOUT	;GET OUTPUT JFN
	MOVX	B,<7B5+1B20>
	OPENF			;OPEN OUTPUT FILE
	  JRST	WRERR1		;CAN NOT OPEN FILE
	STORE	A,PMAPZ,PMAPEZ,0 ;CLEAR TEMPS
	HRRZ	A,OPNOUT	;GET OUTPUT JFN
	DVCHR			;SEE IF DISK
	TLNE	B,777		; ..
	JRST	RNGO		;NOT A DISK
	HRRZ	A,.JBHRL	;GET END OF HISEG
	ADDI	A,1		;POINT TO FIRST FREE
	TDNE	A,[-1,,777]	;WAS .JBHRL GOOD?
	HALT	.		;SOMEONE BROKE LINK
	LSH	A,-9		;GET PAGE #
	MOVEM	A,PMAPPG	;SAVE PAGE NUMBER
	MOVN	A,A		;GET NUMBER OF PAGES TO
	ADDI	A,700		; PMAP IN ONE CHUNK
	MOVEM	A,PMAPF		;REMEMBER THAT
> ;TOPS-20
	JRST	RNGO		;NO GO INTO THE REAL PROGRAM, SETUP DONE.
;ERRORS DURING SPECIFICATIONS

IF TOPS-10,<
RDERR1:	PUSHJ	P,E.DFO##	;OPEN ERROR
	JRST	RUNOF1		;GO TRY AGAIN

RDERR2:	HRRZ	A,LKPBLK+.RBEXT	;GET ERROR CODE
	JUMPN	A,RDER2E	;UNLESS NOT FOUND, GO GIVE ERROR
	MOVX	B,FX.NUL	;SEE IF NULL EXTENSION
	TDNE	B,.FXMOD(X)	; ..
	AOBJN	S1,.+2		;YES--SEE IF MORE NAMES TO TRY
	JRST	RDER2E		;NO--GO GIVE ERROR NOW
	HLLZ	B,EXTTAB(S1)	;ELSE, GET NEXT CHOICE
	MOVEM	B,LKPBLK+.RBEXT	;SET FOR LOOKUP
	JRST	SETUP2		;GO BACK AND TRY IT
RDER2E:	PUSHJ	P,E.DFL##	;LOOKUP ERROR
	JRST	SETER4		;RELEASE INPUT AND TRY AGAIN

> ;END TOPS-10
WRERR1:	SETZM	SCNLOC		;CLEAR WILD SCAN
	PUSHJ	P,E.SCO##	;ERROR--OUTPUT OPEN
	JRST	SETER4		;FINISH UP
IF TOPS-10,<
WRERR2:	PUSHJ	P,E.SCL##	;ENTER ERROR
	JRST	SETER3		;FINISH UP

RDERR3:	MSG$	NID,ERR,,No input device
	PUSHJ	P,.TSPAC##	;TYPE A SPACE
	MOVE	A,.FXDEV(X)	;GET INPUT DEVICE
	PUSHJ	P,.TSIXN##
> ;END TOPS-10
SETER2:	PUSHJ	P,.TCRLF
IF TOPS-10,<
SETER3:	RELEAS	F.FOUT,
SETER4:	RELEAS	F.FIN,
> ;END TOPS-10
IF TOPS-20,<
SETER3:	HRRZ	A,OPNOUT
	CLOSF
	  JFCL
SETER4:	HRRZ	A,OPNBLK
	TLO	A,(1B0)
	CLOSF
	  JFCL
> ;TOPS-20
	JRST	RUNOF1

EXTTAB:		;TABLE OF XWD DEFAULT INPUT EXTENSION, OUTPUT EXT.
	SIXBIT	/RNOMEM/	;FIRST IS DEFAULT INPUT IF WILDCARD
				;KEEP REST IN ALPHABETIC ORDER
	SIXBIT	/RNBBLB/
	SIXBIT	/RNCCCO/
	SIXBIT	/RNDDOC/
	SIXBIT	/RNEERR/
	SIXBIT	/RNHHLP/
PLMEXT:	SIXBIT	/RNLPLM/
	SIXBIT	/RNMMAN/
	SIXBIT	/RNPOPR/
	SIXBIT	/RNSSTD/
	SIXBIT	/   MEM/	;LAST IS DEFAULT OUTPUT EXTENSION
EXTN==.-EXTTAB
;HERE WHEN FILES OPENED

RNGO:	MOVE	A,[FLASTD,,CCTABL]
	BLT	A,CCTEND	;PRESET .FLAG TABLE
	HLRZ	D,INEXT		;GET EXTENSION

	SETOM	GCSCH		;NO SAVED CHARACTER
	SETOM	ULMCH		; ..
	SKIPL	A,SCNLPP	;GET /LINES:N
	CAIGE	A,12		;MAKE SURE AT LEAST MIN
	MOVEI	A,AD.LPP	;INITIAL LENGTH OF PAGE
	SKIPGE	SCNPAG		;IF NO /NOPAGING OR /PAGING
	CAIE	D,'RNH'		;SEE IF HELP FILE
	SKIPN	SCNPAG		;NOT HELP--SEE IF /NOPAGING
	HRLOI	A,INFIN		;YES--SET INFINITY		[205]
	MOVEM	A,PNLPG
	MOVEM	A,NLPG
	MOVEI	A,AD.WID	;INITIAL RIGHT MARGIN
	CAIN	D,'RNH'		;SEE IF HELP FILE
	MOVEI	A,HRMRG		;YES--GET SPECIAL WIDTH
	SKIPL	SCNWID		;IF /WIDTH,
	MOVE	A,SCNWID	; GET IT INSTEAD
	MOVEM	A,PRMRG
	MOVEM	A,RMARG
	STORE	A,LMARG,,ILMRG	;SET INITIAL LEFT MARGIN
	SKIPN	SCNNMB		;IF /NONUMBERING,
	SETOM	FLNUMB		; SET .NONUMBER
	SKIPGE	A,SCNOVR	;OVER SWITCH ON?
	MOVEI	A,AD.OVR	;NO
	IDIVI	A,^D8		;THIS FOR TABS
	MOVEM	A,FILOVT	;SAVE TABS OVER
	MOVEM	B,FILOVR	;SAVE SPACES OVER
	MOVEI	A,ILPGNO	;INITIAL PAGE NUMBER
	MOVEM	A,PAGENO
	PUSHJ	P,SETRNG	;SET L.SUPO IF NOT IN /RANGE
	MOVEI	A,IPARIN	;INITIAL PARAGRAPH INDENTING
	MOVEM	A,PARIND
	STORE	A,PARSPC,,IPARVS	;DEFAULT VERT SPACING OF PARAGRAPHS
	MOVEI	A,IPARTP	;INITIAL
	MOVEM	A,PARTPG	; PARAGRAPH TEST PAGE
	MOVEI	PA,LINBF	;INITIALIZE LINE INPUT POINTER
	PUSHJ	P,CSP
	MOVEM	A,LNIN1		;STORE.
	MOVEM	B,LNIN2		; ..
	SKIPGE	A,SCNCAS	;GET SWITCH CASE
	MOVEI	A,AD.CAS	;NONE--DEFAULT TO UPPER
	MOVE	A,[ULCAS
		   0]-1(A)	;CONVERT TO INTERNAL FORMAT
	MOVEM	A,FILCAS	;SET INITIAL FILE CASE
	MOVEM	A,CAS		;STORE CURRENT FILE CASE
				CONT.
	SKIPGE	A,SCNSPG	;GET /SPACING SWITCH
	MOVEI	A,AD.SPC	;NONE--GET DEFAULT
	MOVEM	A,NSPNG		;STORE AS INITIAL VALUE
	SKIPG	A,SCNHDR	;SEE IF /HEADER
	MOVEI	A,AD.HDR	;NO--USE DEFAULT
	MOVEM	A,FILHDR	;INITIALIZE SETTING

	SKIPGE	SCNPAG		;SEE IF /PAGING OR /NOPAGING
	CAIE	D,'RNH'		;NO--SEE IF HELP FILE
	SKIPN	SCNPAG		;NOT HELP--SEE IF /NOPAGING
	JRST	[SETOM FLNOPG	;HELP OR /NOPAGING--SET .NO PAG
		 SETOM FLNHDR	; AND .NO HEAD
		 JRST  .+1]	;AND PROCEED

	MOVEI	A,AD.UND	;GET DEFAULT /UNDERLINE
	TLNE	F,L.ULIN	;SEE IF /UNDERLINE:SEPARATE
	MOVEI	A,ADSUND	;YES--DIFFERENT DEFAULT
	SKIPG	ULCHO		;SEE IF USER GAVE /UNDERLINE
	MOVEM	A,ULCHO		;NO--SUPPLY DEFAULT

	MOVE	A,[IOWD 3*LN$IFS,IFSTK] ;[244] IF STACK POINTER
	MOVEM	A,IFSTKP	;[244] STORE FOR .IF
	HRRZ	PA,.JBFF	;GET FREE AREA
	MOVEM	PA,XTOP		;INITIAL INDEX POINTERS
	MOVEM	PA,XBOT		; ..
IF TOPS-10,<
	HRRZ	PA,.JBREL	;INITIALIZE FOOTNOTE STUFF
	SUBI	PA,^D200	;SPACE FOR SOME FOOTNOTES?
	HRRZ	A,.JBFF		; ..
	CAIL	A,0(PA)		; ..
	JRST	[ADDI PA,^D1000	;NO. ASK FOR MORE CORE
		 CORE PA,	; ..
		   JFCL		;BUT DONT PANIC IF NOT THERE
		 JRST .+1]
	HRRZ	PA,.JBREL	;GIVE HALF OF CORE TO FOOTNOTES
> ;END TOPS-10
IF TOPS-20,<
	MOVEI	PA,RUNOFF-11	;TOP OF LOWSEG
	HRRZ	A,.JBFF		;END OF USED CORE
> ;END TOPS-20
	SUBI	PA,0(A)		;AND HALF TO INDEX
	ASH	PA,-1		; ..
	ADDI	PA,0(A)		;.JBFF PLUS HALF DIFFERENCE
	HRRZM	PA,FOOTBF	;SAVE FOR COMPARISON LATER
	HRRZM	PA,INIFBF	;SAVE SE WE CAN TELL IF MOVED
	PUSHJ	P,CSP		; ..
	MOVEM	A,FOOTP1	;STORE
	MOVEM	B,FOOTP2
	MOVEM	A,FOOTP3	;IN BOTH POINTERS
	MOVEM	B,FOOTP4
				CONT.
	MOVEI	PA,CMEBFP	;POINT TO COMMAND ERROR BUFFER
	MOVEI	A,CMEBF		;WORD ADDRESS
	MOVEI	B,CMEBFL	;WORD LENGTH
	PUSHJ	P,ICI		;INITIALIZE CHARACTER POINTERS

	MOVEI	PA,SLIN		;POINT TO POINTERS
	MOVEI	A,SLINBF	;WORD ADDRESS
	MOVEI	B,SLINBL	;WORD LENGTH
	PUSHJ	P,ICI		;SET INITIAL POINTERS

	MOVEI	PA,TECBFP	;POINT TO BUFFER FOR TEST END
	MOVEI	A,TECBF		;WORD ADDRESS
	MOVEI	B,LN$TEC	;WORD LENGTH
	PUSHJ	P,ICI		;INITIALIZE CHARACTER POINTERS

	MOVSI	A,-LN$TAB	;LENGTH OF TAB STOP TABLE
	MOVEI	B,0		;PRESET TO 8,16,24,...
INTABL:	ADDI	B,8		;ADVANCE TO NEXT
	MOVEM	B,TABTAB(A)	;STORE
	AOBJN	A,INTABL	;LOOP FOR ENTIRE TABLE
	HRRZM	A,NTABS		;STORE NUMBER WE SET
	MOVE	B,SCNTYP	;GET /TYPESET SWITCH
	CAIN	B,TYPLPT	;IF /TYPESET:LPT
	SETZM	B		; TREAT AS NORMAL OUTPUT
	MOVEI	A,1		;SET 1/1
	SKIPLE	B		;UNLESS TYPESETTING (NOT LPT)
	MOVEI	A,TYPSWD	;GET TYPESETTING WIDTH
	MOVEM	A,TYPMUL	;STORE AS SPACING MULTIPLIER
	SKIPLE	B		;UNLESS TYPESETTING (NOT LPT)
	MOVE	A,PRMRG		;GET PAGE WIDTH
	MOVEM	A,TYPDIV	;STORE AS SPACING DIVISOR

	MOVEI	A,FOUTCS	;PRESET FILE
	SKIPLE	SCNTYP		; OUTPUT ROUTINE
	MOVEI	A,OUTTYP	;IF TYPESETTING--MUST CONVERT
	MOVEM	A,FOUTCH	;STORE
				CONT.
	HLRZ	B,INEXT  ;GET EXTENSION
	MOVSI	A,-NSLEXT	;LENGTH OF SELECTION TABLE
RNGSEL:	HLRZ	C,SELEXT(A)	;GET EXTENSION
	CAME	C,B		;SEE IF SAME
	AOBJN	A,RNGSEL	;NO--LOOP
	HRRZ	A,SELEXT(A)	;GET SELECTION ADDRESS
	MOVE	B,SCNSEL	;GET /SELECT VALUE
	AOSE	B		;SEE IF DEFAULT
	MOVEI	A,SCNSEL	;A NOW POINTS TO DEFAULT
	SKIPE	A		;IF NO DEFAULT
	SKIPN	B,(A)		;OR NO VALUE,
	JRST	RNGNSL		; SUPPRESS SELECTION
	CAIN	B,1		;SEE IF /NOSELECT
	JRST	RNGNSL		;YES--NO SELECTION
	TRO	F,R.SLCT!R.SLLK	;SET .SELECTION MODE
	MOVSI	C,-4		;COUNT OF MASK SIZE
RNGYSL:	MOVEI	A,0		;CLEAR JUNK
	LSHC	A,7		;PEEL OUT NEXT CHAR
	MOVEM	A,SELPFX(C)	;STORE IN ARRAY
	AOBJN	C,RNGYSL	;LOOP
RNGNSL:	AOS	DIDSOM		;FORCE FIRST WAIT
	SKIPLE	SCNSIM		;FORMFEED OR LF'S?
	JRST	RNG1		;LINEFEEDS. REQUEST POSITIONING
	SKIPL	TTISOT		;SEE IF TTY: OUTPUT
	SKIPLE	SCNPAU		;OR IF PAUSE MODE IS ON
	PUSHJ	P,FRCFRM	;YES--FORCE FORM FEED
	JRST	RNG2		;AND GO.

RNG1:	MOVEI	A,[ASCIZ \
Position paper, type space.
\]
	PUSHJ	P,.TSTRG	;ASK FOR POSITIONING
	PUSHJ	P,BPGXY		;WAIT FOR A CHARACTER
				CONT.
RNG2:	SKIPG	SCNTYP		;SEE IF TYPESETTING
	JRST	RNG3		;NO--PROCEED
	MOVEI	A,FOUTTT	;SET FOR FILE OUTPUT FROM .TOUTS
	PUSHJ	P,.TYOCH##	; GET BACK ORIGINAL
	SAVE$	A		;SAVE FOR RESTORE
	MOVEI	A,[ASCIZ \<RUNOFF version \]
	PUSHJ	P,.TSTRG##	;ISSUE COMMENT
	MOVE	A,.JBVER	;GET OUR VERSION
	PUSHJ	P,.TVERW##	;ISSUE IT
	MOVEI	A,[ASCIZ \ run on \]
	PUSHJ	P,.TSTRG##	;ISSUE COMMENT
	PUSHJ	P,.TDATN##	;ISSUE TODAY'S DATE
IF TOPS-10,<
	MOVEI	A,[ASCIZ \
  from file \]
	PUSHJ	P,.TSTRG##	;ISSUE COMMENT
	MOVE	A,LKPBLK+.RBNAM	;GET FILE NAME
	PUSHJ	P,.TSIXN##	;ISSUE IN SIXBIT
	MOVEI	A,"."		;GET SEPARATOR
	PUSHJ	P,.TCHAR##	;ISSUE
	HLLZ	A,LKPBLK+.RBEXT	;GET EXTENSION
	PUSHJ	P,.TSIXN##	;ISSUE IN SIXBIT
	MOVEI	A,[ASCIZ \ created \]
	PUSHJ	P,.TSTRG##	;ISSUE COMMENT
	LDB	A,[POINTR (LKPBLK+.RBEXT,RB.CRX)]
	MOVE	B,LKPBLK+.RBPRV	;GET REST OF CREATION
	LSH	B,^L<RB.CRD>	;ABUT EXTENSION OF DATE
	LSHC	A,WID(RB.CRD)	;FORMAT TOGETHER
	PUSHJ	P,.TDATE##	;ISSUE IT
	PUSHJ	P,.TSPAC##	;SPACE OVER
	LDB	A,[POINTR (LKPBLK+.RBPRV,RB.CRT)]
	IMULI	A,^D60000	;CONVERT TO MILLI-SEC.
	PUSHJ	P,.TTIME##	;ISSUE THAT
> ;END TOPS-10
	MOVEI	A,[ASCIZ \>[*CAT]\]
	MOVE	B,SCNTYP	;GET /TYPESET
	CAIN	B,TYPLPT	;IF /TYPESET:LPT
	MOVEI	A,[ASCIZ \>[*LPTR]\] ; USE SPECIAL SETUP
	CAIN	B,TYPTXT	;IF /TYPESET:TXT
	MOVEI	A,[ASCIZ \>[*TXT6]\] ; USE ITS SETUP
	PUSHJ	P,.TSTRG##	;ISSUE MACRO TO START TYPESETTING OFF
	PUSHJ	P,LRMTYP	;ISSUE INITIAL MARGINS
	PUSHJ	P,.TCRLF##	;CLEAN LINE
	RSTR$	A		;RESTORE ORIGINAL TYPER
	PUSHJ	P,.TYOCH##	;TELL .TOUTS
	PUSHJ	P,STSTYP	;SET TAB STOPS FOR TYPESETTING
RNG3:	PUSHJ	P,LINSET	;SET UP FOR LINE
	PUSHJ	P,LINDFN	;INITIALIZE TO NORMAL CASE RULES
	JRST	LGO		;AND INTO MAIN LOOP, LINE INPUT
;TABLE OF XWD EXTENSION,ADDRESS OF DEFAULT .SELECTION

;+
;^THE TABLE "<SELEXT" IS A SET
;OF PAIRS OF FILE EXTENSION AND DEFAULT .<SELECT
;MODE FOR THAT EXTENSION.  ^EVERY LANGUAGE'S EXTENSION SHOULD
;APPEAR HERE IN THE FORM OF 'EXTENSION',,ADDRESS OF SELECTION
;SO THAT THE PROGRAM LOGIC MANUAL OF ANY PROGRAM CAN BE
;OBTAINED BY THE <RUNOFF COMMAND _<FILE NAME_>.  ^THE USER
;DOES NOT NEED TO REMEMBER THE COMMENTING CONVENTION FOR EACH
;LANGUAGE TO EXTRACT THE PROGRAM'S DOCUMENTATION.  ^IF A PROGRAM
;NEEDS ITS DOCUMENTATION TO BE FLAGGED BY NON-STANDARD CHARACTERS,
;IT SHOULD START WITH A .<SELECT COMMAND UNDER THE STANDARD
;CONVENTION.  ^THIS COMMAND WILL THEN SWITCH THE FILE TO ITS
;OWN SELECTION MODE.
;-

SELEXT:			;SELECTION TABLE
	'ALG',,SELEXL		;ALGOL
	'BAS',,SELQUT		;BASIC
	'BLI',,SELEXL		;BLISS
	'B10',,SELEXL		;BLISS-10
	'B11',,SELEXL		;BLISS-11
	'FAI',,SELEXL		;FAIL
	'FOR',,SELEXL		;FORTRAN-10
	'F40',,SELEXL		;F40
	'MAC',,SELSEM		;MACRO-10
	'N  ',,SELNEL		;NELIAC
	'PAL',,SELSLH		;PAL-10
	'P11',,SELSEM		;MACY-11
NSLEXT==.-SELEXT		;LENGTH
	0,,0			;MUST BE END

;TABLES OF DEFAULT .SELECTIONS

;+
;^THE FOLLOWING ARE THE STANDARD .<SELECT SETTINGS
;FOR EACH LANGUAGE:
;.LEFT MAR 5.TAB STOP 5,25.NOFLAGS
;SWITCH TO -&+- TO AVOID PATTERN IN SELSEM
;-.SELECT -

SELEXL:	ASCIZ	/!&+-/	;-&. ;MOST LANGUAGES	! & + -
SELNEL:	ASCIZ	/!!/	;-&. ;NELIAC	! !
SELQUT:	ASCIZ	/'&+-/	;-&. ;BASIC	' & + -
SELSEM:	ASCIZ	/;&+-/	;-&. ;ASSEMBLERS	; & + -
SELSLH:	ASCIZ	\/&+-\	;-&. ;PAL-10	/ & + -

	;-&.FLAGS ;.SELECT _;
;&.LEFT MAR 0
;&^WHERE THE CHARACTERS ARE GIVEN IN
;&THE SAME ORDER AS IN THE .<SELECT COMMAND.
;HERE AT END OF FILE

ENDFL1:	PUSHJ	P,BPAGE		;OUTPUT TO TOP OF PAGE, TO GET FOOTNOTES
ENDFIL:	PUSHJ	P,OUTNJ		;FINISH LAST LINE
	MOVE	A,FOOTP3	;ARE THERE ANY REMAINING FOOTNOTES?
	CAME	A,FOOTP4	; ..
	JRST	ENDFL1		;YES. FORCE THEM OUT.
	SKIPL	TTISOT		;PAGE IF TTY OUTPUT
	SKIPLE	SCNPAU		;PAGE IF IN PAUSE MODE
	PUSHJ	P,FORM		;TO TOP OF FORM
	MOVE	A,IFSTKP	;[244] GET IF STACK POINTER
	CAME	A,[IOWD 3*LN$IFS,IFSTK] ;[244] UP TO TOP?
	JRST	E$$TFE		;[244] NO--SAY TOO FEW END COMMANDS
	SKIPN	MJSPDL		;SEE IF NOTE/LS PDL EMPTY
	JRST	ENDF2		;YES--OK
	MSG$	TFE,WRN,,Too few end commands
	PUSHJ	P,.TCRLF	;END LINE

ENDF2:	PUSHJ	P,NEGINC	;CATCH ANY REMAINING NEG IND MESSAGES
	SKIPGE	TTISOT		;SEE IF TTY: OUTPUT
	JRST	ENDFLX		;YES--SUPPRESS INFO
IF TOPS-10,<
	SKPINL
	  JFCL			;TURN CONTROL-O OFF
> ;END TOPS-10
	PUSHJ	P,ISUFLN	;NO--ISSUE IT
	PUSHJ	P,.TTABC##	;TAB OVER
	MOVE	A,PAGECT	;HOW MANY PAGES?
	SKIPE	LINECT
	AOS	A,PAGECT	;ROUND UP IF PARTIAL PAGE
	PUSHJ	P,.TDECW##
	MOVEI	A,[ASCIZ / pages
/]
	MOVE	N,PAGECT	;IN CASE IT'S ONE.
	CAIN	N,1		;GET THE GRAMMAR RIGHT
	MOVEI	A,[ASCIZ / page
/]
	PUSHJ	P,.TSTRG##	;AND TEXT
ENDFLX:
IF TOPS-10,<
	RELEAS	F.FIN,		;LET GO OF INPUT FILE
> ;END TOPS-10
IF TOPS-20,<
	HRRZ	A,OPNBLK	;GET THE INPUT JFN
	TLO	A,(1B0)		;DO NOT RELEASE JFN
	CLOSF			;CLOSE THE INPUT FILE
	  SKIPA			;ERROR
	JRST	ENDFA		;CLOSED OK
	MSG$	ECI,ERR,,ERROR CLOSING INPUT FILE
ENDFA:> ;END TOPS-20

IF TOPS-10,<
	RELEAS	F.FOUT,		;RELEASE OUTPUT FILE
> ;END TOPS-10
IF TOPS-20,<
	HRRZ	A,OPNOUT	;GET OUTPUT JFN
	HRLI	A,12
	MOVE	B,BYTECT	
	SETOM	C
	SKIPE	B
	CHFDB			;SET CORRECT BYTE COUNT
	HRLI	A,11
	MOVX	B,7B11
	MOVX	C,77B11
	SKIPE	BYTECT
	CHFDB
	SETOM	A
	HRLI	B,.FHSLF
	HRR	B,PMAPPG
	MOVE	C,PMAPF
	TXO	C,PM%CNT
	SKIPE	BYTECT
	PMAP
	HRRZ	A,OPNOUT	;GET JFN AGAIN
	CLOSF			;CLOSE FILE
	  SKIPA			;ERROR
	JRST	RUNOF1		;CLOSED OK
	MSG$	ECO,ERR,,ERROR CLOSING OUTPUT FILE
> ;END TOPS-20
	JRST	RUNOF1
	SUBTTL	INPUT SECTION

;+
;.CHAPTER TEXT INPUT LOGIC
;
;^THE MAIN TEXT CHARACTER INPUT LOOP STARTS AT THE
;LABEL "<LIN".  ^AFTER EACH CHARACTER IS PROCESSED
;CONTROL RETURNS TO "<LIN" IF THE LAST CHARACTER WAS
;A TAB OR SPACE AND TO "<LIN1" IF NOT.  ^DURING THE
;TEXT SCAN, A TWO ENTRY HISTORY IS KEPT OF THE LAST
;TWO CHARACTERS SEEN IN LOCATION "<LCH".
;^THIS TEXT LOOP HANDLES SPACES, TABS, AND
;LINE FEEDS SPECIALLY.  ^EVERYTHING ELSE IS JUST ACCUMULATED
;UNTIL THE INPUT BUFFER IS FULL ENOUGH TO GENERATE SOME
;OUTPUT.  ^WHEN THAT IS SO, THE OUTPUT ROUTINE "<OUTLJ"
;IS CALLED, AND THEN INPUT SCANNING IS RESUMED.
;-

LIN:	SKIPG	LINEC		;SEE IF NEW PAGE
	PUSHJ	P,HEADIN	;YES--GET IT BEFORE PROCEEDING
	HRRZ	CH,LCH		;GET LAST CHAR
	CAIE	CH,C.NXS	;SEE IF NON-EXPANDABLE SPACE
	CAIN	CH,C.SPC	;OR REGULAR SPACE
	SKIPA			;YES--SAVE
	SETZM	LCH		;ELSE--CLEAR CHAR MEMORY
LIN1:	PUSHJ	P,GCIN		;READ CHARACTER WITH PRE-TRANSLATE
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	AOS	LINNSC		;YES--COUNT NON-SPACING QUOTE
	CAIN	CH,.CHTAB	;TAB?
	SKIPLE	SCNTYP		; UNLESS TYPESETTING
	SKIPA			;NO
	JRST	LTAB		;YES. SPECIAL HANDLING
	CAIN	CH,.CHLFD	;LINE FEED?
	JRST	LGO		;YES. GO LOOK FOR NEXT COMMAND
	MOVE	A,CH		;GET CHARACTER
	ANDI	A,CHRMSK	;MASK TO ASCII
	CAIG	A,C.FLGS	;SOME OTHER INTERNAL FLAG?
	JRST	LINNS		;YES. TREAT AS NON-SPACING
	CAIE	CH,C.NXS	;NON EXPANDABLE SPACE?
	CAIN	CH,C.SPC	;OR REGULAR SPACE?
	JRST	LSPAC		;YES. GO HANDLE SPACING
LIN3:	PUSHJ	P,WLNIN1	;WRITE CHAR IN INPUT BUFFER
	PUSHJ	P,SLCH		;SAVE LAST CHARACTER
	SOSL	LINBK		;TIME TO BREAK LINE YET?
	JRST	LIN1		;NO. LOOP FOR MORE
	PUSHJ	P,OUTLJ		;YES. OUTPUT LINE,JUSTIFIED IF FLAGS
				; SAY SO, AND SET FOR NEXT LINE
	JRST	LIN1		;PROCESS NEXT LINE.

LINNS:	PUSHJ	P,WLNIN1	;WRITE CHAR IN LINE BUFFER
	PUSHJ	P,SLCH		;SAVE LAST CHARACTER
	AOS	LINNSC		;COUNT NON-SPACING CHARACTERS
	CAIN	CH,LCHPVT+"H"-100 ;[237] BACKSPACE?
	AOS	LINNSC		;[237] YES--COUNT IT TWICE
	JRST	LIN1		;BACK INTO LOOP
;ROUTINE TO SAVE LAST TWO CHARACTERS LOOKING FOR TWO ALPHAS

;+
;^THE ROUTINE "<SLCH" MAINTAINS THE HISTORY BUFFER WORD,
;"<LCH".  ^THIS ALWAYS HAS THE LAST TWO CHARACTERS STORED
;IN THE INPUT BUFFER EXCEPT THAT IT IS CLEARED AT THE BEGINNING
;OF EACH INPUT LINE AND AFTER EACH SPACE AND TAB.
;-

SLCH:	CAIN	CH,C.ULS	;IGNORE UNDERLINES
	POPJ	P,		; ..
REPEAT 0,<		;NO LONGER GOOD IDEA [EDIT 153]
	TRZ	F,R.LASA	;CLEAR FLAG
	HLRZ	A,LCH		;GET OLDEST CHAR
	ANDI	A,CHRMSK	;STRIP FLAGS
	CAIG	A,"Z"+ULCAS	;SEE IF ALPHA
	CAIGE	A,"A"		; ..
	JRST	SLCHX		;NO
	CAIGE	A,"A"+ULCAS	; ..
	CAIG	A,"Z"		; ..
	SKIPA			;OK
	JRST	SLCHX		;NO
	HRRZ	A,LCH		;GET LAST CHAR
	ANDI	A,CHRMSK	;STRIP FLAGS
	CAIG	A,"Z"+ULCAS	;SEE IF ALPHA
	CAIGE	A,"A"		; ..
	JRST	SLCHX		;NO
	CAIGE	A,"A"+ULCAS	; ..
	CAIG	A,"Z"		; ..
	SKIPA			;OK
	JRST	SLCHX		;NO
	TRO	F,R.LASA	;FLAG TWO ALPHAS
>;END REPEAT 0 [EDIT 153]
;HERE WHEN DONE
SLCHX:	HRL	CH,LCH		;MOVE LAST OVER
	MOVEM	CH,LCH		;STORE THIS AS LAST
	TLZ	CH,-1		;CLEAR JUNK			[153]
	POPJ	P,		;RETURN
;SUBROUTINE TO INITIALIZE COUNTS AND POINTERS FOR A NEW LINE

;+
;^THE ROUTINE "<LINSET" IS USED TO INITIALIZE THE TEXT
;INPUT BUFFER.  ^IT RESETS THE POINTERS, INTIALIZES THE
;COUNTERS AND CLEARS OUT ANY HISTORY FROM THE PREVIOUS
;LINE.  ^WHILE SCANNING INPUT TEXT, THE FOLLOWING ARE MAINTAINED:
;.TAB STOP 10
;. ;<LINBK	A DOWN COUNTER OF OUTPUT SPACE
;. ;<LNINCT	A DOWN COUNTER OF INPUT TEXT BUFFER SPACE
;. ;<SPCNT	A COUNT OF SPACES IN THE INPUT
;. ;<NSPCH	A COUNT OF NON-SPACING CHARACTERS
;. ;<CPOS	THE OUTPUT POSITION COUNTER
;. ;<LINNSC	A COUNT OF NON-SPACING CHARACTERS IN THE INPUT BUFFER
;-

LINSET:	MOVE	A,RMARG		;COMPUTE REAL WIDTH OF LINE
	SUB	A,LMARG		;AS DIFFERENCE OF MARGINS
	SUB	A,INDCT		;MINUS INDENTING
	MOVEM	A,LINBK		;STORE IN LINE-BREAK COUNT
	MOVEI	A,5*LN$LIN	;GET MAX CHARS IN LINE BUFFER
	MOVEM	A,LNINCT	;SET INTO COUNTER
	SETOM	SPCNT		;INITIAL COUNTS OF SPACING
	SETZM	NSPCH		; AND NON-SPACING CHARS
	SETZM	CPOS		;CARRIAGE POSITION IS FAR LEFT
	SETZM	LINNSC		;NO NON-SPACING CHARACTERS
	MOVEI	A,ULPBF		;UNDERLINE POSITION BUFFER AT START
	MOVEM	A,ULPOS		; ..
	MOVE	A,LNIN1		;CLEAR LINE INPUT BUFFER BY MOVING 
	MOVEM	A,LNIN2		; END POINTER BACK TO START
	MOVEM	A,LSTSP		;SET LAST SPACING CHARACTER BACK HERE
	SOS	LSTSP		;MINUS ONE, SO OFF START OF BUFFER
	PJRST	LINUPC		;UPDATE THISXX PAGE COUNTS
;HERE ON TAB DURING LINE INPUT

;+
;^WHEN A TAB IS SEEN WHILE PROCESSING THE INPUT TEXT, THE
;PROGRAM TRANSFERS TO LOCATION "<LTAB".  ^THE CURRENT
;HORIZONTAL POSITION IS COMPUTED AND THE TAB STOP TABLE
;IS EXAMINED TO FIND THE NEXT POSITION. ^IF THIS TAB IS BEYOND
;THE TABLE OR WOULD BE BEYOND THE RIGHT MARGIN, IT IS TREATED
;AS A SPACE BY JUMPING TO "<LSPAC".
;^IF THE TAB IS REASONABLE, IT IS THEN
;REPLACED BY THE RIGHT NUMBER OF QUOTED SPACES.  ^ALSO,
;ALL PREVIOUS SPACES ON THE SAME LINE ARE REPLACED BY
;QUOTED SPACES TO KEEP THEM FROM BEING EXPANDED DURING
;JUSTIFICATION.
;-

LTAB:	MOVE	A,LNIN2		;DETERMINE PRESENT POSITION
	SUB	A,LNIN1
	SUB	A,LINNSC
	ADD	A,LMARG
	ADD	A,INDCT
	PUSHJ	P,TAB		;FIND WHERE NEXT TAB STOP IS
	CAML	A,LINBK		;WOULD THAT MANY EQUAL OR EXCEED LINE SIZE?
	JRST	LSPAC		;YES. TREAT AS SPACE, NOT TAB
	MOVN	X,A		;NO. NEGATE NUMBER OF SPACES
	MOVEI	CH,C.NXS	;PUT N NON-EXPANDABLE SPACES IN BUFFER
	PUSHJ	P,WLNINC	; ..
	AOJL	X,.-1		; ..
	MOVEI	C,C.NXS		;GET A NON-EXPANDABLE SPACE
	MOVEI	PA,LNIN1	;POINT TO INPUT STRING
	PUSH	P,(PA)		;SAVE IT
LTABSL:	SKIPGE	SPCNT		;ANY SPACES LEFT?
	JRST	LTABX		;NO--EXIT
LTABS1:	PUSHJ	P,GCI		;GET NEXT CHAR IN LINE
	  JRST	LTABX		;GIVE UP IF NONE (ERROR?)
	CAIE	CH,C.SPC	;SEE IF SPACE
	JRST	LTABS1		;NO--LOOP ON
	DPB	C,CBYTAB(B)	;YES--REPLACE WITH NON-EXPANDABLE SPACE
	SOS	SPCNT		;AND DECREMENT COUNT OF SPACES
	JRST	LTABSL		;LOOP UNTIL DONE
LTABX:	POP	P,(PA)		;RESTORE INPUT POINTER
	JRST	LIN		;AND BACK INTO LINE INPUT ROUTINE
;+
;^WHEN A SPACE IS SEEN IN THE TEXT INPUT SCAN, CONTROL IS
;TRANSFERED TO LOCATION "<LSPAC".  ^LEADING SPACES AND MULTIPLE
;SPACES ARE DISCARDED.  ^IF THE SPACE WAS PRECEEDED BY A PERIOD,
;EXCLAMATION, QUESTION, COLON, OR SEMI-COLON AND THAT IN TURN
;WAS PRECEEDED BY AT LEAST TWO ALPHABETICS, THEN THE SPACE IS
;DOUBLED.  ^IN ANY CASE, THE NUMBER OF SPACES IS COUNTED AND
;THE LAST SPACE SEEN IS MAINTAINED.  ^THE CHARACTER IS
;STORED AND THE SCAN RESUMES.
;-

LSPAC:	TLNN	F,L.FILL	;FILLING INPUT BEYOND BREAKS?
	JRST	LSPC1		;NO. SIMPLER PROCESSING
	MOVE	A,LNIN2		;FILTER OUT LEADING SPACES
	SUBI	A,1		;GET START OF BUFFER MINUS ONE
	CAMG	A,LSTSP		;IS THAT WHERE LAST SPACE IS?
	JRST	LIN		;YES. JUST IGNORE THIS SPACE
	HRRZ	CH,LCH		;GET PREVIOUS CHARACTER. WHAT WAS IT?
	CAIE	CH,C.SPC	;A SPACE?
	CAIN	CH,C.NXS	;OR NON-EXPANDABLE SPACE?
	JRST	LIN		;YES. FILTER MULTIPLE SPACES
				;***DELETED TRNE F,R.LASA	[153]
	TRNE	F,R.NPER	;SEE IF .NOPERIOD
	JRST	LSPC1		;RIGHT--SKIP SPECIAL TESTS
	SKIPLE	A,SCNTYP	;SEE IF /TYPESET
	CAIN	A,TYPLPT	;AND NOT /TYPESET:LPT
	SKIPA			;NO--PROCEED
	JRST	LSPC1		;YES--DON'T DOUBLE THE SPACE
	CAIN	CH,C.EXCL	;EXCLAMATION POINT FOLLOWED BY SPACE?
	JRST	LSPCD		;YES. SPECIAL PROCESSING
	CAIE	CH,C.COLN	;SEE IF COLON
	CAIN	CH,C.SEMC	;OR SEMI-COLON
	JRST	LSPCD		;YES--SPECIAL PROCESSING
	CAIE	CH,C.QM		;QUEST FOLLOWED BY SPACE, OR
	CAIN	CH,C.PD		;PERIOD FOLLOWED BY SPACE?
LSPCD:	SKIPG	LINBK		;YES. ANY MOBE ROOM LEFT?
	JRST	LSPC1		;NO. JUST STORE THE SPACE
LSPC0:	MOVE	A,LNIN2		;YES. FORCE DOUBLE SPACE ON OUTPUT FILE
	MOVEM	A,LSTSP		;SAVE POINTER AT LAST (THIS) SPACE.
	MOVE	A,LINNSC	;POSITION OF LAST NON-SPACING CHARACTER
	MOVEM	A,LSTNSP	;SAVE AS LST ...
	AOS	SPCNT		;COUNT SPACING CHARACTER
	MOVEI	CH,C.SPC	;WRITE THIS SPACE INTO BUFFER
	PUSHJ	P,WLNINC	; ..
	MOVEI	CH,C.NXS	;NON-EXPANDABLE SPACE
	JRST	LIN3		; TO BUFFER. THUS 2 IF ANY AT ALL AFTER PD

LSPC1:	MOVE	A,LNIN2		;HERE TO STORE AND COUNT A SPACE
	MOVEM	A,LSTSP		;SAVE POSITION OF THIS SPACE
	MOVE	A,LINNSC	;AND NON-SPACING CHAR POSN
	MOVEM	A,LSTNSP	; ..
	AOS	SPCNT		;COUNT THIS SPACE
	MOVEI	CH,C.SPC	;SPACE CHARACTER (EXPANDABLE)
	JRST	LIN3		; ..
;ENTER HERE AFTER INITIALIZATION AND AT START OF EACH LINE.

;+
;^COMMANDS TO <RUNOFF ARE GIVEN ON LINES WHICH START WITH
;THE FLAG CHARACTER ".".  ^THIS CHARACTER MUST BE THE
;FIRST CHARACTER OF THE LINE TO BE RECOGNIZED.
;^MULTIPLE COMMANDS CAN BE GIVEN ON ONE LINE BY SEPARATING
;THEM BY THE CHARACTER ";" IN WHICH CASE THE PERIOD FLAG
;CHARACTER FOR THE NEXT COMMAND MUST FOLLOW IMMEDIATELY
;AFTER THE SEMI-COLON (OTHERWISE, THE LINE WOULD BE TREATED
;AS TEXT).  ^FOR COMPATABILITY WITH EARLIER VERSIONS OF
;<RUNOFF, A FEW COMMANDS (<TITLE, <SUBTITLE, AND <INDEX)
;DO NOT RECOGNIZE THE SEMI-COLON AS THE END OF THE COMMAND.
;^IF <RUNOFF IS IN .<AUTOPARAGRAPH MODE, A BLANK LINE
;OR A LINE STARTING WITH ONE OR MORE SPACES OR TABS WILL BE
;CONSIDERED THE START OF A NEW PARAGRAPH.
;-

LGO:	PUSHJ	P,CCIN		;READ INITIAL CHARACTER ON LINE
	IFEOF$	ENDFIL		;IF END OF FILE, ALL DONE
	CAMN	CH,CC.END	;END OF FOOTNOTE?
	JRST	FOOTND		;YES. GO FINISH FOOTNOTE PROCESSING
LGO1:	CAMN	CH,CC.CON	;PERIOD AS FIRST CHAR?
	JRST	CMN		;YES. GO READ COMMAND LINE
	TLNN	F,L.FILL	;SEE IF FILLING			[167]
	JRST	LGO2		;NO--IGNORE AUTOPARAG, ETC.	[167]
	CAIN	CH,.CHLFD	;SEE IF LINE-FEED
	JRST	LGOAP		;YES--MAYBE AUTO PARAGRAPH
	CAIE	CH,C.SPC	;LEADING SPACE?
	CAIN	CH,.CHTAB	; OR TAB?
	JRST	LGOAP		;YES--TRY AUTO PARAGRAPH
	TRNN	F,R.AUTB	;NO--SEE IF AUTO TABLE
	JRST	LGO2		;NO--PROCEED NORMALLY
	JRST	LGOSAP		;YES--GO SET AUTOPARAGRAPH
LGOAP:	TRNN	F,R.SPPR	;YES--IN .AUTOPARAGRAPH?
	JRST	LGO2		;NO
LGOSAP:	MOVEM	CH,GCSCH	;YES, SAVE CHAR FOR RE-EATING
	PUSHJ	P,PARAGF	;MAKE NEW PARAGRAPH
	PUSHJ	P,RSKIPS	;SKIP COMMAND SPACES AND TABS
	  SETOM	GCSCH		;CLEAR ANY RE-EATING
				CONT.
LGO2:	CAIN	CH,.CHLFD	;LINEFEED ON INPUT?
	JRST	LGO		;YES. IGNORE IT.
	MOVEM	CH,GCSCH	;NONE OF ABOVE SPECIAL CASES. SAVE.
				;DELETE SETZM LCH		[215]
	TLZE	F,L.NFSP	;SPECIAL HEADER CASE
	JRST	LIN		;GO START LINE WITHOUT FREE SPACE
	TLNE	F,L.FILL	;FILLING FROM INPUT FILE?
	JRST	LSPAC		;YES. TREAT AS IF A SPACE WERE INPUT
	MOVE	A,LNIN2		;SEE IF LINE EMPTY
	CAMLE	A,LNIN1		; (IF WE DIDN'T, IT WOULD CLEAR INDCT)
	JRST	LGO3		;NO--GO OUTPUT			[177]
	SKIPL	SPCNT		;IF SOME SPACES,		[177]
	AOS	SPCNT		; COUNT ONE MORE		[177]
	JRST	LGO4		;SKIP OUTPUT			[177]
LGO3:	PUSHJ	P,OUTLIN	;NO. OUTPUT THIS LINE
LGO4:	PUSHJ	P,LINSET	;THEN SETUP FOR NEW LINE
	JRST	LIN		;AND START ANOTHER.
	SUBTTL	DOT COMMAND SCANNER

;+
;.CHAPTER DOT COMMAND SCANNER
;-

;READ AND DISPATCH ON COMMAND

;+
;^COMMANDS TO <RUNOFF ARE EXPRESSED AS ONE OR TWO KEY-WORDS
;TO IDENTIFY THE COMMAND FOLLOWED BY OPTIONAL ARGUMENTS.
;^THE KEYWORDS MAY BE ABBREVIATED AS LONG AS ENOUGH LETTERS
;ARE TYPED TO ALLOW THE WORD TO BE RECOGNIZED UNIQUELY.
;^THIS FORM OF ABBREVIATION SHOULD ONLY BE USED TO DROP THE END
;OF VERY LONG COMMANDS BECAUSE THE ABBREVIATIONS ARE NOT
;GUARANTEED INTO NEW VERSIONS OF <RUNOFF.
;^SOME COMMANDS ARE USED SO OFTEN THAT A SINGLE LETTER ABBREVIATION
;HAS BEEN DEFINED. ^FOR THE REST, A TWO
;OR THREE LETTER ABBREVIATION HAS BEEN DEFINED.
;-

CMN:	PUSHJ	P,STRCMN	;INITIALIZE COMMAND ERROR POINTERS
	PUSHJ	P,CMGWD		;GET FIRST ALPHABETIC WORD ON COMMAND LINE
	  JRST	CMN1		;NO ALPHAS THERE. GO CONTEMPLATE.
	MOVE	S1,[XWD -CMTL1,CMTAB]	;POINTER TO COMMAND FIRST WORDS
CMNREP:	PUSHJ	P,CMREC		;TRY TO RECOGNIZE ONE.
	  JRST	ILCM		;NO GOOD.
	HLRZ	A,0(D)		;GET THE DISPATCH ADDRESS
	JRST	(A)		;AND GO TO IT. PARSE SECOND WORD AT
				; THAT CODE IF NEEDED.

				CONT.
;+
;^THE FIRST KEY-WORD OF A COMMAND LINE MUST START IN THE
;FIRST COLUMN FOLLOWING THE COMMAND FLAG CHARACTER ".".  ^IF THIS
;COLUMN DOES NOT HAVE AN ALPHABETIC IN IT, IT IS
;NOT A KEY-WORD COMMAND.  ^IN THIS CASE, IF IT
;IS A SPACE OR TAB, WE HAVE THE ULTIMATE ABBREVIATION FOR A
;_.<BREAK COMMAND.  ^SIMILARLY, IF THE LINE CONSISTS OF
;ONLY THE PERIOD (COMMAND FLAG CHARACTER), IT IS A BREAK.
;^IF THE CHARACTER IS "!" OR ";", THEN THE LINE
;IS A COMMENT (".;" IS RECOGNIZED AS A COMMENT FOR
;COMPATABILITY WITH PREVIOUS VERSIONS OF <RUNOFF).
;^FINALLY, IF THE LINE STARTS "..", THEN THIS IS TREATED AS
;THE SAME AS "__." WHICH IS A TEXT CHARACTER ".".
;-

CMN1:	CAIE	CH,C.SPC	;SPACE?
	CAIN	CH,.CHTAB	; OR TAB?
	JRST	$BREAK		;YES--DO A $BREAK
	CAIN	CH,.CHLFD	;BLANK COMMAND?
	JRST	$BREAK		;YES--DO A $BREAK
	CAIE	CH,C.SEMI	;COMMENT?
	CAIN	CH,C.COMT	; ..
	JRST	$COMME		;YES. NO ACTION.
	CAMN	CH,CC.CON	;COMMAND?
	JRST	LGO2		;NO--.. IS A TEXT .
	JRST	ILCM		;OTHERWISE, COMMAND LINE IS ILLEGAL.
$COMME:	SETOM	GCSCH		;CLEAR ANY RE-EATING
	PUSHJ	P,ENDCMT	;SKIP COMMENT
	JRST	ENDCMX		;COMPLETE COMMAND
;+
;^AFTER ALL THE ARGUMENTS FOR A COMMAND ARE FOUND, THE
;ONLY THING WHICH CAN REMAIN ON THE COMMAND LINE ARE
;SPACES, TABS, AND COMMENTS PRECEEDED BY THE CHARACTER "!".
;^COMMAND PROCESSORS WHICH CAUSE AN IMPLICIT BREAK USUALLY RETURN
;TO THE LOCATION "<ENDBCM" WHICH RESETS THE INPUT LINE
;BUFFER, SKIPS FINAL BLANKS AND COMMENTS AND RETURNS TO SCAN
;THE NEXT LINE. ^NOTE THAT THIS ROUTINE DOES NOT ACTUALLY
;FORCE OUT THE RESIDUAL TEXT IN THE LINE BUFFER; THAT IS
;ACCOMPLISHED BY THE INDIVIDUAL COMMAND ROUTINE'S CALLING THE
;ROUTINE "<OUTNJ".   ^COMMAND PROCESSORS WHICH DO NOT CAUSE AN
;IMPLICIT BREAK NORMALLY RETURN TO THE LOCATION "<ENDCM" WHICH
;SKIPS FINAL BLANKS AND COMMENTS AND RETURNS TO SCAN THE
;NEXT LINE.  ^COMMAND PROCESSORS WHICH HAVE ALREADY SCANNED TO
;THE END OF THE LINE (SUCH AS .<CENTER) RETURN TO THE LOCATION
;"<ENDCMX" WHICH SIMPLY CLEAR COMMAND MODE AND SCANS FOR
;THE NEXT LINE.
;-

ENDBCM:	PUSHJ	P,LINSET	;SET FOR NEW LINE (BREAK COMMAND)
ENDCM:	PUSHJ	P,FRCEND	;GO FORCE TO END OF COMMAND LINE
ENDCMX:	TRZ	F,R.CCOM	;CLEAR COMMAND INDICATOR
	PUSHJ	P,LINDFN	;CLEAR SPECIAL CASING RULES
	JRST	LGO		;GO DO NEXT PIECE OF WORK
;+
;^THE ROUTINE "<FRCEND" SKIPS TRAILING SPACES AND TABS AND
;COMMENTS STARTING WITH "!".  ^IF IT FINDS ANYTHING ELSE BEFORE
;THE FIRST ";" (MULTIPLE COMMAND INDICATOR) OR END OF LINE,
;IT ISSUES THE WARNING MESSAGE <JEC.
;-

FRCEND:	PUSHJ	P,RSKIPS	;SKIP OVER SPACES AND TABS
	  JRST	[CAIN CH,C.COMT  ;SEE IF COMMENT
		 JRST ENDCMT	;YES--GO HANDLE
		 JRST ENDCMN]	;NO--END OF COMMAND
	MSG$	JEC,WRN,,<Junk at end of command: ">
	PUSHJ	P,TYPCOM	;ISSUE COMMAND

;+
;^THE ROUTINE "<ENDCMT" SKIPS ALL CHARACTERS UNTIL THE
;FIRST ";" OR END OF LINE.  ^IT IS USUALLY INVOKED WHEN THE
;COMMENT INDICATOR ("!") IS SEEN IN A COMMAND.
;^THE ROUTINE "<ENDCMN" CLEARS COMMAND MODE.
;-

ENDCMT:	PUSHJ	P,CCIN		;GET NEXT CHAR
	CAIE	CH,C.SEMI	;SEE IF NEW COMMAND
	CAIN	CH,.CHLFD	;SEE IF END YET
	SKIPA			;YES--RETURN
	JRST	ENDCMT		;NO--LOOP
ENDCMN:	TRZ	F,R.CCOM	;CLEAR COMMAND INDICATOR
	SETOM	GCSCH		;CLEAR ANY RE-EATING
	CAMN	CH,CC.CON	;SEE IF PERIOD
	MOVEM	CH,GCSCH	;YES--SET TO RESCAN IT
	POPJ	P,
;SUBROUTINES FOR COMMAND SCANNER

;+
;^THE ROUTINE "<STRCMN" INITIALIZES A COMMAND LINE AND IS
;USUALLY CALLED AFTER THE COMMAND FLAG (".") IS SEEN.
;-

STRCMN:	TRO	F,R.CCOM	;SET COMMAND INDICATOR
	MOVEI	PA,CMEBFP	;POINT TO COMMAND ERROR POINTERS
	PJRST	RCI		;RESET POINTERS

;+
;^MOST COMMANDS ARE PARSED BY CALLING THE COMMAND GET CHARACTER
;ROUTINE "<CMCIN" WHICH IS THE STANDARD GET CHARACTER ROUTINE
;WITH THE ADDITION THAT LOWER CASE ALPHABETICS (A-Z) ARE
;CONVERTED TO UPPER CASE (^A-^Z).
;
;^THE ROUTINE "<CMCFUC" WILL FORCE A LOWER CASE ALPHABETIC
;INTO UPPER CASE.
;-

CMCIN:	PUSHJ	P,CCIN		;READ FROM INPUT FILE
CMCFUC:	CAIG	CH,"Z"+ULCAS	;CHECK FOR LOWER CASE LETTERS
	CAIGE	CH,"A"+ULCAS	;..
	POPJ	P,		;NO. RETURN CHARACTER
	TRZ	CH,ULCAS	;YES. MAKE UPPER CASE FOR COMMAND ROUTINE
	POPJ	P,		; AND RETURN UC EQUIVALENT
;ILLEGAL COMMAND ROUTINE

;+
;^INCORRECT COMMANDS CAN BE FLAGGED BY JUMPING TO THE ROUTINE
;"<ILCM" FROM THE TOP-LEVEL OF ANY COMMAND PROCESSOR.  ^IT
;DISCARDS THE REST OF THE COMMAND LINE AND ISSUES THE FATAL
;MESSAGE <ILC.
;^ALTERNATIVELY, THE COMMAND PROCESSOR CAN INVOKE THE
;MACRO <ILCM$ WHICH WILL ISSUE A SPECIFIC FATAL MESSAGE
;BY JUMPING TO THE LOCATION "<ILCMSG" WITH LH(^A) CONTAINING THE
;ERROR PREFIX AND THE RH(^A) POINTING TO THE MESSAGE
;WHICH SHOULD BE UNDER 28 CHARACTERS LONG. ^EITHER ROUTINE WILL FOLLOW THE MESSAGE
;WITH THE FIRST 30 CHARACTERS OF THE COMMAND AND THE CLOSING
;QUOTE MARK.  ^FINALLY, A SECOND LINE WILL BE ADDED WHICH GIVES
;THE INPUT AND OUTPUT FILE LOCATIONS OF THE ERROR.
;-

ILCM:	PUSHJ	P,ENDCMT	;NOW ADD REST OF LINE
	ILCM$	ILC,Illegal command
;HERE FROM MANY ERROR ROUTINES
;INVOKED BY THE ILCM$ MACRO
ILCMSG:	PUSHJ	P,ERRMSG	;ISSUE ERROR MESSAGE
	PUSHJ	P,TYPCOM	;TYPE MESSAGE, ETC.
	JRST	ENDCMX		;GO DISCARD THE REST OF COMMAND LINE
;ROUTINE TO TYPE ERROR MESSAGE, COMMAND LINE, AND LOCATION

;+
;^THE ROUTINE "<TYPCOM" IS CALLED AFTER ISSUING A MESSAGE
;WHICH SHOULD END WITH THE SEQUENCE ':#"'.  ^THIS WILL
;BE FOLLOWED BY THE COMMAND LINE TEXT IN ERROR UP TO
;A MAXIMUM OF 30 CHARACTERS FOLLOWED BY A QUOTE.  ^THEN
;THE MESSAGE WILL BE FOLLOWED BY ANOTHER LINE WHICH
;GIVES THE INPUT AND OUTPUT FILE LOCATIONS OF THE ERROR.
;^THE ERROR MESSAGE SHOULD BE NO MORE THAN 28 CHARACTERS
;EXCLUDING THE STANDARD PREFIX AND THE ':#"'.
;^THIS WILL ENSURE THAT THE MESSAGE FITS ON ONE 72-COLUMN LINE.
;-

TYPCOM:	PUSHJ	P,.VERBO##	;GET /MESSAGE
	TXNN	A,JWW.FL	;SEE IF :NOFIRST
	PJRST	.TCRLF##	;YES--JUST GIVE END OF LINE
	HRRZ	A,CC.CON	;GET COMMAND FLAG
	PUSHJ	P,.TFCHR##	;ISSUE IT
TYPCM1:	MOVEI	PA,CMEBFP	;READ OUT COMMAND BUFFER
	PUSHJ	P,GCI		; TO TELETYPE
	  JRST	ILCM4		;END OF LINE
	CAIE	CH,C.SEMI	;SEE IF MULT. COMMAND
	CAIN	CH,.CHLFD	;OR END OF LINE
	JRST	ILCM4		;YES--ALL DONE
	MOVE	A,CH		;GET CHARACTER
	ANDI	A,CHRMSK	;REMOVE QUOTE
	PUSHJ	P,.TFCHR##	;TYPE IT
	JRST	TYPCM1		;LOOP FOR WHOLE LINE
ILCM4:	MOVEI	A,""""
	PUSHJ	P,.TCHAR##
;+
;^ROUTINE "<ONPAG" SHOULD BE CALLED AFTER EVERY ERROR MESSAGE
;TO IDENTIFY THE INPUT AND OUTPUT FILE LOCATIONS OF THE ERROR.
;^IT STARTS WITH A CARRIAGE-RETURN LINE-FEED PAIR, THEN TABS IN
;AND GIVES THE OUTPUT PAGE NUMBER, THE INPUT LINE COUNT FOR THIS
;INPUT PAGE, THE LINE SEQUENCE NUMBER IF THE FILE IS SEQUENCED
;AND THE INPUT PAGE NUMBER.  ^IT ENDS WITH A CARRIAGE-RETURN
;LINE-FEED PAIR.
;-

ONPAG:	PUSHJ	P,.VERBO##	;GET /MESSAGE
	TXNN	A,JWW.FL	;SEE IF :NOFIRST
	PJRST	.TCRLF##	;YES--IGNORE THIS LINE
	MOVEI	A,[ASCIZ /
	on output page /]

	PUSHJ	P,.TSTRG
	SAVE$	<B,C>
	SKIPN	A,SECNUM	;SEE IF CHAPTERS
	JRST	ONPAG0		;NO--PROCEED
	PUSHJ	P,TYPCHP	;YES--GIVE NUMBER
	MOVEI	A,"-"		;AND
	PUSHJ	P,.TCHAR	;SEPARATE IT
ONPAG0:	MOVE	A,PAGENO
	PUSHJ	P,.TDECW	;OUTPUT PAGE NUMBER
	SKIPN	A,SUBPGE	;SEE IF IN SUB-PAGE
	JRST	ONPAG1		;NO--PROCEED BELOW
	ADDI	A,"A"-2		;CONVERT TO LETTER
	CAILE	A,"Z"		;SEE IF ALPHA
	MOVEI	A,"?"		;NO--INDICATE OVERFLOW
	PUSHJ	P,.TCHAR	;TYPE IT ALSO
				CONT.
ONPAG1:	TLNE	F,L.FOOT	;SEE IF IN FOOTNOTE
	JRST	[MOVEI A,[ASCIZ /; in footnote/]
		 PUSHJ P,.TSTRG	;YES--DON'T KNOW PAGE
		 JRST  ONPAGX]	;FINISH UP
	MOVEI	A,[ASCIZ /; on input line /]
	PUSHJ	P,.TSTRG
	MOVE	A,INLINE	;GET INPUT LINE NUMBER
	PUSHJ	P,.TDECW	;TYPE LINE NUMBER
	SKIPN	B,INSEQN	;SEE IF THIS LINE
	MOVE	B,INSEQL	;NO--GET PREVIOUS
	JUMPE	B,ONPAG2	;GIVE UP IF NEITHER
	MOVEI	A,[ASCIZ / (line # /]
	PUSHJ	P,.TSTRG
	MOVEI	A,B		;POINT TO LITERAL
	MOVEI	C,0		;TERMINATE STRING
	PUSHJ	P,.TSTRG	;TYPE IT
	MOVEI	A,")"		;CLOSE BRACKET
	PUSHJ	P,.TCHAR
ONPAG2:	MOVEI	A,[ASCIZ / of page /]
	PUSHJ	P,.TSTRG
	MOVE	A,INPAGE	;GET INPUT PAGE COUNTER
	AOS	A		;PAGE COUNTER IS ONE SHY
	PUSHJ	P,.TDECW
ONPAGX:	RSTR$	<C,B>
	PJRST	.TCRLF##
;GET NEXT COMMAND WORD INTO CMBF.

;+
;^THE ROUTINES "<CMGNWD" AND "<CMGWD" ARE USED
;BY COMMAND PROCESSORS TO SCAN ALPHABETIC WORDS FROM A COMMAND
;LINE.  "<CMGWD" READS THE NEXT STRING OF ALPHABETICS
;INTO THE COMMAND BUFFER "<CMBF" AND TERMINATES ON THE FIRST
;NON-ALPHABETIC FOUND, WHICH IS LEFT IN ACCUMULATOR <CH
;AND LOCATION <GCSCH.
;"<CMGNWD" DOES THE SAME THING EXCEPT THAT IT FIRST SKIPS
;ANY LEADING SPACES OR TABS.  ^THUS, IT IS USED FOR GETTING THE
;NEXT WORD IN A COMMAND.
;-

CMGNWD:	PUSHJ	P,RSKIPS	;SKIP SPACES AND TABS
	  JFCL			;IGNORE EOL

;COMMAND GET WORD INTO CMBF. TERMINATES ON NON-ALPHABETIC.
;SKIPS UNLESS THERE ARE NO ALPHABETICS AT ALL.
CMGWD:	MOVEI	PA,CMBF		;INITIAL STRING POINTER TO WORD BUFFER
	PUSHJ	P,CSP		;MAKE THE POINTER
	MOVEM	A,CMSTP		;STORE IT
	MOVEM	B,CMST2		; ..
	TRZ	F,R.MULN	;INDICATE NOT STRING OF NUMBERS  YET
	MOVEI	N,<ECMBF-CMBF>*5	;FOR END TEST
CMGWDL:	PUSHJ	P,CMCIN		;GET AN UPPER CASE CHARACTER
	CAIG	CH,"Z"		;ALPHABETIC?
	CAIGE	CH,"A"		; ..
	JRST	CMGWD1		;NO. GO SEE IF EMPTY WORD.
	MOVEI	PA,CMSTP	;WHERE TO PUT THE CHARACTERS
	SOSLE	N		;MAKE SURE THERE'S ROOM.
	PUSHJ	P,WCI		;STORE IT.
	JRST	CMGWDL		;LOOP TO END OF WORD.

CMGWD1:	MOVEM	CH,GCSCH	;STORE BREAK CHARACTER FOR RESCAN
	MOVE	A,CMSTP		;WAS THERE ANYTHING AT ALL?
	CAME	A,CMST2		; ..
	AOS	(P)		;YES. SKIP RETURN
	POPJ	P,		;NO. NON-SKIP.
;COMMAND RECOGNIZER

;+
;^THE ROUTINE "<CMREC" COMPARES A WORD FOUND BY THE ROUTINE
;"<CMGWD" AGAINST A LIST OF CANDIDATES AND FINDS THE ONE
;WHICH MATCHES, ALLOWING FOR ABBREVIATIONS.  ^THE LIST OF
;CANDIDATES IS PASSED AS AN <AOBJN POINTER IN ACCUMULATOR
;^S1 (I.E., IN THE FORM -LENGTH,,LOCATION) WHERE THE RIGHT HALF
;OF EACH WORD IN THE TABLE IS THE ADDRESS OF AN <ASCIZ STRING
;OF THE WORDS IN UPPER CASE.  ^THIS ROUTINE WILL TAKE THE NON-SKIP
;RETURN IF THE WORD IS NOT RECOGNIZED.  ^IF THE WORD IS
;RECOGNIZED, IT WILL SKIP RETURN WITH ACCUMULATOR ^D POINTING
;TO THE SUCCESSFUL ENTRY.  ^THUS, THE TYPICAL CALLING PATTERN
;IS: ^^
;.LEFT MAR 5.TAB STOP 5,13,29
;. ;MOVE	S1,[-LENGTH,,TABLE]
;. ;PUSHJ	P,CMREC	;RECOGNIZE WORD
;. ;##JRST	ERROR	;HERE IF NOT RECOGNIZABLE
;. ;HLRZ	A,(D)	;GET VALUE
;.LEFT MAR 0
;\\
;-

CMREC:	SETO	N1,		;START COUNTER OF MATCHES AT -1
	MOVE	B,CMST2
	MOVEM	B,TT2
CMREC1:	MOVE	A,CMSTP		;COPY OVER THE POINTER TO TEST WORD
	MOVEM	A,TT1		;INTO TT1/TT2
	HRRZ	S2,(S1)		;MAKE POINTER TO A TABLE ENTRY
	HRLI	S2,(POINT 7,)	; ..
	MOVEI	PA,TT1		;FOR GCI ROUTINE
CMRECL:	PUSHJ	P,GCI		;GET CHAR FROM USERS WORD
	  JRST	CMRECA		;END OF HIS STRING
	ILDB	X,S2		;ONE FROM TABLE
	CAMN	X,CH		;DO THEY MATCH?
	JRST	CMRECL		;YES. LOOK ONWARD.
CMREC2:	AOBJN	S1,CMREC1	;TRY ANOTHER COMMAND
	JUMPN	N1,CPOPJ	;IF 0 OR .GE. 2 MATCHES, QUIT.
	JRST	CPOPJ1		;ONE MATCHING ABBREVIATION. SKIP RETURN.

;HERE IF MATCHED TO END OF USER INPUT
CMRECA:	MOVE	D,S1		;COPY CURRENT POINTER IN CASE UNIQUE
	ILDB	X,S2		;GET NEXT COMMAND LIST CHARACTER
	JUMPE	X,CPOPJ1	;IF NULL, MATCH IS EXACT. QUIT.
	AOJA	N1,CMREC2	;NOT EXACT. COUNT ABBREV'S,
;READ SIGNED DECIMAL NUMBER FOR COMMAND DECODER
;RCNR--UPDATE N IF RELATIVE OR ABSOLUTE AND NON-SKIP IF NULL
;RCNO--NON-SKIP IF NULL NUMBER (NO DIGIT)
;RCN--NON-SKIP AT EOL
;RETURN N=NUMBER, N1=+-1 IF SIGNED, 0 IF NOT

;+
;^THE ROUTINES "<RCN", "<RCNO", AND "<RCNR" ALL
;READ DIFFERENT FLAVORS OF THE NEXT DECIMAL NUMBER.  "<RCN"
;READS THE NUMBER WITH A POSSIBLE SIGN.  ^IF NO NUMBER
;IS PRESENT, IT TAKES THE NON-SKIP RETURN.  ^OTHERWISE,
;IT SKIPS LEADING SPACES AND TABS, READS THE NUMBER, AND SKIP
;RETURNS WITH THE VALUE IN ACCUMULATOR ^N AND WITH ACCUMULATOR
;^N1 SET TO -1, 0, OR +1 IF THE NUMBER WAS PRECEEDED BY A MINUS,
;NO SIGN, OR A PLUS RESPECTIVELY.  ^IF THIS ROUTINE IS CALLED
;SEVERAL TIMES IN SUCCESSION, IT WILL ALLOW THE NUMBERS
;TO BE SEPARATED BY EITHER SPACES AND TABS OR BY ONE COMMA WHICH
;MAY BE SURROUNDED BY ANY NUMBER OF SPACES AND TABS.
;^THE ROUTINE "<RCNO" DOES THE SAME EXCEPT THAT IT WILL
;ALSO TAKE THE NON-SKIP RETURN IF THE VALUE WAS NULL (I.E., NO
;DIGIT WAS TYPED); WHEREAS "<RCN" NON-SKIPS ONLY AT END OF
;COMMAND.  ^THE ROUTINE "<RCNR" ACCEPTS A RELATIVE
;OR ABSOLUTE VALUE AND GIVES THE NON-SKIP RETURN ANYTIME THE
;VALUE IS ABSENT.  ^IT IS CALLED WITH THE STANDARD OR CURRENT
;VALUE IN ACCUMULATOR ^N AND RETURNS WITH THIS UPDATED IF
;RELATIVE OR REPLACED IF ABSOLUTE.  ^RELATIVE NUMBERS ARE
;INDICATED BY BEING SIGNED, WHILE ABSOLUTE NUMBERS HAVE NO
;SIGN.  ^IF THE NON-SKIP RETURN IS TAKEN, ACCUMULATOR ^N
;WILL BE LEFT UNALTERED.
;-

RCNR:	PUSH	P,N		;SAVE CURRENT VALUE
	PUSHJ	P,RCN		;READ NUMBER
	  JFCL			;IGNORE EOL
	SKIPN	N1		;SEE IF RELATIVE (+-)
	TRNN	F,R.NNUL	;OR NULL
	ADD	N,(P)		;YES--ADD CURRENT VALUE
	POP	P,(P)		;DISCARD INPUT
	SKIPN	N1		;SEE IF SIGN
	TRNE	F,R.NNUL	;OR DIGIT
	JRST	CPOPJ1		;YES--SKIP RETURN
	POPJ	P,		;NO--NON-SKIP

RCNO:	PUSHJ	P,RCN		;GET NUMBER
	  POPJ	P,		;IF EOL, NULL
	TRNN	F,R.NNUL	;SEE IF NULL
	POPJ	P,		;YES--RETURN AS SUCH
	JRST	CPOPJ1		;NO--RETURN VALUE
				CONT.
RCN:	SETZB	N,N1		;CLEAR ANSWER AC
	TRZ	F,R.NNUL	;SET FOR NULL VALUE
	PUSHJ	P,RSKIPS	;SKIP LEADING SPACES AND TABS
	  POPJ	P,		;RETURN IF EOL
	TRNE	F,R.MULN	;SEE IF MULTIPLE VALUES
	CAIE	CH,C.CMA	; AND COMMA
	JRST	RCNS		;NO--GO CHECK SIGN
	SETOM	GCSCH		;DON'T RE-EAT
	PUSHJ	P,RSKIPS	;YES--SKIP COMMA AND SPACES AND TABS
	  JRST	RCNX		;EXIT IF EOL
;HERE TO CHECK FOR SIGN
RCNS:	CAIN	CH,C.PLUS	;SEE IF +
	MOVEI	N1,1		;YES--SET FLAG
	CAIN	CH,C.MINS	;SEE IF -
	SETOM	N1		;YES--SET FLAG
	SKIPE	N1		;SEE IF SIGNED,
	SETOM	GCSCH		;YES--DON'T RE-EAT SIGN
RCNL:	PUSHJ	P,CCIN		;READ ANOTHER CHARACTER
	CAIG	CH,"9"		;THIS CHAR A DIGIT?
	CAIGE	CH,"0"		; ..
	JRST	RCNX		;NO. STOP HERE.
	IMULI	N,12
	ADDI	N,-"0"(CH)	;YES. ADD IN THIS DIGIT
	TRO	F,R.NNUL	;FLAG SOMETHING THERE
	JRST	RCNL		;AND LOOP FOR MORE.

;+
;^THE ROUTINE <RCANO IS JUST LIKE <RCNO WITHOUT SIGNS
;EXCEPT THAT ITS INPUT IS ALPHABETICS, RADIX 26.
;-

RCANO:	PUSHJ	P,RCAN		;GET NUMBER
	  POPJ	P,		;IF EOL, NULL
	TRNN	F,R.NNUL	;SEE IF NULL
	POPJ	P,		;YES--RETURN AS SUCH
	JRST	CPOPJ1		;NO--RETURN VALUE

RCAN:	SETZB	N,N1		;CLEAR ANSWER AC
	TRZ	F,R.NNUL	;SET FOR NULL VALUE
	PUSHJ	P,RSKIPS	;SKIP LEADING SPACES AND TABS
	  POPJ	P,		;RETURN IF EOL
	TRNE	F,R.MULN	;SEE IF MULTIPLE VALUES
	CAIE	C,C.CMA		; AND COMMA
	JRST	RCANL		;NO--GO INPUT NUMBER
	SETOM	GCSCH		;DON'T RE-EAT
	PUSHJ	P,RSKIPS	;YES--SKIP COMMA AND SPACES AND TABS
	  JRST	RCNX		;EXIT IF EOL
				CONT.
RCANL:	PUSHJ	P,CMCIN		;GET CHARACTER IN UPPER CASE
	CAIG	CH,"Z"		;SEE IF LETTER
	CAIGE	CH,"A"		; ..
	JRST	RCNX		;NO--STOP HERE.
	IMULI	N,^D26		;ADVANCE RAD 26
	ADDI	N,1-"A"(CH)	;ADD IN THIS DIGIT
	TRO	F,R.NNUL	;FLAG SOMETHING THERE
	JRST	RCANL		;LOOP FOR MORE


;HERE TO EXIT FROM NUMERIC INPUT ROUTINES

RCNX:	SKIPGE	N1		;IS SIGN NEGATIVE?
	MOVNS	N		;NEGATE NUMBER
	MOVEM	CH,GCSCH	;STORE BREAK CHARACTER
	TRO	F,R.MULN	;SET MULTIPLE NUMBERS FLAG
	JRST	CPOPJ1		;AND RETURN FROM RCNO


;+
;^THE ROUTINE "<RSIXN" WILL READ THE NEXT WORD IN <SIXBIT
;AND RETURN THE FIRST SIX LETTERS IN ^N.  ^ONLY ALPHABETICS
;ARE ALLOWED.
;-

RSIXN:	MOVE	D,[POINT 6,N]	;SETUP POINTER TO ANSWER
	MOVEI	N,0		;CLEAR ACCUMULATOR
	PUSHJ	P,RSKIPS	;SKIP TO NEXT WORD
	  JFCL			;IGNORE EOL
RSIXL:	PUSHJ	P,CMCIN		;GET CHARACTER IN UPPER CASE
	CAIG	CH,"Z"		;SEE IF LETTER
	CAIGE	CH,"A"		; ..
	JRST	[MOVEM	CH,GCSCH  ;NO--PREPARE TO REEAT LATER
		 POPJ  P,]	;RETURN
	SUBI	CH,40		;YES--CONVERT TO SIXBIT
	TLNE	D,(77B5)	;SEE IF OVERFLOW
	IDPB	CH,D		;NO--STORE AWAY
	JRST	RSIXL		;AND LOOP
;ROUTINE TO SKIP SPACES AND TABS
;NON-SKIP RETURN IF EOL

;+
;^THE ROUTINE "<RSKIPS" WILL SKIP CONSECUTIVE SPACES
;AND TABS UNTIL IT FINDS A CHARACTER WHICH IS NEITHER.  ^IF
;IT REACHES THE END OF THE COMMAND, IT WILL TAKE THE NON-SKIP
;RETURN, OTHERWISE IT TAKES THE SKIP RETURN WITH THE
;CHARACTER IN ACCUMULATOR <CH AND IN LOCATION <GCSCH.
;-

RSKIPS:	PUSHJ	P,CCIN		;GET NEXT CHAR
	PUSHJ	P,CMSOME	;SEE IF SOMETHING ELSE
	  JRST	RSKIPL		;NO--GIVE EOL RETURN
	CAIE	CH,C.SPC	;SEE IF SPACE
	CAIN	CH,.CHTAB	; OR TAB
	JRST	RSKIPS		;YES--SKIP ONWARD
	AOS	(P)		;NO--GIVE SKIP RETURN
RSKIPL:	MOVEM	CH,GCSCH	;STORE CODE
	POPJ	P,		;RETURN


;+
;^THE ROUTINE "<CMSOME" WILL CHECK THE
;CURRENT CHARACTER TO SEE IF IT IS THE END OF A COMMAND.  ^IF
;SO, THE NON-SKIP RETURN WILL BE TAKEN.  ^OTHERWISE,
;THE SKIP RETURN WILL BE TAKEN. ^THE ROUTINE <CMSOMP IS THE
;SAME EXCEPT IT IS USED BY COMMANDS WHICH TAKE TEXT ARGUMENTS.
;-

CMSOME:	CAIE	CH,C.COMT	;SEE IF COMMENT INDICATOR
	CAMN	CH,CC.CON	;OR PERIOD (NEXT COMMAND)
	POPJ	P,		;YES--END OF COMMAND
CMSOMP:	CAIE	CH,C.SEMI	;SEE IF SEMICOLON (MULT. COMMANDS)
	CAIN	CH,.CHLFD	;OR END OF LINE
	POPJ	P,		;YES--END OF COMMAND
	JRST	CPOPJ1		;NO--MORE COMMING
;+
;.CHAPTER DOT COMMAND PROCESSORS
;
;^COMMAND DISPATCH ADDRESSES ARE NAMED AS FOLLOWS:
;. ;^IF IT IS A ONE WORD COMMAND, THE NAME IS $ FOLLOWED
;BY THE FIRST FIVE CHARACTERS OF THE KEYWORD (E.G.,
;$<FIGUR FOR THE COMMAND .<FIGURE.
;. ;^IF IT IS A TWO WORD COMMAND, THE FIRST WORD DISPATCH
;IS $$ FOLLOWED BY THE FIRST FOUR CHARACTERS OF THE KEYWORD
;(E.G., $$<RIGH FOR THE COMMANDS .<RIGHT
;AND .<RIGHT <MARGIN).  ^IF THERE ARE
;BOTH SINGLE AND DOUBLE WORD COMMANDS WITH THE SAME FIRST
;WORD THEN THE SINGLE COMMAND WILL RE-DISPATCH TO THE
;LOCATION $ FOLLOWED BY THE FIRST FIVE LETTERS OF THE NAME
;(E.G., $<RIGHT IN THE PREVIOUS EXAMPLE).
;. ;^FOR TWO WORD COMMANDS, THE SECOND WORD DISPATCH IS
;$ FOLLOWED BY THE FIRST TWO LETTERS OF THE FIRST WORD FOLLOWED
;BY . FOLLOWED BY THE FIRST TWO LETTERS OF THE SECOND WORD
;(E.G., ^^$RI.MA\\ IN THE PREVIOUS EXAMPLE).
;. ;^COMMANDS WHICH ARE STRICT SYNONYMS USE THE MAIN VERSION'S
;NAME TO DETERMINE THE DISPATCH LOCATION.
;-

DEFINE CM (A,B) <	XWD A,[ASCIZ \B\]	>

				CONT.
CMTAB:			;TABLE OF FIRST WORD OF COMMANDS

	CM	$AUTOP,<AP>
	CM	$APPEN,<APPENDIX>;	AX
	CM	$AUTOT,<AT>
	CM	$AUTOP,<AUTOPARAGRAPH>;	AP
	CM	$AUTOT,<AUTOTABLE>;	AT
	CM	$APPEN,<AX>

	CM	$BLANK,<B>
	CM	$BE.BA,<BB>
	CM	$$BEGI,<BEGIN>;		BB
	CM	$BLANK,<BLANK>;		B
	CM	$BREAK,<BR>
	CM	$BREAK,<BREAK>;		BR

	CM	$CENTE,<C>
	CM	$CO.CH,<CC>
	CM	$CENTE,<CENTER>;	C
	CM	$CENTE,<CENTRE>;	C
	CM	$CHAPT,<CH>
	CM	$CHAPT,<CHAPTER>;	CH
	CM	$COMME,<COMMENT>
	CM	$$CONT,<CONTROL>;	CC

	CM	$DI.BA,<DBB>
	CM	$$DISA,<DISABLE>;	DBB
	CM	$$DO,<DO>;		DX
	CM	$DO.IN,<DX>

	CM	$$END,<E>
	CM	$EN.BA,<EB>
	CM	$AN.BA,<EBB>
	CM	$$ENAB,<ENABLE>;		EBB
	CM	$ENDIF,<EI>
	CM	$EN.LI,<EL>
	CM	$END,<ELS>
	CM	$ELSE,<ELSE>;		***NO ABBR***
	CM	$$END,<EN>
CMEND:	CM	$$END,<END>;		EL,ELS,EN,ES,ESL
	CM	$ENDIF,<ENDIF>;		EI
	CM	$EN.SU,<ES>
	CM	$EN.SE,<ESL>
				CONT.
	CM	$FILL,<F>
	CM	$FIGURE,<FG>
	CM	$FIGUR,<FIGURE>;	FG
	CM	$FILL,<FILL>;		F
	CM	$$FIRS,<FIRST>;		FT
	CM	$FLAGS,<FL>
	CM	$FLAGS,<FLAGS>;		FL
	CM	$FOOTN,<FN>
	CM	$FOOTN,<FOOTNOTE>;	FN
	CM	$FI.TI,<FT>

	CM	$HEADE,<HD>
	CM	$$HEAD,<HEADERS>;	HD,HL
	CM	$HE.LE,<HL>

	CM	$INDEN,<I>
	CM	$IF,<IF>;		IF
	CM	$IFNOT,<IFNOT>;		IN
	CM	$IFNOT,<IN>
	CM	$INDEN,<INDENT>;	I
	CM	$INDEX,<INDEX>;		X

	CM	$JUSTI,<J>
	CM	$JUSTI,<JUSTIFY>;	J

	CM	$$LEFT,<L>
	CM	$LO.CA,<LC>
	CM	$LI.EL,<LE>
	CM	$$LEFT,<LEFT>;		L,LM
	CM	$$LIST,<LIST>;		LE,LS
	CM	$LITER,<LITERAL>;	LT
	CM	$LE.MA,<LM>
	CM	$$LOWE,<LOWER>;		LC
	CM	$LIST,<LS>
	CM	$LITER,<LT>
				CONT.
	CM	$$NO,<N>
	CM	$NOAUT,<NAP>
	CM	$NOAUT,<NAT>
	CM	$NO.CH,<NCC>
	CM	$NOFIL,<NF>
	CM	$NOFLA,<NFL>
	CM	$NOHEA,<NHD>
	CM	$NOJUS,<NJ>
	CM	$NUMBE,<NM>
	CM	$NONUM,<NNM>
	CM	$$NO,<NO>;		N
	CM	$NOAUT,<NOAUTOPARAGRAPH>; NAP
	CM	$NOAUT,<NOAUTOTABLE>;	NAT
	CM	$$NOCO,<NOCONTROL>;	NCC
	CM	$NOFIL,<NOF>
	CM	$NOFIL,<NOFILL>;	NF
	CM	$NOFLA,<NOFLAGS>;	NFL
	CM	$NOHEA,<NOHEADERS>;	NHD
	CM	$NOJUS,<NOJUSTIFY>;	NJ
	CM	$NONUM,<NONUMBER>;	NNM
	CM	$NOPAG,<NOPAGING>;	NPA
	CM	$NOPER,<NOPERIOD>;	NPR
	CM	$NOSEL,<NOSELECTION>;	NSL
	CM	$NOSPA,<NOSPACE>;	NSP
	CM	$NOSUB,<NOSUBTITLE>;	NST
	CM	$NOTE,<NOTE>;		NT
	CM	$NOPAG,<NPA>
	CM	$NOPER,<NPR>
	CM	$NOSEL,<NSL>
	CM	$NOSPA,<NSP>
	CM	$NOSUB,<NST>
	CM	$NOTE,<NT>
	CM	$NUMBE,<NUMBER>;	NM
				CONT.
	CM	$PARAG,<P>
	CM	$PAGIN,<PA>
	CM	$$PAGE,<PAG>
	CM	$$PAGE,<PAGE>;		PG,PS
	CM	$PAGIN,<PAGING>;	PA
	CM	$$PAPE,<PAPER>;		PS
	CM	$PARAG,<PARAGRAPH>;	P
	CM	$PERIO,<PERIOD>;	PR
	CM	$PAGE,<PG>
	CM	$PERIO,<PR>
	CM	$$PRIN,<PRINT>;		PX
	CM	$PA.SI,<PS>
	CM	$PR.IN,<PX>

	CM	$$RIGH,<R>
	CM	$$RIGH,<RIGHT>;		R,RM
	CM	$RI.MA,<RM>

	CM	$SKIP,<S>
	CM	$STAND,<SD>
	CM	$SELEC,<SELECTION>;	SL
	CM	$SKIP,<SKIP>;		S
	CM	$SELEC,<SL>
	CM	$SPACI,<SP>
	CM	$SPACI,<SPACING>;	SP
	CM	$SUBPA,<SPG>
	CM	$SUBTI,<ST>
	CM	$STAND,<STANDARD>;	SD
	CM	$SUBIN,<SUBINDEX>;	X
	CM	$SUBPA,<SUBPAGE>;	SPG
	CM	$SUBTI,<SUBT>
	CM	$SUBTI,<SUBTITLE>;	ST
	CM	$SUBTI,<SUBTTL>;	ST
				CONT.
	CM	$TITLE,<T>
	CM	$$TAB,<TAB>;		TS
	CM	$$TEST,<TEST>;		TP
	CM	$TITLE,<TITLE>;		T
	CM	$TE.PA,<TP>
	CM	$TA.ST,<TS>
	CM	$TYPES,<TY>
	CM	$TYPES,<TYPESET>;	TY

	CM	$UP.CA,<UC>
	CM	$$UPPE,<UPPER>;		UC

	CM	$VARIA,<VARIABLE>;	VR
	CM	$VARIA,<VR>

	CM	$SUBIN,<X>
CMTL1==.-CMTAB
;+

;.HL1	_.NO COMMAND

;^THIS COMMAND TAKES A SECOND WORD TO DETERMINE
;THE COMMAND.  ^IT THEN DISPATCHES ON THAT WORD.  ^EACH .<NO
;COMMAND APPEARS IN THE COMMAND TABLE TWICE, ONCE AS A
;SINGLE KEYWORD COMMAND OF THE FORM .^^NO\\XXX AND ONCE AS A
;TWO WORD COMMAND OF THE FORM .<NO XXX.
;-

$$NO:	MOVE	S1,[-CMNTL1,,CMNTAB]  ;POINT TO NO TABLE
	PUSHJ	P,CMGNWD	;GET NEXT WORD
	  JRST	ILCM		;ILLEGAL IF MISSING
	JRST	CMNREP		;GO SCAN/DISPATCH

CMNTAB:			;NO COMMAND TABLE
	CM	$NOAUT,<AP>
	CM	$NOAUT,<AT>
	CM	$NOAUT,<AUTOPARAGRAPH>;	AP
	CM	$NOAUT,<AUTOTABLE>;	AT
	CM	$NO.CH,<CC>
	CM	$$NOCO,<CONTROL>;	CC
	CM	$NOFIL,<F>
	CM	$NOFIL,<FILL>;		F
	CM	$NOFLA,<FL>
	CM	$NOFLA,<FLAGS>;		FL
	CM	$NOHEA,<HD>
	CM	$NOHEA,<HEADERS>;	HD
	CM	$NOJUS,<J>
	CM	$NOJUS,<JUSTIFY>;	J
	CM	$NONUM,<NM>
	CM	$NONUM,<NUMBER>;	NM
	CM	$NOPAG,<PA>
	CM	$NOPAG,<PAGING>;	PA
	CM	$NOPER,<PERIOD>;	PR
	CM	$NOPER,<PR>
	CM	$NOSEL,<SELECTION>;	SL
	CM	$NOSEL,<SL>
	CM	$NOSUB,<ST>
	CM	$NOSUB,<SUBTITLE>;	ST
CMNTL1==.-CMNTAB
;+

;.HL1	_.END COMMAND

;^THIS COMMAND TAKES A SECOND KEYWORD TO DEFINE THE COMMAND.
;^IT THEN REDISPATCHES BASED ON THIS SECOND WORD.
;-

$$END:	MOVE	S1,[-ECMTL1,,ECMTAB]
	PUSHJ	P,CMGNWD	;GET NEXT WORD
	  JRST	$END		;.END IF NONE
	JRST	CMNREP		;GO SCAN/DISPATCH

ECMTAB:	CM	$EN.BA,<BAR>
	CM	$EN.FO,<FOOTNOTE>
	CM	$END,<LIST>
	CM	$EN.LI,<LITERAL>
	CM	$END,<NOTE>
	CM	$EN.SE,<SELECTION>
	CM	$EN.SU,<SUBPAGE>
ECMTL1==.-ECMTAB
;+

;.HL1	TWO WORD COMMANDS

;^EACH OF THESE COMMANDS TAKES EXACTLY ONE WORD AS THE SECOND
;KEYWORD.  ^THESE CAN EVEN HAVE THAT WORD ABBREVIATED TO NOTHING!
;^PROCESSING GETS THE NEXT WORD (IF NULL THEN OK), THEN CHECKS
;THAT WHATEVER WAS TYPED WAS SPELLED CORRECTLY.  ^THEN IT
;DISPATCHES TO THE PROCESSOR.
;^THE COMMANDS ARE:^^

;. ;_.BEGIN BAR
;. ;_.CONTROL CHARACTERS
;. ;_.DISABLE BAR
;. ;_.DO INDEX
;. ;_.ENABLE BAR
;. ;_.FIRST TITLE
;. ;_.LOWER CASE
;. ;_.NOCONTROL CHARACTERS
;. ;_.PAPER SIZE
;. ;_.PRINT INDEX
;. ;_.TAB STOPS
;. ;_.TEST PAGE
;. ;_.UPPER CASE
;-	\\

DEFINE MC2 ($FIRST,$SECON,$ONE)<
	XLIST
$FIRST:	PUSHJ	P,CMGNWD	;;GET NEXT WORD IF ANY
	  JRST	$ONE		;;NO. ASSUME IT'S ABBREVIATED OUT.
	HRROI	S1,[EXP [ASCIZ /$SECON/]]	;;ONLY ONE WORD IN "TABLE"
	PUSHJ	P,CMREC		;;SEE IF THAT'S IT.
	  JRST	ILCM		;;NO. SECOND WORD WRONG.
	LIST
	JRST	$ONE		;;OK. GO TO ROUTINE.
>
				CONT.
MC2 $$BEGI,<BAR>,$BE.BA
MC2 $$CONT,<CHARACTERS>,$CO.CH
MC2 $$DISA,<BAR>,$DI.BA
MC2 $$DO,<INDEX>,$DO.IN
MC2 $$ENAB,<BAR>,$AN.BA
MC2 $$FIRS,<TITLE>,$FI.TI
MC2 $$LOWE,<CASE>,$LO.CA
MC2 $$NOCO,<CHARACTERS>,$NO.CH
MC2 $$PAPE,<SIZE>,$PA.SI
MC2 $$PRIN,<INDEX>,$PR.IN
MC2 $$TAB,<STOPS>,$TA.ST
MC2 $$TEST,<PAGE>,$TE.PA
MC2 $$UPPE,<CASE>,$UP.CA
;+

;.HL1	ONE/TWO WORD COMMANDS

;^THESE COMMANDS HAVE BOTH ONE WORD AND TWO WORD MEANINGS
;THAT ARE DIFFERENT.  ^THE PROCEDURE IS THE SAME AS ABOVE
;EXCEPT THAT THE TWO DISPATCH ADDRESSES ARE DIFFERENT.
;^THESE COMMANDS ARE: ^^

;. ;_.LEFT (MARGIN)
;. ;_.LIST (ELEMENT)
;. ;_.PAGE (SIZE)
;. ;_.RIGHT (MARGIN)
;-	\\

DEFINE MC3 ($FIRST,$SECON,$ONE,$TWO)<
	XLIST
$FIRST:	PUSHJ	P,CMGNWD	;;GET NEXT WORD IF ANY
	LIST
	  JRST	$ONE		;;NO. GO TO ONE WORD ROUTINE
	XLIST
	HRROI	S1,[EXP [ASCIZ /$SECON/]]	;;ONLY ONE WORD IN "TABLE"
	PUSHJ	P,CMREC		;;SEE IF THAT'S IT.
	  JRST	ILCM		;;NO. SECOND WORD WRONG.
	LIST
	JRST	$TWO		;;OK. GO TO TWO WORD ROUTINE.
>

MC3	$$LEFT,MARGIN,$INDEN,$LE.MA
MC3	$$LIST,ELEMENT,$LIST,$LI.EL
MC3	$$PAGE,SIZE,$PAGE,$PA.SI
MC3	$$RIGH,MARGIN,$RIGHT,$RI.MA
	SUBTTL	DOT COMMANDS

$INDEN:	PUSHJ	P,OUTNJ		;OUTPUT REST OF CURRENT LINE
	PUSHJ	P,RCNO		;READ SIGNED DECIMAL NUMBER
PARAG1:	  MOVE	N,PARIND	;NONE. USE CURRENT VALUE
	MOVE	A,N		;GET COPY
	ADD	A,LMARG		;COMPUTE RESULTANT
	SKIPL	A		;VERIFY NOT TOO SMALL		[201]
	CAMLE	A,RMARG		;LEGITIMATE VALUE?
	JRST	ILCM		;NO. COMPLAIN
	MOVEM	N,INDCT		;YES. STORE ARGUMENT
	JRST	ENDBCM		;END OF BREAK COMMAND

$BREAK:	PUSHJ	P,OUTNJ		;THE SIMPLE BREAK COMMAND.
	JRST	ENDBCM		;RETURN AS ALL BREAK COMMANDS DO

$UP.CA:	TDZA	A,A		;SET CASE OFFSET TO ZERO
$LO.CA:	MOVEI	A,ULCAS		;SET FOR LOWER CASE OFFSET
	MOVEM	A,FILCAS	;STORE INITIAL FILE CASE
	MOVEM	A,CAS		;STORE CURRENT FILE CASE
	JRST	ENDCM		;END OF COMMAND (NOT BREAK)

;PAGE COMMAND

$EN.SU:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SETZM	SUBPGE		;END SUBPAGE
	JRST	$PAGE		;CLEAR SUBPAGE FLAG
$SUBPA:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SKIPN	SUBPGE		;SUBPAGE--SET FLAG
	AOS	SUBPGE		;UNLESS ALREADY SET
$PAGE:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;PAGE--END LINE
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,BPAGE		;BREAK PAGE
	JRST	ENDBCM		;END BREAK COMMAND

;TEST PAGE COMMAND

$TE.PA:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;BREAK LINE FIRST
	PUSHJ	P,RCNO		;GET ARGUMENT OF TEST
	  JRST	ILCM		;MUST BE ONE
	JUMPLE	N,ILCM		;ERROR IF NEG OR ZERO
	PUSHJ	P,TSTPAG	;TEST SHOWS NEAR END, BREAK PAGE
	  JFCL			;DOESN'T MATTER IF BROKE
	JRST	ENDBCM		;RETURN FROM TEST PAGE
;SET RIGHT MARGIN COMMAND

$RI.MA:	PUSHJ	P,OUTNJ		;BREAK-CLASS COMMAND
	MOVE	N,RMARG		;GET CURRENT RIGHT MARGIN
	PUSHJ	P,RCNR		;ADD ARGUMENT
	  MOVE	N,PRMRG		;IF NONE, INITIALIZE
	CAMG	N,LMARG		;MUST ALSO BE RIGHT OF LEFT MARGIN
	JRST	ILCM		;ISNT. ERROR
	CAMLE	N,PRMRG		;SEE IF WITHIN PAPER SIZE
	MOVEM	N,PRMRG		;NO--UPDATE PAGE WIDTH
	MOVEM	N,RMARG		;STORE RIGHT MARGIN
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,LRMTYP	;ISSUE MARGINS FOR TYPESETTING
	JRST	ENDBCM		;END OF COMMAND

;SET LEFT MARGIN COMMAND

$LE.MA:	PUSHJ	P,OUTNJ		;BREAK COMMAND
	MOVE	N,LMARG		;GET CURRENT LEFT MARGIN
	PUSHJ	P,RCNR		;ADD ARGUMENT
	  MOVEI	N,ILMRG		;IF NONE,INITIALIZE
	JUMPL	N,ILCM		;ERROR IF NEG OR ZERO
	CAML	N,RMARG		;AND LESS THAN RIGHT MARGIN?
	JRST	ILCM		;NO. ERROR.
	MOVEM	N,LMARG		;OK SAVE AS LEFT MARGIN
	MOVN	A,N		;GET NEGATIVE			[201]
	CAMLE	A,PARIND	;SEE IF PARAG INDENT TOO LEFT	[201]
	MOVEM	A,PARIND	;YES--DECREASE PARAG INDENT TO FIT	[201]
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,NEGINC	;ISSUE NIC MESSAGE IF NEEDED
	PUSHJ	P,LRMTYP	;ISSUE MARGINS FOR TYPESETTING
	JRST	ENDBCM		;AND END BREAK-CLASS COMMAND
;PAGE SIZE COMMAND

$PA.SI:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	MOVE	N,PNLPG		;GET CURRENT SIZE
	PUSHJ	P,RCNR		;ADD ARGUMENT
	  JFCL			;IGNORE NULL
	CAIG	N,12		;LONG ENOUGH TO BE REASONABLE FOR HEADING
	  JRST	ILCM		;NO. ERROR
	EXCH	N,PNLPG		;SAVE AS LENGTH
	SUB	N,PNLPG		;SEE HOW MUCH SHORTER
	MOVNS	N		;CHANGE TO HOW MUCH LONGER
	ADDM	N,NLPG		;CHANGE LINES LEFT THIS PAGE
	SETZM	FLNOPG		;CLEAR .NOPAGING
	PUSHJ	P,OUTNJ		;BREAK COMMAND
	MOVE	N,PRMRG		;GET CURRENT WIDTH
	PUSHJ	P,RCNR		;SEE IF SECOND ARGUMENT
	  JFCL			;IGNORE ABSENCE
	CAMG	N,LMARG
	JRST	ILCM
	MOVEM	N,PRMRG		;STORE PAGE WIDTH
	MOVEM	N,RMARG
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,LRMTYP	;ISSUE MARGINS FOR TYPESETTING
	JRST	ENDBCM		;END OF COMMAND

;PAGING/NO PAGING COMMANDS

$NOPAG:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	HRLOI	A,INFIN		;SET LENGTH OF THIS
	MOVEM	A,NLPG		; PAGE TO INFIN.
	SETOM	FLNOPG		;SET NOPAGING
	JRST	ENDCM		;END COMMAND
$PAGIN:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SETZM	FLNOPG		;CLEAR NOPAGING
	MOVE	A,PNLPG		;GET PAGE SIZE			[205]
	CAMGE	A,NLPG		;IF SMALLER,			[205]
	MOVEM	A,NLPG		;SET INTO LINES THIS PAGE	[205]
	JRST	ENDCM		;END COMMAND
;.STANDARD COMMAND

$STAND:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;BREAK LINE
	MOVE	N,PRMRG		;GET PREVIOUS PAGE WIDTH
	PUSHJ	P,RCNR		;GET RELATIVE NEW WIDTH
	  JFCL			;IGNORE NULL
	JUMPLE	N,ILCM		;ERROR IF NEGATIVE
	MOVSI	A,-LNSDTB	;GET LENGHT OF STANDARD TABLE
SDLP:	HRRZ	B,SDTB(A)	;GET ENTRY
	CAME	B,N		;SEE IF MATCH
	AOBJN	A,SDLP		;NO--LOOP
	JUMPGE	A,SDX		;UNKNOWN--LEAVE LENGTH ALONE
	HLRZ	A,SDTB(A)	;GET LENGTH
	SKIPN	A		;UNLESS 0
	JRST	SDX		; (0)
	EXCH	A,PNLPG		;ALSO SET PERMANENT LENGTH
	SUB	A,PNLPG		;FIND OUT HOW BIG A CHANGE
	MOVNS	A		;POSITIVE INCREMENT
	ADDM	A,NLPG		;UPDATE LENGTH THIS PAGE

;HERE TO RESET MANY VARIABLE PARAMETERS
SDX:	STORE	A,PARIND,,SPARIN	;SET PARAG. INDENT
SDXY:	SETZM	FLNOPG		;SET .PAGING
	MOVEM	N,PRMRG		;SET PAGE WIDTH
	MOVEM	N,RMARG		;SET RIGHT MARGIN
	STORE	A,LMARG,,ILMRG	;INITILIZE .LEFT MARGIN
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,NEGINC	;ISSUE NIC MESSAGE IF NEEDED
	PUSHJ	P,LRMTYP	;ISSUE MARGINS FOR TYPESETTING
	SKIPG	A,SCNSPG	;RESET
	MOVEI	A,AD.SPC	;  INITIAL
	MOVEM	A,NSPNG		;  SPACING
	MOVE	A,FILCAS	;GET FILE CASE
	MOVEM	A,CAS		;RESET CURRENT CASE
	TLO	F,L.PJUS!L.JUST!L.FILL  ;.FILL;.JUSTIFY
	PUSHJ	P,JUSTYP	;ISSUE JUSTIFICATION TO TYPESET
	JRST	ENDBCM		;END BREAK COMMAND

	RADIX	10
SDTB:			;LENGTH,,WIDTH
	AD.LPP,,AD.WID
IFN AD.WID-60,<	58,,60	>
	PD.LPP,,PD.WID
IFN PD.WID-70,<	64,,70	>
LNSDTB==.-SDTB
	RADIX	8
;PARAGRAPH COMMAND

$PARAG:	PUSHJ	P,OUTNJ		;FINISH CURRENT LINE
	PUSHJ	P,RCNO		;GET VALUE
	  MOVE	N,PARIND	;NULL--GET OLD VALUE
	MOVEM	N,PARIND	;STORE PARA INDENT VALUE
	PUSHJ	P,RCNO		;GET VALUE OF VERT SPACING
	  MOVE	N,PARSPC	;NULL--GET OLD VALUE
	CAML	N,[-1]		;SEE IF TOO SMALL
	CAILE	N,MX.SPC	; OR TOO LARGE
	JRST	ILCM		;YES--ERROR
	MOVEM	N,PARSPC	;OK--STORE VERTICAL SPACING
	MOVE	N,PARTPG	;GET OLD TEST PAGE
	PUSHJ	P,RCNR		;GET RELATIVE VALUE
	  JFCL			;IGNORE NULL
	JUMPL	N,ILCM		;ERROR IF NEG
	MOVEM	N,PARTPG	;STORE UPDATED VALUE
	PUSHJ	P,PARAG0	;DO THE PARAGRAPH OPERATION
	JRST	PARAG1		;CHECK ARG AND RETURN

PARAGF:	PUSHJ	P,OUTNJ		;OUTPUT PARTIAL LINE
	SETOM	FRCPAR		;FORCE PARAGRAPH
	MOVE	N,PARIND	;SET FOR INDENT
	MOVEM	N,INDCT		; ..
	PJRST	LINSET		;AS IF BREAK COMMAND

PARAG0:	SETZM	FRCPAR		;CLEAR ANY FORCED PARAGRAPHS
	SKIPG	SCNTYP		;UNLESS TYPESETTING,
	SKIPE	FLSOPG		; SEE IF BEYOND HEADING
	SKIPN	SMINSC		;SEE IF SOMETHING THIS SECTION AND
	POPJ	P,		;NO. RETURN
	MOVE	A,NSPNG		;GET NORMAL LINE-SPACING
	ADDI	A,1		;COMPUTE SIZE OF PARAGRAPH BREAK
	ASH	A,-1		; ..
	MOVE	B,PARSPC	;GET PARAGRAPH SPACING
	IMUL	B,NSPNG		;TIMES CURRENT SPACING
	SKIPL	B		;SEE IF -1
	MOVE	A,B		;NO--USE THAT INSTEAD
	MOVE	N,PARTPG	;GET DEFAULT TEST PAGE
	IMUL	N,NSPNG		;MULT BY SPACING
	ADD	N,A		;CHECK FOR END OF PAGE
	ADD	N,NSPNG		; ..
	PUSHJ	P,TSTPAG	;SEE IF END
	  POPJ	P,		;YES--DON'T SPACE AFTER BREAK
	PJRST	SKIPN		;NO--SKIP N LINES
;AUTOPARAGRAPH/NO AUTOPARAGRAPH COMMANDS

$AUTOP:	TRZ	F,R.AUTB	;CLEAR AUTOTABLE
	TROA	F,R.SPPR	;SET AUTOPARAGRAPH
$NOAUT:	TRZ	F,R.SPPR!R.AUTB	;CLEAR AUTOPARAGRAPH AND AUTOTABLE
	JRST	ENDCM		;END COMMAND

;AUTOTABLE/NO AUTOTABLE COMMANDS

$AUTOT:	TRZ	F,R.SPPR	;CLEAR AUTOPARAGRAPH
	TRO	F,R.AUTB	;SET AUTOTABLE
	JRST	ENDCM		;END COMMAND
;NUMBER COMMAND [PAGE/SUBPAGE/INDEX/CHAPTER/APPENDIX] [N]

$NUMBE:	PUSHJ	P,CMGNWD	;GET NEXT WORD, IF ANY
	  JRST	[MOVEI S1,PAGENO  ;NONE, ASSUME PRIMARY PAGE
		 JRST  NUMBEN]	; AND GO HANDLE
	MOVE	S1,[-7,,[    1,,[ASCIZ /APPENDIX/]
			SECNUM,,[ASCIZ /CHAPTER/]
			     0,,[ASCIZ /INDEX/]
			     3,,[ASCIZ /LEVEL/]
			     4,,[ASCIZ /LIST/]
			PAGENO,,[ASCIZ /PAGE/]
			     2,,[ASCIZ /SUBPAGE/]  ]]
	PUSHJ	P,CMREC		;RECOGNIZE WORD
	  JRST	ILCM		;ERROR IF UNKNOWN
	HLRZ	S1,(D)		;GET ADDRESS OR CODE
	CAILE	S1,77		;SEE IF CODE
	JRST	NUMBEN		;NO--JUST USE ADDRESS
	JUMPE	S1,NUMBEI	;JUMP IF INDEX
	CAIN	S1,1		;SEE IF APPENDIX
	JRST	NUMBEA		;YES--GO HANDLE
	CAIN	S1,3		;SEE IF LEVEL
	JRST	NUMBEV		;YES--GO HANDLE
	CAIN	S1,4		;SEE IF LIST
	JRST	NUMBEL		;YES--GO HANDLE

;HERE ON .NUMBER SUBPAGE

	MOVE	N,SUBPGE	;NO--MUST BE SUBPAGE
	SOS	N		;GET ACTUAL SUBPAGE
	PUSHJ	P,RCNR		;GET RELATIVE NUMBER
	  JRST	[PUSHJ P,CMCIN	;NOT NUMBER--TRY LETTER
		 CAIL  CH,"A"	;CHECK
		 CAILE CH,"Z"	;  ALPHABETIC
		 JRST  ILCM	;ERROR IF NOT
		 MOVEI N,1-"A"(CH)  ;CONVERT TO OFFSET NUMBER
		 JRST  .+1]	;AND PROCEED
	JUMPLE	N,ILCM		;ERROR IF NEGATIVE
	CAIL	N,^D26		;ERROR IF TOO LARGE
	JRST	ILCM		;(USER CAUSED OVERFLOW)
	MOVEM	N,SUBPGE	;STORE AS SUBPAGE
	JRST	NUMBEX		;GO EXIT
				CONT.
;HERE ON .NUMBER LEVEL

NUMBEV:	MOVEI	D,1		;COUNT THE DEPTH
NUMBV1:	CAIL	D,LN$SEC	;DON'T OVERFLOW
	JRST	ILCM		;ERROR IF HE DOES
	MOVE	N,SECNUM(D)	;GET OLD VALUE
	PUSHJ	P,RCNR		;GET RELATIVE NUMBER
	  JRST	NUMBV2		;NULL--LEAVE ALONE
	JUMPLE	N,ILCM		;ERROR IF NEGATIVE
	MOVEM	N,SECNUM(D)	;STORE NEW VALUE
NUMBV2:	CAIN	CH,C.CMA	;SEE IF SEPARATOR
	AOJA	D,NUMBV1	;YES--LOOP FOR ANOTHER
	SOS	SECNUM(D)	;BACKUP LAST ONE
	SOS	SECNUM(D)	;ALSO ALLOW FOR ZERSEC
	MOVE	A,D		;POSITION DEPTH FOR ZERSEC
	PUSHJ	P,ZERSEC	;UPDATE LASHL AND CLEAR COUNTERS
	JRST	NUMBEX		;EXIT FROM NUMBER COMMAND

;HERE ON .NUMBER LIST COMMAND
;ARGUMENTS ARE DEPTH, COUNT

NUMBEL:	MOVE	N,LASLS		;GET LAST LIST DEPTH
	PUSHJ	P,RCNR		;GET RELATIVE DEPTH
	  JFCL			;NULL IS OK
	JUMPL	N,ILCM		;ERROR IF BAD DEPTH
	CAILE	N,LN$MJP	;OR IF TOO BIG
	JRST	ILCM		; GIVE ERROR
	MOVE	D,N		;SAVE DEPTH FOR LATER
	MOVE	N,LSTCNT(D)	;GET CURRENT COUNT
	AOS	N		;ADVANCE TO NEXT ITEM
	PUSHJ	P,RCNR		;INPUT RELATIVE NUMBER
	  JFCL			;NULL IS OK, BUT SILLY
	JUMPLE	N,ILCM		;ERROR IF NEGATIVE
	SOS	N		;BACK UP FOR .LE COMMAND
	MOVEM	N,LSTCNT(D)	;STORE
	MOVEM	D,LASLS		;STORE NEW DEPTH
	JRST	NUMBEX		;EXIT FROM NUMBER COMMAND
				CONT.
;HERE ON .NUMBER INDEX

NUMBEI:	HRROS	SECNUM		;INDEX--SET FLAG
	JRST	NUMBEX		;AND GO EXIT

;HERE ON .NUMBER APPENDIX

NUMBEA:	MOVEI	S1,SECNUM	;POINT TO CHAPTER NUMBER
	HRRZ	N,SECNUM	;GET CURRENT CHAPTER NUMBER
	TXZN	N,APPXFL	;SEE IF APPENDIX FLAG SET
	MOVEI	N,0		;NO--SET APPENDIX 0
	AOS	N		;ALLOW FOR FUTURE SOS N		[213]
	PUSHJ	P,RCNR		;GET RELATIVE NUMBER
	  JRST	[PUSHJ P,RCANO	;NULL--TRY ALPHA INPUT
		   JFCL		;NULL AGAIN--OK
		 JRST  .+1]	;PROCEED
	JUMPLE	N,ILCM		;ERROR IF LE 0
	CAIL	N,APPXFL	;SEE IF TOO BIG
	JRST	ILCM		;NO--ERROR
	TXO	N,APPXFL	;FORCE INTO APPENDIX RANGE
	JRST	NUMBEO		;AND FINISH CHAPTER STUFF

;HERE ON .NUMBER PAGE OR CHAPTER

NUMBEN:	HRRZ	N,(S1)		;GET OLD VALUE
	AOS	N		;ALLOW FOR FUTURE SOS N		[213]
	PUSHJ	P,RCNR		;ADD RELATIVE NUMBER
	  JFCL			;IGNORE NULL

;HERE TO FINISH NUMBER COMMAND

NUMBEO:	CAIE	S1,PAGENO	;UNLESS SETTING PAGE,		[172]
	JUMPE	N,ILCM		; ZERO IS ILLEGAL		[172]
	JUMPL	N,ILCM		;ERROR IF NEG			[172]
	CAIN	S1,PAGENO	;UNLESS SETTING PAGE NUMBER	[226]
	SKIPE	LINEC		; AT THE TOP OF A PAGE,		[226]
	SOS	N		; BACKUP FOR LATER USE

;HERE TO EXIT FROM NUMBER COMMAND

	MOVEM	N,(S1)		;STORE NEW NUMBER
NUMBEX:	SETZM	FLNUMB		;TURN ON FLAG TO CAUSE NUMBERING
	JRST	ENDCM		;END COMMAND

;NONUMBER COMMAND

$NONUM:	SETOM	FLNUMB		;TURN OFF NUMBERING.
	JRST	ENDCM		;END OF NON-BREAK COMMAND
;HEADER COMMAND TAKES THREE WORD VALUES

$$HEAD:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,CMGNWD	;GET NEXT WORD
	  JRST	HEADER		;TURN ON HEADERS IF NO ARG
	MOVE	S1,[-4,,[HEADUPPER,,[ASCIZ /UPPER/]
			 HEADMIXED,,[ASCIZ /MIXED/]
			 HEADLOWER,,[ASCIZ /LOWER/]
				-1,,[ASCIZ /LEVEL/] ]]
	PUSHJ	P,CMREC		;LOOKUP WORD
	  JRST	ILCM		;ERROR IF NOT FOUND
	HLRZ	A,(D)		;GET VALUE
	CAIN	A,-1		;SEE IF SPECIAL VALUE
	JRST	$HE.LE		;YES--GO DO .HL COMMAND
	MOVEM	A,FILHDR	;STORE FOR PAGE ROUTINE (MOVED AS [246])
$HEADE:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
HEADER:	SETZM	FLNHDR		;RESUME HEADERS
	JRST	ENDCM		;END COMMAND

$NOHEA:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SETOM	FLNHDR		;SUPPRESS HEADERS
	JRST	ENDCM		;END COMMAND

;TITLE COMMAND

$TITLE:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,CLRTTL	;CLEAR OLD TITLE
	MOVEI	D,5*LN$TTL-1	;SET BUFFER LIMIT
	PUSHJ	P,GCIN		;READ CHARACTER AFTER COMMAND
	CAIN	CH,C.SPC	;SPACE? SKIP JUST ONE.
SETTL1:	PUSHJ	P,GCIN		;READ A CHARACTER
	CAIN	CH,.CHLFD	;END OF COMMAND LINE?
	JRST	ENDCMX		;YES. QUIT
	MOVEI	PA,TTLP1	;NO. PUT CHAR IN STRING BUFFER
	PUSHJ	P,WCI		; ..
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	SOS	D		;YES--ALLOW FOR ITS SPACE
	SOJG	D,SETTL1	;LOOP TILL END
	PUSHJ	P,E$$IBO	;ERROR IF OVERFLOW
	JRST	$COMME		;IGNORE REST AS COMMENT
				CONT.
;SUBTITLE COMMAND

$SUBTI:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,CLRSTT	;CLEAR SUBTITLE
	SETOM	DOSTTL		;INDICATE TO PRINT SUBTITLES
	MOVEI	D,5*LN$TTL-1	;COUNT OF BUFFER SIZE
	PUSHJ	P,GCIN		;GET CHARACTER FROM INPUT LINE
	CAIN	CH,C.SPC	;SKIP ONE LEADING SPACE
SETST1:	PUSHJ	P,GCIN		;GET CHARACTER FROM INPUT LINE
	CAIN	CH,.CHLFD	;END OF LINE ON INPUT?
	JRST	ENDCMX		;YES. END OF SUBTITLE COMMAND
	MOVEI	PA,STTLP1	;NO. WRITE INTO BUFFER
	PUSHJ	P,WCI		; ..
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	SOS	D		;YES--ALLOW FOR ITS SPACE
	SOJG	D,SETST1	;LOOP TILL END OF LINE
	PUSHJ	P,E$$IBO	;ERROR IF OVERFLOW
	JRST	$COMME		;TREAT REST AS COMMENT

;NO SUBTITLE COMMAND

$NOSUB:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SETZM	DOSTTL		;INDICATE NO SUBTITLE
	JRST	ENDCM		;END COMMAND

;FIRST TITLE COMMAND

$FI.TI:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SETOM	FLTITL		;SET TITLE FLAG
	JRST	ENDCM		;END COMMAND

;SPACING COMMAND

$SPACI:	PUSHJ	P,OUTNJ		;BREAK LINE FIRST
	PUSHJ	P,RCNO		;GET ARGUMENT OF SPACING COMMAND
	  JRST	ILCM		;MUST BE ONE
	CAIG	N,MX.SPC	;MUST BE IN RANGE 1 TO 5
	CAIG	N,0		; ..
	  JRST	ILCM		;NOT. ERROR.
	MOVEM	N,NSPNG		;OK. STORE AS NORMAL SPACING
	JRST	ENDBCM		;END OF SPACING COMMAND
;SELECT/NO SELECT COMMANDS

$SELEC:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	MOVSI	C,-4		;NEED FOUR ARGS
SELLOP:	PUSHJ	P,GCIN		;GET NEXT ARG
	PUSHJ	P,CMSOME	;SEE IF END OF COMMAND
	  JRST	SELDON		;YES--THAT'S ALL
	CAIE	CH,.CHTAB	;SEE IF TAB
	CAIN	CH,C.SPC	; OR SPACE
	JRST	SELLOP		;YES--SKIP IT
	CAIG	CH,C.FLGS	;SEE IF INTERNAL FLAG
	JRST	ILCM		;YES--INDICATE ERROR
	ANDI	CH,CHRMSK	;MASK TO REAL CHARACTER
	MOVEM	CH,SELPFX(C)	;NO--STORE CHARACTER
	AOBJN	C,SELLOP	;LOOP UNTIL DONE
	SETOM	CH		;SUPPRESS CHAR
SELDON:	CAIN	CH,.CHLFD	;IF AT END OF LINE,
	TRO	F,R.SLLK	; PRESET SEARCHING MODE.
	MOVEM	CH,GCSCH	;RE-EAT
	TROA	F,R.SLCT	;SET SELECT MODE
$NOSEL:	TRZ	F,R.SLCT	;CLEAR SELECT MODE
	TRZ	F,R.SLRG	;CLEAR SELECT RANGE (+-)
	SETZM	ESLCTF		;CLEAR .END SELECT MODE
	JRST	ENDCM		;END OF COMMAND

;.END SELECT

$EN.SE:	TRNN	F,R.SLCT	;IF NOT IN .SELECT,
	JRST	ILCM		; THIS IS AN ERROR
	SETOM	ESLCTF		;OTHERWISE, SET FLAG
	JRST	ENDCM		;AND END COMMAND

;PERIOD/NO PERIOD COMMANDS

$PERIO:	TRZA	F,R.NPER	;CLEAR .NOPERIOD
$NOPER:	TRO	F,R.NPER	;SET .NOPERIOD
	JRST	ENDCM		;END COMMAND

;.CONTROL/.NO CONTROL CHARACTERS

$CO.CH:	TROA	F,R.ALCC	;SET FLAG TO ALLOW CONTROLS
$NO.CH:	TRZ	F,R.ALCC	;CLEAR FLAG ON CONTROLS
	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	JRST	ENDCM		;END COMMAND

;.NOSPACE (SUPPRESSES THE FREE SPACE AT END OF PREVIOUS LINE

$NOSPA:	TLO	F,L.NFSP	;SET TO SUPPRESS FREE SPACE
	JRST	ENDCM		;END COMMAND (NO BREAK)
;NOFLAG/FLAG COMMANDS

$NOFLA:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,CMGNWD	;GET WORD
	  JRST	NOFLAA		;NONE--THEREFORE ALL
	MOVE	S1,[-LENFLA,,FLATAB]
	PUSHJ	P,CMREC		;LOOKUP WORD
	  JRST	ILCM		;ERROR IF UNKNOWN
	HLRZ	D,(D)		;GET ADDRESS
	JUMPE	D,NOFLAA	;ALL IF NOT SPECIFIC
	HRROS	(D)		;SUPPRESS MATCHES
	JRST	ENDCM		;RETURN

$FLAGS:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,CMGNWD	;GET WORD
	  JRST	FLAGAA		;NONE--THEREFORE ALL
	MOVE	S1,[-LENFLA,,FLATAB]
	PUSHJ	P,CMREC		;LOOKUP WORD
	  JRST	ILCM		;ERROR IF UNKNOWN
	HLRZ	D,(D)		;GET ADDRESS
	JUMPE	D,FLAGAA	;ALL IF NOT SPECIFIC
FLAGSL:	PUSHJ	P,GCIN		;GET NEXT CHARACTER
	PUSHJ	P,CMSOME	;SEE IF END OF COMMAND
	  JRST	[MOVEM CH,GCSCH	;YES--SET TO RE-EAT
		 HRRZ  CH,(D)	;GET OLD VALUE
		 JRST  FLAGSF]	; PROCEED
	CAIE	CH,.CHTAB	;SEE IF SPACE
	CAIN	CH,C.SPC	;AND TAB
	JRST	FLAGSL		;YES--LOOP
FLAGSF:	ANDI	CH,CHRMSK	;MASK TO REAL CHARACTER
	MOVEM	CH,(D)		;STORE IN CONTROLLING WORD
	JRST	ENDCM		;END COMMAND

FLAGAA:	TRZA	F,R.NFLA	;.FLAG ALL--CLEAR FLAG SUPPRESSION
NOFLAA:	TRO	F,R.NFLA	;.NOFLAG ALL--SUPPRESS FLAGS
	JRST	ENDCM		;END OF EITHER COMMAND
				CONT.
FLATAB:	CM	0,<ALL>
	CM	CC.CAP,<CAPITALIZE>
	CM	CC.CON,<CONTROL>
	CM	CC.END,<ENDFOOTNOTE>
	CM	CC.IND,<INDEX>
	CM	CC.LOW,<LOWERCASE>
	CM	CC.QUO,<QUOTE>
	CM	CC.SPA,<SPACE>
	CM	CC.SUB,<SUBINDEX>
	CM	CC.UND,<UNDERLINE>
	CM	CC.UPP,<UPPERCASE>
LENFLA==.-FLATAB

FLASTD:		;PARALLELS CCTABL
	-1,,C.CAP
	C.CNT
	C.EFNT
	-1,,C.IND
	C.DN
	C.QNC
	C.QS
	C.SIF
	C.ULI
	C.UP
IFN .-FLASTD+CCTABL-CCTEND-1,<PRINTX	?CCTABL AND FLASTD DISAGREE>
$JUSTI:	PUSHJ	P,OUTNJ		;BREAK COMMAND
	TLO	F,L.PJUS+L.JUST	;TURN ON JUSTIFYING
	JRST	ENDJFC		;AND RETURN FROM COMMAND

$NOJUS:	PUSHJ	P,OUTNJ		;BREAK CURRENT LINE
	TLZ	F,L.PJUS+L.JUST	;TURN OFF JUSTIFY BITS
	JRST	ENDJFC		;AND FINISH COMMAND

$FILL:	PUSHJ	P,OUTNJ		;BREAK COMMAND
	TLO	F,L.FILL+L.JUST	;TURN ON FILLING, COPY L.PJUS TO L.JUST
	TLNN	F,L.PJUS	;COPY PERMANENT FLAG
	TLZ	F,L.JUST	;TO CURRENT ONE.
	JRST	ENDJFC		;END OF COMMAND

$NOFIL:	PUSHJ	P,OUTNJ		;BREAK CURRENT LINE
	TLZ	F,L.FILL+L.JUST	;TURN OFF FILLING AND JUSTIFYING
ENDJFC:	PUSHJ	P,JUSTYP	;TELL TYPESET OF JUSTIFICATION RULES
	JRST	ENDBCM		;END OF COMMAND

$TA.ST:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	SETZB	D,NTABS		;CLEAR NUMBER OF TABS
SETT1:	PUSHJ	P,RCN		;GET ANOTHER STOP IF ANY
	  JRST	[PUSHJ P,STSTYP	;SET TAB STOPS FOR TYPESETTING
		 JRST  ENDCM]	;THEN RETURN
	AOS	X,NTABS		;ADVANCE COUNTER
	CAILE	X,LN$TAB	;SEE IF OVERFLOW
	JRST	ILCM		;YES--GIVE ERROR
	TRNN	F,R.NNUL	;SEE IF NUL
	MOVE	N,TABTAB-1(X)	;YES--GET PREVIOUS VALUE
	CAMG	N,D		;SEE IF MONOTONIC
	JRST	ILCM		;NO--ERROR
	MOVE	D,N		;YES--UPDATE TEST
	MOVEM	N,TABTAB-1(X)	;STORE RESULT
	JRST	SETT1		;LOOP

;ROUTINE TO FIND NEXT TABSTOP FOR OUTLIN ROUTINE. CALL
;WITH CURRENT POSITION IN A.
;RETURNS NUMBER OF SPACES TO ISSUE IN A.

TAB:	MOVEI	X,0		;START AT FIRST TABSTOP
	JRST	TAB1		;PRE-ENDCHECK, IN CASE NONE.
TAB2:	MOVE	C,TABTAB-1(X)	;GET CURRENT TAB STOP
	CAMGE	A,C		;THIS STOP BEYOND CURRENT POS?
	JRST	TAB3		;YES. GET DIFFERENCE
TAB1:	CAMGE	X,NTABS		;LOOKED AT ALL TAB STOPS?
	AOJA	X,TAB2		;NO. LOOK AT ANOTHER
	MOVE	C,RMARG		;YES. ASSUME A TABSTOP AT RIGHT END
TAB3:	SUB	C,A		;GET DISTANCE TO TABSTOP
	MOVE	A,C		;ANSWER IN A
	POPJ	P,		;RETURN
;LINE SKIPPING COMMANDS

$SKIP:	SKIPA	S2,NSPNG	;SKIP COMMAND. N CURRENT LINES
$BLANK:	MOVEI	S2,1		;BLANK COMMAND. N REAL LINES
	SAVE$	S2		;SAVE S2 FOR SAFETY
	PUSHJ	P,OUTNJ		;OUTPUT CURRENT LINE
	RSTR$	S2		;RESTORE S2
	PUSHJ	P,RCNO		;GET OPTIONAL ARGUMENT
	  MOVEI	N,1		;IF NONE, ASSUME 1
	JUMPE	N,ILCM		;ERROR IF ZERO
	IMUL	N,S2		;MULTIPLY BY 1 OR NSPNG
	JUMPG	N,LINSK1	;IF POSITIVE, THEN FROM HERE
LINSK0:	MOVE	N1,N		;COPY ARGUMENT
	ADD	N,NLPG		;COMPUTE DISTANCE FROM END
	SUB	N,LINEC		; ..
	JUMPG	N,LINSK2	;SOME ROOM, PROCEED
	SKIPN	FLSOPG		;IF AT TOP
	JRST	ILCM		;AND NO ROOM, ERROR
	PUSHJ	P,BPAGE		;OK--NEW PAGE
	MOVE	N,N1		;RECOVER ARGUMENT
	JRST	LINSK0		;LOOP TO WIN
LINSK1:	SKIPN	FLSOPG		;AT TOP OF PAGE?
	SKIPLE	SCNTYP		; AND NOT TYPESETTING
	SKIPA			;NO--ISSUE
	JRST	ENDBCM		;YES. IGNORE BLANK COMMAND.
LINSK2:	MOVE	A,N		;CHECK IF ROOM ON PAGE
	ADD	N,NSPNG		;PLUS SPACING TO NEXT LINE
	PUSHJ	P,TSTPAG	;SEE IF END
	  SKIPA			;YES--DON'T SPACE AFTER BREAK
	PUSHJ	P,SKIPNC	;NO--SPACE OUT C(A) LINES
	JRST	ENDBCM		;END OF COMMAND
				CONT.
$FIGUR:	PUSHJ	P,OUTNJ		;BREAK COMMAND
	MOVEI	D,0		;SET FLAG
	PUSHJ	P,CMGNWD	;SEE IF KEY WORD
	  JRST	FIGUR1		;NO--IMMEDIATE
	HRROI	S1,[EXP [ASCIZ /DEFERRED/]]
	PUSHJ	P,CMREC		;YES--SEE IF DEFERRED
	  JRST	ILCM		;NO--ERROR
	MOVEI	D,1		;OK--SET FLAG
FIGUR1:	PUSHJ	P,RCNO		;GET ARGUMENT
	  MOVEI	N,1		;IF NONE,ASSUME ONE LINE
	CAMG	N,NLPG		;CHECK FOR RATIONAL ARGUMENT
	CAIG	N,0		; ..
	  JRST	ILCM		;BAD. ERROR.
	PUSH	P,N		;SAVE DESIRED SPACE
	ADD	N,LINEC		;SEE IF NEED NEW PAGE FOR FIGURE
	CAMGE	N,NLPG		;WOULD THIS OVERFLOW PAGE
	JRST	FIGUR3		;NO--DO IT NOW
	JUMPE	D,FIGUR2	;YES--IF IMMEDIATE, GO FORCE PAGE
	POP	P,N		;IF DEFERRED, RECOVER ARG
	ADDM	N,DEFFIG	;SAVE DEFERRED FIGURE
	JRST	ENDBCM		;AND FINISH BREAK COMMAND
FIGUR2:	SKIPG	SCNTYP		;YES. SEE IF NOT TYPESETTING
	PUSHJ	P,BPAGE		;YES. BREAK PAGE
FIGUR3:	SKIPG	LINEC		;SEE IF NEW PAGE
	PUSHJ	P,HEADIN	;YES--ISSUE HEADING
	POP	P,A		;GET BACK DESIRED SIZE
	PUSHJ	P,SKIPN		;SPACE THAT OUT
	JRST	ENDBCM		;END OF BREAK COMMAND
;LITERAL N COMMAND--READ NEXT N LINES OF FILE AS LITERAL TEXT
;MUST BE FOLLOWED BY END LITERAL COMMAND

$LITER:	PUSHJ	P,OUTNJ		;BREAK PREVIOUS TEXT
	SKIPG	LINEC		;SEE IF TOP OF PAGE
	PUSHJ	P,HEADIN	;YES--OUTPUT HEADER
	PUSHJ	P,RCNO		;GET NUMBER
	  SKIPA	N,[-1]		;FLAG NO COUNT
	JUMPLE	N,ILCM		;ERROR IF NEG OR ZERO
	MOVEM	N,LITCNT	;STORE COUNT FOR LOOP
	PUSHJ	P,FRCEND	;SKIP REST OF COMMAND LINE

;HERE ON EACH CHARACTER IN LITERAL TEXT LINE
LITER1:	PUSHJ	P,RTECMC	;GET DELAYED TEXT IF ANY
	  PUSHJ	P,CCIN		;GET CHARACTER
	IFEOF$	LITER3		;EXIT LOOP IF EOF
	SKIPN	CPOS		;SEE IF AT START
	JRST	[PUSHJ P,LINUPC	;UPDATE THISXX LINE COUNTS
		 PUSH  P,CH	;SAVE CH
		 SKIPG LINEC	;SEE IF AT TOP OF PAGE
		 PUSHJ P,HEADIN	;YES--ISSUE HEADING
		 PUSHJ P,FILSEQ	;OUTPUT FILE SEQUENCE
		 MOVE  A,LMARG	;GET LEFT MARGIN
		 SKIPG SCNTYP	;UNLESS TYPESETTING,
		 PUSHJ P,NSPAC	;SPACE IN TO IT
		 POP   P,CH	;RESTORE CH
		 JRST  .+1]	;PROCEED
	CAIN	CH,.CHLFD	;SEE IF END OF LINE
	JRST	LITER3		;YES--GO HANDLE IT
	SKIPE	NTABS		;SEE IF .TAB STOPS SET
	CAIE	CH,.CHTAB	;YES--SEE IF TAB
	JRST	LITER2		;NO--HANDLE AS IS
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	LITER2		;YES--NO SPECIAL TAB EXPANSION
	MOVE	A,CPOS		;GET CURRENT POSITION
	PUSHJ	P,TAB		;GET NEXT TAB SETTING
	SKIPG	A		;SEE IF POSITIVE
	MOVEI	A,1		;NO--AT LEAST ONE SPACE
	PUSHJ	P,NSPAC		;OUTPUT THAT MANY SPACES
	JRST	LITER1		;AND LOOP

LITER2:	PUSHJ	P,CCCOUT	;NO--OUTPUT CHAR
	JRST	LITER1		;LOOP
				CONT.
;HERE AT END OF EACH LINE IN LITERAL TEXT
LITER3:	PUSH	P,CH		;SAVE CHARACTER
	MOVEI	S1,[ASCIZ \/L
\]
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	PUSHJ	P,FMES		;YES--BREAK NO JUSTIFY
	PUSHJ	P,OUTLE		;OUTPUT END OF LINE AND SPACING
	POP	P,CH		;RESTORE CHARACTER
LITER4:	IFEOF$	LITERX		;EXIT LOOP IF EOF
	PUSHJ	P,CCIN		;GET FIRST CHARACTER
	IFEOF$	LITERX		;EXIT LOOP IF EOF
	TLNE	F,L.FOOT	;SEE IF FOOTNOTE
	CAME	CH,CC.END	;YES--SEE IF END OF FOOTNOTE
	SKIPA			;NO--CONTINUE
	JRST	LITERX		;YES--EXIT LOOP AT END OF FOOTNOTE
	MOVEM	CH,GCSCH	;SAVE CHARACTER
	SOSLE	N,LITCNT	;COUNT DOWN LINES SEEN
	JRST	LITER1		;LOOP UNTIL DONE N LINES
	JUMPE	N,LITER5	;COUNT HAS RUN OUT

;HERE AT START OF LINE WHEN NOT COUNTING

	MOVEI	A,CCIN		;INDICATE READ ROUTINE
	MOVEI	B,$EN.LI	;INDICATE END HANDLER
	PUSHJ	P,TSTECM	;GO LOOK AT LINE
	  JRST	LITER1		;NOT END, SO RESUME HANDLING
	JRST	ENDBCM		;EXIT IF END LITERAL
				CONT.
;HERE AT END OF LITERAL BY COUNT--DOUBLE CHECK FOR END LITERAL

LITER5:	CAIN	CH,.CHLFD	;SEE IF LINE FEED
	JRST	[AOS  LITCNT	;YES--RESET COUNT AND
		 JRST LITER4]	; SKIP BLANK LINE
	PUSHJ	P,STRCMN	;START COMMAND ERROR BUFFER
	CAME	CH,CC.CON	;SEE IF COMMAND
	JRST	LITERX		;NO--ERROR
	SETOM	GCSCH		;CLEAR SAVED CHARACTER
	PUSHJ	P,CMGWD		;YES--GET FIRST WORD
	  JRST	LITERX		;ERROR
	MOVE	S1,[-CMTL1,,CMTAB]
	PUSHJ	P,CMREC		;LOOK UP
	  JRST	LITERX		;ERROR
	HLRZ	D,(D)		;GET DISPATCH ADDRESS
	CAIN	D,$EN.LI	;SEE IF END LITERAL
	JRST	ENDBCM		;YES--ALL DONE
	CAIE	D,$$END		;VERIFY .END
	JRST	LITERX		;NO--ERROR
LITER6:	PUSHJ	P,CMGNWD	;GET SECOND WORD
	  JRST	LITERX		;ERROR
	MOVE	S1,[-ECMTL1,,ECMTAB]
	PUSHJ	P,CMREC		;GO RECOGNIZE IT
	  JRST	LITERX		;NO--ERROR
	HLRZ	A,(D)		;GET DISPATCH ADDRESS
	CAIN	A,$EN.LI	;SEE IF END LITERAL
	JRST	ENDBCM		;YES--END OF LITERAL PROCESSING

;HERE ON ERRORS AT END OF LITERAL

LITERX:	PUSHJ	P,ENDCMT	;SKIP REST OF COMMAND
	ILCM$	LDE,Literal doesn't end with ".END LITERAL"

;.END LITERAL COMMAND

$EN.LI:	PUSHJ	P,ENDCMT	;SKIP REST OF COMMAND
	ILCM$	ELD,END LITERAL doesn't follow LITERAL
;.NOTE COMMAND	(SAVE CURRENT STATE)
;PERIOD AND EXCLAMATION ARE VALID TEXT.

$NOTE:	PUSHJ	P,OUTNJ		;BREAK PREVIOUS LINE
	SKIPG	LINEC		;IF START OF PAGE,
	PUSHJ	P,HEADIN	; ISSUE PAGE HEADING
	MOVEI	N,NFSPAC	;SET FOR FINAL SPACING
	PUSHJ	P,PSHMJS	;SAVE MARGINS, ETC.
	MOVEI	A,NPMARG	;SET NOTE
	SKIPE	LMARG		; PRIMARY UNLESS NOT
	MOVEI	A,NSMARG	; AT LEFT BORDER
	ADDM	A,LMARG		; LEFT MARGIN
	MOVNS	A		;MOVE RIGHT MARGIN
	ADDM	A,RMARG		; IN THE SAME DISTANCE
	MOVEI	A,NSPACG	;SET NOTE
	MOVEM	A,NSPNG		; SPACING
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,LRMTYP	;ISSUE MARGINS FOR TYPESETTING
	TLO	F,L.JUST!L.FILL	;.FILL
	TLNN	F,L.PJUS	;COPY .JUSTIFY
	TLZ	F,L.JUST	; FLAG
	PUSHJ	P,JUSTYP	;ISSUE JUSTIFICATION TO TYPESET
	MOVEI	A,NHSPAC	;SET INITIAL SPACING
	IMUL	A,NSPNG		; TIMES CURRENT SPACING
	MOVE	N,PARTPG	;GET PARAGRAPH TEST PAGE
	ADDI	N,1+NASPAC	;ALLOW FOR NOTE HEADING
	IMUL	N,NSPNG		;TIMES SPACING
	ADDI	N,(A)		;INCLUDE SPACES
	PUSHJ	P,TSTPAG	;SEE IF ROOM
	  SKIPA			;NO--GONE TO NEW PAGE
	PUSHJ	P,SKIPN		;YES--DO THE SKIP
	MOVE	N,RMARG		;R MARGIN
	ADD	N,LMARG		;SUM OF MARGINS
	HRLI	N,NASPAC	;SET FOR SPACE AFTER HEADER
	MOVEM	N,CENPOS	;SET FOR CENTER COMMAND
	SETOM	CENTTL		;DON'T CHANGE TITLE
	MOVEI	S1,[ASCIZ \[*NT]\]
	SKIPLE	SCNTYP		;IF TYPESETTING
	PUSHJ	P,FMES		; ISSUE INDICATION
	PUSHJ	P,RSKIPS	;SKIP SPACES AND TABS
	  JRST	NOTEN		;IF NO MORE, THAT'S ALL
	SKIPG	SCNTYP		;UNLESS TYPESETTING,
	PUSHJ	P,CENT		; GO CENTER LINE
	SKIPLE	SCNTYP		;IF TYPESETTING,
	PUSHJ	P,INPTYP	; SEND REST OF LINE TO THEM
	PUSHJ	P,ATTYP		;ISSUE END OF MACRO FOR TYPESETTING
	JRST	ENDBCM		;FINISH COMMAND PROCESSING
				CONT.
;HERE IF NO STRING ON .NOTE COMMAND

NOTEN:	PUSHJ	P,FILSEQ	;ISSUE SEQUENCE NUMBERS
	HRRZ	A,CENPOS	;CENTER
	SUBI	A,4		;ALLOW FOR "NOTE"
	LSH	A,-1		;CENTER IS 1/2
	SKIPG	SCNTYP		;UNLESS TYPESETTING,
	PUSHJ	P,NSPAC		; SPACE OVER
	MOVEI	S1,[ASCIZ /NOTE/]
	PUSHJ	P,MCOUT		;OUTPUT "NOTE"
	PUSHJ	P,ATTYP		;ISSUE END OF MACRO FOR TYPESETTING
	SKIPLE	SCNTYP		;IF TYPESETTING,
	JRST	ENDBCM		; ALL DONE
	PUSHJ	P,SKIPS		;END LINE
	PUSHJ	P,CENTX		;FINISH CENTERED LINE
	JRST	ENDBCM		;AND COMMAND

;.LIST COMMANDS	(SAVE CURRENT STATE)

$LIST:	PUSHJ	P,OUTNJ		;BREAK PREVIOUS LINE
	MOVNI	N,LFSPAC	;SET FOR NO SPECIAL SPACING
	PUSHJ	P,PSHMJS	;SAVE MARGINS, ETC.
	PUSHJ	P,RCNO		;GET ARGUMENT
	  MOVE	N,NSPNG		;NULL--GET CURRENT SPACING
	JUMPLE	N,ILCM		;ERROR IF NEGATIVE
	CAILE	N,MX.SPC	;SEE IF TOO BIG
	JRST	ILCM		;YES--ERROR
	MOVEM	N,NSPNG		;SET NEW .SPACING
	MOVEI	N,L0LMAR	;GET LIST MARGIN 9
	SKIPE	LMARG		;IS LEFT MARGIN 0
	MOVEI	N,LSLMAR	;NO, GET 4
	ADDM	N,LMARG		;INCR LEFT MARGIN
	SETZM	INDCT		;CLEAR INDENT
	PUSHJ	P,LRMTYP	;ISSUE MARGINS FOR TYPESETTING
	AOS	N,LASLS		;INCREMENT LIST DEPTH
	CAILE	N,LN$MJP	;SEE IF OVERFLOW
	SOS	N,LASLS		;YES--BACK OFF
	SETZM	LSTCNT(N)	;CLEAR COUNTER
	MOVEI	S1,[ASCIZ \[*LS]\]
	SKIPLE	SCNTYP		;IF TYPESET,
	PUSHJ	P,FMES		; TELL TYPESET
	JRST	ENDBCM		;END BREAK COMMAND
				CONT.
;.END (NOTE)	(RESTORES STATE)

$END:	PUSHJ	P,OUTNJ		;BREAK PREVIOUS LINE
	PUSHJ	P,POPMJS	;RESTORE STATE
	SETZM	INDCT		;CLEAR INDENT
	SKIPGE	N		;SEE IF ENDING A LIST
	SOS	LASLS		;YES--DECREMENT DEPTH
	SKIPGE	LASLS		;SEE IF UNDERFLOW
	SETZM	LASLS		;YES--PROTECT OURSELF
	MOVEI	S1,[ASCIZ \[*EN]\]
	SKIPGE	N		;IF END LIST,
	MOVEI	S1,[ASCIZ \[*ELS]\]
	SKIPLE	SCNTYP		;IF TYPESET,
	PUSHJ	P,FMES		; TELL TTYPESET
	MOVMS	N		;GET ABSOLUTE VALUE
	IMUL	N,NSPNG		;MULT POST SPACING BY
	MOVE	A,N		; CURRENT SPACING
	PUSHJ	P,SKIPNC	; AND ISSUE IT
	JRST	ENDBCM		;END BREAK COMMAND

;.LIST ELEMENT

$LI.EL:	PUSHJ	P,OUTNJ		;BREAK PREVIOUS LINE
	PUSHJ	P,PARAG0	;SETUP PARAGRAPH
	MOVEI	S1,[ASCIZ \[*LE]\]
	SKIPLE	SCNTYP		;IF TYPESETTING,
	PUSHJ	P,FMES		; TELL TYPESET
	MOVE	N,LASLS		;GET LIST DEPTH
	AOS	N,LSTCNT(N)	;COUNT THIS ENTRY
	PUSHJ	P,COUNTD	;SEE HOW MANY DIGITS
	ADDI	A,LESPAC+1	;ALLOW ALSO FOR ".##"
	CAMLE	A,LMARG		;BUT AVOID UNDERFLOW
	MOVE	A,LMARG		; ..
	MOVNM	A,INDCT		;SPECIFY AS NEGATIVE INDENT
	PUSHJ	P,LINSET	;SETUP NEW LINE
	MOVE	N,LASLS		;GET DEPTH
	MOVE	N,LSTCNT(N)	;GET COUNT
	PUSHJ	P,DECINP	;STORE IN LINE
	MOVEI	CH,C.PD		;GET PERIOD
	PUSHJ	P,WLNINC	;STORE THAT
	MOVEI	D,LESPAC	;GET COUNT OF SPACES
	MOVEI	CH,C.NXS	;GET NON-EXPANDABLE SPACE ITSELF
	PUSHJ	P,WLNINC	;STORE IT
	SOJG	D,.-1		;LOOP UNTIL DONE
	TLO	F,L.NFSP	;INDICATE NO FREE SPACE
	JRST	ENDCM		;FINISH WITHOUT BREAK
;.RIGHT COMMAND

$RIGHT:	PUSHJ	P,RCNO		;GET NUMBER
	  JFCL			;IGNORE ERROR
	SUB	N,RMARG		;COMPUTE -<R.MARG.-ARG>
	JUMPG	N,ILCM		;ERROR IF N GT R.MARG.
	MOVE	A,N		;MAKE A COPY
	ADD	A,PRMRG		;COMPARE WITH PAGE WIDTH
	JUMPL	A,ILCM		;ERROR IF TO RIGHT OF PAGE WIDTH
	JRST	CENT0		;AND GO INTO .CENTER CODE

;CENTER COMMAND
;PERIOD AND EXCLAMATION ARE VALID TEXT.

$CENTE:	MOVE	N,PRMRG		;GET RIGHT SIDE OF PAPER
	PUSHJ	P,RCNR		;SEE IF ANY ARGUMENT
	  JFCL			;IGNORE NULL
	JUMPLE	N,ILCM		;ERROR IF NEG OR ZERO
	MOVE	A,N		;COMPARE
	LSH	A,-1		;  TO
	CAML	A,PRMRG		;  RIGHT MARGIN
	JRST	ILCM		;ERROR IF BEYOND
CENT0:	HRRZM	N,CENPOS	;SAVE POSITION
	SETOM	CENTTL		;DON'T CHANGE TITLE
	PUSHJ	P,OUTNJ		;OUTPUT CURRENT LINE
	PUSHJ	P,FRCEND	;SKIP TO END OF COMMAND
	PUSHJ	P,CENT		;GO DO THE CENTERING
	JRST	ENDBCM		;AND FINISH PROCESSING
;ROUTINE TO ACTUALLY DO THE CENTERING.  IT MUST
;BE INITIALIZED WITH CENPOS AS FOLLOWS:
;RH(CENPOS) = +N IF CENTER ON COL.N/2
;	      -N IF RIGHT ADJUST ON COL.N
;LH(CENPOS) = +N IF SKIP N AFTER LINE
;	      -N DITTO, BUT COMMAND CAN END WITH ; ETC.

CENT:	SETZM	INDCT		;CLEAR INDENT
	SKIPG	LINEC		;SEE IF TOP OF PAPER
	PUSHJ	P,HEADIN	;YES--OUTPUT HEADING
	PUSHJ	P,LINSET	;INITIALIZE LINE COUNTER
	MOVEI	C,0		;COUNT OF TRAILING SPACES AND TABS
CENTL:	PUSHJ	P,GCIN		;READ LINE TO BE CENTERED
	SKIPGE	CENPOS		;SEE IF NEW STYLE COMMAND
	JRST	[PUSHJ P,CMSOMP	;YES--SEE IF END OF COMMAND	[165]
		   JRST CENT2	;YES--THAT'S ALL
		 JRST  .+1]	;NO--CONTINUE
	CAIN	CH,.CHLFD	;THROUGH LINE FEED
	JRST	CENT2		; LINE FEED--DONE.
	CAIN	CH,.CHTAB	;SEE IF TAB
	MOVEI	CH,C.SPC	;YES--CHANGE TO SPACE
	CAIE	CH,C.SPC	;SEE IF SPACE
	TDZA	C,C		;NO--CLEAR COUNT
	SOS	C		;YES--COUNT IT
	CAIN	CH,LCHPVT!C.SPC	;[236] IS THIS A FORCED SPACE?
	AOS	NSPCH		;[236] YES--COUNT IT AS NON-SPACE
	PUSHJ	P,WLNIN1	;PUT IN LINE INPUT BUFFER
	SOSGE	CENTTL		;SEE IF TITLE CHANGING
	JRST	CENTL		;NO OR FULL
	MOVEI	PA,TTLP1	;YES--POINT TO IT
	PUSHJ	P,WCI		;STORE
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	SOS	CENTTL		;YES--EXTRA COUNT
	JRST	CENTL		;LOOP FOR MORE
				CONT.
CENT2:	MOVEM	CH,GCSCH	;END--SAVE CHARACTER
	ADDB	C,LNIN2		;CHOP TRAILING SPACES/TABS
	HRRE	A,CENPOS	;RESTORE ARGUMENT
	CAMG	C,LNIN1		;SEE IF BLANK LINE
	JRST	CENTBL		;YES--GO HANDLE
	SKIPLE	SCNTYP		;IF TYPESETTING,
	JRST	CENTYP		; GO HANDLE SPECIALLY
	JUMPLE	A,[MOVN  B,A	;IF NEG, WAS .RIGHT
		   HRLOI A,INFIN
		   JRST  CENT3]
	ADD	A,LNIN1		;AS HALF RIGHT MARGIN
	SUB	A,LNIN2		;MINUS HALF OF LINE SIZE
	ADD	A,NSPCH		; INCLUDING UNDERLINES, ETC.
	ASH	A,-1		;TAKE HALF
	MOVE	B,PRMRG		;GET RIGHT MARGIN
CENT3:	ADD	B,LNIN1		;SUBTRACT
	SUB	B,LNIN2		;WIDTH
	ADD	B,NSPCH		;HANDLE NON-SPACING CONTENT
	CAMLE	A,B		;SEE IF TOO FAR RIGHT
	MOVE	A,B		;YES--SHIFT LEFT
	SUB	A,LMARG		;COUNTERACT MARGINS
	MOVEM	A,INDCT		;SET AS FUNNY INDENT
	PUSHJ	P,OUTNJ		;OUTPUT THE LINE
	JRST	CENTX		;FINISH CENTER COMMAND
				CONT.
;HERE TO OUTPUT FOR TYPESETTING

CENTYP:	JUMPLE	A,RGHTYP	;IF RIGHT ADJUSTING, GO HANDLE
	MOVE	N,A		;GET IN USEFUL PLACE
	SUB	A,LMARG		;SEE IF
	CAMN	A,RMARG		; CENTERED IN MARGINS
	JRST	[PUSHJ P,LINTYP	;YES--OUTPUT LINE BUFFER
		 MOVEI S1,[ASCIZ \/C/L
\]
		 PUSHJ P,FMES	;CENTER AND END LINE
		 JRST  CENTX]	;AND GO FINISH UP
	MOVEI	S1,[ASCIZ \[T%][TS\]
	PUSHJ	P,FMES		;ELSE, CLEAR TABS
	IMUL	N,TYPMUL	;CONVERT COLUMN TO
	IMULI	N,^D12		; HORIZONTAL
	MOVE	A,TYPDIV	; SPACING
	LSH	A,1		; (ALLOW FOR N/2)
	IDIV	N,A		; INTO POINTS
	CAML	N1,TYPDIV	; AND ROUND
	AOS	N		; OFF
	PUSHJ	P,TYPHSP	;OUTPUT HORIZONTAL SPACING
	MOVEI	CH,"]"		;END COMMAND
	PUSHJ	P,FOUT		; FOR TYPESETTING
	PUSHJ	P,LINTYP	;OUTPUT LINE BUFFER
	MOVEI	S1,[ASCIZ \/A/L
\]
	PUSHJ	P,FMES		;CENTER ON TAB
	PUSHJ	P,STSTYP	;SET TAB STOPS
	JRST	CENTX		;AND GO FINISH UP

;HERE FOR TYPESETTING RIGHT ADJUSTED
RGHTYP:	MOVE	N,RMARG		;GET RIGHT MARGIN
	ADD	N,A		;GET OFFSET BACK INDENT
	JUMPE	N,RGHTY1	;IF FULL RIGHT, NO HANG
	MOVEI	S1,[ASCIZ \/?[HR\]
	PUSHJ	P,FMES		;CLEAR LINE AND HANG RIGHT
	PUSHJ	P,TYPDSP	;ISSUE AMOUNT OF HANG
	MOVEI	S1,[ASCIZ \,0,1]\]
	PUSHJ	P,FMES		;FOR ONE LINE, NO DELAY
RGHTY1:	PUSHJ	P,LINTYP	;OUTPUT LINE BUFFER
	MOVEI	S1,[ASCIZ \/R
\]
	PUSHJ	P,FMES		;RIGHT ADJUST
	JRST	CENTX		;AND GO FINISH UP

CENTBL:	PUSHJ	P,OUTLEX	;SKIP BLANK LINE IF BLANK
CENTX:	HLRE	A,CENPOS	;GET SPACING
	MOVMS	A		;GET ABS. VALUE
	IMUL	A,NSPNG		;SET SPACING
	PJRST	SKIPN		;OUTPUT SPACING AND RETURN
;BAR COMMANDS:

;ENABLE BAR

$AN.BA:	SKIPN	SCNBAR		;SEE IF /BAR:0
	JRST	ENDCM		;YES--IGNORE BAR ACTIVITY
	MOVEI	S1,[ASCIZ \[*EBB]\]
	SKIPLE	SCNTYP		;IF TYPESET,
	JRST	TYPBAR		; GO HANDLE
	SETOM	BARSW		;INDICATE ENABLED
	JRST	ENDCM		;END COMMAND

;BEGIN BAR

$BE.BA:	MOVEI	S1,[ASCIZ \[*BB]\]
	SKIPLE	SCNTYP		;IF TYPESET,
	JRST	TYPBAR		; GO HANDLE
	SKIPN	BARSW		;IF BARS DISABLED,
	JRST	ENDCM		; JUST IGNORE BAR
	SETOM	BARON		;INDICATE BARS
	SETOM	BARNPY		;SET BAR MODE FOR START ALSO
	JRST	ENDCM		;END COMMAND

;DISABLE BAR
;END BAR

$DI.BA:	MOVEI	S1,[ASCIZ \[*DB]\]
	SKIPLE	SCNTYP		;IF TYPESET,
	JRST	TYPBAR		; GO HANDLE
	SETZM	BARSW		;DISABLE BARS
	SETZM	BARNPY		;CLEAR HANGING BAR
$EN.BA:	MOVEI	S1,[ASCIZ \[*EB]\]
	SKIPLE	SCNTYP		;IF TYPESET,
	JRST	TYPBAR		; GO HANDLE
	SETZM	BARON		;STOP BARS
	MOVE	B,LNIN1		;IF INPUT BUFFER
	CAMN	B,LNIN2		; EMPTY, AND
	SKIPE	CPOS		;IF AT START OF LINE,
	SKIPA			;NO
	SETZM	BARNPY		;YES--CLEAR BAR THIS LINE FLAG
	JRST	ENDCM		;END COMMAND

;HERE IF /TYPESET ON A BAR COMMAND

TYPBAR:	SKIPE	SCNBAR		;UNLESS /NOBAR,
	PUSHJ	P,FMES		;ISSUE MACRO TO TYPESET
	JRST	ENDCM		;AND END COMMAND
;.TYPESET COMMAND
;	TAKES LIST OF ARGUMENTS SEPARATED BY SPACE OR COMMA
;	EACH ITEM IS ONE OF:
;		SPACE		SPACE OUTPUT (DEFAULT=NO SPACES)
;		BOLD	)
;		ITALICS	)--	SELECT SPECIAL CASE
;		REGULAR )	  (RESTORES TO REGULAR
;		SMALLCAPS)	    UNLESS AT END)
;
;		"STRING"	STRING HAS " AS ""
;		[STRING]	INCLUDES []
;		<STRING>	INCLUDES <>
;		+CHAR		INCLUDES +
;		/CHAR		INCLUDES /

$TYPES:	SKIPG	SCNTYP		;SEE IF /TYPESET
	JRST	$COMME		;NO--TREAT AS COMMENT
	SETOM	FLTYPC		;INDICATE .TYPESET
	SETZM	FLTYPR		;DON'T RESTORE REGULAR FONT
	PUSHJ	P,OUTLIN	;OUTPUT WHAT WE HAVE SO FAR
	SETZM	FLTYPC		;CLEAR .TYPESET MODE

TYPESL:	PUSHJ	P,CMGNWD	;GET NEXT COMMAND WORD
	  JRST	TYPESC		;NULL--GO SEE IF SPECIAL
	MOVE	S1,[-LENTYP,,TYPTAB]
	PUSHJ	P,CMREC		;GO LOOK IN TABLE
	  JRST	ILCM		;ERROR IF NOT FOUND
	HLRZ	S1,(D)		;GET VALUE
	SKIPN	S1		;IF 0, "SPACE"
	JRST	[MOVEI CH," "	;ISSUE SPACE
		 PUSHJ P,FOUT	; TO OUTPUT
		 JRST  TYPESL]	;LOOP FOR MORE
	SETOM	FLTYPR		;INDICATE FONT SETTING
	PUSHJ	P,FMES		;ISSUE FONT CHANGE
	JRST	TYPESL		;LOOP FOR MORE

TYPESC:	PUSHJ	P,CMSOME	;SEE IF END OF COMMAND
	  JRST	TYPESX		;YES--EXIT
	PUSHJ	P,CCIN		;GET SEPARATOR
	CAIN	CH,","		;IF COMMA,
	JRST	TYPESL		; JUST LOOP FOR MORE WORK
	MOVMS	FLTYPR		;INDICATE TEXT FOLLOWING FONT
	CAIE	CH,"+"		;IF PI-CASE
	CAIN	CH,"/"		;OR ESCAPE,
	JRST	[PUSHJ P,FOUT	; ISSUE THIS CHARACTER
		 PUSHJ P,CCIN	; GET NEXT CHAR
		 PUSHJ P,FOUT	; ISSUE THAT
		 CAIN  CH,.CHLFD ;DEFEND AGAINST LINE FEED
		 JRST  TYPESX	; YES--EXIT
		 JRST  TYPESL]	; NO--LOOP FOR MORE WORK
				CONT.
;HERE WHEN LOOKING FOR A QUOTED STRING IN .TYPESET COMMAND

	MOVEI	C2,0		;CLEAR MATCH
	CAIN	CH,"["		;SEE IF BRACKET MODE
	MOVEI	C2,"]"		;YES--SET END CODE
	CAIN	CH,"<"		;SEE IF COMMENT
	MOVEI	C2,">"		;YES--SET END CODE
	CAIN	CH,""""		;SEE IF QUOTED STRING
	HRROI	C2,""""		;YES--SET QUOTED END CODE
	JUMPE	C2,ILCM		;IF NOT RECOGNIZED, ERROR
	SKIPL	C2		;UNLESS QUOTE,
TYPESS:	PUSHJ	P,FOUT		; ISSUE THIS CHARACTER
	PUSHJ	P,CCIN		;GET NEXT CHARACTER
	CAIN	CH,.CHLFD	;SEE IF END OF LINE
	JRST	TYPESX		;YES--END COMMAND
	CAIE	CH,(C2)		;SEE IF MATCHES END
	JRST	TYPESS		;NO--LOOP OUTPUTTING
	SKIPL	C2		;YES--SEE IF QUOTE
	JRST	[PUSHJ P,FOUT	;NO--ISSUE END
		 JRST  TYPESL]	; AND LOOP FOR MORE WORK
	PUSHJ	P,CCIN		;YES--GET NEXT CHARACTER
	CAIN	CH,(C2)		;SEE IF DOUBLED QUOTE
	JRST	TYPESS		;YES--REPRESENTS ONE QUOTE
	MOVEM	CH,GCSCH	;NO--TRUE END, PREPARE TO REEAT
	JRST	TYPESL		;LOOP FOR MORE WORK

TYPESX:	MOVEI	S1,[ASCIZ \[FR]\]
	SKIPLE	FLTYPR		;IF FONT THEN TEXT,
	PUSHJ	P,FMES		; RESTORE REGULAR FONT
	SETZM	FLTYPR		;CLEAR FLAG
	SETOM	FLTYPS		;SET TO SUPPRESS NEXT FREE SPACE
	TLO	F,L.NFSP	;SET FOR NO ENDING SPACE
	MOVEI	S1,CRLFM	;GIVE EXTRA CRLF
	PUSHJ	P,FMES		; TO HANDLE TYPESET LINE LIMIT
	JRST	ENDBCM		;GO RE-INITIALIZE BUFFER

TYPTAB:			;TABLE OF [FONT SET],,COMMAND
	CM	<[ASCIZ \[FB]\]>,<BOLD>
	CM	<[ASCIZ \[FI]\]>,<ITALICS>
	CM	<[ASCIZ \[FR]\]>,<REGULAR>
	CM	<[ASCIZ \[FM]\]>,<SLANT>
	CM	<[ASCIZ \[FS]\]>,<SMALLCAPS>
	CM	<	      0>,<SPACE>
LENTYP==.-TYPTAB
	SUBTTL	CHAPTER AND SECTION OPERATIONS

;+
;.CHAPTER CHAPTER AND SECTION OPERATIONS
;-

;.CHAPTER COMMAND
; DOES .BREAK.PAGE.BLANK12.CENTER;^^CHAPTER N
; ALSO SETS NEW TITLE
; .BLANK1.CENTER;TITLE(REST OF COMMAND)
; .BLANK3;RESETS CASE, MARGINS, SPACING, JUST/FILL
;PERIOD AND EXCLAMATION ARE VALID TEXT

$CHAPT:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;FINISH CURRENT LINE
	PUSHJ	P,BPAGE		;BREAK PAGE
	JRST	CHAPT		;GO DO THE WORK

;.APPENDIX COMMAND
;SAME AS .CHAPTER EXCEPT PAGE NUMBERS A-1, ETC.

$APPEN:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;FINISH CURRENT LINE
	PUSHJ	P,BPAGE		;BREAK PAGE
	MOVX	A,APPXFL	;SET APPENDIX
	TDNN	A,SECNUM	; FLAG UNLESS
	MOVEM	A,SECNUM	; ALREADY SET
				CONT.
;^THE CHAPTER AND APPENDIX COMMANDS MERGE TOGETHER HERE
;TO ACTUALLY OUTPUT THE HEADING.

CHAPT:	MOVEI	A,ILPGNO	;RESET
	MOVEM	A,PAGENO	; PAGE COUNTER
	SETZM	SUBPGE		;CLEAR SUBPAGING
	SKIPLE	B,PNLPG		;GET PAGE LENGTH		[205]
	CAIG	B,^D1000	;UNLESS ABSURD, THEN		[205]
	MOVEI	B,^D64		;USE "STANDARD"			[205]
	MOVEI	A,CHAPTB	;WANT TWELVE BLANK LINES
	IMUL	A,B		;TIMES PAGE LENGTH
	IDIVI	A,^D64		;DIVIDED BY NOMINAL LENGTH
	PUSHJ	P,SKIPN		;GET THEM
	SETOM	FLTITL		;INDICATE TO START TITLES
	MOVEI	A,0		;LEVELS TO ZERO COUNTER
	PUSHJ	P,ZERSEC	;ZERO LOWER LEVELS
	PUSHJ	P,FILSEQ	;OUTPUT FILE SEQUENCE
	MOVE	A,SECNUM	;GET CHAPTER NUMBER
	PUSHJ	P,COUNTC	;COUNT DIGITS
	MOVE	B,A		;SAVE
	MOVE	A,PRMRG		;GET PAPER WIDTH
	SUBI	A,^D8(B)	;ALLOW FOR "CHAPTER N"
	MOVE	C,SECNUM	;GET CHAPTER NUMBER
	TXNE	C,APPXFL	;SEE IF APPENDIX
	SOS	A		;YES--ALLOW FOR WIDER WORD
	LSH	A,-1		;COMPUTE CENTER
	SKIPG	SCNTYP		;UNLESS TYPESETTING
	PUSHJ	P,NSPAC		;SPACE IN
	MOVEI	S1,[ASCIZ/CHAPTER /]	;INSERT WORD "CHAPTER"
	TXNE	C,APPXFL	;CHECK FOR APPENDIX
	MOVEI	S1,[ASCIZ/APPENDIX /]  ;YES--USE "APPENDIX" INSTEAD
	SKIPG	SCNTYP		;UNLESS TYPESETTING
	PUSHJ	P,MCOUT		; OUTPUT IT
	MOVEI	S1,[ASCIZ \[*CH]\]
	TXNE	C,APPXFL	;CHECK FOR APPENDIX
	MOVEI	S1,[ASCIZ \[*AX]\]
	SKIPLE	SCNTYP		;IF TYPESETTING
	PUSHJ	P,FMES		; OUTPUT MACRO CALL
	MOVE	N,SECNUM	;WHAT CHAPTER?
	PUSHJ	P,CHPPRT	;OUTPUT NUMBER
	PUSHJ	P,ATTYP		;END TYPESETTING MACRO ARG
	MOVEI	A,CHAPTC+1	;WANT A BLANK LINE
	SKIPG	SCNTYP		;UNLESS TYPESETTING
	PUSHJ	P,SKIPN		; OUTPUT IT
	PUSHJ	P,CLRTTL	;RESET AND CLEAR TITLE BUFFER
	MOVEI	A,5*LN$TTL-1	;SET COUNT
	MOVEM	A,CENTTL	;FOR CENTER ROUTINE
	PUSHJ	P,CLRSTT	;CLEAR SUBTITLE
				CONT.
	PUSHJ	P,RSKIPS	;SKIP TO TITLE
	  JRST	CHAPX		;MISSING--JUST FINISH
	PUSHJ	P,LINDFL	;FORCE LINE UPPER CASE
	SKIPLE	SCNTYP		;IF TYPESETTING
	JRST	[PUSHJ P,INPTYP	; OUTPUT REST OF COMMAND
		 JRST  CHAPX]	; AND PROCEED
	MOVE	N,PRMRG		;GET PAPER WIDTH
	HRLI	N,-CHAPTD	;SET FOR 3 BLANKS AFTER
	MOVEM	N,CENPOS	;SET INFO FOR CENT PROCESSING
	PUSHJ	P,CENT		;GO CENTER LINE
CHAPX:	PUSHJ	P,ATTYP		;END TYPESETTING MACRO ARG
	MOVE	N,PRMRG		;END OF CHAP COMMAND
	SETZM	SMINSC		;INDICATE NOTHING IN THIS SECTION
	JRST	SDXY		;RESET PARAMETERS


;.HEADER LEVEL COMMAND
;TAKES NUMBER THEN TEXT AS ARGUMENT.  NUMBER IS THE
;SECTION DEPTH (1-4); THE TEXT IS THE SECTION TITLE.
; DOES A .BREAK.TP<PARAG+7>.BLANK3
; THEN TYPES A.B.C.D (DECIMAL COUNTS)##^^(IF HL1)TEXT
; THEN IF .HL1-2 .BLANK1
; ELSE CONTINUES #-#
;CAPITALIZES FIRST LETTER OF EACH WORD (ALL LETTERS IF .HL1).
;FINALLY, RESETS CASE, JUST/FILL
;PERIOD AND EXCLAMATION ARE VALID TEXT.

$HE.LE:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;OUTPUT PREVIOUS LINE
	MOVE	N,PARTPG	;GET PARAGRAPH .TP
	IMUL	N,NSPNG		;TIMES SPACING
	ADDI	N,HEADLT+HEADLB	;ALLOW FOR .HL SPACING
	PUSHJ	P,TSTPAG	;SEE IF ROOM ON PAGE
	  JRST  HL1		;NO--CONTINUE
	MOVEI	A,HEADLB	;ROOM--ISSUE LEADING BLANK
	SKIPE	SMINSC		;UNLESS BLANK SECTION,
	PUSHJ	P,SKIPNC	; LINES
				CONT.
HL1:	SKIPN	N,LASHL		;GET LAST DEPTH INDICATOR
	MOVEI	N,1		;(START AT 1)
	PUSHJ	P,RCNR		;GET RELATIVE HEADING LEVEL
	  JFCL			;NULL IS SAME AS LAST ONE
	CAIG	N,LN$SEC	;SEE IF 6 OR LESS
	CAIG	N,0		;SEE IS NOT ZERO
	JRST	ILCM		;ERROR
	TLO	F,L.PJUS!L.JUST!L.FILL  ;SET .FILL.JUST
	PUSHJ	P,JUSTYP	;ISSUE JUSTIFICATION TO TYPESET
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	[MOVEI S1,[ASCIZ \[*HL\]
		 PUSHJ P,FMES	;YES--INDICATE IT
		 SAVE$ N	;PRESERVE LEVEL
		 PUSHJ P,DECPRT	;INDICATE LEVEL
		 RSTR$ N	;RESTORE LEVEL
		 MOVEI CH,"]"	;END MACRO CALL
		 PUSHJ P,FOUT	; ..
		 JRST  .+1]	;AND CONTINUE
	MOVE	A,N		;PUT LEVEL IN A
	PUSHJ	P,ZERSEC	;ZERO APPROPRIATELY
	PUSHJ	P,LINDFO	;FORCE EACH WORD CAPITALIZED
	CAIN	N,1		;IS IT FIRST LEVEL?
	PUSHJ	P,LINDFL	;YES--FORCE LINE UPPER CASE
	PUSHJ	P,OUTSEC	;GO PUT OUT HEADING
				;NOTE--A SET TO 0 IF NO HEADING
	SAVE$	A		;PRESERVE VALUE
	MOVEI	CH,C.TAT	;SET END OF TYPESETTING MACRO
	PUSHJ	P,WLNIN1	; INTO INPUT BUFFER
	RSTR$	A		;RESTORE FLAG
	AOS	LINNSC		;COUNT AS NON-SPACING
	MOVE	B,FILCAS	;GET INITIAL CASE MODE
	MOVEM	B,CAS		;MAKE IT CURRENT MODE
	MOVE	N,LASHL		;GET HEADING LEVEL
	CAIL	N,3		;IF .HL1 OR .HL2
	JRST	HD3OUT		;NO--GO HANDLE
	PUSHJ	P,OUTNJ		;YES--OUTPUT LEFT JUSTIFIED
	MOVEI	A,HEADLC	;ISSUE FINAL
	PUSHJ	P,SKIPN		; BLANK
	SETZM	SMINSC		;INDICATE NOTHING IN THIS SECTION YET
	JRST	ENDBCM		;AND END THIS BREAK COMMAND
;HERE IF .HL3 OR GREATER
HD3OUT:	JUMPE	A,HD3OUN	;IF NO NAME, SKIP SEPARATOR
	MOVEI	CH,C.NXS	;GET NON-EXPANDABLE SPACE
	PUSHJ	P,WLNINC	;STORE
	MOVEI	CH,C.HYPH	;GET HYPHEN
	PUSHJ	P,WLNINC	;STORE
	MOVEI	CH,C.NXS	;GET NON-EXPANDABLE SPACE
	PUSHJ	P,WLNINC	;STORE
HD3OUN:	TLO	F,L.NFSP	;INDICATE NO FREE SPACE
	SETZM	SMINSC		;INDICATE NOTHING IN THIS SECTION YET
	JRST	ENDCM		;END LINE WITHOUT CLEARING BUFFER
;ROUTINE TO ZERO COUNTERS BEYOND A SPECIFIED LEVEL
;AND COUNT AT THIS LEVEL
;CALL WITH LEVEL IN A (0=CHAPTER)

ZERSEC:	MOVEM	A,LASHL		;SAVE AS CURRENT/LAST HL
	AOS	SECNUM(A)	;COUNT THIS ONE
ZRSCLP:	ADDI	A,1		;GO TO NEXT LOWER LEVEL
	CAIL	A,LN$SEC	;SEE IF DONE
	POPJ	P,		;YES--RETURN
	SETZM	SECNUM(A)	;NO--ZERO THIS LEVEL
	JRST	ZRSCLP		;LOOP

;ROUTINE TO OUTPUT CURRENT SECTION'S NUMBER
;CALLED WITH N=CURRENT SECTION LEVEL (1 FOR .HL1)
;RETURNS A=0 IF NO HEADING SPECIFIED

OUTSEC:	MOVN	D,N		;GET NEG LEVEL
	HRLZI	D,-1(D)		;SET FOR AOBJN INCL. CHAPTER
	SKIPN	SECNUM		;SEE IF.CHAP
	AOBJN	D,.+1		;NO--SKIP CHAPTER LEVEL
	TLC	D,-1		;SEE IF .HL1 WITHOUT CHAPTER
	TLCN	D,-1		; ..
	SUB	D,[1,,0]	;YES--MIN OF TWO LEVELS
OUTSEL:	MOVE	N,SECNUM(D)	;GET THIS SECTION'S NUMBER
	TRNN	D,-1		;SEE IF CHAPTER LEVEL
	PUSHJ	P,CHPINP	;YES--ISSUE IN CHAPTER FORMAT
	TRNE	D,-1		;ELSE,
	PUSHJ	P,DECINP	; CONVERT TO DECIMAL IN INPUT BUFFER
	AOBJP	D,SECSPC	;COUNT--EXIT IF DONE
	MOVEI	CH,C.PD		;NO--GET PERIOD
	PUSHJ	P,WLNINC	;ENTER AS SEPARATOR
	JRST	OUTSEL		;LOOP
				CONT.
;HERE AT END OF ISSUEING SECTION ID
SECSPC:	MOVEI	CH,C.NXS	;GET NON-EXPANDABLE SPACE
	PUSHJ	P,WLNINC	;ENTER IN INPUT
	PUSHJ	P,WLNINC	;AND A SECOND TIME
	PUSHJ	P,RSKIPS	;SKIP TO TEXT IN COMMAND
	  JRST	[SETZM A	;IF NO TEXT
		 POPJ  P,]	; RETURN WITH A=0
	SETOM	C		;INDICATE NO SUBTITLE
	MOVE	A,LASHL		;GET HL LEVEL
	CAIE	A,1		;SEE IF HL1
	JRST	HLLP		;NO--DON'T CHANGE SUBTITLE
	PUSHJ	P,CLRSTT	;CLEAR SUBTITLE
	MOVEI	C,5*LN$TTL-1	;GET LENGTH
HLLP:	PUSHJ	P,GCIN		;GET NEXT LINE OF TEXT
	CAIE	CH,.CHTAB	;SEE IF TAB
	CAIN	CH,C.SPC	; OR SPACE
	JRST	HLSP		;YES--GO HANDLE
	PUSHJ	P,CMSOMP	;SEE IF DONE			[165]
	  JRST	HLXT		;YES--RETURN
HLST:	CAIG	CH,C.FLGS	;[234] INTERNAL FLAG?
	JRST	HLSU		;[234] YES--SPECIAL PROCESSING
	PUSHJ	P,WLNINC	;NO--STORE
	SOJL	C,HLLP		;COUNT DOWN SPACE IN SUBTITLE
	MOVEI	PA,STTLP1	;IF ROOM (AND HL1)
	PUSHJ	P,WCI		;STORE
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	SOS	C		;YES--COUNT SPACE
	JRST	HLLP		;AND LOOP FOR MORE

HLSU:	PUSHJ	P,WLNIN1	;[234] STORE IN LINE BUFFER
	AOS	LINNSC		;[234] COUNT IT UP
	JRST	HLLP		;[234] BACK FOR MORE

HLSP:	PUSHJ	P,RSKIPS	;IGNORE MULT. SPACES AND TABS
	  JFCL			;IGNORE EOL INDICATION
	MOVEI	CH,C.NXS	;ELSE USE ONE NON-EPANDABLE ONE
	JRST	HLST		;IN BUFFER
HLXT:	MOVEM	CH,GCSCH	;SET TO RESCAN THIS CHAR
	SETOM	A		;INDICATE SOME HEADER
	POPJ	P,		;THEN RETURN

;ROUTINE TO CLEAR THE CURRENT SUBTITLE BUFFER

CLRSTT:	MOVEI	PA,STTLBF	;POINT TO SUBTITLE
	PUSHJ	P,CSP		;COMPUTE POINTERS TO BUFFER
	MOVEM	A,STTLP1	;STORE
	MOVEM	B,STTLP2	; EMPTY
	POPJ	P,		;RETURN

;ROUTINE TO CLEAR THE CURRENT TITLE BUFFER

CLRTTL:	MOVEI	PA,TTLBUF	;POINT TO TITLE
	PUSHJ	P,CSP		;COMPUTE POINTERS TO BUFFER
	MOVEM	A,TTLP1		;STORE
	MOVEM	B,TTLP2		; EMPTY
	POPJ	P,		;RETURN
	SUBTTL	VARIABLE AND IF OPERATIONS

;+.CHAPTER VARIABLE AND IF OPERATIONS
;-

;.VARIABLE COMMAND

$VARIA:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	MOVE	S1,FILNVR	;GET COUNT
	AOS	S1		;INCREMENT COUNT
	CAILE	S1,LN$VAR	;SEE IF TOO MANY
	JRST	[MOVEM S1,FILNVR ;YES--UPDATE COUNT TO GET MESSAGE ONLY ONCE
		 ILCM$ (EVL,Exceeding VARIABLE list)]
	SETOM	FILVVR-1(S1)	;SET VALUE TO FALSE
	PUSHJ	P,RSIXN		;GET VARIABLE NAME IN SIXBIT
	JUMPE	N,ILCM		;ERROR IF BLANK
	MOVEM	N,FILVAR-1(S1)	;STORE IN TABLE
	PUSHJ	P,VALVAR	;LOOK IN TABLE
	  SKIPA			;OK IF MISSING
	JRST	E$$DVN		;ERROR IF DUPLICATE
	PUSHJ	P,RSKIPS	;SKIP SPACES
	  JRST	ILCM		;ERROR IF DONE
	CAIN	CH,C.CMA	;SEE IF COMMA
	SETOM	GCSCH		;YES--SKIP IT
	PUSHJ	P,RSKIPS	;SKIP SPACES
	  JRST	ILCM		;ERROR IF DONE
	PUSHJ	P,CCIN		;GET TRUE FLAG FOR DRAFTS
	TXZ	CH,LCHPVT	;CLEAR QUOTE
	HRLZM	CH,FILFVR-1(S1)	;STORE
	PUSHJ	P,RSKIPS	;SKIP SPACES
	  JRST	ILCM		;ERROR IF DONE
	CAIN	CH,C.CMA	;SEE IF COMMA
	SETOM	GCSCH		;YES--SKIP IT
	PUSHJ	P,RSKIPS	;SKIP SPACES
	  JRST	ILCM		;ERROR IF DONE
	PUSHJ	P,CCIN		;GET FALSE FLAG FOR DRAFTS
	TXZ	CH,LCHPVT	;CLEAR QUOTE
	HRRM	CH,FILFVR-1(S1)	;STORE
	MOVE	N,FILVAR-1(S1)	;GET BACK NAME
	MOVN	A,SCNNVR	;SEE HOW MANY FROM USER
	HRLZS	A		;POSITION FOR AOBJN
	CAME	N,SCNVAR(A)	;SEE IF MATCH
	AOBJN	A,.-1		;NO--TRY NEXT			[220]
	SKIPGE	A		;SEE IF DEFINED AS VARIANT	[220]
	SETZM	FILVVR-1(S1)	;YES--FLAG TRUE
	MOVEM	S1,FILNVR	;ALL OK--UPDATE REAL COUNT
	JRST	ENDCM		;FINISH COMMAND

	ILCM$	DVN,Duplicate VARIABLE name
;.IF/.IFNOT/.ELSE/.ENDIF COMMANDS

$IF:	PUSHJ	P,RSIXN		;GET VARIABLE NAME
	PUSHJ	P,VALVAR	;GET VALUE
	  JRST	E$$UKV		;ERROR IF UNKNOWN
	PUSHJ	P,PUSHIF	;[244] STACK IF'S
	MOVEM	A,VRSKIP	;SAVE INDEX FOR END TESTS
	MOVEM	N,IFSKIP	;SET VALUE
	JRST	ENDVCM		;END VARIABLE COMMAND

$IFNOT:	PUSHJ	P,RSIXN		;GET VARIABLE NAME
	PUSHJ	P,VALVAR	;GET VALUE
	  JRST	E$$UKV		;ERROR IF UNKNOWN
	PUSHJ	P,PUSHIF	;[244] STACK IF'S
	MOVEM	A,VRSKIP	;SAVE INDEX FOR END TESTS
	SETCAM	N,IFSKIP	;SET VALUE
	JRST	ENDVCM		;END VARIABLE COMMAND

$ELSE:	PUSHJ	P,RSIXN		;GET VARIABLE NAME
	PUSHJ	P,VALVAR	;GET VALUE
	  JRST	E$$UKV		;ERROR IF UNKNOWN
	CAME	A,VRSKIP	;SEE IF SAME VARIABLE
	JRST	E$$BEE		;BAD .ELSE
	SETCMM	IFSKIP		;YES--COMPLEMENT VALUE
	JRST	ENDVCM		;END VARIABLE COMMAND

$ENDIF:	PUSHJ	P,RSIXN		;GET VARIABLE NAME
	PUSHJ	P,VALVAR	;GET VALUE
	  JRST	E$$UKV		;ERROR IF UNKNOWN
	CAME	A,VRSKIP	;SEE IF SAME VARIABLE
	JRST	E$$BEE		;[244] BAD END 
	MOVE	B,IFSTKP	;[244] GET STACK POINTER
	POP	B,FLSKIP	;[244] RESTORE STATUS
	POP	B,IFSKIP	;[244]     ..
	POP	B,VRSKIP	;[244,247] ..
	MOVEM	B,IFSTKP	;[244] STORE POINTER BACK
	JRST	ENDCM		;END COMMAND
;SUBROUTINE TO FIND VALUE OF VARIABLE IN N
;SKIP RETURNS WITH VALUE IN N; NON-SKIP IF UNDEFINED
;	RETURNS A/ POINTER TO VARIABLE

VALVAR:	MOVN	A,FILNVR	;GET COUNT
	JUMPE	A,CPOPJ		;NOT FOUND IF NO VARIABLES YET
	CAMGE	A,[-LN$VAR]	;SEE IF OVERFLOWED
	MOVNI	A,LN$VAR	;YES--SET MAX
	HRLZS	A		;POSITION FOR AOBJN
	CAME	N,FILVAR(A)	;SEE IF MATCH
	AOBJN	A,.-1		;NO--LOOP
	JUMPGE	A,CPOPJ		;IF NO MATCH, GIVE ERROR
	MOVE	N,FILVVR(A)	;GET VALUE
	JRST	CPOPJ1		;GIVE GOOD RETURN

	ILCM$	UKV,Unknown VARIABLE
	ILCM$	BEE,BAD .ENDIF OR .ELSE (NAMES DO NOT MATCH)
;HERE TO END ONE OF THE IF COMMANDS TO SEE IF FLAGS NEED TO
;BE PRINTED AND WHETHER TO SKIP INPUT
;CALLED WITH A/ INDEX TO CONTROL VARIABLE

ENDVCM:	SKIPG	SCNDRF		;SEE IF /DRAFT
	JRST	ENDVCN		;NO, OR /NODRAFT
	MOVE	B,FILFVR(A)	;GET VARIABLE FLAGS
	SKIPE	IFSKIP		;SEE IF SKIPPING
	MOVSS	B		;NO--SWITCH TO REGULAR FLAG
	TLZ	B,-1		;CLEAR UNNEEDED FLAG
	LSH	B,^D36-^D14	;POSITION AT START OF WORD
	TLO	B,(ASCIZ / /)	;INCLUDE A BLANK
	MOVEM	B,FLSKIP	;STORE AS PRINTOUT FLAG
	JRST	ENDCM		;SINCE /DRAFT, INCLUDE ALL VERSIONS

;HERE TO SEE IF SKIPPING INPUT

ENDVCN:	SKIPN	IFSKIP		;SEE IF SKIPPING
	JRST	ENDCM		;NO--JUST END COMMAND
	SAVE$	<F,CAS>		;YES--SAVE CASE AND UNDERLINE LOCKS
	PUSHJ	P,FRCEND	;FORCE TO END OF LINE

;LOOP HERE OVER EACH LINE OF INPUT LOOKING FOR .ENDIF/.ELSE/.IF[NOT]

ENDVCL:	TRZ	F,R.CCOM	;CLEAR COMMAND INDICATOR
	PUSHJ	P,CCIN		;GET NEXT INPUT
	IFEOF$	ENDVCY		;IF EOF, BREAK OUT
	CAMN	CH,CC.END	;SEE IF END OF FOOTNOTE
	TLNN	F,L.FOOT	;YES--SEE IF IN FOOTNOTE
	SKIPA			;NO--PROCEED
	JRST	ENDVCX		;YES--TERMINATE
	CAME	CH,CC.CON	;SEE IF CONTROL LINE
	JRST	ENDVCT		;NO--SKIP TO END OF LINE
	PUSHJ	P,STRCMN	;YES--START COMMAND LINE
	PUSHJ	P,CMGWD		;GET COMMAND WORD
	  JRST	ENDVCT		;ERROR--SKIP TO END OF LINE
	MOVE	S1,[XWD -CMTL1,CMTAB]  ;LOOK IN MAIN COMMAND TABLE
	PUSHJ	P,CMREC		;GO RECOGNIZE
	  JRST	ENDVCT		;ERROR--SKIP TO END OF LINE
	HLRZ	S1,(D)		;FOUND--GET DISPATCH ADDRESS
	CAIE	S1,$IF		;SEE IF .IF
	CAIN	S1,$IFNOT	; OR IF .IFNOT
	JRST	ENDVCI		;YES--GO HANDLE
	CAIE	S1,$ELSE	;SEE IF .ELSE
	CAIN	S1,$ENDIF	; OR IF .ENDIF
	SKIPA			;YES--GO DO IT
	JRST	ENDVCT		;NO--SKIP REST OF LINE
				CONT.
;HERE WHEN .IF[NOT]/.ELSE/.ENDIF FOUND

ENDVCI:	JSP	A,ENDVCR	;OK--RESTORE FLAGS, ETC.
	JRST	(S1)		;GO TO ROUTINE

;HERE TO SKIP REST OF THIS LINE

ENDVCS:	PUSHJ	P,CCIN		;GET NEXT CHARACTER
ENDVCT:	IFEOF$	ENDVCY		;IF EOF, BREAK OUT
	CAIE	CH,.CHLFD	;IF NOT END OF LINE,
	JRST	ENDVCS		;  LOOP ONWARDS
	JRST	ENDVCL		;NEW LINE--GO EXAMINE INPUT

;HERE WHEN TIME TO BREAK OUT OF SKIPPING

ENDVCX:	MOVEM	CH,GCSCH	;STORE FOR RESCAN
ENDVCY:	JSP	A,ENDVCR	;RESTORE FLAGS, ETC.
	JRST	LGO		;AND GO TO NEXT LINE PROCESSING

;LOCAL SUBROUTINE TO RESTORE FLAGS SAVED AT START OF ENDVCN

ENDVCR:	RSTR$	<CAS,B>		;RESTORE CASE LOCK
	TLZ	F,L.ULMS	;CLEAR UNDERLINE LOCK
	TLNE	B,L.ULMS	;SEE IF UNDERLINE LOCK SET
	TLO	F,L.ULMS	;YES--RESTORE IT
	JRST	(A)		;RETURN TO CALLER

;ROUTINE TO STACK IF'S
PUSHIF:	MOVE	B,IFSTKP	;[244] GET STACK POINTER
	PUSH	B,VRSKIP	;[244] SAVE STATE
	PUSH	B,IFSKIP	;[244]     ..
	PUSH	B,FLSKIP	;[244]     ..
	MOVEM	B,IFSTKP	;[244] STORE POINTER BACK
	POPJ	P,0		;[244] RETURN
	SUBTTL	INDEX OPERATIONS

;+.CHAPTER INDEXING
;-


;LINKED LIST FORMAT IS:

;	!=======================================================!
;	!      CHAIN TO PAGES       !      POINTER TO TEXT      !
;	!-------------------------------------------------------!
;	!      CHAPTER       !           PAGE           !SUBPAGE!
;	!-------------------------------------------------------!
;	!      PREVIOUS ENTRY       !        NEXT ENTRY         !
;	!=======================================================!
;
;FOR OTHER REFERENCES TO THIS ITEM:
;
;	!=======================================================!
;	!  CHAIN PAGES THIS ENTRY   !             0             !
;	!-------------------------------------------------------!
;	!      CHAPTER       !           PAGE           !SUBPAGE!
;	!=======================================================!

L.L==0		;LH=POINTER TO LIST OF PAGES THIS ENTRY
R.T==0		;RH=POINTER TO TEXT (MAIN ENTRY ONLY)
W.P==1		;PAGE NUMBER IN FORMAT OF BYTE
		;   (36.-PGWID-SPWID) CHAPTER (PGWID) PAGE (SPWID) SUBPAGE
L.B==2		;LH=BACKWARD ENTRY LIST POINTER
R.F==2		;RH=FORWARD ENTRY LIST POINTER

;ROUTINE TO ADD ITEM TO INDEX DATA AT TOP OF CORE
;PERIOD AND EXCLAMATION ARE VALID TEXT.

$SUBIN:	TRNN	F,R.NFLA	;SEE IF .NOFLAGS ALL
	TDZA	A,A		;NO--SUBINDEX, NOT INDEX.
$INDEX:	SETOM	A		;NOT SUBINDEX
	SETCAM	A,SUBIDX	;SET FLAG FOR LATER
	SETZM	ICBUF		;FIRST, PUT ITEM IN COMPARISON BUFFER
	MOVE	A,[XWD ICBUF,ICBUF+1]
	BLT	A,ICBFE		;CLEAR COMPARISON BUFFER
	MOVE	S1,[POINT 7,ICBUF]
	SAVE$	CC.IND		;SAVE .FLAG INDEX
	HRROS	CC.IND		;TURN OFF .FLAG INDEX
				CONT.
	HRRZ	D,CAS		;SAVE CASE
	MOVEI	A,ULCAS		;FORCE .LOWER CASE
	MOVEM	A,CAS		; FOR .INDEX
	TLZE	F,L.ULMS	;CLEAR UNDERLINE LOCK
	TLO	D,L.ULMS	; SAVING IT
	MOVEI	N,<ICBFE-ICBUF>*5-1	;END TEST ON BUFFER
INDX0:	PUSHJ	P,GCIN		;GET CHARACTER OF INDEX DATA
	CAIE	CH,C.SPC	;SKIP LEADING SPACES OR TABS
	CAIN	CH,.CHTAB	; ..
	JRST	INDX0		; ..
	CAIL	CH,"A"+ULCAS	;SEE IF LOWER
	CAILE	CH,"Z"+ULCAS	; CASE
	JRST	INDX1		;NO--PROCEED
	TRNN	F,R.FRCC	;YES--DID USER FORCE IT
	SUBI	CH,ULCAS	;NO--MAKE UPPER CASE
INDX1:	SKIPE	SUBIDX		;IF SUBINDEX, ALLOW MULT COMMANDS
	JRST	[PUSHJ P,CMSOMP  ;SEE IF MORE COMMAND		[165]
		   JRST INDX2	;NO--ALL DONE
		 JRST  .+1]	;YES--CONTINUE
	CAIN	CH,.CHLFD	;COPY THROUGH END OF LINE
	JRST	INDX2		;END.
	SKIPE	SUBIDX		;INDEX OR SUBINDEX?
	CAME	CH,CC.SUB	;SUBINDEX. FLAG CHARACTER?
	SKIPA			;NO.
	MOVEI	CH,C.SIFI	;YES. TRANSLATE TO INTERNAL.
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	JRST	[MOVEI A,C.QUTI	;YES--GET INTERNAL QUOTE
		 IDPB  A,S1	;STORE IT
		 SOS   N	;COUNT IT
		 JRST  .+1]	;PROCEED
	IDPB	CH,S1		;STORE CHARACTER OF INDEX DATA
	PUSHJ	P,GCIN		;GET NEXT CHARACTER
	SOJG	N,INDX1		;LOOP IF ROOM
INDX2:	MOVEM	CH,GCSCH	;SAVE FINAL FOR END EATER
	HRRZM	D,CAS		;RESTORE TEXT CASING
	RSTR$	CC.IND		;RESTORE .FLAG INDEX
	TLZ	F,L.ULMS	;CLEAR UNDERLINE LOCK
	TLZE	D,L.ULMS	;RESTORE
	TLO	F,L.ULMS	; ORIGINAL
	PUSHJ	P,DOINDX	;GO SET INTO INDEX
	JRST	ENDCM		;END OF COMMAND
;ROUTINE TO ENTER BUFFER INTO INDEX

DOINDX:	SAVE$	<A,B,C,D,CH,C2,PA> ;SAVE ENOUGH AC'S
	IBP	S1		;FIND PLACE FOR ITEM IN INDEX
	MOVEI	S1,1(S1)	;SIZE OF BLOCK TO BE ADDED
	SUBI	S1,ICBUF	; ..
	HRRZ	A,XFIRST	;GET ADDRESS OF FIRST ITEM SO FAR
	JUMPE	A,INDXV		;IF NONE, LIST IS EMPTY. START IT.

;LOOP OVER OLD ENTRIES TO LOCATE THIS ONE
INDXL2:	TLZ	F,L.IDXC!L.IDXD	;CLEAR CASE-DIFFERENCE CATCHER
	HRRZ	B,R.T(A)	;ADDRESS OF ASCIZ OF OLD ITEM
	HRLI	B,(POINT 7,)	;POINTER TO IT.
	MOVE	C,[POINT 7,ICBUF]	;POINTER TO NEW ITEM
;LOOP OVER CHARACTERS IN THE STRINGS
INDXL1:	ILDB	CH,B		;GET CHAR OF OLD
	CAIN	CH,C.QUTI	;SEE IF QUOTE
	ILDB	CH,B		;[242] YES-- GET NEXT CHAR
	ILDB	C2,C		;AND ONE OF NEW
	CAIN	C2,C.QUTI	;SEE IF QUOTE
	ILDB	C2,C		;[242]YES--GET NEXT CHAR
	CAMN	CH,C2		;SAME BEFORE CASE MERGE?
	JRST	INDXL5		;YES--PROCEED
	CAIE	CH,C.ULS	;SEE IF UNDERLINE
	CAIN	C2,C.ULS	; ..
	JRST	INDXL3		;YES--GO HANDLE
				CONT.
	TLOE	F,L.IDXC  	;SEE IF FIRST ONE DIFFERING
	JRST	INDXL5		;NO--CONTINUE
	CAMG	CH,C2		;YES--COMPARE
	TLO	F,L.IDXD 	;SET FLAG
INDXL3:	MOVE	D,CH		;SAVE ORIGINAL
	CAIN	CH,C.ULS	;SEE IF UNDERLINE
	ILDB	CH,B		;YES--GET SUCCESSOR
	CAIN	C2,C.ULS	;SEE IF UNDERLINE
	ILDB	C2,C		;YES--GET SUCCESSOR
	TLOE	F,L.IDXC	;SEE IF FIRST TIME
	JRST	INDXL5		;NO--PROCEED
	CAIN	D,C.ULS		;SEE IF OLD WAS IT
	TLO	F,L.IDXD	;YES--IT WINS
INDXL5:	CAIL	CH,"A"+ULCAS	;CONVERT LC TO UC
	CAILE	CH,"Z"+ULCAS
	SKIPA
	TRZ	CH,ULCAS	; ..
	CAIL	C2,"A"+ULCAS	; ..
	CAILE	C2,"Z"+ULCAS
	SKIPA
	TRZ	C2,ULCAS	; ..
	CAMN	CH,C2		;SAME?
	JUMPN	CH,INDXL1	;YES. LOOP UNLESS END OF STRINGS
	CAMLE	CH,C2		;WHICH IS FIRST?
	JRST	INDX3		;NEW ONE IS FIRST, AND DIFFERENT
	CAMN	CH,C2		;ARE THEY IDENTICAL?
	JRST	INDX4		;YES. NO NEED FOR NEW COPY. ADJUST POINTERS
;HERE WHEN NEW ONE IS AFTER THIS ONE
IDX4A:	HRRZ	B,R.F(A)	;NO. OLD ONE IS FIRST. LOOK FURTHER
	JUMPE	B,INDX5		;END OF LIST. NEW IS LAST
	MOVEI	A,(B)		;MOVE LINK TO A
	JRST	INDXL2		;LOOK FURTHER
				CONT.
;HERE WHEN NEW ONE IS BEFORE ENTRY
INDX3:	PUSHJ	P,INDXAD	;ADD ITEM WITH PAGE NO TO STORAGE (UNLINKED)
	HLRZ	B,L.B(A)	;WHO PRECEDED OLD?
	SKIPN	B		;ANYONE?
	HRRZM	PA,XFIRST	;NO. NEW IS FIRST OF ALL.
	HRLM	PA,L.B(A)	;NEW IS PREDECESSOR OF OLD
	HRRM	A,R.F(PA)	;OLD IS SUCCESSOR OF NEW, NO PREDECESSOR
	SKIPE	B		;IF ANYONE PRECEDED OLD,
	HRRM	PA,R.F(B)	;MAKE NEW ONE BE HIS SUCCESSOR
	HRLM	B,L.B(PA)	;AND OLD'S PRED IS NOW NEW'S PRED
	JRST	INDXX		;RETURN FROM INDEX COMMAND

;HERE WHEN NEW ONE MATCHES THIS ENTRY
INDX4:	TLNE	F,L.IDXC	;SEEM THE SAME. WERE CASES DIFFERENT?
	JRST	[TLNE	F,L.IDXD ;YES--SEE IF FLAG SET
		 JRST	IDX4A	;YES--NEW COMES AFTER
		 JRST	INDX3]	;NO--NEW COMES FIRST

;HERE WHEN REPEATED INDEX ITEM
	HLRZ	B,L.L(A)	;GET PAGE LIST POINTER
	JUMPN	B,[MOVE A,B	;ALREADY A POINTER, ADVANCE IT
		   JRST .-1]	;LOOP TO END OF PAGE CHAIN
	PUSHJ	P,INDXFP	;COMPUTE COMPRESSED PAGE
	CAMN	B,W.P(A)	;SEE IF MATCHES
	JRST	INDXX		;YES--SKIP IT AND SAVE SPACE
	HRRZ	PA,XTOP		;POINT TO FREE SPACE
	ADDI	PA,2		;MAKE ROOM FOR PAGE ENTRY
	CAML	PA,FOOTBF	;SEE IF OVERFLOWING
	PUSHJ	P,EXPAND	;YES--MAKE ROOM
	HRRZ	PA,XTOP		;POINT TO FREE SPACE
	MOVEI	C,2(PA)		;NEW FREE POINT
	MOVEM	C,XTOP		;STORE FOR LATER
	MOVEM	B,W.P(PA)	;STORE PAGE
	SETZM	L.L!R.T(PA)	;CLEAR POINTERS IN NEW ENTRY
	HRLM	PA,L.L(A)	;ADD TO CHAIN
	JRST	INDXX		;THEN RETURN

;HERE WHEN NEW IS FOR END OF LIST
INDX5:	PUSHJ	P,INDXAD	;CREATE TEXT AND POINTER BLOCK WITH PAGENO
	HRRM	PA,R.F(A)	;MAKE NEW FOLLOW OLD
	HRLZM	A,L.B!R.F(PA)	;AND OLD PRECEDE NEW.
	JRST	INDXX		;RETURN FROM INDEX COMMAND

INDXV:	PUSHJ	P,INDXAD	;CREATE TEXT AND POINTER BLOCK, PAGE NO
	HRRZM	PA,XFIRST	;THIS IS FIRST ITEM (AND ONLY)
INDXX:	RSTR$	<PA,C2,CH,D,C,B,A>  ;RESTORE SAVED AC'S
	POPJ	P,		;END OF INDEX COMMAND
;ROUTINE TO ADD INDEX ENTRY TO LINKED LIST

INDXAD:	HRRZ	PA,XTOP		;GET TOP OF INDEX STORAGE
	ADDI	PA,3(S1)	;NEED 3 WORDS PLUS TEXT
	CAML	PA,FOOTBF	;LESS THAN BASE OF FOOTNOTES?
	PUSHJ	P,EXPAND	;NO. TRY TO EXPAND
	HRRZ	PA,XTOP		;GET TOP OF INDEX
	SAVE$	PA		;SAVE BASE OF NEW ITEM
	MOVE	B,PA		;COMPUTE NEW TOP OF INDEX
	ADDI	B,3(S1)		; ..
	HRRZM	B,XTOP		;STORE IN TOP OF INDEX POINTER
	HRLZI	B,ICBUF		;TRANSFER TEXT INTO BUFFER
	HRRI	B,3(PA)		;INTO TEXT AREA
	HRRZM	B,L.L!R.T(PA)	;STORE TEXT ADDRESS
	ADDI	PA,3-1(S1)	;FINAL "TO" ADDRESS
	BLT	B,(PA)		;TRANSFER INDEX ITEM
	RSTR$	PA		;RESTORE BASE OF INDEX
	SETZM	L.B!R.F(PA)	;NO POINTERS YET.
	PUSHJ	P,INDXFP	;COMPUTE COMPRESSED PAGE NUMBER
	MOVEM	B,W.P(PA)	;STORE COMPRESSED PAGE NUMBER
	POPJ	P,		;AND RETURN.

;SUBROUTINE TO COMPUTE COMPRESSED PAGE NUMBER

INDXFP:	SKIPGE	B,SECNUM	;GET CHAPTER NUMBER
	SETOM	B		;-1 FOR INDEX
	LSH	B,SPWID+PGWID	;POSITION IT
	MOVE	C,PAGENO	;GET PAGE NUMBER
	ANDX	C,PGMASK	;PREVENT OVERFLOW
	LSH	C,SPWID		;POSITION IT
	IOR	B,C		;INCLUDE IN RESULT
	SKIPE	C,SUBPGE	;GET SUBPAGE NUMBER
	SOS	C		;BACK OFF OFFSET
	CAILE	C,"Z"-"A"+1	;SEE IF IN RANGE
	SETOM	C		;NO--INDICATE OVERFLOW
	ANDI	C,SPMASK	;MASK TO PREVENT OVERFLOW
	IOR	B,C		;INCLUDE IN RESULT
	POPJ	P,		;RETURN
;PRINT INDEX ONTO FILE

$DO.IN:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;BREAK OUTPUT
;[241]	SKIPN	A,SECNUM	;SEE IF CHAPTER DOCUMENT
;[241]	JRST	$PR.IN		;NO--JUST DO PRINT INDEX
;[241]	JUMPL	A,DOIN1		;IF ALREADY IN INDEX, SKIP NEW PAGE
	SKIPGE	SECNUM		;[241] ALREADY IN INDEX?
	JRST	DOIN1		;[241] YES--SKIP TO NEW PAGE
	PUSHJ	P,BPAGE		;YES--BREAK PAGE
	HRROS	SECNUM		;FLAG INDEX
	MOVEI	A,ILPGNO	;RESET
	MOVEM	A,PAGENO	;  PAGE COUNTER
	SETZM	SUBPGE		;CLEAR SUBPAGING
	PUSHJ	P,CLRTTL	;CLEAR OUT PREVIOUS TITLE
	MOVEI	A,5*LN$TTL-1	;SET LIMIT
	MOVEM	A,CENTTL	;SET INDICATOR FOR CENT TO STORE TITLE
	PUSHJ	P,CLRSTT	;CLEAR SUBTITLE
	PUSHJ	P,HEADIN	;OUTPUT HEADING
DOIN1:	SKIPLE	SCNTYP		;IF TYPESETTING
	JRST	[MOVEI S1,[ASCIZ \[*DX]\]
		 PUSHJ P,FMES	; ISSUE MACRO CALL
		 JRST  DOIN2]	; AND CONTINUE
	MOVE	N,RMARG		;GET R MARGIN
	ADD	N,LMARG		; AND LEFT
	HRLI	N,-INDEXD	;SPACING AFTER
	MOVEM	N,CENPOS	;SET FOR CENTER COMMAND
DOIN2:	PUSHJ	P,RSKIPS	;SKIP SPACES AND TABS
	  JRST	INDEXN		;IF NO MORE, THAT'S ALL
	SKIPLE	SCNTYP		;IF TYPESETTING
	JRST	[PUSHJ P,INPTYP	; ISSUE REST OF COMMAND
		 JRST  INDEXX]	; AND CONTINUE
	PUSHJ	P,LINDFL	;FORCE FULL UPPER CASE
	PUSHJ	P,CENT		;GO CENTER LINE
	JRST	INDEXX		;THEN PRINT INDEX

;HERE WHEN NO STRING ON .DO INDEX COMMAND

INDEXN:	PUSHJ	P,FILSEQ	;ISSUE SEQUENCE NUMBERS
	HRRZ	A,CENPOS	;GET CENTER
	SUBI	A,5		;ALLOW FOR "INDEX"
	LSH	A,-1		;CENTER IS 1/2
	PUSHJ	P,NSPAC		;SPACE OVER
	MOVEI	S1,[ASCIZ /INDEX/]
	PUSHJ	P,MCOUT		;OUTPUT "INDEX"
	SKIPLE	SCNTYP		;IF TYPESETTING,
	JRST	INDEXX		; THAT'S IT
	PUSHJ	P,SKIPS		;END LINE
	PUSHJ	P,CENTX		;FINISH CENTERED LINE
INDEXX:	PUSHJ	P,ATTYP		;END TYPESETTING MACRO ARGUMENT
				CONT.

$PR.IN:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	ILIFNT		; ILLEGAL
	PUSHJ	P,OUTNJ		;BREAK COMMAND. OUTPUT LINE.
	SETZM	INDCT		;CLEAR INDENT
	HRRZ	A,XFIRST	;GET FIRST ITEM IN INDEX
	JUMPE	A,PINDXX	;QUIT IF NONE.
	HRRZM	A,OIXC		;SAVE CURRENT POINTER
	SETZM	OIXL		;CLEAR CURRENT LETTER

PINDL1:	SKIPG	LINEC		;SEE IF TOP OF PAGE
	PUSHJ	P,HEADIN	;YES--OUTPUT HEADING
	HRRZ	B,OIXC		;GET POINTER TO TEXT OF THIS ITEM
	HRRZ	B,R.T(B)	; ..
	HRLI	B,(POINT 7,)	;ASCIZ POINTER
	ILDB	CH,B		;GET FIRST LETTER
	CAIN	CH,C.ULS	;SEE IF UNDERLINE
	ILDB	CH,B		;YES--GET NEXT
	CAIL	CH,"A"+ULCAS	;LOWER CASE?
	CAILE	CH,"Z"+ULCAS
	SKIPA
	TRZ	CH,ULCAS	;YES. MAKE UPPER.
	CAMN	CH,OIXL		;SAME AS INITIAL LETTER OF PREVIOUS ONE?
	JRST	PINDX1		;YES. SKIP THIS
	MOVEM	CH,OIXL		;SAVE THIS CHARACTER
	PUSHJ	P,SKIPSC
PINDX1:	PUSHJ	P,BLKSEQ	;BLANKS FOR SEQUENCE
	MOVE	A,LMARG		;SPACE IN TO LEFT MARGIN
	PUSHJ	P,NSPAC		; ..
	HRRZ	S1,OIXC		;GET POINTER TO ASCII
	PUSHJ	P,PINDXP	;OUTPUT STRING OF ASCIZ, CONVERTING SIF
	TRZ	F,R.PGSQ	;CLEAR PAGE SEQUENCE FLAG
	MOVE	A,RMARG		;NOW GO TO MIDDLE OF LINE
	ADD	A,LMARG		;IF NOT THERE YET
	ASH	A,-1		; ..
PIND1:	MOVEI	CH,C.SPC	;GET A SPACE
PIND1A:	PUSHJ	P,CCOUT		;MAY JRST TO HERE FROM INDEXED JRST BELOW
				;OUTPUT SPACE OR PERIOD TO FILE
	CAMG	A,CPOS		;AT OR PAST MIDDLE OF PAGE?
	JRST	PIND2		;YES. GO OUTPUT NUMBERS FROM INDEX DATA.
	MOVEI	CH,C.PD		;GET A DOT FOR OUTPUT
	MOVE	B,CPOS		;GET CURRENT POSITION ON LINE
	ANDI	B,1		;ONLY LOW ORDER BIT (EVEN OR ODD COLUMN)
	JRST	PIND1(B)	;TO PIND1 FOR SPACE OR PIND1A FOR DOT
PIND2:	MOVEI	CH,C.SPC	;OUTPUT ONE SPACE BEFORE PAGE NO'S
	PUSHJ	P,CCOUT		;OUTPUT, COUNTING POSITION
	HLRZ	B,OIXC		;GET PAGE NUMBER OF THIS ENTRY
	SKIPN	B		;IF NOT REPEATED,
	HRRZ	B,OIXC		; GET THIS ONE
	MOVE	N,W.P(B)	; ..
	PUSHJ	P,PINDPG	;PRINT PAGE AND SUBPAGE
				CONT.
PINDX2:	HLRZ	C,L.L(B)	;GET REPEATED PAGES POINTER
	HRLM	C,OIXC		;STORE FOR LATER
	JUMPE	C,PINDX3	;JUMP IF DONE
	MOVE	N,W.P(C)	;SAME. GET PAGE NUMBERS OF BOTH

	MOVE	N1,N		;COPY PAGE NUMBER
	SOS	N1		;DECREMENT SUBPAGE
	CAMN	N1,W.P(B)	;SEE IF =LAST+1
	JRST	PINDX5		;YES--CONCATENATE
	MOVE	C,W.P(B)	;NO--TRY MAIN PAGE
	LSH	C,-SPWID
	AOS	C
	MOVE	A,N
	LSH	A,-SPWID
	CAMN	A,C
	JRST	PINDX5		;YES--CONCATENATE
	MOVE	N,W.P(B)	;NO--GET OLD NUMBER
	TRZE	F,R.PGSQ	;CLEAR SEQUENCING
	PUSHJ	P,PINDPG	;PRINT IF WAS ON
	MOVEI	CH,","		;PUT COMMA BETWEEN PAGE NUMBERS
	PUSHJ	P,CCOUT
				CONT.
	MOVEI	B,2		;START COUNTING CHARACTERS INCLUDE SPACE,COMMA
	HLRZ	A,OIXC		;GET BLOCK AGAIN
	MOVE	N,W.P(A)	;GET PAGE NUMBER AGAIN
	TRNE	N,SPMASK	;SEE IF SUBPAGE
	ADDI	B,1		;YES--ADD ONE
	LSH	N,-SPWID	;SET TO PRIME NUMBER
	MOVE	C,N		;SAVE COPY OF CHAPTER
	ANDX	N,PGMASK	;CUT PAGE OUT
	PUSHJ	P,COUNTD	;COUNT ITS DIGITS
	ADD	B,A		;ADD TO COUNT
	LSH	C,-PGWID	;POSITION CHAPTER NUMBER
	MOVE	N,C		;RESTORE TO N
	SKIPE	N		;IF CHAPTER,
	ADDI	B,1		;  COUNT -
	CAIN	N,CHMASK	;SEE IF INDEX
	SETOM	N		;YES--CHANGE TO -1
	PUSHJ	P,COUNTC	;COUNT CHAPTER'S DIGITS
	ADD	B,A		;ADD TO RESULT
	ADDI	B,1		;ALLOW FOR POSSIBLE -
	SKIPE	SECNUM		;SEE IF CHAPTERS
	ADDI	B,3		;YES--ALLOW FOR #TO# INSTEAD
	ADD	B,CPOS		;WHERE WILL WE BE AFTER NEXT NO.?
	CAMG	B,RMARG		;AFTER RIGHT MARGIN?
	JRST	PIND2		;NO. GO OUTPUT THE NUMBER
	PUSHJ	P,SKIPS		;SKIP N LINES
	PUSHJ	P,BLKSEQ	;BLANKS FOR SEQUENCE
	MOVE	A,RMARG		;NOW FIND MIDDLE OF PAGE
	ADD	A,LMARG		;AS LEFT PLUS RIGHT OVER TWO
	ASH	A,-1		; ..
	PUSHJ	P,NSPAC		;SPACE OVER TO THERE
	JRST	PIND2		;AND THEN OUTPUT NUMBER
				CONT.
PINDX5:	MOVEI	S1,[ASCIZ /-/]	;CONCATENATE
	SKIPE	SECNUM		;SEE IF CHAPTER DOCUMENT
	MOVEI	S1,[ASCIZ / to /]  ;YES--DIFFERENT MARKER
	TRON	F,R.PGSQ	;SET FLAG
	PUSHJ	P,MCOUT		;OUTPUT HYPHEN ONCE
	HLRZ	B,OIXC		;MOVE TO NEXT ENTRY IN LIST
	JRST	PINDX2		;CONTINUE

;HERE AT END OF LIST OF PAGES THIS ENTRY
PINDX3:	TRZE	F,R.PGSQ	;SEE IF CONCATENATING
	PUSHJ	P,PINDPG	;YES--BIND OFF ENTRY
	PUSHJ	P,SKIPS		;OUTPUT SPACING FOR END OF LINE
	HRRZ	C,OIXC		;GET THIS MAIN ENTRY
	HRRZ	C,R.F(C)	;GET NEXT MAIN ENTRY
	MOVEM	C,OIXC		;STORE AS CURRENT ENTRY
	JUMPN	C,PINDL1	;GO ON TO NEXT ITEM IN LIST

PINDXX:	TRZE	F,R.PGSQ	;SEE IF CONCATENATING
	PUSHJ	P,PINDPG	;YES--BIND OFF ENTRY
	PUSHJ	P,SKIPSC	;BLANK LINE AT END
	HRRZ	A,XBOT		;CLEAR INDEX POINTERS
	MOVEM	A,XTOP		; ..
	SETZM	XFIRST		; ..
	HRRZS	SECNUM		;CLEAR INDEX FLAG
	MOVE	B,INIFBF	;ORIGINAL BASE OF FOOTNOTE AREA
	CAMN	B,FOOTBF	;DID WE EVER MOVE BUFFER?
	JRST	ENDBCM		;NO--LEAVE ALONE
	EXCH	A,FOOTBF	;SET BOTTOM OF FOOTNOTE		[204]
	HRLZ	B,A		;BUILD				[204]
	SUB	A,FOOTBF	; BLT				[204]
	HRR	B,FOOTBF	; POINTER			[204]
IF TOPS-10,<
	HRRZ	C,.JBREL	;END OF FOOTNOTE		[204]
> ;END TOPS-10
IF TOPS-20,<
	MOVEI	C,RUNOFF-11	;END OF LOWSEG
> ;END TOPS-20
	SUB	C,A		;NEW END			[204]
	BLT	B,(C)		;COPY FOOTNOTES DOWN		[204]
IF TOPS-10,<
	CORE	C,		;RESET CORE DOWN		[204]
	  JFCL			;IGNORE ERRORS			[204]
> ;END TOPS-10
	IMUL	A,[-5]		;CONVERT TO BYTE COUNT		[204]
	ADDM	A,FOOTP1	;BACK				[204]
	ADDM	A,FOOTP2	; DOWN				[204]
	ADDM	A,FOOTP3	; FOOTNOTE			[204]
	ADDM	A,FOOTP4	; POINTERS			[204]
	HRRZS	SECNUM		;CLEAR INDEX FLAG
	JRST	ENDBCM		;RETURN FROM PINDX COMMAND
;ROUTINE TO PRINT PAGE AND SUBPAGE FOR INDEX

PINDPG:	MOVE	C,N		;SAVE SUBPAGE
	LSH	N,-SPWID-PGWID	;POSITION CHAPTER
	SKIPE	N		;SEE IF CHAPTER
	JRST	[CAIN  N,CHMASK	;YES--SEE IF INDEX
		 SETOM N	;YES--CHANGE TO -1
		 PUSHJ P,CHPPRT	;PRINT CHAPTER
		 MOVEI CH,"-"	;PRINT
		 PUSHJ P,CCOUT	;  HYPHEN SEPARATOR
		 JRST  .+1]	;PROCEED
	MOVE	N,C		;RECOVER PAGE
	LSH	N,-SPWID	;POSITION PAGE
	ANDX	N,PGMASK	;REMOVE JUNK
	PUSHJ	P,DECPRT	;OUTPUT PAGE NUMBER
	MOVE	CH,C		;RESTORE SUBPAGE
	ANDI	CH,SPMASK	;MASK DOWN
	JUMPE	CH,CPOPJ	;RETURN IF NONE
	ADDI	CH,"A"-1	;CONVERT TO ASCII
	CAILE	CH,"Z"		;SEE IF ALPHA
	MOVEI	CH,"?"		;NO--INDICATE OVERFLOW
	PJRST	CCOUT		;AND OUTPUT IT
;ROUTINE TO PRINT INDEX LINE'S STRING, HANDLING SUB-INDEX FLAGGING

PINDXP:	HRRZ	A,R.T(S1)	;MAKE POINTER TO STRING
	HRLI	A,(POINT 7,)	; ...
	PUSH	P,A		;STASH ON STACK
	MOVEI	D,0		;INITIALIZE SIFI COUNTER
	HLRZ	B,L.B(S1)	;GET BACK POINTER
	JUMPE	B,PXPLD		;NONE--NEED TO PRINT INDEX HEADER
	HRRZ	B,R.T(B)	;GET ITS STRING
	HRLI	B,(POINT 7,)	;MAKE POINTER
PXPL:	ILDB	CH,A		;GET A CHARACTER
	CAIN	CH,C.QUTI	;SEE IF QUOTE
	JRST	[ILDB CH,A	;YES--GET NEXT
		 TXO  CH,LCHPVT	;FLAG IT
		 JRST .+1]
	ILDB	C,B		;GET CORRESPONDING CHAR OF PREVIOUS
	CAIN	C,C.QUTI	;SEE IF QUOTE
	JRST	[ILDB C,B	;YES--GET NEXT
		 TXO  C,LCHPVT	;FLAG IT
		 JRST .+1]
	CAIN	CH,C.SIFI	;SEE IF > MATCH END		[225]
	JUMPE	C,[MOVEM A,(P)	;YES--STORE POINTER SO FAR	[225]
		   AOJA  D,PXPLD] ; AND COUNT SIF AND END	[225]
	CAME	C,CH		;SEE IF SAME
	JRST	PXPLD		;NO--THEN MUST ISSUE PREFIX
	JUMPE	CH,PXPLD	;QUIT AT END OF STRING
	CAIE	CH,C.SIFI	;INTERNAL FLAG?
	JRST	PXPL		;NO. CHECK FOR SIF MATCH
	MOVEM	A,(P)		;YES. STORE POINTER SO FAR
	AOJA	D,PXPL		;COUNT SIF AND LOOP
;HERE WHEN STRINGS ARE DIFERENT
PXPLD:	MOVE	A,D		;GET SIF COUNT
	IMULI	A,SINDIN	;INDENT SINDIN SPACES EACH
	PUSHJ	P,NSPAC		; ..
	MOVE	A,(P)		;RECOVER START OF LAST SIF STRING
PXPPL:	ILDB	CH,A		;GET NEXT CHAR
	CAIN	CH,C.QUTI	;SEE IF QUOTE
	JRST	[ILDB CH,A	;YES--GET NEXT
		 TXO  CH,LCHPVT	;FLAG IT
		 JRST .+1]
	JUMPE	CH,PXPPX	;EXIT IF DONE
	CAIN	CH,C.SIFI	;SEE IF ANOTHER SIF
	JRST	PXPPS		;YES--GO HANDLE
	PUSHJ	P,CCOUT		;NO--OUTPUT TO FILE
	JRST	PXPPL		;AND LOOP
PXPPS:	MOVEM	A,(P)		;UPDATE MEMORY OF STRING
	PUSHJ	P,SKIPS		;OUTPUT END OF LINE
	PUSHJ	P,BLKSEQ	;OUTPUT BLANK FOR SEQUENCE
	MOVE	A,LMARG		;GET LEFT MARGIN
	PUSHJ	P,NSPAC		;SPACE IN TO IT
	AOJA	D,PXPLD		;LOOP, COUNTING SIF
PXPPX:	POP	P,A		;ALL DONE--DISCARD POINTER
	POPJ	P,		;RETURN
	SUBTTL	FOOTNOTE OPERATIONS

;+.CHAPTER FOOTNOTES
;-

;FOOTNOTE N COMMAND

$FOOTN:	TLNE	F,L.FOOT	;ARE WE INSIDE A FOOTNOTE?
	JRST	ILLFNT		;YES. THAT DOESNT WORK
	PUSHJ	P,RCNO		;HOW MANY LINES TO RESERVE?
	  JRST	ILCM		;MUST HAVE SPEC
	JUMPLE	N,ILCM		;ERROR IF NEG OR ZERO
	IMUL	N,NSPNG		;RESERVE N TIMES SPACING
	ADDM	N,FOOTC		;ADD TO RESERVED FOOTNOTE LINES
	PUSHJ	P,FRCEND	;SKIP TO END OF THIS LINE
	MOVE	CH,CC.UPP	;INITIALIZE FOR ^^
	SKIPE	CAS		;CHECK CASE LOCK
	MOVE	CH,CC.LOW	;LOWER--CHANGE TO \\
	JUMPLE	CH,FOOTN0	;IF TURNED OFF, IGNORE
	PUSHJ	P,WCIFTN	;STORE ONE
	PUSHJ	P,WCIFTN	; AND A SECOND
FOOTN0:	MOVEI	CH,.CHLFD	;AND START NEW LINE
	PUSHJ	P,WCIFTN	;IN CASE COMMAND NEXT
	SKIPN	BARSW		;SEE IF BAR ENABLED
	JRST	FOOTN3		;NO--GO INTO FOOTNOTE DATA
	MOVE	CH,CC.CON	;YES--GET COMMAND MARKER
	PUSHJ	P,WCIFTN	;STORE IN BUFFER
	MOVEI	CH,"B"		;GET "BB"
	SKIPN	BARON		;IF BAR OFF,
	MOVEI	CH,"E"		; GET "EB"
	PUSHJ	P,WCIFTN	;STORE B OR E
	MOVEI	CH,"B"		;GET "B"
	PUSHJ	P,WCIFTN	; AND SECOND B
	MOVEI	CH,.CHLFD	;GET END OF LINE
	PUSHJ	P,WCIFTN	;STORE IT
	JRST	FOOTN3		;AND GO HANDLE FOOTNOTE TEXT
				CONT.
FOOTN1:	PUSHJ	P,RTECMC	;GET ANY HANGING TEXT
	  PUSHJ	P,CCIN		;READ A CHARACTER
	PUSHJ	P,WCIFTN	;WRITE CHARACTER IN BUFFER
	CAIE	CH,.CHLFD	;END OF LINE?
	JRST	FOOTN1		;NO.
FOOTN3:	PUSHJ	P,CCIN		;YES. SEE WHAT CHAR AFTER LF IS
	IFEOF$	FOOTEF		;END OF FILE?
	CAMN	CH,CC.END	;END FLAG (EXCL) ?
	JRST	FOOTEF		;YES--GO TO END PROCESSING
	MOVEM	CH,GCSCH	;ELSE STORE CHAR
	MOVEI	A,CCIN		;SET READER
	MOVEI	B,$EN.FO	;INDICATE END FOOTNOTE
	PUSHJ	P,TSTECM	;SEE IF .END FOOTNOTE NEXT
	  JRST	FOOTN1		;NO. STORE ANOTHER LINE
FOOTEF:	MOVE	CH,CC.END	;SET END OF FOOTNOTE CHAR.
	PUSHJ	P,WCIFTN	;YES. STORE THIS CHARACTER
	PUSHJ	P,STRCMN	;CLEAR COMMAND ERROR BUFFER
	JRST	ENDCM		;AND RETURN TO COMMAND ROUTINE

ILLFNT:	PUSHJ	P,ENDCMT	;SKIP REST OF COMMAND
	ILCM$	FIF,Footnote inside footnote

ILIFNT:	PUSHJ	P,ENDCMT	;SKIP REST OF COMMAND
	ILCM$	IFT,Illegal inside footnote

;HERE ON .END FOOTNOTE COMMAND

$EN.FO:	PUSHJ	P,ENDCMT	;SKIP REST OF LINE
	ILCM$	EFD,END FOOTNOTE doesn't follow FOOTNOTE
;START PROCESSING FOOTNOTE BUFFER. CALLED FROM BPAGE WHEN FOOTP3 POINTER
;NOT EMPTY

FOOTGO:	HRLOI	A,INFIN		;SET HUGE PAGE SIZE TO PREVENT EXTRA FORMS
	EXCH	A,NLPG		;AND GET CURRENT LENGTH
	SUB	A,LINEC		;DISTANCE TO END
	PUSHJ	P,SKIPN		; SKIP TO END OF PAGE BEFORE FOOTNOTES
	PUSH	P,RMARG		;SAVE THESE ITEMS OVER FOOTNOTE PROCESSING
	MOVE	A,PRMRG		;GET PAGE SIZE
	MOVEM	A,RMARG		;SET AS RIGHT MARGIN
	PUSH	P,LMARG
	STORE	A,LMARG,,ILMRG
	PUSH	P,CAS		;SAVE CASE
	MOVE	A,FILCAS	;GET INITIAL CASE
	MOVEM	A,CAS		;SET TO START FOOTNOTE CONSISTENTLY
	PUSH	P,BARSW		;SAVE BAR ENABLE, DON'T CHANGE
	PUSH	P,BARON		;SAVE BAR INDICATOR
	PUSH	P,BARNPY	; ..
	SETZM	BARON		;AND CLEAR
	SETZM	BARNPY		; THEM
	PUSH	P,LASLS		;SAVE LIST DEPTH
	AOS	A,LASLS		;ADVANCE TO NEXT
	CAILE	A,LN$MJP	;MAKE SURE NOT TOO FAR
	SOS	A,LASLS		;YES--BACK UP
	SETZM	LSTCNT(A)	;CLEAR THIS ENTRY
	PUSH	P,PARIND	;SAVE PARA INDENTING
	PUSH	P,PARSPC	;SAVE VERTICAL PARA SPACING
	PUSH	P,PARTPG	;SAVE PARAGRAPH TEST PAGE
	PUSH	P,INDCT		;SAVE ANY INDENTING ABOUT TO BE DONE
	SETZM	INDCT		;AND CLEAR IT FOR FOOTNOTE
	PUSH	P,F		;SAVE CURRENT FLAGS
	TLO	F,L.PJUS+L.JUST+L.FILL	;AND START WITH THESE DURING FTN
	PUSHJ	P,JUSTYP	;ISSUE JUSTIFICATION TO TYPESET
	PUSH	P,NSPNG
	SKIPGE	A,SCNSPG	;SEE IF /SPACING
	MOVEI	A,AD.SPC	;NO--SET TO DEFAULT
	MOVEM	A,NSPNG		;SET IT
	PUSH	P,GCSCH
	TLO	F,L.FOOT	;FLAG IN FOOTNOTE PROCESSING
	SETOM	GCSCH		;CLOBBER ANY SAVED CHARACTERS
	MOVEI	PA,FOOTWB	;PREPARE END-OF-LINE-HOLDING-BUFFER
	PUSHJ	P,CSP		; ..
	MOVEM	A,FOOTS1	; ..
	MOVEM	B,FOOTS2	; BUFFER IS EMPTY
	TLZN	F,L.GCIN	;NO SAVED INFO. WAS THERE ANY?
	JRST	FOOTS3		;NO. LEAVE.
				CONT.
FOOTSB:	PUSHJ	P,GGCINP	;GET A CHARACTER FROM SAVED BUFFER
	  JRST	FOOTS3		;NO MORE
	MOVEI	PA,FOOTS1	;SAVE BUFFER
	PUSHJ	P,WCI
	JRST	FOOTSB		;LOOP UNTIL SAVED BUFFER ALL MOVED

FOOTS3:	PUSHJ	P,LINSET	;INITIALIZE LINE FOR START OF FOOTNOTE
	JRST	LGO		;AND GO PROCESS SAVED FOOTNOTE COMMANDS

;HERE WHEN LINE ROUTINE DISCOVERS INITIAL EXCLAMATION

FOOTND:	TLNN	F,L.FOOT	;PROCESSING FOOTNOTES?
	JRST	LGO1		;NO. EXTRANEOUS CUE.
	PUSHJ	P,OUTNJ		;YES. FINISH UP LINE
	MOVE	A,FOOTP3	;ANY MORE FOOTNOTES COMING?
	CAME	A,FOOTP4	; ..
	JRST	LGO		;YES. GO READ SOME MORE
	CAML	A,FOOTP2	;ANY UNPROCESSED FOOTNOTES TO ADD?
	JRST	FOOTN6		;NO.
	MOVEM	A,TT5		;YES. ADD THEM TO LIST.
	MOVE	B,FOOTP2	;SAVE POINTER TO REMAINING COMMANDS
	MOVEM	B,TT6		; ..
	MOVE	A,FOOTP1	;CLEAR OUT BUFFERS
	MOVEM	A,FOOTP2	; ..
	MOVEM	A,FOOTP3	; ..
	MOVEM	A,FOOTP4	; ..
FOOTN4:	MOVEI	PA,TT5		;COPY TT5 STRING TO FOOTP1
	PUSHJ	P,GCI		;GET A CHARACTER
	  JRST	FOOTN5		;NO MORE.
	PUSHJ	P,WCIFTN	;WRITE IN FOOTNOTE POINTER 1
	JRST	FOOTN4		;LOOP TILL DONE

FOOTN6:	MOVE	A,FOOTP1	;CLEAR FOOTNOTE BUFFERS
	MOVEM	A,FOOTP2	; ..
	MOVEM	A,FOOTP3	; ..
	MOVEM	A,FOOTP4	; ..
				CONT.
FOOTN5:	TLZ	F,L.ESOL+L.FOOT	;INITIALIZE LEFT/RIGHT FLAG
				; AND MARK NOT IN FOOTNOTE MODE NOW
	POP	P,GCSCH		;RESTORE SAVED PARAMETERS
	POP	P,NSPNG
	POP	P,A		;GET BACK OLD FLAGS
	AND	A,[L.PJUS!L.JUST!L.FILL,,R.SPPR!R.AUTB]	;ONLY THOSE TO RESTORE
	ANDCM	F,[L.PJUS!L.JUST!L.FILL,,R.SPPR!R.AUTB]
	IOR	F,A		;AND RESTORE THE ONES FROM BEFORE FOOTNOTE
	PUSHJ	P,JUSTYP	;ISSUE JUSTIFICATION TO TYPESET
	POP	P,INDCT
	POP	P,PARTPG	;RESTORE PARAGRAPH
	POP	P,PARSPC
	POP	P,PARIND
	POP	P,LASLS		;RESTORE LIST DEPTH
	POP	P,BARNPY	;RESTORE FLAGS
	POP	P,BARON		; ..
	POP	P,BARSW		;RESTORE BAR ENABLE
	POP	P,CAS		;RESTORE CASE
	POP	P,LMARG
	POP	P,RMARG
	MOVE	A,PNLPG		;RESET LENGTH OF PAGE
	SKIPE	FLNOPG		;SEE IF NO PAGING
	HRLOI	A,INFIN		;YES--SET TO INFIN.
	MOVEM	A,NLPG		; ..
	MOVE	A,FOOTS1	;WAS PARTIAL LINE SAVED?
	CAMN	A,FOOTS2	; ..
	JRST	FOOTS4		;NO.
	MOVE	B,FOOTS2	;YES. PUT POINTER IN GCINP
	MOVEM	A,GCINP		; ..
	MOVEM	B,GCINP+1	; ..
	TLO	F,L.GCIN	;AND FLAG TO LOOK AT THAT BUFFER
FOOTS4:	POPJ	P,		;RETURN TO LINE PROCESSOR
				CONT.
WCIFTN:	MOVE	A,FOOTP2	;WRITE IN FOOTNOTE BUFFER, CHECKING SIZE
	IDIVI	A,5		; ..
	ADDI	A,2		;IS THIS ADDRESS HITTING TOP OF CORE?
IF TOPS-10,<
	HRRZ	B,.JBREL	; ..
> ;END TOPS-10
IF TOPS-20,<
	MOVEI	B,RUNOFF-11	;WHERE HISEG STARTS
> ;END TOPS-20
	CAMGE	A,B		; ..
	JRST	WCIFT1		;OK. NO PROBLEM.
IF TOPS-10,<
	MOVEI	B,1(B)		;NEED ANOTHER K
	CORE	B,		;ASK FOR IT
> ;TOPS-10
	  JRST	E$$NEC		;CAN'T HAVE IT. GIVE UP.
IF TOPS-10,<
	SKIPGE	TTISOT		;SEE IF TTY OUTPUT
	JRST	WCIFT1		;YES--SUPPRESS INFO MESSAGE
	SAVE$	<C,D>
	MSG$	KCF,INF,,
	HRRZ	A,.JBREL	;CURRENT SIZE
	ADDI	A,1		;TELL NEXT UNIT (ALLOW FOR 0)
	PUSHJ	P,.TCORW##
	MOVEI	A,[ASCIZ / core - footnote]
/]
	PUSHJ	P,.TSTRG
	RSTR$	<D,C>
> ;END TOPS-10
WCIFT1:	MOVEI	PA,FOOTP1	;NOW WRITE CHARACTER
	PJRST	WCI		; ..
	SUBTTL	OUTPUT SECTION

;+.CHAPTER OUTPUT PROCESSING
;-

;LINE OUTPUT ROUTINE. THREE ENTRY POINTS

OUTNSP:	SUB	A,B		;LENGTH OF LINE
	SUB	A,LSTNSP	;LESS NON-SPACING CHARS
	ADD	A,LMARG		;ADD LENGTH TO LMARG
	CAMLE	A,RMARG		;CHECK FOR VALID LENGTH
	JRST	E$$CJL		;TOO LONG
	JRST	OUTNJ1		;OUTPUT NON-JUSTIFIED

OUTNJ:	MOVE	A,LNIN2		;HERE TO OUTPUT CURRENT LINE, NOT JUSTIFIED
	TLNN	F,L.FILL	;SEE IF FILLING			[177]
	JRST	[SKIPL SPCNT	;NO--IF SPACES,			[177]
		 AOS   SPCNT	; ADVANCE SPACE COUNT		[177]
		 PUSHJ P,OUTLIN	;OUTPUT LINE			[177]
		 JRST  OUTNJ0]	;AND PROCEED			[177]
	PUSHJ	P,OUTNJ2	;CLEAR L.TJUS, CALL BODY OF ROUTINE
OUTNJ0:	TLZ	F,L.ESOL	;CLEAR LEFT/RIGHT SPACING FLAG
	SKIPLE	SCNTYP		;IF /TYPESET,
	TLNE	F,L.FOOT	; AND NOT IN FOOTNOTE,
	POPJ	P,		;NO--ALL DONE
	SKIPN	FOOTC		;YES--SEE IF SOME FOOTNOTES
	POPJ	P,		;NO--RETURN
	MOVE	A,FOOTP2	;YES--UPDATE
	MOVEM	A,FOOTP4	; POINTER
	SETZM	FOOTC		;CLEAR FOOTNOTE COUNTS
	MOVEI	S1,[ASCIZ \
/L----------/L/L[P8,10]
\]
	PUSHJ	P,FMES		;SEPARATE FOOTNOTES
	PUSHJ	P,FOOTGO	;ISSUE FOOTNOTES
	MOVEI	S1,[ASCIZ \
/L/L----------/L/L[P10,12]
\]
	PJRST	FMES		;SEPARATE FOOTNOTES AND RETURN
				CONT.
OUTLJ:	MOVE	A,LSTSP		;END OF LINE IS LAST SPACE, IF ANY
	CAMG	A,LNIN1		;..
OUTLIN:	MOVE	A,LNIN2		;ELSE END OF INPUT LINE
	TLO	F,L.TJUS	;COPY L.JUST TO L.TJUS
	TLNN	F,L.JUST
OUTNJ2:	TLZ	F,L.TJUS	; ..
	MOVEM	A,LOUT2		;SAVE END OF LINE TO CONSIDER
	MOVE	B,LNIN1		;AND BEGINNING.
	MOVEM	B,LOUT1		; ..
	CAMG	A,LOUT1		;LINE EMPTY?
	JRST	[SETZM FRCPAR	;CLEAR FORCED PARAGRAPH
		 PJRST LINSET]	;RETURN, INITIALIZING INPUT BUFFER
	TLNN	F,L.TJUS	;JUSTIFYING THIS LINE?
	JRST	OUTNJ1		;NO.
	SKIPG	SPCNT		;YES. ANY SPACES IN LINE?
	JRST	OUTNSP		;NO.SEE WHAT TO DO
	MOVE	A,RMARG		;YES. COMPUTE WHERE TO EXPAND THEM
	SUB	A,LMARG		;SIZE OF LINE
	SUB	A,INDCT		; ..
	ADD	A,LOUT1		;SUBTRACT SIZE OF DATA
	SUB	A,LOUT2		;..
	ADD	A,LSTNSP	;COMPENSATE FOR NON-SPACING CHARACTERS
	IDIV	A,SPCNT		;NOW FIND HOW MANY MULT SPACES EACH SPACE IS
	MOVEM	A,EXSP1		;MULTIPLIER FOR ALL SPACES
	TLNE	F,L.ESOL	;EXTRAS TO LEFT OR RIGHT?
	JRST	OUTJC1		;LEFT. STORE NUMBER OF EXTRA SPACES
	MOVNS	B		;RIGHT. GET SPACES BEFORE EXTRAS
	ADD	B,SPCNT		;..
OUTJC1:	MOVEM	B,EXSP2		;STORE FOR LATER
				CONT.
OUTNJ1:	SKIPE	FRCPAR		;SEE IF FORCING PARAGRAPH
	PUSHJ	P,PARAG0	;YES--GO DO IT
	SKIPG	LINEC		;IF START OF PAGE,
	PUSHJ	P,HEADIN	;  OUTPUT HEADING
	PUSHJ	P,FILSEQ	;OUTPUT FILE SEQUENCE
	MOVE	A,INDCT		;GET INDENTING IN CASE OF PARAGRAPH
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	OUTLTY		;YES--USE SPECIAL OUTPUT LOGIC
	ADD	A,LMARG		;PLUS LEFT MARGIN
	SKIPGE	A		;IS IT POSITIVE?
	PUSHJ	P,NEGIND	;NO. GIVE ADVISORY WARNING.
	PUSHJ	P,NSPAC		;OUTPUT THAT MANY SPACES
OUTL1:	PUSHJ	P,GLOUT		;READ A CHARACTER FROM OUTPUT BUFFER
	  JRST	OUTLE		;END OF OUTPUT BUFFER
	CAIN	CH,C.SPC	;REAL SPACE?
	JRST	OUTSP		;YES. GO SEND N OF THEM
	PUSHJ	P,CCOUT		;OUTPUT THE CHARACTER
	JRST	OUTL1		;LOOP BACK FOR MORE.

	MSG$	CJL,ERR,,Can't justify line
	PUSHJ	P,ONPAG		;TELL HIM WHERE HE LOST
	MOVE	A,LOUT1		;COPY POINTER TO LINE
	MOVE	B,LOUT2		; ..
	MOVEM	A,TT1		; ..
	MOVEM	B,TT2		; ..
JUSER1:	MOVEI	PA,TT1		;GET CHAR FROM LINE
	PUSHJ	P,GCI		; ..
	  JRST	JUSER2		;END OF LINE
	MOVE	A,CH
	CAIE	A,C.NXS		;SEE IF NON-EXPANDABLE SPACE
	CAIN	A,C.QTS		; OR QUOTED SPACE
	MOVEI	A,C.SPC		;YES--TYPE AS SPACE
	ANDI	A,CHRMSK	;REMOVE QUOTE
	CAIL	A,C.GRPH	;IGNORE NON-GRAPHICS
	PUSHJ	P,.TCHAR	;TYPE IT.
	JRST	JUSER1		;LOOP FOR WHOLE LINE
JUSER2:	PUSHJ	P,.TCRLF	;TYPE OUT CRLF
	TLZ	F,L.TJUS	;SAY NOT JUSTIFYING
	JRST	OUTNJ1		;AND OUTPUT LINE WITHOUT JUSTIFYING
;ROUTINE TO ISSUE ERROR MESSAGE ON NEGATIVE INDENT, I.E.,
;WHEN INDENT TRIES TO GO LEFT OF 0.
;WILL BE ISSUED AS WARNING ONCE PER <LM, <SD, <CHAP COMMAND.
;IF MORE THAN ONCE, REST WILL BE COUNTED AND ISSUED.

NEGIND:	AOS	A,NIACNT	;COUNT ERROR
	CAIE	A,1		;SEE IF FIRST ONE
	JRST	NEGINX		;NO--SKIP MESSAGE
	MSG$	NIA,WRN,,Negative indent attempted
	PUSHJ	P,ONPAG
NEGINX:	MOVEI	A,0		;INDICATE NO SPACING IN
	POPJ	P,

NEGINC:	MOVE	A,NIACNT	;GET NIA COUNT
	SETZM	NIACNT		;CLEAR COUNT
	SOSG	A		;SEE IF GT 1
	POPJ	P,		;NO--NO MESSAGE NEEDED
	SAVE$	<A>		;SAVE COUNT
	MSG$	NIC,WRN,,<An additional >
	RSTR$	<D>		;RESTORE COUNT
	TXNN	A,JWW.FL	;SEE IF /MESSAGE:FIRST
	PJRST	.TCRLF##	;NO--THAT'S ALL
	MOVE	A,D		;RESTORE COUNT
	PUSHJ	P,.TDECW##	;ISSUE COUNT
	MOVEI	A,[ASCIZ \ negative indent\]
	PUSHJ	P,.TSTRG##	;ISSUE STRING
	MOVEI	A,"s"		;GET PLURAL
	CAIE	D,1		;UNLESS ONLY ONE MORE,
	PUSHJ	P,.TCHAR##	; ISSUE IT
	MOVEI	A,[ASCIZ \ counted
\]
	PJRST	.TSTRG##	;ISSUE END OF MESSAGE
;HERE TO OUTPUT LINE FOR TYPESETTING SYSTEM
;IF FILL AND JUSTIFY, JUST ISSUE WITH SPACE AT CRLF
;IF NOFILL AND JUSTIFY, ISSUE WITH /J AT END
;IF NOJUSTIFY, ISSUE WITH /L AT END
;  (FILL, NOJUSTIFY WILL PROBABLY BE WRONG)

;CALL:	A/INDENT
;	JRST OUTLTY

OUTLTY:	MOVE	N,A		;SAVE INDENT
	PUSH	P,FOUTCH	;SAVE OUTPUT ROUTINE
	MOVEI	A,OUTTYQ	;USE SPECIAL ONE
	MOVEM	A,FOUTCH	; WHICH SENDS SPACE AS SPACE
	MOVEI	CH,C.SPC	;START WITH
	AOSE	FLTYPS		; SPACE UNLESS
	PUSHJ	P,FOUT		; FIRST AFTER .TYPESET
	JUMPE	N,OUTLTL	;IF NO INDENT, PROCEED
	MOVEI	S1,[ASCIZ \/?[HL\]
	PUSHJ	P,FMES		;INDICATE HANGING INDENT
	PUSHJ	P,TYPDSP	;ISSUE AMOUNT OF INDENT
	MOVEI	S1,[ASCIZ \,0,1]\]
	PUSHJ	P,FMES		;FOR ONE LINE WITH NO DELAY
OUTLTL:	PUSHJ	P,LOUTYP	;GO TYPE LINE
	SKIPGE	FLTYPC		;SEE IF SPECIAL OUTPUT FOR .TYPESET
	JRST	OUTLTX		;YES--SKIP CRLF
	MOVEI	S1,0		;PRESET NO END CODE
	TLNN	F,L.FILL	;SEE IF .FILL
	MOVEI	S1,[ASCIZ \/J\]	;NO--SET TO JUSTIFY
	TLNN	F,L.TJUS	;SEE IF JUSTIFY
	MOVEI	S1,[ASCIZ \/L\]	;NO--SET TO NOT JUSTIFY
	SKIPE	S1		;IF CODE,
	PUSHJ	P,FMES		; ISSUE FOR TYPESETTING
	MOVEI	S1,CRLFM	;GET END OF LINE
	PUSHJ	P,FMES		;ISSUE IT
	AOS	LINEC		;COUNT LINE
	PUSHJ	P,SETRNG	;UPDATE L.SUPO DEPENDING ON /RANGE
OUTLTX:	POP	P,FOUTCH	;RESTORE OUTPUTTER
	JRST	OUTLE		;GO FINISH LINE
;LINTYP TYPES CONTENTS OF LINBF TO OUTPUT FILE
;LOUTYP TYPES CONTENTS OF OUTPUT BUFFER TO OUTPUT FILE
;CALL:	PUSHJ	P,LINTYP/LOUTYP
;USES ALL AC'S

LINTYP:	MOVE	A,LNIN1		;GET INPUT BUFFER
	MOVEM	A,LOUT1		; POINTER INTO
	EXCH	A,LNIN2		; OUTPUT BUFFER
	MOVEM	A,LOUT2		; POINTERS
	PUSHJ	P,LOUTYP	;ISSUE OUTPUT BUFFER
	PJRST	LINSET		;RETURN WITH CLEAN LINE
LOUTYP:	PUSHJ	P,GLOUT		;GET ANOTHER CHARACTER
	  JRST	[SETOM FLSOPG	;INDICATE SOMETHING ON PAGE
		 SETOM SMINSC	;INDICATE SOMETHING IN SECTION
		 POPJ  P,]	;AND RETURN
	PUSHJ	P,CCOUT		;ISSUE CHARACTER
	JRST	LOUTYP		;LOOP
;HERE TO OUTPUT AN EXPANDABLE SPACE.

OUTSP:	MOVEI	CH,C.SPC	;OUTPUT A TRUE SPACE
	PUSHJ	P,CCOUT		; ..
	TLNN	F,L.TJUS	;ARE WE JUSTIFYING?
	JRST	OUTL1		;NO, JUST LOOP
	SKIPLE	A,EXSP1		;YES. HOW MANY MULTIPLE SPACES?
	PUSHJ	P,NSPAC		;IF ANY, SEND THEM.
	SOSL	EXSP2		;TO EXTRA BLANKS YET?
	JRST	OUTS1		;NO.
	TLNN	F,L.ESOL	;YES. SPACES LEFT OR RIGHT?
	JRST	OUTS2		;RIGHT. OUTPUT A SPACE
	JRST	OUTL1		;LEFT. NO MORE EXTRAS, JUST LOOP
OUTS1:	TLNN	F,L.ESOL	;LEFT OF BREAK. WANT LEFT SPACES?
	JRST	OUTL1		;NO. HOLD FOR LATER
OUTS2:	MOVEI	CH,C.SPC	;YES. OUTPUT A SPACE
	PUSHJ	P,CCOUT		; ..
	JRST	OUTL1		;AND LOOP FOR REST OF LINE
;END OF LINE, AND FOOTNOTE PROCESSING

OUTLE:	SETZM	INDCT		;CLEAR INDENT			[200]
	TLC	F,L.ESOL	;COMPLEMENT L-R FLAG FOR EACH LINE
	MOVE	A,LNIN1		;CLEAR INPUT LINE BUFFER
	EXCH	A,LNIN2		; BY BACKING UP POINTER
	CAMG	A,LOUT2		;ANY LEFT TO OUTPUT?
	JRST	OUTLE4		;NO.
	MOVEM	A,GCIN2		;YES. SAVE POINTER
	MOVE	A,LOUT2		; ..
	MOVEM	A,GCINP		;FOR GET-CHARACTER ROUTINE
	PUSHJ	P,GGCINP	;GET CHARACTER			[176]
	  JRST	OUTLE4		;NONE--OK			[176]
	CAIE	CH,C.SPC	;UNLESS SPACE,			[176]
	SOS	GCINP		; SET TO RE-EAT IT		[176]
	TLO	F,L.GCIN	;NEED TO INPUT FROM BUFFER FIRST
OUTLE4:	SETOM	FLSOPG		;INDICATE SOMETHING ON PAGE
	SKIPG	SCNTYP		;UNLESS TYPESETTING,
OUTLEX:	PUSHJ	P,SKIPS		; OUTPUT CRLFS FOR THIS LINE
	PUSHJ	P,LINSET	;SET UP FOR NEW LINE
	SETOM	SMINSC		;INDICATE SOMETHING IN SECTION
	SKIPE	FOOTC		;ANY FOOTNOTE LINE COMMANDS DECLARED?
OUTFT:	TLNE	F,L.FOOT	;YES. DOING THEM ALREADY?
	POPJ	P,		;YES--RETURN
	MOVE	A,NLPG		;SEE IF ROOM FOR FOOTNOTES
	SUB	A,FOOTC		; ..
	CAMGE	A,LINEC		; ..
	SKIPE	FLSOPG		;NO--SEE IF START OF PAGE
	SKIPLE	SCNTYP		;YES--FORCE FOOTNOTES UNLESS TYPESETTING
	POPJ	P,		;NO. HOLD TILL NEXT PAGE
	MOVEM	A,NLPG		;REDUCE EFFECTIVE PAGE SIZE
	MOVE	B,FOOTP2	;ADD LATEST FOOTNOTES TO POINTER
	MOVEM	B,FOOTP4	; ..
	SETZM	FOOTC		;CLEAR COUNT OF SAVED FOOTNOTE LINES
	SUB	A,NSPNG		;MINUS NORMAL SPACING
	CAMG	A,LINEC		;GREATER THAN LINE COUNT?
	PUSHJ	P,BPAGE		;YES. BREAK PAGE HERE.
	POPJ	P,		; AND RETURN
;TSTPAG WILL BREAK THE PAGE IF NECESSARY
;CALL:	N/LINES NEEDED TO FIT THIS PAGE OK
;	PUSHJ P,TSTPAG
;	RETURN +1 IF HAD TO BREAK TO NEW PAGE
;	RETURN +2 IF ROOM ON PAGE (NO CHANGES TO OUTPUT)

TSTPAG:	TLNE	F,L.FOOT	;IF IN FOOTNOTE,
	JRST	CPOPJ1		; DO NOTHING
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	[PUSH  P,S1	;SAVE S1
		 MOVEI S1,[ASCIZ \[*TP]\]
		 PUSHJ P,FMES	;OUTPUT MACRO
		 POP   P,S1	;RESTORE S1
		 PUSHJ P,DECPRT	;OUTPUT LENGTH OF TEST
		 MOVEI CH,"@"	;OUTPUT
		 PUSHJ P,FOUT	; END OF ARGUMENT
		 JRST  CPOPJ1]	;AND GIVE OK RETURN
	ADD	N,LINEC		;ADD CURRENT LINE POSITION
	CAMG	N,NLPG		;NO--SEE IF ROOM THIS PAGE	[214]
	JRST	CPOPJ1		;YES--GIVE OK RETURN

;BPAGE WILL ALWAYS BREAK TO A NEW PAGE
;IF TYPESETTING, IT WILL ISSUE A FORCED PAGE CALL FOR TYPESETTING

BPAGE:	TLNE	F,L.FOOT	;INSIDE A FOOTNOTE? OR
	POPJ	P,		;YES. DON'T DO IT AGAIN.
	MOVE	A,FOOTP3	;SEE IF ANY DATA IN FOOTNOTE BUFFER
	CAME	A,FOOTP4	; ..
	JRST	[PUSHJ P,FOOTGO	;YES--PROCESS DELAYED FOOTNOTES
		 JRST  FOOTX]	;THEN FINISH PAGE
	SKIPN	FLSOPG		;ARE WE IN HEADING AREA?
	POPJ	P,		;YES. DON'T REALLY BREAK THE PAGE, THEN.
FOOTX:	PUSHJ	P,FORM		;OUTPUT FORMFEED OR LINEFEEDS
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	[PUSH  P,S1	;YES--SAVE STRING POINTER
		 MOVEI S1,[ASCIZ \[*PG]\]
		 PUSHJ P,FMES	;ISSUE MACRO FOR TYPESETTING
		 POP   P,S1	;RESTORE STRING POINTER
		 JRST  .+1]	;PROCEED
	SETZB	A,LINEC		;CURRENT LINE NOW ZERO
	SETZM	FLSOPG		;INDICATE PAGE EMPTY
	SKIPN	SUBPGE		;UNLESS IN A SUBPAGE SEQUENCE,
	AOSA	PAGENO		;COUNT PAGE NUMBER
	AOS	A,SUBPGE	;COUNT SUB-PAGE
	CAIE	A,"Z"-"A"+2	;SEE IF GT 26 SUBPAGES
	JRST	FOOTX1		;NO--OK
	MSG$	SPO,WRN,,Subpage overflow
	PUSH	P,SUBPGE	;CLEAR SUBPAGES FOR ERROR MESS
	SETZM	SUBPGE		; ..
	PUSHJ	P,ONPAG		;SAY WHERE
	POP	P,SUBPGE	;RESET SUBPAGES
FOOTX1:	PJRST	SETRNG		;UPDATE L.SUPO DEPENDING ON /RANGE
;ROUTINE TO SPACE TO TOP OF FORM

FORM:	SKIPG	SCNTYP		;NO FORM FEEDS IF TYPESETTING
	SKIPG	N,LINEC		;GET CURRENT LINE POSITION
	POPJ	P,		;ALREADY AT TOP. RETURN.
	SKIPLE	SCNSIM		;SPACING WITH FF OR LFS
	JRST	BPG2		;LINEFEEDS
FRCFRM:	MOVEI	CH,.CHFFD	;OUTPUT FORMFEED TO FILE
	PUSHJ	P,FOUT		; ..
	JRST	BPG3		;ADJUST COUNTS
BPG2:	IDIVI	N,HWPLN		;IN CASE CURRENT PAGE OVER ONE REAL PAGE
	SUBI	N1,HWPLN	;GET - NUMBER OF LINES T/ TOP OF PAGE
BPG2A:	MOVEI	CH,.CHCRT	;INDICATE CARRIAGE RETURN	[227]
	SKIPLE	SCNCRT		;SEE IF /CRETURN		[227]
	PUSHJ	P,FOUT		;YES--OUTPUT IT			[227]
	MOVEI	CH,.CHLFD	;OUTPUT LINEFEEDS
	PUSHJ	P,FOUT		; ..
	AOJL	N1,BPG2A	; ..
BPG3:	SKIPE	DIDSOM		;IS DID SOME OUTPUT,
	SKIPG	SCNPAU		;WAIT FOR NEW PAPER?
	JRST	BPGX		;NO. RETURN
	SETZM	DIDSOM		;CLEAR OUTPUT INDICATOR
IF TOPS-10,<
	OUT	F.FOUT,		;FORCE ALL OF LINEFEEDS OUT
	  JRST	.+2
	JRST	E$$ODE
BPGXY:	CLRBFI			;CLEAR TYPEIN			[202]
	OUTSTR	[BYTE (7).CHBEL,.CHDEL,.CHDEL,.CHBEL]	;WAKE UP THE OPERATOR

	INCHRW	A		;YES. READ AND DISCARD COMMAND CHAR
	CLRBFI			;AND CLEAR INPUT BUFFER IN CASE MORE.
> ;END TOPS-10
IF TOPS-20,<
BPGXY:	MOVX	A,.PRIIN	;CLEAR INPUT BUFFER
	CFIBF
	HRROI	A,[BYTE (7).CHBEL,.CHDEL,.CHDEL,.CHBEL]
	PSOUT
	PBIN
	MOVX	A,.PRIIN	;CLEAR INPUT BUFFER AGAIN
	CFIBF
> ;END TOPS-20
BPGX:	POPJ	P,		;RETURN FROM FORM ROUTINE
;ROUTINE TO OUTPUT PAGE HEADING

HEADIN:	PUSH	P,BARON		;SAVE BAR INDICATOR
	SETZM	BARON		;CLEAR IT
	SETZM	BARNPY		;ALSO CLEAR START BAR
	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	HEADIY		;YES--SUPPRESS HEADING
	MOVE	A,SCNDWN	;DOWN SPACING
	PUSHJ	P,SKIPN		;SKIP ONE LINE
	MOVEI	A,0		;PRESET NO SPACES
	SKIPE	FLNHDR		;SEE IF .NO HEADERS
	JRST	HEADIX		;RIGHT--FINISH UP
	SKIPN	FLTITL		;SEE IF NO TITLE
	JRST	BPGN		;RIGHT--SKIP ITS CONTENTS
	PUSHJ	P,BLKSEQ	;BLANK FOR SEQUENCE
	MOVEI	PA,TTLP1	;OUTPUT TITLE TO FILE
	PUSHJ	P,PSTRPA	;PRINT STRING FROM PA
	SKIPE	FLNUMB		;WANT PAGE NUMBER?
	JRST	BPGN		;NO.
	MOVE	N,SECNUM	;GET CHAPTER NUMBER
	PUSHJ	P,COUNTC	;COUNT ITS LENGTH
	MOVE	B,A		;SAVE FOR LATER
	MOVE	N,PAGENO	;GET PAGE NUMBER
	PUSHJ	P,COUNTD	;COUNT ITS LENGTH
	MOVE	C,A		;SAVE FOR LATER
	MOVE	A,PRMRG		;FIND POSITION WHERE THIS LEFT US
	ADD	A,ULPOS		; ..
	SUBI	A,ULPBF		;ADD IN ANY UNDERLINES
	SUB	A,TTLP2		;AND TITLE CHARACTERS
	ADD	A,TTLP1		; ..
	SKIPE	SUBPGE		;SUBPAGE?
	SUBI	A,1		;YES. COUNT ITS LETTER
	SUBI	A,5(C)		;MINUS 8 FOR "PAGE NNN"
	SKIPE	SECNUM		;SEE IF CHAPTER
	SUBI	A,1(B)		;MINUS 3 FOR "NN-"
	PUSHJ	P,NSPAC		;SPACE OVER TO THERE
				CONT.
	MOVE	S1,FILHDR	;FIND TYPE OF PAGE CASE
	MOVE	S1,[[ASCIZ /PAGE /]
		    [ASCIZ /Page /]
		    [ASCIZ /page /] ]-1(S1)
	PUSHJ	P,MCOUT		;OUTPUT TO FILE
	SKIPN	N,SECNUM	;SEE IF CHAPTER DOCUMENT
	JRST	BPGNCH		;NO--SKIP ON
	PUSHJ	P,CHPPRT	;YES--OUTPUT CHAPTER NUMBER
	MOVEI	CH,"-"		;OUTPUT
	PUSHJ	P,CCOUT		;SEPARATOR
BPGNCH:	MOVE	N,PAGENO	;OUTPUT PAGE NUMBER
	PUSHJ	P,DECPRT	;DECIMAL PRINT
	SKIPN	CH,SUBPGE	;IN SUBPAGE SEQUENCE?
	JRST	BPGN		;NO
	ADDI	CH,"A"-2	;WHICH IS STORED IN BINARY
	CAILE	CH,"Z"		;SEE IF ALPHA
	MOVEI	CH,"?"		;NO--INDICATE OVERFLOW
	PUSHJ	P,CCOUT		;AND OUTPUT IT TO FINAL COPY FILE
BPGN:	SKIPN	DOSTTL		;SEE IF SUBTITLE WANTED
	JRST	HEADIW		;NO--SKIP IT
	MOVEI	A,1		;OUTPUT THE LINE WITH TITLE
	PUSHJ	P,SKIPN		; ..
	SKIPN	FLTITL		;SEE IF NOTITLE
	JRST	HEADIW		;RIGHT--SKIP SUBTITLE CONTENTS
	PUSHJ	P,BLKSEQ	;BLANK FOR SEQUENCE
	MOVEI	PA,STTLP1	;OUTPUT THE SUBTITLE, IF ANY
	PUSHJ	P,PSTRPA	; ..
HEADIW:	MOVEI	A,1+RHDSPA	;AND OUTPUT THIS LINE,
HEADIX:	ADD	A,DEFFIG	;INCLUDE DEFERRED FIGURES
	PUSHJ	P,SKIPN		;SKIP DEFFERED FIGURE ETC.
HEADIY:	SKIPN	DEFFIG		;SEE IF DEFERRED FIGURE
	SETZM	FLSOPG		;YES--INDICATE SOMETHING ON PAGE
	SETZM	DEFFIG		;CLEAR DEFERRED FIGURES
	SETOM	FLTITL		;CLEAR SUPPRESSION OF FIRST TITLE
	POP	P,BARON		;RESTORE BAR FLAG
	MOVE	A,BARON		;GET BAR INDICATOR
	MOVEM	A,BARNPY	;SET FOR START OF LINE
	POPJ	P,		;RETURN
;SUBROUTINE FOR CHAPTER PAGE NUMBER TO OUTPUT

CHPPRT:	JUMPL	N,[PUSHJ P,SETIND ;GET [ASCIZ /INDEX/]
		   PJRST MCOUT]	;IF NEGATIVE, IT IS INDEX
	TXZN	N,APPXFL	;SEE IF APPENDIX
	PJRST	DECPRT		;NO--ISSUE IN DECIMAL
	SUBI	N,1		;OFFSET (A IS REALLY "0")
CHPPR1:	IDIVI	N,^D26		;USE BASE 26 RADIX
	HRLM	N1,(P)		; PRINTER
	SKIPE	N		;DONE?
	PUSHJ	P,CHPPR1	;NO--HIT IT AGAIN
	HLRZ	CH,(P)		;YES--GET DIGIT
	ADDI	CH,"A"		;MAKE ASCII UPPER CASEE
	PJRST	CCOUT		;AND SEND TO OUTPUT

;SUBROUTINE TO TYPE CHAPTER PAGE NUMBER

TYPCHP:	JUMPL	A,[MOVE  A,S1	;SAVE S1
		   PUSHJ P,SETIND ;GET [ASCIZ /INDEX/]
		   EXCH  A,S1	;RESTORE S1
		   PJRST .TSTRG##]	;IF NEGATIVE, IT IS INDEX
	TXZN	A,APPXFL	;SEE IF APPENDIX
	PJRST	.TDECW##	;NO--ISSUE IN DECIMAL
	SUBI	A,1		;OFFSET (A IS REALLY "0")
TYPCH1:	IDIVI	A,^D26		;USE BASE 26 RADIX
	HRLM	B,(P)		; PRINTER
	SKIPE	A		;DONE?
	PUSHJ	P,TYPCH1	;NO--HIT IT AGAIN
	HLRZ	A,(P)		;YES--GET DIGIT
	ADDI	A,"A"		;MAKE ASCII UPPER CASEE
	PJRST	.TCHAR##	;AND SEND TO OUTPUT

;SUBROUTINE TO PUT A CHAPTER NUMBER INTO INPUT BUFFER

CHPINP:	JUMPL	N,[PUSHJ P,SETIND ;GET [ASCIZ /INDEX/]
		   PJRST MSGINP]  ;ISSUE MESSAGE
	TXZN	N,APPXFL	;SEE IF APPENDIX
	PJRST	DECINP		;NO--ISSUE IN DECIMAL
	SUBI	N,1		;OFFSET (A IS REALLY "0")
CHPIN1:	IDIVI	N,^D26		;USE BASE 26 RADIX
	HRLM	N1,(P)		; PRINTER
	SKIPE	N		;DONE?
	PUSHJ	P,CHPIN1	;NO--HIT IT AGAIN
	HLRZ	CH,(P)		;YES--GET DIGIT
	ADDI	CH,"A"		;MAKE ASCII UPPER CASEE
	PJRST	WLNINC		;GO PUT IN INPUT BUFFER
;SUBROUTINE TO COUNT THE DIGITS IN THE CHAPTER NUMBER

COUNTC:	MOVEI	A,0		;CLEAR COUNTER
	JUMPL	N,[MOVEI A,5	;"INDEX"
		   POPJ  P,]	;RETURN
	TXZN	N,APPXFL	;SEE IF APPENDIX
	PJRST	COUNTD		;NO--COUNT IN DECIMAL
	SUBI	N,1		;ALLOW THAT A IS "0"
COUNTK:	JUMPE	N,CPOPJ		;EXIT WHEN 0 (EVEN IF RESULT IS 0)
	IDIVI	N,^D26		;DIVIDE ARGUMENT
	AOJA	A,COUNTK	;COUNT RESULTING DIGIT

;SUBROUTINE TO PUT STRING INTO INPUT BUFFER

MSGINP:	HRLI	S1,(POINT 7,)	;MAKE BYTE POINTER
MSGINL:	ILDB	CH,S1		;GET NEXT BYTE
	JUMPE	CH,CPOPJ	;RETURN ON NULL
	PUSHJ	P,WLNINC	;GO PUT IN INPUT BUFFER
	JRST	MSGINL		;LOOP

;ROUTINE TO RETURN ADDRESS OF ASCIZ /INDEX/ IN RIGHT CASE

SETIND:	MOVE	S1,FILHDR	;FIND TYPE OF PAGE CASE
	MOVE	S1,[[ASCIZ /INDEX/]
		    [ASCIZ /Index/]
		    [ASCIZ /index/] ]-1(S1)
	POPJ	P,		;RETURN
;SUBROUTINE FOR PAGE NUMBER OUTPUT

PPGNO:	MOVEI	CH,C.NXS	;LEADING SPACES IF NEEDED
	CAIG	N,^D99		;3 DIGITS?
	PUSHJ	P,CCOUT		;NO. SPACE.
	CAIG	N,^D9		;2 DIGITS?
	PUSHJ	P,CCOUT		;NO. SPACE AGAIN.
DECPRT:	MOVEI	CH,"-"		;IN CASE NEGATIVE
	SKIPGE	N		;SEE IF NEGATIVE
	PUSHJ	P,CCOUT		;YES--ISSUE SIGN
DECPR1:	IDIVI	N,12		;STANDARD DECIMAL PRINT ROUTINE
	MOVMS	N1		;POSITIVE DIGIT
	HRLM	N1,(P)		; ..
	SKIPE	N		;DONE?
	PUSHJ	P,DECPR1	;NO
	HLRZ	CH,(P)		;GET A DIGIT
	ADDI	CH,"0"		;MAKE ASCII DIGIT
	PJRST	CCOUT		;OUTPUT TO FILE, COUNTING CPOS

;SUBROUTINE TO PUT A DECIMAL NUMBER INTO INPUT BUFFER

DECINP:	MOVEI	CH,"-"		;IN CASE NEGATIVE
	SKIPGE	N		;SEE IF NEGATIVE
	PUSHJ	P,WLNINC	;YES--ISSUE SIGN
DECIN1:	IDIVI	N,12		;STANDARD DECIMAL ROUTINE TO LINE BUFFER
	MOVMS	N1		;POSITIVE DIGIT
	HRLM	N1,(P)		;..
	SKIPE	N		;DONE?
	PUSHJ	P,DECIN1	;NO
	HLRZ	CH,(P)		;GET A DIGIT
	ADDI	CH,"0"		;MAKE ASCII
	PJRST	WLNINC		;GO PUT IN INPUT BUFFER

;SUBROUTINE TO COUNT THE DIGITS IN A DECIMAL NUMBER

COUNTD:	MOVEI	A,0		;CLEAR COUNTER
	SKIPGE	N		;SEE IF NEGATIVE
	AOS	A		;YES--ALLOW EXTRA SPACE
COUNTL:	JUMPE	N,CPOPJ		;EXIT WHEN 0 (EVEN IF RESULT IS 0)
	IDIVI	N,^D10		;DIVIDE ARGUMENT
	AOJA	A,COUNTL	;COUNT RESULTING DIGIT
;SUBROUTINE TO SKIP N LINES ON OUTPUT FILE

SKIPNC:	SKIPE	FLSOPG		;N LINES UNLESS AT TOP OF PAGE
	JRST	SKIPN		;NOT AT TOP--PROCEED
SKIPSC:	SKIPN	FLSOPG		;STANDARD SKIP UNLESS AT TOP OF PAGE
	POPJ	P,		;AT TOP--IGNORE REQUEST
SKIPS:	MOVE	A,NSPNG		;STANDARD SKIP
SKIPN:	JUMPLE	A,CPOPJ		;RETURN IF NONE TO DO
	TLNN	F,L.UMOD	;NEED TO CONSIDER SAVED UNDERLINES?
	PUSHJ	P,CCOUT3	;YES. GO DO SO.
	ADDM	A,LINEC		;COUNT LINES
	PUSHJ	P,SETRNG	;UPDATE L.SUPO DEPENDING ON /RANGE
	SETOM	FLSOPG		;INDICATE SOMETHING ON PAGE
	SETZM	NSPCH		;CLEAR PER-LINE COUNTS
	SKIPN	CPOS		;IF AT LEFT EDGE,
	JRST	CCOUL1		; HANDLE AS A SECOND BLANK LINE
	SETZM	CPOS		; ..
	JRST	CCOUL2		;GO OUTPUT IT
;LOOP HERE OVER BLANK LINES
CCOUL1:	SAVE$	A		;SAVE AC
	SKIPE	BARON		;SEE IF BAR NEEDED
	PUSHJ	P,BLKSEQ	;YES--OUTPUT BAR
	RSTR$	A		;RESTORE AC
	MOVEI	S1,[BYTE (7).CHLFD,0] ;JUST <LF> FROM HERE	[175]
	SKIPG	SCNCRT		;SEE IF /CRETURN, OR		[227]
	SKIPE	BARON		;SEE IF WE DID BAR
CCOUL2:	MOVEI	S1,CRLFM	;YES--NEED REAL CRLF
	SKIPLE	SCNTYP		;IF TYPESETTING,
	MOVEI	S1,[ASCIZ \/L\]	; FORCE, BLANK LINE
	PUSHJ	P,FMES		;OUTPUT CRLF TO LINE
	SOJG	A,CCOUL1	;OUTPUT AS MANY AS REQUESTED
	MOVE	A,BARON		;COPY BAR FLAG
	MOVEM	A,BARNPY	; TO START OF LINE
	SKIPLE	SCNTYP		;IF TYPESETTING,
	POPJ	P,		; ALL DONE
	MOVE	A,LINEC		;CHECK FOR END OF PAGE
	ADD	A,NSPNG		;POSITION OF NEXT LINE IF ALLOWED
	CAMLE	A,NLPG		;UP TO A FULL PAGE?
	PUSHJ	P,BPAGE		;YES. HANDLE HEADING
	POPJ	P,		;RETURN FROM SKIPN

CRLFM:	ASCIZ	/
/
;ROUTINE TO OUTPUT N SPACES TO OUTPUT FILE, N .GE. 0, N IN A.

NSPAC:	JUMPLE	A,CPOPJ		;RETURN IF NONE TO OUTPUT
	MOVEI	CH,C.NXS	;GET A NON-EXPANDABLESPACE
	PUSHJ	P,CCOUT		;OUTPUT TO FILE
	SOJG	A,.-2		;LOOP FOR N SPACES
	POPJ	P,		;AND RETURN.

;ROUTINES TO OUTPUT A STRING TO THE OUTPUT FILE

PSTRPA:	MOVE	A,(PA)		;GET POINTER FROM PA
	MOVE	B,1(PA)		; ..
	MOVEM	A,PSTRP		;STORE IN TEMP
	MOVEM	B,PSTRP+1	; ..
PSTRL:	MOVEI	PA,PSTRP	;GET A CHARACTER FROM THE TEMP POINTER
	PUSHJ	P,GCI		; ..
	  POPJ	P,		;NONE LEFT
	PUSHJ	P,CCOUT		;OUTPUT CHAR TO FILE
	JRST	PSTRL		;LOOP FOR WHOLE STRING
;OUTPUT STRING TO FILE, COUNTING POSITION

MCOUT:	HRLI	S1,(POINT 7)	;MAKE STRING POINTER
MCOUT1:	ILDB	CH,S1		;GET NEXT CHARACTER
	JUMPE	CH,CPOPJ	;RETURN WHEN NULL
	PUSHJ	P,CCOUT		;ELSE, OUTPUT IT
	JRST	MCOUT1		;AND LOOP

;SUBROUTINE TO OUTPUT CHARACTER TO FILE,AFTER SOME TESTS

CCOUT:	CAIE	CH,C.ULS	;UNDERLINE CHARACTER?
	JRST	CCCOUT		;NO.
	TLNN	F,L.UMOD	;YES. BY LINE?
	JRST	CCOUT2		;YES.
	SKIPLE	SCNTYP		;IF TYPESETTING,
	JRST	UNLTYP		; ISSUE SPECIAL CODE FOR TYPESETTING
	MOVE	CH,ULCHO	;CONVERT TO OUTPUT UNDERLINE
	TLNN	F,L.UBSP	;NO. BY BACKSPACING?
	PJRST	FOUT		;NO. ASSUME NON-SPACING
	PUSHJ	P,FOUT		;YES. SEND UNDERLINE
	MOVEI	CH,.CHCNH	;AND FOLLOW WITH BACKSPACE

;SUBROUTINE TO OUTPUT CHARACTER LITERALLY TO FILE

CCCOUT:	CAIN	CH,C.TAT	;SEE IF TYPESET AT
	JRST	[SKIPG SCNTYP	;YES--SEE IF TYPESETTING
		 POPJ  P,	;NO--IGNORE IT
		 PJRST ATTYP]	;YES--ISSUE IT AND RETURN
	PUSHJ	P,@FOUTCH	;SEND TO OUTPUT FILE
	ANDI	CH,CHRMSK	;MASK TO ASCII
	CAIE	CH,.CHTAB	;SEE IF TAB, OR
	CAIL	CH,C.GRPH	;SEE IF GRAPHIC
	AOS	CPOS		;COUNT POSITION OF CARRIAGE
	POPJ	P,		;AND RETURN.

CCOUT2:	MOVE	B,CPOS		;YES. STORE POSITION IN BUFFER FOR LATER
	MOVEM	B,@ULPOS	;INTO UNDERLINE BUFFER
	AOS	B,ULPOS		;STEP BUFFER POINTER. (SHOULD CHECK IT)
	CAIL	B,ULPBF+LN$UND	;SEE IF UNDERLINE BUFFER OVERFLOW
	SOS	ULPOS		;YES--IGONRE IT
	POPJ	P,		;RETURN WITHOUT TYPING THE UNDERLINE.
;CONTINUATION OF OUTPUT N LINES

CCOUT3:	MOVEI	B,ULPBF		;START CONSIDERING UNDERLINE BUFFER
	CAMN	B,ULPOS		;ANY UNDERLINES IN THE BUFFER?
	JRST	CCOUT5		;NO. GO SEND LINE
	SAVE$	A		;SAVE NUMBER OF LINES TO BE OUTPUT
	TLNE	F,L.USUP	;UNDERLINES SUPPRESSED?
	JRST	CCOUT4		;YES. SKIP OUTPUT SECTION
	MOVEM	B,ULPT1		;STORE START OF BUFFER
	MOVEI	CH,.CHCRT	;OUTPUT CARRIAGE RETURN TO LINE
	PUSHJ	P,FOUT		;SEND TO FILE (NO LF YET)
	TLNE	F,L.ULIN	;SEE IF /UNDERLINE:SEPARATE
	JRST	[MOVEI CH,.CHLFD  ;YES--ISSUE LINE FEED
		 PUSHJ P,FOUT	; ..
		 AOS   LINEC	;COUNT LINE
		 PUSHJ P,SETRNG	;UPDATE L.SUPO DEPENDING ON /RANGE
		 JRST  .+1]	;AND PROCEED
	PUSHJ	P,BLKSEQ	;SKIP SEQUENCE FIELD
	SETZM	CPOS		;START AT BEGINNING OF LINE
CCOUT6:	MOVE	A,@ULPT1	;GET POSITION WHERE UNDERLINE GOES
	SUB	A,CPOS		;HOW FAR TO IT?
	PUSHJ	P,NSPAC		;SPACE TO THE UNDERLINE
	MOVE	CH,ULCHO	;GET LINE-PRINTER UNDERSCORE CHARACTER
	PUSHJ	P,FOUT		;SEND TO FILE
	AOS	CPOS		;COUNT POSITION
	AOS	A,ULPT1		;COUNT UNDERLINE BUFFER POINTER
	CAME	A,ULPOS		;UP THRU LAST UNDERLINE?
	JRST	CCOUT6		;NO. GO OUTPUT ANOTHER ONE
CCOUT4:	MOVEI	A,ULPBF		;YES. RESET TO START OF BUFFER
	MOVEM	A,ULPOS		; ..
	RSTR$	A		;RESTORE NUMBER OF LINES
CCOUT5:	POPJ	P,		;AND GO OUTPUT THEM

;HERE IF TYPESETTING, TO INDICATE UNDERLINE NEXT

UNLTYP:	SAVE$	S1		;SAVE STRING POINTER
	MOVEI	S1,[ASCIZ \[FI]\]
	SKIPN	AFTRNC		;IF ALREADY SET, DON'T REPEAT
	PUSHJ	P,FMES		;SWITCH TO ITALICS
	MOVSI	S1,[ASCIZ \[FR]\]
	MOVEM	S1,AFTRNC	;DEFERRED SWITCH BACK
	RSTR$	S1		;RESTORE STRING POINTER
	POPJ	P,		;RETURN
	SUBTTL	TYPESET TRANSLATION LOGIC

;+.CHAPTER TYPESET TRANSLATION LOGIC
;-

;+.UC.TS16

;RUNOFF starts the translation by inserting a  comment  which
;identifies  the  version of RUNOFF, the date it was run, the
;name of the file being processed and its creation  date  and
;time.   Text  is  processed by copying each character to the
;output.  Case control commands are processed, so the  output
;file  is  in  upper  and  lower  case  as appropriate to the
;requested format.  Horizontal spacing commands (explicit and
;implicit)   are   converted   into  the  comparable  TYPESET
;commands.  In particular, RUNOFF breaks the input into lines
;just as if it were doing the final copy itself.  Underlining
;is converted to italics.  The double space after  a  period,
;etc.,  is  dropped  unless the final output is /TYPESET:LPT.
;When  the  various   commands   and   internal   flags   are
;encountered,  if  RUNOFF can not complete processing itself,
;it generates the appropriate TYPESET-10 command.   If  there
;is  no  perfect  command,  then  RUNOFF generates a macro to
;TYPESET-10.  If the macro corresponds to a  RUNOFF  command,
;then  the  macro  name  is  the  same as the standard RUNOFF
;command abbreviation (e.g., [*TP] for any test page  whether
;a user command or an implicit one).
;
;Commands which relate to horizontal spacing are  treated  as
;follows.   The  comparable commands are issued to TYPESET-10
;but  the  spacing  is  modified  in  order  to   achieve   a
;typesetting  width of 36 unless /TYPESET:LPT is selected (in
;which case, the RUNOFF spacing is kept).  The conversion  to
;width  36  is  achieved  by  multiplying the input number by
;36/page width as set in the  last  PAPER  SIZE  or  STANDARD
;command.  The result is issued as picas and points.
;
;Commands relating to pagination are converted to  TYPESET-10
;macros  and  are  ignored.   Similarly,  the output does not
;include sequence numbers, change bars, or variable flagging.
;Since  the  paging  will  be  chosen  by  the  final editor,
;footnotes are dumped as soon as  possible.   In  particular,
;they  are  output at the next break surrounded by horizontal
;lines to help break them up.
;RUNOFF produces the following  macros  when  translating  to
;TYPESET-10.  They are generally issued right in line without
;any free line feeds.

;.LM16.P-16,,6.AUTOTABLE

;[*ACUTE]	output acute accent
;
;[*AX]	center  appendix  heading;	first   arg   is
;	letter, second is title
;
;[*BB]	begin change bar
;
;[*BKSLSH]	output backslash character
;
;[*CAT] 	used at start of file when /TYPESET:CAT
;
;[*CH]	center chapter heading;  first arg is number,
;	second is title
;
;[*CONTRL]	represents control character in  input;	arg
;	is  one  character  in  upper  case  for the
;	control with "?" representing delete
;
;[*CRCFLX]	output circumflex accent
;
;[*DB]	disable change bars
;
;[*DX]	center index heading;  arg is header
;
;[*EB]	end change bar
;
;[*EBB] 	enable change bars
;
;[*ELS] 	end list
;
;[*EN]	end note

		CONT.
;
;[*HLn]	header level n (1-5);  arg is numbered title
;
;[*LE]	list element (no argument;  followed by
;
;the element number, then "./N/N".
;
;[*LFTANG]	output left angle bracket
;
;[*LFTBRC]	output left brace
;
;[*LS]	start list
;
;[*LPTR]	used at start of file when /TYPESET:LPT
;
;[*NT]	note heading;   argument  is  heading  to  be
;	centered
;
;[*PG]	force a new page
;
;[*RHTANG]	output right angle bracket
;
;[*RHTBRC]	output right brace
;
;[*TILDE]	output tilde
;
;[*TP]	test page;  arg is number of lines
;
;[*TXT6]	used at start of file when /TYPESET:TXT
;
;[*UNDRLN]	output underline (do not overprint)
;
;[*VRTBAR]	output vertical bar
;.PG.P0.LM0.AUTOPARAGRAPH

;RUNOFF uses the following TYPESET commands  when  converting
;the  input  to  TYPESET-10.   In general, they are issued in
;line without a free line feed.  /L is usually followed by  a
;line feed except when it is a SKIP or BLANK command.

;.LM16.P-16.AUTOTABLE

;/A	center on a tab stop (used for  .CENTER  with
;	arg)
;
;/C	center on page (used for .CENTER without arg)
;
;/J	ends a line under .JUSTIFY.NOFILL
;
;/L	force a new line (used on break and for blank
;	lines)
;
;/N	fixed space ("#")
;
;/R	right adjust
;
;/U	tabulate (for input tabs)
;
;/?	break if something on line
;
;++	output "+"
;
;+A	output "@"
;
;+[	output "["
;
;+]	output "]"
;
;+/	output "/"

		CONT.
;
;[Cn]	set column width (right margin)
;
;[FB]	bold face (.TYPESET BOLD)
;
;[FI]	italics face (underline and .TYPESET ITALICS)
;
;[FM]	slant face (.TYPESET SLANT)
;
;[FR]	regular face
;
;[FS]	smallcaps face (.TYPESET SMALLCAPS)
;
;[HLn,0,1]      indent next line
;
;[HRn,0,1]      adjust next line to right margin
;
;[ILn]	set left margin
;
;[P8,10]	size of footnotes
;
;[P10,12]	size of normal text
;
;[RR]	ragged right (.NOJUSTIFY)
;
;[R%]	justify
;
;[TSi,j,...]    set tab stops
;
;[T%]	clear tab stops

;-.P0.LM0.AUTOPARAGRAPH.LC.TS8,,,,,,,,,,,,,,,
	SUBTTL	HANDY-DANDY SUBROUTINES

;+.CHAPTER HANDY SUBROUTINES
;-

;+
;^THE ROUTINE "<TSTECM" LOOKS AT THE LINE ABOUT TO BE
;INPUT AND CHECKS IT TO SEE IF IT IS EXACTLY ONE END COMMAND,
;NAMELY, THE ONE WHICH TERMINATES THE CURRENT TEXT
;BRACKET. ^IT IS USED WHEN A COMMAND TAKES SEVERAL LINES
;OF TEXT AS AN ARGUMENT AND IS TERMINATED BY A COMMAND OF THE
;FORM .END XXX.
;
;^THIS ROUTINE IS CALLED AT THE BEGINNING OF EACH LINE OF
;TEXT:
;	1/ ADDRESS OF CHARACTER INPUT ROUTINE TO USE
;	2/ ADDRESS OF ROUTINE WHICH HANDLES THE .END
;		COMMAND OF THE TYPE DESIRED
;	PUSHJ	P,TSTECM
;	RETURNS +1 IF NOT END YET
;	RETURNS +2 IF MATCH
;
;^SEE WRITEUP OF "<RTECMC" FOR NORMAL CHARACTER READ.
;-

TSTECM:	MOVEM	A,RINCHR	;SAVE ADDRESS OF INPUT ROUTINE
	MOVEM	B,ADRECM	;SAVE ADDRESS OF MATCH
	MOVEI	PA,TECBFP	;POINT TO END TEST BUFFER
	PUSHJ	P,RCI		;CLEAR BUFFER
	MOVEI	N,5*LN$TEC-2	;SET COUNT
	PUSHJ	P,TECGCN	;READ FIRST CHARACTER IGNORING GCSCH AS SPECIAL
	CAME	CH,CC.CON	;SEE IF CONTROL INDICATOR
	JRST	TECECX		;NO--JUST CLEAN UP
	PUSHJ	P,STRCMN	;INDICATE COMMAND

	PUSHJ	P,TECGWD	;GET WORD
	  JRST	TECECX		;BUFFER FULL--NOT A MATCH

;HERE WHEN FIRST WORD HAS BEEN READ

	MOVE	S1,[-CMTL1,,CMTAB] ;POINT TO COMMAND TABLE
	PUSHJ	P,CMREC		;TRY TO RECOGNIZE IT
	  JRST	TECECX		;NOT A MATCH
	HLRZ	A,(D)		;GET DISPATCH ADDRESS
	CAMN	A,ADRECM	;SEE IF OURS
	JRST	TECFND		;YES--INDICATE FOUND
	CAIE	A,$$END		;NO--SEE IF .END
	JRST	TECECX		;NO--NOT A MATCH
				CONT.
;HERE WHEN FIRST WORD IS ".END"

TECSKP:	PUSHJ	P,TECGCH	;SKIP SPACES
	PUSHJ	P,CMSOME	;SEE IF END OF COMMAND
	  JRST	TECECX		;YES--NO MATCH
	CAIE	CH,C.SPC	;SEE IF SPACE
	CAIN	CH,.CHTAB	; OR TAB
	JUMPG	N,TECSKP	;YES--LOOP IF ROOM
	MOVEM	CH,GCSCH	;SET TO RESCAN

	PUSHJ	P,TECGWD	;GET WORD
	  JRST	TECECX		;BUFFER FULL--NOT A MATCH

;HERE WHEN SECOND WORD HAS BEEN READ

	MOVE	S1,[-ECMTL1,,ECMTAB] ;POINT TO END COMMAND TABLE
	PUSHJ	P,CMREC		;TRY TO RECOGNIZE IT
	  JRST	TECECX		;NOT A MATCH
	HLRZ	A,(D)		;GET DISPATCH ADDRESS
	CAMN	A,ADRECM	;SEE IF OURS
	JRST	TECFND		;YES--INDICATE FOUND
	JRST	TECECX		;NO--NO MATCH

;HERE WHEN REJECT

TECECX:	TRZ	F,R.CCOM	;CLEAR COMMAND
	SETOM	GCSCH		;CLEAR ANY HANGING RE-EAT SINCE IN BUFFER
	POPJ	P,		;RETURN FAILURE

;HERE WHEN ACCEPT COMMAND

TECFND:	MOVEI	PA,TECBFP	;POINT TO SPECIAL BUFFER
	PUSHJ	P,RCI		;CLEAR IT
	JRST	CPOPJ1		;GIVE WIN RETURN
;ROUTINE TO READ A WORD FOR TSTECM

TECGWD:	MOVEI	PA,CMBF		;POINT TO COMMAND BUFFER
	PUSHJ	P,CSP		;COMPUTE POINTERS
	MOVEM	A,CMSTP		;STORE THEM
	MOVEM	B,CMST2		; ..
	MOVEI	N1,<ECMBF-CMBF>*5 ;FOR END TEST
TECGW1:	JUMPLE	N,CPOPJ		;ERROR IF OVERFLOW TEMP STRING
	SOJLE	N1,CPOPJ	;ERROR IF OVERFLOW COMMAND STRING
	PUSHJ	P,TECGCH	;READ CHARACTER
	PUSHJ	P,CMCFUC	;FORCE UPPER CASE
	CAIG	CH,"Z"		;SEE IF
	CAIGE	CH,"A"		; ALPHABETIC
	JRST	CMGWD1		;NO--ALL DONE
	MOVEI	PA,CMSTP	;POINT TO COMMAND BUFFER
	PUSHJ	P,WCI		;STORE IT
	JRST	TECGW1		;LOOP FOR MORE
;ROUTINE TO READ AND SAVE A CHARACTER FOR TSTECM

TECGCH:	SKIPL	CH,GCSCH	;SEE IF SOMETHING SAVED
	JRST	[SETOM GCSCH	;YES--CLEAR IT
		 POPJ  P,]	;AND RETURN IT WITHOUT STORE
TECGCN:	PUSHJ	P,@RINCHR	;NO--READ ANOTHER CHAR
				;FALL INTO STORING IT

;ROUTINE TO HANDLE STORE IN TEMP STRING BUFFER

TECWCI:	SOS	N		;COUNT DOWN SPACE
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	SOS	N		;YES--COUNT THAT TOO
	MOVEI	PA,TECBFP	;POINT TO BUFFER AREA
	PJRST	SCI		;DO PROTECTED STORE

;+
;^THE ROUTINE "<RTECMC" IS TO BE CALLED FOR EACH CHARACTER
;IN THE TEXT BRACKET. ^IT READS OUT THE TEMPORARY STRING TEXT
;BUFFER IF ANY, OR ELSE IT TAKES THE NON-SKIP RETURN.
;CALL:
;	PUSHJ	P,RTECMC
;	RETURN +1 IF NOTHING IN BUFFER
;	RETURN +2 WITH NEXT CHARACTER
;-

RTECMC:	SKIPN	TECBFP		;SEE IF FAST EXIT
	POPJ	P,		;YES
	MOVEI	PA,TECBFP	;POINT TO TEMP BUFFER
	PUSHJ	P,GCI		;GET NEXT CHAR
	  JRST	[SETZB CH,TECBFP ;DONE--INDICATE FAST EXIT
		 POPJ  P,]	;GIVE NULL RETURN
	JRST	CPOPJ1		;GIVE WIN RETURN
;ROUTINES TO HANDLE FOUR-WORD CHARACTER INDEX BLOCKS
;	FORMAT:	INCREMENT AND READ INDEX
;		INCREMENT AND STORE INDEX
;		FIRST-1 CHARACTER ADDRESS
;		LAST CHARACTER ADDRESS
;	ALL CALLS WITH PA=ADDRESS OF INDEX BLOCK

;INITIALIZE BLOCK--CALL WITH WORD ADDRESS IN A, WORD LENGTH IN B

ICI:	IMULI	A,5		;CONVERT TO CHARACTER ADDRESS
	SOS	A		;BACK OFF TO START WITH INCREMENT
	MOVEM	A,2(PA)		;INITIALIZEFIRST-1
	IMULI	B,5		;CONVERT TO CHARACTER LENGTH
	ADD	A,B		;COMPUTE LAST
	MOVEM	A,3(PA)		;INITIALIZE LAST

;RESET BLOCK--SETS READ/STORE TO FIRST-1

RCI:	MOVE	A,2(PA)		;GET FIRST-1
	MOVEM	A,(PA)		;INITIALIZE READ
	MOVEM	A,1(PA)		;INITIALIZE STORE
	POPJ	P,		;RETURN

;PROTECTED STORE--STORE CH; USES A,B

SCI:	AOS	A,1(PA)		;INCREMENT POINTER
	MOVE	B,A		;COPY VALUE
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	AOS	B		;YES--UP ONCE MORE
	CAMG	B,3(PA)		;COMPARE TO LAST
	JRST	WCI1		;OK--GO DO THE STORE
	SOS	1(PA)		;NO--REVERSE POINTER
	POPJ	P,		;AND RETURN
;REST USE A TWO WORD BLOCK

;ROUTINE TO COMPUTE EMPTY STRING POINTER

CSP:	MOVE	A,PA		;GET ARGUMENT
	IMULI	A,5		;CONVERT TO CHARACTERS
	SOS	B,A		;BACK UP ONE, COPY TO B
	POPJ	P,		;RETURN

;ROUTINES TO GET CHARACTER AND INCREMENT STRING POINTER

GGCINP:	SKIPA	PA,[EXP GCINP]
GLOUT:	MOVEI	PA,LOUT1	;PARTICULAR ARGUMENTS
GCI:	MOVE	A,(PA)		;GET FIRST POINTER
	CAML	A,1(PA)		;ANYTHING IN STRING?
	POPJ	P,		;NO. NON-SKIP RETURN.
	AOS	A,(PA)		;YES. COUNT AND GET FIRST POINTER
	IDIVI	A,5		;CONVERT TO WORD AND BYTE
	LDB	CH,CBYTAB(B)	;GET THE CHARACTER
	CAIN	CH,C.QUTI	;SEE IF QUOTED
	JRST	[PUSHJ P,GCI	;YES--GET NEXT CHAR
		   TDZA  CH,CH
		 TXO   CH,LCHPVT  ;FLAG IT
		 JRST  .+1]
CPOPJ1:	AOS	(P)		;SKIP RETURN
CPOPJ:	POPJ	P,		;RETURN.
;ROUTINES TO WRITE CHARACTER AND INCREMENT POINTERS

WLNINC:	SOS	LINBK		;COUNT DOWN SPACE IN BUFFER
WLNIN1:	MOVEI	PA,LNIN1	;STANDARD ARG
	MOVE	A,(PA)		;GET START
	CAMN	A,1(PA)		;SEE IF EMPTY
	PUSHJ	P,LINUPC	;YES--UPDATE THISXX COUNTERS
	TXNE	CH,LCHPVT	;SEE IF QUOTED
	JRST	[SOSN LNINCT	;YES--COUNT DOWN
		 JRST E$$IBO	;ERROR IF OVERFLOW
		 JRST .+1]	;OK
	SOSLE	A,LNINCT	;CHECK LINE COUNT
	JRST	WCI		;OK--GO AHEAD
	JUMPL	A,CPOPJ		;OVER--DISCARD CHARACTER
	MSG$	IBO,ERR,,Input buffer overflow
	PJRST	ONPAG		;SAY WHERE AND RETURN
WCI:	AOS	A,1(PA)		;COUNT POINTER AND GET IT.
WCI1:	TXNE	CH,LCHPVT	;SEE IF QUOTED
	JRST	[PUSH  P,CH	;YES--SAVE AWAY
		 MOVEI CH,C.QUTI  ;GET INTERNAL QUOTE
		 PUSHJ P,.+1	;STORE THAT
		 POP   P,CH	;RESTORE ARGUMENT
		 AOS   A,1(PA)	;COUNT UP
		 JRST  .+1]	;PROCEED
	IDIVI	A,5		;CONVERT TO WORD AND BYTE
	DPB	CH,CBYTAB(B)	;STORE CHARACTER
	POPJ	P,		;RETURN

CBYTAB:	POINT	7,0(A),6
	POINT	7,0(A),13
	POINT	7,0(A),20
	POINT	7,0(A),27
	POINT	7,0(A),34
;ROUTINE TO STACK MARGINS, JUSTIFICATION, SPACING

PSHMJS:	AOSG	A,MJSPDL	;INCREMENT STACK
	JRST	[SETZM MJSPDL	;HAD UNDERFLOWED--FIX UP
		 JRST  PSHMJS]	;TRY AGAIN
	CAILE	A,LN$MJP	;SEE IF OVERFLOW
	JRST	E..TNN		;YES--GO GIVE ERROR
	IMULI	A,LN$MJS	;MULT BY LENGTH OF FRAME
	ADD	A,[-LN$MJS-1,,MJSPDB-LN$MJS-1]
	PUSH	A,RMARG		;SAVE RIGHT MARGIN
	PUSH	A,LMARG		;SAVE LEFT MARGIN
	PUSH	A,NSPNG		;SAVE SPACING
	PUSH	A,F		;SAVE JUSTIFY AND FILL FLAGS
	HRRM	N,(A)		;GET POST-RESTORE SPACE
	POPJ	P,		;RETURN

E..TNN:	CAIE	A,LN$MJP+1	;SEE IF JUST OVER
	POPJ	P,		;NO--ALREADY GAVE MESSAGE
	MSG$	TNN,WRN,,Too many nested notes
	PJRST	ONPAG		;TELL WHERE AND RETURN

;ROUTINE TO RESTORE FROM STACK

POPMJS:	MOVEI	N,0		;IN CASE ERROR EXIT, RETURN 0
	SOSGE	A,MJSPDL	;BACK UP POINTER
	JRST	E..UME		;ERROR IF TOO FAR
	CAIL	A,LN$MJP	;SEE IF HAD OVERFLOWED
	POPJ	P,		;YES--DON'T RESTORE YET
	IMULI	A,LN$MJS	;ALLOW FOR FRAME SIZE
	ADD	A,[LN$MJS,,MJSPDB+LN$MJS-1]
	POP	A,B		;RESTORE FLAGS
	HRRE	N,B		;RESTORE POST-RESTORE SPACE
	TLZ	F,L.FILL!L.PJUS!L.JUST
	AND	B,[L.FILL!L.PJUS!L.JUST,,0]
	IOR	F,B		; FOR JUSTIFY AND FILL
	PUSHJ	P,JUSTYP	;SEND JUSTIFICATION TO TYPESET
	POP	A,NSPNG		;RESTORE SPACING
	POP	A,LMARG		;RESTORE LEFT MARGIN
	POP	A,RMARG		;RESTORE RIGHT MARGIN
	PJRST	LRMTYP		;RETURN, ISSUING MARGINS FOR TYPESETTING

E..UME:	AOJN	A,CPOPJ		;SEE IF FIRST UNDERFLOW
	MSG$	UME,WRN,,Unmatched end command
	PJRST	ONPAG		;TELL WHERE AND RETURN
;ROUTINE TO OUTPUT HEADING SEQUENCE NUMBER OF INPUT FILE

FILSEQ:	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	FILSEY		;YES--NO SEQUENCE
	MOVEI	CH,.CHTAB	;TAB OVER TO TEXT
	SKIPE	A,FILOVT	;IF ZERO DO NOTHING
	PUSHJ	P,FOUT		;OUTPUT TAB
	SOJG	A,.-1		;REDO IF NECESSARY
	TRNN	F,R.SEQU	;SEE IF /SEQUENCE
	JRST	FILSEX		;NO--
	TLNE	F,L.FOOT	;SEE IF IN FOOTNOTE
	JRST	BLKSQ1		;YES--OMIT SEQUENCE NUMBERS
	MOVE	B,THISEQ	;GET THIS INPUT LINE'S SEQUENCE
	JUMPE	B,FILSQ1	;NOT SEQUENCED--GO USE COUNT
	MOVEI	C,0		;ADD ASCIZ TERMINATOR
	MOVEI	S1,B		;POINT TO SEQUENCE
	PUSHJ	P,FMES		;OUTPUT TO FILE
	JRST	FILSQ2		;PROCEED WITH PAGE NUMBER
;HERE IF INPUT FILE NOT SEQUENCED
FILSQ1:	MOVE	N,THISLN	;GET LINE COUNT THIS INPUT PAGE
	AOS	N		;ADD ONE
	MOVEI	CH,C.NXS	;PRESET SPACE
	CAIG	N,^D9999	;SEE IF FIVE DIGITS
	PUSHJ	P,CCOUT		;NO--SPACE OVER			[216]
	CAIG	N,^D999		;SEE IF FOUR DIGITS
	PUSHJ	P,CCOUT		;NO--SPACE OVER			[216]
	PUSHJ	P,PPGNO		;ISSUE AS AT LEAST THREE CHARS
;HERE AFTER LINE NUMBER (.GE. 5 CHARS)
FILSQ2:	MOVEI	CH,"/"		;SEPARATOR FOR PAGE
	PUSHJ	P,FOUT		;OUTPUT IT
	MOVE	N,THISPG	;GET INPUT PAGE COUNT
	AOS	N		;COUNT UP FOR THIS PAGE
	PUSHJ	P,PPGNO		;OUTPUT AT LEAST THREE CHARS
	JRST	FILSEW		;PUT IN BLANK SPACES
				CONT.
;ROUTINE TO OUTPUT BLANK HEADING SEQUENCE FIELD

BLKSEQ:	SKIPLE	SCNTYP		;SEE IF TYPESETTING
	JRST	FILSEY		;YES--NO SEQUENCE
	MOVEI	CH,.CHTAB	;TAB OVER
	SKIPE	A,FILOVT	;DO NOTHING IF ZERO
	PUSHJ	P,FOUT		;OUTPUT
	SOJG	A,.-1		;REDO IF NECESSARY
BLKSQ1:	TRNN	F,R.SEQU	;SEE IF /SEQUENCE
	JRST	FILSEX		;NO--PUT IN BLANK SPACES
	MOVEI	CH,.CHTAB	;TAB OVER THE SEQUENCE
	PUSHJ	P,FOUT		; NUMBERS
	MOVEI	CH," "		;GET A SPACE
	PUSHJ	P,FOUT		;OUTPUT IT (SEQ IS 9 CHARS LONG)

FILSEW:	MOVEI	S1,FLSKIP	;GET HEADER LINE PREFIX (/DRAFT)
	PUSHJ	P,FMES		;ISSUE TO OUTPUT
	MOVEI	CH,.CHTAB	;TAB OVER TO
	PUSHJ	P,FOUT		; ACTUAL START
FILSEX:	MOVE	A,FILOVR	;GET NO. OF BLANK SPACES
	PUSHJ	P,NSPAC		;OUTPUT BLANK SPACES
FILSEY:	SKIPE	BARSW		;SEE IF BARS ENABLED
	PUSHJ	P,OUTBAR	;YES--DO SPECIAL OUTPUT
	SETZM	CPOS		;CLEAR HORIZONTAL POSITION
	POPJ	P,		;AND RETURN

;ROUTINE TO OUTPUT BAR OR EQUIVALENT SPACES

OUTBAR:	MOVEI	A,BARWID	;PRESET FOR 2 BLANKS
	SKIPN	BARON		;SEE IF ENDED WITH BAR
	SKIPE	BARNPY		; OR HAD ONE IN LINE
	SKIPA			;YES--WILL NEED BAR
	PJRST	NSPAC		;NO--ISSUE SPACES INSTEAD
	SKIPG	CH,SCNBAR	;GET BAR CHARACTER
	MOVEI	CH,AD.BAR	;NONE--USE DEFAULT
	PUSHJ	P,FOUT		;OUTPUT IT
	MOVEI	A,BARWID-1	;AND ONE SPACE
	PJRST	NSPAC		; TO OFFSET IT

;ROUTINE TO UPDATE THIS OUTPUT LINE'S INITIAL INPUT LINE COUNTS

LINUPC:	SKIPN	A,INSEQN	;GET CURRENT INPUT SEQUENCE
	MOVE	A,INSEQL	;OR PREVIOUS
	MOVEM	A,THISEQ	;STORE
	MOVE	A,INLINE	;GET CURRENT INPUT LINE COUNT
	MOVEM	A,THISLN	;STORE
	MOVE	A,INPAGE	;GET CURRENT INPUT PAGE COUNT
	MOVEM	A,THISPG	;STORE
	POPJ	P,		;RETURN
;TYPESETTING OUTPUT ROUTINES

;OUTTYP OUTPUTS CHARACTER FOR TYPESETTING PACKAGE TRANSLATING
;ASCII TO JH CHARACTER SET
;OUTTYQ DITTO EXCEPT SPACE PASSES THROUGH UNTOUCHED
;CALL:	CH/ASCII CHARACTER
;	PUSHJ P,OUTTYP/OUTTYQ
;	RETURNS +1 WITH ALL AC'S INTACT
;
;LEAVES ALL CHARACTERS INTACT EXCEPT:
;	(TYPET)-(TYPETX-1) PRECEEDED BY +
;	(TYPETX) CHANGED TO +A
;	(TYPETX+1)-(LTYPET) CHANGED TO MACROS
;	UNEXPANDABLE SPACE CHANGED TO /N
;	(OUTTYP ONLY) SPACE CHANGED TO /N
;	TAB CHANGED TO /U

OUTTYP:	SAVE$	CH		;SAVE CHARACTER
	ANDI	CH,CHRMSK	;REMOVE POSSIBLE QUOTE
	CAIE	CH,C.SPC	;SEE IF SPACE
	SKIPA	CH,(P)		;NO--RESTORE ORIGINAL CHARACTER
	MOVEI	CH,C.NXS	;YES--CHANGE TO NON-EXPANDABLE ONE
	JRST	OUTTY1		;ENTER REGULAR ROUTINE
				CONT.
OUTTYQ:	SAVE$	CH		;SAVE CHARACTER
OUTTY1:	SAVE$	S1		;SAVE S1
	HRRZ	S1,AFTRNC	;GET DEFERRED STRING
	JUMPN	S1,[SAVE$ CH	;SET--SAVE CH
		    SETZM AFTRNC ;CLEAR MEMORY
		    PUSHJ P,FMES ;ISSUE IT
		    RSTR$ CH	;RESTORE CH
		    JRST  .+1]	;PROCEED
	CAIE	CH,C.QTS	;SEE IF QUOTED SPACE
	CAIN	CH,C.NXS	;SEE IF NON-EXPANDABLE SPACE
	JRST	[MOVEI S1,[ASCIZ \/N\] ;YES--SPECIAL OUTPUT
		 PUSHJ P,FMES	;ISSUE FOR TYPESETTING
		 JRST  OUTTYY]	;AND FINISH UP
	ANDI	CH,CHRMSK	;REMOVE POSSIBLE QUOTE
	CAIGE	CH,C.GRPH	;SEE IF GRAPHIC
	CAIN	CH,.CHTAB	; OR TAB
	CAIN	CH,.CHDEL	; BUT NOT DELETE
	JRST	[SAVE$ CH	;NO--SAVE CHARACTER
		 MOVEI S1,[ASCIZ \[*CONTRL]\]
		 PUSHJ P,FMES	;INDICATE CONTROL CHARACTER
		 RSTR$ CH	;RECOVER CHARACTER
		 TRC  CH,CCUCAS ;CONVERT TO UPPER CASE (DELETE TO ?)
		 PUSHJ P,OUTTYQ	;ISSUE IT THAT WAY
		 MOVEI CH,"@"	;INDICATE END OF ARGUMENT
		 JRST  OUTTY9]	;AND FINISH UP
	MOVSI	S1,-LTYPET	;LOOK IN TABLE OF SPECIALS
	CAME	CH,TYPET(S1)	;SEE IF MATCH
	AOBJN	S1,.-1		;NO--LOOP ON
	JUMPGE	S1,OUTTY9	;OK IF NOT FOUND

	MOVE	S1,TYPETM(S1)	;MACRO--GET TEXT
	PUSHJ	P,FMES		;ISSUE MACRO CALL
	JRST	OUTTYX		;GO FINISH UP

OUTTY9:	PUSHJ	P,FOUT		;ISSUE CHARACTER
	CAIE	CH,C.SPC	;UNLESS SPACE,
OUTTYX:	HLRZS	AFTRNC		;PROMOTE DEFERRED TEXT
OUTTYY:	RSTR$	S1		;RESTORE S1
	RSTR$	CH		;RESTORE ORIGINAL CHARACTER
	POPJ	P,		;RETURN
				CONT.
;TABLE OF SPECIAL ASCII CHARACTERS WHICH DO NOT REPRESENT THEMSELVES

TYPET:	"["		;THESE ARE PI CASE THEMSELVES
	"]"
	"/"
	"+"
	"@"		;PI CASE A
	.CHTAB		;TABULATE
	"\"		;THESE NEED MACROS
	"<"
	">"
	"^"
	"_"
	"@"+ULCAS
	"["+ULCAS
	"]"+ULCAS
	"\"+ULCAS
	"^"+ULCAS
LTYPET==.-TYPET

;TABLE OF MACROS TO MATCH

TYPETM:	[ASCIZ \+[\]
	[ASCIZ \+]\]
	[ASCIZ \+/\]
	[ASCIZ \++\]
	[ASCIZ \+A\]
	[ASCIZ \/U\]	;TABULATE
	[ASCIZ \[*BKSLSH]\]
	[ASCIZ \[*LFTANG]\]
	[ASCIZ \[*RHTANG]\]
	[ASCIZ \[*CRCFLX]\]
	[ASCIZ \[*UNDRLN]\]
	[ASCIZ \[*ACUTE]\]
	[ASCIZ \[*LFTBRC]\]
	[ASCIZ \[*RHTBRC]\]
	[ASCIZ \[*VRTBAR]\]
	[ASCIZ \[*TILDE]\]
;ROUTINE TO TELL TYPESET OF THE CURRENT JUSTIFICATION RULES

JUSTYP:	SKIPG	SCNTYP		;SEE IF TYPESET
	POPJ	P,		;NO--DO NOTHING
	MOVEI	S1,[ASCIZ \[R%]\]
	TLNN	F,L.JUST	;IF NOT JUSTIFYING,
	MOVEI	S1,[ASCIZ \[RR]\]
	PJRST	FMES		;ISSUE STRING AND RETURN
;INPTYP SENDS REST OF INPUT COMMAND FOR TYPESETTING AS IS
;PERIOD AND EXCLAMATION ARE VALID TEXT.
;CALL:	PUSHJ	P,INPTYP
;USES ALL AC'S

INPTYP:	PUSHJ	P,GCIN		;GET NEXT CHARACTER
	PUSHJ	P,CMSOMP	;SEE IF END			[165]
	  JRST	[MOVEM CH,GCSCH	;YES--SAVE FOR RESCAN
		 MOVEI S1,CRLFM	;ISSUE NEW LINE FOR
		 PJRST FMES]	; NEATNESS, AND RETURN
	CAIN	CH,.CHTAB	;SEE IF TAB
	MOVEI	CH,C.SPC	;YES--CHANGE TO SPACE
	PUSHJ	P,CCOUT		;ISSUE TO OUTPUT
	JRST	INPTYP		;LOOP ONWARDS

;ATTYP ISSUES A TYPESETTING MACRO ARGUMENT BREAK
;CALL:	PUSHJ	P,ATTYP
;PRESERVES ALL AC'S

ATTYP:	SKIPG	SCNTYP		;SEE IF TYPESETTING
	POPJ	P,		;NO--RETURN
	SAVE$	CH		;SAVE ACCUMULATOR
	MOVEI	CH,"@"		;GET SEPARATOR
	PUSHJ	P,FOUT		;ISSUE IT
	RSTR$	CH		;RESTORE ACCUMULATOR
	POPJ	P,		;RETURN

;STSTYP ISSUES CURRENT TAB STOP SETTINGS FOR TYPESETTING
;CALL:	PUSHJ	P,STSTYP
;SAVES ALL AC'S

STSTYP:	SKIPG	SCNTYP		;SEE IF TYPESETTING
	POPJ	P,		;NO--RETURN
	SAVE$	<CH,S1,N,N1,D>	;SAVE ACCUMULATORS
	MOVEI	S1,[ASCIZ \[T%]\]
	PUSHJ	P,FMES		;CLEAR OLD SETTINGS
	MOVN	D,NTABS		;GET -NUMBER OF TAB STOPS
	JUMPGE	D,STSTYX	;EXIT IF NONE
	HRLZS	D		;MAKE INTO COUNTER
	MOVEI	S1,[ASCIZ \[TS\]
	PUSHJ	P,FMES		;PREPARE TO SET NEW SETTINGS
STSTYL:	MOVEI	CH,","		;GET SEPARATOR
	TRNE	D,-1		;SEE IF FIRST
	PUSHJ	P,FOUT		;NO--ISSUE
	MOVE	N,TABTAB(D)	;GET THIS STOP
	PUSHJ	P,TYPDSP	;ISSUE IN CORRECT UNITS
	AOBJN	D,STSTYL	;LOOP UNTIL DONE
	MOVEI	S1,[ASCIZ \]
\]
	PUSHJ	P,FMES		; COMMAND
STSTYX:	RSTR$	<D,N1,N,S1,CH>	;RESTORE ACCUMULATORS
	POPJ	P,		;RETURN
;LRMTYP ROUTINE TO ISSUE MARGINS FOR TYPESETTING
;CALL:	PUSHJ P,LRMTYP
;	RETURNS +1 WITH AC'S PRESERVED
;IF TYPESETTING, ISSUES LEFT AND RIGHT MARGINS

LRMTYP:	SKIPG	SCNTYP		;SEE IF TYPESETTING
	POPJ	P,		;NO--JUST RETURN
	SAVE$	<S1,CH,N,N1>	;SAVE SOME AC'S
	MOVEI	S1,[ASCIZ \[IL\]
	PUSHJ	P,FMES		;ISSUE LEFT
	MOVE	N,LMARG		; MARGIN
	PUSHJ	P,TYPDSP	; IN PICAS
	MOVEI	S1,[ASCIZ \][C\]
	PUSHJ	P,FMES		;ISSUE RIGHT
	MOVE	N,RMARG		; MARGIN
	PUSHJ	P,TYPDSP	; IN PICAS
	MOVEI	CH,"]"		;CLOSE CALLS
	PUSHJ	P,FOUT		; FOR TYPESETTING
	MOVE	N,PRMRG		;GET PERMANENT RIGHT EDGE
	MOVE	N1,TYPMUL	;GET MULTIPLIER
	CAIE	N1,1		;UNLESS 1:1,
	MOVEM	N,TYPDIV	; STORE RM AS SPACING DIVISOR
	RSTR$	<N1,N,CH,S1>	;RESTORE AC'S
	POPJ	P,		;RETURN

;TYPDSP ISSUES A NUMBER CONVERTED FOR TYPESETTING HORIZONTAL SPACING
;CALL:	N/WIDTH IN PRINTER SPACES
;	PUSHJ	P,TYPDSP
;
;TYPHSP ISSUES TYPESETTING HORIZONTAL SPACING
;CALL:	N/WIDTH IN POINTS
;	PUSHJ	P,TYPHSP
;
;	BOTH RETURN +1 AFTER TYPING A.B
;USES N, N1, CH

TYPDSP:	IMUL	N,TYPMUL	;MULTIPLY BY CONVERSION NUMERATOR
	IMULI	N,^D12		;CONVERT TO POINTS FROM PICAS
	IDIV	N,TYPDIV	;DIVIDE BY CONVERSION DIVISOR
	SKIPE	N1		;SEE IF EXCESS
	AOS	N		;YES--ROUND UP (N/POINTS)
TYPHSP:	IDIVI	N,^D12		;CONVERT TO PICAS WITH REMAINDER
	SKIPN	N1		;SEE IF REMAINDER
	PJRST	DECPRT		;NO--ISSUE DECIMAL PICAS
	SAVE$	N1		;YES--SAVE REMAINDER POINTS
	PUSHJ	P,DECPRT	;ISSUE DECIMAL PICAS
	MOVEI	CH,"."		;ISSUE SEPARATOR
	PUSHJ	P,CCOUT		;ISSUE
	RSTR$	N		;RESTORE REMAINDER POINTS
	MOVMS	N		;GET ABSOLUTE VALUE
	PJRST	DECPRT		;ISSUE IN DECIMAL
;I/O SUBRS

FMES:	SKIPN	AFTRNC		;SEE IF DEFERRED OUTPUT
	JRST	FMES1		;NO--CONTINUE
	SAVE$	S1		;YES--SAVE STRING
	MOVE	S1,AFTRNC	;GET DEFFERED STUFF
	SETZM	AFTRNC		;CLEAR MEMORY
	TRNN	S1,-1		;SEE IF SET UP
	MOVSS	S1		;NO--SWITCH
	PUSHJ	P,FMES1		;ISSUE IT
	RSTR$	S1		;RESTORE STRING
FMES1:	HRLI	S1,(POINT 7,)	;MAKE BYTE POINTER
FMESL:	ILDB	CH,S1
	JUMPE	CH,CPOPJ	;RETURN ON NULL
	PUSHJ	P,FOUT		;OUTPUT CHARACTER
	JRST	FMESL		;LOOP

;FOUTTT IS ROUTINE TO OUTPUT CHARACTER FROM A (T1)
;CALL:	A/CHARACTER
;	PUSHJ	P,FOUTTT
;	RETURN +1 WITH ALL AC'S PRESERVED

FOUTTT:	EXCH	CH,A		;MOVE TO RUNOFF AC
	PUSHJ	P,FOUT		;ISSUE TO FILE
	EXCH	CH,A		;RESTORE TO ORIGINAL
	POPJ	P,		;RETURN
;FOUT IS ROUTINE TO OUTPUT CHARACTER FROM CH
;CALL:	CH/CHARACTER
;	PUSHJ	P,FOUT
;	RETURN +1 WITH ALL AC'S PRESERVED

FOUTCS:	CAIE	CH,C.QTS	;SEE IF QUOTED SPACE
	CAIN	CH,C.NXS	; OR NON-EXPANDABLE SPACE
	MOVEI	CH,C.SPC	;YES--CHANGE TO REAL SPACE
FOUT:	TLNE	F,L.SUPO	;SEE IF SUPPRESSING OUTPUT
	POPJ	P,		; YES--DON'T OUTPUT
IF TOPS-10,<
	SOSLE	H.FOUT+.BFCTR	;ROOM IN BUFFER?
	JRST	FOUTOK		;YES.
	OUT	F.FOUT,		;NO. SEND BUFFER
	  JRST	.+2
	JRST	E$$ODE		;YES.
FOUTOK:	IDPB	CH,H.FOUT+.BFPTR  ;PUT CHAR IN BUFFER
> ;END TOPS-10
IF TOPS-20,<
	SKIPN	PMAPF		;ANYTHING PMAPED
	JRST	DOBOUT		;NO--JUST DO A BOUT
	SOSG	WINCNT		;ROOM IN WINDOW?
	PUSHJ	P,MAPWIN	;NO--PMAP NEXT HUNK
	AOS	BYTECT		;YES--COUNT BYTE
	IDPB	CH,BYTEPT	;STORE BYTE
	JRST	NOBOUT		;SKIP BOUT
DOBOUT:	SAVE$	<A,B>		;SAVE A AND B
	HRRZ	A,OPNOUT	;GET OUTPUT JFN
	HRRZ	B,CH		;GET BYTE
	BOUT			;WRITE IT
	  ERJMP	E$$ODE		;ERROR
	RSTR$	<B,A>		;RESTORE A AND B
NOBOUT:
> ;END TOPS-20
	PUSH	P,CH		;SAVE CH
	CAIN	CH,.CHLFD	;LINEFEED?
	JRST	FOUT1		;YES. GO COUNT IT
	CAIN	CH,.CHFFD	;FORMFEED?
	JRST	FOUT2		;YES. GO COUNT IT.
	POP	P,CH		;RESTORE CH
	POPJ	P,		;AND RETURN

FOUT1:	AOS	CH,LINECT	;COUNT THE LINES
	CAIGE	CH,LPTLEN	;FILL THE LPT?
	JRST	FOUTXX		;NO
FOUT2:	SETZM	LINECT		;TOP OF PAGE. NO LINES.
	AOS	PAGECT		;COUNT PAGES.
FOUTXX:	POP	P,CH		;RETRIEVE CHARACTER
	AOS	DIDSOM		;INDICATE SOMETHING OUTPUT
	POPJ	P,

	MSG$	ODE,ERR,,Output error
	PUSHJ	P,.TSPAC##
IF TOPS-10,<
	GETSTS	F.FOUT,A	;GET BAD STATUS
	PUSHJ	P,.TOCTW##	;TYPE IN OCTAL
> ;END TOPS-10
	JRST	SETER2		;GO RELEASE CHANNELS AND START OVER
IF TOPS-20,<
MAPWIN:	SAVE$	<A,B,C,D>	;SAVE JSYS AC'S
	MOVE	A,PMAPF		;GET SIZE OF WINDOW
	IMULI	A,^D5*^D512	;BYTE COUNT
	MOVEM	A,WINCNT	;STORE 
	MOVE	A,PMAPPG	;GET PAGE NUMBER
	LSH	A,9		;CONVERT TO ADDRESS
	HRLI	A,(POINT 7,0)	;MAKE INTO BYTE POINTER
	MOVEM	A,BYTEPT	;SAVE POINTER
	HRLZ	A,OPNOUT	;GET OUTPUT JFN
	HRR	A,FILEPG	;FILE PAGE
	HRLI	B,.FHSLF	;THIS PROCESS
	HRR	B,PMAPPG	;PAGE NUMBER
	MOVE	C,PMAPF		;NUMBER OF PAGES
	TXO	C,PM%CNT!PM%WT	;WRITE ACCESS
	PMAP			;MAP THE FILE
	MOVE	A,PMAPF		;UPDATE FILE PAGE NUMBER
	ADDM	A,FILEPG	; FOR NEXT HUNK
	RSTR$	<D,C,B,A>
	POPJ	P,0		;RETURN
> ;END TOPS-20
;+
;<SETRNG IS A ROUTINE TO SET OR UPDATE <L.SUPO, THE FLAG
;WHICH SUPPRESSES OUTPUT BECAUSE OF THE </IRANGE AND </ORANGE
;SWITCHES.  ^IT SHOULD BE CALLED EVERY TIME THE OUTPUT
;LINE COUNTER OR PAGE COUNTER IS UPDATED.
;^IF BOTH </IRANGE AND </ORANGE ARE SET, BOTH MUST BE
;SATISFIED TO ALLOW OUTPUT.
;^THIS ROUTINE PRESERVES ALL ACCUMULATORS.
;-

SETRNG:	SKIPN	SCNNOR		;SEE IF /ORANGE
	SKIPE	SCNNIR		; OR /IRANGE
	SKIPA			;YES--DO ALGORITHM
	POPJ	P,		;NO--RETURN QUICKLY
	SAVE$	<A,B,C>		;SAVE SOME AC'S
	SKIPN	A,SCNNOR	;SEE IF /ORANGE
	JRST	SETIRG		;NO--GO CHECK /IRANGE
	IMULI	A,3		;TRIPLE
	SUBI	A,3		;OFFSET (0,3,...)
SETORL:	HRRZ	B,SCNORG(A)	;GET START PAGE
	CAMG	B,PAGENO	;COMPARE TO OUTPUT PAGE
	JRST	[HLRZ  B,SCNORG+2(A) ;OK--GET START CHAPTER
		 CAMLE B,SECNUM	;COMPARE TO OUTPUT CHAPTER
		 JRST  .+1	;FAIL--TRY NEXT SET
		 HLRZ  B,SCNORG(A) ;OK--GET START LINE
		 CAMLE B,LINEC	;COMPARE TO OUTPUT LINE
		 JRST  .+1	;FAIL--TRY NEXT SET
		 HRRZ  B,SCNORG+1(A) ;OK--GET END PAGE
		 CAMGE B,PAGENO	;COMPARE TO OUTPUT PAGE
		 JRST  .+1	;FAIL--TRY NEXT SET
		 HRRZ  B,SCNORG+2(A) ;OK--GET END CHAPTER
		 CAMGE B,SECNUM	;COMPARE TO OUTPUT CHAPTER
		 JRST  .+1	;FAIL--TRY NEXT SET
		 HLRZ  B,SCNORG+1(A) ;OK--GET END LINE
		 CAMGE B,LINEC	;COMPARE TO OUTPUT LINE
		 JRST  .+1	;FAIL--TRY NEXT SET
		 JRST  SETIRG]	;MATCH--PASS TO /IRANGE TESTS
	SUBI	A,2		;FAILED--BACK DOWN INDEX
	SOJGE	A,SETORL	;LOOP UNTIL ALL /ORANGES TRIED
	JRST	SETRGN		;NONE IN RANGE, SO SUPPRESS OUTPUT
				CONT.
;HERE TO CHECK /IRANGE

SETIRG:	SKIPN	SCNNIR		;SEE IF /IRANGE
	JRST	SETRGK		;NO--OK TO OUTPUT
	MOVEI	C,0		;PRESET INPUT LINE NUMBER
	SKIPN	B,INSEQN	;GET SEQUENCE CODE
	MOVE	B,INSEQL	; USE OLD ONE IF BLANK
SETIRC:	MOVEI	A,0		;CLEAR AC
	LSHC	A,7		;GET NEXT CHARACTER
	SUBI	A,"0"		;REMOVE OFFSET
	SKIPL	A		;IF NEGATIVE,
	CAILE	A,^D9		; OR TOO BIG,
	TDZA	A,A		; MUST BE JUNK
	IMULI	C,^D10		;ADVANCE RESULT
	ADDI	C,(A)		;INCLUDE NEW VALUE
	JUMPN	B,SETIRC	;LOOP UNTIL ALL DONE
	MOVE	A,INLINE	;GET PHYSICAL COUNT-1
	SKIPN	C		;UNLESS SOMETHING HERE,
	MOVEI	C,1(A)		; GET PHYSICAL COUNT
	MOVE	A,SCNNIR	;GET COUNT OF /IRANGES
	IMULI	A,3		;TRIPLE
	SUBI	A,3		;OFFSET (0,3,...)
SETIRL:	HRRZ	B,SCNIRG(A)	;GET START PAGE
	SOS	B		;(INPAGE IS ONE LOW)
	CAMG	B,INPAGE	;COMPARE TO INPUT PAGE
	JRST	[HLRZ  B,SCNIRG(A) ;OK--GET START LINE
		 CAMLE B,C	;COMPARE TO INPUT LINE
		 JRST  .+1	;FAIL--TRY NEXT SET
		 HRRZ  B,SCNIRG+1(A) ;OK--GET END PAGE
		 SOS   B	;(INPAGE IS ONE LOW)
		 CAMGE B,INPAGE	;COMPARE TO INPUT PAGE
		 JRST  .+1	;FAIL--TRY NEXT SET
		 HLRZ  B,SCNIRG+1(A) ;OK--GET END LINE
		 CAMGE B,C	;COMPARE TO INPUT LINE
		 JRST  .+1	;FAIL--TRY NEXT SET
		 JRST  SETRGK]	;MATCH--OK TO OUTPUT
	SUBI	A,2		;FAILED--BACK DOWN INDEX
	SOJGE	A,SETIRL	;LOOP UNTIL ALL /IRANGES TRIED

SETRGN:	TLOA	F,L.SUPO	;NO MATCHES--SUPPRESS OUTPUT
SETRGK:	TLZ	F,L.SUPO	;OK--ALLOW OUTPUT
	RSTR$	<C,B,A>		;RESTORE AC'S
	POPJ	P,		;RETURN
;ROUTINE TO GRAB ANOTHER K OF CORE.

EXPAND:
IF TOPS-10,<
	SAVE$	<A,B>		;SAVE AN AC
	HRRO	B,.JBREL	;GET CURRENT CORE
	MOVEI	A,1(B)		;ANOTHER K
	CORE	A,
	 JRST 	E$$NEC		;CAN'T GET IT.
	HRRZ	A,.JBREL	;GET NEW CORE SIZE
	SUBI	A,(B)		;GET GROWTH DISTANCE
	ADDM	A,FOOTBF	;ADVANCE STARTING ADDRESS
	IMULI	A,5		;ADD TO THESE CHARACTER POINTERS
	ADDM	A,FOOTP1
	ADDM	A,FOOTP2
	ADDM	A,FOOTP3
	ADDM	A,FOOTP4
	HRRZ	A,.JBREL	;GET NEW END OF REGION
EXPL:	POP	B,(A)		;REVERSE
	CAML	A,FOOTBF	; BLT
	SOJA	A,EXPL		; ENTIRE BUFFER
	SKIPGE	TTISOT		;SEE IF TTY OUTPUT
	JRST	EXPNDX		;YES--SUPPRESS INFO MESSAGE
	SAVE$	<C,D>
	MSG$	KCI,INF,,
	HRRZ	A,.JBREL	;HOW BIG NOW?
	ADDI	A,1		;ROUND UP (ALLOW FOR 0 COUNT)
	PUSHJ	P,.TCORW##	;TYPE NUMBER OF K
	MOVEI	A,[ASCIZ / core-index]
/]
	PUSHJ	P,.TSTRG	;AND TEXT
	RSTR$	<D,C>
EXPNDX:	RSTR$	<B,A>		; ..
	POPJ	P,		;AND RETURN

	MSG$	NEC,ERR,,Not enough core
	PUSHJ	P,.TSPAC##
	HRRZ	A,.JBREL
	ADDI	A,1		;ROUND UP (ALLOW FOR 0 COUNT)
	PUSHJ	P,.TCORW##	;ISSUE IN K OR PAGES
	JRST	SETER2
> ;END TOPS-10
IF TOPS-20,<
	MSG$	NEC,ERR,,ADDRESS SPACE FULL
>
	SUBTTL	INPUT CHARACTER PROCESSORS

;+.CHAPTER INPUT CHARACTER PROCESSING
;-

;GET INPUT CHARACTER FROM SOURCE FILE HANDLING ESCAPE CHARACTERS
;RETURNS CH=1B17+CHAR (GE 40) IF QUOTED
;	    TAB, LF, OR CHAR .GE. 40
;	    37 IF #, 32 IF UNDERLINE FOLLOWED BY CHAR (EXC. 37,40)
;	    LF THEN -1 IF EOF
;USES A, CH

GCIN:	TRZ	F,R.FRCC	;CLEAR CASE FORCING INDICATOR
	TLNE	F,L.GCIN	;STILL READING FROM BUFFER?
	JRST	GCIN1		;YES. GO RE-READ CHARACTER
GCIN3:	SKIPL	GCSCH		;NO. SAVED A CHARACTER?
	JRST	GCIN5		;YES. GO GET IT.
	SKIPL	ULMCH		;SAVING CHARACTER DUE TO UNDERLINE?
	JRST	ULMC1		;YES. GO GET IT.
GCIN5:	PUSHJ	P,CCIN		;NO. GET CHARACTER FROM FILE.
	TRNE	F,R.NFLA	;SEE IF .NOFLAGS
	JRST	GCINL		;YES--SKIP SPECIAL TESTS
	CAMN	CH,CC.QUO	;QUOTING A CHARACTER?
	JRST	CWR1		;YES. GO GET REAL CHARACTER
	CAMN	CH,CC.UPP	;UPSHIFT CHARACTER?
	JRST	SHUP1		;YES. SEE IF SHIFT-LOCK
	CAMN	CH,CC.LOW	;DOWNSHIFT CHARACTER?
	JRST	SHDN1		;YES. SEE IF SHIFT-UNLOCK
	CAMN	CH,CC.UND	;UNDERLINE REQUEST?
	JRST	ULCH		;YES. GO PROCESS
	CAMN	CH,CC.SPA	;QUOTED SPACE?
	JRST	QTSP1		;YES.
GCINL:	CAIG	CH,"Z"		;UPPER CASE LETTER?
	CAIGE	CH,"A"		;..
	JRST	GCINR		;NO.
	ADD	CH,CAS		;YES. ADD ON CURRENT CASE
GCINR:	CAIL	CH,LCHPVT	;SEE IF CONTROL
	CAIL	CH,LCHPVT!C.GRPH ; CHARACTER AS TEXT
	SKIPA			;NO--MUST BE GRAPHIC
	AOS	NSPCH		;YES--COUNT IT AS NON-SPACING
	PUSHJ	P,LINDCP	;GO HANDLE INDEXING AND CAPS
	  JRST	GCIN		;FLAG CHARACTER--START OVER
	TLNE	F,L.ULMS	;UNDERLINE SHIFT-LOCK ON?
	JRST	ULMC2		;YES. GO HANDLE
	POPJ	P,		;NO. HAVE CHARACTER NOW.
				CONT.
;SPECIAL CASES OF INPUT CHARACTER.

QTSP1:	MOVEI	CH,C.QTS	;QUOTED SPACE (NO UNDERLINING)
	JRST	GCINR		;RETURN WITHOUT UNDERLINE

ULCH:	AOS	NSPCH		;COUNT NON-SPACING INPUT
	MOVEI	CH,C.ULS	;CONVERT TO STORAGE UNDERLINE
	POPJ	P,		;AND RETURN

GCIN1:	PUSHJ	P,GGCINP	;GET CHARFROM INPUT BUFFER
	  TLZA	F,L.GCIN	;NONE LEFT.
	POPJ	P,		;RETURN IT.
	JRST	GCIN3		;GO READ FROM FILE, ETC.

;MORE SPECIAL CASES OF GET-CHARACTER ROUTINE

CWR1:	TRO	F,R.QNIC	;QUOTE NEXT INPUT
	PUSHJ	P,CCIN		;READ CHARACTER, NO TRANSLATION
	TRZ	F,R.QNIC	;CLEAR QUOTING
	IFEOF$	GCINR		;IF EOF, ALL DONE
	CAIN	CH,.CHLFD	;SEE IF LINE FEED
	JRST	GCINR		;YES--RETURN
	TXO	CH,LCHPVT	;FLAG TO NOT RECOGNIZE
	JRST	GCINR		;AND RETURN IT, MAYBE UNDERLINED
				CONT.
SHUP1:	PUSHJ	P,CCIN		;READ A CHARACTER
	CAMN	CH,CC.UND	;UNDERLINE? LOCK ON UNDERLINE?
	JRST	ULMON		;YES.
	CAMN	CH,CC.QUO	;SEE IF QUOTE
	JRST	CWR1		;YES--GO DO IT
	CAMN	CH,CC.LOW	;SEE IF LOWER CASE
	JRST	SHDN1		;YES--GO DO THAT
	CAMN	CH,CC.SPA	;SEE IF FIXED SPACE
	JRST	QTSP1		;YES--DON'T CAPITALIZE IT
	TRO	F,R.FRCC	;INDICATE FORCED CASE
	CAMN	CH,CC.UPP	;DOUBLE UPSHIFT?
	JRST	SHUP2		;YES--GO SET LOCK
	CAIG	CH,"Z"+ULCAS	;SEE IF LOWER CASE
	CAIGE	CH,"A"+ULCAS	; CHARACTER
	SKIPA			;NO--IGNORE REQUEST
	SUBI	CH,ULCAS	;YES--FORCE TO UPPER CASE
	JRST	GCINR		;RETURN WITH RESULT
SHUP2:	SETZM	CAS		;DOUBLE UPSHIFT. CLEAR CASE OFFSET
	JRST	GCIN3		;AND GO READ ANOTHER CHARACTER.

SHDN1:	PUSHJ	P,CCIN		;GET ANOTHER CHARACTER
	CAMN	CH,CC.UND	;UNLOCK UNDERLINE?
	JRST	ULMOF		;YES. GO DO SO.
	CAMN	CH,CC.QUO	;SEE IF QUOTE
	JRST	CWR1		;YES--GO DO IT
	CAMN	CH,CC.UPP	;SEE IF UPPER CASE
	JRST	SHUP1		;YES--GO DO THAT
	CAMN	CH,CC.SPA	;SEE IF FIXED SPACE
	JRST	QTSP1		;YES--DON'T LOWER CASE IT
	TRO	F,R.FRCC	;INDICATE FORCED CASE
	CAMN	CH,CC.LOW	;SECOND DOWNSHIFT?
	JRST	SHDN2		;YES.
	CAIG	CH,"Z"		;IN RANGE FOR LOWERING?
	CAIGE	CH,"A"		; ..
	SKIPA			;NO.
	ADDI	CH,ULCAS	;YES. MAKE IT LOWER CASE
	JRST	GCINR		;RETURN THIS, UNDERLINED IF NEEDED.
SHDN2:	MOVEI	A,ULCAS		;SET CASE OFFSET TO LC FOR LETTERS
	MOVEM	A,CAS		; ..
	JRST	GCIN3		;AND GO READ ANOTHER CHARACTER
				CONT.
ULMON:	TLOA	F,L.ULMS	;UNDERLINE LOCKED ON
ULMOF:	TLZ	F,L.ULMS	;UNDERLINE LOCKED OFF
	JRST	GCIN3		;GO READ ANOTHER CHARACTER

ULMC2:		;HERE WHEN RETURNING A CHAR, BUT UNDERLINE LOCKED ON.
	IFEOF$	CPOPJ		;IF EOF, RETURN
	CAIG	CH,C.GRPH	;SEE IF FLAG OR SPACE
	POPJ	P,		;YES--RETURN
	CAIL	CH,LCHPVT	;SEE IF QUOTED
	CAIL	CH,LCHPVT!C.GRPH ; CONTROL CHARACTER AND NOT SPACE	[174]
	SKIPA			;NO--NEED TO UNDERLINE
	POPJ	P,		;YES--DON'T UNDERLINE IT
	MOVEM	CH,ULMCH	;THIS MAY BE UNDERLINED. SAVE IT FOR LATER
	JRST	ULCH		;AND PUT OUT UNDERLINE (BUFFER OR FILE)

ULMC1:	MOVE	CH,ULMCH	;RESTORE SAVED CHARACTER
	SETOM	ULMCH		;NEGATIVE TO INDICATE NOT THERE.
	POPJ	P,		;RETURN WITH THIS SAVED CHARACTER
;ROUTINE TO HANDLE INDEXING AND CAPITALIZING OF TEXT WORDS

;+
;^THE ROUTINE "<LINDCP" SCANS THE INCOMING TEXT FOR WORDS
;PRECEEDED BY THE CAPITALIZE AND INDEX FLAG CHARACTERS.  ^IF
;IT FINDS SUCH A FLAG, IT SETS A FLAG IN ^F AND THEN
;CAPITALIZES AND/OR INDEXES THE FOLLOWING WORD AS THE
;USER REQUESTED.  ^FOR THIS PURPOSE, A WORD IS DEFINED AS
;A STRING OF CONSECUTIVE CHARACTERS EXCLUDING ANY
;SPACES OR END OF LINE.
;-

LINDCL:	SETOM	AUTIDX		;INDICATE AUTO INDEX
	STORE	A,ICBUF,ICBFE,0	;START OF WORD--CLEAR INDEX
	MOVNI	A,LN$IDX*5-1	;PRESET COUNT
	MOVEM	A,ICBUFC	; ..
	MOVE	A,[POINT 7,ICBUF]
	MOVEM	A,ICBUFP	;PRESET POINTER
	POPJ	P,		;RETURN TO GET A REAL CHARACTER

LINDCP:	CAIN	CH,.CHLFD	;SEE IF NEW LINE
	PUSHJ	P,LINDFN	;YES--FORCE NORMAL CASE RULES
	TRNE	F,R.NFLA	;SEE IF .NO FLAGS
	PJRST	@LINDCX		;RIGHT--NO SPECIALS
	CAMN	CH,CC.IND	;SEE IF INDEX FLAG
	JRST	[TLCE F,L.INDX	;YES--SET FLAG
		 POPJ P,	; IF ALREADY ON, RETURN
		 JRST LINDCL]	;AND GO INITIALIZE INDEX
	CAMN	CH,CC.CAP	;SEE IF CAPS FLAG
	JRST	[TLC  F,L.CAPS	;YES--SET FLAG
		 POPJ P,]	;AND RETURN
	TLNN	F,L.INDX!L.CAPS	;SEE IF ANY FLAGS SET
	SKIPE	AUTIDX		; OR WAS INDEXING
	SKIPA			;YES--PROCEED
	PJRST	@LINDCX		;NO--RETURN TO CALLER

	PUSHJ	P,LINDCS	;SEE IF SPACE OR END OF WORD
	  JRST	LINDCW		;NO--GO HANDLE CONTENTS OF WORD
LINDCE:
	TLZ	F,L.CAPS!L.INDX	;END OF WORD--CLEAR FLAGS
	SKIPN	AUTIDX		;SEE IF AUTO INDEX
	PJRST	@LINDCX		;NO--JUST RETURN
	SETZM	AUTIDX		;YES--CLEAR FLAG
	SKIPN	ICBUF		;SEE IF SOMETHING ACCUMULATED
	PJRST	@LINDCX		;NO--RETURN
				CONT.
;HERE AT END OF WORD IF IT WAS INDEXED

	SAVE$	S1		;SAVE STRING POINTER
	MOVE	S1,ICBUFP	;GET POINTER
	PUSHJ	P,DOINDX	;GO DO THE INDEXING
	RSTR$	S1		;RESTORE POINTER
	PJRST	@LINDCX		;RETURN

;HERE WITH CHARACTER IN A WORD

LINDCW:	PUSHJ	P,@LINDCX	;GO HANDLE FORCED CASE IF ANY
	  JFCL			;IGNORE NON-SKIP
	TLNE	F,L.CAPS	;SEE IF CAPITALIZING
	TRNE	F,R.FRCC	; AND USER HAS NOT FORCED IT
	JRST	LINDCI		;WRONG--PROCEED
	CAIL	CH,"A"+ULCAS	;YES--SEE IF
	CAILE	CH,"Z"+ULCAS	; LOWER CASE
	SKIPA			;NO--PROCEED
	SUBI	CH,ULCAS	;YES--FORCE UPPER
LINDCI:	TLNN	F,L.INDX	;SEE IF INDEXING
	JRST	CPOPJ1		;RETURN IF NOT
	MOVE	A,CH		;COPY CHARACTER
	TLNN	F,L.CAPS	;SEE IF CAPITALIZING
	TRNE	F,R.FRCC	;OR SEE IF USER FORCED THE CASE
	JRST	LINDCC		;YES--DON'T DEFAULT IT
	SKIPN	ICBUF		;SEE IF FIRST
	JRST	[CAIL	A,"A"+ULCAS  ;SEE IF
		 CAILE	A,"Z"+ULCAS  ; LOWER CASE
		 JRST	LINDCC	;NO--PROCEED
		 SUBI	A,ULCAS	;YES--FORCE UPPER
		 JRST	LINDCC]
	CAIL	A,"A"		;LATER WORD
	CAILE	A,"Z"		; --SEE IF UPPER CASE
	SKIPA			;NO--LEAVE ALONE
	ADDI	A,ULCAS		;YES--FORCE LOWER

LINDCC:	AOSL	ICBUFC		;COUNT DOWN BUFFER
	JRST	CPOPJ1		;RETURN IF OVERFLOW
	IDPB	A,ICBUFP	;STORE TEXT
	JRST	CPOPJ1		;RETURN
;+
;^THE ROUTINES <LINDFL, <LINDFO, AND <LINDFN PRESET 
;<LINDCW TO FORCE CAPITALIZATION FOR ALL LETTERS IN THE LINE,
;FOR ONE LETTER PER WORD ON THIS LINE, OR NONE.  ^EACH
;STORES EITHER <CPOPJ1, <LINDCT OR <LINDCU IN THE LOCATION
;<LINDCX. <LINDFO ALSO SETS THE SIGN BIT TO FLAG
;THE NEED TO CHANGE BETWEEN <LINDCT AND <LINDCU AROUND THE
;FIRST CHARACTER OF EACH WORD.  ^THESE CONDITIONS ARE AUTOMATICALLY
;CLEARED AT THE END OF EACH LINE OF INPUT.
;-

LINDFN:	MOVEI	A,CPOPJ1	;SET AS NO-OP
	MOVEM	A,LINDCX
	POPJ	P,

LINDFL:	MOVEI	A,LINDCU	;SET TO FORCE UPPER
	MOVEM	A,LINDCX
	POPJ	P,

LINDFO:	MOVEI	A,LINDCU	;SET TO FORCE UPPER ONCE/WORD
	TLO	A,(1B0)		;INDICATE ONCE/WORD
	MOVEM	A,LINDCX
	POPJ	P,
;+
;<LINDCU WILL FORCE A LOWER CASE INPUT CHARACTER TO
;UPPER CASE UNLESS THE USER CONTROLLED THE CASE ON THIS
;CHARACTER EXPLICITLY.
;-

LINDCU:	TRNE	F,R.FRCC	;SEE IF USER FORCED CASE
	JRST	LINDCV		;YES--GO EXIT
	CAIL	CH,"A"+ULCAS	;NO--SEE IF LOWER CASE
	CAILE	CH,"Z"+ULCAS	; ..
	SKIPA			;NOT LOWER--LEAVE ALONE
	SUBI	CH,ULCAS	;LOWER--FORCE TO UPPER
LINDCV:	MOVEI	A,LINDCT	;PREPARE TO IGNORE REST OF WORD
	SKIPGE	LINDCX		;SEE IF ONCE/WORD MODE
	HRRM	A,LINDCX	;YES--IGNORE REST OF WORD
LINDCT:	PUSHJ	P,LINDCS	;SEE IF SPACE OR END OF WORD
	  JRST	CPOPJ1		;NO--JUST RETURN
	MOVEI	A,LINDCU	;PREPARE TO RESTORE FORCED UPPER
	SKIPGE	LINDCX		;SEE IF CAPITALIZE ONCE/WORD MODE
	HRRM	A,LINDCX	;YES--FORCE NEXT UPPER
	JRST	CPOPJ1		;SKIP RETURN

;+
;<LINDCS CHECKS TO SEE IF THE CURRENT CHARACTER IS THE END OF
;A WORD.  ^IT TESTS AGAINST END OF LINE, AND VARIOUS
;FORMS OF SPACE AND TAB.
;-

LINDCS:	CAIE	CH,C.QTS	;SEE IF QUOTED SPACE
	CAIN	CH,C.SPC	;SEE IF SPACE
	JRST	CPOPJ1		;YES--END OF WORD
	CAIE	CH,.CHTAB	;SEE IF TAB
	CAIN	CH,C.QS		;SEE IF QUOTED SPACE
	JRST	CPOPJ1		;YES--END OF WORD
	CAIE	CH,C.NXS	;SEE IF NON-EXPANDING SPACE
	CAIN	CH,.CHLFD	;SEE IF END OF LINE
	JRST	CPOPJ1		;YES--END OF WORD
	IFEOF$	CPOPJ1		;AT EOF, END OF WORD
	POPJ	P,		;NOT END OF WORD
;ROUTINE TO READ INPUT FROM FILE OR FOOTNOTE AS APPROPRIATE
;RETURNS CH=TAB, LF, OR CHAR .GE. 40
;	    LF THEN -1 IF EOF
;USES A, CH

CCIN:	SKIPL	CH,GCSCH	;ANY CHARACTER SAVED FROM EARLIER PASS?
	JRST	[SETOM	GCSCH	;FLAG NO MORE SAVED CHAR
		 POPJ	P,]	;STORE IN BUFFER AND RETURN
	TLNN	F,L.FOOT	;CHARACTERS COMING FROM FOOTNOTE?
	PJRST	CCINF		;NO. READ FROM FILE

	MOVEI	PA,FOOTP3	;GET CHARACTER FROM FOOTNOTE STRING
	PUSHJ	P,GCI		;GET THE CHARACTER
	  SKIPA			;NONE THERE. THIS IS AN ERROR.
	PJRST	SAVCMN		;STORE IN BUFFER AND RETURN
	MOVEI	CH,.CHLFD	;STASH AN END OF LINE
	MOVEM	CH,GCSCH	;IN THE NEXT CHAR SAVE
	MOVE	CH,CC.END	;AND RETURN AN END OF FOOTNOTE
	PJRST	SAVCMN		;STORE IN BUFFER AND RETURN

;HERE TO READ FROM FILE--SKIPING ANY UN-SELECTED CHARS.

CCINF:	TRNN	F,R.SLCT	;SEE IF .SELECT MODE
	PJRST	FIN		;NO--STRAIGHT FILE READING
	SKIPE	ESLCTF		;YES--MAKE SURE NOT IN .END SELECT	[230]
	JRST	CCINE		;NO--GO HANDLE .END SELECT		[230]
	TRZN	F,R.SLLK	;SEE IF LOOKING FOR SELECTION
	JRST	CCING		;NO--CONTINUE WITH THIS LINE

;LOOP HERE WHEN SKIPING CHARACTERS
CCINLK:	PUSHJ	P,FIN		;YES--GET CHAR
	IFEOF$	CPOPJ		;DONE IF EOF
CCINLL:	CAME	CH,SELPFX	;SEE IF .SELECT PREFIX
	JRST	CCINLK		;NO--LOOP ONWARDS
	PUSHJ	P,FIN		;YES--GET NEXT CHAR
	IFEOF$	CPOPJ		;DONE IF EOF
	CAMN	CH,SELSNG	;SEE IF SINGLE LINE PREFIX
	JRST	CCING		;YES--GO GET THAT LINE
	TRNE	F,R.SLRG	;NO--ARE WE IN +- RANGE
	JRST	CCINRG		;YES--GO HANDLE THAT
	CAME	CH,SELSTR	;NO--SEE IF START OF +- RANGE
	JRST	CCINLL		;NO--LOOP AGAIN FOR SELECT PREFIX
	TRO	F,R.SLRG	;YES--SET RANGE
	JRST	CCING		; AND GO GIVE THIS LINE
;HERE WHEN IN +- SELECT RANGE AND SELECTION PREFIX SEEN
CCINRG:	CAME	CH,SELSTP	;SEE IF STOP FLAG
	JRST	CCINGX		;NO--RETURN THIS LINE
	TRZ	F,R.SLRG	;YES--CLEAR FLAG AND RETURN THIS LINE
	JRST	CCING		;GET NEXT CHARACTER
				CONT.
;HERE WHEN AT START OF LINE UNDER .END SELECT
CCINE:	SAVE$	PA		;MAKE A POINTER AC
CCINE1:	MOVEI	PA,SLIN		;POINT TO TEMP BUFFER
	PUSHJ	P,GCI		;GET NEXT CHARACTER
	  JRST	CCINE2		;NONE IN STRING, SO LOOK AT FILE
	RSTR$	PA		;SOMETHING SAVED, RETURN IT
	POPJ	P,		; TO CALLER
CCINE2:	PUSHJ	P,RCI		;REWIND TEMP STRING
CCINE3:	PUSHJ	P,CCFIN		;READ, STORING COPY IN BUFFER
	  JRST	CCINE1		;DONE--GIVE TO CALLER
CCINE4:	CAME	CH,SELPFX	;IF NOT SELECT PREFIX,
	JRST	CCINE3		; LOOP ACROSS LINE
	PUSHJ	P,CCFIN		;PREFIX--GET NEXT CHARACTER
	  JRST	CCINE1		;DONE--GIVE TO CALLER
	CAME	CH,SELSNG	;IF NOT SELECT SINGLE FLAG,
	JRST	CCINE4		; LOOP ACCROSS LINE
	SETZM	ESLCTF		;MATCH--CLEAR .END SELECT
	TRZ	F,R.SLLK	;INDICATE SELECT MATCH FOUND
	RSTR$	PA		;RESTORE CALLER'S AC
	JRST	CCING		;AND RETURN NEXT CHARACTER

;HERE WHEN RETURNING SELECTED LINE
CCING:	PUSHJ	P,FIN		;GET NEXT CHAR
CCINGX:	CAIN	CH,.CHLFD	;SEE IF END OF LINE
	TRO	F,R.SLLK	;YES--NOTE NEED TO SEARCH FOR PREFIX
	POPJ	P,		;RETURN TO CALLER

;ROUTINE TO READ FROM FILE AND STORE IN STRING BUFFER
;NON-SKIP ON END OF LINE OR BUFFER FULL

CCFIN:	MOVE	A,SLIN+1	;GET NEXT STORE
	AOS	A		;ALLOW FOR QUOTING
	CAML	A,SLIN+3	;SEE IF ROOM FOR ONE
	POPJ	P,		;NO ROOM--FAIL
	PUSHJ	P,FIN		;ROOM--GET NEXT CHARACTER
	PUSHJ	P,SCI		;STORE AWAY
	CAIN	CH,.CHLFD	;SEE IF END OF LINE
	POPJ	P,		;YES--FAIL
	JRST	CPOPJ1		;NO--GIVE OK RETURN
;ROUTINE TO READ FROM INPUT FILE
;RETURNS CH=LF, TAB, OR CHAR .GE. 40;  LF THEN -1 ON EOF
;IF /CONTROL, OR QUOTING, ALLOWS CONTROL CHARACTERS
;IF BOTH, LET NULL, CR, VTAB, HTAB, FFEED, ^Z, RUBOUT ALSO
;NEVER QUOTES LINE FEED
;USES A, CH

FINSEQ:	TRON	F,R.FSEQ	;REMEMBER TO DISCARD CHAR AFTER SEQ NO
	SKIPA	CH,[POINT 7,INSEQN]
	MOVE	CH,INSEQP	;GET POINTER TO SEQUENCE NUMBER
	TLNE	CH,(76B5)	;SEE IF NOT OVERFLOWED
	IDPB	A,CH		;OK--STORE
	MOVEM	CH,INSEQP	;RESTORE UPDATED POINTER

FINL:	TRZ	F,R.LCWV	;INDICATE NOT VERT MOTION LAST

FIN:	PUSHJ	P,.NXDTW##	;GET NEXT BYTE FROM FILE
	  JRST	FINEOF		;ALL DONE
	MOVE	CH,@B.DC##+1	;CHECK FOR SEQ NO.
	TRNE	CH,1		; ..
	JRST	FINSEQ		;YES. DISCARD.
	MOVE	CH,A		;GET BYTE
	TRZE	F,R.FSEQ	;IS THIS TAB AFTER SEQ NO?
	JRST	FIN		;YES--DISCARD IT
	TRC	F,R.QNIC!R.ALCC	;SEE IF BOTH /CON AND QUOTE
	TRCN	F,R.QNIC!R.ALCC	; ..
	JRST	FIN0		;YES--SUPPRESS SPECIAL TESTS
	CAIN	CH,.CHDEL	;OR RUBOUTS
	JRST	FIN		;GET ANOTHER
	JUMPE	CH,FIN		;JUNK NULLS
	CAIL	CH,C.GRPH	;FILTER ILLEGAL CONTROLS
	JRST	SAVCMN		;RETURN CHARACTER
	CAIE	CH,.CHCRT	;CARRIAGE RETURN
	CAIN	CH,.CHCNZ	; OR ^Z
	JRST	FINL		;YES--IGNORE THEM
FIN0:	MOVE	A,CH		;MAKE COPY OF VALUE
	CAIE	CH,.CHFFD	;SEE IF NEW PAGE
	JRST	FIN1		;NO--PROCEED
	SETOM	INLINE		;YES--CLEAR LINE COUNTER
	AOS	INPAGE		;INCREMENT PAGE COUNTER
FIN1:	CAIE	CH,.CHVTB	;VERT TAB
	CAIN	CH,.CHFFD	; OR FORM FEED
	MOVEI	CH,.CHLFD	;YES--CHANGE TO LINE FEED
	CAIE	CH,.CHLFD	;SEE IF NEW LINE
	JRST	FIN2		;NO--PROCEED
	AOS	INLINE		;YES--COUNT LINE
	MOVE	A,INSEQN	;COPY LAST LINES'S SEQUENCE
	MOVEM	A,INSEQL	; FOR ERROR MESSAGES
	SETZM	INSEQN		;CLEAR SEQUENCE NUMBER
	TROE	F,R.LCWV	;SET VERT MOTION
	JRST	FIN		;IF SECOND ONE, DISCARD IT
				CONT.
FIN2:	TRC	F,R.QNIC!R.ALCC	;SEE IF BOTH /CON AND QUOTE
	TRCN	F,R.QNIC!R.ALCC	; ..
	SKIPA	CH,A		;YES--RESTORE REAL VALUE
	CAIE	CH,.CHTAB	;TAB
	CAIN	CH,.CHLFD	; LINE FEED?
	JRST	SAVCMN
	CAIN	CH,C.SPC	;IF SPACE,
	JRST	SAVCMN		; DON'T QUOTE IT
	TRNN	F,R.QNIC!R.ALCC	;SEE IF /CONT OR QUOTING
	JRST	E$$IIF		;NO--ERROR
	TXO	CH,LCHPVT	;YES--QUOTE IT
	JRST	SAVCMN		;GO FINISH UP

	MSG$	IIF,WRN,,<">
	MOVE	A,CH		;GET THE BADDIE BACK
	PUSHJ	P,.TFCHR##
	MOVEI	A,[ASCIZ \" ignored in input file\]
	PUSHJ	P,.TSTRG
	PUSHJ	P,ONPAG		;TELL WHERE WE ARE
	JRST	FINL		;GET ANOTHER CHARACTER

FINEF1:	MOVE	CH,EOFPTR	;INITIAL EOF POINTER
	MOVEM	CH,INEOFP
FINEOF:	ILDB	CH,INEOFP	;GET LITERAL CHARACTER
	JUMPE	CH,FINEF1	;IF NONE, RESTART LITERAL

SAVCMN:	CAIE	CH,.CHLFD	;SEE IF VERT MOTION
	TRZ	F,R.LCWV	;NO--CLEAR INDICATOR
	TRNN	F,R.CCOM	;SEE IF COMMAND
	POPJ	P,		;NO--JUST RETURN
	SAVE$	<PA,B>		;PRESERVE POINTER		[170]
	MOVEI	PA,CMEBFP	;POINT TO COMMAND ERROR BUFFER
	PUSHJ	P,SCI		;DO SAFE STORE
	RSTR$	<B,PA>		;RESTORE POINTER		[170]
	POPJ	P,		;RETURN CHARACTER

EOFPTR:	POINT	36,EOFDAT
EOFDAT:	EXP	.CHLFD,.CHLFD,.CHLFD,-1,-1,0
	SUBTTL	ERROR MESSAGE HANDLING

;+.CHAPTER ERROR MESSAGE HANDLING
;.HL1 ERROR MESSAGE ROUTINES
;-

;+
;^ROUTINE <ERRMSG (AND <WRNMSG AND <INFMES) ARE RESPONSIBLE
;FOR ISSUING ERROR (AND WARNING AND INFORMATIVE)
;MESSAGES COMPLETE WITH THE <RUNOFF MESSAGE PREFIX.
;^THEY ARE INVOKED BY THE <MSG$ MACRO AND 
;CLOBBER ACCUMULATORS ^A-^D.
;^THEY ISSUE A ? (OR % OR [), THEN <RNF FOLLOWED
;BY THE THREE LETTER CODE IN LH(^A). ^THEN THEY SPACE OVER
;AND ISSUE THE MESSAGE TEXT POINTED TO FROM THE RH(^A).
;^IF NECESSARY, THE FILE WILL BE IDENTIFIED AND IF
;OUTPUT IS TO THE <TTY:, ITS BUFFER WILL BE FLUSHED.
;-

ERRMSG:	MOVSI	B,"?"		;GET PREFIX
	JRST	XXXMSG		;GO TO COMMON HANDLER
WRNMSG:	MOVSI	B,"%"		;GET PREFIX
	JRST	XXXMSG		;GO TO COMMON HANDLER
INFMES:	MOVSI	B,"["		;GET PREFIX
XXXMSG:
IF TOPS-10,<
	SKIPE	TTISOT		;SEE IF TTY IS OUTPUT 
	JRST	[OUTPUT F.FOUT,	;YES--FORCE OUT
		 JRST   XXXMSC]
> ;END TOPS-10
	SKIPE	ISDFLN		;NO--SEE IF ISSUED FILE NAME
	JRST	XXXMSC		;YES--PROCEED
	PUSHJ	P,ISUFLN	;NO--DO SO
	PUSHJ	P,.TCRLF##	;END LINE
	SETOM	ISDFLN		;AND INDICATE THAT WE DID
XXXMSC:	HRR	B,A		;COPY THE TEXT TO B
	HLRZS	A		;POSITION THE 3-LETTER CODE
	HRLI	A,'RNF'		;ADD RUNOFF PREFIX
	HRRZ	C,(P)		;GET LOCATION
	PJRST	.ERMSA##	;ISSUE MESSAGE PREFIX, ETC.

;ROUTINE TO FORCE TO START OF TTY LINE

.TNEWL::SKIPE	TTISOT		;SEE IF TTY IS OUTPUT
	PUSHJ	P,.TCRLF	;YES--ISSUE <CRLF>
	POPJ	P,		;RETURN
;+
;<ISUFLN IS A ROUTINE TO ISSUE THE NAME OF THE INPUT
;FILE.  ^THIS IS CALLED ON EACH ERROR MESSAGE AND AT THE
;END OF FILE.  ^IT PREFIXES THE MESSAGE WITH
;THE WORD "<RUNOFF:" IF IN <CCL MODE.
;-

ISUFLN:	PUSHJ	P,.PSH4T##	;SAVE TEMPS
	MOVEI	A,[ASCIZ /RUNOFF: /]
	SKIPE	CCLF1		;SEE IF CCL CALL
	PUSHJ	P,.TSTRG##	;YES--NAME PROGRAM
IF TOPS-10,<
	MOVE	A,LKPBLK+.RBNAM	;GET INPUT FILE NAME
	PUSHJ	P,.TSIXN##	;TYPE IT
> ;END TOPS-10
IF TOPS-20,<
	HRRZ	B,OPNBLK	;GET INPUT JFN
	JUMPE	B,ISUFLX	;PUNT IF NO JFN HANDY
	HRROI	A,.STEMP##	;TEMP BUFFER
	MOVSI	C,(1B8)		;JUST FILE NAME
	JFNS
	MOVEI	A,.STEMP##	;POINT TO ANSWER
	PUSHJ	P,.TSTRG##	;PRINT IT OUT
>
ISUFLX:	PUSHJ	P,.POP4T##	;RESTORE TEMPS
	POPJ	P,		;RETURN
IF TOPS-20,<
;BLOCK FOR GTJFN
GTJFNB:	EXP	1B2+1B11+1B13
	XWD	377777,377777
	EXP	0
	EXP	0
	EXP	0
	XWD	-1,DFIEXT
	EXP	0
	EXP	0
	EXP	0
> ;END TOPS-20
;+
;.HL1 ERROR MESSAGES AND DESCRIPTIONS
;
;.AUTOTABLE.LM5.P-5,1,7.TS.UPPER CASE.NOFLAGS

	COMMENT	\

;.NOSELECT
.P;	?RNFCJL CAN'T JUSTIFY LINE

.SK1;		The string of input between spaces (and end of line)
		is  greater  than  the  separation  between left and
		right margins and therefore  does  not  fit  in  the
		output even before any attempt to expand spaces.

.P;	?RNFDVN DUPLICATE VARIABLE NAME:  ".command"

.SK1;		This variable command is  attempting  to  declare  a
		variable  which  has  already  been  declared.  This
		declaration will be ignored.

.P;	?RNFEFD END FOOTNOTE DOESN'T FOLLOW FOOTNOTE:  ".command"

.SK1;		This end footnote command appears at a place in  the
		file  which  is not immediately following a footnote
		command and the corresponding footnote data.

.P;	?RNFELD END LITERAL DOESN'T FOLLOW LITERAL:  ".command"

.SK1;		This end literal command appears at a place  in  the
		file  which  is  not immediately following a literal
		command and  the  corresponding  literal  text.   It
		probably  reflects  that  the  count  on the literal
		command is incorrect.

.P;	?RNFEVL EXCEEDING VARIABLE LIST:  ".command"

.SK1;		Only a maximum of  20  variables  can  be  declared.
		This  command  is  attempting  to  declare the 21-st
		variable.    This   and   all    further    variable
		declarations  will  be ignored, although the message
		will not be repeated.

.P;	?RNFFIF FOOTNOTE INSIDE FOOTNOTE:  ".command"

.SK1;		This command  is  attempting  to  start  a  footnote
		definition   only   it   occurs  within  a  footnote
		definition, which is illegal. It probably  indicates
		that  the  previous  footnote  definition  was never
		terminated.

.P;	?RNFIBO INPUT BUFFER OVERFLOW

.SK1;		A string of characters has been input  which  is  so
		long  between  spaces  (or  the  right  margin is so
		large) that it  has  overflowed  the  internal  line
		buffer storage area.

.P;	?RNFIFT ILLEGAL IN FOOTNOTE:  ".command"

.SK1;		This command is illegal within a footnote.
.P;	%RNFIIF ^x IGNORED IN INPUT FILE

.SK1;		Control characters are not normally allowed  in  the
		input  file.  This  character was input and is being
		ignored.   If  it  should  be  input,  then  declare
		".CONTROL CHARACTERS" in order to make it legal.

.P;	?RNFILC ILLEGAL COMMAND:  ".command"

.SK1;		This command  is  illegal  for  some  reason.   Most
		reasons  are  that  a key word was not recognized or
		that an argument was out of range.

.P;	%RNFJEC JUNK AT END OF COMMAND:  ".command"

.SK1;		The command, after all its arguments, still has some
		other characters which are not blanks or comments.

.P;	[RNFKCF nK CORE - FOOTNOTE]

.SK1;		Core was expanded because of growth in the  footnote
		storage  area.   If  this  repeats  indefinitely  it
		probably indicates that the footnote was  improperly
		terminated.

.P;	[RNFKCI nK CORE - INDEX]

.SK1;		Core was expanded because of  growth  in  the  index
		storage  area.   In  a  well  indexed  document this
		message should be output occasionally as  processing
		progresses.

.P;	?RNFLDE LITERAL DOESN'T END WITH .END LITERAL:  ".command"

.SK1;		After a counted literal, the next line is not an end
		literal  command.   This probably indicates that the
		count is wrong.

.P;	?RNFNEC NOT ENOUGH CORE nK

.SK1;		Core has been expanded to  the  limit  of  what  the
		monitor  is  allowed  to  assign  to  this job.  The
		processing is aborted at this point.

.P;	?RNFNFS NO FILE SPECIFIED

.SK1;		The user has specified some switches  or  an  output
		file, but has not specified an input file.
.P;	%RNFNIA NEGATIVE INDENT ATTEMPTED

.SK1;		The sum of the indent and the left  margin  is  less
		than zero, meaning that the line should start to the
		left of the left edge of the paper.  Either the left
		margin  has been misset or the indent is wrong.  The
		indent might be implicit in  a  paragraph  or  table
		request.  This message is output only once until the
		next left margin or SD command.

.P;	%RNFNIC ANOTHER n NEGATIVE INDENTS COUNTED

.SK1;		This message indicates how many additional  negative
		indents were discovered since the last NIA message.

.P;	?RNFNID NO INPUT DEVICE

.SK1;		The user has  failed  to  specify  either  an  input
		device or file.

.P;	?RNFODE OUTPUT ERROR xxxxxx

.SK1;		The output file has an I/O error whose octal code is
		included in the message.

.P;	%RNFSPO SUBPAGE OVERFLOW

.SK1;		While  incrementing  the  subpage  counter,  it  got
		larger  than  26.   This probably indicates that the
		end subpage command is missing.

.P;	%RNFTFE TOO FEW END COMMANDS

.SK1;		When the end of the input was reached there were not
		the  same  number  of  end (or end list or end note)
		commands as there had been list and  note  commands.
		This  probably  indicates  that  an  end  command is
		missing.

.P;	?RNFTMI INSUFFICIENT CORE FOR COMMAND

.SK1;		The  user  has  specified   so   many   input   file
		specifications  that  RUNOFF could not fit them into
		core.  The command  should  be  split  into  several
		commands.

.P;	?RNFTMR TOO MANY RANGES

.SK1;		The user has specified too  many  IRANGE  or  ORANGE
		pairs to fit in the storage space assigned (20 pairs
		each).  Fewer ranges should be specified.
.P;	?RNFTMV TOO MANY /VARIANTS

.SK1;		The user has specified  too  many  VARIANTS  in  the
		command.   Only  20 variants can be specified in one
		command.

.P;	%RNFTNN TOO MANY NESTED NOTES

.SK1;		More than 6 nested  notes  and  lists  has  occured.
		This   probably  indicates  that  one  or  more  end
		commands is missing.

.P;	?RNFUKV UNKNOWN VARIABLE:  ".command"

.SK1;		On an if, ifnot, else, or endif command  a  variable
		was  referenced which was not declared in a variable
		command. This usually indicates a spelling error  or
		a missing variable command.

.P;	%RNFUME UNMATCHED END COMMAND

.SK1;		More end commands have occured  than  list  or  note
		commands.

.P;	?RNFVVZ /VARIANT VALUE ZERO

.SK1;		In a VARIANT switch, the value  was  null  or  zero.
		Variants always have names.


.SELECT

\	;END OF COMMENT


;+
;.DO INDEX
;-

	END	RUNOFF		;&.SKIP 2;[End of RUNOFF.PLM]