Google
 

Trailing-Edge - PDP-10 Archives - scratch - 10,7/unscsp/sos/sosjus.mac
There are 3 other files named sosjus.mac in the archive. Click here to see a list.
	TITLE	SOSJUS - Justify and Join commands
;		-----------------------------
; 
; This file contains the J commands as follows:
;	1. Test for the various J commands
;	2. The justify command
;	3. The join (J) command
; 
 
	SEARCH	SOSTCS
	$INIT
 
; Flag definitions for this module
 
JFFLG==PDFL1			; Do fill only
JRFLG==PDFL2			; Justify right
JCFLG==PDFL3			; Justify center
JBLF==PDFL4			; Justify sees a blank
JLFLG==PDFL5			; Justify left
JPER==PDFL6			; Saw a period (or something like it)
JWFLG==PDFL7			; Justfiy words only (Ragged right)
 
	SUBTTL	TEST FOR THE VARIOUS J COMMANDS
 
IFN	JUSTSW,<
JUST::
	PUSHJ	P,GNCH##	; Get a character
	PUSH	P,C		; Save character
	TRZ	C,40		; Convert to upper case
	CAIN	C,"R"
	TRO	FL2,JRFLG	; R for right
	CAIN	C,"L"
	TRO	FL2,JLFLG	; L for left
	CAIN	C,"C"
	TRO	FL2,JCFLG	; C for center
	CAIN	C,"U"		; U for justify
	TRO	FL2,JFFLG	; Which is the only thing which fills
	CAIN	C,"W"		; W for words
	TRO	FL2,JWFLG!JFFLG
	POP	P,C		; Restore c
	TRNN	FL2,JRFLG!JLFLG!JCFLG!JFFLG!JWFLG
	JRST	JOIN		; Must be line number for join
	SUBTTL	THE JUSTIFY COMMAND
 
; Here when we verify we have a JU, JC, JW, or JR command
 
	MOVE	T1,RMAR 	; Check that this guy is largest
	CAMLE	T1,LMAR
	CAMG	T1,PMAR
	NERROR	MAR
	PUSHJ	P,GET2SD##	; Get range
	PUSHJ	P,CKTRMF##	; Make sure it terminates correctly
	MOVE	T1,LOLN		; First line number of range
	MOVEM	T1,LIBUF	; Also set new first line to same
	TLO	FL2,NORENT	; Protect this region from interruption
	PUSHJ	P,FINDLO##	; Find it
	PUSHJ	P,INITOL	; Set it up
	MOVEM	T1,LIBUF	; Set new line number same as old
	PUSHJ	P,INITNL	; And set up the new one
	SETZM	TPNT		; Tell JGET there is nothing in LIBUF2
	MOVE	T1,LMAR 	; Set left margin
	TRNE	FL2,JFFLG	; If filling
	MOVE	T1,PMAR 	; Make this start of paragraph
	SOS	T1
	MOVEM	T1,INDNT	; For indentation
	MOVEM	T1,LINL 	; And line length
; This is the part that gets a character from the old line

JGET:	SKIPN	TPNT		; Is there any unprocessed tail?
	JRST	JGET1		; No, get a character
	MOVE	T1,ELIN 	; Are we at end of line?
	CAMN	T1,TPNT
	JRST	JGET2		; Yes, start getting from old line
	ILDB	T1,TPNT 	; No, get a character
	JRST	JPUT		; And put.
JGET2:	SETZM	TPNT		; End of tail

JGET1:	AOS	OCNT1		; Step character count
JGET1A: ILDB	T1,PNTR 	; Load a character
	CAIE	T1,15		; Is this a CR?
	JRST	JGET3		; No,test for end of line
	TRNN	FL2,JFFLG	; Are we filling?
	JRST	JGET1A		; No, we're through after the LF
	MOVEI	T1," "		; Yes, make it a blank
	JRST	JPUT		; And go put
JGET3:	CAIE	T1,12		; End of line?
	JRST	JPUT		; Not yet, so go put
JGET4:				; End of line
	HRRZ	T1,PNTR 	; Current word in buffer for deletion
	SUB	T1,OPTR 	; - start of old line
	AOS	T1		; +1 = word count of old line
	MOVEM	T1,OCNT 	; For insed
	TRNN	FL2,JFFLG	; If we are not filling
	JRST	JGETE		; Do what we have to do
	SETZM	NCNT		; Otherwise we delete old line
	MOVE	PNTR,OPTR	; Which starts  here
	PUSHJ	P,INSED##	; Using INSED
	PUSHJ	P,INITOL	; Do setup on it and check range
