[dbohdan] 2015-03-25: The following code is a [Tk] [spreadsheet] inspired, title included, by http://jsfiddle.net/ondras/hYfN3/. Halfway through writing it I found the [tiny spreadsheet] and lifted the idea of tracing variable reads to trigger recalculation from it. One important difference from the tiny spreadsheet is that TEAIPTT does not require a Tcl [expr] patch. **Feature comparison with the JavaScript version** | ✓ Under 35 lines of plain Tcl/Tk (rather than 30 lines of vanilla JS*) | | ✓ Libraries used: none | | ✓ [Excel]-like syntax (formulas start with "=") | | ✓ Support for arbitrary expressions (=A1+B2*C3) | | ✓ Circular reference prevention | | ✗ Automatic persistence | * Lines are assumed to be up to 100 characters long (because the JavaScript spreadsheet uses lines longer than 80 characters, 100 is the next common limit and using lines of unlimited length would feel like cheating). **Screenshot** [under-35-line-spreadsheet-screenshot] **Code** ====== #!/usr/bin/wish foreach row {0 1 2 3 4 5 6} { foreach {column columnName} {0 "" 1 A 2 B 3 C 4 D 5 E 6 F} { set widget [if {$column == 0 || $row == 0} { ::ttk::label .label$columnName$row -text [expr { $row == 0 ? $columnName : $row }] } else { lassign {"" ""} ::formula($columnName$row) ::$columnName$row trace add variable ::$columnName$row read recalc ::ttk::entry .cell$columnName$row -textvar ::$columnName$row -width 10 -validate focus \ -validatecommand [list ::reveal-formula $columnName$row %V %s] }] grid $widget -row $row -column $column } } proc set-cell {cell value} { .cell$cell delete 0 end .cell$cell insert 0 $value } proc recalc {cell args} { if {$::formula($cell) ne ""} { catch {set-cell $cell [uplevel #0 [list \ expr [regsub -all {([A-F][1-6])} $::formula($cell) {$\1}]]]} } } proc reveal-formula {cell event value} { if {$event eq "focusin"} { if {$::formula($cell) ne ""} { set-cell $cell =$::formula($cell) } } else { ;# focusout if {[string match "=*" $value]} { set ::formula($cell) [string range $value 1 end] } foreach otherCell [array names ::formula] { recalc $otherCell } } return 1 } ====== ---- [AMG]: Exchanged the row and column [foreach] lines so that the tab key moves across rather than down. <>Application | GUI | Spreadsheet