[INHERIT('UTILITYOPS','ARGOPS'), environment('flagops')] MODULE FLAGOPS; CONST tab = 9; ncharsintab = 8; TYPE dsrflagtype = record representation : char; turnedon : boolean end; dsrflagclasses = (notaflag, control, uppercase, lowercase, quote, space, underline, bold, overstrike, hyphenate, break, period, capitalize, endfootnote, comment, substitute); flagtabletype = array[dsrflagclasses] of dsrflagtype; tabrecordtype = record tabread : boolean; charcountintab : integer end; styletype = (undetermined, decimal, octal, hexidecimal, romanupper, romanlower, romanmixed, letterupper, letterlower, lettermixed, nostyle); enhancmentstates = (notenhanced, singlecharenhanced, enhancmentlocked); VAR lastinputchar, currentchar : [EXTERNAL] char; capitalizetext, lowercasetext : [EXTERNAL] boolean; inputcontainstexcommands : [EXTERNAL] boolean; inliteral : [EXTERNAL] boolean; totallines, totalchars : [EXTERNAL] integer; flagtable : [EXTERNAL] flagtabletype; tabrecord : [EXTERNAL] tabrecordtype; LOG : [EXTERNAL] text; columncounter : [EXTERNAL] integer; infootnote : [EXTERNAL] boolean; boldactive : [EXTERNAL] enhancmentstates; underlineactive : [EXTERNAL] enhancmentstates; startnofillagain : [EXTERNAL] boolean; fill : [EXTERNAL] boolean; listnestlevel : [EXTERNAL] integer; [GLOBAL] PROCEDURE beginnofill( var outfile : text ); begin if (fill) and (listnestlevel = 0) then begin writeln(outfile,'{\obeylines \obeyspaces % - begin no fill'); fill := false end else begin writeln(outfile,'% - RNOTOTEX obeylines, obeyspaces already active'); writeln( log,'% - RNOTOTEX obeylines, obeyspaces already active') end end; [GLOBAL] PROCEDURE endnofill( var outfile : text ); begin if (not fill) and (listnestlevel = 0) then begin writeln(outfile,'} % - end of no fill'); fill := true end else begin writeln(outfile,'% - RNOTOTEX obeylines, obeyspaces not active'); writeln( log,'% - RNOTOTEX obeylines, obeyspaces not active') end end; [GLOBAL] PROCEDURE writeflagname( var outfile : text; f : dsrflagclasses ); begin case f of notaflag : write(outfile,'?????'); control : write(outfile,'CONTROL'); uppercase : write(outfile,'UPPERCASE'); lowercase : write(outfile,'LOWERCASE'); quote : write(outfile,'QUOTE'); space : write(outfile,'SPACE'); underline : write(outfile,'UNDERLINE'); bold : write(outfile,'BOLD'); overstrike : write(outfile,'OVERSTRIKE'); hyphenate : write(outfile,'HYPYENATE'); capitalize : write(outfile,'CAPITALIZE'); endfootnote : write(outfile,'END FOOTNOTE'); comment : write(outfile,'COMMENT'); substitute : write(outfile,'SUBSTITUTE') end end; [GLOBAL] FUNCTION isastylespecifier( arg : argument ) : styletype; label routineexit; var s : pckstr; classification : styletype; begin s := argliteral( arg, TRUE ); classification := undetermined; if (s.body[1] = 'D') and (s.length = 1) then begin classification := decimal; goto routineexit end; if (s.body[1] = 'O') and (s.length = 1) then begin classification := octal; goto routineexit end; if (s.body[1] = 'H') and (s.length = 1) then begin classification := hexidecimal; goto routineexit end; if (s.body = 'RU') and (s.length = 2) then begin classification := romanupper; goto routineexit end; if (s.body = 'RL') and (s.length = 2) then begin classification := romanlower; goto routineexit end; if (s.body = 'RM') and (s.length = 2) then begin classification := romanmixed; goto routineexit end; if (s.body = 'LU') and (s.length = 2) then begin classification := letterupper; goto routineexit end; if (s.body = 'LL') and (s.length = 2) then begin classification := letterlower; goto routineexit end; if (s.body = 'LM') and (s.length = 2) then begin classification := lettermixed; goto routineexit end; routineexit : isastylespecifier := classification end; [GLOBAL] PROCEDURE initflagtable; var f : dsrflagclasses; begin for f := notaflag to substitute do case f of notaflag : begin flagtable[f].representation := blank; flagtable[f].turnedon := false end; control : begin flagtable[f].representation := '.'; flagtable[f].turnedon := true end; uppercase : begin flagtable[f].representation := '^'; flagtable[f].turnedon := true end; lowercase : begin flagtable[f].representation := '\'; flagtable[f].turnedon := true end; quote : begin flagtable[f].representation := '_'; flagtable[f].turnedon := true end; space : begin flagtable[f].representation := '#'; flagtable[f].turnedon := true end; underline : begin flagtable[f].representation := '&'; flagtable[f].turnedon := true end; bold : begin flagtable[f].representation := '*'; flagtable[f].turnedon := false end; overstrike : begin flagtable[f].representation := '%'; flagtable[f].turnedon := false end; hyphenate : begin flagtable[f].representation := '='; flagtable[f].turnedon := false end; break : begin flagtable[f].representation := '|'; flagtable[f].turnedon := false end; period : begin flagtable[f].representation := '+'; flagtable[f].turnedon := false end; capitalize : begin flagtable[f].representation := '<'; flagtable[f].turnedon := false end; endfootnote : begin flagtable[f].representation := '!'; flagtable[f].turnedon := false end; comment : begin flagtable[f].representation := '!'; flagtable[f].turnedon := true end; substitute : begin flagtable[f].representation := '$'; flagtable[f].turnedon := false end end { case } end; {initflagtable} [GLOBAL] FUNCTION flagclass( ch : char ) : dsrflagclasses; var class : dsrflagclasses; foundclass : boolean; begin class := control; foundclass := false; while (class <> substitute) and ( not foundclass) do if (ch = flagtable[class].representation) and (flagtable[class].turnedon)then foundclass := true else class := succ(class); if foundclass then if inliteral then if class = control then flagclass := control else flagclass := notaflag else flagclass := class else flagclass := notaflag end; [GLOBAL] PROCEDURE initcharreader(var f : text ); begin reset(f); lastinputchar := blank; read(f, currentchar); totallines := 0; totalchars := 0; columncounter := 1; if ord(currentchar) = tab then begin tabrecord.tabread := true; tabrecord.charcountintab := ncharsintab end else begin tabrecord.tabread := false; tabrecord.charcountintab := 0 end end; [GLOBAL] PROCEDURE getnextchar( var f : text; var gotten : boolean ); function nexttabcolumn( startingcolumn : integer ) : integer; var i : integer; begin i := startingcolumn; repeat i := i + 1 until (i-1) mod ncharsintab = 0; nexttabcolumn := i; writeln(log,'nexttabcolumn input = ',startingcolumn:1,', output = ',i:1) end; begin gotten := false; if NOT eof(f) then if NOT eoln(f) then with tabrecord do begin lastinputchar := currentchar; gotten := true; columncounter := columncounter + 1; if (tabread) and (charcountintab > 0) then begin currentchar := blank; charcountintab := charcountintab - 1; if charcountintab = 0 then tabread := false end else begin totalchars := totalchars + 1; read( f, currentchar ); if currentchar < blank then begin if ord(currentchar) = tab then begin tabread := true; charcountintab := nexttabcolumn( columncounter ) - columncounter-1; writeln(log,'charcountintab = ',charcountintab) end; currentchar := blank end end end end; [GLOBAL] PROCEDURE startunderline( var outfile : text; class : enhancmentstates); begin if class <> notenhanced then case underlineactive of notenhanced : begin write(outfile,'\underline{'); underlineactive := class end; singlecharenhanced : nullstatement; enhancmentlocked : nullstatement end; underlineactive := class end; [GLOBAL] PROCEDURE stopunderline( var outfile : text ); begin case underlineactive of notenhanced : nullstatement; singlecharenhanced : begin write(outfile,'} '); underlineactive := notenhanced end; enhancmentlocked : nullstatement end end; [GLOBAL] PROCEDURE startbold( var outfile : text; class : enhancmentstates); begin if class <> notenhanced then case boldactive of notenhanced : begin write(outfile,'{\bf '); boldactive := class end; singlecharenhanced : nullstatement; enhancmentlocked : nullstatement end; boldactive := class end; [GLOBAL] PROCEDURE stopbold( var outfile : text ); begin case boldactive of notenhanced : nullstatement; singlecharenhanced : begin write(outfile,'} '); boldactive := notenhanced end; enhancmentlocked : nullstatement end end; [GLOBAL] PROCEDURE passblanks( var infile, outfile : text; writethem : boolean ); var gotten, keeppassing : boolean; begin keeppassing := true; gotten := true; repeat if (currentchar = blank) and (gotten) then begin if writethem then write(outfile, blank ); getnextchar(infile, gotten) end else keeppassing := false until NOT keeppassing end; [GLOBAL] PROCEDURE texwrite( var f : text; ch : char ); const maxtrys = 2; var ntrys : integer; written : boolean; begin ntrys := 0; written := false; repeat if (inputcontainstexcommands) or (inliteral) then write(f, ch, error := continue) else if ch >= blank then if ch in ['#','$','%','&','_','^','{','}','~'] then write(f, '\',ch, error := continue) else if ch = '\' then write(f,'\backslash ', error := continue) else write(f, ch, error := continue); if status(f) > 0 then begin writeln(f, error := continue); ntrys := ntrys + 1 end else written := true until (written) or (ntrys > maxtrys); if ntrys > maxtrys then errorexit('TEXWRITE','error writing to output') end; [GLOBAL] PROCEDURE writecurrentchar( var infile, outfile : text ); var gotten : boolean; begin if capitalizetext then currentchar := capchar( currentchar ); if lowercasetext then currentchar := lcchar( currentchar ); case flagclass(currentchar) of notaflag : begin stopunderline( outfile ); stopbold( outfile ); texwrite(outfile, currentchar) end; control : begin stopunderline( outfile ); stopbold( outfile ); texwrite(outfile, currentchar) end; uppercase : begin getnextchar(infile, gotten); if gotten then case flagclass(currentchar) of underline : startunderline( outfile, enhancmentlocked); bold : startbold( outfile, enhancmentlocked ); otherwise texwrite(outfile, capchar(currentchar)) end end; lowercase : begin getnextchar(infile, gotten); if gotten then case flagclass(currentchar) of underline : begin if underlineactive <> notenhanced then write(outfile,'} '); underlineactive := notenhanced end; bold : begin if boldactive <> notenhanced then write(outfile,'} '); boldactive := notenhanced end; otherwise texwrite(outfile, lcchar(currentchar)) end end; quote : begin getnextchar(infile, gotten); if gotten then texwrite(outfile, currentchar ) end; space : write(outfile,'\ '); underline : begin getnextchar(infile, gotten ); if gotten then begin startunderline( outfile, singlecharenhanced); texwrite(outfile, currentchar) end else texwrite(outfile, currentchar) end; bold : begin getnextchar(infile, gotten); if gotten then begin startbold( outfile, singlecharenhanced); texwrite(outfile, currentchar) end else texwrite(outfile, currentchar) end; overstrike : begin getnextchar(infile, gotten); if gotten then begin startbold( outfile, singlecharenhanced); texwrite(outfile, currentchar) end else texwrite(outfile, currentchar) end; hyphenate : write(outfile,'--'); break : writeln(outfile,'\linebreak'); period : write(outfile,'\nonfrenchspacing '); capitalize : begin getnextchar( infile, gotten); if gotten then texwrite(outfile, capchar(currentchar)) end; endfootnote : begin if (columncounter = 1) and (infootnote) then begin if not fill then endnofill( outfile ); writeln(outfile,'} % - end of footnote'); writeln( log,'} % - end of footnote'); infootnote := false; if startnofillagain then begin startnofillagain := false; beginnofill( outfile ) end end else texwrite(outfile, currentchar) end; comment : begin if flagclass(lastinputchar) = control then write(outfile,'% ') else texwrite(outfile,currentchar) end; substitute : texwrite(outfile, currentchar) end { case } end; [GLOBAL] PROCEDURE newline( var infile, outfile : text; putcrlf : boolean ); var gotten : boolean; begin if eoln(infile) then begin readln(infile); totallines := totallines + 1; columncounter := 1 end; if putcrlf then writeln(outfile); while (eoln(infile)) and (not eof(infile)) do begin readln(infile); writeln(outfile); columncounter := 1; totallines := totallines + 1 end; if not eof(infile) then begin read(infile, currentchar); totalchars := totalchars + 1; lastinputchar := blank end; if ord(currentchar) = tab then begin tabrecord.charcountintab := ncharsintab; tabrecord.tabread := true end else begin tabrecord.charcountintab := 0; tabrecord.tabread := false end; if currentchar < blank then currentchar := blank end; [GLOBAL] PROCEDURE changeflagchar( flag : dsrflagclasses; newchar:char); begin flagtable[flag].representation := newchar; write(log,'[internal flag representation change for '); writeflagname(log, flag); writeln(log,' to "',newchar,'"]') end; [GLOBAL] PROCEDURE turnflagon( flag : dsrflagclasses ); begin flagtable[flag].turnedon := true; write(log,'[internal flag '); writeflagname(log, flag); writeln(log,' enabled]') end; [GLOBAL] PROCEDURE turnflagoff( flag : dsrflagclasses ); begin flagtable[flag].turnedon := false; write(log,'[internal flag '); writeflagname(log, flag); writeln(log,' disabled]') end; [GLOBAL] PROCEDURE texwritearg( var outfile : text; arg : argument ); var s : pckstr; i, l : integer; begin s := argliteral( arg, false ); l := length( s ); for i := 1 to l do texwrite(outfile, s.body[i]); write(outfile, blank) end; END.