1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
############################################################################
#
# File: colmize.icn
#
# Subject: Procedures to arrange data into columns
#
# Author: Robert J. Alexander
#
# Date: June 15, 1990
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# colmize() -- Arrange data into columns.
#
# Procedure to arrange a number of data items into multiple columns.
# Items are arranged in column-wise order, that is, the sequence runs
# down the first column, then down the second, etc.
#
# This procedure goes to great lengths to print the items in as few
# vertical lines as possible.
#
############################################################################
procedure colmize(entries,maxcols,space,minwidth,tag,tagspace,tagminwidth,rowwise,distribute)
local mean,cols,lines,width,i,x,wid,extra,t,j,first_tagfield,tagfield
#
# Process arguments -- provide defaults.
#
# entries: a list of items to be columnized
/maxcols := 80 # max width of output lines
/space := 2 # min nbr of spaces between columns
/minwidth := 0 # min column width
# tag: a label to be placed on the first line of output
/tagminwidth := 0
/tagspace := 2
# rowwise: if nonnull, entries are listed in rowwise order rather than
# columnwise
#
#
# Process the tag field information. The tag will appear on the
# first line to the left of the data.
#
if \tag then {
tagminwidth <:= *tag + tagspace
maxcols -:= tagminwidth
first_tagfield := left(tag, tagminwidth - tagspace) || repl(" ",tagspace)
tagfield := repl(" ",tagminwidth)
} else
tagfield := first_tagfield := ""
# Starting with a trial number-of-columns that is guaranteed
# to be too wide, successively reduce the number until the
# items can be packed into the allotted width.
#
mean := 0
every mean +:= *!entries
mean := mean / (0 ~= *entries) | 1
every cols := (maxcols + space) * 2 / (mean + space) to 1 by -1 do {
lines := (*entries + cols - 1) / cols
width := list(cols,minwidth)
i := 0
if /rowwise then { # if column-wise
every x := !entries do {
width[i / lines + 1] <:= *x + space
i +:= 1
}
}
else { # else row-wise
every x := !entries do {
width[i % cols + 1] <:= *x + space
i +:= 1
}
}
wid := 0
every x := !width do wid +:= x
if wid <= maxcols + space then break
}
#
# Now output the data in columns.
#
extra := (\distribute & (maxcols - wid) / (0 < cols - 1)) | 0
if /rowwise then { # if column-wise
every i := 1 to lines do {
if i = 1 then
t := first_tagfield
else
t := tagfield
every j := 0 to cols - 1 do
t ||:= left(entries[i + j * lines],width[j + 1] + extra)
suspend trim(t)
}
}
else { # else row-wise
every i := 0 to lines - 1 do {
if i = 0 then
t := first_tagfield
else
t := tagfield
every j := 1 to cols do
t ||:= left(entries[j + i * cols],width[j] + extra)
suspend trim(t)
}
}
end
|