[racket] scribble syntax suggestion wrt text-mode and racket-mode arguments

52 views
Skip to first unread message

Matthew Butterick

unread,
Jun 9, 2013, 8:05:22 PM6/9/13
to Racket mailing list
Semantically, "an operation [in Scribble] doesn’t care whether it’s used with [...] or {...}." Therefore, it would be useful if Scribble expressions were not syntactically limited to the form @ ‹cmd› [ ‹datum›* ] { ‹text-body› }, and instead allowed text-mode and racket-mode arguments to be freely & indefinitely sequenced.

What I've found using Scribble is that many of the functions one writes are, of course, intended to operate on a text argument. So the text-mode argument naturally wants to come first in the function:

@cross-ref{This text}

Now, suppose I want to add an optional second argument. The natural place for this optional argument would be after the first:

@cross-ref{This text}["where.html"]  

or

@cross-ref{This text){where.html}

But AFAIK, Scribble forbids these patterns. So I might try this:

@cross-ref["where.html"]{This text}

But that doesn't work either, because the cross-ref function expects the target text to be in the first position. So either I must forego idiomatic Scribble expressions altogether:

@(cross-ref "This text" "where.html") 

Or use a keyword argument:

@cross-ref[#:destination "where.html"]{This text}

As a workaround, that's OK. But at this point, Scribble is reaching up into my code and starting to impose design restrictions (namely, keyword arguments) that have ripple effects elsewhere.

Robby Findler

unread,
Jun 9, 2013, 9:14:20 PM6/9/13
to Matthew Butterick, Racket mailing list
But a block of text does not always turn into a single argument, so I'm not sure how to do what you ask.

Robby


____________________
  Racket Users list:
  http://lists.racket-lang.org/users


Matthew Butterick

unread,
Jun 10, 2013, 12:15:27 AM6/10/13
to Racket mailing list
Perhaps I'm overlooking some obvious complication. But today, the pattern of how Scribble parses @ ‹cmd› [ ‹datum›* ] { ‹text-body› } is roughly "apply <cmd> to the list formed by concatenating the datum arguments and the text-body arguments". So it seems to me that this pattern could be logically extended to cover any number of datum or text-body blocks.

For instance, today, this expression:

@foo[1 2]{3          
4}

expands to:

(foo 1 2 "3" "\n" "4")

Therefore, this expression:

@foo{3          
4}[5 6]

would expand to

(foo "3" "\n" "4" 5 6)

And this:

@foo[1 2]{3          
4}[5 6]{7
8}

To this:

(foo 1 2 "3" "\n" "4" 5 6 "7" "\n" "8")

If you needed a text body to become a single argument, you would just do what you do today, which is add another set of braces to produce a sublist. So this:

@foo{@{3          
4}}[5 6]

Would become:

(foo ("3" "\n" "4") 5 6)

You could also convert the sublist back into a string with string-join. But again, that's consistent with current behavior, so NBD.

Robby Findler

unread,
Jun 10, 2013, 8:20:11 AM6/10/13
to Matthew Butterick, Racket mailing list
Would something like this work for your use? 

'@f{3
    4 @5 @6}

=

'(f "3" "\n" "4 " 5 " " 6)

(Eli may know a way to get around the extra spaces that get inserted.)

Robby

Eli Barzilay

unread,
Jun 24, 2013, 5:52:35 AM6/24/13
to Matthew Butterick, Racket mailing list
The thing is that using two {}s is actually useful for curried
functions. For example:

#lang scribble/text
@(define ((foo . text1) . text2)
@list{1. @text1
2. @text2})
@@foo{blah blah blah}{foo bar baz}

and this extension holds for a [] that follows a {}.

But there is a little known extension of the @... escape syntax -- you
can use bars not only to delimit the racket expression from the
surrounding text, you can also use it to include multiple expressions
with no text between them. For example, instead of the:

> @foo{3
> 4}[5 6]

which you suggested, you can use

@foo{3
4@|5 6|}

--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
Reply all
Reply to author
Forward
0 new messages