diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/textmodes/ispell.el | 714 |
1 files changed, 493 insertions, 221 deletions
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 138a3022627..4772fe8a3c8 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el | |||
| @@ -4,8 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: Ken Stevens <k.stevens@ieee.org> | 5 | ;; Author: Ken Stevens <k.stevens@ieee.org> |
| 6 | ;; Maintainer: Ken Stevens <k.stevens@ieee.org> | 6 | ;; Maintainer: Ken Stevens <k.stevens@ieee.org> |
| 7 | ;; Stevens Mod Date: Fri Aug 4 09:41:50 PDT 2000 | 7 | ;; Stevens Mod Date: Mon Jan 7 12:32:44 PST 2003 |
| 8 | ;; Stevens Revision: 3.4 | 8 | ;; Stevens Revision: 3.6 |
| 9 | ;; Status : Release with 3.1.12+ and 3.2.0+ ispell. | 9 | ;; Status : Release with 3.1.12+ and 3.2.0+ ispell. |
| 10 | ;; Bug Reports : ispell-el-bugs@itcorp.com | 10 | ;; Bug Reports : ispell-el-bugs@itcorp.com |
| 11 | ;; Web Site : http://kdstevens.com/~stevens/ispell-page.html | 11 | ;; Web Site : http://kdstevens.com/~stevens/ispell-page.html |
| @@ -129,6 +129,24 @@ | |||
| 129 | 129 | ||
| 130 | ;; Modifications made in latest versions: | 130 | ;; Modifications made in latest versions: |
| 131 | 131 | ||
| 132 | ;; Revision 3.6 2003/01/07 12:32:44 kss | ||
| 133 | ;; Removed extra -d LIB in dictionary defs. (Pavel Janik) | ||
| 134 | ;; Filtered process calls with duplicate dictionary entries. | ||
| 135 | ;; Fixed bug where message-text-end is inside a mime skipped region. | ||
| 136 | ;; Minor fixes to get ispell menus right in XEmacs | ||
| 137 | ;; Fixed skip regexp so it doesn't match stuff like `/.\w'. | ||
| 138 | ;; Detecting dictionary change not working. Fixed. kss | ||
| 139 | ;; function `ispell-change-dictionary' now only completes valid dicts. | ||
| 140 | |||
| 141 | ;; Revision 3.5 2001/7/11 18:43:57 kss | ||
| 142 | ;; Added fix for aspell to work in XEmacs (ispell-check-version). | ||
| 143 | ;; Added Portuguese dictionary definition. | ||
| 144 | ;; New feature: MIME mail message support, Fcc support. | ||
| 145 | ;; Bug fix: retain comment syntax on lines with region skipping. (TeX $ bug...) | ||
| 146 | ;; Improved allocation for graphic mode lines. (Miles Bader) | ||
| 147 | ;; Support -v flag for old versions of aspell. (Eli Zaretskii) | ||
| 148 | ;; Clear minibuffer on ^G from ispell-help (Tak Ota) | ||
| 149 | |||
| 132 | ;; Revision 3.4 2000/8/4 09:41:50 kss | 150 | ;; Revision 3.4 2000/8/4 09:41:50 kss |
| 133 | ;; Support new color display functions. | 151 | ;; Support new color display functions. |
| 134 | ;; Fixed misalignment offset bug when replacing a string after a shift made. | 152 | ;; Fixed misalignment offset bug when replacing a string after a shift made. |
| @@ -203,7 +221,7 @@ | |||
| 203 | (defun buffer-substring-no-properties (start end) | 221 | (defun buffer-substring-no-properties (start end) |
| 204 | (buffer-substring start end))) | 222 | (buffer-substring start end))) |
| 205 | 223 | ||
| 206 | (defalias 'ispell-check-version 'check-ispell-version) | 224 | (defalias 'check-ispell-version 'ispell-check-version) |
| 207 | 225 | ||
| 208 | ;;; ********************************************************************** | 226 | ;;; ********************************************************************** |
| 209 | ;;; The following variables should be set according to personal preference | 227 | ;;; The following variables should be set according to personal preference |
| @@ -308,6 +326,13 @@ E.g. you may use the following value: | |||
| 308 | :group 'ispell) | 326 | :group 'ispell) |
| 309 | 327 | ||
| 310 | 328 | ||
| 329 | (defcustom ispell-message-fcc-skip 50000 | ||
| 330 | "*Query before saving Fcc message copy if attachment larger than this value. | ||
| 331 | Always stores Fcc copy of message when nil." | ||
| 332 | :type '(choice integer (const :tag "off" nil)) | ||
| 333 | :group 'ispell) | ||
| 334 | |||
| 335 | |||
| 311 | (defcustom ispell-grep-command "egrep" | 336 | (defcustom ispell-grep-command "egrep" |
| 312 | "Name of the grep command for search processes." | 337 | "Name of the grep command for search processes." |
| 313 | :type 'string | 338 | :type 'string |
| @@ -445,12 +470,20 @@ buffer's major mode." | |||
| 445 | (const :tag "use-mode-name" use-mode-name)) | 470 | (const :tag "use-mode-name" use-mode-name)) |
| 446 | :group 'ispell) | 471 | :group 'ispell) |
| 447 | 472 | ||
| 473 | (make-variable-buffer-local 'ispell-skip-html) | ||
| 474 | |||
| 448 | 475 | ||
| 449 | ;;; Define definitions here only for personal dictionaries. | 476 | ;;; Define definitions here only for personal dictionaries. |
| 450 | ;;;###autoload | 477 | ;;;###autoload |
| 451 | (defcustom ispell-local-dictionary-alist nil | 478 | (defcustom ispell-local-dictionary-alist nil |
| 452 | "*Contains local or customized dictionary definitions. | 479 | "*Contains local or customized dictionary definitions. |
| 453 | See `ispell-dictionary-alist'." | 480 | |
| 481 | These will override the values in `ispell-dictionary-alist'. | ||
| 482 | |||
| 483 | Customization changes made to `ispell-dictionary-alist' will not operate | ||
| 484 | over emacs sessions. To make permanent changes to your dictionary | ||
| 485 | definitions, you will need to make your changes in this variable, save, | ||
| 486 | and then re-start emacs." | ||
| 454 | :type '(repeat (list (choice :tag "Dictionary" | 487 | :type '(repeat (list (choice :tag "Dictionary" |
| 455 | (string :tag "Dictionary name") | 488 | (string :tag "Dictionary name") |
| 456 | (const :tag "default" nil)) | 489 | (const :tag "default" nil)) |
| @@ -465,7 +498,7 @@ See `ispell-dictionary-alist'." | |||
| 465 | (const "~nroff") (const "~list") | 498 | (const "~nroff") (const "~list") |
| 466 | (const "~latin1") (const "~latin3") | 499 | (const "~latin1") (const "~latin3") |
| 467 | (const :tag "default" nil)) | 500 | (const :tag "default" nil)) |
| 468 | (choice :tag "Character set" | 501 | (choice :tag "Coding system" |
| 469 | (const iso-8859-1) | 502 | (const iso-8859-1) |
| 470 | (const iso-8859-2) | 503 | (const iso-8859-2) |
| 471 | (const koi8-r)))) | 504 | (const koi8-r)))) |
| @@ -485,13 +518,13 @@ See `ispell-dictionary-alist'." | |||
| 485 | ("brasileiro" ; Brazilian mode | 518 | ("brasileiro" ; Brazilian mode |
| 486 | "[A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]" | 519 | "[A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]" |
| 487 | "[^A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]" | 520 | "[^A-Z\301\311\315\323\332\300\310\314\322\331\303\325\307\334\302\312\324a-z\341\351\355\363\372\340\350\354\362\371\343\365\347\374\342\352\364]" |
| 488 | "[']" nil ("-d" "brasileiro") nil iso-8859-1) | 521 | "[']" nil nil nil iso-8859-1) |
| 489 | ("british" ; British version | 522 | ("british" ; British version |
| 490 | "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B" "-d" "british") nil iso-8859-1) | 523 | "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1) |
| 491 | ("castellano" ; Spanish mode | 524 | ("castellano" ; Spanish mode |
| 492 | "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" | 525 | "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" |
| 493 | "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" | 526 | "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" |
| 494 | "[-]" nil ("-B" "-d" "castellano") "~tex" iso-8859-1) | 527 | "[-]" nil ("-B") "~tex" iso-8859-1) |
| 495 | ("castellano8" ; 8 bit Spanish mode | 528 | ("castellano8" ; 8 bit Spanish mode |
| 496 | "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" | 529 | "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" |
| 497 | "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" | 530 | "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]" |
| @@ -505,7 +538,7 @@ See `ispell-dictionary-alist'." | |||
| 505 | '(("czech" | 538 | '(("czech" |
| 506 | "[A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" | 539 | "[A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" |
| 507 | "[^A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" | 540 | "[^A-Za-z\301\311\314\315\323\332\331\335\256\251\310\330\317\253\322\341\351\354\355\363\372\371\375\276\271\350\370\357\273\362]" |
| 508 | "" nil ("-B" "-d" "czech") nil iso-8859-2) | 541 | "" nil ("-B") nil iso-8859-2) |
| 509 | ("dansk" ; Dansk.aff | 542 | ("dansk" ; Dansk.aff |
| 510 | "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]" | 543 | "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]" |
| 511 | "[']" nil ("-C") nil iso-8859-1) | 544 | "[']" nil ("-C") nil iso-8859-1) |
| @@ -535,76 +568,77 @@ See `ispell-dictionary-alist'." | |||
| 535 | ("francais" ; Francais.aff | 568 | ("francais" ; Francais.aff |
| 536 | "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" | 569 | "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" |
| 537 | "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" | 570 | "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374]" |
| 538 | "[-']" t nil "~list" iso-8859-1))) | 571 | "[-']" t nil "~list" iso-8859-1) |
| 572 | ("francais-tex" ; Francais.aff | ||
| 573 | "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" | ||
| 574 | "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" | ||
| 575 | "[-'^`\"]" t nil "~tex" iso-8859-1))) | ||
| 539 | 576 | ||
| 540 | 577 | ||
| 541 | ;;; Fourth part of dictionary, shortened for loaddefs.el | 578 | ;;; Fourth part of dictionary, shortened for loaddefs.el |
| 542 | ;;;###autoload | 579 | ;;;###autoload |
| 543 | (setq | 580 | (setq |
| 544 | ispell-dictionary-alist-4 | 581 | ispell-dictionary-alist-4 |
| 545 | '(("francais-tex" ; Francais.aff | 582 | '(("german" ; german.aff |
| 546 | "[A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" | ||
| 547 | "[^A-Za-z\300\302\306\307\310\311\312\313\316\317\324\331\333\334\340\342\347\350\351\352\353\356\357\364\371\373\374\\]" | ||
| 548 | "[-'^`\"]" t nil "~tex" iso-8859-1) | ||
| 549 | ("german" ; german.aff | ||
| 550 | "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1) | 583 | "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1) |
| 551 | ("german8" | 584 | ("german8" ; german.aff |
| 552 | "[a-zA-Z\304\326\334\344\366\337\374]" | 585 | "[a-zA-Z\304\326\334\344\366\337\374]" |
| 553 | "[^a-zA-Z\304\326\334\344\366\337\374]" | 586 | "[^a-zA-Z\304\326\334\344\366\337\374]" |
| 554 | "[']" t ("-C" "-d" "german") "~latin1" iso-8859-1) | 587 | "[']" t ("-C" "-d" "german") "~latin1" iso-8859-1) |
| 555 | ("italiano" ; Italian.aff | 588 | ("italiano" ; Italian.aff |
| 556 | "[A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" | 589 | "[A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" |
| 557 | "[^A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" | 590 | "[^A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]" |
| 558 | "[-]" nil ("-B" "-d" "italian") "~tex" iso-8859-1))) | 591 | "[-]" nil ("-B" "-d" "italian") "~tex" iso-8859-1) |
| 559 | 592 | ("nederlands" ; Nederlands.aff | |
| 560 | |||
| 561 | ;;; Fifth part of dictionary, shortened for loaddefs.el | ||
| 562 | ;;;###autoload | ||
| 563 | (setq | ||
| 564 | ispell-dictionary-alist-5 | ||
| 565 | '(("nederlands" ; Nederlands.aff | ||
| 566 | "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" | 593 | "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
| 567 | "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" | 594 | "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
| 568 | "[']" t ("-C") nil iso-8859-1) | 595 | "[']" t ("-C") nil iso-8859-1) |
| 569 | ("nederlands8" ; Dutch8.aff | 596 | ("nederlands8" ; Dutch8.aff |
| 570 | "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" | 597 | "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
| 571 | "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" | 598 | "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]" |
| 572 | "[']" t ("-C") nil iso-8859-1) | 599 | "[']" t ("-C") nil iso-8859-1))) |
| 573 | ("norsk" ; 8 bit Norwegian mode | 600 | |
| 601 | |||
| 602 | ;;; Fifth part of dictionary, shortened for loaddefs.el | ||
| 603 | ;;;###autoload | ||
| 604 | (setq | ||
| 605 | ispell-dictionary-alist-5 | ||
| 606 | '(("norsk" ; 8 bit Norwegian mode | ||
| 574 | "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" | 607 | "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" |
| 575 | "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" | 608 | "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]" |
| 576 | "[\"]" nil ("-d" "norsk") "~list" iso-8859-1) | 609 | "[\"]" nil nil "~list" iso-8859-1) |
| 577 | ("norsk7-tex" ; 7 bit Norwegian TeX mode | 610 | ("norsk7-tex" ; 7 bit Norwegian TeX mode |
| 578 | "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]" | 611 | "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]" |
| 579 | "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1))) | 612 | "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1) |
| 613 | ("polish" ; Polish mode | ||
| 614 | "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" | ||
| 615 | "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" | ||
| 616 | "" nil nil nil iso-8859-2) | ||
| 617 | ("portugues" ; Portuguese mode | ||
| 618 | "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" | ||
| 619 | "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" | ||
| 620 | "[']" t ("-C") "~latin1" iso-8859-1))) | ||
| 580 | 621 | ||
| 581 | 622 | ||
| 582 | ;;; Sixth part of dictionary, shortened for loaddefs.el | 623 | ;;; Sixth part of dictionary, shortened for loaddefs.el |
| 583 | ;;;###autoload | 624 | ;;;###autoload |
| 584 | (setq | 625 | (setq |
| 585 | ispell-dictionary-alist-6 | 626 | ispell-dictionary-alist-6 |
| 586 | ;; include Russian iso character set too? | 627 | ;; include Russian iso coding system too? |
| 587 | ;; "[']" t ("-d" "russian") "~latin1" iso-8859-1 | 628 | ;; "[']" t ("-d" "russian") "~latin1" iso-8859-1 |
| 588 | '(("polish" ; polish mode | 629 | '(("russian" ; Russian.aff (KOI8-R charset) |
| 589 | "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" | ||
| 590 | "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]" | ||
| 591 | "" nil ( "-d" "polish") nil iso-8859-2) | ||
| 592 | ("russian" ; Russian.aff (KOI8-R charset) | ||
| 593 | "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" | 630 | "[\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" |
| 594 | "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" | 631 | "[^\341\342\367\347\344\345\263\366\372\351\352\353\354\355\356\357\360\362\363\364\365\346\350\343\376\373\375\370\371\377\374\340\361\301\302\327\307\304\305\243\326\332\311\312\313\314\315\316\317\320\322\323\324\325\306\310\303\336\333\335\330\331\337\334\300\321]" |
| 595 | "" nil ("-d" "russian") nil koi8-r) | 632 | "" nil nil nil koi8-r) |
| 633 | ("slovak" ; Slovakian | ||
| 634 | "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" | ||
| 635 | "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" | ||
| 636 | "" nil ("-B") nil iso-8859-2) | ||
| 596 | ("svenska" ; Swedish mode | 637 | ("svenska" ; Swedish mode |
| 597 | "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" | 638 | "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" |
| 598 | "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" | 639 | "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]" |
| 599 | "[']" nil ("-C") "~list" iso-8859-1) | 640 | "[']" nil ("-C") "~list" iso-8859-1))) |
| 600 | ("portugues" | 641 | |
| 601 | "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" | ||
| 602 | "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]" | ||
| 603 | "[']" t ("-C" "-d" "portugues") "~latin1" iso-8859-1) | ||
| 604 | ("slovak" | ||
| 605 | "[A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" | ||
| 606 | "[^A-Za-z\301\304\311\315\323\332\324\300\305\245\335\256\251\310\317\253\322\341\344\351\355\363\372\364\340\345\265\375\276\271\350\357\273\362]" | ||
| 607 | "" nil ("-B" "-d" "slovak") nil iso-8859-2))) | ||
| 608 | 642 | ||
| 609 | ;;;###autoload | 643 | ;;;###autoload |
| 610 | (defcustom ispell-dictionary-alist | 644 | (defcustom ispell-dictionary-alist |
| @@ -672,7 +706,7 @@ LANGUAGE.aff file \(e.g., english.aff\)." | |||
| 672 | (const "~nroff") (const "~list") | 706 | (const "~nroff") (const "~list") |
| 673 | (const "~latin1") (const "~latin3") | 707 | (const "~latin1") (const "~latin3") |
| 674 | (const :tag "default" nil)) | 708 | (const :tag "default" nil)) |
| 675 | (choice :tag "Character set" | 709 | (choice :tag "Coding System" |
| 676 | (const iso-8859-1) | 710 | (const iso-8859-1) |
| 677 | (const iso-8859-2) | 711 | (const iso-8859-2) |
| 678 | (const koi8-r)))) | 712 | (const koi8-r)))) |
| @@ -701,10 +735,10 @@ LANGUAGE.aff file \(e.g., english.aff\)." | |||
| 701 | (defvar ispell-offset -1 | 735 | (defvar ispell-offset -1 |
| 702 | "Offset that maps protocol differences between ispell 3.1 versions.") | 736 | "Offset that maps protocol differences between ispell 3.1 versions.") |
| 703 | 737 | ||
| 704 | (defconst ispell-version "ispell.el 3.4 -- Fri Aug 4 09:41:50 PDT 2000") | 738 | (defconst ispell-version "ispell.el 3.6 - 7-Jan-2003") |
| 705 | 739 | ||
| 706 | 740 | ||
| 707 | (defun check-ispell-version (&optional interactivep) | 741 | (defun ispell-check-version (&optional interactivep) |
| 708 | "Ensure that `ispell-program-name' is valid and the correct version. | 742 | "Ensure that `ispell-program-name' is valid and the correct version. |
| 709 | Returns version number if called interactively. | 743 | Returns version number if called interactively. |
| 710 | Otherwise returns the library directory name, if that is defined." | 744 | Otherwise returns the library directory name, if that is defined." |
| @@ -719,7 +753,9 @@ Otherwise returns the library directory name, if that is defined." | |||
| 719 | (let ((case-fold-search-val case-fold-search) | 753 | (let ((case-fold-search-val case-fold-search) |
| 720 | ;; avoid bugs when syntax of `.' changes in various default modes | 754 | ;; avoid bugs when syntax of `.' changes in various default modes |
| 721 | (default-major-mode 'fundamental-mode) | 755 | (default-major-mode 'fundamental-mode) |
| 722 | (default-directory temporary-file-directory) | 756 | (default-directory (or (and (boundp 'temporary-file-directory) |
| 757 | temporary-file-directory) | ||
| 758 | default-directory)) | ||
| 723 | result status) | 759 | result status) |
| 724 | (save-excursion | 760 | (save-excursion |
| 725 | (let ((buf (get-buffer " *ispell-tmp*"))) | 761 | (let ((buf (get-buffer " *ispell-tmp*"))) |
| @@ -737,6 +773,7 @@ Otherwise returns the library directory name, if that is defined." | |||
| 737 | (if (string-match "\\`aspell" speller) "-v" "-vv")))) | 773 | (if (string-match "\\`aspell" speller) "-v" "-vv")))) |
| 738 | (goto-char (point-min)) | 774 | (goto-char (point-min)) |
| 739 | (if interactivep | 775 | (if interactivep |
| 776 | ;; report version information of ispell and ispell.el | ||
| 740 | (progn | 777 | (progn |
| 741 | (end-of-line) | 778 | (end-of-line) |
| 742 | (setq result (concat (buffer-substring-no-properties (point-min) | 779 | (setq result (concat (buffer-substring-no-properties (point-min) |
| @@ -807,7 +844,7 @@ and added as a submenu of the \"Edit\" menu.") | |||
| 807 | 'reload)) | 844 | 'reload)) |
| 808 | 845 | ||
| 809 | (defvar ispell-library-directory (condition-case () | 846 | (defvar ispell-library-directory (condition-case () |
| 810 | (check-ispell-version) | 847 | (ispell-check-version) |
| 811 | (error nil)) | 848 | (error nil)) |
| 812 | "Directory where ispell dictionaries reside.") | 849 | "Directory where ispell dictionaries reside.") |
| 813 | 850 | ||
| @@ -823,37 +860,55 @@ and added as a submenu of the \"Edit\" menu.") | |||
| 823 | ) | 860 | ) |
| 824 | "Non-nil means that the OS supports asynchronous processes.") | 861 | "Non-nil means that the OS supports asynchronous processes.") |
| 825 | 862 | ||
| 863 | (defun ispell-valid-dictionary-list () | ||
| 864 | "Returns a list of valid dictionaries. | ||
| 865 | The variable `ispell-library-directory' defines the library location." | ||
| 866 | (let ((dicts ispell-dictionary-alist) | ||
| 867 | (dict-list (cons "default" nil)) | ||
| 868 | name load-dict) | ||
| 869 | (dolist (dict dicts) | ||
| 870 | (setq name (car dict) | ||
| 871 | load-dict (car (cdr (member "-d" (nth 5 dict))))) | ||
| 872 | ;; Include if the dictionary is in the library, or dir not defined. | ||
| 873 | (if (and | ||
| 874 | name | ||
| 875 | ;; include all dictionaries if lib directory not known. | ||
| 876 | (or (not ispell-library-directory) | ||
| 877 | (file-exists-p (concat ispell-library-directory | ||
| 878 | "/" name ".hash")) | ||
| 879 | (file-exists-p (concat ispell-library-directory "/" name ".has")) | ||
| 880 | (and load-dict | ||
| 881 | (or (file-exists-p (concat ispell-library-directory | ||
| 882 | "/" load-dict ".hash")) | ||
| 883 | (file-exists-p (concat ispell-library-directory | ||
| 884 | "/" load-dict ".has")))))) | ||
| 885 | (setq dict-list (cons name dict-list)))) | ||
| 886 | dict-list)) | ||
| 887 | |||
| 888 | |||
| 826 | ;;;###autoload | 889 | ;;;###autoload |
| 827 | (if ispell-menu-map-needed | 890 | (if ispell-menu-map-needed |
| 828 | (let ((dicts (reverse (cons (cons "default" nil) ispell-dictionary-alist))) | 891 | (let ((dicts (if (fboundp 'ispell-valid-dictionary-list) |
| 829 | (dir (if (boundp 'ispell-library-directory) ispell-library-directory)) | 892 | (ispell-valid-dictionary-list) |
| 830 | (dict-map (make-sparse-keymap "Dictionaries")) | 893 | (mapcar (lambda (x) (or (car x) "default")) |
| 831 | name load-dict) | 894 | ispell-dictionary-alist))) |
| 895 | (dict-map (make-sparse-keymap "Dictionaries"))) | ||
| 832 | (setq ispell-menu-map (make-sparse-keymap "Spell")) | 896 | (setq ispell-menu-map (make-sparse-keymap "Spell")) |
| 833 | ;; add the dictionaries to the bottom of the list. | 897 | ;; add the dictionaries to the bottom of the list. |
| 834 | (define-key ispell-menu-map [default] | 898 | (if (not dicts) |
| 835 | '("Select Default Dict" | 899 | (define-key ispell-menu-map [default] |
| 836 | "Dictionary for which Ispell was configured" | 900 | '("Select Default Dict" |
| 837 | . (lambda () (interactive) | 901 | "Dictionary for which Ispell was configured" |
| 838 | (ispell-change-dictionary "default")))) | 902 | . (lambda () (interactive) |
| 903 | (ispell-change-dictionary "default"))))) | ||
| 839 | (fset 'ispell-dict-map dict-map) | 904 | (fset 'ispell-dict-map dict-map) |
| 840 | (define-key ispell-menu-map [dictionaries] | 905 | (define-key ispell-menu-map [dictionaries] |
| 841 | `(menu-item "Select Dict" ispell-dict-map)) | 906 | `(menu-item "Select Dict" ispell-dict-map)) |
| 842 | (dolist (dict dicts) | 907 | (dolist (name dicts) |
| 843 | (setq name (car dict) | 908 | (define-key dict-map (vector (intern name)) |
| 844 | load-dict (car (cdr (member "-d" (nth 5 dict))))) | 909 | (cons (concat "Select " (capitalize name) " Dict") |
| 845 | (cond ((not (stringp name))) | 910 | `(lambda () (interactive) |
| 846 | ((or (not dir) ; load all if library dir not defined | 911 | (ispell-change-dictionary ,name))))))) |
| 847 | (file-exists-p (concat dir "/" name ".hash")) | ||
| 848 | (file-exists-p (concat dir "/" name ".has")) | ||
| 849 | (and load-dict | ||
| 850 | (or (file-exists-p (concat dir "/" load-dict ".hash")) | ||
| 851 | (file-exists-p (concat dir "/" load-dict ".has"))))) | ||
| 852 | (define-key dict-map (vector (intern name)) | ||
| 853 | (cons (concat "Select " (capitalize name) " Dict") | ||
| 854 | `(lambda () (interactive) | ||
| 855 | (ispell-change-dictionary ,name))))))))) | ||
| 856 | |||
| 857 | 912 | ||
| 858 | ;;; define commands in menu in opposite order you want them to appear. | 913 | ;;; define commands in menu in opposite order you want them to appear. |
| 859 | ;;;###autoload | 914 | ;;;###autoload |
| @@ -928,9 +983,10 @@ and added as a submenu of the \"Edit\" menu.") | |||
| 928 | ;;; XEmacs versions 19 & 20 | 983 | ;;; XEmacs versions 19 & 20 |
| 929 | (if (and (featurep 'xemacs) | 984 | (if (and (featurep 'xemacs) |
| 930 | (featurep 'menubar) | 985 | (featurep 'menubar) |
| 931 | (null ispell-menu-xemacs) | 986 | ;;(null ispell-menu-xemacs) |
| 932 | (not (and (boundp 'infodock-version) infodock-version))) | 987 | (not (and (boundp 'infodock-version) infodock-version))) |
| 933 | (let ((dicts (cons (cons "default" nil) ispell-dictionary-alist)) | 988 | (let ((dicts (if (fboundp 'ispell-valid-dictionary-list) |
| 989 | (reverse (ispell-valid-dictionary-list)))) | ||
| 934 | (current-menubar (or current-menubar default-menubar)) | 990 | (current-menubar (or current-menubar default-menubar)) |
| 935 | (menu | 991 | (menu |
| 936 | '(["Help" (describe-function 'ispell-help) t] | 992 | '(["Help" (describe-function 'ispell-help) t] |
| @@ -944,37 +1000,33 @@ and added as a submenu of the \"Edit\" menu.") | |||
| 944 | ["Complete Word Frag"ispell-complete-word-interior-frag t] | 1000 | ["Complete Word Frag"ispell-complete-word-interior-frag t] |
| 945 | ["Complete Word" ispell-complete-word t] | 1001 | ["Complete Word" ispell-complete-word t] |
| 946 | ["Kill Process" ispell-kill-ispell t] | 1002 | ["Kill Process" ispell-kill-ispell t] |
| 1003 | ["Customize..." (customize-group 'ispell) t] | ||
| 1004 | ;; flyspell-mode may not be bound... | ||
| 1005 | ;;["flyspell" flyspell-mode | ||
| 1006 | ;; :style toggle :selected flyspell-mode ] | ||
| 947 | "-" | 1007 | "-" |
| 948 | ["Save Personal Dict"(ispell-pdict-save t t) t] | 1008 | ["Save Personal Dict"(ispell-pdict-save t t) t] |
| 949 | ["Change Dictionary" ispell-change-dictionary t] | 1009 | ["Change Dictionary" ispell-change-dictionary t]))) |
| 950 | ["Select Default" (ispell-change-dictionary "default") t])) | 1010 | (if (null dicts) |
| 951 | name load-dict) | 1011 | (setq dicts (cons "default" nil))) |
| 952 | (while dicts | 1012 | (dolist (name dicts) |
| 953 | (setq name (car (car dicts)) | 1013 | (setq menu (append menu |
| 954 | load-dict (car (cdr (member "-d" (nth 5 (car dicts))))) | 1014 | (list |
| 955 | dicts (cdr dicts)) | 1015 | (vector |
| 956 | ;; Include if the dictionary is in the library, or dir not defined. | 1016 | (concat "Select " (capitalize name)) |
| 957 | (if (and (stringp name) | 1017 | (list 'ispell-change-dictionary name) |
| 958 | (or (not ispell-library-directory) | 1018 | t))))) |
| 959 | (file-exists-p (concat ispell-library-directory "/" | ||
| 960 | name ".hash")) | ||
| 961 | (file-exists-p (concat ispell-library-directory "/" | ||
| 962 | name ".has")) | ||
| 963 | (and load-dict | ||
| 964 | (or (file-exists-p (concat ispell-library-directory "/" | ||
| 965 | load-dict ".hash")) | ||
| 966 | (file-exists-p (concat ispell-library-directory "/" | ||
| 967 | load-dict ".has")))))) | ||
| 968 | (setq menu (append menu | ||
| 969 | (list | ||
| 970 | (vector (concat "Select " (capitalize name)) | ||
| 971 | (list 'ispell-change-dictionary name) | ||
| 972 | t)))))) | ||
| 973 | (setq ispell-menu-xemacs menu) | 1019 | (setq ispell-menu-xemacs menu) |
| 974 | (if current-menubar | 1020 | (if current-menubar |
| 975 | (progn | 1021 | (progn |
| 976 | (delete-menu-item '("Edit" "Spell")) ; in case already defined | 1022 | (if (car (find-menu-item current-menubar '("Cmds"))) |
| 977 | (add-menu '("Edit") "Spell" ispell-menu-xemacs))))) | 1023 | (progn |
| 1024 | ;; XEmacs 21.2 | ||
| 1025 | (delete-menu-item '("Cmds" "Spell-Check")) | ||
| 1026 | (add-menu '("Cmds") "Spell-Check" ispell-menu-xemacs)) | ||
| 1027 | ;; previous | ||
| 1028 | (delete-menu-item '("Edit" "Spell")) ; in case already defined | ||
| 1029 | (add-menu '("Edit") "Spell" ispell-menu-xemacs)))))) | ||
| 978 | 1030 | ||
| 979 | ;;; Allow incrementing characters as integers in XEmacs 20 | 1031 | ;;; Allow incrementing characters as integers in XEmacs 20 |
| 980 | (if (and (featurep 'xemacs) | 1032 | (if (and (featurep 'xemacs) |
| @@ -1060,7 +1112,8 @@ Protects against bogus binding of `enable-multibyte-characters' in XEmacs." | |||
| 1060 | "Marker for return point from recursive edit.") | 1112 | "Marker for return point from recursive edit.") |
| 1061 | 1113 | ||
| 1062 | (defvar ispell-checking-message nil | 1114 | (defvar ispell-checking-message nil |
| 1063 | "Non-nil when we're checking a mail message.") | 1115 | "Non-nil when we're checking a mail message. |
| 1116 | Set to the MIME boundary locations when checking messages.") | ||
| 1064 | 1117 | ||
| 1065 | (defconst ispell-choices-buffer "*Choices*") | 1118 | (defconst ispell-choices-buffer "*Choices*") |
| 1066 | 1119 | ||
| @@ -1100,10 +1153,16 @@ The last occurring definition in the buffer will be used.") | |||
| 1100 | (ispell-pdict-keyword forward-line) | 1153 | (ispell-pdict-keyword forward-line) |
| 1101 | (ispell-parsing-keyword forward-line) | 1154 | (ispell-parsing-keyword forward-line) |
| 1102 | ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*") | 1155 | ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*") |
| 1103 | ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage" . "^---* End of [Ff]orwarded [Mm]essage") | 1156 | ;; assume multiline uuencoded file? "\nM.*$"? |
| 1157 | ("^begin [0-9][0-9][0-9] [^ \t]+$" . "\nend\n") | ||
| 1158 | ("^%!PS-Adobe-[123].0" . "\n%%EOF\n") | ||
| 1159 | ("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage" | ||
| 1160 | . "^---* End of [Ff]orwarded [Mm]essage") | ||
| 1104 | ;; Matches e-mail addresses, file names, http addresses, etc. The `-+' | 1161 | ;; Matches e-mail addresses, file names, http addresses, etc. The `-+' |
| 1105 | ;; pattern necessary for performance reasons when `-' part of word syntax. | 1162 | ;; pattern necessary for performance reasons when `-' part of word syntax. |
| 1106 | ("\\(-+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+\\)") | 1163 | ("\\(--+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)") |
| 1164 | ;; above checks /.\w sequences | ||
| 1165 | ;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)") | ||
| 1107 | ;; This is a pretty complex regexp. It can be simplified to the following: | 1166 | ;; This is a pretty complex regexp. It can be simplified to the following: |
| 1108 | ;; "\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+" | 1167 | ;; "\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+" |
| 1109 | ;; but some valid text will be skipped, e.g. "his/her". This could be | 1168 | ;; but some valid text will be skipped, e.g. "his/her". This could be |
| @@ -1151,6 +1210,22 @@ Delete or add any regions you want to be automatically selected | |||
| 1151 | for skipping in latex mode.") | 1210 | for skipping in latex mode.") |
| 1152 | 1211 | ||
| 1153 | 1212 | ||
| 1213 | ;;;###autoload | ||
| 1214 | (defvar ispell-html-skip-alists | ||
| 1215 | '(("<[cC][oO][dD][eE]\\>[^>]*>" "</[cC][oO][dD][eE]*>") | ||
| 1216 | ("<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "</[sS][cC][rR][iI][pP][tT]>") | ||
| 1217 | ("<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "</[aA][pP][pP][lL][eE][tT]>") | ||
| 1218 | ("<[vV][eE][rR][bB]\\>[^>]*>" "<[vV][eE][rR][bB]\\>[^>]*>") | ||
| 1219 | ;;("<[tT][tT]\\>[^>]*>" "<[tT][tT]\\>[^>]*>") | ||
| 1220 | ("<[tT][tT]/" "/") | ||
| 1221 | ("<[^ \t\n>]" ">") | ||
| 1222 | ("&[^ \t\n;]" "[; \t\n]")) | ||
| 1223 | "*Lists of start and end keys to skip in HTML buffers. | ||
| 1224 | Same format as `ispell-skip-region-alist' | ||
| 1225 | Note - substrings of other matches must come last | ||
| 1226 | (e.g. \"<[tT][tT]/\" and \"<[^ \t\n>]\").") | ||
| 1227 | |||
| 1228 | |||
| 1154 | (defvar ispell-local-pdict ispell-personal-dictionary | 1229 | (defvar ispell-local-pdict ispell-personal-dictionary |
| 1155 | "A buffer local variable containing the current personal dictionary. | 1230 | "A buffer local variable containing the current personal dictionary. |
| 1156 | If non-nil, the value must be a string, which is a file name. | 1231 | If non-nil, the value must be a string, which is a file name. |
| @@ -1241,9 +1316,8 @@ pass it the output of the last ispell invocation." | |||
| 1241 | (insert string) | 1316 | (insert string) |
| 1242 | (if (not (memq cmd cmds-to-defer)) | 1317 | (if (not (memq cmd cmds-to-defer)) |
| 1243 | (let (coding-system-for-read coding-system-for-write status) | 1318 | (let (coding-system-for-read coding-system-for-write status) |
| 1244 | (if (or (featurep 'xemacs) | 1319 | (if (and (boundp 'enable-multibyte-characters) |
| 1245 | (and (boundp 'enable-multibyte-characters) | 1320 | enable-multibyte-characters) |
| 1246 | enable-multibyte-characters)) | ||
| 1247 | (setq coding-system-for-read (ispell-get-coding-system) | 1321 | (setq coding-system-for-read (ispell-get-coding-system) |
| 1248 | coding-system-for-write (ispell-get-coding-system))) | 1322 | coding-system-for-write (ispell-get-coding-system))) |
| 1249 | (set-buffer output-buf) | 1323 | (set-buffer output-buf) |
| @@ -1313,7 +1387,7 @@ This will check or reload the dictionary. Use \\[ispell-change-dictionary] | |||
| 1313 | or \\[ispell-region] to update the Ispell process. | 1387 | or \\[ispell-region] to update the Ispell process. |
| 1314 | 1388 | ||
| 1315 | return values: | 1389 | return values: |
| 1316 | nil word is correct or spelling is accpeted. | 1390 | nil word is correct or spelling is accepted. |
| 1317 | 0 word is inserted into buffer-local definitions. | 1391 | 0 word is inserted into buffer-local definitions. |
| 1318 | \"word\" word corrected from word list. | 1392 | \"word\" word corrected from word list. |
| 1319 | \(\"word\" arg\) word is hand entered. | 1393 | \(\"word\" arg\) word is hand entered. |
| @@ -1355,16 +1429,26 @@ quit spell session exited." | |||
| 1355 | (cond ((eq poss t) | 1429 | (cond ((eq poss t) |
| 1356 | (or quietly | 1430 | (or quietly |
| 1357 | (message "%s is correct" | 1431 | (message "%s is correct" |
| 1358 | (funcall ispell-format-word word)))) | 1432 | (funcall ispell-format-word word))) |
| 1433 | (and (fboundp 'extent-at) | ||
| 1434 | (extent-at start) | ||
| 1435 | (delete-extent (extent-at start)))) | ||
| 1359 | ((stringp poss) | 1436 | ((stringp poss) |
| 1360 | (or quietly | 1437 | (or quietly |
| 1361 | (message "%s is correct because of root %s" | 1438 | (message "%s is correct because of root %s" |
| 1362 | (funcall ispell-format-word word) | 1439 | (funcall ispell-format-word word) |
| 1363 | (funcall ispell-format-word poss)))) | 1440 | (funcall ispell-format-word poss))) |
| 1441 | (and (fboundp 'extent-at) | ||
| 1442 | (extent-at start) | ||
| 1443 | (delete-extent (extent-at start)))) | ||
| 1364 | ((null poss) (message "Error in ispell process")) | 1444 | ((null poss) (message "Error in ispell process")) |
| 1365 | (ispell-check-only ; called from ispell minor mode. | 1445 | (ispell-check-only ; called from ispell minor mode. |
| 1366 | (beep) | 1446 | (if (fboundp 'make-extent) |
| 1367 | (message "%s is incorrect" (funcall ispell-format-word word))) | 1447 | (let ((ext (make-extent start end))) |
| 1448 | (set-extent-property ext 'face ispell-highlight-face) | ||
| 1449 | (set-extent-property ext 'priority 2000)) | ||
| 1450 | (beep) | ||
| 1451 | (message "%s is incorrect"(funcall ispell-format-word word)))) | ||
| 1368 | (t ; prompt for correct word. | 1452 | (t ; prompt for correct word. |
| 1369 | (save-window-excursion | 1453 | (save-window-excursion |
| 1370 | (setq replace (ispell-command-loop | 1454 | (setq replace (ispell-command-loop |
| @@ -1516,9 +1600,11 @@ Global `ispell-quit' set to start location to continue spell session." | |||
| 1516 | (save-excursion | 1600 | (save-excursion |
| 1517 | (set-buffer (get-buffer-create ispell-choices-buffer)) | 1601 | (set-buffer (get-buffer-create ispell-choices-buffer)) |
| 1518 | (setq mode-line-format (concat "-- %b -- word: " word)) | 1602 | (setq mode-line-format (concat "-- %b -- word: " word)) |
| 1519 | ;; XEmacs: prevent thick modeline vs increasing height in overlay-window | 1603 | ;; XEmacs: no need for horizontal scrollbar in choices window |
| 1520 | ;;(and (fboundp 'set-specifier) | 1604 | (and (fboundp 'set-specifier) |
| 1521 | ;; (set-specifier has-modeline-p (cons (current-buffer) nil))) | 1605 | (boundp 'horizontal-scrollbar-visible-p) |
| 1606 | (set-specifier horizontal-scrollbar-visible-p nil | ||
| 1607 | (cons (current-buffer) nil))) | ||
| 1522 | (erase-buffer) | 1608 | (erase-buffer) |
| 1523 | (if guess | 1609 | (if guess |
| 1524 | (progn | 1610 | (progn |
| @@ -1789,7 +1875,7 @@ Global `ispell-quit' set to start location to continue spell session." | |||
| 1789 | (set-window-start (selected-window) | 1875 | (set-window-start (selected-window) |
| 1790 | (if (> (point) visible) visible (point))) | 1876 | (if (> (point) visible) visible (point))) |
| 1791 | (goto-char end) | 1877 | (goto-char end) |
| 1792 | (select-window (previous-window)) ; *Choices* window | 1878 | (select-window choices-window) |
| 1793 | (enlarge-window window-line))) | 1879 | (enlarge-window window-line))) |
| 1794 | ;; Overlay *Choices* window when it isn't showing | 1880 | ;; Overlay *Choices* window when it isn't showing |
| 1795 | (ispell-overlay-window (max line ispell-choices-win-default-height))) | 1881 | (ispell-overlay-window (max line ispell-choices-win-default-height))) |
| @@ -1830,9 +1916,9 @@ SPC: Accept word this time. | |||
| 1830 | ;;This shouldn't be necessary: with-electric-help needs | 1916 | ;;This shouldn't be necessary: with-electric-help needs |
| 1831 | ;; an optional argument telling it about the smallest | 1917 | ;; an optional argument telling it about the smallest |
| 1832 | ;; acceptable window-height of the help buffer. | 1918 | ;; acceptable window-height of the help buffer. |
| 1833 | (if (< (window-height) 15) | 1919 | ;;(if (< (window-height) 15) |
| 1834 | (enlarge-window | 1920 | ;; (enlarge-window |
| 1835 | (- 15 (ispell-adjusted-window-height)))) | 1921 | ;; (- 15 (ispell-adjusted-window-height)))) |
| 1836 | (princ "Selections are: | 1922 | (princ "Selections are: |
| 1837 | 1923 | ||
| 1838 | DIGIT: Replace the word with a digit offered in the *Choices* buffer. | 1924 | DIGIT: Replace the word with a digit offered in the *Choices* buffer. |
| @@ -2062,9 +2148,8 @@ text line, the returned value may be smaller than that from | |||
| 2062 | `window-height'." | 2148 | `window-height'." |
| 2063 | (cond ((fboundp 'window-text-height) | 2149 | (cond ((fboundp 'window-text-height) |
| 2064 | (1+ (window-text-height window))) | 2150 | (1+ (window-text-height window))) |
| 2065 | ((if (fboundp 'display-graphic-p) | 2151 | ((or (and (fboundp 'display-graphic-p) (display-graphic-p)) |
| 2066 | (display-graphic-p) | 2152 | (and (featurep 'xemacs) window-system)) |
| 2067 | (featurep 'xemacs)) | ||
| 2068 | (1- (window-height window))) | 2153 | (1- (window-height window))) |
| 2069 | (t | 2154 | (t |
| 2070 | (window-height window)))) | 2155 | (window-height window)))) |
| @@ -2171,7 +2256,8 @@ Keeps argument list for future ispell invocations for no async support." | |||
| 2171 | (if ispell-local-dictionary | 2256 | (if ispell-local-dictionary |
| 2172 | (setq ispell-dictionary ispell-local-dictionary)) | 2257 | (setq ispell-dictionary ispell-local-dictionary)) |
| 2173 | (setq args (ispell-get-ispell-args)) | 2258 | (setq args (ispell-get-ispell-args)) |
| 2174 | (if ispell-dictionary ; use specified dictionary | 2259 | (if (and ispell-dictionary ; use specified dictionary |
| 2260 | (not (member "-d" args))) ; only define if not overridden | ||
| 2175 | (setq args | 2261 | (setq args |
| 2176 | (append (list "-d" ispell-dictionary) args))) | 2262 | (append (list "-d" ispell-dictionary) args))) |
| 2177 | (if ispell-personal-dictionary ; use specified pers dict | 2263 | (if ispell-personal-dictionary ; use specified pers dict |
| @@ -2209,8 +2295,8 @@ Keeps argument list for future ispell invocations for no async support." | |||
| 2209 | (ispell-kill-ispell t) | 2295 | (ispell-kill-ispell t) |
| 2210 | (message "Starting new Ispell process...") | 2296 | (message "Starting new Ispell process...") |
| 2211 | (sit-for 0) | 2297 | (sit-for 0) |
| 2212 | (check-ispell-version) | 2298 | (setq ispell-library-directory (ispell-check-version) |
| 2213 | (setq ispell-process-directory default-directory | 2299 | ispell-process-directory default-directory |
| 2214 | ispell-process (ispell-start-process) | 2300 | ispell-process (ispell-start-process) |
| 2215 | ispell-filter nil | 2301 | ispell-filter nil |
| 2216 | ispell-filter-continue nil) | 2302 | ispell-filter-continue nil) |
| @@ -2298,7 +2384,9 @@ With prefix argument, set the default dictionary." | |||
| 2298 | (interactive | 2384 | (interactive |
| 2299 | (list (completing-read | 2385 | (list (completing-read |
| 2300 | "Use new dictionary (RET for current, SPC to complete): " | 2386 | "Use new dictionary (RET for current, SPC to complete): " |
| 2301 | (cons (cons "default" nil) ispell-dictionary-alist) nil t) | 2387 | (and (fboundp 'ispell-valid-dictionary-list) |
| 2388 | (mapcar (lambda (x)(cons x nil)) (ispell-valid-dictionary-list))) | ||
| 2389 | nil t) | ||
| 2302 | current-prefix-arg)) | 2390 | current-prefix-arg)) |
| 2303 | (if (equal dict "default") (setq dict nil)) | 2391 | (if (equal dict "default") (setq dict nil)) |
| 2304 | ;; This relies on completing-read's bug of returning "" for no match | 2392 | ;; This relies on completing-read's bug of returning "" for no match |
| @@ -2342,6 +2430,8 @@ Return nil if spell session is quit, | |||
| 2342 | (interactive "r") ; Don't flag errors on read-only bufs. | 2430 | (interactive "r") ; Don't flag errors on read-only bufs. |
| 2343 | (if (not recheckp) | 2431 | (if (not recheckp) |
| 2344 | (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc. | 2432 | (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc. |
| 2433 | (let ((skip-region-start (make-marker)) | ||
| 2434 | (rstart (make-marker))) | ||
| 2345 | (unwind-protect | 2435 | (unwind-protect |
| 2346 | (save-excursion | 2436 | (save-excursion |
| 2347 | (message "Spell checking %s using %s dictionary..." | 2437 | (message "Spell checking %s using %s dictionary..." |
| @@ -2353,19 +2443,11 @@ Return nil if spell session is quit, | |||
| 2353 | (goto-char reg-start) | 2443 | (goto-char reg-start) |
| 2354 | (let ((transient-mark-mode) | 2444 | (let ((transient-mark-mode) |
| 2355 | (case-fold-search case-fold-search) | 2445 | (case-fold-search case-fold-search) |
| 2356 | (skip-region-start (make-marker)) | 2446 | (query-fcc t) |
| 2357 | (skip-regexp (ispell-begin-skip-region-regexp)) | 2447 | in-comment key) |
| 2358 | (skip-alist ispell-skip-region-alist) | ||
| 2359 | key) | ||
| 2360 | (if (eq ispell-parser 'tex) | ||
| 2361 | (setq case-fold-search nil | ||
| 2362 | skip-alist | ||
| 2363 | (append (car ispell-tex-skip-alists) | ||
| 2364 | (car (cdr ispell-tex-skip-alists)) | ||
| 2365 | skip-alist))) | ||
| 2366 | (let (message-log-max) | 2448 | (let (message-log-max) |
| 2367 | (message "searching for regions to skip")) | 2449 | (message "searching for regions to skip")) |
| 2368 | (if (re-search-forward skip-regexp reg-end t) | 2450 | (if (re-search-forward (ispell-begin-skip-region-regexp) reg-end t) |
| 2369 | (progn | 2451 | (progn |
| 2370 | (setq key (buffer-substring-no-properties | 2452 | (setq key (buffer-substring-no-properties |
| 2371 | (match-beginning 0) (match-end 0))) | 2453 | (match-beginning 0) (match-end 0))) |
| @@ -2374,6 +2456,7 @@ Return nil if spell session is quit, | |||
| 2374 | (let (message-log-max) | 2456 | (let (message-log-max) |
| 2375 | (message "Continuing spelling check using %s dictionary..." | 2457 | (message "Continuing spelling check using %s dictionary..." |
| 2376 | (or ispell-dictionary "default"))) | 2458 | (or ispell-dictionary "default"))) |
| 2459 | (set-marker rstart reg-start) | ||
| 2377 | (set-marker ispell-region-end reg-end) | 2460 | (set-marker ispell-region-end reg-end) |
| 2378 | (while (and (not ispell-quit) | 2461 | (while (and (not ispell-quit) |
| 2379 | (< (point) ispell-region-end)) | 2462 | (< (point) ispell-region-end)) |
| @@ -2381,25 +2464,44 @@ Return nil if spell session is quit, | |||
| 2381 | (if (and (marker-position skip-region-start) | 2464 | (if (and (marker-position skip-region-start) |
| 2382 | (<= skip-region-start (point))) | 2465 | (<= skip-region-start (point))) |
| 2383 | (progn | 2466 | (progn |
| 2384 | (ispell-skip-region key skip-alist) ; moves pt past region. | 2467 | ;; If region inside line comment, must keep comment start. |
| 2385 | (setq reg-start (point)) | 2468 | (setq in-comment (point) |
| 2386 | (if (and (< reg-start ispell-region-end) | 2469 | in-comment |
| 2387 | (re-search-forward skip-regexp | 2470 | (and comment-start |
| 2388 | ispell-region-end t)) | 2471 | (or (null comment-end) (string= "" comment-end)) |
| 2472 | (save-excursion | ||
| 2473 | (beginning-of-line) | ||
| 2474 | (re-search-forward comment-start in-comment t)) | ||
| 2475 | comment-start)) | ||
| 2476 | ;; Can change skip-regexps (in ispell-message) | ||
| 2477 | (ispell-skip-region key) ; moves pt past region. | ||
| 2478 | (set-marker rstart (point)) | ||
| 2479 | ;; check for saving large attachments... | ||
| 2480 | (setq query-fcc (and query-fcc | ||
| 2481 | (ispell-ignore-fcc skip-region-start | ||
| 2482 | rstart))) | ||
| 2483 | (if (and (< rstart ispell-region-end) | ||
| 2484 | (re-search-forward | ||
| 2485 | (ispell-begin-skip-region-regexp) | ||
| 2486 | ispell-region-end t)) | ||
| 2389 | (progn | 2487 | (progn |
| 2390 | (setq key (buffer-substring-no-properties | 2488 | (setq key (buffer-substring-no-properties |
| 2391 | (car (match-data)) | 2489 | (car (match-data)) |
| 2392 | (car (cdr (match-data))))) | 2490 | (car (cdr (match-data))))) |
| 2393 | (set-marker skip-region-start | 2491 | (set-marker skip-region-start |
| 2394 | (- (point) (length key))) | 2492 | (- (point) (length key))) |
| 2395 | (goto-char reg-start)) | 2493 | (goto-char rstart)) |
| 2396 | (set-marker skip-region-start nil)))) | 2494 | (set-marker skip-region-start nil)))) |
| 2397 | (setq reg-end (if (marker-position skip-region-start) | 2495 | (setq reg-end (max (point) |
| 2398 | (min skip-region-start ispell-region-end) | 2496 | (if (marker-position skip-region-start) |
| 2399 | (marker-position ispell-region-end))) | 2497 | (min skip-region-start ispell-region-end) |
| 2498 | (marker-position ispell-region-end)))) | ||
| 2400 | (let* ((start (point)) | 2499 | (let* ((start (point)) |
| 2401 | (end (save-excursion (end-of-line) (min (point) reg-end))) | 2500 | (end (save-excursion (end-of-line) (min (point) reg-end))) |
| 2402 | (string (ispell-get-line start end))) | 2501 | (string (ispell-get-line start end in-comment))) |
| 2502 | (if in-comment ; account for comment chars added | ||
| 2503 | (setq start (- start (length in-comment)) | ||
| 2504 | in-comment nil)) | ||
| 2403 | (setq end (point)) ; "end" tracks region retrieved. | 2505 | (setq end (point)) ; "end" tracks region retrieved. |
| 2404 | (if string ; there is something to spell check! | 2506 | (if string ; there is something to spell check! |
| 2405 | ;; (special start end) | 2507 | ;; (special start end) |
| @@ -2413,6 +2515,8 @@ Return nil if spell session is quit, | |||
| 2413 | (if (and (not (and recheckp ispell-keep-choices-win)) | 2515 | (if (and (not (and recheckp ispell-keep-choices-win)) |
| 2414 | (get-buffer ispell-choices-buffer)) | 2516 | (get-buffer ispell-choices-buffer)) |
| 2415 | (kill-buffer ispell-choices-buffer)) | 2517 | (kill-buffer ispell-choices-buffer)) |
| 2518 | (set-marker skip-region-start nil) | ||
| 2519 | (set-marker rstart nil) | ||
| 2416 | (if ispell-quit | 2520 | (if ispell-quit |
| 2417 | (progn | 2521 | (progn |
| 2418 | ;; preserve or clear the region for ispell-continue. | 2522 | ;; preserve or clear the region for ispell-continue. |
| @@ -2429,48 +2533,70 @@ Return nil if spell session is quit, | |||
| 2429 | (if (not recheckp) (set-marker ispell-region-end nil)) | 2533 | (if (not recheckp) (set-marker ispell-region-end nil)) |
| 2430 | ;; Only save if successful exit. | 2534 | ;; Only save if successful exit. |
| 2431 | (ispell-pdict-save ispell-silently-savep) | 2535 | (ispell-pdict-save ispell-silently-savep) |
| 2432 | (message "Spell-checking done")))) | 2536 | (message "Spell-checking done"))))) |
| 2433 | 2537 | ||
| 2434 | 2538 | ||
| 2435 | ;;; Creates the regexp for skipping a region. | ||
| 2436 | ;;; Makes the skip-regexp local for tex buffers adding in the | ||
| 2437 | ;;; tex expressions to skip as well. | ||
| 2438 | ;;; Call AFTER ispell-buffer-local-parsing. | ||
| 2439 | (defun ispell-begin-skip-region-regexp () | 2539 | (defun ispell-begin-skip-region-regexp () |
| 2440 | (let ((skip-regexp (ispell-begin-skip-region))) | 2540 | "Returns a regexp of the search keys for region skipping. |
| 2541 | Includes `ispell-skip-region-alist' plus tex, tib, html, and comment keys. | ||
| 2542 | Must call after ispell-buffer-local-parsing due to dependence on mode." | ||
| 2543 | ;; start with regions generic to all buffers | ||
| 2544 | (let ((skip-regexp (ispell-begin-skip-region ispell-skip-region-alist))) | ||
| 2545 | ;; Comments | ||
| 2441 | (if (and (null ispell-check-comments) comment-start) | 2546 | (if (and (null ispell-check-comments) comment-start) |
| 2442 | (setq skip-regexp (concat (regexp-quote comment-start) "\\|" | 2547 | (setq skip-regexp (concat (regexp-quote comment-start) "\\|" |
| 2443 | skip-regexp))) | 2548 | skip-regexp))) |
| 2444 | (if (and (eq 'exclusive ispell-check-comments) comment-start) | 2549 | (if (and (eq 'exclusive ispell-check-comments) comment-start) |
| 2550 | ;; search from end of current comment to start of next comment. | ||
| 2445 | (setq skip-regexp (concat (if (string= "" comment-end) "^" | 2551 | (setq skip-regexp (concat (if (string= "" comment-end) "^" |
| 2446 | (regexp-quote comment-end)) | 2552 | (regexp-quote comment-end)) |
| 2447 | "\\|" skip-regexp))) | 2553 | "\\|" skip-regexp))) |
| 2554 | ;; tib | ||
| 2448 | (if ispell-skip-tib | 2555 | (if ispell-skip-tib |
| 2449 | (setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp))) | 2556 | (setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp))) |
| 2557 | ;; html stuff | ||
| 2450 | (if ispell-skip-html | 2558 | (if ispell-skip-html |
| 2451 | (setq skip-regexp (concat "<[cC][oO][dD][eE]\\>[^>]*>" "\\|" | 2559 | (setq skip-regexp (concat |
| 2452 | "<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "\\|" | 2560 | (ispell-begin-skip-region ispell-html-skip-alists) |
| 2453 | "<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "\\|" | 2561 | "\\|" |
| 2454 | "<[vV][eE][rR][bB]\\>[^>]*>" "\\|" | 2562 | skip-regexp))) |
| 2455 | ;; "<[tT][tT]\\>[^>]*>" "\\|" | 2563 | ;; tex |
| 2456 | "<[tT][tT]/" "\\|" | ||
| 2457 | "<" "\\|" | ||
| 2458 | "&" "\\|" | ||
| 2459 | skip-regexp))) | ||
| 2460 | (if (eq ispell-parser 'tex) | 2564 | (if (eq ispell-parser 'tex) |
| 2461 | (setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|" | 2565 | (setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|" |
| 2462 | skip-regexp))) | 2566 | skip-regexp))) |
| 2567 | ;; messages | ||
| 2568 | (if (and ispell-checking-message | ||
| 2569 | (not (eq t ispell-checking-message))) | ||
| 2570 | (setq skip-regexp (concat | ||
| 2571 | (mapconcat (lambda (lst) (car lst)) | ||
| 2572 | ispell-checking-message | ||
| 2573 | "\\|") | ||
| 2574 | "\\|" | ||
| 2575 | skip-regexp))) | ||
| 2576 | |||
| 2577 | ;; return new regexp | ||
| 2463 | skip-regexp)) | 2578 | skip-regexp)) |
| 2464 | 2579 | ||
| 2465 | 2580 | ||
| 2581 | (defun ispell-begin-skip-region (skip-alist) | ||
| 2582 | "Regular expression for start of regions to skip generated from SKIP-ALIST. | ||
| 2583 | Each selection should be a key of SKIP-ALIST; | ||
| 2584 | otherwise, the current line is skipped." | ||
| 2585 | (mapconcat (lambda (lst) (if (stringp (car lst)) (car lst) (eval (car lst)))) | ||
| 2586 | skip-alist | ||
| 2587 | "\\|")) | ||
| 2588 | |||
| 2589 | |||
| 2466 | (defun ispell-begin-tex-skip-regexp () | 2590 | (defun ispell-begin-tex-skip-regexp () |
| 2467 | "Regular expression of tex commands to skip. | 2591 | "Regular expression of tex commands to skip. |
| 2468 | Generated from `ispell-tex-skip-alists'." | 2592 | Generated from `ispell-tex-skip-alists'." |
| 2469 | (concat | 2593 | (concat |
| 2594 | ;; raw tex keys | ||
| 2470 | (mapconcat (function (lambda (lst) (car lst))) | 2595 | (mapconcat (function (lambda (lst) (car lst))) |
| 2471 | (car ispell-tex-skip-alists) | 2596 | (car ispell-tex-skip-alists) |
| 2472 | "\\|") | 2597 | "\\|") |
| 2473 | "\\|" | 2598 | "\\|" |
| 2599 | ;; keys wrapped in begin{} | ||
| 2474 | (mapconcat (function (lambda (lst) | 2600 | (mapconcat (function (lambda (lst) |
| 2475 | (concat "\\\\begin[ \t\n]*{[ \t\n]*" | 2601 | (concat "\\\\begin[ \t\n]*{[ \t\n]*" |
| 2476 | (car lst) | 2602 | (car lst) |
| @@ -2479,17 +2605,30 @@ Generated from `ispell-tex-skip-alists'." | |||
| 2479 | "\\|"))) | 2605 | "\\|"))) |
| 2480 | 2606 | ||
| 2481 | 2607 | ||
| 2482 | (defun ispell-begin-skip-region () | 2608 | (defun ispell-skip-region-list () |
| 2483 | "Regular expression of regions to skip for all buffers. | 2609 | "Returns a list describing key and body regions to skip for this buffer. |
| 2484 | Each selection should be a key of `ispell-skip-region-alist'; | 2610 | Includes regions defined by `ispell-skip-region-alist', tex mode, |
| 2485 | otherwise, the current line is skipped." | 2611 | `ispell-html-skip-alists', and `ispell-checking-message'. |
| 2486 | (mapconcat (function (lambda (lst) (if (stringp (car lst)) (car lst) | 2612 | Manual checking must include comments and tib references. |
| 2487 | (eval (car lst))))) | 2613 | The list is of the form described by variable `ispell-skip-region-alist'. |
| 2488 | ispell-skip-region-alist | 2614 | Must call after `ispell-buffer-local-parsing' due to dependence on mode." |
| 2489 | "\\|")) | 2615 | (let ((skip-alist ispell-skip-region-alist)) |
| 2616 | ;; only additional explicit region definition is tex. | ||
| 2617 | (if (eq ispell-parser 'tex) | ||
| 2618 | (setq case-fold-search nil | ||
| 2619 | skip-alist (append (car ispell-tex-skip-alists) | ||
| 2620 | (car (cdr ispell-tex-skip-alists)) | ||
| 2621 | skip-alist))) | ||
| 2622 | (if ispell-skip-html | ||
| 2623 | (setq skip-alist (append ispell-html-skip-alists skip-alist))) | ||
| 2624 | (if (and ispell-checking-message | ||
| 2625 | (not (eq t ispell-checking-message))) | ||
| 2626 | (setq skip-alist (append ispell-checking-message skip-alist))) | ||
| 2627 | skip-alist)) | ||
| 2490 | 2628 | ||
| 2491 | 2629 | ||
| 2492 | (defun ispell-tex-arg-end (&optional arg) | 2630 | (defun ispell-tex-arg-end (&optional arg) |
| 2631 | "Skip across ARG number of braces." | ||
| 2493 | (condition-case nil | 2632 | (condition-case nil |
| 2494 | (progn | 2633 | (progn |
| 2495 | (while (looking-at "[ \t\n]*\\[") (forward-sexp)) | 2634 | (while (looking-at "[ \t\n]*\\[") (forward-sexp)) |
| @@ -2500,12 +2639,42 @@ otherwise, the current line is skipped." | |||
| 2500 | (sit-for 2)))) | 2639 | (sit-for 2)))) |
| 2501 | 2640 | ||
| 2502 | 2641 | ||
| 2503 | ;;; Skips to region-end from point, or a single line. | 2642 | (defun ispell-ignore-fcc (start end) |
| 2504 | ;;; Places point at end of region skipped. | 2643 | "Deletes the Fcc: message header when large attachments are included. |
| 2505 | (defun ispell-skip-region (key alist) | 2644 | Return value `nil' if file with large attachments are saved. |
| 2645 | This can be used to avoid multiple questions for multiple large attachments. | ||
| 2646 | Returns point to starting location afterwards." | ||
| 2647 | (let ((result t)) | ||
| 2648 | (if (and ispell-checking-message ispell-message-fcc-skip) | ||
| 2649 | (if (< ispell-message-fcc-skip (- end start)) | ||
| 2650 | (let (case-fold-search head-end) | ||
| 2651 | (goto-char (point-min)) | ||
| 2652 | (setq head-end | ||
| 2653 | (or (re-search-forward | ||
| 2654 | (concat "^" (regexp-quote mail-header-separator) "$") | ||
| 2655 | nil t) | ||
| 2656 | (re-search-forward "^$" nil t) | ||
| 2657 | (point-min))) | ||
| 2658 | (goto-char (point-min)) | ||
| 2659 | (if (re-search-forward "^Fcc:" head-end t) | ||
| 2660 | (if (y-or-n-p | ||
| 2661 | "Save copy of this message with large attachments? ") | ||
| 2662 | (setq result nil) | ||
| 2663 | (beginning-of-line) | ||
| 2664 | (kill-line 1))) | ||
| 2665 | (goto-char end)))) | ||
| 2666 | result)) | ||
| 2667 | |||
| 2668 | |||
| 2669 | (defun ispell-skip-region (key) | ||
| 2670 | "Skips across KEY and then to end of region. | ||
| 2671 | Key lookup determines region to skip. | ||
| 2672 | Point is placed at end of skipped region." | ||
| 2506 | ;; move over key to begin checking. | 2673 | ;; move over key to begin checking. |
| 2507 | (forward-char (length key)) | 2674 | (forward-char (length key)) |
| 2508 | (let ((start (point)) | 2675 | (let ((start (point)) |
| 2676 | ;; Regenerate each call... This function can change region definition. | ||
| 2677 | (alist (ispell-skip-region-list)) | ||
| 2509 | alist-key null-skip) | 2678 | alist-key null-skip) |
| 2510 | (cond | 2679 | (cond |
| 2511 | ;; what about quoted comment, or comment inside strings? | 2680 | ;; what about quoted comment, or comment inside strings? |
| @@ -2519,26 +2688,6 @@ otherwise, the current line is skipped." | |||
| 2519 | (search-forward comment-start ispell-region-end :end)) | 2688 | (search-forward comment-start ispell-region-end :end)) |
| 2520 | ((and ispell-skip-tib (string-match ispell-tib-ref-beginning key)) | 2689 | ((and ispell-skip-tib (string-match ispell-tib-ref-beginning key)) |
| 2521 | (re-search-forward ispell-tib-ref-end ispell-region-end t)) | 2690 | (re-search-forward ispell-tib-ref-end ispell-region-end t)) |
| 2522 | ((and ispell-skip-html (string-match "</" key)) | ||
| 2523 | (search-forward ">" ispell-region-end t)) | ||
| 2524 | ((and ispell-skip-html (string-match "<[cC][oO][dD][eE]\\>[^>]*>" key)) | ||
| 2525 | (search-forward-regexp "</[cC][oO][dD][eE]>" ispell-region-end t)) | ||
| 2526 | ((and ispell-skip-html | ||
| 2527 | (string-match "<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" key)) | ||
| 2528 | (search-forward-regexp "</[sS][cC][rR][iI][pP][tT]>" ispell-region-end t)) | ||
| 2529 | ((and ispell-skip-html | ||
| 2530 | (string-match "<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" key)) | ||
| 2531 | (search-forward-regexp "</[aA][pP][pP][lL][eE][tT]>" ispell-region-end t)) | ||
| 2532 | ((and ispell-skip-html (string-match "<[vV][eE][rR][bB]\\>[^>]*>" key)) | ||
| 2533 | (search-forward-regexp "</[vV][eE][rR][bB]>" ispell-region-end t)) | ||
| 2534 | ;;((and ispell-skip-html (string-match "<[tT][tT]\\>[^>]*>" key)) | ||
| 2535 | ;; (search-forward-regexp "</[tT][tT]>" ispell-region-end t)) | ||
| 2536 | ((and ispell-skip-html (string-match "<[tT][tT]/" key)) | ||
| 2537 | (search-forward "/" ispell-region-end t)) | ||
| 2538 | ((and ispell-skip-html (string-match "<" key)) | ||
| 2539 | (search-forward ">" ispell-region-end t)) | ||
| 2540 | ((and ispell-skip-html (string-match "&" key)) | ||
| 2541 | (search-forward-regexp "[; \t\n]" ispell-region-end t)) | ||
| 2542 | ;; markings from alist | 2691 | ;; markings from alist |
| 2543 | (t | 2692 | (t |
| 2544 | (while alist | 2693 | (while alist |
| @@ -2551,13 +2700,14 @@ otherwise, the current line is skipped." | |||
| 2551 | ((not (consp alist)) | 2700 | ((not (consp alist)) |
| 2552 | ;; Search past end of spell region to find this region end. | 2701 | ;; Search past end of spell region to find this region end. |
| 2553 | (re-search-forward (eval alist) (point-max) t)) | 2702 | (re-search-forward (eval alist) (point-max) t)) |
| 2554 | ((consp alist) | 2703 | ((and (= 1 (length alist)) |
| 2555 | (if (stringp alist) | 2704 | (stringp (car alist))) |
| 2556 | (re-search-forward alist (point-max) t) | 2705 | (re-search-forward (car alist) (point-max) t)) |
| 2557 | (setq null-skip t) ; error handling in functions! | 2706 | (t |
| 2558 | (if (consp (cdr alist)) | 2707 | (setq null-skip t) ; error handling in functions! |
| 2559 | (apply (car alist) (cdr alist)) | 2708 | (if (consp (cdr alist)) |
| 2560 | (funcall (car alist)))))) | 2709 | (apply (car alist) (cdr alist)) |
| 2710 | (funcall (car alist))))) | ||
| 2561 | (setq alist nil)) | 2711 | (setq alist nil)) |
| 2562 | (setq alist (cdr alist)))))) | 2712 | (setq alist (cdr alist)))))) |
| 2563 | (if (and (= start (point)) (null null-skip)) | 2713 | (if (and (= start (point)) (null null-skip)) |
| @@ -2570,7 +2720,7 @@ otherwise, the current line is skipped." | |||
| 2570 | 2720 | ||
| 2571 | ;;; Grab the next line of data. | 2721 | ;;; Grab the next line of data. |
| 2572 | ;;; Returns a string with the line data | 2722 | ;;; Returns a string with the line data |
| 2573 | (defun ispell-get-line (start end) | 2723 | (defun ispell-get-line (start end in-comment) |
| 2574 | (let ((ispell-casechars (ispell-get-casechars)) | 2724 | (let ((ispell-casechars (ispell-get-casechars)) |
| 2575 | string) | 2725 | string) |
| 2576 | (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS | 2726 | (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS |
| @@ -2580,7 +2730,8 @@ otherwise, the current line is skipped." | |||
| 2580 | ;; (forward-char 1)) ; not needed as quoted below. | 2730 | ;; (forward-char 1)) ; not needed as quoted below. |
| 2581 | ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS | 2731 | ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS |
| 2582 | (re-search-forward "[][()${}]" end t)) ; or MATH COMMANDS | 2732 | (re-search-forward "[][()${}]" end t)) ; or MATH COMMANDS |
| 2583 | (setq string (concat "^" (buffer-substring-no-properties start end) | 2733 | (setq string (concat "^" in-comment |
| 2734 | (buffer-substring-no-properties start end) | ||
| 2584 | "\n")) | 2735 | "\n")) |
| 2585 | (goto-char end)) | 2736 | (goto-char end)) |
| 2586 | (t (goto-char end))) ; EMPTY LINE, skip it. | 2737 | (t (goto-char end))) ; EMPTY LINE, skip it. |
| @@ -2637,7 +2788,7 @@ Returns the sum shift due to changes in word replacements." | |||
| 2637 | ;; `query-replace' makes multiple corrections on the starting line. | 2788 | ;; `query-replace' makes multiple corrections on the starting line. |
| 2638 | (if (/= (+ word-len (point)) | 2789 | (if (/= (+ word-len (point)) |
| 2639 | (progn | 2790 | (progn |
| 2640 | ;; NB: Search can fail with Mule character sets that don't | 2791 | ;; NB: Search can fail with Mule coding systems that don't |
| 2641 | ;; display properly. Ignore the error in this case? | 2792 | ;; display properly. Ignore the error in this case? |
| 2642 | (search-forward (car poss) (+ word-len (point)) t) | 2793 | (search-forward (car poss) (+ word-len (point)) t) |
| 2643 | (point))) | 2794 | (point))) |
| @@ -2881,7 +3032,8 @@ looking for a dictionary, please see the distribution of the GNU ispell | |||
| 2881 | program, or do an Internet search; there are various dictionaries | 3032 | program, or do an Internet search; there are various dictionaries |
| 2882 | available on the net." | 3033 | available on the net." |
| 2883 | (interactive) | 3034 | (interactive) |
| 2884 | (if (and transient-mark-mode mark-active) | 3035 | (if (and (boundp 'transient-mark-mode) transient-mark-mode |
| 3036 | (boundp 'mark-active) mark-active) | ||
| 2885 | (ispell-region (region-beginning) (region-end)) | 3037 | (ispell-region (region-beginning) (region-end)) |
| 2886 | (ispell-buffer))) | 3038 | (ispell-buffer))) |
| 2887 | 3039 | ||
| @@ -2946,8 +3098,6 @@ Don't read buffer-local settings or word lists." | |||
| 2946 | ;;; ********************************************************************** | 3098 | ;;; ********************************************************************** |
| 2947 | ;;; Ispell Message | 3099 | ;;; Ispell Message |
| 2948 | ;;; ********************************************************************** | 3100 | ;;; ********************************************************************** |
| 2949 | ;;; Original from D. Quinlan, E. Bradford, A. Albert, and M. Ernst | ||
| 2950 | |||
| 2951 | 3101 | ||
| 2952 | (defvar ispell-message-text-end | 3102 | (defvar ispell-message-text-end |
| 2953 | (mapconcat (function identity) | 3103 | (mapconcat (function identity) |
| @@ -2955,9 +3105,9 @@ Don't read buffer-local settings or word lists." | |||
| 2955 | ;; Don't spell check signatures | 3105 | ;; Don't spell check signatures |
| 2956 | "^-- $" | 3106 | "^-- $" |
| 2957 | ;; Matches postscript files. | 3107 | ;; Matches postscript files. |
| 2958 | "^%!PS-Adobe-[123].0" | 3108 | ;;"^%!PS-Adobe-[123].0" |
| 2959 | ;; Matches uuencoded text | 3109 | ;; Matches uuencoded text |
| 2960 | "^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM" | 3110 | ;;"^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM" |
| 2961 | ;; Matches shell files (especially auto-decoding) | 3111 | ;; Matches shell files (especially auto-decoding) |
| 2962 | "^#! /bin/[ck]?sh" | 3112 | "^#! /bin/[ck]?sh" |
| 2963 | ;; Matches context difference listing | 3113 | ;; Matches context difference listing |
| @@ -2974,6 +3124,97 @@ If it is a string, limit at first occurrence of that regular expression. | |||
| 2974 | Otherwise, it must be a function which is called to get the limit.") | 3124 | Otherwise, it must be a function which is called to get the limit.") |
| 2975 | 3125 | ||
| 2976 | 3126 | ||
| 3127 | (defun ispell-mime-multipartp (&optional limit) | ||
| 3128 | "Return multipart message start boundary or nil if none." | ||
| 3129 | ;; caller must ensure `case-fold-search' is set to `t' | ||
| 3130 | (and | ||
| 3131 | (re-search-forward | ||
| 3132 | "Content-Type: *multipart/\\([^ \t\n]*;[ \t]*[\n]?[ \t]*\\)+boundary=" | ||
| 3133 | limit t) | ||
| 3134 | (let (boundary) | ||
| 3135 | (if (looking-at "\"") | ||
| 3136 | (let (start) | ||
| 3137 | (forward-char) | ||
| 3138 | (setq start (point)) | ||
| 3139 | (while (not (looking-at "\"")) | ||
| 3140 | (forward-char 1)) | ||
| 3141 | (setq boundary (buffer-substring-no-properties start (point)))) | ||
| 3142 | (let ((start (point))) | ||
| 3143 | (while (looking-at "[-0-9a-zA-Z'()+_,./:=?]") | ||
| 3144 | (forward-char)) | ||
| 3145 | (setq boundary (buffer-substring-no-properties start (point))))) | ||
| 3146 | (if (< (length boundary) 1) | ||
| 3147 | (setq boundary nil) | ||
| 3148 | (concat "--" boundary))))) | ||
| 3149 | |||
| 3150 | |||
| 3151 | (defun ispell-mime-skip-part (boundary) | ||
| 3152 | "Moves point across header, or entire MIME part if message is encoded. | ||
| 3153 | All specified types except `7bit' `8bit' and `quoted-printable' are considered | ||
| 3154 | encoded and therefore skipped. See rfc 1521, 2183, ... | ||
| 3155 | If no boundary is given, then entire message is skipped. | ||
| 3156 | |||
| 3157 | This starts one line ABOVE the MIME content messages, on the boundary marker, | ||
| 3158 | for operation with the generic region-skipping code. | ||
| 3159 | This places new MIME boundaries into variable `ispell-checking-message'." | ||
| 3160 | (forward-line) ; skip over boundary to headers | ||
| 3161 | (let ((save-case-fold-search case-fold-search) | ||
| 3162 | (continuep t) | ||
| 3163 | textp) | ||
| 3164 | (setq case-fold-search t | ||
| 3165 | ispell-skip-html nil) | ||
| 3166 | (while continuep | ||
| 3167 | (setq continuep nil) | ||
| 3168 | (if (looking-at "Content-Type: *text/") | ||
| 3169 | (progn | ||
| 3170 | (goto-char (match-end 0)) | ||
| 3171 | (if (looking-at "html") | ||
| 3172 | (setq ispell-skip-html t)) | ||
| 3173 | (setq textp t | ||
| 3174 | continuep t) | ||
| 3175 | (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t) | ||
| 3176 | (forward-line))) | ||
| 3177 | (if (looking-at "Content-Transfer-Encoding: *\\([^ \t\n]*\\)") | ||
| 3178 | (let ((match (buffer-substring (match-beginning 1) (match-end 1)))) | ||
| 3179 | (setq textp (member (upcase match) | ||
| 3180 | ;; only spell check the following encodings: | ||
| 3181 | '("7BIT" "8BIT" "QUOTED-PRINTABLE" "BINARY")) | ||
| 3182 | continuep t) | ||
| 3183 | (goto-char (match-end 0)) | ||
| 3184 | (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t) | ||
| 3185 | (forward-line))) | ||
| 3186 | ;; hierarchical boundary definition | ||
| 3187 | (if (looking-at "Content-Type: *multipart/") | ||
| 3188 | (let ((new-boundary (ispell-mime-multipartp))) | ||
| 3189 | (if (string-match new-boundary boundary) | ||
| 3190 | (setq continuep t) | ||
| 3191 | ;; first pass redefine skip function to include new boundary | ||
| 3192 | ;;(re-search-backward boundary nil t) | ||
| 3193 | (forward-line) | ||
| 3194 | (setq ispell-checking-message | ||
| 3195 | (cons | ||
| 3196 | (list new-boundary 'ispell-mime-skip-part new-boundary) | ||
| 3197 | (if (eq t ispell-checking-message) nil | ||
| 3198 | ispell-checking-message)) | ||
| 3199 | textp t | ||
| 3200 | continuep t))) | ||
| 3201 | ;; Skip all MIME headers that don't affect spelling | ||
| 3202 | (if (looking-at "Content-[^ \t]*: *\\(.*;[ \t]*[\n]\\)*.*$") | ||
| 3203 | (progn | ||
| 3204 | (setq continuep t) | ||
| 3205 | (goto-char (match-end 0)) | ||
| 3206 | (forward-line))))) | ||
| 3207 | |||
| 3208 | (setq case-fold-search save-case-fold-search) | ||
| 3209 | (if textp | ||
| 3210 | (point) | ||
| 3211 | ;; encoded message. Skip to boundary, or entire message. | ||
| 3212 | (if (not boundary) | ||
| 3213 | (goto-char (point-max)) | ||
| 3214 | (re-search-forward boundary nil t) | ||
| 3215 | (beginning-of-line) | ||
| 3216 | (point))))) | ||
| 3217 | |||
| 2977 | 3218 | ||
| 2978 | ;;;###autoload | 3219 | ;;;###autoload |
| 2979 | (defun ispell-message () | 3220 | (defun ispell-message () |
| @@ -2998,7 +3239,8 @@ You can bind this to the key C-c i in GNUS or mail by adding to | |||
| 2998 | (interactive) | 3239 | (interactive) |
| 2999 | (save-excursion | 3240 | (save-excursion |
| 3000 | (goto-char (point-min)) | 3241 | (goto-char (point-min)) |
| 3001 | (let* ( | 3242 | (let* (boundary mimep |
| 3243 | (ispell-skip-region-alist-save ispell-skip-region-alist) | ||
| 3002 | ;; Nil when message came from outside (eg calling emacs as editor) | 3244 | ;; Nil when message came from outside (eg calling emacs as editor) |
| 3003 | ;; Non-nil marker of end of headers. | 3245 | ;; Non-nil marker of end of headers. |
| 3004 | (internal-messagep | 3246 | (internal-messagep |
| @@ -3023,10 +3265,10 @@ You can bind this to the key C-c i in GNUS or mail by adding to | |||
| 3023 | " \\|\t")) | 3265 | " \\|\t")) |
| 3024 | (cite-regexp ;Prefix of quoted text | 3266 | (cite-regexp ;Prefix of quoted text |
| 3025 | (cond | 3267 | (cond |
| 3026 | ((functionp 'sc-cite-regexp) ; sc 3.0 | 3268 | ((functionp 'sc-cite-regexp) ; sc 3.0 |
| 3027 | (concat "\\(" (sc-cite-regexp) "\\)" "\\|" | 3269 | (concat "\\(" (sc-cite-regexp) "\\)" "\\|" |
| 3028 | (ispell-non-empty-string sc-reference-tag-string))) | 3270 | (ispell-non-empty-string sc-reference-tag-string))) |
| 3029 | ((boundp 'sc-cite-regexp) ; sc 2.3 | 3271 | ((boundp 'sc-cite-regexp) ; sc 2.3 |
| 3030 | (concat "\\(" sc-cite-regexp "\\)" "\\|" | 3272 | (concat "\\(" sc-cite-regexp "\\)" "\\|" |
| 3031 | (ispell-non-empty-string sc-reference-tag-string))) | 3273 | (ispell-non-empty-string sc-reference-tag-string))) |
| 3032 | ((or (equal major-mode 'news-reply-mode) ;GNUS 4 & below | 3274 | ((or (equal major-mode 'news-reply-mode) ;GNUS 4 & below |
| @@ -3068,7 +3310,9 @@ You can bind this to the key C-c i in GNUS or mail by adding to | |||
| 3068 | (progn | 3310 | (progn |
| 3069 | ;; Spell check any original Subject: | 3311 | ;; Spell check any original Subject: |
| 3070 | (goto-char (point-min)) | 3312 | (goto-char (point-min)) |
| 3071 | (setq case-fold-search t) | 3313 | (setq case-fold-search t |
| 3314 | mimep (re-search-forward "MIME-Version:" end-of-headers t)) | ||
| 3315 | (goto-char (point-min)) | ||
| 3072 | (if (re-search-forward "^Subject: *" end-of-headers t) | 3316 | (if (re-search-forward "^Subject: *" end-of-headers t) |
| 3073 | (progn | 3317 | (progn |
| 3074 | (goto-char (match-end 0)) | 3318 | (goto-char (match-end 0)) |
| @@ -3082,12 +3326,41 @@ You can bind this to the key C-c i in GNUS or mail by adding to | |||
| 3082 | (while (looking-at "\n[ \t]") | 3326 | (while (looking-at "\n[ \t]") |
| 3083 | (end-of-line 2)) | 3327 | (end-of-line 2)) |
| 3084 | (point))))))) | 3328 | (point))))))) |
| 3085 | (setq case-fold-search old-case-fold-search) | 3329 | (if mimep |
| 3086 | (goto-char end-of-headers) | 3330 | (progn |
| 3331 | (goto-char (point-min)) | ||
| 3332 | (setq boundary (ispell-mime-multipartp end-of-headers)))) | ||
| 3333 | ;; Adjust message limit to MIME message if necessary. | ||
| 3334 | (and boundary | ||
| 3335 | (re-search-forward (concat boundary "--") nil t) | ||
| 3336 | (re-search-backward boundary nil t) | ||
| 3337 | (< (point) (marker-position limit)) | ||
| 3338 | (set-marker limit (point))) | ||
| 3339 | (goto-char (point-min)) | ||
| 3340 | ;; Select type or skip checking if this is a non-multipart message | ||
| 3341 | ;; Point moved to end of buffer if region is encoded. | ||
| 3342 | (if (and mimep (not boundary)) | ||
| 3343 | (let (skip-regexp) ; protect from `ispell-mime-skip-part' | ||
| 3344 | (goto-char (point-min)) | ||
| 3345 | (re-search-forward "Content-[^ \t]*:" end-of-headers t) | ||
| 3346 | (forward-line -1) ; following fn starts one line above | ||
| 3347 | (ispell-mime-skip-part nil) | ||
| 3348 | ;; if message-text-end region, limit may be less than point. | ||
| 3349 | (if (> (point) limit) | ||
| 3350 | (set-marker limit (point))))) | ||
| 3351 | (goto-char (max end-of-headers (point))) | ||
| 3087 | (forward-line 1) | 3352 | (forward-line 1) |
| 3353 | (setq case-fold-search old-case-fold-search) | ||
| 3354 | ;; Define MIME regions to skip. | ||
| 3355 | (if boundary | ||
| 3356 | (setq ispell-checking-message | ||
| 3357 | (list (list boundary 'ispell-mime-skip-part boundary)))) | ||
| 3088 | (ispell-region (point) limit)) | 3358 | (ispell-region (point) limit)) |
| 3089 | (set-marker end-of-headers nil) | 3359 | (set-marker end-of-headers nil) |
| 3090 | (set-marker limit nil))))) | 3360 | (set-marker limit nil) |
| 3361 | (setq ispell-skip-region-alist ispell-skip-region-alist-save | ||
| 3362 | ispell-skip-html nil | ||
| 3363 | case-fold-search old-case-fold-search))))) | ||
| 3091 | 3364 | ||
| 3092 | 3365 | ||
| 3093 | (defun ispell-non-empty-string (string) | 3366 | (defun ispell-non-empty-string (string) |
| @@ -3128,9 +3401,9 @@ Includes Latex/Nroff modes and extended character mode." | |||
| 3128 | (ispell-send-string "-\n")) ; set mode to normal (nroff) | 3401 | (ispell-send-string "-\n")) ; set mode to normal (nroff) |
| 3129 | ;; If needed, test for SGML & HTML modes and set a buffer local nil/t value. | 3402 | ;; If needed, test for SGML & HTML modes and set a buffer local nil/t value. |
| 3130 | (if (and ispell-skip-html (not (eq ispell-skip-html t))) | 3403 | (if (and ispell-skip-html (not (eq ispell-skip-html t))) |
| 3131 | (set (make-local-variable 'ispell-skip-html) | 3404 | (setq ispell-skip-html |
| 3132 | (not (null (string-match "sgml\\|html\\|xml" | 3405 | (not (null (string-match "sgml\\|html\\|xml" |
| 3133 | (downcase (symbol-name major-mode))))))) | 3406 | (downcase (symbol-name major-mode))))))) |
| 3134 | ;; Set default extended character mode for given buffer, if any. | 3407 | ;; Set default extended character mode for given buffer, if any. |
| 3135 | (let ((extended-char-mode (ispell-get-extended-character-mode))) | 3408 | (let ((extended-char-mode (ispell-get-extended-character-mode))) |
| 3136 | (if extended-char-mode | 3409 | (if extended-char-mode |
| @@ -3196,8 +3469,7 @@ Both should not be used to define a buffer-local dictionary." | |||
| 3196 | (ispell-kill-ispell t) | 3469 | (ispell-kill-ispell t) |
| 3197 | (setq ispell-personal-dictionary ispell-local-pdict))) | 3470 | (setq ispell-personal-dictionary ispell-local-pdict))) |
| 3198 | ;; Reload if new dictionary defined. | 3471 | ;; Reload if new dictionary defined. |
| 3199 | (if (and ispell-local-dictionary | 3472 | (if (not (equal ispell-local-dictionary ispell-dictionary)) |
| 3200 | (not (equal ispell-local-dictionary ispell-dictionary))) | ||
| 3201 | (ispell-change-dictionary ispell-local-dictionary))) | 3473 | (ispell-change-dictionary ispell-local-dictionary))) |
| 3202 | 3474 | ||
| 3203 | 3475 | ||