multiple text arguments? #116

Open
opened 3 years ago by aalexei · 5 comments
aalexei commented 3 years ago (Migrated from github.com)

Hi, I'm wanting to use Pollen to generate math-heavy material for a website. It seems that the best way to do this at the moment is to keep the maths in LaTeX using KaTeX to generate the maths output and everything else is written in Pollen. I have this working ok, but I'm tripping up on how to nicely convert some LaTeX macros to Pollen. I'd rather have minimal inclusion of LaTeX as a 'necessary evil' and the majority of the coding occurring in Pollen/Racket than having two systems to debug.

LaTeX allows for macros to have multiple arguments like:

\newcommand{\ketbra}[2]{|#1\rangle\langle#2|}

While I can do something like:

(define (ketbra label1 label2) (format "|~a\\rangle\\langle~a|" label1 label2) )

It looks ugly in text since you have to use strings:

◊ketbra["\\phi_+" "\\phi_+"]

Is it possible to write a pollen function with multiple text parts, something like the following?

◊ketbra{\phi_+}{\phi_+}
Hi, I'm wanting to use Pollen to generate math-heavy material for a website. It seems that the best way to do this at the moment is to keep the maths in LaTeX using KaTeX to generate the maths output and everything else is written in Pollen. I have this working ok, but I'm tripping up on how to nicely convert some LaTeX macros to Pollen. I'd rather have minimal inclusion of LaTeX as a 'necessary evil' and the majority of the coding occurring in Pollen/Racket than having two systems to debug. LaTeX allows for macros to have multiple arguments like: ``` \newcommand{\ketbra}[2]{|#1\rangle\langle#2|} ``` While I can do something like: ``` (define (ketbra label1 label2) (format "|~a\\rangle\\langle~a|" label1 label2) ) ``` It looks ugly in text since you have to use strings: ``` ◊ketbra["\\phi_+" "\\phi_+"] ``` Is it possible to write a pollen function with multiple text parts, something like the following? ``` ◊ketbra{\phi_+}{\phi_+} ```
sorawee commented 3 years ago (Migrated from github.com)

It's not possible with Scribble's reader (which is what Pollen is based on), but you can kinda simulate it by doing something like:

◊ketbra[◊text{\phi_+}
        ◊text{\phi_+}]
It's not possible with Scribble's reader (which is what Pollen is based on), but you can kinda simulate it by doing something like: ``` ◊ketbra[◊text{\phi_+} ◊text{\phi_+}] ```
aalexei commented 3 years ago (Migrated from github.com)

I guess it's also possible to add extra control characters:

(define (ketbra text) (apply format "|~a\\rangle\\langle ~a|" (string-split text "│")) )

so that the following works (where "│" is a unicode character unlikely to appear in tex)

◊ketbra{\phi_+│\phi_+}

This form would be easily extendable to any number of arguments including a variable length lists, for things like tables and matrices.

I guess it's also possible to add extra control characters: ``` (define (ketbra text) (apply format "|~a\\rangle\\langle ~a|" (string-split text "│")) ) ``` so that the following works (where "│" is a unicode character unlikely to appear in tex) ``` ◊ketbra{\phi_+│\phi_+} ``` This form would be easily extendable to any number of arguments including a variable length lists, for things like tables and matrices.
aalexei commented 3 years ago (Migrated from github.com)

Ok, need something more sophisticated if the arguments can have nested expressions

Ok, need something more sophisticated if the arguments can have nested expressions
mbutterick commented 3 years ago (Migrated from github.com)

Though you can only have one pair of curly braces in each expression, you can nest subexpressions (each with their own curly braces) as deep as you want, e.g. —

◊ketbra{◊label1{\phi_+} ◊label2{\phi_+}}
Though you can only have one pair of curly braces in each expression, you can nest subexpressions (each with their own curly braces) as deep as you want, e.g. — ``` ◊ketbra{◊label1{\phi_+} ◊label2{\phi_+}} ```
aalexei commented 3 years ago (Migrated from github.com)

Thanks for the responses! Here's something closer to what I had in mind:

First a method to split lists at a marker (from https://codereview.stackexchange.com/a/87626)

(define (split-by lst x)
  (foldr (lambda (element next)
           (if (eqv? element x)
               (cons '() next)
               (cons (cons element (car next)) (cdr next))))
         (list '()) lst))

Use a pollen variable set to a symbol so it gets tokenized as a separate element and we don't have to search within strings and possibly have to break them apart.

(define s 'separator)
(define (ketbra . text)
  (let* ([bits (split-by text 'separator)]
         [arg1 (list-ref bits 0)]
         [arg2 (list-ref bits 1)])
    `(@ "|" ,@arg1 "\\rangle\\langle" ,@arg2 "|")))

So it's possible to write

◊ketbra{\psi^+◊s \psi^+}

which is about as terse as the macro in latex and it will parse arbitrary text expression for each argument. Easy to extend too, even for variable-length 'arguments' like for a table where the cells can contain any text or pollen commands:

(define c 'separator-col)
(define r 'separator-row)
(define (table-plain . text)
    (txexpr 'table '((class "table-plain"))
      (map (lambda (row)
        (txexpr 'tr '() (map (lambda (col) (txexpr 'td '() col))
          (split-by row 'separator-col))))
              (split-by text 'separator-row))))

e.g.

◊table-plain{
A ◊c ◊em{B} ◊r
◊b{C} ◊c ◊em{◊b{D}}}
Thanks for the responses! Here's something closer to what I had in mind: First a method to split lists at a marker (from https://codereview.stackexchange.com/a/87626) ``` (define (split-by lst x) (foldr (lambda (element next) (if (eqv? element x) (cons '() next) (cons (cons element (car next)) (cdr next)))) (list '()) lst)) ``` Use a pollen variable set to a symbol so it gets tokenized as a separate element and we don't have to search within strings and possibly have to break them apart. ``` (define s 'separator) (define (ketbra . text) (let* ([bits (split-by text 'separator)] [arg1 (list-ref bits 0)] [arg2 (list-ref bits 1)]) `(@ "|" ,@arg1 "\\rangle\\langle" ,@arg2 "|"))) ``` So it's possible to write ``` ◊ketbra{\psi^+◊s \psi^+} ``` which is about as terse as the macro in latex and it will parse arbitrary text expression for each argument. Easy to extend too, even for variable-length 'arguments' like for a table where the cells can contain any text or pollen commands: ``` (define c 'separator-col) (define r 'separator-row) (define (table-plain . text) (txexpr 'table '((class "table-plain")) (map (lambda (row) (txexpr 'tr '() (map (lambda (col) (txexpr 'td '() col)) (split-by row 'separator-col)))) (split-by text 'separator-row)))) ``` e.g. ``` ◊table-plain{ A ◊c ◊em{B} ◊r ◊b{C} ◊c ◊em{◊b{D}}} ```
This repo is archived. You cannot comment on issues.
No Milestone
No project
No Assignees
1 Participants
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-users#116
Loading…
There is no content yet.