Add hooks for gcc handling
[gnus] / lisp / html2text.el
index 41fea4b..8c20547 100644 (file)
@@ -1,34 +1,33 @@
 ;;; html2text.el --- a simple html to plain text converter
 ;;; html2text.el --- a simple html to plain text converter
-;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+;; Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
 ;; Author: Joakim Hove <hove@phys.ntnu.no>
 
 ;; This file is part of GNU Emacs.
 
 
 ;; Author: Joakim Hove <hove@phys.ntnu.no>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 ;; GNU Emacs 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
+;; 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
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 ;; These functions provide a simple way to wash/clean html infected
 ;; mails.  Definitely do not work in all cases, but some improvement
 
 ;;; Commentary:
 
 ;; These functions provide a simple way to wash/clean html infected
 ;; mails.  Definitely do not work in all cases, but some improvement
-;; in readability is generally obtained. Formatting is only done in
+;; in readability is generally obtained.  Formatting is only done in
 ;; the buffer, so the next time you enter the article it will be
 ;; "re-htmlized".
 ;;
 ;; the buffer, so the next time you enter the article it will be
 ;; "re-htmlized".
 ;;
-;; The main function is "html2text"
+;; The main function is `html2text'.
 
 ;;; Code:
 
 
 ;;; Code:
 
 (defvar html2text-format-single-element-list '(("hr" . html2text-clean-hr)))
 
 (defvar html2text-replace-list
 (defvar html2text-format-single-element-list '(("hr" . html2text-clean-hr)))
 
 (defvar html2text-replace-list
-  '(("&nbsp;" . " ") ("&gt;" . ">") ("&lt;" . "<") ("&quot;" . "\""))
+  '(("&acute;" . "`")
+    ("&amp;" . "&")
+    ("&apos;" . "'")
+    ("&brvbar;" . "|")
+    ("&cent;" . "c")
+    ("&circ;" . "^")
+    ("&copy;" . "(C)")
+    ("&curren;" . "(#)")
+    ("&deg;" . "degree")
+    ("&divide;" . "/")
+    ("&euro;" . "e")
+    ("&frac12;" . "1/2")
+    ("&gt;" . ">")
+    ("&iquest;" . "?")
+    ("&laquo;" . "<<")
+    ("&ldquo" . "\"")
+    ("&lsaquo;" . "(")
+    ("&lsquo;" . "`")
+    ("&lt;" . "<")
+    ("&mdash;" . "--")
+    ("&nbsp;" . " ")
+    ("&ndash;" . "-")
+    ("&permil;" . "%%")
+    ("&plusmn;" . "+-")
+    ("&pound;" . "£")
+    ("&quot;" . "\"")
+    ("&raquo;" . ">>")
+    ("&rdquo" . "\"")
+    ("&reg;" . "(R)")
+    ("&rsaquo;" . ")")
+    ("&rsquo;" . "'")
+    ("&sect;" . "§")
+    ("&sup1;" . "^1")
+    ("&sup2;" . "^2")
+    ("&sup3;" . "^3")
+    ("&tilde;" . "~"))
   "The map of entity to text.
 
 This is an alist were each element is a dotted pair consisting of an
   "The map of entity to text.
 
 This is an alist were each element is a dotted pair consisting of an