JGETF:	ILDB	T1,PNTR 	; Get first character
	AOS	OCNT1		; Step character count
	CAIE	T1,11		; Is it a tab
	CAIN	T1,15		; Or CR?
	JRST	PARA		; Yes, start a new paragraph
	TRNE	FL2,JWFLG	; If we are doing a "jw"
	CAIE	T1," "		; And a line starts with a space
	JRST	JPUT
	JRST	JGETF		; Then ignore it
JGETE:	MOVE	T1,LINL 	; Line length
	MOVEM	T1,WRDL 	; Because CR as blank was deleted
	MOVEM	ALTP,LWRD	; Also store pointer to end of line
	CAMLE	T1,MAXL 	; If line was too long,
	RERROR	LTL		; Tell him so
	PUSHJ	P,JSUB		; Clean up new line and put it out
	PUSHJ	P,INITOL	; Set up next line
	MOVEM	T1,LIBUF	; Set new line number same as old
	SETZM	TPNT		; Nothing in LIBUF2
	JRST	JGET2		; Start munching
; This is the part that puts a character into the new line


JPUT:	CAIE	T1," "		; Is this a blank?
	JRST	JPUTN		; No, check some other stuff
	TRNN	FL2,JPER	; Have we seen a period or something?
	JRST	JPUTB1		; No, process as usual
	TRZ	FL2,JPER	; Yes, turn off flag
	AOS	WCNT		; Increment word count
	MOVE	T2,LINL 	; Get current length
	MOVEM	T2,WRDL 	; Save it for JSUB
	MOVEM	ALTP,LWRD	; Also save the current pointer
	IDPB	T1,ALTP 	; Deposit a blank
	TRO	FL2,JBLF	; Say we saw a blank
	AOJA	T2,JPUT1	; Increment count, deposit second blank
JPUTB1: TROE	FL2,JBLF	; A blank, was there one before it?
	JRST	JGET		; Yes, we don't want it
	TRNN	FL2,JFFLG	; Are we filling?
	TRZ	FL2,JBLF	; No, permit an extra blank
	AOS	WCNT		; Step wordcount
	MOVE	T2,LINL 	; Get length so far
	MOVEM	T2,WRDL 	; And save it for jsub
	MOVEM	ALTP,LWRD	; And store pointer to end of word
	JRST	JPUT1		; Then put blank in buffer
JPUTN:	TRZ	FL2,JBLF!JPER	; Not a blank
	CAIE	T1,":"		; Is it a colon?
	CAIN	T1,"."		; Is it a period
	TRO	FL2,JPER
	CAIE	T1,"!"		; Or exclamation?
	CAIN	T1,"?"		; Or question mark
	TRO	FL2,JPER
JPUTN1: MOVE	T2,LINL 	; Length so far
JPUT1:	IDPB	T1,ALTP 	; Deposit character
	ADD	T2,@WTBL	; Width of character
	CAIN	T1,10		; Adjust back-spaces
	SUBI	T2,2		; By subtracting 2
	CAILE	T1,37		; A non-spacing character?
	JRST	.+3		; Nope
	CAIL	T1,30		; Characters 30 - 37 have zero width
	SUBI	T2,1		; Adjust line width for them
	CAIE	T1,11		; Was that a tab?
	JRST	JPUT2		; No
	TRZE	T2,7		; Yes, if last 3 bits are nonzero
	ADDI	T2,10		; We wern't at tab position
	SETZM	WCNT		; Reset wordcount
	SETZM	LWRD		; Last word location
	MOVEM	ALTP,BLIN	; And logical beginning of line for jsub
	TRNE	FL2,JFFLG	; If filling
	TRO	FL2,JBLF	; Delete a following blank
JPUT2:	MOVEM	T2,LINL 	; Store new length
	CAMLE	T2,MAXL 	; Are we over the end?
	JRST	JPUTEL		; Yes, end line we are now on
	CAME	ALTP,[POINT 7,LIBUF2+MXWPL,34]; No.  Filled buffer?
	JRST	JGET		; Not yet, get another
JPUTEL: SKIPE	LWRD		; Any words yet?
	JRST	JPUTE		; Yes, put out line
	RERROR	LTL		; No, tell him line too long
	MOVE	T2,MAXL 	; Say line is long enough
	MOVEM	T2,WRDL
