capybara/ext-mathml/main.rkt

56 lines
1.7 KiB
Racket

#lang racket/base
(require racket/list racket/match racket/port racket/runtime-path racket/string
xml)
(define-runtime-path *js-path* "./mathml-render.js")
(provide transform-xexprs get-styles)
(define (mathtex-type? s)
(and (string? s) (regexp-match #rx"^math/tex" s) #t))
(define (transform-xexprs xexprs)
(map transform-xexpr xexprs))
(define (run-mathjax source block?)
(define-values [proc out in err]
(subprocess #f #f #f "/usr/bin/env" "node" (path->string *js-path*)))
(define out-str #f)
(define err-str "")
(define out-reader (thread (λ () (set! out-str (port->string out)))))
(define err-reader (thread (λ () (set! err-str (port->string err)))))
(write-string source in)
(flush-output in)
(close-output-port in)
(subprocess-wait proc)
(thread-wait out-reader)
(thread-wait err-reader)
(define err-trimmed (string-trim err-str))
(unless (string=? "" err-trimmed)
(error "mathjax process raised error!" err-trimmed))
(unless out-str
(error "mathjax process didn't return anything!"))
(match-define (list 'math attrs bodies ...) (string->xexpr out-str))
`(math ,(cons (list 'display (if block? "block" "inline"))
(filter (λ (x) (not (eq? (first x) 'display))) attrs))
,@bodies))
(define (transform-xexpr xexpr)
(match xexpr
[(list 'script (list (list 'type (? mathtex-type? type)))
bodies ...)
(define body (apply string-append bodies))
(define block? (> (length (string-split type " ")) 1))
(run-mathjax body block?)]
[(list tag attrs body ...)
(cons tag (cons attrs (map transform-xexpr body)))]
[(? string? str) str]))
(define (get-styles) "")