-old string, and a replacement string. This replacement is done by the
-function \"html2text-substitute\" which basically performs a
-replace-string operation for every element in the list. This is
+old string, and a replacement string.  This replacement is done by the
+function `html2text-substitute' which basically performs a
+`replace-string' operation for every element in the list.  This is
 completely verbatim - without any use of REGEXP.")
 
 (defvar html2text-remove-tag-list
 completely verbatim - without any use of REGEXP.")
 
 (defvar html2text-remove-tag-list
@@ -56,11 +90,11 @@ completely verbatim - without any use of REGEXP.")
   "A list of removable tags.
 
 This is a list of tags which should be removed, without any
   "A list of removable tags.
 
 This is a list of tags which should be removed, without any
-formatting.  Observe that if you the tags in the list are presented
-*without* any \"<\" or \">\". All occurences of a tag appearing in
-this list are removed, irrespective of whether it is a closing or
-opening tag, or if the tag has additional attributes. The actual
-deletion is done by the function \"html2text-remove-tags\".
+formatting.  Note that tags in the list are presented *without*
+any \"<\" or \">\".  All occurrences of a tag appearing in this
+list are removed, irrespective of whether it is a closing or
+opening tag, or if the tag has additional attributes.  The
+deletion is done by the function `html2text-remove-tags'.
 
 For instance the text:
 
 
 For instance the text:
 
@@ -74,8 +108,10 @@ If this list contains the element \"font\".")
 
 (defvar html2text-format-tag-list
   '(("b"         . html2text-clean-bold)
 
 (defvar html2text-format-tag-list
   '(("b"         . html2text-clean-bold)
+    ("strong"     . html2text-clean-bold)
     ("u"         . html2text-clean-underline)
     ("i"         . html2text-clean-italic)
     ("u"         . html2text-clean-underline)
     ("i"         . html2text-clean-italic)
+    ("em"         . html2text-clean-italic)
     ("blockquote" . html2text-clean-blockquote)
     ("a"          . html2text-clean-anchor)
     ("ul"         . html2text-clean-ul)
     ("blockquote" . html2text-clean-blockquote)
     ("a"          . html2text-clean-anchor)
     ("ul"         . html2text-clean-ul)
@@ -85,9 +121,9 @@ If this list contains the element \"font\".")
   "An alist of tags and processing functions.
 
 This is an alist where each dotted pair consists of a tag, and then
   "An alist of tags and processing functions.
 
 This is an alist where each dotted pair consists of a tag, and then
-the name of a function to be called when this tag is found. The
+the name of a function to be called when this tag is found.  The
 function is called with the arguments p1, p2, p3 and p4. These are
 function is called with the arguments p1, p2, p3 and p4. These are
-demontrated below:
+demonstrated below:
 
 \"<b> This is bold text </b>\"
  ^   ^                 ^    ^
 
 \"<b> This is bold text </b>\"
  ^   ^                 ^    ^
@@ -115,24 +151,16 @@ formatting, and then moved afterward.")
 ;; <Utility functions>
 ;;
 
 ;; <Utility functions>
 ;;
 
-(defun html2text-buffer-head ()
-  (if (string= mode-name "Article")
-      (beginning-of-buffer)
-    (beginning-of-buffer)
-    )
-  )
 
 
-(defun html2text-replace-string (from-string to-string p1 p2)
-  (goto-char p1)
+(defun html2text-replace-string (from-string to-string min max)
+  "Replace FROM-STRING with TO-STRING in region from MIN to MAX."
+  (goto-char min)
   (let ((delta (- (string-width to-string) (string-width from-string)))
        (change 0))
   (let ((delta (- (string-width to-string) (string-width from-string)))
        (change 0))
-    (while (search-forward from-string p2 t)
+    (while (search-forward from-string max t)
       (replace-match to-string)
       (replace-match to-string)
-      (setq change (+ change delta))
-      )
-    change
-    )
-  )
+      (setq change (+ change delta)))
+    change))
 
 ;;
 ;; </Utility functions>
 
 ;;
 ;; </Utility functions>
@@ -145,11 +173,11 @@ formatting, and then moved afterward.")
 ;; <Functions related to attributes> i.e. <font size=+3>
 ;;
 
 ;; <Functions related to attributes> i.e. <font size=+3>
 ;;
 
-(defun html2text-attr-value (attr-list attr)
-  (nth 1 (assoc attr attr-list))
-  )
+(defun html2text-attr-value (list attribute)
+  "Get value of ATTRIBUTE from LIST."
+  (nth 1 (assoc attribute list)))
 
 
-(defun html2text-get-attr (p1 p2 tag)
+(defun html2text-get-attr (p1 p2)
   (goto-char p1)
   (re-search-forward " +[^ ]" p2 t)
   (let* ((attr-string (buffer-substring-no-properties (1- (point)) (1- p2)))
   (goto-char p1)
   (re-search-forward " +[^ ]" p2 t)
   (let* ((attr-string (buffer-substring-no-properties (1- (point)) (1- p2)))
@@ -165,45 +193,32 @@ formatting, and then moved afterward.")
      ;; size=3
      ((string-match "[^ ]=[^ ]" prev)
       (let ((attr  (nth 0 (split-string prev "=")))
      ;; size=3
      ((string-match "[^ ]=[^ ]" prev)
       (let ((attr  (nth 0 (split-string prev "=")))
-           (value (nth 1 (split-string prev "="))))
-       (setq attr-list (cons (list attr value) attr-list))
-       )
-      )
+           (value (substring prev (1+ (string-match "=" prev)))))
+       (setq attr-list (cons (list attr value) attr-list))))
      ;; size= 3
      ((string-match "[^ ]=\\'" prev)
      ;; size= 3
      ((string-match "[^ ]=\\'" prev)
-      (setq attr-list (cons (list (substring prev 0 -1) this) attr-list))
-      )
-     )
+      (setq attr-list (cons (list (substring prev 0 -1) this) attr-list))))
 
     (while (< index (length tmp-list))
       (cond
        ;; size=3
        ((string-match "[^ ]=[^ ]" this)
        (let ((attr  (nth 0 (split-string this "=")))
 
     (while (< index (length tmp-list))
       (cond
        ;; size=3
        ((string-match "[^ ]=[^ ]" this)
        (let ((attr  (nth 0 (split-string this "=")))
-             (value (nth 1 (split-string this "="))))
-         (setq attr-list (cons (list attr value) attr-list))
-         )
-       )
+             (value (substring prev (1+ (string-match "=" this)))))
+         (setq attr-list (cons (list attr value) attr-list))))
        ;; size =3
        ((string-match "\\`=[^ ]" this)
        (setq attr-list (cons (list prev (substring this 1)) attr-list)))
        ;; size =3
        ((string-match "\\`=[^ ]" this)
        (setq attr-list (cons (list prev (substring this 1)) attr-list)))
-
        ;; size= 3
        ((string-match "[^ ]=\\'" this)
        ;; size= 3
        ((string-match "[^ ]=\\'" this)
-       (setq attr-list (cons (list (substring this 0 -1) next) attr-list))
-       )
-
+       (setq attr-list (cons (list (substring this 0 -1) next) attr-list)))
        ;; size = 3
        ((string= "=" this)
        ;; size = 3
        ((string= "=" this)
-       (setq attr-list (cons (list prev next) attr-list))
-       )
-       )
+       (setq attr-list (cons (list prev next) attr-list))))
       (setq index (1+ index))
       (setq prev this)
       (setq this next)
       (setq index (1+ index))
       (setq prev this)
       (setq this next)
