[plt-scheme] Using texpict or mrpict

From: Paulo J. Matos (pocm at soton.ac.uk)
Date: Tue Nov 7 17:39:53 EST 2006

Hope you like this one...

I've decided, instead of adding a layer to tex2im into planet, to hack
tex2im into PLT-Scheme. :-) This way, no tex2im is required in your

The code is as follows (I'll try to send it up tommorrow to planet,
after a few more fixes and tests):
(module mrtex2im mzscheme
  ;; Scheme Port of the tex2im utility
  (require (lib "kw.ss")
           (lib "class.ss")
           (lib "process.ss")
           (lib "mred.ss" "mred")
           (lib "file.ss"))

  (current-directory (find-system-path 'temp-dir))

  (define setup-latex-path (make-parameter (build-path "/usr/bin/latex")))
  (define setup-dvips-path (make-parameter (build-path "/usr/bin/dvips")))
  (define setup-convert-path (make-parameter (build-path "/usr/bin/convert")))

  (define (get-string-from-port fileport)
    ;; returns a string with the file contents
    (let loop ((str "") (line (read-line fileport)))
      (if (eof-object? line)
          (loop (string-append str "\n" line)
                (read-line fileport)))))

  ;; Given a file path with latex code returns a path with the
respective eps file.
  (define (run-latex/dvips file)
    (let ([dvi-file (string-append (path->string file) ".dvi")]
          [eps-file (string-append (path->string file) ".eps")])
      (if (and (zero? (system*/exit-code (setup-latex-path)
"-interaction=batchmode" (path->string file)))
               (zero? (system*/exit-code (setup-dvips-path) "-o"
eps-file "-E" dvi-file)))
              (printf "WARNING: Error generating latex or postscript file.")))))

  (define (run-convert trans? aa? bgcolor res file)
    (let ([png-file (string-append file ".png")])
      (if trans?
          (system*/exit-code (setup-convert-path)
                             (if aa? "-antialias" "+antialias")
                             "-transparent" bgcolor
          (system*/exit-code (setup-convert-path)
                             (if aa? "-antialias" "+antialias")

  (define/kw (tex2im str-or-path ;; Latex string or path to input file
                     [resolution "150x150"]
                     [bgcolor "white"]
                     [fgcolor "black"]
                     [transparency #f]
                     [noformula #f]
                     [anti-aliasing #t]
                     [extra-header (build-path (find-system-path
'home-dir) ".tex2im-header")])
    (let ([tmp-file (make-temporary-file)])
      (with-output-to-file tmp-file
        (lambda ()
          ;; Output header
          (printf "\\documentclass[12pt]{article} \\usepackage{color}
\\usepackage[dvips]{graphicx} \\pagestyle{empty}")
        ;; Output header in file
          (if (file-exists? extra-header)
              (printf (call-with-input-file #:extra-header
                        (lambda (fileport)
                          (get-string-from-port fileport)))))
          (printf "\\pagecolor{~a} \\begin{document} {\\color{~a}"
bgcolor fgcolor)
          (if (not noformula) (printf "\\begin{eqnarray*}"))
          (if (string? str-or-path)
              ;; latex code is in string
              (printf str-or-path)
              ;; latex code is in file
              (printf (call-with-input-file str-or-path
                        (lambda (fileport)
                          (get-string-from-port fileport)))))
          (if (not noformula) (printf "\\end{eqnarray*}"))
          (printf "}\\end{document}"))
      (make-object bitmap%
           (run-convert transparency anti-aliasing bgcolor resolution
                        (run-latex/dvips tmp-file))

  (provide tex2im))

Try it (if you have convert, latex and dvips on /usr/bin:
> (require (lib "utils.ss" "texpict")) ;; cool way to view this inside drscheme
> (bitmap (tex2im "x^2 +2"))
> (bitmap (tex2im "\\frac{x^2 + x + 3}{2}"
                  #:bgcolor "blue"
                  #:fgcolor "white"))

I always wondered how nice it would be to hack a CAS inside PLTScheme
and use this for expression pretty-printing. :-) I've done something
really simple with impressive visual results.
I'll have to organize the code to planet, write some simple docs (it's
all based in keyword arguments), forward stdout of system*/exit-error
calls to /dev/null in a portable way (any suggestions?) and possibly
use latex instead of slatex. Probably nicer and more portable since
slatex is supported by PLT-Scheme natively.

Suggestions are very welcome.

Paulo Jorge Matos - pocm at soton.ac.uk
PhD Student @ ECS
University of Southampton, UK

Posted on the users mailing list.