JPUTE:	TRNE	FL2,JFFLG	; Unless we're not filling
	PUSHJ	P,JSUB		; Move out a new line, after justifying 
	JRST	JGET		; Then get another character
; This puts out a new line

NLOUT:	MOVEI	T1,15		; Add a CR
	IDPB	T1,ALTP
	MOVEI	T1,12		; And a LF
	IDPB	T1,ALTP
	HRRZ	T1,ALTP 	; Last word of line
	SUBI	T1,LIBUF	; -first
	AOS	T1		; +1=wordcount
	MOVEM	T1,NCNT 	; For insertion into buffer
	TRNE	FL2,JFFLG	; If filling
	SETZM	OCNT		; Insert before
	MOVE	PNTR,OPTR	; Else replace, the old line
	PUSHJ	P,INSED 	; Done by insed
	SETZM	OLDLIN		; Prevent order messages here
	PUSHJ	P,FINDN##	; Find old line
	TRNN	FL2,JFFLG	; If not filling
	JRST	INITNL		; Set up new line on the way back
	MOVE	T2,INCR 	; Incr for line numbers
	MOVE	T1,LIBUF	; Old line number
	PUSHJ	P,ASCIAD##	; Add to make new one
 
; Insure new line number does not bump into next line
 
	CAMGE	T1,CLN		; New line # greater or equal to next one?
	JRST	NLOK		; Nope, we're ok
	MOVE	T1,CLN		; Yes it is
	MOVE	T2,LIBUF	; Load up the line numbers
	PUSHJ	P,ASCAV##	; And try the average of the two
	MOVE	T1,T2		; Move resulting line number into t1
	CAMLE	T1,LIBUF	; Did we go backwards?
	JRST	NLOK		; Nope, all is well
	MOVE	T1,LIBUF	; Things don't look good...
	MOVE	T2,LN1##	; So lets just use incr of 1
	PUSHJ	P,ASCIAD	; Add small increment onto line number
 
; Here for the new line insertion
 
NLOK:	MOVEM	T1,LIBUF	; And store it away
	CAMG	T1,MAXLN	; Too high?
	JRST	NLO2		; No, exit
	AOS	T1,CPG		; Yes, will soon be on next page
	MOVEM	T1,CPGL 	; And logical page
	AOS	HIPG
	PUSHJ	P,INSPMK##	; Insert a page mark
	MOVE	T2,INCR 	; Incr again
	MOVEM	T2,LIBUF	; To make first line number
	OUTSTR	[ASCIZ /%Page mark inserted
/]
NLO2:	MOVE	T1,OCNT1	; Characters processed so far
	MOVEM	PNTR,OPTR	; Remember where we are
	AOS	PNTR		; Skip line number
	HRLI	PNTR,(<POINT 7,0>); Make byte pointer
NLO1:	IBP	PNTR		; To move pntr back
	SOJGE	T1,NLO1 	; To where we found it
	JRST	INITNL		; Then set up new line on way back
; This sets up a new old line for get

INITOL: PUSHJ	P,GETLTH##	; Make sure all of it is in core
	PUSHJ	P,FINDN1##	; Get number back again.
INITO1: HRRZM	PNTR,OPTR	; Save pointer to start of line
	PUSHJ	P,ONMOV##	; Check range
	JRST	JSTEND		; Finished
	CAMN	T1,PGMK 	; Is it a pagemark?
	JRST	INITOP		; Yes
	MOVE	T2,CPG		; And page
	DMOVEM	T1,CLN		; Save current page/line
	SETZM	OCNT1		; No characters yet
	SETZM	TCHR		; Not known to be start of paragraph
	AOS	PNTR		; Skip line number
	HRLI	PNTR,(<POINT 7,0>); Make byte pointer
	IBP	PNTR		; Skip initial tab
	POPJ	P,		; Exit
INITOP: 			; Found a pagemark
	TRNE	FL2,JFFLG	; Are we filling?
	JRST	INITOD		; Yes, delete it
	AOS	T2,CPG		; No, we are on new page
	MOVEM	T2,CPGL
	PUSHJ	P,FINDN 	; Find next line
	JRST	INITOL		; And see what's there
INITOD:	PUSHJ	P,DLTPAG##	; Delete the page mark
	SOS	BGPG		; Now have one less page
	SOS	HIPG
	JRST	INITOL		; Look at next line