-      (setq next (nth (1+ index) tmp-list))
-      )
-
+      (setq next (nth (1+ index) tmp-list)))
     ;;
     ;; Tags with no accompanying "=" i.e. value=nil
     ;;
     ;;
     ;; Tags with no accompanying "=" i.e. value=nil
     ;;
@@ -212,41 +227,25 @@ formatting, and then moved afterward.")
     (setq next (nth 2 tmp-list))
     (setq index 1)
 
     (setq next (nth 2 tmp-list))
     (setq index 1)
 
-    (if (not (string-match "=" prev))
-       (progn
-         (if (not (string= (substring this 0 1) "="))
-             (setq attr-list (cons (list prev nil) attr-list))
-           )
-         )
-      )
-
+    (when (and (not (string-match "=" prev))
+              (not (string= (substring this 0 1) "=")))
+      (setq attr-list (cons (list prev nil) attr-list)))
     (while (< index (1- (length tmp-list)))
     (while (< index (1- (length tmp-list)))
-      (if (not (string-match "=" this))
-         (if (not (or (string= (substring next 0 1) "=")
-                      (string= (substring prev -1) "=")))
-             (setq attr-list (cons (list this nil) attr-list))
-           )
-       )
+      (when (and (not (string-match "=" this))
+                (not (or (string= (substring next 0 1) "=")
+                         (string= (substring prev -1) "="))))
+       (setq attr-list (cons (list this nil) attr-list)))
       (setq index (1+ index))
       (setq prev this)
       (setq this next)
       (setq index (1+ index))
       (setq prev this)
       (setq this next)
-      (setq next (nth (1+ index) tmp-list))
-      )
-
-    (if this
-       (progn
-         (if (not (string-match "=" this))
-             (progn
-               (if (not (string= (substring prev -1) "="))
-                   (setq attr-list (cons (list this nil) attr-list))
-                 )
-               )
-           )
-         )
-      )
-    attr-list ;; return - value
-    )
-  )
+      (setq next (nth (1+ index) tmp-list)))
+
+    (when (and this
+              (not (string-match "=" this))
+              (not (string= (substring prev -1) "=")))
+      (setq attr-list (cons (list this nil) attr-list)))
+    ;; return - value
+    attr-list))
 
 ;;
 ;; </Functions related to attributes>
 
 ;;
 ;; </Functions related to attributes>
