/* * mc - multi-columnate. * Mike Meyer, 1989 * * usage: mc [[file] ] [chars ] [width ] * [columns ] [gutter ] * * splits file up into columns separate columns of width colwidth spread * across ttywidth characters with gutterwidth spacing between columns. * * Defaults: * * file: stdin * chars: width of the output window * width: longest line of input * gutter: 2 * columns: as many as will fit in chars * * You cannot specify all of chars, width & cols. One must be allowed to * default. If width is specified, that will not include the gutter. The * priorities are first to make everything fit in a column, then to make * it all fit on the screen - figuring it's better to chop the last column * than all of them. Anything specified is wired down, and will not be changed * even if it means things won't fit. * * one character abbreviations are allowable for all keywords except * columns, which requires 2 to distinguish it from chars. * * Note that the names given are the internal names for the program. You * can change them freely by changing the parms assignment. At the same time, * you ought to change the parms.#.abbrev values to make them work for * whatever words you chose. And this is because I couldn't think of * keywords I really liked... */ parse arg args /* * parms holds the parameters we use for formatting things. parms itself is * a list of their names, the variable for each name is assigned that * the value of it's position in the parms list. The stem variable then holds * the value of that parm under the index the word has. */ parms = "FILE CHARS WIDTH GUTTER COLUMNS" parms.0 = words(parms) do i = 1 to parms.0 interpret word(parms, i) '=' i parms.i.abbrev = 1 end parms.file = "" parms.chars = "" parms.width = "" parms.gutter = "" parms.columns = "" parms.columns.abbrev = 2 /* Special case */ argerror = 0 /* No errors yet. */ i = 1 do while i <= words(args) dofile = 1 do j = 1 to parms.0 if abbrev(word(parms, j), upper(word(args, i)), parms.j.abbrev) then do if parms.j ~= "" then do say "You can only specify" word(parms, j) "once." argerror = 1 end parms.j = word(args, i + 1) i = i + 2 dofile = 0 end end if dofile then do if parms.file ~= "" then do say "You can only specify" word(parms, file) "once." argerror = 1 end parms.file = word(args, i) i = i + 1 end end /* * Got our users parms, now check the restrictions. */ do i = 1 to parms.0 if i = file then iterate i if parms.i ~= "" & ~datatype(parms.i, 'Numeric') then do say word(parms, i) "must be a number, not" parms.i'.' argerror = 1 end end if parms.chars ~= "" & parms.width ~= "" & parms.columns ~= "" then do say "You must let one of" word(parms, chars) || ',' , word(parms, width) 'or' word(parms, columns) 'default!' argerror = 1 end if argerror then exit 10 /* * A qad integrity check - 0 columns means no output, so exit. */ if parms.columns ~= "" then do if parms.columns = 0 then exit end /* * Ok, we got what the user said. Now, get the file into memory, * and find it's longest line. */ if parms.file = "" then 'execio stem lines.' else 'execio read' parms.file 'stem lines.' /* * third integrity check - no input lines means also no output. */ if lines.0 = "LINES.0" then exit maxline = 0 do i = 1 to lines.0 lines.i = strip(lines.i, 'Trailing') if maxline < length(lines.i) then maxline = length(lines.i) end /* * final integrity check - no non-empty lines also means no output */ if maxline = 0 then exit /* * Got input data; now deal with all those defaults. */ if parms.gutter = "" then parms.gutter = 2 if parms.chars = "" then do if parms.columns = "" then do parms.chars = ttywidth() if parms.width = "" then parms.width = maxline parms.columns = (parms.chars - parms.gutter) , % (parms.width + parms.gutter) end else do if parms.width = "" then parms.width = maxline parms.chars = parms.columns * (parms.width + parms.gutter) , - parms.gutter /* No gutter on last column */ end end else if parms.columns = "" then do if parms.width = "" then parms.width = maxline parms.columns = (parms.chars - parms.gutter) , % (parms.width + parms.gutter) end else if parms.width ~= "" then do Say "ALERT! Program reached impossible state!" exit 20 end else parms.width = ((parms.chars - parms.gutter) % parms.columns) - parms.gutter /* * now, set the names to their values, instead of their indices, for speed. */ gutter = copies(" ", parms.gutter) width = parms.width columns = max(1, parms.columns) i = 1 do while i <= lines.0 outline = left(lines.i, width) do j = 1 to columns - 1 i = i + 1 if i > lines.0 then leave outline = outline || gutter || left(lines.i, width) end say outline i = i + 1 end exit /* * ttywidth - just return the width of the window we're talking to. */ ttywidth: procedure return 80 /* Until I figure out what to do here */