commit cbfe4536d6239c9ae5c95c52cab11402623c3b81 Author: Yann Esposito (Yogsototh) Date: Tue Jul 30 23:23:01 2019 +0200 Initial commit, emacs package is not straightforward. diff --git a/org-auto-id.el b/org-auto-id.el new file mode 100644 index 0000000..18baa8e --- /dev/null +++ b/org-auto-id.el @@ -0,0 +1,88 @@ +;;; org-auto-id.el --- Add custom id to all org entries, useful for html exporting. -*- lexical-binding: t; -*- + +;; Copyright (C) 2019 Yann Esposito + +;; Author: Yann Esposito +;; Maintainer: Yann Esposito +;; Created: 28 Jul 2019 +;; Version: 0.1 +;; Keywords: org +;; Homepage: https://gitlab.esy.fun/yogsototh/org-auto-id +;; Package-Requires: ((emacs "24.4") org (org-auto-id "0.1")) + +;; This file is not part of GNU Emacs + +;;; Commentary: +;; Will warn you if you have duplicate CUSTOM_ID. + +;;; License: + +;; Licensed under the same terms as Emacs. + +;;; Code: + +(require 'org) + +(with-eval-after-load 'org + (defvar org-auto-id--all-ids '() + "List as set of all ids of the current org-file") + + (defun org-auto-id-format (title) + "Generate a new org-id using TITLE." + (concat (downcase (replace-regexp-in-string "\\W" "-" title)))) + + (defun org-auto-id-add-id (id &optional new?) + "Add the id to the set of existing ids, warn if not a generation of new id." + (if (member id org-auto-id--all-ids) + (progn (unless new? + (message "Duplicate CUSTOM_ID found: %s" id)) + (org-auto-id-add-id (format "%s-%04x" id (random (expt 16 4))) new?)) + (progn + (add-to-list 'org-auto-id--all-ids id) + id))) + + (defun org-auto-id-custom-id-get (&optional pom create) + "Get the CUSTOM_ID property of the entry at point-or-marker POM. +If POM is nil, refer to the entry at point. +If the entry does not have an CUSTOM_ID, the function returns nil. +However, when CREATE is non nil, create a CUSTOM_ID if none is present already. +In any case, the CUSTOM_ID of the entry is returned." + (interactive) + (org-with-point-at pom + (let ((id (org-entry-get nil "CUSTOM_ID"))) + (cond + ((and id (stringp id) (string-match "\\S-" id)) + (progn + (org-auto-id-add-id id) + id)) + (create + (let ((id (org-auto-id-format (org-entry-get nil "ITEM")))) + (let ((new-id (org-auto-id-add-id id t))) + (org-entry-put pom "CUSTOM_ID" new-id) + new-id))))))) + + (defun org-auto-id-add-ids-to-headlines-in-file () + "Add CUSTOM_ID properties to all headlines. +In the current file, all headlines which do not already have a CUSTOM_ID. +Only adds ids if the `auto-id' option is set to `t' in the file somewhere. +ie, #+OPTIONS: auto-id:t" + (interactive) + (save-excursion + (widen) + (goto-char (point-min)) + (let ((add-suffix (re-search-forward "^#\\+OPTIONS:.* auto-id-add-suffix:t" (point-max) t))) + (when (re-search-forward "^#\\+OPTIONS:.* auto-id:t" (point-max) t) + (setq org-auto-id--all-ids '()) + (org-map-entries (lambda () (org-auto-id-custom-id-get (point) 'create))))))) + + (add-hook 'org-mode-hook + (lambda () + (add-hook 'before-save-hook + (lambda () + (when (and (eq major-mode 'org-mode) + (eq buffer-read-only nil)) + (org-auto-id-add-ids-to-headlines-in-file))))))) + +(provide 'org-auto-id) + +;;; org-auto-id.el ends here