| 
					
				 | 
			
			
				@@ -0,0 +1,121 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; org-attach-embedded-images.el --- Transmute images to attachments 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Copyright 2018 Free Software Foundation, Inc. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Author: Marco Wahl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Version: 0.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Keywords: org, media 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; 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, 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 GNU Emacs.  If not, see <http://www.gnu.org/licenses/>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; Commentary: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; There are occasions when images are displayed in a subtree which 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; are not (yet) org attachments.  For example if you copy and paste a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; part of a web page (containing images) from eww to an org subtree. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; This module provides command `org-attach-embedded-images-in-subtree' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; to save such images as attachments and insert org links to them. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; To use you might put the following in your .emacs: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; (require 'org-attach-embedded-images) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Use 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;     M-x org-attach-embedded-images-in-subtree 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; in a subtree with embedded images.  The images get attached and can 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; later be reviewed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Note: Possibly 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;     M-x org-toggle-inline-images is needed to see inline 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; images in Org mode. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Code: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(require 'org) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(require 'org-attach) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Auxiliary functions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun org-attach-embedded-images--next-property-display-data (position limit) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Return position of the next property-display location with image data. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Return nil if there is no next display property. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+POSITION and LIMIT as in `next-single-property-change'." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (let ((pos (next-single-property-change position 'display nil limit))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (while (and (< pos limit) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		(let ((display-prop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		       (plist-get (text-properties-at pos) 'display))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		  (or (not display-prop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		      (not (plist-get (cdr display-prop) :data))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (setq pos (next-single-property-change pos 'display nil limit))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pos)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun org-attach-embedded-images--attach-with-sha1-name (data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Save the image given as DATA as org attachment with its sha1 as name. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Return the filename." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (let* ((extension (symbol-name (image-type-from-data data))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         (basename (concat (sha1 data) "." extension)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         (org-attach-filename 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (concat (org-attach-dir t) "/" basename))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (unless (file-exists-p org-attach-filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (with-temp-file org-attach-filename 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (setq buffer-file-coding-system 'binary) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (set-buffer-multibyte nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (insert data))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (org-attach-sync) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    org-attach-filename)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;; Command 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;;###autoload 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun org-attach-embedded-images-in-subtree () 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  "Save the displayed images as attachments and insert links to them." 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (interactive) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (if (org-before-first-heading-p) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (message "Before first heading.  Nothing has been attached.") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (save-excursion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (let ((beg (progn (org-back-to-heading) (point))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (end (progn (org-end-of-subtree) (point))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    (names nil)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	;; pass 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(goto-char beg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(while (< (goto-char (org-attach-embedded-images--next-property-display-data (point) end)) end) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	  (let ((data (plist-get (cdr (plist-get (text-properties-at (point)) 'display)) :data))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    (assert data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    (push (org-attach-embedded-images--attach-with-sha1-name data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		  names))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	;; pass 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(setq names (nreverse names)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(goto-char beg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(while names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	  (goto-char (org-attach-embedded-images--next-property-display-data (point) end)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (while (get-text-property (point) 'display) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	    (goto-char (next-property-change (point) nil end))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (skip-chars-forward "]") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (insert (concat "\n[[" (pop names) "]]"))))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(provide 'org-attach-embedded-images) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; org-attach-embedded-images.el ends here 
			 |