diff --git a/dollar.rkt b/dollar.rkt index 607113f3b..7afd062db 100644 --- a/dollar.rkt +++ b/dollar.rkt @@ -9,7 +9,12 @@ 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) + (for-syntax racket/base)) (provide $ $$ @@ -23,6 +28,20 @@ use-mathjax with-html5) +(define-syntax (if-version≥6.12 stx) + (syntax-case stx () + [(_ . rest) + (if (and (not (regexp-match #px"^6\\.11\\.0\\.900$" (version))) + (or (regexp-match #px"^6(\\.([0123456789]|10|11)(\\..*|)|)$" (version)) + (regexp-match #px"^[123245]\\..*$" (version)))) + #'(begin) + #'(begin . rest))])) + +(if-version≥6.12 + (provide $-tex2svg + $$-tex2svg + use-tex2svg + current-tex2svg-path)) ;; KaTeX does not work well with the HTML 4.01 Transitional loose DTD, ;; so we define a style modifier which replaces the prefix for HTML rendering. (define (with-html5 doc-style) @@ -293,6 +312,42 @@ EOTEX (elem #:style math-inline-style-katex (map (λ (s) (katex-convert-unicode s #t)) (flatten strs)))) +(if-version≥6.12 + (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 +355,14 @@ EOTEX (elem #:style math-display-style-katex (map (λ (s) (katex-convert-unicode s #t)) (flatten strs)))) +(if-version≥6.12 + (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 +376,12 @@ EOTEX ($$-html-handler $$-mathjax) (void)) +(if-version≥6.12 + (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..2dc1e2b43 100644 --- a/scribblings/scribble-math.scrbl +++ b/scribblings/scribble-math.scrbl @@ -164,6 +164,28 @@ 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?] which contains the given + @racket[math] rendered as 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. + + This procedure requires Racket 6.12 or later.} + +@defproc[($$-tex2svg [math (listof? string?)]) element?]{ + Produces an @racket[element?] which contains the given + @racket[math] rendered as 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. + + This procedure requires Racket 6.12 or later.} + @defproc[(use-katex) void?]{ This shorthand calls @racket[($-html-handler $-katex)] and @racket[($$-html-handler $$-katex)]. The mathematical @@ -194,6 +216,38 @@ 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. + + This procedure requires Racket 6.12 or later.} + +@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[$-tex2svg] and @racket[$$-tex2svg] use this parameter only + when rendering the document as HTML. + + This parameter requires Racket 6.12 or later.} + + @;@$${\sum_{i=0}ⁿ xᵢ³} When using MathJax, @racket[$] and @racket[$$] wrap their @@ -204,6 +258,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] @@ -266,4 +324,4 @@ $\sum x^3$ is typeset as-is, like the rest of the text. draw(root, (0,0)); shipout(scale(2)*currentpicture.fit()); } -} \ No newline at end of file +}