Version 9 of WikiRun

Updated 2003-07-19 03:33:19

After being annoyed for too long that running code snippets from the wiki involves opening an editor, my answer is WikiRun.

It loads a wiki page (page number only in this version, someone else write a regexp to get it from the page name?), finds the first range of lines between '----' characters that only has indented text and runs that.

So, just save this page as wikirun, use your editor (one last time) and:

 # wikirun 8656 

for example!

Oh, and as a side note, running code like this from the wiki can be considered dangerous. Remember, anyone can edit wiki pages, including any code on wiki pages!

-- 31Mar2003 PS


 #!/bin/sh
 # Next line restarts with Tcl \
 exec tclsh "$0" ${1+"$@"}

 package require http

 set wiki http://mini.net/tcl/

 switch $tcl_platform(platform) {
    unix {
        set sh wish
    } 
    windows {
        set sh c:\\tcl\\wish.exe
    }
    default {
        set sh wish
    }
 }
 proc runScript { page data } {
    global argv
    #search the page for the first text block separated by '----'
    #with indented text only.
    #See http://wiki.tcl.tk/wikirun/
    #for an example. 
    regexp -nocase {<textarea[^>]*>(.*)</textarea[^>]*>} $data --> data
    set data [string map {&quot; \" &gt; > &lt; < &amp; &} $data] 

    set snippets [split [string map [list ---- \x80] $data] \x80]
    foreach snippet $snippets {
        if { [isScript $snippet] } {
            set fp [open $page.tcl w]
            puts $fp [string trim $snippet]
            close $fp
            if { [llength $argv] > 1 } {
                exec -- $::sh $page.tcl [lrange $argv 1 end]
            } else {
                exec -- $::sh $page.tcl
            }
            break
        }
    }    
 }

 proc isScript { text } {
    #returns 1 if a number of lines is a 'script'. 0 if not.
    foreach line [split $text \n] {
        set line [string trimright $line]
        if { [string length $line] > 0 && \
                 ![string equal [string index $line 0] " "] } {
            return 0
        }
    }
    return 1
 }

 set tok [::http::geturl $wiki[lindex $argv 0]@]

 switch [::http::status $tok] {
    ok {
        set data [::http::data $tok]
        ::http::cleanup $tok                 
        runScript [lindex $argv 0] $data        
        exit
    }
    eof {
        puts stderr "Document contained no data"
    }
    error {
        puts stderr [http::error $tok]
    }
 }

 ::http::cleanup $tok

WikiRun is quite equivalent to using the wiki-reaper with a pipe (on systems that have pipes)

 wikiReap TkGoldberg | wish

This is just an example fetching the TkGoldberg game and running it immediately (I called the program from the wiki-reaper page wikiReap here)

See also:

Ah. Right. So much for an extensive search-before-you-code -- PS


escargo 31 Mar 2003 - Actually this raises an interesting point. How can a reaper know what code to capture? My wish-reaper (based on wiki-reaper) grabs everything that is preformatted. WikiRun only grabs the first thing. Reaping a page with multiple versions is problematic because later versions and initial versions tend to collide. On the other hand, grabbing the first version may avoid that problem, but has the different problem of not getting the latest version. Maybe we need some kind of markup to identify the correct runnable code; alternatively, people who put multiple versions on one page should use the if 0 { trick to preserve the code but make it not runnable.

Lars H: The markup question gets us back to Literate programming in a Wiki.

Luciano ES - July 19, 2003 - How about this:

 <wiki app>
 all code a man can get
 </wiki app>

 <wiki app>
 "All Code a Man Can Get - Yet Another Trilogy"
 </wiki app>

That would be enough for a reaper to know what to reap, and invisible to the human eye.


[ Category Tcler's Wiki ]