Richard Suchenwirth 2008-06-24 - The following is a rather small program, which may not fulfil all expectations people might have from a Wiki. It is
The markup language consists only of [brackets] around link names. Pages are created if they don't exist, when a link to them is clicked. Each page is rendered with two special links, "Back" and "Index" (leading to an alphabetic page list, recreated every call time).
When a page is left, it is saved to the backing store (the array p). When the app exits, the contents of the backing store are saved to the file it was started with (or, if no name was given, pwiki.txt). No warranty as usual, but enjoy :^)
package require Tk set thisdir [info script]/.. proc main argv { global p history if {[llength $argv]==0} {set ::argv [list $::thisdir/pwiki.txt]} source [lindex $::argv 0] pack [scrollbar .y -command ".t yview"] -fill y -side right pack [text .t -wrap word -yscrollcommand ".y set" -font {Helvetica 10}] \ -fill both -expand 1 -side left .t tag configure head -font {Helvetica 16} .t tag configure link -foreground blue -underline 1 .t tag bind link <1> "click %W %x %y" bind .t <F5> {render %W [lindex $history end]} set history "" render .t "" bind . <Destroy> {save [lindex $::argv 0]} update idletasks catch {bind . <ConfigureRequest> {::etcl::autofit %W}} } proc render {w page} { if {$page eq "Back"} {set page [do_back $w]} if {$page eq "Index"} {do_index $w} global p history if {[lindex $history end] ne $page} {lappend history $page} set title [lindex [split [$w get 1.0 1.end] \t] 0] if {$title ne ""} { set p($title) [string trim [$w get 2.0 end] \n] ;# save previous page } $w delete 1.0 end if ![info exists p($page)] {set p($page) ""} $w insert end $page head \t "" Back link " - " "" Index link \n\n foreach line [split $p($page) \n] { foreach {nonlink link} [split $line {[]}] { $w insert end $nonlink if {$link ne ""} {$w insert end \[ "" $link link \] ""} } $w insert end \n } } proc click {w x y} { set range [$w tag prevrange link [$w index @$x,$y]] if [llength $range] {render $w [eval $w get $range]} } proc do_back w { global history set history [lrange $history 0 end-1] lindex $history end } proc do_index w { global p set p(Index) "" foreach i [lsort -dict [array names p]] { if {$i ne "Index"} {append p(Index) \[$i\]\n} } } proc save filename { global p set f [open $filename w] foreach i [lsort -dict [array names p]] { puts $f [list set p($i) $p($i)] } close $f } main $argv
MHo: An error message occurs if pwiki.txt isn't there.
LV: An error message occurs if the file passed in as an argument isn't there as well. Also, if the file being source'd in has some sort of error in it (say someone tried editing the file directly, etc.), an error will be raised.
RS Hm.. and the error message says "no such file or directory"? Isn't that helpful enough? :^) For hand-edited files, the user who did it is of course the sole responsible.
LV I wonder how much code would be needed to add support of color images. It might be interesting to be able to build a wiki around one's photos.
RS This much - 6 lines to replace the one $link ne "" line above:
if {$link ne ""} { if [file exists $::thisdir/$link] { set im [image create photo -file $::thisdir/$link] $w image create end -image $im } else {$w insert end \[ "" $link link \] ""} }
This assumes the images are all in the same directory as pwiki.tcl and pwiki.txt. However, when saving back pages, the image pathnames get lost... so we'll need some more thinking here...#
WJG (28/0607) Richard, I couldn't get the pages to save. Have I missed out a step? Yet this looks like another RS testpiece. Would you have any objection if I later adapt the code to create a Gnocl version? - RS: First, all code I post is free as air, so feel free to do anything with it. For the saving problem: I did of course test before I wikified, but forgot to mention some test conditions (which come from imperfect design):
set p() {[About]}
This will prepare a page titled "About", from where you can start creating pages. Not brilliant design.. will think it over.