Last update: 2023-11-20

referenceを追加する時にTitleを自動取得する   Emacs OrgMode

org-captureをつかってURLを追加したいが、 Headingタイトルを考えるのがめんどくさいので自動的に取得してほしい。

capture-templateを書く

URLからDOMを得る方法を参考にしてcapture-template生成用の関数を書いてみた。

(defun my/org-capture-new-reference ()
  (let* ((url (read-from-minibuffer "URL: "))
         (dom (with-current-buffer
                (url-retrieve-synchronously url)
                (libxml-parse-html-region url-http-end-of-headers (point-max))))
         (title (dom-text (dom-by-tag dom 'title))))
    (format "* %s
:PROPERTIES:
:ROAM_REFS: %s
:END:" title url)))

重複のチェックもしたい

roam_refsに重複がないか確認して、すでに存在する場合は追加しないようにしたほうが良さそう。

(defun my/org-new-reference-exists (url)
  (when-let* ((url-ref (progn
                         (string-match "\\(^.*:\\)\\(//.*$\\)" url)
                         (match-string 2 url)))
              (exist (org-roam-db-query
                      [:select [ref]
                               :from refs
                               :where (= ref $s1)]
                      url-ref)))))

(my/new-reference-already-exists "https://www.google.com")  ; 存在する場合はrefが返る
//www.google.com

重複チェックありバージョン

バリデーションを入れて関数を書き直す。

(defun my/org-capture-new-reference ()
  (let* ((url (read-from-minibuffer "URL: "))
         (url-not-exist (not (my/reference-already-exists url)))
         (dom (ignore-errors
                (with-current-buffer
                    (url-retrieve-synchronously url)
                  (libxml-parse-html-region url-http-end-of-headers (point-max)))))
         (title (dom-text (dom-by-tag dom 'title))))
    (unless url-not-exist
      (error "Already exists Ref: %s" url))
    (format "* %s%%?
:PROPERTIES:
:ROAM_REFS: %s
:END:" title url)))
my/org-capture-new-reference

実行してみる

(let* ((org-capture-templates
        '(("r" "reference"
           plain (file "/tmp/hoge.org")
           (function my/org-capture-new-reference)))))
  (org-capture))

重複する場合はこんなエラーが出たので良さそう。

Already exists Ref: https://www.google.com