diff --git a/dollar.rkt b/dollar.rkt index 607113f3b..c8458223a 100644 --- a/dollar.rkt +++ b/dollar.rkt @@ -9,7 +9,11 @@ setup/collects "katex-convert-unicode.rkt" "mathjax-convert-unicode.rkt" - racket/list) + racket/list + (only-in xml cdata) + (only-in racket/match match) + (only-in racket/system process) + (only-in racket/port port->string)) (provide $ $$ @@ -19,8 +23,12 @@ $$-katex $-mathjax $$-mathjax + $-tex2svg + $$-tex2svg use-katex use-mathjax + use-tex2svg + current-tex2svg-path with-html5) ;; KaTeX does not work well with the HTML 4.01 Transitional loose DTD, @@ -293,6 +301,41 @@ EOTEX (elem #:style math-inline-style-katex (map (λ (s) (katex-convert-unicode s #t)) (flatten strs)))) +(define current-tex2svg-path (make-parameter #f)) + +(define (find-tex2svg) + (define paths + (list + "./node_modules/.bin/" + "/usr/local/lib/node_modules/mathjax-node-cli/bin/" + "/usr/lib/node_modules/mathjax-node-cli/bin/" + "/usr/local/bin/" + "/usr/local/sbin/" + "/usr/bin/" + "/usr/sbin/")) + (for/or ([path paths]) + (file-exists? (format "~a/tex2svg" path)))) + +(define tex2svg + (let ([tex2svg-path (find-tex2svg)]) + (lambda (#:inline [inline #f] strs) + (if (or (current-tex2svg-path) tex2svg-path) + (match (process (format + "tex2svg ~a'~a'" + (if inline "--inline " "") + (apply string-append strs))) + [`(,stdout . ,_) + (port->string stdout)]) + (error 'tex2svg "Cannot find tex2svg in path or common places; set path manually with current-tex2svg-path."))))) + + +(define ($-tex2svg strs) + (elem #:style (style #f + (list + (xexpr-property + (cdata #f #f (tex2svg #:inline #t (flatten strs))) + (cdata #f #f "")))))) + (define ($$-mathjax strs) (elem #:style math-display-style-mathjax strs)) @@ -300,6 +343,13 @@ EOTEX (elem #:style math-display-style-katex (map (λ (s) (katex-convert-unicode s #t)) (flatten strs)))) +(define ($$-tex2svg strs) + (elem #:style (style #f + (list + (xexpr-property + (cdata #f #f (tex2svg (flatten strs))) + (cdata #f #f "")))))) + (define $-html-handler (make-parameter $-katex)) (define $$-html-handler (make-parameter $$-katex)) @@ -313,6 +363,11 @@ EOTEX ($$-html-handler $$-mathjax) (void)) +(define (use-tex2svg) + ($-html-handler $-tex2svg) + ($$-html-handler $$-tex2svg) + (void)) + (define ($ . strs) (let ([$- ($-html-handler)]) (cond-element diff --git a/info.rkt b/info.rkt index 9fa461e60..3be25c5cd 100644 --- a/info.rkt +++ b/info.rkt @@ -11,6 +11,6 @@ (define test-omit-paths '("MathJax" "katex")) (define scribblings '(("scribblings/scribble-math.scrbl" ()))) (define pkg-desc "Typesetting math and Asymptote figures in Scribble documents") -(define version "0.9") +(define version "0.10") (define pkg-authors '(|Georges Dupéron| |Jens Axel Søgaard|)) diff --git a/scribblings/scribble-math.scrbl b/scribblings/scribble-math.scrbl index 94738d1b2..ce0807bef 100644 --- a/scribblings/scribble-math.scrbl +++ b/scribblings/scribble-math.scrbl @@ -164,6 +164,24 @@ details see the documentation of @racket[with-html5]. that when the page is loaded into a browser, MathJax can recognise it and render it in @tech{display mode}.} +@defproc[($-tex2svg [math (listof? string?)]) element?]{ + Produces an @racket[element?] renders an HTML SVG literal. + It is rendered in @tech{inline mode} math using @tt{tex2svg}. + More precisely, the resulting element uses the @racket[xexpr-property] to + render the SVG directly to the HTML document. + This means no new scripts or stylesheets are added to the document. + It also has no style, so its style cannot be customized. + } + +@defproc[($$-tex2svg [math (listof? string?)]) element?]{ +Produces an @racket[element?] renders an HTML SVG literal. +It is rendered in @tech{display mode} math using @tt{tex2svg}. +More precisely, the resulting element uses the @racket[xexpr-property] to +render the SVG directly to the HTML document. +This means no new scripts or stylesheets are added to the document. +It also has no style, so its style cannot be customized. +} + @defproc[(use-katex) void?]{ This shorthand calls @racket[($-html-handler $-katex)] and @racket[($$-html-handler $$-katex)]. The mathematical @@ -194,6 +212,35 @@ details see the documentation of @racket[with-html5]. page if the user changes the default before typesetting any math.} +@defproc[(use-tex2svg) void?]{ + This shorthand calls @racket[($-html-handler $-tex2svg)] and + @racket[($$-html-handler $$-tex2svg)]. The mathematical forumulas passed to + @racket[$] and @racket[$$] which appear later in the document will therefore be + typeset using @tt{tex2svg}. + + No new CSS or JavaScript libraries will be added to the document. Instead, the + generated HTML document have the math embedded directly an @tt{svg}. + + This requires that @tt{tex2svg} is installed on the system. You can install it + globally via @tt{sudo npm install --global mathjax-node-cli} or locally with + @tt{npm install mathjax-node-cli}. The backend will attempt to find the + @tt{tex2svg}, preferring local sources. You can set the path manually with + the parameter @racket[current-tex2svg-path]. + + @tt{tex2svg} will only be used when rendering an HTML document, and only if it + uses @racket[$] or @racket[$$] to render math. It is therefore safe to call + this function in libraries to change the default handler. +} + +@defparam[current-tex2svg-path path path? #:value #f]{ +A parameter whose value is the path to the @tt{tex2svg} binary. +This binary is used to transform math code into HTML when using the @tt{tex2svg} +backend. +The functions @racket[$] and @racket[$$] use this parameter only when rendering +the document as HTML. +} + + @;@$${\sum_{i=0}ⁿ xᵢ³} When using MathJax, @racket[$] and @racket[$$] wrap their @@ -204,6 +251,10 @@ process elements with this class, so it is safe to use @tt{$} signs in the source document. For example, the text $\sum x^3$ is typeset as-is, like the rest of the text. +When using @tt{tex2svg}, no additional JavaScript processing is done on the +page, so it is safe to use @tt{$} signs in the source document. For example, the +text $\sum x^3$ is typeset as-is, like the rest of the text. + @section{Drawing figures with Asymptote} @defmodule[scribble-math/asymptote]