[racket] Making a section optional in Scribble

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Dec 23 14:20:44 EST 2014

On Wed, Dec 17, 2014 at 1:55 PM, Matthew Butterick <mb at mbtype.com> wrote:
> 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.

(I think that you mean the other way -- you prefer that it does return a
list with all of the string expressions instead of silently dropping
them all except for the last one...)

> 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".

An important point here is that it's not scribble rules -- it's rather
Racket's rules applied to the syntax that the above is read as.  But
yes, it doesn't help much, and I expect many people to trip up on this.
That's why I really wanted to find some way to change internal begins in
the scribble languages to collect them all in a list.

(BTW, in one of the last experiments I had with the syntax, I made
@foo{bar} read as something like (dispatch foo ("bar")) with the idea of
allowing people to define a specific `dispatch' macro that does whatever
you want.  But I eventually concluded that having such "hidden
identifiers" pop up as a result of reading stuff is not a good idea.)

> 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:
> [...]
> @when*[some-condition]{
>       @section{Section two}
>       AKA section @(+ 1 1)}

That shouldn't work outside of that too...  So you want some global hook
to convert random values.

> 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>
> ?

There is a `begin/text' which is doing that, and deals with the tricky
bits of allowing definitions too, so something like this is closer to
what you want (modulo that conversion which is besides this issue):

    (define-syntax-rule (when* C  E ...) (when C (begin/text E ...)))

That's obviously a bad name for short things -- but if there was a
redefine-able `#%begin' thing, then that would make it possible.

Also, if you want to play with a more extreme approach, you can write a
macro that looks at the syntax properties of what it gets, and expands
differently when used with an @-form than it does otherwise.  An even
more radical thing would be to redefine `#%module-begin' that converts
all {...} texts (except in quotes, etc) into uses of `begin/text'.

But that's more risky in killing the uniformity and making possibly
confusing interactions.

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

Posted on the users mailing list.