INITNL: SETZM	LIBUF+1 	; Code to zero the line buffer
	MOVE	T1,[XWD LIBUF+1,LIBUF+2]
	BLT	T1,LIBUF+MXWPL+1
	MOVE	ALTP,[POINT 7,LIBUF2]; Point altp at start of libuf2
	MOVEI	T1,11		; Tab to start line
	IDPB	T1,ALTP 	; So insert it
	MOVEM	ALTP,BLIN	; And save logical beginning of line
	TRO	FL2,JBLF	; Keep from inserting leading blanks
	TRZ	FL2,JPER
	MOVE	T1,LMAR 	; Set left margin
	SOS	T1		; Margin -1 = extra blanks
	MOVEM	T1,LINL 	; For extra line length
	MOVEM	T1,INDNT	; And indentation
	SETZB	T1,WCNT 	; And there are no words yet
	SETZM	WRDL		; Nor characters, for that matter
	EXCH	T1,LWRD 	; Reset pointer to last word
	MOVEM	T1,TPNT 	; But save it to get tail
	POPJ	P,		; Return
; This starts a new paragraph

PARA:	MOVEM	T1,TCHR 	; Store terminating character
	SKIPE	LWRD		; Any words yet?
	PUSHJ	P,JSUB		; Yes, get rid of old line
	MOVE	T1,TCHR 	; Get terminator back
	SETZM	TCHR		; Don't confuse people
	SETZM	TPNT		; Tell jget nothing remains in libuf2
	SETZM	INDNT		; If tab, no special indentation
	SETZM	LINL
	CAIN	T1,11		; Is it a tab?
	JRST	JPUT		; Yes, put it in new line
	PUSHJ	P,JSUB		; Must have been blank line
	MOVE	T1,PMAR 	; Set paragraph margin
	SOS	T1
	MOVEM	T1,INDNT
	MOVEM	T1,LINL
	JRST	JGET		; So get new character

; This finishes everything up

JSTEND: SETOM	TCHR		; Fake end of paragraph
	SKIPE	LWRD		; Anything left?
	PUSHJ	P,JSUB		; Yes, get rid of it
	MOVE	PNTR,OPTR	; Get back old pointer
	MOVE	T1,(PNTR)	; Get line number
	MOVEM	T1,LIBUF	; Save number of next line
	PUSHJ	P,FINDB##	; Get line last filled
	MOVEM	T1,CLN		; Set it as current line
	EXCH	T1,LIBUF
	SKIPE	T1		; End of file?
	CAMN	T1,PGMK 	; Page mark next?
	JRST	COMND## 	; Don't worry about order
	CAMG	T1,LIBUF	; Order trouble?
	NERROR	ORDER		; Yes
	JRST	COMND		; No, we're through.
; At last!  the justification of all this stuff!

JSUB:	MOVEM	ALTP,ELIN	; Save end of line for get
	MOVE	ALTP,[POINT 7,LIBUF+1]; Where to deposit
	MOVE	T4,[POINT 7,LIBUF2]; Where to load
	MOVNS	JFLOP		; Put blanks in other side this time
JSUB1:	ILDB	T1,T4		; Get a character
	IDPB	T1,ALTP 	; And move it
	CAME	T4,BLIN 	; Was that the last tab?
	JRST	JSUB1		; No, move another
	SKIPN	T5,LWRD 	; If no words there
	MOVE	T5,ELIN 	; This is where to stop
	SKIPN	WRDL		; If nothing is there at all
	JRST	NLOUT		; Put out blank line
; Now we compute number of blanks to insert, if any
	SETZM	T2
	SETZM	BPW
	SETZM	REM
	MOVEI	T1," "		; We fill with blanks
	TRNE	FL2,JLFLG	; If left justifying,
	JRST	JSUBM1		; We may start filling to move the line right
	MOVE	T2,MAXL 	; Desired length
	SUB	T2,WRDL 	; -length we have = what we want
	JUMPE	T2,JSUBM1	; If zero, go move rest of line
	IDIV	T2,@WTBL	; /width of blank = blanks we need
	TRNE	FL2,JCFLG	; If centering
	ASH	T2,-1		; We only want half as many
	TRNE	FL2,JRFLG!JCFLG ; If not justifying both margins
	JRST	JSUBM1		; Go put in some blanks
	SOSLE	WCNT		; If less than 2 words
	SKIPE	TCHR		; Or end of paragraph
	JRST	JSUBM		; Don't bother
	IDIV	T2,WCNT 	; Blanks/words
	MOVEM	T2,BPW		; = blanks per word
	MOVEM	T3,REM		; And remainder
	SKIPL	JFLOP
	JRST	JSUBM
	AOS	BPW		; Every other line
	SUB	T3,WCNT 	; We add extra blanks
	MOVNM	T3,REM		; On the other side
