On Jul 19, 2016, at 9:42 PM, Joel Dueck <[email protected]> wrote:
>
> So to that end I wrote the poly-branch-tag macro, a simplified version of
> which is here:
>
> (define-for-syntax site-poly-targets '(pdf html))
>
> (define-syntax (poly-branch-tag stx)
> (syntax-parse stx
> [(_ TAG:id)
> (with-syntax ([POLY-FUNCS (for/list ([target (in-list
> site-poly-targets)])
> (list target (format-id stx "~a-~a"
> target #'TAG)))])
> #'(define-tag-function (TAG attributes elems)
> (define poly-func (second (assq (current-poly-target)
> 'POLY-FUNCS)))
> ((eval poly-func) attributes elems)))]))
The problem is with 'POLY-FUNCS in the macro template. When you put the quote
mark on the front, then everything inside POLY-FUNCS gets treated as a symbol.
But in fact, you only want the target name to behave as a symbol, and you want
your new function-name identifier to behave as a variable (that refers to your
imported function).
The solution is to match the target and function separately in your
`with-syntax` pattern, and then only put the quote mark on the first one (once
this problem is fixed, notice that the `eval` becomes unnecessary; notice also
the use of the `...` matching operator so we can handle the new syntax bits in
the template one at a time, rather than all at once):
;;;;
#lang racket
(require rackunit (for-syntax syntax/parse racket/syntax) pollen/tag
pollen/setup)
(define (html-bold . xs) "this is html-bold")
(define (pdf-bold . xs) "this is pdf-bold")
(define-for-syntax site-poly-targets '(pdf html))
(define-syntax (poly-branch-tag stx)
(syntax-parse stx
[(_ TAG:id)
(with-syntax ([((POLY-TARGET POLY-FUNC) ...) (for/list ([target (in-list
site-poly-targets)])
(list target
(format-id stx "~a-~a" target #'TAG)))])
#'(define-tag-function (TAG attributes elems)
(define poly-func (second (assq (current-poly-target) (list (list
'POLY-TARGET POLY-FUNC) ...))))
(poly-func attributes elems)))]))
(poly-branch-tag bold)
(check-equal? (bold "hi")
"this is html-bold")
(check-equal? (parameterize ([current-poly-target 'pdf])
(bold "hi"))
"this is pdf-bold")
;;;;
Alternatively, you could write the `poly-branch-tag` macro using a `case`
statement. No leading quote necessary for POLY-TARGET here, because `case`
auto-quotes whatever is on the left side of each branch. (Notice again the use
of `...` to repeat the branch with each target / function pair.)
;;;;
(define-syntax (poly-branch-tag stx)
(syntax-parse stx
[(_ TAG:id)
(with-syntax ([((POLY-TARGET POLY-FUNC) ...) (for/list ([target (in-list
site-poly-targets)])
(list target
(format-id stx "~a-~a" target #'TAG)))])
#'(define (TAG . xs)
(case (current-poly-target)
[(POLY-TARGET) (apply POLY-FUNC xs)] ...)))]))
;;;
> I started by using the (case) branching, but I wanted a way to be able to add
> output formats in the future without fiddling with the macro every time.
>
> All of this seemed to be working fine in my single-file DrRacket test, but
> when I try this in an actual Pollen project I get an error (see end of this
> post). It complains that html-bold is undefined, but it is very clearly
> defined in tags-html.rkt (which also contains a (provide (all-defined-out))
> directive). Indeed, I can change test.poly.pm to call html-bold directly and
> that works. So calling html-bold directly works, but a macro that evaluates
> to ((eval 'html-bold) args) doesn't.
>
> I feel I must be missing some nuance of the scope in which Pollen files work.
> E.g., I can run the following in DrRacket:
>
> (define (html-bold attrs elems)
> `(strong ,@elems))
> ((eval 'html-bold) '() '("ahoy"))
>
> But the following in test.poly.pm gives me the same error as I get when using
> my macro:
>
> #lang pollen
>
> ◊(define (html-bold elems) `(strong ,@title))
> ◊((eval 'html-bold) '() '("ahoy"))
>
> raco pollen render -t html posts/test.poly.pm
> rendering posts/test.poly.pm
> rendering: posts/test.poly.pm as test.html
> rendering: /template.html.p as /template.html
> html-bold: undefined;
> cannot reference undefined identifier
> context...:
> ...n/pollen/tag.rkt:79:10
> (submod /Users/joel/Documents/code/thenotepad/posts/test.poly.pm g1083
> inner): [running body]
> (submod /Users/joel/Documents/code/thenotepad/post/test.poly.pm g1083):
> [traversing imports]
> /Users/joel/Documents/code/thenotepad/posts/test.poly.pm: [traversing
> imports]
>
> /Users/joel/Library/Racket/6.4/pkgs/pollen/pollen/private/cache-utils.rkt:33:0:
> path->hash
>
> /Users/joel/Library/Racket/6.4/pkgs/pollen/pollen/private/cache-utils.rkt:76:14:
> temp16
> /Applications/Racket v6.4/collects/file/cache.rkt:63:2: fetch-and-continue
> /Applications/Racket
> v6.4/collects/racket/contract/private/arrow-val-first.rkt:335:3
>
> /Users/joel/Library/Racket/6.4/pkgs/pollen/pollen/private/cache-utils.rkt:67:0:
> cache-ref!
> /Applications/Racket v6.4/collects/racket/private/more-scheme.rkt:373:13:
> hash-ref!
> /Users/joel/Library/Racket/6.4/pkgs/pollen/pollen/cache.rkt:24:4:
> cached-require-base
> /Users/joel/Library/Racket/6.4/pkgs/pollen/pollen/render.rkt:169:0:
> render-markup-or-markdown-source33
> render26
> render-from-source-or-output-path
> loop
> (submod
> /Users/joel/Library/Racket/6.4/pkgs/pollen/pollen/private/command.rkt raco):
> [running body]
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Pollen" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"Pollen" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.