Guide to TTN's Personal Scheme Library


Next: , Up: (dir)

Guide to TTN's Personal Scheme Library

This document describes ttn-pers-scheme 0.49: a collection of Guile Scheme code, documentation and maintenance methodology, released under the GNU GPL version 3.

You should have received a copy of the GNU General Public License along with this software; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Alphabetical list of all modules


Next: , Previous: Top, Up: Top

1 Overview

1.1 So why re-invent?

Joy of implementation is a fine fix for a while. Getting twisted and experiencing KFJC and KSCM are the nice touch. Satisfying.

Personal mistakes (when recognized) are a sharp blade. Toolsmithing veers between kludge and laser. Code is data for tools, of course.

Personal expression is never original, they say. That's ok, too.

All this is to say: from form flows function, if given the right form. In this case, the library is the form I choose, and the experience arising from its maintenance is the function I seek. From this experience hopefully I can learn the ways of the masters.

1.2 Library Layout

To keep things simple all modules are in the ttn namespace with names that look something like:

     (ttn save-buffer)               ;; ttn/save-buffer.scm
     (ttn edit)                      ;; ttn/edit.scm
     (ttn parse-rfc822)              ;; ttn/parse-rfc822.scm

The corresponding filename, shown to the right of the module name, is the one used in both the distribution and the installation. This naming convention conforms to the guile module system's module name to filename resolution algorithm, as long as the parent of the ttn directory is included in the %load-path list. For normal installation (i.e., make install), that parent directory would be guile's non-version-specific site-lisp directory.

Each module is declared using a define-module form that: names the module; names those modules upon which it depends; and in some cases, names the exported variables. In all other cases, exported variables are named in a separate export form. Each module's source file has exactly one define-module form, although sometimes there may be more than one export form.

1.3 Guide Layout

The functional organization of the library is the subject of the rest of this guide. In addition to a linear listing of the modules and their related commentary (see In Theory), we present common functional groupings based on specific programming tasks, to give a better feel of what modules work well together (see In Practice).

The selected tasks vary in scope from the very small (still somewhat modular) to the very large (practically standalone application). Often there is additional critique of the library and/or the task drawn from the experiences of the author. May the gray hairs be put to good use!


Next: , Previous: Overview, Up: Top

2 In Theory

Here is the list of all the (ttn foo) modules, sorted alphabetically by the foo part. In theory, this is all the documentation you need to make use of ttn-pers-scheme, but reference material alone does not a good guide make, so feel free to skip to the next chapter (see In Practice) and return here later.


Next: , Up: In Theory

2.1 module (ttn abbrev-tree)

This module provides procedures to formulate and parse tables of strings that may have abbreviations. In gdb(1), for example, ‘i b’ means the same as “info breakpoints”. Although this is modeled after gdb's admirable help system, the code is generic w/ the gdb-specific stuff factored as gdb-style-WHATEVER functions.

These are low-level record-manipulation procedures:

     (make-ab fullname) ⇒ abbrev-tree record
     (ab? object) ⇒ bool
     (ab-fullname ab) ⇒ string
     (ab-children ab) ⇒ list of children abbrev-trees
     (ab-children-set! ab list)
     (ab-data ab) ⇒ data associated with abbrev-tree ab
     (ab-data-set! ab data)
     (make-aba alias ab) ⇒ abbrev-tree-alias record
     (aba? object) ⇒ bool
     (aba-alias aba) ⇒ alias
     (aba-ab aba) ⇒ ab

These procedures display messages in GDB's style:

— Procedure: gdb-style-ambiguous name tree choices

Display an "ambiguous command" message a la gdb.

— Procedure: gdb-style-undefined name tree

Display an "undefined command" message a la gdb.

The rest of the procedures are the high-level interface.

— Procedure: abtree-climb name tree sturdy ambiguous shaky [so-far...]

See if NAME is visible as a child in TREE, as either an abbrev tree or an alias. If found, STURDY is called with the fullname of the child. If not found, SHAKY is called with NAME and TREE as args. If there is ambiguity, AMBIGUOUS is called with args NAME, TREE and a list of possible fullnames.

At this time, the optional arg SO-FAR is not used, but it will probably be tacked on as the optional arg for STURDY, SHAKY and AMBIGUOUS at some point (as a place for caller-defined data).

If module configuration variable `%careful%' is #t, children that are neither abbrev trees nor aliases throw a `bad-child' error. Otherwise, such children result in an immediate call to SHAKY as described above.

— Procedure: abtree-add tree fullname-path data

