Bezoar 26 March 2008 I wanted to reformat a text table to reduce the width of each column and NOT truncate the contents. I turned to tcllib's matrix and report packages to accomplish this as I mistakenly thought that the report package would word wrap automatically. This unfortunately is not the case. However by using textutils you can preprocess the cell data and get the result you want this example script does that.
package require struct::matrix
package require report
package require textutil
# fill array with dummy data
set mytable(0,0) "Elements"
set mytable(0,1) "Element A"
set mytable(0,2) "Element B"
set mytable(0,3) "Element C"
set mytable(0,4) "Element D"
set mytable(1,0) "Description"
set mytable(1,1) "ABCDEFGHIJKLMENOP QRST UVW X YZ 1234 5676 9 10 11 12 13 141516"
set mytable(1,2) "ABCDEFGHIJKLMENOP QRST UVW X YZ 1234 5676 9 10 11 12 13 141516"
set mytable(1,3) "ABCDEFGHIJKLMENOP QRST UVW X YZ 1234 5676 9 10 11 12 13 141516"
set mytable(1,4) "ABCDEFGHIJKLMENOP QRST UVW X YZ 1234 5676 9 10 11 12 13 141516"
# define a style and create a report object with that style
proc getReport { name columns style args } {
::report::defstyle simpletable {} {
data set [split "[string repeat "| " [columns]]|"]
top set [split "[string repeat "+ - " [columns]]+"]
bottom set [top get]
top enable
bottom enable
}
set r [ report::report $name $columns style simpletable ]
return $r
}
# for report object named name take column list and set the
# width for each column. Also pass in the data to modify it
# to fit within the new column size.
proc setReportColumnSizes { name columnlist dataArray } {
upvar $dataArray a
r sizes $columnlist
for { set i 0 } { $i < [llength $columnlist] } { incr i } {
foreach index [ array names a $i,* ] {
set a($index) [ textutil::adjust $a($index) -length [lindex $columnlist $i ] -justify left -strictlength true ]
}
}
}
set columns 2
# calculate number of rows
set rows [ expr [ llength [ array names mytable ] ] / $columns ]
set r [ getReport r $columns simpletable ]
#make column one 15 characters wide make column 2 25 characters wide
set sizelist { 15 25 }
# set report column sizes and use textutil::adjust to modify cell data
setReportColumnSizes r $sizelist mytable
#create matrix
set m [ struct::matrix m ]
# create requisite rows and columns
m add columns $columns
m add rows $rows
# link array to matix ... filling in array fills matrix
m link tablex
# fill in matrix
array set tablex [array get mytable]
# output report
puts "[r printmatrix m ]"Results in :
+---------------+-------------------------+ |Elements |Description | |Element A |ABCDEFGHIJKLMENOP QRST | | |UVW X YZ 1234 5676 9 10 | | |11 12 13 141516 | |Element B |ABCDEFGHIJKLMENOP QRST | | |UVW X YZ 1234 5676 9 10 | | |11 12 13 141516 | |Element C |ABCDEFGHIJKLMENOP QRST | | |UVW X YZ 1234 5676 9 10 | | |11 12 13 141516 | |Element D |ABCDEFGHIJKLMENOP QRST | | |UVW X YZ 1234 5676 9 10 | | |11 12 13 141516 | +---------------+-------------------------+
if run without textutil pre-procesing the data is truncated :
+---------------+-------------------------+ |Elements |Description | |Element A |676 9 10 11 12 13 141516| |Element B |676 9 10 11 12 13 141516| |Element C |676 9 10 11 12 13 141516| |Element D |676 9 10 11 12 13 141516| +---------------+-------------------------+