summaryrefslogtreecommitdiff
path: root/ipl/procs/rewrap.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/procs/rewrap.icn')
-rw-r--r--ipl/procs/rewrap.icn154
1 files changed, 154 insertions, 0 deletions
diff --git a/ipl/procs/rewrap.icn b/ipl/procs/rewrap.icn
new file mode 100644
index 0000000..21d8f80
--- /dev/null
+++ b/ipl/procs/rewrap.icn
@@ -0,0 +1,154 @@
+############################################################################
+#
+# File: rewrap.icn
+#
+# Subject: Procedures for advanced line rewrap
+#
+# Author: Richard L. Goerwitz
+#
+# Date: March 3, 1996
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# Version: 1.4
+#
+############################################################################
+#
+# 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