[comp.lang.icon] word/line procedure

nowlin@isidev.UUCP (05/16/91)

 > From Kimmo Kettunen
 > 
 > I have a following, obviosly simple problem. I have made a nice Icon
 > procedure, which divides a text file one word/line.  It is much easier,
 > ...
 > 	procedure main()
 >    		while line:=read() do write(map(line," ","\l"))
 > 	end 
 > 
 > It works fine and fast, but it produces also empty lines which I cannot get
 > rid off in the same procedure, although I try to filter them out with
 > something like
 > 
 > 	if *line > 0 then write(line)

First you have to remember that in Icon you're working on strings, NOT
lines.  The result of the map() is not a series of lines but the same basic
string with spaces changed to newlines.  The length of the string hasn't
changed.  Testing the length of the string to discard empty lines won't do
any good at this point.
 
 > But if I make the first procedure to write the stuff in a file and then
 > process that file with the procedure
 > 
 > 	procedure main()
 >   		while line:=read() do if *line > 0 then write(line)
 > 	end

The reason testing the length works on the second pass is that now you're
reading in the original string in little pieces, one line at a time.  If
some of these pieces are empty lines they now exhibit zero length and can
be discarded.

 > ...
 > I would still like to know, how I actually could make it work in one shot.
 > I have tried different solutions, but they do not work. Can anybody
 > explain it?

I diddled your basic design, which is a neat idea by the way, and instead
of writing out the entire mapped string I write it out in pieces that are
delimited by the newlines that were mapped into the string.  This allows
the program to skip over consecutive bunches of newlines and thereby
discard the "blank lines" in one pass.  You'll have to test its speed.  It
may not be that fast now.

    procedure main()

        # convert input spaces to newlines and scan the result
        while line := map(read()," ","\l") do line ?  {

            # skip initial newlines
            tab(many('\l'))

            # write out substrings delimited by newlines
            while write(tab(upto('\l'))) do

                # skip newlines
                tab(many('\l'))

            # write out the last substring
            if not pos(0) then write(tab(0))
        }

    end

I'd assign the newline cset to a variable since it's used several places
now and maybe change the map to handle more "white space" characters than
just the space.  The tab comes to mind.  It's a good program idea.


  --- ---
   | S | Iconic Software, Inc.  -  Jerry Nowlin  -  uunet!isidev!nowlin
  --- ---