## 4.1 Expanding TAB Characters Revisited

In Program 4.1 the revised formulation of the `Expand` procedure is shown. As before the file objects are created, but now both files inherit from `Open.text` as well. This class provides methods for buffered input and output.

  `local
  fun {Insert N Is}
  if N>0 then {Insert N-1 & |Is} else Is end
  end
  fun {ScanLine Is Tab N}
  case Is of nil then nil
  [] I|Ir then
  case I
  of &\t then M=Tab-(N mod Tab) in {Insert M {ScanLine Ir Tab M+N}}
  [] &\b then I|{ScanLine Ir Tab {Max 0 N-1}}
  else I|{ScanLine Ir Tab N+1}
  end
  end
  end
  proc {Scan Tab IF OF}
  Is={IF getS($)}
  in
  if Is==false then
  {IF close} {OF close}
  else
  {OF putS({ScanLine Is Tab 0})}
  {Scan Tab IF OF}
  end
  end
  class TextFile
  from Open.file Open.text
  end
  in
  proc {Expand Tab IN ON}
  {Scan Tab
  {New TextFile init(name:IN)}
  {New TextFile init(name: ON
  flags: [write create truncate])}}
  end
  end`

Program 4.1: The Incremental `Expand` Procedure

The procedure `Scan` applies the input file object `IF` to the message `getS($)`. It yields either `false`, in case the end of the file is reached, or a string. This string contains exactly one line of the input file (without a newline character).

The expansion of TAB characters is done in the function `ScanLine` as before. The expanded lines are written with the `putS` method.