Home · Blog · Planet Digital Humanities

David Maus M. A.

Digital Humanities Publishing

Quick'n'dirty: Compile XSL-FO to PDF from Emacs

David Maus, 16.04.2018 · Twitter · Comment · Permalink

Execute Apache FOP from within Emacs and compile current file to PDF (or any other supported output formats).

;;; xslfo-mode.el --- Minor mode for working with XSL-FO files

(defvar xslfo-fop-outspec '(("pdf" . "pdf")
("rtf" . "rtf")
("txt" . "txt")
("at" . "xml")
("if" . "xml")
("png" . "png")
("tiff" . "tiff")
("ps" . "ps")
("pcl" . "pcl")
("pdfa1b" . "pdf"))
"Apache FOP output formats.")

(define-minor-mode xslfo-mode
"Minor mode for working with XSL-FO files."
:init-value nil
:lighter "XSL-FO"
:keymap `((,(kbd "C-c C-c") . xslfo-compile)))

(defmacro xslfo-fop-outspec-extension (name)
`(or (cdr (assoc ,name xslfo-fop-outspec)) "bin"))

(defun xslfo-compile (&optional arg)
(interactive "P")
(let* ((outspec (if arg (completing-read "Output format: " (mapcar #'car xslfo-fop-outspec) #'stringp t (caar xslfo-fop-outspec))
"pdf"))
(srcfile (or buffer-file-name (error "Buffer not visiting a file")))
(outfile (concat (expand-file-name (file-name-sans-extension srcfile)) "." (xslfo-fop-outspec-extension outspec)))
(bufname (concat "*XSL-FO: " outfile "*")))
(with-current-buffer (get-buffer-create bufname)
(erase-buffer)
(when (= 0 (apply #'call-process (executable-find "fop") nil t t (list (concat "-" outspec) outfile srcfile)))
(message "Wrote %s" outfile)
(display-buffer bufname)))))

(provide 'xslfo-mode)

;;; xslfo-mode.el ends here