summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaromil <jaromil@dyne.org>2013-02-19 14:34:05 (GMT)
committer Jaromil <jaromil@dyne.org>2013-02-19 14:35:45 (GMT)
commit28fcafaa7a70303bc888148610d3185fd3983582 (patch)
tree1df69e354f3b14c2fe274a5cb5443db0bde9e734
parentb5d7d1af079761fd841b12c5152d4cde81b11ebf (diff)
dictionary words spell with aspell
-rw-r--r--elisp/flyspell.el2460
-rw-r--r--elisp/ispell.el3639
-rwxr-xr-xspell/aspellbin0 -> 1017516 bytes
-rw-r--r--spell/aspell-0.60.6.1/ABOUT-NLS1101
-rw-r--r--spell/aspell-0.60.6.1/COPYING504
-rw-r--r--spell/aspell-0.60.6.1/Makefile.am400
-rw-r--r--spell/aspell-0.60.6.1/README378
-rw-r--r--spell/aspell-0.60.6.1/TODO5
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/CcHelper.pm339
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/Create.pm109
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/Info.pm161
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/Methods.pm58
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/ProcCc.pm129
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/ProcCxx.pm164
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/ProcImpl.pm129
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/ProcNative.pm182
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/ProcNativeImpl.pm97
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/Read.pm210
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/Type.pm94
-rw-r--r--spell/aspell-0.60.6.1/auto/MkSrc/Util.pm111
-rw-r--r--spell/aspell-0.60.6.1/auto/auto0
-rw-r--r--spell/aspell-0.60.6.1/auto/mk-doc.pl51
-rw-r--r--spell/aspell-0.60.6.1/auto/mk-src.in1070
-rwxr-xr-xspell/aspell-0.60.6.1/auto/mk-src.pl73
-rw-r--r--spell/aspell-0.60.6.1/common/asc_ctype.hpp44
-rw-r--r--spell/aspell-0.60.6.1/common/basic_list.hpp68
-rw-r--r--spell/aspell-0.60.6.1/common/block_slist-t.hpp55
-rw-r--r--spell/aspell-0.60.6.1/common/block_slist.hpp76
-rw-r--r--spell/aspell-0.60.6.1/common/cache-t.hpp101
-rw-r--r--spell/aspell-0.60.6.1/common/cache.cpp122
-rw-r--r--spell/aspell-0.60.6.1/common/cache.hpp86
-rw-r--r--spell/aspell-0.60.6.1/common/can_have_error.cpp30
-rw-r--r--spell/aspell-0.60.6.1/common/can_have_error.hpp29
-rw-r--r--spell/aspell-0.60.6.1/common/char_vector.hpp18
-rw-r--r--spell/aspell-0.60.6.1/common/clone_ptr-t.hpp45
-rw-r--r--spell/aspell-0.60.6.1/common/clone_ptr.hpp54
-rw-r--r--spell/aspell-0.60.6.1/common/config.cpp1525
-rw-r--r--spell/aspell-0.60.6.1/common/config.hpp281
-rw-r--r--spell/aspell-0.60.6.1/common/convert.cpp1095
-rw-r--r--spell/aspell-0.60.6.1/common/convert.hpp417
-rw-r--r--spell/aspell-0.60.6.1/common/copy_ptr.hpp58
-rw-r--r--spell/aspell-0.60.6.1/common/document_checker.cpp77
-rw-r--r--spell/aspell-0.60.6.1/common/document_checker.hpp62
-rw-r--r--spell/aspell-0.60.6.1/common/enumeration.hpp123
-rw-r--r--spell/aspell-0.60.6.1/common/error.cpp52
-rw-r--r--spell/aspell-0.60.6.1/common/error.hpp37
-rw-r--r--spell/aspell-0.60.6.1/common/errors.cpp700
-rw-r--r--spell/aspell-0.60.6.1/common/errors.hpp193
-rw-r--r--spell/aspell-0.60.6.1/common/file_data_util.cpp75
-rw-r--r--spell/aspell-0.60.6.1/common/file_data_util.hpp20
-rw-r--r--spell/aspell-0.60.6.1/common/file_util.cpp235
-rw-r--r--spell/aspell-0.60.6.1/common/file_util.hpp63
-rw-r--r--spell/aspell-0.60.6.1/common/filter.cpp139
-rw-r--r--spell/aspell-0.60.6.1/common/filter.hpp67
-rw-r--r--spell/aspell-0.60.6.1/common/filter_char.hpp50
-rw-r--r--spell/aspell-0.60.6.1/common/filter_char_vector.hpp41
-rw-r--r--spell/aspell-0.60.6.1/common/filter_debug.hpp41
-rw-r--r--spell/aspell-0.60.6.1/common/fstream.cpp149
-rw-r--r--spell/aspell-0.60.6.1/common/fstream.hpp101
-rw-r--r--spell/aspell-0.60.6.1/common/generic_copy_ptr-t.hpp63
-rw-r--r--spell/aspell-0.60.6.1/common/generic_copy_ptr.hpp63
-rw-r--r--spell/aspell-0.60.6.1/common/getdata.cpp193
-rw-r--r--spell/aspell-0.60.6.1/common/getdata.hpp68
-rw-r--r--spell/aspell-0.60.6.1/common/gettext.h100
-rw-r--r--spell/aspell-0.60.6.1/common/gettext_init.cpp28
-rw-r--r--spell/aspell-0.60.6.1/common/hash-t.hpp234
-rw-r--r--spell/aspell-0.60.6.1/common/hash.hpp337
-rw-r--r--spell/aspell-0.60.6.1/common/hash_fun.hpp53
-rw-r--r--spell/aspell-0.60.6.1/common/indiv_filter.hpp100
-rw-r--r--spell/aspell-0.60.6.1/common/info.cpp781
-rw-r--r--spell/aspell-0.60.6.1/common/info.hpp147
-rw-r--r--spell/aspell-0.60.6.1/common/iostream.cpp13
-rw-r--r--spell/aspell-0.60.6.1/common/iostream.hpp24
-rw-r--r--spell/aspell-0.60.6.1/common/istream.hpp35
-rw-r--r--spell/aspell-0.60.6.1/common/itemize.cpp106
-rw-r--r--spell/aspell-0.60.6.1/common/itemize.hpp20
-rw-r--r--spell/aspell-0.60.6.1/common/key_info.hpp30
-rw-r--r--spell/aspell-0.60.6.1/common/lock.hpp68
-rw-r--r--spell/aspell-0.60.6.1/common/lsort.hpp164
-rw-r--r--spell/aspell-0.60.6.1/common/mutable_container.hpp30
-rw-r--r--spell/aspell-0.60.6.1/common/mutable_string.hpp76
-rw-r--r--spell/aspell-0.60.6.1/common/ndebug.hpp8
-rw-r--r--spell/aspell-0.60.6.1/common/objstack.cpp80
-rw-r--r--spell/aspell-0.60.6.1/common/objstack.hpp171
-rw-r--r--spell/aspell-0.60.6.1/common/ostream.hpp67
-rw-r--r--spell/aspell-0.60.6.1/common/parm_string.hpp116
-rw-r--r--spell/aspell-0.60.6.1/common/posib_err.cpp128
-rw-r--r--spell/aspell-0.60.6.1/common/posib_err.hpp249
-rw-r--r--spell/aspell-0.60.6.1/common/simple_string.hpp65
-rw-r--r--spell/aspell-0.60.6.1/common/speller.cpp18
-rw-r--r--spell/aspell-0.60.6.1/common/speller.hpp131
-rw-r--r--spell/aspell-0.60.6.1/common/stack_ptr.hpp54
-rw-r--r--spell/aspell-0.60.6.1/common/string.cpp86
-rw-r--r--spell/aspell-0.60.6.1/common/string.hpp498
-rw-r--r--spell/aspell-0.60.6.1/common/string_enumeration.hpp39
-rw-r--r--spell/aspell-0.60.6.1/common/string_list.cpp120
-rw-r--r--spell/aspell-0.60.6.1/common/string_list.hpp100
-rw-r--r--spell/aspell-0.60.6.1/common/string_map.cpp89
-rw-r--r--spell/aspell-0.60.6.1/common/string_map.hpp125
-rw-r--r--spell/aspell-0.60.6.1/common/string_pair.hpp25
-rw-r--r--spell/aspell-0.60.6.1/common/string_pair_enumeration.hpp31
-rw-r--r--spell/aspell-0.60.6.1/common/strtonum.cpp95
-rw-r--r--spell/aspell-0.60.6.1/common/strtonum.hpp19
-rw-r--r--spell/aspell-0.60.6.1/common/tokenizer.cpp31
-rw-r--r--spell/aspell-0.60.6.1/common/tokenizer.hpp72
-rw-r--r--spell/aspell-0.60.6.1/common/type_id.hpp27
-rw-r--r--spell/aspell-0.60.6.1/common/vararray.hpp54
-rw-r--r--spell/aspell-0.60.6.1/common/vector.hpp61
-rw-r--r--spell/aspell-0.60.6.1/common/word_list.hpp30
-rwxr-xr-xspell/aspell-0.60.6.1/compile144
-rwxr-xr-xspell/aspell-0.60.6.1/config.rpath614
-rw-r--r--spell/aspell-0.60.6.1/configure.ac585
-rw-r--r--spell/aspell-0.60.6.1/data/cp1250.cmap1991
-rw-r--r--spell/aspell-0.60.6.1/data/cp1250.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1251.cmap1903
-rw-r--r--spell/aspell-0.60.6.1/data/cp1251.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1252.cmap1943
-rw-r--r--spell/aspell-0.60.6.1/data/cp1252.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1253.cmap2148
-rw-r--r--spell/aspell-0.60.6.1/data/cp1253.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1254.cmap1944
-rw-r--r--spell/aspell-0.60.6.1/data/cp1254.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1255.cmap2251
-rw-r--r--spell/aspell-0.60.6.1/data/cp1255.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1256.cmap2476
-rw-r--r--spell/aspell-0.60.6.1/data/cp1256.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1257.cmap1962
-rw-r--r--spell/aspell-0.60.6.1/data/cp1257.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/cp1258.cmap2403
-rw-r--r--spell/aspell-0.60.6.1/data/cp1258.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/dvorak.kbd25
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-1.cmap1922
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-1.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-10.cmap1971
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-10.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-11.cmap1508
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-11.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-13.cmap1961
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-13.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-14.cmap2010
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-14.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-15.cmap1934
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-15.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-16.cmap1951
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-16.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-2.cmap1983
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-2.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-3.cmap1935
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-3.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-4.cmap1970
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-4.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-5.cmap1895
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-5.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-6.cmap2201
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-6.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-7.cmap2145
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-7.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-8.cmap1483
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-8.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-9.cmap1937
-rw-r--r--spell/aspell-0.60.6.1/data/iso-8859-9.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/koi8-r.cmap1857
-rw-r--r--spell/aspell-0.60.6.1/data/koi8-r.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/koi8-u.cmap1869
-rw-r--r--spell/aspell-0.60.6.1/data/koi8-u.cset262
-rw-r--r--spell/aspell-0.60.6.1/data/split.kbd23
-rw-r--r--spell/aspell-0.60.6.1/data/standard.kbd25
-rw-r--r--spell/aspell-0.60.6.1/examples/Makefile.am13
-rw-r--r--spell/aspell-0.60.6.1/examples/example-c.c343
-rw-r--r--spell/aspell-0.60.6.1/examples/list-dicts.c44
-rw-r--r--spell/aspell-0.60.6.1/gen/filter.pot127
-rw-r--r--spell/aspell-0.60.6.1/gen/mk-dirs_h.pl16
-rw-r--r--spell/aspell-0.60.6.1/gen/mk-filter-pot.pl34
-rw-r--r--spell/aspell-0.60.6.1/gen/mk-static-filter.pl197
-rw-r--r--spell/aspell-0.60.6.1/gen/settings.h.in161
-rw-r--r--spell/aspell-0.60.6.1/interfaces/cc/aspell.h734
-rw-r--r--spell/aspell-0.60.6.1/interfaces/cc/pspell.h122
-rw-r--r--spell/aspell-0.60.6.1/lib/can_have_error-c.cpp40
-rw-r--r--spell/aspell-0.60.6.1/lib/config-c.cpp172
-rw-r--r--spell/aspell-0.60.6.1/lib/document_checker-c.cpp78
-rw-r--r--spell/aspell-0.60.6.1/lib/dummy.cpp1
-rw-r--r--spell/aspell-0.60.6.1/lib/error-c.cpp24
-rw-r--r--spell/aspell-0.60.6.1/lib/filter-c.cpp46
-rw-r--r--spell/aspell-0.60.6.1/lib/filter_entry.hpp19
-rw-r--r--spell/aspell-0.60.6.1/lib/find_speller.cpp494
-rw-r--r--spell/aspell-0.60.6.1/lib/info-c.cpp112
-rw-r--r--spell/aspell-0.60.6.1/lib/mutable_container-c.cpp39
-rw-r--r--spell/aspell-0.60.6.1/lib/new_checker.cpp26
-rw-r--r--spell/aspell-0.60.6.1/lib/new_config.cpp24
-rw-r--r--spell/aspell-0.60.6.1/lib/new_filter.cpp540
-rw-r--r--spell/aspell-0.60.6.1/lib/new_fmode.cpp783
-rw-r--r--spell/aspell-0.60.6.1/lib/speller-c.cpp173
-rw-r--r--spell/aspell-0.60.6.1/lib/string_enumeration-c.cpp52
-rw-r--r--spell/aspell-0.60.6.1/lib/string_list-c.cpp76
-rw-r--r--spell/aspell-0.60.6.1/lib/string_map-c.cpp91
-rw-r--r--spell/aspell-0.60.6.1/lib/string_pair_enumeration-c.cpp44
-rw-r--r--spell/aspell-0.60.6.1/lib/word_list-c.cpp37
-rw-r--r--spell/aspell-0.60.6.1/lib5/Makefile.am16
-rw-r--r--spell/aspell-0.60.6.1/lib5/aspell-dummy.cpp0
-rw-r--r--spell/aspell-0.60.6.1/lib5/pspell-dummy.cpp0
-rw-r--r--spell/aspell-0.60.6.1/m4/codeset.m421
-rw-r--r--spell/aspell-0.60.6.1/m4/gettext.m4419
-rw-r--r--spell/aspell-0.60.6.1/m4/glibc2.m430
-rw-r--r--spell/aspell-0.60.6.1/m4/glibc21.m430
-rw-r--r--spell/aspell-0.60.6.1/m4/iconv.m4101
-rw-r--r--spell/aspell-0.60.6.1/m4/intdiv0.m470
-rw-r--r--spell/aspell-0.60.6.1/m4/intl.m4259
-rw-r--r--spell/aspell-0.60.6.1/m4/intldir.m419
-rw-r--r--spell/aspell-0.60.6.1/m4/intmax.m433
-rw-r--r--spell/aspell-0.60.6.1/m4/inttypes-pri.m436
-rw-r--r--spell/aspell-0.60.6.1/m4/inttypes_h.m426
-rw-r--r--spell/aspell-0.60.6.1/m4/lcmessage.m430
-rw-r--r--spell/aspell-0.60.6.1/m4/lib-ld.m4110
-rw-r--r--spell/aspell-0.60.6.1/m4/lib-link.m4644
-rw-r--r--spell/aspell-0.60.6.1/m4/lib-prefix.m4185
-rw-r--r--spell/aspell-0.60.6.1/m4/libtool.m47275
-rw-r--r--spell/aspell-0.60.6.1/m4/lock.m4311
-rw-r--r--spell/aspell-0.60.6.1/m4/longdouble.m431
-rw-r--r--spell/aspell-0.60.6.1/m4/longlong.m448
-rw-r--r--spell/aspell-0.60.6.1/m4/ltoptions.m4368
-rw-r--r--spell/aspell-0.60.6.1/m4/ltsugar.m4123
-rw-r--r--spell/aspell-0.60.6.1/m4/ltversion.m423
-rw-r--r--spell/aspell-0.60.6.1/m4/lt~obsolete.m492
-rw-r--r--spell/aspell-0.60.6.1/m4/nls.m431
-rw-r--r--spell/aspell-0.60.6.1/m4/po.m4428
-rw-r--r--spell/aspell-0.60.6.1/m4/printf-posix.m444
-rw-r--r--spell/aspell-0.60.6.1/m4/progtest.m492
-rw-r--r--spell/aspell-0.60.6.1/m4/size_max.m462
-rw-r--r--spell/aspell-0.60.6.1/m4/stdint_h.m426
-rw-r--r--spell/aspell-0.60.6.1/m4/uintmax_t.m430
-rw-r--r--spell/aspell-0.60.6.1/m4/ulonglong.m448
-rw-r--r--spell/aspell-0.60.6.1/m4/visibility.m452
-rw-r--r--spell/aspell-0.60.6.1/m4/wchar_t.m420
-rw-r--r--spell/aspell-0.60.6.1/m4/wint_t.m420
-rw-r--r--spell/aspell-0.60.6.1/m4/xsize.m413
-rw-r--r--spell/aspell-0.60.6.1/maintainer/FIXMEs9
-rw-r--r--spell/aspell-0.60.6.1/maintainer/README-CVS53
-rw-r--r--spell/aspell-0.60.6.1/maintainer/TODO5
-rwxr-xr-xspell/aspell-0.60.6.1/maintainer/autogen22
-rwxr-xr-xspell/aspell-0.60.6.1/maintainer/config-debug7
-rwxr-xr-xspell/aspell-0.60.6.1/maintainer/config-opt7
-rw-r--r--spell/aspell-0.60.6.1/manual/Makefile.am14
-rw-r--r--spell/aspell-0.60.6.1/manual/aspell-dev.info1786
-rw-r--r--spell/aspell-0.60.6.1/manual/aspell-dev.texi1103
-rw-r--r--spell/aspell-0.60.6.1/manual/aspell-import.129
-rw-r--r--spell/aspell-0.60.6.1/manual/aspell.1352
-rw-r--r--spell/aspell-0.60.6.1/manual/aspell.info6981
-rw-r--r--spell/aspell-0.60.6.1/manual/aspell.texi5749
-rw-r--r--spell/aspell-0.60.6.1/manual/crubadan.texi93
-rw-r--r--spell/aspell-0.60.6.1/manual/fdl.texi448
-rw-r--r--spell/aspell-0.60.6.1/manual/lang-supported.texi197
-rw-r--r--spell/aspell-0.60.6.1/manual/lang-unsupported.texi10
-rw-r--r--spell/aspell-0.60.6.1/manual/lgpl.texi565
-rw-r--r--spell/aspell-0.60.6.1/manual/mksrc.texi297
-rw-r--r--spell/aspell-0.60.6.1/manual/oo-only.texi18
-rw-r--r--spell/aspell-0.60.6.1/manual/prezip-bin.1115
-rw-r--r--spell/aspell-0.60.6.1/manual/pspell-config.125
-rw-r--r--spell/aspell-0.60.6.1/manual/readme.texi423
-rw-r--r--spell/aspell-0.60.6.1/manual/run-with-aspell.141
-rw-r--r--spell/aspell-0.60.6.1/manual/word-list-compress.197
-rw-r--r--spell/aspell-0.60.6.1/misc/po-filter.c145
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/context-filter.info23
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/context.cpp267
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/email-filter.info23
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/email.cpp115
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/html-filter.info26
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/ccpp.amf18
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/comment.amf12
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/email.amf8
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/html.amf13
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/none.amf5
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/nroff.amf10
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/perl.amf16
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/sgml.amf12
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/tex.amf10
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/texinfo.amf10
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/modes/url.amf7
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/nroff-filter.info10
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/nroff.cpp312
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/sgml-filter.info23
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/sgml.cpp604
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/tex-filter.info105
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/tex.cpp767
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/texinfo-filter.info52
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/texinfo.cpp231
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/url-filter.info9
-rw-r--r--spell/aspell-0.60.6.1/modules/filter/url.cpp66
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/affix.cpp1439
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/affix.hpp130
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/asuggest.hpp58
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/block_vector.hpp54
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/check_list.hpp47
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/data.cpp468
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/data.hpp223
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/data_id.hpp29
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/data_util.hpp46
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/editdist.cpp56
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/editdist.hpp30
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/editdist2.hpp28
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/language.cpp742
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/language.hpp476
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/leditdist.cpp308
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/leditdist.hpp68
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/matrix.hpp22
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/multi_ws.cpp88
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/phonet.cpp472
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/phonet.hpp70
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/phonetic.cpp208
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/phonetic.hpp32
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/primes.cpp51
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/primes.hpp129
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/readonly_ws.cpp1191
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/speller_impl.cpp742
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/speller_impl.hpp262
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/suggest.cpp1430
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/suggest.hpp44
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/typo_editdist.cpp196
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/typo_editdist.hpp78
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/vector_hash-t.hpp191
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/vector_hash.hpp291
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/weights.hpp23
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/wordinfo.hpp60
-rw-r--r--spell/aspell-0.60.6.1/modules/speller/default/writable.cpp940
-rw-r--r--spell/aspell-0.60.6.1/modules/tokenizer/basic.cpp80
-rw-r--r--spell/aspell-0.60.6.1/myspell/Makefile.am5
-rw-r--r--spell/aspell-0.60.6.1/myspell/README7
-rw-r--r--spell/aspell-0.60.6.1/myspell/README.munch13
-rw-r--r--spell/aspell-0.60.6.1/myspell/README.replacetable25
-rw-r--r--spell/aspell-0.60.6.1/myspell/en_US.aff188
-rw-r--r--spell/aspell-0.60.6.1/myspell/munch.c870
-rw-r--r--spell/aspell-0.60.6.1/myspell/munch.h121
-rw-r--r--spell/aspell-0.60.6.1/po/LINGUAS31
-rw-r--r--spell/aspell-0.60.6.1/po/Makefile.in.in403
-rw-r--r--spell/aspell-0.60.6.1/po/Makevars41
-rw-r--r--spell/aspell-0.60.6.1/po/POTFILES.in17
-rw-r--r--spell/aspell-0.60.6.1/po/Rules-quot47
-rw-r--r--spell/aspell-0.60.6.1/po/aspell.pot1336
-rw-r--r--spell/aspell-0.60.6.1/po/ast.gmobin0 -> 31476 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ast.po1404
-rw-r--r--spell/aspell-0.60.6.1/po/be.gmobin0 -> 9388 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/be.po1495
-rw-r--r--spell/aspell-0.60.6.1/po/boldquot.sed10
-rw-r--r--spell/aspell-0.60.6.1/po/ca.gmobin0 -> 31200 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ca.po1405
-rw-r--r--spell/aspell-0.60.6.1/po/cs.gmobin0 -> 30327 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/cs.po1416
-rw-r--r--spell/aspell-0.60.6.1/po/da.gmobin0 -> 30308 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/da.po1400
-rw-r--r--spell/aspell-0.60.6.1/po/de.gmobin0 -> 31567 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/de.po1400
-rw-r--r--spell/aspell-0.60.6.1/po/en@boldquot.header25
-rw-r--r--spell/aspell-0.60.6.1/po/en@quot.header22
-rw-r--r--spell/aspell-0.60.6.1/po/en_GB.gmobin0 -> 26694 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/en_GB.po1536
-rw-r--r--spell/aspell-0.60.6.1/po/es.gmobin0 -> 30992 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/es.po1491
-rw-r--r--spell/aspell-0.60.6.1/po/fi.gmobin0 -> 31196 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/fi.po1421
-rw-r--r--spell/aspell-0.60.6.1/po/fr.gmobin0 -> 30846 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/fr.po1421
-rw-r--r--spell/aspell-0.60.6.1/po/ga.gmobin0 -> 31007 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ga.po1400
-rw-r--r--spell/aspell-0.60.6.1/po/id.gmobin0 -> 30561 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/id.po1400
-rw-r--r--spell/aspell-0.60.6.1/po/insert-header.sin23
-rw-r--r--spell/aspell-0.60.6.1/po/it.gmobin0 -> 30659 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/it.po1410
-rw-r--r--spell/aspell-0.60.6.1/po/ja.gmobin0 -> 33543 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ja.po1386
-rw-r--r--spell/aspell-0.60.6.1/po/mn.gmobin0 -> 33965 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/mn.po1436
-rw-r--r--spell/aspell-0.60.6.1/po/ms.gmobin0 -> 2427 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ms.po1345
-rw-r--r--spell/aspell-0.60.6.1/po/nl.gmobin0 -> 31043 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/nl.po1408
-rw-r--r--spell/aspell-0.60.6.1/po/pt_BR.gmobin0 -> 7762 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/pt_BR.po1475
-rw-r--r--spell/aspell-0.60.6.1/po/quot.sed6
-rw-r--r--spell/aspell-0.60.6.1/po/remove-potcdate.sin19
-rw-r--r--spell/aspell-0.60.6.1/po/ro.gmobin0 -> 30755 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ro.po1558
-rw-r--r--spell/aspell-0.60.6.1/po/ru.gmobin0 -> 29830 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/ru.po1384
-rw-r--r--spell/aspell-0.60.6.1/po/rw.gmobin0 -> 1155 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/rw.po1576
-rw-r--r--spell/aspell-0.60.6.1/po/sk.gmobin0 -> 30868 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/sk.po1386
-rw-r--r--spell/aspell-0.60.6.1/po/sl.gmobin0 -> 29868 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/sl.po1417
-rw-r--r--spell/aspell-0.60.6.1/po/sr.gmobin0 -> 10940 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/sr.po1512
-rw-r--r--spell/aspell-0.60.6.1/po/stamp-po1
-rw-r--r--spell/aspell-0.60.6.1/po/sv.gmobin0 -> 14272 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/sv.po1353
-rw-r--r--spell/aspell-0.60.6.1/po/tg.gmobin0 -> 14033 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/tg.po1558
-rw-r--r--spell/aspell-0.60.6.1/po/uk.gmobin0 -> 37762 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/uk.po1385
-rw-r--r--spell/aspell-0.60.6.1/po/vi.gmobin0 -> 33964 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/vi.po1400
-rw-r--r--spell/aspell-0.60.6.1/po/wa.gmobin0 -> 18376 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/wa.po1376
-rw-r--r--spell/aspell-0.60.6.1/po/zh_CN.gmobin0 -> 7972 bytes
-rw-r--r--spell/aspell-0.60.6.1/po/zh_CN.po1336
-rw-r--r--spell/aspell-0.60.6.1/prog/aspell.cpp2948
-rw-r--r--spell/aspell-0.60.6.1/prog/check_funs.cpp896
-rw-r--r--spell/aspell-0.60.6.1/prog/check_funs.hpp42
-rw-r--r--spell/aspell-0.60.6.1/prog/checker_string.cpp165
-rw-r--r--spell/aspell-0.60.6.1/prog/checker_string.hpp117
-rw-r--r--spell/aspell-0.60.6.1/prog/compress.c147
-rw-r--r--spell/aspell-0.60.6.1/prog/prezip.c260
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/aspell-import84
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/ispell32
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/mkconfig27
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/precat260
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/preunzip260
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/prezip260
-rw-r--r--spell/aspell-0.60.6.1/scripts/run-with-aspell.create7
-rwxr-xr-xspell/aspell-0.60.6.1/scripts/spell6
-rw-r--r--spell/aspell-0.60.6.1/win32/settings.h92
-rwxr-xr-xspell/build.zsh9
-rw-r--r--spell/dict/ccpp.amf18
-rw-r--r--spell/dict/comment.amf12
-rw-r--r--spell/dict/cp1250.cmap1991
-rw-r--r--spell/dict/cp1250.cset262
-rw-r--r--spell/dict/cp1251.cmap1903
-rw-r--r--spell/dict/cp1251.cset262
-rw-r--r--spell/dict/cp1252.cmap1943
-rw-r--r--spell/dict/cp1252.cset262
-rw-r--r--spell/dict/cp1253.cmap2148
-rw-r--r--spell/dict/cp1253.cset262
-rw-r--r--spell/dict/cp1254.cmap1944
-rw-r--r--spell/dict/cp1254.cset262
-rw-r--r--spell/dict/cp1255.cmap2251
-rw-r--r--spell/dict/cp1255.cset262
-rw-r--r--spell/dict/cp1256.cmap2476
-rw-r--r--spell/dict/cp1256.cset262
-rw-r--r--spell/dict/cp1257.cmap1962
-rw-r--r--spell/dict/cp1257.cset262
-rw-r--r--spell/dict/cp1258.cmap2403
-rw-r--r--spell/dict/cp1258.cset262
-rw-r--r--spell/dict/dvorak.kbd25
-rw-r--r--spell/dict/email.amf8
-rw-r--r--spell/dict/en-common.rwsbin0 -> 2334032 bytes
-rw-r--r--spell/dict/en-variant_0.multi2
-rw-r--r--spell/dict/en-variant_0.rwsbin0 -> 34736 bytes
-rw-r--r--spell/dict/en-variant_1.multi2
-rw-r--r--spell/dict/en-variant_1.rwsbin0 -> 87248 bytes
-rw-r--r--spell/dict/en-variant_2.multi2
-rw-r--r--spell/dict/en-variant_2.rwsbin0 -> 95808 bytes
-rw-r--r--spell/dict/en-w_accents-only.rwsbin0 -> 108416 bytes
-rw-r--r--spell/dict/en-w_accents.multi3
-rw-r--r--spell/dict/en-wo_accents-only.rwsbin0 -> 108416 bytes
-rw-r--r--spell/dict/en-wo_accents.multi3
-rw-r--r--spell/dict/en.dat6
-rw-r--r--spell/dict/en.multi2
-rw-r--r--spell/dict/en_CA-variant_0.multi2
-rw-r--r--spell/dict/en_CA-variant_0.rwsbin0 -> 37328 bytes
-rw-r--r--spell/dict/en_CA-variant_1.multi2
-rw-r--r--spell/dict/en_CA-variant_1.rwsbin0 -> 73344 bytes
-rw-r--r--spell/dict/en_CA-w_accents-only.rwsbin0 -> 91760 bytes
-rw-r--r--spell/dict/en_CA-w_accents.multi3
-rw-r--r--spell/dict/en_CA-wo_accents-only.rwsbin0 -> 91760 bytes
-rw-r--r--spell/dict/en_CA-wo_accents.multi3
-rw-r--r--spell/dict/en_CA.multi2
-rw-r--r--spell/dict/en_GB-ise-w_accents-only.rwsbin0 -> 92560 bytes
-rw-r--r--spell/dict/en_GB-ise-w_accents.multi3
-rw-r--r--spell/dict/en_GB-ise-wo_accents-only.rwsbin0 -> 92560 bytes
-rw-r--r--spell/dict/en_GB-ise-wo_accents.multi3
-rw-r--r--spell/dict/en_GB-ise.multi2
-rw-r--r--spell/dict/en_GB-ize-w_accents-only.rwsbin0 -> 92176 bytes
-rw-r--r--spell/dict/en_GB-ize-w_accents.multi3
-rw-r--r--spell/dict/en_GB-ize-wo_accents-only.rwsbin0 -> 92176 bytes
-rw-r--r--spell/dict/en_GB-ize-wo_accents.multi3
-rw-r--r--spell/dict/en_GB-ize.multi2
-rw-r--r--spell/dict/en_GB-variant_0.multi2
-rw-r--r--spell/dict/en_GB-variant_0.rwsbin0 -> 26256 bytes
-rw-r--r--spell/dict/en_GB-variant_1.multi2
-rw-r--r--spell/dict/en_GB-variant_1.rwsbin0 -> 62784 bytes
-rw-r--r--spell/dict/en_GB-w_accents.multi2
-rw-r--r--spell/dict/en_GB-wo_accents.multi2
-rw-r--r--spell/dict/en_GB.multi2
-rw-r--r--spell/dict/en_US-variant_0.multi2
-rw-r--r--spell/dict/en_US-variant_1.multi2
-rw-r--r--spell/dict/en_US-w_accents-only.rwsbin0 -> 90576 bytes
-rw-r--r--spell/dict/en_US-w_accents.multi3
-rw-r--r--spell/dict/en_US-wo_accents-only.rwsbin0 -> 90576 bytes
-rw-r--r--spell/dict/en_US-wo_accents.multi3
-rw-r--r--spell/dict/en_US.multi2
-rw-r--r--spell/dict/en_affix.dat226
-rw-r--r--spell/dict/en_phonet.dat250
-rw-r--r--spell/dict/english-variant_0.alias2
-rw-r--r--spell/dict/english-variant_1.alias2
-rw-r--r--spell/dict/english-variant_2.alias2
-rw-r--r--spell/dict/english-w_accents.alias2
-rw-r--r--spell/dict/english-wo_accents.alias2
-rw-r--r--spell/dict/english.alias2
-rw-r--r--spell/dict/html.amf13
-rw-r--r--spell/dict/iso-8859-1.cmap1922
-rw-r--r--spell/dict/iso-8859-1.cset262
-rw-r--r--spell/dict/iso-8859-10.cmap1971
-rw-r--r--spell/dict/iso-8859-10.cset262
-rw-r--r--spell/dict/iso-8859-11.cmap1508
-rw-r--r--spell/dict/iso-8859-11.cset262
-rw-r--r--spell/dict/iso-8859-13.cmap1961
-rw-r--r--spell/dict/iso-8859-13.cset262
-rw-r--r--spell/dict/iso-8859-14.cmap2010
-rw-r--r--spell/dict/iso-8859-14.cset262
-rw-r--r--spell/dict/iso-8859-15.cmap1934
-rw-r--r--spell/dict/iso-8859-15.cset262
-rw-r--r--spell/dict/iso-8859-16.cmap1951
-rw-r--r--spell/dict/iso-8859-16.cset262
-rw-r--r--spell/dict/iso-8859-2.cmap1983
-rw-r--r--spell/dict/iso-8859-2.cset262
-rw-r--r--spell/dict/iso-8859-3.cmap1935
-rw-r--r--spell/dict/iso-8859-3.cset262
-rw-r--r--spell/dict/iso-8859-4.cmap1970
-rw-r--r--spell/dict/iso-8859-4.cset262
-rw-r--r--spell/dict/iso-8859-5.cmap1895
-rw-r--r--spell/dict/iso-8859-5.cset262
-rw-r--r--spell/dict/iso-8859-6.cmap2201
-rw-r--r--spell/dict/iso-8859-6.cset262
-rw-r--r--spell/dict/iso-8859-7.cmap2145
-rw-r--r--spell/dict/iso-8859-7.cset262
-rw-r--r--spell/dict/iso-8859-8.cmap1483
-rw-r--r--spell/dict/iso-8859-8.cset262
-rw-r--r--spell/dict/iso-8859-9.cmap1937
-rw-r--r--spell/dict/iso-8859-9.cset262
-rw-r--r--spell/dict/koi8-r.cmap1857
-rw-r--r--spell/dict/koi8-r.cset262
-rw-r--r--spell/dict/koi8-u.cmap1869
-rw-r--r--spell/dict/koi8-u.cset262
-rw-r--r--spell/dict/l-grc.cmap2639
-rw-r--r--spell/dict/l-grc.cset261
-rw-r--r--spell/dict/none.amf5
-rw-r--r--spell/dict/nroff.amf10
-rw-r--r--spell/dict/perl.amf16
-rw-r--r--spell/dict/sgml.amf12
-rw-r--r--spell/dict/split.kbd23
-rw-r--r--spell/dict/standard.kbd25
-rw-r--r--spell/dict/tex.amf10
-rw-r--r--spell/dict/texinfo.amf10
-rw-r--r--spell/dict/u-deva.cmap1362
-rw-r--r--spell/dict/u-deva.cset262
-rw-r--r--spell/dict/url.amf7
-rw-r--r--spell/dictionaries.el142
-rwxr-xr-xspell/ispell32
547 files changed, 246398 insertions, 0 deletions
diff --git a/elisp/flyspell.el b/elisp/flyspell.el
new file mode 100644
index 0000000..ce93e82
--- /dev/null
+++ b/elisp/flyspell.el
@@ -0,0 +1,2460 @@
+;;; <pre>
+;;; flyspell.el --- on-the-fly spell checker
+
+;; Copyright (C) 1998, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Manuel Serrano <Manuel.Serrano@inria.fr>
+;; Version: 1.7p
+;; Keywords: convenience
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Flyspell is a minor Emacs mode performing on-the-fly spelling
+;; checking.
+;;
+;; To enable Flyspell minor mode, type M-x flyspell-mode.
+;; This applies only to the current buffer.
+;;
+;; To enable Flyspell in text representing computer programs, type
+;; M-x flyspell-prog-mode.
+;; In that mode only text inside comments is checked.
+;;
+;; Note: consider setting the variable ispell-parser to `tex' to
+;; avoid TeX command checking; use `(setq ispell-parser 'tex)'.
+;;
+;; Some user variables control the behavior of flyspell. They are
+;; those defined under the `User variables' comment.
+
+;;; Code:
+(require 'ispell)
+
+;*---------------------------------------------------------------------*/
+;* Group ... */
+;*---------------------------------------------------------------------*/
+(defgroup flyspell nil
+ "Spell checking on the fly."
+ :tag "FlySpell"
+ :prefix "flyspell-"
+ :group 'ispell
+ :group 'processes)
+
+;*---------------------------------------------------------------------*/
+;* Which emacs are we currently running */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-emacs
+ (cond
+ ((string-match "XEmacs" emacs-version)
+ 'xemacs)
+ (t
+ 'emacs))
+ "The type of Emacs we are currently running.")
+
+(defvar flyspell-use-local-map
+ (or (eq flyspell-emacs 'xemacs)
+ (not (string< emacs-version "20"))))
+
+;*---------------------------------------------------------------------*/
+;* User configuration ... */
+;*---------------------------------------------------------------------*/
+(defcustom flyspell-highlight-flag t
+ "*How Flyspell should indicate misspelled words.
+Non-nil means use highlight, nil means use minibuffer messages."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-mark-duplications-flag t
+ "*Non-nil means Flyspell reports a repeated word as an error."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-sort-corrections nil
+ "*Non-nil means, sort the corrections alphabetically before popping them."
+ :group 'flyspell
+ :version "21.1"
+ :type 'boolean)
+
+(defcustom flyspell-duplicate-distance -1
+ "*The maximum distance for finding duplicates of unrecognized words.
+This applies to the feature that when a word is not found in the dictionary,
+if the same spelling occurs elsewhere in the buffer,
+Flyspell uses a different face (`flyspell-duplicate-face') to highlight it.
+This variable specifies how far to search to find such a duplicate.
+-1 means no limit (search the whole buffer).
+0 means do not search for duplicate unrecognized spellings."
+ :group 'flyspell
+ :version "21.1"
+ :type 'number)
+
+(defcustom flyspell-delay 3
+ "*The number of seconds to wait before checking, after a \"delayed\" command."
+ :group 'flyspell
+ :type 'number)
+
+(defcustom flyspell-persistent-highlight t
+ "*Non-nil means misspelled words remain highlighted until corrected.
+If this variable is nil, only the most recently detected misspelled word
+is highlighted."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-highlight-properties t
+ "*Non-nil means highlight incorrect words even if a property exists for this word."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-default-delayed-commands
+ '(self-insert-command
+ delete-backward-char
+ backward-or-forward-delete-char
+ delete-char
+ scrollbar-vertical-drag
+ backward-delete-char-untabify)
+ "The standard list of delayed commands for Flyspell.
+See `flyspell-delayed-commands'."
+ :group 'flyspell
+ :version "21.1"
+ :type '(repeat (symbol)))
+
+(defcustom flyspell-delayed-commands nil
+ "List of commands that are \"delayed\" for Flyspell mode.
+After these commands, Flyspell checking is delayed for a short time,
+whose length is specified by `flyspell-delay'."
+ :group 'flyspell
+ :type '(repeat (symbol)))
+
+(defcustom flyspell-default-deplacement-commands
+ '(next-line
+ previous-line
+ scroll-up
+ scroll-down)
+ "The standard list of deplacement commands for Flyspell.
+See `flyspell-deplacement-commands'."
+ :group 'flyspell
+ :version "21.1"
+ :type '(repeat (symbol)))
+
+(defcustom flyspell-default-ignored-commands
+ '(fill-paragraph)
+ "The standard list of ignored commands for Flyspell.
+ See `flyspell-delayed-commands'."
+ :group 'flyspell
+ :version "21.3"
+ :type '(repeat (symbol)))
+
+ (defcustom flyspell-ignored-commands nil
+ "List of commands that are \"ignored\" for Flyspell mode.
+ The changes in the text made by these commands are ignored. This list is meant for commands that change text in a way that does not affect individual words, such as `fill-paragraph'."
+ :group 'flyspell
+ :version "21.3"
+ :type '(repeat (symbol)))
+
+(defcustom flyspell-deplacement-commands nil
+ "List of commands that are \"deplacement\" for Flyspell mode.
+After these commands, Flyspell checking is performed only if the previous
+command was not the very same command."
+ :group 'flyspell
+ :version "21.1"
+ :type '(repeat (symbol)))
+
+(defcustom flyspell-issue-welcome-flag t
+ "*Non-nil means that Flyspell should display a welcome message when started."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-issue-message-flag t
+ "*Non-nil means that Flyspell emits messages when checking words."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-incorrect-hook nil
+ "*List of functions to be called when incorrect words are encountered.
+Each function is given three arguments: the beginning and the end
+of the incorrect region. The third is either the symbol 'doublon' or the list
+of possible corrections as returned by 'ispell-parse-output'.
+
+If any of the functions return non-Nil, the word is not highlighted as
+incorrect."
+ :group 'flyspell
+ :version "21.1"
+ :type 'hook)
+
+(defcustom flyspell-default-dictionary nil
+ "A string that is the name of the default dictionary.
+This is passed to the `ispell-change-dictionary' when flyspell is started.
+If the variable `ispell-local-dictionary' or `ispell-dictionary' is non-nil
+when flyspell is started, the value of that variable is used instead
+of `flyspell-default-dictionary' to select the default dictionary.
+Otherwise, if `flyspell-default-dictionary' is nil, it means to use
+Ispell's ultimate default dictionary."
+ :group 'flyspell
+ :version "21.1"
+ :type '(choice string (const :tag "Default" nil)))
+
+(defcustom flyspell-tex-command-regexp
+ "\\(\\(begin\\|end\\)[ \t]*{\\|\\(cite[a-z*]*\\|label\\|ref\\|eqref\\|usepackage\\|documentclass\\)[ \t]*\\(\\[[^]]*\\]\\)?{[^{}]*\\)"
+ "A string that is the regular expression that matches TeX commands."
+ :group 'flyspell
+ :version "21.1"
+ :type 'string)
+
+(defcustom flyspell-check-tex-math-command nil
+ "*Non nil means check even inside TeX math environment.
+TeX math environments are discovered by the TEXMATHP that implemented
+inside the texmathp.el Emacs package. That package may be found at:
+http://strw.leidenuniv.nl/~dominik/Tools"
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-dictionaries-that-consider-dash-as-word-delimiter
+ '("francais" "deutsch8" "norsk")
+ "List of dictionary names that consider `-' as word delimiter."
+ :group 'flyspell
+ :version "21.1"
+ :type '(repeat (string)))
+
+(defcustom flyspell-abbrev-p
+ nil
+ "*If non-nil, add correction to abbreviation table."
+ :group 'flyspell
+ :version "21.1"
+ :type 'boolean)
+
+(defcustom flyspell-use-global-abbrev-table-p
+ nil
+ "*If non-nil, prefer global abbrev table to local abbrev table."
+ :group 'flyspell
+ :version "21.1"
+ :type 'boolean)
+
+;;;###autoload
+(defcustom flyspell-mode-line-string " Fly"
+ "*String displayed on the modeline when flyspell is active.
+Set this to nil if you don't want a modeline indicator."
+ :group 'flyspell
+ :type '(choice string (const :tag "None" nil)))
+
+(defcustom flyspell-large-region 1000
+ "*The threshold that determines if a region is small.
+The `flyspell-region' function is invoked if the region is small, the
+word are checked one after the other using regular flyspell check
+means. If the region is large, a new Ispell process is spawned to get
+speed.
+
+if flyspell-large-region is nil, regions are treated as small."
+ :group 'flyspell
+ :version "21.1"
+ :type '(choice number boolean))
+
+(defcustom flyspell-insert-function (function insert)
+ "*Function for inserting word by flyspell upon correction."
+ :group 'flyspell
+ :type 'function)
+
+(defcustom flyspell-before-incorrect-word-string nil
+ "String used to indicate an incorrect word starting."
+ :group 'flyspell
+ :type '(choice string (const nil)))
+
+(defcustom flyspell-after-incorrect-word-string nil
+ "String used to indicate an incorrect word ending."
+ :group 'flyspell
+ :type '(choice string (const nil)))
+
+(defcustom flyspell-use-meta-tab t
+ "*Non-nil means that flyspell uses META-TAB to correct word."
+ :group 'flyspell
+ :type 'boolean)
+
+(defcustom flyspell-auto-correct-binding
+ (cond
+ ((eq flyspell-emacs 'xemacs)
+ [(control \;)])
+ (t
+ [?\C-\;]))
+ "The key binding for flyspell auto correction."
+ :group 'flyspell)
+
+;*---------------------------------------------------------------------*/
+;* Mode specific options */
+;* ------------------------------------------------------------- */
+;* Mode specific options enable users to disable flyspell on */
+;* certain word depending of the emacs mode. For instance, when */
+;* using flyspell with mail-mode add the following expression */
+;* in your .emacs file: */
+;* (add-hook 'mail-mode */
+;* '(lambda () (setq flyspell-generic-check-word-p */
+;* 'mail-mode-flyspell-verify))) */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-generic-check-word-p nil
+ "Function providing per-mode customization over which words are flyspelled.
+Returns t to continue checking, nil otherwise.
+Flyspell mode sets this variable to whatever is the `flyspell-mode-predicate'
+property of the major mode name.")
+(make-variable-buffer-local 'flyspell-generic-check-word-p)
+
+;*--- mail mode -------------------------------------------------------*/
+(put 'mail-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
+(put 'message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
+(defun mail-mode-flyspell-verify ()
+ "This function is used for `flyspell-generic-check-word-p' in Mail mode."
+ (let ((header-end (save-excursion
+ (goto-char (point-min))
+ (re-search-forward
+ (concat "^"
+ (regexp-quote mail-header-separator)
+ "$")
+ nil t)
+ (point)))
+ (signature-begin (save-excursion
+ (goto-char (point-max))
+ (re-search-backward message-signature-separator
+ nil t)
+ (point))))
+ (cond ((< (point) header-end)
+ (and (save-excursion (beginning-of-line)
+ (looking-at "^Subject:"))
+ (> (point) (match-end 0))))
+ ((> (point) signature-begin)
+ nil)
+ (t
+ (save-excursion
+ (beginning-of-line)
+ (not (looking-at "[>}|]\\|To:")))))))
+
+;*--- texinfo mode ----------------------------------------------------*/
+(put 'texinfo-mode 'flyspell-mode-predicate 'texinfo-mode-flyspell-verify)
+(defun texinfo-mode-flyspell-verify ()
+ "This function is used for `flyspell-generic-check-word-p' in Texinfo mode."
+ (save-excursion
+ (forward-word -1)
+ (not (looking-at "@"))))
+
+;*--- tex mode --------------------------------------------------------*/
+(put 'tex-mode 'flyspell-mode-predicate 'tex-mode-flyspell-verify)
+(defun tex-mode-flyspell-verify ()
+ "This function is used for `flyspell-generic-check-word-p' in LaTeX mode."
+ (and
+ (not (save-excursion
+ (re-search-backward "^[ \t]*%%%[ \t]+Local" (point-min) t)))
+ (not (save-excursion
+ (let ((this (point-marker))
+ (e (progn (end-of-line) (point-marker))))
+ (beginning-of-line)
+ (if (re-search-forward "\\\\\\(cite\\|label\\|ref\\){[^}]*}" e t)
+ (and (>= this (match-beginning 0))
+ (<= this (match-end 0)) )))))))
+
+;*--- sgml mode -------------------------------------------------------*/
+(put 'sgml-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
+(put 'html-mode 'flyspell-mode-predicate 'sgml-mode-flyspell-verify)
+
+(defun sgml-mode-flyspell-verify ()
+ "This function is used for `flyspell-generic-check-word-p' in SGML mode."
+ (not (save-excursion
+ (let ((this (point-marker))
+ (s (progn (beginning-of-line) (point-marker)))
+ (e (progn (end-of-line) (point-marker))))
+ (or (progn
+ (goto-char this)
+ (and (re-search-forward "[^<]*>" e t)
+ (= (match-beginning 0) this)))
+ (progn
+ (goto-char this)
+ (and (re-search-backward "<[^>]*" s t)
+ (= (match-end 0) this)))
+ (and (progn
+ (goto-char this)
+ (and (re-search-forward "[^&]*;" e t)
+ (= (match-beginning 0) this)))
+ (progn
+ (goto-char this)
+ (and (re-search-backward "&[^;]*" s t)
+ (= (match-end 0) this)))))))))
+
+;*---------------------------------------------------------------------*/
+;* Programming mode */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-prog-text-faces
+ '(font-lock-string-face font-lock-comment-face font-lock-doc-face)
+ "Faces corresponding to text in programming-mode buffers.")
+
+(defun flyspell-generic-progmode-verify ()
+ "Used for `flyspell-generic-check-word-p' in programming modes."
+ (let ((f (get-text-property (point) 'face)))
+ (memq f flyspell-prog-text-faces)))
+
+;;;###autoload
+(defun flyspell-prog-mode ()
+ "Turn on `flyspell-mode' for comments and strings."
+ (interactive)
+ (setq flyspell-generic-check-word-p 'flyspell-generic-progmode-verify)
+ (flyspell-mode 1)
+ (run-hooks 'flyspell-prog-mode-hook))
+
+;*---------------------------------------------------------------------*/
+;* Overlay compatibility */
+;*---------------------------------------------------------------------*/
+(autoload 'make-overlay "overlay" "Overlay compatibility kit." t)
+(autoload 'overlayp "overlay" "Overlay compatibility kit." t)
+(autoload 'overlays-in "overlay" "Overlay compatibility kit." t)
+(autoload 'delete-overlay "overlay" "Overlay compatibility kit." t)
+(autoload 'overlays-at "overlay" "Overlay compatibility kit." t)
+(autoload 'overlay-put "overlay" "Overlay compatibility kit." t)
+(autoload 'overlay-get "overlay" "Overlay compatibility kit." t)
+(autoload 'previous-overlay-change "overlay" "Overlay compatibility kit." t)
+
+;*---------------------------------------------------------------------*/
+;* The minor mode declaration. */
+;*---------------------------------------------------------------------*/
+(eval-when-compile (defvar flyspell-local-mouse-map))
+
+;;;###autoload
+(defvar flyspell-mode nil)
+(make-variable-buffer-local 'flyspell-mode)
+
+(defvar flyspell-mouse-map
+ (let ((map (make-sparse-keymap)))
+ (if flyspell-use-meta-tab
+ (define-key map "\M-\t" #'flyspell-auto-correct-word))
+ (define-key map (if (featurep 'xemacs) [button2] [down-mouse-2])
+ #'flyspell-correct-word)
+ (if (not (featurep 'xemacs))
+ (define-key map [(shift down-mouse-2)] #'flyspell-correct-word))
+ (define-key map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
+ (define-key map [(control \,)] 'flyspell-goto-next-error)
+ (define-key map [(control \.)] 'flyspell-auto-correct-word)
+ map))
+
+;;;###autoload
+(defvar flyspell-mode-map (make-sparse-keymap))
+
+;; mouse, keyboard bindings and misc definition
+(when (or (assoc 'flyspell-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'flyspell-mode flyspell-mode-map)
+ minor-mode-map-alist)))
+ (if flyspell-use-meta-tab
+ (define-key flyspell-mode-map "\M-\t" 'flyspell-auto-correct-word))
+ (cond
+ ((eq flyspell-emacs 'xemacs)
+ (define-key flyspell-mode-map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
+ (define-key flyspell-mode-map [(control \,)] 'flyspell-goto-next-error)
+ (define-key flyspell-mode-map [(control \.)] 'flyspell-auto-correct-word))
+ (flyspell-use-local-map
+ (define-key flyspell-mode-map flyspell-auto-correct-binding 'flyspell-auto-correct-previous-word)
+ (define-key flyspell-mode-map [?\C-\,] 'flyspell-goto-next-error)
+ (define-key flyspell-mode-map [?\C-\.] 'flyspell-auto-correct-word))))
+
+
+;; the name of the overlay property that defines the keymap
+(defvar flyspell-overlay-keymap-property-name 'keymap)
+
+;; dash character machinery
+(defvar flyspell-consider-dash-as-word-delimiter-flag nil
+ "*Non-nil means that the `-' char is considered as a word delimiter.")
+(make-variable-buffer-local 'flyspell-consider-dash-as-word-delimiter-flag)
+(defvar flyspell-dash-dictionary nil)
+(make-variable-buffer-local 'flyspell-dash-dictionary)
+(defvar flyspell-dash-local-dictionary nil)
+(make-variable-buffer-local 'flyspell-dash-local-dictionary)
+
+;*---------------------------------------------------------------------*/
+;* Highlighting */
+;*---------------------------------------------------------------------*/
+(defface flyspell-incorrect-face
+ (if (eq flyspell-emacs 'xemacs)
+ '((((class color)) (:foreground "OrangeRed" :bold t :underline t))
+ (t (:bold t)))
+ '((((class color)) (:foreground "OrangeRed" :weight bold :underline t))
+ (t (:weight bold))))
+ "Face used for marking a misspelled word in Flyspell."
+ :group 'flyspell)
+
+(defface flyspell-duplicate-face
+ (if (eq flyspell-emacs 'xemacs)
+ '((((class color)) (:foreground "Gold3" :bold t :underline t))
+ (t (:bold t)))
+ '((((class color)) (:foreground "Gold3" :weight bold :underline t))
+ (t (:weight bold))))
+ "Face used for marking a misspelled word that appears twice in the buffer.
+See also `flyspell-duplicate-distance'."
+ :group 'flyspell)
+
+(defvar flyspell-overlay nil)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-mode ... */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-mode (&optional arg)
+ "Minor mode performing on-the-fly spelling checking.
+Ispell is automatically spawned on background for each entered words.
+The default flyspell behavior is to highlight incorrect words.
+With no argument, this command toggles Flyspell mode.
+With a prefix argument ARG, turn Flyspell minor mode on iff ARG is positive.
+
+Bindings:
+\\[ispell-word]: correct words (using Ispell).
+\\[flyspell-auto-correct-word]: automatically correct word.
+\\[flyspell-auto-correct-previous-word]: automatically correct the last misspelled word.
+\\[flyspell-correct-word] (or down-mouse-2): popup correct words.
+
+Hooks:
+This runs `flyspell-mode-hook' after flyspell is entered.
+
+Remark:
+`flyspell-mode' uses `ispell-mode'. Thus all Ispell options are
+valid. For instance, a personal dictionary can be used by
+invoking `ispell-change-dictionary'.
+
+Consider using the `ispell-parser' to check your text. For instance
+consider adding:
+\(add-hook 'tex-mode-hook (function (lambda () (setq ispell-parser 'tex))))
+in your .emacs file.
+
+\\[flyspell-region] checks all words inside a region.
+\\[flyspell-buffer] checks the whole buffer."
+ (interactive "P")
+ (let ((old-flyspell-mode flyspell-mode))
+ ;; Mark the mode as on or off.
+ (setq flyspell-mode (not (or (and (null arg) flyspell-mode)
+ (<= (prefix-numeric-value arg) 0))))
+ ;; Do the real work.
+ (unless (eq flyspell-mode old-flyspell-mode)
+ (if flyspell-mode
+ (flyspell-mode-on)
+ (flyspell-mode-off))
+ ;; Force modeline redisplay.
+ (set-buffer-modified-p (buffer-modified-p)))))
+
+;*---------------------------------------------------------------------*/
+;* Autoloading */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(if (fboundp 'add-minor-mode)
+ (add-minor-mode 'flyspell-mode
+ 'flyspell-mode-line-string
+ flyspell-mode-map
+ nil
+ 'flyspell-mode)
+ (or (assoc 'flyspell-mode minor-mode-alist)
+ (setq minor-mode-alist
+ (cons '(flyspell-mode flyspell-mode-line-string)
+ minor-mode-alist)))
+
+ (or (assoc 'flyspell-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'flyspell-mode flyspell-mode-map)
+ minor-mode-map-alist))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-buffers ... */
+;* ------------------------------------------------------------- */
+;* For remembering buffers running flyspell */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-buffers nil)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-minibuffer-p ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-minibuffer-p (buffer)
+ "Is BUFFER a minibuffer?"
+ (let ((ws (get-buffer-window-list buffer t)))
+ (and (consp ws) (window-minibuffer-p (car ws)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-version ... */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-version ()
+ "The flyspell version"
+ (interactive)
+ "1.7p")
+
+;*---------------------------------------------------------------------*/
+;* flyspell-accept-buffer-local-defs ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-accept-buffer-local-defs ()
+ ;; strange problem. If buffer in current window has font-lock turned on,
+ ;; but SET-BUFFER was called to point to an invisible buffer, this ispell
+ ;; call will reset the buffer to the buffer in the current window. However,
+ ;; it only happens at startup (fix by Albert L. Ting).
+ (let ((buf (current-buffer)))
+ (ispell-accept-buffer-local-defs)
+ (set-buffer buf))
+ (if (not (and (eq flyspell-dash-dictionary ispell-dictionary)
+ (eq flyspell-dash-local-dictionary ispell-local-dictionary)))
+ ;; the dictionary has changed
+ (progn
+ (setq flyspell-dash-dictionary ispell-dictionary)
+ (setq flyspell-dash-local-dictionary ispell-local-dictionary)
+ (if (member (or ispell-local-dictionary ispell-dictionary)
+ flyspell-dictionaries-that-consider-dash-as-word-delimiter)
+ (setq flyspell-consider-dash-as-word-delimiter-flag t)
+ (setq flyspell-consider-dash-as-word-delimiter-flag nil)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-mode-on ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-mode-on ()
+ "Turn Flyspell mode on. Do not use this; use `flyspell-mode' instead."
+ (setq ispell-highlight-face 'flyspell-incorrect-face)
+ ;; local dictionaries setup
+ (ispell-change-dictionary
+ (or ispell-local-dictionary ispell-dictionary flyspell-default-dictionary))
+ ;; we have to force ispell to accept the local definition or
+ ;; otherwise it could be too late, the local dictionary may
+ ;; be forgotten!
+ (flyspell-accept-buffer-local-defs)
+ ;; we put the `flyspell-delayed' property on some commands
+ (flyspell-delay-commands)
+ ;; we put the `flyspell-deplacement' property on some commands
+ (flyspell-deplacement-commands)
+ ;; we put the `flyspell-ignored' property on some commands
+ (flyspell-ignore-commands)
+ ;; we bound flyspell action to post-command hook
+ (if (eq flyspell-emacs 'xemacs)
+ (make-local-hook 'post-command-hook))
+ (add-hook 'post-command-hook (function flyspell-post-command-hook) t t)
+ ;; we bound flyspell action to pre-command hook
+ (if (eq flyspell-emacs 'xemacs)
+ (make-local-hook 'pre-command-hook))
+ (add-hook 'pre-command-hook (function flyspell-pre-command-hook) t t)
+ ;; we bound flyspell action to after-change hook
+ (make-local-variable 'after-change-functions)
+ (setq after-change-functions
+ (cons 'flyspell-after-change-function after-change-functions))
+ ;; set flyspell-generic-check-word-p based on the major mode
+ (let ((mode-predicate (get major-mode 'flyspell-mode-predicate)))
+ (if mode-predicate
+ (setq flyspell-generic-check-word-p mode-predicate)))
+ ;; work around the fact that the `local-map' text-property replaces the
+ ;; buffer's local map rather than shadowing it.
+ (set (make-local-variable 'flyspell-mouse-map)
+ (let ((map (copy-keymap flyspell-mouse-map)))
+ (set-keymap-parent map (current-local-map))
+ (if (and (eq flyspell-emacs 'emacs)
+ (not (string< emacs-version "20")))
+ (define-key map '[tool-bar] nil))
+ map))
+ (set (make-local-variable 'flyspell-mode-map)
+ (let ((map (copy-keymap flyspell-mode-map)))
+ (set-keymap-parent map (current-local-map))
+ (if (and (eq flyspell-emacs 'emacs)
+ (not (string< emacs-version "20")))
+ (define-key map '[tool-bar] nil))
+ map))
+ ;; the welcome message
+ (if (and flyspell-issue-message-flag
+ flyspell-issue-welcome-flag
+ (interactive-p))
+ (let ((binding (where-is-internal 'flyspell-auto-correct-word
+ nil 'non-ascii)))
+ (message
+ (if binding
+ (format "Welcome to flyspell. Use %s or Mouse-2 to correct words."
+ (key-description binding))
+ "Welcome to flyspell. Use Mouse-2 to correct words."))))
+ ;; we end with the flyspell hooks
+ (run-hooks 'flyspell-mode-hook))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-delay-commands ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delay-commands ()
+ "Install the standard set of Flyspell delayed commands."
+ (mapcar 'flyspell-delay-command flyspell-default-delayed-commands)
+ (mapcar 'flyspell-delay-command flyspell-delayed-commands))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-delay-command ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delay-command (command)
+ "Set COMMAND to be delayed, for Flyspell.
+When flyspell `post-command-hook' is invoked because a delayed command
+as been used the current word is not immediately checked.
+It will be checked only after `flyspell-delay' seconds."
+ (interactive "SDelay Flyspell after Command: ")
+ (put command 'flyspell-delayed t))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-deplacement-commands ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-deplacement-commands ()
+ "Install the standard set of Flyspell deplacement commands."
+ (mapcar 'flyspell-deplacement-command flyspell-default-deplacement-commands)
+ (mapcar 'flyspell-deplacement-command flyspell-deplacement-commands))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-deplacement-command ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-deplacement-command (command)
+ "Set COMMAND that implement cursor movements, for Flyspell.
+When flyspell `post-command-hook' is invoked because of a deplacement command
+as been used the current word is checked only if the previous command was
+not the very same deplacement command."
+ (interactive "SDeplacement Flyspell after Command: ")
+ (put command 'flyspell-deplacement t))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-ignore-commands ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-ignore-commands ()
+ "Install the standard set of Flyspell ignored commands."
+ (mapcar 'flyspell-ignore-command flyspell-default-ignored-commands)
+ (mapcar 'flyspell-ignore-command flyspell-ignored-commands))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-ignore-command ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-ignore-command (command)
+ "Set COMMAND to be ignored, for Flyspell.
+When flyspell `post-command-hook' is invoked because of an
+ignored command having been used, the changes in the text made by
+that command are ignored. This feature is meant for commands that
+change text in a way that does not affect individual words, such
+as `fill-paragraph'."
+ (interactive "SMake Flyspell ignore changes made by Command: ")
+ (put command 'flyspell-ignored t))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-word-cache ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-word-cache-start nil)
+(defvar flyspell-word-cache-end nil)
+(defvar flyspell-word-cache-word nil)
+(defvar flyspell-word-cache-result '_)
+(make-variable-buffer-local 'flyspell-word-cache-start)
+(make-variable-buffer-local 'flyspell-word-cache-end)
+(make-variable-buffer-local 'flyspell-word-cache-word)
+(make-variable-buffer-local 'flyspell-word-cache-result)
+
+;*---------------------------------------------------------------------*/
+;* The flyspell pre-hook, store the current position. In the */
+;* post command hook, we will check, if the word at this position */
+;* has to be spell checked. */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-pre-buffer nil)
+(defvar flyspell-pre-point nil)
+(defvar flyspell-pre-column nil)
+(defvar flyspell-pre-pre-buffer nil)
+(defvar flyspell-pre-pre-point nil)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-previous-command ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-previous-command nil
+ "The last interactive command checked by Flyspell.")
+
+;*---------------------------------------------------------------------*/
+;* flyspell-pre-command-hook ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-pre-command-hook ()
+ "Save the current buffer and point for Flyspell's post-command hook."
+ (interactive)
+ (setq flyspell-pre-buffer (current-buffer))
+ (setq flyspell-pre-point (point))
+ (setq flyspell-pre-column (current-column)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-mode-off ... */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-mode-off ()
+ "Turn Flyspell mode off."
+ ;; we remove the hooks
+ (remove-hook 'post-command-hook (function flyspell-post-command-hook) t)
+ (remove-hook 'pre-command-hook (function flyspell-pre-command-hook) t)
+ (setq after-change-functions (delq 'flyspell-after-change-function
+ after-change-functions))
+ ;; we remove all the flyspell hilightings
+ (flyspell-delete-all-overlays)
+ ;; we have to erase pre cache variables
+ (setq flyspell-pre-buffer nil)
+ (setq flyspell-pre-point nil)
+ ;; we mark the mode as killed
+ (setq flyspell-mode nil))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-check-pre-word-p ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-pre-word-p ()
+ "Return non-nil if we should check the word before point.
+More precisely, it applies to the word that was before point
+before the current command."
+ (cond
+ ((or (not (numberp flyspell-pre-point))
+ (not (bufferp flyspell-pre-buffer))
+ (not (buffer-live-p flyspell-pre-buffer)))
+ nil)
+ ((and (eq flyspell-pre-pre-point flyspell-pre-point)
+ (eq flyspell-pre-pre-buffer flyspell-pre-buffer))
+ nil)
+ ((or (and (= flyspell-pre-point (- (point) 1))
+ (eq (char-syntax (char-after flyspell-pre-point)) ?w))
+ (= flyspell-pre-point (point))
+ (= flyspell-pre-point (+ (point) 1)))
+ nil)
+ ((and (symbolp this-command)
+ (not executing-kbd-macro)
+ (or (get this-command 'flyspell-delayed)
+ (and (get this-command 'flyspell-deplacement)
+ (eq flyspell-previous-command this-command)))
+ (or (= (current-column) 0)
+ (= (current-column) flyspell-pre-column)
+ (eq (char-syntax (char-after flyspell-pre-point)) ?w)))
+ nil)
+ ((not (eq (current-buffer) flyspell-pre-buffer))
+ t)
+ ((not (and (numberp flyspell-word-cache-start)
+ (numberp flyspell-word-cache-end)))
+ t)
+ (t
+ (or (< flyspell-pre-point flyspell-word-cache-start)
+ (> flyspell-pre-point flyspell-word-cache-end)))))
+
+;*---------------------------------------------------------------------*/
+;* The flyspell after-change-hook, store the change position. In */
+;* the post command hook, we will check, if the word at this */
+;* position has to be spell checked. */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-changes nil)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-after-change-function ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-after-change-function (start stop len)
+ "Save the current buffer and point for Flyspell's post-command hook."
+ (interactive)
+ (unless (and (symbolp this-command) (get this-command 'flyspell-ignored))
+ (setq flyspell-changes (cons (cons start stop) flyspell-changes))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-check-changed-word-p ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-changed-word-p (start stop)
+ "Return t when the changed word has to be checked.
+The answer depends of several criteria.
+Mostly we check word delimiters."
+ (cond
+ ((and (memq (char-after start) '(?\n ? )) (> stop start))
+ t)
+ ((not (numberp flyspell-pre-point))
+ t)
+ ((and (>= flyspell-pre-point start) (<= flyspell-pre-point stop))
+ nil)
+ ((let ((pos (point)))
+ (or (>= pos start) (<= pos stop) (= pos (1+ stop))))
+ nil)
+ (t
+ t)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-check-word-p ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-word-p ()
+ "Return t when the word at `point' has to be checked.
+The answer depends of several criteria.
+Mostly we check word delimiters."
+ (cond
+ ((<= (- (point-max) 1) (point-min))
+ ;; the buffer is not filled enough
+ nil)
+ ((and (and (> (current-column) 0)
+ (not (eq (current-column) flyspell-pre-column)))
+ (save-excursion
+ (backward-char 1)
+ (and (looking-at (flyspell-get-not-casechars))
+ (or flyspell-consider-dash-as-word-delimiter-flag
+ (not (looking-at "\\-"))))))
+ ;; yes because we have reached or typed a word delimiter.
+ t)
+ ((symbolp this-command)
+ (cond
+ ((get this-command 'flyspell-deplacement)
+ (not (eq flyspell-previous-command this-command)))
+ ((get this-command 'flyspell-delayed)
+ ;; the current command is not delayed, that
+ ;; is that we must check the word now
+ (if (or (fboundp 'about-xemacs) (featurep 'xemacs))
+ (sit-for flyspell-delay nil)
+ (sit-for flyspell-delay 0 nil)))
+ (t t)))
+ (t t)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-debug-signal-no-check ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-no-check (msg obj)
+ (setq debug-on-error t)
+ (save-excursion
+ (let ((buffer (get-buffer-create "*flyspell-debug*")))
+ (set-buffer buffer)
+ (erase-buffer)
+ (insert "NO-CHECK:\n")
+ (insert (format " %S : %S\n" msg obj)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-debug-signal-pre-word-checked ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-pre-word-checked ()
+ (setq debug-on-error t)
+ (save-excursion
+ (let ((buffer (get-buffer-create "*flyspell-debug*")))
+ (set-buffer buffer)
+ (insert "PRE-WORD:\n")
+ (insert (format " pre-point : %S\n" flyspell-pre-point))
+ (insert (format " pre-buffer : %S\n" flyspell-pre-buffer))
+ (insert (format " cache-start: %S\n" flyspell-word-cache-start))
+ (insert (format " cache-end : %S\n" flyspell-word-cache-end))
+ (goto-char (point-max)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-debug-signal-word-checked ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-word-checked ()
+ (setq debug-on-error t)
+ (save-excursion
+ (let ((oldbuf (current-buffer))
+ (buffer (get-buffer-create "*flyspell-debug*"))
+ (point (point)))
+ (set-buffer buffer)
+ (insert "WORD:\n")
+ (insert (format " this-cmd : %S\n" this-command))
+ (insert (format " delayed : %S\n" (and (symbolp this-command)
+ (get this-command 'flyspell-delayed))))
+ (insert (format " ignored : %S\n" (and (symbolp this-command)
+ (get this-command 'flyspell-ignored))))
+ (insert (format " point : %S\n" point))
+ (insert (format " prev-char : [%c] %S\n"
+ (progn
+ (set-buffer oldbuf)
+ (let ((c (if (> (point) (point-min))
+ (save-excursion
+ (backward-char 1)
+ (char-after (point)))
+ ? )))
+ (set-buffer buffer)
+ c))
+ (progn
+ (set-buffer oldbuf)
+ (let ((c (if (> (point) (point-min))
+ (save-excursion
+ (backward-char 1)
+ (and (and (looking-at (flyspell-get-not-casechars)) 1)
+ (and (or flyspell-consider-dash-as-word-delimiter-flag
+ (not (looking-at "\\-"))) 2))))))
+ (set-buffer buffer)
+ c))))
+ (insert (format " because : %S\n"
+ (cond
+ ((not (and (symbolp this-command)
+ (get this-command 'flyspell-delayed)))
+ ;; the current command is not delayed, that
+ ;; is that we must check the word now
+ 'not-delayed)
+ ((progn
+ (set-buffer oldbuf)
+ (let ((c (if (> (point) (point-min))
+ (save-excursion
+ (backward-char 1)
+ (and (looking-at (flyspell-get-not-casechars))
+ (or flyspell-consider-dash-as-word-delimiter-flag
+ (not (looking-at "\\-"))))))))
+ (set-buffer buffer)
+ c))
+ ;; yes because we have reached or typed a word delimiter.
+ 'separator)
+ ((not (integerp flyspell-delay))
+ ;; yes because the user had set up a no-delay configuration.
+ 'no-delay)
+ (t
+ 'sit-for))))
+ (goto-char (point-max)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-debug-signal-changed-checked ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-debug-signal-changed-checked ()
+ (setq debug-on-error t)
+ (save-excursion
+ (let ((buffer (get-buffer-create "*flyspell-debug*"))
+ (point (point)))
+ (set-buffer buffer)
+ (insert "CHANGED WORD:\n")
+ (insert (format " point : %S\n" point))
+ (goto-char (point-max)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-post-command-hook ... */
+;* ------------------------------------------------------------- */
+;* It is possible that we check several words: */
+;* 1- the current word is checked if the predicate */
+;* FLYSPELL-CHECK-WORD-P is true */
+;* 2- the word that used to be the current word before the */
+;* THIS-COMMAND is checked if: */
+;* a- the previous word is different from the current word */
+;* b- the previous word as not just been checked by the */
+;* previous FLYSPELL-POST-COMMAND-HOOK */
+;* 3- the words changed by the THIS-COMMAND that are neither the */
+;* previous word nor the current word */
+;*---------------------------------------------------------------------*/
+(defun flyspell-post-command-hook ()
+ "The `post-command-hook' used by flyspell to check a word on-the-fly."
+ (interactive)
+ (when flyspell-mode
+ (with-local-quit
+ (let ((command this-command))
+ (if (flyspell-check-pre-word-p)
+ (save-excursion
+ '(flyspell-debug-signal-pre-word-checked)
+ (set-buffer flyspell-pre-buffer)
+ (save-excursion
+ (goto-char flyspell-pre-point)
+ (flyspell-word))))
+ (if (flyspell-check-word-p)
+ (progn
+ '(flyspell-debug-signal-word-checked)
+ (flyspell-word)
+ ;; we remember which word we have just checked.
+ ;; this will be used next time we will check a word
+ ;; to compare the next current word with the word
+ ;; that as been registered in the pre-command-hook
+ ;; that is these variables are used within the predicate
+ ;; FLYSPELL-CHECK-PRE-WORD-P
+ (setq flyspell-pre-pre-buffer (current-buffer))
+ (setq flyspell-pre-pre-point (point)))
+ (progn
+ (setq flyspell-pre-pre-buffer nil)
+ (setq flyspell-pre-pre-point nil)
+ ;; when a word is not checked because of a delayed command
+ ;; we do not disable the ispell cache.
+ (if (and (symbolp this-command) (get this-command 'flyspell-delayed))
+ (progn
+ (setq flyspell-word-cache-end -1)
+ (setq flyspell-word-cache-result '_)))))
+ (while (consp flyspell-changes)
+ (let ((start (car (car flyspell-changes)))
+ (stop (cdr (car flyspell-changes))))
+ (if (flyspell-check-changed-word-p start stop)
+ (save-excursion
+ '(flyspell-debug-signal-changed-checked)
+ (goto-char start)
+ (flyspell-word)))
+ (setq flyspell-changes (cdr flyspell-changes))))
+ (setq flyspell-previous-command command)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-notify-misspell ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-notify-misspell (start end word poss)
+ (let ((replacements (if (stringp poss)
+ poss
+ (if flyspell-sort-corrections
+ (sort (car (cdr (cdr poss))) 'string<)
+ (car (cdr (cdr poss)))))))
+ (if flyspell-issue-message-flag
+ (message (format "mispelling `%s' %S" word replacements)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-word-search-backward ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-word-search-backward (word bound)
+ (save-excursion
+ (let ((r '())
+ p)
+ (while (and (not r) (setq p (search-backward word bound t)))
+ (let ((lw (flyspell-get-word '())))
+ (if (and (consp lw) (string-equal (car lw) word))
+ (setq r p)
+ (goto-char p))))
+ r)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-word-search-forward ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-word-search-forward (word bound)
+ (save-excursion
+ (let ((r '())
+ p)
+ (while (and (not r) (setq p (search-forward word bound t)))
+ (let ((lw (flyspell-get-word '())))
+ (if (and (consp lw) (string-equal (car lw) word))
+ (setq r p)
+ (goto-char (1+ p)))))
+ r)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-word ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-word (&optional following)
+ "Spell check a word."
+ (interactive (list current-prefix-arg))
+ (if (interactive-p)
+ (setq following ispell-following-word))
+ (save-excursion
+ ;; use the correct dictionary
+ (flyspell-accept-buffer-local-defs)
+ (let* ((cursor-location (point))
+ (flyspell-word (flyspell-get-word following))
+ start end poss word)
+ (if (or (eq flyspell-word nil)
+ (and (fboundp flyspell-generic-check-word-p)
+ (not (funcall flyspell-generic-check-word-p))))
+ t
+ (progn
+ ;; destructure return flyspell-word info list.
+ (setq start (car (cdr flyspell-word))
+ end (car (cdr (cdr flyspell-word)))
+ word (car flyspell-word))
+ ;; before checking in the directory, we check for doublons.
+ (cond
+ ((and (or (not (eq ispell-parser 'tex))
+ (and (> start (point-min))
+ (not (eq (char-after (1- start)) ?}))
+ (not (eq (char-after (1- start)) ?\\))))
+ flyspell-mark-duplications-flag
+ (save-excursion
+ (goto-char (1- start))
+ (let ((p (flyspell-word-search-backward
+ word
+ (- start (1+ (- end start))))))
+ (and p (/= p (1- start))))))
+ ;; yes, this is a doublon
+ (flyspell-highlight-incorrect-region start end 'doublon)
+ nil)
+ ((and (eq flyspell-word-cache-start start)
+ (eq flyspell-word-cache-end end)
+ (string-equal flyspell-word-cache-word word))
+ ;; this word had been already checked, we skip
+ flyspell-word-cache-result)
+ ((and (eq ispell-parser 'tex)
+ (flyspell-tex-command-p flyspell-word))
+ ;; this is a correct word (because a tex command)
+ (flyspell-unhighlight-at start)
+ (if (> end start)
+ (flyspell-unhighlight-at (- end 1)))
+ t)
+ (t
+ ;; we setup the cache
+ (setq flyspell-word-cache-start start)
+ (setq flyspell-word-cache-end end)
+ (setq flyspell-word-cache-word word)
+ ;; now check spelling of word.
+ (process-send-string ispell-process "%\n")
+ ;; put in verbose mode
+ (process-send-string ispell-process
+ (concat "^" word "\n"))
+ ;; we mark the ispell process so it can be killed
+ ;; when emacs is exited without query
+ (if (fboundp 'process-kill-without-query)
+ (process-kill-without-query ispell-process))
+ ;; wait until ispell has processed word
+ (while (progn
+ (accept-process-output ispell-process)
+ (not (string= "" (car ispell-filter)))))
+ ;; (process-send-string ispell-process "!\n")
+ ;; back to terse mode.
+ (setq ispell-filter (cdr ispell-filter))
+ (if (consp ispell-filter)
+ (setq poss (ispell-parse-output (car ispell-filter))))
+ (let ((res (cond ((eq poss t)
+ ;; correct
+ (setq flyspell-word-cache-result t)
+ (flyspell-unhighlight-at start)
+ (if (> end start)
+ (flyspell-unhighlight-at (- end 1)))
+ t)
+ ((and (stringp poss) flyspell-highlight-flag)
+ ;; correct
+ (setq flyspell-word-cache-result t)
+ (flyspell-unhighlight-at start)
+ (if (> end start)
+ (flyspell-unhighlight-at (- end 1)))
+ t)
+ ((null poss)
+ (setq flyspell-word-cache-result t)
+ (flyspell-unhighlight-at start)
+ (if (> end start)
+ (flyspell-unhighlight-at (- end 1)))
+ t)
+ ((or (and (< flyspell-duplicate-distance 0)
+ (or (save-excursion
+ (goto-char start)
+ (flyspell-word-search-backward
+ word
+ (point-min)))
+ (save-excursion
+ (goto-char end)
+ (flyspell-word-search-forward
+ word
+ (point-max)))))
+ (and (> flyspell-duplicate-distance 0)
+ (or (save-excursion
+ (goto-char start)
+ (flyspell-word-search-backward
+ word
+ (- start
+ flyspell-duplicate-distance)))
+ (save-excursion
+ (goto-char end)
+ (flyspell-word-search-forward
+ word
+ (+ end
+ flyspell-duplicate-distance))))))
+ (setq flyspell-word-cache-result nil)
+ (if flyspell-highlight-flag
+ (flyspell-highlight-duplicate-region
+ start end)
+ (message (format "duplicate `%s'" word)))
+ nil)
+ (t
+ (setq flyspell-word-cache-result nil)
+ ;; incorrect highlight the location
+ (if flyspell-highlight-flag
+ (flyspell-highlight-incorrect-region
+ start end poss)
+ (flyspell-notify-misspell start end word poss))
+ nil))))
+ ;; return to original location
+ (goto-char cursor-location)
+ (if ispell-quit (setq ispell-quit nil))
+ res))))))))
+
+;* {*---------------------------------------------------------------------*} */
+;* {* flyspell-tex-math-initialized ... *} */
+;* {*---------------------------------------------------------------------*} */
+;* (defvar flyspell-tex-math-initialized nil) */
+;* */
+;* {*---------------------------------------------------------------------*} */
+;* {* flyspell-math-tex-command-p ... *} */
+;* {* ------------------------------------------------------------- *} */
+;* {* This function uses the texmathp package to check if (point) *} */
+;* {* is within a tex command. In order to avoid using *} */
+;* {* condition-case each time we use the variable *} */
+;* {* flyspell-tex-math-initialized to make a special case the first *} */
+;* {* time that function is called. *} */
+;* {*---------------------------------------------------------------------*} */
+;* (defun flyspell-math-tex-command-p () */
+;* (cond */
+;* (flyspell-check-tex-math-command */
+;* nil) */
+;* ((eq flyspell-tex-math-initialized t) */
+;* (texmathp)) */
+;* ((eq flyspell-tex-math-initialized 'error) */
+;* nil) */
+;* (t */
+;* (setq flyspell-tex-math-initialized t) */
+;* (condition-case nil */
+;* (texmathp) */
+;* (error (progn */
+;* (setq flyspell-tex-math-initialized 'error) */
+;* nil)))))) */
+
+;*---------------------------------------------------------------------*/
+;* flyspell-math-tex-command-p ... */
+;* ------------------------------------------------------------- */
+;* This function uses the texmathp package to check if point */
+;* is within a TeX math environment. `texmathp' can yield errors */
+;* if the document is currently not valid TeX syntax. */
+;*---------------------------------------------------------------------*/
+(defun flyspell-math-tex-command-p ()
+ (when (fboundp 'texmathp)
+ (if flyspell-check-tex-math-command
+ nil
+ (condition-case nil
+ (texmathp)
+ (error nil)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-tex-command-p ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-tex-command-p (word)
+ "Return t if WORD is a TeX command."
+ (or (save-excursion
+ (let ((b (car (cdr word))))
+ (and (re-search-backward "\\\\" (- (point) 100) t)
+ (or (= (match-end 0) b)
+ (and (goto-char (match-end 0))
+ (looking-at flyspell-tex-command-regexp)
+ (>= (match-end 0) b))))))
+ (flyspell-math-tex-command-p)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-casechars-cache ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-casechars-cache nil)
+(defvar flyspell-ispell-casechars-cache nil)
+(make-variable-buffer-local 'flyspell-casechars-cache)
+(make-variable-buffer-local 'flyspell-ispell-casechars-cache)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-get-casechars ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-get-casechars ()
+ "This function builds a string that is the regexp of word chars.
+In order to avoid one useless string construction,
+this function changes the last char of the `ispell-casechars' string."
+ (let ((ispell-casechars (ispell-get-casechars)))
+ (cond
+ ((eq ispell-parser 'tex)
+ (setq flyspell-ispell-casechars-cache ispell-casechars)
+ (setq flyspell-casechars-cache
+ (concat (substring ispell-casechars
+ 0
+ (- (length ispell-casechars) 1))
+ "]"))
+ flyspell-casechars-cache)
+ (t
+ (setq flyspell-ispell-casechars-cache ispell-casechars)
+ (setq flyspell-casechars-cache ispell-casechars)
+ flyspell-casechars-cache))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-get-not-casechars-cache ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-not-casechars-cache nil)
+(defvar flyspell-ispell-not-casechars-cache nil)
+(make-variable-buffer-local 'flyspell-not-casechars-cache)
+(make-variable-buffer-local 'flyspell-ispell-not-casechars-cache)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-get-not-casechars ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-get-not-casechars ()
+ "This function builds a string that is the regexp of non-word chars."
+ (let ((ispell-not-casechars (ispell-get-not-casechars)))
+ (cond
+ ((eq ispell-parser 'tex)
+ (setq flyspell-ispell-not-casechars-cache ispell-not-casechars)
+ (setq flyspell-not-casechars-cache
+ (concat (substring ispell-not-casechars
+ 0
+ (- (length ispell-not-casechars) 1))
+ "]"))
+ flyspell-not-casechars-cache)
+ (t
+ (setq flyspell-ispell-not-casechars-cache ispell-not-casechars)
+ (setq flyspell-not-casechars-cache ispell-not-casechars)
+ flyspell-not-casechars-cache))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-get-word ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-get-word (following &optional extra-otherchars)
+ "Return the word for spell-checking according to Ispell syntax.
+If optional argument FOLLOWING is non-nil or if `flyspell-following-word'
+is non-nil when called interactively, then the following word
+\(rather than preceding\) is checked when the cursor is not over a word.
+Optional second argument contains otherchars that can be included in word
+many times.
+
+Word syntax described by `flyspell-dictionary-alist' (which see)."
+ (let* ((flyspell-casechars (flyspell-get-casechars))
+ (flyspell-not-casechars (flyspell-get-not-casechars))
+ (ispell-otherchars (ispell-get-otherchars))
+ (ispell-many-otherchars-p (ispell-get-many-otherchars-p))
+ (word-regexp (concat flyspell-casechars
+ "+\\("
+ (if (not (string= "" ispell-otherchars))
+ (concat ispell-otherchars "?"))
+ (if extra-otherchars
+ (concat extra-otherchars "?"))
+ flyspell-casechars
+ "+\\)"
+ (if (or ispell-many-otherchars-p
+ extra-otherchars)
+ "*" "?")))
+ did-it-once prevpt
+ start end word)
+ ;; find the word
+ (if (not (looking-at flyspell-casechars))
+ (if following
+ (re-search-forward flyspell-casechars (point-max) t)
+ (re-search-backward flyspell-casechars (point-min) t)))
+ ;; move to front of word
+ (re-search-backward flyspell-not-casechars (point-min) 'start)
+ (while (and (or (and (not (string= "" ispell-otherchars))
+ (looking-at ispell-otherchars))
+ (and extra-otherchars (looking-at extra-otherchars)))
+ (not (bobp))
+ (or (not did-it-once)
+ ispell-many-otherchars-p)
+ (not (eq prevpt (point))))
+ (if (and extra-otherchars (looking-at extra-otherchars))
+ (progn
+ (backward-char 1)
+ (if (looking-at flyspell-casechars)
+ (re-search-backward flyspell-not-casechars (point-min) 'move)))
+ (setq did-it-once t
+ prevpt (point))
+ (backward-char 1)
+ (if (looking-at flyspell-casechars)
+ (re-search-backward flyspell-not-casechars (point-min) 'move)
+ (backward-char -1))))
+ ;; Now mark the word and save to string.
+ (if (not (re-search-forward word-regexp (point-max) t))
+ nil
+ (progn
+ (setq start (match-beginning 0)
+ end (point)
+ word (buffer-substring-no-properties start end))
+ (list word start end)))))
+
+(defun flyspell-get-word.old (following)
+ "Return the word for spell-checking according to Ispell syntax.
+If argument FOLLOWING is non-nil or if `ispell-following-word'
+is non-nil when called interactively, then the following word
+\(rather than preceding\) is checked when the cursor is not over a word.
+Optional second argument contains other chars that can be included in word
+many times.
+
+Word syntax described by `ispell-dictionary-alist' (which see)."
+ (let* ((flyspell-casechars (flyspell-get-casechars))
+ (flyspell-not-casechars (flyspell-get-not-casechars))
+ (ispell-otherchars (ispell-get-otherchars))
+ (ispell-many-otherchars-p (ispell-get-many-otherchars-p))
+ (word-regexp (if (string< "" ispell-otherchars)
+ (concat flyspell-casechars
+ "+\\("
+ ispell-otherchars
+ (if (> (length ispell-otherchars) 0) "?")
+ flyspell-casechars
+ "+\\)"
+ (if ispell-many-otherchars-p
+ "*" "?"))
+ (concat flyspell-casechars "+")))
+ did-it-once
+ start end word)
+ ;; find the word
+ (if (not (looking-at flyspell-casechars))
+ (if following
+ (re-search-forward flyspell-casechars (point-max) t)
+ (re-search-backward flyspell-casechars (point-min) t)))
+ ;; move to front of word
+ (re-search-backward flyspell-not-casechars (point-min) 'start)
+ (let ((pos nil))
+ (if (string< "" ispell-otherchars)
+ (while (and (looking-at ispell-otherchars)
+ (not (bobp))
+ (or (not did-it-once)
+ ispell-many-otherchars-p)
+ (not (eq pos (point))))
+ (setq pos (point))
+ (setq did-it-once t)
+ (backward-char 1)
+ (if (looking-at flyspell-casechars)
+ (re-search-backward flyspell-not-casechars (point-min) 'move)
+ (backward-char -1)))))
+ ;; Now mark the word and save to string.
+ (if (eq (re-search-forward word-regexp (point-max) t) nil)
+ nil
+ (progn
+ (setq start (match-beginning 0)
+ end (point)
+ word (buffer-substring-no-properties start end))
+ (list word start end)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-small-region ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-small-region (beg end)
+ "Flyspell text between BEG and END."
+ (save-excursion
+ (if (> beg end)
+ (let ((old beg))
+ (setq beg end)
+ (setq end old)))
+ (goto-char beg)
+ (let ((count 0))
+ (while (< (point) end)
+ (if (and flyspell-issue-message-flag (= count 100))
+ (progn
+ (message "Spell Checking...%d%%"
+ (* 100 (/ (float (- (point) beg)) (- end beg))))
+ (setq count 0))
+ (setq count (+ 1 count)))
+ (flyspell-word)
+ (sit-for 0)
+ (let ((cur (point)))
+ (forward-word 1)
+ (if (and (< (point) end) (> (point) (+ cur 1)))
+ (backward-char 1)))))
+ (backward-char 1)
+ (if flyspell-issue-message-flag (message "Spell Checking completed."))
+ (flyspell-word)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-external-ispell-process ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-external-ispell-process '()
+ "The external Flyspell Ispell process.")
+
+;*---------------------------------------------------------------------*/
+;* flyspell-external-ispell-buffer ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-external-ispell-buffer '())
+(defvar flyspell-large-region-buffer '())
+(defvar flyspell-large-region-beg (point-min))
+(defvar flyspell-large-region-end (point-max))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-external-point-words ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-external-point-words ()
+ (let ((buffer flyspell-external-ispell-buffer))
+ (set-buffer buffer)
+ (beginning-of-buffer)
+ (let ((size (- flyspell-large-region-end flyspell-large-region-beg))
+ (start flyspell-large-region-beg)
+ (pword "")
+ (pcount 1))
+ ;; now we are done with ispell, we have to find the word in
+ ;; the initial buffer
+ (while (< (point) (- (point-max) 1))
+ ;; we have to fetch the incorrect word
+ (if (re-search-forward "\\([^\n]+\\)\n" (point-max) t)
+ (let ((word (match-string 1)))
+ (if (string= word pword)
+ (setq pcount (1+ pcount))
+ (progn
+ (setq pword word)
+ (setq pcount 1)))
+ (goto-char (match-end 0))
+ (if flyspell-issue-message-flag
+ (message "Spell Checking...%d%% [%s]"
+ (* 100 (/ (float (point)) (point-max)))
+ word))
+ (set-buffer flyspell-large-region-buffer)
+ (goto-char flyspell-large-region-beg)
+ (let ((keep t)
+ (n 0))
+ (while (and (or (< n pcount) keep)
+ (search-forward word flyspell-large-region-end t))
+ (progn
+ (goto-char (- (point) 1))
+ (setq n (1+ n))
+ (setq keep (flyspell-word))))
+ (if (= n pcount)
+ (setq flyspell-large-region-beg (point))))
+ (set-buffer buffer))
+ (goto-char (point-max)))))
+ ;; we are done
+ (if flyspell-issue-message-flag (message "Spell Checking completed."))
+ ;; ok, we are done with pointing out incorrect words, we just
+ ;; have to kill the temporary buffer
+ (kill-buffer flyspell-external-ispell-buffer)
+ (setq flyspell-external-ispell-buffer nil)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-process-localwords ... */
+;* ------------------------------------------------------------- */
+;* This function is used to prevent checking words declared */
+;* explictitly correct on large regions. */
+;*---------------------------------------------------------------------*/
+(defun flyspell-process-localwords ()
+ "Parse Localwords in the buffer and remove them from the mispellings
+buffer before flyspell attempts to check them."
+ (let (localwords
+ (current-buffer curbuf)
+ (mispellings-buffer buffer)
+ (ispell-casechars (ispell-get-casechars)))
+ ;; Get localwords from the original buffer
+ (save-excursion
+ (set-buffer current-buffer)
+;* (flyspell-delete-all-overlays) */
+ (beginning-of-buffer)
+ ;; Localwords parsing stolen form ispell.el
+ (while (search-forward ispell-words-keyword nil t)
+ (let ((end (save-excursion (end-of-line) (point)))
+ string)
+ ;; buffer-local words separated by a space, and can contain
+ ;; any character other than a space. Not rigorous enough.
+ (while (re-search-forward " *\\([^ ]+\\)" end t)
+ (setq string (buffer-substring-no-properties (match-beginning 1)
+ (match-end 1)))
+ ;; This can fail when string contains a word with illegal chars.
+ ;; Error handling needs to be added between ispell and emacs.
+ (if (and (< 1 (length string))
+ (equal 0 (string-match ispell-casechars string)))
+ (setq localwords (add-to-list 'localwords string)))))))
+ ;; Remove localwords matches
+ (set-buffer mispellings-buffer)
+ (while localwords
+ (beginning-of-buffer)
+ (delete-matching-lines (concat "^" (car localwords) "$"))
+ (setq localwords (cdr localwords)))
+ (end-of-buffer)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-large-region ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-large-region (beg end)
+ (let* ((curbuf (current-buffer))
+ (buffer (get-buffer-create "*flyspell-region*")))
+ (setq flyspell-external-ispell-buffer buffer)
+ (setq flyspell-large-region-buffer curbuf)
+ (setq flyspell-large-region-beg beg)
+ (setq flyspell-large-region-end end)
+ (set-buffer buffer)
+ (erase-buffer)
+ ;; this is done, we can start checking...
+ (if flyspell-issue-message-flag (message "Checking region..."))
+ (set-buffer curbuf)
+ (let ((c (apply 'call-process-region beg
+ end
+ ispell-program-name
+ nil
+ buffer
+ nil
+ (if (boundp 'ispell-list-command)
+ ispell-list-command
+ "-l")
+ (let (args)
+ ;; Local dictionary becomes the global dictionary in use.
+ (if ispell-local-dictionary
+ (setq ispell-dictionary ispell-local-dictionary))
+ (setq args (ispell-get-ispell-args))
+ (if ispell-dictionary ; use specified dictionary
+ (setq args
+ (append (list "-d" ispell-dictionary) args)))
+ (if ispell-personal-dictionary ; use specified pers dict
+ (setq args
+ (append args
+ (list "-p"
+ (expand-file-name
+ ispell-personal-dictionary)))))
+ (setq args (append args ispell-extra-args))
+ args))))
+ (if (= c 0)
+ (progn
+ (flyspell-process-localwords)
+ (with-current-buffer curbuf
+ (flyspell-delete-region-overlays beg end))
+ (flyspell-external-point-words))
+ (error "Can't check region...")))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-region ... */
+;* ------------------------------------------------------------- */
+;* Because `ispell -a' is too slow, it is not possible to use */
+;* it on large region. Then, when ispell is invoked on a large */
+;* text region, a new `ispell -l' process is spawned. The */
+;* pointed out words are then searched in the region a checked with */
+;* regular flyspell means. */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-region (beg end)
+ "Flyspell text between BEG and END."
+ (interactive "r")
+ (if (= beg end)
+ ()
+ (save-excursion
+ (if (> beg end)
+ (let ((old beg))
+ (setq beg end)
+ (setq end old)))
+ (if (and flyspell-large-region (> (- end beg) flyspell-large-region))
+ (flyspell-large-region beg end)
+ (flyspell-small-region beg end)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-buffer ... */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun flyspell-buffer ()
+ "Flyspell whole buffer."
+ (interactive)
+ (flyspell-region (point-min) (point-max)))
+
+;*---------------------------------------------------------------------*/
+;* old next error position ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-old-buffer-error nil)
+(defvar flyspell-old-pos-error nil)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-goto-next-error ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-goto-next-error ()
+ "Go to the next previously detected error.
+In general FLYSPELL-GOTO-NEXT-ERROR must be used after
+FLYSPELL-BUFFER."
+ (interactive)
+ (let ((pos (point))
+ (max (point-max)))
+ (if (and (eq (current-buffer) flyspell-old-buffer-error)
+ (eq pos flyspell-old-pos-error))
+ (progn
+ (if (= flyspell-old-pos-error max)
+ ;; goto beginning of buffer
+ (progn
+ (message "Restarting from beginning of buffer")
+ (goto-char (point-min)))
+ (forward-word 1))
+ (setq pos (point))))
+ ;; seek the next error
+ (while (and (< pos max)
+ (let ((ovs (overlays-at pos))
+ (r '()))
+ (while (and (not r) (consp ovs))
+ (if (flyspell-overlay-p (car ovs))
+ (setq r t)
+ (setq ovs (cdr ovs))))
+ (not r)))
+ (setq pos (1+ pos)))
+ ;; save the current location for next invocation
+ (setq flyspell-old-pos-error pos)
+ (setq flyspell-old-buffer-error (current-buffer))
+ (goto-char pos)
+ (if (= pos max)
+ (message "No more miss-spelled word!"))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-overlay-p ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-overlay-p (o)
+ "A predicate that return true iff O is an overlay used by flyspell."
+ (and (overlayp o) (overlay-get o 'flyspell-overlay)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-delete-region-overlays ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delete-region-overlays (beg end)
+ "Delete overlays used by flyspell in a given region."
+ (let ((l (overlays-in beg end)))
+ (while (consp l)
+ (progn
+ (if (flyspell-overlay-p (car l))
+ (delete-overlay (car l)))
+ (setq l (cdr l))))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-delete-all-overlays ... */
+;* ------------------------------------------------------------- */
+;* Remove all the overlays introduced by flyspell. */
+;*---------------------------------------------------------------------*/
+(defun flyspell-delete-all-overlays ()
+ "Delete all the overlays used by flyspell."
+ (flyspell-delete-region-overlays (point-min) (point-max)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-unhighlight-at ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-unhighlight-at (pos)
+ "Remove the flyspell overlay that are located at POS."
+ (if flyspell-persistent-highlight
+ (let ((overlays (overlays-at pos)))
+ (while (consp overlays)
+ (if (flyspell-overlay-p (car overlays))
+ (delete-overlay (car overlays)))
+ (setq overlays (cdr overlays))))
+ (if (flyspell-overlay-p flyspell-overlay)
+ (delete-overlay flyspell-overlay))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-properties-at-p ... */
+;* ------------------------------------------------------------- */
+;* Is there an highlight properties at position pos? */
+;*---------------------------------------------------------------------*/
+(defun flyspell-properties-at-p (pos)
+ "Return t if there is a text property at POS, not counting `local-map'.
+If variable `flyspell-highlight-properties' is set to nil,
+text with properties are not checked. This function is used to discover
+if the character at POS has any other property."
+ (let ((prop (text-properties-at pos))
+ (keep t))
+ (while (and keep (consp prop))
+ (if (and (eq (car prop) 'local-map) (consp (cdr prop)))
+ (setq prop (cdr (cdr prop)))
+ (setq keep nil)))
+ (consp prop)))
+
+;*---------------------------------------------------------------------*/
+;* make-flyspell-overlay ... */
+;*---------------------------------------------------------------------*/
+(defun make-flyspell-overlay (beg end face mouse-face)
+ "Allocate an overlay to highlight an incorrect word.
+BEG and END specify the range in the buffer of that word.
+FACE and MOUSE-FACE specify the `face' and `mouse-face' properties
+for the overlay."
+ (let ((flyspell-overlay (make-overlay beg end nil t nil)))
+ (overlay-put flyspell-overlay 'face face)
+ (overlay-put flyspell-overlay 'mouse-face mouse-face)
+ (overlay-put flyspell-overlay 'flyspell-overlay t)
+ (overlay-put flyspell-overlay 'evaporate t)
+ (overlay-put flyspell-overlay 'help-echo "mouse-2: correct word at point")
+ (if flyspell-use-local-map
+ (overlay-put flyspell-overlay
+ flyspell-overlay-keymap-property-name
+ flyspell-mouse-map))
+ (when (eq face 'flyspell-incorrect-face)
+ (and (stringp flyspell-before-incorrect-word-string)
+ (overlay-put flyspell-overlay 'before-string
+ flyspell-before-incorrect-word-string))
+ (and (stringp flyspell-after-incorrect-word-string)
+ (overlay-put flyspell-overlay 'after-string
+ flyspell-after-incorrect-word-string)))
+ flyspell-overlay))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-highlight-incorrect-region ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-highlight-incorrect-region (beg end poss)
+ "Set up an overlay on a misspelled word, in the buffer from BEG to END."
+ (unless (run-hook-with-args-until-success
+ 'flyspell-incorrect-hook beg end poss)
+ (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg)))
+ (progn
+ ;; we cleanup all the overlay that are in the region, not
+ ;; beginning at the word start position
+ (if (< (1+ beg) end)
+ (let ((os (overlays-in (1+ beg) end)))
+ (while (consp os)
+ (if (flyspell-overlay-p (car os))
+ (delete-overlay (car os)))
+ (setq os (cdr os)))))
+ ;; we cleanup current overlay at the same position
+ (if (and (not flyspell-persistent-highlight)
+ (overlayp flyspell-overlay))
+ (delete-overlay flyspell-overlay)
+ (let ((os (overlays-at beg)))
+ (while (consp os)
+ (if (flyspell-overlay-p (car os))
+ (delete-overlay (car os)))
+ (setq os (cdr os)))))
+ ;; now we can use a new overlay
+ (setq flyspell-overlay
+ (make-flyspell-overlay beg end
+ 'flyspell-incorrect-face
+ 'highlight))))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-highlight-duplicate-region ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-highlight-duplicate-region (beg end)
+ "Set up an overlay on a duplicated word, in the buffer from BEG to END."
+ (if (or flyspell-highlight-properties (not (flyspell-properties-at-p beg)))
+ (progn
+ ;; we cleanup current overlay at the same position
+ (if (and (not flyspell-persistent-highlight)
+ (overlayp flyspell-overlay))
+ (delete-overlay flyspell-overlay)
+ (let ((overlays (overlays-at beg)))
+ (while (consp overlays)
+ (if (flyspell-overlay-p (car overlays))
+ (delete-overlay (car overlays)))
+ (setq overlays (cdr overlays)))))
+ ;; now we can use a new overlay
+ (setq flyspell-overlay
+ (make-flyspell-overlay beg end
+ 'flyspell-duplicate-face
+ 'highlight)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-auto-correct-cache ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-auto-correct-pos nil)
+(defvar flyspell-auto-correct-region nil)
+(defvar flyspell-auto-correct-ring nil)
+(defvar flyspell-auto-correct-word nil)
+(make-variable-buffer-local 'flyspell-auto-correct-pos)
+(make-variable-buffer-local 'flyspell-auto-correct-region)
+(make-variable-buffer-local 'flyspell-auto-correct-ring)
+(make-variable-buffer-local 'flyspell-auto-correct-word)
+
+;*---------------------------------------------------------------------*/
+;* flyspell-check-previous-highlighted-word ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-previous-highlighted-word (&optional arg)
+ "Correct the closer misspelled word.
+This function scans a mis-spelled word before the cursor. If it finds one
+it proposes replacement for that word. With prefix arg, count that many
+misspelled words backwards."
+ (interactive)
+ (let ((pos1 (point))
+ (pos (point))
+ (arg (if (or (not (numberp arg)) (< arg 1)) 1 arg))
+ ov ovs)
+ (if (catch 'exit
+ (while (and (setq pos (previous-overlay-change pos))
+ (not (= pos pos1)))
+ (setq pos1 pos)
+ (if (> pos (point-min))
+ (progn
+ (setq ovs (overlays-at (1- pos)))
+ (while (consp ovs)
+ (setq ov (car ovs))
+ (setq ovs (cdr ovs))
+ (if (and (overlay-get ov 'flyspell-overlay)
+ (= 0 (setq arg (1- arg))))
+ (throw 'exit t)))))))
+ (save-excursion
+ (goto-char pos)
+ (ispell-word))
+ (error "No word to correct before point"))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-display-next-corrections ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-display-next-corrections (corrections)
+ (let ((string "Corrections:")
+ (l corrections)
+ (pos '()))
+ (while (< (length string) 80)
+ (if (equal (car l) flyspell-auto-correct-word)
+ (setq pos (cons (+ 1 (length string)) pos)))
+ (setq string (concat string " " (car l)))
+ (setq l (cdr l)))
+ (while (consp pos)
+ (let ((num (car pos)))
+ (put-text-property num
+ (+ num (length flyspell-auto-correct-word))
+ 'face
+ 'flyspell-incorrect-face
+ string))
+ (setq pos (cdr pos)))
+ (if (fboundp 'display-message)
+ (display-message 'no-log string)
+ (message string))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-abbrev-table ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-abbrev-table ()
+ (if flyspell-use-global-abbrev-table-p
+ global-abbrev-table
+ local-abbrev-table))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-define-abbrev ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-define-abbrev (name expansion)
+ (let ((table (flyspell-abbrev-table)))
+ (when table
+ (define-abbrev table name expansion))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-auto-correct-word ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-auto-correct-word ()
+ "Correct the current word.
+This command proposes various successive corrections for the current word."
+ (interactive)
+ (let ((pos (point))
+ (old-max (point-max)))
+ ;; use the correct dictionary
+ (flyspell-accept-buffer-local-defs)
+ (if (and (eq flyspell-auto-correct-pos pos)
+ (consp flyspell-auto-correct-region))
+ ;; we have already been using the function at the same location
+ (let* ((start (car flyspell-auto-correct-region))
+ (len (cdr flyspell-auto-correct-region)))
+ (flyspell-unhighlight-at start)
+ (delete-region start (+ start len))
+ (setq flyspell-auto-correct-ring (cdr flyspell-auto-correct-ring))
+ (let* ((word (car flyspell-auto-correct-ring))
+ (len (length word)))
+ (rplacd flyspell-auto-correct-region len)
+ (goto-char start)
+ (if flyspell-abbrev-p
+ (if (flyspell-already-abbrevp (flyspell-abbrev-table)
+ flyspell-auto-correct-word)
+ (flyspell-change-abbrev (flyspell-abbrev-table)
+ flyspell-auto-correct-word
+ word)
+ (flyspell-define-abbrev flyspell-auto-correct-word word)))
+ (funcall flyspell-insert-function word)
+ (flyspell-word)
+ (flyspell-display-next-corrections flyspell-auto-correct-ring))
+ (flyspell-ajust-cursor-point pos (point) old-max)
+ (setq flyspell-auto-correct-pos (point)))
+ ;; fetch the word to be checked
+ (let ((word (flyspell-get-word nil)))
+ (setq flyspell-auto-correct-region nil)
+ (if (consp word)
+ (let ((start (car (cdr word)))
+ (end (car (cdr (cdr word))))
+ (word (car word))
+ poss)
+ (setq flyspell-auto-correct-word word)
+ ;; now check spelling of word.
+ (process-send-string ispell-process "%\n") ;put in verbose mode
+ (process-send-string ispell-process (concat "^" word "\n"))
+ ;; wait until ispell has processed word
+ (while (progn
+ (accept-process-output ispell-process)
+ (not (string= "" (car ispell-filter)))))
+ (setq ispell-filter (cdr ispell-filter))
+ (if (consp ispell-filter)
+ (setq poss (ispell-parse-output (car ispell-filter))))
+ (cond
+ ((or (eq poss t) (stringp poss))
+ ;; don't correct word
+ t)
+ ((null poss)
+ ;; ispell error
+ (error "Ispell: error in Ispell process"))
+ (t
+ ;; the word is incorrect, we have to propose a replacement
+ (let ((replacements (if flyspell-sort-corrections
+ (sort (car (cdr (cdr poss))) 'string<)
+ (car (cdr (cdr poss))))))
+ (if (consp replacements)
+ (progn
+ (let ((replace (car replacements)))
+ (let ((new-word replace))
+ (if (not (equal new-word (car poss)))
+ (progn
+ ;; the save the current replacements
+ (setq flyspell-auto-correct-region
+ (cons start (length new-word)))
+ (let ((l replacements))
+ (while (consp (cdr l))
+ (setq l (cdr l)))
+ (rplacd l (cons (car poss) replacements)))
+ (setq flyspell-auto-correct-ring
+ replacements)
+ (flyspell-unhighlight-at start)
+ (delete-region start end)
+ (funcall flyspell-insert-function new-word)
+ (if flyspell-abbrev-p
+ (if (flyspell-already-abbrevp
+ (flyspell-abbrev-table) word)
+ (flyspell-change-abbrev
+ (flyspell-abbrev-table)
+ word
+ new-word)
+ (flyspell-define-abbrev word
+ new-word)))
+ (flyspell-word)
+ (flyspell-display-next-corrections
+ (cons new-word flyspell-auto-correct-ring))
+ (flyspell-ajust-cursor-point pos
+ (point)
+ old-max))))))))))
+ (ispell-pdict-save t)))
+ (setq flyspell-auto-correct-pos (point))))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-auto-correct-previous-pos ... */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-auto-correct-previous-pos nil
+ "Holds the start of the first incorrect word before point.")
+
+;*---------------------------------------------------------------------*/
+;* flyspell-auto-correct-previous-hook ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-auto-correct-previous-hook ()
+ "Hook to track successive calls to `flyspell-auto-correct-previous-word'.
+Sets flyspell-auto-correct-previous-pos to nil"
+ (interactive)
+ (remove-hook 'pre-command-hook (function flyspell-auto-correct-previous-hook) t)
+ (unless (eq this-command (function flyspell-auto-correct-previous-word))
+ (setq flyspell-auto-correct-previous-pos nil)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-auto-correct-previous-word ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-auto-correct-previous-word (position)
+ "*Auto correct the first mispelled word that occurs before point."
+ (interactive "d")
+
+ (add-hook 'pre-command-hook
+ (function flyspell-auto-correct-previous-hook) t t)
+
+ (save-excursion
+ (unless flyspell-auto-correct-previous-pos
+ ;; only reset if a new overlay exists
+ (setq flyspell-auto-correct-previous-pos nil)
+
+ (let ((overlay-list (overlays-in (point-min) position))
+ (new-overlay 'dummy-value))
+
+ ;; search for previous (new) flyspell overlay
+ (while (and new-overlay
+ (or (not (flyspell-overlay-p new-overlay))
+ ;; check if its face has changed
+ (not (eq (get-char-property
+ (overlay-start new-overlay) 'face)
+ 'flyspell-incorrect-face))))
+ (setq new-overlay (car-safe overlay-list))
+ (setq overlay-list (cdr-safe overlay-list)))
+
+ ;; if nothing new exits new-overlay should be nil
+ (if new-overlay;; the length of the word may change so go to the start
+ (setq flyspell-auto-correct-previous-pos
+ (overlay-start new-overlay)))))
+
+ (when flyspell-auto-correct-previous-pos
+ (save-excursion
+ (goto-char flyspell-auto-correct-previous-pos)
+ (let ((ispell-following-word t));; point is at start
+ (if (numberp flyspell-auto-correct-previous-pos)
+ (goto-char flyspell-auto-correct-previous-pos))
+ (flyspell-auto-correct-word))
+ ;; the point may have moved so reset this
+ (setq flyspell-auto-correct-previous-pos (point))))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-correct-word ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-correct-word (event)
+ "Pop up a menu of possible corrections for a misspelled word.
+The word checked is the word at the mouse position."
+ (interactive "e")
+ ;; use the correct dictionary
+ (flyspell-accept-buffer-local-defs)
+ ;; retain cursor location (I don't know why but save-excursion here fails).
+ (let ((save (point)))
+ (mouse-set-point event)
+ (let ((cursor-location (point))
+ (word (flyspell-get-word nil))
+ (case-fold-search nil))
+ (if (consp word)
+ (let ((start (car (cdr word)))
+ (end (car (cdr (cdr word))))
+ (word (car word))
+ poss replace)
+ ;; now check spelling of word.
+ (process-send-string ispell-process "%\n") ;put in verbose mode
+ (process-send-string ispell-process (concat "^" word "\n"))
+ ;; wait until ispell has processed word
+ (while (progn
+ (accept-process-output ispell-process)
+ (not (string= "" (car ispell-filter)))))
+ (setq ispell-filter (cdr ispell-filter))
+ (if (consp ispell-filter)
+ (setq poss (ispell-parse-output (car ispell-filter))))
+ (cond
+ ((or (eq poss t) (stringp poss))
+ ;; don't correct word
+ t)
+ ((null poss)
+ ;; ispell error
+ (error "Ispell: error in Ispell process"))
+ ((string-match "GNU" (emacs-version))
+ ;; the word is incorrect, we have to propose a replacement
+ (setq replace (flyspell-emacs-popup event poss word))
+ (cond ((eq replace 'ignore)
+ (goto-char save)
+ nil)
+ ((eq replace 'save)
+ (goto-char save)
+ (process-send-string ispell-process
+ (concat "*" word "\n"))
+ (flyspell-unhighlight-at cursor-location)
+ (setq ispell-pdict-modified-p '(t)))
+ ((or (eq replace 'buffer) (eq replace 'session))
+ (process-send-string ispell-process
+ (concat "@" word "\n"))
+ (if (null ispell-pdict-modified-p)
+ (setq ispell-pdict-modified-p
+ (list ispell-pdict-modified-p)))
+ (flyspell-unhighlight-at cursor-location)
+ (goto-char save)
+ (if (eq replace 'buffer)
+ (ispell-add-per-file-word-list word)))
+ (replace
+ (flyspell-unhighlight-at cursor-location)
+ (let ((new-word (if (atom replace)
+ replace
+ (car replace)))
+ (cursor-location
+ (+ (- (length word) (- end start))
+ cursor-location)))
+ (if (not (equal new-word (car poss)))
+ (let ((old-max (point-max)))
+ (delete-region start end)
+ (funcall flyspell-insert-function new-word)
+ (if flyspell-abbrev-p
+ (flyspell-define-abbrev word new-word))
+ (flyspell-ajust-cursor-point save
+ cursor-location
+ old-max)))))
+ (t
+ (goto-char save)
+ nil)))
+ ((eq flyspell-emacs 'xemacs)
+ (flyspell-xemacs-popup
+ event poss word cursor-location start end save)
+ (goto-char save)))
+ (ispell-pdict-save t))))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-xemacs-correct ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-xemacs-correct (replace poss word cursor-location start end save)
+ "The xemacs popup menu callback."
+ (cond ((eq replace 'ignore)
+ nil)
+ ((eq replace 'save)
+ (process-send-string ispell-process (concat "*" word "\n"))
+ (process-send-string ispell-process "#\n")
+ (flyspell-unhighlight-at cursor-location)
+ (setq ispell-pdict-modified-p '(t)))
+ ((or (eq replace 'buffer) (eq replace 'session))
+ (process-send-string ispell-process (concat "@" word "\n"))
+ (flyspell-unhighlight-at cursor-location)
+ (if (null ispell-pdict-modified-p)
+ (setq ispell-pdict-modified-p
+ (list ispell-pdict-modified-p)))
+ (if (eq replace 'buffer)
+ (ispell-add-per-file-word-list word)))
+ (replace
+ (let ((old-max (point-max))
+ (new-word (if (atom replace)
+ replace
+ (car replace)))
+ (cursor-location (+ (- (length word) (- end start))
+ cursor-location)))
+ (if (not (equal new-word (car poss)))
+ (progn
+ (delete-region start end)
+ (goto-char start)
+ (funcall flyspell-insert-function new-word)
+ (if flyspell-abbrev-p
+ (flyspell-define-abbrev word new-word))))
+ (flyspell-ajust-cursor-point save cursor-location old-max)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-ajust-cursor-point ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-ajust-cursor-point (save cursor-location old-max)
+ (if (>= save cursor-location)
+ (let ((new-pos (+ save (- (point-max) old-max))))
+ (goto-char (cond
+ ((< new-pos (point-min))
+ (point-min))
+ ((> new-pos (point-max))
+ (point-max))
+ (t new-pos))))
+ (goto-char save)))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-emacs-popup ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-emacs-popup (event poss word)
+ "The Emacs popup menu."
+ (if (not event)
+ (let* ((mouse-pos (mouse-position))
+ (mouse-pos (if (nth 1 mouse-pos)
+ mouse-pos
+ (set-mouse-position (car mouse-pos)
+ (/ (frame-width) 2) 2)
+ (unfocus-frame)
+ (mouse-position))))
+ (setq event (list (list (car (cdr mouse-pos))
+ (1+ (cdr (cdr mouse-pos))))
+ (car mouse-pos)))))
+ (let* ((corrects (if flyspell-sort-corrections
+ (sort (car (cdr (cdr poss))) 'string<)
+ (car (cdr (cdr poss)))))
+ (cor-menu (if (consp corrects)
+ (mapcar (lambda (correct)
+ (list correct correct))
+ corrects)
+ '()))
+ (affix (car (cdr (cdr (cdr poss)))))
+ (base-menu (let ((save (if (consp affix)
+ (list
+ (list (concat "Save affix: " (car affix))
+ 'save)
+ '("Accept (session)" session)
+ '("Accept (buffer)" buffer))
+ '(("Save word" save)
+ ("Accept (session)" session)
+ ("Accept (buffer)" buffer)))))
+ (if (consp cor-menu)
+ (append cor-menu (cons "" save))
+ save)))
+ (menu (cons "flyspell correction menu" base-menu)))
+ (car (x-popup-menu event
+ (list (format "%s [%s]" word (or ispell-local-dictionary
+ ispell-dictionary))
+ menu)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-xemacs-popup ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-xemacs-popup (event poss word cursor-location start end save)
+ "The XEmacs popup menu."
+ (let* ((corrects (if flyspell-sort-corrections
+ (sort (car (cdr (cdr poss))) 'string<)
+ (car (cdr (cdr poss)))))
+ (cor-menu (if (consp corrects)
+ (mapcar (lambda (correct)
+ (vector correct
+ (list 'flyspell-xemacs-correct
+ correct
+ (list 'quote poss)
+ word
+ cursor-location
+ start
+ end
+ save)
+ t))
+ corrects)
+ '()))
+ (affix (car (cdr (cdr (cdr poss)))))
+ (menu (let ((save (if (consp affix)
+ (vector
+ (concat "Save affix: " (car affix))
+ (list 'flyspell-xemacs-correct
+ ''save
+ (list 'quote poss)
+ word
+ cursor-location
+ start
+ end
+ save)
+ t)
+ (vector
+ "Save word"
+ (list 'flyspell-xemacs-correct
+ ''save
+ (list 'quote poss)
+ word
+ cursor-location
+ start
+ end
+ save)
+ t)))
+ (session (vector "Accept (session)"
+ (list 'flyspell-xemacs-correct
+ ''session
+ (list 'quote poss)
+ word
+ cursor-location
+ start
+ end
+ save)
+ t))
+ (buffer (vector "Accept (buffer)"
+ (list 'flyspell-xemacs-correct
+ ''buffer
+ (list 'quote poss)
+ word
+ cursor-location
+ start
+ end
+ save)
+ t)))
+ (if (consp cor-menu)
+ (append cor-menu (list "-" save session buffer))
+ (list save session buffer)))))
+ (popup-menu (cons (format "%s [%s]" word (or ispell-local-dictionary
+ ispell-dictionary))
+ menu))))
+
+;*---------------------------------------------------------------------*/
+;* Some example functions for real autocorrecting */
+;*---------------------------------------------------------------------*/
+(defun flyspell-maybe-correct-transposition (beg end poss)
+ "Check replacements for transposed characters.
+
+If the text between BEG and END is equal to a correction suggested by
+Ispell, after transposing two adjacent characters, correct the text,
+and return t.
+
+The third arg POSS is either the symbol 'doublon' or a list of
+possible corrections as returned by 'ispell-parse-output'.
+
+This function is meant to be added to 'flyspell-incorrect-hook'."
+ (when (consp poss)
+ (catch 'done
+ (save-excursion
+ (goto-char (1+ beg))
+ (while (< (point) end)
+ (transpose-chars 1)
+ (when (member (buffer-substring beg end) (car (cdr (cdr poss))))
+ (throw 'done t))
+ (transpose-chars -1)
+ (forward-char))
+ nil))))
+
+(defun flyspell-maybe-correct-doubling (beg end poss)
+ "Check replacements for doubled characters.
+
+If the text between BEG and END is equal to a correction suggested by
+Ispell, after removing a pair of doubled characters, correct the text,
+and return t.
+
+The third arg POSS is either the symbol 'doublon' or a list of
+possible corrections as returned by 'ispell-parse-output'.
+
+This function is meant to be added to 'flyspell-incorrect-hook'."
+ (when (consp poss)
+ (catch 'done
+ (save-excursion
+ (let ((last (char-after beg))
+ this)
+ (goto-char (1+ beg))
+ (while (< (point) end)
+ (setq this (char-after))
+ (if (not (char-equal this last))
+ (forward-char)
+ (delete-char 1)
+ (when (member (buffer-substring beg (1- end)) (car (cdr (cdr poss))))
+ (throw 'done t))
+ ;; undo
+ (insert-char this 1))
+ (setq last this))
+ nil)))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-already-abbrevp ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-already-abbrevp (table word)
+ (let ((sym (abbrev-symbol word table)))
+ (and sym (symbolp sym))))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-change-abbrev ... */
+;*---------------------------------------------------------------------*/
+(defun flyspell-change-abbrev (table old new)
+ (set (abbrev-symbol old table) new))
+
+;*---------------------------------------------------------------------*/
+;* flyspell-auto-correct-previous-word advice ... */
+;*---------------------------------------------------------------------*/
+(defadvice flyspell-auto-correct-previous-word
+ (around easymacs-flyspell-auto-correct)
+ "Correct current word if misspelled, else previous
+ misspelling. Protect against accidentally changing a word
+ that cannot be seen, because it is somewhere off the screen."
+ (let ((top) (bot))
+ (save-excursion
+ (move-to-window-line 0)
+ (setq top (point))
+ (move-to-window-line -1)
+ (setq bot (point)))
+ (save-restriction
+ (narrow-to-region top bot)
+ (save-excursion
+ (re-search-forward "\\s \\|\\'" nil t)
+ (overlay-recenter (point))
+ ad-do-it))))
+
+(ad-activate 'flyspell-auto-correct-previous-word)
+
+(provide 'flyspell)
+;;; flyspell.el ends here
+;;; </pre>
diff --git a/elisp/ispell.el b/elisp/ispell.el
new file mode 100644
index 0000000..5cd98ef
--- /dev/null
+++ b/elisp/ispell.el
@@ -0,0 +1,3639 @@
+;;; ispell.el --- interface to International Ispell Versions 3.1 and 3.2
+
+;; Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+;; Author: Ken Stevens <k.stevens@ieee.org>
+;; Maintainer: Ken Stevens <k.stevens@ieee.org>
+;; Stevens Mod Date: Mon Sep 22 13:24:34 PDT 2003
+;; Stevens Revision: 3.7 beta
+;; Status : Release with 3.1.12+ and 3.2.0+ ispell.
+;; Bug Reports : ispell-el-bugs@itcorp.com
+;; Web Site : http://kdstevens.com/~stevens/ispell-page.html
+;; Keywords: unix wp
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Note: version numbers and time stamp are not updated
+;; when this file is edited for release with GNU emacs.
+
+;;; Commentary:
+
+;; INSTRUCTIONS
+
+;; This code contains a section of user-settable variables that you
+;; should inspect prior to installation. Look past the end of the history
+;; list. Set them up for your locale and the preferences of the majority
+;; of the users. Otherwise the users may need to set a number of variables
+;; themselves.
+;; You particularly may want to change the default dictionary for your
+;; country and language.
+;; Most dictionary changes should be made in this file so all users can
+;; enjoy them. Local or modified dictionaries are supported in your .emacs
+;; file. Modify the variable `ispell-local-dictionary-alist' to include
+;; these dictionaries, and they will be installed when ispell.el is loaded.
+
+;; Depending on the mail system you use, you may want to include these:
+;; (add-hook 'news-inews-hook 'ispell-message)
+;; (add-hook 'mail-send-hook 'ispell-message)
+;; (add-hook 'mh-before-send-letter-hook 'ispell-message)
+
+;; Ispell has a TeX parser and a nroff parser (the default).
+;; The parsing is controlled by the variable ispell-parser. Currently
+;; it is just a "toggle" between TeX and nroff, but if more parsers are
+;; added it will be updated. See the variable description for more info.
+
+
+;; TABLE OF CONTENTS
+
+;; ispell-word
+;; ispell-region
+;; ispell-buffer
+;; ispell-message
+;; ispell-comments-and-strings
+;; ispell-continue
+;; ispell-complete-word
+;; ispell-complete-word-interior-frag
+;; ispell-change-dictionary
+;; ispell-kill-ispell
+;; ispell-pdict-save
+;; ispell-skip-region-alist
+
+;; Commands in ispell-region:
+;; Character replacement: Replace word with choice. May query-replace.
+;; ` ': Accept word this time.
+;; `i': Accept word and insert into private dictionary.
+;; `a': Accept word for this session.
+;; `A': Accept word and place in buffer-local dictionary.
+;; `r': Replace word with typed-in value. Rechecked.
+;; `R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+;; `?': Show these commands
+;; `x': Exit spelling buffer. Move cursor to original point.
+;; `X': Exit spelling buffer. Leaves cursor at the current point, and permits
+;; the check to be completed later.
+;; `q': Quit spelling session (Kills ispell process).
+;; `l': Look up typed-in replacement in alternate dictionary. Wildcards okay.
+;; `u': Like `i', but the word is lower-cased first.
+;; `m': Place entered value in personal dictionary, then recheck current word.
+;; `C-l': redraws screen
+;; `C-r': recursive edit
+;; `C-z': suspend emacs or iconify frame
+
+;; Buffer-Local features:
+;; There are a number of buffer-local features that can be used to customize
+;; ispell for the current buffer. This includes language dictionaries,
+;; personal dictionaries, parsing, and local word spellings. Each of these
+;; local customizations are done either through local variables, or by
+;; including the keyword and argument(s) at the end of the buffer (usually
+;; prefixed by the comment characters). See the end of this file for
+;; examples. The local keywords and variables are:
+
+;; ispell-dictionary-keyword language-dictionary
+;; uses local variable ispell-local-dictionary
+;; ispell-pdict-keyword personal-dictionary
+;; uses local variable ispell-local-pdict
+;; ispell-parsing-keyword mode-arg extended-char-arg
+;; ispell-words-keyword any number of local word spellings
+
+;; Region skipping:
+;; Place new regular expression definitions of regions you prefer not to
+;; spell check in `ispell-skip-region-alist'. Mode-dependent features can
+;; be added to latex by modifying `ispell-tex-skip-alists'.
+;; `ispell-message' contains some custom skipping code for e-mail messages.
+
+;; BUGS:
+;; Need a way to select between different character mappings without separate
+;; dictionary entries.
+;; Multi-byte characters if not defined by current dictionary may result in the
+;; evil "misalignment error" in some versions of MULE emacs.
+;; On some versions of emacs, growing the minibuffer fails.
+;; see `ispell-help-in-bufferp'.
+;; Recursive edits (?C-r or ?R) inside a keyboard text replacement check (?r)
+;; can cause misalignment errors.
+
+;; HISTORY
+
+;; Modifications made in latest versions:
+
+;; Revision 3.7 2003/09/22 13:24:34 kss
+;; Highly improved region shipping and selection.
+;; User defined library directory locations now supported.
+;; Selection of preferred binary [ai]spell possible.
+;; Updated `framepop' support.
+
+;; Revision 3.6 2003/01/07 12:32:44 kss
+;; Removed extra -d LIB in dictionary defs. (Pavel Janik)
+;; Filtered process calls with duplicate dictionary entries.
+;; Fixed bug where message-text-end is inside a mime skipped region.
+;; Minor fixes to get ispell menus right in XEmacs
+;; Fixed skip regexp so it doesn't match stuff like `/.\w'.
+;; Detecting dictionary change not working. Fixed. kss
+;; function `ispell-change-dictionary' now only completes valid dicts.
+
+;; Revision 3.5 2001/7/11 18:43:57 kss
+;; Added fix for aspell to work in XEmacs (ispell-check-version).
+;; Added Portuguese dictionary definition.
+;; New feature: MIME mail message support, Fcc support.
+;; Bug fix: retain comment syntax on lines with region skipping. (TeX $ bug...)
+;; Improved allocation for graphic mode lines. (Miles Bader)
+;; Support -v flag for old versions of aspell. (Eli Zaretskii)
+;; Clear minibuffer on ^G from ispell-help (Tak Ota)
+
+;; Revision 3.4 2000/8/4 09:41:50 kss
+;; Support new color display functions.
+;; Fixed misalignment offset bug when replacing a string after a shift made.
+;; Set to standard Author/Maintainer heading,
+;; ensure localwords lists are separated from the text by newline. (Dave Love)
+;; Added dictionary definition for Italian (William Deakin)
+;; HTML region skipping greatly improved. (Chuck D. Phillips)
+;; improved menus. Fixed regexp matching http/email addresses.
+;; one arg always for xemacs sleep-for (gunnar Evermann)
+;; support for synchronous processes (Eli Zaretskii)
+
+;; Revision 3.3 1999/11/29 11:38:34 kss
+;; Only word replacements entered in from the keyboard are rechecked.
+;; This fixes a bug in tex parsing and misalignment.
+;; Exceptions exist for recursive edit and query-replace, with tex error
+;; condition tested. Recursive editing improved.
+;; XEmacs repair for when `enable-multibyte-characters' defined - Didier Verna.
+;; ispell-help fixed for XEmacs. Choices minibuffer now displayed in XEmacs.
+;; Only list valid dictionaries in Spell menu. Russian dictionary doesn't allow
+;; run-together words, and uses koi8-r font. Don't skip text in html <TT>
+;; fonts.
+
+;; Revision 3.2 1999/5/7 14:25:14 kss
+;; Accept ispell versions 3.X.Y where X>=1
+;; fine tuned latex region skipping. Fixed bug in ispell-word that did not
+;; point in right place on words < 2 chars. Simplified ispell-minor-mode.
+;; Fixed bug in TeX parsing when math commands are in the comments.
+;; Removed calls to `when' macro.
+
+;; Revision 3.1 1998/12/1 13:21:52 kss
+;; Improved and fixed customize support.
+;; Improved and fixed comments in variables and messages.
+;; A coding system is now required for all languages.
+;; casechars improved for castellano, castellano8, and norsk dictionaries.
+;; Dictionary norsk7-tex removed. Dictionary polish added.
+;; Dictionaries redefined at load-time to support dictionary changes.
+;; Menu redefined at load time to support dictionary changes.
+;; ispell-check-version added as an alias for `check-ispell-version'.
+;; Spelling suggestions returned in order generated by ispell.
+;; Small bug fixed in matching ispell error messages.
+;; Robustness added to ensure `case-fold-search' doesn't get redefined.
+;; Fixed bug that didn't respect case of word in `ispell-complete-word'.
+;; Multibyte character coding support added for process interactions.
+;; Ensure ispell process has terminated before starting new process.
+;; This can otherwise confuse process filters and hang ispell.
+;; Improved skipping support for SGML.
+;; Fixed bug using ^M rather than \r in `ispell-minor-check'.
+;; Improved message reference matching in `ispell-message'.
+;; Fixed bug in returning to nroff mode from tex mode.
+
+
+;;; Code:
+
+;;; Custom.el macros require recompiling this when they are not present.
+;;; Add in backward compatible custom support.
+(eval-when-compile
+ (if (not (fboundp 'defcustom))
+ (defmacro defcustom (symbol value doc &rest args)
+ "Empty replacement for defcustom when not supplied."
+ `(defvar ,symbol ,value ,doc))))
+
+(eval-when-compile
+ (if (not (fboundp 'defgroup))
+ (defmacro defgroup (&rest args)
+ "Empty replacement for defgroup when not supplied.")))
+
+(defgroup ispell nil
+ "User variables for emacs ispell interface."
+ :group 'applications)
+
+(if (not (fboundp 'buffer-substring-no-properties))
+ (defun buffer-substring-no-properties (start end)
+ (buffer-substring start end)))
+
+(defalias 'check-ispell-version 'ispell-check-version)
+
+;;; **********************************************************************
+;;; The following variables should be set according to personal preference
+;;; and location of binaries:
+;;; **********************************************************************
+
+
+;;; ******* THIS FILE IS WRITTEN FOR ISPELL VERSION 3.1+
+
+;;; ------- general parsing options
+
+
+(defcustom ispell-check-comments t
+ "*Spelling of comments checked when non-nil.
+When set to `exclusive', ONLY comments are checked. (For code comments).
+Warning! Not checking comments, when a comment start is embedded in strings,
+may produce undesired results."
+ :type '(choice (const exclusive) (const :tag "off" nil) (const :tag "on" t))
+ :group 'ispell)
+
+(defcustom ispell-parser 'use-mode-name
+ "Determines selection of region skipping regular expressions.
+Special value `use-mode-name' sets parsing based on the `major-mode'.
+Other modes set parsing to predefined regexp values.
+
+Mail message parsing uses special commands in function `ispell-message'."
+ :type '(choice (const :tag "use buffer major mode" use-mode-name)
+ (const :tag "latex" tex)
+ (const :tag "po-mode" po-mode)
+ (const :tag "html markups" html)
+ (const :tag "generic text" nil))
+ :group 'ispell)
+
+(defcustom ispell-skip-html 'use-mode-name
+ "*Indicates whether ispell should skip spell checking of SGML markup.
+If t, always skip SGML markup; if nil, never skip; if non-t and non-nil,
+guess whether SGML markup should be skipped according to the name of the
+buffer's major mode."
+ :type '(choice (const :tag "always" t) (const :tag "never" nil)
+ (const :tag "use-mode-name" use-mode-name))
+ :group 'ispell)
+
+(defcustom ispell-skip-tib nil
+ "*Skips spell checking of `tib' bibliography references when non-nil.
+Skips any text between strings matching regular expressions
+`ispell-tib-ref-beginning' and `ispell-tib-ref-end'.
+
+TeX users beware: Any field starting with [. will skip until a .] -- even
+your whole buffer -- unless you set `ispell-skip-tib' to nil. That includes
+a [.5mm] type of number...."
+ :type 'boolean
+ :group 'ispell)
+
+;;;--------------------
+
+(defcustom ispell-highlight-p 'block
+ "*Highlight spelling errors when non-nil.
+When set to `block', assumes a block cursor with TTY displays."
+ :type '(choice (const block) (const :tag "off" nil) (const :tag "on" t))
+ :group 'ispell)
+
+(defcustom ispell-highlight-face 'highlight
+ "*The face used for Ispell highlighting. For Emacses with overlays.
+Possible values are `highlight', `modeline', `secondary-selection',
+`region', and `underline'.
+This variable can be set by the user to whatever face they desire.
+It's most convenient if the cursor color and highlight color are
+slightly different."
+ :type 'face
+ :group 'ispell)
+
+(defcustom ispell-query-replace-choices nil
+ "*Corrections made throughout region when non-nil.
+Uses `query-replace' (\\[query-replace]) for corrections."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-keep-choices-win t
+ "*When not nil, the `*Choices*' window remains for spelling session.
+This minimizes redisplay thrashing."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-choices-win-default-height 2
+ "*The default size of the `*Choices*' window, including mode line.
+Must be greater than 1."
+ :type 'integer
+ :group 'ispell)
+
+(defcustom ispell-prefer-aspell nil
+ "*Select preference between using the `ispell' or `aspell' program.
+`ispell' is used by default.
+When this variable is set, `aspell' is used if it is installed on the system."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-program-name
+(or (and (executable-find "aspell")
+ (or ispell-prefer-aspell
+ (not (executable-find "ispell")))
+ "aspell")
+ "ispell")
+ "Program invoked by \\[ispell-word] and \\[ispell-region] commands."
+ :type 'string
+ :group 'ispell)
+
+(defcustom ispell-alternate-dictionary
+ (cond ; ((file-exists-p "/usr/dict/web2") "/usr/dict/web2")
+ ; ((file-exists-p "/usr/share/dict/web2") "/usr/share/dict/web2")
+ ; ((file-exists-p "/usr/dict/words") "/usr/dict/words")
+ ; ((file-exists-p "/usr/lib/dict/words") "/usr/lib/dict/words")
+ ; ((file-exists-p "/usr/share/dict/words") "/usr/share/dict/words")
+ (t (concat AutOrgRes "/dict"))
+ (t "/Applications/AutOrg.app/Contents/Resources/AutOrg/dict")
+ ; ((file-exists-p "/usr/share/lib/dict/words")
+ ; "/usr/share/lib/dict/words")
+ ; ((file-exists-p "/sys/dict") "/sys/dict")
+ ; (t "/usr/dict/words"))
+ )
+ "*Alternate dictionary for spelling help."
+ :type '(choice file (const :tag "None" nil))
+ :group 'ispell)
+
+(defcustom ispell-complete-word-dict ispell-alternate-dictionary
+ "*Dictionary used for word completion."
+ :type '(choice file (const :tag "None" nil))
+ :group 'ispell)
+
+(defcustom ispell-message-dictionary-alist nil
+ "*List used by `ispell-message' to select a new dictionary.
+It consists of pairs (REGEXP . DICTIONARY). If REGEXP is found
+in the message headers, `ispell-local-dictionary' will be set to
+DICTIONARY if `ispell-local-dictionary' is not buffer-local.
+E.g. you may use the following value:
+ '((\"^Newsgroups:[ \\t]*de\\\\.\" . \"deutsch8\")
+ (\"^To:[^\\n,]+\\\\.de[ \\t\\n,>]\" . \"deutsch8\"))"
+ :type '(repeat (cons regexp string))
+ :group 'ispell)
+
+
+(defcustom ispell-message-fcc-skip 50000
+ "*Query before saving Fcc message copy if attachment larger than this value.
+Always stores Fcc copy of message when nil."
+ :type '(choice integer (const :tag "off" nil))
+ :group 'ispell)
+
+
+(defcustom ispell-grep-command "egrep"
+ "Name of the grep command for search processes."
+ :type 'string
+ :group 'ispell)
+
+(defcustom ispell-grep-options "-i"
+ "String of options to use when running the program in `ispell-grep-command'.
+Should probably be \"-i\" or \"-e\".
+Some machines (like the NeXT) don't support \"-i\""
+ :type 'string
+ :group 'ispell)
+
+(defcustom ispell-look-command
+ (cond ((file-exists-p "/bin/look") "/bin/look")
+ ((file-exists-p "/usr/local/bin/look") "/usr/local/bin/look")
+ ((file-exists-p "/usr/bin/look") "/usr/bin/look")
+ (t "look"))
+ "Name of the look command for search processes.
+This must be an absolute file name."
+ :type 'file
+ :group 'ispell)
+
+(defcustom ispell-look-p (file-exists-p ispell-look-command)
+ "*Non-nil means use `look' rather than `grep'.
+Default is based on whether `look' seems to be available."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-have-new-look nil
+ "*Non-nil means use the `-r' option (regexp) when running `look'."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-look-options (if ispell-have-new-look "-dfr" "-df")
+ "String of command options for `ispell-look-command'."
+ :type 'string
+ :group 'ispell)
+
+(defcustom ispell-use-ptys-p nil
+ "When non-nil, Emacs uses ptys to communicate with Ispell.
+When nil, Emacs uses pipes."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-following-word nil
+ "*Non-nil means `ispell-word' checks the word around or after point.
+Otherwise `ispell-word' checks the preceding word."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-help-in-bufferp nil
+ "*Non-nil means display interactive keymap help in a buffer.
+The following values are supported:
+ nil Expand the minibuffer and display a short help message
+ there for a couple of seconds.
+ t Pop up a new buffer and display a short help message there
+ for a couple of seconds.
+ electric Pop up a new buffer and display a long help message there.
+ User can browse and then exit the help mode."
+ :type '(choice (const electric) (const :tag "off" nil) (const :tag "on" t))
+ :group 'ispell)
+
+(defcustom ispell-quietly nil
+ "*Non-nil means suppress messages in `ispell-word'."
+ :type 'boolean
+ :group 'ispell)
+
+(defcustom ispell-format-word (function upcase)
+ "*Formatting function for displaying word being spell checked.
+The function must take one string argument and return a string."
+ :type 'function
+ :group 'ispell)
+
+(defcustom ispell-use-framepop-p nil
+ "When non-nil ispell uses framepop to display choices in a dedicated frame.
+You can set this variable to dynamically use framepop if you are in a
+window system by evaluating the following on startup to set this variable:
+ (and window-system (condition-case () (require 'framepop) (error nil)))"
+ :type 'boolean
+ :group 'ispell)
+
+;;;###autoload
+(defcustom ispell-personal-dictionary nil
+ "*File name of your personal spelling dictionary, or nil.
+If nil, the default personal dictionary, \"~/.ispell_DICTNAME\" is used,
+where DICTNAME is the name of your default dictionary."
+ :type '(choice file
+ (const :tag "default" nil))
+ :group 'ispell)
+
+(defcustom ispell-silently-savep nil
+ "*When non-nil, save the personal dictionary without confirmation."
+ :type 'boolean
+ :group 'ispell)
+
+;;; This is the local dictionary to use. When nil the default dictionary will
+;;; be used. Change set-default call to use a new default dictionary.
+(defcustom ispell-local-dictionary nil
+ "If non-nil, the dictionary to be used for Ispell commands.
+The value must be a string dictionary name in `ispell-dictionary-alist'.
+
+Setting `ispell-local-dictionary' to a value has the same effect as
+calling \\[ispell-change-dictionary] with that value. This variable
+is automatically set when defined in the file with either
+`ispell-dictionary-keyword' or the Local Variable syntax.
+
+To create a non-standard default dictionary (not from `ispell-dictionary-alist')
+call function `set-default' with the new dictionary name."
+ :type '(choice string
+ (const :tag "default" nil))
+ :group 'ispell)
+
+(make-variable-buffer-local 'ispell-local-dictionary)
+
+;; Call this function set up the default dictionary if not English.
+;;(set-default 'ispell-local-dictionary nil)
+
+
+(defcustom ispell-extra-args nil
+ "*If non-nil, a list of extra switches to pass to the Ispell program.
+For example, (\"-W\" \"3\") to cause it to accept all 1-3 character
+words as correct. See also `ispell-dictionary-alist', which may be used
+for language-specific arguments."
+ :type '(repeat string)
+ :group 'ispell)
+
+
+(defcustom ispell-library-directory nil
+ "*Directory where ispell dictionaries reside.
+If nil, the library directory compiled into ispell will be used."
+ :type '(choice string
+ (const :tag "default" nil))
+ :group 'ispell)
+
+;;; Define definitions here only for personal dictionaries.
+;;;###autoload
+(defcustom ispell-local-dictionary-alist nil
+ "*Contains local or customized dictionary definitions.
+
+These will override the values in `ispell-dictionary-alist'.
+
+Customization changes made to `ispell-dictionary-alist' will not operate
+over emacs sessions. To make permanent changes to your dictionary
+definitions, you will need to make your changes in this variable, save,
+and then re-start emacs."
+ :type '(repeat (list (choice :tag "Dictionary"
+ (string :tag "Dictionary name")
+ (const :tag "default" nil))
+ (regexp :tag "Case characters")
+ (regexp :tag "Non case characters")
+ (regexp :tag "Other characters")
+ (boolean :tag "Many other characters")
+ (repeat :tag "Ispell command line args"
+ (string :tag "Arg"))
+ (choice :tag "Extended character mode"
+ (const "~tex") (const "~plaintex")
+ (const "~nroff") (const "~list")
+ (const "~latin1") (const "~latin3")
+ (const :tag "default" nil))
+ (choice :tag "Coding system"
+ (const iso-8859-1)
+ (const iso-8859-2)
+ (const koi8-r))))
+ :group 'ispell)
+
+
+;;; split dictionary so line length is smaller in loaddefs.el
+
+;;; First part of dictionary, shortened for loaddefs.el
+;;;###autoload
+(setq
+ ispell-dictionary-alist-1
+ '((nil ; default (English.aff)
+ "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
+ ("american" ; Yankee English
+ "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
+ ("brasileiro" ; Brazilian mode
+ "[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]"
+ "[^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]"
+ "[']" nil nil nil iso-8859-1)
+ ("british" ; British version
+ "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)
+ ("castellano" ; Spanish mode
+ "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
+ "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
+ "[-]" nil ("-B") "~tex" iso-8859-1)
+ ("castellano8" ; 8 bit Spanish mode
+ "[A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
+ "[^A-Z\301\311\315\321\323\332\334a-z\341\351\355\361\363\372\374]"
+ "[-]" nil ("-B" "-d" "castellano") "~latin1" iso-8859-1)))
+
+
+;;; Second part of dictionary, shortened for loaddefs.el
+;;;###autoload
+(setq
+ ispell-dictionary-alist-2
+ '(("czech"
+ "[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]"
+ "[^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]"
+ "" nil ("-B") nil iso-8859-2)
+ ("dansk" ; Dansk.aff
+ "[A-Z\306\330\305a-z\346\370\345]" "[^A-Z\306\330\305a-z\346\370\345]"
+ "[']" nil ("-C") nil iso-8859-1)
+ ("deutsch" ; Deutsch.aff
+ "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1)
+ ("deutsch8"
+ "[a-zA-Z\304\326\334\344\366\337\374]"
+ "[^a-zA-Z\304\326\334\344\366\337\374]"
+ "[']" t ("-C" "-d" "deutsch") "~latin1" iso-8859-1)
+ ("english" ; make English explicitly selectable
+ "[A-Za-z]" "[^A-Za-z]" "[']" nil ("-B") nil iso-8859-1)))
+
+
+;;; Third part of dictionary, shortened for loaddefs.el
+;;;###autoload
+(setq
+ ispell-dictionary-alist-3
+ '(("esperanto"
+ "[A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]"
+ "[^A-Za-z\246\254\266\274\306\330\335\336\346\370\375\376]"
+ "[-']" t ("-C") "~latin3" iso-8859-1)
+ ("esperanto-tex"
+ "[A-Za-z^\\]" "[^A-Za-z^\\]"
+ "[-'`\"]" t ("-C" "-d" "esperanto") "~tex" iso-8859-1)
+ ("francais7"
+ "[A-Za-z]" "[^A-Za-z]" "[`'^---]" t nil nil iso-8859-1)
+ ("francais" ; Francais.aff
+ "[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]"
+ "[^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]"
+ "[-']" t nil "~list" iso-8859-1)
+ ("francais-tex" ; Francais.aff
+ "[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\\]"
+ "[^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\\]"
+ "[-'^`\"]" t nil "~tex" iso-8859-1)))
+
+
+;;; Fourth part of dictionary, shortened for loaddefs.el
+;;;###autoload
+(setq
+ ispell-dictionary-alist-4
+ '(("german" ; german.aff
+ "[a-zA-Z\"]" "[^a-zA-Z\"]" "[']" t ("-C") "~tex" iso-8859-1)
+ ("german8" ; german.aff
+ "[a-zA-Z\304\326\334\344\366\337\374]"
+ "[^a-zA-Z\304\326\334\344\366\337\374]"
+ "[']" t ("-C" "-d" "german") "~latin1" iso-8859-1)
+ ("italiano" ; Italian.aff
+ "[A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]"
+ "[^A-Z\300\301\310\311\314\315\322\323\331\332a-z\340\341\350\351\354\355\363\371\372]"
+ "[-]" nil ("-B" "-d" "italian") "~tex" iso-8859-1)
+ ("nederlands" ; Nederlands.aff
+ "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
+ "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
+ "[']" t ("-C") nil iso-8859-1)
+ ("nederlands8" ; Dutch8.aff
+ "[A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
+ "[^A-Za-z\300-\305\307\310-\317\322-\326\331-\334\340-\345\347\350-\357\361\362-\366\371-\374]"
+ "[']" t ("-C") nil iso-8859-1)))
+
+
+;;; Fifth part of dictionary, shortened for loaddefs.el
+;;;###autoload
+(setq
+ ispell-dictionary-alist-5
+ '(("norsk" ; 8 bit Norwegian mode
+ "[A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]"
+ "[^A-Za-z\305\306\307\310\311\322\324\330\345\346\347\350\351\362\364\370]"
+ "[\"]" nil nil "~list" iso-8859-1)
+ ("norsk7-tex" ; 7 bit Norwegian TeX mode
+ "[A-Za-z{}\\'^`]" "[^A-Za-z{}\\'^`]"
+ "[\"]" nil ("-d" "norsk") "~plaintex" iso-8859-1)
+ ("polish" ; Polish mode
+ "[A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
+ "[^A-Za-z\241\243\246\254\257\261\263\266\274\277\306\312\321\323\346\352\361\363]"
+ "" nil nil nil iso-8859-2)
+ ("portugues" ; Portuguese mode
+ "[a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
+ "[^a-zA-Z\301\302\311\323\340\341\342\351\352\355\363\343\372]"
+ "[']" t ("-C") "~latin1" iso-8859-1)))
+
+
+;;; Sixth part of dictionary, shortened for loaddefs.el
+;;;###autoload
+(setq
+ ispell-dictionary-alist-6
+ ;; include Russian iso coding system too?
+ ;; "[']" t ("-d" "russian") "~latin1" iso-8859-1
+ '(("russian" ; Russian.aff (KOI8-R charset)
+ "[\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]"
+ "[^\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]"
+ "" nil nil nil koi8-r)
+ ("slovak" ; Slovakian
+ "[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]"
+ "[^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]"
+ "" nil ("-B") nil iso-8859-2)
+ ("svenska" ; Swedish mode
+ "[A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]"
+ "[^A-Za-z\345\344\366\351\340\374\350\346\370\347\305\304\326\311\300\334\310\306\330\307]"
+ "[']" nil ("-C") "~list" iso-8859-1)))
+
+
+;;;###autoload
+(defcustom ispell-dictionary-alist
+ (append ispell-local-dictionary-alist ; dictionary customizations
+ ispell-dictionary-alist-1 ispell-dictionary-alist-2
+ ispell-dictionary-alist-3 ispell-dictionary-alist-4
+ ispell-dictionary-alist-5 ispell-dictionary-alist-6)
+ "An alist of dictionaries and their associated parameters.
+
+Each element of this list is also a list:
+
+\(DICTIONARY-NAME CASECHARS NOT-CASECHARS OTHERCHARS MANY-OTHERCHARS-P
+ ISPELL-ARGS EXTENDED-CHARACTER-MODE CHARACTER-SET\)
+
+DICTIONARY-NAME is a possible string value of variable `ispell-dictionary',
+nil means the default dictionary.
+
+CASECHARS is a regular expression of valid characters that comprise a
+word.
+
+NOT-CASECHARS is the opposite regexp of CASECHARS.
+
+OTHERCHARS is a regexp of characters in the NOT-CASECHARS set but which can be
+used to construct words in some special way. If OTHERCHARS characters follow
+and precede characters from CASECHARS, they are parsed as part of a word,
+otherwise they become word-breaks. As an example in English, assume the
+regular expression \"[']\" for OTHERCHARS. Then \"they're\" and
+\"Steven's\" are parsed as single words including the \"'\" character, but
+\"Stevens'\" does not include the quote character as part of the word.
+If you want OTHERCHARS to be empty, use the empty string.
+Hint: regexp syntax requires the hyphen to be declared first here.
+
+MANY-OTHERCHARS-P is non-nil when multiple OTHERCHARS are allowed in a word.
+Otherwise only a single OTHERCHARS character is allowed to be part of any
+single word.
+
+ISPELL-ARGS is a list of additional arguments passed to the ispell
+subprocess.
+
+EXTENDED-CHARACTER-MODE should be used when dictionaries are used which
+have been configured in an Ispell affix file. (For example, umlauts
+can be encoded as \\\"a, a\\\", \"a, ...) Defaults are ~tex and ~nroff
+in English. This has the same effect as the command-line `-T' option.
+The buffer Major Mode controls Ispell's parsing in tex or nroff mode,
+but the dictionary can control the extended character mode.
+Both defaults can be overruled in a buffer-local fashion. See
+`ispell-parsing-keyword' for details on this.
+
+CHARACTER-SET used for languages with multibyte characters.
+
+Note that the CASECHARS and OTHERCHARS slots of the alist should
+contain the same character set as casechars and otherchars in the
+LANGUAGE.aff file \(e.g., english.aff\)."
+ :type '(repeat (list (choice :tag "Dictionary"
+ (string :tag "Dictionary name")
+ (const :tag "default" nil))
+ (regexp :tag "Case characters")
+ (regexp :tag "Non case characters")
+ (regexp :tag "Other characters")
+ (boolean :tag "Many other characters")
+ (repeat :tag "Ispell command line args"
+ (string :tag "Arg"))
+ (choice :tag "Extended character mode"
+ (const "~tex") (const "~plaintex")
+ (const "~nroff") (const "~list")
+ (const "~latin1") (const "~latin3")
+ (const :tag "default" nil))
+ (choice :tag "Coding System"
+ (const iso-8859-1)
+ (const iso-8859-2)
+ (const koi8-r))))
+ :group 'ispell)
+
+;;; update the dictionaries at load time
+(setq ispell-dictionary-alist
+ (append ispell-local-dictionary-alist ; dictionary customizations
+ ispell-dictionary-alist-1 ispell-dictionary-alist-2
+ ispell-dictionary-alist-3 ispell-dictionary-alist-4
+ ispell-dictionary-alist-5 ispell-dictionary-alist-6))
+
+
+
+;;; **********************************************************************
+;;; The following are used by ispell, and should not be changed.
+;;; **********************************************************************
+
+
+
+;;; The version must be 3.1 or greater for this version of ispell.el
+;;; There is an incompatibility between version 3.1.12 and lower versions.
+(defconst ispell-required-version '(3 1 12)
+ "Ispell versions with which this version of ispell.el is known to work.")
+(defvar ispell-offset -1
+ "Offset that maps protocol differences between ispell 3.1 versions.")
+
+(defconst ispell-version "ispell.el 3.7 beta - 22-Sep-2003")
+
+
+(defun ispell-check-version (&optional interactivep)
+ "Ensure that `ispell-program-name' is valid and the correct version.
+Returns version number if called interactively.
+Otherwise returns the library directory name, if that is defined."
+ ;; This is a little wasteful as we actually launch ispell twice: once
+ ;; to make sure it's the right version, and once for real. But people
+ ;; get confused by version mismatches *all* the time (and I've got the
+ ;; email to prove it) so I think this is worthwhile. And the -v[ersion]
+ ;; option is the only way I can think of to do this that works with
+ ;; all versions, since versions earlier than 3.0.09 didn't identify
+ ;; themselves on startup.
+ (interactive "p")
+ (let ((case-fold-search-val case-fold-search)
+ ;; avoid bugs when syntax of `.' changes in various default modes
+ (default-major-mode 'fundamental-mode)
+ (default-directory (or (and (boundp 'temporary-file-directory)
+ temporary-file-directory)
+ default-directory))
+ result status)
+ (save-excursion
+ (let ((buf (get-buffer " *ispell-tmp*")))
+ (if buf (kill-buffer buf)))
+ (set-buffer (get-buffer-create " *ispell-tmp*"))
+ (erase-buffer)
+ (setq status (call-process
+ ispell-program-name nil t nil
+ ;; aspell doesn't accept the -vv switch.
+ (let ((case-fold-search
+ (memq system-type '(ms-dos windows-nt)))
+ (speller
+ (file-name-nondirectory ispell-program-name)))
+ ;; Assume anything that isn't `aspell' is Ispell.
+ (if (string-match "\\`aspell" speller) "-v" "-vv"))))
+ (goto-char (point-min))
+ (if interactivep
+ ;; report version information of ispell and ispell.el
+ (progn
+ (end-of-line)
+ (setq result (concat (buffer-substring-no-properties (point-min)
+ (point))
+ ", "
+ ispell-version))
+ (message result))
+ ;; return library directory.
+ (if (re-search-forward "LIBDIR = \\\"\\([^ \t\n]*\\)\\\"" nil t)
+ (setq result (buffer-substring (match-beginning 1) (match-end 1)))))
+ (goto-char (point-min))
+ (if (not (memq status '(0 nil)))
+ (error "%s exited with %s %s" ispell-program-name
+ (if (stringp status) "signal" "code") status))
+ (setq case-fold-search t
+ status (re-search-forward
+ (concat "\\<\\("
+ (format "%d" (car ispell-required-version))
+ "\\)\\.\\([0-9]*\\)\\.\\([0-9]*\\)\\>")
+ nil t)
+ case-fold-search case-fold-search-val)
+ (if (or (not status) ; major version mismatch
+ (< (car (read-from-string (buffer-substring-no-properties
+ (match-beginning 2) (match-end 2))))
+ (car (cdr ispell-required-version)))) ; minor version mismatch
+ (error "%s version 3 release %d.%d.%d or greater is required"
+ ispell-program-name (car ispell-required-version)
+ (car (cdr ispell-required-version))
+ (car (cdr (cdr ispell-required-version))))
+ ;; check that it is the correct version.
+ (if (and (= (car (read-from-string (buffer-substring-no-properties
+ (match-beginning 2)(match-end 2))))
+ (car (cdr ispell-required-version)))
+ (< (car (read-from-string (buffer-substring-no-properties
+ (match-beginning 3)(match-end 3))))
+ (car (cdr (cdr ispell-required-version)))))
+ (setq ispell-offset 0)))
+ (kill-buffer (current-buffer)))
+ result))
+
+
+
+;;; The preparation of the menu bar menu must be autoloaded
+;;; because otherwise this file gets autoloaded every time Emacs starts
+;;; so that it can set up the menus and determine keyboard equivalents.
+
+
+;;;###autoload
+(defvar ispell-menu-map nil "Key map for ispell menu.")
+;;; redo menu when loading ispell to get dictionary modifications
+(setq ispell-menu-map nil)
+
+;;;###autoload
+(defvar ispell-menu-xemacs nil
+ "Spelling menu for XEmacs.
+If nil when package is loaded, a standard menu will be set,
+and added as a submenu of the \"Edit\" menu.")
+
+;;; Break out XEmacs menu and split into several calls to avoid having
+;;; long lines in loaddefs.el. Detect need off following constant.
+
+;;; Set up dictionary
+;;;###autoload
+(defvar ispell-menu-map-needed
+ ;; only needed when not version 18 and not XEmacs.
+ (and (not ispell-menu-map)
+ (not (featurep 'xemacs))
+ 'reload))
+
+(defvar ispell-process nil
+ "The process object for Ispell.")
+
+(defvar ispell-async-processp (and (fboundp 'kill-process)
+ (fboundp 'process-send-string)
+ (fboundp 'accept-process-output)
+ ;;(fboundp 'start-process)
+ ;;(fboundp 'set-process-filter)
+ ;;(fboundp 'process-kill-without-query)
+ )
+ "Non-nil means that the OS supports asynchronous processes.")
+
+(defun ispell-valid-dictionary-list ()
+ "Returns a list of valid dictionaries.
+The variable `ispell-library-directory' defines the library location."
+ (let ((dicts ispell-dictionary-alist)
+ (dict-list (cons "default" nil))
+ name load-dict)
+ (dolist (dict dicts)
+ (setq name (car dict)
+ load-dict (car (cdr (member "-d" (nth 5 dict)))))
+ ;; Include if the dictionary is in the library, or dir not defined.
+ (if (and
+ name
+ ;; include all dictionaries if lib directory not known.
+ (or (not ispell-library-directory)
+ (file-exists-p (concat ispell-library-directory "/"
+ name ".hash"))
+ (file-exists-p (concat ispell-library-directory "/"
+ name ".hash.gz"))
+ (file-exists-p (concat ispell-library-directory "/" name ".has"))
+ (and load-dict
+ (or (file-exists-p (concat ispell-library-directory
+ "/" load-dict ".hash"))
+ (file-exists-p (concat ispell-library-directory
+ "/" load-dict ".hash.gz"))
+ (file-exists-p (concat ispell-library-directory
+ "/" load-dict ".has"))))))
+ (setq dict-list (cons name dict-list))))
+ dict-list))
+
+
+;;;###autoload
+(if ispell-menu-map-needed
+ (let ((dicts (if (fboundp 'ispell-valid-dictionary-list)
+ (ispell-valid-dictionary-list)
+ (mapcar (lambda (x) (or (car x) "default"))
+ ispell-dictionary-alist)))
+ (dict-map (make-sparse-keymap "Dictionaries")))
+ (setq ispell-menu-map (make-sparse-keymap "Spell"))
+ ;; add the dictionaries to the bottom of the list.
+ (if (not dicts)
+ (define-key ispell-menu-map [default]
+ '("Select Default Dict"
+ "Dictionary for which Ispell was configured"
+ . (lambda () (interactive)
+ (ispell-change-dictionary "default")))))
+ (fset 'ispell-dict-map dict-map)
+ (define-key ispell-menu-map [dictionaries]
+ `(menu-item "Select Dict" ispell-dict-map))
+ (dolist (name dicts)
+ (define-key dict-map (vector (intern name))
+ (cons (concat "Select " (capitalize name) " Dict")
+ `(lambda () (interactive)
+ (ispell-change-dictionary ,name)))))))
+
+;;; define commands in menu in opposite order you want them to appear.
+;;;###autoload
+(if ispell-menu-map-needed
+ (progn
+ (define-key ispell-menu-map [ispell-change-dictionary]
+ '(menu-item "Change Dictionary..." ispell-change-dictionary
+ :help "Supply explicit dictionary file name"))
+ (define-key ispell-menu-map [ispell-kill-ispell]
+ '(menu-item "Kill Process" ispell-kill-ispell
+ :enable (and (boundp 'ispell-process) ispell-process
+ (eq (ispell-process-status) 'run))
+ :help "Terminate Ispell subprocess"))
+ (define-key ispell-menu-map [ispell-pdict-save]
+ '(menu-item "Save Dictionary"
+ (lambda () (interactive) (ispell-pdict-save t t))
+ :help "Save personal dictionary"))
+ (define-key ispell-menu-map [ispell-customize]
+ '(menu-item "Customize..."
+ (lambda () (interactive) (customize-group 'ispell))
+ :help "Customize spell checking options"))
+ (define-key ispell-menu-map [ispell-help]
+ ;; use (x-popup-menu last-nonmenu-event(list "" ispell-help-list)) ?
+ '(menu-item "Help"
+ (lambda () (interactive) (describe-function 'ispell-help))
+ :help "Show standard Ispell keybindings and commands"))
+ (define-key ispell-menu-map [flyspell-mode]
+ '(menu-item "Automatic spell checking (Flyspell)"
+ flyspell-mode
+ :help "Check spelling while you edit the text"
+ :button (:toggle . flyspell-mode)))
+ (define-key ispell-menu-map [ispell-complete-word]
+ '(menu-item "Complete Word" ispell-complete-word
+ :help "Complete word at cursor using dictionary"))
+ (define-key ispell-menu-map [ispell-complete-word-interior-frag]
+ '(menu-item "Complete Word Fragment" ispell-complete-word-interior-frag
+ :help "Complete word fragment at cursor"))))
+
+;;;###autoload
+(if ispell-menu-map-needed
+ (progn
+ (define-key ispell-menu-map [ispell-continue]
+ '(menu-item "Continue Spell-Checking" ispell-continue
+ :enable (and (boundp 'ispell-region-end)
+ (marker-position ispell-region-end)
+ (equal (marker-buffer ispell-region-end)
+ (current-buffer)))
+ :help "Continue spell checking last region"))
+ (define-key ispell-menu-map [ispell-word]
+ '(menu-item "Spell-Check Word" ispell-word
+ :help "Spell-check word at cursor"))
+ (define-key ispell-menu-map [ispell-comments-and-strings]
+ '(menu-item "Spell-Check Comments" ispell-comments-and-strings
+ :help "Spell-check only comments and strings"))))
+
+;;;###autoload
+(if ispell-menu-map-needed
+ (progn
+ (define-key ispell-menu-map [ispell-region]
+ '(menu-item "Spell-Check Region" ispell-region
+ :enable mark-active
+ :help "Spell-check text in marked region"))
+ (define-key ispell-menu-map [ispell-message]
+ '(menu-item "Spell-Check Message" ispell-message
+ :help "Skip headers and included message text"))
+ (define-key ispell-menu-map [ispell-buffer]
+ '(menu-item "Spell-Check Buffer" ispell-buffer
+ :help "Check spelling of selected buffer"))
+ ;;(put 'ispell-region 'menu-enable 'mark-active)
+ (fset 'ispell-menu-map (symbol-value 'ispell-menu-map))))
+
+;;; XEmacs versions 19 & 20
+(if (and (featurep 'xemacs)
+ (featurep 'menubar)
+ ;;(null ispell-menu-xemacs)
+ (not (and (boundp 'infodock-version) infodock-version)))
+ (let ((dicts (if (fboundp 'ispell-valid-dictionary-list)
+ (reverse (ispell-valid-dictionary-list))))
+ (current-menubar (or current-menubar default-menubar))
+ (menu
+ '(["Help" (describe-function 'ispell-help) t]
+ ;;["Help" (popup-menu ispell-help-list) t]
+ ["Check Message" ispell-message t]
+ ["Check Buffer" ispell-buffer t]
+ ["Check Comments" ispell-comments-and-strings t]
+ ["Check Word" ispell-word t]
+ ["Check Region" ispell-region (or (not zmacs-regions) (mark))]
+ ["Continue Check" ispell-continue t]
+ ["Complete Word Frag"ispell-complete-word-interior-frag t]
+ ["Complete Word" ispell-complete-word t]
+ ["Kill Process" ispell-kill-ispell t]
+ ["Customize..." (customize-group 'ispell) t]
+ ;; flyspell-mode may not be bound...
+ ;;["flyspell" flyspell-mode
+ ;; :style toggle :selected flyspell-mode ]
+ "-"
+ ["Save Personal Dict"(ispell-pdict-save t t) t]
+ ["Change Dictionary" ispell-change-dictionary t])))
+ (if (null dicts)
+ (setq dicts (cons "default" nil)))
+ (dolist (name dicts)
+ (setq menu (append menu
+ (list
+ (vector
+ (concat "Select " (capitalize name))
+ (list 'ispell-change-dictionary name)
+ t)))))
+ (setq ispell-menu-xemacs menu)
+ (if current-menubar
+ (progn
+ (if (car (find-menu-item current-menubar '("Cmds")))
+ (progn
+ ;; XEmacs 21.2
+ (delete-menu-item '("Cmds" "Spell-Check"))
+ (add-menu '("Cmds") "Spell-Check" ispell-menu-xemacs))
+ ;; previous
+ (delete-menu-item '("Edit" "Spell")) ; in case already defined
+ (add-menu '("Edit") "Spell" ispell-menu-xemacs))))))
+
+;;; Allow incrementing characters as integers in XEmacs 20
+(if (and (featurep 'xemacs)
+ (fboundp 'int-char))
+ (fset 'ispell-int-char 'int-char)
+ ;; Emacs and XEmacs 19 or earlier
+ (fset 'ispell-int-char 'identity))
+
+
+;;; **********************************************************************
+
+
+;;; This variable contains the current dictionary being used if the ispell
+;;; process is running. Otherwise it contains the global default.
+(defvar ispell-dictionary nil
+ "The name of the current dictionary, or nil for the default.
+When `ispell-local-dictionary' is nil, `ispell-dictionary' is used to select
+the dictionary for new buffers.
+
+This is passed to the ispell process using the `-d' switch and is
+used as key in `ispell-dictionary-alist' (which see).")
+
+(defun ispell-decode-string (str)
+ "Decodes multibyte character strings.
+Protects against bogus binding of `enable-multibyte-characters' in XEmacs."
+ (if (and (or (featurep 'xemacs)
+ (and (boundp 'enable-multibyte-characters)
+ enable-multibyte-characters))
+ (fboundp 'decode-coding-string)
+ (ispell-get-coding-system))
+ (decode-coding-string str (ispell-get-coding-system))
+ str))
+
+(defun ispell-get-casechars ()
+ (ispell-decode-string
+ (nth 1 (assoc ispell-dictionary ispell-dictionary-alist))))
+(defun ispell-get-not-casechars ()
+ (ispell-decode-string
+ (nth 2 (assoc ispell-dictionary ispell-dictionary-alist))))
+(defun ispell-get-otherchars ()
+ (ispell-decode-string
+ (nth 3 (assoc ispell-dictionary ispell-dictionary-alist))))
+(defun ispell-get-many-otherchars-p ()
+ (nth 4 (assoc ispell-dictionary ispell-dictionary-alist)))
+(defun ispell-get-ispell-args ()
+ (nth 5 (assoc ispell-dictionary ispell-dictionary-alist)))
+(defun ispell-get-extended-character-mode ()
+ (nth 6 (assoc ispell-dictionary ispell-dictionary-alist)))
+(defun ispell-get-coding-system ()
+ (nth 7 (assoc ispell-dictionary ispell-dictionary-alist)))
+
+
+(defvar ispell-pdict-modified-p nil
+ "Non-nil means personal dictionary has modifications to be saved.")
+
+;;; If you want to save the dictionary when quitting, must do so explicitly.
+;;; When non-nil, the spell session is terminated.
+;;; When numeric, contains cursor location in buffer, and cursor remains there.
+(defvar ispell-quit nil)
+
+(defvar ispell-process-directory nil
+ "The directory where `ispell-process' was started.")
+
+(defvar ispell-filter nil
+ "Output filter from piped calls to Ispell.")
+
+(defvar ispell-filter-continue nil
+ "Control variable for Ispell filter function.")
+
+(defvar ispell-output-buffer nil
+ "Buffer used for reading output of a synchronous Ispell subprocess.")
+
+(defvar ispell-session-buffer nil
+ "Buffer used for passing input to a synchronous Ispell subprocess.")
+
+(defvar ispell-cmd-args nil
+ "Command-line arguments to pass to a synchronous Ispell subprocess.")
+
+(defvar ispell-query-replace-marker (make-marker)
+ "Marker for `query-replace' processing.")
+
+(defvar ispell-recursive-edit-marker (make-marker)
+ "Marker for return point from recursive edit.")
+
+(defvar ispell-checking-message nil
+ "Non-nil when we're checking a mail message.
+Set to the MIME boundary locations when checking messages.")
+
+(defconst ispell-choices-buffer "*Choices*")
+
+(defvar ispell-overlay nil "Overlay variable for Ispell highlighting.")
+
+;;; *** Buffer Local Definitions ***
+
+(defconst ispell-words-keyword "LocalWords: "
+ "The keyword for local oddly-spelled words to accept.
+The keyword will be followed by any number of local word spellings.
+There can be multiple of these keywords in the file.")
+
+(defconst ispell-dictionary-keyword "Local IspellDict: "
+ "The keyword for a local dictionary to use.
+The keyword must be followed by a correct dictionary name in
+`ispell-dictionary-alist'. When multiple occurrences exist, the last keyword
+definition is used.")
+
+(defconst ispell-pdict-keyword "Local IspellPersDict: "
+ "The keyword for defining buffer local dictionaries.
+Keyword must be followed by the filename of a personal dictionary.
+The last occurring definition in the buffer will be used.")
+
+(defconst ispell-parsing-keyword "Local IspellParsing: "
+ "The keyword for overriding default Ispell parsing.
+The above keyword string should be followed by `latex-mode' or
+`nroff-mode' to put the current buffer into the desired parsing mode.
+
+Extended character mode can be changed for this buffer by placing
+a `~' followed by an extended-character mode -- such as `~.tex'.
+The last occurring definition in the buffer will be used.")
+
+(defvar ispell-tib-ref-beginning "[[<]\\."
+ "Regexp matching the beginning of a Tib reference.")
+
+(defvar ispell-tib-ref-end "\\.[]>]"
+ "Regexp matching the end of a Tib reference.")
+
+;;;###autoload
+(defvar ispell-skip-region-alist
+ '((ispell-words-keyword forward-line)
+ (ispell-dictionary-keyword forward-line)
+ (ispell-pdict-keyword forward-line)
+ (ispell-parsing-keyword forward-line)
+ ("^---*BEGIN PGP [A-Z ]*--*" . "^---*END PGP [A-Z ]*--*")
+ ;; assume multiline uuencoded file? "\nM.*$"?
+ ("^begin [0-9][0-9][0-9] [^ \t]+$" . "\nend\n")
+ ("^%!PS-Adobe-[123].0" . "\n%%EOF\n")
+ ;; Matches e-mail addresses, file names, http addresses, etc. The `-+'
+ ;; pattern necessary for performance reasons when `-' part of word syntax.
+ ("\\(--+\\|\\(/\\w\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")
+ ;; above checks /.\w sequences
+ ;;("\\(--+\\|\\(/\\|\\(\\(\\w\\|[-_]\\)+[.:@]\\)\\)\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_~=?&]\\)+\\)+\\)")
+ ;; This is a pretty complex regexp. It can be simplified to the following:
+ ;; "\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+"
+ ;; but some valid text will be skipped, e.g. "his/her". This could be
+ ;; fixed up (at the expense of a moderately more complex regexp)
+ ;; by not allowing "/" to be the character which triggers the
+ ;; identification of the computer name, e.g.:
+ ;; "\\(\\w\\|[-_]\\)+[.:@]\\(\\w\\|[-_]\\)*\\([.:/@]+\\(\\w\\|[-_]\\|~\\)+\\)+"
+ )
+ "Alist expressing beginning and end of regions not to spell check.
+The alist key must be a regular expression.
+Valid forms include:
+ (KEY) - just skip the key.
+ (KEY . REGEXP) - skip to the end of REGEXP. REGEXP may be string or symbol.
+ (KEY REGEXP) - skip to end of REGEXP. REGEXP must be a string.
+ (KEY FUNCTION ARGS) - FUNCTION called with ARGS returns end of region.")
+
+
+
+;;;###autoload
+(defvar ispell-tex-skip-alists
+ '((;;("%\\[" . "%\\]") ; AMStex block comment...
+ ;; All the standard LaTeX keywords from L. Lamport's guide:
+ ;; \cite, \hspace, \hspace*, \hyphenation, \include, \includeonly, \input,
+ ;; \label, \nocite, \rule (in ispell - rest included here)
+ ("\\\\addcontentsline" ispell-tex-arg-end 2)
+ ("\\\\add\\(tocontents\\|vspace\\)" ispell-tex-arg-end)
+ ("\\\\\\([aA]lph\\|arabic\\)" ispell-tex-arg-end)
+ ;;("\\\\author" ispell-tex-arg-end)
+ ("\\\\bibliographystyle" ispell-tex-arg-end)
+ ("\\\\makebox" ispell-tex-arg-end 0)
+ ("\\\\e?psfig" ispell-tex-arg-end)
+ ("\\\\document\\(class\\|style\\)" .
+ "\\\\begin[ \t\n]*{[ \t\n]*document[ \t\n]*}"))
+ (;; delimited with \begin. In ispell: displaymath, eqnarray, eqnarray*,
+ ;; equation, minipage, picture, tabular, tabular* (ispell)
+ ("\\(figure\\|table\\)\\*?" ispell-tex-arg-end 0)
+ ("list" ispell-tex-arg-end 2)
+ ("program" . "\\\\end[ \t\n]*{[ \t\n]*program[ \t\n]*}")
+ ("verbatim\\*?" . "\\\\end[ \t\n]*{[ \t\n]*verbatim\\*?[ \t\n]*}")))
+ "*Lists of regions to be skipped in TeX mode.
+First list is used raw.
+Second list has key placed inside \\begin{}.
+
+Delete or add any regions you want to be automatically selected
+for skipping in latex mode.")
+
+
+;;;###autoload
+(defvar ispell-html-skip-alists
+ '(("<[cC][oO][dD][eE]\\>[^>]*>" "</[cC][oO][dD][eE]*>")
+ ("<[sS][cC][rR][iI][pP][tT]\\>[^>]*>" "</[sS][cC][rR][iI][pP][tT]>")
+ ("<[aA][pP][pP][lL][eE][tT]\\>[^>]*>" "</[aA][pP][pP][lL][eE][tT]>")
+ ("<[vV][eE][rR][bB]\\>[^>]*>" "<[vV][eE][rR][bB]\\>[^>]*>")
+ ;;("<[tT][tT]\\>[^>]*>" "<[tT][tT]\\>[^>]*>")
+ ("<[tT][tT]/" "/")
+ ("<[^ \t\n>]" ">")
+ ("&[^ \t\n;]" "[; \t\n]"))
+ "*Lists of start and end keys to skip in HTML buffers.
+Same format as `ispell-skip-region-alist'
+Note - substrings of other matches must come last
+ (e.g. \"<[tT][tT]/\" and \"<[^ \t\n>]\").")
+
+
+;;;###autoload
+(defvar ispell-po-mode-skip-alists
+ '(("^\\(#~ \\)?msgid" . "^\\(#~ \\)?msgstr")
+ ("^#[:,]" . "\n"))
+ "*Start and end keys to skip undesired language text in po-mode buffers.")
+
+(defvar ispell-local-pdict ispell-personal-dictionary
+ "A buffer local variable containing the current personal dictionary.
+If non-nil, the value must be a string, which is a file name.
+
+If you specify a personal dictionary for the current buffer which is
+different from the current personal dictionary, the effect is similar
+to calling \\[ispell-change-dictionary]. This variable is automatically
+set when defined in the file with either `ispell-pdict-keyword' or the
+local variable syntax.")
+
+(make-variable-buffer-local 'ispell-local-pdict)
+
+(defvar ispell-buffer-local-name nil
+ "Contains the buffer name if local word definitions were used.
+Ispell is then restarted because the local words could conflict.")
+
+(defvar ispell-region-end (make-marker)
+ "Marker that allows spelling continuations.")
+
+(defvar ispell-check-only nil
+ "If non-nil, `ispell-word' does not try to correct the word.")
+
+(defvar ispell-parser-mode nil
+ "The regular expression mode for parsing the current region.")
+
+;;; **********************************************************************
+;;; **********************************************************************
+
+
+
+;;;###autoload
+(define-key esc-map "$" 'ispell-word)
+
+
+(defun ispell-accept-output (&optional timeout-secs timeout-msecs)
+ "Wait for output from ispell process, or TIMEOUT-SECS and TIMEOUT-MSECS.
+If asynchronous subprocesses are not supported, call `ispell-filter' and
+pass it the output of the last ispell invocation."
+ (if ispell-async-processp
+ (accept-process-output ispell-process timeout-secs timeout-msecs)
+ (if (null ispell-process)
+ (error "No Ispell process to read output from!")
+ (let ((buf ispell-output-buffer)
+ ispell-output)
+ (if (not (bufferp buf))
+ (setq ispell-filter nil)
+ (save-excursion
+ (set-buffer buf)
+ (setq ispell-output (buffer-substring-no-properties
+ (point-min) (point-max))))
+ (ispell-filter t ispell-output)
+ (save-excursion
+ (set-buffer buf)
+ (erase-buffer)))))))
+
+
+(defun ispell-send-string (string)
+ "Send the string STRING to the Ispell process."
+ (if ispell-async-processp
+ (process-send-string ispell-process string)
+ ;; Asynchronous subprocesses aren't supported on this losing system.
+ ;; We keep all the directives passed to Ispell during the entire
+ ;; session in a buffer, and pass them anew each time we invoke
+ ;; Ispell to process another chunk of text. (Yes, I know this is a
+ ;; terrible kludge, and it's a bit slow, but it does get the work done.)
+ (let ((cmd (aref string 0))
+ ;; The following commands are not passed to Ispell until
+ ;; we have a *real* reason to invoke it.
+ (cmds-to-defer '(?* ?@ ?~ ?+ ?- ?! ?%))
+ (default-major-mode 'fundamental-mode)
+ (session-buf ispell-session-buffer)
+ (output-buf ispell-output-buffer)
+ (ispell-args ispell-cmd-args)
+ (defdir ispell-process-directory)
+ prev-pos)
+ (save-excursion
+ (set-buffer session-buf)
+ (setq prev-pos (point))
+ (setq default-directory defdir)
+ (insert string)
+ (if (not (memq cmd cmds-to-defer))
+ (let (coding-system-for-read coding-system-for-write status)
+ (if (and (boundp 'enable-multibyte-characters)
+ enable-multibyte-characters)
+ (setq coding-system-for-read (ispell-get-coding-system)
+ coding-system-for-write (ispell-get-coding-system)))
+ (set-buffer output-buf)
+ (erase-buffer)
+ (set-buffer session-buf)
+ (setq status
+ (apply 'call-process-region (point-min) (point-max)
+ ispell-program-name nil
+ output-buf nil
+ "-a" "-m" ispell-args))
+ (set-buffer output-buf)
+ (goto-char (point-min))
+ (save-match-data
+ (if (not (looking-at "@(#) "))
+ (progn
+ (error "Ispell error: %s"
+ (buffer-substring-no-properties
+ (point) (progn (end-of-line) (point))))
+ (sit-for 5)))
+ ;; If STRING is "^Z\n", we just started Ispell and need
+ ;; to retain its version ID line in the output buffer.
+ ;; Otherwise, remove the ID line, as it will confuse
+ ;; `ispell-filter'.
+ (or (string= string "\032\n")
+ (progn
+ (forward-line)
+ (delete-region (point-min) (point))))
+ ;; If STRING begins with ^ or any normal character, we need
+ ;; to remove the last line from the session buffer, since it
+ ;; was just spell-checked, and we don't want to check it again.
+ ;; The same goes for the # command, since Ispell already saved
+ ;; the personal dictionary.
+ (set-buffer session-buf)
+ (delete-region prev-pos (point))
+ ;; Ispell run synchronously saves the personal dictionary
+ ;; after each successful command. So we can remove any
+ ;; lines in the session buffer that insert words into the
+ ;; dictionary.
+ (if (memq status '(0 nil))
+ (let ((more-lines t))
+ (goto-char (point-min))
+ (while more-lines
+ (if (looking-at "^\\*")
+ (let ((start (point)))
+ (forward-line)
+ (delete-region start (point)))
+ (setq more-lines (= 0 (forward-line))))))))))))))
+
+
+
+;;;###autoload
+(defun ispell-word (&optional following quietly continue)
+ "Check spelling of word under or before the cursor.
+If the word is not found in dictionary, display possible corrections
+in a window allowing you to choose one.
+
+If optional argument FOLLOWING is non-nil or if `ispell-following-word'
+is non-nil when called interactively, then the following word
+\(rather than preceding\) is checked when the cursor is not over a word.
+When the optional argument QUIETLY is non-nil or `ispell-quietly' is non-nil
+when called interactively, non-corrective messages are suppressed.
+
+With a prefix argument (or if CONTINUE is non-nil),
+resume interrupted spell-checking of a buffer or region.
+
+Word syntax described by `ispell-dictionary-alist' (which see).
+
+This will check or reload the dictionary. Use \\[ispell-change-dictionary]
+or \\[ispell-region] to update the Ispell process.
+
+return values:
+nil word is correct or spelling is accepted.
+0 word is inserted into buffer-local definitions.
+\"word\" word corrected from word list.
+\(\"word\" arg\) word is hand entered.
+quit spell session exited."
+
+ (interactive (list nil nil current-prefix-arg))
+ (if continue
+ (ispell-continue)
+ (if (interactive-p)
+ (setq following ispell-following-word
+ quietly ispell-quietly))
+ (ispell-accept-buffer-local-defs) ; use the correct dictionary
+ (let ((cursor-location (point)) ; retain cursor location
+ (word (ispell-get-word following))
+ start end poss new-word replace)
+ ;; De-structure return word info list.
+ (setq start (car (cdr word))
+ end (car (cdr (cdr word)))
+ word (car word))
+
+ ;; now check spelling of word if it has 3 or more characters.
+ (cond
+ ((> (length word) 2)
+ (or quietly
+ (message "Checking spelling of %s..."
+ (funcall ispell-format-word word)))
+ (ispell-send-string "%\n") ; put in verbose mode
+ (ispell-send-string (concat "^" word "\n"))
+ ;; wait until ispell has processed word
+ (while (progn
+ (ispell-accept-output)
+ (not (string= "" (car ispell-filter)))))
+ ;;(ispell-send-string "!\n") ;back to terse mode.
+ (setq ispell-filter (cdr ispell-filter)) ; remove extra \n
+ (if (and ispell-filter (listp ispell-filter))
+ (if (> (length ispell-filter) 1)
+ (error "Ispell and its process have different character maps")
+ (setq poss (ispell-parse-output (car ispell-filter)))))
+ (cond ((eq poss t)
+ (or quietly
+ (message "%s is correct"
+ (funcall ispell-format-word word)))
+ (and (fboundp 'extent-at)
+ (extent-at start)
+ (delete-extent (extent-at start))))
+ ((stringp poss)
+ (or quietly
+ (message "%s is correct because of root %s"
+ (funcall ispell-format-word word)
+ (funcall ispell-format-word poss)))
+ (and (fboundp 'extent-at)
+ (extent-at start)
+ (delete-extent (extent-at start))))
+ ((null poss) (message "Error in ispell process"))
+ (ispell-check-only ; called from ispell minor mode.
+ (if (fboundp 'make-extent)
+ (let ((ext (make-extent start end)))
+ (set-extent-property ext 'face ispell-highlight-face)
+ (set-extent-property ext 'priority 2000))
+ (beep)
+ (message "%s is incorrect"(funcall ispell-format-word word))))
+ (t ; prompt for correct word.
+ (save-window-excursion
+ (setq replace (ispell-command-loop
+ (car (cdr (cdr poss)))
+ (car (cdr (cdr (cdr poss))))
+ (car poss) start end)))
+ (cond ((equal 0 replace)
+ (ispell-add-per-file-word-list (car poss)))
+ (replace
+ (setq new-word (if (atom replace) replace (car replace))
+ cursor-location (+ (- (length word) (- end start))
+ cursor-location))
+ (if (not (equal new-word (car poss)))
+ (progn
+ (delete-region start end)
+ (setq start (point))
+ (insert new-word)
+ (setq end (point))))
+ (if (not (atom replace)) ;recheck spelling of replacement
+ (progn
+ (if (car (cdr replace)) ; query replace requested
+ (save-window-excursion
+ (query-replace word new-word t)))
+ (goto-char start)
+ ;; single word could be split into multiple words
+ (setq ispell-quit (not (ispell-region start end)))
+ ))))
+ ;; keep if rechecking word and we keep choices win.
+ (if (get-buffer ispell-choices-buffer)
+ (kill-buffer ispell-choices-buffer))))
+ (ispell-pdict-save ispell-silently-savep)
+ ;; NB: Cancels ispell-quit incorrectly if called from ispell-region
+ (if ispell-quit (setq ispell-quit nil replace 'quit))))
+ (goto-char cursor-location) ; return to original location
+ replace)))
+
+
+(defun ispell-get-word (following &optional extra-otherchars)
+ "Return the word for spell-checking according to ispell syntax.
+If optional argument FOLLOWING is non-nil or if `ispell-following-word'
+is non-nil when called interactively, then the following word
+\(rather than preceding\) is checked when the cursor is not over a word.
+Optional second argument contains otherchars that can be included in word
+many times.
+
+Word syntax described by `ispell-dictionary-alist' (which see)."
+ (let* ((ispell-casechars (ispell-get-casechars))
+ (ispell-not-casechars (ispell-get-not-casechars))
+ (ispell-otherchars (ispell-get-otherchars))
+ (ispell-many-otherchars-p (ispell-get-many-otherchars-p))
+ (word-regexp (concat ispell-casechars
+ "+\\("
+ (if (not (string= "" ispell-otherchars))
+ (concat ispell-otherchars "?"))
+ (if extra-otherchars
+ (concat extra-otherchars "?"))
+ ispell-casechars
+ "+\\)"
+ (if (or ispell-many-otherchars-p
+ extra-otherchars)
+ "*" "?")))
+ did-it-once prevpt
+ start end word)
+ ;; find the word
+ (if (not (looking-at ispell-casechars))
+ (if following
+ (re-search-forward ispell-casechars (point-max) t)
+ (re-search-backward ispell-casechars (point-min) t)))
+ ;; move to front of word
+ (re-search-backward ispell-not-casechars (point-min) 'start)
+ (while (and (or (and (not (string= "" ispell-otherchars))
+ (looking-at ispell-otherchars))
+ (and extra-otherchars (looking-at extra-otherchars)))
+ (not (bobp))
+ (or (not did-it-once)
+ ispell-many-otherchars-p)
+ (not (eq prevpt (point))))
+ (if (and extra-otherchars (looking-at extra-otherchars))
+ (progn
+ (backward-char 1)
+ (if (looking-at ispell-casechars)
+ (re-search-backward ispell-not-casechars (point-min) 'move)))
+ (setq did-it-once t
+ prevpt (point))
+ (backward-char 1)
+ (if (looking-at ispell-casechars)
+ (re-search-backward ispell-not-casechars (point-min) 'move)
+ (backward-char -1))))
+ ;; Now mark the word and save to string.
+ (if (not (re-search-forward word-regexp (point-max) t))
+ (if ispell-check-only
+ ;; return dummy word when just flagging misspellings
+ (list "" (point) (point))
+ (error "No word found to check!"))
+ (setq start (match-beginning 0)
+ end (point)
+ word (buffer-substring-no-properties start end))
+ (list word start end))))
+
+
+;;; Global ispell-pdict-modified-p is set by ispell-command-loop and
+;;; tracks changes in the dictionary. The global may either be
+;;; a value or a list, whose value is the state of whether the
+;;; dictionary needs to be saved.
+
+;;;###autoload
+(defun ispell-pdict-save (&optional no-query force-save)
+ "Check to see if the personal dictionary has been modified.
+If so, ask if it needs to be saved."
+ (interactive (list ispell-silently-savep t))
+ (if (and ispell-pdict-modified-p (listp ispell-pdict-modified-p))
+ (setq ispell-pdict-modified-p (car ispell-pdict-modified-p)))
+ (if (or ispell-pdict-modified-p force-save)
+ (if (or no-query (y-or-n-p "Personal dictionary modified. Save? "))
+ (progn
+ (ispell-send-string "#\n") ; save dictionary
+ (message "Personal dictionary saved."))))
+ ;; unassert variable, even if not saved to avoid questioning.
+ (setq ispell-pdict-modified-p nil))
+
+
+(defun ispell-command-loop (miss guess word start end)
+ "Display possible corrections from list MISS.
+GUESS lists possibly valid affix construction of WORD.
+Returns nil to keep word.
+Returns 0 to insert locally into buffer-local dictionary.
+Returns string for new chosen word.
+Returns list for new replacement word (will be rechecked).
+ Query-replace when list length is 2.
+ Automatic query-replace when second element is `query-replace'.
+Highlights the word, which is assumed to run from START to END.
+Global `ispell-pdict-modified-p' becomes a list where the only value
+indicates whether the dictionary has been modified when option `a' or `i' is
+used.
+Global `ispell-quit' set to start location to continue spell session."
+ (let ((count ?0)
+ (line ispell-choices-win-default-height)
+ ;; ensure 4 context lines.
+ (max-lines (- (ispell-adjusted-window-height) 4))
+ (choices miss)
+ (window-min-height (min window-min-height
+ ispell-choices-win-default-height))
+ (command-characters '( ? ?i ?a ?A ?r ?R ?? ?x ?X ?q ?l ?u ?m ))
+ (dedicated (window-dedicated-p (selected-window)))
+ (skipped 0)
+ char num result textwin dedicated-win)
+
+ ;; setup the *Choices* buffer with valid data.
+ (save-excursion
+ (set-buffer (get-buffer-create ispell-choices-buffer))
+ (setq mode-line-format (concat "-- %b -- word: " word))
+ ;; XEmacs: no need for horizontal scrollbar in choices window
+ (and (fboundp 'set-specifier)
+ (boundp 'horizontal-scrollbar-visible-p)
+ (set-specifier horizontal-scrollbar-visible-p nil
+ (cons (current-buffer) nil)))
+ (erase-buffer)
+ (if guess
+ (progn
+ (insert "Affix rules generate and capitalize "
+ "this word as shown below:\n\t")
+ (while guess
+ (if (> (+ 4 (current-column) (length (car guess)))
+ (window-width))
+ (progn
+ (insert "\n\t")
+ (setq line (1+ line))))
+ (insert (car guess) " ")
+ (setq guess (cdr guess)))
+ (insert "\nUse option `i' if this is a correct composition"
+ " from the derivative root.\n")
+ (setq line (+ line (if choices 3 2)))))
+ (while (and choices
+ (< (if (> (+ 7 (current-column) (length (car choices))
+ (if (> count ?~) 3 0))
+ (window-width))
+ (progn
+ (insert "\n")
+ (setq line (1+ line)))
+ line)
+ max-lines))
+ ;; not so good if there are over 20 or 30 options, but then, if
+ ;; there are that many you don't want to scan them all anyway...
+ (while (memq count command-characters) ; skip command characters.
+ (setq count (ispell-int-char (1+ count))
+ skipped (1+ skipped)))
+ (insert "(" count ") " (car choices) " ")
+ (setq choices (cdr choices)
+ count (ispell-int-char (1+ count))))
+ (setq count (ispell-int-char (- count ?0 skipped))))
+
+ ;; ensure word is visible
+ (if (not (pos-visible-in-window-p end))
+ (sit-for 0))
+
+ ;; allow temporary split of dedicated windows...
+ (if dedicated
+ (progn
+ (setq dedicated-win (selected-window))
+ (set-window-dedicated-p dedicated-win nil)))
+
+ ;; Display choices for misspelled word.
+ (ispell-show-choices line end)
+ (select-window (setq textwin (next-window)))
+
+ ;; highlight word, protecting current buffer status
+ (unwind-protect
+ (progn
+ (and ispell-highlight-p
+ (ispell-highlight-spelling-error start end t))
+ ;; Loop until a valid choice is made.
+ (while
+ (eq
+ t
+ (setq
+ result
+ (progn
+ (undo-boundary)
+ (let (message-log-max)
+ (message (concat "C-h or ? for more options; SPC to leave "
+ "unchanged, Character to replace word")))
+ (let ((inhibit-quit t))
+ (setq char (if (fboundp 'read-char-exclusive)
+ (read-char-exclusive)
+ (read-char))
+ skipped 0)
+ (if (or quit-flag (= char ?\C-g)) ; C-g is like typing X
+ (setq char ?X
+ quit-flag nil)))
+ ;; Adjust num to array offset skipping command characters.
+ (let ((com-chars command-characters))
+ (while com-chars
+ (if (and (> (car com-chars) ?0) (< (car com-chars) char))
+ (setq skipped (1+ skipped)))
+ (setq com-chars (cdr com-chars)))
+ (setq num (- char ?0 skipped)))
+
+ (cond
+ ((= char ? ) nil) ; accept word this time only
+ ((= char ?i) ; accept and insert word into pers dict
+ (ispell-send-string (concat "*" word "\n"))
+ (setq ispell-pdict-modified-p '(t)) ; dictionary modified!
+ nil)
+ ((or (= char ?a) (= char ?A)) ; accept word without insert
+ (ispell-send-string (concat "@" word "\n"))
+ (if (null ispell-pdict-modified-p)
+ (setq ispell-pdict-modified-p
+ (list ispell-pdict-modified-p)))
+ (if (= char ?A) 0)) ; return 0 for ispell-add buffer-local
+ ((or (= char ?r) (= char ?R)) ; type in replacement
+ (and (eq 'block ispell-highlight-p) ; refresh tty's
+ (ispell-highlight-spelling-error start end nil t))
+ (let ((result
+ (if (or (= char ?R) ispell-query-replace-choices)
+ (list (read-string
+ (format "Query-replacement for %s: "word)
+ word)
+ t)
+ (cons (read-string "Replacement for: " word)
+ nil))))
+ (and (eq 'block ispell-highlight-p)
+ (ispell-highlight-spelling-error start end nil
+ 'block))
+ result))
+ ((or (= char ??) (= char help-char) (= char ?\C-h))
+ (and (eq 'block ispell-highlight-p)
+ (ispell-highlight-spelling-error start end nil t))
+ (ispell-help)
+ (and (eq 'block ispell-highlight-p)
+ (ispell-highlight-spelling-error start end nil
+ 'block))
+ t)
+ ;; Quit and move point back.
+ ((= char ?x)
+ (ispell-pdict-save ispell-silently-savep)
+ (message "Exited spell-checking")
+ (setq ispell-quit t)
+ nil)
+ ;; Quit and preserve point.
+ ((= char ?X)
+ (ispell-pdict-save ispell-silently-savep)
+ (message "%s"
+ (substitute-command-keys
+ (concat "Spell-checking suspended;"
+ " use C-u \\[ispell-word] to resume")))
+ (setq ispell-quit start)
+ nil)
+ ((= char ?q)
+ (if (y-or-n-p "Really kill Ispell process? ")
+ (progn
+ (ispell-kill-ispell t) ; terminate process.
+ (setq ispell-quit (or (not ispell-checking-message)
+ (point))
+ ispell-pdict-modified-p nil))
+ t)) ; continue if they don't quit.
+ ((= char ?l)
+ (and (eq 'block ispell-highlight-p) ; refresh tty displays
+ (ispell-highlight-spelling-error start end nil t))
+ (let ((new-word (read-string
+ "Lookup string (`*' is wildcard): "
+ word)))
+ (if new-word
+ (progn
+ (save-excursion
+ (set-buffer (get-buffer-create
+ ispell-choices-buffer))
+ (erase-buffer)
+ (setq count ?0
+ skipped 0
+ mode-line-format (concat
+ "-- %b -- word: "
+ new-word)
+ miss (lookup-words new-word)
+ choices miss
+ line ispell-choices-win-default-height)
+ (while (and choices ; adjust choices window.
+ (< (if (> (+ 7 (current-column)
+ (length (car choices))
+ (if (> count ?~) 3 0))
+ (window-width))
+ (progn
+ (insert "\n")
+ (setq line (1+ line)))
+ line)
+ max-lines))
+ (while (memq count command-characters)
+ (setq count (ispell-int-char (1+ count))
+ skipped (1+ skipped)))
+ (insert "(" count ") " (car choices) " ")
+ (setq choices (cdr choices)
+ count (ispell-int-char (1+ count))))
+ (setq count (ispell-int-char
+ (- count ?0 skipped))))
+ (ispell-show-choices line end)
+ (select-window (next-window)))))
+ (and (eq 'block ispell-highlight-p)
+ (ispell-highlight-spelling-error start end nil
+ 'block))
+ t) ; reselect from new choices
+ ((= char ?u) ; insert lowercase into dictionary
+ (ispell-send-string (concat "*" (downcase word) "\n"))
+ (setq ispell-pdict-modified-p '(t)) ; dictionary modified!
+ nil)
+ ((= char ?m) ; type in what to insert
+ (ispell-send-string
+ (concat "*" (read-string "Insert: " word) "\n"))
+ (setq ispell-pdict-modified-p '(t))
+ (cons word nil))
+ ((and (>= num 0) (< num count))
+ (if ispell-query-replace-choices ; Query replace flag
+ (list (nth num miss) 'query-replace)
+ (nth num miss)))
+ ((= char ?\C-l)
+ (redraw-display) t)
+ ((= char ?\C-r)
+ ;; This may have alignment errors if current line is edited
+ (if (marker-position ispell-recursive-edit-marker)
+ (progn
+ (message "Only one recursive edit session supported")
+ (beep)
+ (sit-for 2))
+ (set-marker ispell-recursive-edit-marker start)
+ ;;(set-marker ispell-region-end reg-end)
+ (and ispell-highlight-p ; unhighlight
+ (ispell-highlight-spelling-error start end))
+ (unwind-protect
+ (progn
+ (message
+ "%s"
+ (substitute-command-keys
+ (concat "Exit recursive edit with"
+ " \\[exit-recursive-edit]")))
+ (save-window-excursion (save-excursion
+ (recursive-edit))))
+ ;; protected
+ (goto-char ispell-recursive-edit-marker)
+ (if (not (equal (marker-buffer
+ ispell-recursive-edit-marker)
+ (current-buffer)))
+ (progn
+ (set-marker ispell-recursive-edit-marker nil)
+ (error
+ "Cannot continue ispell from this buffer.")))
+ (set-marker ispell-recursive-edit-marker nil)))
+ (list word nil)) ; recheck starting at this word.
+ ((= char ?\C-z)
+ (funcall (key-binding "\C-z"))
+ t)
+ (t (ding) t))))))
+ result)
+ ;; protected
+ (and ispell-highlight-p ; unhighlight
+ (save-window-excursion
+ (select-window textwin)
+ (ispell-highlight-spelling-error start end)))
+ (if dedicated
+ (set-window-dedicated-p dedicated-win t)))))
+
+
+
+(defun ispell-show-choices (line end)
+ "Shows the choices in another buffer or frame."
+ (if (and ispell-use-framepop-p (fboundp 'framepop-display-buffer))
+ (framepop-display-buffer ispell-choices-buffer)
+ ;;(if (> (framepop-count-visual-lines ispell-choices-buffer) 1)
+ ;; (progn
+ ;; (framepop-grow (- (framepop-count-visual-lines ispell-choices-buffer) 1))
+ ;; (framepop-show-frame)))
+ (let ((choices-window (get-buffer-window ispell-choices-buffer)))
+ (if choices-window
+ (if (= line (ispell-adjusted-window-height choices-window))
+ (select-window choices-window)
+ ;; *Choices* window changed size. Adjust the choices window
+ ;; without scrolling the spelled window when possible
+ (let ((window-line
+ (- line (ispell-adjusted-window-height choices-window)))
+ (visible (progn (vertical-motion -1) (point))))
+ (if (< line ispell-choices-win-default-height)
+ (setq window-line (+ window-line
+ (- ispell-choices-win-default-height
+ line))))
+ (move-to-window-line 0)
+ (vertical-motion window-line)
+ (set-window-start (selected-window)
+ (if (> (point) visible) visible (point)))
+ (goto-char end)
+ (select-window choices-window)
+ (enlarge-window window-line)))
+ ;; Overlay *Choices* window when it isn't showing
+ (ispell-overlay-window (max line ispell-choices-win-default-height)))
+ (switch-to-buffer ispell-choices-buffer)
+ (goto-char (point-min)))))
+
+
+;;;###autoload
+(defun ispell-help ()
+ "Display a list of the options available when a misspelling is encountered.
+
+Selections are:
+
+DIGIT: Replace the word with a digit offered in the *Choices* buffer.
+SPC: Accept word this time.
+`i': Accept word and insert into private dictionary.
+`a': Accept word for this session.
+`A': Accept word and place in `buffer-local dictionary'.
+`r': Replace word with typed-in value. Rechecked.
+`R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+`?': Show these commands.
+`x': Exit spelling buffer. Move cursor to original point.
+`X': Exit spelling buffer. Leaves cursor at the current point, and permits
+ the aborted check to be completed later.
+`q': Quit spelling session (Kills ispell process).
+`l': Look up typed-in replacement in alternate dictionary. Wildcards okay.
+`u': Like `i', but the word is lower-cased first.
+`m': Place typed-in value in personal dictionary, then recheck current word.
+`C-l': redraws screen
+`C-r': recursive edit
+`C-z': suspend emacs or iconify frame"
+
+ (if (equal ispell-help-in-bufferp 'electric)
+ (progn
+ (require 'ehelp)
+ (with-electric-help
+ (function (lambda ()
+ ;;This shouldn't be necessary: with-electric-help needs
+ ;; an optional argument telling it about the smallest
+ ;; acceptable window-height of the help buffer.
+ ;;(if (< (window-height) 15)
+ ;; (enlarge-window
+ ;; (- 15 (ispell-adjusted-window-height))))
+ (princ "Selections are:
+
+DIGIT: Replace the word with a digit offered in the *Choices* buffer.
+SPC: Accept word this time.
+`i': Accept word and insert into private dictionary.
+`a': Accept word for this session.
+`A': Accept word and place in `buffer-local dictionary'.
+`r': Replace word with typed-in value. Rechecked.
+`R': Replace word with typed-in value. Query-replaced in buffer. Rechecked.
+`?': Show these commands.
+`x': Exit spelling buffer. Move cursor to original point.
+`X': Exit spelling buffer. Leaves cursor at the current point, and permits
+ the aborted check to be completed later.
+`q': Quit spelling session (Kills ispell process).
+`l': Look up typed-in replacement in alternate dictionary. Wildcards okay.
+`u': Like `i', but the word is lower-cased first.
+`m': Place typed-in value in personal dictionary, then recheck current word.
+`C-l': redraws screen
+`C-r': recursive edit
+`C-z': suspend emacs or iconify frame")
+ nil ;undocumented requirement of with-electric-help
+ ))))
+
+
+ (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; "
+ "[i]nsert into private dictionary"))
+ (help-2 (concat "[l]ook a word up in alternate dictionary; "
+ "e[x/X]it; [q]uit session"))
+ (help-3 (concat "[u]ncapitalized insert into dict. "
+ "Type 'x C-h d ispell-help' for more help")))
+ (save-window-excursion
+ (if ispell-help-in-bufferp
+ (progn
+ (ispell-overlay-window 4)
+ (switch-to-buffer (get-buffer-create "*Ispell Help*"))
+ (insert (concat help-1 "\n" help-2 "\n" help-3))
+ (sit-for 5)
+ (kill-buffer "*Ispell Help*"))
+ (unwind-protect
+ (progn
+ (select-window (minibuffer-window))
+ (erase-buffer)
+ (message nil)
+ ;;(set-minibuffer-window (selected-window))
+ (enlarge-window 2)
+ (insert (concat help-1 "\n" help-2 "\n" help-3))
+ (sit-for 5))
+ (erase-buffer)))))))
+
+
+(defun lookup-words (word &optional lookup-dict)
+ "Look up WORD in optional word-list dictionary LOOKUP-DICT.
+A `*' serves as a wild card. If no wild cards, `look' is used if it exists.
+Otherwise the variable `ispell-grep-command' contains the command used to
+search for the words (usually egrep).
+
+Optional second argument contains the dictionary to use; the default is
+`ispell-alternate-dictionary'."
+ ;; We don't use the filter for this function, rather the result is written
+ ;; into a buffer. Hence there is no need to save the filter values.
+ (if (null lookup-dict)
+ (setq lookup-dict ispell-alternate-dictionary))
+
+ (let* ((process-connection-type ispell-use-ptys-p)
+ (wild-p (string-match "\\*" word))
+ (look-p (and ispell-look-p ; Only use look for an exact match.
+ (or ispell-have-new-look (not wild-p))))
+ (ispell-grep-buffer (get-buffer-create "*Ispell-Temp*")) ; result buf
+ (prog (if look-p ispell-look-command ispell-grep-command))
+ (args (if look-p ispell-look-options ispell-grep-options))
+ status results loc)
+ (unwind-protect
+ (save-window-excursion
+ (message "Starting \"%s\" process..." (file-name-nondirectory prog))
+ (set-buffer ispell-grep-buffer)
+ (if look-p
+ nil
+ ;; convert * to .*
+ (insert "^" word "$")
+ (while (search-backward "*" nil t) (insert "."))
+ (setq word (buffer-string))
+ (erase-buffer))
+ (setq status (if lookup-dict
+ (call-process prog nil t nil args word lookup-dict)
+ (call-process prog nil t nil args word)))
+ ;; grep returns status 1 and no output when word not found, which
+ ;; is a perfectly normal thing.
+ (if (stringp status)
+ (setq results (cons (format "error: %s exited with signal %s"
+ (file-name-nondirectory prog) status)
+ results))
+ ;; else collect words into `results' in FIFO order
+ (goto-char (point-max))
+ ;; assure we've ended with \n
+ (or (bobp) (= (preceding-char) ?\n) (insert ?\n))
+ (while (not (bobp))
+ (setq loc (point))
+ (forward-line -1)
+ (setq results (cons (buffer-substring-no-properties (point)
+ (1- loc))
+ results)))))
+ ;; protected
+ (kill-buffer ispell-grep-buffer)
+ (if (and results (string-match ".+: " (car results)))
+ (error "%s error: %s" ispell-grep-command (car results))))
+ results))
+
+
+;;; "ispell-filter" is a list of output lines from the generating function.
+;;; Each full line (ending with \n) is a separate item on the list.
+;;; "output" can contain multiple lines, part of a line, or both.
+;;; "start" and "end" are used to keep bounds on lines when "output" contains
+;;; multiple lines.
+;;; "ispell-filter-continue" is true when we have received only part of a
+;;; line as output from a generating function ("output" did not end with \n)
+;;; THIS FUNCTION WILL FAIL IF THE PROCESS OUTPUT DOESN'T END WITH \n!
+;;; This is the case when a process dies or fails. The default behavior
+;;; in this case treats the next input received as fresh input.
+
+(defun ispell-filter (process output)
+ "Output filter function for ispell, grep, and look."
+ (let ((start 0)
+ (continue t)
+ end)
+ (while continue
+ (setq end (string-match "\n" output start)) ; get text up to the newline.
+ ;; If we get out of sync and ispell-filter-continue is asserted when we
+ ;; are not continuing, treat the next item as a separate list. When
+ ;; ispell-filter-continue is asserted, ispell-filter *should* always be a
+ ;; list!
+
+ ;; Continue with same line (item)?
+ (if (and ispell-filter-continue ispell-filter (listp ispell-filter))
+ ;; Yes. Add it to the prev item
+ (setcar ispell-filter
+ (concat (car ispell-filter) (substring output start end)))
+ ;; No. This is a new line and item.
+ (setq ispell-filter
+ (cons (substring output start end) ispell-filter)))
+ (if (null end)
+ ;; We've completed reading the output, but didn't finish the line.
+ (setq ispell-filter-continue t continue nil)
+ ;; skip over newline, this line complete.
+ (setq ispell-filter-continue nil end (1+ end))
+ (if (= end (length output)) ; No more lines in output
+ (setq continue nil) ; so we can exit the filter.
+ (setq start end)))))) ; else move start to next line of input
+
+
+;;; This function destroys the mark location if it is in the word being
+;;; highlighted.
+(defun ispell-highlight-spelling-error-generic (start end &optional highlight
+ refresh)
+ "Highlight the word from START to END with a kludge using `inverse-video'.
+When the optional third arg HIGHLIGHT is set, the word is highlighted;
+otherwise it is displayed normally.
+Uses block cursor to highlight one character.
+Optional REFRESH will unhighlighted then highlight, using block cursor
+ highlighting when REFRESH is equal to `block'."
+ (and (eq 'block ispell-highlight-p)
+ (or (eq 'block refresh)
+ (setq start (1+ start)))) ; On block non-refresh, inc start.
+ (let ((modified (buffer-modified-p)) ; don't allow this fn to modify buffer
+ (buffer-read-only nil) ; Allow highlighting read-only buffers.
+ (text (buffer-substring-no-properties start end)) ; Save hilight region
+ (inhibit-quit t) ; inhibit interrupt processing here.
+ (buffer-undo-list t)) ; don't clutter the undo list.
+ (goto-char end)
+ (delete-region start end)
+ (insert-char ? (- end start)) ; minimize amount of redisplay
+ (sit-for 0) ; update display
+ (if highlight (setq inverse-video (not inverse-video))) ; toggle video
+ (delete-region start end) ; delete whitespace
+ (insert text) ; insert text in inverse video.
+ (sit-for 0) ; update display showing inverse video.
+ (if (not highlight)
+ (goto-char end)
+ (setq inverse-video (not inverse-video)) ; toggle video
+ (and (eq 'block ispell-highlight-p)
+ (goto-char (1- start)))) ; use block cursor to "highlight" char
+ (set-buffer-modified-p modified) ; don't modify if flag not set.
+ (and refresh ; re-highlight
+ (ispell-highlight-spelling-error-generic
+ (if (eq 'block refresh) start (- start 2)) end t))))
+
+
+(defun ispell-highlight-spelling-error-xemacs (start end &optional highlight)
+ "Highlight the word from START to END using `isearch-highlight'.
+When the optional third arg HIGHLIGHT is set, the word is highlighted,
+otherwise it is displayed normally."
+ (if highlight
+ (isearch-highlight start end)
+ (isearch-dehighlight t))
+ ;;(sit-for 0)
+ )
+
+
+(defun ispell-highlight-spelling-error-overlay (start end &optional highlight)
+ "Highlight the word from START to END using overlays.
+When the optional third arg HIGHLIGHT is set, the word is highlighted
+otherwise it is displayed normally.
+
+The variable `ispell-highlight-face' selects the face to use for highlighting."
+ (if highlight
+ (progn
+ (setq ispell-overlay (make-overlay start end))
+ (overlay-put ispell-overlay 'face ispell-highlight-face))
+ (delete-overlay ispell-overlay)))
+
+
+(defun ispell-highlight-spelling-error (start end &optional highlight refresh)
+ (cond
+ ((featurep 'xemacs)
+ (ispell-highlight-spelling-error-xemacs start end highlight))
+ ((and (featurep 'faces)
+ (or (and (fboundp 'display-color-p) (display-color-p))
+ window-system))
+ (ispell-highlight-spelling-error-overlay start end highlight))
+ (t (ispell-highlight-spelling-error-generic start end highlight refresh))))
+
+(defun ispell-adjusted-window-height (&optional window)
+ "Like `window-height', adjusted to correct for the effect of tall mode-lines.
+The value returned is actually the nominal number of text-lines in the
+window plus 1. On a terminal, this is the same value returned by
+`window-height', but if the window has a mode-line is taller than a normal
+text line, the returned value may be smaller than that from
+`window-height'."
+ (cond ((fboundp 'window-text-height)
+ (1+ (window-text-height window)))
+ ((or (and (fboundp 'display-graphic-p) (display-graphic-p))
+ (and (featurep 'xemacs) window-system))
+ (1- (window-height window)))
+ (t
+ (window-height window))))
+
+(defun ispell-overlay-window (height)
+ "Create a window covering the top HEIGHT lines of the current window.
+Ensure that the line above point is still visible but otherwise avoid
+scrolling the current window. Leave the new window selected."
+ (save-excursion
+ (let ((oldot (save-excursion (vertical-motion -1) (point)))
+ (top (save-excursion (move-to-window-line height) (point))))
+ ;; If line above old point (line starting at oldot) would be
+ ;; hidden by new window, scroll it to just below new win
+ ;; otherwise set top line of other win so it doesn't scroll.
+ (if (< oldot top) (setq top oldot))
+ ;; if frame is unsplitable, temporarily disable that...
+ (if (cdr (assq 'unsplittable (frame-parameters (selected-frame))))
+ (let ((frame (selected-frame)))
+ (modify-frame-parameters frame '((unsplittable . nil)))
+ (split-window nil height)
+ (modify-frame-parameters frame '((unsplittable . t))))
+ (split-window nil height))
+ (let ((deficit (- height (ispell-adjusted-window-height))))
+ (when (> deficit 0)
+ ;; Number of lines the window is still too short. We ensure that
+ ;; there are at least (1- HEIGHT) lines visible in the window.
+ (enlarge-window deficit)
+ (goto-char top)
+ (vertical-motion deficit)
+ (setq top (min (point) oldot))))
+ (set-window-start (next-window) top))))
+
+
+;;; Should we add a compound word match return value?
+(defun ispell-parse-output (output &optional accept-list shift)
+ "Parse the OUTPUT string from Ispell process and return:
+1: t for an exact match.
+2: A string containing the root word matched via suffix removal.
+3: A list of possible correct spellings of the format:
+ (\"ORIGINAL-WORD\" OFFSET MISS-LIST GUESS-LIST)
+ ORIGINAL-WORD is a string of the possibly misspelled word.
+ OFFSET is an integer giving the line offset of the word.
+ MISS-LIST and GUESS-LIST are possibly null lists of guesses and misses.
+4: nil when an error has occurred.
+
+Optional second arg ACCEPT-LIST is list of words already accepted.
+Optional third arg SHIFT is an offset to apply based on previous corrections."
+ (cond
+ ((string= output "") t) ; for startup with pipes...
+ ((string= output "*") t) ; exact match
+ ((string= output "-") t) ; compound word match
+ ((eq (aref output 0) ?+) ; found because of root word
+ (substring output 2)) ; return root word
+ ((equal 0 (string-match "[\ra-zA-Z]" output))
+ (ding) ; error message from ispell!
+ (message (concat "Ispell error: " output))
+ (sit-for 5)
+ nil)
+ (t ; need to process &, ?, and #'s
+ (let ((type (aref output 0)) ; &, ?, or #
+ (original-word (substring output 2 (string-match " " output 2)))
+ (cur-count 0) ; contains number of misses + guesses
+ count miss-list guess-list offset)
+ (setq output (substring output (match-end 0))) ; skip over misspelling
+ (if (eq type ?#)
+ (setq count 0) ; no misses for type #
+ (setq count (string-to-int output) ; get number of misses.
+ output (substring output (1+ (string-match " " output 1)))))
+ (setq offset (string-to-int output))
+ (if (eq type ?#) ; No miss or guess list.
+ (setq output nil)
+ (setq output (substring output (1+ (string-match " " output 1)))))
+ (while output
+ (let ((end (string-match ", \\|\\($\\)" output))) ; end of miss/guess.
+ (setq cur-count (1+ cur-count))
+ (if (> cur-count count)
+ (setq guess-list (cons (substring output 0 end) guess-list))
+ (setq miss-list (cons (substring output 0 end) miss-list)))
+ (if (match-end 1) ; True only when at end of line.
+ (setq output nil) ; no more misses or guesses
+ (setq output (substring output (+ end 2))))))
+ ;; return results. Accept word if it was already accepted.
+ ;; adjust offset.
+ (if (member original-word accept-list)
+ t
+ (list original-word
+ (if (numberp shift) (+ shift offset) offset)
+ (nreverse miss-list) (nreverse guess-list)))))))
+
+
+(defun ispell-process-status ()
+ "Return the status of the Ispell process.
+When asynchronous processes are not supported, `run' is always returned."
+ (if ispell-async-processp
+ (process-status ispell-process)
+ (and ispell-process 'run)))
+
+
+(defun ispell-start-process ()
+ "Start the ispell process, with support for no asynchronous processes.
+Keeps argument list for future ispell invocations for no async support."
+ (let (args)
+ ;; Local dictionary becomes the global dictionary in use.
+ (if ispell-local-dictionary
+ (setq ispell-dictionary ispell-local-dictionary))
+ (setq args (ispell-get-ispell-args))
+ (if (and ispell-dictionary ; use specified dictionary
+ (not (member "-d" args))) ; only define if not overridden
+ (setq args
+ ;;(append (list "-d" ispell-dictionary) args)
+ (append (list "-d"
+ (shell-quote-argument
+ (paths-construct-path (list ispell-dictionary)
+ ispell-library-directory)))
+ args)))
+ (if ispell-personal-dictionary ; use specified pers dict
+ (setq args
+ (append args
+ (list "-p"
+ (expand-file-name ispell-personal-dictionary)))))
+ (setq args (append args ispell-extra-args))
+
+ (if ispell-async-processp
+ (let ((process-connection-type ispell-use-ptys-p))
+ (apply 'start-process
+ "ispell" nil ispell-program-name
+ "-a" ; accept single input lines
+ "-m" ; make root/affix combos not in dict
+ args))
+ (setq ispell-cmd-args args
+ ispell-output-buffer (generate-new-buffer " *ispell-output*")
+ ispell-session-buffer (generate-new-buffer " *ispell-session*"))
+ (ispell-send-string "\032\n") ; so Ispell prints version and exits
+ t)))
+
+
+
+(defun ispell-init-process ()
+ "Check status of Ispell process and start if necessary."
+ (if (and ispell-process
+ (eq (ispell-process-status) 'run)
+ ;; If we're using a personal dictionary, ensure
+ ;; we're in the same default directory!
+ (or (not ispell-personal-dictionary)
+ (equal ispell-process-directory default-directory)))
+ (setq ispell-filter nil ispell-filter-continue nil)
+ ;; may need to restart to select new personal dictionary.
+ (ispell-kill-ispell t)
+ (message "Starting new Ispell process...")
+ (sit-for 0)
+ (if (not ispell-library-directory)
+ (setq ispell-library-directory (ispell-check-version)))
+ (setq ispell-process-directory default-directory
+ ispell-process (ispell-start-process)
+ ispell-filter nil
+ ispell-filter-continue nil)
+ (if ispell-async-processp
+ (set-process-filter ispell-process 'ispell-filter))
+ ;; protect against bogus binding of `enable-multibyte-characters' in XEmacs
+ (if (and (or (featurep 'xemacs)
+ (and (boundp 'enable-multibyte-characters)
+ enable-multibyte-characters))
+ (fboundp 'set-process-coding-system))
+ (set-process-coding-system ispell-process (ispell-get-coding-system)
+ (ispell-get-coding-system)))
+ ;; Get version ID line
+ (ispell-accept-output 3)
+ ;; get more output if filter empty?
+ (if (null ispell-filter) (ispell-accept-output 3))
+ (cond ((null ispell-filter)
+ (error "%s did not output version line" ispell-program-name))
+ ((and
+ (stringp (car ispell-filter))
+ (if (string-match "warning: " (car ispell-filter))
+ (progn
+ (ispell-accept-output 3) ; was warn msg.
+ (stringp (car ispell-filter)))
+ (null (cdr ispell-filter)))
+ (string-match "^@(#) " (car ispell-filter)))
+ ;; got the version line as expected (we already know it's the right
+ ;; version, so don't bother checking again.)
+ nil)
+ (t
+ ;; Otherwise, it must be an error message. Show the user.
+ ;; But first wait to see if some more output is going to arrive.
+ ;; Otherwise we get cool errors like "Can't open ".
+ (sleep-for 1)
+ (ispell-accept-output 3)
+ (error "%s" (mapconcat 'identity ispell-filter "\n"))))
+ (setq ispell-filter nil) ; Discard version ID line
+ (let ((extended-char-mode (ispell-get-extended-character-mode)))
+ (if extended-char-mode ; ~ extended character mode
+ (ispell-send-string (concat extended-char-mode "\n"))))
+ (if ispell-async-processp
+ (process-kill-without-query ispell-process))))
+
+;;;###autoload
+(defun ispell-kill-ispell (&optional no-error)
+ "Kill current Ispell process (so that you may start a fresh one).
+With NO-ERROR, just return non-nil if there was no Ispell running."
+ (interactive)
+ (if (not (and ispell-process
+ (eq (ispell-process-status) 'run)))
+ (or no-error
+ (error "There is no ispell process running!"))
+ (if ispell-async-processp
+ (progn
+ (process-send-eof ispell-process)
+ (if (eq (ispell-process-status) 'run)
+ (ispell-accept-output 1))
+ (if (eq (ispell-process-status) 'run)
+ (kill-process ispell-process))
+ (while (not (or (eq (ispell-process-status) 'exit)
+ (eq (ispell-process-status) 'signal)))
+ (sleep-for 0.25)))
+ ;; synchronous processes
+ (ispell-send-string "\n") ; make sure side effects occurred.
+ (kill-buffer ispell-output-buffer)
+ (kill-buffer ispell-session-buffer)
+ (setq ispell-output-buffer nil
+ ispell-session-buffer nil))
+ (setq ispell-process nil)
+ (message "Ispell process killed")
+ nil))
+
+
+;;; ispell-change-dictionary is set in some people's hooks. Maybe this should
+;;; call ispell-init-process rather than wait for a spell checking command?
+
+;;;###autoload
+(defun ispell-change-dictionary (dict &optional arg)
+ "Change `ispell-dictionary' (q.v.) to DICT and kill old Ispell process.
+A new one will be started as soon as necessary.
+
+By just answering RET you can find out what the current dictionary is.
+
+With prefix argument, set the default dictionary."
+ (interactive
+ (list (completing-read
+ "Use new dictionary (RET for current, SPC to complete): "
+ (and (fboundp 'ispell-valid-dictionary-list)
+ (mapcar (lambda (x)(cons x nil)) (ispell-valid-dictionary-list)))
+ nil t)
+ current-prefix-arg))
+ (if (equal dict "default") (setq dict nil))
+ ;; This relies on bug in completing-read that returns "" for no match
+ (cond ((equal dict "")
+ (message "Using %s dictionary"
+ (or ispell-local-dictionary ispell-dictionary "default")))
+ ((and (equal dict ispell-dictionary)
+ (or (null ispell-local-dictionary)
+ (equal dict ispell-local-dictionary)))
+ ;; Specified dictionary is the default already. No-op
+ (and (interactive-p)
+ (message "No change, using %s dictionary" (or dict "default"))))
+ (t ; reset dictionary!
+ (if (assoc dict ispell-dictionary-alist)
+ (progn
+ (if (or arg (null dict)) ; set default dictionary
+ (setq ispell-dictionary dict))
+ (if (null arg) ; set local dictionary
+ (setq ispell-local-dictionary dict)))
+ (error "Undefined dictionary: %s" dict))
+ (ispell-kill-ispell t)
+ (message "(Next %sIspell command will use %s dictionary)"
+ (cond ((equal ispell-local-dictionary ispell-dictionary)
+ "")
+ (arg "global ")
+ (t "local "))
+ (or (if (or (equal ispell-local-dictionary ispell-dictionary)
+ (null arg))
+ ispell-local-dictionary
+ ispell-dictionary)
+ "default")))))
+
+
+;;; Spelling of comments are checked when ispell-check-comments is non-nil.
+
+;;;###autoload
+(defun ispell-region (reg-start reg-end &optional recheckp shift)
+ "Interactively check a region for spelling errors.
+Return nil if spell session is quit,
+ otherwise returns shift offset amount for last line processed."
+ (interactive "r") ; Don't flag errors on read-only bufs.
+ (if (not recheckp)
+ (ispell-accept-buffer-local-defs)) ; set up dictionary, local words, etc.
+ (let ((skip-region-start (make-marker))
+ (rstart (make-marker)))
+ (unwind-protect
+ (save-excursion
+ (message "Spell checking %s using %s dictionary..."
+ (if (and (= reg-start (point-min)) (= reg-end (point-max)))
+ (buffer-name) "region")
+ (or ispell-dictionary "default"))
+ ;; Returns cursor to original location.
+ (save-window-excursion
+ (goto-char reg-start)
+ (let ((transient-mark-mode)
+ (case-fold-search case-fold-search)
+ (query-fcc t)
+ in-comment key)
+ (let (message-log-max)
+ (message "searching for regions to skip"))
+ (if (re-search-forward (ispell-begin-skip-region-regexp) reg-end t)
+ (progn
+ (setq key (buffer-substring-no-properties
+ (match-beginning 0) (match-end 0)))
+ (set-marker skip-region-start (- (point) (length key)))
+ (goto-char reg-start)))
+ (let (message-log-max)
+ (message "Continuing spelling check using %s dictionary..."
+ (or ispell-dictionary "default")))
+ (set-marker rstart reg-start)
+ (set-marker ispell-region-end reg-end)
+ (while (and (not ispell-quit)
+ (< (point) ispell-region-end))
+ ;; spell-check region with skipping
+ (if (and (marker-position skip-region-start)
+ (<= skip-region-start (point)))
+ (progn
+ ;; If region inside line comment, must keep comment start.
+ (setq in-comment (point)
+ in-comment
+ (and comment-start
+ (or (null comment-end) (string= "" comment-end))
+ (save-excursion
+ (beginning-of-line)
+ (re-search-forward comment-start in-comment t))
+ comment-start))
+ ;; Can change skip-regexps (in ispell-message)
+ (ispell-skip-region key) ; moves pt past region.
+ (set-marker rstart (point))
+ ;; check for saving large attachments...
+ (setq query-fcc (and query-fcc
+ (ispell-ignore-fcc skip-region-start
+ rstart)))
+ (if (and (< rstart ispell-region-end)
+ (re-search-forward
+ (ispell-begin-skip-region-regexp)
+ ispell-region-end t))
+ (progn
+ (setq key (buffer-substring-no-properties
+ (car (match-data))
+ (car (cdr (match-data)))))
+ (set-marker skip-region-start
+ (- (point) (length key)))
+ (goto-char rstart))
+ (set-marker skip-region-start nil))))
+ (setq reg-end (max (point)
+ (if (marker-position skip-region-start)
+ (min skip-region-start ispell-region-end)
+ (marker-position ispell-region-end))))
+ (let* ((start (point))
+ (end (save-excursion (end-of-line) (min (point) reg-end)))
+ (string (ispell-get-line start end in-comment)))
+ (if in-comment ; account for comment chars added
+ (setq start (- start (length in-comment))
+ in-comment nil))
+ (setq end (point)) ; "end" tracks region retrieved.
+ (if string ; there is something to spell check!
+ ;; (special start end)
+ (setq shift (ispell-process-line string
+ (and recheckp shift))))
+ (goto-char end)))))
+ (if ispell-quit
+ nil
+ (or shift 0)))
+ ;; protected
+ (if (and (not (and recheckp ispell-keep-choices-win))
+ (get-buffer ispell-choices-buffer))
+ (kill-buffer ispell-choices-buffer))
+ (set-marker skip-region-start nil)
+ (set-marker rstart nil)
+ (if ispell-quit
+ (progn
+ ;; preserve or clear the region for ispell-continue.
+ (if (not (numberp ispell-quit))
+ (set-marker ispell-region-end nil)
+ ;; Ispell-continue enabled - ispell-region-end is set.
+ (goto-char ispell-quit))
+ ;; Check for aborting
+ (if (and ispell-checking-message (numberp ispell-quit))
+ (progn
+ (setq ispell-quit nil)
+ (error "Message send aborted")))
+ (if (not recheckp) (setq ispell-quit nil)))
+ (if (not recheckp) (set-marker ispell-region-end nil))
+ ;; Only save if successful exit.
+ (ispell-pdict-save ispell-silently-savep)
+ (message "Spell-checking done")))))
+
+
+(defun ispell-begin-skip-region-regexp ()
+ "Returns a regexp of the search keys for region skipping.
+Includes `ispell-skip-region-alist' plus tex, tib, html, and comment keys.
+Must call after ispell-buffer-local-parsing due to dependence on mode."
+ ;; start with regions generic to all buffers
+ (let ((skip-regexp (ispell-begin-skip-region ispell-skip-region-alist)))
+ ;; Comments
+ (if (and (null ispell-check-comments) comment-start)
+ (setq skip-regexp (concat (regexp-quote comment-start) "\\|"
+ skip-regexp)))
+ (if (and (eq 'exclusive ispell-check-comments) comment-start)
+ ;; search from end of current comment to start of next comment.
+ (setq skip-regexp (concat (if (string= "" comment-end) "^"
+ (regexp-quote comment-end))
+ "\\|" skip-regexp)))
+ ;; tib
+ (if ispell-skip-tib
+ (setq skip-regexp (concat ispell-tib-ref-beginning "\\|" skip-regexp)))
+ ;; html stuff
+ (if (or (eq ispell-parser-mode 'html) (eq ispell-skip-html t))
+ (setq skip-regexp (concat
+ (ispell-begin-skip-region ispell-html-skip-alists)
+ "\\|"
+ skip-regexp)))
+ ;; tex
+ (if (eq ispell-parser-mode 'tex)
+ (setq skip-regexp (concat (ispell-begin-tex-skip-regexp) "\\|"
+ skip-regexp)))
+ ;; po-mode stuff
+ (if (eq ispell-parser-mode 'po-mode)
+ (setq skip-regexp (concat
+ (ispell-begin-skip-region ispell-po-mode-skip-alists)
+ "\\|"
+ skip-regexp)))
+ ;; messages
+ (if (and ispell-checking-message
+ (not (eq t ispell-checking-message)))
+ (setq skip-regexp (concat
+ (mapconcat (lambda (lst) (car lst))
+ ispell-checking-message
+ "\\|")
+ "\\|"
+ skip-regexp)))
+
+ ;; return new regexp
+ skip-regexp))
+
+
+(defun ispell-begin-skip-region (skip-alist)
+ "Regular expression for start of regions to skip generated from SKIP-ALIST.
+Each selection should be a key of SKIP-ALIST;
+otherwise, the current line is skipped."
+ (mapconcat (lambda (lst) (if (stringp (car lst)) (car lst) (eval (car lst))))
+ skip-alist
+ "\\|"))
+
+
+(defun ispell-begin-tex-skip-regexp ()
+ "Regular expression of tex commands to skip.
+Generated from `ispell-tex-skip-alists'."
+ (concat
+ ;; raw tex keys
+ (mapconcat (function (lambda (lst) (car lst)))
+ (car ispell-tex-skip-alists)
+ "\\|")
+ "\\|"
+ ;; keys wrapped in begin{}
+ (mapconcat (function (lambda (lst)
+ (concat "\\\\begin[ \t\n]*{[ \t\n]*"
+ (car lst)
+ "[ \t\n]*}")))
+ (car (cdr ispell-tex-skip-alists))
+ "\\|")))
+
+
+(defun ispell-skip-region-list ()
+ "Returns a list describing key and body regions to skip for this buffer.
+Includes regions defined by `ispell-skip-region-alist', tex mode,
+`ispell-html-skip-alists', `ispell-po-mode-skip-alists',
+and `ispell-checking-message'.
+Manual checking must include comments and tib references.
+The list is of the form described by variable `ispell-skip-region-alist'.
+Must call after `ispell-buffer-local-parsing' due to dependence on mode."
+ (let ((skip-alist ispell-skip-region-alist))
+ ;; only additional explicit region definition is tex.
+ (if (eq ispell-parser-mode 'tex)
+ (setq case-fold-search nil
+ skip-alist (append (car ispell-tex-skip-alists)
+ (car (cdr ispell-tex-skip-alists))
+ skip-alist)))
+ (if (or (eq ispell-parser-mode 'html) (eq ispell-skip-html t))
+ (setq skip-alist (append ispell-html-skip-alists skip-alist)))
+ (if (eq ispell-parser-mode 'po-mode)
+ (setq skip-alist (append ispell-po-mode-skip-alists skip-alist)))
+ (if (and ispell-checking-message
+ (not (eq t ispell-checking-message)))
+ (setq skip-alist (append ispell-checking-message skip-alist)))
+ skip-alist))
+
+
+(defun ispell-tex-arg-end (&optional arg)
+ "Skip across ARG number of braces."
+ (condition-case nil
+ (progn
+ (while (looking-at "[ \t\n]*\\[") (forward-sexp))
+ (forward-sexp (or arg 1)))
+ (error
+ (message "error skipping s-expressions at point %d." (point))
+ (beep)
+ (sit-for 2))))
+
+
+(defun ispell-ignore-fcc (start end)
+ "Deletes the Fcc: message header when large attachments are included.
+Return value `nil' if file with large attachments are saved.
+This can be used to avoid multiple questions for multiple large attachments.
+Returns point to starting location afterwards."
+ (let ((result t))
+ (if (and ispell-checking-message ispell-message-fcc-skip)
+ (if (< ispell-message-fcc-skip (- end start))
+ (let (case-fold-search head-end)
+ (goto-char (point-min))
+ (setq head-end
+ (or (re-search-forward
+ (concat "^" (regexp-quote mail-header-separator) "$")
+ nil t)
+ (re-search-forward "^$" nil t)
+ (point-min)))
+ (goto-char (point-min))
+ (if (re-search-forward "^Fcc:" head-end t)
+ (if (y-or-n-p
+ "Save copy of this message with large attachments? ")
+ (setq result nil)
+ (beginning-of-line)
+ (kill-line 1)))
+ (goto-char end))))
+ result))
+
+
+(defun ispell-skip-region (key)
+ "Skips across KEY and then to end of region.
+Key lookup determines region to skip.
+Point is placed at end of skipped region."
+ ;; move over key to begin checking.
+ (forward-char (length key))
+ (let ((start (point))
+ ;; Regenerate each call... This function can change region definition.
+ (alist (ispell-skip-region-list))
+ alist-key null-skip)
+ (cond
+ ;; what about quoted comment, or comment inside strings?
+ ((and (null ispell-check-comments) comment-start
+ (string= key comment-start))
+ (if (string= "" comment-end)
+ (forward-line)
+ (search-forward comment-end ispell-region-end t)))
+ ((and (eq 'exclusive ispell-check-comments) comment-start
+ (string= key comment-end))
+ (search-forward comment-start ispell-region-end :end))
+ ((and ispell-skip-tib (string-match ispell-tib-ref-beginning key))
+ (re-search-forward ispell-tib-ref-end ispell-region-end t))
+ ;; markings from alist
+ (t
+ (while alist
+ (setq alist-key (eval (car (car alist))))
+ (if (string-match alist-key key)
+ (progn
+ (setq alist (cdr (car alist)))
+ (cond
+ ((null alist) (setq null-skip t)) ; done! Just skip key.
+ ((not (consp alist))
+ ;; Search past end of spell region to find this region end.
+ (re-search-forward (eval alist) (point-max) t))
+ ((and (= 1 (length alist))
+ (stringp (car alist)))
+ (re-search-forward (car alist) (point-max) t))
+ (t
+ (setq null-skip t) ; error handling in functions!
+ (if (consp (cdr alist))
+ (apply (car alist) (cdr alist))
+ (funcall (car alist)))))
+ (setq alist nil))
+ (setq alist (cdr alist))))))
+ (if (and (= start (point)) (null null-skip))
+ (progn
+ (message "Matching region end for `%s' point %d not found"
+ key (point))
+ (beep)
+ (sit-for 2)))))
+
+
+;;; Grab the next line of data.
+;;; Returns a string with the line data
+(defun ispell-get-line (start end in-comment)
+ (let ((ispell-casechars (ispell-get-casechars))
+ string)
+ (cond ; LOOK AT THIS LINE AND SKIP OR PROCESS
+ ((eolp) ; END OF LINE, just go to next line.
+ (forward-line))
+ ;;((looking-at "[-#@*+!%~^]") ; SKIP SPECIAL ISPELL CHARACTERS
+ ;; (forward-char 1)) ; not needed as quoted below.
+ ((or (re-search-forward ispell-casechars end t) ; TEXT EXISTS
+ (re-search-forward "[][()${}]" end t)) ; or MATH COMMANDS
+ (setq string (concat "^" in-comment
+ (buffer-substring-no-properties start end)
+ "\n"))
+ (goto-char end))
+ (t (goto-char end))) ; EMPTY LINE, skip it.
+ string))
+
+
+;;; Avoid error messages when compiling for these dynamic variables.
+(eval-when-compile
+ (defvar start)
+ (defvar end))
+
+(defun ispell-process-line (string shift)
+ "Sends a LINE of text to ispell and processes the result.
+This will modify the buffer for spelling errors.
+Requires variables START and END to be defined in its lexical scope.
+Returns the sum shift due to changes in word replacements."
+ ;;(declare special start end)
+ (let (poss accept-list)
+ (if (not (numberp shift))
+ (setq shift 0))
+ ;; send string to spell process and get input.
+ (ispell-send-string string)
+ (while (progn
+ (ispell-accept-output)
+ ;; Last item of output contains a blank line.
+ (not (string= "" (car ispell-filter)))))
+ ;; parse all inputs from the stream one word at a time.
+ ;; Place in FIFO order and remove the blank item.
+ (setq ispell-filter (nreverse (cdr ispell-filter)))
+ (while (and (not ispell-quit) ispell-filter)
+ ;; get next word, accounting for accepted words and start shifts
+ (setq poss (ispell-parse-output (car ispell-filter)
+ accept-list shift))
+ (if (and poss (listp poss)) ; spelling error occurred.
+ ;; Whenever we have misspellings, we can change
+ ;; the buffer. Keep boundaries as markers.
+ ;; Markers can move with highlighting! This destroys
+ ;; end of region markers line-end and ispell-region-end
+ (let ((word-start
+ (copy-marker (+ start ispell-offset (car (cdr poss)))))
+ (word-len (length (car poss)))
+ (line-end (copy-marker end))
+ (line-start (copy-marker start))
+ recheck-region replace)
+ (goto-char word-start)
+ ;; Adjust the horizontal scroll & point
+ (ispell-horiz-scroll)
+ (goto-char (+ word-len word-start))
+ (ispell-horiz-scroll)
+ (goto-char word-start)
+ (ispell-horiz-scroll)
+
+ ;; Alignment cannot be tracked and this error will occur when
+ ;; `query-replace' makes multiple corrections on the starting line.
+ (if (/= (+ word-len (point))
+ (progn
+ ;; NB: Search can fail with Mule coding systems that don't
+ ;; display properly. Ignore the error in this case?
+ (search-forward (car poss) (+ word-len (point)) t)
+ (point)))
+ ;; This occurs due to filter pipe problems
+ (error (concat "Ispell misalignment: word "
+ "`%s' point %d; probably incompatible versions")
+ (car poss) (marker-position word-start)))
+ ;; ispell-cmd-loop can go recursive & change buffer
+ (if ispell-keep-choices-win
+ (setq replace (ispell-command-loop
+ (car (cdr (cdr poss)))
+ (car (cdr (cdr (cdr poss))))
+ (car poss) (marker-position word-start)
+ (+ word-len (marker-position word-start))))
+ (save-window-excursion
+ (setq replace (ispell-command-loop
+ (car (cdr (cdr poss)))
+ (car (cdr (cdr (cdr poss))))
+ (car poss) (marker-position word-start)
+ (+ word-len (marker-position word-start))))))
+
+ (goto-char word-start)
+ ;; Recheck when query replace edit changes misspelled word.
+ ;; Error in tex mode when a potential math mode change exists.
+ (if (and replace (listp replace) (= 2 (length replace)))
+ (if (and (eq ispell-parser-mode 'tex)
+ (string-match "[\\\\][]()[]\\|\\\\begin\\|\\$"
+ (regexp-quote string)))
+ (error
+ "Don't start query replace on a line with math characters"
+ )
+ (set-marker line-end (point))
+ (setq ispell-filter nil
+ recheck-region t)))
+
+ ;; insert correction if needed
+ (cond
+ ((or (null replace)
+ (equal 0 replace)) ; ACCEPT/INSERT
+ (if (equal 0 replace) ; BUFFER-LOCAL DICT ADD
+ (ispell-add-per-file-word-list (car poss)))
+ ;; do not recheck accepted word on this line
+ (setq accept-list (cons (car poss) accept-list)))
+ (t ; replacement word selected or entered
+ (delete-region (point) (+ word-len (point)))
+ (if (not (listp replace))
+ (progn
+ (insert replace) ; insert dictionary word
+ (setq accept-list (cons replace accept-list)))
+ (let ((replace-word (car replace)))
+ ;; Recheck hand entered replacement word
+ (insert replace-word)
+ (if (car (cdr replace))
+ (save-window-excursion
+ (delete-other-windows) ; to correctly show help.
+ ;; Assume case-replace &
+ ;; case-fold-search correct?
+ (query-replace (car poss) (car replace) t)))
+ (goto-char word-start)
+ ;; do not recheck if already accepted
+ (if (member replace-word accept-list)
+ (setq accept-list (cons replace-word accept-list)
+ replace replace-word)
+ (let ((region-end (copy-marker ispell-region-end)))
+ (setq recheck-region ispell-filter
+ ispell-filter nil ; save filter
+ shift 0 ; already accounted
+ shift (ispell-region
+ word-start
+ (+ word-start (length replace-word))
+ t shift))
+ (if (null shift) ; quitting check.
+ (setq shift 0))
+ (set-marker ispell-region-end region-end)
+ (set-marker region-end nil)
+ (setq ispell-filter recheck-region
+ recheck-region nil
+ replace replace-word)))))
+
+ (setq shift (+ shift (- (length replace) word-len)))
+
+ ;; Move line-start across word...
+ ;; new shift function does this now...
+ ;;(set-marker line-start (+ line-start
+ ;; (- (length replace)
+ ;; (length (car poss)))))
+ ))
+ (if (not ispell-quit)
+ (let (message-log-max)
+ (message "Continuing spelling check using %s dictionary..."
+ (or ispell-dictionary "default"))))
+ (sit-for 0)
+ (setq start (marker-position line-start)
+ end (marker-position line-end))
+ ;; Adjust markers when end of region lost from highlighting.
+ (if (and (not recheck-region) (< end (+ word-start word-len)))
+ (setq end (+ word-start word-len)))
+ (if (= word-start ispell-region-end)
+ (set-marker ispell-region-end (+ word-start word-len)))
+ ;; going out of scope - unneeded
+ (set-marker line-start nil)
+ (set-marker word-start nil)
+ (set-marker line-end nil)))
+ ;; finished with misspelling!
+ (setq ispell-filter (cdr ispell-filter)))
+ shift))
+
+
+;;;###autoload
+(defun ispell-comments-and-strings ()
+ "Check comments and strings in the current buffer for spelling errors."
+ (interactive)
+ (goto-char (point-min))
+ (let (state done)
+ (while (not done)
+ (setq done t)
+ (setq state (parse-partial-sexp (point) (point-max)
+ nil nil state 'syntax-table))
+ (if (or (nth 3 state) (nth 4 state))
+ (let ((start (point)))
+ (setq state (parse-partial-sexp start (point-max)
+ nil nil state 'syntax-table))
+ (if (or (nth 3 state) (nth 4 state))
+ (error "Unterminated string or comment"))
+ (save-excursion
+ (setq done (not (ispell-region start (point))))))))))
+
+
+;;;###autoload
+(defun ispell-buffer ()
+ "Check the current buffer for spelling errors interactively."
+ (interactive)
+ (ispell-region (point-min) (point-max)))
+
+
+;;;###autoload
+(defun ispell-continue ()
+ "Continue a halted spelling session beginning with the current word."
+ (interactive)
+ (if (not (marker-position ispell-region-end))
+ (message "No session to continue. Use 'X' command when checking!")
+ (if (not (equal (marker-buffer ispell-region-end) (current-buffer)))
+ (message "Must continue ispell from buffer %s"
+ (buffer-name (marker-buffer ispell-region-end)))
+ (ispell-region
+ ;; find beginning of current word:
+ (car (cdr (ispell-get-word t)))
+ (marker-position ispell-region-end)))))
+
+
+;;; Horizontal scrolling
+(defun ispell-horiz-scroll ()
+ "Places point within the horizontal visibility of its window area."
+ (if truncate-lines ; display truncating lines?
+ ;; See if display needs to be scrolled.
+ (let ((column (- (current-column) (max (window-hscroll) 1))))
+ (if (and (< column 0) (> (window-hscroll) 0))
+ (scroll-right (max (- column) 10))
+ (if (>= column (- (window-width) 2))
+ (scroll-left (max (- column (window-width) -3) 10)))))))
+
+
+;;; Interactive word completion.
+;;; Forces "previous-word" processing. Do we want to make this selectable?
+
+;;;###autoload
+(defun ispell-complete-word (&optional interior-frag)
+ "Try to complete the word before or under point (see `lookup-words').
+If optional INTERIOR-FRAG is non-nil then the word may be a character
+sequence inside of a word.
+
+Standard ispell choices are then available."
+ (interactive "P")
+ (let ((cursor-location (point))
+ (case-fold-search-val case-fold-search)
+ (word (ispell-get-word nil "\\*")) ; force "previous-word" processing.
+ start end possibilities replacement)
+ (setq start (car (cdr word))
+ end (car (cdr (cdr word)))
+ word (car word)
+ possibilities
+ (or (string= word "") ; Will give you every word
+ (lookup-words (concat (and interior-frag "*") word
+ (if (or interior-frag (null ispell-look-p))
+ "*"))
+ ispell-complete-word-dict)))
+ (cond ((eq possibilities t)
+ (message "No word to complete"))
+ ((null possibilities)
+ (message "No match for \"%s\"" word))
+ (t ; There is a modification...
+ (setq case-fold-search nil) ; Try and respect case of word.
+ (cond
+ ((string-equal (upcase word) word)
+ (setq possibilities (mapcar 'upcase possibilities)))
+ ((eq (upcase (aref word 0)) (aref word 0))
+ (setq possibilities (mapcar (function
+ (lambda (pos)
+ (if (eq (aref word 0) (aref pos 0))
+ pos
+ (capitalize pos))))
+ possibilities))))
+ (setq case-fold-search case-fold-search-val)
+ (save-window-excursion
+ (setq replacement
+ (ispell-command-loop possibilities nil word start end)))
+ (cond
+ ((equal 0 replacement) ; BUFFER-LOCAL ADDITION
+ (ispell-add-per-file-word-list word))
+ (replacement ; REPLACEMENT WORD
+ (delete-region start end)
+ (setq word (if (atom replacement) replacement (car replacement))
+ cursor-location (+ (- (length word) (- end start))
+ cursor-location))
+ (insert word)
+ (if (not (atom replacement)) ; recheck spelling of replacement.
+ (progn
+ (goto-char cursor-location)
+ (ispell-word nil t)))))
+ (if (get-buffer ispell-choices-buffer)
+ (kill-buffer ispell-choices-buffer))))
+ (ispell-pdict-save ispell-silently-savep)
+ (goto-char cursor-location)))
+
+
+;;;###autoload
+(defun ispell-complete-word-interior-frag ()
+ "Completes word matching character sequence inside a word."
+ (interactive)
+ (ispell-complete-word t))
+
+
+;;;###autoload
+(defun ispell ()
+ "Interactively check a region or buffer for spelling errors.
+If `transient-mark-mode' is on, and a region is active, spell-check
+that region. Otherwise spell-check the buffer.
+
+Ispell dictionaries are not distributed with Emacs. If you are
+looking for a dictionary, please see the distribution of the GNU ispell
+program, or do an Internet search; there are various dictionaries
+available on the net."
+ (interactive)
+ (if (and (boundp 'transient-mark-mode) transient-mark-mode
+ (boundp 'mark-active) mark-active)
+ (ispell-region (region-beginning) (region-end))
+ (ispell-buffer)))
+
+
+;;; **********************************************************************
+;;; Ispell Minor Mode
+;;; **********************************************************************
+
+(defvar ispell-minor-mode nil
+ "Non-nil if Ispell minor mode is enabled.")
+;; Variable indicating that ispell minor mode is active.
+(make-variable-buffer-local 'ispell-minor-mode)
+
+(or (assq 'ispell-minor-mode minor-mode-alist)
+ (setq minor-mode-alist
+ (cons '(ispell-minor-mode " Spell") minor-mode-alist)))
+
+(defvar ispell-minor-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map " " 'ispell-minor-check)
+ (define-key map "\r" 'ispell-minor-check)
+ map)
+ "Keymap used for Ispell minor mode.")
+
+(or (not (boundp 'minor-mode-map-alist))
+ (assoc 'ispell-minor-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'ispell-minor-mode ispell-minor-keymap)
+ minor-mode-map-alist)))
+
+;;;###autoload
+(defun ispell-minor-mode (&optional arg)
+ "Toggle Ispell minor mode.
+With prefix arg, turn Ispell minor mode on iff arg is positive.
+
+In Ispell minor mode, pressing SPC or RET
+warns you if the previous word is incorrectly spelled.
+
+All the buffer-local variables and dictionaries are ignored -- to read
+them into the running ispell process, type \\[ispell-word] SPC."
+ (interactive "P")
+ (setq ispell-minor-mode
+ (not (or (and (null arg) ispell-minor-mode)
+ (<= (prefix-numeric-value arg) 0))))
+ (force-mode-line-update))
+
+(defun ispell-minor-check ()
+ "Check previous word then continue with the normal binding of this key.
+Don't check previous word when character before point is a space or newline.
+Don't read buffer-local settings or word lists."
+ (interactive "*")
+ (let ((ispell-minor-mode nil)
+ (ispell-check-only t)
+ (last-char (char-after (1- (point)))))
+ (command-execute (key-binding (this-command-keys)))
+ (if (not (or (eq last-char ?\ ) (eq last-char ?\n)
+ (and (eq ispell-parser-mode 'html)
+ (eq ispell-skip-html t)
+ (or (eq last-char ?>)
+ (eq last-char ?\;)))))
+ (ispell-word nil t))))
+
+
+;;; **********************************************************************
+;;; Ispell Message
+;;; **********************************************************************
+
+(defvar ispell-message-text-end
+ (mapconcat (function identity)
+ '(
+ ;; Don't spell check signatures
+ "^-- $"
+ ;; Matches postscript files.
+ ;;"^%!PS-Adobe-[123].0"
+ ;; Matches uuencoded text
+ ;;"^begin [0-9][0-9][0-9] .*\nM.*\nM.*\nM"
+ ;; Matches shell files (especially auto-decoding)
+ "^#! /bin/[ck]?sh"
+ ;; Matches context difference listing
+ "\\(\\(^cd .*\n\\)?diff -c .*\\)?\n\\*\\*\\* .*\n--- .*\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*"
+ ;; Matches unidiff difference listing
+ "\\(diff -u .*\\)?\n--- .*\n\\+\\+\\+ .*\n@@ [-+][0-9]+,[0-9]+ [-+][0-9]+,[0-9]+ @@\n"
+ ;; Matches reporter.el bug report
+ "^current state:\n==============\n"
+ ;; Matches commonly used "cut" boundaries
+ "^\\(- \\)?[-=_]+\\s ?\\(cut here\\|Environment Follows\\)")
+ "\\|")
+ "*End of text which will be checked in `ispell-message'.
+If it is a string, limit at first occurrence of that regular expression.
+Otherwise, it must be a function which is called to get the limit.")
+
+
+(defun ispell-mime-multipartp (&optional limit)
+ "Return multipart message start boundary or nil if none."
+ ;; caller must ensure `case-fold-search' is set to `t'
+ (and
+ (re-search-forward
+ "Content-Type: *multipart/\\([^ \t\n]*;[ \t]*[\n]?[ \t]*\\)+boundary="
+ limit t)
+ (let (boundary)
+ (if (looking-at "\"")
+ (let (start)
+ (forward-char)
+ (setq start (point))
+ (while (not (looking-at "\""))
+ (forward-char 1))
+ (setq boundary (buffer-substring-no-properties start (point))))
+ (let ((start (point)))
+ (while (looking-at "[-0-9a-zA-Z'()+_,./:=?]")
+ (forward-char))
+ (setq boundary (buffer-substring-no-properties start (point)))))
+ (if (< (length boundary) 1)
+ (setq boundary nil)
+ (concat "--" boundary)))))
+
+
+(defun ispell-mime-skip-part (boundary)
+ "Moves point across header, or entire MIME part if message is encoded.
+All specified types except `7bit' `8bit' and `quoted-printable' are considered
+encoded and therefore skipped. See rfc 1521, 2183, ...
+If no boundary is given, then entire message is skipped.
+
+This starts one line ABOVE the MIME content messages, on the boundary marker,
+for operation with the generic region-skipping code.
+This places new MIME boundaries into variable `ispell-checking-message'."
+ (forward-line) ; skip over boundary to headers
+ (let ((save-case-fold-search case-fold-search)
+ (continuep t)
+ textp)
+ (setq case-fold-search t
+ ispell-parser-mode nil)
+ (while continuep
+ (setq continuep nil)
+ (if (looking-at "Content-Type: *text/")
+ (progn
+ (goto-char (match-end 0))
+ (if (looking-at "html")
+ (setq ispell-parser-mode 'html))
+ (setq textp t
+ continuep t)
+ (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t)
+ (forward-line)))
+ (if (looking-at "Content-Transfer-Encoding: *\\([^ \t\n]*\\)")
+ (let ((match (buffer-substring (match-beginning 1) (match-end 1))))
+ (setq textp (member (upcase match)
+ ;; only spell check the following encodings:
+ '("7BIT" "8BIT" "QUOTED-PRINTABLE" "BINARY"))
+ continuep t)
+ (goto-char (match-end 0))
+ (re-search-forward "\\(.*;[ \t]*[\n]\\)*.*$" nil t)
+ (forward-line)))
+ ;; hierarchical boundary definition
+ (if (looking-at "Content-Type: *multipart/")
+ (let ((new-boundary (ispell-mime-multipartp)))
+ (if (string-match new-boundary boundary)
+ (setq continuep t)
+ ;; first pass redefine skip function to include new boundary
+ ;;(re-search-backward boundary nil t)
+ (forward-line)
+ (setq ispell-checking-message
+ (cons
+ (list new-boundary 'ispell-mime-skip-part new-boundary)
+ (if (eq t ispell-checking-message) nil
+ ispell-checking-message))
+ textp t
+ continuep t)))
+ ;; Skip all MIME headers that don't affect spelling
+ (if (looking-at "Content-[^ \t]*: *\\(.*;[ \t]*[\n]\\)*.*$")
+ (progn
+ (setq continuep t)
+ (goto-char (match-end 0))
+ (forward-line)))))
+
+ (setq case-fold-search save-case-fold-search)
+ (if textp
+ (point)
+ ;; encoded message. Skip to boundary, or entire message.
+ (if (not boundary)
+ (goto-char (point-max))
+ (re-search-forward boundary nil t)
+ (beginning-of-line)
+ (point)))))
+
+
+;;;###autoload
+(defun ispell-message ()
+ "Check the spelling of a mail message or news post.
+Don't check spelling of message headers except the Subject field.
+Don't check included messages.
+
+To abort spell checking of a message region and send the message anyway,
+use the `x' command. (Any subsequent regions will be checked.)
+The `X' command aborts the message send so that you can edit the buffer.
+
+To spell-check whenever a message is sent, include the appropriate lines
+in your .emacs file:
+ (add-hook 'message-send-hook 'ispell-message) ;; GNUS 5
+ (add-hook 'news-inews-hook 'ispell-message) ;; GNUS 4
+ (add-hook 'mail-send-hook 'ispell-message)
+ (add-hook 'mh-before-send-letter-hook 'ispell-message)
+
+You can bind this to the key C-c i in GNUS or mail by adding to
+`news-reply-mode-hook' or `mail-mode-hook' the following lambda expression:
+ (function (lambda () (local-set-key \"\\C-ci\" 'ispell-message)))"
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (let* (boundary mimep
+ (ispell-skip-region-alist-save ispell-skip-region-alist)
+ ;; Nil when message came from outside (eg calling emacs as editor)
+ ;; Non-nil marker of end of headers.
+ (internal-messagep
+ (re-search-forward
+ (concat "^" (regexp-quote mail-header-separator) "$") nil t))
+ (end-of-headers ; Start of body.
+ (copy-marker
+ (or internal-messagep
+ (re-search-forward "^$" nil t)
+ (point-min))))
+ (limit (copy-marker ; End of region we will spell check.
+ (cond
+ ((not ispell-message-text-end) (point-max))
+ ((char-or-string-p ispell-message-text-end)
+ (if (re-search-forward ispell-message-text-end nil t)
+ (match-beginning 0)
+ (point-max)))
+ (t (min (point-max) (funcall ispell-message-text-end))))))
+ (default-prefix ; Vanilla cite prefix (just used for cite-regexp)
+ (if (and (boundp 'mail-yank-prefix) mail-yank-prefix)
+ (ispell-non-empty-string mail-yank-prefix)
+ " \\|\t"))
+ (cite-regexp ;Prefix of quoted text
+ (cond
+ ((featurep 'supercite) ; sc 3.0
+ (concat "\\(" (sc-cite-regexp) "\\)" "\\|"
+ (ispell-non-empty-string sc-reference-tag-string)))
+ ((featurep 'sc) ; sc 2.3
+ (concat "\\(" sc-cite-regexp "\\)" "\\|"
+ (ispell-non-empty-string sc-reference-tag-string)))
+ ((or (equal major-mode 'news-reply-mode) ;GNUS 4 & below
+ (equal major-mode 'message-mode)) ;GNUS 5
+ (concat "In article <" "\\|"
+ "[^,;&+=\n]+ <[^,;&+=]+> writes:" "\\|"
+ message-yank-prefix "\\|"
+ default-prefix))
+ ((equal major-mode 'mh-letter-mode) ; mh mail message
+ (concat "[^,;&+=\n]+ writes:" "\\|"
+ (ispell-non-empty-string mh-ins-buf-prefix)))
+ ((not internal-messagep) ; Assume nn sent us this message.
+ (concat "In [a-zA-Z.]+ you write:" "\\|"
+ "In <[^,;&+=]+> [^,;&+=]+ writes:" "\\|"
+ " *> *"))
+ ((boundp 'vm-included-text-prefix) ; VM mail message
+ (concat "[^,;&+=\n]+ writes:" "\\|"
+ (ispell-non-empty-string vm-included-text-prefix)))
+ (t default-prefix)))
+ (ispell-skip-region-alist
+ (cons (list (concat "^\\(" cite-regexp "\\)")
+ (function forward-line))
+ (cons '("^---* \\(Start of \\)?[Ff]orwarded [Mm]essage"
+ . "^---* End of [Ff]orwarded [Mm]essage")
+ ispell-skip-region-alist)))
+ (old-case-fold-search case-fold-search)
+ (dictionary-alist ispell-message-dictionary-alist)
+ (ispell-checking-message t))
+
+ ;; Select dictionary for message
+ (or (local-variable-p 'ispell-local-dictionary (current-buffer))
+ (while dictionary-alist
+ (goto-char (point-min))
+ (if (re-search-forward (car (car dictionary-alist))
+ end-of-headers t)
+ (setq ispell-local-dictionary (cdr (car dictionary-alist))
+ dictionary-alist nil)
+ (setq dictionary-alist (cdr dictionary-alist)))))
+
+ (unwind-protect
+ (progn
+ ;; Spell check any original Subject:
+ (goto-char (point-min))
+ (setq case-fold-search t
+ mimep (re-search-forward "MIME-Version:" end-of-headers t))
+ (goto-char (point-min))
+ (if (re-search-forward "^Subject: *" end-of-headers t)
+ (progn
+ (goto-char (match-end 0))
+ (if (and (not (looking-at ".*Re\\>"))
+ (not (looking-at "\\[")))
+ (progn
+ (setq case-fold-search old-case-fold-search)
+ (ispell-region (point)
+ (progn ;Tab-initiated continuation lns.
+ (end-of-line)
+ (while (looking-at "\n[ \t]")
+ (end-of-line 2))
+ (point)))))))
+ (if mimep
+ (progn
+ (goto-char (point-min))
+ (setq boundary (ispell-mime-multipartp end-of-headers))))
+ ;; Adjust message limit to MIME message if necessary.
+ (and boundary
+ (re-search-forward (concat boundary "--") nil t)
+ (re-search-backward boundary nil t)
+ (< (point) (marker-position limit))
+ (set-marker limit (point)))
+ (goto-char (point-min))
+ ;; Select type or skip checking if this is a non-multipart message
+ ;; Point moved to end of buffer if region is encoded.
+ (if (and mimep (not boundary))
+ (let (skip-regexp) ; protect from `ispell-mime-skip-part'
+ (goto-char (point-min))
+ (re-search-forward "Content-[^ \t]*:" end-of-headers t)
+ (forward-line -1) ; following fn starts one line above
+ (ispell-mime-skip-part nil)
+ ;; if message-text-end region, limit may be less than point.
+ (if (> (point) limit)
+ (set-marker limit (point)))))
+ (goto-char (max end-of-headers (point)))
+ (forward-line 1)
+ (setq case-fold-search old-case-fold-search)
+ ;; Define MIME regions to skip.
+ (if boundary
+ (setq ispell-checking-message
+ (list (list boundary 'ispell-mime-skip-part boundary))))
+ (ispell-region (point) limit))
+ (set-marker end-of-headers nil)
+ (set-marker limit nil)
+ (setq ispell-skip-region-alist ispell-skip-region-alist-save
+ ispell-parser-mode nil
+ case-fold-search old-case-fold-search)))))
+
+
+(defun ispell-non-empty-string (string)
+ (if (or (not string) (string-equal string ""))
+ "\\'\\`" ; An unmatchable string if string is null.
+ (regexp-quote string)))
+
+
+;;; **********************************************************************
+;;; Buffer Local Functions
+;;; **********************************************************************
+
+
+(defun ispell-accept-buffer-local-defs ()
+ "Load all buffer-local information, restarting Ispell when necessary."
+ (ispell-buffer-local-dict) ; May kill ispell-process.
+ (ispell-buffer-local-words) ; Will initialize ispell-process.
+ (ispell-buffer-local-parsing))
+
+
+(defun ispell-buffer-local-parsing ()
+ "Place Ispell into parsing mode for this buffer.
+Overrides the default parsing mode.
+Includes Latex/Nroff modes and extended character mode."
+ ;; (ispell-init-process) must already be called.
+ (ispell-send-string "!\n") ; Put process in terse mode.
+ ;; We assume all major modes with "tex-mode" in them should use latex parsing
+ ;; When exclusively checking comments, set to raw text mode (nroff).
+ (if (and (not (eq 'exclusive ispell-check-comments))
+ (or (and (eq ispell-parser 'use-mode-name)
+ (string-match "[Tt][Ee][Xx]-mode"
+ (symbol-name major-mode)))
+ (eq ispell-parser 'tex)))
+ (progn
+ (ispell-send-string "+\n") ; set ispell mode to tex
+ (if (not (eq ispell-parser 'tex))
+ (setq ispell-parser-mode 'tex)))
+ (ispell-send-string "-\n")) ; set mode to normal (nroff)
+ ;; If needed, test for SGML & HTML modes and set a buffer local nil/t value.
+ (if (or (eq ispell-skip-html t)
+ (and (eq ispell-skip-html 'use-mode-name)
+ (string-match "sgml\\|html\\|xml"
+ (downcase (symbol-name major-mode)))))
+ (setq ispell-parser-mode 'html))
+ ;; Set default extended character mode for given buffer, if any.
+ (if (and (or (eq ispell-parser 'po-mode)
+ (eq ispell-parser 'use-mode-name))
+ (string-match "po-mode" (downcase (symbol-name major-mode))))
+ (setq ispell-parser-mode 'po-mode))
+ (let ((extended-char-mode (ispell-get-extended-character-mode)))
+ (if extended-char-mode
+ (ispell-send-string (concat extended-char-mode "\n"))))
+ ;; Set buffer-local parsing mode and extended character mode, if specified.
+ (save-excursion
+ (goto-char (point-max))
+ ;; Uses last occurrence of ispell-parsing-keyword
+ (if (search-backward ispell-parsing-keyword nil t)
+ (let ((end (save-excursion (end-of-line) (point)))
+ string)
+ (search-forward ispell-parsing-keyword)
+ (while (re-search-forward " *\\([^ \"]+\\)" end t)
+ ;; space separated definitions.
+ (setq string (downcase (buffer-substring-no-properties
+ (match-beginning 1) (match-end 1))))
+ (cond ((and (string-match "latex-mode" string)
+ (not (eq 'exclusive ispell-check-comments)))
+ (ispell-send-string "+\n~tex\n"))
+ ((string-match "nroff-mode" string)
+ (ispell-send-string "-\n~nroff\n"))
+ ((string-match "~" string) ; Set extended character mode.
+ (ispell-send-string (concat string "\n")))
+ (t (message "Invalid Ispell Parsing argument!")
+ (sit-for 2))))))))
+
+
+;;; Can kill the current ispell process
+
+(defun ispell-buffer-local-dict ()
+ "Initializes local dictionary and local personal dictionary.
+When a dictionary is defined in the buffer (see variable
+`ispell-dictionary-keyword'), it will override the local setting
+from \\[ispell-change-dictionary].
+Both should not be used to define a buffer-local dictionary."
+ (save-excursion
+ (goto-char (point-min))
+ (let (end)
+ ;; Override the local variable definition.
+ ;; Uses last occurrence of ispell-dictionary-keyword.
+ (goto-char (point-max))
+ (if (search-backward ispell-dictionary-keyword nil t)
+ (progn
+ (search-forward ispell-dictionary-keyword)
+ (setq end (save-excursion (end-of-line) (point)))
+ (if (re-search-forward " *\\([^ \"]+\\)" end t)
+ (setq ispell-local-dictionary
+ (buffer-substring-no-properties (match-beginning 1)
+ (match-end 1))))))
+ (goto-char (point-max))
+ (if (search-backward ispell-pdict-keyword nil t)
+ (progn
+ (search-forward ispell-pdict-keyword)
+ (setq end (save-excursion (end-of-line) (point)))
+ (if (re-search-forward " *\\([^ \"]+\\)" end t)
+ (setq ispell-local-pdict
+ (buffer-substring-no-properties (match-beginning 1)
+ (match-end 1))))))))
+ ;; Reload if new personal dictionary defined.
+ (if (and ispell-local-pdict
+ (not (equal ispell-local-pdict ispell-personal-dictionary)))
+ (progn
+ (ispell-kill-ispell t)
+ (setq ispell-personal-dictionary ispell-local-pdict)))
+ ;; Reload if new dictionary defined.
+ (if (not (equal ispell-local-dictionary ispell-dictionary))
+ (ispell-change-dictionary ispell-local-dictionary)))
+
+
+(defun ispell-buffer-local-words ()
+ "Loads the buffer-local dictionary in the current buffer."
+ (if (and ispell-buffer-local-name
+ (not (equal ispell-buffer-local-name (buffer-name))))
+ (progn
+ (ispell-kill-ispell t)
+ (setq ispell-buffer-local-name nil)))
+ (ispell-init-process)
+ (save-excursion
+ (goto-char (point-min))
+ (while (search-forward ispell-words-keyword nil t)
+ (or ispell-buffer-local-name
+ (setq ispell-buffer-local-name (buffer-name)))
+ (let ((end (save-excursion (end-of-line) (point)))
+ (ispell-casechars (ispell-get-casechars))
+ string)
+ ;; buffer-local words separated by a space, and can contain
+ ;; any character other than a space. Not rigorous enough.
+ (while (re-search-forward " *\\([^ ]+\\)" end t)
+ (setq string (buffer-substring-no-properties (match-beginning 1)
+ (match-end 1)))
+ ;; This can fail when string contains a word with illegal chars.
+ ;; Error handling needs to be added between ispell and emacs.
+ (if (and (< 1 (length string))
+ (equal 0 (string-match ispell-casechars string)))
+ (ispell-send-string (concat "@" string "\n"))))))))
+
+
+;;; returns optionally adjusted region-end-point.
+
+(defun ispell-add-per-file-word-list (word)
+ "Add WORD to the per-file word list."
+ (or ispell-buffer-local-name
+ (setq ispell-buffer-local-name (buffer-name)))
+ (save-excursion
+ (goto-char (point-min))
+ (let ((old-case-fold-search case-fold-search)
+ line-okay search done found)
+ (while (not done)
+ (setq case-fold-search nil
+ search (search-forward ispell-words-keyword nil 'move)
+ found (or found search)
+ line-okay (< (+ (length word) 1 ; 1 for space after word..
+ (progn (end-of-line) (current-column)))
+ 80)
+ case-fold-search old-case-fold-search)
+ (if (or (and search line-okay)
+ (null search))
+ (progn
+ (setq done t)
+ (if (null search)
+ (progn
+ (open-line 1)
+ (unless found (newline))
+ (insert (concat comment-start " " ispell-words-keyword))
+ (if (> (length comment-end) 0)
+ (save-excursion
+ (newline)
+ (insert comment-end)))))
+ (insert (concat " " word))))))))
+
+(add-to-list 'debug-ignored-errors "^No word found to check!$")
+
+(provide 'ispell)
+
+
+;;; LOCAL VARIABLES AND BUFFER-LOCAL VALUE EXAMPLES.
+
+;;; Local Variable options:
+;;; mode: name(-mode)
+;;; eval: expression
+;;; local-variable: value
+
+;;; The following sets the buffer local dictionary to `american' English
+;;; and spell checks only comments.
+
+;;; Local Variables:
+;;; mode: emacs-lisp
+;;; comment-column: 40
+;;; ispell-check-comments: exclusive
+;;; ispell-local-dictionary: "american"
+;;; End:
+
+
+;;; MORE EXAMPLES OF ISPELL BUFFER-LOCAL VALUES
+
+;;; The following places this file in nroff parsing and extended char modes.
+;;; Local IspellParsing: nroff-mode ~nroff
+;;; Change IspellPersDict to IspellPersDict: to enable the following line.
+;;; Local IspellPersDict ~/.ispell_lisp
+;;; The following were automatically generated by ispell using the 'A' command:
+; LocalWords: settable alist inews mh frag pdict Wildcards iconify arg tex kss
+; LocalWords: alists minibuffer bufferp autoload loaddefs aff Dansk KOI SPC op
+; LocalWords: Francais Nederlands charset autoloaded popup nonmenu regexp num
+; LocalWords: AMStex hspace includeonly nocite epsfig displaymath eqnarray reg
+; LocalWords: minipage modeline pers dict unhighlight buf grep sync prev inc
+; LocalWords: fn hilight oldot NB AIX msg init bufs pt cmd eg multibyte
+; LocalWords: uuencoded unidiff sc nn VM SGML eval IspellPersDict unsplitable
+; LocalWords: lns XEmacs html casechars Multibyte Aug unix wp iso multiline
+; LocalWords: multipart aspell Fcc regexps tib russian latin Slovakian
+
+;;; ispell.el ends here
diff --git a/spell/aspell b/spell/aspell
new file mode 100755
index 0000000..d23ad2c
--- /dev/null
+++ b/spell/aspell
Binary files differ
diff --git a/spell/aspell-0.60.6.1/ABOUT-NLS b/spell/aspell-0.60.6.1/ABOUT-NLS
new file mode 100644
index 0000000..ec20977
--- /dev/null
+++ b/spell/aspell-0.60.6.1/ABOUT-NLS
@@ -0,0 +1,1101 @@
+1 Notes on the Free Translation Project
+***************************************
+
+Free software is going international! The Free Translation Project is
+a way to get maintainers of free software, translators, and users all
+together, so that free software will gradually become able to speak many
+languages. A few packages already provide translations for their
+messages.
+
+ If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site. But you do _not_
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+ Installers will find here some useful hints. These notes also
+explain how users should proceed for getting the programs to use the
+available translations. They tell how people wanting to contribute and
+work on translations can contact the appropriate team.
+
+ When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used. The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+1.1 Quick configuration advice
+==============================
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+ ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed. So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias, message inheritance, automatic
+charset conversion or plural form handling) as the implementation here.
+It is also not possible to offer this additional functionality on top
+of a `catgets' implementation. Future versions of GNU `gettext' will
+very likely convey even more functionality. So it might be a good idea
+to change to GNU `gettext' as soon as possible.
+
+ So you need _not_ provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+1.2 INSTALL Matters
+===================
+
+Some packages are "localizable" when properly installed; the programs
+they contain can be made to speak your own native language. Most such
+packages use GNU `gettext'. Other packages have their own ways to
+internationalization, predating GNU `gettext'.
+
+ By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system already
+provides the GNU `gettext' functions. If not, the included GNU
+`gettext' library will be used. This library is wholly contained
+within this package, usually in the `intl/' subdirectory, so prior
+installation of the GNU `gettext' package is _not_ required.
+Installers may use special options at configuration time for changing
+the default behaviour. The commands:
+
+ ./configure --with-included-gettext
+ ./configure --disable-nls
+
+will, respectively, bypass any pre-existing `gettext' to use the
+internationalizing routines provided within this package, or else,
+_totally_ disable translation of messages.
+
+ When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this. This might not be desirable. You should use
+the more recent version of the GNU `gettext' library. I.e. if the file
+`intl/VERSION' shows that the library which comes with this package is
+more recent, you should use
+
+ ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+ The configuration process will not test for the `catgets' function
+and therefore it will not be used. The reason is that even an
+emulation of `gettext' on top of `catgets' could not provide all the
+extensions of the GNU `gettext' library.
+
+ Internationalized packages usually have many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language. Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package. However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+1.3 Using This Package
+======================
+
+As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
+and `CC' is an ISO 3166 two-letter country code. For example, let's
+suppose that you speak German and live in Germany. At the shell
+prompt, merely execute `setenv LANG de_DE' (in `csh'),
+`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
+This can be done from your `.login' or `.profile' file, once and for
+all.
+
+ You might think that the country code specification is redundant.
+But in fact, some languages have dialects in different countries. For
+example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
+country code serves to distinguish the dialects.
+
+ The locale naming convention of `LL_CC', with `LL' denoting the
+language and `CC' denoting the country, is the one use on systems based
+on GNU libc. On other systems, some variations of this scheme are
+used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
+locales supported by your system for your language by running the
+command `locale -a | grep '^LL''.
+
+ Not all programs have translations for all languages. By default, an
+English message is shown in place of a nonexistent translation. If you
+understand other languages, you can set up a priority list of languages.
+This is done through a different environment variable, called
+`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
+for the purpose of message handling, but you still need to have `LANG'
+set to the primary language; this is required by other parts of the
+system libraries. For example, some Swedish users who would rather
+read translations in German than English for when Swedish is not
+available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
+
+ Special advice for Norwegian users: The language code for Norwegian
+bokma*l changed from `no' to `nb' recently (in 2003). During the
+transition period, while some message catalogs for this language are
+installed under `nb' and some older ones under `no', it's recommended
+for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
+older translations are used.
+
+ In the `LANGUAGE' environment variable, but not in the `LANG'
+environment variable, `LL_CC' combinations can be abbreviated as `LL'
+to denote the language's main dialect. For example, `de' is equivalent
+to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
+(Portuguese as spoken in Portugal) in this context.
+
+1.4 Translating Teams
+=====================
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list. The up-to-date list of
+teams can be found at the Free Translation Project's homepage,
+`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
+area.
+
+ If you'd like to volunteer to _work_ at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is _not_ the same as the list itself, it has
+`-request' appended. For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+ subscribe
+
+ Keep in mind that team members are expected to participate
+_actively_ in translations, or at solving translational difficulties,
+rather than merely lurking around. If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `translation@iro.umontreal.ca' to reach the
+coordinator for all translator teams.
+
+ The English team is special. It works at improving and uniformizing
+the terminology in use. Proven linguistic skills are praised more than
+programming skills, here.
+
+1.5 Available Packages
+======================
+
+Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of October
+2006. The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination, with a
+translation percentage of at least 50%.
+
+ Ready PO files af am ar az be bg bs ca cs cy da de el en en_GB eo
+ +----------------------------------------------------+
+ GNUnet | [] |
+ a2ps | [] [] [] [] [] |
+ aegis | () |
+ ant-phone | () |
+ anubis | [] |
+ ap-utils | |
+ aspell | [] [] [] [] [] |
+ bash | [] [] [] |
+ batchelor | [] |
+ bfd | |
+ bibshelf | [] |
+ binutils | [] |
+ bison | [] [] |
+ bison-runtime | |
+ bluez-pin | [] [] [] [] [] |
+ cflow | [] |
+ clisp | [] [] |
+ console-tools | [] [] |
+ coreutils | [] [] [] |
+ cpio | |
+ cpplib | [] [] [] |
+ cryptonit | [] |
+ darkstat | [] () [] |
+ dialog | [] [] [] [] [] [] |
+ diffutils | [] [] [] [] [] [] |
+ doodle | [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] |
+ error | [] [] [] [] |
+ fetchmail | [] [] () [] |
+ fileutils | [] [] |
+ findutils | [] [] [] |
+ flex | [] [] [] |
+ fslint | [] |
+ gas | |
+ gawk | [] [] [] |
+ gbiff | [] |
+ gcal | [] |
+ gcc | [] |
+ gettext-examples | [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] |
+ gettext-tools | [] [] |
+ gimp-print | [] [] [] [] |
+ gip | [] |
+ gliv | [] |
+ glunarclock | [] |
+ gmult | [] [] |
+ gnubiff | () |
+ gnucash | () () [] |
+ gnucash-glossary | [] () |
+ gnuedu | |
+ gnulib | [] [] [] [] [] [] |
+ gnunet-gtk | |
+ gnutls | |
+ gpe-aerial | [] [] |
+ gpe-beam | [] [] |
+ gpe-calendar | |
+ gpe-clock | [] [] |
+ gpe-conf | [] [] |
+ gpe-contacts | |
+ gpe-edit | [] |
+ gpe-filemanager | |
+ gpe-go | [] |
+ gpe-login | [] [] |
+ gpe-ownerinfo | [] [] |
+ gpe-package | |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] |
+ gpe-taskmanager | [] [] |
+ gpe-timesheet | [] |
+ gpe-today | [] [] |
+ gpe-todo | |
+ gphoto2 | [] [] [] [] |
+ gprof | [] [] |
+ gpsdrive | () () |
+ gramadoir | [] [] |
+ grep | [] [] [] [] [] [] |
+ gretl | |
+ gsasl | |
+ gss | |
+ gst-plugins | [] [] [] [] |
+ gst-plugins-base | [] [] [] |
+ gst-plugins-good | [] [] [] [] [] [] [] |
+ gstreamer | [] [] [] [] [] [] [] |
+ gtick | () |
+ gtkam | [] [] [] |
+ gtkorphan | [] [] |
+ gtkspell | [] [] [] [] |
+ gutenprint | [] |
+ hello | [] [] [] [] [] |
+ id-utils | [] [] |
+ impost | |
+ indent | [] [] [] |
+ iso_3166 | [] [] |
+ iso_3166_2 | |
+ iso_4217 | [] |
+ iso_639 | [] [] |
+ jpilot | [] |
+ jtag | |
+ jwhois | |
+ kbd | [] [] [] [] |
+ keytouch | |
+ keytouch-editor | |
+ keytouch-keyboa... | |
+ latrine | () |
+ ld | [] |
+ leafpad | [] [] [] [] [] |
+ libc | [] [] [] [] [] |
+ libexif | [] |
+ libextractor | [] |
+ libgpewidget | [] [] [] |
+ libgpg-error | [] |
+ libgphoto2 | [] [] |
+ libgphoto2_port | [] [] |
+ libgsasl | |
+ libiconv | [] [] |
+ libidn | [] [] |
+ lifelines | [] () |
+ lilypond | [] |
+ lingoteach | |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] [] |
+ mailutils | [] |
+ make | [] [] |
+ man-db | [] () [] [] |
+ minicom | [] [] [] |
+ mysecretdiary | [] [] |
+ nano | [] [] [] |
+ nano_1_0 | [] () [] [] |
+ opcodes | [] |
+ parted | |
+ pilot-qof | [] |
+ psmisc | [] |
+ pwdutils | |
+ python | |
+ qof | |
+ radius | [] |
+ recode | [] [] [] [] [] [] |
+ rpm | [] [] |
+ screem | |
+ scrollkeeper | [] [] [] [] [] [] [] [] |
+ sed | [] [] [] |
+ sh-utils | [] [] |
+ shared-mime-info | [] [] [] [] |
+ sharutils | [] [] [] [] [] [] |
+ shishi | |
+ silky | |
+ skencil | [] () |
+ sketch | [] () |
+ solfege | |
+ soundtracker | [] [] |
+ sp | [] |
+ stardict | [] |
+ system-tools-ba... | [] [] [] [] [] [] [] [] [] |
+ tar | [] |
+ texinfo | [] [] [] |
+ textutils | [] [] [] |
+ tin | () () |
+ tp-robot | [] |
+ tuxpaint | [] [] [] [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux | [] [] [] [] |
+ vorbis-tools | [] [] [] [] |
+ wastesedge | () |
+ wdiff | [] [] [] [] |
+ wget | [] [] |
+ xchat | [] [] [] [] [] [] |
+ xkeyboard-config | |
+ xpad | [] [] |
+ +----------------------------------------------------+
+ af am ar az be bg bs ca cs cy da de el en en_GB eo
+ 10 0 1 2 9 22 1 42 41 2 60 95 16 1 17 16
+
+ es et eu fa fi fr ga gl gu he hi hr hu id is it
+ +--------------------------------------------------+
+ GNUnet | |
+ a2ps | [] [] [] () |
+ aegis | |
+ ant-phone | [] |
+ anubis | [] |
+ ap-utils | [] [] |
+ aspell | [] [] [] |
+ bash | [] [] [] |
+ batchelor | [] [] |
+ bfd | [] |
+ bibshelf | [] [] [] |
+ binutils | [] [] [] |
+ bison | [] [] [] [] [] [] |
+ bison-runtime | [] [] [] [] [] |
+ bluez-pin | [] [] [] [] [] |
+ cflow | [] |
+ clisp | [] [] |
+ console-tools | |
+ coreutils | [] [] [] [] [] [] |
+ cpio | [] [] [] |
+ cpplib | [] [] |
+ cryptonit | [] |
+ darkstat | [] () [] [] [] |
+ dialog | [] [] [] [] [] [] [] [] |
+ diffutils | [] [] [] [] [] [] [] [] [] |
+ doodle | [] [] |
+ e2fsprogs | [] [] [] |
+ enscript | [] [] [] |
+ error | [] [] [] [] [] |
+ fetchmail | [] |
+ fileutils | [] [] [] [] [] [] |
+ findutils | [] [] [] [] |
+ flex | [] [] [] |
+ fslint | [] |
+ gas | [] [] |
+ gawk | [] [] [] [] |
+ gbiff | [] |
+ gcal | [] [] |
+ gcc | [] |
+ gettext-examples | [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] |
+ gettext-tools | [] [] [] |
+ gimp-print | [] [] |
+ gip | [] [] [] |
+ gliv | () |
+ glunarclock | [] [] [] |
+ gmult | [] [] [] |
+ gnubiff | () () |
+ gnucash | () () () |
+ gnucash-glossary | [] [] |
+ gnuedu | [] |
+ gnulib | [] [] [] [] [] [] [] [] |
+ gnunet-gtk | |
+ gnutls | |
+ gpe-aerial | [] [] |
+ gpe-beam | [] [] |
+ gpe-calendar | |
+ gpe-clock | [] [] [] [] |
+ gpe-conf | [] |
+ gpe-contacts | [] [] |
+ gpe-edit | [] [] [] [] |
+ gpe-filemanager | [] |
+ gpe-go | [] [] [] |
+ gpe-login | [] [] [] |
+ gpe-ownerinfo | [] [] [] [] [] |
+ gpe-package | [] |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] [] [] |
+ gpe-taskmanager | [] [] [] |
+ gpe-timesheet | [] [] [] [] |
+ gpe-today | [] [] [] [] |
+ gpe-todo | [] |
+ gphoto2 | [] [] [] [] [] |
+ gprof | [] [] [] [] |
+ gpsdrive | () () [] () |
+ gramadoir | [] [] |
+ grep | [] [] [] [] [] [] [] [] [] [] [] [] |
+ gretl | [] [] [] |
+ gsasl | [] [] |
+ gss | [] |
+ gst-plugins | [] [] [] |
+ gst-plugins-base | [] [] |
+ gst-plugins-good | [] [] [] |
+ gstreamer | [] [] [] |
+ gtick | [] |
+ gtkam | [] [] [] [] |
+ gtkorphan | [] [] |
+ gtkspell | [] [] [] [] [] [] |
+ gutenprint | [] |
+ hello | [] [] [] [] [] [] [] [] [] [] [] [] [] |
+ id-utils | [] [] [] [] [] |
+ impost | [] [] |
+ indent | [] [] [] [] [] [] [] [] [] [] |
+ iso_3166 | [] [] [] |
+ iso_3166_2 | [] |
+ iso_4217 | [] [] [] [] |
+ iso_639 | [] [] [] [] [] |
+ jpilot | [] [] |
+ jtag | [] |
+ jwhois | [] [] [] [] [] |
+ kbd | [] [] |
+ keytouch | [] |
+ keytouch-editor | [] |
+ keytouch-keyboa... | [] |
+ latrine | [] [] [] |
+ ld | [] [] |
+ leafpad | [] [] [] [] [] [] |
+ libc | [] [] [] [] [] |
+ libexif | [] |
+ libextractor | [] |
+ libgpewidget | [] [] [] [] [] |
+ libgpg-error | |
+ libgphoto2 | [] [] [] |
+ libgphoto2_port | [] [] |
+ libgsasl | [] [] |
+ libiconv | [] [] |
+ libidn | [] [] |
+ lifelines | () |
+ lilypond | [] |
+ lingoteach | [] [] [] |
+ lynx | [] [] [] |
+ m4 | [] [] [] [] |
+ mailutils | [] [] |
+ make | [] [] [] [] [] [] [] [] |
+ man-db | () |
+ minicom | [] [] [] [] |
+ mysecretdiary | [] [] [] |
+ nano | [] [] [] [] [] [] |
+ nano_1_0 | [] [] [] [] [] |
+ opcodes | [] [] [] [] |
+ parted | [] [] [] [] |
+ pilot-qof | |
+ psmisc | [] [] [] |
+ pwdutils | |
+ python | |
+ qof | [] |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] [] [] |
+ rpm | [] [] |
+ screem | |
+ scrollkeeper | [] [] [] |
+ sed | [] [] [] [] [] |
+ sh-utils | [] [] [] [] [] [] [] |
+ shared-mime-info | [] [] [] [] [] [] |
+ sharutils | [] [] [] [] [] [] [] [] |
+ shishi | |
+ silky | [] |
+ skencil | [] [] |
+ sketch | [] [] |
+ solfege | [] |
+ soundtracker | [] [] [] |
+ sp | [] |
+ stardict | [] |
+ system-tools-ba... | [] [] [] [] [] [] [] [] |
+ tar | [] [] [] [] [] [] [] |
+ texinfo | [] [] |
+ textutils | [] [] [] [] [] |
+ tin | [] () |
+ tp-robot | [] [] [] [] |
+ tuxpaint | [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | [] [] |
+ util-linux | [] [] [] [] [] [] [] |
+ vorbis-tools | [] [] |
+ wastesedge | () |
+ wdiff | [] [] [] [] [] [] [] [] |
+ wget | [] [] [] [] [] [] [] [] |
+ xchat | [] [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] [] [] |
+ xpad | [] [] [] |
+ +--------------------------------------------------+
+ es et eu fa fi fr ga gl gu he hi hr hu id is it
+ 88 22 14 2 40 115 61 14 1 8 1 6 59 31 0 52
+
+ ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no
+ +-------------------------------------------------+
+ GNUnet | |
+ a2ps | () [] [] () |
+ aegis | () |
+ ant-phone | [] |
+ anubis | [] [] [] |
+ ap-utils | [] |
+ aspell | [] [] |
+ bash | [] |
+ batchelor | [] [] |
+ bfd | |
+ bibshelf | [] |
+ binutils | |
+ bison | [] [] [] |
+ bison-runtime | [] [] [] |
+ bluez-pin | [] [] [] |
+ cflow | |
+ clisp | [] |
+ console-tools | |
+ coreutils | [] |
+ cpio | |
+ cpplib | [] |
+ cryptonit | [] |
+ darkstat | [] [] |
+ dialog | [] [] |
+ diffutils | [] [] [] |
+ doodle | |
+ e2fsprogs | [] |
+ enscript | [] |
+ error | [] |
+ fetchmail | [] [] |
+ fileutils | [] [] |
+ findutils | [] |
+ flex | [] [] |
+ fslint | [] [] |
+ gas | |
+ gawk | [] [] |
+ gbiff | [] |
+ gcal | |
+ gcc | |
+ gettext-examples | [] [] |
+ gettext-runtime | [] [] [] |
+ gettext-tools | [] [] |
+ gimp-print | [] [] |
+ gip | [] [] |
+ gliv | [] |
+ glunarclock | [] [] |
+ gmult | [] [] |
+ gnubiff | |
+ gnucash | () () |
+ gnucash-glossary | [] |
+ gnuedu | |
+ gnulib | [] [] [] [] |
+ gnunet-gtk | |
+ gnutls | |
+ gpe-aerial | [] |
+ gpe-beam | [] |
+ gpe-calendar | [] |
+ gpe-clock | [] [] [] |
+ gpe-conf | [] [] |
+ gpe-contacts | [] |
+ gpe-edit | [] [] [] |
+ gpe-filemanager | [] [] |
+ gpe-go | [] [] [] |
+ gpe-login | [] [] [] |
+ gpe-ownerinfo | [] [] |
+ gpe-package | [] [] |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] [] |
+ gpe-taskmanager | [] [] [] [] |
+ gpe-timesheet | [] |
+ gpe-today | [] [] |
+ gpe-todo | [] |
+ gphoto2 | [] [] |
+ gprof | |
+ gpsdrive | () () () |
+ gramadoir | () |
+ grep | [] [] [] [] |
+ gretl | |
+ gsasl | [] |
+ gss | |
+ gst-plugins | [] |
+ gst-plugins-base | |
+ gst-plugins-good | [] |
+ gstreamer | [] |
+ gtick | |
+ gtkam | [] |
+ gtkorphan | [] |
+ gtkspell | [] [] |
+ gutenprint | |
+ hello | [] [] [] [] [] [] |
+ id-utils | [] |
+ impost | |
+ indent | [] [] |
+ iso_3166 | [] |
+ iso_3166_2 | [] |
+ iso_4217 | [] [] [] |
+ iso_639 | [] [] |
+ jpilot | () () () |
+ jtag | |
+ jwhois | [] |
+ kbd | [] |
+ keytouch | [] |
+ keytouch-editor | |
+ keytouch-keyboa... | |
+ latrine | [] |
+ ld | |
+ leafpad | [] [] |
+ libc | [] [] [] [] [] |
+ libexif | |
+ libextractor | |
+ libgpewidget | [] |
+ libgpg-error | |
+ libgphoto2 | [] |
+ libgphoto2_port | [] |
+ libgsasl | [] |
+ libiconv | |
+ libidn | [] [] |
+ lifelines | [] |
+ lilypond | |
+ lingoteach | [] |
+ lynx | [] [] |
+ m4 | [] [] |
+ mailutils | |
+ make | [] [] [] |
+ man-db | () |
+ minicom | [] |
+ mysecretdiary | [] |
+ nano | [] [] [] |
+ nano_1_0 | [] [] [] |
+ opcodes | [] |
+ parted | [] [] |
+ pilot-qof | |
+ psmisc | [] [] [] |
+ pwdutils | |
+ python | |
+ qof | |
+ radius | |
+ recode | [] |
+ rpm | [] [] |
+ screem | [] |
+ scrollkeeper | [] [] [] [] |
+ sed | [] [] |
+ sh-utils | [] [] |
+ shared-mime-info | [] [] [] [] [] |
+ sharutils | [] [] |
+ shishi | |
+ silky | [] |
+ skencil | |
+ sketch | |
+ solfege | |
+ soundtracker | |
+ sp | () |
+ stardict | [] [] |
+ system-tools-ba... | [] [] [] [] |
+ tar | [] [] [] |
+ texinfo | [] [] [] |
+ textutils | [] [] [] |
+ tin | |
+ tp-robot | [] |
+ tuxpaint | [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux | [] [] |
+ vorbis-tools | [] |
+ wastesedge | [] |
+ wdiff | [] [] |
+ wget | [] [] |
+ xchat | [] [] [] [] |
+ xkeyboard-config | [] |
+ xpad | [] [] [] |
+ +-------------------------------------------------+
+ ja ko ku ky lg lt lv mk mn ms mt nb ne nl nn no
+ 52 24 2 2 1 3 0 2 3 21 0 15 1 97 5 1
+
+ nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
+ +------------------------------------------------------+
+ GNUnet | |
+ a2ps | () [] [] [] [] [] [] |
+ aegis | () () |
+ ant-phone | [] [] |
+ anubis | [] [] [] |
+ ap-utils | () |
+ aspell | [] [] |
+ bash | [] [] [] |
+ batchelor | [] [] |
+ bfd | |
+ bibshelf | [] |
+ binutils | [] [] |
+ bison | [] [] [] [] [] |
+ bison-runtime | [] [] [] [] |
+ bluez-pin | [] [] [] [] [] [] [] [] [] |
+ cflow | [] |
+ clisp | [] |
+ console-tools | [] |
+ coreutils | [] [] [] [] |
+ cpio | [] [] [] |
+ cpplib | [] |
+ cryptonit | [] [] |
+ darkstat | [] [] [] [] [] [] |
+ dialog | [] [] [] [] [] [] [] [] [] |
+ diffutils | [] [] [] [] [] [] |
+ doodle | [] [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] [] |
+ error | [] [] [] [] |
+ fetchmail | [] [] [] |
+ fileutils | [] [] [] [] [] |
+ findutils | [] [] [] [] [] [] |
+ flex | [] [] [] [] [] |
+ fslint | [] [] [] [] |
+ gas | |
+ gawk | [] [] [] [] |
+ gbiff | [] |
+ gcal | [] |
+ gcc | [] |
+ gettext-examples | [] [] [] [] [] [] [] [] |
+ gettext-runtime | [] [] [] [] [] [] [] [] |
+ gettext-tools | [] [] [] [] [] [] [] |
+ gimp-print | [] [] |
+ gip | [] [] [] [] |
+ gliv | [] [] [] [] |
+ glunarclock | [] [] [] [] [] [] |
+ gmult | [] [] [] [] |
+ gnubiff | () |
+ gnucash | () [] |
+ gnucash-glossary | [] [] [] |
+ gnuedu | |
+ gnulib | [] [] [] [] [] |
+ gnunet-gtk | [] |
+ gnutls | [] [] |
+ gpe-aerial | [] [] [] [] [] [] [] |
+ gpe-beam | [] [] [] [] [] [] [] |
+ gpe-calendar | [] |
+ gpe-clock | [] [] [] [] [] [] [] [] |
+ gpe-conf | [] [] [] [] [] [] [] |
+ gpe-contacts | [] [] [] [] [] |
+ gpe-edit | [] [] [] [] [] [] [] [] |
+ gpe-filemanager | [] [] |
+ gpe-go | [] [] [] [] [] [] |
+ gpe-login | [] [] [] [] [] [] [] [] |
+ gpe-ownerinfo | [] [] [] [] [] [] [] [] |
+ gpe-package | [] [] |
+ gpe-sketchbook | [] [] [] [] [] [] [] [] |
+ gpe-su | [] [] [] [] [] [] [] [] |
+ gpe-taskmanager | [] [] [] [] [] [] [] [] |
+ gpe-timesheet | [] [] [] [] [] [] [] [] |
+ gpe-today | [] [] [] [] [] [] [] [] |
+ gpe-todo | [] [] [] [] |
+ gphoto2 | [] [] [] [] [] |
+ gprof | [] [] [] |
+ gpsdrive | [] [] [] |
+ gramadoir | [] [] |
+ grep | [] [] [] [] [] [] [] [] |
+ gretl | [] |
+ gsasl | [] [] [] |
+ gss | [] [] [] |
+ gst-plugins | [] [] [] [] |
+ gst-plugins-base | [] |
+ gst-plugins-good | [] [] [] [] |
+ gstreamer | [] [] [] |
+ gtick | [] |
+ gtkam | [] [] [] [] |
+ gtkorphan | [] |
+ gtkspell | [] [] [] [] [] [] [] [] |
+ gutenprint | [] |
+ hello | [] [] [] [] [] [] [] [] |
+ id-utils | [] [] [] [] |
+ impost | [] |
+ indent | [] [] [] [] [] [] |
+ iso_3166 | [] [] [] [] [] [] |
+ iso_3166_2 | |
+ iso_4217 | [] [] [] [] |
+ iso_639 | [] [] [] [] |
+ jpilot | |
+ jtag | [] |
+ jwhois | [] [] [] [] |
+ kbd | [] [] [] |
+ keytouch | [] |
+ keytouch-editor | [] |
+ keytouch-keyboa... | [] |
+ latrine | [] [] |
+ ld | [] |
+ leafpad | [] [] [] [] [] [] |
+ libc | [] [] [] [] [] |
+ libexif | [] |
+ libextractor | [] [] |
+ libgpewidget | [] [] [] [] [] [] [] |
+ libgpg-error | [] [] |
+ libgphoto2 | [] |
+ libgphoto2_port | [] [] [] |
+ libgsasl | [] [] [] [] |
+ libiconv | [] [] |
+ libidn | [] [] () |
+ lifelines | [] [] |
+ lilypond | |
+ lingoteach | [] |
+ lynx | [] [] [] |
+ m4 | [] [] [] [] [] |
+ mailutils | [] [] [] [] |
+ make | [] [] [] [] |
+ man-db | [] [] |
+ minicom | [] [] [] [] [] |
+ mysecretdiary | [] [] [] [] |
+ nano | [] [] [] |
+ nano_1_0 | [] [] [] [] |
+ opcodes | [] [] |
+ parted | [] |
+ pilot-qof | [] |
+ psmisc | [] [] |
+ pwdutils | [] [] |
+ python | |
+ qof | [] [] |
+ radius | [] [] |
+ recode | [] [] [] [] [] [] [] |
+ rpm | [] [] [] [] |
+ screem | |
+ scrollkeeper | [] [] [] [] [] [] [] |
+ sed | [] [] [] [] [] [] [] [] [] |
+ sh-utils | [] [] [] |
+ shared-mime-info | [] [] [] [] [] |
+ sharutils | [] [] [] [] |
+ shishi | [] |
+ silky | [] |
+ skencil | [] [] [] |
+ sketch | [] [] [] |
+ solfege | [] |
+ soundtracker | [] [] |
+ sp | |
+ stardict | [] [] [] |
+ system-tools-ba... | [] [] [] [] [] [] [] [] [] |
+ tar | [] [] [] [] [] |
+ texinfo | [] [] [] [] |
+ textutils | [] [] [] |
+ tin | () |
+ tp-robot | [] |
+ tuxpaint | [] [] [] [] [] |
+ unicode-han-tra... | |
+ unicode-transla... | |
+ util-linux | [] [] [] [] |
+ vorbis-tools | [] [] |
+ wastesedge | |
+ wdiff | [] [] [] [] [] [] |
+ wget | [] [] [] [] |
+ xchat | [] [] [] [] [] [] [] |
+ xkeyboard-config | [] [] |
+ xpad | [] [] [] |
+ +------------------------------------------------------+
+ nso or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv ta
+ 0 2 3 58 30 54 5 73 72 4 40 46 11 50 128 2
+
+ tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu
+ +---------------------------------------------------+
+ GNUnet | [] | 2
+ a2ps | [] [] [] | 19
+ aegis | | 0
+ ant-phone | [] [] | 6
+ anubis | [] [] [] | 11
+ ap-utils | () [] | 4
+ aspell | [] [] [] | 15
+ bash | [] | 11
+ batchelor | [] [] | 9
+ bfd | | 1
+ bibshelf | [] | 7
+ binutils | [] [] [] | 9
+ bison | [] [] [] | 19
+ bison-runtime | [] [] [] | 15
+ bluez-pin | [] [] [] [] [] [] | 28
+ cflow | [] [] | 5
+ clisp | | 6
+ console-tools | [] [] | 5
+ coreutils | [] [] | 16
+ cpio | [] [] [] | 9
+ cpplib | [] [] [] [] | 11
+ cryptonit | | 5
+ darkstat | [] () () | 15
+ dialog | [] [] [] [] [] | 30
+ diffutils | [] [] [] [] | 28
+ doodle | [] | 6
+ e2fsprogs | [] [] | 10
+ enscript | [] [] [] | 16
+ error | [] [] [] [] | 18
+ fetchmail | [] [] | 12
+ fileutils | [] [] [] | 18
+ findutils | [] [] [] | 17
+ flex | [] [] | 15
+ fslint | [] | 9
+ gas | [] | 3
+ gawk | [] [] | 15
+ gbiff | [] | 5
+ gcal | [] | 5
+ gcc | [] [] [] | 6
+ gettext-examples | [] [] [] [] [] [] | 27
+ gettext-runtime | [] [] [] [] [] [] | 28
+ gettext-tools | [] [] [] [] [] | 19
+ gimp-print | [] [] | 12
+ gip | [] [] | 12
+ gliv | [] [] | 8
+ glunarclock | [] [] [] | 15
+ gmult | [] [] [] [] | 15
+ gnubiff | [] | 1
+ gnucash | () | 2
+ gnucash-glossary | [] [] | 9
+ gnuedu | [] | 2
+ gnulib | [] [] [] [] [] | 28
+ gnunet-gtk | | 1
+ gnutls | | 2
+ gpe-aerial | [] [] | 14
+ gpe-beam | [] [] | 14
+ gpe-calendar | [] | 3
+ gpe-clock | [] [] [] [] | 21
+ gpe-conf | [] [] | 14
+ gpe-contacts | [] [] | 10
+ gpe-edit | [] [] [] [] | 20
+ gpe-filemanager | [] | 6
+ gpe-go | [] [] | 15
+ gpe-login | [] [] [] [] [] | 21
+ gpe-ownerinfo | [] [] [] [] | 21
+ gpe-package | [] | 6
+ gpe-sketchbook | [] [] | 16
+ gpe-su | [] [] [] | 20
+ gpe-taskmanager | [] [] [] | 20
+ gpe-timesheet | [] [] [] [] | 18
+ gpe-today | [] [] [] [] [] | 21
+ gpe-todo | [] | 7
+ gphoto2 | [] [] [] [] | 20
+ gprof | [] [] | 11
+ gpsdrive | | 4
+ gramadoir | [] | 7
+ grep | [] [] [] [] | 34
+ gretl | | 4
+ gsasl | [] [] | 8
+ gss | [] | 5
+ gst-plugins | [] [] [] | 15
+ gst-plugins-base | [] [] [] | 9
+ gst-plugins-good | [] [] [] [] [] | 20
+ gstreamer | [] [] [] | 17
+ gtick | [] | 3
+ gtkam | [] | 13
+ gtkorphan | [] | 7
+ gtkspell | [] [] [] [] [] [] | 26
+ gutenprint | | 3
+ hello | [] [] [] [] [] | 37
+ id-utils | [] [] | 14
+ impost | [] | 4
+ indent | [] [] [] [] | 25
+ iso_3166 | [] [] [] [] | 16
+ iso_3166_2 | | 2
+ iso_4217 | [] [] | 14
+ iso_639 | [] | 14
+ jpilot | [] [] [] [] | 7
+ jtag | [] | 3
+ jwhois | [] [] [] | 13
+ kbd | [] [] | 12
+ keytouch | [] | 4
+ keytouch-editor | | 2
+ keytouch-keyboa... | [] | 3
+ latrine | [] [] | 8
+ ld | [] [] [] [] | 8
+ leafpad | [] [] [] [] | 23
+ libc | [] [] [] | 23
+ libexif | [] | 4
+ libextractor | [] | 5
+ libgpewidget | [] [] [] | 19
+ libgpg-error | [] | 4
+ libgphoto2 | [] | 8
+ libgphoto2_port | [] [] [] | 11
+ libgsasl | [] | 8
+ libiconv | [] | 7
+ libidn | [] [] | 10
+ lifelines | | 4
+ lilypond | | 2
+ lingoteach | [] | 6
+ lynx | [] [] [] | 15
+ m4 | [] [] [] | 18
+ mailutils | [] | 8
+ make | [] [] [] | 20
+ man-db | [] | 6
+ minicom | [] | 14
+ mysecretdiary | [] [] | 12
+ nano | [] [] | 17
+ nano_1_0 | [] [] [] | 18
+ opcodes | [] [] | 10
+ parted | [] [] [] | 10
+ pilot-qof | [] | 3
+ psmisc | [] | 10
+ pwdutils | [] | 3
+ python | | 0
+ qof | [] | 4
+ radius | [] | 6
+ recode | [] [] [] | 25
+ rpm | [] [] [] [] | 14
+ screem | [] | 2
+ scrollkeeper | [] [] [] [] | 26
+ sed | [] [] [] | 22
+ sh-utils | [] | 15
+ shared-mime-info | [] [] [] [] | 24
+ sharutils | [] [] [] | 23
+ shishi | | 1
+ silky | [] | 4
+ skencil | [] | 7
+ sketch | | 6
+ solfege | | 2
+ soundtracker | [] [] | 9
+ sp | [] | 3
+ stardict | [] [] [] [] | 11
+ system-tools-ba... | [] [] [] [] [] [] [] | 37
+ tar | [] [] [] [] | 20
+ texinfo | [] [] [] | 15
+ textutils | [] [] [] | 17
+ tin | | 1
+ tp-robot | [] [] [] | 10
+ tuxpaint | [] [] [] | 16
+ unicode-han-tra... | | 0
+ unicode-transla... | | 2
+ util-linux | [] [] [] | 20
+ vorbis-tools | [] [] | 11
+ wastesedge | | 1
+ wdiff | [] [] | 22
+ wget | [] [] [] | 19
+ xchat | [] [] [] [] | 29
+ xkeyboard-config | [] [] [] [] | 11
+ xpad | [] [] [] | 14
+ +---------------------------------------------------+
+ 77 teams tg th tk tr uk ven vi wa xh zh_CN zh_HK zh_TW zu
+ 170 domains 0 1 1 77 39 0 136 10 1 48 5 54 0 2028
+
+ Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect. This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+ For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer. There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+ If October 2006 seems to be old, you may fetch a more recent copy of
+this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date
+matrix with full percentage details can be found at
+`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
+
+1.6 Using `gettext' in new packages
+===================================
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU `gettext' in your
+package. Of course you have to respect the GNU Library General Public
+License which covers the use of the GNU `gettext' library. This means
+in particular that even non-free programs can use `libintl' as a shared
+library, whereas only free software can use `libintl' as a static
+library or use modified versions of `libintl'.
+
+ Once the sources are changed appropriately and the setup can handle
+the use of `gettext' the only thing missing are the translations. The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project. Therefore the information given above
+applies also for every other Free Software Project. Contact
+`translation@iro.umontreal.ca' to make the `.pot' files available to
+the translation teams.
+
diff --git a/spell/aspell-0.60.6.1/COPYING b/spell/aspell-0.60.6.1/COPYING
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/spell/aspell-0.60.6.1/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/spell/aspell-0.60.6.1/Makefile.am b/spell/aspell-0.60.6.1/Makefile.am
new file mode 100644
index 0000000..950319d
--- /dev/null
+++ b/spell/aspell-0.60.6.1/Makefile.am
@@ -0,0 +1,400 @@
+AUTOMAKE_OPTIONS = foreign subdir-objects
+SUBDIRS = . po manual
+DIST_SUBDIRS = ${SUBDIRS} examples myspell lib5
+
+# These are needed due to a bug in Automake
+pkgdatadir = @pkgdatadir@
+pkglibdir = @pkglibdir@
+
+filterdir = ${pkglibdir}
+optdir = ${pkgdatadir}
+localedir = ${datadir}/locale
+
+PERLPROG = @PERLPROG@
+
+AM_CPPFLAGS = -I${srcdir}/gen -I${srcdir}/common \
+ -I${srcdir}/interfaces/cc/ -I${srcdir}/modules/speller/default/
+
+SUFFIXES = .info
+
+noinst_DATA =
+EXTRA_DIST = config.rpath win32/Makefile win32/settings.h
+
+########################################################################
+#
+# libaspell and friends
+#
+
+lib_LTLIBRARIES = libaspell.la
+
+if PSPELL_COMPATIBILITY
+lib_LTLIBRARIES += libpspell.la
+endif
+
+libaspell_la_SOURCES =\
+ common/cache.cpp\
+ common/string.cpp\
+ common/getdata.cpp\
+ common/itemize.cpp\
+ common/file_util.cpp\
+ common/string_map.cpp\
+ common/string_list.cpp\
+ common/config.cpp\
+ common/posib_err.cpp\
+ common/errors.cpp\
+ common/error.cpp\
+ common/fstream.cpp\
+ common/iostream.cpp\
+ common/info.cpp\
+ common/can_have_error.cpp\
+ common/convert.cpp\
+ common/tokenizer.cpp\
+ common/speller.cpp\
+ common/document_checker.cpp\
+ common/filter.cpp\
+ common/objstack.cpp \
+ common/strtonum.cpp\
+ common/gettext_init.cpp\
+ common/file_data_util.cpp\
+ modules/speller/default/readonly_ws.cpp\
+ modules/speller/default/suggest.cpp\
+ modules/speller/default/data.cpp\
+ modules/speller/default/multi_ws.cpp\
+ modules/speller/default/phonetic.cpp\
+ modules/speller/default/writable.cpp\
+ modules/speller/default/speller_impl.cpp\
+ modules/speller/default/phonet.cpp\
+ modules/speller/default/typo_editdist.cpp\
+ modules/speller/default/editdist.cpp\
+ modules/speller/default/primes.cpp\
+ modules/speller/default/language.cpp\
+ modules/speller/default/leditdist.cpp\
+ modules/speller/default/affix.cpp\
+ modules/tokenizer/basic.cpp\
+ lib/filter-c.cpp\
+ lib/word_list-c.cpp\
+ lib/info-c.cpp\
+ lib/mutable_container-c.cpp\
+ lib/error-c.cpp\
+ lib/document_checker-c.cpp\
+ lib/string_map-c.cpp\
+ lib/new_config.cpp\
+ lib/config-c.cpp\
+ lib/string_enumeration-c.cpp\
+ lib/can_have_error-c.cpp\
+ lib/dummy.cpp\
+ lib/new_filter.cpp\
+ lib/new_fmode.cpp\
+ lib/string_list-c.cpp\
+ lib/find_speller.cpp\
+ lib/speller-c.cpp\
+ lib/string_pair_enumeration-c.cpp\
+ lib/new_checker.cpp
+
+libaspell_la_LIBADD = $(LTLIBINTL) $(PTHREAD_LIB)
+
+if INCREMENTED_SONAME
+libaspell_la_LDFLAGS = -version-info 16:5:0 -no-undefined
+else
+libaspell_la_LDFLAGS = -version-info 16:5:1 -no-undefined
+endif
+
+if PSPELL_COMPATIBILITY
+libpspell_la_SOURCES = lib/dummy.cpp
+
+libpspell_la_LIBADD = libaspell.la
+
+if INCREMENTED_SONAME
+libpspell_la_LDFLAGS = -version-info 16:5:0 -no-undefined
+else
+libpspell_la_LDFLAGS = -version-info 16:5:1 -no-undefined
+endif
+
+endif
+
+EXTRA_DIST += common/*.hpp common/*.h\
+ modules/speller/default/*.hpp\
+ lib/*.hpp
+
+########################################################################
+#
+# Aspell Program
+#
+
+AM_CPPFLAGS += -DLOCALEDIR="$(localedir)"
+
+bin_PROGRAMS = word-list-compress aspell prezip-bin
+
+word_list_compress_SOURCES = prog/compress.c
+
+aspell_SOURCES = prog/aspell.cpp prog/check_funs.cpp prog/checker_string.cpp
+
+aspell_LDADD = libaspell.la $(CURSES_LIB)
+
+prezip_bin_SOURCES = prog/prezip.c
+
+EXTRA_DIST += prog/*.hpp
+
+########################################################################
+#
+# Filter Modules
+#
+
+# This is for filters which are ALWAYS static. Currently only the
+# URL filter
+
+libaspell_la_SOURCES += modules/filter/url.cpp
+static_optfiles = modules/filter/url-filter.info
+
+dynamic_optfiles =
+
+###
+### To add a new filter follow the instruction that begin with '###'
+###
+
+### Add the .info file your filter comes with
+optfiles = \
+ modules/filter/email-filter.info\
+ modules/filter/tex-filter.info\
+ modules/filter/sgml-filter.info\
+ modules/filter/html-filter.info\
+ modules/filter/context-filter.info\
+ modules/filter/nroff-filter.info\
+ modules/filter/texinfo-filter.info
+
+### Add all your aspell mode files ###
+fltfiles = \
+ modules/filter/modes/html.amf \
+ modules/filter/modes/sgml.amf \
+ modules/filter/modes/tex.amf \
+ modules/filter/modes/email.amf \
+ modules/filter/modes/ccpp.amf \
+ modules/filter/modes/none.amf \
+ modules/filter/modes/perl.amf \
+ modules/filter/modes/url.amf \
+ modules/filter/modes/comment.amf \
+ modules/filter/modes/nroff.amf\
+ modules/filter/modes/texinfo.amf
+
+if COMPILE_IN_FILTERS
+
+static_optfiles += ${optfiles}
+
+### Add your filter sources here,
+### starting with file containing filter class definition followed by
+### file containing filter member implementation.
+libaspell_la_SOURCES +=\
+ modules/filter/email.cpp\
+ modules/filter/tex.cpp\
+ modules/filter/sgml.cpp\
+ modules/filter/context.cpp\
+ modules/filter/nroff.cpp\
+ modules/filter/texinfo.cpp
+
+else # not COMPILE_IN_FILTERS
+
+dynamic_optfiles += ${optfiles}
+filter_ldflags = -module -avoid-version
+
+### Add name of filter library containing your filter. Name always
+### must look like lib<filtername>-filter.la see development manual
+filter_LTLIBRARIES = email-filter.la tex-filter.la\
+ sgml-filter.la context-filter.la\
+ nroff-filter.la texinfo-filter.la
+
+email_filter_la_SOURCES = modules/filter/email.cpp
+email_filter_la_LIBADD = libaspell.la
+email_filter_la_LDFLAGS = ${filter_ldflags}
+
+tex_filter_la_SOURCES = modules/filter/tex.cpp
+tex_filter_la_LIBADD = libaspell.la
+tex_filter_la_LDFLAGS = ${filter_ldflags}
+
+sgml_filter_la_SOURCES = modules/filter/sgml.cpp
+sgml_filter_la_LIBADD = libaspell.la
+sgml_filter_la_LDFLAGS = ${filter_ldflags}
+
+context_filter_la_SOURCES = modules/filter/context.cpp
+context_filter_la_LIBADD = libaspell.la
+context_filter_la_LDFLAGS = ${filter_ldflags}
+
+nroff_filter_la_SOURCES = modules/filter/nroff.cpp
+nroff_filter_la_LIBADD = libaspell.la
+nroff_filter_la_LDFLAGS = ${filter_ldflags}
+
+texinfo_filter_la_SOURCES = modules/filter/texinfo.cpp
+texinfo_filter_la_LIBADD = libaspell.la
+texinfo_filter_la_LDFLAGS = ${filter_ldflags}
+
+### Before this line add the corresponding <yourfilterlibrary>_SOURCES and
+### <yourfilterlibrary>_LIBADD lines. The later at least has to look
+### like <yourfilterlibrary>_LIBADD = ${top_builddir}/lib/libaspell.la
+### in order to make your filter build properly
+
+endif # COMPILE_IN_FILTERS
+
+noinst_DATA += $(static_optfiles) gen/filter.pot
+opt_DATA = $(dynamic_optfiles)
+filter_DATA = $(fltfiles)
+
+# settings.h added as a dependency so it will get recreated if
+# the COMPILE_IN_FILTERS option changes
+gen/static_filters.src.cpp: ${static_optfiles} gen/mk-static-filter.pl gen/settings.h
+ ${PERLPROG} gen/mk-static-filter.pl ${static_optfiles}
+
+lib/new_filter.cpp: gen/static_filters.src.cpp
+
+gen/filter.pot: gen/mk-filter-pot.pl ${static_optfiles} ${dynamic_optfiles}
+ ${PERLPROG} gen/mk-filter-pot.pl
+
+EXTRA_DIST += ${static_optfiles} ${dynamic_optfiles} ${fltfiles} \
+ gen/mk-static-filter.pl gen/mk-filter-pot.pl\
+ gen/filter.pot
+
+CLEANFILES = gen/static_filters.src.cpp
+
+########################################################################
+#
+# Mk Dirs Target
+#
+
+common/config.cpp: gen/dirs.h
+
+gen/dirs.h: gen/mk-dirs_h.pl
+ cd gen; perl mk-dirs_h.pl ${prefix} ${pkgdatadir} ${pkglibdir} ${sysconfdir} > dirs.h
+
+EXTRA_DIST += gen/mk-dirs_h.pl
+CLEANFILES += gen/dirs.h
+
+########################################################################
+#
+# Scripts
+#
+
+bin_SCRIPTS = scripts/run-with-aspell scripts/aspell-import \
+ scripts/prezip scripts/preunzip scripts/precat
+
+pkgdata_SCRIPTS = scripts/spell scripts/ispell
+
+scripts/run-with-aspell: scripts/run-with-aspell.create
+ sh ${srcdir}/scripts/run-with-aspell.create ${pkgdatadir} > scripts/run-with-aspell
+ chmod 755 scripts/run-with-aspell
+
+
+if PSPELL_COMPATIBILITY
+
+bin_SCRIPTS += scripts/pspell-config
+scripts/pspell-config: scripts/mkconfig
+ sh ${srcdir}/scripts/mkconfig ${VERSION} ${datadir} ${pkgdatadir}
+CLEANFILES += scripts/pspell-config
+
+endif
+
+CLEANFILES += scripts/run-with-aspell
+
+EXTRA_DIST += scripts/mkconfig scripts/spell scripts/ispell \
+ scripts/run-with-aspell.create scripts/aspell-import\
+ scripts/prezip scripts/preunzip scripts/precat
+
+########################################################################
+#
+# auto
+#
+
+# FIXME: add dependences
+
+noinst_DATA += auto
+
+mksrc = \
+ auto/mk-src.in auto/mk-src.pl auto/mk-doc.pl\
+ auto/MkSrc/CcHelper.pm auto/MkSrc/Methods.pm\
+ auto/MkSrc/ProcImpl.pm auto/MkSrc/Read.pm\
+ auto/MkSrc/Create.pm auto/MkSrc/ProcCc.pm\
+ auto/MkSrc/ProcNativeImpl.pm auto/MkSrc/Type.pm\
+ auto/MkSrc/Info.pm auto/MkSrc/ProcCxx.pm\
+ auto/MkSrc/ProcNative.pm auto/MkSrc/Util.pm
+
+#auto: @MAINTAINER_MODE_TRUE@ ${mksrc}
+# cd auto; perl mk-src.pl
+# cd auto; perl auto/mk-doc.pl
+# touch auto/auto
+
+EXTRA_DIST += auto/auto auto/mk-src.txt ${mksrc}
+
+
+########################################################################
+#
+# interfaces
+#
+
+include_HEADERS = interfaces/cc/aspell.h
+
+if PSPELL_COMPATIBILITY
+
+pspell_includedir = ${includedir}/pspell
+
+pspell_include_HEADERS = interfaces/cc/pspell.h
+
+endif
+
+########################################################################
+#
+# Misc Top level
+#
+
+pkgdata_DATA = \
+ data/cp1250.cmap data/cp1250.cset \
+ data/cp1251.cmap data/cp1251.cset \
+ data/cp1252.cmap data/cp1252.cset \
+ data/cp1253.cmap data/cp1253.cset \
+ data/cp1254.cmap data/cp1254.cset \
+ data/cp1255.cmap data/cp1255.cset \
+ data/cp1256.cmap data/cp1256.cset \
+ data/cp1257.cmap data/cp1257.cset \
+ data/cp1258.cmap data/cp1258.cset \
+ data/iso-8859-1.cmap data/iso-8859-1.cset \
+ data/iso-8859-2.cmap data/iso-8859-2.cset \
+ data/iso-8859-3.cmap data/iso-8859-3.cset \
+ data/iso-8859-4.cmap data/iso-8859-4.cset \
+ data/iso-8859-5.cmap data/iso-8859-5.cset \
+ data/iso-8859-6.cmap data/iso-8859-6.cset \
+ data/iso-8859-7.cmap data/iso-8859-7.cset \
+ data/iso-8859-8.cmap data/iso-8859-8.cset \
+ data/iso-8859-9.cmap data/iso-8859-9.cset \
+ data/iso-8859-10.cmap data/iso-8859-10.cset \
+ data/iso-8859-11.cmap data/iso-8859-11.cset \
+ data/iso-8859-13.cmap data/iso-8859-13.cset \
+ data/iso-8859-14.cmap data/iso-8859-14.cset \
+ data/iso-8859-15.cmap data/iso-8859-15.cset \
+ data/iso-8859-16.cmap data/iso-8859-16.cset \
+ data/koi8-r.cmap data/koi8-r.cset \
+ data/koi8-u.cmap data/koi8-u.cset \
+ data/dvorak.kbd data/split.kbd data/standard.kbd
+
+EXTRA_DIST += config.rpath README ${pkgdata_DATA} m4/*.m4 \
+ misc/po-filter.c
+
+README: manual/readme.texi
+ makeinfo --no-validate --no-headers $< > README
+
+maintainer-clean-local:
+ @find . \( -name '*.?pp' -o -name '*.h' -o -name '*.info' \) -print |\
+ xargs grep -l "Automatically generated file." |\
+ xargs rm
+
+dist-hook:
+ mkdir $(distdir)/maintainer
+ cp autogen config-opt config-debug TODO FIXMEs README-CVS \
+ $(distdir)/maintainer
+
+ACLOCAL_AMFLAGS = -I m4
+
+.PHONY: .manual fake-manual
+
+.manual:
+ $(MAKE) -C manual manual
+manual: .manual
+ $(MAKE) -C manual manual
+
+fake-manual:
+ $(MAKE) -C manual fake-manual
diff --git a/spell/aspell-0.60.6.1/README b/spell/aspell-0.60.6.1/README
new file mode 100644
index 0000000..0a3d277
--- /dev/null
+++ b/spell/aspell-0.60.6.1/README
@@ -0,0 +1,378 @@
+Appendix A Installing
+*********************
+
+Aspell requires gcc 2.95 (or better) as the C++ compiler. Other C++
+compilers should work with some effort. Other C++ compilers for mostly
+POSIX compliant (Unix, Linux, BeOS, Cygwin) systems should work without
+any major problems provided that the compile can handle all of the
+advanced C++ features Aspell uses. C++ compilers for non-Unix systems
+might work but it will take some work. Aspell at very least requires a
+Unix-like environment (`sh', `grep', `sed', `tr', ...), and Perl in
+order to build. Aspell also uses a few POSIX functions when necessary.
+
+ The latest version can always be found at GNU Aspell's home page at
+`http://aspell.net'.
+
+A.1 Generic Install Instructions
+================================
+
+ ./configure && make
+
+ For additional `configure' options type `./configure --help'. You
+can control what C++ compiler is used by setting the environment
+variable `CXX' before running configure and you can control what flags
+are passed to the C++ compile via the environment variable `CXXFLAGS'.
+Static libraries are disabled by default since static libraries will
+not work right due to the mixing of C and C++. When a C program links
+with the static libraries in Aspell it is likely to crash because
+Aspell's C++ objects are not getting initialized correctly. However,
+if for some reason you want them, you can enable them via
+`--enable-static'.
+
+ Aspell should then compile without any additional user intervention.
+If you run into problems please first check the sections below as that
+might solve your problem.
+
+ To install the program simply type
+
+ make install
+
+ After Aspell is installed at least one dictionary needs to be
+installed. You can find them at `http://aspell.net/'. The `aspell'
+program must be in your path in order for the dictionaries to install
+correctly.
+
+ If you do not have Ispell or the traditional Unix `spell' utility
+installed on your system then you should also copy the compatibility
+scripts `ispell' and `spell' located in the `scripts/' directory into
+your binary directory which is usually `/usr/local/bin' so that
+programs that expect the `ispell' or `spell' command will work
+correctly.
+
+A.2 HTML Manuals and `make clean'
+=================================
+
+The Aspell distribution includes HTML versions of the User and
+Developer's manual. Unfortunately, doing a `make clean' will erase
+them. This is due to a limitation of automake which is not easily
+fixed. If makeinfo is installed they can easily be rebuild with `make
+aspell.html aspell-dev.html', or you can unpack them from the tarbar.
+
+A.3 Curses Notes
+================
+
+If you are having problems compiling `check_funs.cpp' then the most
+likely reason is due to incompatibilities with the curses
+implementation on your system. You should first try disabling the
+"wide" curses library by with the `--disable-wide-curses' configure
+option.. By doing so you will lose support for properly displaying
+UTF-8 characters but you may still be able to get the full screen
+interface. If this fails than you can disable curses support
+altogether with the `--disable-curses' configure option. By doing this
+you will lose the nice full screen interface but hopefully you will be
+able to at least get Aspell to compile correctly.
+
+ If the curses library is installed in a non-standard location than
+you can specify the library and include directory with
+`--enable-curses=LIB' and `--enable-curses-include=DIR'.
+
+ `LIB' can either be the complete path of the library--for example
+ /usr/local/curses/libcurses.a
+ or the name of the library (for example `ncurses') or a combined
+location and library in the form `-LLIBDIR -lLIB' (for example
+`-L/usr/local/ncurses/lib -lncurses').
+
+ DIR is the location of the curses header files (for example
+`/usr/local/ncurses/include').
+
+A.3.1 Unicode Support
+---------------------
+
+In order for Aspell to correctly spell check UTF-8 documents in full
+screen mode the "wide" version of the curses library must be installed.
+This is different from the normal version of curses library, and is
+normally named `libcursesw' (with a `w' at the end) or `libncursesw'.
+UTF-8 documents will not display correctly without the right curses
+version installed.
+
+ In addition your system must also support the `mblen' function.
+Although this function was defined in the ISO C89 standard (ANSI
+X3.159-1989), not all systems have it.
+
+A.4 Loadable Filter Notes
+=========================
+
+Support for being able to load additional filter modules at run-time
+has only been verified to work on Linux platforms. If you get linker
+errors when trying to use a filter, then it is likely that loadable
+filter support is not working yet on your platform. Thus, in order to
+get Aspell to work correctly you will need to avoid compiling the
+filters as individual modules by using the
+`--enable-compile-in-filters' when configuring Aspell with
+`./configure'.
+
+A.5 Upgrading from Aspell 0.50
+==============================
+
+The dictionary format has changed so dictionaries will need to be
+recompiled.
+
+ All data, by default, is now included in `LIBDIR/aspell-0.60' so
+that multiple versions of Aspell can more peacefully coexist. This
+included both the dictionaries and the language data files which were
+stored in `SHAREDIR/aspell' before Aspell 0.60.
+
+ The format of the character data files has changed. The new
+character data files are installed with Aspell so you should not have
+to worry about it unless you made a custom one.
+
+ The dictionary option `strip-accents' has been removed. For this
+reason the old English dictionary (up to 0.51) will no longer work. A
+new English dictionary is now available which avoids using this option.
+In addition the `ignore-accents' option is currently unimplemented.
+
+ The flag `-l' is now a shortcut for `--lang', instead of `--list' as
+it was with Aspell 0.50.
+
+A.5.1 Binary Compatibility
+--------------------------
+
+The Aspell 0.60 library is binary compatible with the Aspell 0.50
+library. For this reason I chose _not_ to increment the major version
+number (so-name) of the shared library by default which means programs
+that were compiled for Aspell 0.50 will also work for Aspell 0.60.
+However, this means that having both Aspell 0.50 and Aspell 0.60
+installed at the same time can be pragmatic. If you wish to allow both
+Aspell 0.50 and 0.60 to be installed at the same time then you can use
+the configure option `--incremented-soname' which will increment
+so-name. You should only use this option if you know what you are
+doing. It is up to you to somehow ensure that both the Aspell 0.50 and
+0.60 executables can coexist.
+
+ If after incrementing the so-name you wish to allow programs compiled
+for Aspell 0.50 to use Aspell 0.60 instead (thus implying that Aspell
+0.50 is not installed) then you can use a special compatibility library
+which can be found in the `lib5' directory. This directory will not be
+entered when building or installing Aspell so you must manually build
+and install this library. You should build it after the rest of Aspell
+is built. The order in which this library is installed, with relation
+to the rest of Aspell, is also important. If it is installed _after_
+the rest of Aspell then new programs will link to the old library
+(which will work for Aspell 0.50 or 0.60) when built, if installed
+_before_, new programs will link with the new library (Aspell 0.60
+only).
+
+A.6 Upgrading from Aspell .33/Pspell .12
+========================================
+
+Aspell has undergone an extremely large number of changes since the
+previous Aspell/Pspell release. For one thing Pspell has been merged
+with Aspell so there in no longer two separate libraries you have to
+worry about.
+
+ Because of the massive changes between Aspell/Pspell and Aspell 0.50
+you may want to clean out the old files before installing the the new
+Aspell. To do so do a `make uninstall' in the original Aspell and
+Pspell source directories.
+
+ The way dictionaries are handled has also changed. This includes a
+change in the naming conventions of both language names and
+dictionaries. Due to the language name change, your old personal
+dictionaries will not be recognized. However, you can import the old
+dictionaries by running the `aspell-import' script. This also means
+that dictionaries designed to work with older versions of Aspell are
+not likely to function correctly. Fortunately new dictionary packages
+are available for most languages. You can find them off of the Aspell
+home page at `http://aspell.net'.
+
+ The Pspell ABI is now part of Aspell except that the name of
+everything has changed due to the renaming of Pspell to Aspell. In
+particular please note the following name changes:
+
+ pspell -> aspell
+ manager -> speller
+ emulation -> enumeration
+ master_word_list -> main_word_list
+
+ Please also note that the name of the `language-tag' option has
+changed to `lang'. However, for backward compatibility the
+`language-tag' option will still work.
+
+ However, you should also be able to build applications that require
+Pspell with the new Aspell as a backward compatibility header file is
+provided.
+
+ Due to a change in the way dictionaries are handled, scanning for
+`.pwli' files in order to find out which dictionaries are available
+will no longer work. This means that programs that relied on this
+technique may have problems finding dictionaries. Fortunately, GNU
+Aspell now provided a uniform way to list all installed dictionaries
+via the c API. See the file `list-dicts.c' in the `examples/'
+directory for an example of how to do this. Unfortunately there isn't
+any simple way to find out which dictionaries are installed which will
+work with both the old Aspell/Pspell and the new GNU Aspell.
+
+A.7 Upgrading from a Pre-0.50 snapshot
+======================================
+
+At the last minute I decided to merge the `speller-util' program into
+the main `aspell' program. You may wish to remove that `speller-util'
+program to avoid confusion. This also means that dictionaries designed
+to work with the snapshot will no longer work with the official release.
+
+A.8 WIN32 Notes
+===============
+
+A.8.1 Getting the WIN32 version
+-------------------------------
+
+The latest version of the native Aspell/WIN32 port, including binaries,
+can be found at `http://aspell.net/win32'. This page has,
+unfortunately, not been updated for Aspell 0.60. If you are interested
+in updated the native port please let me know.
+
+A.8.2 Building the WIN32 version
+--------------------------------
+
+There are two basically different ways of building Aspell using GCC for
+WIN32: You can either use the Cygwin compiler, which will produce
+binaries that depend on the POSIX layer in `cygwin1.dll'. The other
+way is using MinGW GCC, those binaries use the native C runtime from
+Microsoft (MSVCRT.DLL).
+
+A.8.2.1 Building Aspell using Cygwin
+....................................
+
+This works exactly like on other POSIX compatible systems using the
+`./configure && make && make install' cycle. Some versions of Cygwin
+GCC will fail to link, this is caused by an incorrect `libstdc++.la' in
+the `/lib' directory. After removing or renaming this file, the build
+progress should work (GCC-2.95 and GCC-3.x should work).
+
+A.8.2.2 Building Aspell using MinGW
+...................................
+
+There are several different ways to build Aspell using MinGW. The
+easiest way is to use a Cygwin compiler but instruct it to build a
+native binary rather than a Cygwin one. To do this configure with:
+
+ ./configure CFLAGS='-O2 -mno-cygwin' CXXFLAGS='-O2 -mno-cygwin'
+
+ You may also want to add the option `--enable-win32-relocatable' to
+use more windows friendly directories. *Note Win32-Directories::. In
+this case configure with:
+
+ ./configure CFLAGS='-O2 -mno-cygwin' CXXFLAGS='-O2 -mno-cygwin' --enable-win32-relocatable
+
+ It should also be possible to build Aspell using the MSYS
+environment. But this has not been very well tested. If building with
+MSYS _do not_ add `CFLAGS ...' to configure.
+
+A.8.2.3 Building Aspell without using Cygwin or MSYS
+....................................................
+
+It is also possible to build Aspell without Cygwin of MinGW by using
+the files in the `win32/' subdirectory. However, these files have not
+been updated to work with Aspell 0.60. Thus the following instructions
+will not work without some effort. If you do get Aspell to compile
+this way please send me the updated files so that I can include them
+with the next release.
+
+ To compile Aspell with the MinGW compiler, you will need at least
+GCC-3.2 (as shipped with MinGW-2.0.3) and some GNU tools like `rm' and
+`cp'. The origin of those tools doesn't matter, it has shown to work
+with any tools from MinGW/MSys, Cygwin or Linux. To build Aspell, move
+into the `win32' subdirectory and type `make'. You can enable some
+additional build options by either commenting out the definitions at
+the head of the Makefile or passing those values as environment
+variables or at the `make' command line. Following options are
+supported:
+
+`DEBUGVERSION'
+ If set to "1", the binaries will include debugging information
+ (resulting in a much bigger size).
+
+`CURSESDIR'
+ Enter the path to the pdcurses library here, in order to get a
+ nicer console interface (see below).
+
+`MSVCLIB'
+ Enter the filename of MS `lib.exe' here, if you want to build
+ libraries that can be imported from MS Visual C++.
+
+`WIN32_RELOCATABLE'
+ If set to "1", Aspell will detect the prefix from the path where
+ the DLL resides (see below for further details).
+
+`TARGET'
+ Sets a prefix to be used for cross compilation (e.g.
+ `/usr/local/bin/i586-mingw32msvc-' to cross compile from Linux).
+
+ There are also a MinGW compilers available for Cygwin and Linux, both
+versions are able to compile Aspell using the prebuilt `Makefile'.
+While the Cygwin port automatically detects the correct compiler, the
+Linux version depends on setting the `TARGET' variable in the
+`Makefile' (or environment) to the correct compiler prefix.
+
+ Other compilers may work. There is a patch for MS Visual C++ 6.0
+available at `ftp://ftp.gnu.org/gnu/aspell', but it needs a lot of
+changes to the Aspell sources. It has also been reported that the
+Intel C++ compiler can be used for compilation.
+
+A.8.3 (PD)Curses
+----------------
+
+In order to get the nice full screen interface when spell checking
+files, a curses implementation that does not require Cygwin is
+required. The PDCurses (`http://pdcurses.sourceforge.net')
+implementation is known to work, other implementations may work however
+they have not been tested. See the previous section for information on
+specifying the location of the curses library and include file.
+
+ Curses notes:
+
+ * PDcurses built with MinGW needs to be compiled with
+ `-DPDC_STATIC_BUILD' to avoid duplicate declaration of `DllMain'
+ when compiling `aspell.exe'.
+
+ * The curses enabled version can cause trouble in some shells (MSys
+ `rxvt', `emacs') and will produce errors like `initscr() LINES=1
+ COLS=1: too small'. Use a non-curses version for those purposes.
+
+A.8.4 Directories
+-----------------
+
+If Aspell is configured with `--enable-win32-relocatable' or compiled
+with `WIN32_RELOCATABLE=1' when using a Makefile, it can be run from
+any directory: it will set `PREFIX' according to its install location
+(assuming it resides in `PREFIX\\bin'). Your personal wordlists will
+be saved in the `PREFIX' directory with their names changed from
+`.aspell.LANG.*' to `LANG.*' (you can override the path by setting the
+`HOME' environment variable).
+
+A.8.5 Installer
+---------------
+
+The installer registers the DLLs as shared libraries, you should
+increase the reference counter to avoid the libraries being uninstalled
+if your application still depends on them (and decrease it again when
+uninstalling your program). The reference counters are located under:
+ HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs
+
+ The install location and version numbers are stored under
+
+ HKLM\SOFTWARE\Aspell
+
+A.8.6 WIN32 consoles
+--------------------
+
+The console uses a different encoding than GUI applications, changing
+this to to a Windows encoding (e.g. 1252) is not supported on
+Win9x/Me. On WinNT (and later) those codepages can be set by first
+changing the console font to `lucida console', then changing the
+codepage using `chcp 1252'.
+
+ Some alternative shells (e.g. MSys' `rxvt' or Cygwin's `bash') do a
+codepage conversion (if correctly set up), so running Aspell inside
+those shells might be a workaround for Win9x.
+
diff --git a/spell/aspell-0.60.6.1/TODO b/spell/aspell-0.60.6.1/TODO
new file mode 100644
index 0000000..1126a89
--- /dev/null
+++ b/spell/aspell-0.60.6.1/TODO
@@ -0,0 +1,5 @@
+Consider adding support for recognizing options translated in a
+ different language.
+
+
+
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/CcHelper.pm b/spell/aspell-0.60.6.1/auto/MkSrc/CcHelper.pm
new file mode 100644
index 0000000..e814a1a
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/CcHelper.pm
@@ -0,0 +1,339 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::CcHelper;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(to_c_return_type c_error_cond
+ to_type_name make_desc make_func call_func
+ make_c_method call_c_method form_c_method
+ make_cxx_method);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::Type;
+
+sub to_type_name ( $ $ ; \% );
+
+=head1 Code Generation Modes
+
+The code generation modes are currently one of the following:
+
+ cc: Mode used to create types suitable for C interface
+ cc_cxx: Like cc but typenames don't have a leading Aspell prefix
+ cxx: Mode used to create types suitable for CXX interface
+ native: Mode in which types are suitable for the internal implementation
+ native_no_err: Like Native but with out PosibErr return types
+
+=head1 MkSrc::CcHelper
+
+Helper functions used by interface generation code:
+
+=over
+
+=item to_c_return_type ITEM
+
+.
+
+=cut
+
+sub to_c_return_type ( $ ) {
+ my ($d) = @_;
+ return $d->{type} unless exists $d->{'posib err'};
+ return 'int' if one_of $d->{type}, ('void', 'bool', 'unsigned int');
+ return $d->{type};
+}
+
+=item c_error_cond ITEM
+
+.
+
+=cut
+
+sub c_error_cond ( $ ) {
+ my ($d) = @_;
+ die unless exists $d->{'posib err'};
+ return '-1' if one_of $d->{type}, ('bool', 'unsigned int', 'int');
+ return '0';
+}
+
+=item make_func NAME @TYPES PARMS ; %ACCUM
+
+Creates a function prototype
+
+Parms can be any of:
+
+ mode: code generation mode
+
+=cut
+
+sub make_func ( $ \@ $ ; \% ) {
+ my ($name, $d, $p, $accum) = @_;
+ $accum = {} unless defined $accum;
+ my @d = @$d;
+ return (join '',
+ (to_type_name(shift @d, {%$p,pos=>'return'}, %$accum),
+ ' ',
+ to_lower $name,
+ '(',
+ (join ', ', map {to_type_name $_, {%$p,pos=>'parm'}, %$accum} @d),
+ ')'));
+}
+
+=item call_func NAME @TYPES PARMS ; %ACCUM
+
+Return a string to call a func. Will prefix the function with return
+if the functions returns a non-void type;
+
+Parms can be any of:
+
+ mode: code generation mode
+
+=cut
+
+sub call_func ( $ \@ $ ; \% ) {
+ my ($name, $d, $p, $accum) = @_;
+ $accum = {} unless defined $accum;
+ my @d = @$d;
+ my $func_ret = to_type_name(shift @d, {%$p,pos=>'return'}, %$accum);
+ return (join '',
+ (($func_ret eq 'void' ? '' : 'return '),
+ to_lower $name,
+ '(',
+ (join ', ', map {to_type_name $_,
+ {%$p,pos=>'parm',use_type=>false}, %$accum} @d),
+ ')'));
+}
+
+=item to_type_name ITEM PARMS ; %ACCUM
+
+Converts item into a type name.
+
+Parms can be any of:
+
+ mode: code generation mode
+ use_type: include the actual type
+ use_name: include the name on the type
+ pos: either "return" or "other"
+
+=cut
+
+sub to_type_name ( $ $ ; \% ) {
+ my ($d, $p, $accum) = @_;
+ $accum = {} unless defined $accum;
+
+ my $mode = $p->{mode};
+ die unless one_of $mode, qw(cc cc_cxx cxx native native_no_err);
+ my $is_cc = one_of $mode, qw(cc cc_cxx cxx);
+ my $is_native = one_of $mode, qw(native native_no_err);
+
+ my $pos = $p->{pos};
+ my $t = finalized_type($pos eq 'return' && $is_cc
+ ? to_c_return_type $d
+ : $d->{type});
+ $p->{use_type} = true unless exists $p->{use_type};
+ $p->{use_name} = true unless exists $p->{use_name};
+ $p->{pos} = 'other' unless exists $p->{pos};
+
+ my $name = $t->{name};
+ my $type = $t->{type};
+
+ return ( (to_type_name {%$d, type=>'string'}, $p, %$accum) ,
+ (to_type_name {%$d, type=>'int', name=>"$d->{name}_size"}, $p, %$accum) )
+ if $name eq 'encoded string' && $is_cc && $pos eq 'parm';
+
+ my $str;
+
+ if ($p->{use_type})
+ {
+ $str .= "const " if $t->{const};
+
+ if ($name eq 'string') {
+ if ($is_native && $pos eq 'parm') {
+ $accum->{headers}{'parm string'} = true;
+ $str .= "ParmString";
+ } else {
+ $str .= "const char *";
+ }
+ } elsif ($name eq 'string obj') {
+ die unless $pos eq 'return';
+ if ($is_cc) {
+ $str .= "const char *";
+ } else {
+ $accum->{headers}{'string'} = true;
+ $str .= "String";
+ }
+ } elsif ($name eq 'encoded string') {
+ $str .= "const char *";
+ } elsif ($name eq '') {
+ $str .= "void";
+ } elsif ($name eq 'bool' && $is_cc) {
+ $str .= "int";
+ } elsif ($type eq 'basic') {
+ $str .= $name;
+ } elsif (one_of $type, qw(enum class struct union)) {
+ my $c_type = $type eq 'class' ? 'struct' : $type;
+ if ($t->{pointer}) {
+ $accum->{types}->{$name} = $t;
+ } else {
+ $accum->{headers}->{$t->{created_in}} = true;
+ }
+ $str .= "$c_type Aspell" if $mode eq 'cc';
+ $str .= to_mixed($name);
+ } else {
+ print STDERR "Warning: Unknown Type: $name\n";
+ $str .= "{unknown type: $name}";
+ }
+
+ if ($t->{pointer} && $type eq 'class' && $mode eq 'cxx') {
+ $str .= "Ptr";
+ } elsif ($t->{pointer}) {
+ $str .= " *";
+ }
+
+ }
+
+ if (defined $d->{name} && $p->{use_name})
+ {
+ $str .= " " unless $str eq '';
+ $str .= to_lower($d->{name});
+ }
+
+ $str .= "[$t->{array}]" if $t->{array} && $p->{use_type};
+
+ return $str;
+}
+
+=item make_desc DESC ; LEVEL
+
+Make a C comment out of DESC optionally indenting it LEVEL spaces.
+
+=cut
+
+sub make_desc ( $ ; $ ) {
+ my ($desc, $indent) = @_;
+ return '' unless defined $desc;
+ my @desc = split /\n/, $desc;
+ $indent = 0 unless defined $indent;
+ $indent = ' 'x$indent;
+ return ("$indent/* ".
+ join("\n$indent * ", @desc).
+ " */\n");
+}
+
+=item make_c_method CLASS ITEM PARMS ; %ACCUM
+
+Create the phototype for a C method which is really a function.
+
+Parms is any of:
+
+ mode: code generation mode
+ no_aspell: if true do not include aspell in the name
+ this_name: name for the paramater representing the current object
+
+=item call_c_method CLASS ITEM PARMS ; %ACCUM
+
+Like make_c_method but instead returns the appropriate string to call
+the function. If the function returns a non-void type the string will
+be prefixed with a return statement.
+
+=item form_c_method CLASS ITEM PARMS ; %ACCUM
+
+Like make_c_method except that it returns the array:
+
+ ($func, $data, $parms, $accum)
+
+which is suitable for passing into make_func. It will return an
+empty array if it can not make a method from ITEM.
+
+=cut
+
+sub form_c_method ($ $ $ ; \% )
+{
+ my ($class, $d, $p, $accum) = @_;
+ $accum = {} unless defined $accum;
+ my $mode = $p->{mode};
+ my $this_name = defined $p->{this_name} ? $p->{this_name} : 'ths';
+ my $name = $d->{name};
+ my $func = '';
+ my @data = ();
+ @data = @{$d->{data}} if defined $d->{data};
+ if ($d->{type} eq 'constructor') {
+ if (defined $name) {
+ $func = $name;
+ } else {
+ $func = "new aspell $class";
+ }
+ splice @data, 0, 0, {type => $class} unless exists $d->{'returns alt type'};
+ } elsif ($d->{type} eq 'destructor') {
+ $func = "delete aspell $class";
+ splice @data, 0, 0, ({type => 'void'}, {type=>$class, name=>$this_name});
+ } elsif ($d->{type} eq 'method') {
+ if (exists $d->{'c func'}) {
+ $func = $d->{'c func'};
+ } elsif (exists $d->{'prefix'}) {
+ $func = "$d->{prefix} $name";
+ } else {
+ $func = "aspell $class $name";
+ }
+ if (exists $d->{'const'}) {
+ splice @data, 1, 0, {type => "const $class", name=> $this_name};
+ } else {
+ splice @data, 1, 0, {type => "$class", name=> $this_name};
+ }
+ } else {
+ return ();
+ }
+ $func = "aspell $func" unless $func =~ /aspell/;
+ $func =~ s/aspell\ ?// if exists $p->{no_aspell};
+ return ($func, \@data, $p, $accum);
+}
+
+sub make_c_method ($ $ $ ; \%)
+{
+ my @ret = &form_c_method(@_);
+ return undef unless @ret > 0;
+ return &make_func(@ret);
+}
+
+sub call_c_method ($ $ $ ; \%)
+{
+ my @ret = &form_c_method(@_);
+ return undef unless @ret > 0;
+ return &call_func(@ret);
+}
+
+=item make_cxx_method ITEM PARMS ; %ACCUM
+
+Create the phototype for a C++ method.
+
+Parms is one of:
+
+ mode: code generation mode
+
+=cut
+
+sub make_cxx_method ( $ $ ; \% ) {
+ my ($d, $p, $accum) = @_;
+ my $ret;
+ $ret .= make_func $d->{name}, @{$d->{data}}, $p, %$accum;
+ $ret .= " const" if exists $d->{const};
+ return $ret;
+}
+
+=back
+
+=cut
+
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/Create.pm b/spell/aspell-0.60.6.1/auto/MkSrc/Create.pm
new file mode 100644
index 0000000..e467a10
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/Create.pm
@@ -0,0 +1,109 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::Create;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(create_cc_file create_file);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::Info;
+
+=head1 MKSrc::Create
+
+=over
+
+=item create_cc_file PARMS
+
+Create a source file.
+
+ Required Parms: type, dir, name, data
+ Boolean Parms: header, cxx
+ Optional Parms: namespace (required if cxx), pre_ext, accum
+
+=item create_file FILENAME DATA
+
+Writes DATA to FILENAME but only if DATA differs from the content of
+the file and the string:
+
+ Automatically generated file.
+
+is present in the existing file if it already exists.
+
+=back
+
+=cut
+
+sub create_cc_file ( % );
+
+sub create_file ( $ $ );
+
+sub create_cc_file ( % ) {
+ my (%p) = @_;
+ $p{name} = $p{data}{name} unless exists $p{name};
+ $p{ext} = $p{cxx} ? ($p{header} ? 'hpp' : 'cpp') : 'h';
+ my $body;
+ my %accum = exists $p{accum} ? (%{$p{accum}}) : ();
+ foreach my $d (@{$p{data}{data}}) {
+ next unless exists $info{$d->{type}}{proc}{$p{type}};
+ $body .= $info{$d->{type}}{proc}{$p{type}}->($d, \%accum);
+ }
+ return unless length($body) > 0;
+ my $file = <<'---';
+/* Automatically generated file. Do not edit directly. */
+
+/* This file is part of The New Aspell
+ * Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+ * license version 2.0 or 2.1. You should have received a copy of the
+ * LGPL license along with this library if you did not you can find it
+ * at http://www.gnu.org/. */
+
+---
+ my $hm = "ASPELL_". to_upper($p{name})."__".to_upper($p{ext});
+ $file .= "#ifndef $hm\n#define $hm\n\n" if $p{header};
+ $file .= "#include \"aspell.h\"\n" if $p{type} eq 'cxx';
+ $file .= "#include \"settings.h\"\n" if $p{type} eq 'native_impl' && $p{name} eq 'errors';
+ $file .= "#include \"gettext.h\"\n" if $p{type} eq 'native_impl' && $p{name} eq 'errors';
+ $file .= cmap {"#include \"".to_lower($_).".hpp\"\n"} sort keys %{$accum{headers}};
+ $file .= "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" if $p{header} && !$p{cxx};
+ $file .= "\nnamespace $p{namespace} {\n\n" if $p{cxx};
+ if (defined $info{forward}{proc}{$p{type}}) {
+ my @types = sort {$a->{name} cmp $b->{name}} (values %{$accum{types}});
+ $file .= cmap {$info{forward}{proc}{$p{type}}->($_)} @types;
+ }
+ $file .= "\n";
+ $file .= $body;
+ $file .= "\n\n}\n\n" if $p{cxx};
+ $file .= "#ifdef __cplusplus\n}\n#endif\n" if $p{header} && !$p{cxx};
+ $file .= "#endif /* $hm */\n" if $p{header};
+ create_file $p{dir}.'/'.to_lower($p{name}).$p{pre_ext}.'.'.$p{ext}, $file;
+}
+
+sub create_file ( $ $ ) {
+ my ($filename, $to_write) = @_;
+ local $/ = undef;
+ my $existing = '';
+ open F,"../$filename" and $existing=<F>;
+ if ($to_write eq $existing) {
+ print "File \"$filename\" unchanged.\n";
+ } elsif (length $existing > 0 && $existing !~ /Automatically generated file\./) {
+ print "Will not write over \"$filename\".\n";
+ } else {
+ print "Creating \"$filename\".\n";
+ open F, ">../$filename" or die;
+ print F $to_write;
+ }
+}
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/Info.pm b/spell/aspell-0.60.6.1/auto/MkSrc/Info.pm
new file mode 100644
index 0000000..5d30ec5
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/Info.pm
@@ -0,0 +1,161 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::Info;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(%info %types %methods);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+=head1 MkSrc::Info
+
+=head2 %info
+
+The info array contains information on how to process the info in
+mk-src.pl. It has the following layout
+
+ <category> => options => []
+ groups => [] # if undef than anything is accepted
+ creates_type => "" # the object will create a new type
+ # as specified
+ proc => <impl type> => sub {}
+
+where <impl type> is one of:
+
+ cc: for "aspell.h" header file
+ cxx: for C++ interface implemented on top of cc interface
+ native: for creation of header files used internally by aspell
+ impl: for definition of functions declared in cc interface.
+ the definitions use the native header files
+ native_impl: for implementations of stuff declared in the native
+ header files
+
+each proc sub should take the following argv
+
+ $data: a subtree of $master_data
+ $accum:
+
+<options> is one of:
+
+ desc: description of the object
+ prefix:
+ posib err: the method may return an error condition
+ c func:
+ const: the method is a const member
+ c only: only include in the external interface
+ c impl headers: extra headers that need to be included in the C impl
+ c impl: use this as the c impl instead of the default
+ cxx impl: use this as the cxx impl instead of the default
+ returns alt type: the constructor returns some type other than
+ the object from which it is a member of
+ no native: do not attemt to create a native implementation
+ treat as object: treat as a object rather than a pointer
+
+The %info structure is initialized as follows:
+
+=cut
+
+#pod
+ our %info =
+ (
+ root => {
+ options => [],
+ groups => ['methods', 'group']},
+ methods => {
+ # methods is a collection of methods which will be inserted into
+ # a class after some simple substation rules. A $ will be
+ # replaced with name of the class.
+ options => ['strip', 'prefix', 'c impl headers'],
+ groups => undef},
+ group => {
+ # a group is a colection of objects which should be grouped together
+ # this generally means they will be in the same source file
+ options => ['no native'],
+ groups => ['enum', 'struct', 'union', 'func', 'class', 'errors']},
+ enum => {
+ # basic C enum
+ options => ['desc', 'prefix'],
+ creates_type => 'enum'},
+ struct => {
+ # basic c struct
+ options => ['desc', 'treat as object'],
+ groups => undef,
+ creates_type => 'struct',},
+ union => {
+ # basic C union
+ options => ['desc', 'treat as object'],
+ groups => undef,
+ creates_type => 'union'},
+ class => {
+ # C++ class
+ options => ['c impl headers'],
+ groups => undef,
+ creates_type => 'class'},
+ errors => {}, # possible errors
+ method => {
+ # A class method
+ options => ['desc', 'posib err', 'c func', 'const',
+ 'c only', 'c impl', 'cxx impl'],
+ groups => undef},
+ constructor => {
+ # A class constructor
+ options => ['returns alt type', 'c impl', 'desc'],
+ groups => 'types'},
+ destructor => {
+ # A class destructor
+ options => [],
+ groups => undef},
+ );
+#cut
+
+=pod
+
+In addition to the categories listed above a "methods" catagory by
+be specified in under the class category. A "methods" catagory is
+created for each methods group under the name "<methods name> methods"
+When groups is undefined a type name may be specified in place of
+a category
+
+=head2 %types
+
+types contains a master list of all types. This includes basic types
+and ones created in mk-src.in. The basic types include:
+
+=cut
+
+my @types =
+ (
+#pod
+ 'void', 'bool', 'pointer', 'double',
+ 'string', 'encoded string', 'string obj',
+ 'char', 'unsigned char',
+ 'short', 'unsigned short',
+ 'int', 'unsigned int',
+ 'long', 'unsigned long'
+#cut
+ );
+
+our %types;
+use MkSrc::Type;
+foreach my $t (@types) {
+ update_type $t, {type=>'basic'}}
+
+=head2 %methods
+
+%methods is used for holding the "methods" information
+
+=cut
+
+our %methods;
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/Methods.pm b/spell/aspell-0.60.6.1/auto/MkSrc/Methods.pm
new file mode 100644
index 0000000..b8587dc
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/Methods.pm
@@ -0,0 +1,58 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::Methods;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(copy_methods);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Info;
+
+sub copy_n_sub ( $ $ );
+sub copy_methods ( $ $ $ ) {
+ my ($d, $data, $class_name) = @_;
+ my $ms = $methods{$d->{type}};
+ if (not defined $d->{name}) {
+ $d->{name} = $class_name;
+ $d->{name} =~ s/ [^ ]+$// if $ms->{strip} == 1;
+ }
+ my @lst;
+ if (defined $ms->{'c impl headers'}) {
+ $data->{'c impl headers'} .= ",$ms->{'c impl headers'}";
+ }
+ foreach my $m (@{$ms->{data}}) {
+ push @lst, copy_n_sub($m, $d->{name});
+ $lst[-1]{prefix} = $m->{prefix} if exists $d->{prefix};
+ }
+ return @lst
+}
+
+sub copy_n_sub ( $ $ ) {
+ my ($d, $name) = @_;
+ my $new_d = {};
+ foreach my $k (keys %$d) {
+ if ($k eq 'data') {
+ $new_d->{data} = [];
+ foreach my $d0 (@{$d->{data}}) {
+ push @{$new_d->{data}}, copy_n_sub($d0, $name);
+ }
+ } else {
+ $new_d->{$k} = $d->{$k};
+ $new_d->{$k} =~ s/\$/$name/g unless ref $new_d->{$k};
+ }
+ }
+ return $new_d;
+}
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/ProcCc.pm b/spell/aspell-0.60.6.1/auto/MkSrc/ProcCc.pm
new file mode 100644
index 0000000..47c4338
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/ProcCc.pm
@@ -0,0 +1,129 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::ProcCc;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::CcHelper;
+use MkSrc::Info;
+
+sub make_c_object ( $ @ );
+
+$info{group}{proc}{cc} = sub {
+ my ($data) = @_;
+ my $ret;
+ my $stars = (70 - length $data->{name})/2;
+ $ret .= "/";
+ $ret .= '*'x$stars;
+ $ret .= " $data->{name} ";
+ $ret .= '*'x$stars;
+ $ret .= "/\n";
+ foreach my $d (@{$data->{data}}) {
+ $ret .= "\n\n";
+ $ret .= $info{$d->{type}}{proc}{cc}->($d);
+ }
+ $ret .= "\n\n";
+ return $ret;
+};
+
+$info{enum}{proc}{cc} = sub {
+ my ($d) = @_;
+ my $n = "Aspell".to_mixed($d->{name});
+ return ("\n".
+ make_desc($d->{desc}).
+ "enum $n {" .
+ join(', ',
+ map {"Aspell".to_mixed($d->{prefix}).to_mixed($_->{type})}
+ @{$d->{data}}).
+ "};\n" .
+ "typedef enum $n $n;\n"
+ );
+};
+
+$info{struct}{proc}{cc} = sub {
+ return make_c_object "struct", @_;
+};
+
+$info{union}{proc}{cc} = sub {
+ return make_c_object "union", $_[0];
+};
+
+$info{class}{proc}{cc} = sub {
+ my ($d) = @_;
+ my $class = $d->{name};
+ my $classname = "Aspell".to_mixed($class);
+ my $ret = "";
+ $ret .= "typedef struct $classname $classname;\n\n";
+ foreach (@{$d->{data}}) {
+ my $s = make_c_method($class, $_, {mode=>'cc'});
+ next unless defined $s;
+ $ret .= "\n";
+ $ret .= make_desc($_->{desc});
+ $ret .= make_c_method($class, $_, {mode=>'cc'}).";\n";
+ }
+ $ret .= "\n";
+ return $ret;
+};
+
+$info{func}{proc}{cc} = sub {
+ my ($d) = @_;
+ return (make_desc($d->{desc}).
+ make_func("aspell ".$d->{name}, @{$d->{data}}, {mode => 'cc'}).';');
+};
+
+$info{errors}{proc}{cc} = sub {
+ my ($d) = @_;
+ my $p;
+ my $ret;
+ $p = sub {
+ my ($level, $data) = @_;
+ return unless defined $data;
+ foreach my $d (@$data) {
+ $ret .= "extern const struct AspellErrorInfo * const ";
+ $ret .= ' 'x$level;
+ $ret .= "aerror_";
+ $ret .= to_lower($d->{type});
+ $ret .= ";\n";
+ $p->($level + 2, $d->{data});
+ }
+ };
+ $p->(0, $d->{data});
+ return $ret;
+};
+
+sub make_c_object ( $ @ ) {
+ my ($t, $d) = @_;
+ my $struct;
+ $struct .= "Aspell";
+ $struct .= to_mixed($d->{name});
+ return (join "\n\n", grep {$_ ne ''}
+ join ('',
+ "$t $struct {\n",
+ (map {"\n".make_desc($_->{desc},2).
+ " ".to_type_name($_, {mode=>'cc'}). ";\n"}
+ grep {$_->{type} ne 'method'
+ && $_->{type} ne 'cxx constructor'}
+ @{$d->{data}}),
+ "\n};\n"),
+ "typedef $t $struct $struct;",
+ join ("\n",
+ map {make_c_method($d->{name}, $_, {mode=>'cc'}).";"}
+ grep {$_->{type} eq 'method'}
+ @{$d->{data}})
+ )."\n";
+}
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/ProcCxx.pm b/spell/aspell-0.60.6.1/auto/MkSrc/ProcCxx.pm
new file mode 100644
index 0000000..1fc610b
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/ProcCxx.pm
@@ -0,0 +1,164 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::ProcCxx;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(%info %types %methods);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::CcHelper;
+use MkSrc::Info;
+
+$info{forward}{proc}{cxx} = sub {
+ my ($type) = @_;
+ my $n = to_mixed($_->{name});
+ if ($type->{type} eq 'class') {
+ return "typedef Aspell$n * ${n}Ptr;\n";
+ } elsif (one_of $type->{type}, 'struct', 'union') {
+ return "typedef Aspell$n $n;\n";
+ } else {
+ return "";
+ }
+};
+
+$info{group}{proc}{cxx} = sub {
+ my ($data, $accum) = @_;
+ my $str;
+ foreach my $d (@{$data->{data}}) {
+ my $s = $info{$d->{type}}{proc}{cxx}->($d, $accum);
+ $str .= "\n\n$s" if defined $s;
+ }
+ my $ret = "";
+ if (defined $str) {
+ my $stars = (70 - length $data->{name})/2;
+ $ret .= "/".('*'x$stars)." $data->{name} ".('*'x$stars)."/\n";
+ $ret .= $str;
+ $ret .= "\n\n";
+ }
+ return $ret;
+};
+
+$info{enum}{proc}{cxx} = sub {
+ my ($d) = @_;
+ my $n = to_mixed($d->{name});
+ return ("\n".
+ make_desc($d->{desc}).
+ "typedef Aspell$n $n;\n".
+ join('',
+ map {my $en = to_mixed($d->{prefix}).to_mixed($_->{type});
+ "static const $n $en = Aspell$en;\n"}
+ @{$d->{data}})
+ );
+};
+
+$info{struct}{proc}{cxx} = sub {
+ my ($d, $accum) = @_;
+ my $n = to_mixed($d->{name});
+ $accum->{types}{$d->{name}} = $d;
+ return undef;
+};
+
+$info{union}{proc}{cxx} = sub {
+ my ($d, $accum) = @_;
+ my $n = to_mixed($d->{name});
+ $accum->{types}{$d->{name}} = $d;
+ return undef;
+};
+
+$info{class}{proc}{cxx} = sub {
+ my ($d, $accum) = @_;
+ my $class = $d->{name};
+ my $cn = to_mixed($class);
+ my $cl = to_lower($class);
+ my $cp = "${cn}Ptr";
+ $accum->{types}{$d->{name}} = $d;
+ my $ret;
+ $ret = <<"---";
+struct ${cn}Ref {
+ $cp ptr;
+ ${cn}Ref ($cp rhs) : ptr(rhs) {}
+};
+
+class $cn {
+ $cp ptr;
+public:
+
+ explicit $cn($cp p = 0) : ptr(p) {}
+
+ $cn($cn & other) : ptr (other.release()) {}
+ ~$cn() {del();}
+
+ $cn & operator=($cn & other)
+ {reset(other.release()); return *this;}
+
+ $cp get() const {return ptr;}
+ operator $cp () const {return ptr;}
+
+ $cp release () {$cp p = ptr; ptr = 0; return p;}
+
+ void del() {delete_aspell_$cl(ptr); ptr = 0;}
+ void reset($cp p) {assert(ptr==0); ptr = p;}
+ $cn & operator=($cp p) {reset(p); return *this;}
+
+ $cn(${cn}Ref rhs) : ptr(rhs.ptr) {}
+
+ $cn& operator= (${cn}Ref rhs) {reset(rhs.ptr); return *this;}
+
+ operator ${cn}Ref() {return ${cn}Ref(release());}
+
+---
+ foreach (@{$d->{data}}) {
+ next unless $_->{type} eq 'method';
+ $ret .= " ".make_cxx_method($_, {mode=>'cxx'})."\n";
+ $ret .= " {\n";
+ $ret .= " ".call_c_method($class, $_, {mode=>'cc', this_name=>'ptr'}).";\n";
+ $ret .= " }\n\n";
+ }
+ $ret .= "};\n";
+ foreach (@{$d->{data}}) {
+ next unless $_->{type} eq 'constructor';
+ $ret .= "static inline ";
+ $ret .= make_c_method $class, $_, {mode=>'cxx', no_aspell=>true};
+ $ret .= "{\n";
+ $ret .= " ".call_c_method($class, $_, {mode=>'cc'}).";\n";
+ $ret .= "}\n\n";
+ }
+ return $ret;
+};
+
+$info{errors}{proc}{cxx} = sub {
+ my ($d) = @_;
+ my $p;
+ my $ret;
+ $p = sub {
+ my ($level, $data) = @_;
+ return unless defined $data;
+ foreach my $d (@$data) {
+ $ret .= "static const ErrorInfo * const ";
+ $ret .= ' 'x$level;
+ $ret .= to_lower($d->{type});
+ $ret .= "_error" if defined $d->{data} || $level == 0;
+ $ret .= " = ";
+ $ret .= "aerror_";
+ $ret .= to_lower($d->{type});
+ $ret .= ";\n";
+ $p->($level + 2, $d->{data});
+ }
+ };
+ $p->(0, $d->{data});
+ return $ret;
+};
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/ProcImpl.pm b/spell/aspell-0.60.6.1/auto/MkSrc/ProcImpl.pm
new file mode 100644
index 0000000..b8628fd
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/ProcImpl.pm
@@ -0,0 +1,129 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::ProcImpl;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::CcHelper;
+use MkSrc::Info;
+use MkSrc::Create;
+
+$info{forward}{proc}{impl} = sub {
+ my ($type) = @_;
+ return "$type->{type} ".to_mixed($type->{name}).";\n";
+};
+
+$info{group}{proc}{impl} = sub {
+ my ($data) = @_;
+ create_cc_file (type => 'impl',
+ cxx => true,
+ namespace => 'acommon',
+ dir => "lib",
+ pre_ext => "-c",
+ header => false,
+ data => $data,
+ accum => {headers => {$data->{name} => true} }
+ );
+};
+
+$info{class}{proc}{impl} = sub {
+ my ($data, $accum) = @_;
+ my $ret;
+ foreach (grep {$_ ne ''} split /\s*,\s*/, $data->{'c impl headers'}) {
+ $accum->{headers}{$_} = true;
+ }
+ foreach my $d (@{$data->{data}}) {
+ next unless one_of $d->{type}, qw(method constructor destructor);
+ my @parms = @{$d->{data}} if exists $d->{data};
+ my $m = make_c_method $data->{name}, $d, {mode=>'cc_cxx', use_name=>true}, %$accum;
+ next unless defined $m;
+ $ret .= "extern \"C\" $m\n";
+ $ret .= "{\n";
+ if (exists $d->{'c impl'}) {
+ $ret .= cmap {" $_\n"} split /\n/, $d->{'c impl'};
+ } else {
+ if ($d->{type} eq 'method') {
+ my $ret_type = shift @parms;
+ my $ret_native = to_type_name $ret_type, {mode=>'native_no_err', pos=>'return'}, %$accum;
+ my $snum = 0;
+ foreach (@parms) {
+ my $n = to_lower($_->{name});
+ if ($_->{type} eq 'encoded string') {
+ $accum->{headers}{'mutable string'} = true;
+ $accum->{headers}{'convert'} = true;
+ $ret .= " ths->temp_str_$snum.clear();\n";
+ $ret .= " ths->to_internal_->convert($n, ${n}_size, ths->temp_str_$snum);\n";
+ $ret .= " unsigned int s$snum = ths->temp_str_$snum.size();\n";
+ $_ = "MutableString(ths->temp_str_$snum.mstr(), s$snum)";
+ $snum++;
+ } else {
+ $_ = $n;
+ }
+ }
+ my $parms = '('.(join ', ', @parms).')';
+ my $exp = "ths->".to_lower($d->{name})."$parms";
+ if (exists $d->{'posib err'}) {
+ $accum->{headers}{'posib err'} = true;
+ $ret .= " PosibErr<$ret_native> ret = $exp;\n";
+ $ret .= " ths->err_.reset(ret.release_err());\n";
+ $ret .= " if (ths->err_ != 0) return ".(c_error_cond $ret_type).";\n";
+ if ($ret_type->{type} eq 'void') {
+ $ret_type = {type=>'special'};
+ $exp = "1";
+ } else {
+ $exp = "ret.data";
+ }
+ }
+ if ($ret_type->{type} eq 'string obj') {
+ $ret .= " ths->temp_str = $exp;\n";
+ $exp = "ths->temp_str.c_str()";
+ } elsif ($ret_type->{type} eq 'encoded string') {
+ die;
+ # This is not used and also not implemented right
+ $ret .= " if (to_encoded_ != 0) (*to_encoded)($exp,temp_str_);\n";
+ $ret .= " else temp_str_ = $exp;\n";
+ $exp = "temp_str_0.data()";
+ }
+ if ($ret_type->{type} eq 'const word list') {
+ $accum->{headers}{'word list'} = true;
+ $ret .= " if (ret.data)\n";
+ $ret .= " const_cast<WordList *>(ret.data)->from_internal_ = ths->from_internal_;\n";
+ }
+ $ret .= " ";
+ $ret .= "return " unless $ret_type->{type} eq 'void';
+ $ret .= $exp;
+ $ret .= ";\n";
+ } elsif ($d->{type} eq 'constructor') {
+ my $name = $d->{name} ? $d->{name} : "new $data->{name}";
+ $name =~ s/aspell\ ?//; # FIXME: Abstract this in a function
+ $name = to_lower($name);
+ shift @parms if exists $d->{'returns alt type'}; # FIXME: Abstract this in a function
+ my $parms = '('.(join ', ', map {$_->{name}} @parms).')';
+ $ret .= " return $name$parms;\n";
+ } elsif ($d->{type} eq 'destructor') {
+ $ret .= " delete ths;\n";
+ }
+ }
+ $ret .= "}\n\n";
+ }
+ return $ret;
+};
+
+$info{struct}{proc}{impl} = $info{class}{proc}{impl};
+
+$info{union}{proc}{impl} = $info{class}{proc}{impl};
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/ProcNative.pm b/spell/aspell-0.60.6.1/auto/MkSrc/ProcNative.pm
new file mode 100644
index 0000000..6d74e52
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/ProcNative.pm
@@ -0,0 +1,182 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::ProcNative;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::CcHelper;
+use MkSrc::Info;
+use MkSrc::Create;
+use MkSrc::Type;
+
+sub make_native_obj ( $ @ );
+
+$info{forward}{proc}{native} = sub {
+ my ($type) = @_;
+ return "$type->{type} ".to_mixed($type->{name}).";\n";
+};
+
+$info{group}{proc}{native} = sub {
+ my ($data) = @_;
+ return if exists $data->{'no native'};
+ create_cc_file (type => 'native',
+ cxx => true,
+ namespace => 'acommon',
+ dir => "common",
+ header => true,
+ data => $data);
+};
+
+$info{enum}{proc}{native} = sub {
+ my ($data) = @_;
+ my $n = to_mixed($data->{name});
+ return ("enum $n {" .
+ join (',',
+ map {to_mixed($data->{prefix}).to_mixed($_->{type})}
+ @{$data->{data}}).
+ "};\n");
+};
+
+
+$info{struct}{proc}{native} = sub {
+ return make_native_obj 'struct', @_;
+};
+
+$info{union}{proc}{native} = sub {
+ return make_native_obj 'union', @_;
+};
+
+$info{class}{proc}{native} = sub {
+ return make_native_obj 'class', @_;
+};
+
+$info{errors}{proc}{native} = sub {
+ my ($data, $accum) = @_;
+ my $ret;
+ $accum->{types}{"error info"} = finalized_type "error info";
+ my $p0;
+ $p0 = sub {
+ my ($level, $data) = @_;
+ return unless defined $data;
+ foreach my $d (@$data) {
+ $ret .= "extern \"C\" const ErrorInfo * const ";
+ $ret .= ' 'x$level;
+ $ret .= "aerror_";
+ $ret .= to_lower($d->{type});
+ $ret .= ";\n";
+ $p0->($level + 2, $d->{data});
+ }
+ };
+ my $p1;
+ $p1 = sub {
+ my ($level, $data) = @_;
+ return unless defined $data;
+ foreach my $d (@$data) {
+ $ret .= "static const ErrorInfo * const ";
+ $ret .= ' 'x$level;
+ $ret .= to_lower($d->{type});
+ $ret .= "_error" if defined $d->{data} || $level == 0;
+ $ret .= " = aerror_";
+ $ret .= to_lower($d->{type});
+ $ret .= ";\n";
+ $p1->($level + 2, $d->{data});
+ }
+ };
+ $p0->(0, $data->{data});
+ $ret .= "\n\n";
+ $p1->(0, $data->{data});
+ return $ret;
+};
+
+sub make_cxx_constructor ( $ $ ; \% ) {
+ my ($class, $p, $accum) = @_;
+ my $ret;
+ $ret .= to_mixed($class);
+ $ret .= "(";
+ $ret .= join ', ', map {to_type_name $_, {mode=>'native',pos=>'parm'}, %$accum} @$p;
+ $ret .= ")";
+ return $ret;
+}
+
+sub make_native_obj ( $ @ ) {
+ my ($t, $data, $accum) = @_;
+ my $obj = to_mixed($data->{name});
+ my @defaults;
+ my @public;
+ foreach my $d (@{$data->{data}}) {
+ next unless $d->{type} eq 'public';
+ next if $d->{name} eq $data->{name};
+ push @public, to_mixed($d->{name});
+ my $typ = finalized_type $d->{name};
+ $accum->{headers}{$typ->{created_in}} = true;
+ }
+ my $ret;
+ $ret .= "$t $obj ";
+ $ret .= ": ".join(', ', map {"public $_"} @public).' ' if @public;
+ $ret .= "{\n";
+ $ret .= " public:\n" if $t eq 'class';
+ foreach my $d (@{$data->{data}}) {
+ next if exists $d->{'c only'};
+ next if one_of $d->{type}, qw(constructor destructor public);
+ $ret .= " ";
+ if ($d->{type} eq 'method') {
+ my $is_vir = $t eq 'class' && !exists $d->{'cxx impl'};
+ $ret .= "virtual " if $is_vir;
+ $ret .= make_cxx_method $d, {mode=>'native'}, %$accum;
+ $ret .= $is_vir ? " = 0;\n"
+ : exists $d->{'cxx impl'} ? " { $d->{'cxx impl'}; }\n"
+ : ";\n";
+ } elsif ($d->{type} eq 'cxx constructor') {
+ $ret .= make_cxx_constructor $data->{name}, $d->{data}, %$accum;
+ $ret .= exists $d->{'cxx impl'} ? " $d->{'cxx impl'}\n"
+ : ";\n";
+ } else { # is a type
+ if (exists $d->{default}) {
+ push @defaults, $d;
+ }
+ if ($d->{type} eq 'cxx member') {
+ foreach (split /\s*,\s*/, $d->{'headers'}) {
+ $accum->{headers}{$_} = true;
+ }
+ $ret .= $d->{what};
+ } elsif ($t eq 'class') {
+ $ret .= to_type_name $d, {mode=>'native'}, %$accum;
+ $ret .= "_";
+ } else {
+ $ret .= to_type_name $d, {mode=>'cc_cxx'}, %$accum;
+ }
+ $ret .= ";\n";
+ }
+ }
+ if (@defaults || $t eq 'class') {
+ $ret .= " $obj()";
+ if (@defaults) {
+ $ret .= " : ";
+ $ret .= join ', ', map {to_lower($_->{name}).($t eq 'class'?'_':'')."($_->{default})"} @defaults;
+ }
+ $ret .= " {}\n";
+ }
+ $ret .= " virtual ~${obj}() {}\n" if $t eq 'class';
+ $ret .= "};\n";
+ foreach my $d (@{$data->{data}}) {
+ next unless $d->{type} eq 'constructor';
+ $ret .= make_c_method $data->{name}, $d, {mode=>'native',no_aspell=>false}, %$accum;
+ $ret .= ";\n";
+ }
+ return $ret;
+}
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/ProcNativeImpl.pm b/spell/aspell-0.60.6.1/auto/MkSrc/ProcNativeImpl.pm
new file mode 100644
index 0000000..39d692b
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/ProcNativeImpl.pm
@@ -0,0 +1,97 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::ProcNativeImpl;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(%info %types %methods);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::CcHelper;
+use MkSrc::Info;
+use MkSrc::Create;
+
+$info{forward}{proc}{native_impl} = sub {
+ my ($type) = @_;
+ return "$type->{type} ".to_mixed($type->{name}).";\n";
+};
+
+$info{group}{proc}{native_impl} = sub {
+ my ($data) = @_;
+ create_cc_file (type => 'native_impl',
+ cxx => true,
+ namespace => 'acommon',
+ dir => "common",
+ header => false,
+ data => $data,
+ accum => {headers => {$data->{name} => true} }
+ );
+};
+
+$info{errors}{proc}{native_impl} = sub {
+ my $ret;
+ my $p;
+ $p = sub {
+ my ($isa, $parms, $data) = @_;
+ my @parms = (@$parms, (split /, */, $data->{parms}));
+ my $parm_idx = sub {
+ my ($p) = @_;
+ return 0 if $p eq 'prim';
+ for (my $i = 0; $i != @parms; ++$i) {
+ return $i+1 if $parms[$i] eq $p;
+ }
+ die "can't find parm for \"$p\"";
+ };
+ my $proc_mesg = sub {
+ my @mesg = split /\%(\w+)/, $_[0];
+ my $mesg = '';
+ while (true) {
+ my $m = shift @mesg;
+ $m =~ s/\"/\\\"/g;
+ $mesg .= $m;
+ my $p = shift @mesg;
+ last unless defined $p;
+ $mesg .= "%$p:";
+ $mesg .= $parm_idx->($p);
+ }
+ if (length $mesg == 0) {
+ $mesg = 0;
+ } else {
+ $mesg = "N_(\"$mesg\")";
+ }
+ return $mesg;
+ };
+ my $mesg = $proc_mesg->($data->{mesg});
+ my $name = "aerror_".to_lower($data->{type});
+ $ret .= "static const ErrorInfo $name\_obj = {\n";
+ $ret .= " ".(defined $isa ? "$isa": 0).", // isa\n";
+ $ret .= " $mesg, // mesg\n";
+ $ret .= " ".scalar @parms.", // num_parms\n";
+ $ret .= " {".(join ', ', map {"\"$_\""} (@parms ? @parms : ("")))."} // parms\n";
+ $ret .= "};\n";
+ $ret .= "extern \"C\" const ErrorInfo * const $name = &$name\_obj;\n";
+ $ret .= "\n";
+ foreach my $d (@{$data->{data}}) {
+ $ret .= $p->($name, \@parms, $d);
+ }
+ };
+ my ($data, $accum) = @_;
+ $accum->{headers}{'error'} = true;
+ foreach my $d (@{$data->{data}}) {
+ $ret .= $p->(undef, [], $d);
+ }
+ return $ret;
+};
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/Read.pm b/spell/aspell-0.60.6.1/auto/MkSrc/Read.pm
new file mode 100644
index 0000000..4b3d1d0
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/Read.pm
@@ -0,0 +1,210 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::Read;
+
+BEGIN {
+ use Exporter;
+ @ISA = qw(Exporter);
+ @EXPORT = qw(read);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use MkSrc::Util;
+use MkSrc::Type;
+use MkSrc::Info;
+use MkSrc::Methods;
+
+my $line = '';
+my $level = 0;
+my $base_level = 0;
+my $in_pod = undef;
+
+my $master_data = {type=>'root', name=>undef};
+# master_data contains all the information in mk-src.in and then some.
+# It has the following structure
+# <tree>
+# <tree> := <options>
+# data => <tree>
+# where each tree represents an entry in mk-src.in.
+# The following two options are always provided:
+# name: the name of the entry
+# type: the catagory or type name
+# Additional options are the same as specified in %info
+
+=head1 MkSrc::Read
+
+=over
+
+=item read
+
+Read in "mk-src.in" and returns a data structure which has the
+following format:
+
+ <tree>
+ <tree> := <options>
+ data => <tree>
+ where each tree represents an entry in mk-src.in.
+ The following two options are always provided:
+ name: the name of the entry
+ type: the catagory or type name
+ Additional options are the same as specified in %info
+
+=back
+
+=cut
+
+sub advance ( );
+sub parse ( $ $ );
+sub prep ( $ $ $ );
+
+sub read ( )
+{
+ open IN, "mk-src.in" or die;
+ advance;
+ parse $master_data, 0;
+ close IN;
+ prep $master_data, '', {};
+ return $master_data;
+}
+
+sub need_options ( $ );
+sub valid_option ( $ $ );
+sub valid_group ( $ $ );
+sub store_group ( $ $ );
+
+sub advance ( ) {
+ $line = undef;
+ do {
+ $line = <IN>;
+ return unless defined $line;
+ $in_pod = $1 if $line =~ /^\=(\w+)/;
+ $line = '' if $in_pod;
+ $in_pod = undef if $in_pod && $in_pod eq 'cut';
+ $line =~ s/\#.*$//;
+ $line =~ s/^(\t*)//;
+ $level = $base_level + length($1);
+ $line =~ s/\s*$//;
+ ++$base_level if $line =~ s/^\{$//;
+ --$base_level if $line =~ s/^\}$//;
+ $line =~ s/\\([{}])/$1/g;
+ } while ($line eq '');
+ #print "$level:$line\n";
+}
+
+sub parse ( $ $ ) {
+ my ($data, $this_level) = @_;
+ if (need_options $data) {
+ for (;;) {
+ return if $level < $this_level;
+ return unless defined $line;
+ die if $level > $this_level;
+ last if $line eq '/';
+ my $k;
+ ($k, $line) = split /\=\>/, $line;
+ $k =~ s/^\s*(.+?)\s*$/$1/;
+ my $v = $line;
+ print STDERR "The option \"$k\" is invalid for the group \"$data->{type}\"\n"
+ unless valid_option $data, $k;
+ advance;
+ for (;;) {
+ return unless defined $line;
+ last if $level <= $this_level;
+ $v .= "\n$line";
+ advance;
+ }
+ $v =~ s/^[ \t\n]+//;
+ $v =~ s/[ \t\n]+$//;
+ $data->{$k} = $v;
+ }
+ return unless $line eq '/';
+ advance;
+ } else {
+ advance if $line eq '/';
+ }
+ $data->{data} = [];
+ for (;;) {
+ return if $level < $this_level;
+ return unless defined $line;
+ die if $level > $this_level;
+ my ($type, $name) = split /:/, $line;
+ $type =~ s/^\s*(.+?)\s*$/$1/;
+ $name =~ s/^\s*(.+?)\s*$/$1/;
+ print STDERR "The subgroup \"$type\" is invalid in the group \"$data->{type}\"\n"
+ unless valid_group $data, $type;
+ my $d = {type=>$type, name=>$name};
+ store_group $d, $data;
+ advance;
+ parse($d, $this_level + 1);
+ }
+}
+
+sub prep ( $ $ $ ) {
+ my ($data, $group, $stack) = @_;
+ my $d = creates_type $data;
+ update_type $d->{name}, {%$d,created_in=>$group} if (defined $d);
+ $group = $data->{name} if $data->{type} eq 'group';
+ $stack = {%$stack, prev=>$data, $data->{type}=>$data};
+ if ($data->{type} eq 'method') {
+ die unless $data->{data};
+ $data->{data}[0]{'posib err'} = true if exists $data->{'posib err'};
+ }
+ my $i = 0;
+ my $lst = $data->{data};
+ return unless defined $lst;
+ while ($i != @$lst) {
+ my $d = $lst->[$i];
+ if (exists $methods{$d->{type}}) {
+ splice @$lst, $i, 1, copy_methods($d, $data, $stack->{class}{name});
+ } else {
+ prep $d, $group, $stack;
+ ++$i;
+ }
+ }
+}
+
+#
+# Parser helper functions
+#
+
+sub need_options ( $ ) {
+ my ($i, $o) = @_;
+ my $options = $info{$i->{type}}{options};
+ return true unless ref $options eq 'ARRAY';
+ return true unless @$options == 0;
+ return false;
+}
+
+sub valid_option ( $ $ ) {
+ my ($i, $o) = @_;
+ my $options = $info{$i->{type}}{options};
+ return true unless ref $options eq 'ARRAY';
+ return scalar ( grep {$_ eq $o} @$options);
+}
+
+sub valid_group ( $ $ ) {
+ my ($i, $t) = @_;
+ my $groups = $info{$i->{type}}{groups};
+ return true unless ref $groups eq 'ARRAY';
+ return scalar ( grep {$_ eq $t} @$groups);
+}
+
+sub store_group ( $ $ ) {
+ my ($d, $data) = @_;
+ if ($d->{type} eq 'methods') {
+ $methods{"$d->{name} methods"} = $d;
+# Don't usa as groups is now undef
+# push @{$info{class}{groups}}, "$d->{name} methods";
+ } else {
+ push @{$data->{data}}, $d;
+ }
+}
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/Type.pm b/spell/aspell-0.60.6.1/auto/MkSrc/Type.pm
new file mode 100644
index 0000000..2c6ff35
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/Type.pm
@@ -0,0 +1,94 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::Type;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(creates_type update_type finalized_type);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+sub creates_type ( $ );
+sub update_type ( $ ; $ );
+sub finalized_type ( $ );
+
+use MkSrc::Util;
+use MkSrc::Info;
+
+#
+# Type Functions
+#
+
+
+sub creates_type ( $ )
+{
+ my ($i) = @_;
+ my $d;
+ $d->{type} = $info{$i->{type}}{creates_type};
+ return undef unless defined $d->{type};
+ $d->{name} = $i->{name};
+ $d->{treat_as} =
+ ($i->{type} eq 'basic' ? 'special'
+ : exists $i->{'treat as object'} || $i->{type} eq 'enum' ? 'object'
+ : 'pointer');
+ if (my $name = $info{$i->{type}}{creates_name}) {
+ $d->{name} = $name->($i);
+ }
+ return $d;
+}
+
+sub update_type ( $ ; $ )
+{
+ my ($name, $data) = @_;
+ my $d = $types{$name};
+ $types{$name} = $d = {} unless defined $d;
+ $d->{data} = $data if defined $data;
+ $d->{data} = {} unless defined $d->{data};
+ return $d;
+}
+
+sub finalized_type ( $ )
+{
+ my ($name) = @_;
+
+ my $d = $types{$name};
+ $types{$name} = $d = {data=>{}} unless defined $d;
+ return $d unless exists $d->{data};
+
+ while (my ($k,$v) = each %{$d->{data}}) {
+ $d->{$k} = defined $v ? $v : true;
+ }
+ delete $d->{data};
+
+ local $_ = $name;
+
+ s/^const // and $d->{const} = true;
+ s/^array (\d+) // and $d->{array} = $1;
+ s/ ?pointer$// and $d->{pointer} = true;
+ s/ ?object$// and $d->{pointer} = false;
+
+ $_ = 'void' if length $_ == 0;
+
+ my $r = finalized_type $_;
+
+ $d->{type} = exists $r->{type} ? $r->{type} : 'unknown';
+ $d->{name} = $_;
+ $d->{orig_name} = $name;
+ $d->{pointer} = ($r->{treat_as} eq 'pointer')
+ unless exists $d->{pointer};
+ $d->{const} = false unless $d->{pointer};
+ $d->{created_in} = $r->{created_in};
+
+ return $d;
+
+}
+1;
diff --git a/spell/aspell-0.60.6.1/auto/MkSrc/Util.pm b/spell/aspell-0.60.6.1/auto/MkSrc/Util.pm
new file mode 100644
index 0000000..b912a2b
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/MkSrc/Util.pm
@@ -0,0 +1,111 @@
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+package MkSrc::Util;
+
+BEGIN {
+ use Exporter;
+ our @ISA = qw(Exporter);
+ our @EXPORT = qw(false true
+ cmap one_of
+ to_upper to_lower to_mixed);
+}
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+=head1 MkSrc::Util
+
+This module contains various useful utility functions:
+
+=over
+
+=cut
+
+=item false
+
+Returns 0.
+
+=item true
+
+Returns 1.
+
+=cut
+
+sub false () {return 0}
+sub true () {return 1}
+
+=item cmap EXPR LIST
+
+Apply EXPR to each item in LIST and than concatenate the result into
+a string
+
+=cut
+
+sub cmap ( & @ )
+{
+ my ($sub, @d) = @_;
+ return join '', map &$sub, @d;
+}
+
+=item one_of STR LIST
+
+Returns true if LIST contains at least one of STR.
+
+=cut
+
+sub one_of ( $ @ ) {
+ my ($v, @l) = @_;
+ return scalar grep {$_ eq $v} @l;
+}
+
+=item to_upper STR
+
+Convert STR to all uppercase and substitute spaces with underscores.
+
+=cut
+
+sub to_upper( $ ) {
+ local ($_) = @_;
+ s/\-/ /g;
+ s/^\s+//; s/\s+$//; s/(\S)\s+(\S)/$1_$2/g;
+ return uc($_);
+}
+
+=item to_lower STR
+
+Convert STR to all lowercase and substitute spaces with underscores.
+
+=cut
+
+sub to_lower( $ ) {
+ local ($_) = @_;
+ s/\-/ /g;
+ s/^\s+//; s/\s+$//; s/(\S)\s+(\S)/$1_$2/g;
+ return lc($_);
+}
+
+=item to_mixed STR
+
+Convert STR to mixed case where each new word startes with a
+uppercase letter. For example "feed me" would become "FeedMe".
+
+=cut
+
+sub to_mixed( $ ) {
+ local ($_) = @_;
+ s/\-/ /g;
+ s/\s*(\S)(\S*)/\u$1\l$2\E/g;
+ return $_;
+}
+
+=back
+
+=cut
+
+1;
diff --git a/spell/aspell-0.60.6.1/auto/auto b/spell/aspell-0.60.6.1/auto/auto
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/auto
diff --git a/spell/aspell-0.60.6.1/auto/mk-doc.pl b/spell/aspell-0.60.6.1/auto/mk-doc.pl
new file mode 100644
index 0000000..cfd6107
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/mk-doc.pl
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+
+my @files = qw(mk-src.in MkSrc/Info.pm
+ MkSrc/Util.pm
+ MkSrc/Read.pm MkSrc/Create.pm
+ MkSrc/CcHelper.pm);
+
+my $final;
+
+foreach (@files)
+{
+ open IN, $_;
+ $final .= "\n\n### FILE: $_\n\n";
+ while (<IN>)
+ {
+ s/^\#pod\s*/\n\=pod\n\n/;
+ s/^\#cut\s*/\n\=cut\n\n/;
+ $final .= $_;
+ }
+ close IN;
+}
+
+open OUT, ">mk-src.pod" or die;
+print OUT $final;
+close OUT;
+
+use Pod::Checker;
+$parser = Pod::Checker->new();
+$parser->parse_from_file('mk-src.pod', \*STDERR);
+
+use Pod::Text;
+$parser = Pod::Text->new(loose=>1);
+$parser->parse_from_file('mk-src.pod', 'mk-src.txt');
+
+#use Pod::LaTeX;
+#$parser = Pod::LaTeX->new(AddPreamble => 0, AddPostamble => 0);
+#$parser->parse_from_file('mk-src.pod', '../manual/mk-src.tex.new');
+
+#$/ = undef;
+#open IN, '../manual/mk-src.tex';
+#$orig = <IN>;
+#open IN, '../manual/mk-src.tex.new';
+#$new = <IN>;
+#close IN;
+#if ($orig eq $new) {
+# print "mk-src.tex unchanged\n";
+#} else {
+# rename '../manual/mk-src.tex.new', '../manual/mk-src.tex';
+#}
+
+#unlink "mk-src.pod";
diff --git a/spell/aspell-0.60.6.1/auto/mk-src.in b/spell/aspell-0.60.6.1/auto/mk-src.in
new file mode 100644
index 0000000..c514db3
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/mk-src.in
@@ -0,0 +1,1070 @@
+#
+# mk-src.in -- Input file for the Perl program to automatically
+# generate interface code.
+#
+# This file is part of The New Aspell
+# Copyright (C) 2001-2005 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+=head1 mk-src.in
+
+The format of mk-src.in is as follows:
+
+ The following characters are literals: { } / '\ ' \n = >
+
+ <items>
+ <items> := (<item>\n)+
+ <items> := <category>:\ <name> {\n<details>\n} | <<tab>><details>
+ <details> := <options>\n /\n <items>
+ <options> := (<option>\n)*
+ <option> := <key> [=> <value>]
+
+ <<tab>> means everything should be indented by one tab
+
+See MkSrc::Info for a description of the categories and options
+
+=cut
+
+
+group: type id
+{
+/
+union: type id
+ treat as object
+ /
+ unsigned int: num
+ default => 0
+ array 4 char: str
+ cxx constructor:
+ /
+ string: str
+}
+methods: destructible
+ /
+ destructor
+
+# int: ref count
+# default => 0
+#
+# method: ref count
+# desc => Returns a pointer to an int which may be used
+# for reference counting. It will default to 0.
+# This integer is not used by the actual library
+# but may be used my some of the front ends.
+# c only
+# c impl => return &ths->ref_count;
+# /
+# int pointer
+
+methods: copyable
+ /
+ destructible methods
+
+# type id: type id
+#
+# method: type id
+# desc => Two objects of the same pointer type may be
+# assigned to each other only if their type ids
+# are the same.
+# cxx impl => return type_id_.num
+# /
+# unsigned int
+#
+# int: copyable
+# default => 2
+#
+# method: copyable
+# desc => Returns 0 if this object can not be copied,
+# 1 if it may be copied, 2 if it should be
+# copied. Used by some of the front ends to
+# determine if a deep or shallow copy should be
+# made.
+# cxx impl => return copyable_
+# /
+# int
+
+ method: clone
+ const
+ /
+ $
+
+ method: assign
+ /
+ void
+ const $: other
+
+methods: can have error
+ /
+ cxx member: err
+ headers => copy ptr, error
+ what => CopyPtr<Error> err_
+
+ method: error number
+ const
+ c only
+ c impl => return ths->err_ == 0 ? 0 : 1;
+ /
+ unsigned int
+
+ method: error message
+ const
+ c only
+ c impl => return ths->err_ ? ths->err_->mesg : "";
+ /
+ string
+
+ method: error
+ const
+ c only
+ c impl => return ths->err_;
+ /
+ const error
+
+methods: mutable container
+ c impl headers => posib err
+ /
+ public: mutable container
+ method: add
+ /
+ bool
+ string: to_add
+
+ method: remove
+ /
+ bool
+ string: to_rem
+
+ method: clear
+ /
+ void
+
+ method: to mutable container
+ c only
+ c impl => return ths;
+ /
+ mutable container
+
+group: mutable container
+{
+/
+class: mutable container
+ /
+ mutable container methods
+}
+methods: list
+
+ strip => 1
+ /
+ method: empty
+ const
+ /
+ bool
+
+ method: size
+ const
+ /
+ unsigned int
+
+ method: elements
+ const
+ /
+ $ enumeration
+
+methods: enumeration
+
+ strip => 1
+
+ /
+ method: at end
+ const
+ /
+ bool
+
+ method: next
+ /
+ const $
+
+group: key info
+{
+/
+enum: key info type
+ prefix => key info
+ /
+ string
+ int
+ bool
+ list
+
+struct: key info
+ desc => The Key Info object is used for holding information
+ about a valid key.
+ /
+ string: name
+ desc => The name of the key.
+ key info type: type
+ desc => The key type.
+ string: def
+ desc => The default value of the key.
+ string: desc
+ desc => A brief description of the key or NULL if internal value.
+ int: flags
+ int: other data
+}
+group: config
+{
+no native
+/
+class: key info enumeration
+ /
+ enumeration methods
+ copyable methods
+
+class: config
+ c impl headers => error
+ /
+ constructor
+
+ copyable methods
+
+ can have error methods
+
+ method: set extra
+ desc => Sets extra keys which this config class should
+ accept. begin and end are expected to point to
+ the beginning and ending of an array of Aspell
+ Key Info.
+ /
+ void
+ const key info: begin
+ const key info: end
+
+ method: keyinfo
+ posib err
+ desc => Returns the KeyInfo object for the
+ corresponding key or returns NULL and sets
+ error_num to PERROR_UNKNOWN_KEY if the key is
+ not valid. The pointer returned is valid for
+ the lifetime of the object.
+ /
+ const key info
+ string: key
+
+ method: possible elements
+ desc => Returns a newly allocated enumeration of all
+ the possible objects this config class uses.
+ /
+ key info enumeration
+ int: include extra
+
+ method: get default
+ posib err
+ desc => Returns the default value for given key which
+ may involve substituting variables, thus it is
+ not the same as keyinfo(key)->def returns NULL
+ and sets error_num to PERROR_UNKNOWN_KEY if
+ the key is not valid. Uses the temporary
+ string.
+ /
+ string obj
+ string: key
+
+ method: elements
+ desc => Returns a newly allocated enumeration of all
+ the key/value pairs. This DOES not include ones
+ which are set to their default values.
+ /
+ string pair enumeration
+
+ method: replace
+ posib err
+ desc => Inserts an item, if the item already exists it
+ will be replaced. Returns TRUE if it succeeded
+ or FALSE on error. If the key is not valid it
+ sets error_num to PERROR_UNKNOWN_KEY, if the
+ value is not valid it will set error_num to
+ PERROR_BAD_VALUE, if the value can not be
+ changed it sets error_num to
+ PERROR_CANT_CHANGE_VALUE, and if the value is
+ a list and you are trying to set its directory,
+ it sets error_num to PERROR_LIST_SET
+ /
+ void
+ string: key
+ string: value
+
+ method: remove
+ posib err
+ desc => Remove a key and returns TRUE if it exists
+ otherwise return FALSE. This effectively sets
+ the key to its default value. Calling replace
+ with a value of "<default>" will also call
+ remove. If the key does not exist then it sets
+ error_num to 0 or PERROR_NOT, if the key is
+ not valid then it sets error_num to
+ PERROR_UNKNOWN_KEY, if the value can not be
+ changed then it sets error_num to
+ PERROR_CANT_CHANGE_VALUE
+ /
+ void
+ string: key
+
+ method: have
+ const
+ /
+ bool
+ string: key
+
+ method: retrieve
+ posib err
+ desc => Returns NULL on error.
+ /
+ string obj
+ string: key
+
+ method: retrieve list
+ posib err
+ /
+ void
+ string: key
+ mutable container: lst
+
+ method: retrieve bool
+ posib err
+ desc => In "ths" Aspell configuration, search for a
+ character string matching "key" string.
+ If "key" is found then return 1 else return 0.
+ If error encountered, then return -1.
+ /
+ bool
+ string: key
+
+ method: retrieve int
+ posib err
+ desc => In "ths" Aspell configuration, search for an
+ integer value matching "key" string.
+ Return -1 on error.
+ /
+ unsigned int
+ string: key
+
+# method: read_in_settings
+# posib err
+# /
+# bool
+
+# method: settings_read_in
+# /
+# bool
+}
+group: error
+{
+/
+struct: error
+ /
+ string: mesg
+ const error info: err
+ method: is a
+ const
+ /
+ bool
+ const error info: e
+
+struct: error info
+ /
+ const error info: isa
+ string: mesg
+ unsigned int: num parms
+ array 3 string: parms
+}
+group: can have error
+{
+/
+class: can have error
+ c impl headers => error
+ /
+ cxx constructor:
+ cxx impl => : err_(e) {}
+ /
+ error: e
+ can have error methods
+ prefix =>
+ destructible methods
+}
+group: errors
+{
+/
+errors:
+ /
+ other
+ operation not supported
+ mesg => Operation Not Supported: %what
+ parms => what
+ /
+ cant copy
+ unimplemented method
+ mesg => The method "%what" is unimplemented in "%where".
+ parms => where
+ file
+ mesg => %file:
+ parms => file
+ /
+ cant open file
+ mesg => The file "%file" can not be opened
+ /
+ cant read file
+ mesg => The file "%file" can not be opened for reading.
+ cant write file
+ mesg => The file "%file" can not be opened for writing.
+ invalid name
+ mesg => The file name "%file" is invalid.
+ bad file format
+ mesg => The file "%file" is not in the proper format.
+ dir
+ parms => dir
+ /
+ cant read dir
+ mesg => The directory "%dir" can not be opened for reading.
+
+ config
+ parms => key
+ /
+ unknown key
+ mesg => The key "%key" is unknown.
+ cant change value
+ mesg => The value for option "%key" can not be changed.
+ bad key
+ mesg => The key "%key" is not %accepted and is thus invalid.
+ parms => accepted
+ bad value
+ mesg => The value "%value" is not %accepted and is thus invalid for the key "%key".
+ parms => value, accepted
+ duplicate
+ key not string
+ mesg => The key "%key" is not a string.
+ key not int
+ mesg => The key "%key" is not an integer.
+ key not bool
+ mesg => The key "%key" is not a boolean.
+ key not list
+ mesg => The key "%key" is not a list.
+ no_value_reset
+ mesg => The key "%key" does not take any parameters when prefixed by a "reset-".
+ no_value_enable
+ mesg => The key "%key" does not take any parameters when prefixed by an "enable-".
+ no_value_disable
+ mesg => The key "%key" does not take any parameters when prefixed by a "dont-" or "disable-".
+ no_value_clear
+ mesg => The key "%key" does not take any parameters when prefixed by a "clear-".
+
+ language related
+ parms => lang
+ /
+ unknown language
+ mesg => The language "%lang" is not known.
+ unknown soundslike
+ mesg => The soundslike "%sl" is not known.
+ parms => sl
+ language not supported
+ mesg => The language "%lang" is not supported.
+ no wordlist for lang
+ mesg => No word lists can be found for the language "%lang".
+ mismatched language
+ mesg => Expected language "%lang" but got "%prev".
+ parms => prev
+ affix
+ /
+ corrupt affix
+ mesg => Affix '%aff' is corrupt.
+ parms => aff
+ invalid cond
+ mesg => The condition "%cond" is invalid.
+ parms => cond
+ invalid cond strip
+ mesg => The condition "%cond" does not guarantee that "%strip" can always be stripped.
+ parms => cond, strip
+ incorrect encoding
+ mesg => The file "%file" is not in the proper format. Expected the file to be in "%exp" not "%got".
+ parms => file, exp, got
+ encoding
+ parms => encod
+ /
+ unknown encoding
+ mesg => The encoding "%encod" is not known.
+ encoding not supported
+ mesg => The encoding "%encod" is not supported.
+ conversion not supported
+ mesg => The conversion from "%encod" to "%encod2" is not supported.
+ parms => encod2
+ pipe
+ /
+ cant create pipe
+ process died
+ bad input
+ /
+ invalid string
+ mesg => The string "%str" is invalid.
+ parms => str
+ invalid word
+ mesg => The word "%word" is invalid.
+ parms => word
+ invalid affix
+ mesg => The affix flag '%aff' is invalid for word "%word".
+ parms => aff, word
+ inapplicable affix
+ mesg => The affix flag '%aff' can not be applied to word "%word".
+ parms => aff, word
+ unknown unichar
+ mesg =>
+ word list flags
+ /
+ invalid flag
+ conflicting flags
+ version control
+ /
+ bad version string
+ mesg => not a version number
+ filter
+ /
+ cant dlopen file
+ mesg => dlopen returned "%return".
+ parms => return
+ empty filter
+ mesg => The file "%filter" does not contain any filters.
+ parms => filter
+ no such filter
+ mesg => The filter "%filter" does not exist.
+ parms => filter
+ confusing version
+ mesg => Confused by version control.
+ bad version
+ mesg => Aspell version does not match filter's requirement.
+ identical option
+ mesg => Filter option already exists.
+ options only
+ mesg => Use option modifiers only within named option.
+ invalid option modifier
+ mesg => Option modifier unknown.
+ cant describe filter
+ mesg => Error setting filter description.
+ filter mode file
+ /
+ mode option name
+ mesg => Empty option specifier.
+ no filter to option
+ mesg => Option "%option" possibly specified prior to filter.
+ parms => option
+ bad mode key
+ mesg => Unknown mode description key "%key".
+ parms => key
+ expect mode key
+ mesg => Expecting "%modekey" key.
+ parms => modekey
+ mode version requirement
+ mesg => Version specifier missing key: "aspell".
+ confusing mode version
+ mesg => Confused by version control.
+ bad mode version
+ mesg => Aspell version does not match mode's requirement.
+ missing magic expression
+ mesg => Missing magic mode expression.
+ empty file ext
+ mesg => Empty extension at char %char.
+ parms => char
+ filter mode expand
+ mesg => "%mode" error
+ parms => mode
+ /
+ unknown mode
+ mesg => Unknown mode: "%mode".
+ mode extend expand
+ mesg => "%mode" error while extend Aspell modes. (out of memory?)
+ filter mode magic
+ mesg = "%mode": bad magic "%magic"
+ parms => mode, magic
+ /
+ file magic pos
+ mesg => "%mode": no start for magic search given for magic "%magic".
+ file magic range
+ mesg => "%mode": no range for magic search given for magic "%magic".
+ missing magic
+ mesg => "%mode": no magic expression available for magic "%magic".
+ bad magic
+ mesg => "%mode": Magic "%magic": bad regular expression after location specifier; regexp reports: "%regerr".
+ parms => regerr
+
+ expression
+ /
+ invalid expression
+ mesg => "%expression" is not a valid regular expression.
+ parms => expression
+}
+group: speller
+{
+no native
+/
+class: speller
+ c impl headers => error
+ /
+ # FIXME: make a "methods" of the next two contractors
+ # which will probably involve modifying mk-src.pl
+
+ constructor: new aspell speller
+ returns alt type
+ c impl =>
+ PosibErr<Speller *> ret = new_speller(config);
+ if (ret.has_err()) \{
+ return new CanHaveError(ret.release_err());
+ \} else \{
+ return ret;
+ \}
+ /
+ can have error
+ config: config
+
+ constructor: to aspell speller
+ c impl => return static_cast<Speller *>(obj);
+ /
+ can have error: obj
+
+ destructible methods
+
+ can have error methods
+
+ method: config
+ /
+ config
+
+ method: check
+
+ posib err
+ desc => Returns 0 if it is not in the dictionary,
+ 1 if it is, or -1 on error.
+ /
+ bool
+ encoded string: word
+
+ method: add to personal
+
+ posib err
+ desc => Add this word to your own personal word list.
+ /
+ void
+ encoded string: word
+
+ method: add to session
+
+ posib err
+ desc => Add this word to the current spelling session.
+ /
+ void
+ encoded string: word
+
+ method: personal word list
+
+ posib err
+ desc => This is your own personal word list file plus
+ any extra words added during this session to
+ your own personal word list.
+ /
+ const word list
+
+ method: session word list
+
+ posib err
+ desc => This is a list of words added to this session
+ that are not in the main word list or in your
+ own personal list but are considered valid for
+ this spelling session.
+ /
+ const word list
+
+ method: main word list
+
+ posib err
+ desc => This is the main list of words used during this
+ spelling session.
+ /
+ const word list
+
+ method: save all word lists
+
+ posib err
+ /
+ void
+
+ method: clear session
+
+ posib err
+ /
+ void
+
+ method: suggest
+
+ posib err
+ desc => Return NULL on error.
+ The word list returned by suggest is only
+ valid until the next call to suggest.
+ /
+ const word list
+ encoded string: word
+
+ method: store replacement
+
+ posib err
+ /
+ bool
+ encoded string: mis
+ encoded string: cor
+
+}
+
+group: filter
+{
+no native
+/
+class: filter
+ c impl headers => error
+ /
+ destructible methods
+
+ can have error methods
+
+ # FIXME: make a "methods" of the next two contractors
+
+# constructor: new aspell filter
+# returns alt type
+# c impl =>
+# PosibErr<Filter *> ret = new_filter(config);
+# if (ret.has_err()) \{
+# return new CanHaveError(ret.release_err());
+# \} else \{
+# return ret;
+# \}
+# /
+# can have error
+# config: config
+
+ constructor: to aspell filter
+ c impl => return static_cast<Filter *>(obj);
+ /
+ can have error: obj
+
+# method: setup
+#
+# posib err
+# /
+# void
+# speller: speller
+# config: config
+#
+# method: reset
+#
+# /
+# void
+#
+# method: process
+#
+# /
+# void
+# char pointer: str
+# int: size
+#
+# method: config
+#
+# /
+# config
+}
+
+group: document checker
+{
+no native
+/
+struct: token
+ /
+ unsigned int: offset
+ unsigned int: len
+
+class: document checker
+ c impl headers => error
+ /
+ destructible methods
+
+ can have error methods
+
+ # FIXME: make a "methods" of the next two contractors
+
+ constructor: new aspell document checker
+ returns alt type
+ c impl =>
+ PosibErr<DocumentChecker *> ret = new_document_checker(speller);
+ if (ret.has_err()) \{
+ return new CanHaveError(ret.release_err());
+ \} else \{
+ return ret;
+ \}
+ desc => Creates a new document checker.
+ The speller class is expected to last until
+ this class is destroyed.
+ If config is given it will be used to override
+ any relevent options set by this speller class.
+ The config class is not once this function is done.
+ If filter is given then it will take ownership of
+ the filter class and use it to do the filtering.
+ You are expected to free the checker when done.
+ /
+ can have error
+ speller: speller
+
+ constructor: to aspell document checker
+ c impl => return static_cast<DocumentChecker *>(obj);
+ /
+ can have error: obj
+
+ method: reset
+
+ desc => Reset the internal state of the filter.
+ Should be called whenever a new document is
+ being filtered.
+ /
+ void
+
+ method: process
+
+ desc => Process a string.
+ The string passed in should only be split on
+ white space characters. Furthermore, between
+ calls to reset, each string should be passed
+ in exactly once and in the order they appeared
+ in the document. Passing in strings out of
+ order, skipping strings or passing them in
+ more than once may lead to undefined results.
+ /
+ void
+ string: str
+ int: size
+
+ method: next misspelling
+
+ desc => Returns the next misspelled word in the
+ processed string. If there are no more
+ misspelled words, then token.word will be
+ NULL and token.size will be 0
+ /
+ token object
+
+ method: filter
+
+ desc => Returns the underlying filter class.
+ /
+ filter
+}
+
+group: word list
+{
+/
+class: word list
+ c impl headers => string enumeration
+ /
+ cxx member: from internal
+ what => class Convert * from_internal_
+ default => 0
+
+ method: empty
+ const
+ /
+ bool
+
+ method: size
+ const
+ /
+ unsigned int
+
+ method: elements
+ const
+ c impl =>
+ StringEnumeration * els = ths->elements();
+ els->from_internal_ = ths->from_internal_;
+ return els;
+ /
+ string enumeration
+}
+group: string enumeration
+{
+/
+class: string enumeration
+ c impl headers => convert
+ /
+ copyable methods
+ method: at end
+ const
+ /
+ bool
+
+ method: next
+ c impl =>
+ const char * s = ths->next();
+ if (s == 0 || ths->from_internal_ == 0) \{
+ return s;
+ \} else \{
+ ths->temp_str.clear();
+ ths->from_internal_->convert(s,-1,ths->temp_str);
+ ths->from_internal_->append_null(ths->temp_str);
+ return ths->temp_str.data();
+ \}
+ /
+ const string
+
+}
+group: info
+{
+/
+struct: module info
+ /
+ string: name
+ double: order num
+ string: lib dir
+ string list: dict dirs
+ string list: dict exts
+
+struct: dict info
+ /
+ string: name
+ desc => The Name to identify this dictionary by.
+ string: code
+ desc => The language code to identify this dictionary.
+ A two letter UPPER-CASE ISO 639 language code
+ and an optional two letter ISO 3166 country
+ code after a dash or underscore.
+ string: jargon
+ desc => Any extra information to distinguish this
+ variety of dictionary from other dictionaries
+ which may have the same language and size.
+ int: size
+ string: size str
+ desc => A two char digit code describing the size of
+ the dictionary: 10=tiny, 20=really small,
+ 30=small, 40=med-small, 50=med, 60=med-large,
+ 70=large, 80=huge, 90=insane. Please check
+ the README in aspell-lang-200?????.tar.bz2 or
+ see SCOWL (http://wordlist.sourceforge.net)
+ for an example of how these sizes are used.
+ module info: module
+
+class: module info list
+ /
+ constructor: get aspell module info list
+ /
+ config: config
+
+ list methods
+
+class: dict info list
+ /
+ constructor: get aspell dict info list
+ /
+ config: config
+
+ list methods
+
+class: module info enumeration
+ /
+ enumeration methods
+ copyable methods
+
+class: dict info enumeration
+ /
+ enumeration methods
+ copyable methods
+}
+
+group: string list
+{
+/
+class: string list
+ /
+ constructor
+
+ list methods
+
+ mutable container methods
+
+ copyable methods
+}
+
+group: string map
+{
+/
+class: string map
+ /
+ constructor
+
+ mutable container methods
+
+ copyable methods
+
+ list methods: string pair
+
+ method: insert
+ desc => Insert a new element.
+ Will NOT overwrite an existing entry.
+ Returns FALSE if the element already exists.
+ /
+ bool
+ string: key
+ string: value
+
+ method: replace
+ desc => Insert a new element.
+ Will overwrite an existing entry.
+ Always returns TRUE.
+ /
+ bool
+ string: key
+ string: value
+
+ method: lookup
+ const
+ desc => Looks up an element and returns the value.
+ Returns NULL if the element does not exist.
+ Returns an empty string if the element exists
+ but has a NULL value.
+ /
+ string
+ string: key
+}
+
+group: string pair
+{
+/
+struct: string pair
+ treat as object
+ /
+ string: first
+ default => ""
+ string: second
+ default => ""
+}
+group: string pair enumeration
+{
+/
+class: string pair enumeration
+ /
+ enumeration methods
+ copyable methods
+}
+group: cache
+{
+/
+func: reset cache
+ desc => Reset the global cache(s) so that cache queries will
+ create a new object. If existing objects are still in
+ use they are not deleted. If which is NULL then all
+ caches will be reset. Current caches are "encode",
+ "decode", "dictionary", "language", and "keyboard".
+ /
+ bool
+ string: which
+}
+
diff --git a/spell/aspell-0.60.6.1/auto/mk-src.pl b/spell/aspell-0.60.6.1/auto/mk-src.pl
new file mode 100755
index 0000000..a157e71
--- /dev/null
+++ b/spell/aspell-0.60.6.1/auto/mk-src.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+
+#
+# mk-src.pl -- Perl program to automatically generate interface code.
+#
+# This file is part of The New Aspell
+# Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+# license version 2.0 or 2.1. You should have received a copy of the
+# LGPL license along with this library if you did not you can find it
+# at http://www.gnu.org/.
+
+######################################################################
+#
+# Prologue
+#
+
+use strict;
+use warnings;
+no warnings qw(uninitialized);
+no locale;
+
+use Data::Dumper;
+
+use MkSrc::Info;
+use MkSrc::Read;
+use MkSrc::Util;
+use MkSrc::Type;
+use MkSrc::Create;
+
+
+######################################################################
+#
+# Main
+#
+
+my $master_data = read;
+
+# Pure C
+use MkSrc::ProcCc;
+create_cc_file (type => 'cc',
+ dir => 'interfaces/cc',
+ name => 'aspell',
+ header => true,
+ data => $master_data);
+
+# C++ over C
+# Currently incomplete and broken
+#use MkSrc::ProcCxx;
+#create_cc_file (type => 'cxx',
+# cxx => true,
+# namespace => 'aspell',
+# dir => 'interfaces/cxx',
+# name => 'aspell-cxx',
+# header => true,
+# data => $master_data);
+
+# Native
+use MkSrc::ProcNative;
+foreach my $d (@{$master_data->{data}}) {
+ $info{group}{proc}{native}->($d);
+}
+
+# C for C++
+use MkSrc::ProcImpl;
+foreach my $d (@{$master_data->{data}}) {
+ $info{group}{proc}{impl}->($d);
+}
+
+# Impl
+use MkSrc::ProcNativeImpl;
+foreach my $d (@{$master_data->{data}}) {
+ $info{group}{proc}{native_impl}->($d);
+}
diff --git a/spell/aspell-0.60.6.1/common/asc_ctype.hpp b/spell/aspell-0.60.6.1/common/asc_ctype.hpp
new file mode 100644
index 0000000..2d48305
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/asc_ctype.hpp
@@ -0,0 +1,44 @@
+// This file is part of The New Aspell
+// Copyright (C) 2002 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+#ifndef ASC_CTYPE__HPP
+#define ASC_CTYPE__HPP
+
+namespace acommon {
+
+ static inline bool asc_isspace(int c)
+ {
+ return c==' ' || c=='\n' || c=='\r' || c=='\t' || c=='\f' || c=='\v';
+ }
+
+ static inline bool asc_isdigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+ static inline bool asc_islower(int c)
+ {
+ return 'a' <= c && c <= 'z';
+ }
+ static inline bool asc_isupper(int c)
+ {
+ return 'A' <= c && c <= 'Z';
+ }
+ static inline bool asc_isalpha(int c)
+ {
+ return asc_islower(c) || asc_isupper(c);
+ }
+ static inline int asc_tolower(int c)
+ {
+ return asc_isupper(c) ? c + 0x20 : c;
+ }
+ static inline int asc_toupper(int c)
+ {
+ return asc_islower(c) ? c - 0x20 : c;
+ }
+
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/basic_list.hpp b/spell/aspell-0.60.6.1/common/basic_list.hpp
new file mode 100644
index 0000000..c8072fe
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/basic_list.hpp
@@ -0,0 +1,68 @@
+#ifndef autil__basic_list_hh
+#define autil__basic_list_hh
+
+#include <list>
+//#include <ext/slist>
+
+//#include <assert.h>
+
+// This file is part of The New Aspell
+// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+// BasicList is a simple list structure which can either be
+// implemented as a singly or doubly linked list. I created it
+// because a Singly liked list is not part of the C++ standard however
+// the Doubly Linked list does not have the same methods as the doubly
+// linked list because the singly linked list has a bunch of special
+// methods to address the fact that it is far faster to insert
+// elements before the position pointed to by an iterator is far faster
+// than inserting elements after the current position which is what is
+// normally done. Thus it is not possibly to simply substitute a singly
+// linked list with a doubly linked list by changing the name of the
+// container used. This list currently acts as a wrapper for the list
+// (doubly linked list) STL class however it can also very easily be
+// written as a wrapper for the slist (singly linked list) class when
+// it is available (slist is part of the SGI STL but not the C++
+// standard) for better performance.
+
+namespace acommon {
+
+ template <typename T>
+ class BasicList {
+ //typedef __gnu_cxx::slist<T> List;
+ typedef std::list<T> List;
+ List data_;
+ public:
+ // treat the iterators as forward iterators only
+ typedef typename List::iterator iterator;
+ typedef typename List::const_iterator const_iterator;
+ typedef typename List::size_type size_type;
+ bool empty() {return data_.empty();}
+ void clear() {data_.clear();}
+ size_type size() {return data_.size();}
+ iterator begin() {return data_.begin();}
+ iterator end() {return data_.end();}
+ const_iterator begin() const {return data_.begin();}
+ const_iterator end() const {return data_.end();}
+ void push_front(const T & item) {data_.push_front(item);}
+ void pop_front() {data_.pop_front();}
+ T & front() {return data_.front();}
+ const T & front() const {return data_.front();}
+ void swap(BasicList & other) {data_.swap(other.data_);}
+ void sort() {data_.sort();}
+ template<class Pred> void sort(Pred pr) {data_.sort(pr);}
+ void splice_into (BasicList & other, iterator prev, iterator cur)
+ {
+ //++prev;
+ //assert (prev == cur);
+ data_.splice(data_.begin(),other.data_,cur);
+ //data_.splice_after(data_.begin(), prev);
+ }
+ };
+
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/block_slist-t.hpp b/spell/aspell-0.60.6.1/common/block_slist-t.hpp
new file mode 100644
index 0000000..669c4bd
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/block_slist-t.hpp
@@ -0,0 +1,55 @@
+// This file is part of The New Aspell
+// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+#ifndef autil__block_slist_t_hh
+#define autil__block_slist_t_hh
+
+#include <cstdlib>
+#include <cassert>
+
+#include "block_slist.hpp"
+
+namespace acommon {
+
+ template <typename T>
+ void BlockSList<T>::add_block(unsigned int num)
+ {
+ assert (reinterpret_cast<const char *>(&(first_available->next))
+ ==
+ reinterpret_cast<const char *>(first_available));
+ const unsigned int ptr_offset =
+ reinterpret_cast<const char *>(&(first_available->data))
+ - reinterpret_cast<const char *>(&(first_available->next));
+ void * block = malloc( ptr_offset + sizeof(Node) * num );
+ *reinterpret_cast<void **>(block) = first_block;
+ first_block = block;
+ Node * first = reinterpret_cast<Node *>(reinterpret_cast<char *>(block) + ptr_offset);
+ Node * i = first;
+ Node * last = i + num;
+ while (i + 1 != last) {
+ i->next = i + 1;
+ i = i + 1;
+ }
+ i->next = 0;
+ first_available = first;
+ }
+
+ template <typename T>
+ void BlockSList<T>::clear()
+ {
+ void * i = first_block;
+ while (i != 0) {
+ void * n = *reinterpret_cast<void **>(i);
+ free(i);
+ i = n;
+ }
+ first_block = 0;
+ first_available = 0;
+ }
+
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/block_slist.hpp b/spell/aspell-0.60.6.1/common/block_slist.hpp
new file mode 100644
index 0000000..3c9a025
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/block_slist.hpp
@@ -0,0 +1,76 @@
+// This file is part of The New Aspell
+// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+#ifndef autil__block_slist_hh
+#define autil__block_slist_hh
+
+// BlockSList provided a pool of nodes which can be used for singly
+// linked lists. Nodes are allocated in large chunks instead of
+// one at a time which means that getting a new node is very fast.
+// Nodes returned are not initialized in any way. A placement new
+// must be used to construct the the data member and the destructor
+// must explicitly be called.
+
+namespace acommon {
+
+ template <typename T>
+ class BlockSList {
+
+ public:
+
+ struct Node {
+ Node * next;
+ T data;
+ };
+
+ private:
+
+ void * first_block;
+ Node * first_available;
+
+ BlockSList(const BlockSList &);
+ BlockSList & operator= (const BlockSList &);
+
+ public:
+
+ BlockSList()
+ // Default constructor.
+ // add_block must be called before any nodes are available
+ : first_block(0), first_available(0) {};
+
+ Node * new_node()
+ // return a new_node if one is available or null otherwise
+ // Note: the node's data member is NOT initialized in any way.
+ {
+ Node * n = first_available;
+ if (n != 0)
+ first_available = first_available->next;
+ return n;
+ }
+
+ void remove_node(Node * n)
+ // marks the node as availabe
+ // Note: the node's data memeber destructor is NOT called
+ {
+ n->next = first_available;
+ first_available = n;
+ }
+
+ void add_block(unsigned int num);
+ // allocate enough memory for an additional num nodes
+
+ void clear();
+ // free all memory. add_block must then be called before any nodes
+ // are available
+ // Note: the node's data member destructor is NOT called
+
+
+ ~BlockSList() {clear();}
+
+ };
+
+}
+#endif
diff --git a/spell/aspell-0.60.6.1/common/cache-t.hpp b/spell/aspell-0.60.6.1/common/cache-t.hpp
new file mode 100644
index 0000000..c326fd2
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/cache-t.hpp
@@ -0,0 +1,101 @@
+#ifndef ACOMMON_CACHE_T__HPP
+#define ACOMMON_CACHE_T__HPP
+
+#include "lock.hpp"
+#include "cache.hpp"
+
+//#include "iostream.hpp"
+
+namespace acommon {
+
+class GlobalCacheBase
+{
+public:
+ mutable Mutex lock;
+public: // but don't use
+ const char * name;
+ GlobalCacheBase * next;
+ GlobalCacheBase * * prev;
+protected:
+ Cacheable * first;
+ void del(Cacheable * d);
+ void add(Cacheable * n);
+ GlobalCacheBase(const char * n);
+ ~GlobalCacheBase();
+public:
+ void release(Cacheable * d);
+ void detach(Cacheable * d);
+ void detach_all();
+};
+
+template <class D>
+class GlobalCache : public GlobalCacheBase
+{
+public:
+ typedef D Data;
+ typedef typename Data::CacheKey Key;
+public:
+ GlobalCache(const char * n) : GlobalCacheBase(n) {}
+ // "find" and "add" will _not_ acquire a lock
+ Data * find(const Key & key) {
+ D * cur = static_cast<D *>(first);
+ while (cur && !cur->cache_key_eq(key))
+ cur = static_cast<D *>(cur->next);
+ return cur;
+ }
+ void add(Data * n) {GlobalCacheBase::add(n);}
+ // "release" and "detach" _will_ acquire a lock
+ void release(Data * d) {GlobalCacheBase::release(d);}
+ void detach(Data * d) {GlobalCacheBase::detach(d);}
+};
+
+template <class Data>
+PosibErr<Data *> get_cache_data(GlobalCache<Data> * cache,
+ typename Data::CacheConfig * config,
+ const typename Data::CacheKey & key)
+{
+ LOCK(&cache->lock);
+ Data * n = cache->find(key);
+ //CERR << "Getting " << key << " for " << cache->name << "\n";
+ if (n) {
+ n->refcount++;
+ return n;
+ }
+ PosibErr<Data *> res = Data::get_new(key, config);
+ if (res.has_err()) {
+ //CERR << "ERROR\n";
+ return res;
+ }
+ n = res.data;
+ cache->add(n);
+ //CERR << "LOADED FROM DISK\n";
+ return n;
+}
+
+template <class Data>
+PosibErr<Data *> get_cache_data(GlobalCache<Data> * cache,
+ typename Data::CacheConfig * config,
+ typename Data::CacheConfig2 * config2,
+ const typename Data::CacheKey & key)
+{
+ LOCK(&cache->lock);
+ Data * n = cache->find(key);
+ //CERR << "Getting " << key << "\n";
+ if (n) {
+ n->refcount++;
+ return n;
+ }
+ PosibErr<Data *> res = Data::get_new(key, config, config2);
+ if (res.has_err()) {
+ //CERR << "ERROR\n";
+ return res;
+ }
+ n = res.data;
+ cache->add(n);
+ //CERR << "LOADED FROM DISK\n";
+ return n;
+}
+
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/cache.cpp b/spell/aspell-0.60.6.1/common/cache.cpp
new file mode 100644
index 0000000..c4884e5
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/cache.cpp
@@ -0,0 +1,122 @@
+#include <assert.h>
+
+#include "stack_ptr.hpp"
+#include "cache-t.hpp"
+
+namespace acommon {
+
+static StackPtr<Mutex> global_cache_lock(new Mutex);
+static GlobalCacheBase * first_cache = 0;
+
+void Cacheable::copy() const
+{
+ //CERR << "COPY\n";
+ LOCK(&cache->lock);
+ copy_no_lock();
+}
+
+void GlobalCacheBase::del(Cacheable * n)
+{
+ *n->prev = n->next;
+ if (n->next) n->next->prev = n->prev;
+ n->next = 0;
+ n->prev = 0;
+}
+
+void GlobalCacheBase::add(Cacheable * n)
+{
+ assert(n->refcount > 0);
+ n->next = first;
+ n->prev = &first;
+ if (first) first->prev = &n->next;
+ first = n;
+ n->cache = this;
+}
+
+void GlobalCacheBase::release(Cacheable * d)
+{
+ //CERR << "RELEASE\n";
+ LOCK(&lock);
+ d->refcount--;
+ assert(d->refcount >= 0);
+ if (d->refcount != 0) return;
+ //CERR << "DEL\n";
+ if (d->attached()) del(d);
+ delete d;
+}
+
+void GlobalCacheBase::detach(Cacheable * d)
+{
+ LOCK(&lock);
+ if (d->attached()) del(d);
+}
+
+void GlobalCacheBase::detach_all()
+{
+ LOCK(&lock);
+ Cacheable * p = first;
+ while (p) {
+ *p->prev = 0;
+ p->prev = 0;
+ p = p->next;
+ }
+}
+
+void release_cache_data(GlobalCacheBase * cache, const Cacheable * d)
+{
+ cache->release(const_cast<Cacheable *>(d));
+}
+
+GlobalCacheBase::GlobalCacheBase(const char * n)
+ : name (n)
+{
+ LOCK(global_cache_lock);
+ next = first_cache;
+ prev = &first_cache;
+ if (first_cache) first_cache->prev = &next;
+ first_cache = this;
+}
+
+GlobalCacheBase::~GlobalCacheBase()
+{
+ detach_all();
+ LOCK(global_cache_lock);
+ *prev = next;
+ if (next) next->prev = prev;
+}
+
+bool reset_cache(const char * which)
+{
+ LOCK(global_cache_lock);
+ bool any = false;
+ for (GlobalCacheBase * i = first_cache; i; i = i->next)
+ {
+ if (which && strcmp(i->name, which) == 0) {i->detach_all(); any = true;}
+ }
+ return any;
+}
+
+extern "C"
+int aspell_reset_cache(const char * which)
+{
+ return reset_cache(which);
+}
+
+#if 0
+
+struct CacheableImpl : public Cacheable
+{
+ class CacheConfig;
+ typedef String CacheKey;
+ bool cache_key_eq(const CacheKey &);
+ static PosibErr<CacheableImpl *> get_new(const CacheKey &, CacheConfig *);
+};
+
+template
+PosibErr<CacheableImpl *> get_cache_data(GlobalCache<CacheableImpl> *,
+ CacheableImpl::CacheConfig *,
+ const CacheableImpl::CacheKey &);
+
+#endif
+
+}
diff --git a/spell/aspell-0.60.6.1/common/cache.hpp b/spell/aspell-0.60.6.1/common/cache.hpp
new file mode 100644
index 0000000..8770afc
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/cache.hpp
@@ -0,0 +1,86 @@
+#ifndef ACOMMON_CACHE__HPP
+#define ACOMMON_CACHE__HPP
+
+#include "posib_err.hpp"
+
+namespace acommon {
+
+class GlobalCacheBase;
+template <class Data> class GlobalCache;
+
+// get_cache_data (both versions) and release_cache_data will acquires
+// the cache's lock
+
+template <class Data>
+PosibErr<Data *> get_cache_data(GlobalCache<Data> *,
+ typename Data::CacheConfig *,
+ const typename Data::CacheKey &);
+template <class Data>
+PosibErr<Data *> get_cache_data(GlobalCache<Data> *,
+ typename Data::CacheConfig *,
+ typename Data::CacheConfig2 *,
+ const typename Data::CacheKey &);
+
+class Cacheable;
+void release_cache_data(GlobalCacheBase *, const Cacheable *);
+static inline void release_cache_data(const GlobalCacheBase * c, const Cacheable * d)
+{
+ release_cache_data(const_cast<GlobalCacheBase *>(c),d);
+}
+
+class Cacheable
+{
+public: // but don't use
+ Cacheable * next;
+ Cacheable * * prev;
+ mutable int refcount;
+ GlobalCacheBase * cache;
+public:
+ bool attached() {return prev;}
+ void copy_no_lock() const {refcount++;}
+ void copy() const; // Acquires cache->lock
+ void release() const {release_cache_data(cache,this);} // Acquires cache->lock
+ Cacheable(GlobalCacheBase * c = 0) : next(0), prev(0), refcount(1), cache(c) {}
+ virtual ~Cacheable() {}
+};
+
+template <class Data>
+class CachePtr
+{
+ Data * ptr;
+
+public:
+ void reset(Data * p) {
+ if (ptr) ptr->release();
+ ptr = p;
+ }
+ void copy(Data * p) {if (p) p->copy(); reset(p);}
+ Data * release() {Data * tmp = ptr; ptr = 0; return tmp;}
+
+ Data & operator* () const {return *ptr;}
+ Data * operator-> () const {return ptr;}
+ Data * get() const {return ptr;}
+ operator Data * () const {return ptr;}
+
+ CachePtr() : ptr(0) {}
+ CachePtr(const CachePtr & other) {ptr = other.ptr; if (ptr) ptr->copy();}
+ void operator=(const CachePtr & other) {copy(other.ptr);}
+ ~CachePtr() {reset(0);}
+};
+
+template <class Data>
+PosibErr<void> setup(CachePtr<Data> & res,
+ GlobalCache<Data> * cache,
+ typename Data::CacheConfig * config,
+ const typename Data::CacheKey & key) {
+ PosibErr<Data *> pe = get_cache_data(cache, config, key);
+ if (pe.has_err()) return pe;
+ res.reset(pe.data);
+ return no_err;
+}
+
+bool reset_cache(const char * = 0);
+
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/can_have_error.cpp b/spell/aspell-0.60.6.1/common/can_have_error.cpp
new file mode 100644
index 0000000..42bfb79
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/can_have_error.cpp
@@ -0,0 +1,30 @@
+// This file is part of The New Aspell
+// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+#include "error.hpp"
+#include "can_have_error.hpp"
+
+namespace acommon {
+
+ CanHaveError::CanHaveError(Error * e)
+ : err_(e)
+ {}
+
+ CanHaveError::~CanHaveError()
+ {}
+
+ CanHaveError::CanHaveError(const CanHaveError & other)
+ : err_(other.err_) {}
+
+
+ CanHaveError & CanHaveError::operator=(const CanHaveError & other)
+ {
+ err_ = other.err_;
+ return *this;
+ }
+
+
+}
diff --git a/spell/aspell-0.60.6.1/common/can_have_error.hpp b/spell/aspell-0.60.6.1/common/can_have_error.hpp
new file mode 100644
index 0000000..aae735d
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/can_have_error.hpp
@@ -0,0 +1,29 @@
+/* This file is part of The New Aspell
+ * Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+ * license version 2.0 or 2.1. You should have received a copy of the
+ * LGPL license along with this library if you did not you can find it
+ * at http://www.gnu.org/. */
+
+#ifndef ASPELL_CAN_HAVE_ERROR__HPP
+#define ASPELL_CAN_HAVE_ERROR__HPP
+
+#include "copy_ptr.hpp"
+#include "error.hpp"
+
+namespace acommon {
+
+struct Error;
+
+class CanHaveError {
+ public:
+ CanHaveError(Error * e = 0);
+ CopyPtr<Error> err_;
+ virtual ~CanHaveError();
+ CanHaveError(const CanHaveError &);
+ CanHaveError & operator=(const CanHaveError &);
+};
+
+
+}
+
+#endif /* ASPELL_CAN_HAVE_ERROR__HPP */
diff --git a/spell/aspell-0.60.6.1/common/char_vector.hpp b/spell/aspell-0.60.6.1/common/char_vector.hpp
new file mode 100644
index 0000000..6ef061b
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/char_vector.hpp
@@ -0,0 +1,18 @@
+// This file is part of The New Aspell
+// Copyright (C) 2001-2003 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+#ifndef ASPELL_CHAR_VECTOR__HPP
+#define ASPELL_CHAR_VECTOR__HPP
+
+#include "string.hpp"
+#include "ostream.hpp"
+
+namespace acommon
+{
+ typedef String CharVector;
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/clone_ptr-t.hpp b/spell/aspell-0.60.6.1/common/clone_ptr-t.hpp
new file mode 100644
index 0000000..05e7b79
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/clone_ptr-t.hpp
@@ -0,0 +1,45 @@
+// Copyright (c) 2001
+// Kevin Atkinson
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without
+// fee, provided that the above copyright notice appear in all copies
+// and that both that copyright notice and this permission notice
+// appear in supporting documentation. Kevin Atkinson makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied
+// warranty.
+
+#ifndef autil__clone_ptr_t
+#define autil__clone_ptr_t
+
+#include "clone_ptr.hpp"
+#include <typeinfo>
+#include "generic_copy_ptr-t.hpp"
+
+namespace acommon {
+
+ template <typename T>
+ inline T * ClonePtr<T>::Parms::clone(const T * ptr) const {
+ return ptr->clone();
+ }
+
+ template <typename T>
+ void ClonePtr<T>::Parms::assign(T * & rhs, const T * lhs) const {
+ if (typeid(*rhs) == typeid(*lhs)) {
+ rhs->assign(lhs);
+ } else {
+ T * temp = rhs;
+ rhs = lhs->clone();
+ delete temp;
+ }
+ }
+
+ template <typename T>
+ inline void ClonePtr<T>::Parms::del(T * ptr) {
+ delete ptr;
+ }
+
+}
+
+#endif
diff --git a/spell/aspell-0.60.6.1/common/clone_ptr.hpp b/spell/aspell-0.60.6.1/common/clone_ptr.hpp
new file mode 100644
index 0000000..a4a6eef
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/clone_ptr.hpp
@@ -0,0 +1,54 @@
+// Copyright (c) 2001
+// Kevin Atkinson
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without
+// fee, provided that the above copyright notice appear in all copies
+// and that both that copyright notice and this permission notice
+// appear in supporting documentation. Kevin Atkinson makes no
+// representations about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied
+// warranty.
+
+#ifndef autil__clone_ptr
+#define autil__clone_ptr
+
+#include "generic_copy_ptr.hpp"
+
+namespace acommon {
+
+ template <typename T>
+ class ClonePtr
+ {
+ struct Parms {
+ T * clone(const T * ptr) const;
+ void assign(T * & rhs, const T * lhs) const;
+ void del(T * ptr);
+ };
+ GenericCopyPtr<T, Parms> impl;
+
+ public:
+
+ explicit ClonePtr(T * p = 0) : impl(p) {}
+ ClonePtr(const ClonePtr & other) : impl(other.impl) {}
+
+ ClonePtr & operator=(const ClonePtr & other) {
+ impl = other.impl;
+ return *this;
+ }
+
+ void assign(const T * other) {impl.assign(other);}
+ void reset(T * other = 0) {impl.reset(other);}
+
+ T & operator* () const {return *impl;}
+ T * operator-> () const {return impl;}
+ T * get() const {return impl;}
+ operator T * () const {return impl;}
+
+ T * release() {return impl.release();}
+ };
+
+}
+
+#endif
+
diff --git a/spell/aspell-0.60.6.1/common/config.cpp b/spell/aspell-0.60.6.1/common/config.cpp
new file mode 100644
index 0000000..b1e919b
--- /dev/null
+++ b/spell/aspell-0.60.6.1/common/config.cpp
@@ -0,0 +1,1525 @@
+// This file is part of The New Aspell
+// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
+// version 2.0 or 2.1. You should have received a copy of the LGPL
+// license along with this library if you did not you can find
+// it at http://www.gnu.org/.
+
+//#include <stdio.h>
+//#define DEBUG {fprintf(stderr,"File: %s(%i)\n",__FILE__,__LINE__);}
+#include <string.h>
+#include <stdlib.h>
+#include "ndebug.hpp"
+#include <assert.h>
+
+#include "dirs.h"
+#include "settings.h"
+
+#ifdef USE_LOCALE
+# include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+
+#include "cache.hpp"
+#include "asc_ctype.hpp"
+#include "config.hpp"
+#include "errors.hpp"
+#include "file_util.hpp"
+#include "fstream.hpp"
+#include "getdata.hpp"
+#include "itemize.hpp"
+#include "mutable_container.hpp"
+#include "posib_err.hpp"
+#include "string_map.hpp"
+#include "stack_ptr.hpp"
+#include "char_vector.hpp"
+#include "convert.hpp"
+#include "vararray.hpp"
+#include "string_list.hpp"
+
+#include "gettext.h"
+
+#include "iostream.hpp"
+
+#define DEFAULT_LANG "en_US"
+
+// NOTE: All filter options are now stored with he "f-" prefix. However
+// during lookup, the non prefix version is also recognized.
+
+// The "place_holder" field in Entry and the "Vector<int>" parameter of
+// commit_all are there to deal with the fact than when spacing
+// options on the command line such as "--key what" it can not be
+// determined if "what" should be a the value of "key" or if it should
+// be treated as an independent arg. This is because "key" may
+// be a filter option. Filter options KeyInfo are not loaded until
+// after a commit which is not done at the time the options are being
+// read in from the command line. (If the command line arguments are
+// read in after the other settings are read in and committed than any
+// options setting any of the config files will be ignored. Thus the
+// command line must be parsed and options must be added in an
+// uncommitted state). So the solution is to assume it is an
+// independent arg until told otherwise, the position in the arg array
+// is stored along with the value in the "place_holder" field. When
+// the config class is finally committed and it is determined that
+// "what" is really a value for key the stored arg position is pushed
+// onto the Vector<int> so it can be removed from the arg array. In
+// the case of a "lset-*" this will happen in multiple config
+// "Entry"s, so care is taken to only add the arg position once.
+
+namespace acommon {
+
+ const char * const keyinfo_type_name[4] = {
+ N_("string"), N_("integer"), N_("boolean"), N_("list")
+ };
+
+ const int Config::num_parms_[9] = {1, 1, 0, 0, 0,
+ 1, 1, 1, 0};
+
+ typedef Notifier * NotifierPtr;
+
+ Config::Config(ParmStr name,
+ const KeyInfo * mainbegin,
+ const KeyInfo * mainend)
+ : name_(name)
+ , first_(0), insert_point_(&first_), others_(0)
+ , committed_(true), attached_(false)
+ , md_info_list_index(-1)
+ , settings_read_in_(false)
+ , load_filter_hook(0)
+ , filter_mode_notifier(0)
+ {
+ keyinfo_begin = mainbegin;
+ keyinfo_end = mainend;
+ extra_begin = 0;
+ extra_end = 0;
+ }
+
+ Config::~Config() {
+ del();
+ }
+
+ Config::Config(const Config & other)
+ {
+ copy(other);
+ }
+
+ Config & Config::operator= (const Config & other)
+ {
+ del();
+ copy(other);
+ return *this;
+ }
+
+ Config * Config::clone() const {
+ return new Config(*this);
+ }
+
+ void Config::assign(const Config * other) {
+ *this = *(const Config *)(other);
+ }
+
+ void Config::copy(const Config & other)
+ {
+ assert(other.others_ == 0);
+ others_ = 0;
+
+ name_ = other.name_;
+
+ committed_ = other.committed_;
+ attached_ = other.attached_;
+ settings_read_in_ = other.settings_read_in_;
+
+ keyinfo_begin = other.keyinfo_begin;
+ keyinfo_end = other.keyinfo_end;
+ extra_begin = other.extra_begin;
+ extra_end = other.extra_end;
+ filter_modules = other.filter_modules;
+
+#ifdef HAVE_LIBDL
+ filter_modules_ptrs = other.filter_modules_ptrs;
+ for (Vector<Cacheable *>::iterator i = filter_modules_ptrs.begin();
+ i != filter_modules_ptrs.end();
+ ++i)
+ (*i)->copy();
+#endif
+
+ md_info_list_index = other.md_info_list_index;
+
+ insert_point_ = 0;
+ Entry * const * src = &other.first_;
+ Entry * * dest = &first_;
+ while (*src)
+ {
+ *dest = new Entry(**src);
+ if (src == other.insert_point_)
+ insert_point_ = dest;
+ src = &((*src)->next);
+ dest = &((*dest)->next);
+ }
+ if (insert_point_ == 0)
+ insert_point_ = dest;
+ *dest = 0;
+
+ Vector<Notifier *>::const_iterator i = other.notifier_list.begin();
+ Vector<Notifier *>::const_iterator end = other.notifier_list.end();
+
+ for(; i != end; ++i) {
+ Notifier * tmp = (*i)->clone(this);
+ if (tmp != 0)
+ notifier_list.push_back(tmp);
+ }
+ }
+
+ void Config::del()
+ {
+ while (first_) {
+ Entry * tmp = first_->next;
+ delete first_;
+ first_ = tmp;
+ }
+
+ while (others_) {
+ Entry * tmp = others_->next;
+ delete first_;
+ others_ = tmp;
+ }
+
+ Vector<Notifier *>::iterator i = notifier_list.begin();
+ Vector<Notifier *>::iterator end = notifier_list.end();
+
+ for(; i != end; ++i) {
+ delete (*i);
+ *i = 0;
+ }
+
+ notifier_list.clear();
+
+#ifdef HAVE_LIBDL
+ filter_modules.clear();
+ for (Vector<Cacheable *>::iterator i = filter_modules_ptrs.begin();
+ i != filter_modules_ptrs.end();
+ ++i)
+ (*i)->release();
+ filter_modules_ptrs.clear();
+#endif
+ }
+
+ void Config::set_filter_modules(const ConfigModule * modbegin,
+ const ConfigModule * modend)
+ {
+ assert(filter_modules_ptrs.empty());
+ filter_modules.clear();
+ filter_modules.assign(modbegin, modend);
+ }
+
+ void Config::set_extra(const KeyInfo * begin,
+ const KeyInfo * end)
+ {
+ extra_begin = begin;
+ extra_end = end;
+ }
+
+ //
+ //
+ //
+
+
+ //
+ // Notifier methods
+ //
+
+ NotifierEnumeration * Config::notifiers() const
+ {
+ return new NotifierEnumeration(notifier_list);
+ }
+
+ bool Config::add_notifier(Notifier * n)
+ {
+ Vector<Notifier *>::iterator i = notifier_list.begin();
+ Vector<Notifier *>::iterator end = notifier_list.end();
+
+ while (i != end && *i != n)
+ ++i;
+
+ if (i != end) {
+
+ return false;
+
+ } else {
+
+ notifier_list.push_back(n);
+ return true;
+
+ }
+ }
+
+ bool Config::remove_notifier(const Notifier * n)
+ {
+ Vector<Notifier *>::iterator i = notifier_list.begin();
+ Vector<Notifier *>::iterator end = notifier_list.end();
+
+ while (i != end && *i != n)
+ ++i;
+
+ if (i == end) {
+
+ return false;
+
+ } else {
+
+ delete *i;
+ notifier_list.erase(i);
+ return true;
+
+ }
+ }
+
+ bool Config::replace_notifier(const Notifier * o,
+ Notifier * n)
+ {
+ Vector<Notifier *>::iterator i = notifier_list.begin();
+ Vector<Notifier *>::iterator end = notifier_list.end();
+
+ while (i != end && *i != o)
+ ++i;
+
+ if (i == end) {
+
+ return false;
+
+ } else {
+
+ delete *i;
+ *i = n;
+ return true;
+
+ }
+ }
+
+ //
+ // retrieve methods
+ //
+
+ const Config::Entry * Config::lookup(const char * key) const
+ {
+ const Entry * res = 0;
+ const Entry * cur = first_;
+
+ while (cur) {
+ if (cur->key == key && cur->action != NoOp) res = cur;
+ cur = cur->next;
+ }
+
+ if (!res || res->action == Reset) return 0;
+ return res;
+ }
+
+ bool Config::have(ParmStr key) const
+ {
+ PosibErr<const KeyInfo *> pe = keyinfo(key);
+ if (pe.has_err()) {pe.ignore_err(); return false;}
+ return lookup(pe.data->name);
+ }
+
+ PosibErr<String> Config::retrieve(ParmStr key) const
+ {
+ RET_ON_ERR_SET(keyinfo(key), const KeyInfo *, ki);
+ if (ki->type == KeyInfoList) return make_err(key_not_string, ki->name);
+
+ const Entry * cur = lookup(ki->name);
+
+ return cur ? cur->value : get_default(ki);
+ }
+
+ PosibErr<String> Config::retrieve_any(ParmStr key) const
+ {
+ RET_ON_ERR_SET(keyinfo(key), const KeyInfo *, ki);
+
+ if (ki->type != KeyInfoList) {
+ const Entry * cur = lookup(ki->name);
+ return cur ? cur->value : get_default(ki);
+ } else {
+ StringList sl;
+ RET_ON_ERR(retrieve_list(key, &sl));
+ StringListEnumeration els = sl.elements_obj();
+ const char * s;
+ String val;
+ while ( (s = els.next()) != 0 ) {
+ val += s;
+ val += '\n';
+ }
+ val.pop_back();
+ return val;
+ }
+ }
+
+ PosibErr<bool> Config::retrieve_bool(ParmStr key) const
+ {
+ RET_ON_ERR_SET(keyinfo(key), const KeyInfo *, ki);
+ if (ki->type != KeyInfoBool) return make_err(key_not_bool, ki->name);
+
+ const Entry * cur = lookup(ki->name);
+
+ String value(cur ? cur->value : get_default(ki));
+
+ if (value == "false") return false;
+ else return true;
+ }
+
+ PosibErr<int> Config::retrieve_int(ParmStr key) const
+ {
+ assert(committed_); // otherwise the value may not be an integer
+ // as it has not been verified.
+
+ RET_ON_ERR_SET(keyinfo(key), const KeyInfo *, ki);
+ if (ki->type != KeyInfoInt) return make_err(key_not_int, ki->name);
+
+ const Entry * cur = lookup(ki->name);
+
+ String value(cur ? cur->value : get_default(ki));
+
+ return atoi(value.str());
+ }
+
+ void Config::lookup_list(const KeyInfo * ki,
+ MutableContainer & m,
+ bool include_default) const
+ {
+ const Entry * cur = first_;
+ const Entry * first_to_use = 0;
+
+ while (cur) {
+ if (cur->key == ki->name &&
+ (first_to_use == 0 ||
+ cur->action == Reset || cur->action == Set
+ || cur->action == ListClear))
+ first_to_use = cur;
+ cur = cur->next;
+ }
+
+ cur = first_to_use;
+
+ if (include_default &&
+ (!cur ||
+ !(cur->action == Set || cur->action == ListClear)))
+ {
+ String def = get_default(ki);
+ separate_list(def, m, true);
+ }
+
+ if (cur && cur->action == Reset) {
+ cur = cur->next;
+ }
+
+ if (cur && cur->action == Set) {
+ if (!include_default) m.clear();
+ m.add(cur->value);
+ cur = cur->next;
+ }
+
+ if (cur && cur->action == ListClear) {
+ if (!include_default) m.clear();
+ cur = cur->next;
+ }
+
+ while (cur) {
+ if (cur->key == ki->name) {
+ if (cur->action == ListAdd)
+ m.add(cur->value);
+ else if (cur->action == ListRemove)
+ m.remove(cur->value);
+ }
+ cur = cur->next;
+ }
+ }
+
+ PosibErr<void> Config::retrieve_list(ParmStr key,
+ MutableContainer * m) const
+ {
+ RET_ON_ERR_SET(keyinfo(key), const KeyInfo *, ki);
+ if (ki->type != KeyInfoList) return make_err(key_not_list, ki->name);
+
+ lookup_list(ki, *m, true);
+
+ return no_err;
+ }
+
+ static const KeyInfo * find(ParmStr key,
+ const KeyInfo * i,
+ const KeyInfo * end)
+ {
+ while (i != end) {
+ if (strcmp(key, i->name) == 0)
+ return i;
+ ++i;
+ }
+ return i;
+ }
+
+ static const ConfigModule * find(ParmStr key,
+ const ConfigModule * i,
+ const ConfigModule * end)
+ {
+ while (i != end) {
+ if (strcmp(key, i->name) == 0)
+ return i;
+ ++i;
+ }
+ return i;
+ }
+
+ PosibErr<const KeyInfo *> Config::keyinfo(ParmStr key) const
+ {
+ typedef PosibErr<const KeyInfo *> Ret;
+ {
+ const KeyInfo * i;
+ i = acommon::find(key, keyinfo_begin, keyinfo_end);
+ if (i != keyinfo_end) return Ret(i);
+
+ i = acommon::find(key, extra_begin, extra_end);
+ if (i != extra_end) return Ret(i);
+
+ const char * s = strncmp(key, "f-", 2) == 0 ? key + 2 : key.str();
+ const char * h = strchr(s, '-');
+ if (h == 0) goto err;
+
+ String k(s, h - s);
+ const ConfigModule * j = acommon::find(k,
+ filter_modules.pbegin(),
+ filter_modules.pend());
+
+ if (j == filter_modules.pend() && load_filter_hook && committed_) {
+ // FIXME: This isn't quite right
+ PosibErrBase pe = load_filter_hook(const_cast<Config *>(this), k);
+ pe.ignore_err();
+ j = acommon::find(k,
+ filter_modules.pbegin(),
+ filter_modules.pend());
+ }
+
+ if (j == filter_modules.pend()) goto err;
+
+ i = acommon::find(key, j->begin, j->end);
+ if (i != j->end) return Ret(i);
+
+ if (strncmp(key, "f-", 2) != 0) k = "f-";
+ else k = "";
+ k += key;
+ i = acommon::find(k, j->begin, j->end);
+ if (i != j->end) return Ret(i);
+ }
+ err:
+ return Ret().prim_err(unknown_key, key);
+ }
+
+ static bool proc_locale_str(ParmStr lang, String & final_str)
+ {
+ if (lang == 0) return false;
+ const char * i = lang;
+ if (!(asc_islower(i[0]) && asc_islower(i[1]))) return false;
+ final_str.assign(i, 2);
+ i += 2;
+ if (! (i[0] == '_' || i[0] == '-')) return true;
+ i += 1;
+ if (!(asc_isupper(i[0]) && asc_isupper(i[1]))) return true;
+ final_str += '_';
+ final_str.append(i, 2);
+ return true;
+ }
+
+ static void get_lang_env(String & str)
+ {
+ if (proc_locale_str(getenv("LC_MESSAGES"), str)) return;
+ if (proc_locale_str(getenv("LANG"), str)) return;
+ if (proc_locale_str(getenv("LANGUAGE"), str)) return;
+ str = DEFAULT_LANG;
+ }
+
+#ifdef USE_LOCALE
+
+ static void get_lang(String & final_str)
+ {
+ // FIXME: THIS IS NOT THREAD SAFE
+ String locale = setlocale (LC_ALL, NULL);
+ if (locale == "C")
+ setlocale (LC_ALL, "");
+ const char * lang = setlocale (LC_MESSAGES, NULL);
+ bool res = proc_locale_str(lang, final_str);
+ if (locale == "C")
+ setlocale(LC_MESSAGES, locale.c_str());
+ if (!res)
+ get_lang_env(final_str);
+ }
+
+#else
+
+ static inline void get_lang(String & str)
+ {
+ get_lang_env(str);
+ }
+
+#endif
+
+#if defined USE_LOCALE && defined HAVE_LANGINFO_CODESET
+
+ static inline void get_encoding(const Config & c, String & final_str)
+ {
+ const char * codeset = nl_langinfo(CODESET);
+ if (ascii_encoding(c, codeset)) codeset = "none";
+ final_str = codeset;
+ }
+
+#else
+
+ static inline void get_encoding(const Config &, String & final_str)
+ {
+ final_str = "none";
+ }
+
+#endif
+
+ String Config::get_default(const KeyInfo * ki) const
+ {
+ bool in_replace = false;
+ String final_str;
+ String replace;
+ const char * i = ki->def;
+ if (*i == '!') { // special cases
+ ++i;
+
+ if (strcmp(i, "lang") == 0) {
+
+ const Entry * entry;
+ if (entry = lookup("actual-lang"), entry) {
+ return entry->value;
+ } else if (have("master")) {
+ final_str = "<unknown>";
+ } else {
+ get_lang(final_str);
+ }
+
+ } else if (strcmp(i, "encoding") == 0) {
+
+ get_encoding(*this, final_str);
+
+ } else if (strcmp(i, "special") == 0) {
+
+ // do nothing
+
+ } else {
+
+ abort(); // this should not happen
+
+ }
+
+ } else for(; *i; ++i) {
+
+ if (!in_replace) {
+
+ if (*i == '<') {
+ in_replace = true;
+ } else {
+ final_str += *i;
+ }
+
+ } else { // in_replace
+
+ if (*i == '/' || *i == ':' || *i == '|' || *i == '#' || *i == '^') {
+ char sep = *i;
+ String second;
+ ++i;
+ while (*i != '\0' && *i != '>') second += *i++;
+ if (sep == '/') {
+ String s1 = retrieve(replace);
+ String s2 = retrieve(second);
+ final_str += add_possible_dir(s1, s2);
+ } else if (sep == ':') {
+ String s1 = retrieve(replace);
+ final_str += add_possible_dir(s1, second);
+ } else if (sep == '#') {
+ String s1 = retrieve(replace);
+ assert(second.size() == 1);
+ unsigned int s = 0;
+ while (s != s1.size() && s1[s] != second[0]) ++s;
+ final_str.append(s1, s);
+ } else if (sep == '^') {
+ String s1 = retrieve(replace);
+ String s2 = retrieve(second);
+ final_str += figure_out_dir(s1, s2);
+ } else { // sep == '|'
+ assert(replace[0] == '$');
+ const char * env = getenv(replace.c_str()+1);
+ final_str += env ? env : second;
+ }
+ replace = "";
+ in_replace = false;
+
+ } else if (*i == '>') {
+
+ final_str += retrieve(replace).data;
+ replace = "";
+ in_replace = false;
+
+ } else {
+
+ replace += *i;
+
+ }
+
+ }
+
+ }
+ return final_str;
+ }
+
+ PosibErr<String> Config::get_default(ParmStr key) const
+ {
+ RET_ON_ERR_SET(keyinfo(key), const KeyInfo *, ki);
+ return get_default(ki);
+ }
+
+
+
+#define TEST(v,l,a) \
+ do { \
+ if (len == l && memcmp(s, v, l) == 0) { \
+ if (action) *action = a; \
+ return c + 1; \
+ } \
+ } while (false)
+
+ const char * Config::base_name(const char * s, Action * action)
+ {
+ if (action) *action = Set;
+ const char * c = strchr(s, '-');
+ if (!c) return s;
+ unsigned len = c - s;
+ TEST("reset", 5, Reset);
+ TEST("enable", 6, Enable);
+ TEST("dont", 4, Disable);
+ TEST("disable", 7, Disable);
+ TEST("lset", 4, ListSet);
+ TEST("rem", 3, ListRemove);
+ TEST("remove", 6, ListRemove);
+ TEST("add", 3, ListAdd);
+ TEST("clear", 5, ListClear);
+ return s;
+ }
+
+#undef TEST
+
+ void separate_list(ParmStr value, AddableContainer & out, bool do_unescape)
+ {
+ unsigned len = value.size();
+
+ VARARRAY(char, buf, len + 1);
+ memcpy(buf, value, len + 1);
+
+ len = strlen(buf);
+ char * s = buf;
+ char * end = buf + len;
+
+ while (s < end)
+ {
+ if (do_unescape) while (*s == ' ' || *s == '\t') ++s;
+ char * b = s;
+ char * e = s;
+ while (*s != '\0') {
+ if (do_unescape && *s == '\\') {
+ ++s;
+ if (*s == '\0') break;
+ e = s;
+ ++s;
+ } else {
+ if (*s == ':') break;
+ if (!do_unescape || (*s != ' ' && *s != '\t')) e = s;
+ ++s;
+ }
+ }
+ if (s != b) {
+ ++e;
+ *e = '\0';
+ if (do_unescape) unescape(b);
+
+ out.add(b);
+ }
+ ++s;
+ }
+ }
+
+ void combine_list(String & res, const StringList & in)
+ {
+ res.clear();
+ StringListEnumeration els = in.elements_obj();
+ const char * s = 0;
+ while ( (s = els.next()) != 0)
+ {
+ for (; *s; ++s) {
+ if (*s == ':')
+ res.append('\\');
+ res.append(*s);
+ }
+ res.append(':');
+ }
+ if (res.back() == ':') res.pop_back();
+ }
+
+ struct ListAddHelper : public AddableContainer
+ {
+ Config * config;
+ Config::Entry * orig_entry;
+ PosibErr<bool> add(ParmStr val);
+ };
+
+ PosibErr<bool> ListAddHelper::add(ParmStr val)
+ {
+ Config::Entry * entry = new Config::Entry(*orig_entry);
+ entry->value = val;
+ entry->action = Config::ListAdd;
+ config->set(entry);
+ return true;
+ }
+
+ void Config::replace_internal(ParmStr key, ParmStr value)
+ {
+ Entry * entry = new Entry;
+ entry->key = key;
+ entry->value = value;
+ entry->action = Set;
+ entry->next = *insert_point_;
+ *insert_point_ = entry;
+ insert_point_ = &entry->next;
+ }
+
+ PosibErr<void> Config::replace(ParmStr key, ParmStr value)
+ {
+ Entry * entry = new Entry;
+ entry->key = key;
+ entry->value = value;
+ return set(entry);
+ }
+
+ PosibErr<void> Config::remove(ParmStr key)
+ {
+ Entry * entry = new Entry;
+ entry->key = key;
+ entry->action = Reset;
+ return set(entry);
+ }
+
+ PosibErr<void> Config::set(Entry * entry0, bool do_unescape)
+ {
+ StackPtr<Entry> entry(entry0);
+
+ if (entry->action == NoOp)
+ entry->key = base_name(entry->key.str(), &entry->action);
+
+ if (num_parms(entry->action) == 0 && !entry->value.empty())
+ {
+ if (entry->place_holder == -1) {
+ switch (entry->action) {
+ case Reset:
+ return make_err(no_value_reset, entry->key);
+ case Enable:
+ return make_err(no_value_enable, entry->key);
+ case Disable:
+ return make_err(no_value_disable, entry->key);
+ case ListClear:
+ return make_err(no_value_clear, entry->key);
+ default:
+ abort(); // this shouldn't happen
+ }
+ } else {
+ entry->place_holder = -1;
+ }
+ }
+
+ if (entry->action != ListSet) {
+
+ switch (entry->action) {
+ case Enable:
+ entry->value = "true";
+ entry->action = Set;
+ break;
+ case Disable:
+ entry->value = "false";
+ entry->action = Set;
+ break;
+ default:
+ ;
+ }
+ if (do_unescape) unescape(entry->value.mstr());
+
+ entry->next = *insert_point_;
+ *insert_point_ = entry;
+ insert_point_ = &entry->next;
+ entry.release();
+ if (committed_) RET_ON_ERR(commit(entry0)); // entry0 == entry
+
+ } else { // action == ListSet
+
+ Entry * ent = new Entry;
+ ent->key = entry->key;
+ ent->action = ListClear;
+ set(ent);
+
+ ListAddHelper helper;
+ helper.config = this;
+ helper.orig_entry = entry;
+
+ separate_list(entry->value.str(), helper, do_unescape);
+ }
+ return no_err;
+ }
+
+ PosibErr<void> Config::merge(const Config & other)
+ {
+ const Entry * src = other.first_;
+ while (src)
+ {
+ Entry * entry = new Entry(*src);
+ entry->next = *insert_point_;
+ *insert_point_ = entry;
+ insert_point_ = &entry->next;
+ if (committed_) RET_ON_ERR(commit(entry));
+ src = src->next;
+ }
+ return no_err;
+ }
+
+ void Config::lang_config_merge(const Config & other,
+ int which, ParmStr data_encoding)
+ {
+ Conv to_utf8;
+ to_utf8.setup(*this, data_encoding, "utf-8", NormTo);
+ const Entry * src = other.first_;
+ Entry * * ip = &first_;
+ while (src)
+ {
+ const KeyInfo * l_ki = other.keyinfo(src->key);
+ if (l_ki->other_data == which) {
+ const KeyInfo * c_ki = keyinfo(src->key);
+ Entry * entry = new Entry(*src);
+ if (c_ki->flags & KEYINFO_UTF8)
+ entry->value = to_utf8(entry->value);
+ entry->next = *ip;
+ *ip = entry;
+ ip = &entry->next;
+ }
+ src = src->next;
+ }
+ }
+
+
+#define NOTIFY_ALL(fun) \
+ do { \
+ Vector<Notifier *>::iterator i = notifier_list.begin(); \
+ Vector<Notifier *>::iterator end = notifier_list.end(); \
+ while (i != end) { \
+ RET_ON_ERR((*i)->fun); \
+ ++i; \
+ } \
+ } while (false)
+
+ PosibErr<int> Config::commit(Entry * entry, Conv * conv)
+ {
+ PosibErr<const KeyInfo *> pe = keyinfo(entry->key);
+ {
+ if (pe.has_err()) goto error;
+
+ const KeyInfo * ki = pe;
+
+ entry->key = ki->name;
+
+ // FIXME: This is the correct thing to do but it causes problems
+ // with changing a filter mode in "pipe" mode and probably
+ // elsewhere.
+ //if (attached_ && !(ki->flags & KEYINFO_MAY_CHANGE)) {
+ // pe = make_err(cant_change_value, entry->key);
+ // goto error;
+ //}
+
+ int place_holder = entry->place_holder;
+
+ if (conv && ki->flags & KEYINFO_UTF8)
+ entry->value = (*conv)(entry->value);
+
+ if (ki->type != KeyInfoList && list_action(entry->action)) {
+ pe = make_err(key_not_list, entry->key);
+ goto error;
+ }
+
+ assert(ki->def != 0); // if null this key should never have values
+ // directly added to it
+ String value(entry->action == Reset ? get_default(ki) : entry->value);
+
+ switch (ki->type) {
+
+ case KeyInfoBool: {
+
+ bool val;
+
+ if (value.empty() || entry->place_holder != -1) {
+ // if entry->place_holder != -1 than IGNORE the value no
+ // matter what it is
+ entry->value = "true";
+ val = true;
+ place_holder = -1;
+ } else if (value == "true") {
+ val = true;
+ } else if (value == "false") {
+ val = false;
+ } else {
+ pe = make_err(bad_value, entry->key, value,
+ /* TRANSLATORS: "true" and "false" are literal
+ * values and should not be translated.*/
+ _("either \"true\" or \"false\""));
+ goto error;
+ }
+
+ NOTIFY_ALL(item_updated(ki, val));
+ break;
+
+ } case KeyInfoString:
+
+ NOTIFY_ALL(item_updated(ki, value));
+ break;
+
+ case KeyInfoInt:
+ {
+ int num;
+
+ if (sscanf(value.str(), "%i", &num) == 1 && num >= 0) {
+ NOTIFY_ALL(item_updated(ki, num));
+ } else {
+ pe = make_err(bad_value, entry->key, value, _("a positive integer"));
+ goto error;
+ }
+
+ break;
+ }
+ case KeyInfoList:
+
+ NOTIFY_ALL(list_updated(ki));
+ break;
+
<