#!/bin/sh
: ; exec klone $0 "$@"
; The above line allows not to embed the exact path of the klone executable

;;Skeleton of a typical klone script

(setq args (getopts "USAGE: %0 [options] 
words-wraps in place a mail file (xmh format) given as argument
Tries to intelligently word wrap text files.
"
    ("-v" () verbose "verbose operation")
    ("-debug" () enter-debugger-on-error "enter klone debugger on error")
    ("-stackdump" () stackdump-on-error "verbose stack dump on error")
))
(if (not args) (getopts :usage))

(if enter-debugger-on-error (kdb t))
(if stackdump-on-error (stack-dump-on-error t))

(defun main (&aux (file (0 args)) (fd (open file)) (lines (list))
    line
    in-body?
  )
  (catch 'EOF 
    (while t (setq line (expand-tabs (read-line fd)))
      (if in-body?
	(cut-line line)
	(progn
	  (if (= "" line) 
	    (setq in-body? t)
	  )
	  (lappend lines line)
  ))))
  (close fd)
  (setq fd (open file :if-exists :supersede :direction :output))
  (dolist (line lines)
    (write-line line fd)
  )
  (close fd)
)

;; if line too long, cut first part, append it to lines to print, and
;; recurse on rest
(defun cut-line (line &aux cutpos)
  (if line
    (if (> (length line) 78) (progn
	(setq cutpos 78)
	(catch 'Cut
	  (while (> cutpos 40)		;search for blank to cut at
	    (if (seek " \t" (cutpos line)) (progn
		(lappend lines (subseq line 0 cutpos))
		(cut-line (remove-blanks (subseq line cutpos)))
		(throw 'Cut)
	    ))
	    (incf cutpos -1)
	  )
	  (setq cutpos 77)
	  (lappend lines (+ (subseq line 0 cutpos) "\\"))
	  (cut-line (subseq line cutpos))
	)
      )
      (lappend lines line)
)))

;; remove leading blanks on wrapped lines
(setq remove-blanks-re (regcomp "^[ \t]*(.*)$"))
(defun remove-blanks (line  &aux res)
  (regexec remove-blanks-re line)
  (setq res (regsub remove-blanks-re 1))
  (if (/= "" res) 
    (indent-as res (get lines -1))
    ())
)

;; adjust wrapped lines to start at the same indent level as the previous one,
;; trying to guess bullets
(setq indent-as-re (regcomp "^(([ \t]*)([-*o.] )?)")) 
(setq indent-as-re-quot (regcomp "^((>[ >]*)|  [|]|[|])")) 
(defun indent-as (line prevline &aux
  )
  (if (regexec indent-as-re prevline)
    (+ (regsub indent-as-re 2) (make-string (length (regsub indent-as-re 3)))
      line
    )

    (regexec indent-as-re-quot prevline)
    (+ (regsub indent-as-re 1) line)

    line
  )
)

(main)

;;; EMACS MODES
;;; Local Variables: ***
;;; mode:lisp ***
;;; End: ***

