FF 2007-05-13 I remember some people asked about displaying mathematical formula in Tcl. Some implemented typesetting-like systems in pure Tcl. Cause I don't like re-inventing the wheel I preferred using a well known working system, based on a well known typesetting language: TeX (more precisely, the math extensions).Btw the TeX distribution can be quite huge, and sometimes troublesome to install on non-UNIX-like systems (see Windows).Fortunately a nice small application here comes in help: mimetex.mimetex is mainly used in the CGI form, e.g. wikis and forums, to display mathematical formulae (see Wikipedia for a live example). Anyway it can be compiled as a standalone executable, producing nice GIF (anti-aliased, if you want it) output.The script below it is just an example on how to embed it for using into a canvas.I addressed several problems, like working with live iostreams, base64 encoding, and without producing intermediate temporary files. Feel free to improve it (and post it here) if you like.See also: Rendering mathematical formulae for an alternative example, not using TeX at all. #!/bin/sh
# This line continues for Tcl, but is a single line for 'sh' \
exec tclsh "$0" ${1+"$@"}
package require base64
set img {}
#set mimetex_bin "c:/mimetex/mt.exe"
set mimetex_bin "mimetex"
proc render e {
global img
.c delete eee
catch {image delete $img}
set p [open [list |$::mimetex_bin -d $e] r]
fconfigure $p -translation binary -encoding binary
set rawData [base64::encode [read $p]]
close $p
set img [image create photo -data $rawData]
.c create image 10 10 -image $img -tags eee -anchor nw
}
grid [canvas .c] -row 0 -columnspan 2 -sticky news
grid [entry .t -textvariable ee] -row 1 -column 0 -sticky we
grid [button .b -command {render $ee} -text Render] -row 1 -column 1
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1
set ee "x_{1,2}=\\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}"EKB This is really nifty. I've got two friendly amendments:
- I pulled out the pure rendering code into its own namespace (expression -> img) to make it more reusable
- I created a "save" proc + button so that if you like the image you can save it to a file
#!/bin/sh
# This line continues for Tcl, but is a single line for 'sh' \
exec tclsh "$0" ${1+"$@"}
package require base64
namespace eval mtex {
# variable bin "c:/mimetex/mt.exe"
variable bin "mimetex"
}
proc mtex::mtex2img {e {img {}}} {
variable bin
set p [open [list |$bin -d $e] r]
fconfigure $p -translation binary -encoding binary
set rawData [base64::encode [read $p]]
close $p
if {$img eq ""} {
return [image create photo -data $rawData]
} else {
return [image create photo $img -data $rawData]
}
}
proc render e {
global img
.c delete eee
catch {image delete $img}
set img [mtex::mtex2img $e]
.c create image 10 10 -image $img -tags eee -anchor nw
}
proc save {} {
global img
if {![info exists img]} {return}
set fname [tk_getSaveFile -defaultextension ".gif" \
-filetypes {{{GIF Files} {.gif} }}]
# Cancelled the save
if {$fname eq ""} {return}
if [catch {$img write $fname -format GIF} err] {
error "Could not save image: $err"
}
}
grid [canvas .c] -row 0 -columnspan 3 -sticky news
grid [entry .t -textvariable ee] -row 1 -column 0 -sticky we
grid [button .b -command {render $ee} -text Render] -row 1 -column 1
grid [button .s -command {save} -text "Save As"] -row 1 -column 2
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1
set ee "x_{1,2}=\\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}"
