diff options
| author | Gnus developers | 2010-10-31 00:13:12 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2010-10-31 00:13:12 +0000 |
| commit | 953d41c48214643adaca4e51ca80f67a05719f1b (patch) | |
| tree | a8a8f3914fc6b229ea6c5d0a813aff753e7e0fa0 | |
| parent | 8a500a91a222c6c8e9ae6c72e233f1512520504a (diff) | |
| download | emacs-953d41c48214643adaca4e51ca80f67a05719f1b.tar.gz emacs-953d41c48214643adaca4e51ca80f67a05719f1b.zip | |
Merge changes made in Gnus trunk.
nnir.el: General clean-up, and reimplementation of various bits.
nnir.el (nnir-search-engine): Ressurect variable, since it's used later in the file.
shr.el (shr-generic): The text nodes should be text, not :text.
nnir.el: Move defvars around to silence compiler warnings.
shr.el (shr-tag-img): Output "*" instead of "[img]".
| -rw-r--r-- | lisp/gnus/ChangeLog | 36 | ||||
| -rw-r--r-- | lisp/gnus/nnir.el | 940 | ||||
| -rw-r--r-- | lisp/gnus/shr.el | 6 |
3 files changed, 494 insertions, 488 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index ab16707d386..a488a164302 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,39 @@ | |||
| 1 | 2010-10-30 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * shr.el (shr-tag-img): Output "*" instead of "[img]". | ||
| 4 | |||
| 5 | 2010-10-30 Andrew Cohen <cohen@andy.bu.edu> | ||
| 6 | |||
| 7 | * nnir.el move defvar, defcustom around to keep file organized and keep | ||
| 8 | byte-compiler quiet. | ||
| 9 | (nnir-read-parms): accept search-engine as arg. | ||
| 10 | (nnir-run-query): pass search-engine as arg. | ||
| 11 | (nnir-search-engine): remove. | ||
| 12 | |||
| 13 | 2010-10-30 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 14 | |||
| 15 | * shr.el (shr-generic): The text nodes should be text, not :text. | ||
| 16 | |||
| 17 | * nnir.el (nnir-search-engine): Ressurect variable, since it's used | ||
| 18 | later in the file. | ||
| 19 | |||
| 20 | 2010-10-30 Andrew Cohen <cohen@andy.bu.edu> | ||
| 21 | |||
| 22 | * nnir.el: general clean up. allow searching with multiple | ||
| 23 | engines. allow separate extra-parameters for each engine. batch queries | ||
| 24 | when possible. | ||
| 25 | (nnir-imap-default-search-key,nnir-method-default-engines): add | ||
| 26 | customize interface. | ||
| 27 | (nnir-run-gmane): new engine. | ||
| 28 | (nnir-engines): use it. qualify all prompts with engine name. | ||
| 29 | (nnir-search-engine): remove global variable. | ||
| 30 | (nnir-run-hyrex): restore for now. | ||
| 31 | (nnir-extra-parms,nnir-search-history): new variables. | ||
| 32 | (gnus-group-make-nnir-group): use them. | ||
| 33 | (nnir-group-server): remove in favor of gnus-group-server. | ||
| 34 | (nnir-request-group): avoid searching twice. | ||
| 35 | (nnir-sort-groups-by-server): new function. | ||
| 36 | |||
| 1 | 2010-10-30 Julien Danjou <julien@danjou.info> | 37 | 2010-10-30 Julien Danjou <julien@danjou.info> |
| 2 | 38 | ||
| 3 | * gnus-group.el: Remove gnus-group-fetch-control. | 39 | * gnus-group.el: Remove gnus-group-fetch-control. |
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index adb8d094717..9e3dd9c523f 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el | |||
| @@ -32,161 +32,40 @@ | |||
| 32 | 32 | ||
| 33 | ;; TODO: Documentation in the Gnus manual | 33 | ;; TODO: Documentation in the Gnus manual |
| 34 | 34 | ||
| 35 | ;; From: Reiner Steib | 35 | ;; Where in the existing gnus manual would this fit best? |
| 36 | ;; Subject: Re: Including nnir.el | ||
| 37 | ;; Newsgroups: gmane.emacs.gnus.general | ||
| 38 | ;; Message-ID: <v9d5dnp6aq.fsf@marauder.physik.uni-ulm.de> | ||
| 39 | ;; Date: 2006-06-05 22:49:01 GMT | ||
| 40 | ;; | ||
| 41 | ;; On Sun, Jun 04 2006, Sascha Wilde wrote: | ||
| 42 | ;; | ||
| 43 | ;; > The one thing most hackers like to forget: Documentation. By now the | ||
| 44 | ;; > documentation is only in the comments at the head of the source, I | ||
| 45 | ;; > would use it as basis to cook up some minimal texinfo docs. | ||
| 46 | ;; > | ||
| 47 | ;; > Where in the existing gnus manual would this fit best? | ||
| 48 | |||
| 49 | ;; Maybe (info "(gnus)Combined Groups") for a general description. | ||
| 50 | ;; `gnus-group-make-nnir-group' might be described in (info | ||
| 51 | ;; "(gnus)Foreign Groups") as well. | ||
| 52 | |||
| 53 | 36 | ||
| 54 | ;; The most recent version of this can always be fetched from the Gnus | 37 | ;; What does it do? Well, it allows you to search your mail using |
| 55 | ;; repository. See http://www.gnus.org/ for more information. | 38 | ;; some search engine (imap, namazu, swish-e, gmane and others -- see |
| 56 | 39 | ;; later) by typing `G G' in the Group buffer. You will then get a | |
| 57 | ;; This code is still in the development stage but I'd like other | 40 | ;; buffer which shows all articles matching the query, sorted by |
| 58 | ;; people to have a look at it. Please do not hesitate to contact me | 41 | ;; Retrieval Status Value (score). |
| 59 | ;; with your ideas. | ||
| 60 | |||
| 61 | ;; What does it do? Well, it allows you to index your mail using some | ||
| 62 | ;; search engine (freeWAIS-sf, swish-e and others -- see later), | ||
| 63 | ;; then type `G G' in the Group buffer and issue a query to the search | ||
| 64 | ;; engine. You will then get a buffer which shows all articles | ||
| 65 | ;; matching the query, sorted by Retrieval Status Value (score). | ||
| 66 | 42 | ||
| 67 | ;; When looking at the retrieval result (in the Summary buffer) you | 43 | ;; When looking at the retrieval result (in the Summary buffer) you |
| 68 | ;; can type `G T' (aka M-x gnus-summary-nnir-goto-thread RET) on an | 44 | ;; can type `G T' (aka M-x gnus-summary-nnir-goto-thread RET) on an |
| 69 | ;; article. You will be teleported into the group this article came | 45 | ;; article. You will be teleported into the group this article came |
| 70 | ;; from, showing the thread this article is part of. (See below for | 46 | ;; from, showing the thread this article is part of. |
| 71 | ;; restrictions.) | ||
| 72 | |||
| 73 | ;; The Lisp installation is simple: just put this file on your | ||
| 74 | ;; load-path, byte-compile it, and load it from ~/.gnus or something. | ||
| 75 | ;; This will install a new command `G G' in your Group buffer for | ||
| 76 | ;; searching your mail. Note that you also need to configure a number | ||
| 77 | ;; of variables, as described below. | ||
| 78 | 47 | ||
| 79 | ;; Restrictions: | 48 | ;; The Lisp setup may involve setting a few variables and setting up the |
| 80 | ;; | ||
| 81 | ;; * This expects that you use nnml or another one-file-per-message backend, | ||
| 82 | ;; because the others doesn't support nnfolder. | ||
| 83 | ;; * It can only search the mail backend's which are supported by one | ||
| 84 | ;; search engine, because of different query languages. | ||
| 85 | ;; * There are restrictions to the Wais setup. | ||
| 86 | ;; * There are restrictions to the imap setup. | ||
| 87 | ;; * gnus-summary-nnir-goto-thread: Fetches whole group first, before | ||
| 88 | ;; limiting to the right articles. This is much too slow, of | ||
| 89 | ;; course. May issue a query for number of articles to fetch; you | ||
| 90 | ;; must accept the default of all articles at this point or things | ||
| 91 | ;; may break. | ||
| 92 | |||
| 93 | ;; The Lisp setup involves setting a few variables and setting up the | ||
| 94 | ;; search engine. You can define the variables in the server definition | 49 | ;; search engine. You can define the variables in the server definition |
| 95 | ;; like this : | 50 | ;; like this : |
| 96 | ;; (setq gnus-secondary-select-methods '( | 51 | ;; (setq gnus-secondary-select-methods '( |
| 97 | ;; (nnimap "" (nnimap-address "localhost") | 52 | ;; (nnimap "" (nnimap-address "localhost") |
| 98 | ;; (nnir-search-engine namazu) | 53 | ;; (nnir-search-engine namazu) |
| 99 | ;; ))) | 54 | ;; ))) |
| 100 | ;; Or you can define the global ones. The variables set in the mailer- | 55 | ;; The main variable to set is `nnir-search-engine'. Choose one of |
| 101 | ;; definition will be used first. | 56 | ;; the engines listed in `nnir-engines'. (Actually `nnir-engines' is |
| 102 | ;; The variable to set is `nnir-search-engine'. Choose one of the engines | 57 | ;; an alist, type `C-h v nnir-engines RET' for more information; this |
| 103 | ;; listed in `nnir-engines'. (Actually `nnir-engines' is an alist, | 58 | ;; includes examples for setting `nnir-search-engine', too.) |
| 104 | ;; type `C-h v nnir-engines RET' for more information; this includes | ||
| 105 | ;; examples for setting `nnir-search-engine', too.) | ||
| 106 | ;; | ||
| 107 | ;; The variable nnir-mail-backend isn't used anymore. | ||
| 108 | ;; | ||
| 109 | 59 | ||
| 110 | ;; You must also set up a search engine. I'll tell you about the two | 60 | ;; If you use one of the local indices (namazu, find-grep, swish) you |
| 111 | ;; search engines currently supported: | 61 | ;; must also set up a search engine backend. |
| 112 | 62 | ||
| 113 | ;; 1. freeWAIS-sf | 63 | ;; 1. Namazu |
| 114 | ;; | ||
| 115 | ;; As always with freeWAIS-sf, you need a so-called `format file'. I | ||
| 116 | ;; use the following file: | ||
| 117 | ;; | ||
| 118 | ;; ,----- | ||
| 119 | ;; | # Kai's format file for freeWAIS-sf for indexing mails. | ||
| 120 | ;; | # Each mail is in a file, much like the MH format. | ||
| 121 | ;; | | ||
| 122 | ;; | # Document separator should never match -- each file is a document. | ||
| 123 | ;; | record-sep: /^@this regex should never match@$/ | ||
| 124 | ;; | | ||
| 125 | ;; | # Searchable fields specification. | ||
| 126 | ;; | | ||
| 127 | ;; | region: /^[sS]ubject:/ /^[sS]ubject: */ | ||
| 128 | ;; | subject "Subject header" stemming TEXT BOTH | ||
| 129 | ;; | end: /^[^ \t]/ | ||
| 130 | ;; | | ||
| 131 | ;; | region: /^([tT][oO]|[cC][cC]):/ /^([tT][oO]|[cC][cC]): */ | ||
| 132 | ;; | to "To and Cc headers" SOUNDEX BOTH | ||
| 133 | ;; | end: /^[^ \t]/ | ||
| 134 | ;; | | ||
| 135 | ;; | region: /^[fF][rR][oO][mM]:/ /^[fF][rR][oO][mM]: */ | ||
| 136 | ;; | from "From header" SOUNDEX BOTH | ||
| 137 | ;; | end: /^[^ \t]/ | ||
| 138 | ;; | | ||
| 139 | ;; | region: /^$/ | ||
| 140 | ;; | stemming TEXT GLOBAL | ||
| 141 | ;; | end: /^@this regex should never match@$/ | ||
| 142 | ;; `----- | ||
| 143 | ;; | ||
| 144 | ;; 1998-07-22: waisindex would dump core on me for large articles with | ||
| 145 | ;; the above settings. I used /^$/ as the end regex for the global | ||
| 146 | ;; field. That seemed to work okay. | ||
| 147 | |||
| 148 | ;; There is a Perl module called `WAIS.pm' which is available from | ||
| 149 | ;; CPAN as well as ls6-ftp.cs.uni-dortmund.de:/pub/wais/Perl. This | ||
| 150 | ;; module comes with a nifty tool called `makedb', which I use for | ||
| 151 | ;; indexing. Here's my `makedb.conf': | ||
| 152 | ;; | ||
| 153 | ;; ,----- | ||
| 154 | ;; | # Config file for makedb | ||
| 155 | ;; | | ||
| 156 | ;; | # Global options | ||
| 157 | ;; | waisindex = /usr/local/bin/waisindex | ||
| 158 | ;; | wais_opt = -stem -t fields | ||
| 159 | ;; | # `-stem' option necessary when `stemming' is specified for the | ||
| 160 | ;; | # global field in the *.fmt file | ||
| 161 | ;; | | ||
| 162 | ;; | # Own variables | ||
| 163 | ;; | homedir = /home/kai | ||
| 164 | ;; | | ||
| 165 | ;; | # The mail database. | ||
| 166 | ;; | database = mail | ||
| 167 | ;; | files = `find $homedir/Mail -name \*[0-9] -print` | ||
| 168 | ;; | dbdir = $homedir/.wais | ||
| 169 | ;; | limit = 100 | ||
| 170 | ;; `----- | ||
| 171 | ;; | ||
| 172 | ;; The Lisp setup involves the `nnir-wais-*' variables. The most | ||
| 173 | ;; difficult to understand variable is probably | ||
| 174 | ;; `nnir-wais-remove-prefix'. Here's what it does: the output of | ||
| 175 | ;; `waissearch' basically contains the file name and the (full) | ||
| 176 | ;; directory name. As Gnus works with group names rather than | ||
| 177 | ;; directory names, the directory name is transformed into a group | ||
| 178 | ;; name as follows: first, a prefix is removed from the (full) | ||
| 179 | ;; directory name, then all `/' are replaced with `.'. The variable | ||
| 180 | ;; `nnir-wais-remove-prefix' should contain a regex matching exactly | ||
| 181 | ;; this prefix. It defaults to `$HOME/Mail/' (note the trailing | ||
| 182 | ;; slash). | ||
| 183 | |||
| 184 | ;; 2. Namazu | ||
| 185 | ;; | 64 | ;; |
| 186 | ;; The Namazu backend requires you to have one directory containing all | 65 | ;; The Namazu backend requires you to have one directory containing all |
| 187 | ;; index files, this is controlled by the `nnir-namazu-index-directory' | 66 | ;; index files, this is controlled by the `nnir-namazu-index-directory' |
| 188 | ;; variable. To function the `nnir-namazu-remove-prefix' variable must | 67 | ;; variable. To function the `nnir-namazu-remove-prefix' variable must |
| 189 | ;; also be correct, see the documentation for `nnir-wais-remove-prefix' | 68 | ;; also be correct, see the documentation for `nnir-namazu-remove-prefix' |
| 190 | ;; above. | 69 | ;; above. |
| 191 | ;; | 70 | ;; |
| 192 | ;; It is particularly important not to pass any any switches to namazu | 71 | ;; It is particularly important not to pass any any switches to namazu |
| @@ -225,7 +104,7 @@ | |||
| 225 | ;; For maximum searching efficiency I have a cron job set to run this | 104 | ;; For maximum searching efficiency I have a cron job set to run this |
| 226 | ;; command every four hours. | 105 | ;; command every four hours. |
| 227 | 106 | ||
| 228 | ;; 3. find-grep | 107 | ;; 2. find-grep |
| 229 | ;; | 108 | ;; |
| 230 | ;; The find-grep engine simply runs find(1) to locate eligible | 109 | ;; The find-grep engine simply runs find(1) to locate eligible |
| 231 | ;; articles and searches them with grep(1). This, of course, is much | 110 | ;; articles and searches them with grep(1). This, of course, is much |
| @@ -281,39 +160,7 @@ | |||
| 281 | ;; function should return the list of articles as a vector, as | 160 | ;; function should return the list of articles as a vector, as |
| 282 | ;; described above. Then, you need to register this backend in | 161 | ;; described above. Then, you need to register this backend in |
| 283 | ;; `nnir-engines'. Then, users can choose the backend by setting | 162 | ;; `nnir-engines'. Then, users can choose the backend by setting |
| 284 | ;; `nnir-search-engine'. | 163 | ;; `nnir-search-engine' as a server variable. |
| 285 | |||
| 286 | ;; Todo, or future ideas: | ||
| 287 | |||
| 288 | ;; * It should be possible to restrict search to certain groups. | ||
| 289 | ;; | ||
| 290 | ;; * There is currently no error checking. | ||
| 291 | ;; | ||
| 292 | ;; * The summary buffer display is currently really ugly, with all the | ||
| 293 | ;; added information in the subjects. How could I make this | ||
| 294 | ;; prettier? | ||
| 295 | ;; | ||
| 296 | ;; * A function which can be called from an nnir summary buffer which | ||
| 297 | ;; teleports you into the group the current article came from and | ||
| 298 | ;; shows you the whole thread this article is part of. | ||
| 299 | ;; Implementation suggestions? | ||
| 300 | ;; (1998-07-24: There is now a preliminary implementation, but | ||
| 301 | ;; it is much too slow and quite fragile.) | ||
| 302 | ;; | ||
| 303 | ;; * Support other mail backends. In particular, probably quite a few | ||
| 304 | ;; people use nnfolder. How would one go about searching nnfolders | ||
| 305 | ;; and producing the right data needed? The group name and the RSV | ||
| 306 | ;; are simple, but what about the article number? | ||
| 307 | ;; - The article number is encoded in the `X-Gnus-Article-Number' | ||
| 308 | ;; header of each mail. | ||
| 309 | ;; | ||
| 310 | ;; * Support compressed mail files. Probably, just stripping off the | ||
| 311 | ;; `.gz' or `.Z' file name extension is sufficient. | ||
| 312 | ;; | ||
| 313 | ;; * At least for imap, the query is performed twice. | ||
| 314 | ;; | ||
| 315 | |||
| 316 | ;; Have you got other ideas? | ||
| 317 | 164 | ||
| 318 | ;;; Setup Code: | 165 | ;;; Setup Code: |
| 319 | 166 | ||
| @@ -336,116 +183,27 @@ | |||
| 336 | 183 | ||
| 337 | (gnus-declare-backend "nnir" 'mail) | 184 | (gnus-declare-backend "nnir" 'mail) |
| 338 | 185 | ||
| 339 | (defvar nnir-imap-default-search-key "Whole message" | ||
| 340 | "The default IMAP search key for an nnir search. Must be one of | ||
| 341 | the keys in nnir-imap-search-arguments. To use raw imap queries | ||
| 342 | by default set this to \"Imap\"") | ||
| 343 | |||
| 344 | (defvar nnir-imap-search-arguments | ||
| 345 | '(("Whole message" . "TEXT") | ||
| 346 | ("Subject" . "SUBJECT") | ||
| 347 | ("To" . "TO") | ||
| 348 | ("From" . "FROM") | ||
| 349 | ("Imap" . "")) | ||
| 350 | "Mapping from user readable keys to IMAP search items for use in nnir") | ||
| 351 | |||
| 352 | (defvar nnir-imap-search-other "HEADER %S" | ||
| 353 | "The IMAP search item to use for anything other than | ||
| 354 | nnir-imap-search-arguments. By default this is the name of an | ||
| 355 | email header field") | ||
| 356 | |||
| 357 | (defvar nnir-imap-search-argument-history () | ||
| 358 | "The history for querying search options in nnir") | ||
| 359 | |||
| 360 | (defvar nnir-get-article-nov-override-function nil | ||
| 361 | "If non-nil, a function that will be passed each search result. This | ||
| 362 | should return a message's headers in NOV format. | ||
| 363 | |||
| 364 | If this variable is nil, or if the provided function returns nil for a search | ||
| 365 | result, `gnus-retrieve-headers' will be called instead.") | ||
| 366 | |||
| 367 | (defvar nnir-method-default-engines | ||
| 368 | '((nnimap . imap) | ||
| 369 | (nntp . nil)) | ||
| 370 | "Alist of default search engines by server method") | ||
| 371 | |||
| 372 | ;;; Developer Extension Variable: | ||
| 373 | |||
| 374 | (defvar nnir-engines | ||
| 375 | `((wais nnir-run-waissearch | ||
| 376 | ()) | ||
| 377 | (imap nnir-run-imap | ||
| 378 | ((criteria | ||
| 379 | "Search in" ; Prompt | ||
| 380 | ,(mapcar 'car nnir-imap-search-arguments) ; alist for completing | ||
| 381 | nil ; allow any user input | ||
| 382 | nil ; initial value | ||
| 383 | nnir-imap-search-argument-history ; the history to use | ||
| 384 | ,nnir-imap-default-search-key ; default | ||
| 385 | ))) | ||
| 386 | (swish++ nnir-run-swish++ | ||
| 387 | ((group . "Group spec: "))) | ||
| 388 | (swish-e nnir-run-swish-e | ||
| 389 | ((group . "Group spec: "))) | ||
| 390 | (namazu nnir-run-namazu | ||
| 391 | ()) | ||
| 392 | (find-grep nnir-run-find-grep | ||
| 393 | ((grep-options . "Grep options: ")))) | ||
| 394 | "Alist of supported search engines. | ||
| 395 | Each element in the alist is a three-element list (ENGINE FUNCTION ARGS). | ||
| 396 | ENGINE is a symbol designating the searching engine. FUNCTION is also | ||
| 397 | a symbol, giving the function that does the search. The third element | ||
| 398 | ARGS is a list of cons pairs (PARAM . PROMPT). When issuing a query, | ||
| 399 | the FUNCTION will issue a query for each of the PARAMs, using PROMPT. | ||
| 400 | |||
| 401 | The value of `nnir-search-engine' must be one of the ENGINE symbols. | ||
| 402 | For example, use the following line for searching using freeWAIS-sf: | ||
| 403 | (setq nnir-search-engine 'wais) | ||
| 404 | Use the following line if you read your mail via IMAP and your IMAP | ||
| 405 | server supports searching: | ||
| 406 | (setq nnir-search-engine 'imap) | ||
| 407 | Note that you have to set additional variables for most backends. For | ||
| 408 | example, the `wais' backend needs the variables `nnir-wais-program', | ||
| 409 | `nnir-wais-database' and `nnir-wais-remove-prefix'. | ||
| 410 | |||
| 411 | Add an entry here when adding a new search engine.") | ||
| 412 | 186 | ||
| 413 | ;;; User Customizable Variables: | 187 | ;;; User Customizable Variables: |
| 414 | 188 | ||
| 415 | (defgroup nnir nil | 189 | (defgroup nnir nil |
| 416 | "Search nnmh and nnml groups in Gnus with swish-e, freeWAIS-sf, or EWS." | 190 | "Search groups in Gnus with assorted seach engines." |
| 417 | :group 'gnus) | 191 | :group 'gnus) |
| 418 | 192 | ||
| 419 | ;; Mail backend. | 193 | (defcustom nnir-method-default-engines |
| 420 | 194 | '((nnimap . imap) | |
| 421 | ;; TODO: | 195 | (nntp . gmane)) |
| 422 | ;; If `nil', use server parameters to find out which server to search. CCC | 196 | "*Alist of default search engines keyed by server method" |
| 423 | ;; | 197 | :type '(alist) |
| 424 | (defcustom nnir-mail-backend '(nnml "") | ||
| 425 | "*Specifies which backend should be searched. | ||
| 426 | More precisely, this is used to determine from which backend to fetch the | ||
| 427 | messages found. | ||
| 428 | |||
| 429 | This must be equal to an existing server, so maybe it is best to use | ||
| 430 | something like the following: | ||
| 431 | (setq nnir-mail-backend (nth 0 gnus-secondary-select-methods)) | ||
| 432 | The above line works fine if the mail backend you want to search is | ||
| 433 | the first element of gnus-secondary-select-methods (`nth' starts counting | ||
| 434 | at zero)." | ||
| 435 | :type '(sexp) | ||
| 436 | :group 'nnir) | 198 | :group 'nnir) |
| 437 | 199 | ||
| 438 | ;; Search engine to use. | 200 | (defcustom nnir-imap-default-search-key "Whole message" |
| 439 | 201 | "*The default IMAP search key for an nnir search. Must be one of | |
| 440 | (defcustom nnir-search-engine 'wais | 202 | the keys in `nnir-imap-search-arguments'. To use raw imap queries |
| 441 | "*The search engine to use. Must be a symbol. | 203 | by default set this to \"Imap\"" |
| 442 | See `nnir-engines' for a list of supported engines, and for example | 204 | :type '(string) |
| 443 | settings of `nnir-search-engine'." | ||
| 444 | :type '(sexp) | ||
| 445 | :group 'nnir) | 205 | :group 'nnir) |
| 446 | 206 | ||
| 447 | ;; freeWAIS-sf. | ||
| 448 | |||
| 449 | (defcustom nnir-wais-program "waissearch" | 207 | (defcustom nnir-wais-program "waissearch" |
| 450 | "*Name of waissearch executable." | 208 | "*Name of waissearch executable." |
| 451 | :type '(string) | 209 | :type '(string) |
| @@ -501,8 +259,8 @@ Instead, use this: | |||
| 501 | in order to get a group name (albeit with / instead of .). This is a | 259 | in order to get a group name (albeit with / instead of .). This is a |
| 502 | regular expression. | 260 | regular expression. |
| 503 | 261 | ||
| 504 | This variable is very similar to `nnir-wais-remove-prefix', except | 262 | This variable is very similar to `nnir-namazu-remove-prefix', except |
| 505 | that it is for swish++, not Wais." | 263 | that it is for swish++, not Namazu." |
| 506 | :type '(regexp) | 264 | :type '(regexp) |
| 507 | :group 'nnir) | 265 | :group 'nnir) |
| 508 | 266 | ||
| @@ -552,13 +310,47 @@ This could be a server parameter." | |||
| 552 | in order to get a group name (albeit with / instead of .). This is a | 310 | in order to get a group name (albeit with / instead of .). This is a |
| 553 | regular expression. | 311 | regular expression. |
| 554 | 312 | ||
| 555 | This variable is very similar to `nnir-wais-remove-prefix', except | 313 | This variable is very similar to `nnir-namazu-remove-prefix', except |
| 556 | that it is for swish-e, not Wais. | 314 | that it is for swish-e, not Namazu. |
| 557 | 315 | ||
| 558 | This could be a server parameter." | 316 | This could be a server parameter." |
| 559 | :type '(regexp) | 317 | :type '(regexp) |
| 560 | :group 'nnir) | 318 | :group 'nnir) |
| 561 | 319 | ||
| 320 | ;; HyREX engine, see <URL:http://ls6-www.cs.uni-dortmund.de/> | ||
| 321 | |||
| 322 | (defcustom nnir-hyrex-program "nnir-search" | ||
| 323 | "*Name of the nnir-search executable." | ||
| 324 | :type '(string) | ||
| 325 | :group 'nnir) | ||
| 326 | |||
| 327 | (defcustom nnir-hyrex-additional-switches '() | ||
| 328 | "*A list of strings, to be given as additional arguments for nnir-search. | ||
| 329 | Note that this should be a list. Ie, do NOT use the following: | ||
| 330 | (setq nnir-hyrex-additional-switches \"-ddl ddl.xml -c nnir\") ; wrong ! | ||
| 331 | Instead, use this: | ||
| 332 | (setq nnir-hyrex-additional-switches '(\"-ddl\" \"ddl.xml\" \"-c\" \"nnir\"))" | ||
| 333 | :type '(repeat (string)) | ||
| 334 | :group 'nnir) | ||
| 335 | |||
| 336 | (defcustom nnir-hyrex-index-directory (getenv "HOME") | ||
| 337 | "*Index directory for HyREX." | ||
| 338 | :type '(directory) | ||
| 339 | :group 'nnir) | ||
| 340 | |||
| 341 | (defcustom nnir-hyrex-remove-prefix (concat (getenv "HOME") "/Mail/") | ||
| 342 | "*The prefix to remove from each file name returned by HyREX | ||
| 343 | in order to get a group name (albeit with / instead of .). | ||
| 344 | |||
| 345 | For example, suppose that HyREX returns file names such as | ||
| 346 | \"/home/john/Mail/mail/misc/42\". For this example, use the following | ||
| 347 | setting: (setq nnir-hyrex-remove-prefix \"/home/john/Mail/\") | ||
| 348 | Note the trailing slash. Removing this prefix gives \"mail/misc/42\". | ||
| 349 | `nnir' knows to remove the \"/42\" and to replace \"/\" with \".\" to | ||
| 350 | arrive at the correct group name, \"mail.misc\"." | ||
| 351 | :type '(directory) | ||
| 352 | :group 'nnir) | ||
| 353 | |||
| 562 | ;; Namazu engine, see <URL:http://www.namazu.org/> | 354 | ;; Namazu engine, see <URL:http://www.namazu.org/> |
| 563 | 355 | ||
| 564 | (defcustom nnir-namazu-program "namazu" | 356 | (defcustom nnir-namazu-program "namazu" |
| @@ -587,11 +379,83 @@ Instead, use this: | |||
| 587 | "*The prefix to remove from each file name returned by Namazu | 379 | "*The prefix to remove from each file name returned by Namazu |
| 588 | in order to get a group name (albeit with / instead of .). | 380 | in order to get a group name (albeit with / instead of .). |
| 589 | 381 | ||
| 590 | This variable is very similar to `nnir-wais-remove-prefix', except | 382 | For example, suppose that Namazu returns file names such as |
| 591 | that it is for Namazu, not Wais." | 383 | \"/home/john/Mail/mail/misc/42\". For this example, use the following |
| 384 | setting: (setq nnir-namazu-remove-prefix \"/home/john/Mail/\") | ||
| 385 | Note the trailing slash. Removing this prefix gives \"mail/misc/42\". | ||
| 386 | `nnir' knows to remove the \"/42\" and to replace \"/\" with \".\" to | ||
| 387 | arrive at the correct group name, \"mail.misc\"." | ||
| 592 | :type '(directory) | 388 | :type '(directory) |
| 593 | :group 'nnir) | 389 | :group 'nnir) |
| 594 | 390 | ||
| 391 | ;; Imap variables | ||
| 392 | |||
| 393 | (defvar nnir-imap-search-arguments | ||
| 394 | '(("Whole message" . "TEXT") | ||
| 395 | ("Subject" . "SUBJECT") | ||
| 396 | ("To" . "TO") | ||
| 397 | ("From" . "FROM") | ||
| 398 | ("Imap" . "")) | ||
| 399 | "Mapping from user readable keys to IMAP search items for use in nnir") | ||
| 400 | |||
| 401 | (defvar nnir-imap-search-other "HEADER %S" | ||
| 402 | "The IMAP search item to use for anything other than | ||
| 403 | `nnir-imap-search-arguments'. By default this is the name of an | ||
| 404 | email header field") | ||
| 405 | |||
| 406 | (defvar nnir-imap-search-argument-history () | ||
| 407 | "The history for querying search options in nnir") | ||
| 408 | |||
| 409 | ;;; Developer Extension Variable: | ||
| 410 | |||
| 411 | (defvar nnir-engines | ||
| 412 | `((wais nnir-run-waissearch | ||
| 413 | ()) | ||
| 414 | (imap nnir-run-imap | ||
| 415 | ((criteria | ||
| 416 | "Imap Search in" ; Prompt | ||
| 417 | ,(mapcar 'car nnir-imap-search-arguments) ; alist for completing | ||
| 418 | nil ; allow any user input | ||
| 419 | nil ; initial value | ||
| 420 | nnir-imap-search-argument-history ; the history to use | ||
| 421 | ,nnir-imap-default-search-key ; default | ||
| 422 | ))) | ||
| 423 | (gmane nnir-run-gmane | ||
| 424 | ((author . "Gmane Author: "))) | ||
| 425 | (swish++ nnir-run-swish++ | ||
| 426 | ((group . "Swish++ Group spec: "))) | ||
| 427 | (swish-e nnir-run-swish-e | ||
| 428 | ((group . "Swish-e Group spec: "))) | ||
| 429 | (namazu nnir-run-namazu | ||
| 430 | ()) | ||
| 431 | (hyrex nnir-run-hyrex | ||
| 432 | ((group . "Hyrex Group spec: "))) | ||
| 433 | (find-grep nnir-run-find-grep | ||
| 434 | ((grep-options . "Grep options: ")))) | ||
| 435 | "Alist of supported search engines. | ||
| 436 | Each element in the alist is a three-element list (ENGINE FUNCTION ARGS). | ||
| 437 | ENGINE is a symbol designating the searching engine. FUNCTION is also | ||
| 438 | a symbol, giving the function that does the search. The third element | ||
| 439 | ARGS is a list of cons pairs (PARAM . PROMPT). When issuing a query, | ||
| 440 | the FUNCTION will issue a query for each of the PARAMs, using PROMPT. | ||
| 441 | |||
| 442 | The value of `nnir-search-engine' must be one of the ENGINE symbols. | ||
| 443 | For example, for searching a server using namazu include | ||
| 444 | (nnir-search-engine namazu) | ||
| 445 | in the server definition. Note that you have to set additional | ||
| 446 | variables for most backends. For example, the `namazu' backend | ||
| 447 | needs the variables `nnir-namazu-program', | ||
| 448 | `nnir-namazu-index-directory' and `nnir-namazu-remove-prefix'. | ||
| 449 | |||
| 450 | Add an entry here when adding a new search engine.") | ||
| 451 | |||
| 452 | (defvar nnir-get-article-nov-override-function nil | ||
| 453 | "If non-nil, a function that will be passed each search result. This | ||
| 454 | should return a message's headers in NOV format. | ||
| 455 | |||
| 456 | If this variable is nil, or if the provided function returns nil for a search | ||
| 457 | result, `gnus-retrieve-headers' will be called instead.") | ||
| 458 | |||
| 595 | ;;; Internal Variables: | 459 | ;;; Internal Variables: |
| 596 | 460 | ||
| 597 | (defvar nnir-current-query nil | 461 | (defvar nnir-current-query nil |
| @@ -609,43 +473,31 @@ that it is for Namazu, not Wais." | |||
| 609 | (defvar nnir-tmp-buffer " *nnir*" | 473 | (defvar nnir-tmp-buffer " *nnir*" |
| 610 | "Internal: temporary buffer.") | 474 | "Internal: temporary buffer.") |
| 611 | 475 | ||
| 476 | (defvar nnir-search-history () | ||
| 477 | "Internal: the history for querying search options in nnir") | ||
| 478 | |||
| 479 | (defvar nnir-extra-parms nil | ||
| 480 | "Internal: stores request for extra search parms") | ||
| 481 | |||
| 612 | ;;; Code: | 482 | ;;; Code: |
| 613 | 483 | ||
| 614 | ;; Gnus glue. | 484 | ;; Gnus glue. |
| 615 | 485 | ||
| 616 | (defun gnus-group-make-nnir-group (extra-parms query) | 486 | (defun gnus-group-make-nnir-group (nnir-extra-parms) |
| 617 | "Create an nnir group. Asks for query." | 487 | "Create an nnir group. Asks for query." |
| 618 | (interactive "P\nsQuery: ") | 488 | (interactive "P") |
| 619 | (setq nnir-current-query nil | 489 | (setq nnir-current-query nil |
| 620 | nnir-current-server nil | 490 | nnir-current-server nil |
| 621 | nnir-current-group-marked nil | 491 | nnir-current-group-marked nil |
| 622 | nnir-artlist nil) | 492 | nnir-artlist nil) |
| 623 | (let ((parms nil)) | 493 | (let* ((query (read-string "Query: " nil 'nnir-search-history)) |
| 624 | (if extra-parms | 494 | (parms (list (cons 'query query)))) |
| 625 | (setq parms (nnir-read-parms query)) | ||
| 626 | (setq parms (list (cons 'query query)))) | ||
| 627 | (add-to-list 'parms (cons 'unique-id (message-unique-id)) t) | 495 | (add-to-list 'parms (cons 'unique-id (message-unique-id)) t) |
| 628 | (gnus-group-read-ephemeral-group | 496 | (gnus-group-read-ephemeral-group |
| 629 | (concat "nnir:" (prin1-to-string parms)) '(nnir "") t | 497 | (concat "nnir:" (prin1-to-string parms)) '(nnir "") t |
| 630 | (cons (current-buffer) | 498 | (cons (current-buffer) gnus-current-window-configuration) |
| 631 | gnus-current-window-configuration) | ||
| 632 | nil))) | 499 | nil))) |
| 633 | 500 | ||
| 634 | ;; Why is this needed? Is this for compatibility with old/new gnusae? Using | ||
| 635 | ;; gnus-group-server instead works for me. -- Justus Piater | ||
| 636 | (defmacro nnir-group-server (group) | ||
| 637 | "Return the server for a newsgroup GROUP. | ||
| 638 | The returned format is as `gnus-server-to-method' needs it. See | ||
| 639 | `gnus-group-real-prefix' and `gnus-group-real-name'." | ||
| 640 | `(let ((gname ,group)) | ||
| 641 | (if (string-match "^\\([^:]+\\):" gname) | ||
| 642 | (progn | ||
| 643 | (setq gname (match-string 1 gname)) | ||
| 644 | (if (string-match "^\\([^+]+\\)\\+\\(.+\\)$" gname) | ||
| 645 | (format "%s:%s" (match-string 1 gname) (match-string 2 gname)) | ||
| 646 | (concat gname ":"))) | ||
| 647 | (format "%s:%s" (car gnus-select-method) (cadr gnus-select-method))))) | ||
| 648 | |||
| 649 | ;; Summary mode commands. | 501 | ;; Summary mode commands. |
| 650 | 502 | ||
| 651 | (defun gnus-summary-nnir-goto-thread () | 503 | (defun gnus-summary-nnir-goto-thread () |
| @@ -660,22 +512,27 @@ and show thread that contains this article." | |||
| 660 | (id (mail-header-id (gnus-summary-article-header))) | 512 | (id (mail-header-id (gnus-summary-article-header))) |
| 661 | (refs (split-string | 513 | (refs (split-string |
| 662 | (mail-header-references (gnus-summary-article-header))))) | 514 | (mail-header-references (gnus-summary-article-header))))) |
| 663 | (if (eq (car (gnus-group-method group)) 'nnimap) | 515 | (if (eq (car (gnus-find-method-for-group group)) 'nnimap) |
| 664 | (progn (nnimap-possibly-change-group (gnus-group-short-name group) nil) | 516 | (progn |
| 665 | (with-current-buffer (nnimap-buffer) | 517 | (nnimap-possibly-change-group (gnus-group-short-name group) nil) |
| 666 | (let* ((cmd (let ((value (format | 518 | (with-current-buffer (nnimap-buffer) |
| 667 | "(OR HEADER REFERENCES %s HEADER Message-Id %s)" | 519 | (let* ((cmd |
| 668 | id id))) | 520 | (let ((value |
| 669 | (dolist (refid refs value) | 521 | (format |
| 670 | (setq value (format | 522 | "(OR HEADER REFERENCES %s HEADER Message-Id %s)" |
| 671 | "(OR (OR HEADER Message-Id %s HEADER REFERENCES %s) %s)" | 523 | id id))) |
| 672 | refid refid value))))) | 524 | (dolist (refid refs value) |
| 673 | (result (nnimap-command | 525 | (setq value |
| 674 | "UID SEARCH %s" cmd))) | 526 | (format |
| 675 | (gnus-summary-read-group-1 group t t gnus-summary-buffer nil | 527 | "(OR (OR HEADER Message-Id %s HEADER REFERENCES %s) %s)" |
| 676 | (and (car result) | 528 | refid refid value))))) |
| 677 | (delete 0 (mapcar #'string-to-number | 529 | (result (nnimap-command "UID SEARCH %s" cmd))) |
| 678 | (cdr (assoc "SEARCH" (cdr result)))))))))) | 530 | (gnus-summary-read-group-1 |
| 531 | group t t gnus-summary-buffer nil | ||
| 532 | (and (car result) | ||
| 533 | (delete 0 (mapcar | ||
| 534 | #'string-to-number | ||
| 535 | (cdr (assoc "SEARCH" (cdr result)))))))))) | ||
| 679 | (gnus-summary-read-group-1 group t t gnus-summary-buffer | 536 | (gnus-summary-read-group-1 group t t gnus-summary-buffer |
| 680 | nil (list backend-number)) | 537 | nil (list backend-number)) |
| 681 | (gnus-summary-limit (list backend-number)) | 538 | (gnus-summary-limit (list backend-number)) |
| @@ -711,22 +568,17 @@ and show thread that contains this article." | |||
| 711 | ;; Cache miss. | 568 | ;; Cache miss. |
| 712 | (setq nnir-artlist (nnir-run-query group))) | 569 | (setq nnir-artlist (nnir-run-query group))) |
| 713 | (with-current-buffer nntp-server-buffer | 570 | (with-current-buffer nntp-server-buffer |
| 571 | (setq nnir-current-query group) | ||
| 572 | (when server (setq nnir-current-server server)) | ||
| 573 | (setq nnir-current-group-marked gnus-group-marked) | ||
| 714 | (if (zerop (length nnir-artlist)) | 574 | (if (zerop (length nnir-artlist)) |
| 715 | (progn | 575 | (nnheader-report 'nnir "Search produced empty results.") |
| 716 | (setq nnir-current-query nil | ||
| 717 | nnir-current-server nil | ||
| 718 | nnir-current-group-marked nil | ||
| 719 | nnir-artlist nil) | ||
| 720 | (nnheader-report 'nnir "Search produced empty results.")) | ||
| 721 | ;; Remember data for cache. | 576 | ;; Remember data for cache. |
| 722 | (setq nnir-current-query group) | ||
| 723 | (when server (setq nnir-current-server server)) | ||
| 724 | (setq nnir-current-group-marked gnus-group-marked) | ||
| 725 | (nnheader-insert "211 %d %d %d %s\n" | 577 | (nnheader-insert "211 %d %d %d %s\n" |
| 726 | (nnir-artlist-length nnir-artlist) ; total # | 578 | (nnir-artlist-length nnir-artlist) ; total # |
| 727 | 1 ; first # | 579 | 1 ; first # |
| 728 | (nnir-artlist-length nnir-artlist) ; last # | 580 | (nnir-artlist-length nnir-artlist) ; last # |
| 729 | group)))) ; group name | 581 | group)))) ; group name |
| 730 | 582 | ||
| 731 | (deffoo nnir-retrieve-headers (articles &optional group server fetch-old) | 583 | (deffoo nnir-retrieve-headers (articles &optional group server fetch-old) |
| 732 | (save-excursion | 584 | (save-excursion |
| @@ -745,7 +597,7 @@ and show thread that contains this article." | |||
| 745 | (setq artfullgroup (nnir-artitem-group artitem)) | 597 | (setq artfullgroup (nnir-artitem-group artitem)) |
| 746 | (setq artno (nnir-artitem-number artitem)) | 598 | (setq artno (nnir-artitem-number artitem)) |
| 747 | (setq artgroup (gnus-group-real-name artfullgroup)) | 599 | (setq artgroup (gnus-group-real-name artfullgroup)) |
| 748 | (setq server (nnir-group-server artfullgroup)) | 600 | (setq server (gnus-group-server artfullgroup)) |
| 749 | ;; retrieve NOV or HEAD data for this article, transform into | 601 | ;; retrieve NOV or HEAD data for this article, transform into |
| 750 | ;; NOV data and prepend to `novdata' | 602 | ;; NOV data and prepend to `novdata' |
| 751 | (set-buffer nntp-server-buffer) | 603 | (set-buffer nntp-server-buffer) |
| @@ -859,8 +711,8 @@ ready to be added to the list of search results." | |||
| 859 | (defun nnir-run-waissearch (query server &optional group) | 711 | (defun nnir-run-waissearch (query server &optional group) |
| 860 | "Run given query agains waissearch. Returns vector of (group name, file name) | 712 | "Run given query agains waissearch. Returns vector of (group name, file name) |
| 861 | pairs (also vectors, actually)." | 713 | pairs (also vectors, actually)." |
| 862 | (when group | 714 | ;; (when group |
| 863 | (error "The freeWAIS-sf backend cannot search specific groups")) | 715 | ;; (error "The freeWAIS-sf backend cannot search specific groups")) |
| 864 | (save-excursion | 716 | (save-excursion |
| 865 | (let ((qstring (cdr (assq 'query query))) | 717 | (let ((qstring (cdr (assq 'query query))) |
| 866 | (prefix (nnir-read-server-parm 'nnir-wais-remove-prefix server)) | 718 | (prefix (nnir-read-server-parm 'nnir-wais-remove-prefix server)) |
| @@ -900,49 +752,49 @@ pairs (also vectors, actually)." | |||
| 900 | (> (nnir-artitem-rsv x) | 752 | (> (nnir-artitem-rsv x) |
| 901 | (nnir-artitem-rsv y))))))))) | 753 | (nnir-artitem-rsv y))))))))) |
| 902 | 754 | ||
| 903 | ;; IMAP interface. | 755 | ;; imap interface |
| 904 | ;; todo: | 756 | (defun nnir-run-imap (query srv &optional groups) |
| 905 | ;; send queries as literals | ||
| 906 | ;; handle errors | ||
| 907 | |||
| 908 | |||
| 909 | (defun nnir-run-imap (query srv &optional group-option) | ||
| 910 | "Run a search against an IMAP back-end server. | 757 | "Run a search against an IMAP back-end server. |
| 911 | This uses a custom query language parser; see `nnir-imap-make-query' for | 758 | This uses a custom query language parser; see `nnir-imap-make-query' for |
| 912 | details on the language and supported extensions" | 759 | details on the language and supported extensions" |
| 913 | (save-excursion | 760 | (save-excursion |
| 914 | (let ((qstring (cdr (assq 'query query))) | 761 | (let ((qstring (cdr (assq 'query query))) |
| 915 | (server (cadr (gnus-server-to-method srv))) | 762 | (server (cadr (gnus-server-to-method srv))) |
| 916 | (group (or group-option (gnus-group-group-name))) | 763 | (defs (caddr (gnus-server-to-method srv))) |
| 917 | (defs (caddr (gnus-server-to-method srv))) | 764 | (criteria (or (cdr (assq 'criteria query)) |
| 918 | (criteria (or (cdr (assq 'criteria query)) | 765 | (cdr (assoc nnir-imap-default-search-key |
| 919 | (cdr (assoc nnir-imap-default-search-key | 766 | nnir-imap-search-arguments)))) |
| 920 | nnir-imap-search-arguments)))) | 767 | (gnus-inhibit-demon t) |
| 921 | (gnus-inhibit-demon t) | 768 | artlist) |
| 922 | artlist) | ||
| 923 | (message "Opening server %s" server) | 769 | (message "Opening server %s" server) |
| 924 | (condition-case () | 770 | (apply |
| 925 | (when (nnimap-possibly-change-group (gnus-group-short-name group) server) | 771 | 'vconcat |
| 926 | (with-current-buffer (nnimap-buffer) | 772 | (mapcar |
| 927 | (message "Searching %s..." group) | 773 | (lambda (x) |
| 928 | (let ((arts 0) | 774 | (let ((group x)) |
| 929 | (result | 775 | (condition-case () |
| 930 | (nnimap-command "UID SEARCH %s" | 776 | (when (nnimap-possibly-change-group |
| 931 | (if (string= criteria "") | 777 | (gnus-group-short-name group) server) |
| 932 | qstring | 778 | (with-current-buffer (nnimap-buffer) |
| 933 | (nnir-imap-make-query criteria qstring) | 779 | (message "Searching %s..." group) |
| 934 | )))) | 780 | (let ((arts 0) |
| 935 | (mapc | 781 | (result (nnimap-command "UID SEARCH %s" |
| 936 | (lambda (artnum) | 782 | (if (string= criteria "") |
| 937 | (push (vector group artnum 1) artlist) | 783 | qstring |
| 938 | (setq arts (1+ arts))) | 784 | (nnir-imap-make-query |
| 939 | (and (car result) | 785 | criteria qstring))))) |
| 940 | (delete 0 (mapcar #'string-to-number | 786 | (mapc |
| 941 | (cdr (assoc "SEARCH" (cdr result))))))) | 787 | (lambda (artnum) (push (vector group artnum 1) artlist) |
| 942 | (message "Searching %s... %d matches" group arts))) | 788 | (setq arts (1+ arts))) |
| 943 | (message "Searching %s...done" group)) | 789 | (and (car result) |
| 944 | (quit nil)) | 790 | (delete 0 (mapcar #'string-to-number |
| 945 | (reverse artlist)))) | 791 | (cdr (assoc "SEARCH" |
| 792 | (cdr result))))))) | ||
| 793 | (message "Searching %s... %d matches" group arts))) | ||
| 794 | (message "Searching %s...done" group)) | ||
| 795 | (quit nil)) | ||
| 796 | (reverse artlist))) | ||
| 797 | groups))))) | ||
| 946 | 798 | ||
| 947 | (defun nnir-imap-make-query (criteria qstring) | 799 | (defun nnir-imap-make-query (criteria qstring) |
| 948 | "Parse the query string and criteria into an appropriate IMAP search | 800 | "Parse the query string and criteria into an appropriate IMAP search |
| @@ -1132,8 +984,8 @@ actually). | |||
| 1132 | Tested with swish++ 4.7 on GNU/Linux and with swish++ 5.0b2 on | 984 | Tested with swish++ 4.7 on GNU/Linux and with swish++ 5.0b2 on |
| 1133 | Windows NT 4.0." | 985 | Windows NT 4.0." |
| 1134 | 986 | ||
| 1135 | (when group | 987 | ;; (when group |
| 1136 | (error "The swish++ backend cannot search specific groups")) | 988 | ;; (error "The swish++ backend cannot search specific groups")) |
| 1137 | 989 | ||
| 1138 | (save-excursion | 990 | (save-excursion |
| 1139 | (let ( (qstring (cdr (assq 'query query))) | 991 | (let ( (qstring (cdr (assq 'query query))) |
| @@ -1221,8 +1073,8 @@ actually). | |||
| 1221 | Tested with swish-e-2.0.1 on Windows NT 4.0." | 1073 | Tested with swish-e-2.0.1 on Windows NT 4.0." |
| 1222 | 1074 | ||
| 1223 | ;; swish-e crashes with empty parameter to "-w" on commandline... | 1075 | ;; swish-e crashes with empty parameter to "-w" on commandline... |
| 1224 | (when group | 1076 | ;; (when group |
| 1225 | (error "The swish-e backend cannot search specific groups")) | 1077 | ;; (error "The swish-e backend cannot search specific groups")) |
| 1226 | 1078 | ||
| 1227 | (save-excursion | 1079 | (save-excursion |
| 1228 | (let ((qstring (cdr (assq 'query query))) | 1080 | (let ((qstring (cdr (assq 'query query))) |
| @@ -1306,14 +1158,85 @@ Tested with swish-e-2.0.1 on Windows NT 4.0." | |||
| 1306 | (> (nnir-artitem-rsv x) | 1158 | (> (nnir-artitem-rsv x) |
| 1307 | (nnir-artitem-rsv y))))))))) | 1159 | (nnir-artitem-rsv y))))))))) |
| 1308 | 1160 | ||
| 1161 | ;; HyREX interface | ||
| 1162 | (defun nnir-run-hyrex (query server &optional group) | ||
| 1163 | (save-excursion | ||
| 1164 | (let ((artlist nil) | ||
| 1165 | (groupspec (cdr (assq 'group query))) | ||
| 1166 | (qstring (cdr (assq 'query query))) | ||
| 1167 | (prefix (nnir-read-server-parm 'nnir-hyrex-remove-prefix server)) | ||
| 1168 | score artno dirnam) | ||
| 1169 | (when (and (not groupspec) group) | ||
| 1170 | (setq groupspec | ||
| 1171 | (regexp-opt | ||
| 1172 | (mapcar (lambda (x) (gnus-group-real-name x)) group)))) | ||
| 1173 | (set-buffer (get-buffer-create nnir-tmp-buffer)) | ||
| 1174 | (erase-buffer) | ||
| 1175 | (message "Doing hyrex-search query %s..." query) | ||
| 1176 | (let* ((cp-list | ||
| 1177 | `( ,nnir-hyrex-program | ||
| 1178 | nil ; input from /dev/null | ||
| 1179 | t ; output | ||
| 1180 | nil ; don't redisplay | ||
| 1181 | "-i",(nnir-read-server-parm 'nnir-hyrex-index-directory server) ; index directory | ||
| 1182 | ,@(nnir-read-server-parm 'nnir-hyrex-additional-switches server) | ||
| 1183 | ,qstring ; the query, in hyrex-search format | ||
| 1184 | )) | ||
| 1185 | (exitstatus | ||
| 1186 | (progn | ||
| 1187 | (message "%s args: %s" nnir-hyrex-program | ||
| 1188 | (mapconcat 'identity (cddddr cp-list) " ")) | ||
| 1189 | (apply 'call-process cp-list)))) | ||
| 1190 | (unless (or (null exitstatus) | ||
| 1191 | (zerop exitstatus)) | ||
| 1192 | (nnheader-report 'nnir "Couldn't run hyrex-search: %s" exitstatus) | ||
| 1193 | ;; nnir-search failure reason is in this buffer, show it if | ||
| 1194 | ;; the user wants it. | ||
| 1195 | (when (> gnus-verbose 6) | ||
| 1196 | (display-buffer nnir-tmp-buffer)))) ;; FIXME: Dont clear buffer ! | ||
| 1197 | (message "Doing hyrex-search query \"%s\"...done" qstring) | ||
| 1198 | (sit-for 0) | ||
| 1199 | ;; nnir-search returns: | ||
| 1200 | ;; for nnml/nnfolder: "filename mailid weigth" | ||
| 1201 | ;; for nnimap: "group mailid weigth" | ||
| 1202 | (goto-char (point-min)) | ||
| 1203 | (delete-non-matching-lines "^\\S + [0-9]+ [0-9]+$") | ||
| 1204 | ;; HyREX doesn't search directly in groups -- so filter out here. | ||
| 1205 | (when groupspec | ||
| 1206 | (keep-lines groupspec)) | ||
| 1207 | ;; extract data from result lines | ||
| 1208 | (goto-char (point-min)) | ||
| 1209 | (while (re-search-forward | ||
| 1210 | "\\(\\S +\\) \\([0-9]+\\) \\([0-9]+\\)" nil t) | ||
| 1211 | (setq dirnam (match-string 1) | ||
| 1212 | artno (match-string 2) | ||
| 1213 | score (match-string 3)) | ||
| 1214 | (when (string-match prefix dirnam) | ||
| 1215 | (setq dirnam (replace-match "" t t dirnam))) | ||
| 1216 | (push (vector (nnir-group-full-name | ||
| 1217 | (gnus-replace-in-string dirnam "/" ".") server) | ||
| 1218 | (string-to-number artno) | ||
| 1219 | (string-to-number score)) | ||
| 1220 | artlist)) | ||
| 1221 | (message "Massaging hyrex-search output...done.") | ||
| 1222 | (apply 'vector | ||
| 1223 | (sort artlist | ||
| 1224 | (function (lambda (x y) | ||
| 1225 | (if (string-lessp (nnir-artitem-group x) | ||
| 1226 | (nnir-artitem-group y)) | ||
| 1227 | t | ||
| 1228 | (< (nnir-artitem-number x) | ||
| 1229 | (nnir-artitem-number y))))))) | ||
| 1230 | ))) | ||
| 1231 | |||
| 1309 | ;; Namazu interface | 1232 | ;; Namazu interface |
| 1310 | (defun nnir-run-namazu (query server &optional group) | 1233 | (defun nnir-run-namazu (query server &optional group) |
| 1311 | "Run given query against Namazu. Returns a vector of (group name, file name) | 1234 | "Run given query against Namazu. Returns a vector of (group name, file name) |
| 1312 | pairs (also vectors, actually). | 1235 | pairs (also vectors, actually). |
| 1313 | 1236 | ||
| 1314 | Tested with Namazu 2.0.6 on a GNU/Linux system." | 1237 | Tested with Namazu 2.0.6 on a GNU/Linux system." |
| 1315 | (when group | 1238 | ;; (when group |
| 1316 | (error "The Namazu backend cannot search specific groups")) | 1239 | ;; (error "The Namazu backend cannot search specific groups")) |
| 1317 | (save-excursion | 1240 | (save-excursion |
| 1318 | (let ((article-pattern (if (string= (gnus-group-server server) "nnmaildir") | 1241 | (let ((article-pattern (if (string= (gnus-group-server server) "nnmaildir") |
| 1319 | ":[0-9]+" | 1242 | ":[0-9]+" |
| @@ -1375,7 +1298,7 @@ Tested with Namazu 2.0.6 on a GNU/Linux system." | |||
| 1375 | (> (nnir-artitem-rsv x) | 1298 | (> (nnir-artitem-rsv x) |
| 1376 | (nnir-artitem-rsv y))))))))) | 1299 | (nnir-artitem-rsv y))))))))) |
| 1377 | 1300 | ||
| 1378 | (defun nnir-run-find-grep (query server &optional group) | 1301 | (defun nnir-run-find-grep (query server &optional grouplist) |
| 1379 | "Run find and grep to obtain matching articles." | 1302 | "Run find and grep to obtain matching articles." |
| 1380 | (let* ((method (gnus-server-to-method server)) | 1303 | (let* ((method (gnus-server-to-method server)) |
| 1381 | (sym (intern | 1304 | (sym (intern |
| @@ -1387,65 +1310,128 @@ Tested with Namazu 2.0.6 on a GNU/Linux system." | |||
| 1387 | (unless directory | 1310 | (unless directory |
| 1388 | (error "No directory found in method specification of server %s" | 1311 | (error "No directory found in method specification of server %s" |
| 1389 | server)) | 1312 | server)) |
| 1390 | (message "Searching %s using find-grep..." (or group server)) | 1313 | (apply |
| 1391 | (save-window-excursion | 1314 | 'vconcat |
| 1392 | (set-buffer (get-buffer-create nnir-tmp-buffer)) | 1315 | (mapcar (lambda (x) |
| 1393 | (erase-buffer) | 1316 | (let ((group x)) |
| 1394 | (if (> gnus-verbose 6) | 1317 | (message "Searching %s using find-grep..." |
| 1395 | (pop-to-buffer (current-buffer))) | 1318 | (or group server)) |
| 1396 | (cd directory) ; Using relative paths simplifies postprocessing. | 1319 | (save-window-excursion |
| 1397 | (let ((group | 1320 | (set-buffer (get-buffer-create nnir-tmp-buffer)) |
| 1398 | (if (not group) | 1321 | (erase-buffer) |
| 1399 | "." | 1322 | (if (> gnus-verbose 6) |
| 1400 | ;; Try accessing the group literally as well as | 1323 | (pop-to-buffer (current-buffer))) |
| 1401 | ;; interpreting dots as directory separators so the | 1324 | (cd directory) ; Using relative paths simplifies |
| 1402 | ;; engine works with plain nnml as well as the Gnus Cache. | 1325 | ; postprocessing. |
| 1403 | (let ((group (gnus-group-real-name group))) | 1326 | (let ((group |
| 1404 | ;; Replace cl-func find-if. | 1327 | (if (not group) |
| 1405 | (if (file-directory-p group) | 1328 | "." |
| 1406 | group | 1329 | ;; Try accessing the group literally as |
| 1407 | (if (file-directory-p | 1330 | ;; well as interpreting dots as directory |
| 1408 | (setq group (gnus-replace-in-string group "\\." "/" t))) | 1331 | ;; separators so the engine works with |
| 1409 | group)))))) | 1332 | ;; plain nnml as well as the Gnus Cache. |
| 1410 | (unless group | 1333 | (let ((group (gnus-group-real-name group))) |
| 1411 | (error "Cannot locate directory for group")) | 1334 | ;; Replace cl-func find-if. |
| 1412 | (save-excursion | 1335 | (if (file-directory-p group) |
| 1413 | (apply | 1336 | group |
| 1414 | 'call-process "find" nil t | 1337 | (if (file-directory-p |
| 1415 | "find" group "-type" "f" "-name" "[0-9]*" "-exec" | 1338 | (setq group |
| 1416 | "grep" | 1339 | (gnus-replace-in-string |
| 1417 | `("-l" ,@(and grep-options | 1340 | group |
| 1418 | (split-string grep-options "\\s-" t)) | 1341 | "\\." "/" t))) |
| 1419 | "-e" ,regexp "{}" "+")))) | 1342 | group)))))) |
| 1420 | 1343 | (unless group | |
| 1421 | ;; Translate relative paths to group names. | 1344 | (error "Cannot locate directory for group")) |
| 1422 | (while (not (eobp)) | 1345 | (save-excursion |
| 1423 | (let* ((path (split-string | 1346 | (apply |
| 1424 | (buffer-substring (point) (line-end-position)) "/" t)) | 1347 | 'call-process "find" nil t |
| 1425 | (art (string-to-number (car (last path))))) | 1348 | "find" group "-type" "f" "-name" "[0-9]*" "-exec" |
| 1426 | (while (string= "." (car path)) | 1349 | "grep" |
| 1427 | (setq path (cdr path))) | 1350 | `("-l" ,@(and grep-options |
| 1428 | (let ((group (mapconcat 'identity | 1351 | (split-string grep-options "\\s-" t)) |
| 1429 | ;; Replace cl-func: (subseq path 0 -1) | 1352 | "-e" ,regexp "{}" "+")))) |
| 1430 | (let ((end (1- (length path))) | 1353 | |
| 1431 | res) | 1354 | ;; Translate relative paths to group names. |
| 1432 | (while (>= (setq end (1- end)) 0) | 1355 | (while (not (eobp)) |
| 1433 | (push (pop path) res)) | 1356 | (let* ((path (split-string |
| 1434 | (nreverse res)) | 1357 | (buffer-substring |
| 1435 | "."))) | 1358 | (point) |
| 1436 | (push (vector (nnir-group-full-name group server) art 0) | 1359 | (line-end-position)) "/" t)) |
| 1437 | artlist)) | 1360 | (art (string-to-number (car (last path))))) |
| 1438 | (forward-line 1))) | 1361 | (while (string= "." (car path)) |
| 1439 | (message "Searching %s using find-grep...done" (or group server)) | 1362 | (setq path (cdr path))) |
| 1440 | artlist))) | 1363 | (let ((group (mapconcat 'identity |
| 1364 | ;; Replace cl-func: | ||
| 1365 | ;; (subseq path 0 -1) | ||
| 1366 | (let ((end (1- (length path))) | ||
| 1367 | res) | ||
| 1368 | (while | ||
| 1369 | (>= (setq end (1- end)) 0) | ||
| 1370 | (push (pop path) res)) | ||
| 1371 | (nreverse res)) | ||
| 1372 | "."))) | ||
| 1373 | (push | ||
| 1374 | (vector (nnir-group-full-name group server) art 0) | ||
| 1375 | artlist)) | ||
| 1376 | (forward-line 1))) | ||
| 1377 | (message "Searching %s using find-grep...done" | ||
| 1378 | (or group server)) | ||
| 1379 | artlist))) | ||
| 1380 | grouplist)))) | ||
| 1381 | |||
| 1382 | ;; gmane interface | ||
| 1383 | (defun nnir-run-gmane (query srv &optional groups) | ||
| 1384 | "Run a search against a gmane back-end server." | ||
| 1385 | (if (string-match-p "gmane" srv) | ||
| 1386 | (let* ((case-fold-search t) | ||
| 1387 | (qstring (cdr (assq 'query query))) | ||
| 1388 | (server (cadr (gnus-server-to-method srv))) | ||
| 1389 | (groupspec (if groups | ||
| 1390 | (mapconcat | ||
| 1391 | (function (lambda (x) | ||
| 1392 | (format "group:%s" | ||
| 1393 | (gnus-group-short-name x)))) | ||
| 1394 | groups " ") "")) | ||
| 1395 | (authorspec | ||
| 1396 | (if (assq 'author query) | ||
| 1397 | (format "author:%s" (cdr (assq 'author query))) "")) | ||
| 1398 | (search (format "%s %s %s" | ||
| 1399 | qstring groupspec authorspec)) | ||
| 1400 | artlist) | ||
| 1401 | (with-current-buffer nntp-server-buffer | ||
| 1402 | (erase-buffer) | ||
| 1403 | (mm-url-insert | ||
| 1404 | (concat | ||
| 1405 | "http://search.gmane.org/nov.php" | ||
| 1406 | "?" | ||
| 1407 | (mm-url-encode-www-form-urlencoded | ||
| 1408 | `(("query" . ,search) | ||
| 1409 | ("HITSPERPAGE" . "999"))))) | ||
| 1410 | (unless (featurep 'xemacs) (set-buffer-multibyte t)) | ||
| 1411 | (mm-decode-coding-region (point-min) (point-max) 'utf-8) | ||
| 1412 | (goto-char (point-min)) | ||
| 1413 | (forward-line 1) | ||
| 1414 | (while (not (eobp)) | ||
| 1415 | (unless (or (eolp) (looking-at "\x0d")) | ||
| 1416 | (let ((header (nnheader-parse-nov))) | ||
| 1417 | (let ((xref (mail-header-xref header))) | ||
| 1418 | (when (string-match " \\([^:]+\\)[:/]\\([0-9]+\\)" xref) | ||
| 1419 | (push | ||
| 1420 | (vector | ||
| 1421 | (gnus-group-prefixed-name (match-string 1 xref) srv) | ||
| 1422 | (string-to-number (match-string 2 xref)) 1) | ||
| 1423 | artlist))))) | ||
| 1424 | (forward-line 1))) | ||
| 1425 | (reverse artlist)) | ||
| 1426 | (message "Can't search non-gmane nntp groups"))) | ||
| 1441 | 1427 | ||
| 1442 | ;;; Util Code: | 1428 | ;;; Util Code: |
| 1443 | 1429 | ||
| 1444 | (defun nnir-read-parms (query) | 1430 | (defun nnir-read-parms (query nnir-search-engine) |
| 1445 | "Reads additional search parameters according to `nnir-engines'." | 1431 | "Reads additional search parameters according to `nnir-engines'." |
| 1446 | (let ((parmspec (caddr (assoc nnir-search-engine nnir-engines)))) | 1432 | (let ((parmspec (caddr (assoc nnir-search-engine nnir-engines)))) |
| 1447 | (cons (cons 'query query) | 1433 | (nconc query |
| 1448 | (mapcar 'nnir-read-parm parmspec)))) | 1434 | (mapcar 'nnir-read-parm parmspec)))) |
| 1449 | 1435 | ||
| 1450 | (defun nnir-read-parm (parmspec) | 1436 | (defun nnir-read-parm (parmspec) |
| 1451 | "Reads a single search parameter. | 1437 | "Reads a single search parameter. |
| @@ -1461,67 +1447,40 @@ Tested with Namazu 2.0.6 on a GNU/Linux system." | |||
| 1461 | 1447 | ||
| 1462 | (defun nnir-run-query (query) | 1448 | (defun nnir-run-query (query) |
| 1463 | "Invoke appropriate search engine function (see `nnir-engines'). | 1449 | "Invoke appropriate search engine function (see `nnir-engines'). |
| 1464 | If some groups were process-marked, run the query for each of the groups | 1450 | If some groups were process-marked, run the query for each of the groups |
| 1465 | and concat the results." | 1451 | and concat the results." |
| 1466 | (let ((q (car (read-from-string query)))) | 1452 | (let ((q (car (read-from-string query))) |
| 1467 | (if gnus-group-marked | 1453 | (groups (nnir-sort-groups-by-server |
| 1468 | (apply 'vconcat | 1454 | (or gnus-group-marked (list (gnus-group-group-name)))))) |
| 1469 | (mapcar (lambda (x) | 1455 | (apply 'vconcat |
| 1470 | (let* ((server (nnir-group-server x)) | 1456 | (mapcar (lambda (x) |
| 1471 | (engine | 1457 | (let* ((server (car x)) |
| 1472 | (or (nnir-read-server-parm 'nnir-search-engine | 1458 | (nnir-search-engine |
| 1473 | server) | 1459 | (or (nnir-read-server-parm 'nnir-search-engine |
| 1474 | (cdr | 1460 | server) |
| 1475 | (assoc (car (gnus-server-to-method server)) | 1461 | (cdr (assoc (car |
| 1476 | nnir-method-default-engines)))) | 1462 | (gnus-server-to-method server)) |
| 1477 | search-func) | 1463 | nnir-method-default-engines)))) |
| 1478 | (setq search-func (cadr | 1464 | search-func) |
| 1479 | (assoc | 1465 | (setq search-func (cadr |
| 1480 | engine | 1466 | (assoc nnir-search-engine |
| 1481 | nnir-engines))) | ||
| 1482 | (if search-func | ||
| 1483 | (funcall search-func q server x) | ||
| 1484 | nil))) | ||
| 1485 | gnus-group-marked)) | ||
| 1486 | (apply 'vconcat | ||
| 1487 | (mapcar (lambda (x) | ||
| 1488 | (if (and (equal (cadr x) 'ok) (not (equal (cadar x) "-ephemeral"))) | ||
| 1489 | (let* ((server (format "%s:%s" (caar x) (cadar x))) | ||
| 1490 | (engine | ||
| 1491 | (or (nnir-read-server-parm 'nnir-search-engine | ||
| 1492 | server) | ||
| 1493 | (cdr | ||
| 1494 | (assoc (car (gnus-server-to-method server)) | ||
| 1495 | nnir-method-default-engines)))) | ||
| 1496 | search-func) | ||
| 1497 | (setq search-func (cadr | ||
| 1498 | (assoc | ||
| 1499 | engine | ||
| 1500 | nnir-engines))) | 1467 | nnir-engines))) |
| 1501 | (if search-func | 1468 | (if search-func |
| 1502 | (funcall search-func q server nil) | 1469 | (funcall search-func |
| 1503 | nil)) | 1470 | (if nnir-extra-parms |
| 1504 | nil)) | 1471 | (nnir-read-parms q nnir-search-engine) |
| 1505 | gnus-opened-servers) | 1472 | q) |
| 1506 | )) | 1473 | server (cdr x)) |
| 1507 | )) | 1474 | nil))) |
| 1475 | groups)))) | ||
| 1508 | 1476 | ||
| 1509 | (defun nnir-read-server-parm (key server) | 1477 | (defun nnir-read-server-parm (key server) |
| 1510 | "Returns the parameter value of for the given server, where server is of | 1478 | "Returns the parameter value of key for the given server, where |
| 1511 | form 'backend:name'." | 1479 | server is of form 'backend:name'." |
| 1512 | (let ((method (gnus-server-to-method server))) | 1480 | (let ((method (gnus-server-to-method server))) |
| 1513 | (cond ((and method (assq key (cddr method))) | 1481 | (cond ((and method (assq key (cddr method))) |
| 1514 | (nth 1 (assq key (cddr method)))) | 1482 | (nth 1 (assq key (cddr method)))) |
| 1515 | ((and nnir-mail-backend | 1483 | (t nil)))) |
| 1516 | (gnus-server-equal method nnir-mail-backend)) | ||
| 1517 | (symbol-value key)) | ||
| 1518 | (t nil)))) | ||
| 1519 | ;; (if method | ||
| 1520 | ;; (if (assq key (cddr method)) | ||
| 1521 | ;; (nth 1 (assq key (cddr method))) | ||
| 1522 | ;; (symbol-value key)) | ||
| 1523 | ;; (symbol-value key)) | ||
| 1524 | ;; )) | ||
| 1525 | 1484 | ||
| 1526 | (defun nnir-group-full-name (shortname server) | 1485 | (defun nnir-group-full-name (shortname server) |
| 1527 | "For the given group name, return a full Gnus group name. | 1486 | "For the given group name, return a full Gnus group name. |
| @@ -1564,8 +1523,8 @@ The Gnus backend/server information is added." | |||
| 1564 | (elt artitem 2)) | 1523 | (elt artitem 2)) |
| 1565 | 1524 | ||
| 1566 | (defun nnir-artlist-artitem-rsv (artlist n) | 1525 | (defun nnir-artlist-artitem-rsv (artlist n) |
| 1567 | "Returns from ARTLIST the Retrieval Status Value of the Nth artitem | 1526 | "Returns from ARTLIST the Retrieval Status Value of the Nth |
| 1568 | \(counting from 1)." | 1527 | artitem (counting from 1)." |
| 1569 | (nnir-artitem-rsv (nnir-artlist-article artlist n))) | 1528 | (nnir-artitem-rsv (nnir-artlist-article artlist n))) |
| 1570 | 1529 | ||
| 1571 | ;; unused? | 1530 | ;; unused? |
| @@ -1580,6 +1539,17 @@ The Gnus backend/server information is added." | |||
| 1580 | with-dups) | 1539 | with-dups) |
| 1581 | res)) | 1540 | res)) |
| 1582 | 1541 | ||
| 1542 | (defun nnir-sort-groups-by-server (groups) | ||
| 1543 | "sorts a list of groups into an alist keyed by server" | ||
| 1544 | (if (car groups) | ||
| 1545 | (let (value) | ||
| 1546 | (dolist (var groups value) | ||
| 1547 | (let ((server (gnus-group-server var))) | ||
| 1548 | (if (assoc server value) | ||
| 1549 | (nconc (cdr (assoc server value)) (list var)) | ||
| 1550 | (push (cons (gnus-group-server var) (list var)) value)))) | ||
| 1551 | value) | ||
| 1552 | nil)) | ||
| 1583 | 1553 | ||
| 1584 | ;; The end. | 1554 | ;; The end. |
| 1585 | (provide 'nnir) | 1555 | (provide 'nnir) |
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el index bbb7ff18a46..d72473527df 100644 --- a/lisp/gnus/shr.el +++ b/lisp/gnus/shr.el | |||
| @@ -181,7 +181,7 @@ redirects somewhere else." | |||
| 181 | result)) | 181 | result)) |
| 182 | (dolist (sub dom) | 182 | (dolist (sub dom) |
| 183 | (if (stringp sub) | 183 | (if (stringp sub) |
| 184 | (push (cons :text sub) result) | 184 | (push (cons 'text sub) result) |
| 185 | (push (shr-transform-dom sub) result))) | 185 | (push (shr-transform-dom sub) result))) |
| 186 | (nreverse result))) | 186 | (nreverse result))) |
| 187 | 187 | ||
| @@ -194,7 +194,7 @@ redirects somewhere else." | |||
| 194 | (defun shr-generic (cont) | 194 | (defun shr-generic (cont) |
| 195 | (dolist (sub cont) | 195 | (dolist (sub cont) |
| 196 | (cond | 196 | (cond |
| 197 | ((eq (car sub) :text) | 197 | ((eq (car sub) 'text) |
| 198 | (shr-insert (cdr sub))) | 198 | (shr-insert (cdr sub))) |
| 199 | ((listp (cdr sub)) | 199 | ((listp (cdr sub)) |
| 200 | (shr-descend sub))))) | 200 | (shr-descend sub))))) |
| @@ -524,7 +524,7 @@ Return a string with image data." | |||
| 524 | (url (or url (cdr (assq :src cont))))) | 524 | (url (or url (cdr (assq :src cont))))) |
| 525 | (let ((start (point-marker))) | 525 | (let ((start (point-marker))) |
| 526 | (when (zerop (length alt)) | 526 | (when (zerop (length alt)) |
| 527 | (setq alt "[img]")) | 527 | (setq alt "*")) |
| 528 | (cond | 528 | (cond |
| 529 | ((or (member (cdr (assq :height cont)) '("0" "1")) | 529 | ((or (member (cdr (assq :height cont)) '("0" "1")) |
| 530 | (member (cdr (assq :width cont)) '("0" "1"))) | 530 | (member (cdr (assq :width cont)) '("0" "1"))) |