-- 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.