JSUBM:	SETZM	T2
; Move line, inserting blanks
JSUBM1: ADD	T2,INDNT	; Do indentation
JSUBM3: SOJL	T2,JSUBM2	; Quit if none
	IDPB	T1,ALTP 	; Else deposit
	SOJGE	T2,.-1		; And try again
JSUBM2: CAMN	T4,T5		; Was it the last?
	JRST	NLOUT		; Yes, put out new line
	ILDB	T1,T4		; Get another character
	IDPB	T1,ALTP 	; Deposit it
	TRNE	FL2,JWFLG	; Loop if no blank fill
	JRST	JSUBM2
	SKIPN	TCHR		; At end of paragraph we do not look for banks
	TRNN	FL2,JFFLG	; Are we looking for blanks?
	JRST	JSUBM2		; No, move another
JSUBB:	CAIE	T1," "		; Yes, is it a blank?
	JRST	JSUBBN		; No
	TROE	FL2,JBLF	; Yes, did we just see one?
	JRST	JSUBM2		; Yes, move another
	MOVE	T2,BPW		; No, get blanks per word
	SOSL	REM		; If remainder still .gt. 0
	ADD	T2,JFLOP	; Add another on alternate lines
	JRST	JSUBM3		; And put them in
JSUBBN: TRZ	FL2,JBLF	; Not a blank
	JRST	JSUBM2		; Get another
>			; End of justification code
	SUBTTL	THE JOIN (J) COMMAND
 
; Here to join a line
 
IFN	JUSTSW,<
JOIN::	MOVEM	C,SAVC		; Back up scanner one character
>
IFE	JUSTSW,<
JUST::
JOIN::
>
	PUSHJ	P,GET1SD##	; Get line number
	PUSHJ	P,CKTRMF##	; Make sure it terminates correctly
	PUSHJ	P,FINDHI##	; Find line
	MOVE	T2,CPG
	MOVE	T1,(PNTR)
	CAMN	T2,HIPG
	CAME	T1,HILN
	NERROR	NLN
	MOVEM	T2,CPGL
	MOVEM	T1,CLN
	SETZM	LIBUF		; To eliminate garbage at end of line
	MOVE	T1,[XWD LIBUF,LIBUF+1]
	BLT	T1,LIBUF+MXWPL+1
	MOVE	T2,PNTR 	; Get the pointer to the line
	MOVE	T3,(T2) 	; Pick up the first word
	MOVEI	T4,LIBUF	; The place to put it
	JRST	JSALT3		; Transfer
JSALT2: SKIPE	T3,(T2)
	TRNE	T3,1		; Is it the end of the line
	JRST	JSALT1
JSALT3: MOVEM	T3,(T4) 	; Put it away
	ADDI	T4,1
	AOJA	T2,JSALT2
 
JSALT1: MOVEI	T1,(T4) 	; Movei t1,-libuf(t4)
	SUBI	T1,LIBUF
	MOVEM	T1,OCNT
	IMULI	T1,5		; Get count of chrs
	SUBI	T1,6		; We will have to find the true end
	SUBI	T4,2
	HRLI	T4,(<POINT 7,0,27>); Set up pointer
FEND1:	ILDB	T2,T4
	CAIE	T2,15
	AOJA	T1,FEND1
	PUSH	P,T1
	PUSHJ	P,FINDN 	; Get the line to join it to
	CAME	T1,PGMK
	SKIPN	T1
	NERROR	NNN		; No line there to connect to
	POP	P,T2		; Count
	MOVEI	T1,1(PNTR)
	HRLI	T1,(<POINT 7,0,6>); Set to point there
	ADD	T4,[XWD 70000,0]
TRN1:	ILDB	T3,T1
	IDPB	T3,T4
	ADDI	T2,1
	CAIL	T2,MXWPL*5+6
	NERROR	LTL
	CAIE	T3,12
	JRST	TRN1
	SUBI	T1,-1(PNTR)
	PUSH	P,OCNT
	HRRZM	T1,OCNT 	; Size of old second line
	SETZM	NCNT
	PUSHJ	P,INSED
	PUSHJ	P,FINDB 	; Back up
	POP	P,OCNT		; Get its size
	SUBI	T4,LIBUF-1
	HRRZM	T4,NCNT
	PUSHJ	P,INSED
	JRST	COMND
 
	END