Importing Gnus v5.8.3.
[elisp/gnus.git-] / lisp / qp.el
1 ;;; qp.el --- Quoted-Printable functions
2 ;; Copyright (C) 1998,99 Free Software Foundation, Inc.
3
4 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5 ;; This file is part of GNU Emacs.
6
7 ;; GNU Emacs is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU Emacs is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
19 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;;; Commentary:
23
24 ;;; Code:
25
26 (defvar quoted-printable-encoding-characters
27   (mapcar 'identity "0123456789ABCDEFabcdef"))
28
29 (defun quoted-printable-decode-region (from to)
30   "Decode quoted-printable in the region between FROM and TO."
31   (interactive "r")
32   (save-excursion
33     (goto-char from)
34     (while (search-forward "=" to t)
35       (cond
36        ;; End of the line.
37        ((eq (char-after) ?\n)
38         (delete-char -1)
39         (delete-char 1))
40        ;; Encoded character.
41        ((and
42          (memq (char-after) quoted-printable-encoding-characters)
43          (memq (char-after (1+ (point)))
44                quoted-printable-encoding-characters))
45         (subst-char-in-region
46          (1- (point)) (point) ?=
47          (string-to-number
48           (buffer-substring (point) (+ 2 (point)))
49           16))
50         (delete-char 2))
51        ;; Quoted equal sign.
52        ((eq (char-after) ?=)
53         (delete-char 1))
54        ;; End of buffer.
55        ((eobp)
56         (delete-char -1))
57        ;; Invalid.
58        (t
59         (message "Malformed MIME quoted-printable message"))))))
60
61 (defun quoted-printable-decode-string (string)
62   "Decode the quoted-printable-encoded STRING and return the results."
63   (with-temp-buffer
64     (insert string)
65     (quoted-printable-decode-region (point-min) (point-max))
66     (buffer-string)))
67
68 (defun quoted-printable-encode-region (from to &optional fold class)
69   "QP-encode the region between FROM and TO.
70
71 If FOLD fold long lines.  If CLASS, translate the characters 
72 matched by that regexp.
73
74 If `mm-use-ultra-safe-encoding' is set, fold unconditionally and
75 encode lines starting with \"From\"."
76   (interactive "r")
77   (save-excursion
78     (save-restriction
79       (narrow-to-region from to)
80       ;;      (mm-encode-body)
81       ;; Encode all the non-ascii and control characters.
82       (goto-char (point-min))
83       (while (and (skip-chars-forward
84                    (or class "^\000-\007\013\015-\037\200-\377="))
85                   (not (eobp)))
86         (insert
87          (prog1
88              (upcase (format "=%02x" (char-after)))
89            (delete-char 1))))
90       ;; Encode white space at the end of lines.
91       (goto-char (point-min))
92       (while (re-search-forward "[ \t]+$" nil t)
93         (goto-char (match-beginning 0))
94         (while (not (eolp))
95           (insert
96            (prog1
97                (upcase (format "=%02x" (char-after)))
98              (delete-char 1)))))
99       (when (or fold mm-use-ultra-safe-encoding)
100         ;; Fold long lines.
101         (goto-char (point-min))
102         (while (not (eobp))
103           ;; In ultra-safe mode, encode "From " at the beginning of a
104           ;; line.
105           (when mm-use-ultra-safe-encoding
106             (beginning-of-line)
107             (when (looking-at "From ")
108               (replace-match "From=20" nil t)))
109           (end-of-line)
110           (while (> (current-column) 72)
111             (beginning-of-line)
112             (forward-char 71);; 71 char plus an "="
113             (search-backward "=" (- (point) 2) t)
114             (insert "=\n")
115             (end-of-line))
116           (unless (eobp)
117             (forward-line)))))))
118
119 (defun quoted-printable-encode-string (string)
120   "QP-encode STRING and return the results."
121   (mm-with-unibyte-buffer
122     (insert string)
123     (quoted-printable-encode-region (point-min) (point-max))
124     (buffer-string)))
125
126 (provide 'qp)
127
128 ;; qp.el ends here