bkyk8rc3zvpnsf5inmcqq4n3k98cv6hj-my-site-hyper-literate-git.test.suzanne.soy-0.0.1

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

run-pdflatex.rkt (4193B)


      1 #lang scheme/base
      2 
      3 (require scheme/system scheme/port)
      4 
      5 (provide run-pdflatex run-dvipdf-latex run-xelatex)
      6 
      7 (define (run-pdflatex file [notify void]) (run file notify 'pdflatex))
      8 (define (run-dvipdf-latex file [notify void]) 
      9   (parameterize ([function-name 'run-dvipdf-latex])
     10     (run file notify 'dvipdf)))
     11 (define (run-xelatex file [notify void])
     12   (parameterize ([function-name 'run-xelatex])
     13     (run file notify 'xelatex)))
     14 
     15 (define max-runs 5)
     16 (define (run file notify type)
     17   (define latex-cmd-name (cond [(equal? type 'pdflatex) "pdflatex"]
     18                                [(equal? type 'dvipdf) "latex"]
     19                                [(equal? type 'xelatex) "xelatex"]
     20                                [else (err "unknown run type ~a" type)]))
     21   (define cmd
     22     (list (get-latex-binary latex-cmd-name)
     23           "-interaction=batchmode"
     24           (format "~a" file)))
     25   (define logfile (path-replace-suffix file #".log"))
     26   (define (run)
     27     (unless (parameterize ([current-output-port (open-output-nowhere)])
     28               (apply system* cmd))
     29       (unless (file-exists? logfile)
     30         (err "did not generate a log file at ~a" logfile))
     31       (call-with-input-file* logfile
     32         (lambda (log) (copy-port log (current-error-port))))
     33       (err "got error exit code")))
     34   (let loop ([n 0])
     35     (when (= n max-runs)
     36       (err "didn't get a stable result after ~a runs" n))
     37     (if (zero? n)
     38       (notify "running ~a on ~a" latex-cmd-name file)
     39       (notify " running ~a~a time"
     40               (add1 n) 
     41               (case (normalize-for-suffix (add1 n)) [(2) 'nd] [(3) 'rd] [else 'th])))
     42     (run)
     43     ;; see if we get a "Rerun" note, these seem to come in two flavors
     44     ;; * Label(s) may have changed. Rerun to get cross-references right.
     45     ;; * Package longtable Warning: Table widths have changed. Rerun LaTeX.
     46     (cond [(call-with-input-file* logfile
     47              (lambda (log) (regexp-match? #px#"changed\\.\\s+Rerun" log)))
     48            (loop (add1 n))]
     49           [(zero? n)
     50            (notify "WARNING: no \"Rerun\" found in first run of pdflatex for ~a"
     51                    file)]))
     52   (when (equal? type 'dvipdf)
     53     (define dvi-file (path-replace-suffix file #".dvi"))
     54     (define ps-file (path-replace-suffix file #".ps"))
     55     (unless (file-exists? dvi-file) (err "didn't find .dvi file"))
     56     (define dvips (get-latex-binary "dvips"))
     57     (define pstopdf (get-latex-binary "pstopdf"))
     58     (notify "running dvips on ~a" dvi-file)
     59     (define stderr (open-output-bytes))
     60     (unless (parameterize ([current-output-port (open-output-nowhere)]
     61                            [current-error-port stderr])
     62               (system* dvips dvi-file))
     63       (displayln (get-output-bytes stderr))
     64       (err "got error exit code"))
     65     (unless (parameterize ([current-output-port (open-output-nowhere)]
     66                            [current-error-port stderr])
     67               (system* pstopdf ps-file))
     68       (displayln (get-output-bytes stderr))
     69       (err "got error exit code")))
     70   (path-replace-suffix file #".pdf"))
     71 
     72 (define (normalize-for-suffix n)
     73   (cond
     74     [(<= 10 n 20) 0]
     75     [else (modulo n 10)]))
     76 
     77 (define (get-latex-binary name)
     78   (define ans
     79     (case (system-type)
     80       [(macosx) (or (find-executable-path name)
     81                     (for/or ([macosx-candidate-dir (in-list macosx-candidate-dirs)])
     82                       (define macosx-candidate (build-path macosx-candidate-dir name))
     83                       (and (file-exists? macosx-candidate)
     84                            macosx-candidate)))]
     85       [(windows) (or (find-executable-path name)
     86                      (find-executable-path (format "~a.exe" name)))]
     87       [(unix) (find-executable-path name)]))
     88   (unless ans
     89     (err (format "could not find a `~a' executable" name)))
     90   ans)
     91 
     92 (define function-name (make-parameter 'run-pdflatex))
     93 (define (err fmt . args) (apply error (function-name) fmt args))
     94 
     95 ;; under mac os x, gui apps do not get started with
     96 ;; a good path environment, so put likely candidates
     97 ;; for directories holding latex/pdflatex binaries
     98 ;; here so that the "scribble pdf" button is more 
     99 ;; likely to work in drracket
    100 (define macosx-candidate-dirs
    101   '("/usr/texbin" "/Library/TeX/texbin"))