# sprint --- optimize printing on the Spinwriter include "sprint_def.r.i" include SPRINT_COMMON character name (MAXLINE) integer save_lword, state (4), i, junk integer duplx$, gfnarg file_des open external quit_unit shortcall mkonu$ (18) character vert (16), horiz (16) data vert/'P'c,'Q'c,'R'c,'S'c,'T'c,'U'c,'V'c,'W'c,'X'c,'Y'c,'Z'c, '['c,'\'c,']'c,'^'c,'_'c/ data horiz/'@'c,'A'c,'B'c,'C'c,'D'c,'E'c,'F'c,'G'c,'H'c,'I'c,'J'c, 'K'c,'L'c,'M'c,'N'c,'O'c/ define (quit,1) PARSE_COMMAND_LINE ("chjlnsvx"s, "Usage: sprint {-c |-h |-j|-l |-s|-v |-x} []"s) ARG_DEFAULT_INT (c, 1) ARG_DEFAULT_INT (l, 66) if (ARG_PRESENT (h)) if (ARG_VALUE (h) < 0 || 15 < ARG_VALUE (h)) call error ("illegal horizontal spacing"s) if (ARG_PRESENT (v)) if (ARG_VALUE (v) < 1 || 16 < ARG_VALUE (v)) call error ("illegal vertical spacing"s) call mklb$f ($ quit, Quit_label) call mkonu$ ("QUIT$"v, loc (quit_unit)) save_lword = duplx$ (-1) # save terminal configuration junk = duplx$ (or (save_lword, :140000)) # turn off echo and auto-lf call set_delay (0, 0, 1) Pos = 1 # set initial column number Line = 1 # set initial line number Outstanding_lf = 0 # set initial number of outstanding LFs Chunk = 0 # no characters sent since last poll Direction = FORWARD # start print left-to-right Outstanding_poll = FALSE # haven't sent a poll sequence yet OUTCON (CR) # make sure carriage is in column 1... if (~ARG_PRESENT (x)) { OUTCON (FF) # ... and at the top of a page TOP_OF_FORM # allow user to position paper } state (1) = 1 repeat select (gfnarg (name, state)) when (EOF) break when (OK) { Fd = open (name, READ) if (Fd ~= ERR) { for (i = 1; i <= COPIES; i += 1) { if (ARG_PRESENT (h)) Spacing = horiz (ARG_VALUE (h) + 1) else Spacing = DEFARG SET_HORIZONTAL_SPACING if (ARG_PRESENT (v)) Formadvance = vert (ARG_VALUE (v)) else Formadvance = DEFARG SET_VERTICAL_SPACING call sprint call rewind (Fd) } call close (Fd) } else call print (ERROUT, "*s: can't open*n"s, name) } when (ERR) call print (ERROUT, "*s: can't open*n"s, name) call outch (CR) # flush out pending NEWLINEs and return carriage quit; # come to this label on QUIT call rvonu$ ("QUIT$"v) if (Outstanding_poll) WAIT_FOR_ACK if (Fd ~= STDIN) call close (Fd) call set_delay (MIN, MAX, SLOPE) # reset to reasonable value junk = duplx$ (save_lword) # restore echo stop end # sprint --- optimize printing for one file subroutine sprint include SPRINT_COMMON character buf (BUFLENGTH) integer i, j, k, start, size, len integer inbuf while (inbuf (buf, len, start, size) ~= EOF) { if (size == 0) call outch (NEWLINE) # linefeed elif (Pos - start > size - Pos) { # print in reverse direction START_BACKWARD_PRINT if (Pos ~= size) { MOVE_TO_COLUMN (size) Pos = size } for (i = len; i >= start; i -= 1) { k = 0 for (j = i; buf (j) == ' 'c; j -= 1) k += 1 if (k > 3) { # is it cheaper to do absolute positioning? MOVE_TO_COLUMN (Pos - k) Pos -= k i = j # now put out non-blank } if (Pos > 0) # don't print before column 1 call outch (buf (i)) # put out character if (buf (i) == BS) Pos += 1 elif (buf (i) ~= hlf && buf (i) ~= rhlf) Pos -= 1 } call outch (NEWLINE) } else { # print in forward direction START_FORWARD_PRINT if (Pos ~= start) { MOVE_TO_COLUMN (start) Pos = start } for (i = start; i <= len; i += 1) { k = 0 for (j = i; buf (j) == ' 'c; j += 1) k += 1 if (k > 3) { # is it cheaper to do absolute positioning? MOVE_TO_COLUMN (Pos + k) Pos += k i = j # now put out non-blank } if (Pos > 0) # don't print before column 1 call outch (buf (i)) # put out character if (buf (i) == BS) Pos -= 1 elif (buf (i) ~= hlf && buf (i) ~= rhlf) Pos += 1 } call outch (NEWLINE) } } if (EJECT_OPT && Line > 1) call outch (FF) return end # inbuf --- input buffer, returning length and text size integer function inbuf (buf, len, start, size) character buf (BUFLENGTH) integer len, start, size include SPRINT_COMMON integer l, k, i integer getlin l = getlin (buf, Fd) if (l == EOF) return (l) while (buf (l) ~= NEWLINE && l < BUFLENGTH - MAXLINE) { k = getlin (buf (l + 1), Fd) if (k == EOF) break l += k } for (len = l - 1; len > 0; len -= 1) if (buf (len) ~= ' 'c) break for (start = 1; start <= len; start += 1) if (buf (start) ~= ' 'c) break size = 0 for (i = 1; i <= len; i += 1) { if (buf (i) == BS) size -= 1 elif (buf (i) ~= hlf && buf (i) ~= rhlf && buf (i) ~= rlf) size += 1 } return (l) end # outch --- send character; handle timing and vertical spacing subroutine outch (c) character c include SPRINT_COMMON integer sGAMMA (13), sLAMBDA (13), snabla (23), snot (11), snu (11), sphi (7), sPHI (43), spsi (19), sPSI (19), sPI (33), stheta (5), sTHETA (5), szeta (15), siota (13), sXI (63), supsilon (13), schi (7), spsset (19), ssset (21), sle (13), sge (13), simp (9), sexist (31), snexist (33), suniv (15), sor (15), sand (15), sne (5), siso (13), sapeq (13), sscolon (5), sdquote (11), sdollar (5) character vert (16) data _ sGAMMA /a_GAMMA, R, R, R, R, "'"c, L, L, L, L, L, L, 0/, sLAMBDA /L, '/'c, R, R, R, SO, a_bslash, SI, L, L, L, L, 0/, snabla /L, SO, a_bslash, SI, R, R, R, '/'c, L, L, U, U, U, U, '-'c, L, L, L, D, D, D, D, 0/, snot /L, '-'c, R, D, D, "'"c, L, L, U, U, 0/, snu /L, '('c, R, R, R, '/'c, L, L, L, L, 0/, sphi /'o'c, L, D, '|'c, L, U, 0/, sPHI /'o'c, L, L, L, D, D, D, SO, a_brbrace, SI, R, R, R, R, SO, a_blbrace, SI, L, L, L, L, L, L, L, U, U, U, U, U, U, a_trbrace, R, R, R, R, a_tlbrace, L, L, L, D, D, D, 0/, spsi /'|'c, L, '-'c, D, R, R, "'"c, L, L, L, L, L, L, L, "'"c, R, R, U, 0/, sPSI /'I'c, L, '-'c, D, R, R, "'"c, L, L, L, L, L, L, L, "'"c, R, R, U, 0/, sPI /L, L, L, L, L, L, L, L, a_trbrace, R, R, R, R, a_tlbrace, R, R, R, R, a_trbrace, R, R, R, R, a_tlbrace, L, L, L, L, L, L, L, L, 0/, stheta /'O'c, L, '-'c, L, 0/, sTHETA /'O'c, L, '='c, L, 0/, szeta /U, U, U, U, U, '-'c, D, D, D, D, D, 16r24, L, L, 0/, siota /D, D, 16r27, D, D, "'"c, U, U, U, U, L, L, 0/, sXI /'_'c, D, '-'c, U, U, U, U, U, U, U, L, L, '_'c, D, D, D, D, D, D, L, L, L, L, L, "'"c, R, R, R, R, R, R, R, R, R, "'"c, L, D, D, D, D, D, "'"c, L, L, L, L, L, L, L, L, L, L, L, "'"c, U, U, U, U, U, R, R, R, 0/, supsilon /SO, a_backslash, SI, R, R, R, ')'c, L, L, L, L, L, 0/, schi /16r24, L, SO, 16r4A, SI, L, 0/, spsset /U, 'c'c, R, R, U, '-'c, L, D, D, D, '-'c, D, U, U, L, L, L, L, 0/, ssset /U, 'c'c, R, R, U, '-'c, L, D, D, D, '-'c, L, U, U, '_'c, D, L, L, L, L, 0/, sle /U, U, '<'c, L, D, D, D, D, '-'c, U, U, L, 0/, sge /U, U, '>'c, L, D, D, D, D, '-'c, U, U, L, 0/, simp /'='c, R, R, '>'c, L, L, L, L, 0/, sexist /'_'c, U, U, U, U, U, U, U, U, L, '_'c, D, D, D, D, D, D, D, D, R, '-'c, R, R, '|'c, L, L, L, L, L, L, 0/, snexist /'_'c, U, U, U, U, U, U, U, U, L, '_'c, D, D, D, D, D, D, D, D, R, '-'c, L, '/'c, R, R, '|'c, L, L, L, L, L, L, 0/, suniv /SO, a_backslash, SI, R, R, '-'c, R, '/'c, L, L, L, L, L, L, 0/, sor /SO, a_backslash, SI, R, R, R, R, '/'c, L, L, L, L, L, L, 0/, sand /'/'c, R, R, R, R, SO, a_backslash, SI, L, L, L, L, L, L, 0/, sne /'='c, L, '/'c, L, 0/, siso /'='c, L, U, U, U, SO, a_tilde, SI, L, D, D, D, 0/, sapeq /U, SO, a_tilde, SI, D, D, L, SO, a_tilde, SI, U, L, 0/, sscolon /':'c, L, ','c, L, 0/, sdquote /L, L, "'"c, R, R, R, "'"c, L, L, L, 0/, sdollar /'S'c, L, '|'c, L, 0/ data vert/'P'c,'Q'c,'R'c,'S'c,'T'c,'U'c,'V'c,'W'c,'X'c,'Y'c,'Z'c, '['c,'\'c,']'c,'^'c,'_'c/ if (Chunk >= MAXCHUNK) { DISABLE_BREAKS if (Outstanding_poll) # have we polled yet? WAIT_FOR_ACK else Outstanding_poll = TRUE call t1ou (ETX) # send poll character Chunk = 0 ENABLE_BREAKS } if (c == FF) { Chunk += 1 call t1ou (FF) TOP_OF_FORM Line = 1 Outstanding_lf = 0 } elif (c == NEWLINE) { Line += 1 if (Line > PAGE_LENGTH) { Chunk += 1 call t1ou (FF) TOP_OF_FORM Line = 1 Outstanding_lf = 0 } else Outstanding_lf += 1 } else { if (Outstanding_lf ~= 0) { MOVE_TO_LINE (Outstanding_lf) Outstanding_lf = 0 } select (c) when (alpha) OUTSCON (a_alpha) when (ALPHA) OUTCON (a_ALPHA) when (beta) OUTCON (a_beta) when (BETA) OUTCON (a_BETA) when (gamma) OUTSCON (a_gamma) when (GAMMA) call plotstr (sGAMMA) when (delta) OUTSCON (a_delta) when (DELTA) OUTSCON (a_DELTA) when (epsilon) OUTSCON (a_epsilon) when (EPSILON) OUTCON (a_EPSILON) when (zeta) call plotstr (szeta) when (ZETA) OUTCON (a_ZETA) when (eta) OUTSCON (a_eta) when (ETA) OUTCON (a_ETA) when (theta) call plotstr (stheta) when (THETA) call plotstr (sTHETA) when (iota) call plotstr (siota) when (IOTA) OUTCON (a_IOTA) when (kappa) OUTCON ('k'c) when (KAPPA) OUTCON ('K'c) when (lambda) OUTSCON (a_lambda) when (LAMBDA) call plotstr (sLAMBDA) when (mu) OUTCON (a_mu) when (MU) OUTCON (a_MU) when (nu) call plotstr (snu) when (NU) OUTCON (a_NU) when (xi) OUTSCON (a_xi) when (XI) call plotstr (sXI) when (omicron) OUTCON (a_omicron) when (OMICRON) OUTCON (a_OMICRON) when (pi) OUTCON (a_pi) when (PI) call plotstr (sPI) when (rho) OUTSCON (a_rho) when (RHO) OUTCON (a_RHO) when (sigma) OUTSCON (a_sigma) when (SIGMA) OUTDCHAR (PNCHAR(a_tSIGMA), PSCHAR(a_bSIGMA)) when (tau) OUTSCON (a_tau) when (TAU) OUTCON (a_TAU) when (upsilon) call plotstr (supsilon) when (UPSILON) OUTCON ('Y'c) when (phi) call plotstr (sphi) when (PHI) call plotstr (sPHI) when (chi) call plotstr (schi) when (CHI) OUTCON (a_CHI) when (psi) call plotstr (spsi) when (PSI) call plotstr (sPSI) when (omega) OUTSCON (a_omega) when (OMEGA) OUTCON (a_OMEGA) when (infinity) OUTSCON (a_infinity) when (integral) OUTCON (a_integral) when (INTEGRAL) OUTDCHAR (PSCHAR(a_tintegral), PNCHAR(a_bintegral)) when (largerbrace) OUTDCHAR (PNCHAR (a_trbrace), PSCHAR (a_brbrace)) when (largelbrace) OUTDCHAR (PNCHAR (a_tlbrace), PSCHAR (a_blbrace)) when (tilde) OUTSCON (a_tilde) when (backslash) OUTSCON (a_backslash) when (uparrow) OUTSCON (a_uparrow) when (downarrow) OUTSCON (a_downarrow) when (nabla) call plotstr (snabla) when (not) call plotstr (snot) when (partial) OUTSCON (a_partial) when (proportional) OUTSCON (a_proportional) when (psset) call plotstr (spsset) when (sset) call plotstr (ssset) when (le) call plotstr (sle) when (ge) call plotstr (sge) when (imp) call plotstr (simp) when (exist) call plotstr (sexist) when (nexist) call plotstr (snexist) when (univ) call plotstr (suniv) when (OR) call plotstr (sor) when (AND) call plotstr (sand) when (ne) call plotstr (sne) when (iso) call plotstr (siso) when (apeq) call plotstr (sapeq) when (lfloor) OUTSCON (a_lfloor) when (rfloor) OUTSCON (a_rfloor) when (lceil) OUTCON (a_lceil) when (rceil) OUTCON (a_rceil) when (small0) OUTSCON (a_small0) when (small1) OUTSCON (a_small1) when (small2) OUTSCON (a_small2) when (small3) OUTSCON (a_small3) when (small4) OUTSCON (a_small4) when (small5) OUTSCON (a_small5) when (small6) OUTSCON (a_small6) when (small7) OUTSCON (a_small7) when (small8) OUTSCON (a_small8) when (small9) OUTSCON (a_small9) when (scolon) call plotstr (sscolon) when (dquote) call plotstr (sdquote) when (dollar) call plotstr (sdollar) when (rlf) { call t1ou (ESC) call t1ou ('9'c) } when (hlf) { call t1ou (ESC) call t1ou (']'c) call t1ou ('S'c) if (Direction == FORWARD) { call t1ou (LF) Chunk += 4 } else { call t1ou (ESC) call t1ou ('9'c) Chunk += 5 } RESTORE_NORMAL_SPACING } when (rhlf) { call t1ou (ESC) call t1ou (']'c) call t1ou ('S'c) if (Direction == FORWARD) { call t1ou (ESC) call t1ou ('9'c) Chunk += 5 } else { call t1ou (LF) Chunk += 4 } RESTORE_NORMAL_SPACING } else if (c >= 8r020 & c <= 8r037) { # change vertical spacing Formadvance = vert (c - 8r017) SET_VERTICAL_SPACING } else OUTCON (c) } return end # plotstr --- output special character plot string subroutine plotstr (str) integer str (ARB) include SPRINT_COMMON integer i DISABLE_BREAKS # so Spinwriter isn't left in plot mode ENTER_PLOT_MODE if (Direction == REVERSE) { call t1ou (ESC) call t1ou (FWD) Chunk += 2 } for (i = 1; str (i) ~= 0; i += 1) { if (Chunk >= MAXCHUNK) { if (Outstanding_poll) WAIT_FOR_ACK else Outstanding_poll = TRUE call t1ou (ETX) # send poll Chunk = 0 } if (str (i) == U) { call t1ou (ESC) call t1ou ('9'c) Chunk += 2 } else { call t1ou (str (i)) Chunk += 1 } } if (Direction == REVERSE) { call t1ou (ESC) call t1ou (BKWD) Chunk += 2 } EXIT_PLOT_MODE ENABLE_BREAKS return end # position_horizontally --- generate an absolute horiz. tab subroutine position_horizontally (pos) integer pos character second_key, third_key (32) data third_key/'@'c, 'A'c, 'B'c, 'C'c, 'D'c, 'E'c, 'F'c, 'G'c, 'H'c, 'I'c, 'J'c, 'K'c, 'L'c, 'M'c, 'N'c, 'O'c, 'P'c, 'Q'c, 'R'c, 'S'c, 'T'c, 'U'c, 'V'c, 'W'c, 'X'c, 'Y'c, 'Z'c, '['c, '\'c, ']'c, '^'c, '_'c/ if (pos <= 32) second_key = 'P'c elif (pos <= 64) second_key = 'Q'c elif (pos <= 96) second_key = 'R'c elif (pos <= 128) second_key = 'S'c elif (pos <= 160) second_key = 'T'c else second_key = 'U'c call t1ou (ESC) call t1ou (second_key) call t1ou (third_key (mod (pos - 1, 32) + 1)) return end # position_vertically --- generate an relative vertical tab subroutine position_vertically (pos) integer pos integer p character second_key, third_key, tk (32) data tk/'@'c, 'A'c, 'B'c, 'C'c, 'D'c, 'E'c, 'F'c, 'G'c, 'H'c, 'I'c, 'J'c, 'K'c, 'L'c, 'M'c, 'N'c, 'O'c, 'P'c, 'Q'c, 'R'c, 'S'c, 'T'c, 'U'c, 'V'c, 'W'c, 'X'c, 'Y'c, 'Z'c, '['c, '\'c, ']'c, '^'c, '_'c/ p = pos repeat { if (p <= 31) { second_key = 'Z'c third_key = tk (p + 1) p = 0 } else { second_key = '['c if (p <= 63) { third_key = tk (mod (p, 32) + 1) p = 0 } else { third_key = tk (32) p -= 63 } } call t1ou (ESC) call t1ou (second_key) call t1ou (third_key) } until (p == 0) return end # quit_unit --- on-unit for the QUIT$ condition subroutine quit_unit (cp) longint cp include SPRINT_COMMON call t1ou (NEWLINE) call pl1$nl (Quit_label) return end # set_delay --- set terminal delay characteristics subroutine set_delay (minimum, maximum, slope) integer minimum, maximum, slope character cmd (MAXLINE) call encode (cmd, MAXLINE, "*,-8udelay *i *i *i"s, minimum, maximum, slope) call sys$$ (cmd, ERR) return end