home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # File: rewrap.icn
- #
- # Subject: Procedures for advanced line rewrap utility
- #
- # Author: Richard L. Goerwitz
- #
- # Date: June 3, 1991
- #
- ###########################################################################
- #
- # Version: 1.3
- #
- ###########################################################################
- #
- # The procedure rewrap(s,i), included in this file, reformats text
- # fed to it into strings < i in length. Rewrap utilizes a static
- # buffer, so it can be called repeatedly with different s arguments,
- # and still produce homogenous output. This buffer is flushed by
- # calling rewrap with a null first argument. The default for
- # argument 2 (i) is 70.
- #
- # Here's a simple example of how rewrap could be used. The following
- # program reads the standard input, producing fully rewrapped output.
- #
- # procedure main()
- # every write(rewrap(!&input))
- # write(rewrap())
- # end
- #
- # Naturally, in practice you would want to do things like check for in-
- # dentation or blank lines in order to wrap only on a paragraph-by para-
- # graph basis, as in
- #
- # procedure main()
- # while line := read(&input) do {
- # if line == "" then {
- # "" ~== write(rewrap())
- # write(line)
- # } else {
- # if match("\t", line) then {
- # write(rewrap())
- # write(rewrap(line))
- # } else {
- # write(rewrap(line))
- # }
- # }
- # }
- # end
- #
- # Fill-prefixes can be implemented simply by prepending them to the
- # output of rewrap:
- #
- # i := 70; fill_prefix := " > "
- # while line := read(input_file) do {
- # line ?:= (f_bit := tab(many('> ')) | "", tab(0))
- # write(fill_prefix || f_bit || rewrap(line, i - *fill_prefix))
- # etc.
- #
- # Obviously, these examples are fairly simplistic. Putting them to
- # actual use would certainly require a few environment-specific
- # modifications and/or extensions. Still, I hope they offer some
- # indication of the kinds of applications rewrap might be used in.
- #
- # Note: If you want leading and trailing tabs removed, map them to
- # spaces first. Rewrap only fools with spaces, leaving tabs intact.
- # This can be changed easily enough, by running its input through the
- # Icon detab() function.
- #
- ############################################################################
- #
- # See also: wrap.icn
- #
- ############################################################################
-
-
- procedure rewrap(s,i)
-
- local extra_bit, line
- static old_line
- initial old_line := ""
-
- # Default column to wrap on is 70.
- /i := 70
- # Flush buffer on null first argument.
- if /s then {
- extra_bit := old_line
- old_line := ""
- return "" ~== extra_bit
- }
-
- # Prepend to s anything that is in the buffer (leftovers from the last s).
- s ?:= { tab(many(' ')); old_line || trim(tab(0)) }
-
- # If the line isn't long enough, just add everything to old_line.
- if *s < i then old_line := s || " " & fail
-
- s ? {
-
- # While it is possible to find places to break s, do so.
- while any(' -',line := EndToFront(i),-1) do {
- # Clean up and suspend the last piece of s tabbed over.
- line ?:= (tab(many(' ')), trim(tab(0)))
- if *&subject - &pos + *line > i
- then suspend line
- else {
- old_line := ""
- return line || tab(0)
- }
- }
-
- # Keep the extra section of s in a buffer.
- old_line := tab(0)
-
- # If the reason the remaining section of s was unrewrapable was
- # that it was too long, and couldn't be broken up, then just return
- # the thing as-is.
- if *old_line > i then {
- old_line ? {
- if extra_bit := tab(upto(' -')+1) || (tab(many(' ')) | "")
- then old_line := tab(0)
- else extra_bit := old_line & old_line := ""
- return trim(extra_bit)
- }
- }
- # Otherwise, clean up the buffer for prepending to the next s.
- else {
- # If old_line is blank, then don't mess with it. Otherwise,
- # add whatever is needed in order to link it with the next s.
- if old_line ~== "" then {
- # If old_line ends in a dash, then there's no need to add a
- # space to it.
- if old_line[-1] ~== "-"
- then old_line ||:= " "
- }
- }
- }
-
- end
-
-
-
- procedure EndToFront(i)
- # Goes with rewrap(s,i)
- *&subject+1 - &pos >= i | fail
- suspend &subject[.&pos:&pos <- &pos+i to &pos by -1]
- end
-