mirror of
https://github.com/protesilaos/denote.git
synced 2026-09-10 07:16:20 -04:00
149 lines
5.9 KiB
EmacsLisp
149 lines
5.9 KiB
EmacsLisp
;;; denote-org-dblock.el --- Org Dynamic blocks for denote.el -*- lexical-binding: t -*-
|
|
|
|
;; Copyright (C) 2022 Free Software Foundation, Inc.
|
|
|
|
;; Author: Elias Storms <elias.storms@gmail.com>
|
|
;; Maintainer: Denote Development <~protesilaos/denote@lists.sr.ht>
|
|
;; URL: https://git.sr.ht/~protesilaos/denote
|
|
;; Mailing-List: https://lists.sr.ht/~protesilaos/denote
|
|
|
|
;; This file is NOT part of GNU Emacs.
|
|
|
|
;; This program is free software; you can redistribute it and/or modify
|
|
;; it under the terms of the GNU General Public License as published by
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
;; (at your option) any later version.
|
|
;;
|
|
;; This program is distributed in the hope that it will be useful,
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;; GNU General Public License for more details.
|
|
;;
|
|
;; You should have received a copy of the GNU General Public License
|
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
;;; Commentary:
|
|
;;
|
|
;; This file provides a specialized Org-mode extension to Denote: it
|
|
;; introduces Org Dynamic blocks that collect links to Denote notes
|
|
;; based on a provided regexp. In short, this automates
|
|
;; 'denote-link-add-links'.
|
|
;;
|
|
;; For more information, read the commented code below or refer to the
|
|
;; Denote manual
|
|
|
|
;;; Code:
|
|
|
|
(require 'denote)
|
|
(require 'org)
|
|
|
|
;;; Org-mode Dynamic blocks
|
|
|
|
;;;; Dynamic block to search links
|
|
|
|
;; Org-mode has Dynamic blocks the content of which can be computed
|
|
;; dynamically based on their header. This functionality can be
|
|
;; leveraged to create automated lists of links to specific notes
|
|
;; (similar to 'denote-link-add-links', but with the added benefit
|
|
;; that the list can be updated easily).
|
|
;;
|
|
;; A dynamic block of the 'denote-links' type looks like this:
|
|
;;
|
|
;; #+BEGIN: denote-links :regexp "denote"
|
|
;;
|
|
;; #+END:
|
|
;;
|
|
;; With point at the #+BEGIN: line, pressing 'C-c C-c' will replace the
|
|
;; contents of the block with links to notes matching the search
|
|
;; ':regexp'. See also the denote manual on 'denote-link-add-links'.
|
|
;;
|
|
;; Inserting a block can be done via the Org-mode entry point
|
|
;; 'org-dynamic-block-insert-dblock' and selecting 'denote-links' from
|
|
;; the list, or directly by calling 'denote-org-dblock-insert-links'.
|
|
;;
|
|
;;
|
|
;; Org Dynamic blocks of the denote-links type can have the follwoing
|
|
;; arguments (in any order):
|
|
;; 1. :regexp "string" -- the search input (required)
|
|
;; 2. :missing-only t -- to only include missing links
|
|
;; 3. :reverse t -- reverse sort order (or don't, when nil)
|
|
;; 4. :block-name "n" -- to include a name for later processing
|
|
;;
|
|
;; By default ':missing-only t' is included as a parameter in the
|
|
;; block's header, so that only "missing links" are included (i.e.,
|
|
;; links to notes that the current buffer doesn't already link to).
|
|
;; Remove this parameter or set to 'nil' to include all matching
|
|
;; notes.
|
|
;;
|
|
;; With ':reverse' the value of 'denote-link-add-links-sort' can be
|
|
;; let-bound specifically for this list of links. For more
|
|
;; information, see the documentation of this variable.
|
|
;;
|
|
;; With ':block-name "string"' include a '#+NAME: string' line in the
|
|
;; Dynamic block. This allows use of the Dynamic block output as input
|
|
;; for further computation, e.g. in Org source blocks.
|
|
|
|
;;;###autoload
|
|
(defun denote-org-dblock-insert-links (regexp)
|
|
"Create Org dynamic block to insert Denote links matching REGEXP."
|
|
(interactive
|
|
(list
|
|
(read-regexp "Search for notes matching REGEX: " nil 'denote-link--add-links-history)))
|
|
(org-create-dblock (list :name "denote-links"
|
|
:regexp regexp
|
|
:missing-only 't))
|
|
(org-update-dblock))
|
|
|
|
(org-dynamic-block-define "denote-links" 'denote-org-dblock-insert-links)
|
|
|
|
;; By using the `org-dblock-write:' format, Org-mode knows how to
|
|
;; compute the dynamic block. Inner workings of this function copied
|
|
;; from `denote-link-add-links'.
|
|
(defun org-dblock-write:denote-links (params)
|
|
"Function to update `denote-links' Org Dynamic blocks.
|
|
Used by `org-dblock-update' with PARAMS provided by the dynamic block."
|
|
(let ((regexp (plist-get params :regexp))
|
|
(missing-only (plist-get params :missing-only))
|
|
(block-name (plist-get params :block-name))
|
|
(denote-link-add-links-sort (plist-get params :reverse))
|
|
(current-file (buffer-file-name)))
|
|
(when block-name
|
|
(insert "#+name: " block-name "\n"))
|
|
(if missing-only
|
|
(progn
|
|
(denote-link-add-missing-links regexp)
|
|
(join-line)) ;; remove trailing empty line left by denote-link--prepare-links
|
|
(when-let ((files (delete current-file
|
|
(denote-directory-files-matching-regexp regexp))))
|
|
(insert (denote-link--prepare-links files current-file nil))
|
|
(join-line))))) ;; remove trailing empty line
|
|
|
|
;;;; Dynamic block for backlinks
|
|
|
|
;; Similarly, we can create a 'denote-backlinks' block that inserts
|
|
;; links to notes that link to the current note.
|
|
|
|
;; Note that this block type doesn't take any additional parameters
|
|
;; (such as ':missing-only').
|
|
|
|
;;;###autoload
|
|
(defun denote-org-dblock-insert-backlinks ()
|
|
"Insert new Org dynamic block to include backlinks."
|
|
(interactive)
|
|
(org-create-dblock (list :name "denote-backlinks"))
|
|
(org-update-dblock))
|
|
|
|
(org-dynamic-block-define "denote-backlinks" 'denote-org-dblock-insert-backlinks)
|
|
|
|
(defun org-dblock-write:denote-backlinks (_params)
|
|
"Function to update `denote-backlinks' Org Dynamic blocks.
|
|
Used by `org-dblock-update' with PARAMS provided by the dynamic block."
|
|
(when-let* ((file (buffer-file-name))
|
|
(id (denote-retrieve-filename-identifier file))
|
|
(files (delete file (denote--retrieve-files-in-xrefs id))))
|
|
(insert (denote-link--prepare-links files file nil))
|
|
(join-line))) ;; remove trailing empty line
|
|
|
|
(provide 'denote-org-dblock)
|
|
;;; denote-org-dblock.el ends here
|