From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?B?SmFuIELDtmNrZXI=?= Subject: Re: [WISH] Latex WYSIWYG Date: Fri, 24 Jun 2011 16:14:42 +0200 Message-ID: <4E049BD2.10309@jboecker.de> References: <10933380.173491308615732676.JavaMail.tomcat@tomcat2> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070205000608000705020602" Return-path: Received: from eggs.gnu.org ([140.186.70.92]:39589) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qa79o-0000gS-W3 for emacs-orgmode@gnu.org; Fri, 24 Jun 2011 10:14:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qa79l-0007O7-CY for emacs-orgmode@gnu.org; Fri, 24 Jun 2011 10:14:52 -0400 Received: from smtp01.worldserver.net ([217.13.200.36]:36236) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qa79k-0007N3-Gp for emacs-orgmode@gnu.org; Fri, 24 Jun 2011 10:14:49 -0400 In-Reply-To: <10933380.173491308615732676.JavaMail.tomcat@tomcat2> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Sebastian Berchtold Cc: emacs-orgmode@gnu.org This is a multi-part message in MIME format. --------------070205000608000705020602 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 06/21/2011 02:22 AM, Sebastian Berchtold wrote: > Hi, my first post here: So big shout outs to all org-mode hackers. > Great Stuff! > > There is one feature I'd really like to have, but i couldn't find > anything that does what i want. I guess it's just a small hack, but > with my retarded elisp skills it would take me days to implement it. > > WYSIWYG Latex is probably not the correct term for this. What i have > in mind is more like seeing the formula, while editing the > ASCII/Unicode representation. I'll try to explain the idea more > detailed. Hi Sebastian, I have attached a quick and dirty hack I wrote in December 2010. It works by updating an image file whenever the formula at point in your Org buffer changes. If that image file is currently open in an image buffer, that buffer is automatically refreshed. If LaTeX reports an error, the image will not be updated, so you have to check if the image updates when you expect it to to avoid syntax errors. See the comments at the top of the file for usage instructions. Unfortunately, due to lack of time and knowledge of org-mode and elisp, this thing likely still has a lot of bugs and is not implemented properly (I guess it should be a minor mode). However, it seems to work in simple cases. Hope this helps, Jan --------------070205000608000705020602 Content-Type: text/x-emacs-lisp; name="latex-live-preview.el" Content-Disposition: attachment; filename="latex-live-preview.el" Content-Transfer-Encoding: quoted-printable ;; latex-live-preview.el by Jan B=C3=B6cker ;; Feel free to improve this. ;; License: Pick one of GNU GPL v3, BSD, MIT ;; This is a quick and dirty hack to show an automatically updated previe= w image ;; of the LaTeX formula at point in an org-mode buffer. ;; Usage: ;; * Eval the elisp code in this file in some way (e.g. M-x load-file or = M-x eval-buffer) ;; * In your org buffer: M-x jb/toggle-latex-live-preview ;; * Split the window (e.g. C-x 2) ;; * open the exported image file (default: /tmp/livepreview.png) in ;; the second buffer ;; * edit your Org file ;; To speed things up slightly, you might want to move the tempdir to a r= amdisk. ;; the tempdir will contain the exported image and might be cluttered ;; with temporary files from running LaTeX if something goes wrong (defconst jb/latex-live-preview-tempdir "/tmp/") ; must include final / (defconst jb/latex-live-preview-filename "livepreview.png") (defvar jb/current-texfilebase "") (defvar jb/current-tmpdir nil) (defvar jb/current-tofile "") (defvar jb/latex-preview-job nil) (defvar jb/enable-live-preview nil) (defun jb/ocfi (string tofile options buffer) "Modified version of org-create-formula-image" (require 'org-latex) (let* ((tmpdir (if (featurep 'xemacs) (temp-directory) temporary-file-directory)) (texfilebase (make-temp-name (expand-file-name "orgtex" tmpdir))) (texfile (concat texfilebase ".tex")) (dvifile (concat texfilebase ".dvi")) (pngfile (concat texfilebase ".png")) (fnh (if (featurep 'xemacs) (font-height (get-face-font 'default)) (face-attribute 'default :height nil))) (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0)) (dpi (number-to-string (* scale (floor (* 0.9 (if buffer fnh 140.)))))) (fg (or (plist-get options (if buffer :foreground :html-foreground)) "Black")) (bg (or (plist-get options (if buffer :background :html-background)) "Transparent"))) (if (eq fg 'default) (setq fg (org-dvipng-color :foreground))) (if (eq bg 'default) (setq bg (org-dvipng-color :background))) (with-temp-file texfile (insert (org-splice-latex-header org-format-latex-header org-export-latex-default-packages-alist org-export-latex-packages-alist t org-format-latex-header-extra)) (insert "\n\\begin{document}\n" string "\n\\end{document}\n") (require 'org-latex) (org-export-latex-fix-inputenc)) (setq jb/current-texfilebase texfilebase) (setq jb/current-tmpdir tmpdir) (setq jb/current-tofile tofile) (jb/call-latex) )) (defun jb/call-latex () (cd tmpdir) (set-process-sentinel (start-process "live-latex-preview-latex" ; process name nil ; no buffer "latex" "--halt-on-error" (concat jb/current-texfilebase ".tex")) 'jb/call-latex-sentinel) ;(message "latex-live-preview: started latex") ) (defun jb/call-latex-sentinel (process event) ;(message "latex-sentinel: %s" event) (when (string=3D event "finished\n") (jb/call-dvipng)) (when (string=3D event "exited abnormally with code 1\n") (setq jb/current-tmpdir nil) (jb/update-latex-preview))) (defun jb/call-dvipng () (let* ((tmpdir jb/current-tmpdir) (buffer nil) (options org-format-latex-options) (texfilebase jb/current-texfilebase) (texfile (concat texfilebase ".tex")) (dvifile (concat texfilebase ".dvi")) (pngfile (concat texfilebase ".png")) (fnh (if (featurep 'xemacs) (font-height (get-face-font 'default)) (face-attribute 'default :height nil))) (scale (or (plist-get options (if buffer :scale :html-scale)) 1.0)) (dpi (number-to-string (* scale (floor (* 0.9 (if buffer fnh 140.)))))= ) (fg (or (plist-get options (if buffer :foreground :html-foreground)) "Black")) (bg (or (plist-get options (if buffer :background :html-background)) "Transparent"))) (if (eq fg 'default) (setq fg (org-dvipng-color :foreground))) (if (eq bg 'default) (setq bg (org-dvipng-color :background))) (cd tmpdir) (set-process-sentinel (start-process "live-latex-preview-dvipng" nil "dvipng" "-fg" fg "-bg" bg "-D" dpi ;;"-x" scale "-y" scale "-T" "tight" "-o" pngfile dvifile) 'jb/call-dvipng-sentinel) )) (defun jb/call-dvipng-sentinel (process event) (when (string=3D event "finished\n") (copy-file (concat jb/current-texfilebase ".png") jb/current-tofile 'rep= lace) (loop for e in '(".dvi" ".tex" ".aux" ".log" ".png") do (delete-file (concat jb/current-texfilebase e))) =09 (when (get-buffer jb/latex-live-preview-filename) (set-buffer jb/latex-live-preview-filename)=09 (jb/refresh-current-image-buffer)) =09 (setq jb/current-tmpdir nil) (jb/update-latex-preview) )) (defun jb/refresh-current-image-buffer () (flet ((message (msg &rest args) nil)) (clear-image-cache) (revert-buffer nil t t) (image-mode) )) (defun jb/update-latex-preview () (when (and jb/latex-preview-job (not jb/current-tmpdir)) (jb/preview-fragment jb/latex-preview-job) (setq jb/latex-preview-job nil))) =09 (defun jb/preview-fragment (latex) (save-excursion (let ((temporary-file-directory jb/latex-live-preview-tempdir)) (jb/ocfi latex (concat jb/latex-live-preview-tempdir jb/latex-live-pre= view-filename) org-format-latex-options nil)) )) (defun jb/plfp () "Preview the latex fragment at point" (interactive) (catch 'exit (save-excursion (save-restriction (let ((at (org-inside-LaTeX-fragment-p)) beg end msg start-delimiter end-delimiter (add-end-delimiter nil)) (if (not at) (progn (setq jb/latex-preview-job "$ $") (jb/update-latex-preview)) (progn (goto-char (cdr at)) (setq beg (point)) (setq start-delimiter (car at)) ;; (message "start-delimiter is %s " start-delimiter) ;; Determine what the end of this block must look like (setq end-delimiter (cdr (assoc start-delimiter '(("$$" . "$$"), ("\\[" . "\\]"), ("\\(" . "\\)"))))) =20 ;; Set end-delimiter to \end{region} if block starts ;; with \begin{region} (when (not end-delimiter) (save-match-data (if (not (string-match "\\\\begin{\\([^}]*\\)}" start-delimiter)) (throw 'exit nil)) (setq end-delimiter (concat "\\end{" (match-string 1 start-delimite= r) "}")))) ;; (message "end-delimiter is %s " end-delimiter) =20 ;; set end of our region (goto-char (1+ beg)) (setq end (re-search-forward (regexp-quote end-delimiter) nil t)) =20 ;; If there is no end delimiter, make a note that we ;; need to add it later before creating the image. ;; This will make the preview work on unfinished LaTeX blocks. (when (not end)=20 (setq end (point-max)) (setq add-end-delimiter t)) (narrow-to-region beg end) ;; (message "-%s-" (buffer-string)) (goto-char beg) =20 (setq jb/latex-preview-job (concat (buffer-string) (if add-end-delim= iter end-delimiter "") )) (jb/update-latex-preview)))))))) (defun pseudo-message (format-string &rest args) nil) (defun jb/ach (a b c) "hook for after-change-functions" (when jb/enable-live-preview (let ((message (lambda (s &rest args) nil))) (jb/plfp) (setq deactivate-mark nil)))) (defun jb/pch () "hook for post-command-hook" (when jb/enable-live-preview (let ((message (lambda (s &rest args) nil))) (jb/plfp) (setq deactivate-mark nil)))) (defun jb/toggle-latex-live-preview () "toggles the buffer-local variable jb/enable-live-preview" (interactive) (setq jb/current-tmpdir nil) (make-variable-buffer-local 'jb/enable-live-preview) (setq jb/enable-live-preview (not jb/enable-live-preview))) (defun jb/clear-current-tmpdir () (interactive) (setq jb/current-tmpdir nil)) (remove-hook 'after-change-functions 'jb/ach) (remove-hook 'post-command-hook 'jb/pch) (add-hook 'post-command-hook 'jb/pch) (add-hook 'after-change-functions 'jb/ach) --------------070205000608000705020602--