aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGnus developers2010-10-04 22:26:51 +0000
committerKatsumi Yamaoka2010-10-04 22:26:51 +0000
commit71e691a59f04acbd9a03c2d38d7e8971a0ec5115 (patch)
tree61932b3c37d7e6d73a49c15934e87fb238215d76
parent4a93e698f3524e7e8feee2715967ebb0ef673232 (diff)
downloademacs-71e691a59f04acbd9a03c2d38d7e8971a0ec5115.tar.gz
emacs-71e691a59f04acbd9a03c2d38d7e8971a0ec5115.zip
Merge changes made in Gnus trunk.
shr.el: Implement table rendering. shr.el (shr-make-table): Tweak table generation. shr.el (shr-make-table): Fix typo. nnimap.el (nnimap-open-connection): Allow tls as a synonym for ssl. gnus-util.el (gnus-emacs-completing-read): Mapcar collection to list, for XEmacs. nnimap.el (nnimap-close-server): Implement. gnus-salt.el: Remove all gnus-carpal stuff -- it's not useful. nnir.el (nnir-run-imap): Remove spurious space in search string. message.el (message-idna-to-ascii-rhs-1): Don't bug out on addresses without @ signs. gnus-sum.el (gnus-widen-article-window): New variable. shr.el (browse-url): Required. shr.el (shr-ensure-paragraph): Don't insert a new newline after empty-ish lines. shr.el (shr-show-alt-text, shr-browse-image): New commands. gravatar.el (gravatar-retrieved): kill buffer when retrieved. shr.el (shr-browse-url, shr-copy-url): New commands. shr.el (shr-render-td): Protect against too-wide text. spam-report.el (spam-report-url-ping-plain): Don't query about killing the process. nnimap.el (nnimap-finish-retrieve-group-infos): Message while waiting for data. shr.el (shr-tag-blockquote): Ensure paragraph after quote, too. mml-smime.el: Fix gnus-completing-read usage. shr.el (shr-get-image-data): Ensure against the cache file missing. nnimap.el (nnimap-open-connection): Give an error if nnimap-stream is unknown.
-rw-r--r--doc/misc/ChangeLog4
-rw-r--r--doc/misc/gnus-news.texi2
-rw-r--r--doc/misc/gnus.texi79
-rw-r--r--lisp/gnus/ChangeLog55
-rw-r--r--lisp/gnus/gnus-group.el4
-rw-r--r--lisp/gnus/gnus-salt.el171
-rw-r--r--lisp/gnus/gnus-srvr.el6
-rw-r--r--lisp/gnus/gnus-sum.el14
-rw-r--r--lisp/gnus/gnus-util.el6
-rw-r--r--lisp/gnus/gnus-win.el18
-rw-r--r--lisp/gnus/gnus.el7
-rw-r--r--lisp/gnus/gravatar.el3
-rw-r--r--lisp/gnus/message.el4
-rw-r--r--lisp/gnus/mml-smime.el4
-rw-r--r--lisp/gnus/nnimap.el15
-rw-r--r--lisp/gnus/nnir.el2
-rw-r--r--lisp/gnus/shr.el240
-rw-r--r--lisp/gnus/spam-report.el1
18 files changed, 334 insertions, 301 deletions
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 5c2766c8532..b30bb9e5027 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,7 @@
12010-10-04 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * gnus.texi (Misc Article): Document gnus-widen-article-window.
4
12010-10-03 Julien Danjou <julien@danjou.info> 52010-10-03 Julien Danjou <julien@danjou.info>
2 6
3 * emacs-mime.texi (Display Customization): Update 7 * emacs-mime.texi (Display Customization): Update
diff --git a/doc/misc/gnus-news.texi b/doc/misc/gnus-news.texi
index 028539a7fb4..1136d52e51d 100644
--- a/doc/misc/gnus-news.texi
+++ b/doc/misc/gnus-news.texi
@@ -356,6 +356,8 @@ moving articles to a group that has not turned auto-expire on.
356 356
357@item NoCeM support has been removed. 357@item NoCeM support has been removed.
358 358
359@item Carpal mode has been removed.
360
359@end itemize 361@end itemize
360 362
361@end itemize 363@end itemize
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 00f58b2307a..6c20e424f04 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -797,7 +797,6 @@ Various
797* Compilation:: How to speed Gnus up. 797* Compilation:: How to speed Gnus up.
798* Mode Lines:: Displaying information in the mode lines. 798* Mode Lines:: Displaying information in the mode lines.
799* Highlighting and Menus:: Making buffers look all nice and cozy. 799* Highlighting and Menus:: Making buffers look all nice and cozy.
800* Buttons:: Get tendinitis in ten easy steps!
801* Daemons:: Gnus can do things behind your back. 800* Daemons:: Gnus can do things behind your back.
802* Undo:: Some actions can be undone. 801* Undo:: Some actions can be undone.
803* Predicate Specifiers:: Specifying predicates. 802* Predicate Specifiers:: Specifying predicates.
@@ -12847,6 +12846,11 @@ If non-@code{nil}, use the same article buffer for all the groups.
12847(This is the default.) If @code{nil}, each group will have its own 12846(This is the default.) If @code{nil}, each group will have its own
12848article buffer. 12847article buffer.
12849 12848
12849@item gnus-widen-article-window
12850@cindex gnus-widen-article-window
12851If non-@code{nil}, selecting the article buffer with the @kbd{h}
12852command will ``widen'' the article window to take the entire frame.
12853
12850@vindex gnus-article-decode-hook 12854@vindex gnus-article-decode-hook
12851@item gnus-article-decode-hook 12855@item gnus-article-decode-hook
12852@cindex @acronym{MIME} 12856@cindex @acronym{MIME}
@@ -21717,7 +21721,6 @@ four days, Gnus will decay the scores four times, for instance.
21717* Compilation:: How to speed Gnus up. 21721* Compilation:: How to speed Gnus up.
21718* Mode Lines:: Displaying information in the mode lines. 21722* Mode Lines:: Displaying information in the mode lines.
21719* Highlighting and Menus:: Making buffers look all nice and cozy. 21723* Highlighting and Menus:: Making buffers look all nice and cozy.
21720* Buttons:: Get tendinitis in ten easy steps!
21721* Daemons:: Gnus can do things behind your back. 21724* Daemons:: Gnus can do things behind your back.
21722* Undo:: Some actions can be undone. 21725* Undo:: Some actions can be undone.
21723* Predicate Specifiers:: Specifying predicates. 21726* Predicate Specifiers:: Specifying predicates.
@@ -22178,8 +22181,7 @@ glitches. Use at your own peril.
22178buffer should be given. Here's an excerpt of this variable: 22181buffer should be given. Here's an excerpt of this variable:
22179 22182
22180@lisp 22183@lisp
22181((group (vertical 1.0 (group 1.0 point) 22184((group (vertical 1.0 (group 1.0 point)))
22182 (if gnus-carpal (group-carpal 4))))
22183 (article (vertical 1.0 (summary 0.25 point) 22185 (article (vertical 1.0 (summary 0.25 point)
22184 (article 1.0)))) 22186 (article 1.0))))
22185@end lisp 22187@end lisp
@@ -22217,7 +22219,6 @@ Here's a more complicated example:
22217@lisp 22219@lisp
22218(article (vertical 1.0 (group 4) 22220(article (vertical 1.0 (group 4)
22219 (summary 0.25 point) 22221 (summary 0.25 point)
22220 (if gnus-carpal (summary-carpal 4))
22221 (article 1.0))) 22222 (article 1.0)))
22222@end lisp 22223@end lisp
22223 22224
@@ -22228,20 +22229,16 @@ occupy, not a percentage.
22228If the @dfn{split} looks like something that can be @code{eval}ed (to be 22229If the @dfn{split} looks like something that can be @code{eval}ed (to be
22229precise---if the @code{car} of the split is a function or a subr), this 22230precise---if the @code{car} of the split is a function or a subr), this
22230split will be @code{eval}ed. If the result is non-@code{nil}, it will 22231split will be @code{eval}ed. If the result is non-@code{nil}, it will
22231be used as a split. This means that there will be three buffers if 22232be used as a split.
22232@code{gnus-carpal} is @code{nil}, and four buffers if @code{gnus-carpal}
22233is non-@code{nil}.
22234 22233
22235Not complicated enough for you? Well, try this on for size: 22234Not complicated enough for you? Well, try this on for size:
22236 22235
22237@lisp 22236@lisp
22238(article (horizontal 1.0 22237(article (horizontal 1.0
22239 (vertical 0.5 22238 (vertical 0.5
22240 (group 1.0) 22239 (group 1.0))
22241 (gnus-carpal 4))
22242 (vertical 1.0 22240 (vertical 1.0
22243 (summary 0.25 point) 22241 (summary 0.25 point)
22244 (summary-carpal 4)
22245 (article 1.0)))) 22242 (article 1.0))))
22246@end lisp 22243@end lisp
22247 22244
@@ -22618,62 +22615,6 @@ Hook called after creating the score mode menu.
22618@end table 22615@end table
22619 22616
22620 22617
22621@node Buttons
22622@section Buttons
22623@cindex buttons
22624@cindex mouse
22625@cindex click
22626
22627Those new-fangled @dfn{mouse} contraptions is very popular with the
22628young, hep kids who don't want to learn the proper way to do things
22629these days. Why, I remember way back in the summer of '89, when I was
22630using Emacs on a Tops 20 system. Three hundred users on one single
22631machine, and every user was running Simula compilers. Bah!
22632
22633Right.
22634
22635@vindex gnus-carpal
22636Well, you can make Gnus display bufferfuls of buttons you can click to
22637do anything by setting @code{gnus-carpal} to @code{t}. Pretty simple,
22638really. Tell the chiropractor I sent you.
22639
22640
22641@table @code
22642
22643@item gnus-carpal-mode-hook
22644@vindex gnus-carpal-mode-hook
22645Hook run in all carpal mode buffers.
22646
22647@item gnus-carpal-button-face
22648@vindex gnus-carpal-button-face
22649Face used on buttons.
22650
22651@item gnus-carpal-header-face
22652@vindex gnus-carpal-header-face
22653Face used on carpal buffer headers.
22654
22655@item gnus-carpal-group-buffer-buttons
22656@vindex gnus-carpal-group-buffer-buttons
22657Buttons in the group buffer.
22658
22659@item gnus-carpal-summary-buffer-buttons
22660@vindex gnus-carpal-summary-buffer-buttons
22661Buttons in the summary buffer.
22662
22663@item gnus-carpal-server-buffer-buttons
22664@vindex gnus-carpal-server-buffer-buttons
22665Buttons in the server buffer.
22666
22667@item gnus-carpal-browse-buffer-buttons
22668@vindex gnus-carpal-browse-buffer-buttons
22669Buttons in the browse buffer.
22670@end table
22671
22672All the @code{buttons} variables are lists. The elements in these list
22673are either cons cells where the @code{car} contains a text to be displayed and
22674the @code{cdr} contains a function symbol, or a simple string.
22675
22676
22677@node Daemons 22618@node Daemons
22678@section Daemons 22619@section Daemons
22679@cindex demons 22620@cindex demons
@@ -26651,10 +26592,6 @@ Buttons}).
26651You can do lots of strange stuff with the Gnus window & frame 26592You can do lots of strange stuff with the Gnus window & frame
26652configuration (@pxref{Window Layout}). 26593configuration (@pxref{Window Layout}).
26653 26594
26654@item
26655You can click on buttons instead of using the keyboard
26656(@pxref{Buttons}).
26657
26658@end itemize 26595@end itemize
26659 26596
26660 26597
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 33a760eb6f2..a2371a51b48 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,11 +1,64 @@
12010-10-04 Lars Magne Ingebrigtsen <larsi@gnus.org> 12010-10-04 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 2
3 * shr.el (shr-tag-blockquote): Ensure paragraph after quote, too.
4 (shr-get-image-data): Ensure against the cache file missing.
5
6 * nnimap.el (nnimap-finish-retrieve-group-infos): Message while waiting
7 for data.
8
9 * spam-report.el (spam-report-url-ping-plain): Don't query about
10 killing the process.
11
12 * shr.el (shr-render-td): Protect against too-wide text.
13
142010-10-04 Julien Danjou <julien@danjou.info>
15
16 * mml-smime.el (mml-smime-openssl-encrypt-query): Fix choices.
17 (mml-smime-openssl-sign-query): Fix gnus-completing-read call.
18
19 * gravatar.el (gravatar-retrieved): Kill buffer when gravatar has been
20 retrieved.
21
222010-10-04 Lars Magne Ingebrigtsen <larsi@gnus.org>
23
24 * shr.el (browse-url): Required.
25 (shr-ensure-paragraph): Don't insert a new newline after empty-ish
26 lines.
27 (shr-show-alt-text, shr-browse-image): New commands.
28 (shr-browse-url, shr-copy-url): New commands.
29
30 * gnus-sum.el (gnus-widen-article-window): New variable.
31 (gnus-summary-select-article-buffer): Use it.
32
33 * message.el (message-idna-to-ascii-rhs-1): Don't bug out on addresses
34 without @ signs.
35
362010-10-04 Michael Welsh Duggan <md5i@md5i.com> (tiny change)
37
38 * nnir.el (nnir-run-imap): Remove spurious space in search string.
39
402010-10-04 Julien Danjou <julien@danjou.info>
41
42 * gnus-util.el (gnus-emacs-completing-read): Mapcar collection to list,
43 for XEmacs.
44
452010-10-04 Lars Magne Ingebrigtsen <larsi@gnus.org>
46
47 * gnus-salt.el: Remove all gnus-carpal stuff -- it's not useful.
48
49 * nnimap.el (nnimap-open-connection): Allow tls as a synonym for ssl.
50 (nnimap-close-server): Implement.
51
3 * shr.el (shr-ensure-paragraph): Fix the non-empty line case. 52 * shr.el (shr-ensure-paragraph): Fix the non-empty line case.
4 (shr-insert): Tweak line breaking. 53 (shr-insert): Tweak line breaking.
5 (shr-insert): Handle <pre> better. 54 (shr-insert): Handle <pre> better.
6 (shr-tag-li): Get <li> indentation right. 55 (shr-tag-li): Get <li> indentation right.
7 (shr-tag-li): Get <li> indentation even righter. 56 (shr-tag-li): Get <li> indentation even righter.
8 (shr-tag-blockquote): Ensure paragraph start. 57 (shr-tag-blockquote): Ensure paragraph start.
58 (shr-make-table): Tweak table generation.
59 (shr-make-table): Fix typo.
60
61 * shr.el: Implement table rendering.
9 62
102010-10-04 Julien Danjou <julien@danjou.info> 632010-10-04 Julien Danjou <julien@danjou.info>
11 64
@@ -1458,8 +1511,6 @@
1458 * nnimap.el (nnimap-open-connection): If the user doesn't have a 1511 * nnimap.el (nnimap-open-connection): If the user doesn't have a
1459 /etc/services, supply some sensible port defaults. 1512 /etc/services, supply some sensible port defaults.
1460 1513
1461 * dgnushack.el: Define netrc-credentials.
1462
14632010-09-17 Julien Danjou <julien@danjou.info> 15142010-09-17 Julien Danjou <julien@danjou.info>
1464 1515
1465 * mm-decode.el (mm-text-html-renderer): Document gnus-article-html. 1516 * mm-decode.el (mm-text-html-renderer): Document gnus-article-html.
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 2ea5cce7846..d9e36ae6eae 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -1186,9 +1186,7 @@ The following commands are available:
1186(defun gnus-group-setup-buffer () 1186(defun gnus-group-setup-buffer ()
1187 (set-buffer (gnus-get-buffer-create gnus-group-buffer)) 1187 (set-buffer (gnus-get-buffer-create gnus-group-buffer))
1188 (unless (eq major-mode 'gnus-group-mode) 1188 (unless (eq major-mode 'gnus-group-mode)
1189 (gnus-group-mode) 1189 (gnus-group-mode)))
1190 (when gnus-carpal
1191 (gnus-carpal-setup-buffer 'group))))
1192 1190
1193(defun gnus-group-name-charset (method group) 1191(defun gnus-group-name-charset (method group)
1194 (if (null method) 1192 (if (null method)
diff --git a/lisp/gnus/gnus-salt.el b/lisp/gnus/gnus-salt.el
index 21b9d8954fe..a72d594a386 100644
--- a/lisp/gnus/gnus-salt.el
+++ b/lisp/gnus/gnus-salt.el
@@ -869,177 +869,6 @@ Two predefined functions are available:
869 (set-window-point 869 (set-window-point
870 (gnus-get-buffer-window (current-buffer) t) (cdr region)))))) 870 (gnus-get-buffer-window (current-buffer) t) (cdr region))))))
871 871
872;;;
873;;; gnus-carpal
874;;;
875
876(defvar gnus-carpal-group-buffer-buttons
877 '(("next" . gnus-group-next-unread-group)
878 ("prev" . gnus-group-prev-unread-group)
879 ("read" . gnus-group-read-group)
880 ("select" . gnus-group-select-group)
881 ("catch-up" . gnus-group-catchup-current)
882 ("new-news" . gnus-group-get-new-news-this-group)
883 ("toggle-sub" . gnus-group-unsubscribe-current-group)
884 ("subscribe" . gnus-group-unsubscribe-group)
885 ("kill" . gnus-group-kill-group)
886 ("yank" . gnus-group-yank-group)
887 ("describe" . gnus-group-describe-group)
888 "list"
889 ("subscribed" . gnus-group-list-groups)
890 ("all" . gnus-group-list-all-groups)
891 ("killed" . gnus-group-list-killed)
892 ("zombies" . gnus-group-list-zombies)
893 ("matching" . gnus-group-list-matching)
894 ("post" . gnus-group-post-news)
895 ("mail" . gnus-group-mail)
896 ("local" . (lambda () (interactive) (gnus-group-news 0)))
897 ("rescan" . gnus-group-get-new-news)
898 ("browse-foreign" . gnus-group-browse-foreign)
899 ("exit" . gnus-group-exit)))
900
901(defvar gnus-carpal-summary-buffer-buttons
902 '("mark"
903 ("read" . gnus-summary-mark-as-read-forward)
904 ("tick" . gnus-summary-tick-article-forward)
905 ("clear" . gnus-summary-clear-mark-forward)
906 ("expirable" . gnus-summary-mark-as-expirable)
907 "move"
908 ("scroll" . gnus-summary-next-page)
909 ("next-unread" . gnus-summary-next-unread-article)
910 ("prev-unread" . gnus-summary-prev-unread-article)
911 ("first" . gnus-summary-first-unread-article)
912 ("best" . gnus-summary-best-unread-article)
913 "article"
914 ("headers" . gnus-summary-toggle-header)
915 ("uudecode" . gnus-uu-decode-uu)
916 ("enter-digest" . gnus-summary-enter-digest-group)
917 ("fetch-parent" . gnus-summary-refer-parent-article)
918 "mail"
919 ("move" . gnus-summary-move-article)
920 ("copy" . gnus-summary-copy-article)
921 ("respool" . gnus-summary-respool-article)
922 "threads"
923 ("lower" . gnus-summary-lower-thread)
924 ("kill" . gnus-summary-kill-thread)
925 "post"
926 ("post" . gnus-summary-post-news)
927 ("local" . gnus-summary-news-other-window)
928 ("mail" . gnus-summary-mail-other-window)
929 ("followup" . gnus-summary-followup-with-original)
930 ("reply" . gnus-summary-reply-with-original)
931 ("cancel" . gnus-summary-cancel-article)
932 "misc"
933 ("exit" . gnus-summary-exit)
934 ("fed-up" . gnus-summary-catchup-and-goto-next-group)))
935
936(defvar gnus-carpal-server-buffer-buttons
937 '(("add" . gnus-server-add-server)
938 ("browse" . gnus-server-browse-server)
939 ("list" . gnus-server-list-servers)
940 ("kill" . gnus-server-kill-server)
941 ("yank" . gnus-server-yank-server)
942 ("copy" . gnus-server-copy-server)
943 ("exit" . gnus-server-exit)))
944
945(defvar gnus-carpal-browse-buffer-buttons
946 '(("subscribe" . gnus-browse-unsubscribe-current-group)
947 ("exit" . gnus-browse-exit)))
948
949(defvar gnus-carpal-group-buffer "*Carpal Group*")
950(defvar gnus-carpal-summary-buffer "*Carpal Summary*")
951(defvar gnus-carpal-server-buffer "*Carpal Server*")
952(defvar gnus-carpal-browse-buffer "*Carpal Browse*")
953
954(defvar gnus-carpal-attached-buffer nil)
955
956(defvar gnus-carpal-mode-hook nil
957 "*Hook run in carpal mode buffers.")
958
959(defvar gnus-carpal-button-face 'bold
960 "*Face used on carpal buttons.")
961
962(defvar gnus-carpal-header-face 'bold-italic
963 "*Face used on carpal buffer headers.")
964
965(defvar gnus-carpal-mode-map nil)
966(put 'gnus-carpal-mode 'mode-class 'special)
967
968(if gnus-carpal-mode-map
969 nil
970 (setq gnus-carpal-mode-map (make-keymap))
971 (suppress-keymap gnus-carpal-mode-map)
972 (define-key gnus-carpal-mode-map " " 'gnus-carpal-select)
973 (define-key gnus-carpal-mode-map "\r" 'gnus-carpal-select)
974 (define-key gnus-carpal-mode-map gnus-mouse-2 'gnus-carpal-mouse-select))
975
976(defun gnus-carpal-mode ()
977 "Major mode for clicking buttons.
978
979All normal editing commands are switched off.
980\\<gnus-carpal-mode-map>
981The following commands are available:
982
983\\{gnus-carpal-mode-map}"
984 (interactive)
985 (kill-all-local-variables)
986 (setq mode-line-modified (cdr gnus-mode-line-modified))
987 (setq major-mode 'gnus-carpal-mode)
988 (setq mode-name "Gnus Carpal")
989 (setq mode-line-process nil)
990 (use-local-map gnus-carpal-mode-map)
991 (buffer-disable-undo)
992 (setq buffer-read-only t)
993 (make-local-variable 'gnus-carpal-attached-buffer)
994 (gnus-run-mode-hooks 'gnus-carpal-mode-hook))
995
996(defun gnus-carpal-setup-buffer (type)
997 (let ((buffer (symbol-value (intern (format "gnus-carpal-%s-buffer" type)))))
998 (if (get-buffer buffer)
999 ()
1000 (with-current-buffer (gnus-get-buffer-create buffer)
1001 (gnus-carpal-mode)
1002 (setq gnus-carpal-attached-buffer
1003 (intern (format "gnus-%s-buffer" type)))
1004 (let ((buttons (symbol-value
1005 (intern (format "gnus-carpal-%s-buffer-buttons"
1006 type))))
1007 (buffer-read-only nil)
1008 button)
1009 (while buttons
1010 (setq button (car buttons)
1011 buttons (cdr buttons))
1012 (if (stringp button)
1013 (set-text-properties
1014 (point)
1015 (prog2 (insert button) (point) (insert " "))
1016 (list 'face gnus-carpal-header-face))
1017 (set-text-properties
1018 (point)
1019 (prog2 (insert (car button)) (point) (insert " "))
1020 (list 'gnus-callback (cdr button)
1021 'face gnus-carpal-button-face
1022 gnus-mouse-face-prop 'highlight))))
1023 (let ((fill-column (- (window-width) 2)))
1024 (fill-region (point-min) (point-max)))
1025 (set-window-point (get-buffer-window (current-buffer))
1026 (point-min)))))))
1027
1028(defun gnus-carpal-select ()
1029 "Select the button under point."
1030 (interactive)
1031 (let ((func (get-text-property (point) 'gnus-callback)))
1032 (if (null func)
1033 ()
1034 (pop-to-buffer (symbol-value gnus-carpal-attached-buffer))
1035 (call-interactively func))))
1036
1037(defun gnus-carpal-mouse-select (event)
1038 "Select the button under the mouse pointer."
1039 (interactive "e")
1040 (mouse-set-point event)
1041 (gnus-carpal-select))
1042
1043;;; Allow redefinition of functions. 872;;; Allow redefinition of functions.
1044(gnus-ems-redefine) 873(gnus-ems-redefine)
1045 874
diff --git a/lisp/gnus/gnus-srvr.el b/lisp/gnus/gnus-srvr.el
index 2b13f39ddb0..b532b740455 100644
--- a/lisp/gnus/gnus-srvr.el
+++ b/lisp/gnus/gnus-srvr.el
@@ -301,9 +301,7 @@ The following commands are available:
301 "Initialize the server buffer." 301 "Initialize the server buffer."
302 (unless (get-buffer gnus-server-buffer) 302 (unless (get-buffer gnus-server-buffer)
303 (with-current-buffer (gnus-get-buffer-create gnus-server-buffer) 303 (with-current-buffer (gnus-get-buffer-create gnus-server-buffer)
304 (gnus-server-mode) 304 (gnus-server-mode))))
305 (when gnus-carpal
306 (gnus-carpal-setup-buffer 'server)))))
307 305
308(defun gnus-server-prepare () 306(defun gnus-server-prepare ()
309 (gnus-set-format 'server-mode) 307 (gnus-set-format 'server-mode)
@@ -806,8 +804,6 @@ claim them."
806 (funcall gnus-group-prepare-function 804 (funcall gnus-group-prepare-function
807 gnus-level-killed 'ignore 1 'ignore)) 805 gnus-level-killed 'ignore 1 'ignore))
808 (gnus-get-buffer-create gnus-browse-buffer) 806 (gnus-get-buffer-create gnus-browse-buffer)
809 (when gnus-carpal
810 (gnus-carpal-setup-buffer 'browse))
811 (gnus-configure-windows 'browse) 807 (gnus-configure-windows 'browse)
812 (buffer-disable-undo) 808 (buffer-disable-undo)
813 (let ((buffer-read-only nil)) 809 (let ((buffer-read-only nil))
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index c77fd1c4aa3..a0e38d4f4f5 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -474,6 +474,12 @@ If nil, each group will get its own article buffer."
474 :group 'gnus-article-various 474 :group 'gnus-article-various
475 :type 'boolean) 475 :type 'boolean)
476 476
477(defcustom gnus-widen-article-window nil
478 "If non-nil, selecting the article buffer will display only the article buffer."
479 :version "24.1"
480 :group 'gnus-article-various
481 :type 'boolean)
482
477(defcustom gnus-break-pages t 483(defcustom gnus-break-pages t
478 "*If non-nil, do page breaking on articles. 484 "*If non-nil, do page breaking on articles.
479The page delimiter is specified by the `gnus-page-delimiter' 485The page delimiter is specified by the `gnus-page-delimiter'
@@ -3493,8 +3499,6 @@ display only a single character."
3493 ;; Fix by Sudish Joseph <joseph@cis.ohio-state.edu> 3499 ;; Fix by Sudish Joseph <joseph@cis.ohio-state.edu>
3494 (setq gnus-summary-buffer (set-buffer (gnus-get-buffer-create buffer))) 3500 (setq gnus-summary-buffer (set-buffer (gnus-get-buffer-create buffer)))
3495 (gnus-summary-mode group) 3501 (gnus-summary-mode group)
3496 (when gnus-carpal
3497 (gnus-carpal-setup-buffer 'summary))
3498 (when (gnus-group-quit-config group) 3502 (when (gnus-group-quit-config group)
3499 (set (make-local-variable 'gnus-single-article-buffer) nil)) 3503 (set (make-local-variable 'gnus-single-article-buffer) nil))
3500 (make-local-variable 'gnus-article-buffer) 3504 (make-local-variable 'gnus-article-buffer)
@@ -6935,7 +6939,11 @@ displayed, no centering will be performed."
6935 (error "There is no article buffer for this summary buffer") 6939 (error "There is no article buffer for this summary buffer")
6936 (unless (get-buffer-window gnus-article-buffer) 6940 (unless (get-buffer-window gnus-article-buffer)
6937 (gnus-summary-show-article)) 6941 (gnus-summary-show-article))
6938 (gnus-configure-windows 'article t) 6942 (gnus-configure-windows
6943 (if gnus-widen-article-window
6944 'only-article
6945 'article)
6946 t)
6939 (select-window (get-buffer-window gnus-article-buffer)))) 6947 (select-window (get-buffer-window gnus-article-buffer))))
6940 6948
6941(defun gnus-summary-universal-argument (arg) 6949(defun gnus-summary-universal-argument (arg)
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index 26d6e2c08b6..e4b8f8f87da 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -1602,7 +1602,11 @@ SPEC is a predicate specifier that contains stuff like `or', `and',
1602 initial-input history def) 1602 initial-input history def)
1603 "Call standard `completing-read-function'." 1603 "Call standard `completing-read-function'."
1604 (let ((completion-styles gnus-completion-styles)) 1604 (let ((completion-styles gnus-completion-styles))
1605 (completing-read prompt collection nil require-match initial-input history def))) 1605 (completing-read prompt
1606 ;; Old XEmacs (at least 21.4) expect an alist for
1607 ;; collection.
1608 (mapcar 'list collection)
1609 nil require-match initial-input history def)))
1606 1610
1607(defun gnus-ido-completing-read (prompt collection &optional require-match 1611(defun gnus-ido-completing-read (prompt collection &optional require-match
1608 initial-input history def) 1612 initial-input history def)
diff --git a/lisp/gnus/gnus-win.el b/lisp/gnus/gnus-win.el
index df883769b77..809e4c339be 100644
--- a/lisp/gnus/gnus-win.el
+++ b/lisp/gnus/gnus-win.el
@@ -68,12 +68,10 @@ used to display Gnus windows."
68(defvar gnus-buffer-configuration 68(defvar gnus-buffer-configuration
69 '((group 69 '((group
70 (vertical 1.0 70 (vertical 1.0
71 (group 1.0 point) 71 (group 1.0 point)))
72 (if gnus-carpal '(group-carpal 4))))
73 (summary 72 (summary
74 (vertical 1.0 73 (vertical 1.0
75 (summary 1.0 point) 74 (summary 1.0 point)))
76 (if gnus-carpal '(summary-carpal 4))))
77 (article 75 (article
78 (cond 76 (cond
79 (gnus-use-trees 77 (gnus-use-trees
@@ -84,16 +82,13 @@ used to display Gnus windows."
84 (t 82 (t
85 '(vertical 1.0 83 '(vertical 1.0
86 (summary 0.25 point) 84 (summary 0.25 point)
87 (if gnus-carpal '(summary-carpal 4))
88 (article 1.0))))) 85 (article 1.0)))))
89 (server 86 (server
90 (vertical 1.0 87 (vertical 1.0
91 (server 1.0 point) 88 (server 1.0 point)))
92 (if gnus-carpal '(server-carpal 2))))
93 (browse 89 (browse
94 (vertical 1.0 90 (vertical 1.0
95 (browse 1.0 point) 91 (browse 1.0 point)))
96 (if gnus-carpal '(browse-carpal 2))))
97 (message 92 (message
98 (vertical 1.0 93 (vertical 1.0
99 (message 1.0 point))) 94 (message 1.0 point)))
@@ -145,7 +140,6 @@ used to display Gnus windows."
145 (pipe 140 (pipe
146 (vertical 1.0 141 (vertical 1.0
147 (summary 0.25 point) 142 (summary 0.25 point)
148 (if gnus-carpal '(summary-carpal 4))
149 ("*Shell Command Output*" 1.0))) 143 ("*Shell Command Output*" 1.0)))
150 (bug 144 (bug
151 (vertical 1.0 145 (vertical 1.0
@@ -189,10 +183,6 @@ See the Gnus manual for an explanation of the syntax used.")
189 (edit-group . gnus-group-edit-buffer) 183 (edit-group . gnus-group-edit-buffer)
190 (edit-form . gnus-edit-form-buffer) 184 (edit-form . gnus-edit-form-buffer)
191 (edit-server . gnus-server-edit-buffer) 185 (edit-server . gnus-server-edit-buffer)
192 (group-carpal . gnus-carpal-group-buffer)
193 (summary-carpal . gnus-carpal-summary-buffer)
194 (server-carpal . gnus-carpal-server-buffer)
195 (browse-carpal . gnus-carpal-browse-buffer)
196 (edit-score . gnus-score-edit-buffer) 186 (edit-score . gnus-score-edit-buffer)
197 (message . gnus-message-buffer) 187 (message . gnus-message-buffer)
198 (mail . gnus-message-buffer) 188 (mail . gnus-message-buffer)
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el
index 4a5f0f79d64..069596289eb 100644
--- a/lisp/gnus/gnus.el
+++ b/lisp/gnus/gnus.el
@@ -1626,11 +1626,6 @@ slower."
1626 (function-item mail-extract-address-components) 1626 (function-item mail-extract-address-components)
1627 (function :tag "Other"))) 1627 (function :tag "Other")))
1628 1628
1629(defcustom gnus-carpal nil
1630 "*If non-nil, display clickable icons."
1631 :group 'gnus-meta
1632 :type 'boolean)
1633
1634(defcustom gnus-shell-command-separator ";" 1629(defcustom gnus-shell-command-separator ";"
1635 "String used to separate shell commands." 1630 "String used to separate shell commands."
1636 :group 'gnus-files 1631 :group 'gnus-files
@@ -2803,7 +2798,7 @@ gnus-registry.el will populate this if it's loaded.")
2803 gnus-convert-image-to-gray-x-face gnus-convert-face-to-png 2798 gnus-convert-image-to-gray-x-face gnus-convert-face-to-png
2804 gnus-face-from-file) 2799 gnus-face-from-file)
2805 ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree 2800 ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree
2806 gnus-tree-open gnus-tree-close gnus-carpal-setup-buffer) 2801 gnus-tree-open gnus-tree-close)
2807 ("gnus-srvr" gnus-enter-server-buffer gnus-server-set-info 2802 ("gnus-srvr" gnus-enter-server-buffer gnus-server-set-info
2808 gnus-server-server-name) 2803 gnus-server-server-name)
2809 ("gnus-srvr" gnus-browse-foreign-server) 2804 ("gnus-srvr" gnus-browse-foreign-server)
diff --git a/lisp/gnus/gravatar.el b/lisp/gnus/gravatar.el
index d4dfb763167..50b0ba1d636 100644
--- a/lisp/gnus/gravatar.el
+++ b/lisp/gnus/gravatar.el
@@ -125,7 +125,8 @@ You can provide a list of argument to pass to CB in CBARGS."
125 (if (plist-get status :error) 125 (if (plist-get status :error)
126 ;; Error happened. 126 ;; Error happened.
127 (apply cb 'error cbargs) 127 (apply cb 'error cbargs)
128 (apply cb (gravatar-data->image) cbargs))) 128 (apply cb (gravatar-data->image) cbargs))
129 (kill-buffer (current-buffer)))
129 130
130(provide 'gravatar) 131(provide 'gravatar)
131 132
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index d5a620b3b74..546f13af815 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -5736,7 +5736,9 @@ subscribed address (and not the additional To and Cc header contents)."
5736 (mapcar (lambda (rhs) (or (cadr (split-string rhs "@")) "")) 5736 (mapcar (lambda (rhs) (or (cadr (split-string rhs "@")) ""))
5737 (mapcar 'downcase 5737 (mapcar 'downcase
5738 (mapcar 5738 (mapcar
5739 'cadr 5739 (lambda (elem)
5740 (or (cadr elem)
5741 ""))
5740 (mail-extract-address-components field t)))))) 5742 (mail-extract-address-components field t))))))
5741 ;; Note that `rhs' will be "" if the address does not have 5743 ;; Note that `rhs' will be "" if the address does not have
5742 ;; the domain part, i.e., if it is a local user's address. 5744 ;; the domain part, i.e., if it is a local user's address.
diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el
index 62e742f93a1..188717e5921 100644
--- a/lisp/gnus/mml-smime.el
+++ b/lisp/gnus/mml-smime.el
@@ -162,7 +162,7 @@ Whether the passphrase is cached at all is controlled by
162 (and from (smime-get-key-by-email from))) 162 (and from (smime-get-key-by-email from)))
163 (smime-get-key-by-email 163 (smime-get-key-by-email
164 (gnus-completing-read "Sign this part with what signature" 164 (gnus-completing-read "Sign this part with what signature"
165 smime-keys nil nil 165 (mapcar 'car smime-keys) nil nil nil
166 (and (listp (car-safe smime-keys)) 166 (and (listp (car-safe smime-keys))
167 (caar smime-keys)))))))) 167 (caar smime-keys))))))))
168 168
@@ -221,7 +221,7 @@ Whether the passphrase is cached at all is controlled by
221 (while (not done) 221 (while (not done)
222 (ecase (read (gnus-completing-read 222 (ecase (read (gnus-completing-read
223 "Fetch certificate from" 223 "Fetch certificate from"
224 '(("dns") ("ldap") ("file")) t nil nil 224 '("dns" "ldap" "file") t nil nil
225 "ldap")) 225 "ldap"))
226 (dns (setq certs (append certs 226 (dns (setq certs (append certs
227 (mml-smime-get-dns-cert)))) 227 (mml-smime-get-dns-cert))))
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 0aaa797b835..c3c25cbf194 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -316,7 +316,7 @@ textual parts.")
316 (setq port (or nnimap-server-port "imap")) 316 (setq port (or nnimap-server-port "imap"))
317 'starttls)) 317 'starttls))
318 '("imap")) 318 '("imap"))
319 ((eq nnimap-stream 'ssl) 319 ((memq nnimap-stream '(ssl tls))
320 (open-tls-stream 320 (open-tls-stream
321 "*nnimap*" (current-buffer) nnimap-address 321 "*nnimap*" (current-buffer) nnimap-address
322 (setq port 322 (setq port
@@ -324,7 +324,9 @@ textual parts.")
324 (if (netrc-find-service-number "imaps") 324 (if (netrc-find-service-number "imaps")
325 "imaps" 325 "imaps"
326 "993")))) 326 "993"))))
327 '("143" "993" "imap" "imaps")))) 327 '("143" "993" "imap" "imaps"))
328 (t
329 (error "Unknown stream type: %s" nnimap-stream))))
328 connection-result login-result credentials) 330 connection-result login-result credentials)
329 (setf (nnimap-process nnimap-object) 331 (setf (nnimap-process nnimap-object)
330 (get-buffer-process (current-buffer))) 332 (get-buffer-process (current-buffer)))
@@ -424,7 +426,10 @@ textual parts.")
424 result)) 426 result))
425 427
426(deffoo nnimap-close-server (&optional server) 428(deffoo nnimap-close-server (&optional server)
427 t) 429 (when (nnoo-change-server 'nnimap server nil)
430 (ignore-errors
431 (delete-process (get-buffer-process (nnimap-buffer))))
432 t))
428 433
429(deffoo nnimap-request-close () 434(deffoo nnimap-request-close ()
430 t) 435 t)
@@ -974,7 +979,7 @@ textual parts.")
974 (nnimap-possibly-change-group nil server)) 979 (nnimap-possibly-change-group nil server))
975 (with-current-buffer (nnimap-buffer) 980 (with-current-buffer (nnimap-buffer)
976 ;; Wait for the final data to trickle in. 981 ;; Wait for the final data to trickle in.
977 (when (nnimap-wait-for-response (cadar sequences)) 982 (when (nnimap-wait-for-response (cadar sequences) t)
978 ;; Now we should have all the data we need, no matter whether 983 ;; Now we should have all the data we need, no matter whether
979 ;; we're QRESYNCING, fetching all the flags from scratch, or 984 ;; we're QRESYNCING, fetching all the flags from scratch, or
980 ;; just fetching the last 100 flags per group. 985 ;; just fetching the last 100 flags per group.
@@ -1251,7 +1256,7 @@ textual parts.")
1251 (point-min)) 1256 (point-min))
1252 t))) 1257 t)))
1253 (when messagep 1258 (when messagep
1254 (message "Read %dKB" (/ (buffer-size) 1000))) 1259 (message "nnimap read %dk" (/ (buffer-size) 1000)))
1255 (nnheader-accept-process-output process) 1260 (nnheader-accept-process-output process)
1256 (goto-char (point-max))) 1261 (goto-char (point-max)))
1257 openp)) 1262 openp))
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el
index de304bf216b..baba9e0098a 100644
--- a/lisp/gnus/nnir.el
+++ b/lisp/gnus/nnir.el
@@ -985,7 +985,7 @@ details on the language and supported extensions"
985 (message "Searching %s..." group) 985 (message "Searching %s..." group)
986 (let ((arts 0) 986 (let ((arts 0)
987 (result 987 (result
988 (nnimap-command "UID SEARCH %s" 988 (nnimap-command "UID SEARCH %s"
989 (if (string= criteria "") 989 (if (string= criteria "")
990 qstring 990 qstring
991 (nnir-imap-make-query criteria qstring) 991 (nnir-imap-make-query criteria qstring)
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el
index c2c2c2ed280..59d7b784a1f 100644
--- a/lisp/gnus/shr.el
+++ b/lisp/gnus/shr.el
@@ -30,6 +30,8 @@
30 30
31;;; Code: 31;;; Code:
32 32
33(require 'browse-url)
34
33(defgroup shr nil 35(defgroup shr nil
34 "Simple HTML Renderer" 36 "Simple HTML Renderer"
35 :group 'mail) 37 :group 'mail)
@@ -57,6 +59,16 @@ fit these criteria."
57 59
58(defvar shr-width 70) 60(defvar shr-width 70)
59 61
62(defvar shr-map
63 (let ((map (make-sparse-keymap)))
64 (define-key map "a" 'shr-show-alt-text)
65 (define-key map "i" 'shr-browse-image)
66 (define-key map "I" 'shr-insert-image)
67 (define-key map "u" 'shr-copy-url)
68 (define-key map "v" 'shr-browse-url)
69 (define-key map "\r" 'shr-browse-url)
70 map))
71
60(defun shr-transform-dom (dom) 72(defun shr-transform-dom (dom)
61 (let ((result (list (pop dom)))) 73 (let ((result (list (pop dom))))
62 (dolist (arg (pop dom)) 74 (dolist (arg (pop dom))
@@ -97,7 +109,9 @@ fit these criteria."
97(defun shr-ensure-paragraph () 109(defun shr-ensure-paragraph ()
98 (unless (bobp) 110 (unless (bobp)
99 (if (bolp) 111 (if (bolp)
100 (unless (eql (char-after (- (point) 2)) ?\n) 112 (unless (save-excursion
113 (forward-line -1)
114 (looking-at " *$"))
101 (insert "\n")) 115 (insert "\n"))
102 (if (save-excursion 116 (if (save-excursion
103 (beginning-of-line) 117 (beginning-of-line)
@@ -129,17 +143,53 @@ fit these criteria."
129 143
130(defun shr-tag-a (cont) 144(defun shr-tag-a (cont)
131 (let ((url (cdr (assq :href cont))) 145 (let ((url (cdr (assq :href cont)))
146 (start (point))
132 shr-start) 147 shr-start)
133 (shr-generic cont) 148 (shr-generic cont)
134 (widget-convert-button 149 (widget-convert-button
135 'link shr-start (point) 150 'link (or shr-start start) (point)
136 :action 'shr-browse-url 151 :help-echo url)
137 :url url 152 (put-text-property (or shr-start start) (point) 'keymap shr-map)
138 :keymap widget-keymap 153 (put-text-property (or shr-start start) (point) 'shr-url url)))
139 :help-echo url))) 154
140 155(defun shr-browse-url ()
141(defun shr-browse-url (widget &rest stuff) 156 "Browse the URL under point."
142 (browse-url (widget-get widget :url))) 157 (interactive)
158 (let ((url (get-text-property (point) 'shr-url)))
159 (if (not url)
160 (message "No link under point")
161 (browse-url url))))
162
163(defun shr-copy-url ()
164 "Copy the URL under point to the kill ring.
165If called twice, then try to fetch the URL and see whether it
166redirects somewhere else."
167 (interactive)
168 (let ((url (get-text-property (point) 'shr-url)))
169 (cond
170 ((not url)
171 (message "No URL under point"))
172 ;; Resolve redirected URLs.
173 ((equal url (car kill-ring))
174 (url-retrieve
175 url
176 (lambda (a)
177 (when (and (consp a)
178 (eq (car a) :redirect))
179 (with-temp-buffer
180 (insert (cadr a))
181 (goto-char (point-min))
182 ;; Remove common tracking junk from the URL.
183 (when (re-search-forward ".utm_.*" nil t)
184 (replace-match "" t t))
185 (message "Copied %s" (buffer-string))
186 (copy-region-as-kill (point-min) (point-max)))))))
187 ;; Copy the URL to the kill ring.
188 (t
189 (with-temp-buffer
190 (insert url)
191 (copy-region-as-kill (point-min) (point-max))
192 (message "Copied %s" url))))))
143 193
144(defun shr-tag-img (cont) 194(defun shr-tag-img (cont)
145 (when (and (> (current-column) 0) 195 (when (and (> (current-column) 0)
@@ -162,8 +212,28 @@ fit these criteria."
162 (list (current-buffer) start (point-marker)) 212 (list (current-buffer) start (point-marker))
163 t))) 213 t)))
164 (insert " ") 214 (insert " ")
215 (put-text-property start (point) 'keymap shr-map)
216 (put-text-property start (point) 'shr-alt alt)
217 (put-text-property start (point) 'shr-image url)
165 (setq shr-state 'image)))) 218 (setq shr-state 'image))))
166 219
220(defun shr-show-alt-text ()
221 "Show the ALT text of the image under point."
222 (interactive)
223 (let ((text (get-text-property (point) 'shr-alt)))
224 (if (not text)
225 (message "No image under point")
226 (message "%s" text))))
227
228(defun shr-browse-image ()
229 "Browse the image under point."
230 (interactive)
231 (let ((url (get-text-property (point) 'shr-image)))
232 (if (not url)
233 (message "No image under point")
234 (message "Browsing %s..." url)
235 (browse-url url))))
236
167(defun shr-image-fetched (status buffer start end) 237(defun shr-image-fetched (status buffer start end)
168 (when (and (buffer-name buffer) 238 (when (and (buffer-name buffer)
169 (not (plist-get status :error))) 239 (not (plist-get status :error)))
@@ -222,7 +292,8 @@ fit these criteria."
222(defun shr-tag-blockquote (cont) 292(defun shr-tag-blockquote (cont)
223 (shr-ensure-paragraph) 293 (shr-ensure-paragraph)
224 (let ((shr-indentation (+ shr-indentation 4))) 294 (let ((shr-indentation (+ shr-indentation 4)))
225 (shr-generic cont))) 295 (shr-generic cont))
296 (shr-ensure-paragraph))
226 297
227(defun shr-ensure-newline () 298(defun shr-ensure-newline ()
228 (unless (zerop (current-column)) 299 (unless (zerop (current-column))
@@ -254,7 +325,7 @@ fit these criteria."
254 (setq first nil) 325 (setq first nil)
255 (when (and (bolp) 326 (when (and (bolp)
256 (> shr-indentation 0)) 327 (> shr-indentation 0))
257 (insert (make-string shr-indentation ? ))) 328 (shr-indent))
258 ;; The shr-start is a special variable that is used to pass 329 ;; The shr-start is a special variable that is used to pass
259 ;; upwards the first point in the buffer where the text really 330 ;; upwards the first point in the buffer where the text really
260 ;; starts. 331 ;; starts.
@@ -267,15 +338,20 @@ fit these criteria."
267 (insert " ") 338 (insert " ")
268 (setq shr-state 'space)))))) 339 (setq shr-state 'space))))))
269 340
341(defun shr-indent ()
342 (insert (make-string shr-indentation ? )))
343
270(defun shr-get-image-data (url) 344(defun shr-get-image-data (url)
271 "Get image data for URL. 345 "Get image data for URL.
272Return a string with image data." 346Return a string with image data."
273 (with-temp-buffer 347 (with-temp-buffer
274 (mm-disable-multibyte) 348 (mm-disable-multibyte)
275 (url-cache-extract (url-cache-create-filename url)) 349 (when (ignore-errors
276 (when (or (search-forward "\n\n" nil t) 350 (url-cache-extract (url-cache-create-filename url))
277 (search-forward "\r\n\r\n" nil t)) 351 t)
278 (buffer-substring (point) (point-max))))) 352 (when (or (search-forward "\n\n" nil t)
353 (search-forward "\r\n\r\n" nil t))
354 (buffer-substring (point) (point-max))))))
279 355
280(defvar shr-list-mode nil) 356(defvar shr-list-mode nil)
281 357
@@ -328,6 +404,140 @@ Return a string with image data."
328 (apply #'shr-fontize-cont cont types) 404 (apply #'shr-fontize-cont cont types)
329 (shr-ensure-paragraph)) 405 (shr-ensure-paragraph))
330 406
407(defun shr-tag-table (cont)
408 (shr-ensure-paragraph)
409 (setq cont (or (cdr (assq 'tbody cont))
410 cont))
411 (let* ((columns (shr-column-specs cont))
412 (suggested-widths (shr-pro-rate-columns columns))
413 (sketch (shr-make-table cont suggested-widths))
414 (sketch-widths (shr-table-widths sketch (length suggested-widths))))
415 (shr-insert-table (shr-make-table cont sketch-widths t) sketch-widths)))
416
417(defun shr-insert-table (table widths)
418 (shr-insert-table-ruler widths)
419 (dolist (row table)
420 (let ((start (point))
421 (height (let ((max 0))
422 (dolist (column row)
423 (setq max (max max (cadr column))))
424 max)))
425 (dotimes (i height)
426 (shr-indent)
427 (insert "|\n"))
428 (dolist (column row)
429 (goto-char start)
430 (let ((lines (split-string (nth 2 column) "\n")))
431 (dolist (line lines)
432 (when (> (length line) 0)
433 (end-of-line)
434 (insert line "|")
435 (forward-line 1)))
436 ;; Add blank lines at padding at the bottom of the TD,
437 ;; possibly.
438 (dotimes (i (- height (length lines)))
439 (end-of-line)
440 (insert (make-string (length (car lines)) ? ) "|")
441 (forward-line 1)))))
442 (shr-insert-table-ruler widths)))
443
444(defun shr-insert-table-ruler (widths)
445 (shr-indent)
446 (insert "+")
447 (dotimes (i (length widths))
448 (insert (make-string (aref widths i) ?-) ?+))
449 (insert "\n"))
450
451(defun shr-table-widths (table length)
452 (let ((widths (make-vector length 0)))
453 (dolist (row table)
454 (let ((i 0))
455 (dolist (column row)
456 (aset widths i (max (aref widths i)
457 (car column)))
458 (incf i))))
459 widths))
460
461(defun shr-make-table (cont widths &optional fill)
462 (let ((trs nil))
463 (dolist (row cont)
464 (when (eq (car row) 'tr)
465 (let ((i 0)
466 (tds nil))
467 (dolist (column (cdr row))
468 (when (memq (car column) '(td th))
469 (push (shr-render-td (cdr column) (aref widths i) fill)
470 tds)
471 (setq i (1+ i))))
472 (push (nreverse tds) trs))))
473 (nreverse trs)))
474
475(defun shr-render-td (cont width fill)
476 (with-temp-buffer
477 (let ((shr-width width)
478 (shr-indentation 0))
479 (shr-generic cont))
480 (while (re-search-backward "\n *$" nil t)
481 (delete-region (match-beginning 0) (match-end 0)))
482 (goto-char (point-min))
483 (let ((max 0))
484 (while (not (eobp))
485 (end-of-line)
486 (setq max (max max (current-column)))
487 (forward-line 1))
488 (when fill
489 (goto-char (point-min))
490 (while (not (eobp))
491 (end-of-line)
492 (when (> (- width (current-column)) 0)
493 (insert (make-string (- width (current-column)) ? )))
494 (forward-line 1)))
495 (list max (count-lines (point-min) (point-max)) (buffer-string)))))
496
497(defun shr-pro-rate-columns (columns)
498 (let ((total-percentage 0)
499 (widths (make-vector (length columns) 0)))
500 (dotimes (i (length columns))
501 (incf total-percentage (aref columns i)))
502 (setq total-percentage (/ 1.0 total-percentage))
503 (dotimes (i (length columns))
504 (aset widths i (max (truncate (* (aref columns i)
505 total-percentage
506 shr-width))
507 10)))
508 widths))
509
510;; Return a summary of the number and shape of the TDs in the table.
511(defun shr-column-specs (cont)
512 (let ((columns (make-vector (shr-max-columns cont) 1)))
513 (dolist (row cont)
514 (when (eq (car row) 'tr)
515 (let ((i 0))
516 (dolist (column (cdr row))
517 (when (memq (car column) '(td th))
518 (let ((width (cdr (assq :width (cdr column)))))
519 (when (and width
520 (string-match "\\([0-9]+\\)%" width))
521 (aset columns i
522 (/ (string-to-number (match-string 1 width))
523 100.0)))))
524 (setq i (1+ i))))))
525 columns))
526
527(defun shr-count (cont elem)
528 (let ((i 0))
529 (dolist (sub cont)
530 (when (eq (car sub) elem)
531 (setq i (1+ i))))
532 i))
533
534(defun shr-max-columns (cont)
535 (let ((max 0))
536 (dolist (row cont)
537 (when (eq (car row) 'tr)
538 (setq max (max max (shr-count (cdr row) 'td)))))
539 max))
540
331(provide 'shr) 541(provide 'shr)
332 542
333;;; shr.el ends here 543;;; shr.el ends here
diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el
index e73444e85c0..30e0ae58f05 100644
--- a/lisp/gnus/spam-report.el
+++ b/lisp/gnus/spam-report.el
@@ -256,6 +256,7 @@ This is initialized based on `user-mail-address'."
256 80)) 256 80))
257 (error "Could not open connection to %s" host)) 257 (error "Could not open connection to %s" host))
258 (set-marker (process-mark tcp-connection) (point-min)) 258 (set-marker (process-mark tcp-connection) (point-min))
259 (gnus-set-process-query-on-exit-flag tcp-connection nil)
259 (process-send-string 260 (process-send-string
260 tcp-connection 261 tcp-connection
261 (format "GET %s HTTP/1.1\nUser-Agent: %s\nHost: %s\n\n" 262 (format "GET %s HTTP/1.1\nUser-Agent: %s\nHost: %s\n\n"