Extend org-edit-special to editing LaTeX fragments

* lisp/org-src.el (org-src--contents-area): Handle `latex-fragment'.
(org-edit-latex-fragment): New function.
* lisp/org.el (org-edit-special): Use new function.
This commit is contained in:
TEC 2020-05-24 23:35:33 +08:00 committed by Nicolas Goaziou
parent 5454312dbf
commit f5c47d857c
3 changed files with 54 additions and 0 deletions

View File

@ -459,6 +459,13 @@ By default, Haskell blocks are interpreted. By adding =:compile yes=
to a Haskell source block, it will be compiled, executed and the
results will be displayed.
*** Support for ~org-edit-special~ with LaTeX fragments.
Calling ~org-edit-special~ on an inline LaTeX fragment calls a new
function, ~org-edit-latex-fragment~. This functions in a comparable
manner to editing inline source blocks, bringing up a minibuffer set
to LaTeX mode. The math-mode deliminators are read only.
* Version 9.3
** Incompatible changes

View File

@ -363,6 +363,12 @@ where BEG and END are buffer positions and CONTENTS is a string."
(end (progn (goto-char (org-element-property :end datum))
(search-backward "}" (line-beginning-position) t))))
(list beg end (buffer-substring-no-properties beg end))))
((eq type 'latex-fragment)
(let ((beg (org-element-property :begin datum))
(end (org-with-point-at (org-element-property :end datum)
(skip-chars-backward " \t")
(point))))
(list beg end (buffer-substring-no-properties beg end))))
((org-element-property :contents-begin datum)
(let ((beg (org-element-property :contents-begin datum))
(end (org-element-property :contents-end datum)))
@ -959,6 +965,46 @@ Throw an error when not at such a table."
(table-recognize)
t))
(defun org-edit-latex-fragment ()
"Edit LaTeX fragment at point."
(interactive)
(let ((context (org-element-context)))
(unless (and (eq 'latex-fragment (org-element-type context))
(org-src--on-datum-p context))
(user-error "Not on a LaTeX fragment"))
(let* ((contents
(buffer-substring-no-properties
(org-element-property :begin context)
(- (org-element-property :end context)
(org-element-property :post-blank context))))
(delim-length (if (string-match "\\`\\$[^$]" contents)) 1 2))
;; Make the LaTeX deliminators read-only.
(add-text-properties 0 delim-length
(list 'read-only "Cannot edit LaTeX deliminator"
'front-sticky t
'rear-nonsticky t)
contents)
(let ((l (length contents)))
(add-text-properties (- l delim-length) l
(list 'read-only "Cannot edit LaTeX deliminator"
'front-sticky nil
'rear-nonsticky nil)
contents))
(org-src--edit-element
context
(org-src--construct-edit-buffer-name (buffer-name) "LaTeX fragment")
(org-src-get-lang-mode "latex")
(lambda ()
;; Blank lines break things, replace with a single newline.
(while (re-search-forward "\n[ \t]*\n" nil t) (replace-match "\n"))
;; If within a table a newline would disrupt the structure,
;; so remove newlines.
(goto-char (point-min))
(when (org-element-lineage context '(table-cell))
(while (search-forward "\n" nil t) (replace-match " "))))
contents))
t))
(defun org-edit-latex-environment ()
"Edit LaTeX environment at point.
\\<org-src-mode-map>

View File

@ -17347,6 +17347,7 @@ Otherwise, return a user error."
(pcase (org-element-type context)
(`footnote-reference (org-edit-footnote-reference))
(`inline-src-block (org-edit-inline-src-code))
(`latex-fragment (org-edit-latex-fragment))
(`timestamp (if (eq 'inactive (org-element-property :type context))
(call-interactively #'org-time-stamp-inactive)
(call-interactively #'org-time-stamp)))