[racket] Making a section optional in Scribble

From: Matthew Butterick (mb at mbtype.com)
Date: Wed Dec 17 13:55:02 EST 2014

The "listification" of arguments within curly braces is easily the aspect
of Scribble syntax that trips me up the most. I understand why it's done
that way. But for my purposes, I usually want the thing between curly
braces to behave as a block, not as a list.

For instance, in my Pollen package, I use Scribble for HTML templates,
where you want to be able to write things like:

@when[condition]{print
all
the
stuff
here}

Anyone who's familiar with HTML template languages would expect everything
between the curlies to print. But under Scribble rules, you only get the
last word "here".

So I created a `when/block` macro that does the thing I want. [1]

@when/block[condition]{print
all
the
stuff
here}

I suppose it's similar to Eli's when* macro, though mine also does string
conversions. For instance, when* won't work in this case, where a value is
being returned within the curlies:

#lang scribble/base
    @(define some-condition #true)
    @(define-syntax-rule (when* C  E ...) (and C (list E ...)))

@when*[some-condition]{
      @section{Section two}
      AKA section @(+ 1 1)}

I thought about a) modifying Scribble syntax for my Pollen package so that
curly braces behave this way by default (= no, because it breaks too much)
or b) introducing new "block operator" syntax (= like double curly braces,
but that doesn't save too many keystrokes, and we're running out of easily
accessed grouping characters.) Though perhaps:

@when[condition]<print
all
the
stuff
here>

?




[1]
http://pkg-build.racket-lang.org/doc/pollen/Template.html#%28def._%28%28lib._pollen%2Ftemplate..rkt%29._when%2Fblock%29%29

On Wed, Dec 17, 2014 at 1:04 AM, Eli Barzilay <eli at barzilay.org> wrote:
>
> On Tue, Dec 16, 2014 at 9:27 PM, Matthias Felleisen
> <matthias at ccs.neu.edu> wrote:
> >
> > A 'when' expression returns the value of the last expression, in your
> > case the content of the section. By lifting the when out, you get both
> > pieces: [...]
>
> After I complained about it a few times, Matthew made it possible to use
> lists, as well as some other other scribble/text-isms (like ignoring #f
> and void):
>
>     #lang scribble/base
>     @(define some-condition #true)
>     @title{Use Lists}
>     @section{Section one}
>     Section one is for everyone.
>     @(when some-condition
>        (list @section{Section two}
>              "Section two is for some, but not all."
>              "This is more satisfactory."))
>
> But it's more convenient to use the text syntax, and it works better in
> that you don't get the hard-to-find formatting bug that the above
> produced:
>
>     #lang scribble/base
>     @(define some-condition #true)
>     @title{Use Lists}
>     @section{Section one}
>     Section one is for everyone.
>     @(when some-condition
>        @list{@section{Section two}
>              Section two is for some, but not all.
>              This is more satisfactory.})
>
> > This is clearly unsatisfactory but I am sure you can make this look
> > decent with a bit of macrology
>
> A tiny bit of very simple macrology that can still be useful here is:
>
>     #lang scribble/base
>     @(define some-condition #true)
>     @(define-syntax-rule (when* C  E ...) (and C (list E ...)))
>
>     @title{Use Lists}
>     @section{Section one}
>     Section one is for everyone.
>     @when*[some-condition]{
>       @section{Section two}
>       Section two is for some, but not all.
>
>       This is more satisfactory.}
>
> [In my fantasies I get to redefine a #%begin[*] macro to `list'
> (actually, `begin/text') and that makes everything works as people
> usually expect.]
>
> And since lists have no rendering meaning (= they're just flattened) (at
> least that was how I wanted it, hopefuly it didn't change--?), you don't
> need tricks like `append-map' and similar:
>
>     #lang scribble/base
>     @(define some-condition #true)
>     @(define-syntax-rule (when* C  E ...) (and C (list E ...)))
>
>     @title{Use Lists}
>     @section{Section one}
>     Section one is for everyone.
>
>     @(define (triple . x) (build-list 3 (λ(_) (list x "\n" "\n"))))
>     @when*[some-condition]{
>       @triple{
>         @section{Section two}
>         @triple{Section two is for some, but not all.
>
>                 This is more satisfactory.}}}
>
> --
>           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                     http://barzilay.org/                   Maze is Life!
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141217/e278af59/attachment.html>

Posted on the users mailing list.