使用 sexp 捕获组织模式

发布于 2024-11-19 18:10:29 字数 1463 浏览 2 评论 0原文

我正在尝试创建一个捕获模板,将 URL 转换为组织模式链接,并以 </code> 作为链接名称。

我的转换函数如下所示:

(defun get-page-title (url)
  "Get title of web page, whose url can be found in the current line"
  ;; Get title of web page, with the help of functions in url.el
  (with-current-buffer (url-retrieve-synchronously url)
    ;; find title by grep the html code
    (goto-char 0)
    (re-search-forward "<title>\\([^<]*\\)</title>" nil t 1)
    (setq web_title_str (match-string 1))
    ;; find charset by grep the html code
    (goto-char 0)

    ;; find the charset, assume utf-8 otherwise
    (if (re-search-forward "charset=\\([-0-9a-zA-Z]*\\)" nil t 1)
        (setq coding_charset (downcase (match-string 1)))
      (setq coding_charset "utf-8")
    ;; decode the string of title.
    (setq web_title_str (decode-coding-string web_title_str (intern
                                                             coding_charset)))
    )
  (concat "[[" url "][" web_title_str "]]")
  ))

当从正常的 emacs lisp 代码调用时,它返回正确的结果。但是当在此org-capture-template中使用时,它仅返回错误的url

setq org-capture-templates
    (quote
     (("l" "Link" entry (file+headline "" "Links")
       "* \"%c\" %(get-page-title \"%c\")"))))

扩展顺序是否不同?我需要以不同的方式转义字符串吗?魔法? 第一个 %c 只是用于调试字符串,并且确实被打印为“url”。

请不要费心指出使用正则表达式解析 XML 是错误的方法。克苏鲁已经困扰着我,这不会让情况变得更糟。

I'm trying to get create a capture template that converts an URL to an org-mode link with the <title> as the link name.

My conversion function looks like this:

(defun get-page-title (url)
  "Get title of web page, whose url can be found in the current line"
  ;; Get title of web page, with the help of functions in url.el
  (with-current-buffer (url-retrieve-synchronously url)
    ;; find title by grep the html code
    (goto-char 0)
    (re-search-forward "<title>\\([^<]*\\)</title>" nil t 1)
    (setq web_title_str (match-string 1))
    ;; find charset by grep the html code
    (goto-char 0)

    ;; find the charset, assume utf-8 otherwise
    (if (re-search-forward "charset=\\([-0-9a-zA-Z]*\\)" nil t 1)
        (setq coding_charset (downcase (match-string 1)))
      (setq coding_charset "utf-8")
    ;; decode the string of title.
    (setq web_title_str (decode-coding-string web_title_str (intern
                                                             coding_charset)))
    )
  (concat "[[" url "][" web_title_str "]]")
  ))

When called from normal emacs lisp code it returns the correct result. But when used in this org-capture-template it only returns bad url.

setq org-capture-templates
    (quote
     (("l" "Link" entry (file+headline "" "Links")
       "* \"%c\" %(get-page-title \"%c\")"))))

Is the order of expansion different? Do I need to escape the string differently? Magic?
The first %c is only their to debug the string and indeed is getting printed as "url".

Please don't even bother pointing out that parsing XML with regexp is the wrong approach. Cthulhu is already haunting me and this isn't going to make it worse.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

缺⑴份安定 2024-11-26 18:10:29

问题在于模板参数的扩展顺序。简单的 % 模板在 sexp 求值后展开。原始错误消息仍然包含模板,因此会扩展为剪贴板的内容,因此错误消息不包含最初传递给 get-page-title 的字符串。

解决方案是从 sexp 内访问 Kill Ring:

%(get-page-title (current-kill 0))

编辑 此行为现已记录在 org-mode 中。

The problem is the order of expansion of template parameters. The simple % templates are expanded after the sexp has been evaluated. The original error message still contains a template and thus is expanded into the contents of the clipboard and thus the error message contains not the string that was originally passed to get-page-title.

The solution is to access the kill ring from within the sexp:

%(get-page-title (current-kill 0))

