;;; org-capture-config.el --- Org Capture Configuration -*- lexical-binding: t; coding: utf-8; -*- ;; author: Craig Jennings ;;; Commentary: ;; Customizations related to org-capture and org-refile is here. ;; This includes 'cj/org-webpage-clipper' functionality. ;; To ensure the code below is only loaded after org-mode, all code is wrapped in an ;; eval-after-load function. ;; bookmarklet code: ;; text ;; javascript:location.href='org-protocol://capture?template=L&url=%27+encodeURIComponent(location.href)+%27&title=%27+encodeURIComponent(document.title)+%27&body=%27+encodeURIComponent(window.getSelection()) ;; text + selection ;; javascript:location.href='org-protocol://capture?template=p&url=%27+encodeURIComponent(location.href)+%27&title=%27+encodeURIComponent(document.title)+%27&body=%27+encodeURIComponent(window.getSelection()) ;;; Code: (require 'user-constants) ;; -------------------------- Event Capture Formatting ------------------------- ;; Formats event headlines with YY-MM-DD prefix extracted from the scheduled date (defun cj/org-capture-format-event-headline () "Format the event headline with YY-MM-DD prefix from the WHEN timestamp. This function is called during org-capture finalization to prepend the date to the event title for better organization in the schedule file." (when (string= (plist-get org-capture-plist :key) "e") (save-excursion (goto-char (point-min)) ;; Find the WHEN: line with timestamp (when (re-search-forward "^WHEN: \\(<[^>]+>\\)" nil t) (let* ((timestamp (match-string 1)) ;; Parse the timestamp to extract date components (parsed (org-parse-time-string timestamp)) (year (nth 5 parsed)) (month (nth 4 parsed)) (day (nth 3 parsed)) ;; Format as YY-MM-DD (date-prefix (format "%02d-%02d-%02d: " (mod year 100) month day))) ;; Go back to the headline (goto-char (point-min)) ;; Insert date prefix after the asterisks (when (looking-at "^\\(\\*+ \\)\\(.*\\)$") (replace-match (concat "\\1" date-prefix "\\2")))))))) (defun cj/org-capture-event-content () "Get the appropriate content for event capture based on context. Returns the selected text from either Emacs or browser (via org-protocol) formatted appropriately for insertion into the capture template." (cond ;; If called from org-protocol (browser), get the initial from org-store-link-plist ((and (boundp 'org-store-link-plist) org-store-link-plist (plist-get org-store-link-plist :initial)) (concat "\n" (plist-get org-store-link-plist :initial))) ;; If there's a selected region in Emacs, use it from capture plist ((and (stringp (plist-get org-capture-plist :initial)) (not (string= (plist-get org-capture-plist :initial) ""))) (concat "\n" (plist-get org-capture-plist :initial))) ;; Otherwise, return empty string (t ""))) ;; ----------------------- Org Capture PDF Active Region ----------------------- ;; allows capturing the selected region from within a PDF file. (defun cj/org-capture-pdf-active-region () "Capture the active region of the pdf-view buffer. Intended to be called within an org capture template." (let* ((pdf-buf-name (plist-get org-capture-plist :original-buffer)) (pdf-buf (get-buffer pdf-buf-name))) (if (buffer-live-p pdf-buf) (with-current-buffer pdf-buf (car (pdf-view-active-region-text))) (user-error "Buffer %S not alive" pdf-buf-name)))) ;; --------------------------- Org-Capture Templates --------------------------- ;; you can bring up the org capture menu with C-c c (use-package org-protocol :ensure nil ;; built-in :defer .5 :after org :config ;; ORG-CAPTURE TEMPLATES (setq org-protocol-default-template-key "L") (setq org-capture-templates '(("t" "Task" entry (file+headline inbox-file "Inbox") "* TODO %?" :prepend t) ("a" "Appointment" entry (file gcal-file) "* %?\n:PROPERTIES:\n:calendar-id:craigmartinjennings@gmail.com\n:END:\n:org-gcal:\n%^T--%^T\n:END:\n\n" :jump-to-captured t) ("e" "Event" entry (file+headline schedule-file "Scheduled Events") "* %?%:description SCHEDULED: %^t%(cj/org-capture-event-content) Captured On: %U" :prepend t :prepare-finalize cj/org-capture-format-event-headline) ("E" "Epub Text" entry (file+headline inbox-file "Inbox") "* %? #+BEGIN_QUOTE\n %i\n#+END_QUOTE Source: [[%:link][%(buffer-name (org-capture-get :original-buffer))]] Captured On: %U" :prepend t) ;; requires cj/org-capture-pdf-active-region function defined above ("P" "PDF Text" entry (file+headline inbox-file "Inbox") "* %? #+BEGIN_QUOTE\n%(cj/org-capture-pdf-active-region)\n#+END_QUOTE Source:[[%L][%(buffer-name (org-capture-get :original-buffer))]] Captured On: %U" :prepend t) ("p" "Link with Selection" entry (file+headline inbox-file "Inbox") "* %?%:description #+BEGIN_QUOTE\n%i\n#+END_QUOTE [[%:link][%:description]] Captured On: %U\n" :prepend t) ("L" "Link" entry (file+headline inbox-file "Inbox") "* %?%:description [[%:link][%:description]]\nCaptured On: %U" :prepend t :immediate-finish t) ("m" "Mu4e Email" entry (file+headline inbox-file "Inbox") "* TODO %? %(if (string= \"%i\" \"\") \"\" \"\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\") [[%:link][%:description]] Captured On: %U" :prepend t) )) ;; end setq ) ;; end use-package org-protocol ;; ---------------------------- Simple Task Capture ---------------------------- ;; the simplest way to capture a task. Also a simple way to write this function. (define-key global-map (kbd "C-S-t") (kbd "C-c c t")) (provide 'org-capture-config) ;;; org-capture-config.el ends here.