[INHERIT('SCREENHANDLERS','UTILITYOPS','ARGOPS', 'TREEANDLISTOPS','FLAGOPS','CONVERSION'), environment('dsrops')] MODULE DSROPS; CONST indexofpagecommand = 38; VAR totallines : [EXTERNAL] integer; totalgooddsrcommands : [EXTERNAL] integer; totalbaddsrcommands : [EXTERNAL] integer; [GLOBAL] FUNCTION listispagecommand( list : arglist ) : boolean; var s : pckstr; begin listispagecommand := false; if arglistlength(list) = 1 then begin s := argliteral(firstarg(list), TRUE ); if s = 'PAGE' then listispagecommand := true end end; [GLOBAL] PROCEDURE checkfordsrcommand( var infile, outfile : text; var dsrcommand : boolean ); var gotten : boolean; begin if flagclass(currentchar) = control then begin getnextchar(infile, gotten); if gotten then begin if (flagclass(currentchar) <> comment) and (currentchar <> blank) then dsrcommand := true end else begin dsrcommand := false; texwrite(outfile, currentchar) end end else dsrcommand := false end; [GLOBAL] PROCEDURE parsedsrcommand( var infile, outfile : text; var list : arglist; var anothercommand : boolean; var carrychar : boolean; var charcarried : char); const dontwritethem = false; type charidentity = (letter, separator, number, semicolon, quote, commentchar,newdsrcommand); var quotedchar : char; argread : argument; currentargclass : charidentity; done, gotten, atseparator, endofdsrcommand : boolean; i : integer; function charclass( ch : char ) : charidentity; label localexit; begin charclass := separator; if flagclass( ch ) = control then begin charclass := newdsrcommand; goto localexit end; if ch in ['a'..'z','A'..'Z'] then begin charclass := letter; goto localexit end; if ch in ['+','-','0'..'9'] then begin charclass := number; goto localexit end; if ch in [chr(34), chr(39)] then begin charclass := quote; goto localexit end; if flagclass(currentchar) = comment then begin charclass := commentchar; goto localexit end; if ch = ';' then charclass := semicolon; localexit : nullstatement end; procedure startarg( ch : char; var arg : argument; startset : setofargtype); begin initarg(arg, startset, ch, indexofunknowntexcommand, false); end; begin list := nulllist; atseparator := false; endofdsrcommand := false; anothercommand := false; carrychar := false; repeat currentargclass := charclass(currentchar); case currentargclass of letter : begin atseparator := false; startarg(currentchar, argread, [dsrverb,stylespecifier, textpckstr,character]); done := false; repeat getnextchar(infile, gotten); if gotten then begin if charclass(currentchar) = letter then appendchartoarg(currentchar, argread) else done := true end else begin done := true; endofdsrcommand := true end until done; appendargonlist(list, argread ) end; number : begin atseparator := false; startarg(currentchar, argread, [int,signedint,textpckstr,nulltype]); done := false; repeat getnextchar(infile, gotten); if gotten then begin if charclass(currentchar) = number then appendchartoarg(currentchar, argread) else done := true end else begin done := true; endofdsrcommand := true end until done; appendargonlist(list, argread ) end; separator : begin passblanks(infile, outfile, dontwritethem); if (atseparator) and (currentchar <> lastinputchar) then begin startarg(blank, argread, [nulltype]); appendargonlist(list, argread); atseparator := false end else begin if flagclass(currentchar) = control then endofdsrcommand := true else if charclass(currentchar) = separator then begin getnextchar(infile, gotten); if gotten then atseparator := true else begin atseparator := false; startarg(blank, argread, [nulltype]); appendargonlist(list, argread); endofdsrcommand := true end end end end; semicolon : begin endofdsrcommand := true; getnextchar(infile, gotten); if charclass(currentchar) = newdsrcommand then currentargclass := newdsrcommand else begin carrychar := true; charcarried := currentchar end end; quote : begin quotedchar := currentchar; getnextchar(infile, gotten); if gotten then begin startarg(currentchar, argread, [quotedpckstr]); done := false; repeat getnextchar(infile, gotten); if gotten then begin if charclass(currentchar) = quote then begin getnextchar(infile, gotten); done := true; if not gotten then endofdsrcommand := true end else appendchartoarg(currentchar, argread) end else begin endofdsrcommand := true; done := true end until done end else startarg(quotedchar, argread,[textpckstr,character]); appendargonlist(list, argread) end; commentchar : begin endofdsrcommand := true end; newdsrcommand : begin endofdsrcommand := true; end end; {case} until endofdsrcommand; if currentargclass <> newdsrcommand then newline( infile, outfile, false) else anothercommand := true end; PROCEDURE parsefile( var infile, outfile : text; textree : argtree ); const nocrlf = false; putcrlf = true; var dsrcommandfound : boolean; chargotten : boolean; dsrarguments : arglist; texcommandindex : integer; nextcommandtowrite : integer; successfulparse : boolean; depthofsearch : integer; anothercommand : boolean; carrychar : boolean; charcarried, copychar : char; begin ttywritestring('Translating input ...'); totalgooddsrcommands := 0; totalbaddsrcommands := 0; nextcommandtowrite := indexofunknowntexcommand; anothercommand := false; repeat putsecondarytexcommand( outfile, nextcommandtowrite); repeat checkfordsrcommand( infile, outfile, dsrcommandfound ); if dsrcommandfound then begin parsedsrcommand( infile, outfile, dsrarguments, anothercommand,carrychar,charcarried); if listispagecommand( dsrarguments) then begin successfulparse := true; texcommandindex := indexofpagecommand end else searchtreeforlist( textree, dsrarguments,successfulparse, texcommandindex, depthofsearch); if successfulparse then begin totalgooddsrcommands := totalgooddsrcommands + 1; puttexcommand(outfile, texcommandindex, dsrarguments, nextcommandtowrite); if carrychar then begin copychar := currentchar; currentchar := charcarried; writecurrentchar( infile, outfile ); currentchar := copychar end end else begin totalbaddsrcommands := totalbaddsrcommands + 1; write(outfile,'%Unidentified RUNOFF command "'); dumpthelist(outfile, dsrarguments); writeln(outfile,'"') end end else anothercommand := false until (not dsrcommandfound) and (not anothercommand); repeat writecurrentchar( infile, outfile ); getnextchar(infile, chargotten) until not chargotten; newline(infile, outfile, putcrlf) until eof(infile) end; END.