Eugeniu Rosca
Eugeniu Rosca

Reputation: 5305

Pretty print a TCL list

Having a TCL list that looks like below (formatted for better visibility):

set mylist [list \
    "title_1                 title_2        title_3 " \
    "row1col1_bla            row1col2       row1col3 " \
    "r2c1                    r2c2_blablabla r2c3" \
    "r3c1_really_long_string r3c2           r3c3" \
]

I need a procedure that prints $mylist like:

   title_1      title_2  title_3
1) row1col1_bla row1col2 row1col3
2) r2c1         &FN_1    r2c3
3) &FN_2        r3c2     r3c3

  Footnotes:
  FN_1: r2c2_blablabla
  FN_2: r3c1_really_long_string

The procedure should take as input:

The following function does exactly this. Are there any suggestions to possibly simplify or improve it?

#!/usr/bin/tclsh

set COLMAXLEN   12
set SHORTCUT    "FN"

proc puts_list {mylist} {
    global COLMAXLEN SHORTCUT
    set num_row [llength $mylist]
    set num_col [llength [lindex $mylist 0]]
    set ref_list {}

    # Define/init col_width (a list having $num_col elements)
    set col_width {}
    for {set col 0} {$col < $num_col} {incr col} {
        lappend col_width 0
    }

    # Get the max width of each column AND
    # replace the elements > $COLMAXLEN with footnote shortcuts!
    for {set row 0} {$row < $num_row} {incr row} {
        set new_row {}
        for {set col 0} {$col < $num_col} {incr col} {
            set myrow  [lindex $mylist $row]
            set myitem [lindex $myrow $col]
            set mysize [string length $myitem]
            if { $mysize > $COLMAXLEN } {
                lappend ref_list $myitem
                set myitem "&[subst $SHORTCUT]_[llength $ref_list]"
                set mysize [string length $myitem]
            }
            if { $mysize > [lindex $col_width $col] } {
                lset col_width $col $mysize
            }
            lappend new_row $myitem
        }
        lset mylist $row $new_row
    }

    # Start printing
    set num_col_width [expr [string length $num_row] +1]
    puts ""
    for {set row 0} {$row < $num_row} {incr row} {
        if { $row == 0 } {
            puts -nonewline [format "%[subst $num_col_width]s" { }]
        } else {
            puts -nonewline [format "%[subst $num_col_width]s" "$row)"]
        }
        puts -nonewline " "
        for {set col 0} {$col < $num_col} {incr col} {
            set myrow  [lindex $mylist $row]
            set myitem [lindex $myrow $col]
            set mysize [expr [lindex $col_width $col] +1]
            puts -nonewline [format "%-[subst $mysize]s" $myitem]
        }
        puts ""
    }
    puts ""
    puts "  Footnotes:"
    set ref_num [llength $ref_list]
    for {set i 0} {$i < $ref_num} {incr i} {
        puts "  [subst $SHORTCUT]_[format %-[subst [string length $ref_num]]s [expr $i + 1]]: [lindex $ref_list $i]"
    }
    puts ""
}

ASSUMPTION: TCL version is 8.4

Upvotes: 0

Views: 4204

Answers (1)

Hai Vu
Hai Vu

Reputation: 40688

# Print the row number
proc put_row_number {rowNumber} {
    if {$rowNumber == 0} {
        puts -nonewline "   "
    } else {
        puts -nonewline "$rowNumber) "
    }
}

proc put_table {table {colmaxlen 12} {shortcut FN}} {
    set ref {}
    set refCount 0
    set rowCount 0

    foreach row $table {
        put_row_number $rowCount
        incr rowCount
        foreach cell $row {
            if {[string length $cell] > $colmaxlen} {
                incr refCount
                set key "${shortcut}_${refCount}"
                lappend ref $key $cell
                set cell "&$key"
            }
            puts -nonewline [format "%-*s " $colmaxlen $cell]
        }
        puts ""
    }

    puts "\n   Footnotes:"
    foreach {key value} $ref {
        puts "   $key: $value"
    }
}

set mylist {
    "title_1                 title_2        title_3 "
    "row1col1_bla            row1col2       row1col3 "
    "r2c1                    r2c2_blablabla r2c3"
    "r3c1_really_long_string r3c2           r3c3"
}
put_table $mylist

Upvotes: 1

Related Questions