(require 'cl-lib)
(require 'f)
(defconst *tempfile-dir* "/dev/shm")
(defun tex-paragraph-preview ()
(interactive)
(let* ((tex-paragraph (save-excursion
(mark-paragraph)
(buffer-substring (point) (mark))))
(tex-document (tex-equation-context
tex-paragraph))
(png-file (tex-compile-to-image
tex-document)))
(when png-file
(tex-insert-image/normalize-paragraph png-file))))
(defvar-keymap tex-notes-mode-map
"C-c C-l" #'tex-paragraph-preview)
(defun tex-equation-context (tex-paragraph)
(concat
"\\documentclass[fleqn]{article}
\\thispagestyle{empty}
\\usepackage[margin=3pt,a6paper]{geometry}
\\usepackage{amsmath}
\\begin{document}
\\begin{equation*}"
tex-paragraph
"\\end{equation*}
\\end{document}"))
(defun tex-compile-to-image (tex-input)
(with-current-buffer (get-buffer-create "*tex-errors*")
(cl-loop
with default-directory = *tempfile-dir*
with run-id = (symbol-name (gensym "tex"))
with tex-file = (format "%s/%s.tex" *tempfile-dir* run-id)
with dvi-file = (format "%s/%s.dvi" *tempfile-dir* run-id)
with png-file = (format "%s/%s.png" *tempfile-dir* run-id)
initially do (f-write tex-input 'utf-8 tex-file)
for (program . args)
in `(("latex" ,tex-file)
("dvipng" "-D" "400" ,dvi-file "-o" ,png-file)
("magick" ,png-file "-bordercolor" "white"
"-border" "30" ,png-file)
("magick" ,png-file "-transparent" "white" ,png-file))
when (/= 0 (apply #'call-process program nil t nil args))
do (progn (switch-to-buffer "*tex-errors*")
(cl-return nil))
finally (cl-return png-file))))
(defun tex-insert-image/normalize-paragraph (png-file)
(save-excursion
(beginning-of-line) (end-of-paragraph-text)
(unless (looking-at "\n") (insert "\n"))
(save-excursion
(let ((limit (save-excursion
(end-of-paragraph-text) (point))))
(save-excursion
(when (re-search-forward "%magic-string%" limit t)
(delete-region (match-beginning 0) (match-end 0))
(cl-loop repeat 4 while (looking-at "\n")
do (kill-region (point) (1+ (point))))
(newline 1)))
(forward-paragraph)
(insert-image (create-image png-file 'png nil :scale 0.75)
"%magic-string%")
(newline 1)))))
(define-derived-mode tex-notes-mode latex-mode
"TeX notes"
""
(progn (setq buffer-offer-save t)))
(provide 'tex-notes-mode)