Open bluebear94 opened 2 years ago
I'd imagine that to do this, you'd need to:
pollen-html.rkt
and pollen-latex.rkt
at phase n+1The disadvantage is that the generated functions in the main pollen.rkt
wouldn't be able to know what signature to expect, so errors having to do with signatures would blame pollen.rkt
and not the calling code. Exported non-function variables (such as (define br '(br))
wouldn't play well with this approach as well; they'd have to be re-exported as functions, requiring existing code to be changed.
Alternatively:
pollen-html.rkt
and pollen-latex.rkt
at phase n+1but this requires the arguments to be valid X-exprs, so I'm not too keen on that.
If stuff that you are gonna import are run-time definitions, you can use dynamic-require
, FWIW.
I'm not getting much luck using dynamic-require
from Pollen:
pollen.rkt:
#lang racket
(displayln (dynamic-require "pollen/common.rkt" 'sei))
pollen/common.rkt:
#lang racket
(provide sei)
(define sei "○")
This works fine when imported from a .pm file in the project root, but from a file in a subdirectory such as grammar/index.html.pm
, the dynamic-require
tries to require the module at grammar/pollen/common.rkt
.
And now I have a proof of concept. Perhaps the grossest thing I've done in Racket.
(begin-for-syntax
(define (target->module-path target)
(format "pollen/~a.rkt" (symbol->string target)))
(define (exports-from-target target)
(define path (target->module-path target))
(dynamic-require path #f)
(define-values (vars syntaxes) (module->exports path))
(define (get-ids-from-export-list el)
(define el0 (assoc 0 el))
(if el0
(map car (cdr el0))
'()))
(append (get-ids-from-export-list vars)
(get-ids-from-export-list syntaxes)))
(define (exports-from-all-targets targets)
(parameterize ([current-load-relative-directory "/home/kozet/ncv9/src"])
(define exports (make-hash))
(for ([target targets])
(define target-exports (exports-from-target target))
(for ([item-id target-exports])
(define item (dynamic-require (target->module-path target) item-id))
(hash-update! exports
item-id
(lambda (l) (cons (list target item) l))
'())
)
)
exports))
(define EXPORTS (exports-from-all-targets '(html tex)))
)
(define-syntax (generate-reexports obj)
(syntax-case obj ()
[(_)
(with-syntax
([(statements ...)
(for/list ([(item-id items) (in-hash EXPORTS)])
(with-syntax
([item-id-stx (datum->syntax #'obj item-id)]
[(cases ...)
(for/list ([target+item items])
(define target (car target+item))
(define item (cadr target+item))
(with-syntax ([target-stx (datum->syntax #'obj target)]
[item-stx (datum->syntax #'obj item)])
#'[(target-stx)
(keyword-apply item-stx kws kw-args rest)]))])
#'(begin
(provide item-id-stx)
(define item-id-stx
(make-keyword-procedure
(lambda (kws kw-args . rest)
(case (current-poly-target)
cases ...
[else (error (quote item-id-stx) "not defined for ~a" (current-poly-target))]))))))
)])
#'(begin statements ...))
]))
(generate-reexports)
current-load-relative-directory
is currently parameterized to a hard-coded path; I'm still looking for a way to avoid the hard-coding.
As I've mentioned earlier, we can't require
pollen/setup
for syntax because if we did, then loading pollen.rkt
would require pollen/setup
when compiling which depends on pollen.rkt
for the setup parameters ad infinitum. This also prevents us from require
-ing any Pollen-related modules in pollen/html.rkt
or pollen/tex.rkt
.
Can you use define-runtime-path
to solve the wrong directory problem?
Perhaps, but I don't think it'll solve the import cycle.
I think this is the most promising approach that I have come across: https://github.com/otherjoel/thenotepad/tree/master/pollen-local
It does some trickery with defining the functions according to a naming scheme, so it doesn't go by file itself but allows for separating it that way. I'd suggest at polytag.rkt
, where the macro is defined, then the actual tag functions are in other files.
I have a slightly more evolved version of that approach here: https://thelocalyarn.com/code/file?name=pollen.rkt&ci=tip
Is it possible to define tags that depend on the output format by using a separate file for each format?
For example, if I specify
html
andtex
output formats, then can I put the HTML-specific definitions inpollen-html.rkt
and the LaTeX-specific definitions inpollen-latex.rkt
, including whichever file is appropriate for the output?