[plt-scheme] mztext replacement

From: Eli Barzilay (eli at barzilay.org)
Date: Wed Feb 27 19:31:22 EST 2008

On Feb 27, Aleks Bromfield wrote:
> This is great!
> >   * It seems to me that just the above is enough for the usual use of
> >     a saner tex front end.  Do you see any extra bells and whistles
> >     that are needed?
> This is mostly due to my unfamiliarity with Scribble: How would you
> replace defcommand?

If it takes a single {...} argument then you're fine.  For example,
here's a silly example:

  #lang scribble/text
  @(define (angled . body) (list "<" body ">"))@;
  @(define (shout . body) @angled[(map string-upcase body)])@;
  blah @angled{blah @shout{blah} blah} blah

(Notes: the "@;" is to avoid empty lines in the output; inputs from
"{...}"s are lists of strings and whatever subexpressions you put in
with nested `@'s; this means that "@shout{@angled{...}}" will not as
implemented here.)

If it takes two arguments then you need to somehow split the input
into parts.  A quick way:

  #lang scribble/text
     (require scheme/match)
     (define (angled . body) (list "<" body ">"))
     (define (point . body)
       (match (regexp-split #rx" +" (apply string-append body))
         [(list x y) (angled x ", " y)])))@;
  Draw a line from @point{0 y} to @point{100 y}.

A more complete solution that I referred to earlier is to split on
some actual token.  Here's a complete example -- it takes care of a
few details like newlines etc, which is why it might be useful to have
some library function for this:

  #lang scribble/text
     (define (split items token)
       (let loop ([is items] [r '()])
         (cond [(null? is) (list (reverse r))]
               [(eq? token (car is))
                (let ([rest (loop (cdr is) '())])
                  (if (null? r)
                    (cons (reverse (if (equal? "\n" (car r))
                                     (cdr r)
               [else (loop (cdr is) (cons (car is) r))])))
     (define item "foo") ; some unique token
     (define (itemize . body)
       (map (lambda (i) (list "* " i "\n")) (split body item)))
  @itemize{@item You begin with the first thing
           @item and end with the last thing.}

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.