PACKET std printer DEFINES reset printer, (* F. Klapper *) new page, (* 21.05.84 *) start, printer cmd, on, off, material, papersize, limit, change type, print text, x pos, y pos, line: LET begin mark cmd = ""15"", (* Kommandos für 'output buffer' *) end mark cmd = ""14"", bsp cmd = ""8"" , printercmd cmd = ""16"", begin mark code = 15, end mark code = 14, bsp code = 8, printercmd code = 16, cr = ""13"", (* Steuerzeichen für die Ausgabe *) lf = ""10"", underline char = "_", inch = 2.54, (* Konstanten *) max printer cmds per line = 10; INT CONST std length of paper :: 12 * y factor per inch, std width of paper :: cm to x steps (13.2 * inch), std limit :: cm to x steps (12.0 * inch), std first line :: 5, std first collumn :: cm to x steps (inch), no xpos :: - 10; (* beliebige negative ganze Zahl *) INT VAR first collumn, first line, xlimit, actual line, x pos steps, width of paper, length of paper, x pos mode; BOOL VAR block mode, underline on, (* gibt durch on / off gesetzten Zustand an *) underline out; (* gibt Zustand an der bis jetzt durch output buffer ausgegebenen Stelle an *) TEXT VAR buffer, x pos buffer, left margin; ROW max printer cmds per line TEXT VAR cmd arry; INT VAR cmd pointer; length of paper := std length of paper; first line := std first line; actual line := 0; buffer := ""; reset printer; INT PROC cm to x steps (REAL CONST cm): int ((abs (cm) * real (x factor per inch) / inch) + 0.5) END PROC cm to x steps; INT PROC cm to y steps (REAL CONST cm): int ((abs (cm) * real (y factor per inch) / inch) + 0.5) END PROC cm to y steps; PROC start (REAL CONST x, y): first collumn := cm to x steps (x); first line := cm to y steps (y); left margin := first collumn * " " END PROC start; PROC papersize (REAL CONST w, l): width of paper := cm to x steps (w); length of paper := cm to y steps (l); END PROC papersize; PROC limit (REAL CONST x): xlimit := cm to x steps (x); END PROC limit; PROC on (TEXT CONST attribute): IF (attribute SUB 1) = "u" THEN underline on := TRUE; buff CAT begin mark cmd FI. buff: IF xpos steps >= 0 THEN x pos buffer ELSE buffer FI. END PROC on; PROC off (TEXT CONST attribute): IF (attribute SUB 1) = "u" THEN underline on := FALSE; buff CAT end mark cmd FI. buff: IF xpos steps >= 0 THEN x pos buffer ELSE buffer FI. END PROC off; PROC printer cmd (TEXT CONST cmd): IF cmd pointer < max printer cmds per line THEN cmd pointer INCR 1; cmd arry (cmd pointer) := cmd; buff CAT printercmd cmd FI. buff: IF xpos steps >= 0 THEN x pos buffer ELSE buffer FI. END PROC printer cmd; PROC material (TEXT CONST name of material): END PROC material; PROC change type (TEXT CONST name of type): ENDPROC change type; PROC reset printer : new page; (* actual line := 0 *) width of paper := std width of paper; length of paper := std length of paper; first line := std first line; first collumn := std first collumn; xlimit := std limit; xpos mode := 0; cmd pointer := 0; x pos steps := no x pos; buffer := ""; xpos buffer := ""; left margin := first collumn * " "; block mode := FALSE; underline on := FALSE; underline out := FALSE; ENDPROC reset printer; PROC print text (TEXT CONST content, INT CONST mode): IF x pos steps >= 0 THEN x pos buffer CAT content; x pos mode := mode MOD 4; block mode := FALSE ELSE buffer CAT content ; block mode := (mode MOD 4) = 3 FI. END PROC print text; PROC tab and print: SELECT x pos mode OF CASE 0: fill (buffer, " ", x pos steps); CASE 1: fill (buffer, " ", x pos steps - outputlength (x pos buffer)); CASE 2: fill (buffer, " ", x pos steps - outputlength (xpos buffer) DIV 2); CASE 3: fill (buffer, " ", x pos steps); block (x pos buffer, xlimit - x pos steps); OTHERWISE END SELECT; buffer CAT x pos buffer; x pos buffer := ""; x pos steps := no x pos. END PROC tab and print; INT PROC outputlength (TEXT CONST buff): length (buff) - chars (buff, printercmd cmd) - chars (buff, begin mark cmd) - chars (buff, end mark cmd) - chars (buff, bsp cmd) * 2 END PROC outputlength; PROC x pos (REAL CONST cm): IF x pos steps >= 0 THEN tab and print FI; IF underline on THEN buffer CAT end mark cmd; x pos buffer CAT begin mark cmd FI; x pos steps := cm to x steps (cm) END PROC x pos; PROC y pos (REAL CONST cm): IF actual line = 0 THEN output linefeed (first line - actual line); actual line := first line FI; output buffer; INT VAR y lf steps := cm to y steps (cm); output linefeed (y lf steps + first line - actual line); actual line := first line + y lf steps. END PROC y pos; PROC line (REAL CONST proposed lf) : IF actual line = 0 THEN output linefeed (first line - actual line); actual line := first line FI; output buffer; INT VAR done lf; convert into min y steps (proposed lf, done lf); output line feed (done lf); actual line INCR done lf; END PROC line; PROC convert into min y steps (REAL CONST in, INT VAR out): IF in < 0.001 THEN out := 0 ELSE out := int (in); IF out < 1 THEN out := 1 FI FI; ENDPROC convert into min y steps; PROC new page: IF buffer <> "" THEN line (1.0) FI; actual line := actual line MOD length of paper; IF actual line > first line THEN output pagefeed (length of paper - actual line); actual line := 0 FI; END PROC new page; PROC output buffer: IF x pos steps >= 0 THEN tab and print ELIF block mode THEN block (buffer, xlimit) FI ; TEXT VAR bsp buffer := "", underline buffer := ""; INT VAR cmd pos := pos (buffer, ""1"", ""31"", 1), akt cmd pointer := 0, soon out := 0; out (left margin); put leading blanks not underlined; WHILE cmd pos > 0 REP analyze cmd; cmd pos := pos (buffer, ""1"", ""31"", cmd pos) PER; IF underline out THEN fill (underline buffer, underline char, LENGTH buffer) FI; out buffer; out bsp buffer; out underline buffer; buffer := ""; cmd pointer := 0. put leading blanks not underlined: IF underline out THEN INT VAR first non blank pos := pos (buffer, ""33"", ""254"", 1); IF cmd pos > 0 CAND first non blank pos > 0 THEN fill (underline buffer, " ", min (first non blank pos, cmd pos) - 1) ELIF cmd pos > 0 THEN fill (underline buffer, " ", cmd pos - 1) ELSE fill (underline buffer, " ", first non blank pos -1) FI; FI. analyze cmd: SELECT code (buffer SUB cmd pos) OF CASE bsp code : do bsp cmd CASE begin mark code : do begin mark cmd CASE end mark code : do end mark cmd CASE printercmd code : do printercmd cmd OTHERWISE END SELECT. do bsp cmd: fill (bsp buffer, " ", cmd pos - 2); cmd pos DECR 1; bsp buffer CAT (buffer SUB cmd pos); delete char (buffer, cmd pos); delete char (buffer, cmd pos). do begin mark cmd: IF NOT underline out THEN underline out := TRUE; fill (underline buffer, " ", cmd pos -1); delete char (buffer, cmd pos) FI. do end mark cmd: IF underline out THEN underline out := FALSE; fill (underline buffer, underline char, cmd pos - 1); delete char (buffer, cmd pos) FI. do printercmd cmd: IF akt cmd pointer < cmd pointer THEN akt cmd pointer INCR 1; out subtext (buffer, soon out + 1, cmd pos - 1); soon out := cmd pos - 1; delete char (buffer, cmd pos); out (cmd arry (akt cmd pointer)) FI. out buffer: (* out (left margin) steht schon weiter oben *) outsubtext (buffer, soon out + 1). out bsp buffer: IF bsp buffer <> "" THEN out (cr); out (left margin); out (bsp buffer) FI. out underline buffer: IF underline buffer <> "" THEN out (cr); out (left margin); out (underline buffer) FI. END PROC output buffer; PROC fill (TEXT VAR buff, TEXT CONST char, INT CONST len): buff CAT (len - outputlength (buff)) * char END PROC fill; PROC output linefeed (INT CONST min y steps): IF min y steps > 0 THEN out (cr); out (min y steps * lf) FI ENDPROC output linefeed ; PROC output pagefeed (INT CONST rest) : out (cr) ; rest TIMESOUT lf ENDPROC output pagefeed ; (********************* B L O C K **********************************) LET blank = " " , enumeration list = "-).:" ; INT VAR to insert, nr of blanks , nr of big spaces , begin ; TEXT VAR small space , big space ; BOOL VAR right := TRUE ; PROC block (TEXT VAR blockline, INT CONST len): to insert := len - outputlength (blockline); nr of blanks := 0; begin:=0; IF to insert <= 0 THEN LEAVE block FI; IF to insert > (xlimit DIV 3 ) THEN LEAVE block FI; mark the variable blanks; IF nr of blanks <= 0 THEN LEAVE block FI; right := NOT right; compute spaces; insert spaces. mark the variable blanks: skip blanks ; begin := pos(blockline,blank,begin+1); IF (pos (enumeration list, (blockline SUB (begin-1))) > 0 ) THEN skip blanks ; begin := pos(blockline,blank,begin+1); FI; WHILE begin > 0 REP IF single blank gap THEN change (blockline,begin,begin,""0""); nr of blanks INCR 1; ELSE skip blanks FI; begin := pos(blockline,blank,begin+1); ENDREP. single blank gap : ((blockline SUB (begin+1)) <> blank). skip blanks : begin := pos (blockline, ""33"", ""254"", begin+1) . compute spaces: INT VAR steps := to insert ; INT VAR small := steps DIV nr of blanks; nr of big spaces := steps MOD nr of blanks; small space := (small+1) * blank ; big space := small space ; big space CAT blank . insert spaces: IF right THEN insert big spaces on right side ELSE insert big spaces on left side FI. insert big spaces on right side: INT VAR nr of small spaces := nr of blanks - nr of big spaces; INT VAR i; FOR i FROM 1 UPTO nr of small spaces REP change (blockline, ""0"",small space) ENDREP; changeall (blockline,""0"",big space). insert big spaces on left side: INT VAR j; FOR j FROM 1 UPTO nr of big spaces REP change (blockline,""0"",big space) ENDREP; changeall (blockline,""0"",small space). ENDPROC block; INT PROC chars (TEXT CONST text, char) : INT VAR how many := 0 , cmd pos := pos (text, char) ; WHILE cmd pos > 0 REP how many INCR 1 ; cmd pos := pos (text, char, cmd pos+1) PER ; how many ENDPROC chars ; ENDPACKET std printer ;