+================================================+ ! ! ! tk# -- A spreadsheet with a difference! ! ! ! +================================================+ INTRODUCTION: ============= tk# is a simple but intelligent spreadsheet written in tcl/tk. The graphic abilities of tk are used to provide a grid of four interconnected, scrolling panels containing cells with formulas and data values associated with them: <-------------> +-------------+-------------+ ! corner ! head ! ^ +-------------+-------------+ ! ! side ! main ! v +-------------+-------------+ The top and left panels ("head" and "side"), which are narrow and scroll only in one direction, contain the names of the rows/columns. Additionally, they may contain user defined things such as row and column sums, so-called "aggregates", which then also remain always visible even when navigating through the (large) main panel. The scrollable main panel, on the other hand, contains the bulk of the data. Its scrolling behaviour helps when entering large amounts of data. Because of performance reasons, you should not make the main panel larger than, say, 100 x 100 cells; you do wiser to split your application into smaller parts handled separately, save selections from them, and load these together. Be aware that tk# allows saving of the selection (with row/column titles) as well as multiple loading of data files with overlaying, cf. below. One thing that makes tk# special is that IT DO NOT USE NUMBERS but NAMES to refer to rows and columns. Also selection of ranges is based on names and regular expression matching, as is the evaluation of formulas over cell ranges (summation etc.) which is an important part of real life spreadsheet usage (think of bookkeeping!). tk# gives its data files the extension .tk#. These files contain tcl/tk commands which are sourced (executed) when loaded. The extension tl# is reserved for "prepository files" containing proc definitions and the like which can be sourced from a tk# data file. This is intended to load special functionality into the spreadsheet when needed for aspecific application. A third file type that could be considered would be a self-extracting package type, extension .tm#. These files would contain a procedure to separately write out the .tk# and .tl# type information they contain. Not yet implemented. THE CURRENT VERSION: ==================== The current version was coded mainly by Martin Vermeer (mv@fgi.fi) with substantial assistance (beta testing, FreeBSD port* and good ideas) from Bruce Gingery. *) meaning: starting the program and seeing that it works :-) I would hope that others pick up from here both with patches to the base version (but let's be conservative about adding features!) and proc library, or "repository" files for added or special functionality. This version 0.1 for tcl7.6 and tk4.2 (and upwards) runs on - Linux - FreeBSD and should run on many others (non-UNIX will require some work still). I would especially like to see some good .tl# files (ideas are given below. The distribution contains a demo). Send me your best! IDEAS FOR FURTHER DEVELOPMENT: ============================== All the following are suggestions provided by Bruce Gingery for extensions to tk#, internationalization, etc. APPLICATION-SPECIFIC PACKAGES ("REPOSITORIES"): ---------------------------------------------- surv.tl# might contain functions for land-surveying therm.tl# might contain something having to do with thermodynamics. All procs and globals defined within it would be therm_something. chem.tl# might include a table of atomic weights or spectral signatures and functions to deal with them. or molar calculations .. whatever All procs and globals would be chem_something. bus1.tl# might have business forecasting items like net-present-value. icur.tl# might download the latest currency conversions and parse them into a table, THEN allow a person's international holdings of currency to display a current converted value based on money markets. The spreadsheet itself would contain the amount they have in Deutschmarks in US-Dollars, in Francs, in Yen, perhaps Krugerands, bullion. Tcl and Tcl/Tk certainly support enough TCP/IP to do it. pgp.tl# might merely parse a person's public PGP keyring and display the (long) listing in formatted columns - easy to scroll through. To remain compatible with pre-8.0 versions of Tcl/Tk, it could run PGP as a subtask long enough to retrieve the text output. cntry.tl# might merely load an ISO-3166-1 table for display. (I've nearly got *that* done, but hadn't thought of it until now for tknum. SUGGESTED ADD-ON PACKAGES ("REPOSITORIES") FOR SPECIAL FUNCTIONALITY: --------------------------------------------------------------------- Proc..tl# Knows about all built-in procs in the basic tknum.tcl spreadsheet, and all Tcl/Tk built-ins, and its own. Displays all others in a panel, with an edit window. Allows multi-proc-selections with "save to library" button. Auto-renames those saved to match library name. With procname(s) highlighted in its index, the Delete key will cause the proc to be "forgotten" both from the current run and the current spreadsheet, if all-in-a-library are deleted. Hook..tl# Adds load/save hooks and procs to manipulate menu items. Is really a meta-library of sorts, providing functionality to other libraries below. Also wedges end of "ReCalc" for things like graphics .tl#'s below. Cell..tl# 1. Cell-at-x-y where x is index from left, y is index from top. 2. Cell-above 3. Cell-at-left 4. Cell-at-right BUT will take value from prior calculation) 5. Cell-below BUT will take value from prior calculation) 6. Cell-in-same-row-at-index-from-left 7. Cell-in-same-column-at-index-from-top 8. non-scrolling cell-in-same-row-at-index-from-left (from prior) 9. non-scrolling cell-in-same-col-at-index-from-top (from prior) 10. Hotkeyed dup-cell-above (esp when row is spawned from elsewhere) 11. Hotkeyed dup-cell-at-left (esp when col is spawned from elsewhere) Oper..tl# 1. Change order of cell calculations to right-to-left 2. Change order of cell calculations to bottom-to-top 3. Recalculate selected bloc of cells only (already present) 4. Change "insertion point" to be an insert-after 5. Change "insertion point" back to normal. 6. Lock - suspends all attempts to recalculate selected cell(s), which is the logical opposite of recalculate-selection. 7. Unlock current selection. Time..tl# 1. Add time/date formatting to Format menu ([clock format value -format...]) where value is already in cell 2. Insert current time/date in Unix timestamp as a constant 3. Insert updating time/date in Unix timestamp, fix when clock stopped. 4. Difference between 2 dates 5. Difference between 2 timestamps 6. Interpret [clock scan ] to Unix timestamp - may be nested in #1. Sort..tl# 1. Sort entire spreadsheet based on column labels (re-orders columns) 2. Sort entire spreadsheet based on row labels (re-orders rows) 3. Sort entire spreadsheet based on currently selected column (re-orders rows) 4. Sort entire spreadsheet based on currently selected row (reorders columns) 5. Numeric value sort on currently selected column (re-orders rows) 6. Numeric value sort on currently selected row (re-orders columns) 7. Invert current order of rows 8. Invert current order of cols Mtrx..tl# 1. Overwrite with identity matrix at selection. 2. Invert matrix at ... 3. Scalar add/subtract 4. Scalar multiply 5. Scalar divide 6. Vector manipulations 7. Matrix-Matrix manipulations selecting each of 2 matrices from sub-blocs of spreadsheet cells. Rand..tl# Adds presets for various random-number functions, as well as a selection of seeding ideas. Imag..tl# Functions dealing with imaginary numbers in single cells. Bignum..tl# (properly Big#..tl#). Probably only available on Unix. Spawns "dc" as a background process to carry out calculations on larger numbers than Tcl is capable of handling. Capt..tl# Modifies display, export, and save routines so that blocks of the spreadsheet may have easy full-width captions and blankspace between that section and another section. Form..tl# Includes a "setup panel" which defines formatting for content of currently defined columns (if any already entered, takes formatting from last row pre-existing) and creates a "data entry" panel which tabs field-to-field, and ENTERs to add a row, until close button is pressed on panel. Also causes its own setups for this spreadsheet to be saved to spreadsheet .tk# file. Balloon..tl# Adds a balloon (optionally) to each cell. At load, adds a balloon to on-panel buttons. Causes cell-balloon values to be saved with spreadsheet's .tk# file. Snapshot.en.tl# Can't think of a reason for multilingual on this. Takes current spreadsheet and "snapshots" it to another window. (Paints $v()'s and columns/rows). Snapshot has smaller menu and no buttons, but the SPREADSHEET looks the same. For some "what if" uses, multiple snapshots might be on-screen at the same time. Places caption above spreadsheet on window. Files menu on panel has Export, Close, and Quit. No other menus on panel. Drag.en.tl# (if supported by underlying Tcl/Tk already loaded). Adds row and column shifting via drag-n-drop Adds single-cell drag-n-drop which swaps 2 cell's contents Adds single-cell drag-n-drop which copies from-cell to to-cell -- this one might have varied implementations based on WHICH Tcl/Tk shell is in use, or might adapt-on-load depending on what's loaded. Other things for .tl#'s -- Various Graphics .tl# files would interface with a background graphics filter and capture graphical output in an accompanying window - requires Hook, above. Once ONE is done, others would follow, based on which background engine is used, or variations on kinds of plots with the same background engine. I think I pointed this direction in a previous message. Save/conversion options for graphical displays would also be part of such libraries. -- Various "Print" routines. Simple ones would merely base on existing "Export" functionality. Others might snapshot to PostScript, PCL HPGL, and the like. Would require Hook, above, to append to the menu. I think I mentioned this in a previous message. -- Various other "Export" routines. You've provided the basics. Others might want a "native export to HTML table" option or "native export to Encapsulated PostScript" -- Clipboard interface - allows selection of one or more cells with export according to current "Export" options to system clipboard. Currently, the only clipboard export is from the Formula: box. Really this should be a system-specific thing. Some simple clipboards allow for ONE representation, others allow for tagged-single-export, while others allow for multiple tagged exports. This MIGHT come automatically (in its simplest form) via the "snapshot" window above. -- BIDI data entry should be part of the lang..tl# If text strings are entered in Hebrew, for example, it's up to the language implementor to allow for right-to-left entry of such data. Would require additional (dynamic) bindings to the Formula box. ON INTERNATIONALIZATION (I18N): ------------------------------- .tl# files should take ONLY the package name for identification, but may have a language identifier preceeding it. Hence a user might load, specify ckbk.en.tl# for English or ckbk.sv.tl# for Swedish or ckbk.no.tl# for Norwegian or ckbk.jp.tl# for Japansese or ckbk.es.tl# for Spanish or ckbk.de.tl# for German etc. etc. I suggest we reserv "lang..tl# for general internationalization of the application itself. Whatever language, loading lang.xx.tl# would change all labels and menu items, and the built-in manual translated to THAT language. Each lang.* translation file would start out by setting: set lang_name (the ISO-639 value for the language) set lang_code (the ISO-639 CODE for the language, as we will use in filenames) Since the application is already written in English, there probably will never need to be a lang.en.tl# library, but I'll try to spit one out so that it can be used for a prototype. OTOH, with a lang.en.tl# already in existence, a person could change back and forth between another language and English by merely reloading the other file. I18N will have to wait for a future version (who volunteers?). The following contains some good ideas on this: "I have gone through internationalization far enough to find that there are many duplicate constant strings in the program that could be EASILY translated if moved to a single global array with a key set to approximately the English text, but difficult to translate otherwise. Also, the fonts used are normally distributed with ISO-Latin-1 encoding, but where they are specified, they do not specify that encoding. Moving the font-names to that same global array would simplify use in Cyrillic or Japanese, in Arabic or Hebrew. And even in places which might need different ISO-Latin- encodings." SELF-EXTRACTING PACKAGES: ------------------------- The idea is to define a file type consisting of a spreadsheet data file and its associated repository files together in one file, accompanied by a proc definition "tmsplit", designed to write back to the disk separate .tk# (data) and .tl# (repository) files. The tmsplit procedure must be tailormade for every self-extracting package file. The suggested extension for these files is ".tm#" (m for Merged). Here is Bruce Gingery's idea (sketch) of how to write such a procedure: "This tmsplit command is unique in each tm# file, but a secondary processor *can* be created that will automatically create them from a tk# spreadsheet and resident tl# repositories. That program has not yet been written. The usual format is: proc tmsplit {} { set repositories [list name1 name2 name3] ... set procs(name1) [list .....] ... foreach r $repositories { set f [open "$r.tl#" w] if [info exists f] { foreach p [array names procs($r)] { puts -nonewline $f "proc $p \{" puts -nonewline $f [info args $p] puts $f "\} \{" puts $f [info body $p] puts $f "\}" } close $f } else { puts stderr "Creation of $r.tl# failed" exit 1 } } puts stderr "tl# files successfully extracted # code to generate the cleaned tk# spreadsheet here. # left as an exercise for the tm# creator. exit 0 } Repositories which have inline commands which act on load, other than "proc" declarations, must have those commands re-generated by the tmsplit command as the repositories are written."