jpayne@69: # word.tcl -- jpayne@69: # jpayne@69: # This file defines various procedures for computing word boundaries in jpayne@69: # strings. This file is primarily needed so Tk text and entry widgets behave jpayne@69: # properly for different platforms. jpayne@69: # jpayne@69: # Copyright (c) 1996 Sun Microsystems, Inc. jpayne@69: # Copyright (c) 1998 Scritpics Corporation. jpayne@69: # jpayne@69: # See the file "license.terms" for information on usage and redistribution jpayne@69: # of this file, and for a DISCLAIMER OF ALL WARRANTIES. jpayne@69: jpayne@69: # The following variables are used to determine which characters are jpayne@69: # interpreted as white space. jpayne@69: jpayne@69: if {$::tcl_platform(platform) eq "windows"} { jpayne@69: # Windows style - any but a unicode space char jpayne@69: if {![info exists ::tcl_wordchars]} { jpayne@69: set ::tcl_wordchars {\S} jpayne@69: } jpayne@69: if {![info exists ::tcl_nonwordchars]} { jpayne@69: set ::tcl_nonwordchars {\s} jpayne@69: } jpayne@69: } else { jpayne@69: # Motif style - any unicode word char (number, letter, or underscore) jpayne@69: if {![info exists ::tcl_wordchars]} { jpayne@69: set ::tcl_wordchars {\w} jpayne@69: } jpayne@69: if {![info exists ::tcl_nonwordchars]} { jpayne@69: set ::tcl_nonwordchars {\W} jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: # Arrange for caches of the real matcher REs to be kept, which enables the REs jpayne@69: # themselves to be cached for greater performance (and somewhat greater jpayne@69: # clarity too). jpayne@69: jpayne@69: namespace eval ::tcl { jpayne@69: variable WordBreakRE jpayne@69: array set WordBreakRE {} jpayne@69: jpayne@69: proc UpdateWordBreakREs args { jpayne@69: # Ignores the arguments jpayne@69: global tcl_wordchars tcl_nonwordchars jpayne@69: variable WordBreakRE jpayne@69: jpayne@69: # To keep the RE strings short... jpayne@69: set letter $tcl_wordchars jpayne@69: set space $tcl_nonwordchars jpayne@69: jpayne@69: set WordBreakRE(after) "$letter$space|$space$letter" jpayne@69: set WordBreakRE(before) "^.*($letter$space|$space$letter)" jpayne@69: set WordBreakRE(end) "$space*$letter+$space" jpayne@69: set WordBreakRE(next) "$letter*$space+$letter" jpayne@69: set WordBreakRE(previous) "$space*($letter+)$space*\$" jpayne@69: } jpayne@69: jpayne@69: # Initialize the cache jpayne@69: UpdateWordBreakREs jpayne@69: trace add variable ::tcl_wordchars write ::tcl::UpdateWordBreakREs jpayne@69: trace add variable ::tcl_nonwordchars write ::tcl::UpdateWordBreakREs jpayne@69: } jpayne@69: jpayne@69: # tcl_wordBreakAfter -- jpayne@69: # jpayne@69: # This procedure returns the index of the first word boundary after the jpayne@69: # starting point in the given string, or -1 if there are no more boundaries in jpayne@69: # the given string. The index returned refers to the first character of the jpayne@69: # pair that comprises a boundary. jpayne@69: # jpayne@69: # Arguments: jpayne@69: # str - String to search. jpayne@69: # start - Index into string specifying starting point. jpayne@69: jpayne@69: proc tcl_wordBreakAfter {str start} { jpayne@69: variable ::tcl::WordBreakRE jpayne@69: set result {-1 -1} jpayne@69: regexp -indices -start $start -- $WordBreakRE(after) $str result jpayne@69: return [lindex $result 1] jpayne@69: } jpayne@69: jpayne@69: # tcl_wordBreakBefore -- jpayne@69: # jpayne@69: # This procedure returns the index of the first word boundary before the jpayne@69: # starting point in the given string, or -1 if there are no more boundaries in jpayne@69: # the given string. The index returned refers to the second character of the jpayne@69: # pair that comprises a boundary. jpayne@69: # jpayne@69: # Arguments: jpayne@69: # str - String to search. jpayne@69: # start - Index into string specifying starting point. jpayne@69: jpayne@69: proc tcl_wordBreakBefore {str start} { jpayne@69: variable ::tcl::WordBreakRE jpayne@69: set result {-1 -1} jpayne@69: regexp -indices -- $WordBreakRE(before) [string range $str 0 $start] result jpayne@69: return [lindex $result 1] jpayne@69: } jpayne@69: jpayne@69: # tcl_endOfWord -- jpayne@69: # jpayne@69: # This procedure returns the index of the first end-of-word location after a jpayne@69: # starting index in the given string. An end-of-word location is defined to be jpayne@69: # the first whitespace character following the first non-whitespace character jpayne@69: # after the starting point. Returns -1 if there are no more words after the jpayne@69: # starting point. jpayne@69: # jpayne@69: # Arguments: jpayne@69: # str - String to search. jpayne@69: # start - Index into string specifying starting point. jpayne@69: jpayne@69: proc tcl_endOfWord {str start} { jpayne@69: variable ::tcl::WordBreakRE jpayne@69: set result {-1 -1} jpayne@69: regexp -indices -start $start -- $WordBreakRE(end) $str result jpayne@69: return [lindex $result 1] jpayne@69: } jpayne@69: jpayne@69: # tcl_startOfNextWord -- jpayne@69: # jpayne@69: # This procedure returns the index of the first start-of-word location after a jpayne@69: # starting index in the given string. A start-of-word location is defined to jpayne@69: # be a non-whitespace character following a whitespace character. Returns -1 jpayne@69: # if there are no more start-of-word locations after the starting point. jpayne@69: # jpayne@69: # Arguments: jpayne@69: # str - String to search. jpayne@69: # start - Index into string specifying starting point. jpayne@69: jpayne@69: proc tcl_startOfNextWord {str start} { jpayne@69: variable ::tcl::WordBreakRE jpayne@69: set result {-1 -1} jpayne@69: regexp -indices -start $start -- $WordBreakRE(next) $str result jpayne@69: return [lindex $result 1] jpayne@69: } jpayne@69: jpayne@69: # tcl_startOfPreviousWord -- jpayne@69: # jpayne@69: # This procedure returns the index of the first start-of-word location before jpayne@69: # a starting index in the given string. jpayne@69: # jpayne@69: # Arguments: jpayne@69: # str - String to search. jpayne@69: # start - Index into string specifying starting point. jpayne@69: jpayne@69: proc tcl_startOfPreviousWord {str start} { jpayne@69: variable ::tcl::WordBreakRE jpayne@69: set word {-1 -1} jpayne@69: if {$start > 0} { jpayne@69: regexp -indices -- $WordBreakRE(previous) [string range $str 0 $start-1] \ jpayne@69: result word jpayne@69: } jpayne@69: return [lindex $word 0] jpayne@69: }