@@ -262,25 +261,22 @@ formatting, and then moved afterward.")
   (goto-char p1)
   (let ((item-nr 0)
        (items   0))
   (goto-char p1)
   (let ((item-nr 0)
        (items   0))
-    (while (re-search-forward "<li>" p2 t)
+    (while (search-forward "<li>" p2 t)
       (setq items (1+ items)))
     (goto-char p1)
     (while (< item-nr items)
       (setq item-nr (1+ item-nr))
       (setq items (1+ items)))
     (goto-char p1)
     (while (< item-nr items)
       (setq item-nr (1+ item-nr))
-      (re-search-forward "<li>" (point-max) t)
+      (search-forward "<li>" (point-max) t)
       (cond
        ((string= list-type "ul") (insert " o "))
        ((string= list-type "ol") (insert (format " %s: " item-nr)))
       (cond
        ((string= list-type "ul") (insert " o "))
        ((string= list-type "ol") (insert (format " %s: " item-nr)))
-       (t (insert " x ")))
-      )
-    )
-  )
+       (t (insert " x "))))))
 
 (defun html2text-clean-dtdd (p1 p2)
   (goto-char p1)
   (let ((items   0)
        (item-nr 0))
 
 (defun html2text-clean-dtdd (p1 p2)
   (goto-char p1)
   (let ((items   0)
        (item-nr 0))
-    (while (re-search-forward "<dt>" p2 t)
+    (while (search-forward "<dt>" p2 t)
       (setq items (1+ items)))
     (goto-char p1)
     (while (< item-nr items)
       (setq items (1+ items)))
     (goto-char p1)
     (while (< item-nr items)
@@ -313,66 +309,57 @@ formatting, and then moved afterward.")
   (html2text-delete-single-tag p1 p2)
   (goto-char p1)
   (newline 1)
   (html2text-delete-single-tag p1 p2)
   (goto-char p1)
   (newline 1)
-  (insert (make-string fill-column ?-))
-  )
+  (insert (make-string fill-column ?-)))
 
 (defun html2text-clean-ul (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
 
 (defun html2text-clean-ul (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
-  (html2text-clean-list-items p1 (- p3 (- p1 p2)) "ul")
-  )
+  (html2text-clean-list-items p1 (- p3 (- p1 p2)) "ul"))
 
 (defun html2text-clean-ol (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
 
 (defun html2text-clean-ol (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
-  (html2text-clean-list-items p1 (- p3 (- p1 p2)) "ol")
-  )
+  (html2text-clean-list-items p1 (- p3 (- p1 p2)) "ol"))
 
 (defun html2text-clean-dl (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
 
 (defun html2text-clean-dl (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
-  (html2text-clean-dtdd p1 (- p3 (- p1 p2)))
-  )
+  (html2text-clean-dtdd p1 (- p3 (- p1 p2))))
 
 (defun html2text-clean-center (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
 
 (defun html2text-clean-center (p1 p2 p3 p4)
   (html2text-delete-tags p1 p2 p3 p4)
-  (center-region p1 (- p3 (- p2 p1)))
-  )
+  (center-region p1 (- p3 (- p2 p1))))
 
 (defun html2text-clean-bold (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'bold)
 
 (defun html2text-clean-bold (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'bold)
-  (html2text-delete-tags p1 p2 p3 p4)
-  )
+  (html2text-delete-tags p1 p2 p3 p4))
 
 (defun html2text-clean-title (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'bold)
 
 (defun html2text-clean-title (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'bold)
-  (html2text-delete-tags p1 p2 p3 p4)
-  )
+  (html2text-delete-tags p1 p2 p3 p4))
 
 (defun html2text-clean-underline (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'underline)
 
 (defun html2text-clean-underline (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'underline)
-  (html2text-delete-tags p1 p2 p3 p4)
-  )
+  (html2text-delete-tags p1 p2 p3 p4))
 
 (defun html2text-clean-italic (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'italic)
 
 (defun html2text-clean-italic (p1 p2 p3 p4)
   (put-text-property p2 p3 'face 'italic)
-  (html2text-delete-tags p1 p2 p3 p4)
-  )
+  (html2text-delete-tags p1 p2 p3 p4))
 
 (defun html2text-clean-font (p1 p2 p3 p4)
 
 (defun html2text-clean-font (p1 p2 p3 p4)
-  (html2text-delete-tags p1 p2 p3 p4)
-  )
+  (html2text-delete-tags p1 p2 p3 p4))
 
 (defun html2text-clean-blockquote (p1 p2 p3 p4)
 
 (defun html2text-clean-blockquote (p1 p2 p3 p4)
-  (html2text-delete-tags p1 p2 p3 p4)
-  )
+  (html2text-delete-tags p1 p2 p3 p4))
 
 (defun html2text-clean-anchor (p1 p2 p3 p4)
 
 (defun html2text-clean-anchor (p1 p2 p3 p4)
-  ;; If someone can explain how to make the URL clickable I will
-  ;; surely improve upon this.
-  (let* ((attr-list (html2text-get-attr p1 p2 "a"))
+  ;; If someone can explain how to make the URL clickable I will surely
+  ;; improve upon this.
+  ;; Maybe `goto-addr.el' can be used here.
+  (let* ((attr-list (html2text-get-attr p1 p2))
         (href (html2text-attr-value attr-list "href")))
     (delete-region p1 p4)
     (when href
       (goto-char p1)
         (href (html2text-attr-value attr-list "href")))
     (delete-region p1 p4)
     (when href
       (goto-char p1)
-      (insert (substring href 1 -1 ))
+      (insert (if (string-match "\\`['\"].*['\"]\\'" href)
+                 (substring href 1 -1) href))
       (put-text-property p1 (point) 'face 'bold))))
 
 ;;
       (put-text-property p1 (point) 'face 'bold))))
 
 ;;
@@ -388,41 +375,29 @@ formatting, and then moved afterward.")
 
 (defun html2text-fix-paragraph (p1 p2)
   (goto-char p1)
 
 (defun html2text-fix-paragraph (p1 p2)
   (goto-char p1)
-  (let ((has-br-line)
-       (refill-start)
+  (let ((refill-start)
        (refill-stop))
        (refill-stop))
-    (if (re-search-forward "<br>$" p2 t)
-       (setq has-br-line t)
-      )
-    (if has-br-line
-       (progn
-         (goto-char p1)
-         (if (re-search-forward ".+[^<][^b][^r][^>]$" p2 t)
-             (progn
-               (beginning-of-line)
-               (setq refill-start (point))
-               (goto-char p2)
-               (re-search-backward ".+[^<][^b][^r][^>]$" refill-start t)
-               (next-line 1)
-               (end-of-line)
-               ;; refill-stop should ideally be adjusted to
-               ;; accomodate the "<br>" strings which are removed
-               ;; between refill-start and refill-stop.  Can simply
-               ;; be returned from my-replace-string
-               (setq refill-stop (+ (point)
-                                    (html2text-replace-string
-                                     "<br>" ""
-                                     refill-start (point))))
-               ;; (message "Point = %s  refill-stop = %s" (point) refill-stop)
-               ;; (sleep-for 4)
-               (fill-region refill-start refill-stop)
-               )
-           )
-         )
-      )
-    )
-  (html2text-replace-string "<br>" "" p1 p2)
-  )
+    (when (re-search-forward "<br>$" p2 t)
+      (goto-char p1)
+      (when (re-search-forward ".+[^<][^b][^r][^>]$" p2 t)
+       (beginning-of-line)
+       (setq refill-start (point))
+       (goto-char p2)
+       (re-search-backward ".+[^<][^b][^r][^>]$" refill-start t)
+       (forward-line 1)
+       (end-of-line)
+       ;; refill-stop should ideally be adjusted to
+       ;; accommodate the "<br>" strings which are removed
+       ;; between refill-start and refill-stop.  Can simply
+       ;; be returned from my-replace-string
+       (setq refill-stop (+ (point)
+                            (html2text-replace-string
+                             "<br>" ""
+                             refill-start (point))))
+       ;; (message "Point = %s  refill-stop = %s" (point) refill-stop)
+       ;; (sleep-for 4)
+       (fill-region refill-start refill-stop))))
+  (html2text-replace-string "<br>" "" p1 p2))
 
 ;;
 ;; This one is interactive ...
 
 ;;
 ;; This one is interactive ...
@@ -431,11 +406,12 @@ formatting, and then moved afterward.")
   "This _tries_ to fix up the paragraphs - this is done in quite a ad-hook
 fashion, quite close to pure guess-work. It does work in some cases though."
   (interactive)
   "This _tries_ to fix up the paragraphs - this is done in quite a ad-hook
 fashion, quite close to pure guess-work. It does work in some cases though."
   (interactive)
-  (html2text-buffer-head)
-  (replace-regexp "^<br>$" "")
+  (goto-char (point-min))
+  (while (re-search-forward "^<br>$" nil t)
+    (delete-region (match-beginning 0) (match-end 0)))
   ;; Removing lonely <br> on a single line, if they are left intact we
   ;; Removing lonely <br> on a single line, if they are left intact we
-  ;; dont have any paragraphs at all.
-  (html2text-buffer-head)
+  ;; don't have any paragraphs at all.
+  (goto-char (point-min))
   (while (not (eobp))
     (let ((p1 (point)))
       (forward-paragraph 1)
   (while (not (eobp))
     (let ((p1 (point)))
       (forward-paragraph 1)
@@ -457,72 +433,59 @@ fashion, quite close to pure guess-work. It does work in some cases though."
 ;;
 
 (defun html2text-remove-tags (tag-list)
 ;;
 
 (defun html2text-remove-tags (tag-list)
-  "Removes the tags listed in the list \"html2text-remove-tag-list\".
+  "Removes the tags listed in the list `html2text-remove-tag-list'.
 See the documentation for that variable."
   (interactive)
   (dolist (tag tag-list)
 See the documentation for that variable."
   (interactive)
   (dolist (tag tag-list)
-    (html2text-buffer-head)
+    (goto-char (point-min))
     (while (re-search-forward (format "\\(</?%s[^>]*>\\)" tag) (point-max) t)
       (delete-region (match-beginning 0) (match-end 0)))))
 
 (defun html2text-format-tags ()
     (while (re-search-forward (format "\\(</?%s[^>]*>\\)" tag) (point-max) t)
       (delete-region (match-beginning 0) (match-end 0)))))
 
 (defun html2text-format-tags ()
-  "See the variable \"html2text-format-tag-list\" for documentation"
+  "See the variable `html2text-format-tag-list' for documentation."
   (interactive)
   (dolist (tag-and-function html2text-format-tag-list)
     (let ((tag      (car tag-and-function))
          (function (cdr tag-and-function)))
   (interactive)
   (dolist (tag-and-function html2text-format-tag-list)
     (let ((tag      (car tag-and-function))
          (function (cdr tag-and-function)))
-      (html2text-buffer-head)
+      (goto-char (point-min))
       (while (re-search-forward (format "\\(<%s\\( [^>]*\\)?>\\)" tag)
                                (point-max) t)
        (let ((p1)
              (p2 (point))
       (while (re-search-forward (format "\\(<%s\\( [^>]*\\)?>\\)" tag)
                                (point-max) t)
        (let ((p1)
              (p2 (point))
-             (p3) (p4)
-             (attr (match-string 1)))
+             (p3) (p4))
          (search-backward "<" (point-min) t)
          (setq p1 (point))
          (search-backward "<" (point-min) t)
          (setq p1 (point))
-         (re-search-forward (format "</%s>" tag) (point-max) t)
+         (unless (search-forward (format "</%s>" tag) (point-max) t)
+           (goto-char p2)
+           (insert (format "</%s>" tag)))
          (setq p4 (point))
          (search-backward "</" (point-min) t)
          (setq p3 (point))
          (funcall function p1 p2 p3 p4)
          (setq p4 (point))
          (search-backward "</" (point-min) t)
          (setq p3 (point))
          (funcall function p1 p2 p3 p4)
-         (goto-char p1)
-         )
-       )
-      )
-    )
-  )
+         (goto-char p1))))))
 
 (defun html2text-substitute ()
 
 (defun html2text-substitute ()
-  "See the variable \"html2text-replace-list\" for documentation"
+  "See the variable `html2text-replace-list' for documentation."
   (interactive)