From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms1.migadu.com with LMTPS id qHa2Kv5JEmbjgAEAe85BDQ:P1 (envelope-from ) for ; Sun, 07 Apr 2024 09:23:42 +0200 Received: from aspmx1.migadu.com ([2001:41d0:403:58f0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id qHa2Kv5JEmbjgAEAe85BDQ (envelope-from ) for ; Sun, 07 Apr 2024 09:23:42 +0200 X-Envelope-To: larch@yhetil.org Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1712474622; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:list-id:list-help:list-unsubscribe: list-subscribe:list-post; bh=UA/Hak/6VWxpGnEN2CpCng7/rtVJ3qtTo0FnlWpYf4Y=; b=IoY5QLPNlKEfOwyi58ihLRw3NxIsWA0lFGwPIAdENTcFu0epnmbb24AnJiZQLXqMpH8zNq JgangZbCn4Pzuzd6TAOOQdE53UyUjvQIDwihN4bZWcteIsYWNg1aOEW364dGEYwTe22ker KTccnQgrHqlFd0ZQYXSwxWBC+lQIld95wQqqYYLY712HzYAHU2upabfoAnO9DN8QUc5l5Z 9zNc7rFQURod5alJC7quLaRCHSydOhDHnwIPHDmBg8Ab6HdSedOpH6e5tpKEOMcXtDWtnC MMt1+JLR6YtENdBr2AOUkLr+f4k6k04HI34/ycnQI/aorWAfGPOLYESn9tEXpQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" ARC-Seal: i=1; s=key1; d=yhetil.org; t=1712474622; a=rsa-sha256; cv=none; b=YVPyViRSybB9FrJbevSPD6g1a+nDeUNORtfhdeUExki8lFp6EW6NzrnTcsNqHjjDN4xYeB FQ6jSo4xG/+StODQyOZZRrz4SI2tTtqGZ6/4wNkG30yPVx6FlpiM0IhKbM2BoxNy/dV1/9 8AeU46lomw313tXmyyJ9hvyFTfiM067rtiYz8UaIqoHYZTyXvZJDw3bDJdVE3Vs4KdGSPp TRyXTEbiXg2ThDvhyYKifsesyVxf5Cfkk3KA0Q3omj/KDuioJdi9q/TzD/iHST2brIwvkN l/Hrj8Klml6z0y/MT8PQcvbDT32VQ6dI2/UMe3v33kQbC7zIfW2ViwUW/yPPHw== Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 50241F4F3 for ; Sun, 07 Apr 2024 09:23:42 +0200 (CEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rtMrZ-00037q-Sk; Sun, 07 Apr 2024 03:22:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rtMrW-00037X-SL for emacs-orgmode@gnu.org; Sun, 07 Apr 2024 03:22:46 -0400 Received: from www553.your-server.de ([78.46.153.203]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rtMrU-0001d9-SI for emacs-orgmode@gnu.org; Sun, 07 Apr 2024 03:22:46 -0400 Received: from sslproxy02.your-server.de ([78.47.166.47]) by www553.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rtMrN-000OvX-N6; Sun, 07 Apr 2024 09:22:37 +0200 Received: from [2001:9e8:b16:e800:6b38:7775:6c73:7278] (helo=comonad) by sslproxy02.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1rtMrN-00CWxQ-1K; Sun, 07 Apr 2024 09:22:37 +0200 From: Tony Zorman To: emacs-orgmode@gnu.org Cc: karthikchikmagalur@gmail.com Subject: Using org-latex-preview in other major modes User-Agent: Notmuch/0.38.3, Emacs 30.0.50 Date: Sun, 07 Apr 2024 09:22:36 +0200 Message-ID: <87edbhljr7.fsf@hyperspace> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Authenticated-Sender: mail@tony-zorman.com X-Virus-Scanned: Clear (ClamAV 0.103.10/27237/Sat Apr 6 10:24:00 2024) Received-SPF: pass client-ip=78.46.153.203; envelope-from=mail@tony-zorman.com; helo=www553.your-server.de X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_SBL_A=0.1 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Spam-Score: -3.53 X-Migadu-Scanner: mx11.migadu.com X-Spam-Score: -3.53 X-Migadu-Queue-Id: 50241F4F3 X-TUID: winc1wJVJokH --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi, I'm interested in adjusting org-latex-preview to work in other major modes (most notably LaTeX-mode itself, so one can get rid of preview.el). On the advice of Karthik (Cc'd) I'll move the discussion from private mails to this list, so more people who might be interested can join in. I've prodded the code a little bit and, mostly just following [1], managed to implement basic previews in a relatively straightforward fashion. Attached is a proof-of-concept=E2=80=94aptly named latex-latex-preview.el :) The main user facing functions so far are 'latex-latex-preview' to preview the maths fragment at point, and 'latex-latex-preview-region' to preview all fragments in a region. Both functions currently ignore things like numbered equations and environments, though both do not seem exceptionally difficult to add back in. There's also a stub 'latex-latex-preview-auto-mode' minor mode. Stepping in and out of already rendered environments works fine, with the preview being regenerated if needed; only the implementation of 'org-latex-preview-auto--regenerate-overlay' had to change for that. The mode does not currently feature live-previews. The innards of 'org-latex-preview-auto--detect-fragments-in-change' and 'org-latex-preview-live--setup' look a bit more org-specific, with queries to 'org-element-*' functions all over the place, but all of that looks fixable=E2=80=94at least from afar. I will continue prodding the code= a little bit and will report back with any bumps that are hit along the way. Tony [1]: https://abode.karthinks.com/org-latex-preview/latex-preview-everywhere= .html --=-=-= Content-Type: application/emacs-lisp Content-Disposition: inline; filename=latex-latex-preview.el Content-Transfer-Encoding: quoted-printable (require 'org-latex-preview) (require 'dash) (require 'tex) (defun latex-latex-preview--make-preamble () "Slurp the preamble from the `TeX-master-file'. Code stolen from `TeX-region-create'." (save-excursion (save-restriction (set-buffer ; TeX master (find-file-noselect (TeX-master-file TeX-default-extension))) (save-excursion (save-restriction (widen) (goto-char (point-min)) (if (not (re-search-forward TeX-header-end nil t)) "" (re-search-backward TeX-header-end nil t) (string-replace "\\pdfoutput=3D1" ; HACK "" (buffer-substring-no-properties (point-min) (point))))))))) (defun latex-latex-preview--matching-end () "Find the end of the current environment. Like `LaTeX-find-matching-end', but take care of corner cases like being at the very beginning/end of the current environment." (let ((boi (save-excursion (LaTeX-back-to-indentation) (point)))) (cond ((equal (point) boi) (forward-char)) ((pos-eol) (backward-char))) (LaTeX-find-matching-end))) (defun latex-latex-preview--math-bounds () "Bet bounds for maths environment at point, if any. Return a list with (BEG END)." (save-excursion ;; `texmathp' wants us to be *inside* a maths env. (save-match-data (when (looking-at org-latex-preview--tentative-math-re) (goto-char (match-end 0)))) (-if-let* (((mm . beg) (and (texmathp) texmathp-why))) (list beg (and (pcase mm ;; Horrible special casing that should be removed. Als= o, it ;; *is* possible to mix \( with $ etc., but I'm not su= re I ;; even want to allow that. ("$" (search-forward "$" nil t)) ("$$" (search-forward "$$" nil t)) ("\\[" (search-forward "\\]" nil t)) ("\\(" (search-forward "\\)" nil t)) (_ (latex-latex-preview--matching-end))) (point)))))) (defun latex-latex-preview-collect-fragments (&optional beg end) "Collect LaTeX maths fragments between BEG and END. Lots stolen from `org-latex-preview-collect-fragments'." ;; TODO: This does not collect environments at this point, only maths ;; fragments. (let (fragments) (save-excursion (goto-char (or beg (point-min))) (while (re-search-forward org-latex-preview--tentative-math-re end t) (when-let ((bounds (latex-latex-preview--math-bounds)) ;; Avoid duplicating nested latex environments. (_ (not (and fragments (=3D (car bounds) (caar fragments= )))))) (push bounds fragments)))) (nreverse fragments))) (defun latex-latex-preview-place (entries &optional preamble) "Preview LaTeX maths fragments ENTRIES. See `org-latex-preview-place'." (org-latex-preview-place org-latex-preview-process-default entries nil (or preamble (latex-latex-preview--make-preamble)))) ;;;###autoload (defun latex-latex-preview-region (beg end) "Preview all LaTeX fragments in the active region." (interactive "r") (latex-latex-preview-place (latex-latex-preview-collect-fragments beg end) (latex-latex-preview--make-preamble))) ;;;###autoload (defun latex-latex-preview () "Preview LaTeX fragment at point." (interactive) (latex-latex-preview-place (list (latex-latex-preview--math-bounds)) (latex-latex-preview--make-preamble))) (defun latex-latex-preview-clear-cache (beg end) "A primitive version of `org-latex-preview-clear-cache'. TODO: clear-entire-cache." (interactive (cond ((use-region-p) (list (region-beginning) (region-end))) ((latex-latex-preview--math-bounds)) (t (error "latex-latex-preview-clear-cache needs something to clea= r")))) (org-latex-preview-clear-overlays beg end) (let ((imagetype (or (plist-get (alist-get org-latex-preview-process-default org-latex-preview-process-alist) :image-output-type) "png")) ;; TODO: numbered previews ) ;; TODO: This does not quite work yet. (pcase-dolist (`(,begin ,end) (latex-latex-preview-collect-fragments be= g end)) (pcase-let* ((`(,fg ,bg) (org-latex-preview--colors-around begin end)) (value (buffer-substring begin end))) (org-latex-preview--remove-cached (org-latex-preview--hash org-latex-preview-process-default org-latex-preview--preamble-content value imagetype fg bg nil)))) (message "Cleared LaTeX preview cache for %s." (if (or beg end) "region" "buffer")))) ;;; Auto previewing. (defun latex-latex-preview-auto--regenerate-overlay (ov &optional inhibit-r= enumbering) "Regenerate the LaTeX fragment under overlay OV. See `org-latex-preview-auto--regenerate-overlay'. TODO: equation numbering" (with-current-buffer (overlay-buffer ov) (if-let* ((start (overlay-start ov)) (end (overlay-end ov)) (fragment (save-excursion (goto-char start) (latex-latex-preview--math-bounds)))) (if (org-latex-preview--empty-fragment-p ; no org-specific code (buffer-substring-no-properties start end)) (progn (delete-overlay ov) (org-latex-preview--ensure-overlay start end)) ; no org-= specific code (latex-latex-preview-place (list fragment))) ;; Delete overlay of fragment is no longer in maths mode. (delete-overlay ov)))) ;;;###autoload (define-minor-mode latex-latex-preview-auto-mode "See `org-latex-preview-auto-mode'." :global nil (if latex-latex-preview-auto-mode (progn (setq org-latex-preview-auto--marker (make-marker)) ;; This allows us to reuse the code from ;; `org-latex-preview-auto--close-previous-overlay' without having = to ;; copy the whole function. (advice-add 'org-latex-preview-auto--regenerate-overlay :override #'latex-latex-preview-auto--regenerate-overlay) (add-hook 'pre-command-hook #'org-latex-preview-auto--handle-pre-cu= rsor nil 'local) (org-latex-preview-auto--handle-pre-cursor) ; Invoke setup before t= he hook even fires. (add-hook 'post-command-hook #'org-latex-preview-auto--handle-post-= cursor nil 'local) ;; TODO: Live preview ;; (add-hook 'after-change-functions #'org-latex-preview-auto--dete= ct-fragments-in-change nil 'local) ;; (when org-latex-preview-live ;; (org-latex-preview-live--setup)) ) (advice-remove 'org-latex-preview-auto--regenerate-overlay 'latex-latex-preview-auto--regenerate-overlay) (remove-hook 'pre-command-hook #'org-latex-preview-auto--handle-pre-cur= sor 'local) (remove-hook 'post-command-hook #'org-latex-preview-auto--handle-post-c= ursor 'local) ;; (remove-hook 'after-change-functions #'org-latex-preview-auto--detec= t-fragments-in-change 'local) ;; (org-latex-preview-live--teardown) )) (provide 'latex-latex-preview) ;;; latex-latex-preview.el ends here --=-=-= Content-Type: text/plain -- Tony Zorman | https://tony-zorman.com/ --=-=-=--