clsty
1
文章链接:Scaling Latex previews in Emacs | Karthinks
org-mode 下的 latex 预览,默认不会随文本一起缩放。
此文介绍了一种方法,使之成为可能。
实测确实有用。附上 recipe 以作备份。
(defun my/text-scale-adjust-latex-previews ()
"Adjust the size of latex preview fragments when changing the
buffer's text scale."
(pcase major-mode
('latex-mode
(dolist (ov (overlays-in (point-min) (point-max)))
(if (eq (overlay-get ov 'category)
'preview-overlay)
(my/text-scale--resize-fragment ov))))
('org-mode
(dolist (ov (overlays-in (point-min) (point-max)))
(if (eq (overlay-get ov 'org-overlay-type)
'org-latex-overlay)
(my/text-scale--resize-fragment ov))))))
(defun my/text-scale--resize-fragment (ov)
(overlay-put
ov 'display
(cons 'image
(plist-put
(cdr (overlay-get ov 'display))
:scale (+ 1.0 (* 0.25 text-scale-mode-amount))))))
(add-hook 'text-scale-mode-hook #'my/text-scale-adjust-latex-previews)
2 个赞
emacs 里面的图片显示一般有 overlay 和 text-property 两种方式,其中 org-mode 的 LaTeX 和图片预览采用的是 overlay 的形式,而 text-scale-mode
只修改纯文本的显示,所以默认不修改图片的缩放。
这个问题其实可以更通用地解决,下面是我的方案:
;;; adjust image size while adjusting the font size
(defvar eli/image-scale-mode-step 1.2
"Image scale factor.")
(defun eli/set-image-original-scale-factor (beg end img)
"Set original scale factors."
(let* ((ovs (overlays-in beg end))
(original-scale))
(dolist (ov ovs)
(when-let ((scale (overlay-get ov 'original-scale)))
(setq original-scale scale)))
(unless original-scale
(let ((ov (make-overlay beg end)))
(setq original-scale (or (image-property img :scale) 1.0))
(overlay-put ov 'original-scale original-scale)))
original-scale))
(defun eli/delete-image-scale-factor-overlay ()
"Delete all scale factors overlays."
(let ((ovs (overlays-in (point-min) (point-max))))
(mapc (lambda (ov)
(when (overlay-get ov 'original-scale)
(delete-overlay ov)))
ovs)))
(defun eli/overlay-image-scale ()
"Displaying buffer images(overlay property) in a larger/smaller size."
(let* ((latex-ovs (cl-remove-if-not
(lambda (o) (or (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay)
(eq (overlay-get o 'category) 'preview-overlay)))
(overlays-in (point-min) (point-max))))
(ovs (append org-inline-image-overlays latex-ovs)))
(dolist (ov ovs)
(let* ((img (overlay-get ov 'display))
(width (image-property img :width))
(original-width (or (image-property img :original-width)
(image--set-property img
:original-width width)))
(beg (overlay-start ov))
(original-scale
(eli/set-image-original-scale-factor beg (1+ beg) img)))
(when (and (not width)
original-width)
(image--set-property img :width original-width))
(image--set-property img
:scale
(* original-scale
(expt eli/image-scale-mode-step
text-scale-mode-amount)))))))
(defun eli/property-image-scale ()
"Displaying buffer images(text property) in a larger/smaller size."
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(when-let* ((img (get-text-property (point) 'display))
(original-scale
(eli/set-image-original-scale-factor (point)
(1+ (point))
img)))
(when (and img (eq (car-safe img) 'image))
(image--set-property img
:scale
(* original-scale
(expt
eli/image-scale-mode-step
text-scale-mode-amount)))))
(goto-char (next-single-property-change (point)
'display nil (point-max))))))
(defun eli/image-scale (arg)
"Displaying buffer images in a larger/smaller size."
(eli/overlay-image-scale)
(eli/property-image-scale)
(when (< arg 0)
(eli/delete-image-scale-factor-overlay)))
(advice-add 'text-scale-mode :after #'eli/image-scale)
6 个赞
clsty
3
谢谢你,我刚刚正在搜怎么与文本一起缩放图片,此方案刚好解决了我两个问题。