Posted to tcl by Stu at Sat May 10 03:02:34 GMT 2008view pretty
# herring
#
# May 2008
# Stuart Cassoff
#
# Use at your own risk
# (many have died)
#
namespace eval herring {
variable HookUserInfoDialog 0
variable InfoRaw 0
variable TwigRun 0
variable cfg
set cfg(version) 0.1
set cfg(tclsh) /usr/local/bin/tclsh8.5
set cfg(wish) /usr/local/bin/wish8.5
set cfg(twig) ~/tcl/twig/twig.tcl
set cfg(run) $cfg(wish)
set cfg(myTwigListFile) ~/twiglist.twig
set cfg(twigs) {}
# Chat Text Window
set cfg(ctw) .txt
set cfg(aliasMap) [list \
wikiref ::herring::wikiref \
twig ::herring::twig \
]
set cfg(floodcount) 0
set cfg(floodmax) 15
}
proc herring::wikisearch {what {max -1}} {
set z {}
set c 0
set h [http::geturl http://wiki.tcl.tk/_search?S=$what]
if {[http::status $h] eq {ok}} {
foreach {. p n} [regexp -inline -all {<li>.*?\. \. \. <a href="/(.*?)">(.*?)</a>} [http::data $h]] {
lappend z http://wiki.tcl.tk/$p\ \t$n
if {$max == -1} { continue }
if {[incr c] >= $max} { break }
}
}
http::cleanup $h
return $z
}
proc herring::wikiref {msg} {
global Options
if {[llength $msg] == 2} {
set user [lindex $msg 0]
set msg [lindex $msg 1]
if {$user eq {me}} {
set user $Options(Nickname)
}
} else {
set user {}
}
set srchres [wikisearch $msg 10]
if {[llength $srchres] > 0} {
send [join $srchres \n] $user
}
}
proc herring::loadTwigs {{fn {}}} {
variable cfg
if {$fn eq {}} {
set fn $cfg(myTwigListFile)
} elseif {$fn eq {?}} {
set fn [tk_getOpenFile -defaultextension .twig -filetypes {{{TWiG Files} .twig} {{All Files} *}}]
if {$fn eq {}} {
return {}
}
}
set cfg(twigs) {}
set f [open $fn r]
set cfg(twigs) [split [read -nonewline $f] \n]
close $f
return "$fn loaded ok"
}
proc herring::prettyTwigs {twigs {raw 0}} {
if {[llength $twigs] == 0} {
return {no twigs}
}
set t {}
set n 0
foreach l $twigs {
if {$raw} {
set l [linsert $l 0 [incr n].]
} else {
set l "[incr n]. [lindex $l 4]"
}
lappend t $l
}
return [join $t \n]
}
proc herring::twiggit {page {blocks 0}} {
variable cfg
return [exec $cfg(tclsh) $cfg(twig) $page $blocks]
}
proc herring::runTwig {page {blocks 0} {name {}}} {
variable cfg
# exec $cfg(wish) <<[twiggit $page $blocks] &
exec $cfg(tclsh) $cfg(twig) $page $blocks | $cfg(run) &
}
proc herring::viewTwig {page {blocks 0} {name {}}} {
view [twiggit $page $blocks] $name
}
proc herring::twig {msg} {
variable cfg
if {[catch {llength $msg}]} { return }
switch -exact -- [lindex $msg 0] {
load {
set fn {}
set tag {}
if {[llength $msg] == 2} { set fn [lindex $msg 1] }
if {[catch {loadTwigs $fn} e]} { set tag ERROR }
if {$e eq {}} { return }
print $e $tag
}
list {
set start 1
set raw [expr {[lindex $msg $start] eq {-raw}}]
if {$raw} { incr start }
set user [lindex $msg $start]
if {$user ne {}} {
variable HookUserInfoDialog 1
variable TwigInfoRaw $raw
::tkjabber::userinfo $user
return
}
if {[llength $cfg(twigs)] == 0} {
print {no twigs}
return
}
print Loaded\ TWiGs:[expr {$raw?" (raw)":""}]\n[prettyTwigs $cfg(twigs) $raw]
}
view -
run {
if {[lindex $msg 0] eq {view}} {
if {[llength $msg] == 1} {
view
} else {
set tag {}
if {[catch {viewFile [lindex $msg 1]} e]} { set tag ERROR }
if {$e eq {}} { return }
print $e $tag
}
return
}
if {[regexp {^(.+)\.$} [lindex $msg end] -> num]} {
if {[llength $msg] > 2} {
variable HookUserInfoDialog 1
variable TwigRun $num
::tkjabber::userinfo [lindex $msg 1]
return
}
if {[llength $cfg(twigs)] == 0} {
print {no twigs}
return
}
if {$num < 1 || $num >= [llength $cfg(twigs)]} {
print {TWiG not found} ERROR
return
}
incr num -1
set twig [lindex $cfg(twigs) $num]
set page [lindex $twig 0]
set blocks [lindex $twig 1]
set name [lindex $twig 4]
} elseif {[llength $msg] > 1} {
set page [lindex $msg 1]
set blocks [lindex $msg 2]
set name {}
} else {
print "run|view usage:\nrun|view ?user? #.\nrun|view page ?blocks?\nview" SYSTEM
return
}
if {[catch [list [lindex $msg 0]Twig $page $blocks $name] e]} {
print $e ERROR
}
}
? {
set m {}
lappend m "TWiG $cfg(version) Commands:"
lappend m "list ?-raw? ?user?"
lappend m "run|view ?user? #."
lappend m "run|view page ?blocks?"
lappend m "view ?filename?"
lappend m "view ? (ask for file to view)"
lappend m "view {} (view your .twig file)"
lappend m "load ?filename?"
print [join $m \n]
}
default {
print "TWiG $cfg(version)\n/twig ? for help" SYSTEM
}
}
}
proc herring::send {msg {user {me}}} {
global Options
variable floodcount
variable floodmax
incr floodcount
if {$floodcount > $floodmax} {return}
if {$floodcount == $floodmax} {
::tkjabber::msgSend "/nolog stubot: outgoing msg count exceeded $floodmax msgs" -user $Options(Nickname) -attrs [list nolog 1]
return
}
if {[set c [string index $msg 0]] ne { } && $c ne {/}} {
set msg " $msg"
}
if {$user eq {me}} {
set user $Options(Nickname)
}
set max 300
if {[string length $msg] <= $max} {
::tkjabber::msgSend "/nolog$msg" -user $user -attrs [list nolog 1]
} else {
::tkjabber::msgSend "/nolog stubot: outgoing msg exceeded $max chars" -user $Options(Nickname) -attrs [list nolog 1]
}
}
proc herring::print {msg {tag MSG}} {
variable cfg
global Options
if {$tag eq {}} {
info default [lindex [info level 0] 0] tag tag
}
$cfg(ctw) configure -state normal
set stuff [split $msg \n]
$cfg(ctw) insert end TWiG\t[lindex $stuff 0]\n $tag
foreach l [lrange $stuff 1 end] {
$cfg(ctw) insert end \t$l\n $tag
}
$cfg(ctw) configure -state disabled
if {$Options(AutoScroll)} {
$cfg(ctw) see end
}
}
proc herring::run {code} {
variable cfg
exec $cfg(run) <<$code &
}
proc herring::save {what {name {}}} {
if {$name eq {}} {
set name [tk_getSaveFile]
if {$name eq {}} {
return
}
}
if {[catch {
set f [open $name w]
puts -nonewline $f $what
close $f
} e]} {
print $e ERROR
} else {
print "$name saved ok"
}
}
proc herring::viewFile {{fn {}}} {
variable cfg
if {$fn eq {}} {
set fn $cfg(myTwigListFile)
} elseif {$fn eq {?}} {
set fn [tk_getOpenFile]
if {$fn eq {}} {
return {}
}
}
set f [open $fn r]
set d [read -nonewline $f]
close $f
view $d $fn
return {}
}
proc herring::view {{what {}} {title {}}} {
variable ::tkchat::NS
catch {destroy .view}
set dlg [::tkchat::Dialog .view]
set w [${NS}::frame $dlg.f]
wm withdraw $dlg
wm title $dlg $title
if {[llength [info command ::tkchat::img::Tkchat]] != 0} {
catch {wm iconphoto $dlg ::tkchat::img::Tkchat}
}
${NS}::button $w.b -text Dismiss -width -12 -command [list wm withdraw $dlg] -default active
::tkchat::ScrolledWidget text $w.text 0 1 -height 23 -width 80 \
-borderwidth 0 -padx 2 -pady 2 -font FNT
grid $w.text -sticky news
${NS}::button $w.bs -text Save -width -12 -command "::herring::save \[$w.text get 1.0 end\]" -default active
${NS}::button $w.br -text Run -width -12 -command "::herring::run \[$w.text get 1.0 end\]" -default active
grid $w.bs -sticky se
grid ^ $w.br -sticky se -padx 4
grid ^ ^ $w.b -sticky se
grid configure $w.text -columnspan 3
grid rowconfigure $w 0 -weight 1
grid columnconfigure $w 0 -weight 1
$w.text insert end $what
grid $w -sticky news
grid rowconfigure $dlg 0 -weight 1
grid columnconfigure $dlg 0 -weight 1
# $w.text configure -state disabled
# bind $dlg <Return> [list $w.b invoke]
# bind $dlg <Escape> [list $w.b invoke]
bind $dlg <Control-q> [list $w.b invoke]
bind $dlg <Control-Q> [list $w.b invoke]
catch {::tk::PlaceWindow $dlg widget .}
wm deiconify $dlg
# This was originally TkChat's [About]
}
# Here starts the evil section
proc herring::incomingUserInfo {jid desc} {
variable TwigInfoRaw
variable TwigRun
set delim {-*- TWiGs -*-}
set delimmatch {-\*-*TWiGs*-\*-}
set twigs {}
set inTwigs 0
foreach l [split $desc \n] {
set l [string trim $l]
if {$inTwigs} {
if {[string match -nocase $delimmatch $l]} {
set inTwigs 0
} else {
if {![catch {llength $l} len] && $len == 5} {
lappend twigs $l
}
}
} elseif {[string match -nocase $delimmatch $l]} {
set inTwigs 1
}
}
if {$TwigRun > 0} {
set i $TwigRun
set TwigRun 0
if {$i < 1 || $i >= [llength $twigs]} {
print No\ TWiGs\ for\ $jid
return
}
incr i -1
set twig [lindex $twigs $i]
set page [lindex $twig 0]
set blocks [lindex $twig 1]
if {[catch {runTwig $page $blocks} e]} {
send $e
}
} else {
print TWiGs\ for\ $jid:\n[prettyTwigs $twigs $TwigInfoRaw]
}
}
proc herring::pimple {n1 n2 op} {
uplevel 1 {trace remove variable UI(id) write ::herring::pimple}
variable TwigInfo [uplevel 1 { set UI(DESC) }]
rename ::tkchat::Dialog ::herring::_Dialog
proc ::tkchat::Dialog {id} {
rename ::tkchat::Dialog {}
rename ::herring::_Dialog ::tkchat::Dialog
::tkchat::addStatus 0 "Getting [uplevel 1 { set jid }]'s TWiGs ..."
after idle [list ::herring::incomingUserInfo [uplevel 1 { set jid }] [uplevel 1 { set UI(DESC) }]]
uplevel 1 { unset -nocomplain [namespace current]::$id UI }
uplevel 1 { return -level 2 }
}
}
proc ::herring::cow {n1 n2 op} {
trace remove variable ::tkchat::UserInfoWin write ::herring::cow
uplevel 1 {trace add variable UI(id) write ::herring::pimple}
}
if {[info command ::tkchat::_UserInfoDialog] eq {}} {
rename ::tkchat::UserInfoDialog ::tkchat::_UserInfoDialog
}
proc ::tkchat::UserInfoDialog {{jid {}}} {
# upvar #0 ::herring::HookUserInfoDialog HookUserInfoDialog
variable ::herring::HookUserInfoDialog
if {!$HookUserInfoDialog} {
::tkchat::_UserInfoDialog $jid
return
}
set HookUserInfoDialog 0
trace remove variable ::tkchat::UserInfoWin write ::herring::cow
variable UserInfoWin
unset -nocomplain UserInfoWin
trace add variable ::tkchat::UserInfoWin write ::herring::cow
::tkchat::_UserInfoDialog $jid
trace remove variable ::tkchat::UserInfoWin write ::herring::cow
}
# End of evil section
proc ::herring::init {} {
variable cfg
foreach {alias proc} $cfg(aliasMap) {
::tkchat::processAliasCommand "/alias $alias proc $proc"
}
}
namespace eval herring {
init
}
# EOF