booksum - summaries of Tcl code

What is this

The booksum allows to make summaries of Tcl code snippets cut from books.

Perhaps, while reading Tcl texts you came across some code snippets like this "TclOO Tricks" one of wiki.tcl-lang.org:

  ## Class Variables
  % oo::class create foo {
    self export varname
    constructor {} {
        my eval upvar [[self class] varname v] v
        my eval upvar [[self class] varname w] w
    }
    method bar {} {
        variable v
        variable w
        incr v
        incr w 2
        puts "v=$v, w=$w"
    }
  }
  ## Demoing it...
  % foo create x
  % x bar
  % x bar
  % foo create y
  % y bar
... so that you might want to save such code snippets in a summary file, in order to review them afterwards for refreshing your memory
... or to test
... or to play.

Most certainly, you'd like to save the code snippets along with their output, as they've been shown in a console:

    # Class Variables 

  % oo::class create foo {
      self export varname
      constructor {} {
          my eval upvar [[self class] varname v] v
          my eval upvar [[self class] varname w] w
      }
      method bar {} {
          variable v
          variable w
          incr v
          incr w 2
          puts "v=$v, w=$w"
      }
  }
  ==> ::foo

  # Demoing it... 

  % foo create x
  ==> ::x

  % x bar
v=1, w=2

  % x bar
v=2, w=4

  % foo create y
  ==> ::y

  % y bar
v=3, w=6

... or you'd like to publish your own code snippets and results somewhere, e.g. in wiki.tcl-lang.org.

If it is the case, probably you would appreciate the booksum.


How to do this

Copy your code snippet and paste it into the bundle variable of booksum.tcl, in this manner:

  set bundle {
  % oo::class create foo {
    self export varname
    constructor {} {
      my eval upvar [[self class] varname v] v
      my eval upvar [[self class] varname w] w
    }
    # ... rest of foo
  }
  # ... rest of bundle
  }

If you'd made some bundles, you may simply add a new bundle as the last:

  set bundle {
  # ...code of 1st snippet
  }
  set bundle {
  # ...code of 2nd snippet
  }
  set bundle {
  # ...code of 3rd snippet
  }
  # ...
  set bundle {
  % oo::class create foo {
    self export varname
    constructor {} {
      my eval upvar [[self class] varname v] v
      my eval upvar [[self class] varname w] w
    }
    # ... rest of foo
  }
  # ... rest of bundle
  }
So that your last bundle would work alone, while others remain in a museum state.

Well, after these manipulations you should only run the booksum.tcl in a console with one of the following commands:

  tclsh ./booksum.tcl
  tclsh ./booksum.tcl > results.txt
The second one would create results.txt containing the output of the command.

That's all.

Or you may pass a 'bundle' in a file, for example:
  tclsh ./booksum.tcl
  tclsh ./booksum.tcl samples/OOtcl_book.bundle > results.txt


Tips and traps

All of your bundle would be evaluated and executed. If you want some command being visualized in a console, preface it with "% ".

The commands prior to the first '% command' would be executed without showing in a console, so their result only would be printed. They are sort of initializers.

All code lines between '%' are executed as one block of code. This means that the following bundle is erroneous:

  set bundle {
  % oo::class create foo {
      self export varname
  % constructor {} {
      my eval upvar [[self class] varname v] v
      my eval upvar [[self class] varname w] w
    }
    # ... rest of foo
  }
  # ... rest of bundle
  }

because booksum will try to execute

  oo::class create foo {
  self export varname
as a single command block which results in ERROR: missing close-brace.

As for comments, they are naturally skipped at the execution but, being included in % (block-to-execute) %, they are shown BEFORE the result of executed block. For example:

set bundle {
  % set a 10
  # increasing a
  % incr a
}

would results in the following output:

  % set a 10
  # increasing a
  ==> 10

  % incr a
  ==> 11

There are two special commands concerning comments which fix this issue:

  • ** is a commenting command that prints its arguments as an uppercased message
  • ## is a commenting command that prints its arguments 'as is' with an initial '#'
Each of them composes a single "block of code" and as such cannot be used inside another block (e.g. in the body of if, proc, foreach, while and so on). These commands are nearly the same as
  % puts "comment"

For example, the following bundle:

  set bundle {
  ** START

  % set a 10
  ## increasing a
  % incr a
  **
  ** FINISH
  }
would results in:

    START

  % set a 10
  ==> 10

  # increasing a 

  % incr a
  ==> 11

  FINISH


Download

booksum stuff is available here:

Notice that booksum is still disposed to update.


See also