WJG (04/11/07) This week I've spent too many hours using OpenOffice correcting simple single and double quotes in page after page of text files created in my Tk based text editor. Pity I didn't sit down and complete the following proc and use it some time ago. If anyone has any suggestion please include them but please don't change the original code -just add comments to the end of the file.
#---------------
# balanceQuotes.tcl
#---------------
# William J Giddings
# 04/11/07
#---------------
# Enable context sensitive quotations.
# If the input quote mark is preceded by a printable character,
# then closequote otherwise openquote!
#
#---------------
# Notes:
# This is not "smart" and so doesn't attempt to balance quote marks.
#---------------
#!/bin/sh \
exec tclsh "$0" "$@"
package require Tk
#---------------
# w text widget into which the substition is to be made
# c character currently inserted
#---------------
proc balanceQuotes {w c} {
#get the preceding character
set idx [$w index insert]
set str [$w get "$idx -1char" $idx]
# if null is returned, it must be the start of a line
# so make it whitespace
if {$str == "" } {set str " "}
# check for character types
# the character class print is not used as <space> is printable!
if { [string is wordchar $str] || [string is punct $str] } {
# check if the previous character is an open quote.
# nested open quotations need to be allowed for
if { $str == "\u2018" || $str == "\u201C" } {
set i 0
} else {
set i 1
}
if {$c == "apostrophe"} {
if {$i} {
$w insert insert \u2019 ;# single close
} else {
$w insert insert \u2018 ;# single open
}
} else {
# must be quotedl
if {$i} {
$w insert insert \u201D ;# double close
} else {
$w insert insert \u201C ;# double open
}
}
} else {
if {$c == "apostrophe"} {
$w insert insert \u2018 ;# single open
} else {
# must be quotedl
$w insert insert \u201C ;# double open
}
}
}
#---------------
# Demo
#---------------
set txt [text .txt -font {Sans 15}]
pack $txt
bind $txt <Key-apostrophe> { balanceQuotes %W %K ; break }
bind $txt <Key-quotedbl> { balanceQuotes %W %K ; break }MG gets an error about "apostrophe" not being a valid keysym; I think maybe it should be "quoteright"?
WJG (05/11/07) It all works fine on my machine.
MG That's weird; I thought the keysyms were the same across all platforms. What system are you using? (Mine is Tcl 8.4.9 / 8.5a1 on Win XP SP2)
WJG (06/11/07) Suse 10.1, Tcl 8.4.12. My code is fine. Does your system generate a "quoteright" keysym when the error occurs? I can't find that listed in my docs. Try the following binding on a text widget to check what keysym your system generates.
console show
set txt [text .txt]
pack $txt
bind $txt <Key> { puts %K }MG Sorry; I answered this before, but it seems to have disappeared. Yeah, for me the apostrophe key generates a "quoteright" keysym, and that's what's listed in the keysym helpfile I have (the Win .chm from ActiveTcl 8.4.9).
LV Yea, there was data loss last week and my comments were lost as well. I ran the above code against the hummingbird Windows x server, and I got
' => apostrophe ` => grave
WJG (16/11/07) Naturally, just modify the codes to suit. I guess some platform checking could be put in there but perhaps this issue one that Tcl Core guys can resolve in order to maintain cross-platform compatibility.