-- PrintFormat.mesa; edited by Johnsson on 17-Apr-81 9:16:44 -- edited by Paul Rovner on 6-Jan-82 19:30:07 -- edited by Michael Plass on August 27, 1982 5:31 pm DIRECTORY Ascii USING [ControlZ, CR, FF, NUL, SP, TAB], PrintOps USING [ParametersHandle, PressProcsHandle], Press USING [FontSlope, FontWeight, Mica, pageHeight, pageWidth]; PrintFormat: PROGRAM EXPORTS PrintOps = BEGIN DataEnd: PUBLIC SIGNAL = CODE; Mica: TYPE = Press.Mica; ComputeLineWidth: PROCEDURE [p: PrintOps.ParametersHandle] RETURNS [width: Mica] = BEGIN SELECT p.mode FROM portrait => width ← Press.pageWidth - p.margins[right] - p.margins[left]; landscape => width ← Press.pageHeight - p.margins[top] - p.margins[bottom]; ENDCASE => ERROR; width ← width - (p.columns - 1)*(p.betweenColumns); width ← LOOPHOLE[width, CARDINAL]/p.columns; RETURN END; Data: TYPE = RECORD [ b: STRING, procs: PrintOps.PressProcsHandle, getChar: PROCEDURE RETURNS [CHARACTER], spaceWidth: Mica, bol: BOOLEAN ← TRUE, i, whiteLength: CARDINAL ← 0, curX, bWidth: Mica ← 0, indentWidth, charWidth, whiteWidth: Mica ← NULL]; data: POINTER TO Data ← NIL; Format: PUBLIC PROCEDURE [ getChar: PROCEDURE RETURNS [CHARACTER], procs: PrintOps.PressProcsHandle, p: PrintOps.ParametersHandle] RETURNS [lastPage: CARDINAL] = BEGIN char: CHARACTER; ignoring: BOOLEAN ← FALSE; localb: STRING ← [250]; lineWidth: Mica = ComputeLineWidth[p]; localData: Data ← [ b: localb, procs: procs, getChar: getChar, spaceWidth: procs.GetWidthOfCharacter[Ascii.SP]]; tabWidth: Mica = localData.spaceWidth*p.tab; data ← @localData; DO OPEN localData; char ← getChar[ ! DataEnd => EXIT]; IF ignoring AND char # Ascii.CR AND char # Ascii.FF THEN LOOP; SELECT char FROM Ascii.SP => BEGIN IF bol THEN BEGIN curX ← curX + spaceWidth; LOOP END; whiteLength ← i; whiteWidth ← bWidth; IF curX + spaceWidth > lineWidth THEN BEGIN Overflow[]; LOOP END; END; Ascii.CR, Ascii.FF => BEGIN PutPiece[]; procs.Character[char]; bol ← TRUE; indentWidth ← curX ← 0; ignoring ← FALSE; LOOP END; Ascii.TAB => BEGIN IF bol THEN BEGIN curX ← (((curX + spaceWidth)/tabWidth) + 1)*tabWidth; LOOP END; PutPiece[]; procs.Character[char]; curX ← procs.GetCurrentPosition[].x; LOOP END; Ascii.ControlZ => BEGIN PutPiece[]; UNTIL char = Ascii.CR DO char ← getChar[ ! DataEnd => EXIT]; ENDLOOP; procs.Character[char]; bol ← TRUE; indentWidth ← curX ← 0; LOOP END; Ascii.NUL => BEGIN PutPiece[]; char ← getChar[ ! DataEnd => EXIT]; IF char = Ascii.NUL THEN EXIT; LOOP END; '\\ => IF p.nonprog THEN {ProcessLooks[!DataEnd => CONTINUE]; LOOP} ELSE CheckBol[]; 'a,'b,'c,'d,'e,'f,'g,'h,'i,'j,'k,'l,'m,'n,'o,'p,'q,'r,'s,'t,'u,'v,'w,'x,'y,'z, 'A,'B,'C,'D,'E,'F,'G,'H,'I,'J,'K,'L,'M,'N,'O,'P,'Q,'R,'S,'T,'U,'V,'W,'X,'Y,'Z, '1,'2,'3,'4,'5,'6,'7,'8,'9,'0,'!,'@,'#,'$,'%,'~,'&,'*,'(,'),'-,'=,'+,'|,'←,'↑, '[,'],'←,'{,'},'↑,';,':,'','",',,'.,'/,'<,'>,'? => CheckBol[]; ENDCASE => CheckBol[]; charWidth ← procs.GetWidthOfCharacter[char]; IF curX + charWidth > lineWidth THEN IF p.wrap THEN Overflow[] ELSE {ignoring ← TRUE; LOOP}; IF i = b.maxlength THEN PutPiece[]; b[i] ← char; b.length ← i ← i + 1; bWidth ← bWidth + charWidth; curX ← curX + charWidth; ENDLOOP; PutPiece[]; lastPage ← procs.GetCurrentPageNumber[]; data ← NIL; RETURN END; CheckBol: PROCEDURE = INLINE { OPEN data; IF bol THEN { IF (indentWidth ← curX) # 0 THEN procs.SkipSomeSpace[indentWidth]; bol ← FALSE}}; ProcessLooks: PROCEDURE = BEGIN OPEN data; c: CHARACTER ← getChar[]; SELECT c FROM 'f => { font: CARDINAL; weight: Press.FontWeight ← medium; slope: Press.FontSlope ← regular; PutPiece[]; font ← getChar[] - '0; UNTIL (c ← getChar[]) = '\\ DO SELECT c FROM 'b => weight ← bold; 'i => slope ← italic; ENDCASE ENDLOOP; procs.SetCurrentFont[font, weight, slope]}; ENDCASE => {CheckBol[]; RETURN}; END; PutPiece: PROCEDURE = BEGIN OPEN data; IF i # 0 THEN BEGIN procs.PieceOfLine[b, bWidth]; bWidth ← 0; b.length ← i ← whiteLength ← 0; END; END; Overflow: PROCEDURE = BEGIN OPEN data; IF whiteLength = 0 OR whiteLength = b.length THEN BEGIN PutPiece[]; procs.Character[Ascii.CR] END ELSE BEGIN b.length ← whiteLength; procs.PieceOfLine[b, whiteWidth]; procs.Character[Ascii.CR]; bWidth ← bWidth - whiteWidth - spaceWidth; b.length ← i - whiteLength - 1; FOR j: CARDINAL IN [0..b.length) DO b[j] ← b[whiteLength + j + 1]; ENDLOOP; i ← b.length; whiteLength ← 0; END; IF indentWidth # 0 THEN procs.SkipSomeSpace[indentWidth]; curX ← indentWidth + bWidth; END; END... Michael Plass on August 27, 1982 5:31 pm: Put in check for double nulls to ignore Tioga formatting.