On Jul 19, 2016, at 9:42 PM, Joel Dueck <dueckofe...@gmail.com> 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 pollenpub+unsubscr...@googlegroups.com.
> 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 pollenpub+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to