EDIT This behavior is now documented in org-mode.

忘你却要生生世世 2024-11-26 18:10:29

解决方案不是使用 org-protocol.el 吗?
http://orgmode.org/worg/org-contrib/org-protocol.html

我刚刚使用以下模板对其进行了测试(为您想要的标题添加副标题作为标题)。

模板:

("t"
"Testing Template"
entry
(file+headline "~/org/capture.org" "Testing")
"* %^{Title}\n** %:description\n\n  Source: %u, %c\n\n%i"
:empty-lines 1)

然后使用基于浏览器的键绑定(在我的例子中使用 Opera,尽管也提供了 Firefox、Uzbl、Acrobat 和 Conkeror 的示例),我能够捕获以下内容:(

** Testing for StackExchange
*** org-protocol.el - Intercept calls from emacsclient to trigger custom actions

  Source: [2011-08-05 Fri], [[http://orgmode.org/worg/org-contrib/org-protocol.html]
  [org-protocol.el - Intercept calls from emacsclient to trigger custom actions]]

    org-protocol intercepts calls from emacsclient to trigger custom actions
    without external dependencies.

我破坏了 org-link 只是为了保留滚动到最小,原来不是两行)

Wouldn't the solution be to use org-protocol.el?
http://orgmode.org/worg/org-contrib/org-protocol.html

I just tested it with the following template (adding a sub-heading for your desired title as headline).

Template:

("t"
"Testing Template"
entry
(file+headline "~/org/capture.org" "Testing")
"* %^{Title}\n** %:description\n\n  Source: %u, %c\n\n%i"
:empty-lines 1)

Then using a browser-based keybind (in my case with Opera, although examples for Firefox, Uzbl, Acrobat and Conkeror are provided as well) I was able to capture the following:

** Testing for StackExchange
*** org-protocol.el - Intercept calls from emacsclient to trigger custom actions

  Source: [2011-08-05 Fri], [[http://orgmode.org/worg/org-contrib/org-protocol.html]
  [org-protocol.el - Intercept calls from emacsclient to trigger custom actions]]

    org-protocol intercepts calls from emacsclient to trigger custom actions
    without external dependencies.

(I broke the org-link simply to keep the scrolling to a minimum, it was not on two lines originally)

看透却不说透 2024-11-26 18:10:29

@aboabo 在 https://stackoverflow.com/a/21080770/255961 中共享了一个未记录的变量,它提供了更通用的解决方案问题的主题是如何在模板中将 sexp 与关键字值一起使用(超越杀环)。变量 org-store-link-plist 存储传递给捕获的所有信息。因此,您可以直接从这样的函数访问其值:

(defun url()
  (plist-get org-store-link-plist :url))
("w" "capture" entry (file "~/refile.org")
     "* [[%:link][%:description]] :NOTE:\n%(url)%U\n"
     :immediate-finish t) 

PS,根据 手册页(下面引用)在我看来,您在该问题中的方法也应该有效。但我同意你所描述的似乎是实际发生的事情 - 这似乎是相对于手册的一个错误。

%(sexp) 计算 Elisp sexp 并替换为结果。为了方便起见,
%:关键字(见下文)表达式中的占位符将是
在此之前进行了扩展。

@aboabo shared an undocumented variable in https://stackoverflow.com/a/21080770/255961 that provides a more general solution to the question's topic of how to use sexp with keyword values in a template (beyond kill ring). The variable org-store-link-plist stores all the information being passed to the capture. So you can access its values directly from a function like this:

(defun url()
  (plist-get org-store-link-plist :url))
("w" "capture" entry (file "~/refile.org")
     "* [[%:link][%:description]] :NOTE:\n%(url)%U\n"
     :immediate-finish t) 

PS, According to the manual page (quote below) it sounds to me like your approach in teh question should work also. But I agree what you describe is what seems to be actually happening - it seems like a bug relative to the manual.

%(sexp) Evaluate Elisp sexp and replace with the result. For convenience,
%:keyword (see below) placeholders within the expression will be
expanded prior to this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文