-- PrintBravo.mesa; edited by Johnsson on June 25, 1980 9:22 AM
-- converted to Laurel by Ken Pier, July 30, 1981 11:21 AM
-- last edited by Ken Pier, 21 Aug. 1981 10:29 am PDT (Friday)
-- converted to Laurel 6.1 by Ken Pier,May 17, 1983 12:05 PM
DIRECTORY
PrintDefs,
Press USING [
Character, GetCurrentPosition, Mica, SetCurrentFont, SetCurrentTabWidth,
SkipSomeSpace],
VMDefs: FROM "VMDefs" USING [FileHandle],
csD: FROM "CoreStreamDefs";
PrintBravo: PROGRAM IMPORTS PrintDefs, Press, csD EXPORTS PrintDefs =
BEGIN
controlZ: CHARACTER = 32C;
endOfFile: CHARACTER = LAST[CHARACTER];
TAB: CHARACTER = 11C;
return: CHARACTER = 15C;
backSlash: CHARACTER = '\;
defaultLM: Press.Mica = 2998;
scanSH: csD.StreamHandle ← NIL;
copySH: csD.StreamHandle ← NIL;
bold: BOOLEAN;
italic: BOOLEAN;
graphic: BOOLEAN;
visible: BOOLEAN;
underline: BOOLEAN;
leftMargin: INTEGER;
firstLineLeftMargin: INTEGER;
rightMargin: INTEGER;
font: INTEGER;
setTabs: BOOLEAN;
tabs: ARRAY [0..15] OF CARDINAL;
newParagraph: BOOLEAN;
charactersInParagraph: INTEGER;
char: CHARACTER;
NotAtEnd: PROCEDURE[s: csD.StreamHandle] RETURNS [BOOLEAN] =
BEGIN RETURN[csD.GetLength[s] > csD.GetPosition[s]] END;
Get: PROCEDURE RETURNS [c: CHARACTER] =
BEGIN
eos: BOOLEAN ← FALSE;
c ← csD.Read[scanSH ! csD.EndOfStream => {c ← endOfFile; CONTINUE;};];
END;
CollectSuffixedInteger: PROCEDURE [c: CHARACTER] RETURNS [INTEGER] =
BEGIN
local: INTEGER ← 0;
IF c IN ['0..'9] THEN -- to avoid harm to char --
BEGIN
char ← c;
WHILE char IN ['0..'9] DO
local ← local*10 + (char - '0); char ← Get[]; ENDLOOP;
END;
RETURN[local];
END;
IndentStuff: PROCEDURE =
BEGIN
k: INTEGER ← IF newParagraph THEN firstLineLeftMargin ELSE leftMargin;
k ← k - defaultLM;
IF k < 1 THEN RETURN;
Press.SkipSomeSpace[k];
RETURN;
END;
FontStuff: PROCEDURE =
BEGIN
Press.SetCurrentFont[
font, (IF bold THEN bold ELSE medium),
(IF italic THEN italic ELSE regular)];
RETURN;
END;
SetTab: PROCEDURE =
BEGIN
stop, value: CARDINAL;
char ← Get[];
IF char IN ['0..'9] THEN stop ← char - '0 ELSE stop ← char - 'a;
char ← Get[];
IF char = ', THEN
BEGIN
value ← MAX[0, CollectSuffixedInteger[Get[]]];
tabs[stop] ← value;
setTabs ← TRUE;
END
ELSE -- uniform tabs
BEGIN
value ← stop;
WHILE char IN ['0..'9] DO
value ← value*10 + (char - '0); char ← Get[]; ENDLOOP;
Press.SetCurrentTabWidth[value];
setTabs ← FALSE;
END;
UNTIL char = ') DO char ← Get[] ENDLOOP;
char ← Get[];
RETURN;
END;
AdvanceToTab: PROCEDURE =
BEGIN
x: Press.Mica ← Press.GetCurrentPosition[].x + defaultLM;
FOR stop: CARDINAL IN [0..15] DO
IF tabs[stop] # LAST[CARDINAL] AND tabs[stop] > CARDINAL[x] THEN
{Press.SkipSomeSpace[tabs[stop] - x]; EXIT};
REPEAT FINISHED => Press.Character[TAB];
ENDLOOP;
RETURN;
END;
BravoIt: PUBLIC PROCEDURE [fh: VMDefs.FileHandle] =
BEGIN
j: INTEGER;
tempPos: csD.Position;
c: CHARACTER;
setTabs ← FALSE;
tabs ← ALL[LAST[CARDINAL]];
scanSH ← csD.Open[fh, byte, read];
copySH ← csD.Open[fh, byte, read];
BEGIN ENABLE UNWIND => BEGIN scanSH ← PrintDefs.DestroyS[scanSH];
copySH ← PrintDefs.DestroyS[copySH]; END;
IF ~NotAtEnd[scanSH] THEN RETURN;
charactersInParagraph ← 0;
char ← Get[]; -- need a running start --
WHILE NotAtEnd[scanSH] DO
newParagraph ← TRUE;
Press.Character[return]; -- return before every para, even first --
italic ← bold ← graphic ← visible ← underline ← FALSE;
leftMargin ← firstLineLeftMargin ← defaultLM;
font ← 0;
tempPos ← csD.GetPosition[scanSH] - 1;
csD.SetPosition[copySH, tempPos]; -- for the later copy --
UNTIL char = controlZ OR char = endOfFile DO
charactersInParagraph ← charactersInParagraph + 1; char ← Get[]; ENDLOOP;
WHILE char # backSlash AND char # return AND char # endOfFile DO
SELECT char FROM
'l => leftMargin ← CollectSuffixedInteger['0];
'd => firstLineLeftMargin ← CollectSuffixedInteger['0];
'r => rightMargin ← CollectSuffixedInteger['0];
'( => SetTab[];
ENDCASE => char ← Get[];
ENDLOOP;
IF char = backSlash THEN
BEGIN
WHILE char # return AND char # endOfFile DO
SELECT char FROM
'b => BEGIN bold ← TRUE; char ← Get[]; END;
'B => BEGIN bold ← FALSE; char ← Get[]; END;
'i => BEGIN italic ← TRUE; char ← Get[]; END;
'I => BEGIN italic ← FALSE; char ← Get[]; END;
'g => BEGIN graphic ← TRUE; char ← Get[]; END;
'G => BEGIN graphic ← FALSE; char ← Get[]; END;
'v => BEGIN visible ← TRUE; char ← Get[]; END;
'V => BEGIN visible ← FALSE; char ← Get[]; END;
'u => BEGIN underline ← TRUE; char ← Get[]; END;
'U => BEGIN underline ← FALSE; char ← Get[]; END;
'f => font ← CollectSuffixedInteger['0];
'o => -- skip for now --[] ← CollectSuffixedInteger['0];
'0, '1, '2, '3, '4, '5, '6, '7, '8, '9 =>
BEGIN
j ← CollectSuffixedInteger[char];
-- have new run ... first set in ↑ stuff: --
IF newParagraph THEN IndentStuff[];
newParagraph ← FALSE;
FontStuff[];
THROUGH [0..j) DO
IF charactersInParagraph > 0 THEN
BEGIN
c ← csD.Read[copySH];
IF c = TAB AND setTabs THEN AdvanceToTab[]
ELSE Press.Character[c];
IF c = return THEN IndentStuff[];
charactersInParagraph ← charactersInParagraph - 1;
END;
ENDLOOP;
END;
ENDCASE => char ← Get[];
ENDLOOP;
END;
IF char = return THEN char ← Get[];
IF charactersInParagraph > 0 THEN
BEGIN
IF newParagraph THEN IndentStuff[];
newParagraph ← FALSE;
FontStuff[];
WHILE charactersInParagraph > 0 DO
c ← csD.Read[copySH];
IF c = TAB AND setTabs THEN AdvanceToTab[] ELSE Press.Character[c];
IF c = return THEN IndentStuff[];
charactersInParagraph ← charactersInParagraph - 1;
ENDLOOP;
END;
ENDLOOP;
scanSH ← PrintDefs.DestroyS[scanSH];
copySH ← PrintDefs.DestroyS[copySH];
END;--of ENABLED UNWIND block
END;--of PROC BravoIt
END...