[Tkabber-dev] r529 - in trunk/plugins: . translate translate/lib translate/lib/json translate/msgs

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Wed Feb 20 03:50:53 MSK 2013


Author: rejjin
Date: 2013-02-20 03:50:52 +0400 (Wed, 20 Feb 2013)
New Revision: 529

Added:
   trunk/plugins/translate/
   trunk/plugins/translate/Readme_RU
   trunk/plugins/translate/lib/
   trunk/plugins/translate/lib/json/
   trunk/plugins/translate/lib/json/json.tcl
   trunk/plugins/translate/lib/json/json_write.tcl
   trunk/plugins/translate/lib/json/pkgIndex.tcl
   trunk/plugins/translate/msgs/
   trunk/plugins/translate/msgs/ru.msg
   trunk/plugins/translate/translate.tcl
Log:
Translate plugin for yandex service.

Added: trunk/plugins/translate/Readme_RU
===================================================================
(Binary files differ)


Property changes on: trunk/plugins/translate/Readme_RU
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/plugins/translate/lib/json/json.tcl
===================================================================
--- trunk/plugins/translate/lib/json/json.tcl	                        (rev 0)
+++ trunk/plugins/translate/lib/json/json.tcl	2013-02-19 23:50:52 UTC (rev 529)
@@ -0,0 +1,320 @@
+#
+#   JSON parser for Tcl.
+#
+#   See http://www.json.org/ && http://www.ietf.org/rfc/rfc4627.txt
+#
+#   Total rework of the code published with version number 1.0 by
+#   Thomas Maeder, Glue Software Engineering AG
+#
+#   $Id: json.tcl,v 1.7 2011/11/10 21:05:58 andreas_kupries Exp $
+#
+
+if {![package vsatisfies [package provide Tcl] 8.5]} {
+    package require dict
+}
+
+package provide json 1.1.2
+
+namespace eval json {
+    # Regular expression for tokenizing a JSON text (cf. http://json.org/)
+
+    # tokens consisting of a single character
+    variable singleCharTokens { "{" "}" ":" "\\[" "\\]" "," }
+    variable singleCharTokenRE "\[[join $singleCharTokens {}]\]"
+
+    # quoted string tokens
+    variable escapableREs { "[\\\"\\\\/bfnrt]" "u[[:xdigit:]]{4}" }
+    variable escapedCharRE "\\\\(?:[join $escapableREs |])"
+    variable unescapedCharRE {[^\\\"]}
+    variable stringRE "\"(?:$escapedCharRE|$unescapedCharRE)*\""
+
+    # (unquoted) words
+    variable wordTokens { "true" "false" "null" }
+    variable wordTokenRE [join $wordTokens "|"]
+
+    # number tokens
+    # negative lookahead (?!0)[[:digit:]]+ might be more elegant, but
+    # would slow down tokenizing by a factor of up to 3!
+    variable positiveRE {[1-9][[:digit:]]*}
+    variable cardinalRE "-?(?:$positiveRE|0)"
+    variable fractionRE {[.][[:digit:]]+}
+    variable exponentialRE {[eE][+-]?[[:digit:]]+}
+    variable numberRE "${cardinalRE}(?:$fractionRE)?(?:$exponentialRE)?"
+
+    # JSON token
+    variable tokenRE "$singleCharTokenRE|$stringRE|$wordTokenRE|$numberRE"
+
+
+    # 0..n white space characters
+    set whiteSpaceRE {[[:space:]]*}
+
+    # Regular expression for validating a JSON text
+    variable validJsonRE "^(?:${whiteSpaceRE}(?:$tokenRE))*${whiteSpaceRE}$"
+}
+
+
+# Validate JSON text
+# @param jsonText JSON text
+# @return 1 iff $jsonText conforms to the JSON grammar
+#           (@see http://json.org/)
+proc json::validate {jsonText} {
+    variable validJsonRE
+
+    return [regexp -- $validJsonRE $jsonText]
+}
+
+# Parse JSON text into a dict
+# @param jsonText JSON text
+# @return dict (or list) containing the object represented by $jsonText
+proc json::json2dict {jsonText} {
+    variable tokenRE
+
+    set tokens [regexp -all -inline -- $tokenRE $jsonText]
+    set nrTokens [llength $tokens]
+    set tokenCursor 0
+    return [parseValue $tokens $nrTokens tokenCursor]
+}
+
+# Throw an exception signaling an unexpected token
+proc json::unexpected {tokenCursor token expected} {
+     return -code error "unexpected token \"$token\" at position $tokenCursor; expecting $expected"
+}
+
+# Get rid of the quotes surrounding a string token and substitute the
+# real characters for escape sequences within it
+# @param token
+# @return unquoted unescaped value of the string contained in $token
+proc json::unquoteUnescapeString {token} {
+    set unquoted [string range $token 1 end-1]
+    return [subst -nocommands -novariables $unquoted]
+}
+
+# Parse an object member
+# @param tokens list of tokens
+# @param nrTokens length of $tokens
+# @param tokenCursorName name (in caller's context) of variable
+#                        holding current position in $tokens
+# @param objectDictName name (in caller's context) of dict
+#                       representing the JSON object of which to
+#                       parse the next member
+proc json::parseObjectMember {tokens nrTokens tokenCursorName objectDictName} {
+    upvar $tokenCursorName tokenCursor
+    upvar $objectDictName objectDict
+
+    set token [lindex $tokens $tokenCursor]
+    incr tokenCursor
+
+    set leadingChar [string index $token 0]
+    if {$leadingChar eq "\""} {
+        set memberName [unquoteUnescapeString $token]
+
+        if {$tokenCursor == $nrTokens} {
+            unexpected $tokenCursor "END" "\":\""
+        } else {
+            set token [lindex $tokens $tokenCursor]
+            incr tokenCursor
+
+            if {$token eq ":"} {
+                set memberValue [parseValue $tokens $nrTokens tokenCursor]
+                dict set objectDict $memberName $memberValue
+            } else {
+                unexpected $tokenCursor $token "\":\""
+            }
+        }
+    } else {
+        unexpected $tokenCursor $token "STRING"
+    }
+}
+
+# Parse the members of an object
+# @param tokens list of tokens
+# @param nrTokens length of $tokens
+# @param tokenCursorName name (in caller's context) of variable
+#                        holding current position in $tokens
+# @param objectDictName name (in caller's context) of dict
+#                       representing the JSON object of which to
+#                       parse the next member
+proc json::parseObjectMembers {tokens nrTokens tokenCursorName objectDictName} {
+    upvar $tokenCursorName tokenCursor
+    upvar $objectDictName objectDict
+
+    while true {
+        parseObjectMember $tokens $nrTokens tokenCursor objectDict
+
+        set token [lindex $tokens $tokenCursor]
+        incr tokenCursor
+
+        switch -exact $token {
+            "," {
+                # continue
+            }
+            "\}" {
+                break
+            }
+            default {
+                unexpected $tokenCursor $token "\",\"|\"\}\""
+            }
+        }
+    }
+}
+
+# Parse an object
+# @param tokens list of tokens
+# @param nrTokens length of $tokens
+# @param tokenCursorName name (in caller's context) of variable
+#                        holding current position in $tokens
+# @return parsed object (Tcl dict)
+proc json::parseObject {tokens nrTokens tokenCursorName} {
+    upvar $tokenCursorName tokenCursor
+
+    if {$tokenCursor == $nrTokens} {
+        unexpected $tokenCursor "END" "OBJECT"
+    } else {
+        set result [dict create]
+
+        set token [lindex $tokens $tokenCursor]
+
+        if {$token eq "\}"} {
+            # empty object
+            incr tokenCursor
+        } else {
+            parseObjectMembers $tokens $nrTokens tokenCursor result
+        }
+
+        return $result
+    }
+}
+
+# Parse the elements of an array
+# @param tokens list of tokens
+# @param nrTokens length of $tokens
+# @param tokenCursorName name (in caller's context) of variable
+#                        holding current position in $tokens
+# @param resultName name (in caller's context) of the list
+#                   representing the JSON array
+proc json::parseArrayElements {tokens nrTokens tokenCursorName resultName} {
+    upvar $tokenCursorName tokenCursor
+    upvar $resultName result
+
+    while true {
+        lappend result [parseValue $tokens $nrTokens tokenCursor]
+
+        if {$tokenCursor == $nrTokens} {
+            unexpected $tokenCursor "END" "\",\"|\"\]\""
+        } else {
+            set token [lindex $tokens $tokenCursor]
+            incr tokenCursor
+
+            switch -exact $token {
+                "," {
+                    # continue
+                }
+                "\]" {
+                    break
+                }
+                default {
+                    unexpected $tokenCursor $token "\",\"|\"\]\""
+                }
+            }
+        }
+    }
+}
+
+# Parse an array
+# @param tokens list of tokens
+# @param nrTokens length of $tokens
+# @param tokenCursorName name (in caller's context) of variable
+#                        holding current position in $tokens
+# @return parsed array (Tcl list)
+proc json::parseArray {tokens nrTokens tokenCursorName} {
+    upvar $tokenCursorName tokenCursor
+
+    if {$tokenCursor == $nrTokens} {
+        unexpected $tokenCursor "END" "ARRAY"
+    } else {
+        set result {}
+
+        set token [lindex $tokens $tokenCursor]
+
+        set leadingChar [string index $token 0]
+        if {$leadingChar eq "\]"} {
+            # empty array
+            incr tokenCursor
+        } else {
+            parseArrayElements $tokens $nrTokens tokenCursor result
+        }
+
+        return $result
+    }
+}
+
+# Parse a value
+# @param tokens list of tokens
+# @param nrTokens length of $tokens
+# @param tokenCursorName name (in caller's context) of variable
+#                        holding current position in $tokens
+# @return parsed value (dict, list, string, number)
+proc json::parseValue {tokens nrTokens tokenCursorName} {
+    upvar $tokenCursorName tokenCursor
+
+    if {$tokenCursor == $nrTokens} {
+        unexpected $tokenCursor "END" "VALUE"
+    } else {
+        set token [lindex $tokens $tokenCursor]
+        incr tokenCursor
+
+        set leadingChar [string index $token 0]
+        switch -exact -- $leadingChar {
+            "\{" {
+                return [parseObject $tokens $nrTokens tokenCursor]
+            }
+            "\[" {
+                return [parseArray $tokens $nrTokens tokenCursor]
+            }
+            "\"" {
+                # quoted string
+                return [unquoteUnescapeString $token]
+            }
+            "t" -
+            "f" -
+            "n" {
+                # bare word: true, false or null
+                return $token
+            }
+            default {
+                # number?
+                if {[string is double -strict $token]} {
+                    return $token
+                } else {
+                    unexpected $tokenCursor $token "VALUE"
+                }
+            }
+        }
+    }
+}
+
+proc json::dict2json {dictVal} {
+    # XXX: Currently this API isn't symmetrical, as to create proper
+    # XXX: JSON text requires type knowledge of the input data
+    set json ""
+
+    dict for {key val} $dictVal {
+	# key must always be a string, val may be a number, string or
+	# bare word (true|false|null)
+	if {0 && ![string is double -strict $val]
+	    && ![regexp {^(?:true|false|null)$} $val]} {
+	    set val "\"$val\""
+	}
+    	append json "\"$key\": $val," \n
+    }
+
+    return "\{${json}\}"
+}
+
+proc json::list2json {listVal} {
+    return "\[[join $listVal ,]\]"
+}
+
+proc json::string2json {str} {
+    return "\"$str\""
+}


Property changes on: trunk/plugins/translate/lib/json/json.tcl
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/plugins/translate/lib/json/json_write.tcl
===================================================================
--- trunk/plugins/translate/lib/json/json_write.tcl	                        (rev 0)
+++ trunk/plugins/translate/lib/json/json_write.tcl	2013-02-19 23:50:52 UTC (rev 529)
@@ -0,0 +1,185 @@
+# json_write.tcl --
+#
+#	Commands for the generation of JSON (Java Script Object Notation).
+#
+# Copyright (c) 2009-2011 Andreas Kupries <andreas_kupries at sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# RCS: @(#) $Id: json_write.tcl,v 1.2 2011/08/24 20:09:44 andreas_kupries Exp $
+
+# ### ### ### ######### ######### #########
+## Requisites
+
+package require Tcl 8.5
+
+namespace eval ::json::write {
+    namespace export \
+	string array object indented aligned
+
+    namespace ensemble create
+}
+
+# ### ### ### ######### ######### #########
+## API.
+
+proc ::json::write::indented {{bool {}}} {
+    variable indented
+
+    if {[llength [info level 0]] > 2} {
+	return -code error {wrong # args: should be "json::write indented ?bool?"}
+    } elseif {[llength [info level 0]] == 2} {
+	if {![::string is boolean -strict $bool]} {
+	    return -code error "Expected boolean, got \"$bool\""
+	}
+	set indented $bool
+	if {!$indented} {
+	    variable aligned 0
+	}
+    }
+
+    return $indented
+}
+
+proc ::json::write::aligned {{bool {}}} {
+    variable aligned
+
+    if {[llength [info level 0]] > 2} {
+	return -code error {wrong # args: should be "json::write aligned ?bool?"}
+    } elseif {[llength [info level 0]] == 2} {
+	if {![::string is boolean -strict $bool]} {
+	    return -code error "Expected boolean, got \"$bool\""
+	}
+	set aligned $bool
+	if {$aligned} {
+	    variable indented 1
+	}
+    }
+
+    return $aligned
+}
+
+proc ::json::write::string {s} {
+    variable quotes
+    return "\"[::string map $quotes $s]\""
+}
+
+proc ::json::write::array {args} {
+    # always compact form.
+    return "\[[join $args ,]\]"
+}
+
+proc ::json::write::object {args} {
+    # The dict in args maps string keys to json-formatted data. I.e.
+    # we have to quote the keys, but not the values, as the latter are
+    # already in the proper format.
+
+    variable aligned
+    variable indented
+
+    if {[llength $args] %2 == 1} {
+	return -code error {wrong # args, expected an even number of arguments}
+    }
+
+    set dict {}
+    foreach {k v} $args {
+	lappend dict [string $k] $v
+    }
+
+    if {$aligned} {
+	set max [MaxKeyLength $dict]
+    }
+
+    if {$indented} {
+	set content {}
+	foreach {k v} $dict {
+	    if {$aligned} {
+		set k [AlignLeft $max $k]
+	    }
+	    if {[::string match *\n* $v]} {
+		# multi-line value
+		lappend content "    $k : [Indent $v {    } 1]"
+	    } else {
+		# single line value.
+		lappend content "    $k : $v"
+	    }
+	}
+	if {[llength $content]} {
+	    return "\{\n[join $content ,\n]\n\}"
+	} else {
+	    return "\{\}"
+	}
+    } else {
+	# ultra compact form.
+	set tmp {}
+	foreach {k v} $dict {
+	    lappend tmp "$k:$v"
+	}
+	return "\{[join $tmp ,]\}"
+    }
+}
+
+# ### ### ### ######### ######### #########
+## Internals.
+
+proc ::json::write::Indent {text prefix skip} {
+    set pfx ""
+    set result {}
+    foreach line [split $text \n] {
+	if {!$skip} { set pfx $prefix } else { incr skip -1 }
+	lappend result ${pfx}$line
+    }
+    return [join $result \n]
+}
+
+proc ::json::write::MaxKeyLength {dict} {
+    # Find the max length of the keys in the dictionary.
+
+    set lengths 0 ; # This will be the max if the dict is empty, and
+		    # prevents the mathfunc from throwing errors for
+		    # that case.
+
+    foreach str [dict keys $dict] {
+	lappend lengths [::string length $str]
+    }
+
+    return [tcl::mathfunc::max {*}$lengths]
+}
+
+proc ::json::write::AlignLeft {fieldlen str} {
+    return [format %-${fieldlen}s $str]
+    #return $str[::string repeat { } [expr {$fieldlen - [::string length $str]}]]
+}
+
+# ### ### ### ######### ######### #########
+
+namespace eval ::json::write {
+    # Configuration of the layout to write.
+
+    # indented = boolean. objects are indented.
+    # aligned  = boolean. object keys are aligned vertically.
+
+    # aligned  => indented.
+
+    # Combinations of the format specific entries
+    # I A |
+    # - - + ---------------------
+    # 0 0 | Ultracompact (no whitespace, single line)
+    # 1 0 | Indented
+    # 0 1 | Not possible, per the implications above.
+    # 1 1 | Indented + vertically aligned keys
+    # - - + ---------------------
+
+    variable indented 1
+    variable aligned  1
+
+    variable quotes \
+	[list "\"" "\\\"" \\ \\\\ \b \\b \f \\f \n \\n \r \\r \t \\t]
+}
+
+# ### ### ### ######### ######### #########
+## Ready
+
+package provide json::write 1.0.2
+return


Property changes on: trunk/plugins/translate/lib/json/json_write.tcl
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/plugins/translate/lib/json/pkgIndex.tcl
===================================================================
--- trunk/plugins/translate/lib/json/pkgIndex.tcl	                        (rev 0)
+++ trunk/plugins/translate/lib/json/pkgIndex.tcl	2013-02-19 23:50:52 UTC (rev 529)
@@ -0,0 +1,7 @@
+# Tcl package index file, version 1.1
+
+if {![package vsatisfies [package provide Tcl] 8.4]} {return}
+package ifneeded json 1.1.2 [list source [file join $dir json.tcl]]
+
+if {![package vsatisfies [package provide Tcl] 8.5]} {return}
+package ifneeded json::write 1.0.2 [list source [file join $dir json_write.tcl]]


Property changes on: trunk/plugins/translate/lib/json/pkgIndex.tcl
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/plugins/translate/msgs/ru.msg
===================================================================
--- trunk/plugins/translate/msgs/ru.msg	                        (rev 0)
+++ trunk/plugins/translate/msgs/ru.msg	2013-02-19 23:50:52 UTC (rev 529)
@@ -0,0 +1,10 @@
+::msgcat::mcset ru "Translate" "Перевод"
+::msgcat::mcset ru "Autodetect" "Автоопределение"
+::msgcat::mcset ru "Translate result | %s" "Результат перевода | %s"
+::msgcat::mcset ru "Cancel" "Закрыть"
+::msgcat::mcset ru "Error code: %s\nText: %s" "Код ошибки: %s\nТекст: %s"
+::msgcat::mcset ru "Error!" "Ошибка!"
+::msgcat::mcset ru "Exceeded the maximum size of the text." "Превышен максимальный размер текста."
+::msgcat::mcset ru "The text may not be transferred." "Текст не может быть переведен."
+::msgcat::mcset ru "The direction of transfer is not supported." "Заданное направление перевода не поддерживается."
+::msgcat::mcset ru "Error connecting to the server." "Ошибка подключения к серверу."
\ No newline at end of file


Property changes on: trunk/plugins/translate/msgs/ru.msg
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/plugins/translate/translate.tcl
===================================================================
--- trunk/plugins/translate/translate.tcl	                        (rev 0)
+++ trunk/plugins/translate/translate.tcl	2013-02-19 23:50:52 UTC (rev 529)
@@ -0,0 +1,197 @@
+# $Id$
+# Contact: webrenji at gmail.com | rejjin at jabber.dk
+
+lappend ::auto_path [file join [file dirname [info script]] "lib"]
+
+package require http
+package require json
+package require msgcat
+package require BWidget
+
+namespace eval translate {
+	
+	::msgcat::mcload [file join [file dirname [info script]] msgs]
+	
+	variable Urls
+	set Urls(langList) "http://translate.yandex.net/api/v1/tr.json/getLangs"
+	set Urls(detectLang) "http://translate.yandex.net/api/v1/tr.json/detect?text=%text%"
+	set Urls(translateText) "http://translate.yandex.net/api/v1/tr.json/translate?lang=%lang%&text=%text%"
+	
+	variable dLangs
+	array set dLangs {} ;# For breaking exception
+	
+	variable localLang [lindex [split [msgcat::mclocale] _] 0]
+	
+	proc InitMenu {m chatwin X Y x y} {
+		variable dLangs
+		variable localLang
+		
+		set text ""
+		catch { set text [$chatwin get sel.first sel.last] }
+		
+		if {[string length $text] == 0} {
+			return ;# If selection text is none
+		}
+	
+		$m add cascade -label [::msgcat::mc "Translate"] \
+			-menu [menu $m.translate -tearoff 0]
+		$m add separator
+		
+		$m.translate add command -label [::msgcat::mc "Autodetect"] \
+			-command [list [namespace current]::translate $chatwin $localLang]
+		$m.translate add separator
+		
+		foreach lang [array names dLangs] {
+			lassign [split $lang -] from to
+			lappend lngmap($from) $to
+		}
+		
+		foreach left [lsort [array names lngmap]] {
+			$m.translate add cascade -label "$left  " \
+				-menu [menu $m.translate.$left -tearoff 0]
+			foreach right [lsort $lngmap($left)] {
+				$m.translate.$left add command \
+					-label "$left -> $right" \
+					-command [list [namespace current]::translate $chatwin \
+						[join [list $left $right] -] ]
+			}
+		}
+	}
+	
+	proc translate {chatwin lang} {
+		variable Urls
+		
+		set text [::http::formatQuery [$chatwin get sel.first sel.last]]
+		
+		regsub "%lang%" $Urls(translateText) $lang url
+		regsub "%text%" $url $text url
+		
+		if {[catch {set token [::http::geturl $url \
+				-command [namespace current]::translateClbk]}]} {
+			output 0 - -
+			return
+		}
+		
+		::http::wait $token		
+	}
+	
+	proc translateClbk {token} {
+		set data [::http::data $token]
+		set result [::json::json2dict $data]
+		
+		set code [dict get $result "code"]; set text ""
+		if {$code eq "200"} {
+			set text [encoding convertfrom utf-8 \
+				[lindex [dict get $result "text"] 0]]
+			set lang [dict get $result "lang"]
+			output $code $text $lang
+		} else {
+			output $code _ _
+		}
+		
+		::http::cleanup $token
+	}
+	
+	proc output {code text lang} {
+		toplevel .translate
+		
+		.translate configure -borderwidth 2 -relief solid
+		
+		catch {wm attributes .translate -topmost 1}
+		catch {wm overrideredirect .translate 1}
+		catch {wm resizable .translate 0 0}
+		
+		label .translate.header -text [::msgcat::mc "Translate result | %s" $lang]
+		text .translate.result -wrap word -height 14
+		button .translate.cancel -text [::msgcat::mc "Cancel"] \
+			-command {destroy .translate}
+			
+		pack .translate.header -fill x -expand yes
+		pack .translate.result -fill both -expand yes
+		pack .translate.cancel -fill x -expand yes -padx 1 -pady 1
+		
+		BWidget::place .translate 0 0 center
+		
+		if {$code eq "200"} {
+			.translate.result insert 1.0 $text
+		} else {
+			switch -exact $code {
+				413 { 
+					set text [::msgcat::mc "Exceeded the maximum size of the text."]
+				}
+				422 {
+					set text [::msgcat::mc "The text may not be transferred."]
+				}
+				501 {
+					set text [::msgcat::mc "The direction of transfer is not supported."]
+				}
+				0 {
+					set text [::msgcat::mc "Error connecting to the server."]
+				}
+			}
+			
+			.translate.result insert 1.0 [::msgcat::mc "Error code: %s\nText: %s" $code $text]
+			.translate.header configure -text [::msgcat::mc "Error!"]
+		}
+	}
+	
+	proc getLanguageList {} {
+		variable Urls
+		
+		if {[catch {set token [::http::geturl $Urls(langList) \
+				-command [namespace current]::getLanguageListClbk]}]} {
+			return
+		}
+		
+		::http::wait $token
+	}
+	
+	proc getLanguageListClbk {token} {
+		variable dLangs
+		
+		set data [::http::data $token]
+		
+		foreach lang [dict get [::json::json2dict $data] "dirs"] {
+			set dLangs($lang) 0
+		}
+		
+		::http::cleanup $token
+	}
+	
+	proc to_tag {text} {
+		variable texttag
+		variable tagtext
+		
+		if {[info exists texttag($text)]} {
+			return $texttag($text)
+		}
+		
+		regsub -all {[^[:alnum:]]+} $text {} prefix
+		set tag $prefix[rand 1000000000]
+		while {[info exists tagtext($tag)]} {
+			set tag $prefix[rand 1000000000]
+		}
+		
+		set texttag($text) $tag
+		set tagtext($tag) $text
+		
+		return $tag
+	}
+
+	proc rand {num} {
+		return [expr int(floor(rand()*$num))]
+	}
+
+	proc from_tag {tag} {
+		variable tagtext
+
+		if {[info exists tagtext($tag)]} {
+			return $tagtext($tag)
+		}
+		
+		::error::error "Unknown tag $tag"
+	}
+	
+	hook::add chat_win_popup_menu_hook [namespace current]::InitMenu 1
+	hook::add finload_hook [namespace current]::getLanguageList
+}
\ No newline at end of file


Property changes on: trunk/plugins/translate/translate.tcl
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native



More information about the Tkabber-dev mailing list