Initial Commit
[packages] / xemacs-packages / mew / mew / contrib / rfc2368.el
1 ;;; rfc2368.el --- support for rfc 2368
2
3 ;;; Copyright 1999 Sen Nagata <sen@eccosys.com>
4
5 ;; Keywords: rfc 2368, mailto, mail
6 ;; Version: 0.3
7 ;; License: GPL 2
8
9 ;; This file is not a part of GNU Emacs.
10
11 ;;; Commentary:
12 ;;
13 ;; notes:
14 ;;
15 ;;   -repeat after me: "the colon is not part of the header name..."
16 ;;   -if w3 becomes part of emacs, then it may make sense to have this
17 ;;    file depend on w3 -- the maintainer of w3 says merging w/ emacs
18 ;;    is planned!
19 ;;
20 ;; historical note:
21 ;;
22 ;;   this is intended as a replacement for mailto.el
23 ;;
24 ;; acknowledgements:
25 ;;
26 ;;   the functions that deal w/ unhexifying in this file were basically
27 ;; taken from w3 -- i hope to replace them w/ something else soon OR
28 ;; perhaps if w3 becomes a part of emacs soon, use the functions from w3.
29
30 ;;; History:
31 ;;
32 ;; 0.3:
33 ;;
34 ;;  added the constant rfc2368-version
35 ;;  implemented first potential fix for a bug in rfc2368-mailto-regexp
36 ;;  implemented first potential fix for a bug in rfc2368-parse-mailto
37 ;;  (both bugs reported by Kenichi OKADA)
38 ;;
39 ;; 0.2:
40 ;;
41 ;;  started to use checkdoc
42 ;;
43 ;; 0.1:
44 ;;
45 ;;  initial implementation
46
47 ;;; Code:
48 (defconst rfc2368-version "rfc2368.el 0.3")
49
50 ;; only an approximation?
51 ;; see rfc 1738
52 (defconst rfc2368-mailto-regexp
53   "^\\(mailto:\\)\\([^?]+\\)*\\(\\?\\(.*\\)\\)*"
54   "Regular expression to match and aid in parsing a mailto url.")
55
56 ;; describes 'mailto:'
57 (defconst rfc2368-mailto-scheme-index 1
58   "Describes the 'mailto:' portion of the url.")
59 ;; i'm going to call this part the 'prequery'
60 (defconst rfc2368-mailto-prequery-index 2
61   "Describes the portion of the url between 'mailto:' and '?'.")
62 ;; i'm going to call this part the 'query'
63 (defconst rfc2368-mailto-query-index 4
64   "Describes the portion of the url after '?'.")
65
66 ;; for dealing w/ unhexifying strings, my preferred approach is to use
67 ;; a 'string-replace-match-using-function' which can perform a
68 ;; string-replace-match and compute the replacement text based on a
69 ;; passed function -- however, emacs doesn't seem to have such a
70 ;; function yet :-(
71
72 ;; for the moment a rip-off of url-unhex (w3/url.el)
73 (defun rfc2368-unhexify-char (char)
74   "Unhexify CHAR -- e.g. %20 -> <SPC>."
75   (if (> char ?9)
76       (if (>= char ?a)
77           (+ 10 (- char ?a))
78         (+ 10 (- char ?A)))
79     (- char ?0)))
80
81 ;; for the moment a rip-off of url-unhex-string (w3/url.el) (slightly modified)
82 (defun rfc2368-unhexify-string (string)
83   "Unhexify STRING -- e.g. 'hello%20there' -> 'hello there'."
84   (let ((case-fold-search t)
85         (result ""))
86     (while (string-match "%[0-9a-f][0-9a-f]" string)
87       (let* ((start (match-beginning 0))
88              (hex-code (+ (* 16
89                              (rfc2368-unhexify-char (elt string (+ start 1))))
90                           (rfc2368-unhexify-char (elt string (+ start 2))))))
91         (setq result (concat
92                       result (substring string 0 start)
93                       (char-to-string hex-code))
94               string (substring string (match-end 0)))))
95     ;; it seems clearer to do things this way than to just return:
96     ;; (concat result string)
97     (setq result (concat result string))
98     result))
99
100 (defun rfc2368-parse-mailto-url (mailto-url)
101   "Parse MAILTO-URL, and return an alist of header-name, header-value pairs.
102 MAILTO-URL should be a RFC 2368 (mailto) compliant url.  A cons cell w/ a
103 key of 'Body' is a special case and is considered a header for this purpose.
104 The returned alist is intended for use w/ the `compose-mail' interface.
105 Note: make sure MAILTO-URL has been 'unhtmlized' (e.g. &amp; -> &), before
106 calling this function."
107   (let ((case-fold-search t)
108         prequery query headers-alist)
109
110     (if (string-match rfc2368-mailto-regexp mailto-url)
111         (progn
112
113           (setq prequery
114                 (match-string rfc2368-mailto-prequery-index mailto-url))
115           
116           (setq query
117                 (match-string rfc2368-mailto-query-index mailto-url))
118
119           ;; build alist of header name-value pairs
120           (if (not (null query))
121               (setq headers-alist
122                     (mapcar
123                      (lambda (x)
124                        (let* ((temp-list (split-string x "="))
125                               (header-name (car temp-list))
126                               (header-value (cadr temp-list)))
127                          ;; return ("Header-Name" . "header-value")
128                          (cons
129                           (capitalize (rfc2368-unhexify-string header-name))
130                           (rfc2368-unhexify-string header-value))))
131                      (split-string query "&"))))
132
133           ;; deal w/ multiple 'To' recipients
134           (if prequery
135               (progn
136                 (if (assoc "To" headers-alist)
137                     (let* ((our-cons-cell
138                             (assoc "To" headers-alist))
139                            (our-cdr
140                             (cdr our-cons-cell)))
141                       (setcdr our-cons-cell (concat our-cdr ", " prequery)))
142                   (setq headers-alist
143                         (cons (cons "To" prequery) headers-alist)))))
144           
145           headers-alist)
146       
147       (error "Failed to match a mailto: url"))
148     ))
149
150 (provide 'rfc2368)
151
152 ;;; rfc2368.el ends here