Add <code> tag.
[muse-el.git] / lisp / muse-protocols.el
blob16e5da67a25412a09973a5fd73ea8ec0ff55c92c
1 ;;; muse-protocols.el --- URL protocols that Muse recognizes.
3 ;; Copyright (C) 2005 Free Software Foundation, Inc.
5 ;; This file is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation; either version 2, or (at your option)
8 ;; any later version.
10 ;; This file is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;; GNU General Public License for more details.
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with GNU Emacs; see the file COPYING. If not, write to the
17 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 ;; Boston, MA 02110-1301, USA.
20 ;;; Commentary:
22 ;; Here's an example for adding a protocol for the site yubnub, a Web
23 ;; Command line service.
25 ;; (add-to-list 'muse-url-protocols '("yubnub://" muse-browse-url-yubnub
26 ;; muse-resolve-url-yubnub))
28 ;; (defun muse-resolve-url-yubnub (url)
29 ;; "Resolve a yubnub URL."
30 ;; ;; Remove the yubnub://
31 ;; (when (string-match "\\`yubnub://\\(.+\\)" url)
32 ;; (match-string 1)))
34 ;; (defun muse-browse-url-yubnub (url)
35 ;; "If this is a yubnub URL-command, jump to it."
36 ;; (setq url (muse-resolve-url-yubnub url))
37 ;; (browse-url (concat "http://yubnub.org/parser/parse?command="
38 ;; url)))
40 ;;; Contributors:
42 ;; Brad Collins (brad AT chenla DOT org) created the initial version
43 ;; of this.
45 ;;; Code:
47 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 ;; Muse URL Protocols
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 (require 'info)
54 (require 'muse-regexps)
56 (defvar muse-url-regexp nil
57 "A regexp used to match URLs within a Muse page.
58 This is autogenerated from `muse-url-protocols'.")
60 (defun muse-update-url-regexp (sym value)
61 (setq muse-url-regexp
62 (concat "\\<\\(" (mapconcat 'car value "\\|") "\\)"
63 "[^][" muse-regexp-space "\"'()<>^`{}]*"
64 "[^][" muse-regexp-space "\"'()<>^`{}.,;]+"))
65 (set sym value))
67 (defcustom muse-url-protocols
68 '(("info://" muse-browse-url-info nil)
69 ("man://" muse-browse-url-man nil)
70 ("google://" muse-browse-url-google muse-resolve-url-google)
71 ("http:/?/?" browse-url identity)
72 ("https:/?/?" browse-url identity)
73 ("ftp:/?/?" browse-url identity)
74 ("gopher://" browse-url identity)
75 ("telnet://" browse-url identity)
76 ("wais://" browse-url identity)
77 ("file://?" browse-url identity)
78 ("news:" browse-url identity)
79 ("snews:" browse-url identity)
80 ("mailto:" browse-url identity))
81 "A list of (PROTOCOL BROWSE-FUN RESOLVE-FUN) used to match URL protocols.
82 PROTOCOL describes the first part of the URL, including the
83 \"://\" part. This may be a regexp.
85 BROWSE-FUN should accept URL as an argument and open the URL in
86 the current window.
88 RESOLVE-FUN should accept URL as an argument and return the final
89 URL, or nil if no URL should be included."
90 :type '(repeat (list :tag "Protocol"
91 (string :tag "Regexp")
92 (function :tag "Browse")
93 (function :tag "Resolve")))
94 :set 'muse-update-url-regexp
95 :group 'muse)
97 (defun muse-protocol-find (proto list)
98 "Return the first element of LIST whose car matches the regexp PROTO."
99 (setq list (copy-alist list))
100 (let (entry)
101 (while list
102 (when (string-match (caar list) proto)
103 (setq entry (car list)
104 list nil))
105 (setq list (cdr list)))
106 entry))
108 (defun muse-browse-url (url &optional other-window)
109 "Handle URL with the function specified in `muse-url-protocols'.
110 If OTHER-WINDOW is non-nil, open in a different window."
111 (interactive (list (read-string "URL: ")
112 current-prefix-arg))
113 ;; Strip text properties
114 (when (fboundp 'set-text-properties)
115 (set-text-properties 0 (length url) nil url))
116 (when other-window
117 (switch-to-buffer-other-window (current-buffer)))
118 (when (string-match muse-url-regexp url)
119 (let* ((proto (concat "\\`" (match-string 1 url)))
120 (entry (muse-protocol-find proto muse-url-protocols)))
121 (when entry
122 (funcall (cadr entry) url)))))
124 (defun muse-resolve-url (url &rest ignored)
125 "Resolve URL with the function specified in `muse-url-protocols'."
126 (when (string-match muse-url-regexp url)
127 (let* ((proto (concat "\\`" (match-string 1 url)))
128 (entry (muse-protocol-find proto muse-url-protocols)))
129 (when entry
130 (let ((func (car (cddr entry))))
131 (if func
132 (setq url (funcall func url))
133 (setq url nil))))))
134 url)
136 (defun muse-protocol-add (protocol browse-function resolve-function)
137 "Add PROTOCOL to `muse-url-protocols'. PROTOCOL may be a regexp.
139 BROWSE-FUNCTION should be a function that visits a URL in the
140 current buffer.
142 RESOLVE-FUNCTION should be a function that transforms a URL for
143 publishing or returns nil if not linked."
144 (add-to-list 'muse-url-protocols
145 (list protocol browse-function resolve-function))
146 (muse-update-url-regexp 'muse-url-protocols
147 muse-url-protocols))
149 (defun muse-resolve-url-google (url)
150 "Return the correct Google search string."
151 (when (string-match "\\`google:/?/?\\(.+\\)" url)
152 (concat "http://www.google.com/search?q="
153 (match-string 1 url))))
155 (defun muse-browse-url-google (url)
156 "If this is a Google URL, jump to it."
157 (let ((google-url (muse-resolve-url-google url)))
158 (when google-url
159 (browse-url google-url))))
161 (defun muse-browse-url-info (url)
162 "If this in an Info URL, jump to it."
163 (require 'info)
164 (cond
165 ((string-match "\\`info://\\([^#]+\\)#\\(.+\\)" url)
166 (Info-find-node (match-string 1 url)
167 (match-string 2 url)))
168 ((string-match "\\`info://\\([^#]+\\)" url)
169 (Info-find-node (match-string 1 url)
170 "Top"))
171 ((string-match "\\`info://(\\([^)]+\\))\\(.+\\)" url)
172 (Info-find-node (match-string 1 url) (match-string 2 url)))
173 ((string-match "\\`info://\\(.+\\)" url)
174 (Info-find-node (match-string 1 url) "Top"))))
176 (defun muse-browse-url-man (url)
177 "If this in a manpage URL, jump to it."
178 (cond ((string-match "\\`man://\\(.+\\):\\(.+\\)" url)
179 (manual-entry (concat (match-string 1 url)
180 "(" (match-string 2 url) ")")))
181 ((string-match "\\`man://\\(.+\\)" url)
182 (manual-entry (concat (match-string 1 url))))))
184 (provide 'muse-protocols)
186 ;;; muse-protocols.el ends here