Pass the metas hash table to tag functions #166

Closed
opened 6 years ago by jlorieau · 4 comments
jlorieau commented 6 years ago (Migrated from github.com)

It would be useful for tag functions to have access to the metas hash table to render tags. An example of such a use would be to calculate the pagenode's position for chapter and section rendering.

Matthew provided a helpful macro that can be used to wrap tag functions for this purpose. However, I would like to suggest an implementation of a tag function, like define-tag-function that optionally receives the metas hash. I'm not sure whether such a change could be done in a backwards-compatible way, but creating a new function (e.g. define-tag-metas-function), or enabling the passed argument with a setup flag, could be possible alternative solutions.

It would be useful for tag functions to have access to the ```metas``` hash table to render tags. An example of such a use would be to calculate the pagenode's position for chapter and section rendering. Matthew provided a helpful macro that can be used to wrap tag functions for this purpose. However, I would like to suggest an implementation of a tag function, like `define-tag-function` that optionally receives the `metas` hash. I'm not sure whether such a change could be done in a backwards-compatible way, but creating a new function (e.g. `define-tag-metas-function`), or enabling the passed argument with a setup flag, could be possible alternative solutions.
mbutterick commented 6 years ago (Migrated from github.com)

There’s more than one way to do this, so I think it would be a worthwhile mini-tutorial for the docs.

For now, I’m not enthusiastic about upgrading define-tag-function to pass metas as an argument. (Or creating another function in pollen/tag to do it.)

The problem is that this blends the macro and runtime worlds in an awkward way. The technique I showed you before is a macro that depends on grabbing the metas at the caller site. But it assumes that metas is defined there. If it were used in a module without metas defined, it would fail.

True, we could adjust the macro to behave differently based on whether metas is defined. But that just shifts the problem. The body of the tag function will be written to rely on metas. So the operation would still fail.

There’s more than one way to do this, so I think it would be a worthwhile mini-tutorial for the docs. For now, I’m not enthusiastic about upgrading `define-tag-function` to pass `metas` as an argument. (Or creating another function in `pollen/tag` to do it.) The problem is that this blends the macro and runtime worlds in an awkward way. The technique I [showed you before](https://github.com/mbutterick/pollen/issues/163#issuecomment-355832866) is a macro that depends on grabbing the `metas` at the caller site. But it assumes that `metas` is defined there. If it were used in a module without `metas` defined, it would fail. True, we could adjust the macro to behave differently based on whether `metas` is defined. But that just shifts the problem. The body of the tag function will be written to rely on `metas`. So the operation would still fail.
mbutterick commented 6 years ago (Migrated from github.com)

I just pushed an update that adds a current-metas parameter to pollen/core. I’m not ready to document this as part of the public interface. But try it, see if it suits your needs, and report back.

Instead of having to pass metas to a tag function explicitly, the current-metas parameter contains the metas of the source file currently being rendered (or if there is no file, then #f). So you can do things like this:

#lang racket
(require pollen/core) 
(provide (all-defined-out))

(define (tag . xs)
  (if (current-metas)
      (format "metas = ~v" (current-metas))
      "no metas"))

Two caveats:

  • you must import pollen/core to get current-metas

  • you should always assume current-metas could be #f (if the function isn’t being called from inside a Pollen source) and program accordingly

I just pushed an update that adds a `current-metas` parameter to `pollen/core`. I’m not ready to document this as part of the public interface. But try it, see if it suits your needs, and report back. Instead of having to pass `metas` to a tag function explicitly, the `current-metas` parameter contains the metas of the source file currently being rendered (or if there is no file, then `#f`). So you can do things like this: ```racket #lang racket (require pollen/core) (provide (all-defined-out)) (define (tag . xs) (if (current-metas) (format "metas = ~v" (current-metas)) "no metas")) ``` Two caveats: * you must import `pollen/core` to get `current-metas` * you should always assume `current-metas` could be `#f` (if the function isn’t being called from inside a Pollen source) and program accordingly
jlorieau commented 6 years ago (Migrated from github.com)

That's great and a perfect solution. Thanks!

That's great and a perfect solution. Thanks!
mbutterick commented 6 years ago (Migrated from github.com)

Is current-metas working as advertised? If so I will add it to the docs.

Is `current-metas` working as advertised? If so I will add it to the docs.
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#166
Loading…
There is no content yet.