Add to TREE by splitting up FULLNAME-PATH into constituent words and creating children trees. FULLNAME-PATH is scrubbed before splitting. If FULLNAME-PATH already has been added, an error is signalled. [But what about `DATA' ?!?]

— Procedure: abtree-import in-data

Translate IN-DATA, a nested list, into an abbrev tree and return it. For each list in IN-DATA, the car becomes a fullname and the CDR the children. Elements of the cdr can be lists, in which case `abtree-import' is called recursively. This procedure is experimental and may go away.

— Procedure: abtree-expand tree

Recursively add alias children to TREE. Each alias's `ab' slot is either an abbrev tree when unambiguous, or a list of fullnames of possible abbrev trees, when ambiguous. Only TREE's children are consulted and referenced.


Next: , Previous: abbrev-tree, Up: In Theory

2.2 module (ttn bufutils)

This module provides various convenient ways to use Guile 1.4.x's “editing-buffer” module. See Editing Buffer.

Perhaps a few of these procs will migrate into Guile proper at some point in the future.

In the following procs, if filename has #\$ or #\~ in it, it is expanded first with expand-file-name-substituting-env-vars (see expand-file-name).

— Procedure: insert-tree! gb tree

Insert into gb the tree (of strings), walked depth-first. If gb is #f, create a new gap-buffer. Return the gap-buffer.

[NOTE: docs missing for find-file]

— Procedure: write-buffer buffer filename

Write buffer into file filename. This makes the buffer visit that file. filename cannot name a directory.

— Procedure: write-buffer-if-changed buffer filename

Write buffer into file filename, but only if doing so would create a new file or a file with different contents than the pre-existing one. filename cannot name a directory.

— Procedure: save-buffer buffer

Save buffer to disk. buffer should be visiting a file. An error is thrown if buffer is not visiting a file. An error is thrown if the file cannot be written. Return #t if all goes well.


Next: , Previous: bufutils, Up: In Theory

2.3 module (ttn call-process-to-buffers)

This module exports the proc call-process-to-buffers, also available as call-process->buffers.

— Procedure: call-process->buffers program [key-name key-value ...] [args...]

Call program synchronously in separate process with optional args. Return a numeric exit status. Keyword args (all default values are #f) are:

#:inb
Input buffer.
#:outb
Output buffer
#:errb
Error output buffer.
#:norm
Non-#f means that program and args should be passed through args->normalized-list (see shellutils).


Next: , Previous: call-process-to-buffers, Up: In Theory

2.4 module (ttn call-process)

This module exports the proc call-process.

— Procedure: call-process program [key-name key-value ...] [args...]

Call program synchronously in separate process with optional args. Unless give #:outp 0, wait for program to terminate and return a numeric exit status.

#:inp (current-input-port)
Input port. #f means /dev/null.
#:outp (current-output-port)
Output port. #f means discard output; 0 (zero) means discard, don't wait for program to terminate, and return #f.
#:errp (current-error-port)
Error output port. #f means discard output.
#:norm
Non-#f means program and args should be passed through args->normalized-list (see shellutils).


Next: , Previous: call-process, Up: In Theory

2.5 module (ttn cron)

This file exports two macros, cron and cron!.

— Macro: cron cmdline-list [handlers...]

Examine cadr of cmdline-list and invoke one of the handlers.

cmdline-list is a two-element list, of the form:

          (PROG-NAME COMMAND)

handlers is zero or more forms:

          ((KEY) (BODY1) (BODY2) ...)

body1, body2 and so on are optional. key is a symbol or string. The body forms for a key are executed if command matches key. If cmdline-list does not have exactly two elements, a usage message is displayed and a "bad usage" error is thrown. If command matches no key, cron silently returns #t, otherwise, the return value is the value of the last body form executed.

For example:

          #!/usr/local/bin/guile -s
          !#
          (use-modules ((ttn cron) #:select (cron)))
          (exit (cron (command-line)
                  ((hourly) (display "yawn, stretch") (newline))
                  ((daily)  (display "zonk") (newline))))
— Macro: cron! [handlers...]

Call cron with (command-line) and handlers. Exit with the return value.


Next: , Previous: cron, Up: In Theory

2.6 module (ttn cvsutils)

We only deal with the branch represented by the working directory. This could be considered a bug.

— Procedure: cvslog file

Run "cvs log" on file; return an alist describing the head revision. Keys include: rcs-file, working-file, head, locker, date, author and state. All values are strings.

— Procedure: cvs-files-under dir

Return a list of CVS files under dir, as listed by CVS/Entries.

— Procedure: display-cvslog r [fields]

Display alist value r returned by Scheme function cvslog. Optional args fields are symbols specifying which fields to display and in what order. If omitted, display, in this order: rcs-file, working-file, head, date, author, state.

— Procedure: display-cvs-state-summary dir

For directory dir, summarize state info for files in CVS/Entries. Files are grouped by state and sorted w/ most-recently changed first.


Next: , Previous: cvsutils, Up: In Theory

2.7 module (ttn dirutils)

This module exports eight procs and two macros:

       (mkdir-p dir)
       (directory-files dir)
       (filtered-files filter dir)
       (filtered-files-in-vicinity dir filter)
       (not-dot-not-dotdot file)
       (extract-stem-proc ext)
       (filename-sans-end-sep-proc sep-char)
       (file-newer-than-file? file1 file2)
       (save-cwd body)                         <-- macro
       (with-cwd body)                         <-- macro
— Procedure: mkdir-p dir

Create a directory dir, as well as any missing parent dirs.

— Procedure: directory-files dir

Return list of file names in directory dir.

— Procedure: filtered-files filter dir

Apply filter to each file name in dir; return list of non-#f values. filter is a procedure applied to each file name – it should return #f if that file name is to be omitted from the overall list, or a value to be collected. The file name list is not sorted.

— Procedure: filtered-files-in-vicinity dir filter [options...]

In dir, apply filter to each file name; return list of non-#f values. filter is a procedure applied to to each filename – it should return #f if that file name is to be omitted from the overall list. Otherwise, its return value can be a string, or #t which is synonymous with the filename with the dir prefixed. The file name list is not sorted. options are zero or more keywords that modify the behavior:

#:filter-prefixed
Pass to filter each file with dir already prefixed.
#:collect-nodir
For the case when filter returns #t, collect the filename without the dir prefix.

NB: The argument order is opposite that of filtered-files.

— Procedure: not-dot-not-dotdot file

Return #f if file is "." or "..", otherwise return file.

— Procedure: extract-stem-proc ext [transform]

Return a procedure that filters based on ext, a string. The procedure takes a filename and if it ends in .EXT (note dot), returns the portion of the filename before the dot, otherwise #f. Optional arg transform controls precisely how the returned filename is to be processed. If transform is omitted or #f, the extension is discarded. If it is #t, the extension is left alone. If it is a string, the stem is concatenated with it. If it is a procedure, that procedure is applied to the stem, and it's return value, which need not be a string, is collected.

— Procedure: filename-sans-end-sep-proc sep-char

Take sep-char and return a procedure that, given filename, returns a copy of it w/o the ending sep-char.

— Procedure: file-newer-than-file? file1 file2

Return #t if file file1 is newer than file file2. If file1 does not exist, the answer is #f; otherwise, if file2 does not exist, the answer is #t.

In the following macros, if body is null, the return value is unspecified, otherwise it is the value of the last expression in body.

— Macro: save-cwd [body...]

Evaluate body and restore the original cwd afterward.

— Macro: with-cwd dir [body...]

Change directory to dir, evaluate body and restore cwd.


Next: , Previous: dirutils, Up: In Theory

2.8 module (ttn email-log-if-fail)

— Procedure: email-log-if-fail who subject [shell-command...]

Email who w/ subject the log of failed shell-command. who and subject are strings or symbols. shell-command is one or more strings or symbols, to be passed through system*. If shell-command is successful, no email is sent. Log includes both stdout and stderr. Use "mail" for mailer. Return #t if shell-command is successful, otherwise #f.

— Procedure: set-system-mail-program! program

Change the system mail program to program. Normally it is ‘mail’. program should behave similarly: it must support the command-line sequence -s subject recipient, and take the mail message body from stdin.


Next: , Previous: email-log-if-fail, Up: In Theory

2.9 module (ttn expand-file-name)

This module exports four procs:

       (expand-file-name name [default-directory])
       (reset-tilde-cache! [size])
       (substitute-env-vars string)
       (expand-file-name-substituting-env-vars name [default-directory])

Both expand-file-name and substitute-env-vars are directly inspired by Emacs.

— Procedure: expand-file-name name [default-directory]

Convert filename name to absolute, and canonicalize it. Second arg default-directory is directory to start with if name is relative (does not start with slash); if default-directory is #f or missing, (getcwd) is used. File name components that are . are removed, and so are file name components followed by .., along with the .. itself; note that these simplifications are done without checking the resulting file names in the file system. An initial ~/ expands to your home directory. An initial ~USER/ expands to USER's home directory.

— Procedure: reset-tilde-cache! [size]

Reset the cache expand-file-name uses for the results of expanding ~ and ~USER. Optional arg size specifies the hash table bucket count to use (default is 7).

— Procedure: substitute-env-vars string

Substitute environment variables referred to in string. $FOO where FOO is an environment variable name means to substitute the value of that variable. The variable name should be terminated with a character not a letter, digit or underscore; otherwise, enclose the entire variable name in braces. For instance, in ab$cd-x, $cd is treated as an environment variable.

Use $$ to insert a single dollar sign.

— Procedure: expand-file-name-substituting-env-vars name [default-directory]

Substitute env vars in string then expand it as a filename. See substitute-env-vars and expand-file-name.


Next: , Previous: expand-file-name, Up: In Theory

2.10 module (ttn filesystem-tree-to-list)

The procedures in this module use the (ice-9 ftw) module from Guile. See Filesystem Tree Walk.

— Procedure: filesystem-tree->list filename node-proc [control-flags...]

Return the filesystem tree rooted at filename as a nested list of node values as obtained by calling node-proc, a procedure that takes five arguments, on each directory and subdirecory. The arguments to node-proc are explained fully in the nftw documentation.

          (node-proc name statinfo flag base level) => node value

If filename is names a file (not a directory), simply return the node value resulting from one call to node-proc. Otherwise, for each list in the return value, the car is the node value of the directory and the cdr the node values of the children.

The remaining control-flags are passed through to nftw. You need not specify the flag depth; it is automatically included.


Next: , Previous: filesystem-tree-to-list, Up: In Theory

2.11 module (ttn fileutils)

— Procedure: filename-absolute-or-in-vicinity name dir

If name begins with "/", return it. Otherwise, return a new string composed by taking name in vicinity of dir.

— Procedure: filename-sans-end-slash name

Return name, a string, stripping the terminating "/" character. If there is no "/", just return name.

— Procedure: filename-components string

Return a list of filename components parsed from string. Components are delimited by "/", which is discarded. Null string components are also discarded.

— Procedure: filename-components-append ls

Return a string composed by prefixing each element of ls with "/".


Next: , Previous: fileutils, Up: In Theory

2.12 module (ttn flatten)

— Procedure: flatten tree [out]

Walk tree depth-first, displaying elements if they are strings. Signal "bad type" error for non-string, non-list elements. Optional second arg out is a procedure to use instead of display.

— Procedure: flatten-to port tree

Flatten to port (using flatten) the tree, a nested list of strings. If port is #f return a string, instead.


Next: , Previous: flatten, Up: In Theory

2.13 module (ttn gpgutils)

This module exports eight procedures:

      read-line-no-echo                      siginfo:signer
      clearsign-message-interactively        siginfo:time
      verify-signed-message                  siginfo:method
                                             siginfo:sig
                                             siginfo:body
— Procedure: read-line-no-echo prompt

Quietly read a line from current input port, first displaying prompt. Typed characters are not echoed to the screen. Throw bad-environment error if running under Emacs.

— Procedure: clearsign-message-interactively msg

Invoke gpg --clearsign on msg (a string or port), and return the output. Throw bad-environment error if running under Emacs.

— Procedure: verify-signed-message msg

Invoke gpg --verify on msg (a string or port), and return a siginfo value. The elements of this value (all strings) can be extracted using one of the "siginfo:foo" procedures. If the gpg call fails, throw a signature-verification-error with argument the gpg verifier. This verifier is created using make-buffered-caller, q.v.

— Procedure: siginfo:signer si

Return the signer (typically includes name and email address) of si.

— Procedure: siginfo:time si

Return the message-signing time of si.

— Procedure: siginfo:method si

Return the signing method (may include key ID) of si.

— Procedure: siginfo:sig si

Return the signature (hex digits and sometimes "=") of si.

— Procedure: siginfo:body si

Return the body of the message, w/o gnupg message envelope, of si.


Next: , Previous: gpgutils, Up: In Theory

2.14 module (ttn grep)

The procs grep and grep-matches work on lists of strings. Unfortunately, their names are slightly confusing to those used to the shell-command command grep(1). On the other hand (to add to this confusion), grep-l works on a list of files (or file ports).

— Procedure: grep re strings [flags...]

Return list of matches to regexp re from strings list. Optional flags are keywords (or symbols with the same name) which modify regexp matching:

#:invert
the result list is those strings that do NOT match
#:fold-case
consider upper and lower case to be identical
#:count
return length of result list instead of list
#:literal
re specifies a literal string to match

Return list order is the same as in the input list.

— Procedure: grep-matches re strings [flags...]

Return non-#f match results of regexp-exec of regexp re on strings list. Optional flags are keywords (or symbols with the same name) which modify regexp matching:

#:invert
the result list is composed entirely of #t values, with length equal to the number of strings that do NOT match (useful with count flag below)
#:fold-case
consider upper and lower case to be identical
#:count
return length of result list instead of list
#:literal
re specifies a literal string to match

Return list order is the same as in the input list.

— Procedure: grep-l re files

Search for regular expression re in files. Return a list of those that match. re specifies a regular expression that matches on one line (multi-line results not currently supported). files is a list, each element of which can either be a filename or a seekable port. In the returned list, if the element is a port, its read offset is left at the beginning of the line of the first match.


Next: , Previous: grep, Up: In Theory

2.15 module (ttn html-data)

This module exports the following procs:

      (html . x)
      (href url text [name])      ; url can be #f
      (name text)
      (head . x)
      (title . x)
      (link . x)
      (body . x)
      (h1 . x) (h2 . x) ... (h6 . x)
      (br)
      (hr)
      (b . x)
      (p . x)             ; no body => <P>; body => <P> x </P>
      (tt . x)
      (pre . x)
      (tt-pre . x)
      (div . x)
      (span . x)
      (textarea rows cols name x)
      (input type name value)
      (form method action . x)
      (refresh sec url)
      (li . x)
      (ul . x)            ; `li' for each element of x
      (ull x)             ; variant of `ul' that takes a single list
      (dl . x)            ; for each elem of x, car => <DT>, cdr => <DD>
      (dll x)             ; variant of `dl' that takes a single list
      (table . x)
      (tr . x)
      (td . x)
      (copyright . prefix)
      (copyright-since year)
      (center . x)
      (em . x)
      (strong . x)
      (dfn . x)
      (code . x)
      (samp . x)
      (kbd . x)
      (var . x)
      (cite . x)
      (abbr title . x)
      (blockquote . x)
      (q . x)
      (smhdwy-since diff) ; in seconds, may be negative

All procs return lists (possibly nested), suitable for walking with a “flattening” procedure, something like:

     (define (output-html-data x)
       (cond ((string? x) (actual-output x))
             ((list? x) (for-each output-html-data x))
             (else (error "unknown type:" x))))

The proc actual-output might send x to a port, for example. See flatten.


Next: , Previous: html-data, Up: In Theory

2.16 module (ttn html-data2)

— Procedure: ~?xml encoding

Return the tree:

          ("<?xml version=\"1.0\" encoding=\""
           encoding
           "\"?>" :LF)
— Procedure: ~!DOCTYPE type

Return the tree:

          ("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 "
           type-as-capitalized-string
           "//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-"
           type-as-string
           ".dtd\">" :LF)

type is one of #:strict, #:transitional, #:frameset; or a symbol with the same name.

Following is the list of other exported procedures. Each expands (see markup) its arglist into a tree where the element name is the same as the procedure name, but without the tilde (‘~’).

     ~html
     ~head ~title ~base ~meta ~link ~style
     ~script ~noscript
     ~body
     ~div ~p ~h1 ~h2 ~h3 ~h4 ~h5 ~h6
     ~ul ~ol ~li ~dl ~dt ~dd
     ~address
     ~hr
     ~pre ~blockquote
     ~ins ~del
     ~a
     ~span
     ~bdo
     ~br
     ~em ~strong
     ~dfn ~code ~samp ~kbd ~var ~cite ~abbr ~acronym
     ~q ~sub ~sup
     ~tt ~i ~b ~big ~small
     ~object ~param
     ~img ~map ~area
     ~form ~label ~input ~select ~optgroup ~option
     ~textarea ~fieldset ~legend ~button
     ~table ~caption ~thead ~tfoot ~tbody ~colgroup ~col
     ~tr ~th ~td


Next: , Previous: html-data2, Up: In Theory

2.17 module (ttn html-world)

— Procedure: string<-image-command source [invert?]

Concatentate source, a shell command that writes image data to stdout, with a series of shell commands from the Netpbm package. Optional arg invert? non-#f means to include a call to pnminvert in the pipeline.

Execute the pipeline in a subshell and return its output as a string.

— Procedure: randomly-hyperlinked string list-of-links [link-tree]

Profile string for small non-whitespace intervals to be “marked up” as the text of an HTML A element, with reference taken randomly from list-of-links (list of strings). As as special case, if the car of list-of-links is the symbol file-lines, then the cadr is taken to be a filename which must contain one link (URL) per line.

Return an html-data tree (nested list of strings). Optional third arg link-tree specifies a procedure to use instead of href (see html-data) to construct hyperlink references. It should take arguments url and text (both strings), and return a tree (nested list of strings).

— Procedure: html-world.html-data [keyword value...] [links...]

Return an html-data tree made from an ASCII-representation of a globe image. When optional arg links is specified, the single string is profiled for small non-whitespace intervals to be “marked up” as the text of an HTML A element, with the reference taken randomly from links.

links may be the name of a file containing one URL per line. links may also be a list or vector of URLs.

Keyword parameters, default values, and their meanings:

#:size 150 Size in pixels (NxN) of the originating image.


#:gen #:ppmforge Preferred backend program used to generate the image, one of #:xearth, #:xplanet or #:ppmforge. The value can also be a symbol.


#:link-tree href Another procedure to use instead of href (see html-data). It should take arguments url and text (both strings), and return a tree (nested list of strings).


Next: , Previous: html-world, Up: In Theory

2.18 module (ttn listener)

— Procedure: make-listener ear [options...]

Return a thunk that listens with ear, a list in of the form (FAMILY ADDRESS [ARGS]). As a special case, if ear is an integer, it is taken to specify a TCP/IP port p and converted internally to family PF_INET, address INADDR_ANY, and args p. options are alternating keyword ands values:

#:setup-sock
A procedure taking one arg, the listener socket, called right before doing bind. This is a good place for setsockopt calls.
#:nqueue
Number of queued requests, default 10.
#:pre
#:handle
#:post
Procedures that take two args, port and conn, the output of accept. These three procedures are thunkified to form the branches of a dynamic-wind, the child. After calling the post procedure, port is closed. If pre, handle, and post are unspecified, the default action is to do nothing.
#:concurrency
The value may be #:coop-thread, in which case each child is run in its own thread. If it is #f or unspecified, child dispatch is serial.
#:catch-tag
A symbol that will catch any calls to throw that uses it. Normally, the server loop uses #t to catch all throws. This tag (and indeed any args in the throw) are ignored.


Next: , Previous: listener, Up: In Theory

2.19 module (ttn make-buffered-caller)

— Procedure: make-buffered-caller program

Return a procedure capable of calling program w/ optional args. When called, the program stdout and stderr are captured to buffers. The key #:inb (default #f) specifies an input buffer to use for the call.

The returned procedure takes one of the following commands (either a keyword or similarly-named symbol):

#:redefine NEW-DEF
Redefine the called program and its args. new-def is one or more strings.
#:execute
Call program, clearing buffers first. Return raw exit status of the program. See status:exit-val for more info.
#:execute/no-init
Same as #:execute, but do not clear buffers first.
#:outbuf
Return output buffer object.
#:outbuf-string
Return output buffer as a string.
#:outbuf-lines
Return output buffer as a list of strings.
#:errbuf
Return error output buffer.
#:errbuf-string
Return error output buffer as a string.
#:errbuf-lines
Return error output buffer as a list of strings.
#:exit-val
Return exit status from the last execution. Signal an error if #:execute (or #:execute/no-init) command has not yet been issued since closure creation or most recent #:redefine.

The #:outbuf-lines and #:errbuf-lines commands use newline to separate.


Next: , Previous: make-buffered-caller, Up: In Theory

2.20 module (ttn markup)

In addition to the procs described below, the following named strings are available (NB: the colon is part of the variable name):

— String: :DQ

The double-quote character #\", as a string.

— String: :LF

The newline character #\newline, as a string.

— String: :NULL

The null string, "".

— Procedure: symbol<-kw/sym keyword-or-symbol

Return keyword-or-symbol as a symbol.

— Procedure: string<-kw/sym keyword-or-symbol

Return keyword-or-symbol as a string.

— Procedure: peel list

Scan list of the form:

          ([attr-name attr-value ...] [body...])

Each attr-name is either a keyword or a symbol. Each attr-value is either a string, a (possibly) nested list of strings, a symbol or a number. When there are no more attribute names, the rest of the list (which may be null) is taken as the body.

Return a pair whose car is the attributes, formatted (in a tree) as NAME="VALUE"; and whose cdr is the body.

— Procedure: expand elem [key value...]

Return a proc p that expands into a tree based on elem. Precisely, p partitions its arglist with peel into attributes and body and returns the tree:

          ("<" elem attributes [" /"] ">"
           [neck]
           [body ["</" elem ">"]]
           [tail])

Other args are keywords. Here is a list (with default value):

#:xbsc #f
Non-#f means “XMLish (blech) start close”, i.e., the start tag should be rendered as ‘<ELEM />’ instead of of ‘<ELEM>’ (with space and slash before closing angle bracket). Typically, this is specified in conjunction with #:end-tag :NULL.
#:neck :NULL
This is inserted between the initial tag and is not subjected to prep-body. Typically :LF when specified.
#:prep-body #f
This can be a procedure that is passed body and returns a transformed tree. It can also be a a pair whose car is the symbol map and whose cdr is a procedure taking one arg. The effective body is computed by mapping this procedure over all the top-level elements of body.
#:no-end-tag-if-null-body? #f
Non-#f specifies that if body is the empty list, the ‘</ELEM>’ end tag should be omitted entirely.
#:end-tag #f
Specifies an alternative end tag.
#:tail :NULL
A value to be appended at the very end of the tree. Typically :LF when specified.

— Procedure: list<- arg

If arg is already a list, return it. Otherwise return (list arg).

— Procedure: css-tree rule

Return a tree made from expanding CSS rule, a list of the form:

          (target [property value...])

In this form, target can be a string or a flat list of strings; property can be a string, symbol, or keyword, and value can be a string or a nested list of strings.


Next: , Previous: markup, Up: In Theory

2.21 module (ttn mixp)

Mixp is a Guile interface written by Thierry Bézecourt, to expat, an XML Parser written by James Clark.

— Procedure: make-fully-specified-expat-parser init handlers

Return a mixp parser with initial user data init and handlers. handlers is a 14-element vector, which is used by the procs expat:set-FOO-handler, where FOO and the handler elements are as follows:

          element                 0 1
          character-data          2
          processing-instruction  3
          comment                 4
          cdata-section           5 6
          default                 7
          unparsed-entity-decl    8
          namespace-decl          9 10
          not-standalone          11
          external-entity-ref     12
          unknown-encoding        13 #f

Note that for expat:set-unknown-encoding-handler, the second arg is hardcoded to #f.

— Procedure: parse-xml parser [port]

Call mixp:parse on parser and afterwards, return its user data. Optional arg port specifies an input port, otherwise the current input port is used.


Next: , Previous: mixp, Up: In Theory

2.22 module (ttn optargs-kw-utils)

This module exports the proc remove-keys.

— Procedure: remove-keys ls

Remove keywords and their values from list ls. Return a new list. For example:

          (remove-keys '(ok1 #:a 42 #:b 99 ok2 #:c #:d ok3))
          ⇒ (ok1 ok2 ok3)


Next: , Previous: optargs-kw-utils, Up: In Theory

2.23 module (ttn parse-rfc822)

— Procedure: parse-rfc822 mailmsg

Parse mailmsg, return a query proc. mailmsg may be a list of lines (w/o terminating newline), a gap-buffer, or something that make-gap-buffer takes. The query proc takes a symbol comp, and returns the associated message component. Supported values for comp are:

from
first whitespace-delimited token after "^From " on first line
headers
the headers as an alist (keys are strings), order maintained
body
rest of the mail message

Any other query results in a "bad component" error.


Next: , Previous: parse-rfc822, Up: In Theory

2.24 module (ttn personal-pgtable)

This module exports these procedures:

       (get-meta-file) => filename
       (set-meta-file! FILENAME)
       (personal-pgtable-all) => alist
       (personal-pgtable-defs DB TABLE) => defs
       (personal-pgtable-manager DB TABLE) => pgtable-manager
       (personal-pgtable-worker DB TABLE) => pgtable-worker

The meta file contains two forms (sexps), the first a list of elements each of the form: (keyword expansion), and the second a single alist of the form:

      ((DB-1 (TABLE DEF ...) (TABLE DEF ...) ...)
       (DB-2 (TABLE DEF ...) (TABLE DEF ...) ...) ...)

Each db and table are strings, while def... are column definitions. See Column Definitions.

Wherever a keyword from the first form appears in defs, its expansion (a string) is used instead. Env var TTN_PGTABLE_DEFS names this file, otherwise it is taken to be ~/.pgtable-defs by default. This is done at module-load time. To change the meta file after loading, use procedure set-meta-file!.


Next: , Previous: personal-pgtable, Up: In Theory

2.25 module (ttn rcsutils)

We only deal with the main branch. This could be considered a bug.

— Procedure: rlog file

Run rlog(1) on file; return an alist describing the head revision. Keys include: rcs-file, working-file, head, locker, date, author and state. All values are strings.

— Procedure: rcs-files-under dir

Return a list of RCS/*,v files under dir.

— Procedure: display-rlog r [fields]

Display alist value r returned by Scheme function rlog. Optional args fields are symbols specifying which fields to display and in what order. If omitted, display, in this order: rcs-file, working-file, head, date, author, state.

— Procedure: display-rcs-state-summary dir

For directory dir, summarize state info for files in subdir RCS. Files are grouped by state and sorted w/ most-recently changed first.


Next: , Previous: rcsutils, Up: In Theory

2.26 module (ttn read-text-db-table)

A text-db-table is a file that begins with zero or more introductory lines (ignored), followed by a Scheme form starting at the beginning of a line:

       (text-db-table-config
         (meta . META)            ; optional; META is opaque, default #f
         (delim . "\f")
         (fields (NAME1 TYPE1)
                 (NAME2 TYPE2)
                 ...))

name is a symbol or keyword; type is one of the symbols:

sexp
Use read.
sexp-line
Use read, then discard trailing whitespace.
line
Use read-line, discarding eol chars (CR, LF).
rest-lines
Read lines, including eol chars, until next delim.
rest-lines-trim
Like rest-lines but result is string-trim-bothed.

Following the Scheme form is text terminated by the delimiter (a form feed in the above example), which is also ignored. Following this are the records of the database, separated by the delimiter, until the end of the file. The delimiter should NOT be at the end of the file.

This module provides the procedure read-text-db-table and the object property (procedure w/ setter) text-db-table-meta.

— Procedure: read-text-db-table filename/port [flags...]

Read a text-db-table from filename/port, return a list of records. Each record is an alist whose keys are the field names, in order. filename/port can be a filename (string), or an input port. In the latter case, it is left open when done.

As a side effect, the property text-db-table-meta (procedure with setter) for the returned list is set to the table's metadata, if any.

flags is a list of zero or more keywords that change the default behavior. These are the recognized flags:

#:list
Return each record as a list instead of as an alist.
#:closure
Return each record as a closure (procedure) that accepts one arg sel. If #:list is specified, sel is a 0-based integer to index into the record's data. Otherwise, sel names a field in the record's data.


Next: , Previous: read-text-db-table, Up: In Theory

2.27 module (ttn rlog-scan-proc)

The rlog(1) output format has stabilized for over ten years now. It is used by RCS and CVS (slightly modified). This module provides two procs that each return a scanner proc capable of parsing a string in rlog output format:

       (rlog-scan!-proc boxed-keys) => na-scanner
       (rlog-scan-proc keys) => scanner

Both na-scanner and scanner take a string and scan for regular expressions, specified by zero or more of the following keys:

       rcs-file
       working-file
       head
       locker
       date
       author
       state

The difference is in who does the memory allocation. On one hand, boxed-keys is a list of sublists, the car of which is a key and the cdr of which is set by na-scanner (na stands for “non-allocating”). The return value of na-scanner is unspecified. On the other hand, keys is simply a list of keys, and scanner constructs a fresh alist to return to the caller.

A secondary difference is that the alist modified by na-scanner is never shortened in case a particular regular expression does not match – na-scanner places a #f in the cdr – while scanner simply omits such elements from its return value.

As a special case, both keys and boxed-keys may be #f, which is taken to be the same as specifying all the keys.

Additionally, you can use group-logs-by to bin the logs (typically, either by state or by author).

— Procedure: group-logs-by key logs [keep...]

Group logs, a list of alists, by key in each alist. Return a list with elements of the form (KEY L1 L2...), where key is a symbol and l1... are elements of logs.

Optional args keep specify keys of those elements in l1... to collect. If unspecified, return the entire alist.


Next: , Previous: rlog-scan-proc, Up: In Theory

2.28 module (ttn rw-vcg)

This module exports two procs:

      (read-vcg-file filename) => vcg-tree
      (write-vcg-file vcg-tree filename)

Presently, operation relies on the external program sed(1). This means to say that there is a hackish text transform going on in the background instead of “proper” parsing/unparsing, resulting in strange behavior for certain valid inputs.

— Procedure: read-vcg-file filename

Return the internal graph representation object created from reading VCG file filename.

— Procedure: write-vcg-file vcg filename

Write vcg, an internal graph representation, to file filename. If filename is #t, write to stdout.


Next: , Previous: rw-vcg, Up: In Theory

2.29 module (ttn sanity)

— Procedure: add-to-load-path! dir

Prepend dir to %load-path if it is not already present.

— Procedure: know-that-ttn-procedures-docs-is-available!

Prepend to var documentation-files filename of ttn docs. The filename is computed using %search-load-path. Do not modify var if ttn/ttn-pers-scheme.gdf1 is not found.

— Procedure: give-me-a-sane-environment-please!

Set up interactive session environment according to ttn preferences. Specifically, set debug depth, turn on backtrace (on error :-), make the repl verbose, remove "." from %load-path, arrange for package docs to be findable, and extend the read-hash table so that #^Ffoo (where ^F is #\ack or "\C-f" in Emacs nomenclature) reads as a filename (string) formed as a result of passing it through expand-file-name-substituting-env-vars.

— Procedure: pp x

Pretty-print x, using escape sequences in strings.

— Procedure: ppsrc proc

Pretty-print the source of proc. This uses pp.


Next: , Previous: sanity, Up: In Theory

2.30 module (ttn scat)

This file exports these procs:

     (make-scat LEN . DEFAULT-VALUE)
     (scat-len SCAT)
     (scat-default SCAT)
     (scat-concat SCAT1 SCAT2)
     (make-sl FIELD-DEFS)
     (sl-copy SL)
     (sl-edit! SL FIELD-EDITS)
     (sl-from-template SL FIELD-EDITS)
     (sl->bytes SL . BYTE-SIZE)

len and default-value are numbers. field-defs have one of two forms:

     (NAME LENGTH VALUE)
     (NAME HEX-STRING)

In the latter form, length and value are computed from hex-string. field-edits have the form: (name value).

— Procedure: make-scat len [default-value...]

Return a new scat of LEN bits, w/ DEFAULT-VALUE, a number. If DEFAULT-VALUE is omitted, it is taken as 0. If DEFAULT-VALUE takes more bits than LEN, it is silently truncated.

— Procedure: scat-len scat

Return `len' field of SCAT.

— Procedure: scat-default scat

Return `default-value' field of SCAT.

— Procedure: scat-concat scat1 scat2

Return new scat made from SCAT1 and SCAT2. In the result, SCAT1 is shifted left and SCAT2 maintains low-order bits.

— Procedure: make-sl field-defs

Return a new SL structure made from FIELD-DEFS, a list of elements of the form (NAME LENGTH VALUE) or (NAME HEX-STRING). In the latter case, LENGTH and VALUE are computed from HEX-STRING. NAME may be #f, in which means no name. FIELD-DEFS order is maintained in the returned SL.

— Procedure: sl-copy sl

Return a copy of SL.

— Procedure: sl-edit! sl field-edits

Destructively modify SL using FIELD-EDITS, a list. Each element of FIELD-EDITS has the form: (NAME VALUE).

— Procedure: sl-from-template sl field-edits

Copy SL and apply FIELD-EDITS to the new structure. Return the new. This is a non-destructive variant of `sl-edit!'.

— Procedure: sl->bytes sl [byte-size...]

Return list of byte values for SL, in network-byte order. Optional arg BYTE-SIZE indicates how many bits are to be included in a byte, default if omitted is 8. Signal error if SL aggregate bit length is not an integral multiple of the byte size.


Next: , Previous: scat, Up: In Theory

2.31 module (ttn sgf)

This module provides the procs:

      (read-sgf-file filename) => collection
      (write-sgf-file collection filename)
      (children tree) => list or #f
      (nodes tree) => list
      (get node prop) => list of values
      (get-one node prop) => value
      (analyze tree [prefix])

collection is a list of one or more game trees. A game tree is a list w/ car #t and cdr a list of one or more nodes followed by zero or more children game trees. A node is a list of pairs, the car of which is a keyword representing an SGF property and the cdr the associated value, typically a string, number, two-element vector, or a pair of one of these simpler types. A pair for the property value indicates a composed type.

The vector elements are integers specifying column and row zero-based coordinates on a board. For example, #(4 2) represents position E3. For board size n, the vector #(n n) means “PASS”.

Additionally, this module also provides two data tables:

      *properties*
      *format-changes*

The data tables were originally from GNU Go 3.3.15 sources, massaged into Scheme and surrounded by reverse-engineered algorithms one summer night, sans net.cnxn.

2.31.1 data tables

— Scheme List: *properties*

List of property specifications. This is called the FF[4] property index by the GNU Go sources. Each entry has the form: (NICK DESC CONTEXT VALUE-SPECS).

nick
One- or two-character symbol. (Note, however, that in the tree returned by read-sgf-file, nick is represented by a keyword.) Some examples: B, W, FF.
desc
A short string describing the property. Examples: "Black", "White", "Fileformat".
context
A symbol indicating where this property is likely to be found. [Perhaps the actual specification is more restrictive; the current parser ignores this information completely.] Examples: move, setup, root, -.
value-specs
One or more expressions that comprise a mini-language for describing the possible values for this property.
none
Symbol. The property has no value.
double
real
number
Symbols. The value is a number. The first two indicate that the number may be a real number (with component to the right of the radix point).
#(number (LOW . HIGH) ...)
Vector with symbol number at index zero, followed by one or more pairs of integers. The value is a number but constrained to the inclusive range(s) described by low and high. For example, #(number (3 . 5) (8 . 10)) means that the value must be 3, 4, 5, 8, 9, or 10.
text
simpletext
Symbols. The value is a string. Actually, these probably should be differentiated somehow; when we regain internet connection access to the actual spec will clarify things a bit...
color
Symbol. The value is either black or white.
point
move
Symbols. The value is a two-character codification of a vertice on the board, starting from aa. Apparently the value tt means "PASS".
(TYPE-1 . TYPE-2)
Pair of symbols. The value is a composed type, rendered as the first followed by a colon character (:) followed by the second.
(or number (number . number))
List of three elements, exactly as shown. The value can be a single number or a composed type of two numbers.
(or none TYPE)
List of three elements, the first two symbols or and none. The property may take no value, or one of type type (which may be simple or composed).
list TYPE
elist TYPE
Sequence (not a list) of symbol followed by further specification. The property can have multiple values, one after another. The difference between list and elist is not clear at the moment.

— Scheme Vector: *format-changes*

Vector of elements specifying how the SGF format has changed. Each element is one of these values:

nil
no such format version (ERROR!)
integer (same as index)
no info for this format version
pair
car and cdr are, respectively, lists of changed and added property nicks

The expression (1- (vector-length *format-changes*)) evaluates to a number specifying the currently supported file format version.

2.31.2 file i/o

— Procedure: read-sgf-file filename

Return the collection of game trees parsed from reading filename.

— Procedure: write-sgf-file collection filename

Write the collection of game trees to filename.

2.31.3 tree utilities

— Procedure: children tree

Return a list of children game trees for tree, or #f if tree has no children.

— Procedure: nodes tree

Return a list of nodes (minimum is one) for tree.

— Procedure: get node prop

In node, return a list of all values for property prop. The list may be empty or it may contain several values.

— Procedure: get-one node prop

In node, return the value associated with the first occurance of prop.

2.31.4 miscellenous

— Procedure: analyze tree [prefix]

Display to the current output port a simple analysis of tree. (This is more for debugging support than anything serious.) Optional arg prefix specifies the number of spaces to insert at the beginning of the line, for recursive analysis of children trees.


Next: , Previous: sgf, Up: In Theory

2.32 module (ttn shell-command-to-string)

This module is inspired by an Emacs Lisp function by the same name. It exports the following procedures:

      (shell-command-to-string cmd) => string
      (shell-command-to-list cmd [handle-delim]) => list of strings
      (file-lines filename [handle-delim]) => list of strings

cmd is a string. handle-delim is an optional symbol that controls how to handle the newline at the end of each line, one of: trim, concat, peek, split. This is passed to procedure read-line in module (ice-9 rdelim). If unspecified, the default is trim.

If filename has #\~ or #\$ in it, it goes through expand-file-name-substituting-env-vars (see expand-file-name).

For more info on optional arg handle-delim, See Line/Delimited.

Also exported are two aliases to the above procs whose names are formed by replacing the ‘-to-’ with ‘->’. Supposedly more schemey that way.


Next: , Previous: shell-command-to-string, Up: In Theory

2.33 module (ttn shellutils)

This module exports the following procs:

       (system* . args)
       (sysfmt . args)
       (args->normalized-list . args)
— Procedure: system* [args...]

Echo args to make a string and pass it to system.

— Procedure: sysfmt [args...]

Apply simple-format to args and pass to system. The car of args is the format string.

— Procedure: args->normalized-list [args...]

For args, trim surrounding whitespace, join together separated by space, then split apart on space boundaries. For example:

          (args->normalized-list "rsync a b c"
                                 " d "
                                 "e"
                                 "f g h")
          ⇒ ("rsync" "a" "b" "c" "d" "e" "f" "g" "h")


Next: , Previous: shellutils, Up: In Theory

2.34 module (ttn slackful-concat)

This is an attempt at re-injecting slack due to Guile moving from string/symbol inter- to in-operability. Feh.

— Procedure: slackful-concat-proc return-type

Return a procedure that concatenates its args to produce an object of type return-type, one of string or #:string or symbol or #:symbol.


Previous: slackful-concat, Up: In Theory

2.35 module (ttn spewutils)

This module exports the procs:

       (eval-html-data-file file)
       (spew-html! html-data outfile . log)
       (update-page! template-file outfile . log)
       (update-all-pages! source-page pages)
       (update-all-html-data-pages! pages)


Next: , Previous: In Theory, Up: Top

3 In Practice

This chapter delves into one of the primary motivations for development of ttn-pers-scheme: dabbling in various personal projects.


Next: , Up: In Practice

3.1 Learning Scheme Programming

It might seem strange to consider Learning Scheme Programming a personal project, but hey that's me. Towards 1997 I didn't know scheme from elisp and had little idea of what the fuss was all about. I was aware of Guile as a half-way done project in its own right (as of 2004 you could say it's still half-way done: some parts have advanced and some parts have regressed) and because I support the goals of the Free Software Foundation, decided to use it as the basis for my personal cultivation.

Learning is a process that converts time and effort into a progression of improvements in understanding and skill — so hopes the learner! Here's a list of modules, sorted by initial checkin time (oldest first), accompanied by occasional commentary on the evolution of the code and/or interface, as a manifestation of what I have learned. The second date is the last modification time, and the number of revisions is in parentheses.

If this section has bored you to death you should at least take away the important message: learning scheme programming is up to you; in practice the practice of others is less useful to hear about than in theory!


Next: , Previous: Learning Scheme Programming, Up: In Practice

3.2 THUD

To indulge in some light-hearted Verilog envy, I started the THUD project1; and from there pulled the first few modules for ttn-pers-scheme:

These modules, being among the very first, use very simple constructs befitting a beginning programmer. To date, shell-command-to-string is still used in various places, while the others have largely gone neglected. THUD itself has been languishing (until recently) due to lack of attention (not to mention being largely overshadowed by the excellent SIMSYNCH package2 by Aubrey Jaffer, author of SCM and hence the progenitor of Guile). C'ést la vie.


Next: , Previous: THUD, Up: In Practice

3.3 Website Maintenance

Somewhat (but not entirely, I note gratefully) consistent with the concept of things growing (see Learning Scheme Programming) and falling down (see THUD), I enjoyed a bit of physical motion through space for a certain period of time, and began keeping notes of my ponderings in the midst of fearsome bouts of intense two-wheeled concentration, publishing these thoughts on the web as a celebration of survival.3

As no doubt many other dilettantes have done before me, I originally used only Emacs 20 and a bit of elisp on a text-only laptop, to update static pages on the website via a 28.8 modem. This suited me fine for several years, but over time, a mild curiosity about the fancy doodads deprived of this lynx (now w3m) user coupled with a growing interest in the dynamic nature of everything, led me away from the template-filling mindset and towards the tree-walking one.

The modules in ttn-pers-scheme developed in support of this wanderlust fall into a few broad categories.

It turns out website maintenance involves lots of interesting details, even after the wanderlust has subsided. Note that some modules have left the package (see Learning to Let Go), leaving only their names.


Previous: Website Maintenance, Up: In Practice

3.4 Learning to Let Go

Many times, the act of expressing oneself, whether it be in prose, poetry, or structured expressions, is of momentary fulfillment; the value lies more in the act and less in the artifact. This section describes some of the modules retired from ttn-pers-scheme for one reason or another.

[In fact, all of ttn-pers-scheme is going away! See Future.]

(ttn psql)
This module was initially moved into the ttn-do package:

http://www.gnuvola.org/software/ttn-do/

but after a brief stay, migrated to the Guile-PG package:

http://www.gnuvola.org/software/guile-pg/

where it presently resides (and continues to evolve) as module (database postgres-gxrepl).

(ttn ftw)
This module is now part of Guile, as (ice-9 ftw). At one point the code was ready to be added to SLIB, but I let the docs side slide for a few years. When the docs were finally ready, I balked at having to place the code and docs in the public domain, a prerequisite for SLIB inclusion (if I recall correctly). Perhaps that will come to pass, still, but it won't be mentioned here any longer.
(ttn eformat)
This was a module, similar to Guile's (ice-9 infix), initially written by Keisuke Nishida and posted to the mailing lists without a copyright notice around December 2000. I “rescued” it from the public domain so it's only fitting that it freely slide back into that space after some years of inactivity.
(ttn gap-buffer)
This module is now part of Guile, as (ice-9 gap-buffer). Another lesson, no longer captured automatically (see Learning Scheme Programming) since the module's departure, but worth mentioning here anyway, is that the naive implementation with two strings was both incredibly easy to write and incredibly slow; thus, better to have invested design time up front.
(ttn pgtype)
(ttn pgtable)
(ttn pgmeta)
(ttn display-table)
Like (ttn psql), these modules have migrated to, and continue to evolve in, the Guile-PG package. Their names there are (database postgres-types), (database postgres-table), (database postgres-meta) and (database postgres-resdisp), respectively.
(ttn collect-files-sorted-by-mtime)
This module implemented the (same-named) proc, an abstraction that initially seemed like a good idea, but in practice forced too many assumptions on client code. A good example of premature optimization, perhaps.
(ttn defvar)
This module originated with THUD (see THUD), and provided a unified way to access an object's “documentation”. Eventually THUD — its only client — stopped using it and runtime documentation extraction turned out to be not so interesting after all. Guile's module system (once again, sigh) takes partial blame for the disenchantment.
(ttn edit)
This module is now part of Guile, as (ice-9 editing-buffer), with compatible interface and enhanced functionality. Here is the “lesson” of this module:
Non-hygenic macros are more useful than hygenic in this case, since we want environment capture in addition to simple rewriting.

Now, who knows what that really means?!

(ttn flatten-to-buffer)
(ttn find-file)
(ttn save-buffer)
(ttn write-buffer-if-changed)
(ttn write-buffer)
These modules each used to export a single proc whose name coincided with the module name. These procs have now been aggregated, using the same names for the most part (see bufutils). Lesson learned: too much granularity can be a PITA.


Next: , Previous: In Practice, Up: Top

4 Future

As of version 0.50, ttn-pers-scheme is obsoleted by ttn-do, (and other packages) and will no longer be available after 2008-12-31.

The following table indicates where to find equivalent (or, in many cases, extended and improved) functionality for ‘(ttn foo)’ modules:

(ice-9 optargs-kw)
Got optargs-kw-utils.
(scripts read-rfc822)
Got (or perhaps reabsorbs) parse-rfc822.
(thud face)
This THUD module spun off, and now (aptly) reabsorbs, abbrev-tree. Circles and cycles, what's the difference?
(ttn-do cron-walk)
Got cron.
(ttn-do display-state-summary)
Got cvsutils, rcsutils, and rlog-scan-proc.
(ttn-do display-wurld)
Got html-world.
(ttn-do run-signed-batch-job)
Got gpgutils,
(ttn-do sgfc)
Got sgf.
(ttn-do vcg-convert)
Got rw-vcg.
(ttn-do zz xml expat)
Expanded upon, by means of being the basis of, mixp.
(ttn-do zzz filesystem)
Got dirutils, expand-file-name and fileutils.
(ttn-do zzz lookingfor)
Got grep.
(ttn-do zzz publishing)
Got flatten, markup and spewutils.
(ttn-do zzz subprocess)
This module aggregates many process-related modules: call-process-to-buffers, call-process, make-buffered-caller, shell-command-to-string and shellutils.
(ttn-do zzz various-db)
Got personal-pgtable and read-text-db-table.
(ttn-do zzz xhtml-tree)
Got html-data2.

On the other hand, these are modules whose functionality did not make it out of the sinking ship:

     bufutils
     email-log-if-fail
     filesystem-tree-to-list
     html-data
     listener
     sanity
     scat
     slackful-concat


Previous: Future, Up: Top

Index

Here is a list of concepts, procedures and data structures described or mentioned in this manual: