Version 14 of table

Updated 2009-02-09 17:36:14 by LV

Currently there are several implementations of a table widget.

 [[Please update the above list to document other examples]]

RS 2006-05-31: As data structures, tables (taken as rectangular matrixes of strings) can be well represented as a list of lists. Here is code for pretty-printing such a list, the resulting string looking (in fixed-pitch font only) like a table again:

 proc fmtable table {
    set maxs {}
    foreach item [lindex $table 0] {
        lappend maxs [string length $item]
    }
    foreach row [lrange $table 1 end] {
        set i 0
        foreach item $row max $maxs {
            if {[string length $item]>$max} {
                lset maxs $i [string length $item]
            }
            incr i
        }
    }
    set head +
    foreach max $maxs {append head -[string repeat - $max]-+}
    set res $head\n
    foreach row $table {
        append res |
        foreach item $row max $maxs {append res [format " %-${max}s |" $item]}
        append res \n
    }
    append res $head
 }

#-- Testing:

 set data {
    {1 short "long field content"}
    {2 "another long one" short}
    {3 "" hello}
 }
 puts [fmtable $data]

#-- shows

 +---+------------------+--------------------+
 | 1 | short            | long field content |
 | 2 | another long one | short              |
 | 3 |                  | hello              |
 +---+------------------+--------------------+

Extended version, with the framing lines optional:

 proc fmtable {table {lines 0}} {
    set maxs {}
    foreach item [lindex $table 0] {lappend maxs [string length $item]}
    foreach row [lrange $table 1 end] {
        set i 0
        foreach item $row max $maxs {
            if {[string length $item]>$max} {
                lset maxs $i [string length $item]
            }
            incr i
        }
    }
    if $lines {
       set head +
       foreach max $maxs {append head -[string repeat - $max]-+}
       set res $head\n
       set sep |
    } else {set sep ""}
    foreach row $table {
        append res $sep
        foreach item $row max $maxs {append res [format " %-${max}s $sep" $item]}
        append res \n
    }
    if $lines {append res $head}
    set res
 }

#-- Testing the two modes:

 % fmtable {{hello world} {a longstring}}
 hello  world
 a      longstring

 % fmtable {{hello world} {a longstring}} 1
 +-------+------------+
 | hello | world      |
 | a     | longstring |
 +-------+------------+

LV 2007-12018 I was looking at http://extjs.com/ , which provides a JavaScript table with many useful features. One of the features that I particularly liked was how by default, if the user makes a change in a table cell, the widget adds a tic mark indicating that it has been changed. That isn't the only nice feature - but certain one that I found appealing. Does anyone know of a Tk based table widget that provides that sort of functionality built in?