prog = {
  name = "softwrap",
  banner = "softwrap 0.33 (04 Apr 2011) by Reuben Thomas <rrt@sc3d.org>",
  purpose = "Convert hard-wrapped text files into soft-wrapped ones"
}
-- FIXME: softwrap files in place, with ~ backups. Need a framework
-- for transforming files this way.

require "std"

-- Default options
minWidth = 65

-- wrapLines: soft-wrap a list of text lines into paragraphs
-- width: the minimum width of the first line of a paragraph
-- line: list of text lines
-- returns
-- para: list of paragraphs
function wrapLines (width, line)
  local wrapped, i, lines = {}, 1, #line
  repeat
    while i <= lines and (not nuweb or
                          not (string.find (linei, "@{")))
      and (string.len (linei) < width or
           (latex and (string.find (linei, "^\%%") or
                       string.find (linei, "\\") or
                         string.find (linei, "&%s*$"))))
    do
      table.insert (wrapped, linei)
      i = i + 1
    end
    if i <= lines and (nuweb and string.find (linei, "@{")) then
      while i < #line and not (string.find (linei, "@}")) do
        table.insert (wrapped, linei)
        i = i + 1
      end
    end
    if i <= lines then
      table.insert (wrapped, linei)
      i = i + 1
    end
    while i <= lines and string.len (linei) > 0 and
      string.sub (linei, 1, 1) ~= " " and
      not (nuweb and string.find (linei, "@{")) and
      not (latex and (string.find (#wrapped, "\\") or
                      (string.find (linei, "\begin") or
                       string.find (linei, "\end") or
                         string.find (linei, "\item"))))
    do
      wrapped#wrapped = wrapped#wrapped ..
        " " .. linei
      i = i + 1
    end
  until i > lines
  for i = 1, #wrapped do
    wrappedi = wrappedi .. "n"
  end
  return wrapped
end

-- Process a file
function softwrap (file)
  local line = wrapLines (width, io.readlines ())
  io.stdin:close () -- close the input file
  list.map (io.write, line)
end

-- Command-line options
options = {
  Option {{"width", "w"},
    "set the minimum width of the first line of a paragraph",
    "Req", "CHARACTERS"},
  Option {{"latex", "l"},
    "LaTeX mode: comments and lines starting with \begin, \end " ..
      "or \item are not wrapped"},
  Option {{"nuweb", "n"},
    "Nuweb mode: implies LaTeX mode, and chunks (between @{ and " ..
      "@}) will not be wrapped"},
}

-- Main routine
getopt.processArgs ()
width = getopt.opt.width and 1 or minWidth
nuweb = getopt.opt.nuweb and 1
latex = getopt.opt.latex and 1 or nuweb
io.processFiles (softwrap)

-- Changelog

-- 04apr11 0.33 readLines --> readlines
-- 08oct06 0.32 table.getn --> #
-- 18mar06 0.31 Update to match stdlib
-- 17dec03 0.3 Allow input from stdin
-- Fix output bug (0.25 was broken)
-- Update to match stdlib
-- 12sep03 0.25 Update for Lua 5
-- 02feb03 0.24 Now need to print usage message explicitly if no args
-- 02nov02 0.23 Updated to match stdlib
-- 21jun02 0.22 Updated to match stdlib
-- 03jan02 0.21 Updated to match stdlib
-- 20may01,
-- 27jun01-
-- 01jul01 0.2 Rewritten in Lua
-- 22may97-
-- 14oct00 Icon version