Multiple arguments to tag functions? #37

Closed
opened 9 years ago by basus · 2 comments
basus commented 9 years ago (Migrated from github.com)

I've been playing around with ways to implement hyperlinks using tag functions. I think the most generic way would be something like ◊a['href:"url"]{text}, but I'd like to make some custom tags for things like internal links, links to particular domains, etc. Ideally I'd want to write something like ◊internal[url]{text} that clearly separates out the URL from the link text. Is there a simple way to go about doing this? I can't tell what the rules are for splitting the tag contents into the list that gets passed to the tag function.

I've been playing around with ways to implement hyperlinks using tag functions. I think the most generic way would be something like `◊a['href:"url"]{text}`, but I'd like to make some custom tags for things like internal links, links to particular domains, etc. Ideally I'd want to write something like `◊internal[url]{text}` that clearly separates out the URL from the link text. Is there a simple way to go about doing this? I can't tell what the rules are for splitting the tag contents into the list that gets passed to the tag function.
mbutterick commented 9 years ago (Migrated from github.com)

The doc entry on "The relationship of text mode and Racket mode" will be helpful. In short, the arguments in a text-mode command like this:

◊internal[url]{text}

Get converted into this Racket-mode command:

(internal url text)

So the tag function that corresponds to this would look like:

(define (internal url text)
    (do-things))

The wrinkle is that in text mode, the argument between curly braces — in this case, {text} — can actually resolve into multiple arguments (for instance, if it contains nested tags, or multiple lines of text), so what you actually get is this:

(internal url text text2 text3 ...)

So while the tag function above will work with a single text argument, the better habit is to write tag functions with a rest argument, like so:

(define (internal url . text-args)
    (do-things))

The rest argument is a list of all the arguments coming after the other named arguments. So in this case, whether {text} resolves to one text argument or a hundred, they will all be wrapped in a single list of arguments called text-args.

For more about this, see "Multiple input values & rest arguments" in the Pollen docs and "Declaring a rest argument" in the Racket guide.

BTW the shorthand ◊a['href:"url"]{text} is mostly intended for when you're using a default tag function and just want a simple way of stuffing some attributes into the tag. If you're intending to make a custom tag function, it's not necessary (and may in fact be more cumbersome).

The doc entry on ["The relationship of text mode and Racket mode"](http://pkg-build.racket-lang.org/doc/pollen/reader.html#%28part._.The_two_command_modes__text_mode___.Racket_mode%29) will be helpful. In short, the arguments in a text-mode command like this: `◊internal[url]{text}` Get converted into this Racket-mode command: `(internal url text)` So the tag function that corresponds to this would look like: ``` racket (define (internal url text) (do-things)) ``` The wrinkle is that in text mode, the argument between curly braces — in this case, `{text}` — can actually resolve into multiple arguments (for instance, if it contains nested tags, or multiple lines of text), so what you actually get is this: `(internal url text text2 text3 ...)` So while the tag function above will work with a single text argument, the better habit is to write tag functions with a rest argument, like so: ``` racket (define (internal url . text-args) (do-things)) ``` The rest argument is a list of all the arguments coming after the other named arguments. So in this case, whether `{text}` resolves to one text argument or a hundred, they will all be wrapped in a single list of arguments called `text-args`. For more about this, see ["Multiple input values & rest arguments"](http://pkg-build.racket-lang.org/doc/pollen/third-tutorial.html#%28part._.Multiple_input_values___rest_arguments%29) in the Pollen docs and ["Declaring a rest argument"](http://pkg-build.racket-lang.org/doc/guide/lambda.html?q=rest#%28part._rest-args%29) in the Racket guide. BTW the shorthand `◊a['href:"url"]{text}` is mostly intended for when you're using a default tag function and just want a simple way of stuffing some attributes into the tag. If you're intending to make a custom tag function, it's not necessary (and may in fact be more cumbersome).
basus commented 9 years ago (Migrated from github.com)

Ahh... thanks. I just didn't read the text-mode/Racket-mode chapter closely enough and assumed that the first argument was always parsed as attributes.

Ahh... thanks. I just didn't read the text-mode/Racket-mode chapter closely enough and assumed that the first argument was always parsed as attributes.
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: mbutterick/pollen#37
Loading…
There is no content yet.