Align columns: Difference between revisions
Content added Content deleted
(awk) |
Underscore (talk | contribs) (Added Common Lisp.) |
||
Line 344: | Line 344: | ||
} |
} |
||
}</lang> |
}</lang> |
||
=={{header|Common Lisp}}== |
|||
<lang lisp>(defun nonempty (seq) |
|||
(position-if (lambda (x) (declare (ignore x)) t) seq)) |
|||
(defun split (delim seq) |
|||
"Splits seq on delim into a list of subsequences. Trailing empty |
|||
subsequences are removed." |
|||
(labels |
|||
((f (seq &aux (pos (position delim seq))) |
|||
(if pos |
|||
(cons |
|||
(subseq seq 0 pos) |
|||
(f (subseq seq (1+ pos)))) |
|||
(list seq)))) |
|||
(let* |
|||
((list (f seq)) |
|||
(end (position-if #'nonempty list :from-end t))) |
|||
(subseq list 0 (1+ end))))) |
|||
(defun lengthen (list minlen filler-elem &aux (len (length list))) |
|||
"Destructively pads list with filler-elem up to minlen." |
|||
(if (< len minlen) |
|||
(nconc list (make-list |
|||
(- minlen len) :initial-element filler-elem)) |
|||
list)) |
|||
(defun align-columns (text &key (align :left) &aux |
|||
(fmtmod (case align |
|||
(:left "@") |
|||
(:right ":") |
|||
(:center "@:") |
|||
(t (error "Invalid alignment.")))) |
|||
(fields (mapcar |
|||
(lambda (line) (split #\$ line)) |
|||
(split #\Newline text))) |
|||
(mostcols (loop for l in fields maximize (length l))) |
|||
widest) |
|||
(setf fields (mapcar |
|||
(lambda (l) (lengthen l mostcols "")) |
|||
fields)) |
|||
(setf widest (loop |
|||
for col below (length (first fields)) |
|||
collect (loop |
|||
for row in fields maximize (length (elt row col))))) |
|||
(format nil |
|||
(with-output-to-string (s) |
|||
(princ "~{~{" s) |
|||
(dolist (w widest) |
|||
(format s "~~~d~a<~~a~~>" (1+ w) fmtmod)) |
|||
(princ "~}~%~}" s)) |
|||
fields))</lang> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |