procedure AlgolEdit(characterset, linelimit);
   string characterset;
     integer linelimit;
     comment If this procedure is presented an ALGOL 60 program or procedure
     in the form of a sequence of basic symbols, it will transmit to the
     output medium a copy of the text with indentations between each
     begin-end pair and some rearrangement of the blank spaces within the
     text. This procedure is an example of its own output. It is used to
     edit ALGOL 60 text that is difficult to read because, for example, the
     ALGOL has been transcribed from printed documents, or written by
     inexperienced programmers, or stored in compressed form (i.e., with all
     redundant blank spaces removed). The integer “-1” will represent the
     nonbasic symbol “carriage return”, “-2” will represent an end-of-file
     mark, other symbols will have the integer value corresponding to their
     position in the parametric string “characterset”. The string must
     contain exactly the 116 basic symbols of ALGOL 60. The parameter
     line-limit” sets an upper bound on the number of basic symbols that
     the user wishes to appear on a line of output. The identifiers “lsq”
     and “rsq” will be used in place of strings of length one whose only
     elements are “‘” and “’”, respectively;
begin
   integer array spacesbefore, spacesafter[1 : 116], buffer[1 : linelimit];
   integer tabstop, symbol, i, symbolcount, level;
   Boolean newline;
   integer procedure val(s);
      string s;
   begin
      comment The value of this procedure is the integer corresponding
        to the position in the string “characterset” of the symbol in the
        string “s”. The body of the procedure must be expressed in code;
   end val;
   procedure get(symbol);
      integer symbol;
   begin insymbol(2, characterset, symbol);
      if symbol = -2 then go to eof
   end get;
   procedure send(symbol);
      integer symbol;
   begin comment “send” must not break identifiers across lines or
        insert spurious characters into strings;
      integer i, u, v;
      if symbol = -1 ∨ symbolcount ⩾ linelimit
        then
      begin v ≔ tabstop;
         if newline then go to E;
         if level ≠ 0 then
         begin comment Inside a string;
            for i ≔ 1 step 1 until symbolcount do outsymbol(1, characterset, buffer[i]);
            outsymbol(1, characterset, -1) ;
            v ≔ 0
         end else
         begin u ≔ symbolcount;
            newline ≔ true;
            if symbol = -1 then go to D;
            comment Find a convenient place to break the line;
            for u ≔ symbolcount - 1 step -1 until tabstop do
                 if buffer[u + 1] = val(“ ”) ∨ buffer[u] = val(rsq) then go to D;
            u ≔ symbolcount;
            comment Send the line;
            D: for i ≔ 1 step 1 until u do outsymbol(1, characterset, buffer[i]);
            outsymbol(1, characterset, -1);
            comment Find a non-blank character to start the next line;
            for i ≔ u + 1 step 1 until symbolcount do if buffer[i] ≠ val(“ ”) then go to F;
            go to G;
            comment Move a new line to the head of the buffer area;
            F: for i ≔ i step 1 until symbolcount do
               begin v ≔ v + 1;
                  newline ≔ false;
                  buffer[v] ≔ buffer[i]
               end;
            comment Insert blanks for tab stops;
            G: for i ≔ 1 step 1 until tabstop do buffer[i] ≔ val(“ ”)
         end;
         E: symbolcount ≔ v
      end;
      comment Now we can put the new symbol in the buffer array;
      if symbol ≠ -1 ∧ ¬ (newline ∧ symbol = val(“ ”)) then
      begin symbolcount ≔ symbolcount + 1;
         newline ≔ false;
         buffer[symbolcount] ≔ symbol
      end
   end send;
   for symbol ≔ 1 step 1 until 116 do spacesbefore[symbol] ≔ spacesafter[symbol] ≔ 0;
   for symbol ≔ val(“+”), val(“-”), val(“¬”), val(“:”), val(“:=”),
     val(““”), val(“⩽”), val(“=”), val(“≠”), val(“⩾”), val(“””) do
        spacesbefore[symbol] ≔ spacesafter[symbol] ≔ 1;
   for symbol ≔ val(“∧”), val(“∨”), val(“⊂”), val(“≡”), val(“t̲h̲e̲n̲”),
     val(“e̲l̲s̲e̲”), val(“s̲t̲e̲p̲”), val(“u̲n̲t̲i̲l̲”),val(“w̲h̲i̲l̲e̲”), val(“d̲o̲”) do
        spacesbefore[symbol] ≔ spacesafter[symbol] ≔ 2;
   for symbol ≔ val(“g̲o̲ t̲o̲”), val(“b̲e̲g̲i̲n̲”), val(“i̲f̲”), val(“f̲o̲r̲”),
     val(“p̲r̲o̲c̲e̲d̲u̲r̲e̲”), val(“v̲a̲l̲u̲e̲”), val(“o̲w̲n̲”), val(“r̲e̲a̲l̲”),
     val(“B̲o̲o̲l̲e̲a̲n̲”), val(“i̲n̲t̲e̲g̲e̲r̲”), val(“a̲r̲r̲a̲y̲”), val(“s̲w̲i̲t̲c̲h̲”),
     val(“l̲a̲b̲e̲l̲”), val(“s̲t̲r̲i̲n̲g̲”), val(“,”) do spacesafter[symbol] ≔ 2;
   level ≔ symbolcount ≔ tabstop ≔ 0;
   newline ≔ true;
   nextsymbol: deblank: get(symbol);
   scanned: if symbol = val(“ ”) ∨ symbol = -1 then go to deblank;
   if      symbol = val(“b̲e̲g̲i̲n̲”) then send( -1)
     else if symbol = val(“e̲n̲d̲”)   then
   begin tabstop ≔ tabstop - 5;
      send( -1)
   end;
   for i ≔ 1 step 1 until spacesbefore[symbol] do send(val(“ ”));
   send(symbol);
   for i ≔ 1 step 1 until spacesafter[symbol] do send(val(“ ”));
   if symbol = val(“c̲o̲m̲m̲e̲n̲t̲”) then
   begin comment Pass comments on unchanged;
      for i ≔ 1 while symbol ≠ val(“;”) do
         begin get(symbol);
            send(symbol)
         end
   end else if symbol = val(“e̲n̲d̲”) then
   begin comment ‘end’ comments;
      for i ≔ 1 while symbol ≠ val(“;”) do
         begin get(symbol);
            if symbol = val(“e̲l̲s̲e̲”) ∨ symbol = val(“e̲n̲d̲”) then go to scanned;
            send(symbol)
         end
   end else if symbol = val(lsq) then
   begin comment Pass strings on unchanged;
      level ≔ 1;
      for i ≔ 1 while level ≠ 0 do
         begin get(symbol);
            send(symbol);
            if      symbol = val(lsq) then level ≔ level + 1
              else if symbol = val(rsq) then level ≔ level - 1
         end
   end;
   if      symbol = val(“b̲e̲g̲i̲n̲”) then tabstop ≔ tabstop + 5
     else if symbol = val(“;”)     then send(-1);
   go to nextsymbol;
   eof: send( -1);
   outsymbol (1, characterset, -2)
end Algoledit;