mbutterick / pollen-users

please use https://forums.matthewbutterick.com/c/typesetting/ instead
https://forums.matthewbutterick.com/c/typesetting/
52 stars 0 forks source link

Telling apart source of first argument #65

Open basus opened 4 years ago

basus commented 4 years ago

If I'm understanding things correctly, both ◊tagfn["arg"] and ◊tagfn{arg} will pass "arg" as the first argument to the tagfn function. Is there some way to tell these two cases apart? I'm thinking about tag functions where the argument between [] could be optional. For example, a ◊code tag where ◊code['lang]{...} treats the stuff inside {} as 'lang but treats it as plaintext if it's just ◊code{...}.

otherjoel commented 4 years ago

There’s not a way to tell them apart strictly by whether they occur in [ ] vs { }. I’m prettry sure that information gets discarded by the reader.

But you know that anything occurring inside the { } will (almost always) be either a string or a tagged X-expression. You could take advantage of that by testing if the first argument is a plain symbol:

(define (code . elems)
  (define-values (language code-elems)
    (cond [(symbol? (car elems)) (values (car elems) (cdr elems))]
          [else (values 'plaintext elems)]))
  ; ... now do what you like with code-elems depending on language
)

Or, if you don’t mind being a bit more verbose in your markup, you can use keyword arguments to implement optional stuff. E.g., ◊code[#:lang 'python]{...}. And use define-tag-function to handle those automatically

(require pollen/tag txexpr)

(define-tag-function (code attrs elems)
  (define language (attr-ref attrs 'lang 'plaintext)) ; supply a default value
  ; ... now do what you like with elems depending on language
)
mbutterick commented 4 years ago

I’m pretty sure that information gets discarded by the reader.

Yes, that’s correct.