语文老师?!
其实不是很难,大概也就是几个函数的事情
一个大概思路是复用 org 的脚注,给 [fn:\d+]
加上 help-echo
,help-echo
的内容为找到对应脚注位置,然后就可以实现移到脚注就显示了
又或者你喜欢用 org-roam,也可以给 org-mode [[id:*][*]]
的链接加上 help-echo
,内容为对应标题或者描述
个人没需求懒得折腾 想了想第二个有空时会考虑给 org-roam 加上,先随手搜了两个链接供参考
诗词字数短,一页内能看到注释,如果是长篇大论的正文,注释在后面,学习起来,你就不停的翻来翻去,前后乱翻。
并且注释的小字,字号虽然少,但也影响排版,不如用[[ ]] 等特殊符号包起来,字体颜色稍微有一点点变化。这样效果就很好了。
谢谢指点,看视频是我需要的效果,好像之前大佬还发了一个视频,还没看完就删除了,那个也很像。
脚注有一个缺点是还要显示[1],我还设想用文内链接[[ ]] , 将注释写到一个标题的正文中,也是一种办法。
敢问org-roam是大佬写的吗?太厉害了,我之前还以为是外国人写的呢
反正我短期不是特别,你可以先试着研究下能不能实现你的需求
写了个简单的 demo 显示 id 指向 roam node 的 title
(defun org-roam-tip (window object position)
(save-excursion
(goto-char position)
(let* ((link (org-element-context))
(id (org-element-property :path link))
(node (org-roam-node-from-id id)))
(org-roam-node-title node))))
(org-link-set-parameters "id" :help-echo 'org-roam-tip)
不过需要鼠标移动过去才显示,如果想要光标移动到链接🔗上面才显示的可能需要结合 eldoc Re: bug#42484: org-mode should display value of links in mini-buffer - Samuel Wales
org roam 有个函数可以返回 node 下的内容字符串,然后将这个字符串用 posframe 显示出来,就像 youdao-dictionary 这个包中处理翻译结果一样。
是不是效果会更好?
自己小小尝试了一下,可以实现两种链接的预览功能。
- org-roam ID 类型链接。
- 同一 org 文件内 footnote。
代码中使用到了 org-transclusion-content-org-marker
这个函数获取相关页面的 content,所以必须先安装 org-transclusion 包。
代码如下:
(defun org-roam-tip ()
(interactive)
(save-excursion
(let* ((plist)
(link (org-element-context))
(id (org-element-property :path link))
(label (org-element-property :label link))
(mkr (ignore-errors (org-id-find id t)))
(content (plist-get (org-transclusion-content-org-marker mkr plist) :src-content))
(footnote (ignore-errors (buffer-substring-no-properties
(nth 1 (org-footnote-get-definition label))
(nth 2 (org-footnote-get-definition label))))))
(-posframe-tip (or content footnote))
)))
(defun -posframe-tip (string)
"Show STRING using posframe-show."
(unless (and (require 'posframe nil t) (posframe-workable-p))
(error "Posframe not workable"))
(if string
(progn
(with-current-buffer (get-buffer-create "Org Roam Tip")
(let ((inhibit-read-only t))
(erase-buffer)
(insert string)
(goto-char (point-min))))
(posframe-show "Org Roam Tip"
:left-fringe 8
:right-fringe 8
:internal-border-color (face-foreground 'default)
:internal-border-width 1)
(unwind-protect
(push (read-event) unread-command-events)
(progn
(posframe-delete "Org Roam Tip")
(other-frame 0))))
(message "Nothing to look up")))
-posframe-tip
函数是从 youdao-dictionary 抄来的,ღ( ´・ᴗ・` )比心。
移动光标到需要预览的 ID 链接或者 footnote label 上,M-x 调用 org-roam-tip
函数,不过将该函数绑定到 F1-F9 快捷键会更方便。就能看到效果。
效果如下:
-
org-roam ID 类型链接预览。
-
同一 org 文件内 footnote 预览。
不足:
- ID 类型链接中的 content 如果有图片,是无法显示的。
- ID 类型链接中的 content 如果过多,超出 posframe 范围的显示部分是无法显示的,并且没有办法滚动查看。
不知道如何解决?
我也有看古文的需求,是采用的导出的方式。
我参照了 懒猫大神 popweb,基于Web技术的弹窗框架 extension 中插件的写法,完成了 使用 popweb 弹出预览 Org-Roam ID link 和 footnote link 的功能。 仓库地址如下:GitHub - czqhurricnae/popweb: Show popup web window for Emacs ,因为还不知道有没有致命的 bug,所以没有提交 pull request。
配置
配置,我用的是 Spacemacs,还需要另外安装 org-transclusion 这个包:
(defconst hurricane-org-packages
`(
(org-transclusion :location (recipe
:fetcher github
:repo "nobiot/org-transclusion"))
(popweb :location (recipe
:fetcher github
:repo "czqhurricnae/popweb"
:files ("*.*" "extension")))
)
)
(defun hurricane-org/init-org-transclusion ()
(use-package org-transclusion
:config
(setq org-transclusion-include-first-section t)
(setq org-transclusion-exclude-elements '(property-drawer keyword))))
;; /usr/bin/env python3 -m pip install PyQt5 PyQtWebEngine epc
(defun hurricane-org/init-popweb ()
(use-package popweb
:ensure t
:load-path ("elpa/27.2/develop/popweb-20220125.2025" "elpa/27.2/develop/popweb-20220125.2025/extension/latex" "elpa/27.2/develop/popweb-20220125.2025/extension/dict" "elpa/27.2/develop/popweb-20220125.2025/extension/org-roam")
:init
(add-hook 'latex-mode-hook #'popweb-latex-mode)
:config
(require 'popweb-latex)
(require 'popweb-dict-youdao)
(require 'popweb-dict-bing)
(require 'popweb-org-roam-link)))
安装依赖,在终端运行命令,我用的是 Mac:
/usr/bin/env python3 -m pip install PyQt5 PyQtWebEngine epc
或者参考 懒猫大神 的文档进行配置。
预览调用的命令是:popweb-org-roam-link-show
。
效果
效果如下:
-
弹出预览 Org-Roam ID link,只支持 ID 类型,不支持 file 类型。
-
弹出预览 footnote link。
不足
- 没有办法光标移动到支持的链接上时自动弹出预览。
- 预览内容中的图片如果过大不好查看,不知道如何调节预览窗口大小?(在 popweb 的代码中没有找到可以配置的地方)或者使用 org-export-string-as 时对导出图片大小进行调整?自己没有仔细研究,希望有人可以提下意见。
试了下有报错,你瞅瞅啥原因。目前是用的最新的emacs-29
Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
file-truename(nil)
(format "file:%s" (file-truename (plist-get (cdr (car org-publish-project-alist)) :base-directory)))
(let* ((popweb-org-roam-link-index-path (format "file:%s" (file-truename (plist-get (cdr (car org-publish-project-alist)) :base-directory)))) (position (popweb-get-cursor-coordinate)) (x (car position)) (y (cdr position)) (x-offset (popweb-get-cursor-x-offset)) (y-offset (popweb-get-cursor-y-offset)) (frame-x (car (frame-position))) (frame-y (cdr (frame-position))) (frame-w (frame-outer-width)) (frame-h (frame-outer-height)) (show-window (nth 0 info)) (html-string (nth 1 info)) (new-html (not (string= html-string org-roam-link-preview--previous-html)))) (popweb-call-async "call_module_method" popweb-org-roam-link-module-path "pop_org_roam_link_window" (list "org_roam" popweb-org-roam-link-index-path x y x-offset y-offset frame-x frame-y frame-w frame-h show-window new-html html-string)) (popweb-org-roam-link-preview-window-can-hide))
popweb-org-roam-link-preview((t "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE h..."))
popweb-start(popweb-org-roam-link-preview (t "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE h..."))
(progn (popweb-start 'popweb-org-roam-link-preview (list t html-string)) (setq org-roam-link-preview--previous-html html-string))
(if (not (eq html-string org-roam-link-preview--previous-html)) (progn (popweb-start 'popweb-org-roam-link-preview (list t html-string)) (setq org-roam-link-preview--previous-html html-string)))
(if html-string (if (not (eq html-string org-roam-link-preview--previous-html)) (progn (popweb-start 'popweb-org-roam-link-preview (list t html-string)) (setq org-roam-link-preview--previous-html html-string))) (popweb-start 'popweb-org-roam-link-preview (list nil "Hello world")))
(let* ((html-string (get-html-from-link))) (if html-string (if (not (eq html-string org-roam-link-preview--previous-html)) (progn (popweb-start 'popweb-org-roam-link-preview (list t html-string)) (setq org-roam-link-preview--previous-html html-string))) (popweb-start 'popweb-org-roam-link-preview (list nil "Hello world"))))
popweb-org-roam-link-show()
funcall-interactively(popweb-org-roam-link-show)
call-interactively(popweb-org-roam-link-show record nil)
command-execute(popweb-org-roam-link-show record)
counsel-M-x-action("popweb-org-roam-link-show")
ivy-call()
(setq popweb-org-roam-link-index-path (concat "file:" (file-truename default-directory)))
配置中先添加这个试下。因为你的 org-publish 包没有配置 base-directory 变量,无法读取到这个默认值。
把popweb-org-roam-link.el
第56行改成下面就可以用了
(popweb-org-roam-link-index-path (concat "file:" (file-truename default-directory)))
但是位置不太对,弹出的窗口在emacs 窗口最左上角,而不是在当前位置。
感觉都可以参考popweb-latex
,popweb-latex
是可以自适应的创建不同大小窗口的,也能根据当前位置自动弹出预览窗口
修改了部分代码,可以通过配置 org-roam-link-popup-window-width-scale
和 org-roam-link-popup-window-height-scale
改变预览窗口的大小。
弹出窗口的位置应该也有改进,拉取试试看。
popweb-latex 窗口自适应大小的方法好像不适用于这种情况。不知道我代码阅读理解的对不对,毕竟我不是专业程序员。
现在能正常使用啦,固定窗口大小挺好的。
图片大小可以通过设置 #+attr_html: :width xxx
但是设置 #+attr_org: :width xxx
对 popweb-org-roam-link-show
没有作用,不知道有没有什么解决方法
增加了新功能,通过调用 popweb-org-roam-link-preview-select
命令可以对整个文件中的 ID link 和 footnote 搜索并使用 ivy 来选择预览哪个,这样就不必费力的移动光标到自己需要预览的链接上再调用 popweb-org-roam-link-show
了。
简单的视频演示地址:https://www.bilibili.com/video/BV1Cu41117ab/ 。
不足:popweb-org-roam-link-preview-select
命令会让 Emacs 失去 focus 而手动调用 popweb-org-roam-link-show
命令却不会,不知道如何解决?
是不是和 ivy-read,ivy-call 有关?