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