Commit | Line | Data |
---|---|---|
e5f29d66 CD |
1 | ;;; org-w3m.el --- Support from copy and paste from w3m to Org-mode |
2 | ||
ab422c4d | 3 | ;; Copyright (C) 2008-2013 Free Software Foundation, Inc. |
e5f29d66 CD |
4 | |
5 | ;; Author: Andy Stewart <lazycat dot manatee at gmail dot com> | |
6 | ;; Keywords: outlines, hypermedia, calendar, wp | |
7 | ;; Homepage: http://orgmode.org | |
e5f29d66 CD |
8 | ;; |
9 | ;; This file is part of GNU Emacs. | |
10 | ;; | |
11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation, either version 3 of the License, or | |
14 | ;; (at your option) any later version. | |
15 | ||
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
23 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
24 | ;; | |
25 | ;;; Commentary: | |
26 | ||
27 | ;; This file implements copying HTML content from a w3m buffer and | |
8bfe682a | 28 | ;; transforming the text on the fly so that it can be pasted into |
e5f29d66 | 29 | ;; an org-mode buffer with hot links. It will also work for regions |
86fbb8ca | 30 | ;; in gnus buffers that have been washed with w3m. |
e5f29d66 CD |
31 | |
32 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
33 | ;; | |
86fbb8ca | 34 | ;;; Acknowledgments: |
e5f29d66 CD |
35 | |
36 | ;; Richard Riley <rileyrgdev at googlemail dot com> | |
37 | ;; | |
33306645 CD |
38 | ;; The idea of transforming the HTML content with org-mode style is |
39 | ;; proposed by Richard, I'm just coding it. | |
e5f29d66 CD |
40 | ;; |
41 | ||
86fbb8ca CD |
42 | ;;; Code: |
43 | ||
e5f29d66 | 44 | (require 'org) |
e5f29d66 CD |
45 | |
46 | (defun org-w3m-copy-for-org-mode () | |
47 | "Copy current buffer content or active region with `org-mode' style links. | |
48 | This will encode `link-title' and `link-location' with | |
49 | `org-make-link-string', and insert the transformed test into the kill ring, | |
50 | so that it can be yanked into an Org-mode buffer with links working correctly." | |
51 | (interactive) | |
0bd48b37 CD |
52 | (let* ((regionp (org-region-active-p)) |
53 | (transform-start (point-min)) | |
54 | (transform-end (point-max)) | |
55 | return-content | |
56 | link-location link-title | |
57 | temp-position out-bound) | |
58 | (when regionp | |
59 | (setq transform-start (region-beginning)) | |
60 | (setq transform-end (region-end)) | |
61 | ;; Deactivate mark if current mark is activate. | |
62 | (if (fboundp 'deactivate-mark) (deactivate-mark))) | |
e5f29d66 CD |
63 | (message "Transforming links...") |
64 | (save-excursion | |
65 | (goto-char transform-start) | |
0bd48b37 CD |
66 | (while (and (not out-bound) ; still inside region to copy |
67 | (not (org-w3m-no-next-link-p))) ; no next link current buffer | |
68 | ;; store current point before jump next anchor | |
69 | (setq temp-position (point)) | |
70 | ;; move to next anchor when current point is not at anchor | |
86fbb8ca | 71 | (or (get-text-property (point) 'w3m-href-anchor) (org-w3m-get-next-link-start)) |
0bd48b37 CD |
72 | (if (<= (point) transform-end) ; if point is inside transform bound |
73 | (progn | |
74 | ;; get content between two links. | |
75 | (if (> (point) temp-position) | |
76 | (setq return-content (concat return-content | |
77 | (buffer-substring | |
78 | temp-position (point))))) | |
79 | ;; get link location at current point. | |
86fbb8ca | 80 | (setq link-location (get-text-property (point) 'w3m-href-anchor)) |
0bd48b37 CD |
81 | ;; get link title at current point. |
82 | (setq link-title (buffer-substring (point) | |
83 | (org-w3m-get-anchor-end))) | |
84 | ;; concat `org-mode' style url to `return-content'. | |
85 | (setq return-content (concat return-content | |
86 | (org-make-link-string | |
87 | link-location link-title)))) | |
88 | (goto-char temp-position) ; reset point before jump next anchor | |
89 | (setq out-bound t) ; for break out `while' loop | |
90 | )) | |
33306645 | 91 | ;; add the rest until end of the region to be copied |
e5f29d66 | 92 | (if (< (point) transform-end) |
0bd48b37 CD |
93 | (setq return-content |
94 | (concat return-content | |
95 | (buffer-substring (point) transform-end)))) | |
c8d0cf5c | 96 | (org-kill-new return-content) |
e5f29d66 CD |
97 | (message "Transforming links...done, use C-y to insert text into Org-mode file") |
98 | (message "Copy with link transformation complete.")))) | |
99 | ||
100 | (defun org-w3m-get-anchor-start () | |
0bd48b37 | 101 | "Move cursor to the start of current anchor. Return point." |
e5f29d66 CD |
102 | ;; get start position of anchor or current point |
103 | (goto-char (or (previous-single-property-change (point) 'w3m-anchor-sequence) | |
0bd48b37 | 104 | (point)))) |
e5f29d66 CD |
105 | |
106 | (defun org-w3m-get-anchor-end () | |
0bd48b37 | 107 | "Move cursor to the end of current anchor. Return point." |
e5f29d66 CD |
108 | ;; get end position of anchor or point |
109 | (goto-char (or (next-single-property-change (point) 'w3m-anchor-sequence) | |
110 | (point)))) | |
111 | ||
112 | (defun org-w3m-get-next-link-start () | |
0bd48b37 | 113 | "Move cursor to the start of next link. Return point." |
e5f29d66 CD |
114 | (catch 'reach |
115 | (while (next-single-property-change (point) 'w3m-anchor-sequence) | |
116 | ;; jump to next anchor | |
117 | (goto-char (next-single-property-change (point) 'w3m-anchor-sequence)) | |
86fbb8ca | 118 | (when (get-text-property (point) 'w3m-href-anchor) |
0bd48b37 CD |
119 | ;; return point when current is valid link |
120 | (throw 'reach nil)))) | |
e5f29d66 CD |
121 | (point)) |
122 | ||
123 | (defun org-w3m-get-prev-link-start () | |
8bfe682a | 124 | "Move cursor to the start of previous link. Return point." |
e5f29d66 CD |
125 | (catch 'reach |
126 | (while (previous-single-property-change (point) 'w3m-anchor-sequence) | |
127 | ;; jump to previous anchor | |
128 | (goto-char (previous-single-property-change (point) 'w3m-anchor-sequence)) | |
86fbb8ca | 129 | (when (get-text-property (point) 'w3m-href-anchor) |
0bd48b37 CD |
130 | ;; return point when current is valid link |
131 | (throw 'reach nil)))) | |
e5f29d66 CD |
132 | (point)) |
133 | ||
134 | (defun org-w3m-no-next-link-p () | |
0bd48b37 CD |
135 | "Whether there is no next link after the cursor. |
136 | Return t if there is no next link; otherwise, return nil." | |
e5f29d66 CD |
137 | (save-excursion |
138 | (equal (point) (org-w3m-get-next-link-start)))) | |
139 | ||
140 | (defun org-w3m-no-prev-link-p () | |
0bd48b37 CD |
141 | "Whether there is no previous link after the cursor. |
142 | Return t if there is no previous link; otherwise, return nil." | |
e5f29d66 CD |
143 | (save-excursion |
144 | (equal (point) (org-w3m-get-prev-link-start)))) | |
145 | ||
146 | ;; Install keys into the w3m keymap | |
147 | (defvar w3m-mode-map) | |
148 | (defvar w3m-minor-mode-map) | |
149 | (when (and (boundp 'w3m-mode-map) | |
0bd48b37 | 150 | (keymapp w3m-mode-map)) |
e5f29d66 CD |
151 | (define-key w3m-mode-map "\C-c\C-x\M-w" 'org-w3m-copy-for-org-mode) |
152 | (define-key w3m-mode-map "\C-c\C-x\C-w" 'org-w3m-copy-for-org-mode)) | |
153 | (when (and (boundp 'w3m-minor-mode-map) | |
0bd48b37 | 154 | (keymapp w3m-minor-mode-map)) |
e5f29d66 CD |
155 | (define-key w3m-minor-mode-map "\C-c\C-x\M-w" 'org-w3m-copy-for-org-mode) |
156 | (define-key w3m-minor-mode-map "\C-c\C-x\C-w" 'org-w3m-copy-for-org-mode)) | |
157 | (add-hook | |
158 | 'w3m-mode-hook | |
159 | (lambda () | |
160 | (define-key w3m-mode-map "\C-c\C-x\M-w" 'org-w3m-copy-for-org-mode) | |
161 | (define-key w3m-mode-map "\C-c\C-x\C-w" 'org-w3m-copy-for-org-mode))) | |
162 | (add-hook | |
163 | 'w3m-minor-mode-hook | |
164 | (lambda () | |
165 | (define-key w3m-minor-mode-map "\C-c\C-x\M-w" 'org-w3m-copy-for-org-mode) | |
166 | (define-key w3m-minor-mode-map "\C-c\C-x\C-w" 'org-w3m-copy-for-org-mode))) | |
167 | ||
168 | (provide 'org-w3m) | |
169 | ||
e5f29d66 | 170 | ;;; org-w3m.el ends here |