From: yamaoka Date: Mon, 6 May 2002 23:49:30 +0000 (+0000) Subject: Importing Oort Gnus v0.06. X-Git-Tag: ognus-0_06~1 X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a9268a5cbbcc7c74fc6fa94d7a3409cda1d6dbf;p=elisp%2Fgnus.git- Importing Oort Gnus v0.06. --- diff --git a/.cvsignore b/.cvsignore index 75f639b..cfd4873 100644 --- a/.cvsignore +++ b/.cvsignore @@ -7,3 +7,5 @@ diffit makepub cvs-access cup-page +admin +oort diff --git a/ChangeLog b/ChangeLog index b5e8a62..a0f1cd4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2002-04-26 Steve Youngs + + * aclocal.m4 (AC_PATH_INFODIR): New. Defaults to '$prefix/info' + for Emacs and 'site-packages/info' for XEmacs. + (AC_PATH_ETCDIR): Drop 'gnus' off the end of the default directory + for XEmacs. + + * configure.in: Use 'AC_PATH_INFO_DIR'. + +2002-02-22 Steve Youngs + + * aclocal.m4 (AC_PATH_LISPDIR): Default to + .../site-packages/lisp/gnus for XEmacs. + (AC_PATH_ETCDIR): Default to .../site-packages/etc/gnus for + XEmacs. + +2002-02-01 ShengHuo ZHU + + * etc/gnus/gnus.xpm: Remove some garbages at the end of the file. + 2002-01-05 Lars Magne Ingebrigtsen * etc/gnus/oort.xface (X-Face): Oort X-Face from diff --git a/GNUS-NEWS b/GNUS-NEWS index dfbcd18..84dfda9 100644 --- a/GNUS-NEWS +++ b/GNUS-NEWS @@ -1,5 +1,5 @@ GNUS NEWS -- history of user-visible changes. -Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. See the end for copying conditions. Please send Gnus bug reports to bugs@gnus.org. @@ -8,6 +8,73 @@ For older news, see Gnus info node "New Features". * Changes in Oort Gnus +** gnus-summary-line-format + +The default value changed to "%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n". +Moreover gnus-extra-headers, nnmail-extra-headers and +gnus-ignored-from-addresses changed their default so that the users +name will be replaced by the recipient's name or the group name +posting to for NNTP groups. + +** deuglify.el (gnus-article-outlook-deuglify-article) + +A new file from Raymond Scholz for deuglifying +broken Outlook (Express) articles. + +** (require 'gnus-load) + +If you use a stand-alone Gnus distribution, you'd better add (require +'gnus-load) into your ~/.emacs after adding the Gnus lisp directory +into load-path. + +File gnus-load.el contains autoload commands, functions and variables, +some of which may not be included in distributions of Emacsen. + +** gnus-slave-unplugged + +A new command which starts gnus offline in slave mode. + +** message-insinuate-rmail + +Adding (message-insinuate-rmail) and (setq mail-user-agent +'gnus-user-agent) in .emacs convinces RMAIL to compose, reply and +forward messages in message-mode, where you can enjoy the power of +MML. + +** message-minibuffer-local-map + +The line below enables BBDB in resending a message: + +(define-key message-minibuffer-local-map [(tab)] 'bbdb-complete-name) + +** Externalize attachments. + +If gnus-gcc-externalize-attachments (or +message-fcc-externalize-attachments) is non-nil, attach local files as +external parts. + +Command gnus-mime-save-part-and-strip (bound to \C-o on MIME buttons) +saves a part and replaces the part with an external one. It works only +on back ends that support editing. + +** gnus-default-charset + +The default value is determined from the current-language-environment +variable, instead of 'iso-8859-1. Also the ".*" item in +gnus-group-charset-alist is removed. + +** gnus-posting-styles + +Add a new format of match like + + ((header "to" "larsi.*org") + (Organization "Somewhere, Inc.")) + +The old format like the lines below is obsolete. + + (header "to" "larsi.*org" + (Organization "Somewhere, Inc.")) + ** message-ignored-news-headers and message-ignored-mail-headers X-Draft-From and X-Gnus-Agent-Meta-Information have been added into @@ -171,7 +238,7 @@ ever-changing layouts. ---------------------------------------------------------------------- Copyright information: -Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Permission is granted to anyone to make or distribute verbatim copies of this document as received, in any medium, provided that the diff --git a/aclocal.m4 b/aclocal.m4 index 6307910..4e4e435 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -83,11 +83,19 @@ AC_DEFUN(AC_PATH_LISPDIR, [ if test "x$theprefix" = "xNONE"; then theprefix=$ac_default_prefix fi + if test "$EMACS_FLAVOR" = "xemacs"; then + lispdir="\$(datadir)/${EMACS_FLAVOR}/site-packages/lisp/gnus" + else lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp" + fi for thedir in share lib; do potential= if test -d ${theprefix}/${thedir}/${EMACS_FLAVOR}/site-lisp; then - lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-lisp" + if test "$EMACS_FLAVOR" = "xemacs"; then + lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-packages/lisp/gnus" + else + lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp" + fi break fi done @@ -100,13 +108,38 @@ AC_DEFUN(AC_PATH_ETCDIR, [ AC_ARG_WITH(etcdir,[ --with-etcdir=DIR Where to install etc files], etcdir=${withval}) AC_MSG_CHECKING([where etc files should go]) if test -z "$etcdir"; then - dnl Set default value + dnl Set default value. + if test "$EMACS_FLAVOR" = "xemacs"; then + etcdir="\$(lispdir)/../../etc" + else etcdir="\$(lispdir)/../etc" + fi fi AC_MSG_RESULT($etcdir) AC_SUBST(etcdir) ]) +dnl +dnl This is a bit on the "evil hack" side of things. It is so we can +dnl have a different default infodir for XEmacs. A user can still specify +dnl someplace else with '--infodir=DIR'. +dnl +AC_DEFUN(AC_PATH_INFO_DIR, [ + AC_MSG_CHECKING([where the TeXinfo docs should go]) + dnl Set default value. This must be an absolute path. + if test "$infodir" = "\${prefix}/info"; then + if test "$EMACS_FLAVOR" = "xemacs"; then + info_dir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-packages/info" + else + info_dir="\$(prefix)/info" + fi + else + info_dir=$infodir + fi + AC_MSG_RESULT($info_dir) + AC_SUBST(info_dir) +]) + dnl dnl Check whether a function exists in a library dnl All '_' characters in the first argument are converted to '-' diff --git a/configure b/configure index 3953a6b..44e3919 100755 --- a/configure +++ b/configure @@ -1,40 +1,119 @@ #! /bin/sh - # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# Generated by Autoconf 2.52. # +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. -# Defaults: -ac_help= +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --with-xemacs Use XEmacs to build" -ac_help="$ac_help - --with-emacs Use Emacs to build" -ac_help="$ac_help - --with-lispdir=DIR Where to install lisp files" -ac_help="$ac_help - --with-etcdir=DIR Where to install etc files" -ac_help="$ac_help - --with-url=DIR Specify where to find the url package" -ac_help="$ac_help - --with-w3=DIR Specify where to find the w3 package" -ac_help="$ac_help - --with-fonts Assume all fonts required are available" +cross_compiling=no +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +ac_unique_file="lisp/gnus.el" # Initialize some variables set by options. +ac_init_help= +ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. -build=NONE -cache_file=./config.cache +cache_file=/dev/null exec_prefix=NONE -host=NONE no_create= -nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE @@ -43,10 +122,15 @@ program_transform_name=s,x,x, silent= site= srcdir= -target=NONE verbose= x_includes=NONE x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' @@ -60,17 +144,16 @@ oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= ac_prev= for ac_option do - # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" @@ -78,59 +161,59 @@ do continue fi - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. - case "$ac_option" in + case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; + bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) - ac_prev=build ;; + ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; + build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) - datadir="$ac_optarg" ;; + datadir=$ac_optarg ;; -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac - eval "enable_${ac_feature}='$ac_optarg'" ;; + eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -139,95 +222,47 @@ do -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; + exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; -host | --host | --hos | --ho) - ac_prev=host ;; + ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; + host_alias=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; + includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; + infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; + libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; + libexecdir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ @@ -236,12 +271,12 @@ EOF -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; + localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; + mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. @@ -262,26 +297,26 @@ EOF -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; + oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; + prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; + program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; + program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ @@ -298,7 +333,7 @@ EOF | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; + program_transform_name=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) @@ -308,7 +343,7 @@ EOF ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; + sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ @@ -319,58 +354,57 @@ EOF | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; + sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; + site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; + srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; + sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; + ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; + target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.13" - exit 0 ;; + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; *) ac_optarg=yes ;; esac - eval "with_${ac_package}='$ac_optarg'" ;; + eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. @@ -381,98 +415,98 @@ EOF ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; + x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; + x_libraries=$ac_optarg ;; - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } fi -exec 5>./config.log -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute path for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; esac done -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: should be removed in autoconf 3.0. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=lisp/gnus.el +test "$silent" = yes && exec 6>/dev/null # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + ac_confdir=`echo "$ac_prog" | sed 's%[\\/][^\\/][^\\/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then @@ -483,13 +517,274 @@ else fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + { echo "$as_me: error: cannot find sources in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + { echo "$as_me: error: cannot find sources in $srcdir" >&2 + { (exit 1); exit 1; }; } fi fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\EOF + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +EOF + exit 0 +fi +exec 5>config.log +cat >&5 </dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +PATH = $PATH + +_ASUNAME +} >&5 + +cat >&5 <\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + ac_sep=" " ;; + *) ac_configure_args="$ac_configure_args$ac_sep$ac_arg" + ac_sep=" " ;; + esac + # Get rid of the leading space. +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + echo >&5 + echo "## ----------------- ##" >&5 + echo "## Cache variables. ##" >&5 + echo "## ----------------- ##" >&5 + echo >&5 + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} >&5 + sed "/^$/d" confdefs.h >conftest.log + if test -s conftest.log; then + echo >&5 + echo "## ------------ ##" >&5 + echo "## confdefs.h. ##" >&5 + echo "## ------------ ##" >&5 + echo >&5 + cat conftest.log >&5 + fi + (echo; echo) >&5 + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" >&5 + echo "$as_me: exit $exit_status" >&5 + rm -rf conftest* confdefs* core core.* *.core conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then @@ -500,65 +795,134 @@ if test -z "$CONFIG_SITE"; then fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" + { echo "$as_me:798: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + cat "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:809: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi else - echo "creating cache $cache_file" - > $cache_file + { echo "$as_me:817: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:833: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:837: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:843: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:845: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:847: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. It doesn't matter if + # we pass some twice (in addition to the command line arguments). + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + *) ac_configure_args="$ac_configure_args $ac_var=$ac_new_val" + ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:866: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:868: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } fi ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -ac_exeext= -ac_objext=o -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac +echo "#! $SHELL" >conftest.sh +echo "exit 0" >>conftest.sh +chmod +x conftest.sh +if { (echo "$as_me:888: PATH=\".;.\"; conftest.sh") >&5 + (PATH=".;."; conftest.sh) 2>&5 + ac_status=$? + echo "$as_me:891: \$? = $ac_status" >&5 + (exit $ac_status); }; then + ac_path_separator=';' else - ac_n= ac_c='\c' ac_t= + ac_path_separator=: fi +PATH_SEPARATOR="$ac_path_separator" +rm -f conftest.sh - -echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:540: checking whether ${MAKE-make} sets \${MAKE}" >&5 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +echo "$as_me:900: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat > conftestmake <<\EOF + cat >conftest.make <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi -rm -f conftestmake +rm -f conftest.make fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$ac_t""yes" 1>&6 + echo "$as_me:920: result: yes" >&5 +echo "${ECHO_T}yes" >&6 SET_MAKE= else - echo "$ac_t""no" 1>&6 + echo "$as_me:924: result: no" >&5 +echo "${ECHO_T}no" >&6 SET_MAKE="MAKE=${MAKE-make}" fi @@ -572,14 +936,20 @@ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break fi done if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } + { { echo "$as_me:946: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -588,31 +958,39 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:597: checking for a BSD compatible install" >&5 +echo "$as_me:966: checking for a BSD compatible install" >&5 +echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6 if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + ac_save_IFS=$IFS; IFS=$ac_path_separator for ac_dir in $PATH; do + IFS=$ac_save_IFS # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + case $ac_dir/ in + / | ./ | .// | /cC/* \ + | /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* \ + | /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do - if test -f $ac_dir/$ac_prog; then + if $as_executable_p "$ac_dir/$ac_prog"; then if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + grep dspmsg "$ac_dir/$ac_prog" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : + elif test $ac_prog = install && + grep pwplus "$ac_dir/$ac_prog" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 @@ -622,30 +1000,29 @@ else ;; esac done - IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" + INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. - INSTALL="$ac_install_sh" + INSTALL=$ac_install_sh fi fi -echo "$ac_t""$INSTALL" 1>&6 +echo "$as_me:1015: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - if test "${EMACS}" = "t"; then EMACS="" fi @@ -653,93 +1030,94 @@ fi # Check whether --with-xemacs or --without-xemacs was given. if test "${with_xemacs+set}" = set; then withval="$with_xemacs" - if test "${withval}" = "yes"; then EMACS=xemacs; else EMACS=${withval}; fi -fi + if test "${withval}" = "yes"; then EMACS=xemacs; else EMACS=${withval}; fi +fi; # Check whether --with-emacs or --without-emacs was given. if test "${with_emacs+set}" = set; then withval="$with_emacs" - if test "${withval}" = "yes"; then EMACS=emacs; else EMACS=${withval}; fi -fi - + if test "${withval}" = "yes"; then EMACS=emacs; else EMACS=${withval}; fi +fi; # Extract the first word of "makeinfo", so it can be a program name with args. set dummy makeinfo; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:669: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +echo "$as_me:1043: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_MAKEINFO+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$MAKEINFO"; then ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_MAKEINFO="makeinfo" - break - fi - done - IFS="$ac_save_ifs" + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_MAKEINFO="makeinfo" +echo "$as_me:1058: found $ac_dir/$ac_word" >&5 +break +done + test -z "$ac_cv_prog_MAKEINFO" && ac_cv_prog_MAKEINFO="no" fi fi -MAKEINFO="$ac_cv_prog_MAKEINFO" +MAKEINFO=$ac_cv_prog_MAKEINFO if test -n "$MAKEINFO"; then - echo "$ac_t""$MAKEINFO" 1>&6 + echo "$as_me:1067: result: $MAKEINFO" >&5 +echo "${ECHO_T}$MAKEINFO" >&6 else - echo "$ac_t""no" 1>&6 + echo "$as_me:1070: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - # Extract the first word of "emacs", so it can be a program name with args. set dummy emacs; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:700: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_EMACS'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +echo "$as_me:1076: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_EMACS+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$EMACS"; then ac_cv_prog_EMACS="$EMACS" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_EMACS="emacs" - break - fi - done - IFS="$ac_save_ifs" + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + $as_executable_p "$ac_dir/$ac_word" || continue +ac_cv_prog_EMACS="emacs" +echo "$as_me:1091: found $ac_dir/$ac_word" >&5 +break +done + test -z "$ac_cv_prog_EMACS" && ac_cv_prog_EMACS="xemacs" fi fi -EMACS="$ac_cv_prog_EMACS" +EMACS=$ac_cv_prog_EMACS if test -n "$EMACS"; then - echo "$ac_t""$EMACS" 1>&6 + echo "$as_me:1100: result: $EMACS" >&5 +echo "${ECHO_T}$EMACS" >&6 else - echo "$ac_t""no" 1>&6 + echo "$as_me:1103: result: no" >&5 +echo "${ECHO_T}no" >&6 fi + echo "$as_me:1107: checking if $EMACS is really XEmacs" >&5 +echo $ECHO_N "checking if $EMACS is really XEmacs... $ECHO_C" >&6 - - - echo $ac_n "checking if $EMACS is really XEmacs""... $ac_c" 1>&6 -echo "configure:731: checking if $EMACS is really XEmacs" >&5 - elisp="(if (string-match \"XEmacs\" emacs-version) \"yes\" \"no\") " if test -z ""noecho""; then - echo $ac_n "checking for xemacsp""... $ac_c" 1>&6 -echo "configure:736: checking for xemacsp" >&5 + echo "$as_me:1112: checking for xemacsp" >&5 +echo $ECHO_N "checking for xemacsp... $ECHO_C" >&6 fi -if eval "test \"`echo '$''{'EMACS_cv_SYS_xemacsp'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${EMACS_cv_SYS_xemacsp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - + OUTPUT=./conftest-$$ - echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 + echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 @@ -750,7 +1128,8 @@ fi xemacsp=${EMACS_cv_SYS_xemacsp} if test -z ""noecho""; then - echo "$ac_t""$xemacsp" 1>&6 + echo "$as_me:1131: result: $xemacsp" >&5 +echo "${ECHO_T}$xemacsp" >&6 fi XEMACS=${EMACS_cv_SYS_xemacsp} @@ -758,25 +1137,24 @@ fi if test "$XEMACS" = "yes"; then EMACS_FLAVOR=xemacs fi - echo "$ac_t""$XEMACS" 1>&6 - - + echo "$as_me:1140: result: $XEMACS" >&5 +echo "${ECHO_T}$XEMACS" >&6 if test "$prefix" = "NONE"; then - echo $ac_n "checking prefix for your Emacs""... $ac_c" 1>&6 -echo "configure:768: checking prefix for your Emacs" >&5 - + echo "$as_me:1144: checking prefix for your Emacs" >&5 +echo $ECHO_N "checking prefix for your Emacs... $ECHO_C" >&6 + elisp="(expand-file-name \"..\" invocation-directory)" if test -z ""noecho""; then - echo $ac_n "checking for prefix""... $ac_c" 1>&6 -echo "configure:773: checking for prefix" >&5 + echo "$as_me:1149: checking for prefix" >&5 +echo $ECHO_N "checking for prefix... $ECHO_C" >&6 fi -if eval "test \"`echo '$''{'EMACS_cv_SYS_prefix'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${EMACS_cv_SYS_prefix+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - + OUTPUT=./conftest-$$ - echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 + echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 @@ -787,77 +1165,101 @@ fi prefix=${EMACS_cv_SYS_prefix} if test -z ""noecho""; then - echo "$ac_t""$prefix" 1>&6 + echo "$as_me:1168: result: $prefix" >&5 +echo "${ECHO_T}$prefix" >&6 fi prefix=${EMACS_cv_SYS_prefix} - echo "$ac_t""$prefix" 1>&6 + echo "$as_me:1173: result: $prefix" >&5 +echo "${ECHO_T}$prefix" >&6 fi - # Check whether --with-lispdir or --without-lispdir was given. + +# Check whether --with-lispdir or --without-lispdir was given. if test "${with_lispdir+set}" = set; then withval="$with_lispdir" lispdir=${withval} -fi - - echo $ac_n "checking where .elc files should go""... $ac_c" 1>&6 -echo "configure:804: checking where .elc files should go" >&5 +fi; + echo "$as_me:1182: checking where .elc files should go" >&5 +echo $ECHO_N "checking where .elc files should go... $ECHO_C" >&6 if test -z "$lispdir"; then theprefix=$prefix if test "x$theprefix" = "xNONE"; then theprefix=$ac_default_prefix fi + if test "$EMACS_FLAVOR" = "xemacs"; then + lispdir="\$(datadir)/${EMACS_FLAVOR}/site-packages/lisp/gnus" + else lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp" + fi for thedir in share lib; do potential= if test -d ${theprefix}/${thedir}/${EMACS_FLAVOR}/site-lisp; then - lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-lisp" + if test "$EMACS_FLAVOR" = "xemacs"; then + lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-packages/lisp/gnus" + else + lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp" + fi break fi done fi - echo "$ac_t""$lispdir" 1>&6 - - + echo "$as_me:1206: result: $lispdir" >&5 +echo "${ECHO_T}$lispdir" >&6 - # Check whether --with-etcdir or --without-etcdir was given. +# Check whether --with-etcdir or --without-etcdir was given. if test "${with_etcdir+set}" = set; then withval="$with_etcdir" etcdir=${withval} -fi - - echo $ac_n "checking where etc files should go""... $ac_c" 1>&6 -echo "configure:830: checking where etc files should go" >&5 +fi; + echo "$as_me:1214: checking where etc files should go" >&5 +echo $ECHO_N "checking where etc files should go... $ECHO_C" >&6 if test -z "$etcdir"; then - etcdir="\$(lispdir)/../etc" + if test "$EMACS_FLAVOR" = "xemacs"; then + etcdir="\$(lispdir)/../../etc" + else + etcdir="\$(lispdir)/../etc" + fi fi - echo "$ac_t""$etcdir" 1>&6 - - + echo "$as_me:1223: result: $etcdir" >&5 +echo "${ECHO_T}$etcdir" >&6 + + echo "$as_me:1226: checking where the TeXinfo docs should go" >&5 +echo $ECHO_N "checking where the TeXinfo docs should go... $ECHO_C" >&6 + if test "$infodir" = "\${prefix}/info"; then + if test "$EMACS_FLAVOR" = "xemacs"; then + info_dir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-packages/info" + else + info_dir="\$(prefix)/info" + fi + else + info_dir=$infodir + fi + echo "$as_me:1237: result: $info_dir" >&5 +echo "${ECHO_T}$info_dir" >&6 -echo $ac_n "checking for acceptable URL version""... $ac_c" 1>&6 -echo "configure:839: checking for acceptable URL version" >&5 -if eval "test \"`echo '$''{'EMACS_cv_ACCEPTABLE_URL'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +echo "$as_me:1240: checking for acceptable URL version" >&5 +echo $ECHO_N "checking for acceptable URL version... $ECHO_C" >&6 +if test "${EMACS_cv_ACCEPTABLE_URL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test -z ""noecho""; then - echo $ac_n "checking for url-retrieve in url""... $ac_c" 1>&6 -echo "configure:847: checking for url-retrieve in url" >&5 + echo "$as_me:1247: checking for url-retrieve in url" >&5 +echo $ECHO_N "checking for url-retrieve in url... $ECHO_C" >&6 fi library=`echo url | tr _ -` elisp="(progn (fmakunbound 'url-retrieve) (condition-case nil (progn (require '$library) (fboundp 'url-retrieve)) (error (prog1 nil (message \"$library not found\")))))" if test -z ""noecho""; then - echo $ac_n "checking for url""... $ac_c" 1>&6 -echo "configure:854: checking for url" >&5 + echo "$as_me:1254: checking for url" >&5 +echo $ECHO_N "checking for url... $ECHO_C" >&6 fi -if eval "test \"`echo '$''{'EMACS_cv_SYS_url'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${EMACS_cv_SYS_url+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - + OUTPUT=./conftest-$$ - echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 + echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 @@ -868,7 +1270,8 @@ fi url=${EMACS_cv_SYS_url} if test -z ""noecho""; then - echo "$ac_t""$url" 1>&6 + echo "$as_me:1273: result: $url" >&5 +echo "${ECHO_T}$url" >&6 fi if test "${EMACS_cv_SYS_url}" = "nil"; then @@ -880,7 +1283,8 @@ fi HAVE_url=${EMACS_cv_SYS_url} if test -z ""noecho""; then - echo "$ac_t""$HAVE_url" 1>&6 + echo "$as_me:1286: result: $HAVE_url" >&5 +echo "${ECHO_T}$HAVE_url" >&6 fi if test "${HAVE_url}" = "yes"; then @@ -890,18 +1294,18 @@ else fi if test "${EMACS_cv_ACCEPTABLE_URL}" = "yes"; then - + elisp="(file-name-directory (locate-library \"url\"))" if test -z ""noecho""; then - echo $ac_n "checking for url_dir""... $ac_c" 1>&6 -echo "configure:898: checking for url_dir" >&5 + echo "$as_me:1300: checking for url_dir" >&5 +echo $ECHO_N "checking for url_dir... $ECHO_C" >&6 fi -if eval "test \"`echo '$''{'EMACS_cv_SYS_url_dir'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${EMACS_cv_SYS_url_dir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - + OUTPUT=./conftest-$$ - echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 + echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 @@ -912,7 +1316,8 @@ fi url_dir=${EMACS_cv_SYS_url_dir} if test -z ""noecho""; then - echo "$ac_t""$url_dir" 1>&6 + echo "$as_me:1319: result: $url_dir" >&5 +echo "${ECHO_T}$url_dir" >&6 fi EMACS_cv_ACCEPTABLE_URL=$EMACS_cv_SYS_url_dir @@ -920,41 +1325,39 @@ fi fi - # Check whether --with-url or --without-url was given. +# Check whether --with-url or --without-url was given. if test "${with_url+set}" = set; then withval="$with_url" - EMACS_cv_ACCEPTABLE_URL=`( cd $withval && pwd || echo "$withval" ) 2> /dev/null` -fi - + EMACS_cv_ACCEPTABLE_URL=`( cd $withval && pwd || echo "$withval" ) 2> /dev/null` +fi; URL=${EMACS_cv_ACCEPTABLE_URL} - - echo "$ac_t"""${URL}"" 1>&6 + echo "$as_me:1335: result: \"${URL}\"" >&5 +echo "${ECHO_T}\"${URL}\"" >&6 -echo $ac_n "checking for acceptable W3 version""... $ac_c" 1>&6 -echo "configure:936: checking for acceptable W3 version" >&5 -if eval "test \"`echo '$''{'EMACS_cv_ACCEPTABLE_W3'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +echo "$as_me:1338: checking for acceptable W3 version" >&5 +echo $ECHO_N "checking for acceptable W3 version... $ECHO_C" >&6 +if test "${EMACS_cv_ACCEPTABLE_W3+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test -z ""noecho""; then - echo $ac_n "checking for w3-form-encode-xwfu in w3_forms""... $ac_c" 1>&6 -echo "configure:944: checking for w3-form-encode-xwfu in w3_forms" >&5 + echo "$as_me:1345: checking for w3-form-encode-xwfu in w3_forms" >&5 +echo $ECHO_N "checking for w3-form-encode-xwfu in w3_forms... $ECHO_C" >&6 fi library=`echo w3_forms | tr _ -` elisp="(progn (fmakunbound 'w3-form-encode-xwfu) (condition-case nil (progn (require '$library) (fboundp 'w3-form-encode-xwfu)) (error (prog1 nil (message \"$library not found\")))))" if test -z ""noecho""; then - echo $ac_n "checking for w3_forms""... $ac_c" 1>&6 -echo "configure:951: checking for w3_forms" >&5 + echo "$as_me:1352: checking for w3_forms" >&5 +echo $ECHO_N "checking for w3_forms... $ECHO_C" >&6 fi -if eval "test \"`echo '$''{'EMACS_cv_SYS_w3_forms'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${EMACS_cv_SYS_w3_forms+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - + OUTPUT=./conftest-$$ - echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 + echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 @@ -965,7 +1368,8 @@ fi w3_forms=${EMACS_cv_SYS_w3_forms} if test -z ""noecho""; then - echo "$ac_t""$w3_forms" 1>&6 + echo "$as_me:1371: result: $w3_forms" >&5 +echo "${ECHO_T}$w3_forms" >&6 fi if test "${EMACS_cv_SYS_w3_forms}" = "nil"; then @@ -977,7 +1381,8 @@ fi HAVE_w3_forms=${EMACS_cv_SYS_w3_forms} if test -z ""noecho""; then - echo "$ac_t""$HAVE_w3_forms" 1>&6 + echo "$as_me:1384: result: $HAVE_w3_forms" >&5 +echo "${ECHO_T}$HAVE_w3_forms" >&6 fi if test "${HAVE_w3_forms}" = "yes"; then @@ -987,18 +1392,18 @@ else fi if test "${EMACS_cv_ACCEPTABLE_W3}" = "yes"; then - + elisp="(file-name-directory (locate-library \"w3-forms\"))" if test -z ""noecho""; then - echo $ac_n "checking for w3_dir""... $ac_c" 1>&6 -echo "configure:995: checking for w3_dir" >&5 + echo "$as_me:1398: checking for w3_dir" >&5 +echo $ECHO_N "checking for w3_dir... $ECHO_C" >&6 fi -if eval "test \"`echo '$''{'EMACS_cv_SYS_w3_dir'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +if test "${EMACS_cv_SYS_w3_dir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - + OUTPUT=./conftest-$$ - echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 + echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& 5 2>&1 ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& 5 2>&1 retval=`cat ${OUTPUT}` echo "=> ${retval}" >& 5 2>&1 @@ -1009,7 +1414,8 @@ fi w3_dir=${EMACS_cv_SYS_w3_dir} if test -z ""noecho""; then - echo "$ac_t""$w3_dir" 1>&6 + echo "$as_me:1417: result: $w3_dir" >&5 +echo "${ECHO_T}$w3_dir" >&6 fi EMACS_cv_ACCEPTABLE_W3=$EMACS_cv_SYS_w3_dir @@ -1017,67 +1423,68 @@ fi fi - # Check whether --with-w3 or --without-w3 was given. +# Check whether --with-w3 or --without-w3 was given. if test "${with_w3+set}" = set; then withval="$with_w3" - EMACS_cv_ACCEPTABLE_W3=`( cd $withval && pwd || echo "$withval" ) 2> /dev/null` -fi - + EMACS_cv_ACCEPTABLE_W3=`( cd $withval && pwd || echo "$withval" ) 2> /dev/null` +fi; W3=${EMACS_cv_ACCEPTABLE_W3} - - echo "$ac_t"""${W3}"" 1>&6 + echo "$as_me:1433: result: \"${W3}\"" >&5 +echo "${ECHO_T}\"${W3}\"" >&6 test "$LATEX" = t && LATEX= test "$LATEX" || for ac_prog in latex do -# Extract the first word of "$ac_prog", so it can be a program name with args. + # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1038: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_path_LATEX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 +echo "$as_me:1441: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_LATEX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - case "$LATEX" in - /*) + case $LATEX in + [\\/]* | ?:[\\/]*) ac_cv_path_LATEX="$LATEX" # Let the user override the test with a path. ;; - ?:/*) - ac_cv_path_LATEX="$LATEX" # Let the user override the test with a dos path. - ;; *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_path_LATEX="$ac_dir/$ac_word" - break - fi - done - IFS="$ac_save_ifs" + ac_save_IFS=$IFS; IFS=$ac_path_separator +ac_dummy="$PATH" +for ac_dir in $ac_dummy; do + IFS=$ac_save_IFS + test -z "$ac_dir" && ac_dir=. + if $as_executable_p "$ac_dir/$ac_word"; then + ac_cv_path_LATEX="$ac_dir/$ac_word" + echo "$as_me:1458: found $ac_dir/$ac_word" >&5 + break +fi +done + ;; esac fi -LATEX="$ac_cv_path_LATEX" +LATEX=$ac_cv_path_LATEX + if test -n "$LATEX"; then - echo "$ac_t""$LATEX" 1>&6 + echo "$as_me:1469: result: $LATEX" >&5 +echo "${ECHO_T}$LATEX" >&6 else - echo "$ac_t""no" 1>&6 + echo "$as_me:1472: result: no" >&5 +echo "${ECHO_T}no" >&6 fi -test -n "$LATEX" && break + test -n "$LATEX" && break done test -n "$LATEX" || LATEX="no" -echo $ac_n "checking for available fonts""... $ac_c" 1>&6 -echo "configure:1075: checking for available fonts" >&5 +echo "$as_me:1480: checking for available fonts" >&5 +echo $ECHO_N "checking for available fonts... $ECHO_C" >&6 + # Check whether --with-fonts or --without-fonts was given. if test "${with_fonts+set}" = set; then withval="$with_fonts" USE_FONTS="$withval" -fi - +fi; WITH_FONTS_bembo='%' WITHOUT_FONTS_bembo= WITH_FONTS_pfu='%' @@ -1090,7 +1497,7 @@ if test -z "${USE_FONTS}"; then else OUTPUT=./conftest-$$ echo '\nonstopmode\documentclass{article}\usepackage{bembo}\begin{document}\end{document}' > ${OUTPUT} - if ${LATEX} ${OUTPUT} & 5 2>&1 ; then + if ${LATEX} ${OUTPUT} & 5 2>&1 ; then if test -z "${USE_FONTS}"; then USE_FONTS="Adobe Bembo" else @@ -1101,7 +1508,7 @@ if test -z "${USE_FONTS}"; then fi echo '\nonstopmode\documentclass{article}\begin{document}{\fontfamily{pfu}\fontsize{10pt}{10}\selectfont test}\end{document}' > ${OUTPUT} if retval=`${LATEX} ${OUTPUT} & 5`; then - if echo "$retval" | grep 'Some font shapes were not available' >& 5 2>&1 ; then + if echo "$retval" | grep 'Some font shapes were not available' >& 5 2>&1 ; then : else if test -z "${USE_FONTS}"; then @@ -1115,7 +1522,7 @@ if test -z "${USE_FONTS}"; then fi echo '\nonstopmode\documentclass{article}\begin{document}{\fontfamily{bcr}\fontsize{10pt}{10}\selectfont test}\end{document}' > ${OUTPUT} if retval=`${LATEX} ${OUTPUT} & 5`; then - if echo "$retval" | grep 'Some font shapes were not available' >& 5 2>&1 ; then + if echo "$retval" | grep 'Some font shapes were not available' >& 5 2>&1 ; then : else if test -z "${USE_FONTS}"; then @@ -1138,16 +1545,12 @@ elif test "${USE_FONTS}" = yes ; then WITHOUT_FONTS_bcr='%' fi - - - - - if test -z "${USE_FONTS}" ; then USE_FONTS=no fi USE_FONTS=`echo "${USE_FONTS}" | sed 's/,\([^,]*\)$/ and\1/'` -echo "$ac_t"""${USE_FONTS}"" 1>&6 +echo "$as_me:1552: result: \"${USE_FONTS}\"" >&5 +echo "${ECHO_T}\"${USE_FONTS}\"" >&6 if test "${USE_FONTS}" = yes ; then USE_FONTS='Set in Adobe Bembo, Adobe Futura and Bitstream Courier.' elif test "${USE_FONTS}" = no ; then @@ -1156,284 +1559,644 @@ else USE_FONTS="Set in ${USE_FONTS}." fi - - -trap '' 1 2 15 -cat > confcache <<\EOF +ac_config_files="$ac_config_files Makefile etc/Makefile lisp/Makefile texi/Makefile texi/gnusconfig.tex texi/ps/Makefile" +cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. # -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. # -EOF +# `ac_cv_env_foo' variables (set or unset) will be overriden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' fi -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then we branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +cat >confdef2opt.sed <<\EOF +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +t quote +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +t quote +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed - -# Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS <&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL # Generated automatically by configure. # Run this file to recreate the current configuration. -# This directory was configured as follows, -# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# -# $0 $ac_configure_args -# # Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. +# configure, is in config.log if it exists. -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +ac_cs_invocation="\$0 \$@" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Name of the executable. +as_me=`echo "$0" |sed 's,.*[\\/],,'` + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +as_executable_p="test -f" + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + +# NLS nuisances. +$as_unset LANG || test "${LANG+set}" != set || { LANG=C; export LANG; } +$as_unset LC_ALL || test "${LC_ALL+set}" != set || { LC_ALL=C; export LC_ALL; } +$as_unset LC_TIME || test "${LC_TIME+set}" != set || { LC_TIME=C; export LC_TIME; } +$as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set || { LC_CTYPE=C; export LC_CTYPE; } +$as_unset LANGUAGE || test "${LANGUAGE+set}" != set || { LANGUAGE=C; export LANGUAGE; } +$as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set || { LC_COLLATE=C; export LC_COLLATE; } +$as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set || { LC_NUMERIC=C; export LC_NUMERIC; } +$as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set || { LC_MESSAGES=C; export LC_MESSAGES; } + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=:; export CDPATH; } + +exec 6>&1 + +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\EOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." +EOF + +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 do - case "\$ac_option" in + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + shift + set dummy "$ac_option" "$ac_optarg" ${1+"$@"} + shift + ;; + -*);; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_need_defaults=false;; + esac + + case $1 in + # Handling of the options. +EOF +cat >>$CONFIG_STATUS <>$CONFIG_STATUS <<\EOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:1840: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + shift + CONFIG_FILES="$CONFIG_FILES $1" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + shift + CONFIG_HEADERS="$CONFIG_HEADERS $1" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:1859: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + esac + shift done -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" +exec 5>>config.log +cat >&5 << _ACEOF + +## ----------------------- ## +## Running config.status. ## +## ----------------------- ## + +This file was extended by $as_me 2.52, executed with + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + > $ac_cs_invocation +on `(hostname || uname -n) 2>/dev/null | sed 1q` -trap 'rm -fr `echo "Makefile etc/Makefile lisp/Makefile texi/Makefile texi/gnusconfig.tex texi/ps/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +_ACEOF EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@SHELL@%$SHELL%g -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@FFLAGS@%$FFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@SET_MAKE@%$SET_MAKE%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@MAKEINFO@%$MAKEINFO%g -s%@EMACS@%$EMACS%g -s%@XEMACS@%$XEMACS%g -s%@EMACS_FLAVOR@%$EMACS_FLAVOR%g -s%@lispdir@%$lispdir%g -s%@etcdir@%$etcdir%g -s%@HAVE_url@%$HAVE_url%g -s%@URL@%$URL%g -s%@HAVE_w3_forms@%$HAVE_w3_forms%g -s%@W3@%$W3%g -s%@LATEX@%$LATEX%g -s%@WITH_FONTS_bembo@%$WITH_FONTS_bembo%g -s%@WITHOUT_FONTS_bembo@%$WITHOUT_FONTS_bembo%g -s%@WITH_FONTS_pfu@%$WITH_FONTS_pfu%g -s%@WITHOUT_FONTS_pfu@%$WITHOUT_FONTS_pfu%g -s%@WITH_FONTS_bcr@%$WITH_FONTS_bcr%g -s%@WITHOUT_FONTS_bcr@%$WITHOUT_FONTS_bcr%g -s%@USE_FONTS@%$USE_FONTS%g +cat >>$CONFIG_STATUS <<\EOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "etc/Makefile" ) CONFIG_FILES="$CONFIG_FILES etc/Makefile" ;; + "lisp/Makefile" ) CONFIG_FILES="$CONFIG_FILES lisp/Makefile" ;; + "texi/Makefile" ) CONFIG_FILES="$CONFIG_FILES texi/Makefile" ;; + "texi/gnusconfig.tex" ) CONFIG_FILES="$CONFIG_FILES texi/gnusconfig.tex" ;; + "texi/ps/Makefile" ) CONFIG_FILES="$CONFIG_FILES texi/ps/Makefile" ;; + *) { { echo "$as_me:1900: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +EOF +cat >>$CONFIG_STATUS <\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@DEFS@,$DEFS,;t t +s,@LIBS@,$LIBS,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@EMACS@,$EMACS,;t t +s,@XEMACS@,$XEMACS,;t t +s,@EMACS_FLAVOR@,$EMACS_FLAVOR,;t t +s,@lispdir@,$lispdir,;t t +s,@etcdir@,$etcdir,;t t +s,@info_dir@,$info_dir,;t t +s,@HAVE_url@,$HAVE_url,;t t +s,@URL@,$URL,;t t +s,@HAVE_w3_forms@,$HAVE_w3_forms,;t t +s,@W3@,$W3,;t t +s,@LATEX@,$LATEX,;t t +s,@WITH_FONTS_bembo@,$WITH_FONTS_bembo,;t t +s,@WITHOUT_FONTS_bembo@,$WITHOUT_FONTS_bembo,;t t +s,@WITH_FONTS_pfu@,$WITH_FONTS_pfu,;t t +s,@WITHOUT_FONTS_pfu@,$WITHOUT_FONTS_pfu,;t t +s,@WITH_FONTS_bcr@,$WITH_FONTS_bcr,;t t +s,@WITHOUT_FONTS_bcr@,$WITHOUT_FONTS_bcr,;t t +s,@USE_FONTS@,$USE_FONTS,;t t CEOF + EOF -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" + cat >>$CONFIG_STATUS <<\EOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then +cat >>$CONFIG_STATUS <<\EOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; esac - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + { case "$ac_dir" in + [\\/]* | ?:[\\/]* ) as_incr_dir=;; + *) as_incr_dir=.;; +esac +as_dummy="$ac_dir" +for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do + case $as_mkdir_dir in + # Skip DOS drivespec + ?:) as_incr_dir=$as_mkdir_dir ;; + *) + as_incr_dir=$as_incr_dir/$as_mkdir_dir + test -d "$as_incr_dir" || mkdir "$as_incr_dir" + ;; + esac +done; } + + ac_dir_suffix="/`echo $ac_dir|sed 's,^\./,,'`" # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + ac_dots=`echo "$ac_dir_suffix" | sed 's,/[^/]*,../,g'` else ac_dir_suffix= ac_dots= fi - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + case $srcdir in + .) ac_srcdir=. + if test -z "$ac_dots"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_dots | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + ac_srcdir=$ac_dots$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_dots$srcdir ;; esac - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_dots$INSTALL ;; esac - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - + if test x"$ac_file" != x-; then + { echo "$as_me:2117: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated automatically by config.status. */ + configure_input="Generated automatically from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:2135: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:2148: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +EOF +cat >>$CONFIG_STATUS <> $CONFIG_STATUS <>$CONFIG_STATUS <<\EOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi +done EOF -cat >> $CONFIG_STATUS <<\EOF -exit 0 +cat >>$CONFIG_STATUS <<\EOF + +{ (exit 0); exit 0; } EOF chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 +ac_clean_files=$ac_clean_files_save + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi diff --git a/configure.in b/configure.in index 5368962..59ed851 100644 --- a/configure.in +++ b/configure.in @@ -20,6 +20,7 @@ AC_CHECK_PROG(EMACS, emacs, emacs, xemacs) AC_PATH_LISPDIR AC_PATH_ETCDIR +AC_PATH_INFO_DIR AC_CHECK_URL AC_CHECK_W3 GNUS_CHECK_FONTS diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 9f58afd..f894e17 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,21 @@ +2002-04-24 Kai Gro,A_(Bjohann + + * ucs-tables.el (featurep): Barf on XEmacs. + +2002-03-06 ShengHuo ZHU + + * ucs-tables.el: Copy from Emacs 21. + +2002-03-05 ShengHuo ZHU + + * xml.el: Sync with Emacs 21. + +2002-01-25 Josh Huber + + * gpg.el (gpg-command-decrypt): Enable the status-fd command line + option to gpg when decrypting so `mml2015-mailcrypt-decrypt' can + parse and display the output. + 2002-01-01 Lars Magne Ingebrigtsen * gnus-mdrtn.el (gnus-moderation-cancel-article): Insert an extra diff --git a/contrib/gpg.el b/contrib/gpg.el index caf9452..1e5470f 100644 --- a/contrib/gpg.el +++ b/contrib/gpg.el @@ -7,7 +7,7 @@ ;; Keywords: crypto ;; Created: 2000-04-15 -;; $Id: gpg.el,v 1.1.1.2 2002-01-06 22:11:27 yamaoka Exp $ +;; $Id: gpg.el,v 1.1.1.3 2002-05-06 23:49:18 yamaoka Exp $ ;; This file is NOT (yet?) part of GNU Emacs. @@ -342,7 +342,7 @@ endings; the input data shall be treated as binary." :group 'gpg-commands) (defcustom gpg-command-decrypt - '(gpg . ("--decrypt" "--batch" "--passphrase-fd=0")) + '(gpg . ("--status-fd" "2" "--decrypt" "--batch" "--passphrase-fd=0")) "Command to decrypt a message. The invoked program has to read the passphrase from standard input, followed by the encrypted message. It writes the decrypted diff --git a/contrib/ucs-tables.el b/contrib/ucs-tables.el new file mode 100644 index 0000000..0255053 --- /dev/null +++ b/contrib/ucs-tables.el @@ -0,0 +1,2479 @@ +;;; ucs-tables.el --- translation to, from and via Unicode -*- coding: iso-2022-7bit -*- + +;; Copyright (C) 2001 Free Software Foundation, Inc. + +;; Author: Dave Love +;; Keywords: i18n + +;; This file is part of GNU Emacs. + +;; This file 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. + +;; This file 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: + +;; This file provides tables mapping between Unicode numbers and +;; emacs-mule characters from the iso-8859 charsets (and others). It +;; also provides some auxiliary functions. + +;; These tables are used to construct other mappings between the Mule +;; iso8859 charsets and the emacs-unicode charsets and a table that +;; unifies iso8859 characters using a single charset as far as +;; possible. These tables are used by latin1-disp.el to display some +;; Unicode characters without a Unicode font and by utf-8.el to unify +;; Latin-N as far as possible on encoding. + +;; More drastically, they can be used to unify 8859 into Latin-1 plus +;; mule-unicode-0100-24ff on decoding, with the corresponding +;; adjustments on encoding; see `ucs-unify-8859'. Be wary of using +;; unification when, for instance, editing Lisp files such as this one +;; which are supposed to contain distinct 8859 charsets. Also, it can +;; make reading and writing of emacs-mule and iso-2022-based encodings +;; not idempotent. + +;; Global minor modes are provided to unify on encoding and decoding. + +;; The translation table `ucs-mule-to-mule-unicode' is populated. +;; This is used by the `mule-utf-8' coding system to encode extra +;; characters. + +;; Command `ucs-insert' is convenient for inserting a given Unicode. +;; (See also the `ucs' input method.) + +;;; Code: + +(when (featurep 'xemacs) + (error "This file cannot be used with XEmacs. For XEmacs, use latin-unity instead")) + +;;; Define tables, to be populated later. + +(defvar ucs-mule-8859-to-ucs-table (make-translation-table) + "Translation table from Emacs ISO-8859 characters to Unicode. +This maps Emacs characters from the non-Latin-1 +...-iso8859-... charsets to their Unicode code points. This is a +many-to-one mapping.") + +(defvar ucs-mule-8859-to-mule-unicode (make-translation-table) + "Translation table from Emacs ISO-8859 characters to Mule Unicode. +This maps Emacs characters from the non-Latin-1 +...-iso8859-... charsets to characters from the +mule-unicode-... charsets. This is a many-to-one mapping. The +characters translated to are suitable for encoding using the +`mule-utf-8' coding system.") + +;; (defvar ucs-ucs-to-mule-8859-table (make-translation-table) +;; "Translation table from Unicode to Emacs ISO-8859 characters. +;; This maps Unicode code points to corresponding Emacs characters from +;; the ...-iso8859-... charsets. This is made a one-to-one mapping where +;; the same character occurs in more than one set by preferring the Emacs +;; iso-8859-N character with lowest N.") + +;; (defvar ucs-mule-unicode-to-mule-8859 (make-translation-table) +;; "Translation table from Mule Unicode to Emacs ISO-8859 characters. +;; This maps non-Latin-1 Emacs characters from the +;; mule-unicode-... charsets used by the `mule-utf-8' coding system to +;; characters from the ...-iso8859-... charsets. This is made a +;; one-to-one mapping where the same character occurs in more than one +;; set by preferring the Emacs iso-8859-N character with lowest N.") + +(defvar ucs-8859-1-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-2. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-2-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-2. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-3-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-3. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-4-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-4. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-5-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-5. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-7-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-7. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-8-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-8. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-9-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-9. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-14-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-14. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +(defvar ucs-8859-15-encode-table nil + "Used as `translation-table-for-encode' for iso-8859-15. +Translates from the iso8859 charsets and `mule-unicode-0100-24ff'.") + +;; Probably defined by utf-8.el. +(defvar ucs-mule-to-mule-unicode (make-translation-table)) +(unless (get 'ucs-mule-to-mule-unicode 'translation-table) + (define-translation-table 'ucs-mule-to-mule-unicode ucs-mule-to-mule-unicode)) +;;; Set up the tables. + +;; Most of these tables were derived from ones in Mule-UCS. + +;; There doesn't seem to be a need to make these let bindings into +;; defvars, so we'll let the data get GC'ed. +(let ((ucs-8859-2-alist + '((?\,B (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,B!(B . ?\x0104) ;; LATIN CAPITAL LETTER A WITH OGONEK + (?\,B"(B . ?\x02D8) ;; BREVE + (?\,B#(B . ?\x0141) ;; LATIN CAPITAL LETTER L WITH STROKE + (?\,B$(B . ?\x00A4) ;; CURRENCY SIGN + (?\,B%(B . ?\x013D) ;; LATIN CAPITAL LETTER L WITH CARON + (?\,B&(B . ?\x015A) ;; LATIN CAPITAL LETTER S WITH ACUTE + (?\,B'(B . ?\x00A7) ;; SECTION SIGN + (?\,B((B . ?\x00A8) ;; DIAERESIS + (?\,B)(B . ?\x0160) ;; LATIN CAPITAL LETTER S WITH CARON + (?\,B*(B . ?\x015E) ;; LATIN CAPITAL LETTER S WITH CEDILLA + (?\,B+(B . ?\x0164) ;; LATIN CAPITAL LETTER T WITH CARON + (?\,B,(B . ?\x0179) ;; LATIN CAPITAL LETTER Z WITH ACUTE + (?\,B-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,B.(B . ?\x017D) ;; LATIN CAPITAL LETTER Z WITH CARON + (?\,B/(B . ?\x017B) ;; LATIN CAPITAL LETTER Z WITH DOT ABOVE + (?\,B0(B . ?\x00B0) ;; DEGREE SIGN + (?\,B1(B . ?\x0105) ;; LATIN SMALL LETTER A WITH OGONEK + (?\,B2(B . ?\x02DB) ;; OGONEK + (?\,B3(B . ?\x0142) ;; LATIN SMALL LETTER L WITH STROKE + (?\,B4(B . ?\x00B4) ;; ACUTE ACCENT + (?\,B5(B . ?\x013E) ;; LATIN SMALL LETTER L WITH CARON + (?\,B6(B . ?\x015B) ;; LATIN SMALL LETTER S WITH ACUTE + (?\,B7(B . ?\x02C7) ;; CARON + (?\,B8(B . ?\x00B8) ;; CEDILLA + (?\,B9(B . ?\x0161) ;; LATIN SMALL LETTER S WITH CARON + (?\,B:(B . ?\x015F) ;; LATIN SMALL LETTER S WITH CEDILLA + (?\,B;(B . ?\x0165) ;; LATIN SMALL LETTER T WITH CARON + (?\,B<(B . ?\x017A) ;; LATIN SMALL LETTER Z WITH ACUTE + (?\,B=(B . ?\x02DD) ;; DOUBLE ACUTE ACCENT + (?\,B>(B . ?\x017E) ;; LATIN SMALL LETTER Z WITH CARON + (?\,B?(B . ?\x017C) ;; LATIN SMALL LETTER Z WITH DOT ABOVE + (?\,B@(B . ?\x0154) ;; LATIN CAPITAL LETTER R WITH ACUTE + (?\,BA(B . ?\x00C1) ;; LATIN CAPITAL LETTER A WITH ACUTE + (?\,BB(B . ?\x00C2) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (?\,BC(B . ?\x0102) ;; LATIN CAPITAL LETTER A WITH BREVE + (?\,BD(B . ?\x00C4) ;; LATIN CAPITAL LETTER A WITH DIAERESIS + (?\,BE(B . ?\x0139) ;; LATIN CAPITAL LETTER L WITH ACUTE + (?\,BF(B . ?\x0106) ;; LATIN CAPITAL LETTER C WITH ACUTE + (?\,BG(B . ?\x00C7) ;; LATIN CAPITAL LETTER C WITH CEDILLA + (?\,BH(B . ?\x010C) ;; LATIN CAPITAL LETTER C WITH CARON + (?\,BI(B . ?\x00C9) ;; LATIN CAPITAL LETTER E WITH ACUTE + (?\,BJ(B . ?\x0118) ;; LATIN CAPITAL LETTER E WITH OGONEK + (?\,BK(B . ?\x00CB) ;; LATIN CAPITAL LETTER E WITH DIAERESIS + (?\,BL(B . ?\x011A) ;; LATIN CAPITAL LETTER E WITH CARON + (?\,BM(B . ?\x00CD) ;; LATIN CAPITAL LETTER I WITH ACUTE + (?\,BN(B . ?\x00CE) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (?\,BO(B . ?\x010E) ;; LATIN CAPITAL LETTER D WITH CARON + (?\,BP(B . ?\x0110) ;; LATIN CAPITAL LETTER D WITH STROKE + (?\,BQ(B . ?\x0143) ;; LATIN CAPITAL LETTER N WITH ACUTE + (?\,BR(B . ?\x0147) ;; LATIN CAPITAL LETTER N WITH CARON + (?\,BS(B . ?\x00D3) ;; LATIN CAPITAL LETTER O WITH ACUTE + (?\,BT(B . ?\x00D4) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (?\,BU(B . ?\x0150) ;; LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + (?\,BV(B . ?\x00D6) ;; LATIN CAPITAL LETTER O WITH DIAERESIS + (?\,BW(B . ?\x00D7) ;; MULTIPLICATION SIGN + (?\,BX(B . ?\x0158) ;; LATIN CAPITAL LETTER R WITH CARON + (?\,BY(B . ?\x016E) ;; LATIN CAPITAL LETTER U WITH RING ABOVE + (?\,BZ(B . ?\x00DA) ;; LATIN CAPITAL LETTER U WITH ACUTE + (?\,B[(B . ?\x0170) ;; LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + (?\,B\(B . ?\x00DC) ;; LATIN CAPITAL LETTER U WITH DIAERESIS + (?\,B](B . ?\x00DD) ;; LATIN CAPITAL LETTER Y WITH ACUTE + (?\,B^(B . ?\x0162) ;; LATIN CAPITAL LETTER T WITH CEDILLA + (?\,B_(B . ?\x00DF) ;; LATIN SMALL LETTER SHARP S + (?\,B`(B . ?\x0155) ;; LATIN SMALL LETTER R WITH ACUTE + (?\,Ba(B . ?\x00E1) ;; LATIN SMALL LETTER A WITH ACUTE + (?\,Bb(B . ?\x00E2) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX + (?\,Bc(B . ?\x0103) ;; LATIN SMALL LETTER A WITH BREVE + (?\,Bd(B . ?\x00E4) ;; LATIN SMALL LETTER A WITH DIAERESIS + (?\,Be(B . ?\x013A) ;; LATIN SMALL LETTER L WITH ACUTE + (?\,Bf(B . ?\x0107) ;; LATIN SMALL LETTER C WITH ACUTE + (?\,Bg(B . ?\x00E7) ;; LATIN SMALL LETTER C WITH CEDILLA + (?\,Bh(B . ?\x010D) ;; LATIN SMALL LETTER C WITH CARON + (?\,Bi(B . ?\x00E9) ;; LATIN SMALL LETTER E WITH ACUTE + (?\,Bj(B . ?\x0119) ;; LATIN SMALL LETTER E WITH OGONEK + (?\,Bk(B . ?\x00EB) ;; LATIN SMALL LETTER E WITH DIAERESIS + (?\,Bl(B . ?\x011B) ;; LATIN SMALL LETTER E WITH CARON + (?\,Bm(B . ?\x00ED) ;; LATIN SMALL LETTER I WITH ACUTE + (?\,Bn(B . ?\x00EE) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX + (?\,Bo(B . ?\x010F) ;; LATIN SMALL LETTER D WITH CARON + (?\,Bp(B . ?\x0111) ;; LATIN SMALL LETTER D WITH STROKE + (?\,Bq(B . ?\x0144) ;; LATIN SMALL LETTER N WITH ACUTE + (?\,Br(B . ?\x0148) ;; LATIN SMALL LETTER N WITH CARON + (?\,Bs(B . ?\x00F3) ;; LATIN SMALL LETTER O WITH ACUTE + (?\,Bt(B . ?\x00F4) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX + (?\,Bu(B . ?\x0151) ;; LATIN SMALL LETTER O WITH DOUBLE ACUTE + (?\,Bv(B . ?\x00F6) ;; LATIN SMALL LETTER O WITH DIAERESIS + (?\,Bw(B . ?\x00F7) ;; DIVISION SIGN + (?\,Bx(B . ?\x0159) ;; LATIN SMALL LETTER R WITH CARON + (?\,By(B . ?\x016F) ;; LATIN SMALL LETTER U WITH RING ABOVE + (?\,Bz(B . ?\x00FA) ;; LATIN SMALL LETTER U WITH ACUTE + (?\,B{(B . ?\x0171) ;; LATIN SMALL LETTER U WITH DOUBLE ACUTE + (?\,B|(B . ?\x00FC) ;; LATIN SMALL LETTER U WITH DIAERESIS + (?\,B}(B . ?\x00FD) ;; LATIN SMALL LETTER Y WITH ACUTE + (?\,B~(B . ?\x0163) ;; LATIN SMALL LETTER T WITH CEDILLA + (?\,B(B . ?\x02D9) ;; DOT ABOVE + )) + + (ucs-8859-3-alist + '((?\,C (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,C!(B . ?\x0126) ;; LATIN CAPITAL LETTER H WITH STROKE + (?\,C"(B . ?\x02D8) ;; BREVE + (?\,C#(B . ?\x00A3) ;; POUND SIGN + (?\,C$(B . ?\x00A4) ;; CURRENCY SIGN + (?\,C&(B . ?\x0124) ;; LATIN CAPITAL LETTER H WITH CIRCUMFLEX + (?\,C'(B . ?\x00A7) ;; SECTION SIGN + (?\,C((B . ?\x00A8) ;; DIAERESIS + (?\,C)(B . ?\x0130) ;; LATIN CAPITAL LETTER I WITH DOT ABOVE + (?\,C*(B . ?\x015E) ;; LATIN CAPITAL LETTER S WITH CEDILLA + (?\,C+(B . ?\x011E) ;; LATIN CAPITAL LETTER G WITH BREVE + (?\,C,(B . ?\x0134) ;; LATIN CAPITAL LETTER J WITH CIRCUMFLEX + (?\,C-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,C/(B . ?\x017B) ;; LATIN CAPITAL LETTER Z WITH DOT ABOVE + (?\,C0(B . ?\x00B0) ;; DEGREE SIGN + (?\,C1(B . ?\x0127) ;; LATIN SMALL LETTER H WITH STROKE + (?\,C2(B . ?\x00B2) ;; SUPERSCRIPT TWO + (?\,C3(B . ?\x00B3) ;; SUPERSCRIPT THREE + (?\,C4(B . ?\x00B4) ;; ACUTE ACCENT + (?\,C5(B . ?\x00B5) ;; MICRO SIGN + (?\,C6(B . ?\x0125) ;; LATIN SMALL LETTER H WITH CIRCUMFLEX + (?\,C7(B . ?\x00B7) ;; MIDDLE DOT + (?\,C8(B . ?\x00B8) ;; CEDILLA + (?\,C9(B . ?\x0131) ;; LATIN SMALL LETTER DOTLESS I + (?\,C:(B . ?\x015F) ;; LATIN SMALL LETTER S WITH CEDILLA + (?\,C;(B . ?\x011F) ;; LATIN SMALL LETTER G WITH BREVE + (?\,C<(B . ?\x0135) ;; LATIN SMALL LETTER J WITH CIRCUMFLEX + (?\,C=(B . ?\x00BD) ;; VULGAR FRACTION ONE HALF + (?\,C?(B . ?\x017C) ;; LATIN SMALL LETTER Z WITH DOT ABOVE + (?\,C@(B . ?\x00C0) ;; LATIN CAPITAL LETTER A WITH GRAVE + (?\,CA(B . ?\x00C1) ;; LATIN CAPITAL LETTER A WITH ACUTE + (?\,CB(B . ?\x00C2) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (?\,CD(B . ?\x00C4) ;; LATIN CAPITAL LETTER A WITH DIAERESIS + (?\,CE(B . ?\x010A) ;; LATIN CAPITAL LETTER C WITH DOT ABOVE + (?\,CF(B . ?\x0108) ;; LATIN CAPITAL LETTER C WITH CIRCUMFLEX + (?\,CG(B . ?\x00C7) ;; LATIN CAPITAL LETTER C WITH CEDILLA + (?\,CH(B . ?\x00C8) ;; LATIN CAPITAL LETTER E WITH GRAVE + (?\,CI(B . ?\x00C9) ;; LATIN CAPITAL LETTER E WITH ACUTE + (?\,CJ(B . ?\x00CA) ;; LATIN CAPITAL LETTER E WITH CIRCUMFLEX + (?\,CK(B . ?\x00CB) ;; LATIN CAPITAL LETTER E WITH DIAERESIS + (?\,CL(B . ?\x00CC) ;; LATIN CAPITAL LETTER I WITH GRAVE + (?\,CM(B . ?\x00CD) ;; LATIN CAPITAL LETTER I WITH ACUTE + (?\,CN(B . ?\x00CE) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (?\,CO(B . ?\x00CF) ;; LATIN CAPITAL LETTER I WITH DIAERESIS + (?\,CQ(B . ?\x00D1) ;; LATIN CAPITAL LETTER N WITH TILDE + (?\,CR(B . ?\x00D2) ;; LATIN CAPITAL LETTER O WITH GRAVE + (?\,CS(B . ?\x00D3) ;; LATIN CAPITAL LETTER O WITH ACUTE + (?\,CT(B . ?\x00D4) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (?\,CU(B . ?\x0120) ;; LATIN CAPITAL LETTER G WITH DOT ABOVE + (?\,CV(B . ?\x00D6) ;; LATIN CAPITAL LETTER O WITH DIAERESIS + (?\,CW(B . ?\x00D7) ;; MULTIPLICATION SIGN + (?\,CX(B . ?\x011C) ;; LATIN CAPITAL LETTER G WITH CIRCUMFLEX + (?\,CY(B . ?\x00D9) ;; LATIN CAPITAL LETTER U WITH GRAVE + (?\,CZ(B . ?\x00DA) ;; LATIN CAPITAL LETTER U WITH ACUTE + (?\,C[(B . ?\x00DB) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX + (?\,C\(B . ?\x00DC) ;; LATIN CAPITAL LETTER U WITH DIAERESIS + (?\,C](B . ?\x016C) ;; LATIN CAPITAL LETTER U WITH BREVE + (?\,C^(B . ?\x015C) ;; LATIN CAPITAL LETTER S WITH CIRCUMFLEX + (?\,C_(B . ?\x00DF) ;; LATIN SMALL LETTER SHARP S + (?\,C`(B . ?\x00E0) ;; LATIN SMALL LETTER A WITH GRAVE + (?\,Ca(B . ?\x00E1) ;; LATIN SMALL LETTER A WITH ACUTE + (?\,Cb(B . ?\x00E2) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX + (?\,Cd(B . ?\x00E4) ;; LATIN SMALL LETTER A WITH DIAERESIS + (?\,Ce(B . ?\x010B) ;; LATIN SMALL LETTER C WITH DOT ABOVE + (?\,Cf(B . ?\x0109) ;; LATIN SMALL LETTER C WITH CIRCUMFLEX + (?\,Cg(B . ?\x00E7) ;; LATIN SMALL LETTER C WITH CEDILLA + (?\,Ch(B . ?\x00E8) ;; LATIN SMALL LETTER E WITH GRAVE + (?\,Ci(B . ?\x00E9) ;; LATIN SMALL LETTER E WITH ACUTE + (?\,Cj(B . ?\x00EA) ;; LATIN SMALL LETTER E WITH CIRCUMFLEX + (?\,Ck(B . ?\x00EB) ;; LATIN SMALL LETTER E WITH DIAERESIS + (?\,Cl(B . ?\x00EC) ;; LATIN SMALL LETTER I WITH GRAVE + (?\,Cm(B . ?\x00ED) ;; LATIN SMALL LETTER I WITH ACUTE + (?\,Cn(B . ?\x00EE) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX + (?\,Co(B . ?\x00EF) ;; LATIN SMALL LETTER I WITH DIAERESIS + (?\,Cq(B . ?\x00F1) ;; LATIN SMALL LETTER N WITH TILDE + (?\,Cr(B . ?\x00F2) ;; LATIN SMALL LETTER O WITH GRAVE + (?\,Cs(B . ?\x00F3) ;; LATIN SMALL LETTER O WITH ACUTE + (?\,Ct(B . ?\x00F4) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX + (?\,Cu(B . ?\x0121) ;; LATIN SMALL LETTER G WITH DOT ABOVE + (?\,Cv(B . ?\x00F6) ;; LATIN SMALL LETTER O WITH DIAERESIS + (?\,Cw(B . ?\x00F7) ;; DIVISION SIGN + (?\,Cx(B . ?\x011D) ;; LATIN SMALL LETTER G WITH CIRCUMFLEX + (?\,Cy(B . ?\x00F9) ;; LATIN SMALL LETTER U WITH GRAVE + (?\,Cz(B . ?\x00FA) ;; LATIN SMALL LETTER U WITH ACUTE + (?\,C{(B . ?\x00FB) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX + (?\,C|(B . ?\x00FC) ;; LATIN SMALL LETTER U WITH DIAERESIS + (?\,C}(B . ?\x016D) ;; LATIN SMALL LETTER U WITH BREVE + (?\,C~(B . ?\x015D) ;; LATIN SMALL LETTER S WITH CIRCUMFLEX + (?\,C(B . ?\x02D9) ;; DOT ABOVE + )) + + (ucs-8859-4-alist + '((?\,D (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,D!(B . ?\x0104) ;; LATIN CAPITAL LETTER A WITH OGONEK + (?\,D"(B . ?\x0138) ;; LATIN SMALL LETTER KRA + (?\,D#(B . ?\x0156) ;; LATIN CAPITAL LETTER R WITH CEDILLA + (?\,D$(B . ?\x00A4) ;; CURRENCY SIGN + (?\,D%(B . ?\x0128) ;; LATIN CAPITAL LETTER I WITH TILDE + (?\,D&(B . ?\x013B) ;; LATIN CAPITAL LETTER L WITH CEDILLA + (?\,D'(B . ?\x00A7) ;; SECTION SIGN + (?\,D((B . ?\x00A8) ;; DIAERESIS + (?\,D)(B . ?\x0160) ;; LATIN CAPITAL LETTER S WITH CARON + (?\,D*(B . ?\x0112) ;; LATIN CAPITAL LETTER E WITH MACRON + (?\,D+(B . ?\x0122) ;; LATIN CAPITAL LETTER G WITH CEDILLA + (?\,D,(B . ?\x0166) ;; LATIN CAPITAL LETTER T WITH STROKE + (?\,D-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,D.(B . ?\x017D) ;; LATIN CAPITAL LETTER Z WITH CARON + (?\,D/(B . ?\x00AF) ;; MACRON + (?\,D0(B . ?\x00B0) ;; DEGREE SIGN + (?\,D1(B . ?\x0105) ;; LATIN SMALL LETTER A WITH OGONEK + (?\,D2(B . ?\x02DB) ;; OGONEK + (?\,D3(B . ?\x0157) ;; LATIN SMALL LETTER R WITH CEDILLA + (?\,D4(B . ?\x00B4) ;; ACUTE ACCENT + (?\,D5(B . ?\x0129) ;; LATIN SMALL LETTER I WITH TILDE + (?\,D6(B . ?\x013C) ;; LATIN SMALL LETTER L WITH CEDILLA + (?\,D7(B . ?\x02C7) ;; CARON + (?\,D8(B . ?\x00B8) ;; CEDILLA + (?\,D9(B . ?\x0161) ;; LATIN SMALL LETTER S WITH CARON + (?\,D:(B . ?\x0113) ;; LATIN SMALL LETTER E WITH MACRON + (?\,D;(B . ?\x0123) ;; LATIN SMALL LETTER G WITH CEDILLA + (?\,D<(B . ?\x0167) ;; LATIN SMALL LETTER T WITH STROKE + (?\,D=(B . ?\x014A) ;; LATIN CAPITAL LETTER ENG + (?\,D>(B . ?\x017E) ;; LATIN SMALL LETTER Z WITH CARON + (?\,D?(B . ?\x014B) ;; LATIN SMALL LETTER ENG + (?\,D@(B . ?\x0100) ;; LATIN CAPITAL LETTER A WITH MACRON + (?\,DA(B . ?\x00C1) ;; LATIN CAPITAL LETTER A WITH ACUTE + (?\,DB(B . ?\x00C2) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (?\,DC(B . ?\x00C3) ;; LATIN CAPITAL LETTER A WITH TILDE + (?\,DD(B . ?\x00C4) ;; LATIN CAPITAL LETTER A WITH DIAERESIS + (?\,DE(B . ?\x00C5) ;; LATIN CAPITAL LETTER A WITH RING ABOVE + (?\,DF(B . ?\x00C6) ;; LATIN CAPITAL LETTER AE + (?\,DG(B . ?\x012E) ;; LATIN CAPITAL LETTER I WITH OGONEK + (?\,DH(B . ?\x010C) ;; LATIN CAPITAL LETTER C WITH CARON + (?\,DI(B . ?\x00C9) ;; LATIN CAPITAL LETTER E WITH ACUTE + (?\,DJ(B . ?\x0118) ;; LATIN CAPITAL LETTER E WITH OGONEK + (?\,DK(B . ?\x00CB) ;; LATIN CAPITAL LETTER E WITH DIAERESIS + (?\,DL(B . ?\x0116) ;; LATIN CAPITAL LETTER E WITH DOT ABOVE + (?\,DM(B . ?\x00CD) ;; LATIN CAPITAL LETTER I WITH ACUTE + (?\,DN(B . ?\x00CE) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (?\,DO(B . ?\x012A) ;; LATIN CAPITAL LETTER I WITH MACRON + (?\,DP(B . ?\x0110) ;; LATIN CAPITAL LETTER D WITH STROKE + (?\,DQ(B . ?\x0145) ;; LATIN CAPITAL LETTER N WITH CEDILLA + (?\,DR(B . ?\x014C) ;; LATIN CAPITAL LETTER O WITH MACRON + (?\,DS(B . ?\x0136) ;; LATIN CAPITAL LETTER K WITH CEDILLA + (?\,DT(B . ?\x00D4) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (?\,DU(B . ?\x00D5) ;; LATIN CAPITAL LETTER O WITH TILDE + (?\,DV(B . ?\x00D6) ;; LATIN CAPITAL LETTER O WITH DIAERESIS + (?\,DW(B . ?\x00D7) ;; MULTIPLICATION SIGN + (?\,DX(B . ?\x00D8) ;; LATIN CAPITAL LETTER O WITH STROKE + (?\,DY(B . ?\x0172) ;; LATIN CAPITAL LETTER U WITH OGONEK + (?\,DZ(B . ?\x00DA) ;; LATIN CAPITAL LETTER U WITH ACUTE + (?\,D[(B . ?\x00DB) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX + (?\,D\(B . ?\x00DC) ;; LATIN CAPITAL LETTER U WITH DIAERESIS + (?\,D](B . ?\x0168) ;; LATIN CAPITAL LETTER U WITH TILDE + (?\,D^(B . ?\x016A) ;; LATIN CAPITAL LETTER U WITH MACRON + (?\,D_(B . ?\x00DF) ;; LATIN SMALL LETTER SHARP S + (?\,D`(B . ?\x0101) ;; LATIN SMALL LETTER A WITH MACRON + (?\,Da(B . ?\x00E1) ;; LATIN SMALL LETTER A WITH ACUTE + (?\,Db(B . ?\x00E2) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX + (?\,Dc(B . ?\x00E3) ;; LATIN SMALL LETTER A WITH TILDE + (?\,Dd(B . ?\x00E4) ;; LATIN SMALL LETTER A WITH DIAERESIS + (?\,De(B . ?\x00E5) ;; LATIN SMALL LETTER A WITH RING ABOVE + (?\,Df(B . ?\x00E6) ;; LATIN SMALL LETTER AE + (?\,Dg(B . ?\x012F) ;; LATIN SMALL LETTER I WITH OGONEK + (?\,Dh(B . ?\x010D) ;; LATIN SMALL LETTER C WITH CARON + (?\,Di(B . ?\x00E9) ;; LATIN SMALL LETTER E WITH ACUTE + (?\,Dj(B . ?\x0119) ;; LATIN SMALL LETTER E WITH OGONEK + (?\,Dk(B . ?\x00EB) ;; LATIN SMALL LETTER E WITH DIAERESIS + (?\,Dl(B . ?\x0117) ;; LATIN SMALL LETTER E WITH DOT ABOVE + (?\,Dm(B . ?\x00ED) ;; LATIN SMALL LETTER I WITH ACUTE + (?\,Dn(B . ?\x00EE) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX + (?\,Do(B . ?\x012B) ;; LATIN SMALL LETTER I WITH MACRON + (?\,Dp(B . ?\x0111) ;; LATIN SMALL LETTER D WITH STROKE + (?\,Dq(B . ?\x0146) ;; LATIN SMALL LETTER N WITH CEDILLA + (?\,Dr(B . ?\x014D) ;; LATIN SMALL LETTER O WITH MACRON + (?\,Ds(B . ?\x0137) ;; LATIN SMALL LETTER K WITH CEDILLA + (?\,Dt(B . ?\x00F4) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX + (?\,Du(B . ?\x00F5) ;; LATIN SMALL LETTER O WITH TILDE + (?\,Dv(B . ?\x00F6) ;; LATIN SMALL LETTER O WITH DIAERESIS + (?\,Dw(B . ?\x00F7) ;; DIVISION SIGN + (?\,Dx(B . ?\x00F8) ;; LATIN SMALL LETTER O WITH STROKE + (?\,Dy(B . ?\x0173) ;; LATIN SMALL LETTER U WITH OGONEK + (?\,Dz(B . ?\x00FA) ;; LATIN SMALL LETTER U WITH ACUTE + (?\,D{(B . ?\x00FB) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX + (?\,D|(B . ?\x00FC) ;; LATIN SMALL LETTER U WITH DIAERESIS + (?\,D}(B . ?\x0169) ;; LATIN SMALL LETTER U WITH TILDE + (?\,D~(B . ?\x016B) ;; LATIN SMALL LETTER U WITH MACRON + (?\,D(B . ?\x02D9) ;; DOT ABOVE + )) + + (ucs-8859-5-alist + '((?\,L (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,L!(B . ?\x0401) ;; CYRILLIC CAPITAL LETTER IO + (?\,L"(B . ?\x0402) ;; CYRILLIC CAPITAL LETTER DJE + (?\,L#(B . ?\x0403) ;; CYRILLIC CAPITAL LETTER GJE + (?\,L$(B . ?\x0404) ;; CYRILLIC CAPITAL LETTER UKRAINIAN IE + (?\,L%(B . ?\x0405) ;; CYRILLIC CAPITAL LETTER DZE + (?\,L&(B . ?\x0406) ;; CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + (?\,L'(B . ?\x0407) ;; CYRILLIC CAPITAL LETTER YI + (?\,L((B . ?\x0408) ;; CYRILLIC CAPITAL LETTER JE + (?\,L)(B . ?\x0409) ;; CYRILLIC CAPITAL LETTER LJE + (?\,L*(B . ?\x040A) ;; CYRILLIC CAPITAL LETTER NJE + (?\,L+(B . ?\x040B) ;; CYRILLIC CAPITAL LETTER TSHE + (?\,L,(B . ?\x040C) ;; CYRILLIC CAPITAL LETTER KJE + (?\,L-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,L.(B . ?\x040E) ;; CYRILLIC CAPITAL LETTER SHORT U + (?\,L/(B . ?\x040F) ;; CYRILLIC CAPITAL LETTER DZHE + (?\,L0(B . ?\x0410) ;; CYRILLIC CAPITAL LETTER A + (?\,L1(B . ?\x0411) ;; CYRILLIC CAPITAL LETTER BE + (?\,L2(B . ?\x0412) ;; CYRILLIC CAPITAL LETTER VE + (?\,L3(B . ?\x0413) ;; CYRILLIC CAPITAL LETTER GHE + (?\,L4(B . ?\x0414) ;; CYRILLIC CAPITAL LETTER DE + (?\,L5(B . ?\x0415) ;; CYRILLIC CAPITAL LETTER IE + (?\,L6(B . ?\x0416) ;; CYRILLIC CAPITAL LETTER ZHE + (?\,L7(B . ?\x0417) ;; CYRILLIC CAPITAL LETTER ZE + (?\,L8(B . ?\x0418) ;; CYRILLIC CAPITAL LETTER I + (?\,L9(B . ?\x0419) ;; CYRILLIC CAPITAL LETTER SHORT I + (?\,L:(B . ?\x041A) ;; CYRILLIC CAPITAL LETTER KA + (?\,L;(B . ?\x041B) ;; CYRILLIC CAPITAL LETTER EL + (?\,L<(B . ?\x041C) ;; CYRILLIC CAPITAL LETTER EM + (?\,L=(B . ?\x041D) ;; CYRILLIC CAPITAL LETTER EN + (?\,L>(B . ?\x041E) ;; CYRILLIC CAPITAL LETTER O + (?\,L?(B . ?\x041F) ;; CYRILLIC CAPITAL LETTER PE + (?\,L@(B . ?\x0420) ;; CYRILLIC CAPITAL LETTER ER + (?\,LA(B . ?\x0421) ;; CYRILLIC CAPITAL LETTER ES + (?\,LB(B . ?\x0422) ;; CYRILLIC CAPITAL LETTER TE + (?\,LC(B . ?\x0423) ;; CYRILLIC CAPITAL LETTER U + (?\,LD(B . ?\x0424) ;; CYRILLIC CAPITAL LETTER EF + (?\,LE(B . ?\x0425) ;; CYRILLIC CAPITAL LETTER HA + (?\,LF(B . ?\x0426) ;; CYRILLIC CAPITAL LETTER TSE + (?\,LG(B . ?\x0427) ;; CYRILLIC CAPITAL LETTER CHE + (?\,LH(B . ?\x0428) ;; CYRILLIC CAPITAL LETTER SHA + (?\,LI(B . ?\x0429) ;; CYRILLIC CAPITAL LETTER SHCHA + (?\,LJ(B . ?\x042A) ;; CYRILLIC CAPITAL LETTER HARD SIGN + (?\,LK(B . ?\x042B) ;; CYRILLIC CAPITAL LETTER YERU + (?\,LL(B . ?\x042C) ;; CYRILLIC CAPITAL LETTER SOFT SIGN + (?\,LM(B . ?\x042D) ;; CYRILLIC CAPITAL LETTER E + (?\,LN(B . ?\x042E) ;; CYRILLIC CAPITAL LETTER YU + (?\,LO(B . ?\x042F) ;; CYRILLIC CAPITAL LETTER YA + (?\,LP(B . ?\x0430) ;; CYRILLIC SMALL LETTER A + (?\,LQ(B . ?\x0431) ;; CYRILLIC SMALL LETTER BE + (?\,LR(B . ?\x0432) ;; CYRILLIC SMALL LETTER VE + (?\,LS(B . ?\x0433) ;; CYRILLIC SMALL LETTER GHE + (?\,LT(B . ?\x0434) ;; CYRILLIC SMALL LETTER DE + (?\,LU(B . ?\x0435) ;; CYRILLIC SMALL LETTER IE + (?\,LV(B . ?\x0436) ;; CYRILLIC SMALL LETTER ZHE + (?\,LW(B . ?\x0437) ;; CYRILLIC SMALL LETTER ZE + (?\,LX(B . ?\x0438) ;; CYRILLIC SMALL LETTER I + (?\,LY(B . ?\x0439) ;; CYRILLIC SMALL LETTER SHORT I + (?\,LZ(B . ?\x043A) ;; CYRILLIC SMALL LETTER KA + (?\,L[(B . ?\x043B) ;; CYRILLIC SMALL LETTER EL + (?\,L\(B . ?\x043C) ;; CYRILLIC SMALL LETTER EM + (?\,L](B . ?\x043D) ;; CYRILLIC SMALL LETTER EN + (?\,L^(B . ?\x043E) ;; CYRILLIC SMALL LETTER O + (?\,L_(B . ?\x043F) ;; CYRILLIC SMALL LETTER PE + (?\,L`(B . ?\x0440) ;; CYRILLIC SMALL LETTER ER + (?\,La(B . ?\x0441) ;; CYRILLIC SMALL LETTER ES + (?\,Lb(B . ?\x0442) ;; CYRILLIC SMALL LETTER TE + (?\,Lc(B . ?\x0443) ;; CYRILLIC SMALL LETTER U + (?\,Ld(B . ?\x0444) ;; CYRILLIC SMALL LETTER EF + (?\,Le(B . ?\x0445) ;; CYRILLIC SMALL LETTER HA + (?\,Lf(B . ?\x0446) ;; CYRILLIC SMALL LETTER TSE + (?\,Lg(B . ?\x0447) ;; CYRILLIC SMALL LETTER CHE + (?\,Lh(B . ?\x0448) ;; CYRILLIC SMALL LETTER SHA + (?\,Li(B . ?\x0449) ;; CYRILLIC SMALL LETTER SHCHA + (?\,Lj(B . ?\x044A) ;; CYRILLIC SMALL LETTER HARD SIGN + (?\,Lk(B . ?\x044B) ;; CYRILLIC SMALL LETTER YERU + (?\,Ll(B . ?\x044C) ;; CYRILLIC SMALL LETTER SOFT SIGN + (?\,Lm(B . ?\x044D) ;; CYRILLIC SMALL LETTER E + (?\,Ln(B . ?\x044E) ;; CYRILLIC SMALL LETTER YU + (?\,Lo(B . ?\x044F) ;; CYRILLIC SMALL LETTER YA + (?\,Lp(B . ?\x2116) ;; NUMERO SIGN + (?\,Lq(B . ?\x0451) ;; CYRILLIC SMALL LETTER IO + (?\,Lr(B . ?\x0452) ;; CYRILLIC SMALL LETTER DJE + (?\,Ls(B . ?\x0453) ;; CYRILLIC SMALL LETTER GJE + (?\,Lt(B . ?\x0454) ;; CYRILLIC SMALL LETTER UKRAINIAN IE + (?\,Lu(B . ?\x0455) ;; CYRILLIC SMALL LETTER DZE + (?\,Lv(B . ?\x0456) ;; CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + (?\,Lw(B . ?\x0457) ;; CYRILLIC SMALL LETTER YI + (?\,Lx(B . ?\x0458) ;; CYRILLIC SMALL LETTER JE + (?\,Ly(B . ?\x0459) ;; CYRILLIC SMALL LETTER LJE + (?\,Lz(B . ?\x045A) ;; CYRILLIC SMALL LETTER NJE + (?\,L{(B . ?\x045B) ;; CYRILLIC SMALL LETTER TSHE + (?\,L|(B . ?\x045C) ;; CYRILLIC SMALL LETTER KJE + (?\,L}(B . ?\x00A7) ;; SECTION SIGN + (?\,L~(B . ?\x045E) ;; CYRILLIC SMALL LETTER SHORT U + (?\,L(B . ?\x045F) ;; CYRILLIC SMALL LETTER DZHE + )) + + ;; Arabic probably isn't so useful in the absence of Arabic + ;; language support. + (ucs-8859-6-alist + '((?,G (B . ?\x00A0) ;; NO-BREAK SPACE + (?,G$(B . ?\x00A4) ;; CURRENCY SIGN + (?,G,(B . ?\x060C) ;; ARABIC COMMA + (?,G-(B . ?\x00AD) ;; SOFT HYPHEN + (?,G;(B . ?\x061B) ;; ARABIC SEMICOLON + (?,G?(B . ?\x061F) ;; ARABIC QUESTION MARK + (?,GA(B . ?\x0621) ;; ARABIC LETTER HAMZA + (?,GB(B . ?\x0622) ;; ARABIC LETTER ALEF WITH MADDA ABOVE + (?,GC(B . ?\x0623) ;; ARABIC LETTER ALEF WITH HAMZA ABOVE + (?,GD(B . ?\x0624) ;; ARABIC LETTER WAW WITH HAMZA ABOVE + (?,GE(B . ?\x0625) ;; ARABIC LETTER ALEF WITH HAMZA BELOW + (?,GF(B . ?\x0626) ;; ARABIC LETTER YEH WITH HAMZA ABOVE + (?,GG(B . ?\x0627) ;; ARABIC LETTER ALEF + (?,GH(B . ?\x0628) ;; ARABIC LETTER BEH + (?,GI(B . ?\x0629) ;; ARABIC LETTER TEH MARBUTA + (?,GJ(B . ?\x062A) ;; ARABIC LETTER TEH + (?,GK(B . ?\x062B) ;; ARABIC LETTER THEH + (?,GL(B . ?\x062C) ;; ARABIC LETTER JEEM + (?,GM(B . ?\x062D) ;; ARABIC LETTER HAH + (?,GN(B . ?\x062E) ;; ARABIC LETTER KHAH + (?,GO(B . ?\x062F) ;; ARABIC LETTER DAL + (?,GP(B . ?\x0630) ;; ARABIC LETTER THAL + (?,GQ(B . ?\x0631) ;; ARABIC LETTER REH + (?,GR(B . ?\x0632) ;; ARABIC LETTER ZAIN + (?,GS(B . ?\x0633) ;; ARABIC LETTER SEEN + (?,GT(B . ?\x0634) ;; ARABIC LETTER SHEEN + (?,GU(B . ?\x0635) ;; ARABIC LETTER SAD + (?,GV(B . ?\x0636) ;; ARABIC LETTER DAD + (?,GW(B . ?\x0637) ;; ARABIC LETTER TAH + (?,GX(B . ?\x0638) ;; ARABIC LETTER ZAH + (?,GY(B . ?\x0639) ;; ARABIC LETTER AIN + (?,GZ(B . ?\x063A) ;; ARABIC LETTER GHAIN + (?,G`(B . ?\x0640) ;; ARABIC TATWEEL + (?,Ga(B . ?\x0641) ;; ARABIC LETTER FEH + (?,Gb(B . ?\x0642) ;; ARABIC LETTER QAF + (?,Gc(B . ?\x0643) ;; ARABIC LETTER KAF + (?,Gd(B . ?\x0644) ;; ARABIC LETTER LAM + (?,Ge(B . ?\x0645) ;; ARABIC LETTER MEEM + (?,Gf(B . ?\x0646) ;; ARABIC LETTER NOON + (?,Gg(B . ?\x0647) ;; ARABIC LETTER HEH + (?,Gh(B . ?\x0648) ;; ARABIC LETTER WAW + (?,Gi(B . ?\x0649) ;; ARABIC LETTER ALEF MAKSURA + (?,Gj(B . ?\x064A) ;; ARABIC LETTER YEH + (?,Gk(B . ?\x064B) ;; ARABIC FATHATAN + (?,Gl(B . ?\x064C) ;; ARABIC DAMMATAN + (?,Gm(B . ?\x064D) ;; ARABIC KASRATAN + (?,Gn(B . ?\x064E) ;; ARABIC FATHA + (?,Go(B . ?\x064F) ;; ARABIC DAMMA + (?,Gp(B . ?\x0650) ;; ARABIC KASRA + (?,Gq(B . ?\x0651) ;; ARABIC SHADDA + (?,Gr(B . ?\x0652) ;; ARABIC SUKUN + )) + + (ucs-8859-7-alist + '((?\,F (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,F!(B . ?\x2018) ;; LEFT SINGLE QUOTATION MARK + (?\,F"(B . ?\x2019) ;; RIGHT SINGLE QUOTATION MARK + (?\,F#(B . ?\x00A3) ;; POUND SIGN + (?\,F&(B . ?\x00A6) ;; BROKEN BAR + (?\,F'(B . ?\x00A7) ;; SECTION SIGN + (?\,F((B . ?\x00A8) ;; DIAERESIS + (?\,F)(B . ?\x00A9) ;; COPYRIGHT SIGN + (?\,F+(B . ?\x00AB) ;; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,F,(B . ?\x00AC) ;; NOT SIGN + (?\,F-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,F/(B . ?\x2015) ;; HORIZONTAL BAR + (?\,F0(B . ?\x00B0) ;; DEGREE SIGN + (?\,F1(B . ?\x00B1) ;; PLUS-MINUS SIGN + (?\,F2(B . ?\x00B2) ;; SUPERSCRIPT TWO + (?\,F3(B . ?\x00B3) ;; SUPERSCRIPT THREE + (?\,F4(B . ?\x0384) ;; GREEK TONOS + (?\,F5(B . ?\x0385) ;; GREEK DIALYTIKA TONOS + (?\,F6(B . ?\x0386) ;; GREEK CAPITAL LETTER ALPHA WITH TONOS + (?\,F7(B . ?\x00B7) ;; MIDDLE DOT + (?\,F8(B . ?\x0388) ;; GREEK CAPITAL LETTER EPSILON WITH TONOS + (?\,F9(B . ?\x0389) ;; GREEK CAPITAL LETTER ETA WITH TONOS + (?\,F:(B . ?\x038A) ;; GREEK CAPITAL LETTER IOTA WITH TONOS + (?\,F;(B . ?\x00BB) ;; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,F<(B . ?\x038C) ;; GREEK CAPITAL LETTER OMICRON WITH TONOS + (?\,F=(B . ?\x00BD) ;; VULGAR FRACTION ONE HALF + (?\,F>(B . ?\x038E) ;; GREEK CAPITAL LETTER UPSILON WITH TONOS + (?\,F?(B . ?\x038F) ;; GREEK CAPITAL LETTER OMEGA WITH TONOS + (?\,F@(B . ?\x0390) ;; GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + (?\,FA(B . ?\x0391) ;; GREEK CAPITAL LETTER ALPHA + (?\,FB(B . ?\x0392) ;; GREEK CAPITAL LETTER BETA + (?\,FC(B . ?\x0393) ;; GREEK CAPITAL LETTER GAMMA + (?\,FD(B . ?\x0394) ;; GREEK CAPITAL LETTER DELTA + (?\,FE(B . ?\x0395) ;; GREEK CAPITAL LETTER EPSILON + (?\,FF(B . ?\x0396) ;; GREEK CAPITAL LETTER ZETA + (?\,FG(B . ?\x0397) ;; GREEK CAPITAL LETTER ETA + (?\,FH(B . ?\x0398) ;; GREEK CAPITAL LETTER THETA + (?\,FI(B . ?\x0399) ;; GREEK CAPITAL LETTER IOTA + (?\,FJ(B . ?\x039A) ;; GREEK CAPITAL LETTER KAPPA + (?\,FK(B . ?\x039B) ;; GREEK CAPITAL LETTER LAMDA + (?\,FL(B . ?\x039C) ;; GREEK CAPITAL LETTER MU + (?\,FM(B . ?\x039D) ;; GREEK CAPITAL LETTER NU + (?\,FN(B . ?\x039E) ;; GREEK CAPITAL LETTER XI + (?\,FO(B . ?\x039F) ;; GREEK CAPITAL LETTER OMICRON + (?\,FP(B . ?\x03A0) ;; GREEK CAPITAL LETTER PI + (?\,FQ(B . ?\x03A1) ;; GREEK CAPITAL LETTER RHO + (?\,FS(B . ?\x03A3) ;; GREEK CAPITAL LETTER SIGMA + (?\,FT(B . ?\x03A4) ;; GREEK CAPITAL LETTER TAU + (?\,FU(B . ?\x03A5) ;; GREEK CAPITAL LETTER UPSILON + (?\,FV(B . ?\x03A6) ;; GREEK CAPITAL LETTER PHI + (?\,FW(B . ?\x03A7) ;; GREEK CAPITAL LETTER CHI + (?\,FX(B . ?\x03A8) ;; GREEK CAPITAL LETTER PSI + (?\,FY(B . ?\x03A9) ;; GREEK CAPITAL LETTER OMEGA + (?\,FZ(B . ?\x03AA) ;; GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + (?\,F[(B . ?\x03AB) ;; GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + (?\,F\(B . ?\x03AC) ;; GREEK SMALL LETTER ALPHA WITH TONOS + (?\,F](B . ?\x03AD) ;; GREEK SMALL LETTER EPSILON WITH TONOS + (?\,F^(B . ?\x03AE) ;; GREEK SMALL LETTER ETA WITH TONOS + (?\,F_(B . ?\x03AF) ;; GREEK SMALL LETTER IOTA WITH TONOS + (?\,F`(B . ?\x03B0) ;; GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + (?\,Fa(B . ?\x03B1) ;; GREEK SMALL LETTER ALPHA + (?\,Fb(B . ?\x03B2) ;; GREEK SMALL LETTER BETA + (?\,Fc(B . ?\x03B3) ;; GREEK SMALL LETTER GAMMA + (?\,Fd(B . ?\x03B4) ;; GREEK SMALL LETTER DELTA + (?\,Fe(B . ?\x03B5) ;; GREEK SMALL LETTER EPSILON + (?\,Ff(B . ?\x03B6) ;; GREEK SMALL LETTER ZETA + (?\,Fg(B . ?\x03B7) ;; GREEK SMALL LETTER ETA + (?\,Fh(B . ?\x03B8) ;; GREEK SMALL LETTER THETA + (?\,Fi(B . ?\x03B9) ;; GREEK SMALL LETTER IOTA + (?\,Fj(B . ?\x03BA) ;; GREEK SMALL LETTER KAPPA + (?\,Fk(B . ?\x03BB) ;; GREEK SMALL LETTER LAMDA + (?\,Fl(B . ?\x03BC) ;; GREEK SMALL LETTER MU + (?\,Fm(B . ?\x03BD) ;; GREEK SMALL LETTER NU + (?\,Fn(B . ?\x03BE) ;; GREEK SMALL LETTER XI + (?\,Fo(B . ?\x03BF) ;; GREEK SMALL LETTER OMICRON + (?\,Fp(B . ?\x03C0) ;; GREEK SMALL LETTER PI + (?\,Fq(B . ?\x03C1) ;; GREEK SMALL LETTER RHO + (?\,Fr(B . ?\x03C2) ;; GREEK SMALL LETTER FINAL SIGMA + (?\,Fs(B . ?\x03C3) ;; GREEK SMALL LETTER SIGMA + (?\,Ft(B . ?\x03C4) ;; GREEK SMALL LETTER TAU + (?\,Fu(B . ?\x03C5) ;; GREEK SMALL LETTER UPSILON + (?\,Fv(B . ?\x03C6) ;; GREEK SMALL LETTER PHI + (?\,Fw(B . ?\x03C7) ;; GREEK SMALL LETTER CHI + (?\,Fx(B . ?\x03C8) ;; GREEK SMALL LETTER PSI + (?\,Fy(B . ?\x03C9) ;; GREEK SMALL LETTER OMEGA + (?\,Fz(B . ?\x03CA) ;; GREEK SMALL LETTER IOTA WITH DIALYTIKA + (?\,F{(B . ?\x03CB) ;; GREEK SMALL LETTER UPSILON WITH DIALYTIKA + (?\,F|(B . ?\x03CC) ;; GREEK SMALL LETTER OMICRON WITH TONOS + (?\,F}(B . ?\x03CD) ;; GREEK SMALL LETTER UPSILON WITH TONOS + (?\,F~(B . ?\x03CE) ;; GREEK SMALL LETTER OMEGA WITH TONOS + )) + + (ucs-8859-8-alist + '((?\,H (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,H"(B . ?\x00A2) ;; CENT SIGN + (?\,H#(B . ?\x00A3) ;; POUND SIGN + (?\,H$(B . ?\x00A4) ;; CURRENCY SIGN + (?\,H%(B . ?\x00A5) ;; YEN SIGN + (?\,H&(B . ?\x00A6) ;; BROKEN BAR + (?\,H'(B . ?\x00A7) ;; SECTION SIGN + (?\,H((B . ?\x00A8) ;; DIAERESIS + (?\,H)(B . ?\x00A9) ;; COPYRIGHT SIGN + (?\,H*(B . ?\x00D7) ;; MULTIPLICATION SIGN + (?\,H+(B . ?\x00AB) ;; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,H,(B . ?\x00AC) ;; NOT SIGN + (?\,H-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,H.(B . ?\x00AE) ;; REGISTERED SIGN + (?\,H/(B . ?\x00AF) ;; MACRON + (?\,H0(B . ?\x00B0) ;; DEGREE SIGN + (?\,H1(B . ?\x00B1) ;; PLUS-MINUS SIGN + (?\,H2(B . ?\x00B2) ;; SUPERSCRIPT TWO + (?\,H3(B . ?\x00B3) ;; SUPERSCRIPT THREE + (?\,H4(B . ?\x00B4) ;; ACUTE ACCENT + (?\,H5(B . ?\x00B5) ;; MICRO SIGN + (?\,H6(B . ?\x00B6) ;; PILCROW SIGN + (?\,H7(B . ?\x00B7) ;; MIDDLE DOT + (?\,H8(B . ?\x00B8) ;; CEDILLA + (?\,H9(B . ?\x00B9) ;; SUPERSCRIPT ONE + (?\,H:(B . ?\x00F7) ;; DIVISION SIGN + (?\,H;(B . ?\x00BB) ;; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,H<(B . ?\x00BC) ;; VULGAR FRACTION ONE QUARTER + (?\,H=(B . ?\x00BD) ;; VULGAR FRACTION ONE HALF + (?\,H>(B . ?\x00BE) ;; VULGAR FRACTION THREE QUARTERS + ;; These are commented out since the current 8859-8 standard + ;; does not yet define these codepoints, although there are + ;; drafts which do). +; (?\,H@(B . ?\x05B0) ;; HEBREW POINT SHEVA +; (?\,HA(B . ?\x05B1) ;; HEBREW POINT HATAF SEGOL +; (?\,HB(B . ?\x05B2) ;; HEBREW POINT HATAF PATAH +; (?\,HC(B . ?\x05B3) ;; HEBREW POINT HATAF QAMATS +; (?\,HD(B . ?\x05B4) ;; HEBREW POINT HIRIQ +; (?\,HE(B . ?\x05B5) ;; HEBREW POINT TSERE +; (?\,HF(B . ?\x05B6) ;; HEBREW POINT SEGOL +; (?\,HG(B . ?\x05B7) ;; HEBREW POINT PATAH +; (?\,HH(B . ?\x05B8) ;; HEBREW POINT QAMATS +; (?\,HI(B . ?\x05B9) ;; HEBREW POINT HOLAM +; (?\,HK(B . ?\x05BB) ;; HEBREW POINT QUBUTS +; (?\,HL(B . ?\x05BC) ;; HEBREW POINT DAGESH +; (?\,HM(B . ?\x05BD) ;; HEBREW POINT METEG +; (?\,HN(B . ?\x05BE) ;; HEBREW POINT MAQAF +; (?\,HO(B . ?\x05BF) ;; HEBREW POINT RAFE +; (?\,HP(B . ?\x05C0) ;; HEBREW PUNCTUATION PASEQ +; (?\,HQ(B . ?\x05C1) ;; HEBREW POINT SHIN DOT +; (?\,HR(B . ?\x05C2) ;; HEBREW POINT SIN DOT +; (?\,HS(B . ?\x05C3) ;; HEBREW PUNCTUATION SOF PASUQ + (?\,H[(B . ?\x202D) ;; LEFT-TO-RIGHT OVERRIDE + (?\,H\(B . ?\x202E) ;; RIGHT-TO-LEFT OVERRIDE + (?\,H](B . ?\x202C) ;; POP DIRECTIONAL FORMATTING + (?\,H_(B . ?\x2017) ;; DOUBLE LOW LINE + (?\,H`(B . ?\x05D0) ;; HEBREW LETTER ALEF + (?\,Ha(B . ?\x05D1) ;; HEBREW LETTER BET + (?\,Hb(B . ?\x05D2) ;; HEBREW LETTER GIMEL + (?\,Hc(B . ?\x05D3) ;; HEBREW LETTER DALET + (?\,Hd(B . ?\x05D4) ;; HEBREW LETTER HE + (?\,He(B . ?\x05D5) ;; HEBREW LETTER VAV + (?\,Hf(B . ?\x05D6) ;; HEBREW LETTER ZAYIN + (?\,Hg(B . ?\x05D7) ;; HEBREW LETTER HET + (?\,Hh(B . ?\x05D8) ;; HEBREW LETTER TET + (?\,Hi(B . ?\x05D9) ;; HEBREW LETTER YOD + (?\,Hj(B . ?\x05DA) ;; HEBREW LETTER FINAL KAF + (?\,Hk(B . ?\x05DB) ;; HEBREW LETTER KAF + (?\,Hl(B . ?\x05DC) ;; HEBREW LETTER LAMED + (?\,Hm(B . ?\x05DD) ;; HEBREW LETTER FINAL MEM + (?\,Hn(B . ?\x05DE) ;; HEBREW LETTER MEM + (?\,Ho(B . ?\x05DF) ;; HEBREW LETTER FINAL NUN + (?\,Hp(B . ?\x05E0) ;; HEBREW LETTER NUN + (?\,Hq(B . ?\x05E1) ;; HEBREW LETTER SAMEKH + (?\,Hr(B . ?\x05E2) ;; HEBREW LETTER AYIN + (?\,Hs(B . ?\x05E3) ;; HEBREW LETTER FINAL PE + (?\,Ht(B . ?\x05E4) ;; HEBREW LETTER PE + (?\,Hu(B . ?\x05E5) ;; HEBREW LETTER FINAL TSADI + (?\,Hv(B . ?\x05E6) ;; HEBREW LETTER TSADI + (?\,Hw(B . ?\x05E7) ;; HEBREW LETTER QOF + (?\,Hx(B . ?\x05E8) ;; HEBREW LETTER RESH + (?\,Hy(B . ?\x05E9) ;; HEBREW LETTER SHIN + (?\,Hz(B . ?\x05EA) ;; HEBREW LETTER TAV + (?\,H{(B . ?\x202A) ;; LEFT-TO-RIGHT EMBEDDING + (?\,H|(B . ?\x202B) ;; RIGHT-TO-LEFT EMBEDDING + (?\,H}(B . ?\x200E) ;; LEFT-TO-RIGHT MARK + (?\,H~(B . ?\x200F) ;; RIGHT-TO-LEFT MARK + )) + + (ucs-8859-9-alist + '((?\,M (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,M!(B . ?\x00A1) ;; INVERTED EXCLAMATION MARK + (?\,M"(B . ?\x00A2) ;; CENT SIGN + (?\,M#(B . ?\x00A3) ;; POUND SIGN + (?\,M$(B . ?\x00A4) ;; CURRENCY SIGN + (?\,M%(B . ?\x00A5) ;; YEN SIGN + (?\,M&(B . ?\x00A6) ;; BROKEN BAR + (?\,M'(B . ?\x00A7) ;; SECTION SIGN + (?\,M((B . ?\x00A8) ;; DIAERESIS + (?\,M)(B . ?\x00A9) ;; COPYRIGHT SIGN + (?\,M*(B . ?\x00AA) ;; FEMININE ORDINAL INDICATOR + (?\,M+(B . ?\x00AB) ;; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,M,(B . ?\x00AC) ;; NOT SIGN + (?\,M-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,M.(B . ?\x00AE) ;; REGISTERED SIGN + (?\,M/(B . ?\x00AF) ;; MACRON + (?\,M0(B . ?\x00B0) ;; DEGREE SIGN + (?\,M1(B . ?\x00B1) ;; PLUS-MINUS SIGN + (?\,M2(B . ?\x00B2) ;; SUPERSCRIPT TWO + (?\,M3(B . ?\x00B3) ;; SUPERSCRIPT THREE + (?\,M4(B . ?\x00B4) ;; ACUTE ACCENT + (?\,M5(B . ?\x00B5) ;; MICRO SIGN + (?\,M6(B . ?\x00B6) ;; PILCROW SIGN + (?\,M7(B . ?\x00B7) ;; MIDDLE DOT + (?\,M8(B . ?\x00B8) ;; CEDILLA + (?\,M9(B . ?\x00B9) ;; SUPERSCRIPT ONE + (?\,M:(B . ?\x00BA) ;; MASCULINE ORDINAL INDICATOR + (?\,M;(B . ?\x00BB) ;; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,M<(B . ?\x00BC) ;; VULGAR FRACTION ONE QUARTER + (?\,M=(B . ?\x00BD) ;; VULGAR FRACTION ONE HALF + (?\,M>(B . ?\x00BE) ;; VULGAR FRACTION THREE QUARTERS + (?\,M?(B . ?\x00BF) ;; INVERTED QUESTION MARK + (?\,M@(B . ?\x00C0) ;; LATIN CAPITAL LETTER A WITH GRAVE + (?\,MA(B . ?\x00C1) ;; LATIN CAPITAL LETTER A WITH ACUTE + (?\,MB(B . ?\x00C2) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (?\,MC(B . ?\x00C3) ;; LATIN CAPITAL LETTER A WITH TILDE + (?\,MD(B . ?\x00C4) ;; LATIN CAPITAL LETTER A WITH DIAERESIS + (?\,ME(B . ?\x00C5) ;; LATIN CAPITAL LETTER A WITH RING ABOVE + (?\,MF(B . ?\x00C6) ;; LATIN CAPITAL LETTER AE + (?\,MG(B . ?\x00C7) ;; LATIN CAPITAL LETTER C WITH CEDILLA + (?\,MH(B . ?\x00C8) ;; LATIN CAPITAL LETTER E WITH GRAVE + (?\,MI(B . ?\x00C9) ;; LATIN CAPITAL LETTER E WITH ACUTE + (?\,MJ(B . ?\x00CA) ;; LATIN CAPITAL LETTER E WITH CIRCUMFLEX + (?\,MK(B . ?\x00CB) ;; LATIN CAPITAL LETTER E WITH DIAERESIS + (?\,ML(B . ?\x00CC) ;; LATIN CAPITAL LETTER I WITH GRAVE + (?\,MM(B . ?\x00CD) ;; LATIN CAPITAL LETTER I WITH ACUTE + (?\,MN(B . ?\x00CE) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (?\,MO(B . ?\x00CF) ;; LATIN CAPITAL LETTER I WITH DIAERESIS + (?\,MP(B . ?\x011E) ;; LATIN CAPITAL LETTER G WITH BREVE + (?\,MQ(B . ?\x00D1) ;; LATIN CAPITAL LETTER N WITH TILDE + (?\,MR(B . ?\x00D2) ;; LATIN CAPITAL LETTER O WITH GRAVE + (?\,MS(B . ?\x00D3) ;; LATIN CAPITAL LETTER O WITH ACUTE + (?\,MT(B . ?\x00D4) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (?\,MU(B . ?\x00D5) ;; LATIN CAPITAL LETTER O WITH TILDE + (?\,MV(B . ?\x00D6) ;; LATIN CAPITAL LETTER O WITH DIAERESIS + (?\,MW(B . ?\x00D7) ;; MULTIPLICATION SIGN + (?\,MX(B . ?\x00D8) ;; LATIN CAPITAL LETTER O WITH STROKE + (?\,MY(B . ?\x00D9) ;; LATIN CAPITAL LETTER U WITH GRAVE + (?\,MZ(B . ?\x00DA) ;; LATIN CAPITAL LETTER U WITH ACUTE + (?\,M[(B . ?\x00DB) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX + (?\,M\(B . ?\x00DC) ;; LATIN CAPITAL LETTER U WITH DIAERESIS + (?\,M](B . ?\x0130) ;; LATIN CAPITAL LETTER I WITH DOT ABOVE + (?\,M^(B . ?\x015E) ;; LATIN CAPITAL LETTER S WITH CEDILLA + (?\,M_(B . ?\x00DF) ;; LATIN SMALL LETTER SHARP S + (?\,M`(B . ?\x00E0) ;; LATIN SMALL LETTER A WITH GRAVE + (?\,Ma(B . ?\x00E1) ;; LATIN SMALL LETTER A WITH ACUTE + (?\,Mb(B . ?\x00E2) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX + (?\,Mc(B . ?\x00E3) ;; LATIN SMALL LETTER A WITH TILDE + (?\,Md(B . ?\x00E4) ;; LATIN SMALL LETTER A WITH DIAERESIS + (?\,Me(B . ?\x00E5) ;; LATIN SMALL LETTER A WITH RING ABOVE + (?\,Mf(B . ?\x00E6) ;; LATIN SMALL LETTER AE + (?\,Mg(B . ?\x00E7) ;; LATIN SMALL LETTER C WITH CEDILLA + (?\,Mh(B . ?\x00E8) ;; LATIN SMALL LETTER E WITH GRAVE + (?\,Mi(B . ?\x00E9) ;; LATIN SMALL LETTER E WITH ACUTE + (?\,Mj(B . ?\x00EA) ;; LATIN SMALL LETTER E WITH CIRCUMFLEX + (?\,Mk(B . ?\x00EB) ;; LATIN SMALL LETTER E WITH DIAERESIS + (?\,Ml(B . ?\x00EC) ;; LATIN SMALL LETTER I WITH GRAVE + (?\,Mm(B . ?\x00ED) ;; LATIN SMALL LETTER I WITH ACUTE + (?\,Mn(B . ?\x00EE) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX + (?\,Mo(B . ?\x00EF) ;; LATIN SMALL LETTER I WITH DIAERESIS + (?\,Mp(B . ?\x011F) ;; LATIN SMALL LETTER G WITH BREVE + (?\,Mq(B . ?\x00F1) ;; LATIN SMALL LETTER N WITH TILDE + (?\,Mr(B . ?\x00F2) ;; LATIN SMALL LETTER O WITH GRAVE + (?\,Ms(B . ?\x00F3) ;; LATIN SMALL LETTER O WITH ACUTE + (?\,Mt(B . ?\x00F4) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX + (?\,Mu(B . ?\x00F5) ;; LATIN SMALL LETTER O WITH TILDE + (?\,Mv(B . ?\x00F6) ;; LATIN SMALL LETTER O WITH DIAERESIS + (?\,Mw(B . ?\x00F7) ;; DIVISION SIGN + (?\,Mx(B . ?\x00F8) ;; LATIN SMALL LETTER O WITH STROKE + (?\,My(B . ?\x00F9) ;; LATIN SMALL LETTER U WITH GRAVE + (?\,Mz(B . ?\x00FA) ;; LATIN SMALL LETTER U WITH ACUTE + (?\,M{(B . ?\x00FB) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX + (?\,M|(B . ?\x00FC) ;; LATIN SMALL LETTER U WITH DIAERESIS + (?\,M}(B . ?\x0131) ;; LATIN SMALL LETTER DOTLESS I + (?\,M~(B . ?\x015F) ;; LATIN SMALL LETTER S WITH CEDILLA + (?\,M(B . ?\x00FF) ;; LATIN SMALL LETTER Y WITH DIAERESIS + )) + + (ucs-8859-14-alist + '((?\,_ (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,_!(B . ?\x1E02) ;; LATIN CAPITAL LETTER B WITH DOT ABOVE + (?\,_"(B . ?\x1E03) ;; LATIN SMALL LETTER B WITH DOT ABOVE + (?\,_#(B . ?\x00A3) ;; POUND SIGN + (?\,_$(B . ?\x010A) ;; LATIN CAPITAL LETTER C WITH DOT ABOVE + (?\,_%(B . ?\x010B) ;; LATIN SMALL LETTER C WITH DOT ABOVE + (?\,_&(B . ?\x1E0A) ;; LATIN CAPITAL LETTER D WITH DOT ABOVE + (?\,_'(B . ?\x00A7) ;; SECTION SIGN + (?\,_((B . ?\x1E80) ;; LATIN CAPITAL LETTER W WITH GRAVE + (?\,_)(B . ?\x00A9) ;; COPYRIGHT SIGN + (?\,_*(B . ?\x1E82) ;; LATIN CAPITAL LETTER W WITH ACUTE + (?\,_+(B . ?\x1E0B) ;; LATIN SMALL LETTER D WITH DOT ABOVE + (?\,_,(B . ?\x1EF2) ;; LATIN CAPITAL LETTER Y WITH GRAVE + (?\,_-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,_.(B . ?\x00AE) ;; REGISTERED SIGN + (?\,_/(B . ?\x0178) ;; LATIN CAPITAL LETTER Y WITH DIAERESIS + (?\,_0(B . ?\x1E1E) ;; LATIN CAPITAL LETTER F WITH DOT ABOVE + (?\,_1(B . ?\x1E1F) ;; LATIN SMALL LETTER F WITH DOT ABOVE + (?\,_2(B . ?\x0120) ;; LATIN CAPITAL LETTER G WITH DOT ABOVE + (?\,_3(B . ?\x0121) ;; LATIN SMALL LETTER G WITH DOT ABOVE + (?\,_4(B . ?\x1E40) ;; LATIN CAPITAL LETTER M WITH DOT ABOVE + (?\,_5(B . ?\x1E41) ;; LATIN SMALL LETTER M WITH DOT ABOVE + (?\,_6(B . ?\x00B6) ;; PILCROW SIGN + (?\,_7(B . ?\x1E56) ;; LATIN CAPITAL LETTER P WITH DOT ABOVE + (?\,_8(B . ?\x1E81) ;; LATIN SMALL LETTER W WITH GRAVE + (?\,_9(B . ?\x1E57) ;; LATIN SMALL LETTER P WITH DOT ABOVE + (?\,_:(B . ?\x1E83) ;; LATIN SMALL LETTER W WITH ACUTE + (?\,_;(B . ?\x1E60) ;; LATIN CAPITAL LETTER S WITH DOT ABOVE + (?\,_<(B . ?\x1EF3) ;; LATIN SMALL LETTER Y WITH GRAVE + (?\,_=(B . ?\x1E84) ;; LATIN CAPITAL LETTER W WITH DIAERESIS + (?\,_>(B . ?\x1E85) ;; LATIN SMALL LETTER W WITH DIAERESIS + (?\,_?(B . ?\x1E61) ;; LATIN SMALL LETTER S WITH DOT ABOVE + (?\,_@(B . ?\x00C0) ;; LATIN CAPITAL LETTER A WITH GRAVE + (?\,_A(B . ?\x00C1) ;; LATIN CAPITAL LETTER A WITH ACUTE + (?\,_B(B . ?\x00C2) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (?\,_C(B . ?\x00C3) ;; LATIN CAPITAL LETTER A WITH TILDE + (?\,_D(B . ?\x00C4) ;; LATIN CAPITAL LETTER A WITH DIAERESIS + (?\,_E(B . ?\x00C5) ;; LATIN CAPITAL LETTER A WITH RING ABOVE + (?\,_F(B . ?\x00C6) ;; LATIN CAPITAL LETTER AE + (?\,_G(B . ?\x00C7) ;; LATIN CAPITAL LETTER C WITH CEDILLA + (?\,_H(B . ?\x00C8) ;; LATIN CAPITAL LETTER E WITH GRAVE + (?\,_I(B . ?\x00C9) ;; LATIN CAPITAL LETTER E WITH ACUTE + (?\,_J(B . ?\x00CA) ;; LATIN CAPITAL LETTER E WITH CIRCUMFLEX + (?\,_K(B . ?\x00CB) ;; LATIN CAPITAL LETTER E WITH DIAERESIS + (?\,_L(B . ?\x00CC) ;; LATIN CAPITAL LETTER I WITH GRAVE + (?\,_M(B . ?\x00CD) ;; LATIN CAPITAL LETTER I WITH ACUTE + (?\,_N(B . ?\x00CE) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (?\,_O(B . ?\x00CF) ;; LATIN CAPITAL LETTER I WITH DIAERESIS + (?\,_P(B . ?\x0174) ;; LATIN CAPITAL LETTER W WITH CIRCUMFLEX + (?\,_Q(B . ?\x00D1) ;; LATIN CAPITAL LETTER N WITH TILDE + (?\,_R(B . ?\x00D2) ;; LATIN CAPITAL LETTER O WITH GRAVE + (?\,_S(B . ?\x00D3) ;; LATIN CAPITAL LETTER O WITH ACUTE + (?\,_T(B . ?\x00D4) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (?\,_U(B . ?\x00D5) ;; LATIN CAPITAL LETTER O WITH TILDE + (?\,_V(B . ?\x00D6) ;; LATIN CAPITAL LETTER O WITH DIAERESIS + (?\,_W(B . ?\x1E6A) ;; LATIN CAPITAL LETTER T WITH DOT ABOVE + (?\,_X(B . ?\x00D8) ;; LATIN CAPITAL LETTER O WITH STROKE + (?\,_Y(B . ?\x00D9) ;; LATIN CAPITAL LETTER U WITH GRAVE + (?\,_Z(B . ?\x00DA) ;; LATIN CAPITAL LETTER U WITH ACUTE + (?\,_[(B . ?\x00DB) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX + (?\,_\(B . ?\x00DC) ;; LATIN CAPITAL LETTER U WITH DIAERESIS + (?\,_](B . ?\x00DD) ;; LATIN CAPITAL LETTER Y WITH ACUTE + (?\,_^(B . ?\x0176) ;; LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + (?\,__(B . ?\x00DF) ;; LATIN SMALL LETTER SHARP S + (?\,_`(B . ?\x00E0) ;; LATIN SMALL LETTER A WITH GRAVE + (?\,_a(B . ?\x00E1) ;; LATIN SMALL LETTER A WITH ACUTE + (?\,_b(B . ?\x00E2) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX + (?\,_c(B . ?\x00E3) ;; LATIN SMALL LETTER A WITH TILDE + (?\,_d(B . ?\x00E4) ;; LATIN SMALL LETTER A WITH DIAERESIS + (?\,_e(B . ?\x00E5) ;; LATIN SMALL LETTER A WITH RING ABOVE + (?\,_f(B . ?\x00E6) ;; LATIN SMALL LETTER AE + (?\,_g(B . ?\x00E7) ;; LATIN SMALL LETTER C WITH CEDILLA + (?\,_h(B . ?\x00E8) ;; LATIN SMALL LETTER E WITH GRAVE + (?\,_i(B . ?\x00E9) ;; LATIN SMALL LETTER E WITH ACUTE + (?\,_j(B . ?\x00EA) ;; LATIN SMALL LETTER E WITH CIRCUMFLEX + (?\,_k(B . ?\x00EB) ;; LATIN SMALL LETTER E WITH DIAERESIS + (?\,_l(B . ?\x00EC) ;; LATIN SMALL LETTER I WITH GRAVE + (?\,_m(B . ?\x00ED) ;; LATIN SMALL LETTER I WITH ACUTE + (?\,_n(B . ?\x00EE) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX + (?\,_o(B . ?\x00EF) ;; LATIN SMALL LETTER I WITH DIAERESIS + (?\,_p(B . ?\x0175) ;; LATIN SMALL LETTER W WITH CIRCUMFLEX + (?\,_q(B . ?\x00F1) ;; LATIN SMALL LETTER N WITH TILDE + (?\,_r(B . ?\x00F2) ;; LATIN SMALL LETTER O WITH GRAVE + (?\,_s(B . ?\x00F3) ;; LATIN SMALL LETTER O WITH ACUTE + (?\,_t(B . ?\x00F4) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX + (?\,_u(B . ?\x00F5) ;; LATIN SMALL LETTER O WITH TILDE + (?\,_v(B . ?\x00F6) ;; LATIN SMALL LETTER O WITH DIAERESIS + (?\,_w(B . ?\x1E6B) ;; LATIN SMALL LETTER T WITH DOT ABOVE + (?\,_x(B . ?\x00F8) ;; LATIN SMALL LETTER O WITH STROKE + (?\,_y(B . ?\x00F9) ;; LATIN SMALL LETTER U WITH GRAVE + (?\,_z(B . ?\x00FA) ;; LATIN SMALL LETTER U WITH ACUTE + (?\,_{(B . ?\x00FB) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX + (?\,_|(B . ?\x00FC) ;; LATIN SMALL LETTER U WITH DIAERESIS + (?\,_}(B . ?\x00FD) ;; LATIN SMALL LETTER Y WITH ACUTE + (?\,_~(B . ?\x0177) ;; LATIN SMALL LETTER Y WITH CIRCUMFLEX + (?\,_(B . ?\x00FF) ;; LATIN SMALL LETTER Y WITH DIAERESIS + )) + + (ucs-8859-15-alist + '((?\,b (B . ?\x00A0) ;; NO-BREAK SPACE + (?\,b!(B . ?\x00A1) ;; INVERTED EXCLAMATION MARK + (?\,b"(B . ?\x00A2) ;; CENT SIGN + (?\,b#(B . ?\x00A3) ;; POUND SIGN + (?\,b$(B . ?\x20AC) ;; EURO SIGN + (?\,b%(B . ?\x00A5) ;; YEN SIGN + (?\,b&(B . ?\x0160) ;; LATIN CAPITAL LETTER S WITH CARON + (?\,b'(B . ?\x00A7) ;; SECTION SIGN + (?\,b((B . ?\x0161) ;; LATIN SMALL LETTER S WITH CARON + (?\,b)(B . ?\x00A9) ;; COPYRIGHT SIGN + (?\,b*(B . ?\x00AA) ;; FEMININE ORDINAL INDICATOR + (?\,b+(B . ?\x00AB) ;; LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,b,(B . ?\x00AC) ;; NOT SIGN + (?\,b-(B . ?\x00AD) ;; SOFT HYPHEN + (?\,b.(B . ?\x00AE) ;; REGISTERED SIGN + (?\,b/(B . ?\x00AF) ;; MACRON + (?\,b0(B . ?\x00B0) ;; DEGREE SIGN + (?\,b1(B . ?\x00B1) ;; PLUS-MINUS SIGN + (?\,b2(B . ?\x00B2) ;; SUPERSCRIPT TWO + (?\,b3(B . ?\x00B3) ;; SUPERSCRIPT THREE + (?\,b4(B . ?\x017D) ;; LATIN CAPITAL LETTER Z WITH CARON + (?\,b5(B . ?\x00B5) ;; MICRO SIGN + (?\,b6(B . ?\x00B6) ;; PILCROW SIGN + (?\,b7(B . ?\x00B7) ;; MIDDLE DOT + (?\,b8(B . ?\x017E) ;; LATIN SMALL LETTER Z WITH CARON + (?\,b9(B . ?\x00B9) ;; SUPERSCRIPT ONE + (?\,b:(B . ?\x00BA) ;; MASCULINE ORDINAL INDICATOR + (?\,b;(B . ?\x00BB) ;; RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + (?\,b<(B . ?\x0152) ;; LATIN CAPITAL LIGATURE OE + (?\,b=(B . ?\x0153) ;; LATIN SMALL LIGATURE OE + (?\,b>(B . ?\x0178) ;; LATIN CAPITAL LETTER Y WITH DIAERESIS + (?\,b?(B . ?\x00BF) ;; INVERTED QUESTION MARK + (?\,b@(B . ?\x00C0) ;; LATIN CAPITAL LETTER A WITH GRAVE + (?\,bA(B . ?\x00C1) ;; LATIN CAPITAL LETTER A WITH ACUTE + (?\,bB(B . ?\x00C2) ;; LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (?\,bC(B . ?\x00C3) ;; LATIN CAPITAL LETTER A WITH TILDE + (?\,bD(B . ?\x00C4) ;; LATIN CAPITAL LETTER A WITH DIAERESIS + (?\,bE(B . ?\x00C5) ;; LATIN CAPITAL LETTER A WITH RING ABOVE + (?\,bF(B . ?\x00C6) ;; LATIN CAPITAL LETTER AE + (?\,bG(B . ?\x00C7) ;; LATIN CAPITAL LETTER C WITH CEDILLA + (?\,bH(B . ?\x00C8) ;; LATIN CAPITAL LETTER E WITH GRAVE + (?\,bI(B . ?\x00C9) ;; LATIN CAPITAL LETTER E WITH ACUTE + (?\,bJ(B . ?\x00CA) ;; LATIN CAPITAL LETTER E WITH CIRCUMFLEX + (?\,bK(B . ?\x00CB) ;; LATIN CAPITAL LETTER E WITH DIAERESIS + (?\,bL(B . ?\x00CC) ;; LATIN CAPITAL LETTER I WITH GRAVE + (?\,bM(B . ?\x00CD) ;; LATIN CAPITAL LETTER I WITH ACUTE + (?\,bN(B . ?\x00CE) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (?\,bO(B . ?\x00CF) ;; LATIN CAPITAL LETTER I WITH DIAERESIS + (?\,bP(B . ?\x00D0) ;; LATIN CAPITAL LETTER ETH + (?\,bQ(B . ?\x00D1) ;; LATIN CAPITAL LETTER N WITH TILDE + (?\,bR(B . ?\x00D2) ;; LATIN CAPITAL LETTER O WITH GRAVE + (?\,bS(B . ?\x00D3) ;; LATIN CAPITAL LETTER O WITH ACUTE + (?\,bT(B . ?\x00D4) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (?\,bU(B . ?\x00D5) ;; LATIN CAPITAL LETTER O WITH TILDE + (?\,bV(B . ?\x00D6) ;; LATIN CAPITAL LETTER O WITH DIAERESIS + (?\,bW(B . ?\x00D7) ;; MULTIPLICATION SIGN + (?\,bX(B . ?\x00D8) ;; LATIN CAPITAL LETTER O WITH STROKE + (?\,bY(B . ?\x00D9) ;; LATIN CAPITAL LETTER U WITH GRAVE + (?\,bZ(B . ?\x00DA) ;; LATIN CAPITAL LETTER U WITH ACUTE + (?\,b[(B . ?\x00DB) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX + (?\,b\(B . ?\x00DC) ;; LATIN CAPITAL LETTER U WITH DIAERESIS + (?\,b](B . ?\x00DD) ;; LATIN CAPITAL LETTER Y WITH ACUTE + (?\,b^(B . ?\x00DE) ;; LATIN CAPITAL LETTER THORN + (?\,b_(B . ?\x00DF) ;; LATIN SMALL LETTER SHARP S + (?\,b`(B . ?\x00E0) ;; LATIN SMALL LETTER A WITH GRAVE + (?\,ba(B . ?\x00E1) ;; LATIN SMALL LETTER A WITH ACUTE + (?\,bb(B . ?\x00E2) ;; LATIN SMALL LETTER A WITH CIRCUMFLEX + (?\,bc(B . ?\x00E3) ;; LATIN SMALL LETTER A WITH TILDE + (?\,bd(B . ?\x00E4) ;; LATIN SMALL LETTER A WITH DIAERESIS + (?\,be(B . ?\x00E5) ;; LATIN SMALL LETTER A WITH RING ABOVE + (?\,bf(B . ?\x00E6) ;; LATIN SMALL LETTER AE + (?\,bg(B . ?\x00E7) ;; LATIN SMALL LETTER C WITH CEDILLA + (?\,bh(B . ?\x00E8) ;; LATIN SMALL LETTER E WITH GRAVE + (?\,bi(B . ?\x00E9) ;; LATIN SMALL LETTER E WITH ACUTE + (?\,bj(B . ?\x00EA) ;; LATIN SMALL LETTER E WITH CIRCUMFLEX + (?\,bk(B . ?\x00EB) ;; LATIN SMALL LETTER E WITH DIAERESIS + (?\,bl(B . ?\x00EC) ;; LATIN SMALL LETTER I WITH GRAVE + (?\,bm(B . ?\x00ED) ;; LATIN SMALL LETTER I WITH ACUTE + (?\,bn(B . ?\x00EE) ;; LATIN SMALL LETTER I WITH CIRCUMFLEX + (?\,bo(B . ?\x00EF) ;; LATIN SMALL LETTER I WITH DIAERESIS + (?\,bp(B . ?\x00F0) ;; LATIN SMALL LETTER ETH + (?\,bq(B . ?\x00F1) ;; LATIN SMALL LETTER N WITH TILDE + (?\,br(B . ?\x00F2) ;; LATIN SMALL LETTER O WITH GRAVE + (?\,bs(B . ?\x00F3) ;; LATIN SMALL LETTER O WITH ACUTE + (?\,bt(B . ?\x00F4) ;; LATIN SMALL LETTER O WITH CIRCUMFLEX + (?\,bu(B . ?\x00F5) ;; LATIN SMALL LETTER O WITH TILDE + (?\,bv(B . ?\x00F6) ;; LATIN SMALL LETTER O WITH DIAERESIS + (?\,bw(B . ?\x00F7) ;; DIVISION SIGN + (?\,bx(B . ?\x00F8) ;; LATIN SMALL LETTER O WITH STROKE + (?\,by(B . ?\x00F9) ;; LATIN SMALL LETTER U WITH GRAVE + (?\,bz(B . ?\x00FA) ;; LATIN SMALL LETTER U WITH ACUTE + (?\,b{(B . ?\x00FB) ;; LATIN SMALL LETTER U WITH CIRCUMFLEX + (?\,b|(B . ?\x00FC) ;; LATIN SMALL LETTER U WITH DIAERESIS + (?\,b}(B . ?\x00FD) ;; LATIN SMALL LETTER Y WITH ACUTE + (?\,b~(B . ?\x00FE) ;; LATIN SMALL LETTER THORN + (?\,b(B . ?\x00FF) ;; LATIN SMALL LETTER Y WITH DIAERESIS + )) + + (ucs-8859-1-alist + (let ((i 160) + l) + (while (< i 256) + (push (cons (make-char 'latin-iso8859-1 (- i 128)) i) + l) + (setq i (1+ i))) + (nreverse l))) + +;; (case-table (standard-case-table)) +;; (syntax-table (standard-syntax-table)) + ) + + ;; Convert the lists to the basic char tables. + (dolist (n (list 15 14 9 8 7 5 4 3 2 1)) + (let ((alist (symbol-value (intern (format "ucs-8859-%d-alist" n))))) + (dolist (pair alist) + (let ((mule (car pair)) + (uc (cdr pair)) + (mu (decode-char 'ucs (cdr pair)))) + (aset ucs-mule-8859-to-ucs-table mule uc) + ;; (aset ucs-ucs-to-mule-8859-table uc mule) + ;; (aset ucs-mule-unicode-to-mule-8859 mu mule) + (aset ucs-mule-8859-to-mule-unicode mule mu) + (aset ucs-mule-to-mule-unicode mule mu))) +;; I think this is actually done OK in characters.el. +;; Probably things like accents shouldn't have word syntax, but the +;; Latin-N syntax tables currently aren't consistent for such +;; characters anyhow. +;; ;; Make the mule-unicode characters inherit syntax and case info +;; ;; if they don't already have it. +;; (dolist (pair alist) +;; (let ((mule (car pair)) +;; (uc (cdr pair)) +;; (mu (decode-char 'ucs (cdr pair)))) +;; (let ((syntax (aref syntax-table mule))) +;; (if (eq mule (downcase mule)) +;; (if (eq mule (upcase mule)) ; non-letter or uncased letter +;; (progn +;; (if (= 4 (car syntax)) ; left delim +;; (progn +;; (aset syntax-table +;; mu +;; (cons 4 (aref ucs-mule-8859-to-mule-unicode +;; (cdr syntax)))) +;; (aset syntax-table +;; (aref ucs-mule-8859-to-mule-unicode +;; (cdr syntax)) +;; (cons 5 mu))) +;; (aset syntax-table mu syntax)) +;; (aset case-table mu mu))) +;; ;; Upper case letter +;; (let ((lower (aref ucs-mule-8859-to-mule-unicode +;; (aref case-table mule)))) +;; (aset case-table mu lower) +;; (aset case-table lower lower) +;; (modify-syntax-entry lower "w " syntax-table) +;; (modify-syntax-entry mu "w " syntax-table)))))) + )) + ;; Derive tables that can be used as per-coding-system + ;; `translation-table-for-encode's. + (dolist (n (list 15 14 9 8 7 5 4 3 2 1)) + (let* ((alist (symbol-value (intern (format "ucs-8859-%d-alist" n)))) + (encode-translator (set (intern (format "ucs-8859-%d-encode-table" + n)) + (make-translation-table))) + elt) + ;; Start with the mule-unicode component. + (dolist (pair alist) + (let ((mule (car pair)) + (mu (decode-char 'ucs (cdr pair)))) + (aset encode-translator mu mule))) + ;; Find characters from other 8859 sets which map to the same + ;; unicode as some character in this set. + (map-char-table (lambda (k v) + (if (and (setq elt (rassq v alist)) + (not (assq k alist))) + (aset encode-translator k (car elt)))) + ucs-mule-8859-to-ucs-table)))) + +;; Register for use in CCL. +(define-translation-table 'ucs-mule-8859-to-mule-unicode + ucs-mule-8859-to-mule-unicode) + +;; Fixme: Make this reversible, which means frobbing +;; `char-coding-system-table' directly to remove what we added -- see +;; codepages.el. Also make it a user option. +(defun ucs-unify-8859 (&optional encode-only) + "Set up translation tables for unifying characters from ISO 8859. + +On decoding, non-ASCII characters are mapped into the `iso-latin-1' +and `mule-unicode-0100-24ff' charsets. On encoding, these are mapped +back appropriate for the coding system. + +With prefix arg, do unification on encoding only, i.e. don't unify +everything on input operations." + (interactive "P") + (unless encode-only + ;; Unify 8859 on decoding. (Non-CCL coding systems only.) + (set-char-table-parent standard-translation-table-for-decode + ucs-mule-8859-to-mule-unicode)) + ;; Adjust the 8859 coding systems to fragment the unified characters + ;; on encoding. + (dolist (n '(1 2 3 4 5 7 8 9 14 15)) + (let* ((coding-system + (coding-system-base (intern (format "iso-8859-%d" n)))) + (table (symbol-value + (intern (format "ucs-8859-%d-encode-table" n)))) + (safe (coding-system-get coding-system 'safe-chars))) + ;; Actually, the coding system's safe-chars are not normally + ;; used after they've been registered, but we might as well + ;; record them. Setting the parent here is a convenience. + (set-char-table-parent safe table) + ;; Update the table of what encodes to what. + (register-char-codings coding-system table) + (coding-system-put coding-system 'translation-table-for-encode table))) + +;;; The following works for the bundled coding systems, but it's +;;; better to use the Unicode-based ones and make it irrelevant. + +;;; ;; Update the Cyrillic special cases. +;;; ;; `translation-table-for-encode' doesn't work for CCL coding +;;; ;; systems, and `standard-translation-table-for-decode' isn't +;;; ;; applied. +;;; (let ((table (get 'cyrillic-koi8-r-encode-table 'translation-table))) +;;; (map-char-table +;;; (lambda (k v) +;;; (aset table +;;; (or (aref ucs-8859-5-encode-table k) +;;; k) +;;; v)) +;;; table) +;;; (register-char-codings 'cyrillic-koi8 table)) +;;; (let ((table (get 'cyrillic-koi8-r-nonascii-translation-table +;;; 'translation-table))) +;;; (map-char-table +;;; (lambda (k v) +;;; (if v (aset table k (or (aref ucs-mule-8859-to-mule-unicode v) +;;; v)))) +;;; table)) +;;; ;; Redefine this, since the orginal only translated 8859-5. +;;; (define-ccl-program ccl-encode-koi8 +;;; `(1 +;;; ((loop +;;; (read-multibyte-character r0 r1) +;;; (translate-character cyrillic-koi8-r-encode-table r0 r1) +;;; (write-repeat r1)))) +;;; "CCL program to encode KOI8.") +;;; (let ((table (get 'cyrillic-alternativnyj-encode-table 'translation-table))) +;;; (map-char-table +;;; (lambda (k v) +;;; (aset table +;;; (or (aref ucs-8859-5-encode-table k) +;;; k) +;;; v)) +;;; table) +;;; (register-char-codings 'cyrillic-alternativnyj table)) +;;; (let ((table (get 'cyrillic-alternativnyj-nonascii-translation-table +;;; 'translation-table))) +;;; (map-char-table +;;; (lambda (k v) +;;; (if v (aset table +;;; k +;;; (or (aref ucs-mule-8859-to-mule-unicode v) +;;; v)))) +;;; table)) + ) + +(defun ucs-fragment-8859 (&optional encode-only) + "Undo the unification done by `ucs-unify-8859'. +With prefix arg, undo unification on encoding only, i.e. don't undo +unification on input operations." + (interactive "P") + ;; Maybe fix decoding. + (unless encode-only + ;; Unify 8859 on decoding. (Non-CCL coding systems only.) + (set-char-table-parent standard-translation-table-for-decode nil)) + ;; Fix encoding. For each charset, remove the entries in + ;; `char-coding-system-table' added to its safe-chars table (as its + ;; parent). + (dolist (n '(1 2 3 4 5 7 8 9 14 15)) + (let* ((coding-system + (coding-system-base (intern (format "iso-8859-%d" n)))) + (table (symbol-value + (intern (format "ucs-8859-%d-encode-table" n)))) + (safe (coding-system-get coding-system 'safe-chars))) + (map-char-table + (lambda (key val) + (if (and (>= key 128) val) + (let ((codings (aref char-coding-system-table key))) + (aset char-coding-system-table key + (delq coding-system codings))))) + (char-table-parent safe)) + (set-char-table-parent safe nil) + (coding-system-put coding-system 'translation-table-for-encode nil)))) + +;;;###autoload +(define-minor-mode unify-8859-on-encoding-mode + "Set up translation tables for unifying ISO 8859 characters on encoding. + +The ISO 8859 characters sets overlap, e.g. 8859-1 (Latin-1) and +8859-15 (Latin-9) differ only in a few characters. Emacs normally +distinguishes equivalent characters from those ISO-8859 character sets +which are built in to Emacs. This behaviour is essentially inherited +from the European-originated international standards. Treating them +equivalently, by translating to and from a single representation is +called `unification'. (The `utf-8' coding system treats the +characters of European scripts in a unified manner.) + +In this mode, on encoding -- i.e. output operations -- non-ASCII +characters from the built-in ISO 8859 and `mule-unicode-0100-24ff' +charsets are handled automatically by the coding system used if it can +represent them. Thus, say, an e-acute from the Latin-1 charset (the +unified representation) in a buffer saved as Latin-9 will be encoded +directly to a byte value 233. By default, in contrast, you would be +prompted for a general coding system to use for saving the file, which +can cope with separate Latin-1 and Latin-9 representations of e-acute. + +See also command `unify-8859-on-decoding-mode'." + :group 'mule + :global t + :version 21.3 ; who knows...? + :init-value nil + (if unify-8859-on-encoding-mode + (ucs-unify-8859 t) + (ucs-fragment-8859 t))) + +;;;###autoload +(define-minor-mode unify-8859-on-decoding-mode + "Set up translation table for unifying ISO 8859 characters on decoding. +On decoding -- i.e. input operations -- non-ASCII characters from the +built-in ISO 8859 charsets are unified by mapping them into the +`iso-latin-1' and `mule-unicode-0100-24ff' charsets. + +This sets the parent of `standard-translation-table-for-decode'. + +See also command `unify-8859-on-encoding-mode'." + :group 'mule + :global t + :version 21.3 ; who knows...? + :init-value nil + (if unify-8859-on-decoding-mode + (set-char-table-parent standard-translation-table-for-decode + ucs-mule-8859-to-mule-unicode) + (set-char-table-parent standard-translation-table-for-decode nil))) + +(defun ucs-insert (arg) + "Insert the Emacs character representation of the given Unicode. +Interactively, prompts for a hex string giving the code." + (interactive "sUnicode (hex): ") + (insert (decode-char 'ucs (if (integerp arg) + arg + (string-to-number arg 16))))) + +;;; Dealing with non-8859 character sets. + +;; We only set up translation on encoding to utf-8. Also translation +;; tables ucs-CS-encode-table are constructed for some coding systems +;; CS which could be used as `translation-table-for-encode', currently +;; for indian-is13194, lao, thai, tibetan-iso-8bit and +;; vietnamese-viscii. + +;; The alists here cover both coding systems (external charsets), like +;; VISCII, and individual Emacs charsets, like `ipa'. +(let ((vietnamese-viscii + '((?,1!(B . ?$,1o/(B) + (?,1"(B . ?$,1o1(B) + (?,1#(B . ?$,1o7(B) + (?,1$(B . ?$,1o%(B) + (?,1%(B . ?$,1o'(B) + (?,1&(B . ?$,1o)(B) + (?,1'(B . ?$,1o-(B) + (?,1((B . ?$,1o=(B) + (?,1)(B . ?$,1o9(B) + (?,1*(B . ?$,1o?(B) + (?,1+(B . ?$,1oA(B) + (?,1,(B . ?$,1oC(B) + (?,1-(B . ?$,1oE(B) + (?,1.(B . ?$,1oG(B) + (?,1/(B . ?$,1oQ(B) + (?,10(B . ?$,1oS(B) + (?,11(B . ?$,1oU(B) + (?,12(B . ?$,1oW(B) + (?,15(B . ?$,1oY(B) + (?,16(B . ?$,1o](B) + (?,17(B . ?$,1o_(B) + (?,18(B . ?$,1oK(B) + (?,1=(B . ?$,1!a(B) + (?,1>(B . ?$,1o[(B) + (?,1F(B . ?$,1o3(B) + (?,1G(B . ?$,1o5(B) + (?,1O(B . ?$,1os(B) + (?,1Q(B . ?$,1oi(B) + (?,1U(B . ?$,1o!(B) + (?,1V(B . ?$,1ow(B) + (?,1W(B . ?$,1ok(B) + (?,1X(B . ?$,1om(B) + (?,1[(B . ?$,1oy(B) + (?,1\(B . ?$,1ou(B) + (?,1^(B . ?$,1oa(B) + (?,1_(B . ?$,1!p(B) + (?,1`(B . ?,A`(B) + (?,1a(B . ?,Aa(B) + (?,1b(B . ?,Ab(B) + (?,1c(B . ?,Ac(B) + (?,1d(B . ?$,1o#(B) + (?,1e(B . ?$,1 #(B) + (?,1f(B . ?$,1oo(B) + (?,1g(B . ?$,1o+(B) + (?,1h(B . ?,Ah(B) + (?,1i(B . ?,Ai(B) + (?,1j(B . ?,Aj(B) + (?,1k(B . ?$,1o;(B) + (?,1l(B . ?,Al(B) + (?,1m(B . ?,Am(B) + (?,1n(B . ?$,1 I(B) + (?,1o(B . ?$,1oI(B) + (?,1p(B . ?$,1 1(B) + (?,1q(B . ?$,1oq(B) + (?,1r(B . ?,Ar(B) + (?,1s(B . ?,As(B) + (?,1t(B . ?,At(B) + (?,1u(B . ?,Au(B) + (?,1v(B . ?$,1oO(B) + (?,1w(B . ?$,1oM(B) + (?,1x(B . ?$,1oe(B) + (?,1y(B . ?,Ay(B) + (?,1z(B . ?,Az(B) + (?,1{(B . ?$,1!)(B) + (?,1|(B . ?$,1og(B) + (?,1}(B . ?,A}(B) + (?,1~(B . ?$,1oc(B) + + (?,2!(B . ?$,1o.(B) + (?,2"(B . ?$,1o0(B) + (?,2#(B . ?$,1o6(B) + (?,2$(B . ?$,1o$(B) + (?,2%(B . ?$,1o&(B) + (?,2&(B . ?$,1o((B) + (?,2'(B . ?$,1o,(B) + (?,2((B . ?$,1o<(B) + (?,2)(B . ?$,1o8(B) + (?,2*(B . ?$,1o>(B) + (?,2+(B . ?$,1o@(B) + (?,2,(B . ?$,1oB(B) + (?,2-(B . ?$,1oD(B) + (?,2.(B . ?$,1oF(B) + (?,2/(B . ?$,1oP(B) + (?,20(B . ?$,1oR(B) + (?,21(B . ?$,1oT(B) + (?,22(B . ?$,1oV(B) + (?,25(B . ?$,1oX(B) + (?,26(B . ?$,1o\(B) + (?,27(B . ?$,1o^(B) + (?,28(B . ?$,1oJ(B) + (?,2=(B . ?$,1!`(B) + (?,2>(B . ?$,1oZ(B) + (?,2F(B . ?$,1o2(B) + (?,2G(B . ?$,1o4(B) + (?,2O(B . ?$,1or(B) + (?,2Q(B . ?$,1oh(B) + (?,2U(B . ?$,1o (B) + (?,2V(B . ?$,1ov(B) + (?,2W(B . ?$,1oj(B) + (?,2X(B . ?$,1ol(B) + (?,2[(B . ?$,1ox(B) + (?,2\(B . ?$,1ot(B) + (?,2^(B . ?$,1o`(B) + (?,2_(B . ?$,1!o(B) + (?,2`(B . ?,A@(B) + (?,2a(B . ?,AA(B) + (?,2b(B . ?,AB(B) + (?,2c(B . ?,AC(B) + (?,2d(B . ?$,1o"(B) + (?,2e(B . ?$,1 "(B) + (?,2f(B . ?$,1on(B) + (?,2g(B . ?$,1o*(B) + (?,2h(B . ?,AH(B) + (?,2i(B . ?,AI(B) + (?,2j(B . ?,AJ(B) + (?,2k(B . ?$,1o:(B) + (?,2l(B . ?,AL(B) + (?,2m(B . ?,AM(B) + (?,2n(B . ?$,1 H(B) + (?,2o(B . ?$,1oH(B) + (?,2p(B . ?$,1 0(B) + (?,2q(B . ?$,1op(B) + (?,2r(B . ?,AR(B) + (?,2s(B . ?,AS(B) + (?,2t(B . ?,AT(B) + (?,2u(B . ?,AU(B) + (?,2v(B . ?$,1oN(B) + (?,2w(B . ?$,1oL(B) + (?,2x(B . ?$,1od(B) + (?,2y(B . ?,AY(B) + (?,2z(B . ?,AZ(B) + (?,2{(B . ?$,1!((B) + (?,2|(B . ?$,1of(B) + (?,2}(B . ?,A](B) + (?,2~(B . ?$,1ob(B))) + + (thai-tis620 + '((?,T!(B . ?$,1Ba(B) + (?,T"(B . ?$,1Bb(B) + (?,T#(B . ?$,1Bc(B) + (?,T$(B . ?$,1Bd(B) + (?,T%(B . ?$,1Be(B) + (?,T&(B . ?$,1Bf(B) + (?,T'(B . ?$,1Bg(B) + (?,T((B . ?$,1Bh(B) + (?,T)(B . ?$,1Bi(B) + (?,T*(B . ?$,1Bj(B) + (?,T+(B . ?$,1Bk(B) + (?,T,(B . ?$,1Bl(B) + (?,T-(B . ?$,1Bm(B) + (?,T.(B . ?$,1Bn(B) + (?,T/(B . ?$,1Bo(B) + (?,T0(B . ?$,1Bp(B) + (?,T1(B . ?$,1Bq(B) + (?,T2(B . ?$,1Br(B) + (?,T3(B . ?$,1Bs(B) + (?,T4(B . ?$,1Bt(B) + (?,T5(B . ?$,1Bu(B) + (?,T6(B . ?$,1Bv(B) + (?,T7(B . ?$,1Bw(B) + (?,T8(B . ?$,1Bx(B) + (?,T9(B . ?$,1By(B) + (?,T:(B . ?$,1Bz(B) + (?,T;(B . ?$,1B{(B) + (?,T<(B . ?$,1B|(B) + (?,T=(B . ?$,1B}(B) + (?,T>(B . ?$,1B~(B) + (?,T?(B . ?$,1B(B) + (?,T@(B . ?$,1C (B) + (?,TA(B . ?$,1C!(B) + (?,TB(B . ?$,1C"(B) + (?,TC(B . ?$,1C#(B) + (?,TD(B . ?$,1C$(B) + (?,TE(B . ?$,1C%(B) + (?,TF(B . ?$,1C&(B) + (?,TG(B . ?$,1C'(B) + (?,TH(B . ?$,1C((B) + (?,TI(B . ?$,1C)(B) + (?,TJ(B . ?$,1C*(B) + (?,TK(B . ?$,1C+(B) + (?,TL(B . ?$,1C,(B) + (?,TM(B . ?$,1C-(B) + (?,TN(B . ?$,1C.(B) + (?,TO(B . ?$,1C/(B) + (?,TP(B . ?$,1C0(B) + (?,TQ(B . ?$,1C1(B) + (?,TR(B . ?$,1C2(B) + (?,TS(B . ?$,1C3(B) + (?,TT(B . ?$,1C4(B) + (?,TU(B . ?$,1C5(B) + (?,TV(B . ?$,1C6(B) + (?,TW(B . ?$,1C7(B) + (?,TX(B . ?$,1C8(B) + (?,TY(B . ?$,1C9(B) + (?,TZ(B . ?$,1C:(B) + (?,T_(B . ?$,1C?(B) + (?,T`(B . ?$,1C@(B) + (?,Ta(B . ?$,1CA(B) + (?,Tb(B . ?$,1CB(B) + (?,Tc(B . ?$,1CC(B) + (?,Td(B . ?$,1CD(B) + (?,Te(B . ?$,1CE(B) + (?,Tf(B . ?$,1CF(B) + (?,Tg(B . ?$,1CG(B) + (?,Th(B . ?$,1CH(B) + (?,Ti(B . ?$,1CI(B) + (?,Tj(B . ?$,1CJ(B) + (?,Tk(B . ?$,1CK(B) + (?,Tl(B . ?$,1CL(B) + (?,Tm(B . ?$,1CM(B) + (?,Tn(B . ?$,1CN(B) + (?,To(B . ?$,1CO(B) + (?,Tp(B . ?$,1CP(B) + (?,Tq(B . ?$,1CQ(B) + (?,Tr(B . ?$,1CR(B) + (?,Ts(B . ?$,1CS(B) + (?,Tt(B . ?$,1CT(B) + (?,Tu(B . ?$,1CU(B) + (?,Tv(B . ?$,1CV(B) + (?,Tw(B . ?$,1CW(B) + (?,Tx(B . ?$,1CX(B) + (?,Ty(B . ?$,1CY(B) + (?,Tz(B . ?$,1CZ(B) + (?,T{(B . ?$,1C[(B))) + + (tibetan-iso-8bit + '((?$(7!0(B . ?$,1E@(B) + (?$(7!1(B . ?$,1EA(B) + (?$(7!2(B . ?$,1EB(B) + (?$(7!3(B . ?$,1EC(B) + (?$(7!4(B . ?$,1ED(B) + (?$(7!5(B . ?$,1EE(B) + (?$(7!6(B . ?$,1EF(B) + (?$(7!7(B . ?$,1EG(B) + (?$(7!8(B . ?$,1EH(B) + (?$(7!9(B . ?$,1EI(B) + (?$(7!:(B . ?$,1EJ(B) + (?$(7!;(B . ?$,1EK(B) + (?$(7!<(B . ?$,1EL(B) + (?$(7!=(B . ?$,1EM(B) + (?$(7!>(B . ?$,1EN(B) + (?$(7!?(B . ?$,1EO(B) + (?$(7!@(B . ?$,1EP(B) + (?$(7!A(B . ?$,1EQ(B) + (?$(7!B(B . ?$,1ER(B) + (?$(7!C(B . ?$,1ES(B) + (?$(7!D(B . ?$,1ET(B) + (?$(7!E(B . ?$,1EU(B) + (?$(7!F(B . ?$,1EV(B) + (?$(7!G(B . ?$,1EW(B) + (?$(7!H(B . ?$,1EX(B) + (?$(7!I(B . ?$,1EY(B) + (?$(7!J(B . ?$,1EZ(B) + (?$(7!K(B . ?$,1E[(B) + (?$(7!L(B . ?$,1E\(B) + (?$(7!M(B . ?$,1E](B) + (?$(7!N(B . ?$,1E^(B) + (?$(7!O(B . ?$,1E_(B) + (?$(7!P(B . ?$,1E`(B) + (?$(7!Q(B . ?$,1Ea(B) + (?$(7!R(B . ?$,1Eb(B) + (?$(7!S(B . ?$,1Ec(B) + (?$(7!T(B . ?$,1Ed(B) + (?$(7!U(B . ?$,1Ee(B) + (?$(7!V(B . ?$,1Ef(B) + (?$(7!W(B . ?$,1Eg(B) + (?$(7!X(B . ?$,1Eh(B) + (?$(7!Y(B . ?$,1Ei(B) + (?$(7!Z(B . ?$,1Ej(B) + (?$(7![(B . ?$,1Ek(B) + (?$(7!\(B . ?$,1El(B) + (?$(7!](B . ?$,1Em(B) + (?$(7!^(B . ?$,1En(B) + (?$(7!_(B . ?$,1Eo(B) + (?$(7!`(B . ?$,1Ep(B) + (?$(7!a(B . ?$,1Eq(B) + (?$(7!b(B . ?$,1Er(B) + (?$(7!c(B . ?$,1Es(B) + (?$(7!d(B . ?$,1Et(B) + (?$(7!e(B . ?$,1Eu(B) + (?$(7!f(B . ?$,1Ev(B) + (?$(7!g(B . ?$,1Ew(B) + (?$(7!h(B . ?$,1Ex(B) + (?$(7!i(B . ?$,1Ey(B) + (?$(7!j(B . ?$,1Ez(B) + (?$(7!k(B . ?$,1E{(B) + (?$(7!l(B . ?$,1E|(B) + (?$(7!m(B . ?$,1E}(B) + (?$(7!n(B . ?$,1E~(B) + (?$(7!o(B . ?$,1E(B) + (?$(7"!(B . ?$,1F (B) + (?$(7""(B . ?$,1F!(B) + (?$(7"#(B . ?$,1F"(B) + (?$(7"$(B . ?$,1F#(B) + (?$(7"%(B . ?$,1F$(B) + (?$(7"&(B . ?$,1F%(B) + (?$(7"'(B . ?$,1F&(B) + (?$(7"((B . ?$,1F'(B) + (?$(7"*(B . ?$,1F)(B) + (?$(7"+(B . ?$,1F*(B) + (?$(7",(B . ?$,1F+(B) + (?$(7"-(B . ?$,1F,(B) + (?$(7".(B . ?$,1F-(B) + (?$(7"/(B . ?$,1F.(B) + (?$(7"0(B . ?$,1F/(B) + (?$(7"1(B . ?$,1F0(B) + (?$(7"2(B . ?$,1F1(B) + (?$(7"3(B . ?$,1F2(B) + (?$(7"4(B . ?$,1F3(B) + (?$(7"5(B . ?$,1F4(B) + (?$(7"6(B . ?$,1F5(B) + (?$(7"7(B . ?$,1F6(B) + (?$(7"8(B . ?$,1F7(B) + (?$(7"9(B . ?$,1F8(B) + (?$(7":(B . ?$,1F9(B) + (?$(7";(B . ?$,1F:(B) + (?$(7"<(B . ?$,1F;(B) + (?$(7"=(B . ?$,1F<(B) + (?$(7">(B . ?$,1F=(B) + (?$(7"?(B . ?$,1F>(B) + (?$(7"@(B . ?$,1F?(B) + (?$(7"A(B . ?$,1F@(B) + (?$(7"B(B . ?$,1FA(B) + (?$(7"C(B . ?$,1FB(B) + (?$(7"D(B . ?$,1FC(B) + (?$(7"E(B . ?$,1FD(B) + (?$(7"F(B . ?$,1FE(B) + (?$(7"G(B . ?$,1FF(B) + (?$(7"H(B . ?$,1FG(B) + (?$(7"I(B . ?$,1FH(B) + (?$(7"J(B . ?$,1FI(B) + (?$(7"K(B . ?$,1FJ(B) + (?$(7"R(B . ?$,1FQ(B) + (?$(7"S(B . ?$,1FR(B) + (?$(7"T(B . ?$,1FS(B) + (?$(7"U(B . ?$,1FT(B) + (?$(7"V(B . ?$,1FU(B) + (?$(7"W(B . ?$,1FV(B) + (?$(7"X(B . ?$,1FW(B) + (?$(7"Y(B . ?$,1FX(B) + (?$(7"Z(B . ?$,1FY(B) + (?$(7"[(B . ?$,1FZ(B) + (?$(7"\(B . ?$,1F[(B) + (?$(7"](B . ?$,1F\(B) + (?$(7"^(B . ?$,1F](B) + (?$(7"_(B . ?$,1F^(B) + (?$(7"`(B . ?$,1F_(B) + (?$(7"a(B . ?$,1F`(B) + (?$(7"b(B . ?$,1Fa(B) + (?$(7"c(B . ?$,1Fb(B) + (?$(7"d(B . ?$,1Fc(B) + (?$(7"e(B . ?$,1Fd(B) + (?$(7"f(B . ?$,1Fe(B) + (?$(7"g(B . ?$,1Ff(B) + (?$(7"h(B . ?$,1Fg(B) + (?$(7"i(B . ?$,1Fh(B) + (?$(7"j(B . ?$,1Fi(B) + (?$(7"k(B . ?$,1Fj(B) + (?$(7"l(B . ?$,1Fk(B) + (?$(7#!(B . ?$,1Fp(B) + (?$(7#"(B . ?$,1Fq(B) + (?$(7##(B . ?$,1Fr(B) + (?$(7#$(B . ?$,1Fs(B) + (?$(7#%(B . ?$,1Ft(B) + (?$(7#&(B . ?$,1Fu(B) + (?$(7#'(B . ?$,1Fv(B) + (?$(7#((B . ?$,1Fw(B) + (?$(7#*(B . ?$,1Fy(B) + (?$(7#+(B . ?$,1Fz(B) + (?$(7#,(B . ?$,1F{(B) + (?$(7#-(B . ?$,1F|(B) + (?$(7#.(B . ?$,1F}(B) + (?$(7#/(B . ?$,1F~(B) + (?$(7#0(B . ?$,1F(B) + (?$(7#1(B . ?$,1G (B) + (?$(7#2(B . ?$,1G!(B) + (?$(7#3(B . ?$,1G"(B) + (?$(7#4(B . ?$,1G#(B) + (?$(7#5(B . ?$,1G$(B) + (?$(7#6(B . ?$,1G%(B) + (?$(7#7(B . ?$,1G&(B) + (?$(7#8(B . ?$,1G'(B) + (?$(7#9(B . ?$,1G((B) + (?$(7#:(B . ?$,1G)(B) + (?$(7#;(B . ?$,1G*(B) + (?$(7#<(B . ?$,1G+(B) + (?$(7#=(B . ?$,1G,(B) + (?$(7#>(B . ?$,1G-(B) + (?$(7#?(B . ?$,1G.(B) + (?$(7#@(B . ?$,1G/(B) + (?$(7#A(B . ?$,1G0(B) + (?$(7#B(B . ?$,1G1(B) + (?$(7#C(B . ?$,1G2(B) + (?$(7#D(B . ?$,1G3(B) + (?$(7#E(B . ?$,1G4(B) + (?$(7#F(B . ?$,1G5(B) + (?$(7#G(B . ?$,1G6(B) + (?$(7#H(B . ?$,1G7(B) + (?$(7#I(B . ?$,1G8(B) + (?$(7#J(B . ?$,1G9(B) + (?$(7#K(B . ?$,1G:(B) + (?$(7#L(B . ?$,1G;(B) + (?$(7#M(B . ?$,1G<(B) + (?$(7#O(B . ?$,1G>(B) + (?$(7#P(B . ?$,1G?(B) + (?$(7#Q(B . ?$,1G@(B) + (?$(7#R(B . ?$,1GA(B) + (?$(7#S(B . ?$,1GB(B) + (?$(7#T(B . ?$,1GC(B) + (?$(7#U(B . ?$,1GD(B) + (?$(7#V(B . ?$,1GE(B) + (?$(7#W(B . ?$,1GF(B) + (?$(7#X(B . ?$,1GG(B) + (?$(7#Y(B . ?$,1GH(B) + (?$(7#Z(B . ?$,1GI(B) + (?$(7#[(B . ?$,1GJ(B) + (?$(7#\(B . ?$,1GK(B) + (?$(7#](B . ?$,1GL(B) + (?$(7#`(B . ?$,1GO(B))) + + (ipa + '((?,0 (B . ?i) + (?,0!(B . ?$,1#j(B) + (?,0"(B . ?e) + (?,0#(B . ?$,1#[(B) + (?,0$(B . ?,Af(B) + (?,0%(B . ?a) + (?,0&(B . ?$,1#h(B) + (?,0'(B . ?$,1#Y(B) + (?,0((B . ?$,1#P(B) + (?,0)(B . ?$,1#o(B) + (?,0*(B . ?$,1#d(B) + (?,0+(B . ?$,1$,(B) + (?,0,(B . ?$,1#Q(B) + (?,0-(B . ?y) + (?,0.(B . ?$,1$/(B) + (?,0/(B . ?,Ax(B) + (?,00(B . ?$,1 s(B) + (?,01(B . ?$,1#v(B) + (?,02(B . ?$,1$)(B) + (?,03(B . ?$,1#u(B) + (?,04(B . ?u) + (?,05(B . ?$,1$*(B) + (?,06(B . ?o) + (?,07(B . ?$,1#T(B) + (?,08(B . ?$,1#R(B) + (?,0:(B . ?$,1#Z(B) + (?,0@(B . ?p) + (?,0A(B . ?b) + (?,0B(B . ?t) + (?,0C(B . ?d) + (?,0D(B . ?k) + (?,0E(B . ?g) + (?,0F(B . ?f) + (?,0G(B . ?v) + (?,0H(B . ?$,1'8(B) + (?,0I(B . ?,Ap(B) + (?,0J(B . ?s) + (?,0K(B . ?z) + (?,0L(B . ?$,1$#(B) + (?,0M(B . ?$,1$2(B) + (?,0N(B . ?,Ag(B) + (?,0O(B . ?x) + (?,0P(B . ?$,1$!(B) + (?,0Q(B . ?h) + (?,0R(B . ?m) + (?,0S(B . ?n) + (?,0T(B . ?$,1#r(B) + (?,0U(B . ?$,1 k(B) + (?,0V(B . ?r) + (?,0W(B . ?$,1$ (B) + (?,0X(B . ?$,1#y(B) + (?,0Y(B . ?j) + (?,0Z(B . ?l) + (?,0[(B . ?$,1$.(B) + (?,0\(B . ?$,1$?(B) + (?,0](B . ?$,1#e(B) + (?,0^(B . ?w) + (?,0_(B . ?$,1$-(B) + (?,0p(B . ?$,1$h(B) + (?,0q(B . ?$,1$l(B) + (?,0r(B . ?$,1$p(B))) + + (ethiopic + '((?$(3!!(B . ?$,1M@(B) + (?$(3!"(B . ?$,1MA(B) + (?$(3!#(B . ?$,1MB(B) + (?$(3!$(B . ?$,1MC(B) + (?$(3!%(B . ?$,1MD(B) + (?$(3!&(B . ?$,1ME(B) + (?$(3!'(B . ?$,1MF(B) + (?$(3!)(B . ?$,1MH(B) + (?$(3!*(B . ?$,1MI(B) + (?$(3!+(B . ?$,1MJ(B) + (?$(3!,(B . ?$,1MK(B) + (?$(3!-(B . ?$,1ML(B) + (?$(3!.(B . ?$,1MM(B) + (?$(3!/(B . ?$,1MN(B) + (?$(3!0(B . ?$,1MO(B) + (?$(3!1(B . ?$,1MP(B) + (?$(3!2(B . ?$,1MQ(B) + (?$(3!3(B . ?$,1MR(B) + (?$(3!4(B . ?$,1MS(B) + (?$(3!5(B . ?$,1MT(B) + (?$(3!6(B . ?$,1MU(B) + (?$(3!7(B . ?$,1MV(B) + (?$(3!8(B . ?$,1MW(B) + (?$(3!9(B . ?$,1MX(B) + (?$(3!:(B . ?$,1MY(B) + (?$(3!;(B . ?$,1MZ(B) + (?$(3!<(B . ?$,1M[(B) + (?$(3!=(B . ?$,1M\(B) + (?$(3!>(B . ?$,1M](B) + (?$(3!?(B . ?$,1M^(B) + (?$(3!@(B . ?$,1M_(B) + (?$(3!A(B . ?$,1M`(B) + (?$(3!B(B . ?$,1Ma(B) + (?$(3!C(B . ?$,1Mb(B) + (?$(3!D(B . ?$,1Mc(B) + (?$(3!E(B . ?$,1Md(B) + (?$(3!F(B . ?$,1Me(B) + (?$(3!G(B . ?$,1Mf(B) + (?$(3!H(B . ?$,1Mg(B) + (?$(3!I(B . ?$,1Mh(B) + (?$(3!J(B . ?$,1Mi(B) + (?$(3!K(B . ?$,1Mj(B) + (?$(3!L(B . ?$,1Mk(B) + (?$(3!M(B . ?$,1Ml(B) + (?$(3!N(B . ?$,1Mm(B) + (?$(3!O(B . ?$,1Mn(B) + (?$(3!P(B . ?$,1Mo(B) + (?$(3!Q(B . ?$,1Mp(B) + (?$(3!R(B . ?$,1Mq(B) + (?$(3!S(B . ?$,1Mr(B) + (?$(3!T(B . ?$,1Ms(B) + (?$(3!U(B . ?$,1Mt(B) + (?$(3!V(B . ?$,1Mu(B) + (?$(3!W(B . ?$,1Mv(B) + (?$(3!X(B . ?$,1Mw(B) + (?$(3!Y(B . ?$,1Mx(B) + (?$(3!Z(B . ?$,1My(B) + (?$(3![(B . ?$,1Mz(B) + (?$(3!\(B . ?$,1M{(B) + (?$(3!](B . ?$,1M|(B) + (?$(3!^(B . ?$,1M}(B) + (?$(3!_(B . ?$,1M~(B) + (?$(3!`(B . ?$,1M(B) + (?$(3!a(B . ?$,1N (B) + (?$(3!b(B . ?$,1N!(B) + (?$(3!c(B . ?$,1N"(B) + (?$(3!d(B . ?$,1N#(B) + (?$(3!e(B . ?$,1N$(B) + (?$(3!f(B . ?$,1N%(B) + (?$(3!g(B . ?$,1N&(B) + (?$(3!i(B . ?$,1N((B) + (?$(3!k(B . ?$,1N*(B) + (?$(3!l(B . ?$,1N+(B) + (?$(3!m(B . ?$,1N,(B) + (?$(3!n(B . ?$,1N-(B) + (?$(3!q(B . ?$,1N0(B) + (?$(3!r(B . ?$,1N1(B) + (?$(3!s(B . ?$,1N2(B) + (?$(3!t(B . ?$,1N3(B) + (?$(3!u(B . ?$,1N4(B) + (?$(3!v(B . ?$,1N5(B) + (?$(3!w(B . ?$,1N6(B) + (?$(3!y(B . ?$,1N8(B) + (?$(3!{(B . ?$,1N:(B) + (?$(3!|(B . ?$,1N;(B) + (?$(3!}(B . ?$,1N<(B) + (?$(3!~(B . ?$,1N=(B) + (?$(3"#(B . ?$,1N@(B) + (?$(3"$(B . ?$,1NA(B) + (?$(3"%(B . ?$,1NB(B) + (?$(3"&(B . ?$,1NC(B) + (?$(3"'(B . ?$,1ND(B) + (?$(3"((B . ?$,1NE(B) + (?$(3")(B . ?$,1NF(B) + (?$(3"*(B . ?$,1NG(B) + (?$(3"+(B . ?$,1NH(B) + (?$(3",(B . ?$,1NI(B) + (?$(3"-(B . ?$,1NJ(B) + (?$(3".(B . ?$,1NK(B) + (?$(3"/(B . ?$,1NL(B) + (?$(3"0(B . ?$,1NM(B) + (?$(3"1(B . ?$,1NN(B) + (?$(3"2(B . ?$,1NO(B) + (?$(3"3(B . ?$,1NP(B) + (?$(3"4(B . ?$,1NQ(B) + (?$(3"5(B . ?$,1NR(B) + (?$(3"6(B . ?$,1NS(B) + (?$(3"7(B . ?$,1NT(B) + (?$(3"8(B . ?$,1NU(B) + (?$(3"9(B . ?$,1NV(B) + (?$(3":(B . ?$,1NW(B) + (?$(3";(B . ?$,1NX(B) + (?$(3"<(B . ?$,1NY(B) + (?$(3"=(B . ?$,1NZ(B) + (?$(3">(B . ?$,1N[(B) + (?$(3"?(B . ?$,1N\(B) + (?$(3"@(B . ?$,1N](B) + (?$(3"A(B . ?$,1N^(B) + (?$(3"B(B . ?$,1N_(B) + (?$(3"C(B . ?$,1N`(B) + (?$(3"D(B . ?$,1Na(B) + (?$(3"E(B . ?$,1Nb(B) + (?$(3"F(B . ?$,1Nc(B) + (?$(3"G(B . ?$,1Nd(B) + (?$(3"H(B . ?$,1Ne(B) + (?$(3"I(B . ?$,1Nf(B) + (?$(3"K(B . ?$,1Nh(B) + (?$(3"M(B . ?$,1Nj(B) + (?$(3"N(B . ?$,1Nk(B) + (?$(3"O(B . ?$,1Nl(B) + (?$(3"P(B . ?$,1Nm(B) + (?$(3"S(B . ?$,1Np(B) + (?$(3"T(B . ?$,1Nq(B) + (?$(3"U(B . ?$,1Nr(B) + (?$(3"V(B . ?$,1Ns(B) + (?$(3"W(B . ?$,1Nt(B) + (?$(3"X(B . ?$,1Nu(B) + (?$(3"Y(B . ?$,1Nv(B) + (?$(3"Z(B . ?$,1Nw(B) + (?$(3"[(B . ?$,1Nx(B) + (?$(3"\(B . ?$,1Ny(B) + (?$(3"](B . ?$,1Nz(B) + (?$(3"^(B . ?$,1N{(B) + (?$(3"_(B . ?$,1N|(B) + (?$(3"`(B . ?$,1N}(B) + (?$(3"a(B . ?$,1N~(B) + (?$(3"b(B . ?$,1N(B) + (?$(3"c(B . ?$,1O (B) + (?$(3"d(B . ?$,1O!(B) + (?$(3"e(B . ?$,1O"(B) + (?$(3"f(B . ?$,1O#(B) + (?$(3"g(B . ?$,1O$(B) + (?$(3"h(B . ?$,1O%(B) + (?$(3"i(B . ?$,1O&(B) + (?$(3"j(B . ?$,1O'(B) + (?$(3"k(B . ?$,1O((B) + (?$(3"l(B . ?$,1O)(B) + (?$(3"m(B . ?$,1O*(B) + (?$(3"n(B . ?$,1O+(B) + (?$(3"o(B . ?$,1O,(B) + (?$(3"p(B . ?$,1O-(B) + (?$(3"q(B . ?$,1O.(B) + (?$(3"s(B . ?$,1O0(B) + (?$(3"u(B . ?$,1O2(B) + (?$(3"v(B . ?$,1O3(B) + (?$(3"w(B . ?$,1O4(B) + (?$(3"x(B . ?$,1O5(B) + (?$(3"{(B . ?$,1O8(B) + (?$(3"|(B . ?$,1O9(B) + (?$(3"}(B . ?$,1O:(B) + (?$(3"~(B . ?$,1O;(B) + (?$(3#!(B . ?$,1O<(B) + (?$(3#"(B . ?$,1O=(B) + (?$(3##(B . ?$,1O>(B) + (?$(3#%(B . ?$,1O@(B) + (?$(3#'(B . ?$,1OB(B) + (?$(3#((B . ?$,1OC(B) + (?$(3#)(B . ?$,1OD(B) + (?$(3#*(B . ?$,1OE(B) + (?$(3#-(B . ?$,1OH(B) + (?$(3#.(B . ?$,1OI(B) + (?$(3#/(B . ?$,1OJ(B) + (?$(3#0(B . ?$,1OK(B) + (?$(3#1(B . ?$,1OL(B) + (?$(3#2(B . ?$,1OM(B) + (?$(3#3(B . ?$,1ON(B) + (?$(3#5(B . ?$,1OP(B) + (?$(3#6(B . ?$,1OQ(B) + (?$(3#7(B . ?$,1OR(B) + (?$(3#8(B . ?$,1OS(B) + (?$(3#9(B . ?$,1OT(B) + (?$(3#:(B . ?$,1OU(B) + (?$(3#;(B . ?$,1OV(B) + (?$(3#=(B . ?$,1OX(B) + (?$(3#>(B . ?$,1OY(B) + (?$(3#?(B . ?$,1OZ(B) + (?$(3#@(B . ?$,1O[(B) + (?$(3#A(B . ?$,1O\(B) + (?$(3#B(B . ?$,1O](B) + (?$(3#C(B . ?$,1O^(B) + (?$(3#D(B . ?$,1O_(B) + (?$(3#E(B . ?$,1O`(B) + (?$(3#F(B . ?$,1Oa(B) + (?$(3#G(B . ?$,1Ob(B) + (?$(3#H(B . ?$,1Oc(B) + (?$(3#I(B . ?$,1Od(B) + (?$(3#J(B . ?$,1Oe(B) + (?$(3#K(B . ?$,1Of(B) + (?$(3#L(B . ?$,1Og(B) + (?$(3#M(B . ?$,1Oh(B) + (?$(3#N(B . ?$,1Oi(B) + (?$(3#O(B . ?$,1Oj(B) + (?$(3#P(B . ?$,1Ok(B) + (?$(3#Q(B . ?$,1Ol(B) + (?$(3#R(B . ?$,1Om(B) + (?$(3#S(B . ?$,1On(B) + (?$(3#U(B . ?$,1Op(B) + (?$(3#V(B . ?$,1Oq(B) + (?$(3#W(B . ?$,1Or(B) + (?$(3#X(B . ?$,1Os(B) + (?$(3#Y(B . ?$,1Ot(B) + (?$(3#Z(B . ?$,1Ou(B) + (?$(3#[(B . ?$,1Ov(B) + (?$(3#\(B . ?$,1Ow(B) + (?$(3#](B . ?$,1Ox(B) + (?$(3#^(B . ?$,1Oy(B) + (?$(3#_(B . ?$,1Oz(B) + (?$(3#`(B . ?$,1O{(B) + (?$(3#a(B . ?$,1O|(B) + (?$(3#b(B . ?$,1O}(B) + (?$(3#c(B . ?$,1O~(B) + (?$(3#d(B . ?$,1O(B) + (?$(3#e(B . ?$,1P (B) + (?$(3#f(B . ?$,1P!(B) + (?$(3#g(B . ?$,1P"(B) + (?$(3#h(B . ?$,1P#(B) + (?$(3#i(B . ?$,1P$(B) + (?$(3#j(B . ?$,1P%(B) + (?$(3#k(B . ?$,1P&(B) + (?$(3#l(B . ?$,1P'(B) + (?$(3#m(B . ?$,1P((B) + (?$(3#n(B . ?$,1P)(B) + (?$(3#o(B . ?$,1P*(B) + (?$(3#p(B . ?$,1P+(B) + (?$(3#q(B . ?$,1P,(B) + (?$(3#r(B . ?$,1P-(B) + (?$(3#s(B . ?$,1P.(B) + (?$(3#u(B . ?$,1P0(B) + (?$(3#w(B . ?$,1P2(B) + (?$(3#x(B . ?$,1P3(B) + (?$(3#y(B . ?$,1P4(B) + (?$(3#z(B . ?$,1P5(B) + (?$(3#}(B . ?$,1P8(B) + (?$(3#~(B . ?$,1P9(B) + (?$(3$!(B . ?$,1P:(B) + (?$(3$"(B . ?$,1P;(B) + (?$(3$#(B . ?$,1P<(B) + (?$(3$$(B . ?$,1P=(B) + (?$(3$%(B . ?$,1P>(B) + (?$(3$'(B . ?$,1P@(B) + (?$(3$((B . ?$,1PA(B) + (?$(3$)(B . ?$,1PB(B) + (?$(3$*(B . ?$,1PC(B) + (?$(3$+(B . ?$,1PD(B) + (?$(3$,(B . ?$,1PE(B) + (?$(3$-(B . ?$,1PF(B) + (?$(3$.(B . ?$,1PG(B) + (?$(3$/(B . ?$,1PH(B) + (?$(3$0(B . ?$,1PI(B) + (?$(3$1(B . ?$,1PJ(B) + (?$(3$2(B . ?$,1PK(B) + (?$(3$3(B . ?$,1PL(B) + (?$(3$4(B . ?$,1PM(B) + (?$(3$5(B . ?$,1PN(B) + (?$(3$6(B . ?$,1PO(B) + (?$(3$7(B . ?$,1PP(B) + (?$(3$8(B . ?$,1PQ(B) + (?$(3$9(B . ?$,1PR(B) + (?$(3$:(B . ?$,1PS(B) + (?$(3$;(B . ?$,1PT(B) + (?$(3$<(B . ?$,1PU(B) + (?$(3$=(B . ?$,1PV(B) + (?$(3$>(B . ?$,1PW(B) + (?$(3$?(B . ?$,1PX(B) + (?$(3$@(B . ?$,1PY(B) + (?$(3$A(B . ?$,1PZ(B) + (?$(3$B(B . ?$,1P[(B) + (?$(3$C(B . ?$,1P\(B) + (?$(3$D(B . ?$,1P](B) + (?$(3$E(B . ?$,1P^(B) + (?$(3$F(B . ?$,1P_(B) + (?$(3$G(B . ?$,1P`(B) + (?$(3$H(B . ?$,1Pa(B) + (?$(3$I(B . ?$,1Pb(B) + (?$(3$J(B . ?$,1Pc(B) + (?$(3$K(B . ?$,1Pd(B) + (?$(3$L(B . ?$,1Pe(B) + (?$(3$M(B . ?$,1Pf(B) + (?$(3$O(B . ?$,1Ph(B) + (?$(3$P(B . ?$,1Pi(B) + (?$(3$Q(B . ?$,1Pj(B) + (?$(3$R(B . ?$,1Pk(B) + (?$(3$S(B . ?$,1Pl(B) + (?$(3$T(B . ?$,1Pm(B) + (?$(3$U(B . ?$,1Pn(B) + (?$(3$V(B . ?$,1Po(B) + (?$(3$W(B . ?$,1Pp(B) + (?$(3$X(B . ?$,1Pq(B) + (?$(3$Y(B . ?$,1Pr(B) + (?$(3$Z(B . ?$,1Ps(B) + (?$(3$[(B . ?$,1Pt(B) + (?$(3$\(B . ?$,1Pu(B) + (?$(3$](B . ?$,1Pv(B) + (?$(3$^(B . ?$,1Pw(B) + (?$(3$_(B . ?$,1Px(B) + (?$(3$`(B . ?$,1Py(B) + (?$(3$a(B . ?$,1Pz(B) + (?$(3$h(B . ?$,1Q!(B) + (?$(3$i(B . ?$,1Q"(B) + (?$(3$j(B . ?$,1Q#(B) + (?$(3$k(B . ?$,1Q$(B) + (?$(3$l(B . ?$,1Q%(B) + (?$(3$m(B . ?$,1Q&(B) + (?$(3$n(B . ?$,1Q'(B) + (?$(3$o(B . ?$,1Q((B) + (?$(3$p(B . ?$,1Q)(B) + (?$(3$q(B . ?$,1Q*(B) + (?$(3$r(B . ?$,1Q+(B) + (?$(3$s(B . ?$,1Q,(B) + (?$(3$t(B . ?$,1Q-(B) + (?$(3$u(B . ?$,1Q.(B) + (?$(3$v(B . ?$,1Q/(B) + (?$(3$w(B . ?$,1Q0(B) + (?$(3$x(B . ?$,1Q1(B) + (?$(3$y(B . ?$,1Q2(B) + (?$(3$z(B . ?$,1Q3(B) + (?$(3${(B . ?$,1Q4(B) + (?$(3$|(B . ?$,1Q5(B) + (?$(3$}(B . ?$,1Q6(B) + (?$(3$~(B . ?$,1Q7(B) + (?$(3%!(B . ?$,1Q8(B) + (?$(3%"(B . ?$,1Q9(B) + (?$(3%#(B . ?$,1Q:(B) + (?$(3%$(B . ?$,1Q;(B) + (?$(3%%(B . ?$,1Q<(B))) + + (indian-is13194 + '((?(5!(B . ?$,15A(B) + (?(5"(B . ?$,15B(B) + (?(5#(B . ?$,15C(B) + (?(5$(B . ?$,15E(B) + (?(5%(B . ?$,15F(B) + (?(5&(B . ?$,15G(B) + (?(5'(B . ?$,15H(B) + (?(5((B . ?$,15I(B) + (?(5)(B . ?$,15J(B) + (?(5*(B . ?$,15K(B) + (?(5+(B . ?$,15N(B) + (?(5,(B . ?$,15O(B) + (?(5-(B . ?$,15P(B) + (?(5.(B . ?$,15M(B) + (?(5/(B . ?$,15R(B) + (?(50(B . ?$,15S(B) + (?(51(B . ?$,15T(B) + (?(52(B . ?$,15M(B) + (?(53(B . ?$,15U(B) + (?(54(B . ?$,15V(B) + (?(55(B . ?$,15W(B) + (?(56(B . ?$,15X(B) + (?(57(B . ?$,15Y(B) + (?(58(B . ?$,15Z(B) + (?(59(B . ?$,15[(B) + (?(5:(B . ?$,15\(B) + (?(5;(B . ?$,15](B) + (?(5<(B . ?$,15^(B) + (?(5=(B . ?$,15_(B) + (?(5>(B . ?$,15`(B) + (?(5?(B . ?$,15a(B) + (?(5@(B . ?$,15b(B) + (?(5A(B . ?$,15c(B) + (?(5B(B . ?$,15d(B) + (?(5C(B . ?$,15e(B) + (?(5D(B . ?$,15f(B) + (?(5E(B . ?$,15g(B) + (?(5F(B . ?$,15h(B) + (?(5G(B . ?$,15i(B) + (?(5H(B . ?$,15j(B) + (?(5I(B . ?$,15k(B) + (?(5J(B . ?$,15l(B) + (?(5K(B . ?$,15m(B) + (?(5L(B . ?$,15n(B) + (?(5M(B . ?$,15o(B) + (?(5N(B . ?$,16?(B) + (?(5O(B . ?$,15p(B) + (?(5P(B . ?$,15q(B) + (?(5Q(B . ?$,15r(B) + (?(5R(B . ?$,15s(B) + (?(5S(B . ?$,15t(B) + (?(5T(B . ?$,15u(B) + (?(5U(B . ?$,15v(B) + (?(5V(B . ?$,15w(B) + (?(5W(B . ?$,15x(B) + (?(5X(B . ?$,15y(B) + (?(5Z(B . ?$,15~(B) + (?(5[(B . ?$,15(B) + (?(5\(B . ?$,16 (B) + (?(5](B . ?$,16!(B) + (?(5^(B . ?$,16"(B) + (?(5_(B . ?$,16#(B) + (?(5`(B . ?$,16&(B) + (?(5a(B . ?$,16'(B) + (?(5b(B . ?$,16((B) + (?(5c(B . ?$,16%(B) + (?(5d(B . ?$,16*(B) + (?(5e(B . ?$,16+(B) + (?(5f(B . ?$,16,(B) + (?(5g(B . ?$,16)(B) + (?(5h(B . ?$,16-(B) + (?(5i(B . ?$,15|(B) + (?(5j(B . ?$,16D(B) + (?(5q(B . ?$,16F(B) + (?(5r(B . ?$,16G(B) + (?(5s(B . ?$,16H(B) + (?(5t(B . ?$,16I(B) + (?(5u(B . ?$,16J(B) + (?(5v(B . ?$,16K(B) + (?(5w(B . ?$,16L(B) + (?(5x(B . ?$,16M(B) + (?(5y(B . ?$,16N(B) + (?(5z(B . ?$,16O(B))) + + (katakana-jisx0201 + '((?(I!(B . ?$,3sa(B) + (?\(I"(B . ?\$,3sb(B) + (?\(I#(B . ?\$,3sc(B) + (?(I$(B . ?$,3sd(B) + (?(I%(B . ?$,3se(B) + (?(I&(B . ?$,3sf(B) + (?(I'(B . ?$,3sg(B) + (?(I((B . ?$,3sh(B) + (?(I)(B . ?$,3si(B) + (?(I*(B . ?$,3sj(B) + (?(I+(B . ?$,3sk(B) + (?(I,(B . ?$,3sl(B) + (?(I-(B . ?$,3sm(B) + (?(I.(B . ?$,3sn(B) + (?(I/(B . ?$,3so(B) + (?(I0(B . ?$,3sp(B) + (?(I1(B . ?$,3sq(B) + (?(I2(B . ?$,3sr(B) + (?(I3(B . ?$,3ss(B) + (?(I4(B . ?$,3st(B) + (?(I5(B . ?$,3su(B) + (?(I6(B . ?$,3sv(B) + (?(I7(B . ?$,3sw(B) + (?(I8(B . ?$,3sx(B) + (?(I9(B . ?$,3sy(B) + (?(I:(B . ?$,3sz(B) + (?(I;(B . ?$,3s{(B) + (?(I<(B . ?$,3s|(B) + (?(I=(B . ?$,3s}(B) + (?(I>(B . ?$,3s~(B) + (?(I?(B . ?$,3s(B) + (?(I@(B . ?$,3t (B) + (?(IA(B . ?$,3t!(B) + (?(IB(B . ?$,3t"(B) + (?(IC(B . ?$,3t#(B) + (?(ID(B . ?$,3t$(B) + (?(IE(B . ?$,3t%(B) + (?(IF(B . ?$,3t&(B) + (?(IG(B . ?$,3t'(B) + (?(IH(B . ?$,3t((B) + (?(II(B . ?$,3t)(B) + (?(IJ(B . ?$,3t*(B) + (?(IK(B . ?$,3t+(B) + (?(IL(B . ?$,3t,(B) + (?(IM(B . ?$,3t-(B) + (?(IN(B . ?$,3t.(B) + (?(IO(B . ?$,3t/(B) + (?(IP(B . ?$,3t0(B) + (?(IQ(B . ?$,3t1(B) + (?(IR(B . ?$,3t2(B) + (?(IS(B . ?$,3t3(B) + (?(IT(B . ?$,3t4(B) + (?(IU(B . ?$,3t5(B) + (?(IV(B . ?$,3t6(B) + (?(IW(B . ?$,3t7(B) + (?(IX(B . ?$,3t8(B) + (?(IY(B . ?$,3t9(B) + (?(IZ(B . ?$,3t:(B) + (?(I[(B . ?$,3t;(B) + (?(I\(B . ?$,3t<(B) + (?(I](B . ?$,3t=(B) + (?(I^(B . ?$,3t>(B) + (?(I_(B . ?$,3t?(B))) + + (chinese-sisheng + '((?(0!(B . ?$,1 !(B) + (?(0"(B . ?,Aa(B) + (?(0#(B . ?$,1".(B) + (?(0$(B . ?,A`(B) + (?(0%(B . ?$,1 3(B) + (?(0&(B . ?,Ai(B) + (?(0'(B . ?$,1 ;(B) + (?(0((B . ?,Ah(B) + (?(0)(B . ?$,1 K(B) + (?(0*(B . ?,Am(B) + (?(0+(B . ?$,1"0(B) + (?(0,(B . ?,Al(B) + (?(0-(B . ?$,1 m(B) + (?(0.(B . ?,As(B) + (?(0/(B . ?$,1"2(B) + (?(00(B . ?,Ar(B) + (?(01(B . ?$,1!+(B) + (?(02(B . ?,Az(B) + (?(03(B . ?$,1"4(B) + (?(04(B . ?,Ay(B) + (?(05(B . ?$,1"6(B) + (?(06(B . ?$,1"8(B) + (?(07(B . ?$,1":(B) + (?(08(B . ?$,1"<(B) + (?(09(B . ?,A|(B) + (?(0:(B . ?,Aj(B) + (?(0<(B . ?$,1m(B) + (?(0=(B . ?$,1 d(B) + (?(0>(B . ?$,1 h(B) + (?(0?(B . ?$,1"Y(B) + (?(0A(B . ?$,1$i(B) + (?(0B(B . ?$,1$j(B) + (?(0C(B . ?$,1$g(B) + (?(0D(B . ?$,1$k(B) + (?(0E(B . ?$,2@%(B) + (?(0F(B . ?$,2@&(B) + (?(0G(B . ?$,2@'(B) + (?(0H(B . ?$,2@((B) + (?(0I(B . ?$,2@)(B) + (?(0J(B . ?$,2@*(B) + (?(0K(B . ?$,2@+(B) + (?(0L(B . ?$,2@,(B) + (?(0M(B . ?$,2@-(B) + (?(0N(B . ?$,2@.(B) + (?(0O(B . ?$,2@/(B) + (?(0P(B . ?$,2@0(B) + (?(0Q(B . ?$,2@1(B) + (?(0R(B . ?$,2@2(B) + (?(0S(B . ?$,2@3(B) + (?(0T(B . ?$,2@4(B) + (?(0U(B . ?$,2@5(B) + (?(0V(B . ?$,2@6(B) + (?(0W(B . ?$,2@7(B) + (?(0X(B . ?$,2@8(B) + (?(0Y(B . ?$,2@9(B) + (?(0Z(B . ?$,2@:(B) + (?(0[(B . ?$,2@;(B) + (?(0\(B . ?$,2@<(B) + (?(0](B . ?$,2@=(B) + (?(0^(B . ?$,2@>(B) + (?(0_(B . ?$,2@?(B) + (?(0`(B . ?$,2@@(B) + (?(0a(B . ?$,2@A(B) + (?(0b(B . ?$,2@B(B) + (?(0c(B . ?$,2@C(B) + (?(0d(B . ?$,2@D(B) + (?(0e(B . ?$,2@E(B) + (?(0f(B . ?$,2@F(B) + (?(0g(B . ?$,2@G(B) + (?(0h(B . ?$,2@H(B) + (?(0i(B . ?$,2@I(B))) + + (lao + '((?(1!(B . ?$,1D!(B) + (?(1"(B . ?$,1D"(B) + (?(1$(B . ?$,1D$(B) + (?(1'(B . ?$,1D'(B) + (?(1((B . ?$,1D((B) + (?(1*(B . ?$,1D*(B) + (?(1-(B . ?$,1D-(B) + (?(14(B . ?$,1D4(B) + (?(15(B . ?$,1D5(B) + (?(16(B . ?$,1D6(B) + (?(17(B . ?$,1D7(B) + (?(19(B . ?$,1D9(B) + (?(1:(B . ?$,1D:(B) + (?(1;(B . ?$,1D;(B) + (?(1<(B . ?$,1D<(B) + (?(1=(B . ?$,1D=(B) + (?(1>(B . ?$,1D>(B) + (?(1?(B . ?$,1D?(B) + (?(1A(B . ?$,1DA(B) + (?(1B(B . ?$,1DB(B) + (?(1C(B . ?$,1DC(B) + (?(1E(B . ?$,1DE(B) + (?(1G(B . ?$,1DG(B) + (?(1J(B . ?$,1DJ(B) + (?(1K(B . ?$,1DK(B) + (?(1M(B . ?$,1DM(B) + (?(1N(B . ?$,1DN(B) + (?(1O(B . ?$,1DO(B) + (?(1P(B . ?$,1DP(B) + (?(1Q(B . ?$,1DQ(B) + (?(1R(B . ?$,1DR(B) + (?(1S(B . ?$,1DS(B) + (?(1T(B . ?$,1DT(B) + (?(1U(B . ?$,1DU(B) + (?(1V(B . ?$,1DV(B) + (?(1W(B . ?$,1DW(B) + (?(1X(B . ?$,1DX(B) + (?(1Y(B . ?$,1DY(B) + (?(1[(B . ?$,1D[(B) + (?(1\(B . ?$,1D\(B) + (?(1](B . ?$,1D](B) + (?(1`(B . ?$,1D`(B) + (?(1a(B . ?$,1Da(B) + (?(1b(B . ?$,1Db(B) + (?(1c(B . ?$,1Dc(B) + (?(1d(B . ?$,1Dd(B) + (?(1f(B . ?$,1Df(B) + (?(1h(B . ?$,1Dh(B) + (?(1i(B . ?$,1Di(B) + (?(1j(B . ?$,1Dj(B) + (?(1k(B . ?$,1Dk(B) + (?(1l(B . ?$,1Dl(B) + (?(1m(B . ?$,1Dm(B) + (?(1p(B . ?$,1Dp(B) + (?(1q(B . ?$,1Dq(B) + (?(1r(B . ?$,1Dr(B) + (?(1s(B . ?$,1Ds(B) + (?(1t(B . ?$,1Dt(B) + (?(1u(B . ?$,1Du(B) + (?(1v(B . ?$,1Dv(B) + (?(1w(B . ?$,1Dw(B) + (?(1x(B . ?$,1Dx(B) + (?(1y(B . ?$,1Dy(B) + (?(1|(B . ?$,1D|(B) + (?(1}(B . ?$,1D}(B)))) + (let ((table (make-char-table 'safe-chars)) + safe-charsets) + (dolist (cs '(vietnamese-viscii lao chinese-sisheng ipa + katakana-jisx0201 thai-tis620 tibetan-iso-8bit + indian-is13194 ethiopic)) + ;; These tables could be used as translation-table-for-encode by + ;; the relevant coding systems. + (let ((encode-translator + (if (coding-system-p cs) + (set (intern (format "ucs-%s-encode-table" cs)) + (make-translation-table))))) + (dolist (pair (symbol-value cs)) + (aset ucs-mule-to-mule-unicode (car pair) (cdr pair)) + (if encode-translator + (aset encode-translator (cdr pair) (car pair)))) + (if (charsetp cs) + (push cs safe-charsets) + (setq safe-charsets + (append (delq 'ascii (coding-system-get cs 'safe-charsets)) + safe-charsets))))) + (dolist (c safe-charsets) + (aset table (make-char c) t)) + (coding-system-put 'mule-utf-8 'safe-charsets + (append (coding-system-get 'mule-utf-8 'safe-charsets) + safe-charsets)) + (register-char-codings 'mule-utf-8 table))) + +(provide 'ucs-tables) + +;;; ucs-tables.el ends here diff --git a/contrib/xml.el b/contrib/xml.el index d128b83..a495721 100644 --- a/contrib/xml.el +++ b/contrib/xml.el @@ -73,32 +73,30 @@ ;;** ;;******************************************************************* -(defmacro xml-node-name (node) +(defsubst xml-node-name (node) "Return the tag associated with NODE. The tag is a lower-case symbol." - (list 'car node)) + (car node)) -(defmacro xml-node-attributes (node) +(defsubst xml-node-attributes (node) "Return the list of attributes of NODE. The list can be nil." - (list 'nth 1 node)) + (nth 1 node)) -(defmacro xml-node-children (node) +(defsubst xml-node-children (node) "Return the list of children of NODE. This is a list of nodes, and it can be nil." - (list 'cddr node)) + (cddr node)) (defun xml-get-children (node child-name) "Return the children of NODE whose tag is CHILD-NAME. CHILD-NAME should be a lower case symbol." - (let ((children (xml-node-children node)) - match) - (while children - (if (car children) - (if (equal (xml-node-name (car children)) child-name) - (set 'match (append match (list (car children)))))) - (set 'children (cdr children))) - match)) + (let ((match ())) + (dolist (child (xml-node-children node)) + (if child + (if (equal (xml-node-name child) child-name) + (push child match)))) + (nreverse match))) (defun xml-get-attribute (node attribute) "Get from NODE the value of ATTRIBUTE. @@ -155,16 +153,17 @@ and returned as the first element of the list" (forward-char -1) (if (null xml) (progn - (set 'result (xml-parse-tag end parse-dtd)) + (setq result (xml-parse-tag end parse-dtd)) (cond + ((null result)) ((listp (car result)) - (set 'dtd (car result)) + (setq dtd (car result)) (add-to-list 'xml (cdr result))) (t (add-to-list 'xml result)))) ;; translation of rule [1] of XML specifications - (error "XML files can have only one toplevel tag."))) + (error "XML files can have only one toplevel tag"))) (goto-char end))) (if parse-dtd (cons dtd (reverse xml)) @@ -197,7 +196,7 @@ Returns one of: ((looking-at "" end) - (skip-chars-forward " \t\n") - (xml-parse-tag end)) + nil) ;; end tag ((looking-at " \t\n]+\\)") - (let* ((node-name (match-string 1)) - (children (list (intern node-name))) - (case-fold-search nil) ;; XML is case-sensitive + (goto-char (match-end 1)) + (let* ((case-fold-search nil) ;; XML is case-sensitive. + (node-name (match-string 1)) + ;; Parse the attribute list. + (children (list (xml-parse-attlist end) (intern node-name))) pos) - (goto-char (match-end 1)) - - ;; parses the attribute list - (set 'children (append children (list (xml-parse-attlist end)))) ;; is this an empty element ? (if (looking-at "/>") (progn (forward-char 2) - (skip-chars-forward " \t\n") - (append children '(""))) + (nreverse (cons '("") children))) ;; is this a valid start tag ? - (if (= (char-after) ?>) + (if (eq (char-after) ?>) (progn (forward-char 1) - (skip-chars-forward " \t\n") - ;; Now check that we have the right end-tag. Note that this one might - ;; contain spaces after the tag name + ;; Now check that we have the right end-tag. Note that this + ;; one might contain spaces after the tag name (while (not (looking-at (concat ""))) (cond ((looking-at " (point) end) - (error "XML: End tag for %s not found before end of region." + (error "XML: End tag for %s not found before end of region" node-name)) - children - ) + (nreverse children)) ;; This was an invalid start tag (error "XML: Invalid attribute list") )))) (t ;; This is not a tag. - (error "XML: Invalid character.")) + (error "XML: Invalid character")) )) (defun xml-parse-attlist (end) "Return the attribute-list that point is looking at. The search for attributes end at the position END in the current buffer. Leaves the point on the first non-blank character after the tag." - (let ((attlist '()) + (let ((attlist ()) name) (skip-chars-forward " \t\n") (while (looking-at "\\([a-zA-Z_:][-a-zA-Z0-9._:]*\\)[ \t\n]*=[ \t\n]*") - (set 'name (intern (match-string 1))) + (setq name (intern (match-string 1))) (goto-char (match-end 0)) ;; Do we have a string between quotes (or double-quotes), ;; or a simple word ? - (unless (looking-at "\"\\([^\"]+\\)\"") - (unless (looking-at "'\\([^\"]+\\)'") - (error "XML: Attribute values must be given between quotes."))) + (unless (looking-at "\"\\([^\"]*\\)\"") + (unless (looking-at "'\\([^']*\\)'") + (error "XML: Attribute values must be given between quotes"))) ;; Each attribute must be unique within a given element (if (assoc name attlist) - (error "XML: each attribute must be unique within an element.")) + (error "XML: each attribute must be unique within an element")) - (set 'attlist (append attlist - (list (cons name (match-string-no-properties 1))))) + (push (cons name (match-string-no-properties 1)) attlist) (goto-char (match-end 0)) (skip-chars-forward " \t\n") (if (> (point) end) - (error "XML: end of attribute list not found before end of region.")) + (error "XML: end of attribute list not found before end of region")) ) - attlist - )) + (nreverse attlist))) ;;******************************************************************* ;;** @@ -335,25 +332,25 @@ This follows the rule [28] in the XML specifications." (defun xml-parse-dtd (end) "Parse the DTD that point is looking at. The DTD must end before the position END in the current buffer." - (let (dtd type element end-pos) - (forward-char (length "") - (error "XML: invalid DTD (excepting name of the document)")) - - ;; Get the name of the document - (looking-at "\\sw+") - (set 'dtd (list 'dtd (match-string-no-properties 0))) + (forward-char (length "") + (error "XML: invalid DTD (excepting name of the document)")) + + ;; Get the name of the document + (looking-at "\\sw+") + (let ((dtd (list (match-string-no-properties 0) 'dtd)) + type element end-pos) (goto-char (match-end 0)) (skip-chars-forward " \t\n") ;; External DTDs => don't know how to handle them yet (if (looking-at "SYSTEM") - (error "XML: Don't know how to handle external DTDs.")) + (error "XML: Don't know how to handle external DTDs")) (if (not (= (char-after) ?\[)) - (error "XML: Unknown declaration in the DTD.")) + (error "XML: Unknown declaration in the DTD")) ;; Parse the rest of the DTD (forward-char 1) @@ -367,16 +364,16 @@ The DTD must end before the position END in the current buffer." (setq element (intern (match-string-no-properties 1)) type (match-string-no-properties 2)) - (set 'end-pos (match-end 0)) + (setq end-pos (match-end 0)) ;; Translation of rule [46] of XML specifications (cond ((string-match "^EMPTY[ \t\n]*$" type) ;; empty declaration - (set 'type 'empty)) + (setq type 'empty)) ((string-match "^ANY[ \t\n]*$" type) ;; any type of contents - (set 'type 'any)) + (setq type 'any)) ((string-match "^(\\(.*\\))[ \t\n]*$" type) ;; children ([47]) - (set 'type (xml-parse-elem-type (match-string-no-properties 1 type)))) + (setq type (xml-parse-elem-type (match-string-no-properties 1 type)))) ((string-match "^%[^;]+;[ \t\n]*$" type) ;; substitution nil) (t @@ -384,13 +381,12 @@ The DTD must end before the position END in the current buffer." ;; rule [45]: the element declaration must be unique (if (assoc element dtd) - (error "XML: elements declaration must be unique in a DTD (<%s>)." + (error "XML: elements declaration must be unique in a DTD (<%s>)" (symbol-name element))) ;; Store the element in the DTD - (set 'dtd (append dtd (list (list element type)))) - (goto-char end-pos) - ) + (push (list element type) dtd) + (goto-char end-pos)) (t @@ -400,8 +396,7 @@ The DTD must end before the position END in the current buffer." ;; Skip the end of the DTD (search-forward ">" end) - dtd - )) + (nreverse dtd))) (defun xml-parse-elem-type (string) @@ -413,11 +408,11 @@ The DTD must end before the position END in the current buffer." (setq elem (match-string 1 string) modifier (match-string 2 string)) (if (string-match "|" elem) - (set 'elem (append '(choice) + (setq elem (cons 'choice (mapcar 'xml-parse-elem-type (split-string elem "|")))) (if (string-match "," elem) - (set 'elem (append '(seq) + (setq elem (cons 'seq (mapcar 'xml-parse-elem-type (split-string elem ",")))) ))) @@ -425,19 +420,18 @@ The DTD must end before the position END in the current buffer." (setq elem (match-string 1 string) modifier (match-string 2 string)))) - (if (and (stringp elem) - (string= elem "#PCDATA")) - (set 'elem 'pcdata)) + (if (and (stringp elem) (string= elem "#PCDATA")) + (setq elem 'pcdata)) - (cond - ((string= modifier "+") - (list '+ elem)) - ((string= modifier "*") - (list '* elem)) - ((string= modifier "?") - (list '? elem)) - (t - elem)))) + (cond + ((string= modifier "+") + (list '+ elem)) + ((string= modifier "*") + (list '* elem)) + ((string= modifier "?") + (list '? elem)) + (t + elem)))) ;;******************************************************************* @@ -449,15 +443,15 @@ The DTD must end before the position END in the current buffer." (defun xml-substitute-special (string) "Return STRING, after subsituting special XML sequences." (while (string-match "&" string) - (set 'string (replace-match "&" t nil string))) + (setq string (replace-match "&" t nil string))) (while (string-match "<" string) - (set 'string (replace-match "<" t nil string))) + (setq string (replace-match "<" t nil string))) (while (string-match ">" string) - (set 'string (replace-match ">" t nil string))) + (setq string (replace-match ">" t nil string))) (while (string-match "'" string) - (set 'string (replace-match "'" t nil string))) + (setq string (replace-match "'" t nil string))) (while (string-match """ string) - (set 'string (replace-match "\"" t nil string))) + (setq string (replace-match "\"" t nil string))) string) ;;******************************************************************* @@ -468,50 +462,39 @@ The DTD must end before the position END in the current buffer." ;;******************************************************************* (defun xml-debug-print (xml) - (while xml - (xml-debug-print-internal (car xml) "") - (set 'xml (cdr xml))) - ) + (dolist (node xml) + (xml-debug-print-internal node ""))) -(defun xml-debug-print-internal (xml &optional indent-string) +(defun xml-debug-print-internal (xml indent-string) "Outputs the XML tree in the current buffer. The first line indented with INDENT-STRING." (let ((tree xml) attlist) - (unless indent-string - (set 'indent-string "")) - (insert indent-string "<" (symbol-name (xml-node-name tree))) ;; output the attribute list - (set 'attlist (xml-node-attributes tree)) + (setq attlist (xml-node-attributes tree)) (while attlist (insert " ") (insert (symbol-name (caar attlist)) "=\"" (cdar attlist) "\"") - (set 'attlist (cdr attlist))) + (setq attlist (cdr attlist))) (insert ">") - (set 'tree (xml-node-children tree)) + (setq tree (xml-node-children tree)) ;; output the children - (while tree + (dolist (node tree) (cond - ((listp (car tree)) + ((listp node) (insert "\n") - (xml-debug-print-internal (car tree) (concat indent-string " ")) - ) - ((stringp (car tree)) - (insert (car tree)) - ) + (xml-debug-print-internal node (concat indent-string " "))) + ((stringp node) (insert node)) (t - (error "Invalid XML tree"))) - (set 'tree (cdr tree)) - ) + (error "Invalid XML tree")))) (insert "\n" indent-string - "") - )) + ""))) (provide 'xml) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 48d7cb6..b021fd9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,1663 @@ +2002-05-01 20:09:21 Lars Magne Ingebrigtsen + + * gnus.el: Oort Gnus v0.06 is released. + +2002-05-01 Lars Magne Ingebrigtsen <> + + * lpath.el: Bind url-package-version. + +2002-05-01 Simon Josefsson + + * nnfolder.el (nnfolder-request-delete-group): Figure out nov/mrk + filename before deleting the group itself, because the presence of + a group filename decides if long filenames are used or not. + + * gnus-art.el (gnus-button-alist): Don't inline + gnus-button-url-regexp. This makes it possible to change g-b-u-r + without also modifying g-button-alist. + (gnus-button-alist): Fix type to allow variable as well as regexp. + (gnus-article-add-buttons): Evaluate regexp. Strings evaluate to + themselves, variables to its contents. + (gnus-button-entry): Ditto. + +2002-05-01 Simon Josefsson + + * imap.el (imap-parse-resp-text-code, imap-parse-status): Treat + UIDNEXT as a string. + + * nnimap.el (nnimap-string-lessp-numerical): New function. + (nnimap-retrieve-groups): Compare UIDNEXT as strings instead of + integers. + +2002-04-29 Simon Josefsson + + * nnmail.el (nnmail-cache-insert): Accept optional group + parameter. + + * nnimap.el (nnimap-retrieve-groups): Don't send STATUS when + n-r-g-a is disabled. + +2002-04-29 Simon Josefsson + + * nnimap.el (nnimap-split-fancy): Fix doc. + (nnimap-split-fancy): Fix doc. + + * nnimap.el (nnimap-retrieve-groups-asynchronous): New variable. + (nnimap-mailbox-info): New internal variable. + (nnimap-retrieve-groups): Implement faster new mail check. + + * nnimap.el (nnimap-split-articles): Support + nnmail-cache-accepted-message-ids. + (nnimap-request-accept-article): Ditto. + + * imap.el (imap-mailbox-status-asynch): New command. + +2002-04-29 Nevin Kapur + + * gnus.el (gnus-find-subscribed-addresses): Return nil when there + are no subscribed mail groups. + - Strip quoted names when comparing addresses + +2002-04-28 Jesper Harder + + * mm-decode.el (mm-text-html-renderer): Change customize type to + const. + + * gnus-msg.el (gnus-discouraged-post-methods): Fix typo. + (gnus-debug-exclude-variables): do. + +2002-04-27 ShengHuo ZHU + + * gnus-msg.el (gnus-article-mail): Use gnus-msg-mail instead. + Trivial change from Karl Pfl,Ad(Bsterer . + +2002-04-27 Katsumi Yamaoka + + * dns.el (dns-make-network-process): New macro. + (query-dns): Use it. + +2002-04-27 ShengHuo ZHU + + * gnus-msg.el (gnus-summary-reply): Remove unbound variable + article-buffer. + + * mm-url.el (mm-url-package-name): New variable. + (mm-url-package-version): New variable. + (mm-url-insert-file-contents): Bind url-package-name and + url-package-version here. + * nnrss.el (nnrss-insert-w3): Move the bindings. + + * nnrss.el (nnrss-insert-w3): Bind url-package-name and + url-package-version. Trivial change from Andrew J Cosgriff + + + * mm-decode.el (mm-save-part): Fill in file name when GUI saving + attachments. Trivial change from Peter 'Luna' Runestig + . + +2002-04-19 Jesper Harder + + * nnkiboze.el (nnkiboze-request-scan): Call + nnkiboze-possibly-change-group. + (nnkiboze-generate-group): Use mm-with-unibyte to avoid encoding + problems. + (nnkiboze-generate-group): Set newsrc to the *highest* article + number kibozed, not the lowest. + +2002-04-15 Jesper Harder + + * gnus-art.el (article-unsplit-urls): Allow trailing SPC. + +2002-04-24 Kai Gro,A_(Bjohann + From Dan Christensen . + + * nndoc.el (nndoc-type-alist, nndoc-lanl-gov-announce-type-p) + (nndoc-transform-lanl-gov-announce, nndoc-generate-lanl-gov-head): + Recognize math postings. Extract Date (now ignores "(15kb)"). + Extract email address using gnus-extract-address-components + instead of just taking the first word. Create Date and From + headers for message which are missing these headers. Get rid + of spurious \\ lines (purely cosmetic). Extend body-end and + file-end regexps, to exclude more garbage from the message. + Make URL rephrasing regexp more flexible, to match current + format. + +2002-04-23 Simon Josefsson + + * netrc.el: New file, functions copied from gnus-util.el by Ted + Zlatanov . + + * gnus-util.el: Require netrc. + (gnus-netrc-get, gnus-netrc-machine, gnus-parse-netrc): Aliased to + new code in netrc.el. + +2002-04-23 Kai Gro,A_(Bjohann + + * gnus-msg.el (gnus-summary-resend-message-edit): Remove + message-ignored-resent-headers, too. From Matthieu Moy + . + +2002-04-22 Bj,Av(Brn Torkelsson + + * gnus-srvr.el (gnus-server-browse-in-group-buffer): it is a + boolean not a string + * gnus-group.el (gnus-group-line-format): add description of %C + * gnus-group.el (gnus-group-line-format-alist): add gnus-tmp-comment + as %C + * gnus-group.el (gnus-group-insert-group-line): add gnus-tmp-comment + +2002-04-22 Paul Jarc + + * nnmaildir.el (nnmaildir-request-scan): typo: set + nnmaildir-get-new-mail, not nnmaildir-new-mail. Don't call + nnmail-get-new-mail for 'find-new-groups. + +2002-04-21 Paul Jarc + + * nnmaildir.el (nnmaildir-request-update-info, + nnmaildir-request-group, nnmaildir-retrieve-groups): remove + unnecessary calls to nnmaildir-request-scan. + +2002-04-20 Josh Huber + + * gnus-msg.el: + * gnus-msg.el (gnus-message-replysign): New. + * gnus-msg.el (gnus-message-replyencrypt): New. + * gnus-msg.el (gnus-message-replysignencrypted): New. + * gnus-msg.el (gnus-summary-reply): Use the three new variables + (above) to automatically encrypt/sign to encrypted/signed + messages. + * message.el: + * message.el (message-mode-map): Add keybinding for + `message-to-list-only' + * message.el (message-mode): Add description for + `message-to-list-only' + * message.el (message-to-list-only): New. + * message.el (message-make-mft): Changed to use the cl loop macro, + and added optional flag to return only the matched list. (for use + in new message-to-list-only function) + +2002-04-20 Josh Huber + + * gnus-msg.el: + * gnus-msg.el (gnus-message-replysign): + * gnus-msg.el (gnus-replysign): New. + * gnus-msg.el (gnus-replyencrypt): New. + * gnus-msg.el (gnus-replysignencrypted): New. + * gnus-msg.el (gnus-summary-reply): + * message.el: + * message.el (message-mode-map): + * message.el (message-mode): + * message.el (message-to-list-only): New. + * message.el (message-make-mft): + +2002-04-19 ShengHuo ZHU + + * gnus-win.el (gnus-configure-windows-hook): Fix typo. + +2002-04-18 Josh Huber + + * message.el (message-gen-unsubscribed-mft): accept a prefix + argument so CC can be included with C-u C-c C-f C-a + +2002-04-17 Kai Gro,A_(Bjohann + From Ted Zlatanov . + + * spam.el (spam-whitelist, spam-blacklist, spam-enter-whitelist): + Improve docstring. + (spam-enter-blacklist): New command. + + * gnus-sum.el (gnus-spam-mark): New mark. + (gnus-auto-expirable-marks): Add gnus-spam-mark. + (gnus-summary-make-tool-bar): Correct conditional. + (gnus-summary-limit-to-unread): Add gnus-spam-mark. + (gnus-summary-mark-as-spam): New command. + +2002-04-13 Josh Huber + + * mml-sec.el (mml-secure-message): changed to support arbritrary + modes. + * mml-sec.el (mml-secure-message-encrypt-(smime|pgp|pgpmime)): + changed to support "signencrypt" mode. + * mml.el (mml-parse-1): changed to support different secure modes + more easily. (for signencrypt) + +2002-04-11 Stefan Monnier + + * gnus-sum.el (gnus-update-summary-mark-positions) + (gnus-summary-toggle-header): + * gnus-uu.el (gnus-uu-binhex-article, gnus-uu-reginize-string) + (gnus-uu-expand-numbers, gnus-uu-post-make-mime) + (gnus-uu-post-encoded): + * nnfolder.el (nnfolder-possibly-change-group): + * nnimap.el (nnimap-retrieve-headers): + * nnmbox.el (nnmbox-create-mbox): Don't assume point-min == 1. + +2002-04-08 Stefan Monnier + + * nnml.el (nnml-save-nov, nnml-generate-nov-file): + * pop3.el (pop3-md5): Don't hardcode point-min == 1. + +2002-04-12 Katsumi Yamaoka + + * gnus-srvr.el (gnus-server-set-info): Clear + `gnus-server-method-cache' when `gnus-server-alist' is changed. + From Daiki Ueno . + +2002-04-11 Simon Josefsson + + * gnus-sum.el (gnus-summary-force-verify-and-decrypt): Force + viewing of security buttons. Thanks to Nicolas Kowalski + . + + * smime.el (smime-CA-directory): Fix doc. Thanks to Arne + J,Ax(Brgensen . + (smime-sign-buffer): Work in XEmacs. Thanks to Nicolas Kowalski + . + (smime-decrypt-buffer): Ditto. + +2002-04-11 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-prepare): Place point on the emtpy + header line. + +2002-04-11 Per Abrahamsen + + * gnus.el (gnus-refer-article-method): Change `dejanews' to `google'. + +2002-04-08 ShengHuo ZHU + + * gnus-sum.el (gnus-summary-delete-marked-with): Fix typo. + +2002-04-07 ShengHuo ZHU + + * mm-view.el (mm-inline-text-html-render-with-w3): Don't ignore + errors when debug. + +2002-04-07 Josh Huber + + * message.el (message-make-mft): Changed MFT code from using + message-recipients (which included Bcc) to use only the To and CC + headers. + +2002-04-05 Per Abrahamsen + + * gnus-art.el (gnus-treat-from-picon): Add to gnus-picon group and + add link. + (gnus-treat-mail-picon): Ditto. + (gnus-treat-newsgroups-picon): Ditto. + (gnus-picon-databases): Fix custom type. + (gnus-picon-databases): Add link. + (gnus-article-x-face-command): Add to gnus-picon group. + +2002-04-01 Jesper Harder + + * message.el (message-buffer-naming-style): Remove. + +2002-04-02 ShengHuo ZHU + + * gnus-group.el (gnus-group-make-tool-bar): Load tool-bar first. + + * message.el (message-tool-bar-map): Ditto. + + * gnus-sum.el (gnus-summary-make-tool-bar): Ditto. + +2002-04-01 ShengHuo ZHU + + * nnwarchive.el (nnwarchive-mail-archive-article): Fix typo. + +2002-04-01 Paul Jarc + + * nnmaildir.el: fixed some buggy invocations of nnmaildir--pgname. + +2002-03-31 Andrew Cohen + + * dns.el: open-network-stream under XEmacs does udp. + +2002-03-31 Lars Magne Ingebrigtsen + + * spam.el (spam-enter-whitelist): New function. + (spam-parse-whitelist): Ditto. + (spam-refresh-list-cache): Ditto. + (spam-address-whitelisted-p): New function. + + * dns.el (query-dns): Use TCP when make-network-process isn't + available. + (dns-servers): New variable. + (dns-parse-resolv-conf): New function. + (query-dns): Use it. + + * spam.el: New file. + + * dns.el (query-dns): Test. + +2002-03-31 Lars Magne Ingebrigtsen + + * lpath.el (featurep): Bind make-network-process. + +2002-03-31 Paul Jarc + + * nnmaildir.el: Use defstruct. Use a single copy of + nnmail-extra-headers to save memory. Store server's group name + prefix instead of each group's prefixed name. + * nnnil.el (nnnil-retrieve-headers, nnnil-request-list): Erase + nntp-server-buffer. + +2002-03-31 Lars Magne Ingebrigtsen + + * dns.el: New file. + +2002-03-28 Simon Josefsson + + * gnus-sum.el (gnus-summary-dummy-line-format): + * gnus.el (gnus-summary-line-format): Fixing links to Info. + Trivial change from Bj,Av(Brn Torkelsson . + +2002-03-29 Kai Gro,A_(Bjohann + + * gnus-sum.el (gnus-summary-move-article) + (gnus-summary-copy-article): Mention `gnus-move-split-methods' in + the doc string. + +2002-03-28 Simon Josefsson + + * mml-sec.el (mml-secure-message): Search after + mail-header-separator from top of message. + +2002-03-28 Paul Jarc + + * nnmaildir.el: Cosmetic changes. + (nnmaildir--with-nntp-buffer, nnmaildir--with-work-buffer, + nnmaildir--with-nov-buffer, nnmaildir--with-move-buffer, + nnmaildir--group-ls): New macros/functions. Use them. + (nnmaildir--unlink): Evalutate argument only once. + +2002-03-27 Jesper Harder + + * gnus-sum.el (gnus-summary-highlight): Use `eq' when comparing + symbols. + (gnus-summary-highlight-line): Use `gnus-point-at-bol' and + `gnus-point-at-eol'. + +2002-03-27 Paul Jarc + + * nnmaildir.el (nnmaildir--subdir, nnmaildir--nov-dir, + nnmaildir--marks-dir): New macros. Use them. + Use inhibit-quit for atomicity instead of in-memory journaling. + (nnmaildir--edit-prep): New function. + (Local Variables): Use it. + +2002-03-26 Pavel@Janik.cz (Pavel Jan,Bm(Bk) + + * gnus-sum.el (gnus-summary-make-menu-bar): Fix typo. + +2002-03-25 Simon Josefsson + + * message.el (message-mode): Fix doc. + +2002-03-25 Simon Josefsson + + * message.el (message-subject-re-regexp): Skip Re[42]: junk. From + Matthieu Moy . + +2002-03-24 Jesper Harder + + * mml-sec.el (mml-unsecure-message): Add docstring. + +2002-03-23 ShengHuo ZHU + + * nnmail.el (nnmail-large-newsgroup): Fix doc, allow non-numeric + value. + Trivial change from andre@slamdunknetworks.com + +2002-03-22 Josh Huber + + * mml.el (mml-mode-map): Added a keybinding for + `mml-unsecure-message'. Also, added a menu entry for said + function in the Attachments menu. + +2002-03-22 Katsumi Yamaoka + + * canlock.el (canlock-version): Remove. + (canlock-sha1-with-openssl): Don't use `canlock-string-as-unibyte' + here; simplify \x insertions. + (canlock-sha1): New function, always return a unibyte string. + (canlock-make-cancel-key): Use `canlock-sha1'; simplify truncation + of a password. + (canlock-insert-header): Use `canlock-sha1'. + (canlock-verify): Ditto. + +2002-03-21 ShengHuo ZHU + + * message.el (message-fix-before-sending): Add an option that + ignores illegible text. + Trivial change from Mark Milhollan + + * message.el (message-font-lock-keywords): Support multi-line MML + tags. + + * gnus-sum.el (gnus-print-buffer): Remove gnus-decoration. + Trivial change from lorentey@elte.hu (L,Bu(Brentey K,Ba(Broly) + +2002-03-20 Katsumi Yamaoka + + * gnus-sum.el (gnus-summary-make-menu-bar): Use intern'ed function + symbols for "View as different encoding" submenu. + +2002-03-19 Simon Josefsson + + * gnus-sum.el (gnus-summary-make-menu-bar): Add "View as different + encoding" submenu. + +2002-03-19 ShengHuo ZHU + + * gnus-group.el (gnus-group-process-prefix): Make sure there is a mark. + +2002-03-19 Kai Gro,A_(Bjohann + + * gnus-sum.el (gnus-sum-thread-tree-root) + (gnus-sum-thread-tree-single-indent) + (gnus-sum-thread-tree-vertical, gnus-sum-thread-tree-indent) + (gnus-sum-thread-tree-leaf-with-other) + (gnus-sum-thread-tree-single-leaf): Make customizable. + +2002-03-16 Simon Josefsson + + * gnus-util.el (gnus-extract-address-components): Don't break on + names such as James "Kibo" Parry. From Francis Litterio + . + +2002-03-13 Simon Josefsson + + * pop3.el (pop3-open-server): Revert multibyte change. From + Pavel@Janik.cz (Pavel Jan,Bm(Bk). + + * message.el (message-send-mail-with-qmail): Make it work. From + Pavel@Janik.cz (Pavel Jan,Bm(Bk). + +2002-03-13 Josh Huber + + * message.el (message-make-mft): Set case-fold-search while + generating the MFT. Also, a little cleanup in the MFT code. + +2002-03-12 Simon Josefsson + + * message.el (message-qmail-inject-args): May be function. + (message-send-mail-with-qmail): Call function if m-q-i-a is + function. From fn@hungry.org (Faried Nawaz). + +2002-03-12 ShengHuo ZHU + + * message.el (message-abbrevs-loaded): Remove. + (mailabbrev): Require it. + + * nnslashdot.el (nnslashdot-request-article): Remove IFRAME. + +2002-03-12 Katsumi Yamaoka + + * pop3.el (pop3-open-server): Set process buffer unibyte. + +2002-03-10 Lars Magne Ingebrigtsen + + * gnus-fun.el (gnus-subscribe-to-mailing-list): New function. + +2002-03-10 ShengHuo ZHU + + * nnslashdot.el (nnslashdot-request-article): Remove javascript + too. + +2002-03-09 ShengHuo ZHU + + * gnus-sum.el (gnus-summary-save-parts-default-mime): Remove + duplication. + (gnus-summary-save-parts-type-history): Ditto. + (gnus-summary-save-parts-last-directory): Ditto. + Trivial change from andre@slamdunknetworks.com + +2002-03-09 Paul Jarc + + * nnslashdot.el (nnslashdot-request-article): Use "" as the end of the first article. + + * gnus-msg.el (gnus-summary-resend-message-edit): New function. + From Matthieu Moy + + * message.el (message-add-action): Use add-to-list. + (message-delete-action): New function. + + * nndoc.el (nndoc-mail-in-mail-type-p): Break a long regexp into + pieces. + +2002-03-05 Paul Jarc + + * nnnil.el: New file. + * gnus.el (gnus-valid-select-methods): Include nnnil. + +2002-03-05 ShengHuo ZHU + + * message.el (message-syntax-checks): Because canlock is + supported, we disable sender syntax check. + (message-shoot-gnksa-feet): Add cancel-messages option doc. + + * gnus-draft.el (gnus-draft-send): If interactive, use its default + value of message-syntax-checks. + + * qp.el (quoted-printable-decode-region): Doc addition. + From: Eli Zaretskii + + * mail-source.el (make-source-make-complex-temp-name): Use + make-temp-file. + + * mm-util.el (mm-make-temp-file): New function. + * nneething.el (nneething-file-name): Use it. + * mml-smime.el (mml-smime-encrypt): Ditto. + * mm-view.el (mm-inline-wash-with-file): Ditto. + * mm-decode.el (mm-display-external, mm-create-image-xemacs): Ditto. + * gnus-uu.el (gnus-uu-decode-binhex, gnus-uu-decode-binhex-view) + (gnus-uu-digest-mail-forward, gnus-uu-initialize): Ditto. + * gnus-start.el (gnus-slave-save-newsrc): Ditto. + * gnus-fun.el (gnus-convert-image-to-gray-x-face): Ditto. + * gnus-art.el (gnus-mime-print-part): Ditto. + +2002-03-04 Paul Jarc + + * message.el (nnmaildir-article-number-to-base-name): New + function. + (nnmaildir-base-name-to-article-number): New function. + +2002-03-04 Katsumi Yamaoka + + * smime.el (smime-make-temp-file): Don't quote + `temporary-file-directory'. + +2002-03-04 Simon Josefsson + + * smime.el (smime-sign-region): Rename argument keyfiles to + keyfile. You only sign something with one key. + (smime-sign-buffer): Better completing-read prompt. + (smime-decrypt-buffer): Ditto. + + * smime.el (smime-make-temp-file): Make it work under XEmacs. + + * mm-view.el (mm-view-pkcs7-decrypt): Better prompt for + completing-read. + (mm-view-pkcs7-decrypt): CRLF->LF. + +2002-03-04 Paul Jarc + + * message.el (message-hierarchical-addresses): New variable. + (message-get-reply-headers): Use it. + From Ted Zlatanov + +2002-03-03 ShengHuo ZHU + + * message.el (message-mode): If buffer-file-name, don't set auto + save file name. + Trivial change from Geoff Greene + +2002-03-02 ShengHuo ZHU + + * gnus-util.el (gnus-multiple-choice): Use message. XEmacs only + takes one argument in read-char. + + * message.el (message-fix-before-sending): Forward a char. + Check mmu-multibyte-p, add control-1. + +2002-03-01 ShengHuo ZHU + + * gnus-start.el (gnus-read-init-file): Ditto. + + * gnus-agent.el (gnus-agent-fetch-session): Ditto. + + * dgnushack.el (dgnushack-make-load): Ditto. + + * mail-source.el (mail-source-fetch): Extract the right error + code. + + * message.el (message-fix-before-sending): Check illegible text. + + * gnus-util.el (gnus-multiple-choice): New function. + + * gnus-kill.el (gnus-score-insert-help): Removed, because it is + also defined in gnus-score.el. + +2002-03-01 Paul Jarc + + * message.el (message-get-reply-headers): downcase email addresses + for comaparisons for duplicate removal. + +2002-03-01 ShengHuo ZHU + + * mm-view.el (mm-view-pkcs7-verify): New function. A bogus + implementation of PKCS#7, which just allows users read the + message. + (mm-view-pkcs7): Use it. + +2002-02-27 ShengHuo ZHU + + * gnus.el (large-newsgroup-initial): New parameter. + + * gnus-sum.el (gnus-articles-to-read): Use large-newsgroup-initial. + (gnus-summary-insert-old-articles): Ditto. + +2002-02-26 ShengHuo ZHU + + * gnus-sum.el (gnus-articles-to-read): `gnus-large-newsgroup' is + used as the default answer of the question, "How many articles?". + From TSUCHIYA Masatoshi + + * nnagent.el (nnagent-retrieve-headers): Remove articles with + small numbers. + +2002-02-24 ShengHuo ZHU + + * deuglify.el: Fix comments. + +2002-02-23 ShengHuo ZHU + + * html2text.el (html2text-clean-anchor): If there is no HREF, + insert nothing. + + * mml.el (mml-generate-mime-1): Add cdr. + From: andre@slamdunknetworks.com + + * mm-view.el (mm-text-html-renderer-alist): Add html2text. + (mm-text-html-washer-alist): Ditto. + + * mm-decode.el (mm-text-html-renderer): Add html2text. + + * html2text.el: Face lift. + + * html2text.el: New file from Joakim Hove . + +2002-02-22 ShengHuo ZHU + + * gnus-sum.el: Add gnus-article-outlook-deuglify-article. + + * deuglify.el: Change copy right. Add autoload. Add coding-system. + + * deuglify.el: New file. The original file name is + gnus-outlook-deuglify.el from Raymond Scholz . + + * mm-decode.el (mm-display-external): Use + mm-file-name-rewrite-functions. From + +2002-02-22 Paul Jarc + + * nnmaildir.el (nnmaildir-request-list): Report the highest + article number, not the total number of articles. + +2002-02-21 ShengHuo ZHU + + * gnus-sum.el: Move uu key map here. + (gnus-summary-make-menu-bar): Add gnus-summary-save-parts. + +2002-02-21 Paul Jarc + + * nnmaildir.el (nnmaildir-request-expire-articles): Use + nnmail-expiry-wait* if expire-age parameter is not set. + +2002-02-21 ShengHuo ZHU + + * gnus-group.el (gnus-group-sort-groups-by-real-name): New + function. + (gnus-group-sort-selected-groups-by-real-name): New function. + (gnus-group-make-menu-bar): Add sort by real name. + + * gnus-sum.el (gnus-dependencies-add-header): If replaced, don't + rebuild. + (gnus-summary-edit-article-done): Gnus-get-newsgroup-headers takes + nil as dependencies as well. + +2002-02-20 ShengHuo ZHU + + * nndoc.el (nndoc-dissect-mime-parts-sub): Fix MIME-Version header + for mime-parts. + + * gnus-art.el (gnus-article-edit-done): Widen the buffer. + + * gnus-group.el (gnus-group-name-decode): Don't test + multibyte-string, because it breaks XEmacs. + From: TSUCHIYA Masatoshi + + * message.el (message-send-mail): Be talkative. + + * mm-decode.el (mm-inlined-types): Add application/x-emacs-lisp. + (mm-automatic-display): Ditto. + + * mailcap.el (mailcap-mime-data): Ditto. + From: Reiner Steib <4uce.02.r.steib@gmx.net> + +2002-02-20 Katsumi Yamaoka + + * many files: Remove trailing whitespaces, replace spc+tab with + tab, replace leading whitespaces with tabs. + +2002-02-19 Paul Jarc + + * gnus-sum.el (gnus-summary-toggle-header): Fix handling of + articles with no body and no blank line after the header. + +2002-02-19 ShengHuo ZHU + + * mm-decode.el (mm-dissect-multipart): Consider the case of empty + parts. + + * ietf-drums.el (ietf-drums-syntax-table): Modify syntax of + non-ascii chars. + + * rfc2231.el (rfc2231-parse-string): Support non-ascii chars. + + * gnus-art.el (gnus-article-wash-html-with-w3): Remove + w3-delay-image-loads. + * mm-view.el (mm-inline-text-html-render-with-w3): Ditto. + (mm-w3-prepare-buffer): Ditto. + + * mail-source.el (mail-source-fetch-directory): Run scripts. + +2002-02-19 Lars Magne Ingebrigtsen + + * gnus-fun.el (gnus-respond-to-confirmation): Do the right thing + for Majordomo confirmations. + +2002-02-18 Lars Magne Ingebrigtsen + + * gnus-fun.el (gnus-respond-to-confirmation): New command. + +2002-02-11 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-retrieve-headers): Clean up. + +2002-02-18 Paul Jarc + + * gnus-util.el (gnus-parent-id): Ignore trailing whitespace in the + References header field. From Mark Thomas . + +2002-02-18 ShengHuo ZHU + + * mm-view.el (mm-inline-render-with-file): With unibyte buffer. + (mm-inline-render-with-stdin): Ditto. + (mm-inline-render-with-function): Ditto. + (mm-inline-wash-with-file): Bind coding-system-for-write. + (mm-inline-wash-with-stdin): Ditto. + +2002-02-18 ShengHuo ZHU + + Suggested by Felix Natter + + * gnus-art.el (gnus-mime-view-part-externally): Rename from + gnus-mime-externalize-view. + (gnus-mime-view-part-internally): Rename from + gnus-mime-internalize-view. + (gnus-article-view-part-externally): Rename from + gnus-article-externalize-part. + (gnus-mime-action-alist): Change correspondingly. + (gnus-mime-button-commands): Ditto. + (gnus-mime-action-alist): Remove duplication. + + * gnus-sum.el (gnus-summary-mime-map): Change correspondingly. + +2002-02-18 ShengHuo ZHU + + * mm-decode.el (mm-dissect-buffer): Add loose-mime parameter. + + * gnus-art.el (gnus-display-mime): Use it. + + * mm-partial.el (mm-partial-find-parts): Use it. + + * gnus-sum.el (gnus-article-loose-mime): Rename from + gnus-article-no-strict-mime. + (gnus-summary-save-parts): Use it. + +2002-02-18 Katsumi Yamaoka + + * gnus-fun.el (gnus-convert-gray-x-face-to-xpm): Remove unused + local variable. + + * gnus-art.el (article-display-x-face): Don't sort multiple + X-Faces. + +2002-02-18 Katsumi Yamaoka + + * gnus-fun.el (gnus-convert-gray-x-face-to-xpm): Improved to speed + up. Suggested by Yuuichi Teranishi . + + * gnus-art.el (article-display-x-face): Sort gray X-Faces. + +2002-02-17 ShengHuo ZHU + + Some ideas is inspired by code from Hrvoje Niksic + + + * gnus-art.el (gnus-article-wash-function): Set the default to + nil, so that we use mm-text-html-renderer instead. + (article-wash-html): Use mm-text-html-renderer. + + * mm-decode.el (mm-inline-media-tests): Use mm-inline-text-*. + (mm-text-html-renderer): New variable. + (mm-inline-text-html-renderer): Set the default to nil, so that we + use mm-text-html-renderer instead. + + * mm-view.el (mm-inline-text-html): New function. + (mm-text-html-renderer-alist): New variable. + (mm-inline-text-vcard): New function. + (mm-inline-text): Split. + (mm-links-remove-leading-blank): New function. + (mm-inline-render-with-file): New function. + (mm-inline-render-with-stdin): New function. + (mm-inline-render-with-function): New function. + (mm-text-html-washer-alist): New variable. + (mm-inline-wash-with-file): New function. + (mm-inline-wash-with-stdin): New function. + +2002-02-17 ShengHuo ZHU + + * message-utils.el: Fix installation doc. + From: Reiner Steib <4uce.02.r.steib@gmx.net> + +2002-02-16 ShengHuo ZHU + + * gnus-msg.el (gnus-discouraged-post-methods): New variable. + (gnus-post-method): Use it. + (gnus-summary-cancel-article): Find the correct post-method. + + * gnus-soup.el (gnus-soup-send-packet): Via ... using ... + * message.el (message-send-news): Ditto. + Suggested by Lloyd Zusman and IPmonger + + + * gnus.el (gnus-select-method): Fix doc. + (gnus-server-string): Use 'using nntp'. + + * gnus-agent.el (gnus-slave-unplugged): New command. + From: Felix Natter + +2002-02-15 ShengHuo ZHU + + * gnus-art.el (gnus-article-edit-done): Kill-all-local-variables. + Call edit-done-function first, then change the window + configuration. + (gnus-article-edit-mode-map): Add message key bindings. Add menu. + (gnus-article-edit-mode): mml-mode. + + * gnus-util.el (gnus-byte-compile): Work around a bug in XEmacs + 21.4. Suggested by Russ Allbery . + + * message-utils.el: Adopt the file. + + * message-utils.el: New file. + From Holger Schauer + +2002-02-14 ShengHuo ZHU + + * gnus-sum.el (gnus-summary-move-article): Select-article only + when gnus-move-split-methods is non-nil. And we don't render or + mark the article. + + * gnus-fun.el (gnus-shell-command-to-string): New function. + (gnus-shell-command-on-region): New function. + (gnus-random-x-face): Use them. + (gnus-x-face-from-file): Ditto. + (gnus-convert-image-to-gray-x-face): Ditto. + (gnus-convert-gray-x-face-to-xpm): Ditto. + (gnus-convert-image-to-x-face-command): Don't use 2>/dev/null. + +2002-02-14 Katsumi Yamaoka + + * gnus-art.el (gnus-treat-display-xface): Don't use + `shell-command-to-string' when compiling. + (gnus-treat-display-grey-xface): Ditto. + +2002-02-13 Paul Jarc + + * nnmaildir.el (nnmaildir--article-count): If the group is + completely empty, report minimum article number as 1 instead of 0. + +2002-02-13 ShengHuo ZHU + + * gnus-agent.el (gnus-get-predicate): Use nconc. + + * gnus-sum.el (gnus-summary-display-make-predicate): Use + gnus-summary-display-cache as cache. + + * nndoc.el (nndoc-type-alist): Add mail-in-mail type. + (nndoc-mail-in-mail-type-p): New function. + (nndoc-mail-in-mail-article-begin): New function. + +2002-02-12 ShengHuo ZHU + + * mailcap.el (mailcap-mime-data): Use enriched-decode. + + * gnus-cite.el (gnus-article-fill-cited-article): Bind + use-hard-newlines to nil. + + * gnus-xmas.el (gnus-xmas-image-type-available-p): Assume that + image is not available if window-system is not available. + + * gnus-sum.el (gnus-summary-display-make-predicate): Add unread. + +2002-02-11 ShengHuo ZHU + + * gnus.el (gnus-article-unpropagated-mark-lists): Don't propagate + bookmark, because update-mark doesn't handle it correctly. + +2002-02-09 ShengHuo ZHU + + * gnus-soup.el (gnus-soup-send-packet): Send news and mail + directly instead of calling message-send-mail. + + * gnus-start.el (gnus-read-descriptions-file): Use + gnus-default-charset. + + * mm-util.el (mm-guess-mime-charset): New function. + + * gnus.el (gnus-default-charset): Use it. + (gnus-group-charset-alist): Remove .*, Let gnus-default-charset be + the default. + +2002-02-08 ShengHuo ZHU + + * gnus-art.el (gnus-treat-display-grey-xface): New variable. + (article-display-x-face): Use it. Disable grey xface, if + uncompface is not found. + + * message.el (message-mode): Don't enable multibyte on an indirect + buffer. + + * nnrss.el (nnrss-content-function): New variable. + (nnrss-request-article): Use it. + +2002-02-08 ShengHuo ZHU + + * gnus.el: Add article-unsplit-urls. + * gnus-sum.el: Ditto. + * gnus-art.el (gnus-treat-strip-cr): New variable. + (gnus-treatment-function-alist): Use it. + (article-unsplit-urls): New function. + (gnus-article-make-menu-bar): Use it. + From: Michael Cook + +2002-02-08 ShengHuo ZHU + + * gnus-agent.el (gnus-agent-braid-nov): Find the first article to + copy. + +2002-02-07 Paul Jarc + + * gnus-util.el (gnus-split-references): Allow (broken) Message-IDs + with internal whitespace. + (gnus-parent-id): Ditto. + +2002-02-07 ShengHuo ZHU + + * gnus-art.el (gnus-article-treat-body-boundary): Add + gnus-decoration property. + * gnus-msg.el (gnus-copy-article-buffer): Remove gnus-decoration. + + * message.el (message-mode): Set local-abbrev-table. + From Matt Armstrong . + + * gnus-art.el (gnus-article-treat-unfold-headers): Don't remove + too many spaces. + + * rfc2047.el (rfc2047-unfold-region): Ditto. + (rfc2047-decode-region): Don't unfold. Let + gnus-article-treat-unfold-headers do it. + + * gnus-sum.el (gnus-dependencies-add-header): Fix typo. + From: Jesper Harder + +2002-02-06 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-posting-styles): Add x-face-file. + (gnus-configure-posting-styles): Use it. + (gnus-configure-posting-styles): Remove trailing newspaces. + +2002-02-06 ShengHuo ZHU + + * gnus-sum.el (gnus-articles-to-read): Fetch all if the predicate + is non-nil. + + * mm-util.el (mm-use-find-coding-systems-region): Add doc. + + * gnus.el (gnus-server-to-method): Switch position with + gnus-server-get-method. + (gnus-agent): Add doc. + + * gnus-sum.el (gnus-article-no-strict-mime): New variable. + (gnus-summary-save-parts): Use it. + + * gnus-art.el (gnus-display-mime): Use it. + * mm-partial.el (mm-partial-find-parts): Use it. + + * nnweb.el (nnweb-google-parse-1): Use a correct format of date. + + * gnus-agent.el (gnus-agent-summary-make-menu-bar): Fix typo. + From Stefan Reich,Av(Br . + + * nnagent.el (nnagent-request-expire-articles): Don't delete + files. + +2002-02-05 ShengHuo ZHU + + * message.el (message-gen-unsubscribed-mft): New function. + From Sriram Karra . + + * gnus.el (gnus-article-unpropagated-mark-lists): Backslash the + open parenthesis. + + * mm-view.el (mm-w3-prepare-buffer): Bind url-gateway-unplugged. + (mm-inline-text-html-render-with-w3): Ditto. + * gnus-art.el (gnus-article-wash-html-with-w3): Ditto. + Suggested by Dave Love . + + * mm-url.el (mm-url-load-url): Require w3-vars for old versions. + + * nntp.el (nntp-send-command-and-decode): Check PROCESS. + * nntp.el (nntp-send-command): Ditto. + * nntp.el (nntp-send-command-nodelete): Ditto. + +2002-02-04 ShengHuo ZHU + + * mm-url.el (mm-url-load-url): New function. + (mm-url-insert-file-contents): Use it. + + * gnus-msg.el (gnus-summary-mail-forward): Use gnus-article-charset. + + * message.el (message-forward-make-body): Correctly copy + forward-buffer. + + * rfc2047.el (rfc2047-decode-region): Don't decode us-ascii characters. + +2002-02-04 Simon Josefsson + + * gnus-art.el (gnus-article-followup-with-original): Mark with + force, prevent errors when following up from article buffer. + (gnus-article-reply-with-original): Ditto. + + * binhex.el (binhex-decoder-switches): Fix doc. From + Pavel@Janik.cz (Pavel Jan,Bm(Bk). + +2002-02-04 ShengHuo ZHU + + * gnus-art.el (gnus-treatment-function-alist): Move hide-citation, + highlight-citation after emphasize. + +2002-02-04 Simon Josefsson + + * nnfolder.el (nnfolder-open-marks): + + * nnml.el (nnml-open-marks): Message when done. From David + Edmondson . + +2002-02-03 ShengHuo ZHU + + * imap.el (imap-anonymous-auth): Fix typo. + From: Steinar Bang + + * gnus-cache.el (gnus-cache-braid-nov): Use set-buffer instead of + save-excursion. + (gnus-cache-braid-heads): Ditto. + + * gnus-agent.el (gnus-agent-copy-nov-line): Move to the correct + line, because there are extra articles in the overview buffer. + + * nntp.el (nntp-retrieve-groups): Check whether BUF is live. + + * message.el (message-forward-rmail-make-body): Directly use + rmail-msg-restore-non-pruned-header to avoid calling + vertical-motion. + +2002-02-02 ShengHuo ZHU + + * gnus-cache.el (gnus-summary-insert-cached-articles): + (gnus-summary-limit-include-cached): gnus-newsgroup-cached is sorted. + + * gnus-group.el (gnus-group-mark-article-read): Nreverse + gnus-newsgroups-unselected. + + * gnus-agent.el (gnus-summary-set-agent-mark): Use + gnus-add-to-sorted-list. + + * gnus-sum.el (gnus-summary-update-info): gnus-newsgroup-unreads + gnus-newsgroup-unselected are sorted. Use gnus-sorted-union. + (gnus-build-all-threads): Use gnus-add-to-sorted-list. + (gnus-update-read-articles): UNREAD is sorted. + (gnus-newsgroup-unreads, gnus-newsgroup-unselected) + (gnus-newsgroup-marked, gnus-newsgroup-cached) + (gnus-newsgroup-expirable, gnus-newsgroup-downloadable) + (gnus-newsgroup-dormant): Require sorted. + + * gnus-dired.el (gnus-dired-find-file-mailcap): Correctly handle + directories. + (gnus-dired-print): New function. + + * gnus-art.el (gnus-mime-print-part): Add argument filename. Call + ps-despool. + +2002-02-02 Simon Josefsson + + * gnus-dired.el (turn-on-gnus-dired-mode): Autoload. Make defun. + +2002-02-02 ShengHuo ZHU + + * gnus-start.el (gnus-1): Call gnus-agentize if gnus-agent is + t. This makes gnus-agent customizable without putting + gnus-agentize into .gnus. + + * gnus.el (gnus-agent): Make it customizable. + + * gnus-dired.el: New file. + From Benjamin Rutt + + * gnus-cache.el (gnus-cache-articles-in-group): Remove from active + if no article. + (gnus-cache-possibly-remove-article): Ditto. + (gnus-cache-possibly-enter-article): Use gnus-add-to-sorted-list. + +2002-02-01 Simon Josefsson + + * gnus-int.el (gnus-request-accept-article): Use gnus-get-function. + +2002-02-01 Katsumi Yamaoka + + * mm-view.el (mm-w3m-mode-dont-bind-keys): New variable. + (mm-setup-w3m): Don't bind keys listed in the above. + +2002-02-01 Katsumi Yamaoka + + * mm-view.el (mm-inline-text-html-render-with-w3m): Bind + `w3m-safe-url-regexp' with nil if `mm-inline-text-html-with-images' + is non-nil; bind `w3m-force-redisplay' with nil. + + * gnus-art.el (gnus-article-wash-html-with-w3m): Ditto. + + * mm-decode.el (mm-inline-text-html-with-images): Supplement docs. + +2002-01-31 ShengHuo ZHU + + * nnfolder.el (nnfolder-request-replace-article): Unfold. Don't + use mail-header-unfold-field. + + * gnus-cache.el (gnus-summary-insert-cached-articles): Use + gnus-summary-limit. + + * gnus-range.el (gnus-add-to-sorted-list): New function. + * gnus-sum.el (gnus-mark-article-as-read): Use it. + (gnus-mark-article-as-unread): Ditto. + (gnus-summary-mark-article-as-unread): Ditto. + (gnus-build-get-header): Ditto. + (gnus-summary-prepare-threads): Ditto. + (gnus-summary-insert-pseudos): Ditto. + (gnus-articles-to-read): Use gnus-sorted-union and gnus-sorted-nunion. + (gnus-summary-insert-new-articles): Use gnus-sorted-nunion. + (gnus-summary-insert-old-articles): Ditto. + + * gnus-msg.el (gnus-posting-styles): Add new format of header. + (gnus-configure-posting-styles): Support the new format. + + * mail-source.el (mail-source-bind, mail-source-bind-common): Set + edebug-form-spec to (sexp body). + Suggested by Joe Wells . + + * message.el (message-reply-headers): Add doc. + +2002-01-30 ShengHuo ZHU + + * gnus-group.el (gnus-group-delete-group): Nix the entry in + gnus-cache-active-hashtb. + + * gnus-agent.el (gnus-agent-mark-unread-afer-downloaded): New variable. + (gnus-agent-summary-fetch-group): Use it. + + * gnus-msg.el (gnus-debug-files): New variable. + (gnus-debug-exclude-variables): New variable. + (gnus-debug): Use them. + + * gnus-range.el (gnus-range-length): Don't use gnus-uncompress-range. + +2002-01-30 ShengHuo ZHU + + * message.el (message-cite-prefix-regexp): Use text-mode-syntax-table. + (message-mode-syntax-table): Move back the previous position. + + * nnagent.el (nnagent-retrieve-headers): Use gnus-sorted-difference. + + * gnus-agent.el (gnus-agent-retrieve-headers): Use + gnus-sorted-difference. + + * nnsoup.el (nnsoup-request-expire-articles): Use + gnus-sorted-difference. + + * nnheader.el: Autoload gnus-sorted-difference. + + * nnfolder.el (nnfolder-request-expire-articles): Use + gnus-sorted-difference. + + * gnus-cache.el (gnus-cache-retrieve-headers): Use + gnus-sorted-difference. + + * gnus-range.el: Autoload cookies. + (gnus-sorted-difference): New function. + (gnus-sorted-ndifference): New function. + (gnus-sorted-nintersection): Rename from + gnus-set-sorted-intersection. + (gnus-sorted-nunion): Rename from gnus-set-sorted-union. + (gnus-list-range-difference): Rename from + gnus-inverse-list-range-intersection. + (gnus-inverse-list-range-intersection): Use defalias. + + * gnus-sum.el (gnus-select-newsgroup): Use gnus-sorted-difference, + gnus-sorted-ndifference, and gnus-sorted-nintersection. + (gnus-articles-to-read): Use gnus-sorted-difference. + (gnus-summary-limit-mark-excluded-as-read): Use + gnus-sorted-intersection and gnus-sorted-ndifference. + (gnus-list-of-read-articles): Use gnus-list-range-difference. + (gnus-summary-insert-articles): Use gnus-sorted-difference. + + * gnus-sum.el (gnus-summary-update-info): Use gnus-sorted-union. + +2002-01-30 Katsumi Yamaoka + + * gnus-art.el (gnus-article-wash-html-with-w3m): Add keymap + property to the buffer for using emacs-w3m command keys. + + * mm-decode.el (mm-inline-text-html-with-w3m-keymap): New user + option. + + * mm-view.el (mm-w3m-mode-map): New variable. + (mm-w3m-mode-command-alist): New variable. + (mm-w3m-minor-mode): Removed. + (mm-setup-w3m): Setup `mm-w3m-mode-map'; don't add minor mode. + (mm-inline-text-html-render-with-w3m): Add keymap property to the + buffer for using emacs-w3m command keys. + +2002-01-29 ShengHuo ZHU + + * message.el (message-mode-syntax-table): Move forward. + (message-cite-prefix-regexp): Auto detect non word constituents. + (message-cite-prefix-regexp): Don't use with-syntax-table. + + * gnus-sum.el (gnus-summary-update-info): Use + gnus-list-range-intersection. + + * gnus-agent.el (gnus-agent-fetch-headers): Use + gnus-list-range-intersection. + + * gnus-range.el (gnus-range-normalize): Use correct predicate. + (gnus-list-range-intersection): Use it. + (gnus-inverse-list-range-intersection): Ditto. + (gnus-sorted-intersection): Add doc. + (gnus-set-sorted-intersection): Add doc. + (gnus-sorted-union): New function. + (gnus-set-sorted-union): New function. + + * gnus-range.el (gnus-list-range-intersection): Correct the logic. + (gnus-inverse-list-range-intersection): Ditto. + +2002-01-29 Karl Kleinpaste + + * mm-uu.el (mm-uu-type-alist): Add optional leading `0'. + + * gnus-uu.el (gnus-uu-shar-name-marker): Add optional leading `0' + and permit `:' and `\' in order to handle full Windows pathnames. + (gnus-uu-begin-string): Add optional leading `0'. Leading `0' is + technically not correct per standard, but seems to have common use. + +2002-01-29 ShengHuo ZHU + + * gnus-uu.el (gnus-uu-expand-numbers): Ignore errors when + replacing numbers. + +2002-01-28 ShengHuo ZHU + + * gnus-art.el (gnus-article-followup-with-original): Use (mark). + + * gnus-score.el (gnus-score-insert-help): Move to (point-min). + Don't split when the window is small, e.g. when a small *BBDB* + window is the lowest one. + + * gnus-agent.el (gnus-agent-retrieve-headers): Use + nnheader-find-nov-line to speed up. Use nreverse, because it is + sorted. Use nnheader-insert-nov-file. + +2002-01-28 Katsumi Yamaoka + + * mm-decode.el (mm-inline-text-html-with-images): New user option. + + * mm-view.el (mm-inline-text-html-render-with-w3m): Bind the value + of `w3m-display-inline-images' with the value of + `mm-inline-text-html-with-images'. + From: TSUCHIYA Masatoshi . + + * gnus-art.el (gnus-article-wash-html-with-w3m): Ditto. + +2002-01-27 Richard M. Stallman + + * time-date.el: Add autoload cookies. Many doc fixes. + (time-add): New function. + (time-subtract): Renamed from subtract-time. + (subtract-time): New alias for time-subtract. + +2002-01-28 Katsumi Yamaoka + + * gnus-art.el (gnus-article-wash-html-with-w3m): Replace w3m to + emacs-w3m in doc-string. + + * lpath.el: Bind `w3m-cid-retrieve-function-alist' and + `w3m-current-buffer'. + +2002-01-27 TSUCHIYA Masatoshi + + * gnus-art.el (gnus-article-wash-html-with-w3m): Handle cid: URLs. + + * mm-view.el (mm-setup-w3m): Add `mm-w3m-cid-retrieve' to + `w3m-cid-retrieve-function-alist' for `gnus-article-mode'. + (mm-w3m-cid-retrieve): New function. + (mm-inline-text-html-render-with-w3m): Handle cid: URLs. + +2002-01-27 ShengHuo ZHU + + * gnus-agent.el (gnus-agent-fetch-articles): Don't save empty articles. + +2002-01-27 Lars Magne Ingebrigtsen + + * gnus-util.el (gnus-cache-file-contents): Don't use equalp. + +2002-01-26 Lars Magne Ingebrigtsen + + * nnheader.el (nnheader-insert-nov-file): Increased cutoff to + 32K. + + * gnus-sum.el (gnus-summary-expire-articles): Clean up. + + * nnmail.el (nnmail-article-group): Decode headers before running + split rules over them. + (nnmail-mail-splitting-charset): New variable. + + * smiley.el: Replaced with smiley-ems.el. + +2002-01-26 ShengHuo ZHU + + * mm-url.el (mm-url-predefined-programs): Add w3m. + (mm-url-program): Ditto. + +2002-01-26 Lars Magne Ingebrigtsen + + * nnml.el (nnml-use-compressed-files): New variable. + (nnml-filenames-are-evil): Removed. + (nnml-current-group-article-to-file-alist): Don't use. + (nnml-update-file-alist): Inhibit. + (nnml-article-to-file): Use new var. + +2002-01-26 ShengHuo ZHU + + * gnus-util.el (gnus-parse-without-error): Add edebug-form-spec. + + * nnagent.el (nnagent-retrieve-headers): loop until eobp. + +2002-01-26 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-load-alist): Use new caching + function. + + * gnus-util.el (gnus-cache-file-contents): New function. + + * gnus-agent.el (gnus-agent-file-loading-cache): New variable. + (gnus-agent-load-alist): Use it. + + * nnagent.el (nnagent-retrieve-headers): Use optimized function. + + * nnheader.el (nnheader-insert-nov-file): New function. + + * gnus-util.el (gnus-parse-without-error): Correct the loop. + + * gnus-sum.el (gnus-dependencies-add-header): Use in-reply-to if + there are no references. + (gnus-extract-message-id-from-in-reply-to): New function. + (gnus-nov-parse-line): Use in-reply-to if there are no + references. + +2002-01-25 Lars Magne Ingebrigtsen + + * nnagent.el (nnagent-retrieve-headers): Use new macro. + + * gnus-util.el (gnus-parse-without-error): New macro. + +2002-01-25 ShengHuo ZHU + + * gnus-art.el (gnus-article-wash-html-with-w3m): Call w3m-region. + (gnus-article-wash-function): use locate-library to decide which + to use. + +2002-01-25 Simon Josefsson + + * pop3.el (pop3-munge-message-separator): Work if no date. + Trivial patch from Marius Vollmer . + +2002-01-25 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-save-alist): Fix. + + * nnagent.el (nnagent-retrieve-headers): Must have cut too much by + mistake. Reinstated lost code. + +2002-01-25 Josh Huber + + * mml2015.el (mml2015-mailcrypt-decrypt): Display a signature if + one exists in the case of an encrypted message with an internal + signature. + +2002-01-25 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-save-alist): Optimized. + +2002-01-25 Katsumi Yamaoka + + * dgnushack.el: Commented out the experimental code. + +2002-01-25 Lars Magne Ingebrigtsen + + * gnus-range.el (gnus-inverse-list-range-intersection): Off-by-one + error. + + * gnus.el (gnus-server-to-method): Made into subst. + (gnus-server-method-cache): New variable. + (gnus-server-to-method): Use it. + (gnus-group-method-cache): New variable. + (gnus-find-method-for-group-1): Renamed. + (gnus-find-method-for-group): New function. + (gnus-group-method-cache): Removed. + + * gnus-sum.el (gnus-compute-unseen-list): Use new optimized + function. + + * gnus-range.el (gnus-members-of-range): New function. + (gnus-list-range-intersection): Renamed. + (gnus-inverse-list-range-intersection): New function. + + * gnus-sum.el (gnus-compute-unseen-list): Made into own function. + + * nnagent.el (nnagent-retrieve-headers): New implementation. + + * gnus-agent.el (gnus-agent-get-undownloaded-list): New, faster + implementation. + +2002-01-25 Katsumi Yamaoka + + * lpath.el: Fbind `w3m-charset-to-coding-system'; bind + `w3m-meta-content-type-charset-regexp'. + + * mm-view.el (mm-inline-text-html-render-with-w3m): Decode + charset-encoded html contents. + +2002-01-24 ShengHuo ZHU + + * gnus-agent.el (gnus-agent-request-article): Make sure it is not + an empty file. + + * nnweb.el (url): Ignore errors when request url. + + * nnrss.el: Clean up the comments. + +2002-01-24 Katsumi Yamaoka + + * lpath.el: Fbind `w3m-region'; bind `w3m-mode-map'. + + * mm-decode.el (mm-inline-text-html-renderer): New user option. + (mm-inline-media-tests): Test whether the value of + `mm-inline-text-html-renderer' is a function for text/html. + + * mm-view.el (mm-inline-text-html-render-with-w3): New function + separated from `mm-inline-text'. + (mm-w3m-minor-mode): New variable. + (mm-w3m-setup): New variable. + (mm-setup-w3m): New function. + (mm-inline-text-html-render-with-w3m): New function. + (mm-inline-text): Funcall `mm-inline-text-html-renderer' for + text/html. + +2002-01-23 Paul Jarc + + * lpath.el: fbind make-symbolic-link and unix-sync for nnmaildir. + +2002-01-23 Katsumi Yamaoka + + * gnus-xmas.el (gnus-xmas-redefine): Quote `gnus-completing-read' + and `gnus-xmas-completing-read'. + +2002-01-19 TSUCHIYA Masatoshi + + * nneething.el (nneething-message-id-number): Abolished. + (nneething-encode-file-name): Not encode numerical characters. + (nneething-make-head): `nneething-message-id-number' is not + used to generate message IDs. + +2002-01-23 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-emphasis-alist): Include !? as sentence-ending + characters. + +2002-01-22 Lars Magne Ingebrigtsen + + * gnus-xmas.el (gnus-xmas-completing-read): New function. + (gnus-xmas-redefine): Redefine conditionally. + +2002-01-22 Josh Huber + + * mml.el (mml-parse-1): Fixed usage of recipients in the secure + tag. + +2002-01-22 Josh Huber + + * message.el (message-font-lock-keywords): Added the secure tag. + * mml-sec.el: Added functions to generate/modify/remove the secure + tag while in message mode. + * mml-sec.el (mml-secure-message): New. + * mml-sec.el (mml-unsecure-message): New. + * mml-sec.el (mml-secure-message-sign-smime): New. + * mml-sec.el (mml-secure-message-sign-pgp): New. + * mml-sec.el (mml-secure-message-sign-pgpmime): New. + * mml-sec.el (mml-secure-message-encrypt-smime): New. + * mml-sec.el (mml-secure-message-encrypt-pgp): New. + * mml-sec.el (mml-secure-message-encrypt-pgpmime): New. + * mml.el (mml-parse-1): Added code to recognise the secure tag and + convert it to either a part or multipart depending on if there are + other parts in the message. + * mml.el (mml-mode-map): Changed default sign/encrypt keybindings + to use the secure tag, rather than the part tag. + * mml.el (mml-preview): Added a save-excursion to keep cursor + position after doing an MML preview. + +2002-01-22 Lars Magne Ingebrigtsen + + * nnheader.el (nnheader-parse-overview-file): New function. + (nnheader-write-overview-file): New function. + +2002-01-21 Lars Magne Ingebrigtsen + + * gnus.el (gnus-group-fast-parameter): Check better if expansion + in wanted. + + * nnweb.el (nnweb-type-definition): Clean up. + +2002-01-21 Alastair Burt + + * gnus-art.el (gnus-mm-display-part): Make sure that the summary + buffer exists before jumping to it. + +2002-01-21 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-wash-html-with-w3): Made into own + function. + (article-wash-html): Use it. + (gnus-article-wash-function): New variable. + (gnus-article-wash-html-with-w3m): New function. + +2002-01-20 Bj,Av(Brn Torkelsson + + * dgnushack.el (dgnushack-compile): Compile smiley-ems for + XEmacs. + +2002-01-20 John H. Palmieri + + * gnus-fun.el (gnus-convert-image-to-gray-x-face): More standard + command line. + +2002-01-21 Simon Josefsson + + * canlock.el (base64-encode-string): Autoload it from base64. + (canlock-make-cancel-key): Base64 encode unibyte string. + +2002-01-20 Lars Magne Ingebrigtsen + + * nnfolder.el (nnfolder-request-accept-article): Unfold + x-from-line. + (nnfolder-request-replace-article): Ditto. + +2002-01-20 Nevin Kapur + + * gnus-group.el (gnus-group-best-unread-group): Use the right + positioning function. + +2002-01-20 Lars Magne Ingebrigtsen + + * smiley-ems.el (smiley-region): Use new function. + (smiley-update-cache): Use general image functions. + (smiley-region): Use general functions. + + * gnus-util.el (gnus-graphic-display-p): New function. + + * nnmail.el (nnmail-article-group): Allow outputting traces of + non-strings. + + * nndoc.el (nndoc-type-alist): Rules for exim bounces. + (nndoc-exim-bounce-type-p): New function. + + * message.el (message-dont-send): Doc fix. + + * gnus-util.el (gnus-completing-read): Remove + inherit-input-method. + + * gnus-art.el (gnus-treat-smiley): Doc fix. + + * gnus-agent.el (gnus-agent-fetch-headers): Ignore seen and recent + articles. + +2002-01-19 Simon Josefsson + + * imap.el (imap-gssapi-open): Don't wait for logout to complete. + (imap-kerberos4-open): Ditto. + (imap-open): Set port correctly, don't set auth. + +2002-01-20 Lars Magne Ingebrigtsen + + * gnus.el (gnus-version-number): Bump version number. + 2002-01-20 05:33:30 Lars Magne Ingebrigtsen * gnus.el: Oort Gnus v0.05 is released. @@ -5,12 +1665,12 @@ 2002-01-20 Lars Magne Ingebrigtsen * nnkiboze.el (nnkiboze-generate-group): Make sure the directory - exists. + exists. * gnus-spec.el (gnus-string-width-function): New function. (gnus-tilde-cut-form): Use it. (gnus-tilde-max-form): Ditto. - (gnus-use-correct-string-widths): Default to (featurep 'xemacs). + (gnus-use-correct-string-widths): Default to (featurep 'xemacs). (gnus-substring-function): Use it. (gnus-tilde-cut-form): Ditto. (gnus-substring-function): New function. @@ -35,14 +1695,14 @@ 2002-01-19 Daniel Pittman * gnus-sum.el (gnus-summary-first-unseen-or-unread-subject): New - functions. + functions. 2002-01-19 Lars Magne Ingebrigtsen - * gnus.el (gnus-group-find-parameter): Clean up. + * gnus.el (gnus-group-find-parameter): Clean up. * gnus-sum.el (gnus-summary-goto-subject): Error on non-numerical - articles. + articles. * gnus-util.el (gnus-completing-read-with-default): Renamed. @@ -50,7 +1710,7 @@ 2002-01-19 Paul Stodghill - * gnus-agent.el (gnus-category-name): Intern the category name. + * gnus-agent.el (gnus-category-name): Intern the category name. 2002-01-19 Lars Magne Ingebrigtsen @@ -149,20 +1809,20 @@ 2002-01-16 Lars Magne Ingebrigtsen * gnus-sum.el (gnus-summary-initial-limit): Inline - gnus-summary-limit-children. + gnus-summary-limit-children. (gnus-summary-initial-limit): Don't limit if gnus-newsgroup-display is nil. (gnus-summary-initial-limit): No, don't. * gnus-util.el (gnus-put-text-property-excluding-characters-with-faces): Inline - gnus-put-text-property. + gnus-put-text-property. * gnus-spec.el (gnus-default-format-specs): New variable. * gnus-start.el (gnus-read-newsrc-file): Don't clear - gnus-format-specs. - (gnus-read-newsrc-el-file): Default to gnus-default-format-specs. + gnus-format-specs. + (gnus-read-newsrc-el-file): Default to gnus-default-format-specs. * gnus-spec.el (gnus-update-format-specifications): Really check the Gnus version of the .newsrc.eld file. @@ -172,9 +1832,9 @@ before splitting. * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): Inline some - functions. + functions. (gnus-gather-threads-by-references): Inline - `gnus-split-references'. + `gnus-split-references'. * gnus-spec.el (gnus-summary-line-format-spec): New, optimized default value of gnus-summary-line-format-spec. @@ -220,7 +1880,7 @@ * gnus.el: We don't need gnus-article-show-all-headers. - * gnus-art.el (article-show-all, gnus-article-show-all-header): + * gnus-art.el (article-show-all, gnus-article-show-all-header): Ditto. * gnus-sum.el (gnus-summary-select-article): Don't call @@ -266,7 +1926,7 @@ 2002-01-12 Simon Josefsson - * nnimap.el (nnimap-need-unselect-to-notice-new-mail) + * nnimap.el (nnimap-need-unselect-to-notice-new-mail) (nnimap-before-find-minmax-bugworkaround): Use it. (nnimap-find-minmax-uid): Don't reselect current mailbox. (nnimap-dont-close): New variable. @@ -275,13 +1935,13 @@ 2002-01-12 Lars Magne Ingebrigtsen * gnus-art.el (gnus-article-reply-with-original): Use - `mark-active'. + `mark-active'. - * gnus-msg.el (gnus-summary-reply): Don't bug out on regions. + * gnus-msg.el (gnus-summary-reply): Don't bug out on regions. * gnus-logic.el (gnus-advanced-score-rule): Thinko fix. (gnus-score-advanced): Clean up. - (gnus-score-advanced): Accept a multiple of the score. + (gnus-score-advanced): Accept a multiple of the score. 2002-01-12 Simon Josefsson @@ -308,7 +1968,7 @@ * gnus-sum.el (gnus-summary-buffer-name): Return the dead name if it exists. (gnus-summary-setup-buffer): Wake up dead summary buffers. - (gnus-summary-buffer-name): Don't return the dead name after all. + (gnus-summary-buffer-name): Don't return the dead name after all. (gnus-summary-setup-buffer): Kill the dead buffer. * gnus-art.el (gnus-article-followup-with-original): Store the @@ -318,14 +1978,14 @@ * gnus-fun.el (gnus-display-x-face-in-from): Fake it. From: Karl Kleinpaste - + * gnus-art.el (article-display-x-face): Ditto. (gnus-article-reply-with-original): Use gnus-region-active-p. (gnus-article-followup-with-original): Ditto. * gnus-sum.el (gnus-summary-read-group-1): Don't select downloadable article either. - + 2002-01-11 ShengHuo ZHU * gnus-art.el (article-display-x-face): Insert From:. @@ -335,7 +1995,7 @@ gnus-article-prepare-hook. * gnus-agent.el (gnus-agent-retrieve-headers): Load agentview. - (gnus-agent-toggle-plugged): Use gnus-agent-go-online. Move + (gnus-agent-toggle-plugged): Use gnus-agent-go-online. Move gnus-agent-possibly-synchronize-flags to the last. (gnus-agent-go-online): New function. New variable. @@ -346,7 +2006,7 @@ 2002-01-11 ShengHuo ZHU - * message.el (message-ignored-news-headers) + * message.el (message-ignored-news-headers) (message-ignored-mail-headers): Add X-Gnus-Agent-Meta-Information:. Suggested by ARISAWA Akihiro @@ -356,7 +2016,7 @@ (gnus-agent-regenerate): Show messages. 2002-01-11 ShengHuo ZHU - + * gnus-agent.el (gnus-agent-regenerate-group): New function. (gnus-agent-regenerate): New function. (gnus-agent-save-alist): Sort. @@ -401,7 +2061,7 @@ * nnagent.el (nnagent-retrieve-headers): Don't use nnml function. Insert undownloaded NOV. - + * gnus-agent.el (gnus-agent-retrieve-headers): New function. (gnus-agent-request-article): New function. @@ -412,7 +2072,7 @@ (gnus-request-head): Use gnus-agent-request-article. (gnus-request-body): Ditto. - * gnus-art.el (gnus-request-article-this-buffer): Use + * gnus-art.el (gnus-request-article-this-buffer): Use gnus-agent-request-article. * gnus-sum.el (gnus-summary-read-group-1): Don't show the first @@ -836,7 +2496,7 @@ (gnus-convert-image-to-gray-x-face): Ditto. * gnus-sum.el (gnus-summary-make-menu-bar): Add a :keys to - gnus-summary0show-raw-article. + gnus-summary-show-raw-article. 2002-01-02 ShengHuo ZHU @@ -1256,7 +2916,7 @@ 2001-12-29 Lars Magne Ingebrigtsen * gnus-art.el (gnus-treat-unfold-lines): New variable. - (gnus-treat-unfold-headers): Remamed. + (gnus-treat-unfold-headers): Renamed. (gnus-article-treat-unfold-headers): New command and keystroke. * rfc2047.el (rfc2047-encode-message-header): Clean up. @@ -1671,7 +3331,7 @@ 2001-12-03 11:00:00 ShengHuo ZHU * pop3.el (pop3-munge-message-separator): Only use valid date. - From Michael Welsh Duggan . + Trivial patch from Michael Welsh Duggan . * Makefile.in: gnus-load.elc may not be generated. @@ -7833,7 +9493,7 @@ * gnus-sum.el (gnus-summary-edit-article): Remove a hack. * gnus-art.el (gnus-mime-save-part-and-strip): New function. (gnus-mime-action-alist): Use it. - (gnus-mime-button-commands): USe it. + (gnus-mime-button-commands): Use it. * mm-extern.el (mm-extern-local-file): Error when the file is gone. (mm-inline-external-body): unwind-protect. @@ -7935,7 +9595,7 @@ 2000-10-31 Katsumi Yamaoka * gnus-sum.el (gnus-summary-insert-line): Work with quoted - double-quote charcters. + double-quote characters. (gnus-summary-prepare-threads): Ditto. 2000-10-31 08:36:03 ShengHuo ZHU @@ -8160,6 +9820,10 @@ * ChangeLog: Moved to ChangeLog.1. + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Copying and distribution of this file, with or without modification, + are permitted provided the copyright notice and this notice are preserved. + ;; Local Variables: ;; coding: iso-2022-7bit ;; End: diff --git a/lisp/ChangeLog.1 b/lisp/ChangeLog.1 index 3cfb883..c88d229 100644 --- a/lisp/ChangeLog.1 +++ b/lisp/ChangeLog.1 @@ -10095,6 +10095,10 @@ Sat Aug 29 19:32:06 1998 Lars Magne Ingebrigtsen * gnus.el: Gnus v0.2 is released. + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + Copying and distribution of this file, with or without modification, + are permitted provided the copyright notice and this notice are preserved. + ;; Local Variables: ;; coding: iso-2022-7bit ;; End: diff --git a/lisp/binhex.el b/lisp/binhex.el index 120821f..8cdd747 100644 --- a/lisp/binhex.el +++ b/lisp/binhex.el @@ -1,5 +1,5 @@ ;;; binhex.el --- elisp native binhex decode -;; Copyright (c) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +;; Copyright (c) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu ;; Keywords: binhex news @@ -43,11 +43,11 @@ input and write the converted data to its standard output." :group 'gnus-extract) (defcustom binhex-decoder-switches '("-d") - "*List of command line flags passed to the command named by binhex-decoder-program." + "*List of command line flags passed to the command `binhex-decoder-program'." :group 'gnus-extract :type '(repeat string)) -(defcustom binhex-use-external +(defcustom binhex-use-external (executable-find binhex-decoder-program) "*Use external binhex program." :group 'gnus-extract @@ -277,7 +277,7 @@ If HEADER-ONLY is non-nil only decode header and return filename." (interactive "r") (let ((cbuf (current-buffer)) firstline work-buffer status (file-name (expand-file-name - (concat (binhex-decode-region-internal start end t) + (concat (binhex-decode-region-internal start end t) ".data") binhex-temporary-file-directory))) (save-excursion @@ -315,7 +315,7 @@ If HEADER-ONLY is non-nil only decode header and return filename." (defun binhex-decode-region (start end) "Binhex decode region between START and END." (interactive "r") - (if binhex-use-external + (if binhex-use-external (binhex-decode-region-external start end) (binhex-decode-region-internal start end))) diff --git a/lisp/canlock.el b/lisp/canlock.el index 845095f..13e7fbc 100644 --- a/lisp/canlock.el +++ b/lisp/canlock.el @@ -40,12 +40,11 @@ ;;; Code: -(defconst canlock-version "0.8") - (eval-when-compile (require 'cl)) (autoload 'sha1-binary "sha1-el") +(autoload 'base64-encode-string "base64") (defgroup canlock nil "The Cancel-Lock feature." @@ -96,13 +95,6 @@ buffer does not look like a news message." :type 'boolean :group 'canlock) -(eval-when-compile - (defmacro canlock-string-as-unibyte (string) - "Return a unibyte string with the same individual bytes as STRING." - (if (fboundp 'string-as-unibyte) - (list 'string-as-unibyte string) - string))) - (defun canlock-sha1-with-openssl (message) "Make a SHA-1 digest of MESSAGE using OpenSSL." (let (default-enable-multibyte-characters) @@ -116,11 +108,22 @@ buffer does not look like a news message." canlock-openssl-program t t nil canlock-openssl-args) (goto-char (point-min)) (insert "\"") - (while (re-search-forward "[0-9a-f][0-9a-f]" nil t) - (replace-match (concat "\\\\x" (match-string 0)))) + (while (re-search-forward "\\([0-9a-f][0-9a-f]\\)" nil t) + (replace-match "\\\\x\\1")) (insert "\"") (goto-char (point-min)) - (canlock-string-as-unibyte (read (current-buffer))))))) + (read (current-buffer)))))) + +(eval-when-compile + (defmacro canlock-string-as-unibyte (string) + "Return a unibyte string with the same individual bytes as STRING." + (if (fboundp 'string-as-unibyte) + (list 'string-as-unibyte string) + string))) + +(defun canlock-sha1 (message) + "Make a SHA-1 digest of MESSAGE as a unibyte string of length 20 bytes." + (canlock-string-as-unibyte (funcall canlock-sha1-function message))) (defvar canlock-read-passwd nil) (defun canlock-read-passwd (prompt &rest args) @@ -140,26 +143,20 @@ If ARGS, PROMPT is used as an argument to `format'." (defun canlock-make-cancel-key (message-id password) "Make a Cancel-Key header." - (cond ((> (length password) 20) - (setq password (funcall canlock-sha1-function password))) - ((< (length password) 20) - (setq password (concat - password - (make-string (- 20 (length password)) 0))))) - (setq password (concat password (make-string 44 0))) - (let ((ipad (mapconcat (lambda (char) - (char-to-string (logxor 54 char))) + (when (> (length password) 20) + (setq password (canlock-sha1 password))) + (setq password (concat password (make-string (- 64 (length password)) 0))) + (let ((ipad (mapconcat (lambda (byte) + (char-to-string (logxor 54 byte))) password "")) - (opad (mapconcat (lambda (char) - (char-to-string (logxor 92 char))) + (opad (mapconcat (lambda (byte) + (char-to-string (logxor 92 byte))) password ""))) (base64-encode-string - (funcall canlock-sha1-function - (concat - opad - (funcall canlock-sha1-function - (concat ipad - (canlock-string-as-unibyte message-id)))))))) + (canlock-sha1 + (concat opad + (canlock-sha1 + (concat ipad (canlock-string-as-unibyte message-id)))))))) (defun canlock-narrow-to-header () "Narrow the buffer to the head of the message." @@ -250,8 +247,7 @@ message." (insert "Cancel-Key: sha1:" key-for-key "\n")) (when key-for-lock (insert "Cancel-Lock: sha1:" - (base64-encode-string (funcall canlock-sha1-function - key-for-lock)) + (base64-encode-string (canlock-sha1 key-for-lock)) "\n"))))))))) ;;;###autoload @@ -307,9 +303,9 @@ nil instead of to signal an error by setting the option (when locks (when id-for-lock (setq key-for-lock - (base64-encode-string (funcall canlock-sha1-function - (canlock-make-cancel-key - id-for-lock password)))) + (base64-encode-string + (canlock-sha1 (canlock-make-cancel-key id-for-lock + password)))) (when (and locks (not match)) (setq match (string-equal key-for-lock (pop locks))))) (setq locks (if match "good" "bad"))) diff --git a/lisp/deuglify.el b/lisp/deuglify.el new file mode 100644 index 0000000..e3a9bf3 --- /dev/null +++ b/lisp/deuglify.el @@ -0,0 +1,441 @@ +;;; deuglify.el --- deuglify broken Outlook (Express) articles + +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; Copyright (C) 2001,2002 Raymond Scholz + +;; Author: Raymond Scholz +;; Thomas Steffen (unwrapping algorithm, +;; based on an idea of Stefan Monnier) +;; Keywords: mail, news + +;; 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: + +;; This file enables Gnus to repair broken citations produced by +;; common user agents like MS Outlook (Express). It may repair +;; articles of other user agents too. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; Outlook sometimes wraps cited lines before sending a message as +;; seen in this example: +;; +;; Example #1 +;; ---------- +;; +;; John Doe wrote: +;; +;; > This sentence no verb. This sentence no verb. This sentence +;; no +;; > verb. This sentence no verb. This sentence no verb. This +;; > sentence no verb. +;; +;; The function `gnus-outlook-unwrap-lines' tries to recognize those +;; erroneously wrapped lines and will unwrap them. I.e. putting the +;; wrapped parts ("no" in this example) back where they belong (at the +;; end of the cited line above). +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Note that some people not only use broken user agents but also +;; practice a bad citation style by omitting blank lines between the +;; cited text and their own text. +;: +;; Example #2 +;; ---------- +;; +;; John Doe wrote: +;; +;; > This sentence no verb. This sentence no verb. This sentence no +;; You forgot in all your sentences. +;; > verb. This sentence no verb. This sentence no verb. This +;; > sentence no verb. +;; +;; Unwrapping "You forgot in all your sentences." would be illegal as +;; this part wasn't intended to be cited text. +;; `gnus-outlook-unwrap-lines' will only unwrap lines if the resulting +;; citation line will be of a certain maximum length. You can control +;; this by adjusting `gnus-outlook-deuglify-unwrap-max'. Also +;; unwrapping will only be done if the line above the (possibly) +;; wrapped line has a minimum length of `gnus-outlook-deuglify-unwrap-min'. +;; +;; Furthermore no unwrapping will be undertaken if the last character +;; is one of the chars specified in +;; `gnus-outlook-deuglify-unwrap-stop-chars'. Setting this to ".?!" +;; inhibits unwrapping if the cited line ends with a full stop, +;; question mark or exclamation mark. Note that this variable +;; defaults to `nil', triggering a few false positives but generally +;; giving you better results. +;; +;; Unwrapping works on every level of citation. Thus you will be able +;; repair broken citations of broken user agents citing broken +;; citations of broken user agents citing broken citations... +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Citations are commonly introduced with an attribution line +;; indicating who wrote the cited text. Outlook adds superfluous +;; information that can be found in the header of the message to this +;; line and often wraps it. +;; +;; If that weren't enough, lots of people write their own text above +;; the cited text and cite the complete original article below. +;; +;; Example #3 +;; ---------- +;; +;; Hey, John. There's no in all your sentences! +;; +;; John Doe wrote in message +;; news:a87usw8$dklsssa$2@some.news.server... +;; > This sentence no verb. This sentence no verb. This sentence +;; no +;; > verb. This sentence no verb. This sentence no verb. This +;; > sentence no verb. +;; > +;; > Bye, John +;; +;; Repairing the attribution line will be done by function +;; `gnus-outlook-repair-attribution' which calls other function that +;; try to recognize and repair broken attribution lines. See variable +;; `gnus-outlook-deuglify-attrib-cut-regexp' for stuff that should be +;; cut off from the beginning of an attribution line and variable +;; `gnus-outlook-deuglify-attrib-verb-regexp' for the verbs that are +;; required to be found in an attribution line. These function return +;; the point where the repaired attribution line starts. +;; +;; Rearranging the article so that the cited text appears above the +;; new text will be done by function +;; `gnus-outlook-rearrange-citation'. This function calls +;; `gnus-outlook-repair-attribution' to find and repair an attribution +;; line. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Well, and that's what the message will look like after applying +;; deuglification: +;; +;; Example #3 (deuglified) +;; ----------------------- +;; +;; John Doe wrote: +;; +;; > This sentence no verb. This sentence no verb. This sentence no +;; > verb. This sentence no verb. This sentence no verb. This +;; > sentence no verb. +;; > +;; > Bye, John +;; +;; Hey, John. There's no in all your sentences! +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Usage +;; ----- +;; +;; Press `W k' in the Summary Buffer. +;; +;; Non recommended usage :-) +;; --------------------- +;; +;; To automatically invoke deuglification on every article you read, +;; put something like that in your .gnus: +;; +;; (add-hook 'gnus-article-decode-hook 'gnus-outlook-unwrap-lines) +;; +;; or _one_ of the following lines: +;; +;; ;; repair broken attribution lines +;; (add-hook 'gnus-article-decode-hook 'gnus-outlook-repair-attribution) +;; +;; ;; repair broken attribution lines and citations +;; (add-hook 'gnus-article-decode-hook 'gnus-outlook-rearrange-citation) +;; +;; Note that there always may be some false positives, so I suggest +;; using the manual invocation. After deuglification you may want to +;; refill the whole article using `W w'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Limitations +;; ----------- +;; +;; As I said before there may (or will) be a few false positives on +;; unwrapping cited lines with `gnus-outlook-unwrap-lines'. +;; +;; `gnus-outlook-repair-attribution' will only fix the first +;; attribution line found in the article. Furthermore it fixed to +;; certain kinds of attributions. And there may be horribly many +;; false positives, vanishing lines and so on -- so don't trust your +;; eyes. Again I recommend manual invocation. +;; +;; `gnus-outlook-rearrange-citation' carries all the limitations of +;; `gnus-outlook-repair-attribution'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; See ChangeLog for other changes. +;; +;; Revision 1.5 2002/01/27 14:39:17 rscholz +;; * New variable `gnus-outlook-deuglify-no-wrap-chars' to inhibit +;; unwrapping if one these chars is first in the possibly wrapped line. +;; * Improved rearranging of the article. +;; * New function `gnus-outlook-repair-attribution-block' for repairing +;; those big "Original Message (following some headers)" attributions. +;; +;; Revision 1.4 2002/01/03 14:05:00 rscholz +;; Renamed `gnus-outlook-deuglify-article' to +;; `gnus-article-outlook-deuglify-article'. +;; Made it easier to deuglify the article while being in Gnus' Article +;; Edit Mode. (suggested by Phil Nitschke) +;; +;; +;; Revision 1.3 2002/01/02 23:35:54 rscholz +;; Fix a bug that caused succeeding long attribution lines to be +;; unwrapped. Minor doc fixes and regular expression tuning. +;; +;; Revision 1.2 2001/12/30 20:14:34 rscholz +;; Clean up source. +;; +;; Revision 1.1 2001/12/30 20:13:32 rscholz +;; Initial revision +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Code: + +(require 'gnus-art) +(require 'gnus-sum) + +(defconst gnus-outlook-deuglify-version "1.5 Gnus version" + "Version of gnus-outlook-deuglify.") + +;;; User Customizable Variables: + +(defgroup gnus-outlook-deuglify nil + "Deuglify articles generated by broken user agents like MS +Outlook (Express).") + +;;;###autoload +(defcustom gnus-outlook-deuglify-unwrap-min 45 + "Minimum length of the cited line above the (possibly) wrapped line." + :type 'number + :group 'gnus-outlook-deuglify) + +;;;###autoload +(defcustom gnus-outlook-deuglify-unwrap-max 95 + "Maximum length of the cited line after unwrapping." + :type 'number + :group 'gnus-outlook-deuglify) + +(defcustom gnus-outlook-deuglify-cite-marks ">|#%" + "Characters that indicate cited lines." + :type 'string + :group 'gnus-outlook-deuglify) + +(defcustom gnus-outlook-deuglify-unwrap-stop-chars nil ;; ".?!" or nil + "Characters that inhibit unwrapping if they are the last one on the +cited line above the possible wrapped line." + :type 'string + :group 'gnus-outlook-deuglify) + +(defcustom gnus-outlook-deuglify-no-wrap-chars "`" + "Characters that inhibit unwrapping if they are the first one in the +possibly wrapped line." + :type 'string + :group 'gnus-outlook-deuglify) + +(defcustom gnus-outlook-deuglify-attrib-cut-regexp + "\\(On \\|Am \\)?\\(Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\|Sun\\),[^,]+, " + "Regular expression matching the beginning of an attribution line +that should be cut off." + :type 'string + :group 'gnus-outlook-deuglify) + +(defcustom gnus-outlook-deuglify-attrib-verb-regexp + "wrote\\|writes\\|says\\|schrieb\\|schreibt\\|meinte\\|skrev\\|a écrit\\|schreef" + "Regular expression matching the verb used in an attribution line." + :type 'string + :group 'gnus-outlook-deuglify) + +(defcustom gnus-outlook-deuglify-attrib-end-regexp + ": *\\|\\.\\.\\." + "Regular expression matching the end of an attribution line." + :type 'string + :group 'gnus-outlook-deuglify) + + +;; Functions + +;; TODO: don't kill MIME parts +;;;###autoload +(defun gnus-outlook-unwrap-lines () + "Unwrap lines that appear to be wrapped citation lines. You can +control what lines will be unwrapped by frobbing +`gnus-outlook-deuglify-unwrap-min' and +`gnus-outlook-deuglify-unwrap-max', indicating the miminum and maximum +length of an unwrapped citation line." + (interactive) + (save-excursion + (let ((case-fold-search nil) + (inhibit-read-only t) + (cite-marks gnus-outlook-deuglify-cite-marks) + (no-wrap gnus-outlook-deuglify-no-wrap-chars) + (stop-chars gnus-outlook-deuglify-unwrap-stop-chars)) + (gnus-with-article-buffer + (article-goto-body) + (while (re-search-forward + (concat + "^\\([ \t" cite-marks "]*\\)" + "\\([" cite-marks "].*[^\n " stop-chars "]\\)[ \t]?\n" + "\\1\\([^\n " cite-marks no-wrap "]+.*\\)$") + nil t) + (let ((len12 (- (match-end 2) (match-beginning 1))) + (len3 (- (match-end 3) (match-beginning 3)))) + (if (and (> len12 gnus-outlook-deuglify-unwrap-min) + (< (+ len12 len3) gnus-outlook-deuglify-unwrap-max)) + (progn + (replace-match "\\1\\2 \\3") + (goto-char (match-beginning 0)))))))))) + +;; TODO: respect signatures, don't kill MIME parts +(defun gnus-outlook-rearrange-article (from-where) + "Put the text from `from-where' to the end of buffer at the top of +the article buffer." + (save-excursion + (let ((inhibit-read-only t) + (cite-marks gnus-outlook-deuglify-cite-marks)) + (gnus-with-article-buffer + (unless (search-forward-regexp + (concat "^[ \t]*[^" cite-marks "\n]") nil t) + (kill-region from-where (point-max)) + (article-goto-body) + (yank) + (insert "\n")))))) + +;; John Doe wrote in message +;; news:a87usw8$dklsssa$2@some.news.server... + +(defun gnus-outlook-repair-attribution-outlook () + "Repair a broken attribution line (Outlook)." + (save-excursion + (let ((case-fold-search nil) + (inhibit-read-only t) + (cite-marks gnus-outlook-deuglify-cite-marks)) + (gnus-with-article-buffer + (article-goto-body) + (if (re-search-forward + (concat "^\\([^" cite-marks "].+\\)" + "\\(" gnus-outlook-deuglify-attrib-verb-regexp "\\)" + "\\(.*\n?[^\n" cite-marks "].*\\)?" + "\\(" gnus-outlook-deuglify-attrib-end-regexp "\\)$") + nil t) + (progn + (replace-match "\\1\\2\\4") + (match-beginning 0))))))) + + +;; ----- Original Message ----- +;; From: "John Doe" +;; To: "Doe Foundation" +;; Sent: Monday, November 19, 2001 12:13 PM +;; Subject: More Doenuts + +(defun gnus-outlook-repair-attribution-block () + "Repair a big broken attribution block." + (save-excursion + (let ((case-fold-search nil) + (inhibit-read-only t) + (cite-marks gnus-outlook-deuglify-cite-marks)) + (gnus-with-article-buffer + (article-goto-body) + (if (re-search-forward + (concat "^----* ?[^-]+ ?----*\n" + "[^\n]+: \\([^\n]+\\)\n" + "[^\n]+: [^\n]+\n" + "[^\n]+: [^\n]+\n" + "[^\n]+: [^\n]+$") + nil t) + (progn + (replace-match "\\1 wrote:") + (match-beginning 0))))))) + +;; On Wed, 16 Jan 2002 23:23:30 +0100, John Doe wrote: + +(defun gnus-outlook-repair-attribution-other () + "Repair a broken attribution line (other user agents than Outlook)." + (save-excursion + (let ((case-fold-search nil) + (inhibit-read-only t) + (cite-marks gnus-outlook-deuglify-cite-marks)) + (gnus-with-article-buffer + (article-goto-body) + (if (re-search-forward + (concat "^\\("gnus-outlook-deuglify-attrib-cut-regexp"\\)?" + "\\([^" cite-marks "].+\\)\n\\([^\n" cite-marks "].*\\)?" + "\\(" gnus-outlook-deuglify-attrib-verb-regexp "\\).*" + "\\(" gnus-outlook-deuglify-attrib-end-regexp "\\)$") + nil t) + (progn + (replace-match "\\4 \\5\\6\\7") + (match-beginning 0))))))) + +;;;###autoload +(defun gnus-outlook-repair-attribution () + "Repair a broken attribution line." + (interactive) + (or + (gnus-outlook-repair-attribution-other) + (gnus-outlook-repair-attribution-block) + (gnus-outlook-repair-attribution-outlook))) + +(defun gnus-outlook-rearrange-citation () + "Repair broken citations." + (let ((attrib-start (gnus-outlook-repair-attribution))) + ;; rearrange citations if an attribution line has been recognized + (if attrib-start + (gnus-outlook-rearrange-article attrib-start)))) + +;;;###autoload +(defun gnus-outlook-deuglify-article () + "Deuglify broken Outlook (Express) articles." + (interactive) + ;; apply treatment of dumb quotes + (gnus-article-treat-dumbquotes) + ;; repair wrapped cited lines + (gnus-outlook-unwrap-lines) + ;; repair attribution line + (gnus-outlook-rearrange-citation)) + +;;;###autoload +(defun gnus-article-outlook-deuglify-article () + "Deuglify broken Outlook (Express) articles and redisplay." + (interactive) + (gnus-outlook-deuglify-article) + (with-current-buffer (or gnus-article-buffer (current-buffer)) + (gnus-article-prepare-display))) + +(provide 'deuglify) + +;; Local Variables: +;; coding: iso-8859-1 +;; End: + +;;; deuglify.el ends here diff --git a/lisp/dgnushack.el b/lisp/dgnushack.el index d37f23c..ed69d49 100644 --- a/lisp/dgnushack.el +++ b/lisp/dgnushack.el @@ -189,6 +189,14 @@ (t (concat filename ".elc")))) (require 'bytecomp) +;; To avoid having defsubsts and inlines happen. +;(if (featurep 'xemacs) +; (require 'byte-optimize) +; (require 'byte-opt)) +;(defun byte-optimize-inline-handler (form) +; "byte-optimize-handler for the `inline' special-form." +; (cons 'progn (cdr form))) +;(defalias 'byte-compile-file-form-defsubst 'byte-compile-file-form-defun) (push srcdir load-path) (load (expand-file-name "lpath.el" srcdir) nil t) @@ -234,23 +242,23 @@ Modify to suit your needs.")) (condition-case code (require 'w3-parse) (error - (message "No w3: %s %s" code (locate-library "w3-parse")) + (message "No w3: %s %s" (cadr code) (or (locate-library "w3-parse") "")) (dolist (file '("nnultimate.el" "webmail.el" "nnwfm.el")) (setq files (delete file files))))) (condition-case code (require 'mh-e) (error - (message "No mh-e: %s %s" code (locate-library "mh-e")) + (message "No mh-e: %s %s" (cadr code) (or (locate-library "mh-e") "")) (setq files (delete "gnus-mh.el" files)))) (condition-case code (require 'xml) (error - (message "No xml: %s %s" code (locate-library "xml")) + (message "No xml: %s %s" (cadr code) (or (locate-library "xml") "")) (setq files (delete "nnrss.el" files)))) (dolist (file (if (featurep 'xemacs) - '("md5.el" "smiley-ems.el") - '("gnus-xmas.el" "messagexmas.el" "nnheaderxm.el" "smiley.el"))) + '("md5.el") + '("gnus-xmas.el" "messagexmas.el" "nnheaderxm.el"))) (setq files (delete file files))) (dolist (file files) diff --git a/lisp/dns.el b/lisp/dns.el new file mode 100644 index 0000000..475909a --- /dev/null +++ b/lisp/dns.el @@ -0,0 +1,342 @@ +;;; dns.el --- Domain Name Service lookups +;; Copyright (C) 2002 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: network + +;; 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: + +;;; Code: + +(require 'mm-util) + +(defvar dns-timeout 5 + "How many seconds to wait when doing DNS queries.") + +(defvar dns-servers nil + "Which DNS servers to query. +If nil, /etc/resolv.conf will be consulted.") + +;;; Internal code: + +(defvar dns-query-types + '((A 1) + (NS 2) + (MD 3) + (MF 4) + (CNAME 5) + (SOA 6) + (MB 7) + (MG 8) + (MR 9) + (NULL 10) + (WKS 11) + (PRT 12) + (HINFO 13) + (MINFO 14) + (MX 15) + (TXT 16) + (AXFR 252) + (MAILB 253) + (MAILA 254) + (* 255)) + "Names of query types and their values.") + +(defvar dns-classes + '((IN 1) + (CS 2) + (CH 3) + (HS 4)) + "Classes of queries.") + +(defun dns-write-bytes (value &optional length) + (let (bytes) + (dotimes (i (or length 1)) + (push (% value 256) bytes) + (setq value (/ value 256))) + (dolist (byte bytes) + (insert byte)))) + +(defun dns-read-bytes (length) + (let ((value 0)) + (dotimes (i length) + (setq value (logior (* value 256) (following-char))) + (forward-char 1)) + value)) + +(defun dns-get (type spec) + (cadr (assq type spec))) + +(defun dns-inverse-get (value spec) + (let ((found nil)) + (while (and (not found) + spec) + (if (eq value (cadr (car spec))) + (setq found (caar spec)) + (pop spec))) + found)) + +(defun dns-write-name (name) + (dolist (part (split-string name "\\.")) + (dns-write-bytes (length part)) + (insert part)) + (dns-write-bytes 0)) + +(defun dns-read-string-name (string buffer) + (mm-with-unibyte-buffer + (insert string) + (goto-char (point-min)) + (dns-read-name buffer))) + +(defun dns-read-name (&optional buffer) + (let ((ended nil) + (name nil) + length) + (while (not ended) + (setq length (dns-read-bytes 1)) + (if (= 192 (logand length (lsh 3 6))) + (let ((offset (+ (* (logand 63 length) 256) + (dns-read-bytes 1)))) + (save-excursion + (when buffer + (set-buffer buffer)) + (goto-char (1+ offset)) + (setq ended (dns-read-name buffer)))) + (if (zerop length) + (setq ended t) + (push (buffer-substring (point) + (progn (forward-char length) (point))) + name)))) + (if (stringp ended) + (if (null name) + ended + (concat (mapconcat 'identity (nreverse name) ".") "." ended)) + (mapconcat 'identity (nreverse name) ".")))) + +(defun dns-write (spec &optional tcp-p) + "Write a DNS packet according to SPEC. +If TCP-P, the first two bytes of the package with be the length field." + (with-temp-buffer + (dns-write-bytes (dns-get 'id spec) 2) + (dns-write-bytes + (logior + (lsh (if (dns-get 'response-p spec) 1 0) -7) + (lsh + (cond + ((eq (dns-get 'opcode spec) 'query) 0) + ((eq (dns-get 'opcode spec) 'inverse-query) 1) + ((eq (dns-get 'opcode spec) 'status) 2) + (t (error "No such opcode: %s" (dns-get 'opcode spec)))) + -3) + (lsh (if (dns-get 'authoritative-p spec) 1 0) -2) + (lsh (if (dns-get 'truncated-p spec) 1 0) -1) + (lsh (if (dns-get 'recursion-desired-p spec) 1 0) 0))) + (dns-write-bytes + (cond + ((eq (dns-get 'response-code spec) 'no-error) 0) + ((eq (dns-get 'response-code spec) 'format-error) 1) + ((eq (dns-get 'response-code spec) 'server-failure) 2) + ((eq (dns-get 'response-code spec) 'name-error) 3) + ((eq (dns-get 'response-code spec) 'not-implemented) 4) + ((eq (dns-get 'response-code spec) 'refused) 5) + (t 0))) + (dns-write-bytes (length (dns-get 'queries spec)) 2) + (dns-write-bytes (length (dns-get 'answers spec)) 2) + (dns-write-bytes (length (dns-get 'authorities spec)) 2) + (dns-write-bytes (length (dns-get 'additionals spec)) 2) + (dolist (query (dns-get 'queries spec)) + (dns-write-name (car query)) + (dns-write-bytes (cadr (assq (or (dns-get 'type query) 'A) + dns-query-types)) 2) + (dns-write-bytes (cadr (assq (or (dns-get 'class query) 'IN) + dns-classes)) 2)) + (dolist (slot '(answers authorities additionals)) + (dolist (resource (dns-get slot spec)) + (dns-write-name (car resource)) + (dns-write-bytes (cadr (assq (dns-get 'type resource) dns-query-types)) + 2) + (dns-write-bytes (cadr (assq (dns-get 'class resource) dns-classes)) + 2) + (dns-write-bytes (dns-get 'ttl resource) 4) + (dns-write-bytes (length (dns-get 'data resource)) 2) + (insert (dns-get 'data resource)))) + (when tcp-p + (goto-char (point-min)) + (dns-write-bytes (buffer-size) 2)) + (buffer-string))) + +(defun dns-read (packet) + (mm-with-unibyte-buffer + (let ((spec nil) + queries answers authorities additionals) + (insert packet) + (goto-char (point-min)) + (push (list 'id (dns-read-bytes 2)) spec) + (let ((byte (dns-read-bytes 1))) + (push (list 'response-p (if (zerop (logand byte (lsh 1 7))) nil t)) + spec) + (let ((opcode (logand byte (lsh 7 3)))) + (push (list 'opcode + (cond ((eq opcode 0) 'query) + ((eq opcode 1) 'inverse-query) + ((eq opcode 2) 'status))) + spec)) + (push (list 'authoritative-p (if (zerop (logand byte (lsh 1 2))) + nil t)) spec) + (push (list 'truncated-p (if (zerop (logand byte (lsh 1 2))) nil t)) + spec) + (push (list 'recursion-desired-p + (if (zerop (logand byte (lsh 1 0))) nil t)) spec)) + (let ((rc (logand (dns-read-bytes 1) 15))) + (push (list 'response-code + (cond + ((eq rc 0) 'no-error) + ((eq rc 1) 'format-error) + ((eq rc 2) 'server-failure) + ((eq rc 3) 'name-error) + ((eq rc 4) 'not-implemented) + ((eq rc 5) 'refused))) + spec)) + (setq queries (dns-read-bytes 2)) + (setq answers (dns-read-bytes 2)) + (setq authorities (dns-read-bytes 2)) + (setq additionals (dns-read-bytes 2)) + (let ((qs nil)) + (dotimes (i queries) + (push (list (dns-read-name) + (list 'type (dns-inverse-get (dns-read-bytes 2) + dns-query-types)) + (list 'class (dns-inverse-get (dns-read-bytes 2) + dns-classes))) + qs)) + (push (list 'queries qs) spec)) + (dolist (slot '(answers authorities additionals)) + (let ((qs nil) + type) + (dotimes (i (symbol-value slot)) + (push (list (dns-read-name) + (list 'type + (setq type (dns-inverse-get (dns-read-bytes 2) + dns-query-types))) + (list 'class (dns-inverse-get (dns-read-bytes 2) + dns-classes)) + (list 'ttl (dns-read-bytes 4)) + (let ((length (dns-read-bytes 2))) + (list 'data + (dns-read-type + (buffer-substring + (point) + (progn (forward-char length) (point))) + type)))) + qs)) + (push (list slot qs) spec))) + (nreverse spec)))) + +(defun dns-read-type (string type) + (let ((buffer (current-buffer)) + (point (point))) + (prog1 + (mm-with-unibyte-buffer + (insert string) + (goto-char (point-min)) + (cond + ((eq type 'A) + (let ((bytes nil)) + (dotimes (i 4) + (push (dns-read-bytes 1) bytes)) + (mapconcat 'number-to-string (nreverse bytes) "."))) + ((eq type 'NS) + (dns-read-string-name string buffer)) + ((eq type 'CNAME) + (dns-read-string-name string buffer)) + (t string))) + (goto-char point)))) + +(defun dns-parse-resolv-conf () + (when (file-exists-p "/etc/resolv.conf") + (with-temp-buffer + (insert-file-contents "/etc/resolv.conf") + (goto-char (point-min)) + (while (re-search-forward "^nameserver[\t ]+\\([^ \t\n]+\\)" nil t) + (push (match-string 1) dns-servers)) + (setq dns-servers (nreverse dns-servers))))) + +;;; Interface functions. + +(defmacro dns-make-network-process (server) + (if (featurep 'xemacs) + `(let ((coding-system-for-read 'binary) + (coding-system-for-write 'binary)) + (open-network-stream "dns" (current-buffer) ,server "domain" 'udp)) + `(let ((server ,server) + (coding-system-for-read 'binary) + (coding-system-for-write 'binary)) + (if (fboundp 'make-network-process) + (make-network-process + :name "dns" + :coding 'binary + :buffer (current-buffer) + :host server + :service "domain" + :type 'datagram) + (open-network-stream "dns" (current-buffer) server "domain"))))) + +(defun query-dns (name &optional type fullp) + "Query a DNS server for NAME of TYPE. +If FULLP, return the entire record returned." + (setq type (or type 'A)) + (unless dns-servers + (dns-parse-resolv-conf) + (unless dns-servers + (error "No DNS server configuration found"))) + (mm-with-unibyte-buffer + (let ((process (dns-make-network-process (car dns-servers))) + (tcp-p (and (not (fboundp 'make-network-process)) + (not (featurep 'xemacs)))) + (step 100) + (times (* dns-timeout 1000)) + (id (random 65000))) + (process-send-string + process + (dns-write `((id ,id) + (opcode query) + (queries ((,name (type ,type)))) + (recursion-desired-p t)) + tcp-p)) + (while (and (zerop (buffer-size)) + (> times 0)) + (accept-process-output process 0 step) + (decf times step)) + (ignore-errors + (delete-process process)) + (when tcp-p + (goto-char (point-min)) + (delete-region (point) (+ (point) 2))) + (unless (zerop (buffer-size)) + (let ((result (dns-read (buffer-string)))) + (if fullp + result + (let ((answer (car (dns-get 'answers result)))) + (when (eq type (dns-get 'type answer)) + (dns-get 'data answer))))))))) + +(provide 'dns) + +;;; dns.el ends here diff --git a/lisp/gnus-agent.el b/lisp/gnus-agent.el index ef85946..eaf69d9 100644 --- a/lisp/gnus-agent.el +++ b/lisp/gnus-agent.el @@ -128,6 +128,18 @@ If this is `ask' the hook will query the user." (const :tag "Ask" ask)) :group 'gnus-agent) +(defcustom gnus-agent-mark-unread-after-downloaded t + "Indicate whether to mark articles unread after downloaded." + :version "21.1" + :type 'boolean + :group 'gnus-agent) + +(defcustom gnus-agent-download-marks '(download) + "Marks for downloading." + :version "21.1" + :type '(repeat (symbol :tag "Mark")) + :group 'gnus-agent) + ;;; Internal variables (defvar gnus-agent-history-buffers nil) @@ -143,6 +155,7 @@ If this is `ask' the hook will query the user." (defvar gnus-agent-file-name nil) (defvar gnus-agent-send-mail-function nil) (defvar gnus-agent-file-coding-system 'raw-text) +(defvar gnus-agent-file-loading-cache nil) ;; Dynamic variables (defvar gnus-headers) @@ -312,7 +325,7 @@ If this is `ask' the hook will query the user." ["Mark as downloadable" gnus-agent-mark-article t] ["Unmark as downloadable" gnus-agent-unmark-article t] ["Toggle mark" gnus-agent-toggle-mark t] - ["Fetch downloadable" gnus-aget-summary-fetch-group t] + ["Fetch downloadable" gnus-agent-summary-fetch-group t] ["Catchup undownloaded" gnus-agent-catchup t])))) (defvar gnus-agent-server-mode-map (make-sparse-keymap)) @@ -344,7 +357,7 @@ If this is `ask' the hook will query the user." (progn (setq gnus-plugged plugged) (gnus-run-hooks 'gnus-agent-plugged-hook) - (setcar (cdr gnus-agent-mode-status) + (setcar (cdr gnus-agent-mode-status) (gnus-agent-make-mode-line-string " Plugged" 'mouse-2 'gnus-agent-toggle-plugged)) @@ -353,7 +366,7 @@ If this is `ask' the hook will query the user." (gnus-agent-close-connections) (setq gnus-plugged plugged) (gnus-run-hooks 'gnus-agent-unplugged-hook) - (setcar (cdr gnus-agent-mode-status) + (setcar (cdr gnus-agent-mode-status) (gnus-agent-make-mode-line-string " Unplugged" 'mouse-2 'gnus-agent-toggle-plugged))) @@ -380,6 +393,13 @@ If this is `ask' the hook will query the user." (gnus)) ;;;###autoload +(defun gnus-slave-unplugged (&optional arg) + "Read news as a slave unplugged." + (interactive "P") + (setq gnus-plugged nil) + (gnus arg nil 'slave)) + +;;;###autoload (defun gnus-agentize () "Allow Gnus to be an offline newsreader. The normal usage of this command is to put the following as the @@ -670,7 +690,8 @@ the actual number of articles toggled is returned." (push article gnus-newsgroup-undownloaded)) (setq gnus-newsgroup-undownloaded (delq article gnus-newsgroup-undownloaded)) - (push article gnus-newsgroup-downloadable)) + (setq gnus-newsgroup-downloadable + (gnus-add-to-sorted-list gnus-newsgroup-downloadable article))) (gnus-summary-update-mark (if unmark gnus-undownloaded-mark gnus-downloadable-mark) 'unread))) @@ -682,12 +703,21 @@ the actual number of articles toggled is returned." (gnus-agent-method-p gnus-command-method)) (gnus-agent-load-alist gnus-newsgroup-name) ;; First mark all undownloaded articles as undownloaded. - (dolist (article (mapcar (lambda (header) (mail-header-number header)) - gnus-newsgroup-headers)) - (unless (or (cdr (assq article gnus-agent-article-alist)) - (memq article gnus-newsgroup-downloadable) - (memq article gnus-newsgroup-cached)) - (push article gnus-newsgroup-undownloaded))) + (let ((articles (mapcar (lambda (header) (mail-header-number header)) + gnus-newsgroup-headers)) + (agent-articles gnus-agent-article-alist) + candidates article) + (while (setq article (pop articles)) + (while (and agent-articles + (< (caar agent-articles) article)) + (setq agent-articles (cdr agent-articles))) + (when (or (not (cdar agent-articles)) + (not (= (caar agent-articles) article))) + (push article candidates))) + (dolist (article candidates) + (unless (or (memq article gnus-newsgroup-downloadable) + (memq article gnus-newsgroup-cached)) + (push article gnus-newsgroup-undownloaded)))) ;; Then mark downloaded downloadable as not-downloadable, ;; if you get my drift. (dolist (article gnus-newsgroup-downloadable) @@ -722,7 +752,8 @@ the actual number of articles toggled is returned." (dolist (article articles) (setq gnus-newsgroup-downloadable (delq article gnus-newsgroup-downloadable)) - (gnus-summary-mark-article article gnus-unread-mark)))) + (if gnus-agent-mark-unread-after-downloaded + (gnus-summary-mark-article article gnus-unread-mark))))) (when (and (not state) gnus-plugged) (gnus-agent-toggle-plugged nil))))) @@ -790,7 +821,7 @@ the actual number of articles toggled is returned." (goto-char (point-min)) (when (re-search-forward (concat "^" (regexp-quote group) " ") nil t) - (save-excursion + (save-excursion (read (current-buffer)) ;; max (setq oactive-min (read (current-buffer)))) ;; min (gnus-delete-line)) @@ -934,33 +965,35 @@ the actual number of articles toggled is returned." (while pos (narrow-to-region (cdar pos) (or (cdadr pos) (point-max))) (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (when (search-backward "\nXrefs: " nil t) - ;; Handle crossposting. - (skip-chars-forward "^ ") - (skip-chars-forward " ") - (setq crosses nil) - (while (looking-at "\\([^: \n]+\\):\\([0-9]+\\) +") - (push (cons (buffer-substring (match-beginning 1) - (match-end 1)) - (buffer-substring (match-beginning 2) - (match-end 2))) - crosses) - (goto-char (match-end 0))) - (gnus-agent-crosspost crosses (caar pos)))) - (goto-char (point-min)) - (if (not (re-search-forward "^Message-ID: *<\\([^>\n]+\\)>" nil t)) - (setq id "No-Message-ID-in-article") - (setq id (buffer-substring (match-beginning 1) (match-end 1)))) - (let ((coding-system-for-write - gnus-agent-file-coding-system)) - (write-region (point-min) (point-max) - (concat dir (number-to-string (caar pos))) - nil 'silent)) - (when (setq elem (assq (caar pos) gnus-agent-article-alist)) - (setcdr elem t)) - (gnus-agent-enter-history - id (or crosses (list (cons group (caar pos)))) date) + (unless (eobp) ;; Don't save empty articles. + (when (search-forward "\n\n" nil t) + (when (search-backward "\nXrefs: " nil t) + ;; Handle cross posting. + (skip-chars-forward "^ ") + (skip-chars-forward " ") + (setq crosses nil) + (while (looking-at "\\([^: \n]+\\):\\([0-9]+\\) +") + (push (cons (buffer-substring (match-beginning 1) + (match-end 1)) + (buffer-substring (match-beginning 2) + (match-end 2))) + crosses) + (goto-char (match-end 0))) + (gnus-agent-crosspost crosses (caar pos)))) + (goto-char (point-min)) + (if (not (re-search-forward + "^Message-ID: *<\\([^>\n]+\\)>" nil t)) + (setq id "No-Message-ID-in-article") + (setq id (buffer-substring (match-beginning 1) (match-end 1)))) + (let ((coding-system-for-write + gnus-agent-file-coding-system)) + (write-region (point-min) (point-max) + (concat dir (number-to-string (caar pos))) + nil 'silent)) + (when (setq elem (assq (caar pos) gnus-agent-article-alist)) + (setcdr elem t)) + (gnus-agent-enter-history + id (or crosses (list (cons group (caar pos)))) date)) (widen) (pop pos))) (gnus-agent-save-alist group))))) @@ -1016,13 +1049,14 @@ the actual number of articles toggled is returned." gnus-agent-cache) ;; Add article with marks to list of article headers we want to fetch. (dolist (arts (gnus-info-marks (gnus-get-info group))) - (setq articles (gnus-range-add articles (cdr arts)))) + (unless (memq (car arts) '(seen recent)) + (setq articles (gnus-range-add articles (cdr arts))))) (setq articles (sort (gnus-uncompress-sequence articles) '<)) ;; Remove known articles. (when (gnus-agent-load-alist group) - (setq articles (gnus-sorted-intersection + (setq articles (gnus-list-range-intersection articles - (gnus-uncompress-range + (list (cons (1+ (caar (last gnus-agent-article-alist))) (cdr (gnus-active group))))))) ;; Fetch them. @@ -1031,11 +1065,11 @@ the actual number of articles toggled is returned." (when articles (gnus-message 7 "Fetching headers for %s..." group) (save-excursion - (set-buffer nntp-server-buffer) - (unless (eq 'nov (gnus-retrieve-headers articles group)) - (nnvirtual-convert-headers)) - ;; Save these headers for later processing. - (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max)) + (set-buffer nntp-server-buffer) + (unless (eq 'nov (gnus-retrieve-headers articles group)) + (nnvirtual-convert-headers)) + ;; Save these headers for later processing. + (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max)) (when (file-exists-p file) (gnus-agent-braid-nov group articles file)) (let ((coding-system-for-write @@ -1049,78 +1083,87 @@ the actual number of articles toggled is returned." articles)))) (defsubst gnus-agent-copy-nov-line (article) - (let (b e) + (let (art b e) (set-buffer gnus-agent-overview-buffer) - (unless (eobp) + (while (and (not (eobp)) + (< (setq art (read (current-buffer))) article)) + (forward-line 1)) + (beginning-of-line) + (if (or (eobp) + (not (eq article art))) + (set-buffer nntp-server-buffer) (setq b (point)) - (if (eq article (read (current-buffer))) - (setq e (progn (forward-line 1) (point))) - (progn - (beginning-of-line) - (setq e b))) + (setq e (progn (forward-line 1) (point))) (set-buffer nntp-server-buffer) (insert-buffer-substring gnus-agent-overview-buffer b e)))) (defun gnus-agent-braid-nov (group articles file) - (set-buffer gnus-agent-overview-buffer) - (goto-char (point-min)) - (set-buffer nntp-server-buffer) - (erase-buffer) - (nnheader-insert-file-contents file) - (goto-char (point-max)) - (if (or (= (point-min) (point-max)) - (progn - (forward-line -1) - (< (read (current-buffer)) (car articles)))) - ;; We have only headers that are after the older headers, - ;; so we just append them. - (progn - (goto-char (point-max)) - (insert-buffer-substring gnus-agent-overview-buffer)) - ;; We do it the hard way. - (nnheader-find-nov-line (car articles)) - (gnus-agent-copy-nov-line (car articles)) - (pop articles) - (while (and articles - (not (eobp))) - (while (and (not (eobp)) - (< (read (current-buffer)) (car articles))) - (forward-line 1)) - (beginning-of-line) - (unless (eobp) - (gnus-agent-copy-nov-line (car articles)) - (setq articles (cdr articles)))) + (let (start last) + (set-buffer gnus-agent-overview-buffer) + (goto-char (point-min)) + (set-buffer nntp-server-buffer) + (erase-buffer) + (nnheader-insert-file-contents file) + (goto-char (point-max)) + (unless (or (= (point-min) (point-max)) + (progn + (forward-line -1) + (< (setq last (read (current-buffer))) (car articles)))) + ;; We do it the hard way. + (nnheader-find-nov-line (car articles)) + (gnus-agent-copy-nov-line (pop articles)) + (while (and articles + (not (eobp))) + (while (and (not (eobp)) + (< (read (current-buffer)) (car articles))) + (forward-line 1)) + (beginning-of-line) + (unless (eobp) + (gnus-agent-copy-nov-line (pop articles))))) + ;; Copy the rest lines (set-buffer nntp-server-buffer) + (goto-char (point-max)) (when articles - (let (b e) + (when last (set-buffer gnus-agent-overview-buffer) - (setq b (point) - e (point-max)) (while (and (not (eobp)) - (<= (read (current-buffer)) (car articles))) - (forward-line 1) - (setq b (point))) - (set-buffer nntp-server-buffer) - (insert-buffer-substring gnus-agent-overview-buffer b e))))) + (<= (read (current-buffer)) last)) + (forward-line 1)) + (beginning-of-line) + (setq start (point)) + (set-buffer nntp-server-buffer)) + (insert-buffer-substring gnus-agent-overview-buffer start)))) (defun gnus-agent-load-alist (group &optional dir) "Load the article-state alist for GROUP." + (let ((file )) (setq gnus-agent-article-alist - (gnus-agent-read-file + (gnus-cache-file-contents (if dir - (expand-file-name ".agentview" dir) - (gnus-agent-article-name ".agentview" group))))) + (expand-file-name ".agentview" dir) + (gnus-agent-article-name ".agentview" group)) + 'gnus-agent-file-loading-cache + 'gnus-agent-read-file)))) (defun gnus-agent-save-alist (group &optional articles state dir) "Save the article-state alist for GROUP." - (let ((file-name-coding-system nnmail-pathname-coding-system) - print-level print-length item) - (dolist (art articles) - (if (setq item (memq art gnus-agent-article-alist)) - (setcdr item state) - (push (cons art state) gnus-agent-article-alist))) - (setq gnus-agent-article-alist - (sort gnus-agent-article-alist 'car-less-than-car)) + (let* ((file-name-coding-system nnmail-pathname-coding-system) + (prev (cons nil gnus-agent-article-alist)) + (all prev) + print-level print-length item article) + (while (setq article (pop articles)) + (while (and (cdr prev) + (< (caadr prev) article)) + (setq prev (cdr prev))) + (cond + ((not (cdr prev)) + (setcdr prev (list (cons article state)))) + ((> (caadr prev) article) + (setcdr prev (cons (cons article state) (cdr prev)))) + ((= (caadr prev) article) + (setcdr (cadr prev) state))) + (setq prev (cdr prev))) + (setq gnus-agent-article-alist (cdr all)) (with-temp-file (if dir (expand-file-name ".agentview" dir) (gnus-agent-article-name ".agentview" group)) @@ -1171,12 +1214,12 @@ the actual number of articles toggled is returned." (gnus-agent-fetch-group-1 group gnus-command-method)))))) (error (unless (funcall gnus-agent-confirmation-function - (format "Error (%s). Continue? " err)) + (format "Error (%s). Continue? " (cadr err))) (error "Cannot fetch articles into the Gnus agent"))) (quit (unless (funcall gnus-agent-confirmation-function (format "Quit fetching session (%s). Continue? " - err)) + (cadr err))) (signal 'quit "Cannot fetch articles into the Gnus agent")))) (pop methods)) (run-hooks 'gnus-agent-fetch-hook) @@ -1246,18 +1289,20 @@ the actual number of articles toggled is returned." (when arts (gnus-agent-fetch-articles group arts))) ;; Perhaps we have some additional articles to fetch. - (setq arts (assq 'download (gnus-info-marks - (setq info (gnus-get-info group))))) - (when (cdr arts) - (gnus-message 8 "Agent is downloading marked articles...") - (gnus-agent-fetch-articles - group (gnus-uncompress-range (cdr arts))) - (setq marks (delq arts (gnus-info-marks info))) - (gnus-info-set-marks info marks) - (gnus-dribble-enter - (concat "(gnus-group-set-info '" - (gnus-prin1-to-string info) - ")"))))) + (dolist (mark gnus-agent-download-marks) + (setq arts (assq mark (gnus-info-marks + (setq info (gnus-get-info group))))) + (when (cdr arts) + (gnus-message 8 "Agent is downloading marked articles...") + (gnus-agent-fetch-articles + group (gnus-uncompress-range (cdr arts))) + (when (eq mark 'download) + (setq marks (delq arts (gnus-info-marks info))) + (gnus-info-set-marks info marks) + (gnus-dribble-enter + (concat "(gnus-group-set-info '" + (gnus-prin1-to-string info) + ")"))))))) ;;; ;;; Agent Category Mode @@ -1581,9 +1626,11 @@ The following commands are available: (defun gnus-get-predicate (predicate) "Return the predicate for CATEGORY." (or (cdr (assoc predicate gnus-category-predicate-cache)) - (cdar (push (cons predicate - (gnus-category-make-function predicate)) - gnus-category-predicate-cache)))) + (let ((func (gnus-category-make-function predicate))) + (setq gnus-category-predicate-cache + (nconc gnus-category-predicate-cache + (list (cons predicate func)))) + func))) (defun gnus-group-category (group) "Return the category GROUP belongs to." @@ -1815,21 +1862,21 @@ The following commands are available: (erase-buffer) (let ((nnheader-file-coding-system gnus-agent-file-coding-system)) - (nnheader-insert-file-contents file)) - (goto-char (point-min)) + (nnheader-insert-nov-file file (car articles))) + (nnheader-find-nov-line (car articles)) (while (not (eobp)) (when (looking-at "[0-9]") (push (read (current-buffer)) cached-articles)) (forward-line 1)) - (setq cached-articles (sort cached-articles '<)))) - (if (setq uncached-articles - (gnus-set-difference articles cached-articles)) + (setq cached-articles (nreverse cached-articles)))) + (if (setq uncached-articles + (gnus-sorted-difference articles cached-articles)) (progn (set-buffer nntp-server-buffer) (erase-buffer) (let (gnus-agent-cache) - (unless (eq 'nov - (gnus-retrieve-headers + (unless (eq 'nov + (gnus-retrieve-headers uncached-articles group fetch-old)) (nnvirtual-convert-headers))) (set-buffer gnus-agent-overview-buffer) @@ -1871,8 +1918,9 @@ The following commands are available: (gnus-agent-directory) (gnus-agent-group-path group) "/" (number-to-string article))) - (buffer-read-only nil)) - (when (file-exists-p file) + (buffer-read-only nil)) + (when (and (file-exists-p file) + (> (nth 7 (file-attributes file)) 0)) (erase-buffer) (gnus-kill-all-overlays) (let ((coding-system-for-read gnus-cache-coding-system)) @@ -1897,7 +1945,7 @@ The following commands are available: (let ((nnheader-file-coding-system gnus-agent-file-coding-system)) (nnheader-insert-file-contents file))) - (goto-char (point-min)) + (goto-char (point-min)) (while (not (eobp)) (while (not (or (eobp) (looking-at "[0-9]"))) (setq point (point)) @@ -1910,7 +1958,7 @@ The following commands are available: (while (and arts (> n (car arts))) (message "Regenerating NOV %s %d..." group (car arts)) (mm-with-unibyte-buffer - (nnheader-insert-file-contents + (nnheader-insert-file-contents (concat dir (number-to-string (car arts)))) (goto-char (point-min)) (if (search-forward "\n\n" nil t) @@ -1935,15 +1983,15 @@ The following commands are available: (unless clean (gnus-agent-load-alist group)) (setq alist (sort alist 'car-less-than-car)) - (setq gnus-agent-article-alist (sort gnus-agent-article-alist + (setq gnus-agent-article-alist (sort gnus-agent-article-alist 'car-less-than-car)) (while (and alist gnus-agent-article-alist) - (cond + (cond ((< (caar alist) (caar gnus-agent-article-alist)) (push (pop alist) new-alist)) ((> (caar alist) (caar gnus-agent-article-alist)) (push (list (car (pop gnus-agent-article-alist))) new-alist)) - (t + (t (pop gnus-agent-article-alist) (while (and gnus-agent-article-alist (= (caar alist) (caar gnus-agent-article-alist))) @@ -1967,8 +2015,8 @@ The following commands are available: (if (not (re-search-forward "^Message-ID: *<\\([^>\n]+\\)>" nil t)) (setq id "No-Message-ID-in-article") (setq id (buffer-substring (match-beginning 1) (match-end 1)))) - (gnus-agent-enter-history - id (list (cons group article)) + (gnus-agent-enter-history + id (list (cons group article)) (time-to-days (nth 5 (file-attributes file))))))) ;;;###autoload @@ -1979,7 +2027,7 @@ If CLEAN, don't read existing active and agentview files." (message "Regenerating Gnus agent files...") (dolist (gnus-command-method gnus-agent-covered-methods) (let ((active-file (gnus-agent-lib-file "active")) - history-hashtb active-hashtb active-changed + history-hashtb active-hashtb active-changed history-changed point) (gnus-make-directory (file-name-directory active-file)) (if clean @@ -2001,12 +2049,12 @@ If CLEAN, don't read existing active and agentview files." (goto-char (point-min)) (forward-line 1) (while (not (eobp)) - (if (looking-at + (if (looking-at "\\([^\t\n]+\\)\t[0-9]+\t\\([^ \n]+\\) \\([0-9]+\\)") (progn - (unless (string= (match-string 1) + (unless (string= (match-string 1) "last-header-fetched-for-session") - (gnus-sethash (match-string 2) + (gnus-sethash (match-string 2) (cons (string-to-number (match-string 3)) (gnus-gethash-safe (match-string 2) history-hashtb)) @@ -2037,14 +2085,14 @@ If CLEAN, don't read existing active and agentview files." n) (gnus-sethash group arts history-hashtb) (while (and arts gnus-agent-article-alist) - (cond + (cond ((> (car arts) (caar gnus-agent-article-alist)) (when (cdar gnus-agent-article-alist) - (gnus-agent-regenerate-history + (gnus-agent-regenerate-history group (caar gnus-agent-article-alist)) (setq history-changed t)) (setq n (car (pop gnus-agent-article-alist))) - (while (and gnus-agent-article-alist + (while (and gnus-agent-article-alist (= n (caar gnus-agent-article-alist))) (pop gnus-agent-article-alist))) ((< (car arts) (caar gnus-agent-article-alist)) @@ -2053,7 +2101,7 @@ If CLEAN, don't read existing active and agentview files." (pop arts))) (t (setq n (car (pop gnus-agent-article-alist))) - (while (and gnus-agent-article-alist + (while (and gnus-agent-article-alist (= n (caar gnus-agent-article-alist))) (pop gnus-agent-article-alist)) (setq n (pop arts)) @@ -2061,18 +2109,18 @@ If CLEAN, don't read existing active and agentview files." (pop arts))))) (while gnus-agent-article-alist (when (cdar gnus-agent-article-alist) - (gnus-agent-regenerate-history + (gnus-agent-regenerate-history group (caar gnus-agent-article-alist)) (setq history-changed t)) (pop gnus-agent-article-alist)))) (when history-changed - (message "Regenerate the history file of %s:%s" + (message "Regenerate the history file of %s:%s" (car gnus-command-method) (cadr gnus-command-method)) (gnus-agent-save-history)) (gnus-agent-close-history) (when active-changed - (message "Regenerate %s" active-file) + (message "Regenerate %s" active-file) (let ((nnmail-active-file-coding-system gnus-agent-file-coding-system)) (gnus-write-active-file active-file active-hashtb))))) (message "Regenerating Gnus agent files...done")) @@ -2082,8 +2130,8 @@ If CLEAN, don't read existing active and agentview files." (interactive (list t)) (dolist (server gnus-opened-servers) (when (eq (nth 1 server) 'offline) - (if (if (eq force 'ask) - (gnus-y-or-n-p + (if (if (eq force 'ask) + (gnus-y-or-n-p (format "Switch %s:%s into online status? " (caar server) (cadar server))) force) diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index 7888afe..8baf876 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -242,6 +242,7 @@ asynchronously. The compressed face will be piped to this command." (function-item gnus-display-x-face-in-from) function) :version "21.1" + :group 'gnus-picon :group 'gnus-article-washing) (defcustom gnus-article-x-face-too-ugly nil @@ -280,7 +281,7 @@ directly.") (defcustom gnus-emphasis-alist (let ((format - "\\(\\s-\\|^\\|\\=\\|[-\"]\\|\\s(\\)\\(%s\\(\\w+\\(\\s-+\\w+\\)*[.,]?\\)%s\\)\\(\\([-,.;:\"]\\|\\s)\\)+\\s-\\|[?!.]\\s-\\|\\s)\\|\\s-\\)") + "\\(\\s-\\|^\\|\\=\\|[-\"]\\|\\s(\\)\\(%s\\(\\w+\\(\\s-+\\w+\\)*[.,]?\\)%s\\)\\(\\([-,.;:!?\"]\\|\\s)\\)+\\s-\\|[?!.]\\s-\\|\\s)\\|\\s-\\)") (types '(("\\*" "\\*" bold) ("_" "_" underline) @@ -705,10 +706,13 @@ be controlled by `gnus-treat-body-boundary'." string)) (defcustom gnus-picon-databases '("/usr/lib/picon" "/usr/local/faces") - "*Defines the location of the faces database. + "Defines the location of the faces database. For information on obtaining this database of pretty pictures, please see http://www.cs.indiana.edu/picons/ftp/index.html" - :type 'directory + :type '(repeat directory) + :link '(url-link :tag "download" + "http://www.cs.indiana.edu/picons/ftp/index.html") + :link '(custom-manual "(gnus)Picons") :group 'gnus-picon) (defun gnus-picons-installed-p () @@ -767,28 +771,13 @@ used." ("toggle display" . gnus-article-press-button) ("toggle display" . gnus-article-view-part-as-charset) ("view as type" . gnus-mime-view-part-as-type) - ("internalize type" . gnus-mime-internalize-part) - ("externalize type" . gnus-mime-externalize-part)) + ("view internally" . gnus-mime-view-part-internally) + ("view externally" . gnus-mime-view-part-externally)) "An alist of actions that run on the MIME attachment." :group 'gnus-article-mime :type '(repeat (cons (string :tag "name") (function)))) -(defcustom gnus-mime-action-alist - '(("save to file" . gnus-mime-save-part) - ("display as text" . gnus-mime-inline-part) - ("view the part" . gnus-mime-view-part) - ("pipe to command" . gnus-mime-pipe-part) - ("toggle display" . gnus-article-press-button) - ("view as type" . gnus-mime-view-part-as-type) - ("internalize type" . gnus-mime-internalize-part) - ("externalize type" . gnus-mime-externalize-part)) - "An alist of actions that run on the MIME attachment." - :version "21.1" - :group 'gnus-article-mime - :type '(repeat (cons (string :tag "name") - (function)))) - ;;; ;;; The treatment variables ;;; @@ -858,6 +847,13 @@ See Info node `(gnus)Customizing Articles' for details." :group 'gnus-article-treat :type gnus-article-treat-custom) +(defcustom gnus-treat-unsplit-urls nil + "Remove newlines from within URLs. +Valid values are nil, t, `head', `last', an integer or a predicate. +See Info node `(gnus)Customizing Articles' for details." + :group 'gnus-article-treat + :type gnus-article-treat-custom) + (defcustom gnus-treat-leading-whitespace nil "Remove leading whitespace in headers. Valid values are nil, t, `head', `last', an integer or a predicate. @@ -1063,7 +1059,8 @@ See Info node `(gnus)Customizing Articles' for details." (put 'gnus-treat-overstrike 'highlight t) (defcustom gnus-treat-display-xface - (and (or (and (fboundp 'image-type-available-p) + (and (not noninteractive) + (or (and (fboundp 'image-type-available-p) (image-type-available-p 'xbm) (string-match "^0x" (shell-command-to-string "uncompface"))) (and (featurep 'xemacs) @@ -1078,6 +1075,17 @@ See Info node `(gnus)Customizing Articles' and Info node :type gnus-article-treat-head-custom) (put 'gnus-treat-display-xface 'highlight t) +(defcustom gnus-treat-display-grey-xface + (and (not noninteractive) + (string-match "^0x" (shell-command-to-string "uncompface")) + t) + "Display grey X-Face headers. +Valid values are nil, t." + :group 'gnus-article-treat + :version "21.3" + :type 'boolean) +(put 'gnus-treat-display-grey-xface 'highlight t) + (defcustom gnus-treat-display-smileys (if (or (and (featurep 'xemacs) (featurep 'xpm)) @@ -1102,6 +1110,9 @@ Valid values are nil, t, `head', `last', an integer or a predicate. See Info node `(gnus)Customizing Articles' and Info node `(gnus)Picons' for details." :group 'gnus-article-treat + :group 'gnus-picon + :link '(info-link "(gnus)Customizing Articles") + :link '(info-link "(gnus)Picons") :type gnus-article-treat-head-custom) (put 'gnus-treat-from-picon 'highlight t) @@ -1114,6 +1125,9 @@ Valid values are nil, t, `head', `last', an integer or a predicate. See Info node `(gnus)Customizing Articles' and Info node `(gnus)Picons' for details." :group 'gnus-article-treat + :group 'gnus-picon + :link '(info-link "(gnus)Customizing Articles") + :link '(info-link "(gnus)Picons") :type gnus-article-treat-head-custom) (put 'gnus-treat-mail-picon 'highlight t) @@ -1126,6 +1140,9 @@ Valid values are nil, t, `head', `last', an integer or a predicate. See Info node `(gnus)Customizing Articles' and Info node `(gnus)Picons' for details." :group 'gnus-article-treat + :group 'gnus-picon + :link '(info-link "(gnus)Customizing Articles") + :link '(info-link "(gnus)Picons") :type gnus-article-treat-head-custom) (put 'gnus-treat-newsgroups-picon 'highlight t) @@ -1192,6 +1209,9 @@ It is a string, such as \"PGP\". If nil, ask user." :type 'string :group 'mime-security) +(defvar gnus-article-wash-function nil + "Function used for converting HTML into text.") + ;;; Internal variables (defvar gnus-english-month-names @@ -1213,6 +1233,7 @@ It is a string, such as \"PGP\". If nil, ask user." (gnus-treat-fill-article gnus-article-fill-cited-article) (gnus-treat-fill-long-lines gnus-article-fill-long-lines) (gnus-treat-strip-cr gnus-article-remove-cr) + (gnus-treat-unsplit-urls gnus-article-unsplit-urls) (gnus-treat-date-ut gnus-article-date-ut) (gnus-treat-date-local gnus-article-date-local) (gnus-treat-date-english gnus-article-date-english) @@ -1224,8 +1245,6 @@ It is a string, such as \"PGP\". If nil, ask user." (gnus-treat-hide-headers gnus-article-maybe-hide-headers) (gnus-treat-hide-boring-headers gnus-article-hide-boring-headers) (gnus-treat-hide-signature gnus-article-hide-signature) - (gnus-treat-hide-citation gnus-article-hide-citation) - (gnus-treat-hide-citation-maybe gnus-article-hide-citation-maybe) (gnus-treat-strip-list-identifiers gnus-article-hide-list-identifiers) (gnus-treat-leading-whitespace gnus-article-remove-leading-whitespace) (gnus-treat-strip-pgp gnus-article-hide-pgp) @@ -1234,7 +1253,6 @@ It is a string, such as \"PGP\". If nil, ask user." (gnus-treat-mail-picon gnus-treat-mail-picon) (gnus-treat-newsgroups-picon gnus-treat-newsgroups-picon) (gnus-treat-highlight-headers gnus-article-highlight-headers) - (gnus-treat-highlight-citation gnus-article-highlight-citation) (gnus-treat-highlight-signature gnus-article-highlight-signature) (gnus-treat-strip-trailing-blank-lines gnus-article-remove-trailing-blank-lines) @@ -1250,6 +1268,9 @@ It is a string, such as \"PGP\". If nil, ask user." (gnus-treat-display-smileys gnus-treat-smiley) (gnus-treat-capitalize-sentences gnus-article-capitalize-sentences) (gnus-treat-emphasize gnus-article-emphasize) + (gnus-treat-hide-citation gnus-article-hide-citation) + (gnus-treat-hide-citation-maybe gnus-article-hide-citation-maybe) + (gnus-treat-highlight-citation gnus-article-highlight-citation) (gnus-treat-body-boundary gnus-article-treat-body-boundary) (gnus-treat-play-sounds gnus-earcon-display))) @@ -1666,11 +1687,11 @@ unfolded." (with-temp-buffer (insert header) (goto-char (point-min)) - (while (re-search-forward "[\t ]*\n[\t ]+" nil t) + (while (re-search-forward "\n[\t ]" nil t) (replace-match " " t t))) (setq length (- (point-max) (point-min) 1))) (when (< length (window-width)) - (while (re-search-forward "[\t ]*\n[\t ]+" nil t) + (while (re-search-forward "\n[\t ]" nil t) (replace-match " " t t))) (goto-char (point-max))))))) @@ -1685,7 +1706,7 @@ unfolded." (goto-char (point-max)))))) (defun gnus-treat-smiley () - "Display textual emoticons (\"smileys\") as small graphical icons." + "Toggle display of textual emoticons (\"smileys\") as small graphical icons." (interactive) (gnus-with-article-buffer (if (memq 'smiley gnus-article-wash-types) @@ -1721,7 +1742,7 @@ unfolded." (defun gnus-article-treat-body-boundary () "Place a boundary line at the end of the headers." (interactive) - (when (and gnus-body-boundary-delimiter + (when (and gnus-body-boundary-delimiter (> (length gnus-body-boundary-delimiter) 0)) (gnus-with-article-headers (goto-char (point-max)) @@ -1732,7 +1753,8 @@ unfolded." (while (>= (1- (window-width)) (length str)) (setq str (concat str gnus-body-boundary-delimiter))) (substring str 0 (1- (window-width)))) - "\n"))))) + "\n") + (gnus-add-text-properties start (point) '(gnus-decoration 'header)))))) (defun article-fill-long-lines () "Fill lines that are wider than the window width." @@ -1810,7 +1832,7 @@ unfolded." (when (and wash-face-p (progn (goto-char (point-min)) - (not (re-search-forward + (not (re-search-forward "^X-Face\\(-[0-9]+\\)?:[\t ]*" nil t))) (gnus-buffer-live-p gnus-original-article-buffer)) ;; If type `W f', use gnus-original-article-buffer, @@ -1819,10 +1841,24 @@ unfolded." (set-buffer gnus-original-article-buffer)) (save-restriction (mail-narrow-to-head) - (while (gnus-article-goto-header "x-face\\(-[0-9]+\\)?") - (when (match-beginning 2) - (setq grey t)) - (push (mail-header-field-value) x-faces)) + (if gnus-treat-display-grey-xface + (progn + (while (gnus-article-goto-header "X-Face\\(-[0-9]+\\)?") + (if (match-beginning 2) + (progn + (setq grey t) + (push (cons (- (string-to-number (match-string 2))) + (mail-header-field-value)) + x-faces)) + (push (cons 0 (mail-header-field-value)) x-faces))) + (dolist (x-face (prog1 + (if grey + (sort x-faces 'car-less-than-car) + (nreverse x-faces)) + (setq x-faces nil))) + (push (cdr x-face) x-faces))) + (while (gnus-article-goto-header "X-Face") + (push (mail-header-field-value) x-faces))) (setq from (message-fetch-field "from")))) (if grey (let ((xpm (gnus-convert-gray-x-face-to-xpm x-faces)) @@ -1830,7 +1866,7 @@ unfolded." (when xpm (setq image (gnus-create-image xpm 'xpm t)) (gnus-article-goto-header "from") - (when (bobp) + (when (bobp) (insert "From: [no `from' set]\n") (forward-char -17)) (gnus-add-wash-type 'xface) @@ -2038,6 +2074,16 @@ If READ-CHARSET, ask for a coding system." (let ((buffer-read-only nil)) (rfc1843-decode-region (point-min) (point-max))))) +(defun article-unsplit-urls () + "Remove the newlines that some other mailers insert into URLs." + (interactive) + (save-excursion + (let ((buffer-read-only nil)) + (goto-char (point-min)) + (while (re-search-forward + "^\\(\\(https?\\|ftp\\)://\\S-+\\) *\n\\(\\S-+\\)" nil t) + (replace-match "\\1\\3" t))))) + (defun article-wash-html (&optional read-charset) "Format an html article. If READ-CHARSET, ask for a coding system." @@ -2063,14 +2109,43 @@ If READ-CHARSET, ask for a coding system." (save-window-excursion (save-restriction (narrow-to-region (point) (point-max)) - (mm-setup-w3) - (let ((w3-strict-width (window-width)) - (url-standalone-mode t) - (w3-honor-stylesheets nil) - (w3-delay-image-loads t)) - (condition-case var - (w3-region (point-min) (point-max)) - (error)))))))) + (let* ((func (or gnus-article-wash-function mm-text-html-renderer)) + (entry (assq func mm-text-html-washer-alist))) + (if entry + (setq func (cdr entry))) + (cond + ((gnus-functionp func) + (funcall func)) + (t + (apply (car func) (cdr func)))))))))) + +(defun gnus-article-wash-html-with-w3 () + "Wash the current buffer with w3." + (mm-setup-w3) + (let ((w3-strict-width (window-width)) + (url-standalone-mode t) + (url-gateway-unplugged t) + (w3-honor-stylesheets nil)) + (condition-case () + (w3-region (point-min) (point-max)) + (error)))) + +(defun gnus-article-wash-html-with-w3m () + "Wash the current buffer with emacs-w3m." + (mm-setup-w3m) + (save-restriction + (narrow-to-region (point) (point-max)) + (let ((w3m-safe-url-regexp (if mm-inline-text-html-with-images + nil + "\\`cid:")) + (w3m-display-inline-images mm-inline-text-html-with-images) + w3m-force-redisplay) + (w3m-region (point-min) (point-max))) + (when mm-inline-text-html-with-w3m-keymap + (add-text-properties + (point-min) (point-max) + (append '(mm-inline-text-html-with-w3m t) + (gnus-local-map-property mm-w3m-mode-map)))))) (defun article-hide-list-identifiers () "Remove list identifies from the Subject header. @@ -3141,6 +3216,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is article-de-base64-unreadable article-decode-HZ article-wash-html + article-unsplit-urls article-hide-list-identifiers article-hide-pgp article-strip-banner @@ -3237,6 +3313,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is ["Remove quoted-unreadable" gnus-article-de-quoted-unreadable t] ["Remove base64" gnus-article-de-base64-unreadable t] ["Treat html" gnus-article-wash-html t] + ["Remove newlines from within URLs" gnus-article-unsplit-urls t] ["Decode HZ" gnus-article-decode-HZ t])) ;; Note "Commands" menu is defined in gnus-sum.el for consistency @@ -3455,6 +3532,8 @@ If ALL-HEADERS is non-nil, no headers are hidden." gnus-article-mime-handle-alist)) (gnus-set-mode-line 'article)) (article-goto-body) + (unless (bobp) + (forward-line -1)) (set-window-point (get-buffer-window (current-buffer)) (point)) (gnus-configure-windows 'article) t)))))) @@ -3513,8 +3592,8 @@ General format specifiers can also be used. See (gnus-mime-save-part-and-strip "\C-o" "Save and Strip") (gnus-mime-copy-part "c" "View As Text, In Other Buffer") (gnus-mime-inline-part "i" "View As Text, In This Buffer") - (gnus-mime-internalize-part "E" "View Internally") - (gnus-mime-externalize-part "e" "View Externally") + (gnus-mime-view-part-internally "E" "View Internally") + (gnus-mime-view-part-externally "e" "View Externally") (gnus-mime-print-part "p" "Print") (gnus-mime-pipe-part "|" "Pipe To Command...") (gnus-mime-action-on-part "." "Take action on the part"))) @@ -3720,13 +3799,13 @@ General format specifiers can also be used. See (setq buffer-file-name nil)) (goto-char (point-min))))) -(defun gnus-mime-print-part (&optional handle) +(defun gnus-mime-print-part (&optional handle filename) "Print the MIME part under point." - (interactive) + (interactive (list nil (ps-print-preprint current-prefix-arg))) (gnus-article-check-buffer) (let* ((handle (or handle (get-text-property (point) 'gnus-data))) (contents (and handle (mm-get-part handle))) - (file (make-temp-name (expand-file-name "mm." mm-tmp-directory))) + (file (mm-make-temp-file (expand-file-name "mm." mm-tmp-directory))) (printer (mailcap-mime-info (mm-handle-type handle) "print"))) (when contents (if printer @@ -3743,7 +3822,8 @@ General format specifiers can also be used. See (delete-file file)) (with-temp-buffer (insert contents) - (gnus-print-buffer)))))) + (gnus-print-buffer)) + (ps-despool filename))))) (defun gnus-mime-inline-part (&optional handle arg) "Insert the MIME part under point into the current buffer." @@ -3798,7 +3878,7 @@ specified charset." (gnus-newsgroup-ignored-charsets 'gnus-all)) (gnus-article-press-button))))) -(defun gnus-mime-externalize-part (&optional handle) +(defun gnus-mime-view-part-externally (&optional handle) "View the MIME part under point with an external viewer." (interactive) (gnus-article-check-buffer) @@ -3814,7 +3894,7 @@ specified charset." (mm-remove-part handle) (mm-display-part handle))))) -(defun gnus-mime-internalize-part (&optional handle) +(defun gnus-mime-view-part-internally (&optional handle) "View the MIME part under point with an internal viewer. If no internal viewer is available, use an external viewer." (interactive) @@ -3874,10 +3954,10 @@ If no internal viewer is available, use an external viewer." (interactive "p") (gnus-article-part-wrapper n 'gnus-mime-view-part-as-charset)) -(defun gnus-article-externalize-part (n) +(defun gnus-article-view-part-externally (n) "View MIME part N externally, which is the numerical prefix." (interactive "p") - (gnus-article-part-wrapper n 'gnus-mime-externalize-part)) + (gnus-article-part-wrapper n 'gnus-mime-view-part-externally)) (defun gnus-article-inline-part (n) "Inline MIME part N, which is the numerical prefix." @@ -3935,8 +4015,11 @@ If no internal viewer is available, use an external viewer." (let ((window (selected-window)) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets - (save-excursion (set-buffer gnus-summary-buffer) - gnus-newsgroup-ignored-charsets))) + (if (gnus-buffer-live-p gnus-summary-buffer) + (save-excursion + (set-buffer gnus-summary-buffer) + gnus-newsgroup-ignored-charsets) + nil))) (save-excursion (unwind-protect (let ((win (gnus-get-buffer-window (current-buffer) t)) @@ -4052,7 +4135,9 @@ If no internal viewer is available, use an external viewer." ;; We have to do this since selecting the window ;; may change the point. So we set the window point. (set-window-point window point))) - (let* ((handles (or ihandles (mm-dissect-buffer) (mm-uu-dissect))) + (let* ((handles (or ihandles (mm-dissect-buffer + nil gnus-article-loose-mime) + (mm-uu-dissect))) buffer-read-only handle name type b e display) (when (and (not ihandles) (not gnus-displaying-mime)) @@ -4699,9 +4784,9 @@ The text in the region will be yanked. If the region isn't active, the entire article will be yanked." (interactive "P") (let ((article (cdr gnus-article-current)) cont) - (if (not (mark)) + (if (not (mark t)) (gnus-summary-reply (list (list article)) wide) - (setq cont (buffer-substring (point) (mark))) + (setq cont (buffer-substring (point) (mark t))) ;; Deactivate active regions. (when (and (boundp 'transient-mark-mode) transient-mark-mode) @@ -4716,9 +4801,9 @@ the entire article will be yanked." (interactive) (let ((article (cdr gnus-article-current)) cont) - (if (not (gnus-region-active-p)) + (if (not (mark t)) (gnus-summary-followup (list (list article))) - (setq cont (buffer-substring (point) (mark))) + (setq cont (buffer-substring (point) (mark t))) ;; Deactivate active regions. (when (and (boundp 'transient-mark-mode) transient-mark-mode) @@ -4845,7 +4930,7 @@ If given a prefix, show the hidden text instead." (gnus-cache-request-article article group)) 'article) ;; Check the agent cache. - ((and gnus-agent gnus-agent-cache gnus-plugged + ((and gnus-agent gnus-agent-cache gnus-plugged (numberp article) (gnus-agent-request-article article group)) 'article) @@ -4941,17 +5026,68 @@ If given a prefix, show the hidden text instead." ;; Should we be using derived.el for this? (unless gnus-article-edit-mode-map - (setq gnus-article-edit-mode-map (make-sparse-keymap)) + (setq gnus-article-edit-mode-map (make-keymap)) (set-keymap-parent gnus-article-edit-mode-map text-mode-map) + (gnus-define-keys gnus-article-edit-mode-map + "\C-c?" describe-mode "\C-c\C-c" gnus-article-edit-done - "\C-c\C-k" gnus-article-edit-exit) + "\C-c\C-k" gnus-article-edit-exit + "\C-c\C-f\C-t" message-goto-to + "\C-c\C-f\C-o" message-goto-from + "\C-c\C-f\C-b" message-goto-bcc + ;;"\C-c\C-f\C-w" message-goto-fcc + "\C-c\C-f\C-c" message-goto-cc + "\C-c\C-f\C-s" message-goto-subject + "\C-c\C-f\C-r" message-goto-reply-to + "\C-c\C-f\C-n" message-goto-newsgroups + "\C-c\C-f\C-d" message-goto-distribution + "\C-c\C-f\C-f" message-goto-followup-to + "\C-c\C-f\C-m" message-goto-mail-followup-to + "\C-c\C-f\C-k" message-goto-keywords + "\C-c\C-f\C-u" message-goto-summary + "\C-c\C-f\C-i" message-insert-or-toggle-importance + "\C-c\C-f\C-a" message-gen-unsubscribed-mft + "\C-c\C-b" message-goto-body + "\C-c\C-i" message-goto-signature + + "\C-c\C-t" message-insert-to + "\C-c\C-n" message-insert-newsgroups + "\C-c\C-o" message-sort-headers + "\C-c\C-e" message-elide-region + "\C-c\C-v" message-delete-not-region + "\C-c\C-z" message-kill-to-signature + "\M-\r" message-newline-and-reformat + "\C-c\C-a" mml-attach-file + "\C-a" message-beginning-of-line + "\t" message-tab + "\M-;" comment-region) (gnus-define-keys (gnus-article-edit-wash-map "\C-c\C-w" gnus-article-edit-mode-map) "f" gnus-article-edit-full-stops)) +(easy-menu-define + gnus-article-edit-mode-field-menu gnus-article-edit-mode-map "" + '("Field" + ["Fetch To" message-insert-to t] + ["Fetch Newsgroups" message-insert-newsgroups t] + "----" + ["To" message-goto-to t] + ["From" message-goto-from t] + ["Subject" message-goto-subject t] + ["Cc" message-goto-cc t] + ["Reply-To" message-goto-reply-to t] + ["Summary" message-goto-summary t] + ["Keywords" message-goto-keywords t] + ["Newsgroups" message-goto-newsgroups t] + ["Followup-To" message-goto-followup-to t] + ["Mail-Followup-To" message-goto-mail-followup-to t] + ["Distribution" message-goto-distribution t] + ["Body" message-goto-body t] + ["Signature" message-goto-signature t])) + (define-derived-mode gnus-article-edit-mode text-mode "Article Edit" "Major mode for editing articles. This is an extended text-mode. @@ -4961,6 +5097,9 @@ This is an extended text-mode. (make-local-variable 'gnus-prev-winconf) (set (make-local-variable 'font-lock-defaults) '(message-font-lock-keywords t)) + (set (make-local-variable 'mail-header-separator) "") + (easy-menu-add message-mode-field-menu message-mode-map) + (mml-mode) (setq buffer-read-only nil) (buffer-enable-undo) (widen)) @@ -5000,37 +5139,29 @@ groups." (interactive "P") (let ((func gnus-article-edit-done-function) (buf (current-buffer)) - (start (window-start))) - ;; We remove all text props from the article buffer. - (let ((content - (buffer-substring-no-properties (point-min) (point-max))) - (p (point))) - (erase-buffer) - (insert content) - (let ((winconf gnus-prev-winconf)) - (gnus-article-mode) - (set-window-configuration winconf) - ;; Tippy-toe some to make sure that point remains where it was. - (save-current-buffer - (set-buffer buf) - (set-window-start (get-buffer-window (current-buffer)) start) - (goto-char p)))) + (start (window-start)) + (p (point)) + (winconf gnus-prev-winconf)) + (widen) ;; Widen it in case that users narrowed the buffer. + (funcall func arg) + (set-buffer buf) + ;; The cache and backlog have to be flushed somewhat. + (when gnus-keep-backlog + (gnus-backlog-remove-article + (car gnus-article-current) (cdr gnus-article-current))) + ;; Flush original article as well. (save-excursion - (set-buffer buf) - (let ((buffer-read-only nil)) - (funcall func arg)) - ;; The cache and backlog have to be flushed somewhat. - (when gnus-keep-backlog - (gnus-backlog-remove-article - (car gnus-article-current) (cdr gnus-article-current))) - ;; Flush original article as well. - (save-excursion - (when (get-buffer gnus-original-article-buffer) - (set-buffer gnus-original-article-buffer) - (setq gnus-original-article nil))) - (when gnus-use-cache - (gnus-cache-update-article - (car gnus-article-current) (cdr gnus-article-current)))) + (when (get-buffer gnus-original-article-buffer) + (set-buffer gnus-original-article-buffer) + (setq gnus-original-article nil))) + (when gnus-use-cache + (gnus-cache-update-article + (car gnus-article-current) (cdr gnus-article-current))) + ;; We remove all text props from the article buffer. + (kill-all-local-variables) + (gnus-set-text-properties (point-min) (point-max) nil) + (gnus-article-mode) + (set-window-configuration winconf) (set-buffer buf) (set-window-start (get-buffer-window buf) start) (set-window-point (get-buffer-window buf) (point)))) @@ -5097,7 +5228,7 @@ groups." ;; This is how URLs _should_ be embedded in text... ("]*\\)>" 1 t gnus-button-embedded-url 1) ;; Raw URLs. - (,gnus-button-url-regexp 0 t browse-url 0)) + (gnus-button-url-regexp 0 t browse-url 0)) "*Alist of regexps matching buttons in article bodies. Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where @@ -5111,7 +5242,7 @@ PAR: is a number of a regexp grouping whose text will be passed to CALLBACK. CALLBACK can also be a variable, in that case the value of that variable it the real callback function." :group 'gnus-article-buttons - :type '(repeat (list regexp + :type '(repeat (list (choice regexp variable) (integer :tag "Button") (sexp :tag "Form") (function :tag "Callback") @@ -5298,7 +5429,7 @@ specified by `gnus-button-alist'." (article-goto-body) (setq beg (point)) (while (setq entry (pop alist)) - (setq regexp (car entry)) + (setq regexp (eval (car entry))) (goto-char beg) (while (re-search-forward regexp nil t) (let* ((start (and entry (match-beginning (nth 1 entry)))) @@ -5403,7 +5534,7 @@ specified by `gnus-button-alist'." (entry nil)) (while alist (setq entry (pop alist)) - (if (looking-at (car entry)) + (if (looking-at (eval (car entry))) (setq alist nil) (setq entry nil))) entry)) @@ -5574,7 +5705,7 @@ specified by `gnus-button-alist'." (gnus-eval-format gnus-prev-page-line-format nil `(,@(gnus-local-map-property gnus-prev-page-map) - gnus-prev t + gnus-prev t gnus-callback gnus-article-button-prev-page article-type annotation)) (widget-convert-button @@ -5621,7 +5752,7 @@ specified by `gnus-button-alist'." (buffer-read-only nil)) (gnus-eval-format gnus-next-page-line-format nil `(,@(gnus-local-map-property gnus-next-page-map) - gnus-next t + gnus-next t gnus-callback gnus-article-button-next-page article-type annotation)) (widget-convert-button diff --git a/lisp/gnus-bcklg.el b/lisp/gnus-bcklg.el index f95fcee..400dbd5 100644 --- a/lisp/gnus-bcklg.el +++ b/lisp/gnus-bcklg.el @@ -1,5 +1,5 @@ ;;; gnus-bcklg.el --- backlog functions for Gnus -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen diff --git a/lisp/gnus-cache.el b/lisp/gnus-cache.el index 574821e..ed2f79f 100644 --- a/lisp/gnus-cache.el +++ b/lisp/gnus-cache.el @@ -1,5 +1,5 @@ ;;; gnus-cache.el --- cache interface for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -206,7 +206,8 @@ it's not cached." ;; Update the active info. (set-buffer gnus-summary-buffer) (gnus-cache-possibly-update-active group (cons number number)) - (push article gnus-newsgroup-cached) + (setq gnus-newsgroup-cached + (gnus-add-to-sorted-list gnus-newsgroup-cached article)) (gnus-summary-update-secondary-mark article)) t)))))) @@ -279,9 +280,7 @@ it's not cached." ;; the normal way. (let ((gnus-use-cache nil)) (gnus-retrieve-headers articles group fetch-old)) - (let ((uncached-articles (gnus-sorted-intersection - (gnus-sorted-complement articles cached) - articles)) + (let ((uncached-articles (gnus-sorted-difference articles cached)) (cache-file (gnus-cache-file-name group ".overview")) type) ;; We first retrieve all the headers that we don't have in @@ -363,23 +362,25 @@ Returns the list of articles removed." (defun gnus-summary-insert-cached-articles () "Insert all the articles cached for this group into the current buffer." (interactive) - (let ((cached (sort (copy-sequence gnus-newsgroup-cached) '>)) + (let ((cached gnus-newsgroup-cached) (gnus-verbose (max 6 gnus-verbose))) - (unless cached - (gnus-message 3 "No cached articles for this group")) - (while cached - (gnus-summary-goto-subject (pop cached) t)))) + (if (not cached) + (gnus-message 3 "No cached articles for this group") + (save-excursion + (while cached + (gnus-summary-goto-subject (pop cached) t))) + (gnus-summary-limit (append gnus-newsgroup-cached gnus-newsgroup-limit)) + (gnus-summary-position-point)))) (defun gnus-summary-limit-include-cached () "Limit the summary buffer to articles that are cached." (interactive) - (let ((cached (sort (copy-sequence gnus-newsgroup-cached) '>)) - (gnus-verbose (max 6 gnus-verbose))) - (if cached - (progn - (gnus-summary-limit cached) - (gnus-summary-position-point)) - (gnus-message 3 "No cached articles for this group")))) + (let ((gnus-verbose (max 6 gnus-verbose))) + (if gnus-newsgroup-cached + (progn + (gnus-summary-limit gnus-newsgroup-cached) + (gnus-summary-position-point)) + (gnus-message 3 "No cached articles for this group")))) ;;; Internal functions. @@ -467,8 +468,10 @@ Returns the list of articles removed." (point-max) t)) (delete-region (progn (beginning-of-line) (point)) (progn (forward-line 1) (point))))) - (setq gnus-newsgroup-cached - (delq article gnus-newsgroup-cached)) + (unless (setq gnus-newsgroup-cached + (delq article gnus-newsgroup-cached)) + (gnus-sethash gnus-newsgroup-name nil gnus-cache-active-hashtb) + (setq gnus-cache-active-altered t)) (gnus-summary-update-secondary-mark article) t))) @@ -482,9 +485,13 @@ Returns the list of articles removed." (directory-files dir nil "^[0-9]+$" t)) '<)) ;; Update the cache active file, just to synch more. - (when articles - (gnus-cache-update-active group (car articles) t) - (gnus-cache-update-active group (car (last articles)))) + (if articles + (progn + (gnus-cache-update-active group (car articles) t) + (gnus-cache-update-active group (car (last articles)))) + (when (gnus-gethash group gnus-cache-active-hashtb) + (gnus-sethash group nil gnus-cache-active-hashtb) + (setq gnus-cache-active-altered t))) articles))) (defun gnus-cache-braid-nov (group cached &optional file) @@ -508,13 +515,13 @@ Returns the list of articles removed." (< (read (current-buffer)) (car cached))) (forward-line 1)) (beginning-of-line) - (save-excursion - (set-buffer cache-buf) - (if (search-forward (concat "\n" (int-to-string (car cached)) "\t") - nil t) - (setq beg (progn (beginning-of-line) (point)) - end (progn (end-of-line) (point))) - (setq beg nil))) + (set-buffer cache-buf) + (if (search-forward (concat "\n" (int-to-string (car cached)) "\t") + nil t) + (setq beg (progn (beginning-of-line) (point)) + end (progn (end-of-line) (point))) + (setq beg nil)) + (set-buffer nntp-server-buffer) (when beg (insert-buffer-substring cache-buf beg end) (insert "\n")) @@ -536,20 +543,20 @@ Returns the list of articles removed." (car cached))) (search-forward "\n.\n" nil 'move)) (beginning-of-line) - (save-excursion - (set-buffer cache-buf) - (erase-buffer) - (let ((coding-system-for-read - gnus-cache-coding-system)) - (insert-file-contents (gnus-cache-file-name group (car cached)))) - (goto-char (point-min)) - (insert "220 ") - (princ (car cached) (current-buffer)) - (insert " Article retrieved.\n") - (search-forward "\n\n" nil 'move) - (delete-region (point) (point-max)) - (forward-char -1) - (insert ".")) + (set-buffer cache-buf) + (erase-buffer) + (let ((coding-system-for-read + gnus-cache-coding-system)) + (insert-file-contents (gnus-cache-file-name group (car cached)))) + (goto-char (point-min)) + (insert "220 ") + (princ (car cached) (current-buffer)) + (insert " Article retrieved.\n") + (search-forward "\n\n" nil 'move) + (delete-region (point) (point-max)) + (forward-char -1) + (insert ".") + (set-buffer nntp-server-buffer) (insert-buffer-substring cache-buf) (setq cached (cdr cached))) (kill-buffer cache-buf))) @@ -713,7 +720,6 @@ If GROUP is non-nil, also cater to `gnus-cacheable-groups' and (string-match gnus-cacheable-groups group)) (or (not gnus-uncacheable-groups) (not (string-match gnus-uncacheable-groups group))))))) - (provide 'gnus-cache) diff --git a/lisp/gnus-cite.el b/lisp/gnus-cite.el index 6a09a47..1c5e424 100644 --- a/lisp/gnus-cite.el +++ b/lisp/gnus-cite.el @@ -441,7 +441,8 @@ If WIDTH (the numerical prefix), use that text width when filling." (concat "^" (regexp-quote (cdar marks)) " *")) (fill-prefix (if (string= (cdar marks) "") "" - (concat (cdar marks) " ")))) + (concat (cdar marks) " "))) + use-hard-newlines) (fill-region (point-min) (point-max))) (set-marker (caar marks) nil) (setq marks (cdr marks))) diff --git a/lisp/gnus-cus.el b/lisp/gnus-cus.el index 6df3ffa..85c5cbf 100644 --- a/lisp/gnus-cus.el +++ b/lisp/gnus-cus.el @@ -195,7 +195,7 @@ Which articles to display on entering the group. unread and ticked articles. `Other' - Display the articles that satisfy the S-expression. The S-expression + Display the articles that satisfy the S-expression. The S-expression should be in an array form.") (comment (string :tag "Comment") "\ diff --git a/lisp/gnus-diary.el b/lisp/gnus-diary.el index 11a2b83..51c8500 100644 --- a/lisp/gnus-diary.el +++ b/lisp/gnus-diary.el @@ -265,7 +265,7 @@ There are currently two built-in format functions: (o1 (nndiary-next-occurence s1 now)) (o2 (nndiary-next-occurence s2 now))) (if (and (= (car o1) (car o2)) (= (cadr o1) (cadr o2))) - (< (mail-header-number h1) (mail-header-number h2)) + (< (mail-header-number h1) (mail-header-number h2)) (time-less-p o1 o2)))) diff --git a/lisp/gnus-dired.el b/lisp/gnus-dired.el new file mode 100644 index 0000000..22104f6 --- /dev/null +++ b/lisp/gnus-dired.el @@ -0,0 +1,207 @@ +;;; gnus-dired.el --- utility functions where gnus and dired meet + +;; Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002 +;; Free Software Foundation, Inc. + +;; Authors: Benjamin Rutt , +;; Shenghuo Zhu +;; Keywords: mail, news, extensions + +;; 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: + +;; This package provides utility functions for intersections of gnus +;; and dired. To enable the gnus-dired-mode minor mode which will +;; have the effect of installing keybindings in dired-mode, place the +;; following in your ~/.gnus: + +;; (require 'gnus-dired) ;, isn't needed due to autoload cookies +;; (add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode) + +;; Note that if you visit dired buffers before your ~/.gnus file has +;; been read, those dired buffers won't have the keybindings in +;; effect. To get around that problem, you may want to add the above +;; statements to your ~/.emacs instead. + +;;; Code: + +(require 'dired) +(require 'gnus-ems) +(require 'gnus-msg) +(require 'gnus-util) +(require 'message) +(require 'mm-encode) +(require 'mml) + +(defvar gnus-dired-mode nil + "Minor mode for intersections of gnus and dired.") + +(defvar gnus-dired-mode-map nil) + +(unless gnus-dired-mode-map + (setq gnus-dired-mode-map (make-sparse-keymap)) + + (gnus-define-keys gnus-dired-mode-map + "\C-c\C-a" gnus-dired-attach + "\C-c\C-f" gnus-dired-find-file-mailcap + "\C-cP" gnus-dired-print + )) + +(defun gnus-dired-mode (&optional arg) + "Minor mode for intersections of gnus and dired. + +\\{gnus-dired-mode-map}" + (interactive "P") + (when (eq major-mode 'dired-mode) + (set (make-local-variable 'gnus-dired-mode) + (if (null arg) (not gnus-dired-mode) + (> (prefix-numeric-value arg) 0))) + (when gnus-dired-mode + (gnus-add-minor-mode 'gnus-dired-mode "" gnus-dired-mode-map) + (gnus-run-hooks 'gnus-dired-mode-hook)))) + +;;;###autoload +(defun turn-on-gnus-dired-mode () + "Convenience method to turn on gnus-dired-mode." + (gnus-dired-mode 1)) + +;; Method to attach files to a gnus composition. +(defun gnus-dired-attach (files-to-attach) + "Attach dired's marked files to a gnus message composition. +If called non-interactively, FILES-TO-ATTACH should be a list of +filenames." + (interactive + (list + (delq nil + (mapcar + ;; don't attach directories + (lambda (f) (if (file-directory-p f) nil f)) + (nreverse (dired-map-over-marks (dired-get-filename) nil)))))) + (let ((destination nil) + (files-str nil) + (bufs nil)) + ;; warn if user tries to attach without any files marked + (if (null files-to-attach) + (error "No files to attach") + (setq files-str + (mapconcat + (lambda (f) (file-name-nondirectory f)) + files-to-attach ", ")) + (setq bufs (message-buffers)) + + ;; set up destination message buffer + (if (and bufs + (y-or-n-p "Attach files to existing message buffer? ")) + (setq destination + (if (= (length bufs) 1) + (get-buffer (car bufs)) + (completing-read "Attach to which message buffer: " + (mapcar + (lambda (b) + (cons b (get-buffer b))) + bufs) + nil t))) + ;; setup a new gnus message buffer + (gnus-setup-message 'message (message-mail)) + (setq destination (current-buffer))) + + ;; set buffer to destination buffer, and attach files + (set-buffer destination) + (goto-char (point-max)) ;attach at end of buffer + (while files-to-attach + (mml-attach-file (car files-to-attach) + (or (mm-default-file-encoding (car files-to-attach)) + "application/octet-stream") nil) + (setq files-to-attach (cdr files-to-attach))) + (message "Attached file(s) %s" files-str)))) + +(autoload 'mailcap-parse-mailcaps "mailcap" "" t) + +(defun gnus-dired-find-file-mailcap (&optional file-name arg) + "In dired, visit FILE-NAME according to the mailcap file. +If ARG is non-nil, open it in a new buffer." + (interactive (list + (file-name-sans-versions (dired-get-filename) t) + current-prefix-arg)) + (mailcap-parse-mailcaps) + (if (file-exists-p file-name) + (let (mime-type method) + (if (and (not arg) + (not (file-directory-p file-name)) + (string-match "\\.[^\\.]+$" file-name) + (setq mime-type + (mailcap-extension-to-mime + (match-string 0 file-name))) + (stringp + (setq method + (cdr (assoc 'viewer + (car (mailcap-mime-info mime-type + 'all))))))) + (let ((view-command (mm-mailcap-command method file-name nil))) + (message "viewing via %s" view-command) + (start-process "*display*" + nil + shell-file-name + shell-command-switch + view-command)) + (find-file file-name))) + (if (file-symlink-p file-name) + (error "File is a symlink to a nonexistent target") + (error "File no longer exists; type `g' to update Dired buffer")))) + +(defun gnus-dired-print (&optional file-name print-to) + "In dired, print FILE-NAME according to the mailcap file. + +If there is no print command, print in a PostScript image. If the +optional argument PRINT-TO is nil, send the image to the printer. If +PRINT-TO is a string, save the PostScript image in a file with that +name. If PRINT-TO is a number, prompt the user for the name of the +file to save in." + (interactive (list + (file-name-sans-versions (dired-get-filename) t) + (ps-print-preprint current-prefix-arg))) + (mailcap-parse-mailcaps) + (cond + ((file-directory-p file-name) + (error "Can't print a directory")) + ((file-exists-p file-name) + (let (mime-type method) + (if (and (string-match "\\.[^\\.]+$" file-name) + (setq mime-type + (mailcap-extension-to-mime + (match-string 0 file-name))) + (stringp + (setq method (mailcap-mime-info mime-type "print")))) + (call-process shell-file-name nil + (generate-new-buffer " *mm*") + nil + shell-command-switch + (mm-mailcap-command method file-name mime-type)) + (with-temp-buffer + (insert-file-contents file-name) + (gnus-print-buffer)) + (ps-despool print-to)))) + ((file-symlink-p file-name) + (error "File is a symlink to a nonexistent target")) + (t + (error "File no longer exists; type `g' to update Dired buffer")))) + +(provide 'gnus-dired) + +;;; gnus-dired.el ends here diff --git a/lisp/gnus-draft.el b/lisp/gnus-draft.el index 9b18989..887e12d 100644 --- a/lisp/gnus-draft.el +++ b/lisp/gnus-draft.el @@ -131,7 +131,7 @@ (defun gnus-draft-send (article &optional group interactive) "Send message ARTICLE." - (let ((message-syntax-checks (if interactive nil + (let ((message-syntax-checks (if interactive message-syntax-checks 'dont-check-for-anything-just-trust-me)) (message-inhibit-body-encoding (or (not group) (equal group "nndraft:queue") diff --git a/lisp/gnus-dup.el b/lisp/gnus-dup.el index e148f45..a2b5544 100644 --- a/lisp/gnus-dup.el +++ b/lisp/gnus-dup.el @@ -113,7 +113,7 @@ seen in the same session." (gnus-dup-open)) (setq gnus-dup-list-dirty t) ; mark list for saving (let ((data gnus-newsgroup-data) - datum msgid) + datum msgid) ;; Enter the Message-IDs of all read articles into the list ;; and hash table. (while (setq datum (pop data)) @@ -121,11 +121,11 @@ seen in the same session." (> (gnus-data-number datum) 0) (not (memq (gnus-data-number datum) gnus-newsgroup-unreads)) (not (= (gnus-data-mark datum) gnus-canceled-mark)) - (setq msgid (mail-header-id (gnus-data-header datum))) - (not (nnheader-fake-message-id-p msgid)) - (not (intern-soft msgid gnus-dup-hashtb))) + (setq msgid (mail-header-id (gnus-data-header datum))) + (not (nnheader-fake-message-id-p msgid)) + (not (intern-soft msgid gnus-dup-hashtb))) (push msgid gnus-dup-list) - (intern msgid gnus-dup-hashtb)))) + (intern msgid gnus-dup-hashtb)))) ;; Chop off excess Message-IDs from the list. (let ((end (nthcdr gnus-duplicate-list-length gnus-dup-list))) (when end diff --git a/lisp/gnus-ems.el b/lisp/gnus-ems.el index f3fd5a9..fcf3a26 100644 --- a/lisp/gnus-ems.el +++ b/lisp/gnus-ems.el @@ -47,9 +47,7 @@ (autoload 'gnus-xmas-redefine "gnus-xmas") (autoload 'appt-select-lowest-window "appt")) -(if (featurep 'xemacs) - (autoload 'smiley-region "smiley") - (autoload 'smiley-region "smiley-ems")) ; override XEmacs version +(autoload 'smiley-region "smiley") (defun gnus-kill-all-overlays () "Delete all overlays in the current buffer." @@ -118,7 +116,7 @@ ;; original MULE, XEmacs/mule and Emacs 20+ including ;; MULE features. Unfortunately these API are different. In ;; particular, Emacs (including original MULE) and XEmacs are - ;; quite different. Howvere, this version of Gnus doesn't support + ;; quite different. However, this version of Gnus doesn't support ;; anything other than XEmacs 20+ and Emacs 20.3+. ;; Predicates to check are following: @@ -225,7 +223,7 @@ (defun gnus-put-image (glyph &optional string) (insert-image glyph (or string " ")) (unless string - (put-text-property (1- (point)) (point) + (put-text-property (1- (point)) (point) 'gnus-image-text-deletable t)) glyph) diff --git a/lisp/gnus-fun.el b/lisp/gnus-fun.el index 000a26c..190e3c4 100644 --- a/lisp/gnus-fun.el +++ b/lisp/gnus-fun.el @@ -35,11 +35,24 @@ :group 'gnus-fun :type 'string) -(defcustom gnus-convert-image-to-x-face-command "giftopnm %s | ppmnorm 2>/dev/null | pnmscale -width 48 -height 48 | ppmtopgm | pgmtopbm | pbmtoxbm | compface" +(defcustom gnus-convert-image-to-x-face-command "giftopnm %s | ppmnorm | pnmscale -width 48 -height 48 | ppmtopgm | pgmtopbm | pbmtoxbm | compface" "Command for converting a GIF to an X-Face." :group 'gnus-fun :type 'string) +(defun gnus-shell-command-to-string (command) + "Like `shell-command-to-string' except not mingling ERROR." + (with-output-to-string + (call-process shell-file-name nil (list standard-output nil) + nil shell-command-switch command))) + +(defun gnus-shell-command-on-region (start end command) + "A simplified `shell-command-on-region'. +Output to the current buffer, replace text, and don't mingle error." + (call-process-region start end shell-file-name t + (list (current-buffer) nil) + nil shell-command-switch command)) + ;;;###autoload (defun gnus-random-x-face () "Insert a random X-Face header from `gnus-x-face-directory'." @@ -48,7 +61,7 @@ (let* ((files (directory-files gnus-x-face-directory t "\\.pbm$")) (file (nth (random (length files)) files))) (when file - (shell-command-to-string + (gnus-shell-command-to-string (format gnus-convert-pbm-to-x-face-command (shell-quote-argument file))))))) @@ -57,12 +70,13 @@ "Insert an X-Face header based on an image file." (interactive "fImage file name:" ) (when (file-exists-p file) - (shell-command-to-string + (gnus-shell-command-to-string (format gnus-convert-image-to-x-face-command (shell-quote-argument file))))) (defun gnus-convert-image-to-gray-x-face (file depth) - (let* ((mapfile (make-temp-name (expand-file-name "gnus." mm-tmp-directory))) + (let* ((mapfile (mm-make-temp-file (expand-file-name "gnus." + mm-tmp-directory))) (levels (expt 2 depth)) (step (/ 255 (1- levels))) color-alist bits bits-list mask pixel x-faces) @@ -76,8 +90,8 @@ (push (cons (* step i) i) color-alist))) (when (file-exists-p file) (with-temp-buffer - (insert (shell-command-to-string - (format "giftopnm %s | ppmnorm 2>/dev/null | pnmscale -width 48 -height 48 | ppmquant -fs -map %s 2>/dev/null | ppmtopgm | pnmnoraw" + (insert (gnus-shell-command-to-string + (format "giftopnm %s | ppmnorm | pnmscale -width 48 -height 48 | ppmquant -fs -map %s | ppmtopgm | pnmnoraw" (shell-quote-argument file) mapfile))) (goto-char (point-min)) @@ -91,10 +105,10 @@ (insert "P1\n48 48\n") (dolist (bits bits-list) (insert (if (zerop (logand bits mask)) "0 " "1 "))) - (shell-command-on-region + (gnus-shell-command-on-region (point-min) (point-max) - "pbmtoxbm | compface" - (current-buffer) t) + ;; the following is taken from xbmtoikon: + "pbmtoicon | sed '/^[ ]*[*\\\\/]/d; s/[ ]//g; s/,$//' | tr , '\\012' | sed 's/^0x//; s/^/0x/' | pr -l1 -t -w22 -3 -s, | sed 's/,*$/,/' | compface") (push (buffer-string) x-faces)))) (dotimes (i (length x-faces)) (insert (if (zerop i) "X-Face:" (format "X-Face-%s:" i)) @@ -106,41 +120,41 @@ (let* ((depth (length faces)) (scale (/ 255 (1- (expt 2 depth)))) (ok-p t) - bit-list bit-lists pixels pixel) - (dolist (face faces) - (setq bit-list nil) - (with-temp-buffer + (coding-system-for-read 'binary) + (coding-system-for-write 'binary) + default-enable-multibyte-characters + start bit-array bit-arrays pixel) + (with-temp-buffer + (dolist (face faces) + (erase-buffer) (insert (uncompface face)) - (shell-command-on-region + (gnus-shell-command-on-region (point-min) (point-max) - "pnmnoraw 2>/dev/null" - (current-buffer) t) + "pnmnoraw") (goto-char (point-min)) (forward-line 2) + (setq start (point)) + (insert "[") (while (not (eobp)) - (cond - ((eq (following-char) ?0) - (push 0 bit-list)) - ((eq (following-char) ?1) - (push 1 bit-list))) - (forward-char 1))) - (unless (= (length bit-list) (* 48 48)) - (setq ok-p nil)) - (push bit-list bit-lists)) - (when ok-p - (dotimes (i (* 48 48)) - (setq pixel 0) - (dotimes (plane depth) - (setq pixel (+ (* pixel 2) (nth i (nth plane bit-lists))))) - (push pixel pixels)) - (with-temp-buffer + (forward-char 1) + (insert " ")) + (insert "]") + (goto-char start) + (setq bit-array (read (current-buffer))) + (unless (= (length bit-array) (* 48 48)) + (setq ok-p nil)) + (push bit-array bit-arrays)) + (when ok-p + (erase-buffer) (insert "P2\n48 48\n255\n") - (dolist (pixel pixels) + (dotimes (i (* 48 48)) + (setq pixel 0) + (dotimes (plane depth) + (setq pixel (+ (* pixel 2) (aref (nth plane bit-arrays) i)))) (insert (number-to-string (* scale pixel)) " ")) - (shell-command-on-region + (gnus-shell-command-on-region (point-min) (point-max) - "ppmtoxpm 2>/dev/null" - (current-buffer) t) + "ppmtoxpm") (buffer-string))))) ;;;###autoload @@ -176,7 +190,7 @@ colors of the displayed X-Faces." (save-restriction (article-narrow-to-head) (gnus-article-goto-header "from") - (when (bobp) + (when (bobp) (insert "From: [no `from' set]\n") (forward-char -17)) (gnus-add-image diff --git a/lisp/gnus-group.el b/lisp/gnus-group.el index 9278e09..fb3540c 100644 --- a/lisp/gnus-group.el +++ b/lisp/gnus-group.el @@ -159,6 +159,7 @@ with some simple extensions. %G Group name (string) %g Qualified group name (string) %c Short (collapsed) group name. See `gnus-group-uncollapsed-levels'. +%C Group comment (string) %D Group description (string) %s Select method (string) %o Moderated group (char, \"m\") @@ -190,8 +191,8 @@ Also note that if you change the format specification to include any of these specs, you must probably re-start Gnus to see them go into effect. -General format specifiers can also be used. -See (gnus)Formatting Variables." +General format specifiers can also be used. +See `(gnus)Formatting Variables'." :link '(custom-manual "(gnus)Formatting Variables") :group 'gnus-group-visual :type 'string) @@ -474,6 +475,7 @@ simple manner.") (?g gnus-tmp-group ?s) (?G gnus-tmp-qualified-group ?s) (?c (gnus-short-group-name gnus-tmp-group) ?s) + (?C gnus-tmp-comment ?s) (?D gnus-tmp-newsgroup-description ?s) (?o gnus-tmp-moderated ?c) (?O gnus-tmp-moderated-string ?s) @@ -787,7 +789,8 @@ simple manner.") ["Sort by score" gnus-group-sort-groups-by-score t] ["Sort by level" gnus-group-sort-groups-by-level t] ["Sort by unread" gnus-group-sort-groups-by-unread t] - ["Sort by name" gnus-group-sort-groups-by-alphabet t]) + ["Sort by name" gnus-group-sort-groups-by-alphabet t] + ["Sort by real name" gnus-group-sort-groups-by-real-name t]) ("Sort process/prefixed" ["Default sort" gnus-group-sort-selected-groups (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] @@ -802,6 +805,8 @@ simple manner.") ["Sort by unread" gnus-group-sort-selected-groups-by-unread (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] ["Sort by name" gnus-group-sort-selected-groups-by-alphabet + (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))] + ["Sort by real name" gnus-group-sort-selected-groups-by-real-name (or (not (boundp 'gnus-topic-mode)) (not gnus-topic-mode))]) ("Mark" ["Mark group" gnus-group-mark-group @@ -905,9 +910,11 @@ simple manner.") ;; Emacs 21 tool bar. Should be no-op otherwise. (defun gnus-group-make-tool-bar () - (if (and (fboundp 'tool-bar-add-item-from-menu) - (default-value 'tool-bar-mode) - (not gnus-group-toolbar-map)) + (if (and + (condition-case nil (require 'tool-bar) (error nil)) + (fboundp 'tool-bar-add-item-from-menu) + (default-value 'tool-bar-mode) + (not gnus-group-toolbar-map)) (setq gnus-group-toolbar-map (let ((tool-bar-map (make-sparse-keymap)) (load-path (mm-image-load-path))) @@ -1030,8 +1037,7 @@ The following commands are available: result))) (defun gnus-group-name-decode (string charset) - (if (and string charset (featurep 'mule) - (not (mm-multibyte-string-p string))) + (if (and string charset (featurep 'mule)) (mm-decode-coding-string string charset) string)) @@ -1314,6 +1320,9 @@ if it is a string, only list groups matching REGEXP." (gnus-tmp-qualified-group (gnus-group-name-decode (gnus-group-real-name gnus-tmp-group) group-name-charset)) + (gnus-tmp-comment + (or (gnus-group-get-parameter gnus-tmp-group 'comment t) + gnus-tmp-group)) (gnus-tmp-newsgroup-description (if gnus-description-hashtb (or (gnus-group-name-decode @@ -1711,7 +1720,7 @@ Take into consideration N (the prefix) and the list of marked groups." (setq n (1- n)) (gnus-group-next-group way))) (nreverse groups))) - ((gnus-region-active-p) + ((and (gnus-region-active-p) (mark)) ;; Work on the region between point and mark. (let ((max (max (point) (mark))) groups) @@ -1888,14 +1897,14 @@ Return the name of the group if selection was successful." (,(intern (format "%s-address" (car method))) ,(cadr method)) ,@(cddr method))) (let ((group (if (gnus-group-foreign-p group) group - (gnus-group-prefixed-name (gnus-group-real-name group) + (gnus-group-prefixed-name (gnus-group-real-name group) method)))) (gnus-sethash group `(-1 nil (,group ,gnus-level-default-subscribed nil nil ,method ,(cons - (if quit-config + (if quit-config (cons 'quit-config quit-config) (cons 'quit-config (cons gnus-summary-buffer @@ -2073,7 +2082,7 @@ If EXCLUDE-GROUP, do not go to that group." (forward-line 1)) (when best-point (goto-char best-point)) - (gnus-summary-position-point) + (gnus-group-position-point) (and best-point (gnus-group-group-name)))) (defun gnus-group-first-unread-group () @@ -2186,6 +2195,9 @@ doing the deletion." (gnus-group-goto-group group) (gnus-group-kill-group 1 t) (gnus-sethash group nil gnus-active-hashtb) + (when gnus-cache-active-hashtb + (gnus-sethash group nil gnus-cache-active-hashtb) + (setq gnus-cache-active-altered t)) t)) (gnus-group-position-point))) @@ -2686,6 +2698,12 @@ If REVERSE, sort in reverse order." (interactive "P") (gnus-group-sort-groups 'gnus-group-sort-by-alphabet reverse)) +(defun gnus-group-sort-groups-by-real-name (&optional reverse) + "Sort the group buffer alphabetically by real (unprefixed) group name. +If REVERSE, sort in reverse order." + (interactive "P") + (gnus-group-sort-groups 'gnus-group-sort-by-real-name reverse)) + (defun gnus-group-sort-groups-by-unread (&optional reverse) "Sort the group buffer by number of unread articles. If REVERSE, sort in reverse order." @@ -2764,6 +2782,13 @@ sort in reverse order." (interactive (gnus-interactive "P\ny")) (gnus-group-sort-selected-groups n 'gnus-group-sort-by-alphabet reverse)) +(defun gnus-group-sort-selected-groups-by-real-name (&optional n reverse) + "Sort the group buffer alphabetically by real group name. +Obeys the process/prefix convention. If REVERSE (the symbolic prefix), +sort in reverse order." + (interactive (gnus-interactive "P\ny")) + (gnus-group-sort-selected-groups n 'gnus-group-sort-by-real-name reverse)) + (defun gnus-group-sort-selected-groups-by-unread (&optional n reverse) "Sort the group buffer by number of unread articles. Obeys the process/prefix convention. If REVERSE (the symbolic prefix), @@ -3693,10 +3718,10 @@ The hook gnus-suspend-gnus-hook is called before actually suspending." (let ((group-buf (get-buffer gnus-group-buffer))) (mapcar (lambda (buf) (unless (or (member buf (list group-buf gnus-dribble-buffer)) - (progn + (progn (save-excursion - (set-buffer buf) - (eq major-mode 'message-mode)))) + (set-buffer buf) + (eq major-mode 'message-mode)))) (gnus-kill-buffer buf))) (gnus-buffers)) (gnus-kill-gnus-frames) @@ -4020,7 +4045,7 @@ This command may read the active file." (mark gnus-read-mark) active n) (if (get-buffer buffer) - (with-current-buffer buffer + (with-current-buffer buffer (setq active gnus-newsgroup-active) (gnus-activate-group group) (when gnus-newsgroup-prepared @@ -4036,7 +4061,9 @@ This command may read the active file." (while (<= n (cdr gnus-newsgroup-active)) (unless (eq n article) (push n gnus-newsgroup-unselected)) - (setq n (1+ n)))))) + (setq n (1+ n))) + (setq gnus-newsgroup-unselected + (nreverse gnus-newsgroup-unselected))))) (gnus-activate-group group) (gnus-group-make-articles-read group (list article)) diff --git a/lisp/gnus-int.el b/lisp/gnus-int.el index 91c687a..47f4548 100644 --- a/lisp/gnus-int.el +++ b/lisp/gnus-int.el @@ -202,16 +202,16 @@ If it is down, start it up (again)." (setq elem (list gnus-command-method nil) gnus-opened-servers (cons elem gnus-opened-servers))) ;; Set the status of this server. - (setcar (cdr elem) - (if result + (setcar (cdr elem) + (if result (if (eq (cadr elem) 'offline) 'offline 'ok) - (if (and gnus-agent + (if (and gnus-agent (not (eq (cadr elem) 'offline)) (gnus-agent-method-p gnus-command-method)) (or gnus-server-unopen-status - (if (gnus-y-or-n-p + (if (gnus-y-or-n-p (format "Unable to open %s:%s, go offline? " (car gnus-command-method) (cadr gnus-command-method))) @@ -514,9 +514,9 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned." (let ((mail-parse-charset message-default-charset)) (mail-encode-encoded-word-buffer))) (message-encode-message-body))) - (let ((func (car (or gnus-command-method - (gnus-find-method-for-group group))))) - (funcall (intern (format "%s-request-accept-article" func)) + (let ((gnus-command-method (or gnus-command-method + (gnus-find-method-for-group group)))) + (funcall (gnus-get-function gnus-command-method 'request-accept-article) (if (stringp group) (gnus-group-real-name group) group) (cadr gnus-command-method) last))) diff --git a/lisp/gnus-kill.el b/lisp/gnus-kill.el index b134be9..dd6a774 100644 --- a/lisp/gnus-kill.el +++ b/lisp/gnus-kill.el @@ -428,16 +428,6 @@ Returns the number of articles marked as read." 0)))) ;; Parse a Gnus killfile. -(defun gnus-score-insert-help (string alist idx) - (save-excursion - (pop-to-buffer "*Score Help*") - (buffer-disable-undo) - (erase-buffer) - (insert string ":\n\n") - (while alist - (insert (format " %c: %s\n" (caar alist) (nth idx (car alist)))) - (setq alist (cdr alist))))) - (defun gnus-kill-parse-gnus-kill-file () (goto-char (point-min)) (gnus-kill-file-mode) diff --git a/lisp/gnus-ml.el b/lisp/gnus-ml.el index 41f85ae..978b2e3 100644 --- a/lisp/gnus-ml.el +++ b/lisp/gnus-ml.el @@ -177,7 +177,7 @@ If FORCE is non-nil, replace the old ones." (cond ((string-match "]*\\)>" address) (let ((args (match-string 1 address))) - (cond ; with param + (cond ; with param ((string-match "\\(.*\\)\\?\\(.*\\)" args) (setq mailto (match-string 1 args)) (let ((param (match-string 2 args))) @@ -188,7 +188,7 @@ If FORCE is non-nil, replace the old ones." (if (string-match "to=\\([^&]*\\)" param) (push (match-string 1 param) to)) )) - (t (setq mailto args))))) ; without param + (t (setq mailto args))))) ; without param ; other case +(defun gnus-summary-resend-message-edit () + "Resend an article that has already been sent. +A new buffer will be created to allow the user to modify body and +contents of the message, and then, everything will happen as when +composing a new message." + (interactive) + (let ((article (gnus-summary-article-number))) + (gnus-setup-message 'reply-yank + (gnus-summary-select-article t) + (set-buffer gnus-original-article-buffer) + (let ((cur (current-buffer)) + (to (message-fetch-field "to"))) + ;; Get a normal message buffer. + (message-pop-to-buffer (message-buffer-name "Resend" to)) + (insert-buffer-substring cur) + (mime-to-mml) + (message-narrow-to-head-1) + ;; Gnus will generate a new one when sending. + (message-remove-header "Message-ID") + (message-remove-header message-ignored-resent-headers t) + ;; Remove unwanted headers. + (goto-char (point-max)) + (insert mail-header-separator) + (goto-char (point-min)) + (re-search-forward "^To:\\|^Newsgroups:" nil 'move) + (forward-char 1) + (widen))))) + (defun gnus-summary-post-forward (&optional arg) "Forward the current article to a newsgroup. See `gnus-summary-mail-forward' for ARG." @@ -1210,7 +1312,7 @@ If YANK is non-nil, include the original article." (save-excursion (re-search-backward "[ \t\n]" nil t) (1+ (point))) (save-excursion (re-search-forward "[ \t\n]" nil t) (1- (point)))))) (when address - (message-reply address) + (gnus-msg-mail address) (when yank (gnus-inews-yank-articles (list (cdr gnus-article-current))))))) @@ -1274,10 +1376,7 @@ If YANK is non-nil, include the original article." "Attempts to go through the Gnus source file and report what variables have been changed. The source file has to be in the Emacs load path." (interactive) - (let ((files '("gnus.el" "gnus-sum.el" "gnus-group.el" - "gnus-art.el" "gnus-start.el" "gnus-async.el" - "gnus-msg.el" "gnus-score.el" "gnus-win.el" "gnus-topic.el" - "nnmail.el" "message.el")) + (let ((files gnus-debug-files) (point (point)) file expr olist sym) (gnus-message 4 "Please wait while we snoop your variables...") @@ -1300,6 +1399,7 @@ The source file has to be in the Emacs load path." (and (or (eq (car expr) 'defvar) (eq (car expr) 'defcustom)) (stringp (nth 3 expr)) + (not (memq (nth 1 expr) gnus-debug-exclude-variables)) (or (not (boundp (nth 1 expr))) (not (equal (eval (nth 2 expr)) (symbol-value (nth 1 expr))))) @@ -1437,7 +1537,7 @@ this is a reply." (gnus-message 1 "Couldn't store article in group %s: %s" group (gnus-status-message method)) (sit-for 2)) - (when (and group-art + (when (and group-art (or gnus-gcc-mark-as-read gnus-inews-mark-gcc-as-read)) (gnus-group-mark-article-read group (cdr group-art))) @@ -1560,6 +1660,7 @@ this is a reply." ;; Regexp string match on the group name. (string-match match group)) ((eq match 'header) + ;; Obsolete format of header match. (and (gnus-buffer-live-p gnus-article-copy) (with-current-buffer gnus-article-copy (let ((header (message-fetch-field (pop style)))) @@ -1575,8 +1676,17 @@ this is a reply." ;; Variable to be checked. (symbol-value match)))) ((listp match) - ;; This is a form to be evaled. - (eval match))) + (cond + ((eq (car match) 'header) + ;; New format of header match. + (and (gnus-buffer-live-p gnus-article-copy) + (with-current-buffer gnus-article-copy + (let ((header (message-fetch-field (nth 1 match)))) + (and header + (string-match (nth 2 match) header)))))) + (t + ;; This is a form to be evaled. + (eval match))))) ;; We have a match, so we set the variables. (dolist (attribute style) (setq element (pop attribute) @@ -1605,13 +1715,20 @@ this is a reply." ((listp value) (eval value)))) ;; Translate obsolescent value. - (when (eq element 'signature-file) + (cond + ((eq element 'signature-file) (setq element 'signature filep t)) + ((eq element 'x-face-file) + (setq element 'x-face + filep t))) ;; Get the contents of file elems. (when (and filep v) (setq v (with-temp-buffer (insert-file-contents v) + (goto-char (point-max)) + (while (bolp) + (delete-char -1)) (buffer-string)))) (setq results (delq (assoc element results) results)) (push (cons element v) results)))) diff --git a/lisp/gnus-picon.el b/lisp/gnus-picon.el index e273667..188f071 100644 --- a/lisp/gnus-picon.el +++ b/lisp/gnus-picon.el @@ -168,7 +168,7 @@ GLYPH can be either a glyph or a string." gnus-picon-user-directories))) (setcar spec (cons (gnus-picon-create-glyph file) (car spec)))) - + (dotimes (i (1- (length spec))) (when (setq file (gnus-picon-find-face (concat "unknown@" @@ -180,7 +180,7 @@ GLYPH can be either a glyph or a string." (nth (1+ i) spec))))) (setq spec (nreverse spec)) (push (cons address spec) gnus-picon-cache)) - + (gnus-article-goto-header header) (mail-header-narrow-to-field) (when (search-forward address nil t) diff --git a/lisp/gnus-range.el b/lisp/gnus-range.el index 9358c13..b609074 100644 --- a/lisp/gnus-range.el +++ b/lisp/gnus-range.el @@ -1,6 +1,6 @@ ;;; gnus-range.el --- range and sequence functions for Gnus -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -34,7 +34,7 @@ (defsubst gnus-range-normalize (range) "Normalize RANGE. If RANGE is a single range, return (RANGE). Otherwise, return RANGE." - (if (listp (cdr range)) (list range) range)) + (if (listp (cdr-safe range)) range (list range))) (defun gnus-last-element (list) "Return last element of LIST." @@ -61,6 +61,43 @@ If RANGE is a single range, return (RANGE). Otherwise, return RANGE." (setq list2 (cdr list2))) list1)) +;;;###autoload +(defun gnus-sorted-difference (list1 list2) + "Return a list of elements of LIST1 that do not appear in LIST2. +Both lists have to be sorted over <. +The tail of LIST1 is not copied." + (let (out) + (while (and list1 list2) + (cond ((= (car list1) (car list2)) + (setq list1 (cdr list1) + list2 (cdr list2))) + ((< (car list1) (car list2)) + (setq out (cons (car list1) out)) + (setq list1 (cdr list1))) + (t + (setq list2 (cdr list2))))) + (nconc (nreverse out) list1))) + +;;;###autoload +(defun gnus-sorted-ndifference (list1 list2) + "Return a list of elements of LIST1 that do not appear in LIST2. +Both lists have to be sorted over <. +LIST1 is modified." + (let* ((top (cons nil list1)) + (prev top)) + (while (and list1 list2) + (cond ((= (car list1) (car list2)) + (setcdr prev (cdr list1)) + (setq list1 (cdr list1) + list2 (cdr list2))) + ((< (car list1) (car list2)) + (setq prev list1 + list1 (cdr list1))) + (t + (setq list2 (cdr list2))))) + (cdr top))) + +;;;###autoload (defun gnus-sorted-complement (list1 list2) "Return a list of elements that are in LIST1 or LIST2 but not both. Both lists have to be sorted over <." @@ -79,6 +116,7 @@ Both lists have to be sorted over <." (setq list2 (cdr list2))))) (nconc (nreverse out) (or list1 list2))))) +;;;###autoload (defun gnus-intersection (list1 list2) (let ((result nil)) (while list2 @@ -87,8 +125,10 @@ Both lists have to be sorted over <." (setq list2 (cdr list2))) result)) +;;;###autoload (defun gnus-sorted-intersection (list1 list2) - ;; LIST1 and LIST2 have to be sorted over <. + "Return intersection of LIST1 and LIST2. +LIST1 and LIST2 have to be sorted over <." (let (out) (while (and list1 list2) (cond ((= (car list1) (car list2)) @@ -101,9 +141,13 @@ Both lists have to be sorted over <." (setq list2 (cdr list2))))) (nreverse out))) -(defun gnus-set-sorted-intersection (list1 list2) - ;; LIST1 and LIST2 have to be sorted over <. - ;; This function modifies LIST1. +;;;###autoload +(defalias 'gnus-set-sorted-intersection 'gnus-sorted-nintersection) + +;;;###autoload +(defun gnus-sorted-nintersection (list1 list2) + "Return intersection of LIST1 and LIST2 by modifying cdr pointers of LIST1. +LIST1 and LIST2 have to be sorted over <." (let* ((top (cons nil list1)) (prev top)) (while (and list1 list2) @@ -119,6 +163,55 @@ Both lists have to be sorted over <." (setcdr prev nil) (cdr top))) +;;;###autoload +(defun gnus-sorted-union (list1 list2) + "Return union of LIST1 and LIST2. +LIST1 and LIST2 have to be sorted over <." + (let (out) + (while (and list1 list2) + (cond ((= (car list1) (car list2)) + (setq out (cons (car list1) out) + list1 (cdr list1) + list2 (cdr list2))) + ((< (car list1) (car list2)) + (setq out (cons (car list1) out) + list1 (cdr list1))) + (t + (setq out (cons (car list2) out) + list2 (cdr list2))))) + (while list1 + (setq out (cons (car list1) out) + list1 (cdr list1))) + (while list2 + (setq out (cons (car list2) out) + list2 (cdr list2))) + (nreverse out))) + +;;;###autoload +(defun gnus-sorted-nunion (list1 list2) + "Return union of LIST1 and LIST2 by modifying cdr pointers of LIST1. +LIST1 and LIST2 have to be sorted over <." + (let* ((top (cons nil list1)) + (prev top)) + (while (and list1 list2) + (cond ((= (car list1) (car list2)) + (setq prev list1 + list1 (cdr list1) + list2 (cdr list2))) + ((< (car list1) (car list2)) + (setq prev list1 + list1 (cdr list1))) + (t + (setcdr prev (list (car list2))) + (setq prev (cdr prev) + list2 (cdr list2)) + (setcdr prev list1)))) + (while list2 + (setcdr prev (list (car list2))) + (setq prev (cdr prev) + list2 (cdr list2))) + (cdr top))) + (defun gnus-compress-sequence (numbers &optional always-list) "Convert list of numbers to a list of ranges or a single range. If ALWAYS-LIST is non-nil, this function will always release a list of @@ -325,9 +418,58 @@ modified." (setq ranges (cdr ranges))) (not not-stop)))) +(defun gnus-list-range-intersection (list ranges) + "Return a list of numbers in LIST that are members of RANGES. +LIST is a sorted list." + (setq ranges (gnus-range-normalize ranges)) + (let (number result) + (while (setq number (pop list)) + (while (and ranges + (if (numberp (car ranges)) + (< (car ranges) number) + (< (cdar ranges) number))) + (setq ranges (cdr ranges))) + (when (and ranges + (if (numberp (car ranges)) + (= (car ranges) number) + ;; (caar ranges) <= number <= (cdar ranges) + (>= number (caar ranges)))) + (push number result))) + (nreverse result))) + +(defalias 'gnus-inverse-list-range-intersection 'gnus-list-range-difference) + +(defun gnus-list-range-difference (list ranges) + "Return a list of numbers in LIST that are not members of RANGES. +LIST is a sorted list." + (setq ranges (gnus-range-normalize ranges)) + (let (number result) + (while (setq number (pop list)) + (while (and ranges + (if (numberp (car ranges)) + (< (car ranges) number) + (< (cdar ranges) number))) + (setq ranges (cdr ranges))) + (when (or (not ranges) + (if (numberp (car ranges)) + (not (= (car ranges) number)) + ;; not ((caar ranges) <= number <= (cdar ranges)) + (< number (caar ranges)))) + (push number result))) + (nreverse result))) + (defun gnus-range-length (range) "Return the length RANGE would have if uncompressed." - (length (gnus-uncompress-range range))) + (cond + ((null range) + 0) + ((not (listp (cdr range))) + (- (cdr range) (car range) -1)) + (t + (let ((sum 0)) + (dolist (x range sum) + (setq sum + (+ sum (if (consp x) (- (cdr x) (car x) -1) 1)))))))) (defun gnus-sublist-p (list sublist) "Test whether all elements in SUBLIST are members of LIST." @@ -393,6 +535,18 @@ modified." (if item (push item range)) (reverse range))) +;;;###autoload +(defun gnus-add-to-sorted-list (list num) + "Add NUM into sorted LIST by side effect." + (let* ((top (cons nil list)) + (prev top)) + (while (and list (< (car list) num)) + (setq prev list + list (cdr list))) + (unless (eq (car list) num) + (setcdr prev (cons num list))) + (cdr top))) + (provide 'gnus-range) ;;; gnus-range.el ends here diff --git a/lisp/gnus-score.el b/lisp/gnus-score.el index a10fb63..909d39c 100644 --- a/lisp/gnus-score.el +++ b/lisp/gnus-score.el @@ -735,10 +735,13 @@ used as score." (insert (format format (caar alist) (nth idx (car alist)))) (setq alist (cdr alist)) (setq i (1+ i)))) + (goto-char (point-min)) ;; display ourselves in a small window at the bottom (gnus-appt-select-lowest-window) - (split-window) - (pop-to-buffer "*Score Help*") + (if (< (/ (window-height) 2) window-min-height) + (switch-to-buffer "*Score Help*") + (split-window) + (pop-to-buffer "*Score Help*")) (let ((window-min-height 1)) (shrink-window-if-larger-than-buffer)) (select-window (gnus-get-buffer-window gnus-summary-buffer t)))) diff --git a/lisp/gnus-sieve.el b/lisp/gnus-sieve.el index 36c99d0..18300ed 100644 --- a/lisp/gnus-sieve.el +++ b/lisp/gnus-sieve.el @@ -219,7 +219,7 @@ This is returned as a string." (let* ((newsrc (cdr gnus-newsrc-alist)) script) (dolist (info newsrc) - (when (or (not method) + (when (or (not method) (gnus-server-equal method (gnus-info-method info))) (let* ((group (gnus-info-group info)) (spec (gnus-group-find-parameter group 'sieve t))) diff --git a/lisp/gnus-soup.el b/lisp/gnus-soup.el index 1f43068..5fcda57 100644 --- a/lisp/gnus-soup.el +++ b/lisp/gnus-soup.el @@ -1,6 +1,6 @@ ;;; gnus-soup.el --- SOUP packet writing support for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002 ;; Free Software Foundation, Inc. ;; Author: Per Abrahamsen @@ -540,26 +540,35 @@ Return whether the unpacking was successful." (match-beginning 1) (match-end 1))))) (switch-to-buffer tmp-buf) (erase-buffer) + (mm-disable-multibyte) (insert-buffer-substring msg-buf beg end) - (goto-char (point-min)) - (search-forward "\n\n") - (forward-char -1) - (insert mail-header-separator) - (setq message-newsreader (setq message-mailer - (gnus-extended-version))) (cond ((string= (gnus-soup-reply-kind (car replies)) "news") (gnus-message 5 "Sending news message to %s..." (mail-fetch-field "newsgroups")) (sit-for 1) (let ((message-syntax-checks - 'dont-check-for-anything-just-trust-me)) - (funcall message-send-news-function))) + 'dont-check-for-anything-just-trust-me) + (method (if (message-functionp message-post-method) + (funcall message-post-method) + message-post-method)) + result) + (run-hooks 'message-send-news-hook) + (gnus-open-server method) + (message "Sending news via %s..." + (gnus-server-string method)) + (unless (let ((mail-header-separator "")) + (gnus-request-post method)) + (message "Couldn't send message via news: %s" + (nnheader-get-report (car method)))))) ((string= (gnus-soup-reply-kind (car replies)) "mail") (gnus-message 5 "Sending mail to %s..." (mail-fetch-field "to")) (sit-for 1) - (message-send-mail)) + (let ((mail-header-separator "")) + (mm-with-unibyte-current-buffer + (funcall (or message-send-mail-real-function + message-send-mail-function))))) (t (error "Unknown reply kind"))) (set-buffer msg-buf) diff --git a/lisp/gnus-spec.el b/lisp/gnus-spec.el index c9f0e5a..2c756d3 100644 --- a/lisp/gnus-spec.el +++ b/lisp/gnus-spec.el @@ -291,7 +291,7 @@ (wseek 0) (seek 0) (length (length string)) - (string (concat string "\0"))) + (string (concat string "\0"))) ;; Find the start position. (while (and (< seek length) (< wseek start)) @@ -455,7 +455,7 @@ characters when given a pad value." `(let (gnus-position) ,@(gnus-complex-form-to-spec form spec-alist) (if gnus-position - (gnus-put-text-property gnus-position (1+ gnus-position) + (gnus-put-text-property gnus-position (1+ gnus-position) 'gnus-position t))) `(progn ,@(gnus-complex-form-to-spec form spec-alist))))))) @@ -538,7 +538,7 @@ characters when given a pad value." t) (t nil))) - (cond + (cond ;; User-defined spec -- find the spec name. ((eq (setq spec (char-after)) ?u) (forward-char 1) @@ -567,7 +567,7 @@ characters when given a pad value." (user-defined (setq elem (list - (list (intern (format + (list (intern (format (if (stringp user-defined) "gnus-user-format-function-%s" "gnus-user-format-function-%c") diff --git a/lisp/gnus-srvr.el b/lisp/gnus-srvr.el index 736d61a..7b56e8e 100644 --- a/lisp/gnus-srvr.el +++ b/lisp/gnus-srvr.el @@ -57,7 +57,7 @@ The following specs are understood: %s status %a agent covered -General format specifiers can also be used. +General format specifiers can also be used. See (gnus)Formatting Variables." :link '(custom-manual "(gnus)Formatting Variables") :group 'gnus-server-visual @@ -72,7 +72,7 @@ See (gnus)Formatting Variables." "Whether server browsing should take place in the group buffer. If nil, a faster, but more primitive, buffer is used instead." :group 'gnus-server-visual - :type 'string) + :type 'boolean) ;;; Internal variables. @@ -262,24 +262,24 @@ The following commands are available: (if (featurep 'xemacs) (put 'gnus-server-mode 'font-lock-defaults '(gnus-server-font-lock-keywords t)) (set (make-local-variable 'font-lock-defaults) - '(gnus-server-font-lock-keywords t))) + '(gnus-server-font-lock-keywords t))) (gnus-run-hooks 'gnus-server-mode-hook)) (defun gnus-server-insert-server-line (gnus-tmp-name method) (let* ((gnus-tmp-how (car method)) (gnus-tmp-where (nth 1 method)) (elem (assoc method gnus-opened-servers)) - (gnus-tmp-status - (cond + (gnus-tmp-status + (cond ((eq (nth 1 elem) 'denied) "(denied)") ((eq (nth 1 elem) 'offline) "(offline)") (t - (condition-case nil - (if (or (gnus-server-opened method) - (eq (nth 1 elem) 'ok)) + (condition-case nil + (if (or (gnus-server-opened method) + (eq (nth 1 elem) 'ok)) "(opened)" - "(closed)") - ((error) "(error)"))))) + "(closed)") + ((error) "(error)"))))) (gnus-tmp-agent (if (and gnus-agent (member method gnus-agent-covered-methods)) @@ -380,7 +380,11 @@ The following commands are available: (concat "(gnus-server-set-info \"" server "\" '" (prin1-to-string info) ")")) (let* ((server (nth 1 info)) - (entry (assoc server gnus-server-alist))) + (entry (assoc server gnus-server-alist)) + (cached (assoc server gnus-server-method-cache))) + (if cached + (setq gnus-server-method-cache + (delq cached gnus-server-method-cache))) (if entry (setcdr entry info) (setq gnus-server-alist (nconc gnus-server-alist (list (cons server info)))))))) @@ -432,7 +436,7 @@ The following commands are available: (setq alist (cdr alist))) (if alist (setcdr alist (cons killed (cdr alist))) - (setq gnus-server-alist (list killed))))) + (setq gnus-server-alist (list killed))))) (gnus-server-update-server (car killed)) (setq gnus-server-killed-servers (cdr gnus-server-killed-servers)) (gnus-server-position-point))) diff --git a/lisp/gnus-start.el b/lisp/gnus-start.el index 295d4c9..fce7384 100644 --- a/lisp/gnus-start.el +++ b/lisp/gnus-start.el @@ -303,7 +303,7 @@ hierarchy in its entirety." :type 'boolean) (defcustom gnus-auto-subscribed-groups - "^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl" + "^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl\\|^nnmaildir" "*All new groups that match this regexp will be subscribed automatically. Note that this variable only deals with new groups. It has no effect whatsoever on old groups. @@ -446,7 +446,7 @@ Can be used to turn version control on or off." (condition-case var (load file nil t) (error - (error "Error in %s: %s" file var))))))))) + (error "Error in %s: %s" file (cadr var)))))))))) ;; For subscribing new newsgroup @@ -692,6 +692,8 @@ prompt the user for the name of an NNTP server to use." (nnheader-init-server-buffer) (setq gnus-slave slave) (gnus-read-init-file) + (if gnus-agent + (gnus-agentize)) (when gnus-simple-splash (setq gnus-simple-splash nil) @@ -1550,6 +1552,7 @@ newsgroup." ;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb' ;; and compute how many unread articles there are in each group. (defun gnus-get-unread-articles (&optional level) + (setq gnus-server-method-cache nil) (let* ((newsrc (cdr gnus-newsrc-alist)) (level (or level gnus-activate-level (1+ gnus-level-subscribed))) (foreign-level @@ -1917,7 +1920,7 @@ newsgroup." (goto-char (point-min)) (let (group max min) (while (not (eobp)) - (condition-case err + (condition-case () (progn (narrow-to-region (point) (gnus-point-at-eol)) ;; group gets set to a symbol interned in the hash table @@ -2579,7 +2582,7 @@ If FORCE is non-nil, the .newsrc file is read." (save-excursion (set-buffer gnus-dribble-buffer) (let ((slave-name - (make-temp-name (concat gnus-current-startup-file "-slave-"))) + (mm-make-temp-file (concat gnus-current-startup-file "-slave-"))) (modes (ignore-errors (file-modes (concat gnus-current-startup-file ".eld"))))) (let ((coding-system-for-write gnus-ding-file-coding-system)) @@ -2708,7 +2711,8 @@ If FORCE is non-nil, the .newsrc file is read." (name (symbol-name group)) (charset (or (gnus-group-name-charset method name) - (gnus-parameter-charset name)))) + (gnus-parameter-charset name) + gnus-default-charset))) (when (and str charset (featurep 'mule)) (setq str (mm-decode-coding-string str charset))) (set group str))) diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index 0df3f3f..898a563 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -43,6 +43,9 @@ (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t) (autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t) (autoload 'mm-uu-dissect "mm-uu") +(autoload 'gnus-article-outlook-deuglify-article "deuglify" + "Deuglify broken Outlook (Express) articles and redisplay." + t) (defcustom gnus-kill-summary-on-exit t "*If non-nil, kill the summary buffer when you exit from it. @@ -298,7 +301,7 @@ higest-scored article), `unseen' (place point on the subject line of the first unseen article), 'unseen-or-unread' (place point on the subject line of the first unseen article or, if all article have been seen, on the subject line of the first unread article), or a function to be called to -place point on some subject line.." +place point on some subject line." :group 'gnus-group-select :type '(choice (const best) (const unread) @@ -417,6 +420,11 @@ this variable specifies group names." :group 'gnus-summary-marks :type 'character) +(defcustom gnus-spam-mark ?H + "*Mark used for spam articles." + :group 'gnus-summary-marks + :type 'character) + (defcustom gnus-souped-mark ?F "*Mark used for souped articles." :group 'gnus-summary-marks @@ -533,7 +541,7 @@ this variable specifies group names." :type 'boolean) (defcustom gnus-auto-expirable-marks - (list gnus-killed-mark gnus-del-mark gnus-catchup-mark + (list gnus-spam-mark gnus-killed-mark gnus-del-mark gnus-catchup-mark gnus-low-score-mark gnus-ancient-mark gnus-read-mark gnus-souped-mark gnus-duplicate-mark) "*The list of marks converted into expiration if a group is auto-expirable." @@ -576,8 +584,8 @@ with some simple extensions. %S The subject -General format specifiers can also be used. -See (gnus)Formatting Variables." +General format specifiers can also be used. +See `(gnus)Formatting Variables'." :link '(custom-manual "(gnus)Formatting Variables") :group 'gnus-threading :type 'string) @@ -834,30 +842,30 @@ automatically when it is selected." :type 'face) (defcustom gnus-summary-highlight - '(((= mark gnus-canceled-mark) + '(((eq mark gnus-canceled-mark) . gnus-summary-cancelled-face) ((and (> score default-high) - (or (= mark gnus-dormant-mark) - (= mark gnus-ticked-mark))) + (or (eq mark gnus-dormant-mark) + (eq mark gnus-ticked-mark))) . gnus-summary-high-ticked-face) ((and (< score default-low) - (or (= mark gnus-dormant-mark) - (= mark gnus-ticked-mark))) + (or (eq mark gnus-dormant-mark) + (eq mark gnus-ticked-mark))) . gnus-summary-low-ticked-face) - ((or (= mark gnus-dormant-mark) - (= mark gnus-ticked-mark)) + ((or (eq mark gnus-dormant-mark) + (eq mark gnus-ticked-mark)) . gnus-summary-normal-ticked-face) - ((and (> score default-high) (= mark gnus-ancient-mark)) + ((and (> score default-high) (eq mark gnus-ancient-mark)) . gnus-summary-high-ancient-face) - ((and (< score default-low) (= mark gnus-ancient-mark)) + ((and (< score default-low) (eq mark gnus-ancient-mark)) . gnus-summary-low-ancient-face) - ((= mark gnus-ancient-mark) + ((eq mark gnus-ancient-mark) . gnus-summary-normal-ancient-face) - ((and (> score default-high) (= mark gnus-unread-mark)) + ((and (> score default-high) (eq mark gnus-unread-mark)) . gnus-summary-high-unread-face) - ((and (< score default-low) (= mark gnus-unread-mark)) + ((and (< score default-low) (eq mark gnus-unread-mark)) . gnus-summary-low-unread-face) - ((= mark gnus-unread-mark) + ((eq mark gnus-unread-mark) . gnus-summary-normal-unread-face) ((and (> score default-high) (memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))) @@ -995,14 +1003,6 @@ when prompting the user for which type of files to save." :group 'gnus-summary :type 'regexp) - -(defcustom gnus-summary-save-parts-default-mime "image/.*" - "*A regexp to match MIME parts when saving multiple parts of a message -with gnus-summary-save-parts (X m). This regexp will be used by default -when prompting the user for which type of files to save." - :group 'gnus-summary - :type 'regexp) - (defcustom gnus-read-all-available-headers nil "Whether Gnus should parse all headers made available to it. This is mostly relevant for slow backends where the user may @@ -1013,9 +1013,20 @@ that were fetched. Say, for nnultimate groups." (defcustom gnus-summary-muttprint-program "muttprint" "Command (and optional arguments) used to run Muttprint." + :version "21.3" :group 'gnus-summary :type 'string) +(defcustom gnus-article-loose-mime nil + "If non-nil, don't require MIME-Version header. +Some brain-damaged MUA/MTA, e.g. Lotus Domino 5.0.6 clients, does not +supply the MIME-Version header or deliberately strip it From the mail. +Set it to non-nil, Gnus will treat some articles as MIME even if +the MIME-Version header is missed." + :version "21.3" + :type 'boolean + :group 'gnus-article) + ;;; Internal variables (defvar gnus-summary-display-cache nil) @@ -1039,9 +1050,6 @@ that were fetched. Say, for nnultimate groups." (defvar gnus-summary-save-parts-type-history nil) (defvar gnus-summary-save-parts-last-directory nil) -(defvar gnus-summary-save-parts-type-history nil) -(defvar gnus-summary-save-parts-last-directory nil) - ;; Avoid highlighting in kill files. (defvar gnus-summary-inhibit-highlight nil) (defvar gnus-newsgroup-selected-overlay nil) @@ -1150,10 +1158,10 @@ the type of the variable (string, integer, character, etc).") (defvar gnus-newsgroup-limits nil) (defvar gnus-newsgroup-unreads nil - "List of unread articles in the current newsgroup.") + "Sorted list of unread articles in the current newsgroup.") (defvar gnus-newsgroup-unselected nil - "List of unselected unread articles in the current newsgroup.") + "Sorted list of unselected unread articles in the current newsgroup.") (defvar gnus-newsgroup-reads nil "Alist of read articles and article marks in the current newsgroup.") @@ -1161,13 +1169,13 @@ the type of the variable (string, integer, character, etc).") (defvar gnus-newsgroup-expunged-tally nil) (defvar gnus-newsgroup-marked nil - "List of ticked articles in the current newsgroup (a subset of unread art).") + "Sorted list of ticked articles in the current newsgroup (a subset of unread art).") (defvar gnus-newsgroup-killed nil "List of ranges of articles that have been through the scoring process.") (defvar gnus-newsgroup-cached nil - "List of articles that come from the article cache.") + "Sorted list of articles that come from the article cache.") (defvar gnus-newsgroup-saved nil "List of articles that have been saved.") @@ -1184,13 +1192,13 @@ the type of the variable (string, integer, character, etc).") "List of articles that have are recent in the current newsgroup.") (defvar gnus-newsgroup-expirable nil - "List of articles in the current newsgroup that can be expired.") + "Sorted list of articles in the current newsgroup that can be expired.") (defvar gnus-newsgroup-processable nil "List of articles in the current newsgroup that can be processed.") (defvar gnus-newsgroup-downloadable nil - "List of articles in the current newsgroup that can be processed.") + "Sorted list of articles in the current newsgroup that can be processed.") (defvar gnus-newsgroup-undownloaded nil "List of articles in the current newsgroup that haven't been downloaded..") @@ -1202,7 +1210,7 @@ the type of the variable (string, integer, character, etc).") "List of articles in the current newsgroup that have bookmarks.") (defvar gnus-newsgroup-dormant nil - "List of dormant articles in the current newsgroup.") + "Sorted list of dormant articles in the current newsgroup.") (defvar gnus-newsgroup-unseen nil "List of unseen articles in the current newsgroup.") @@ -1729,6 +1737,7 @@ increase the score of each group you read." "6" gnus-article-de-base64-unreadable "Z" gnus-article-decode-HZ "h" gnus-article-wash-html + "u" gnus-article-unsplit-urls "s" gnus-summary-force-verify-and-decrypt "f" gnus-article-display-x-face "l" gnus-summary-stop-page-breaking @@ -1738,7 +1747,8 @@ increase the score of each group you read." "v" gnus-summary-verbose-headers "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive "p" gnus-article-verify-x-pgp-sig - "d" gnus-article-treat-dumbquotes) + "d" gnus-article-treat-dumbquotes + "k" gnus-article-outlook-deuglify-article) (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map) "a" gnus-article-hide @@ -1842,10 +1852,57 @@ increase the score of each group you read." "o" gnus-article-save-part "c" gnus-article-copy-part "C" gnus-article-view-part-as-charset - "e" gnus-article-externalize-part + "e" gnus-article-view-part-externally "E" gnus-article-encrypt-body "i" gnus-article-inline-part - "|" gnus-article-pipe-part)) + "|" gnus-article-pipe-part) + + (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map) + "p" gnus-summary-mark-as-processable + "u" gnus-summary-unmark-as-processable + "U" gnus-summary-unmark-all-processable + "v" gnus-uu-mark-over + "s" gnus-uu-mark-series + "r" gnus-uu-mark-region + "g" gnus-uu-unmark-region + "R" gnus-uu-mark-by-regexp + "G" gnus-uu-unmark-by-regexp + "t" gnus-uu-mark-thread + "T" gnus-uu-unmark-thread + "a" gnus-uu-mark-all + "b" gnus-uu-mark-buffer + "S" gnus-uu-mark-sparse + "k" gnus-summary-kill-process-mark + "y" gnus-summary-yank-process-mark + "w" gnus-summary-save-process-mark + "i" gnus-uu-invert-processable) + + (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map) + ;;"x" gnus-uu-extract-any + "m" gnus-summary-save-parts + "u" gnus-uu-decode-uu + "U" gnus-uu-decode-uu-and-save + "s" gnus-uu-decode-unshar + "S" gnus-uu-decode-unshar-and-save + "o" gnus-uu-decode-save + "O" gnus-uu-decode-save + "b" gnus-uu-decode-binhex + "B" gnus-uu-decode-binhex + "p" gnus-uu-decode-postscript + "P" gnus-uu-decode-postscript-and-save) + + (gnus-define-keys + (gnus-uu-extract-view-map "v" gnus-uu-extract-map) + "u" gnus-uu-decode-uu-view + "U" gnus-uu-decode-uu-and-save-view + "s" gnus-uu-decode-unshar-view + "S" gnus-uu-decode-unshar-and-save-view + "o" gnus-uu-decode-save-view + "O" gnus-uu-decode-save-view + "b" gnus-uu-decode-binhex-view + "B" gnus-uu-decode-binhex-view + "p" gnus-uu-decode-postscript-view + "P" gnus-uu-decode-postscript-and-save-view)) (defvar gnus-article-post-menu nil) @@ -1906,7 +1963,8 @@ increase the score of each group you read." ["Base64" gnus-article-de-base64-unreadable t] ["View all" gnus-mime-view-all-parts t] ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t] - ["Encrypt body" gnus-article-encrypt-body t]) + ["Encrypt body" gnus-article-encrypt-body t] + ["Extract all parts" gnus-summary-save-parts t]) ("Date" ["Local" gnus-article-date-local t] ["ISO8601" gnus-article-date-iso8601 t] @@ -1920,7 +1978,28 @@ increase the score of each group you read." ["Show X-Face" gnus-article-display-x-face t] ["Show picons in From" gnus-treat-from-picon t] ["Show picons in mail headers" gnus-treat-mail-picon t] - ["Show picons in news headers" gnus-treat-newsgroups-picon t]) + ["Show picons in news headers" gnus-treat-newsgroups-picon t] + ("View as different encoding" + ,@(mapcar + (lambda (cs) + ;; Since easymenu under FSF Emacs doesn't allow lambda + ;; forms for menu commands, we should provide intern'ed + ;; function symbols. + (let ((command (intern (format "\ +gnus-summary-show-article-from-menu-as-charset-%s" cs)))) + (fset command + `(lambda () + (interactive) + (let ((gnus-summary-show-article-charset-alist + '((1 . ,cs)))) + (gnus-summary-show-article 1)))) + `[,(symbol-name cs) ,command t])) + (sort (if (fboundp 'coding-system-list) + (coding-system-list) + (mapcar 'car mm-mime-mule-charset-alist)) + (lambda (a b) + (string< (symbol-name a) + (symbol-name b))))))) ("Washing" ("Remove Blanks" ["Leading" gnus-article-strip-leading-blank-lines t] @@ -1953,8 +2032,11 @@ increase the score of each group you read." ["Unfold headers" gnus-article-treat-unfold-headers t] ["Fold newsgroups" gnus-article-treat-fold-newsgroups t] ["Html" gnus-article-wash-html t] + ["URLs" gnus-article-unsplit-urls t] ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t] - ["HZ" gnus-article-decode-HZ t]) + ["HZ" gnus-article-decode-HZ t] + ["OutlooK deuglify" gnus-article-outlook-deuglify-article t] + ) ("Output" ["Save in default format" gnus-summary-save-article ,@(if (featurep 'xemacs) '(t) @@ -2002,7 +2084,8 @@ increase the score of each group you read." ["Unshar and save" gnus-uu-decode-unshar-and-save t] ["Save" gnus-uu-decode-save t] ["Binhex" gnus-uu-decode-binhex t] - ["Postscript" gnus-uu-decode-postscript t]) + ["Postscript" gnus-uu-decode-postscript t] + ["All MIME parts" gnus-summary-save-parts t]) ("Cache" ["Enter article" gnus-cache-enter-article t] ["Remove article" gnus-cache-remove-article t]) @@ -2073,15 +2156,16 @@ increase the score of each group you read." ["Wide reply and yank" gnus-summary-wide-reply-with-original ,@(if (featurep 'xemacs) '(t) '(:help "Mail a reply, quoting this article"))] - ["Very wide reply" gnus-summary-very-wide-reply t] - ["Very wide reply and yank" gnus-summary-very-wide-reply-with-original - ,@(if (featurep 'xemacs) '(t) - '(:help "Mail a very wide reply, quoting this article"))] + ["Very wide reply" gnus-summary-very-wide-reply t] + ["Very wide reply and yank" gnus-summary-very-wide-reply-with-original + ,@(if (featurep 'xemacs) '(t) + '(:help "Mail a very wide reply, quoting this article"))] ["Mail forward" gnus-summary-mail-forward t] ["Post forward" gnus-summary-post-forward t] ["Digest and mail" gnus-uu-digest-mail-forward t] ["Digest and post" gnus-uu-digest-post-forward t] ["Resend message" gnus-summary-resend-message t] + ["Resend message edit" gnus-summary-resend-message-edit t] ["Send bounced mail" gnus-summary-resend-bounced-mail t] ["Send a mail" gnus-summary-mail-other-window t] ["Create a local message" gnus-summary-news-other-window t] @@ -2949,17 +3033,19 @@ buffer that was in action when the last article was fetched." 0 nil 128 t nil "" nil 1) (goto-char (point-min)) (setq pos (list (cons 'unread (and (search-forward "\200" nil t) - (- (point) 2))))) + (- (point) (point-min) 1))))) (goto-char (point-min)) (push (cons 'replied (and (search-forward "\201" nil t) - (- (point) 2))) + (- (point) (point-min) 1))) pos) (goto-char (point-min)) - (push (cons 'score (and (search-forward "\202" nil t) (- (point) 2))) + (push (cons 'score (and (search-forward "\202" nil t) + (- (point) (point-min) 1))) pos) (goto-char (point-min)) (push (cons 'download - (and (search-forward "\203" nil t) (- (point) 2))) + (and (search-forward "\203" nil t) + (- (point) (point-min) 1))) pos))) (setq gnus-summary-mark-positions pos)))) @@ -3517,8 +3603,8 @@ If NO-DISPLAY, don't generate a summary buffer." (setq threads nil) (throw 'infloop t)) (unless (car (symbol-value refs)) - ;; These threads do not refer back to any other articles, - ;; so they're roots. + ;; These threads do not refer back to any other + ;; articles, so they're roots. (setq threads (append (cdr (symbol-value refs)) threads)))) gnus-newsgroup-dependencies))) threads)) @@ -3532,13 +3618,13 @@ if it was already present. If `gnus-summary-ignore-duplicates' is nil then duplicate Message-IDs will not be entered in the DEPENDENCIES table. Otherwise duplicate -Message-IDs will be renamed be renamed to a unique Message-ID before -being entered. +Message-IDs will be renamed to a unique Message-ID before being +entered. Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (let* ((id (mail-header-id header)) (id-dep (and id (intern id dependencies))) - ref ref-dep ref-header) + ref ref-dep ref-header replaced) ;; Enter this `header' in the `dependencies' table. (cond ((not id-dep) @@ -3555,7 +3641,8 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (force-new ;; Overrides an existing entry; ;; just set the header part of the entry. - (setcar (symbol-value id-dep) header)) + (setcar (symbol-value id-dep) header) + (setq replaced t)) ;; Renames the existing `header' to a unique Message-ID. ((not gnus-summary-ignore-duplicates) @@ -3578,8 +3665,8 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (or (mail-header-xref header) ""))) (setq header nil))) - (when header - ;; First check if that we are not creating a References loop. + (when (and header (not replaced)) + ;; First check that we are not creating a References loop. (setq ref (gnus-parent-id (mail-header-references header))) (while (and ref (setq ref-dep (intern-soft ref dependencies)) @@ -3601,6 +3688,11 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (set ref-dep (list nil (symbol-value id-dep))))) header)) +(defun gnus-extract-message-id-from-in-reply-to (string) + (if (string-match "<[^>]+>" string) + (substring string (match-beginning 0) (match-end 0)) + nil)) + (defun gnus-build-sparse-threads () (let ((headers gnus-newsgroup-headers) (mail-parse-charset gnus-newsgroup-charset) @@ -3677,7 +3769,7 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (defsubst gnus-nov-parse-line (number dependencies &optional force-new) (let ((eol (gnus-point-at-eol)) (buffer (current-buffer)) - header) + header references in-reply-to) ;; overview: [num subject from date id refs chars lines misc] (unwind-protect @@ -3695,7 +3787,7 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (nnheader-nov-field)) ; from (nnheader-nov-field) ; date (nnheader-nov-read-message-id) ; id - (nnheader-nov-field) ; refs + (setq references (nnheader-nov-field)) ; refs (nnheader-nov-read-integer) ; chars (nnheader-nov-read-integer) ; lines (unless (eobp) @@ -3706,6 +3798,12 @@ Returns HEADER if it was entered in the DEPENDENCIES. Returns nil otherwise." (widen)) + (when (and (string= references "") + (setq in-reply-to (mail-header-extra header)) + (setq in-reply-to (cdr (assq 'In-Reply-To in-reply-to)))) + (mail-header-set-references + header (gnus-extract-message-id-from-in-reply-to in-reply-to))) + (when gnus-alter-header-function (funcall gnus-alter-header-function header)) (gnus-dependencies-add-header header dependencies force-new))) @@ -3740,7 +3838,9 @@ the id of the parent article (if any)." (push header gnus-newsgroup-headers) (if (memq number gnus-newsgroup-unselected) (progn - (push number gnus-newsgroup-unreads) + (setq gnus-newsgroup-unreads + (gnus-add-to-sorted-list gnus-newsgroup-unreads + number)) (setq gnus-newsgroup-unselected (delq number gnus-newsgroup-unselected))) (push number gnus-newsgroup-ancient))))))) @@ -3766,7 +3866,9 @@ the id of the parent article (if any)." (if (memq (setq article (mail-header-number header)) gnus-newsgroup-unselected) (progn - (push article gnus-newsgroup-unreads) + (setq gnus-newsgroup-unreads + (gnus-add-to-sorted-list + gnus-newsgroup-unreads article)) (setq gnus-newsgroup-unselected (delq article gnus-newsgroup-unselected))) (push article gnus-newsgroup-ancient))) @@ -4239,20 +4341,32 @@ Unscored articles will be counted as having a score of zero." (defvar gnus-tmp-thread-tree-header-string "") -(defvar gnus-sum-thread-tree-root "> " +(defcustom gnus-sum-thread-tree-root "> " "With %B spec, used for the root of a thread. -If nil, use subject instead.") -(defvar gnus-sum-thread-tree-single-indent "" +If nil, use subject instead." + :type 'string + :group 'gnus-thread) +(defcustom gnus-sum-thread-tree-single-indent "" "With %B spec, used for a thread with just one message. -If nil, use subject instead.") -(defvar gnus-sum-thread-tree-vertical "| " - "With %B spec, used for drawing a vertical line.") -(defvar gnus-sum-thread-tree-indent " " - "With %B spec, used for indenting.") -(defvar gnus-sum-thread-tree-leaf-with-other "+-> " - "With %B spec, used for a leaf with brothers.") -(defvar gnus-sum-thread-tree-single-leaf "\\-> " - "With %B spec, used for a leaf without brothers.") +If nil, use subject instead." + :type 'string + :group 'gnus-thread) +(defcustom gnus-sum-thread-tree-vertical "| " + "With %B spec, used for drawing a vertical line." + :type 'string + :group 'gnus-thread) +(defcustom gnus-sum-thread-tree-indent " " + "With %B spec, used for indenting." + :type 'string + :group 'gnus-thread) +(defcustom gnus-sum-thread-tree-leaf-with-other "+-> " + "With %B spec, used for a leaf with brothers." + :type 'string + :group 'gnus-thread) +(defcustom gnus-sum-thread-tree-single-leaf "\\-> " + "With %B spec, used for a leaf without brothers." + :type 'string + :group 'gnus-thread) (defun gnus-summary-prepare-threads (threads) "Prepare summary buffer from THREADS and indentation LEVEL. @@ -4396,7 +4510,9 @@ or a straight list of headers." (setq gnus-newsgroup-unreads (delq number gnus-newsgroup-unreads)) (if gnus-newsgroup-auto-expire - (push number gnus-newsgroup-expirable) + (setq gnus-newsgroup-expirable + (gnus-add-to-sorted-list + gnus-newsgroup-expirable number)) (push (cons number gnus-low-score-mark) gnus-newsgroup-reads)))) @@ -4688,8 +4804,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." (setq cached gnus-newsgroup-cached)) (setq gnus-newsgroup-unreads - (gnus-set-difference - (gnus-set-difference gnus-newsgroup-unreads gnus-newsgroup-marked) + (gnus-sorted-ndifference + (gnus-sorted-ndifference gnus-newsgroup-unreads + gnus-newsgroup-marked) gnus-newsgroup-dormant)) (setq gnus-newsgroup-processable nil) @@ -4702,9 +4819,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." (if (setq articles select-articles) (setq gnus-newsgroup-unselected - (gnus-sorted-intersection - gnus-newsgroup-unreads - (gnus-sorted-complement gnus-newsgroup-unreads articles))) + (gnus-sorted-difference gnus-newsgroup-unreads articles)) (setq articles (gnus-articles-to-read group read-all))) (cond @@ -4736,20 +4851,13 @@ If SELECT-ARTICLES, only select those articles from GROUP." gnus-newsgroup-headers)) (setq gnus-newsgroup-articles fetched-articles) (setq gnus-newsgroup-unreads - (gnus-set-sorted-intersection + (gnus-sorted-nintersection gnus-newsgroup-unreads fetched-articles)) - - ;; The `seen' marks are treated specially. - (if (not gnus-newsgroup-seen) - (setq gnus-newsgroup-unseen gnus-newsgroup-articles) - (dolist (article gnus-newsgroup-articles) - (unless (gnus-member-of-range article gnus-newsgroup-seen) - (push article gnus-newsgroup-unseen))) - (setq gnus-newsgroup-unseen (nreverse gnus-newsgroup-unseen))) + (gnus-compute-unseen-list) ;; Removed marked articles that do not exist. (gnus-update-missing-marks - (gnus-sorted-complement fetched-articles articles)) + (gnus-sorted-difference articles fetched-articles)) ;; We might want to build some more threads first. (when (and gnus-fetch-old-headers (eq gnus-headers-retrieved-by 'nov)) @@ -4778,19 +4886,29 @@ If SELECT-ARTICLES, only select those articles from GROUP." ;; GROUP is successfully selected. (or gnus-newsgroup-headers t))))) +(defun gnus-compute-unseen-list () + ;; The `seen' marks are treated specially. + (if (not gnus-newsgroup-seen) + (setq gnus-newsgroup-unseen gnus-newsgroup-articles) + (setq gnus-newsgroup-unseen + (gnus-inverse-list-range-intersection + gnus-newsgroup-articles gnus-newsgroup-seen)))) + (defun gnus-summary-display-make-predicate (display) (require 'gnus-agent) (when (= (length display) 1) (setq display (car display))) (unless gnus-summary-display-cache - (dolist (elem (append (list (cons 'read 'read) - (cons 'unseen 'unseen)) + (dolist (elem (append '((unread . unread) + (read . read) + (unseen . unseen)) gnus-article-mark-lists)) (push (cons (cdr elem) (gnus-byte-compile `(lambda () (gnus-article-marked-p ',(cdr elem))))) gnus-summary-display-cache))) - (let ((gnus-category-predicate-alist gnus-summary-display-cache)) + (let ((gnus-category-predicate-alist gnus-summary-display-cache) + (gnus-category-predicate-cache gnus-summary-display-cache)) (gnus-get-predicate display))) ;; Uses the dynamically bound `number' variable. @@ -4842,7 +4960,8 @@ If SELECT-ARTICLES, only select those articles from GROUP." (if (or read-all (and (zerop (length gnus-newsgroup-marked)) (zerop (length gnus-newsgroup-unreads))) - (eq gnus-newsgroup-display 'gnus-not-ignore)) + ;; Fetch all if the predicate is non-nil. + gnus-newsgroup-display) ;; We want to select the headers for all the articles in ;; the group, so we select either all the active ;; articles in the group, or (if that's nil), the @@ -4851,9 +4970,9 @@ If SELECT-ARTICLES, only select those articles from GROUP." (gnus-uncompress-range (gnus-active group)) (gnus-cache-articles-in-group group)) ;; Select only the "normal" subset of articles. - (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked - (copy-sequence gnus-newsgroup-unreads)) - '<))) + (gnus-sorted-nunion + (gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked) + gnus-newsgroup-unreads))) (scored-list (gnus-killed-articles gnus-newsgroup-killed articles)) (scored (length scored-list)) (number (length articles)) @@ -4863,20 +4982,29 @@ If SELECT-ARTICLES, only select those articles from GROUP." (cond ((numberp read-all) read-all) + ((numberp gnus-newsgroup-display) + gnus-newsgroup-display) (t (condition-case () (cond ((and (or (<= scored marked) (= scored number)) (numberp gnus-large-newsgroup) (> number gnus-large-newsgroup)) - (let ((input - (read-string - (format - "How many articles from %s (default %d): " - (gnus-limit-string - (gnus-group-decoded-name gnus-newsgroup-name) - 35) - number)))) + (let* ((cursor-in-echo-area nil) + (initial (gnus-parameter-large-newsgroup-initial + gnus-newsgroup-name)) + (input + (read-string + (format + "How many articles from %s (%s %d): " + (gnus-limit-string + (gnus-group-decoded-name gnus-newsgroup-name) + 35) + (if initial "max" "default") + number) + (if initial + (cons (number-to-string initial) + 0))))) (if (string-match "^[ \t]*$" input) number input))) ((and (> scored marked) (< scored number) (> (- scored number) 20)) @@ -4908,9 +5036,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." ;; Select the N most recent articles. (setq articles (nthcdr (- number select) articles)))) (setq gnus-newsgroup-unselected - (gnus-sorted-intersection - gnus-newsgroup-unreads - (gnus-sorted-complement gnus-newsgroup-unreads articles))) + (gnus-sorted-difference gnus-newsgroup-unreads articles)) (when gnus-alter-articles-to-read-function (setq gnus-newsgroup-unreads (sort @@ -5476,29 +5602,24 @@ Return a list of headers that match SEQUENCE (see ;; Allow the user to mangle the headers before parsing them. (gnus-run-hooks 'gnus-parse-headers-hook) (goto-char (point-min)) - (while (not (eobp)) - (condition-case () - (while (and (or sequence allp) - (not (eobp))) - (setq number (read cur)) - (when (not allp) - (while (and sequence - (< (car sequence) number)) - (setq sequence (cdr sequence)))) - (when (and (or allp - (and sequence - (eq number (car sequence)))) - (progn - (setq sequence (cdr sequence)) - (setq header (inline - (gnus-nov-parse-line - number dependencies force-new))))) - (push header headers)) - (forward-line 1)) - (error - (gnus-error 4 "Strange nov line (%d)" - (count-lines (point-min) (point))))) - (forward-line 1)) + (gnus-parse-without-error + (while (and (or sequence allp) + (not (eobp))) + (setq number (read cur)) + (when (not allp) + (while (and sequence + (< (car sequence) number)) + (setq sequence (cdr sequence)))) + (when (and (or allp + (and sequence + (eq number (car sequence)))) + (progn + (setq sequence (cdr sequence)) + (setq header (inline + (gnus-nov-parse-line + number dependencies force-new))))) + (push header headers)) + (forward-line 1))) ;; A common bug in inn is that if you have posted an article and ;; then retrieves the active file, it will answer correctly -- ;; the new article is included. However, a NOV entry for the @@ -5897,13 +6018,13 @@ displayed, no centering will be performed." (marked (gnus-info-marks info)) (active (gnus-active group))) (and info active - (gnus-set-difference - (gnus-sorted-complement - (gnus-uncompress-range active) - (gnus-list-of-unread-articles group)) - (append - (gnus-uncompress-range (cdr (assq 'dormant marked))) - (gnus-uncompress-range (cdr (assq 'tick marked)))))))) + (gnus-list-range-difference + (gnus-list-range-difference + (gnus-sorted-complement + (gnus-uncompress-range active) + (gnus-list-of-unread-articles group)) + (cdr (assq 'dormant marked))) + (cdr (assq 'tick marked)))))) ;; Various summary commands @@ -5977,13 +6098,10 @@ The prefix argument ALL means to select all articles." (when gnus-newsgroup-kill-headers (setq gnus-newsgroup-killed (gnus-compress-sequence - (nconc - (gnus-set-sorted-intersection - (gnus-uncompress-range gnus-newsgroup-killed) - (setq gnus-newsgroup-unselected - (sort gnus-newsgroup-unselected '<))) - (setq gnus-newsgroup-unreads - (sort gnus-newsgroup-unreads '<))) + (gnus-sorted-union + (gnus-list-range-intersection + gnus-newsgroup-unselected gnus-newsgroup-killed) + gnus-newsgroup-unreads) t))) (unless (listp (cdr gnus-newsgroup-killed)) (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) @@ -5993,7 +6111,8 @@ The prefix argument ALL means to select all articles." (set-buffer gnus-group-buffer) (gnus-undo-force-boundary)) (gnus-update-read-articles - group (append gnus-newsgroup-unreads gnus-newsgroup-unselected)) + group (gnus-sorted-union + gnus-newsgroup-unreads gnus-newsgroup-unselected)) ;; Set the current article marks. (let ((gnus-newsgroup-scored (if (and (not gnus-save-score) @@ -6555,20 +6674,18 @@ be displayed." (with-current-buffer gnus-article-buffer (if (not gnus-article-decoded-p) ;; a local variable (mm-disable-multibyte)))) -;;; Hidden headers are not hidden text any more. -;; (when (or all-headers gnus-show-all-headers) -;; (gnus-article-show-all-headers)) (gnus-article-set-window-start (cdr (assq article gnus-newsgroup-bookmarks))) article) -;; (when (or all-headers gnus-show-all-headers) -;; (gnus-article-show-all-headers)) 'old)))) (defun gnus-summary-force-verify-and-decrypt () (interactive) (let ((mm-verify-option 'known) - (mm-decrypt-option 'known)) + (mm-decrypt-option 'known) + (gnus-buttonized-mime-types (append (list "multipart/signed" + "multipart/encrypted") + gnus-buttonized-mime-types))) (gnus-summary-select-article nil 'force))) (defun gnus-summary-set-current-mark (&optional current-mark) @@ -7052,10 +7169,10 @@ articles that are younger than AGE days." (when (> (length days) 0) (setq days (read days))) (if (numberp days) - (progn + (progn (setq days-got t) (if (< days 0) - (progn + (progn (setq younger (not younger)) (setq days (* days -1))))) (message "Please enter a number.") @@ -7136,7 +7253,7 @@ If ALL is non-nil, limit strictly to unread articles." ;; Concat all the marks that say that an article is read and have ;; those removed. (list gnus-del-mark gnus-read-mark gnus-ancient-mark - gnus-killed-mark gnus-kill-file-mark + gnus-killed-mark gnus-spam-mark gnus-kill-file-mark gnus-low-score-mark gnus-expirable-mark gnus-canceled-mark gnus-catchup-mark gnus-sparse-mark gnus-duplicate-mark gnus-souped-mark) @@ -7144,7 +7261,7 @@ If ALL is non-nil, limit strictly to unread articles." (defalias 'gnus-summary-delete-marked-with 'gnus-summary-limit-exclude-marks) (make-obsolete 'gnus-summary-delete-marked-with - 'gnus-summary-limit-exlude-marks) + 'gnus-summary-limit-exclude-marks) (defun gnus-summary-limit-exclude-marks (marks &optional reverse) "Exclude articles that are marked with MARKS (e.g. \"DK\"). @@ -7258,15 +7375,17 @@ fetched for this group." "Mark all unread excluded articles as read. If ALL, mark even excluded ticked and dormants as read." (interactive "P") - (let ((articles (gnus-sorted-complement + (setq gnus-newsgroup-limit (sort gnus-newsgroup-limit '<)) + (let ((articles (gnus-sorted-ndifference (sort (mapcar (lambda (h) (mail-header-number h)) gnus-newsgroup-headers) '<) - (sort gnus-newsgroup-limit '<))) + gnus-newsgroup-limit)) article) (setq gnus-newsgroup-unreads - (gnus-intersection gnus-newsgroup-unreads gnus-newsgroup-limit)) + (gnus-sorted-intersection gnus-newsgroup-unreads + gnus-newsgroup-limit)) (if all (setq gnus-newsgroup-dormant nil gnus-newsgroup-marked nil @@ -8019,6 +8138,7 @@ to save in." (copy-to-buffer buffer (point-min) (point-max)) (set-buffer buffer) (gnus-article-delete-invisible-text) + (gnus-remove-text-with-property 'gnus-decoration) (when (gnus-visual-p 'article-highlight 'highlight) ;; Copy-to-buffer doesn't copy overlay. So redo ;; highlight. @@ -8053,7 +8173,7 @@ If ARG (the prefix) is a number, show the article with the charset defined in `gnus-summary-show-article-charset-alist', or the charset input. If ARG (the prefix) is non-nil and not a number, show the raw article -without any article massaging functions being run. Normally, the key strokes +without any article massaging functions being run. Normally, the key strokes are `C-u g'." (interactive "P") (cond @@ -8149,22 +8269,20 @@ If ARG is a negative number, hide the unwanted header lines." (save-restriction (let* ((buffer-read-only nil) (inhibit-point-motion-hooks t) - hidden e) - (setq hidden - (if (numberp arg) - (>= arg 0) - (save-restriction - (article-narrow-to-head) - (gnus-article-hidden-text-p 'headers)))) - (goto-char (point-min)) - (when (search-forward "\n\n" nil t) - (delete-region (point-min) (1- (point)))) + hidden s e) + (save-restriction + (article-narrow-to-head) + (setq e (point-max) + hidden (if (numberp arg) + (>= arg 0) + (gnus-article-hidden-text-p 'headers)))) + (delete-region (point-min) e) (goto-char (point-min)) - (save-excursion - (set-buffer gnus-original-article-buffer) - (goto-char (point-min)) - (setq e (1- (or (search-forward "\n\n" nil t) (point-max))))) - (insert-buffer-substring gnus-original-article-buffer 1 e) + (with-current-buffer gnus-original-article-buffer + (goto-char (setq s (point-min))) + (setq e (search-forward "\n\n" nil t) + e (if e (1- e) (point-max)))) + (insert-buffer-substring gnus-original-article-buffer s e) (save-restriction (narrow-to-region (point-min) (point)) (article-decode-encoded-words) @@ -8219,6 +8337,10 @@ If TO-NEWSGROUP is string, do not prompt for a newsgroup to move to. If SELECT-METHOD is non-nil, do not move to a specific newsgroup, but re-spool using this method. +When called interactively with TO-NEWSGROUP being nil, the value of +the variable `gnus-move-split-methods' is used for finding a default +for the target newsgroup. + For this function to work, both the current newsgroup and the newsgroup that you want to move to have to support the `request-move' and `request-accept' functions. @@ -8249,16 +8371,21 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." art-group to-method new-xref article to-groups) (unless (assq action names) (error "Unknown action %s" action)) - ;; We have to select an article to give - ;; `gnus-read-move-group-name' an opportunity to suggest an - ;; appropriate default. - (unless (gnus-buffer-live-p gnus-original-article-buffer) - (let ((gnus-display-mime-function nil) - (gnus-article-prepare-hook nil)) - (gnus-summary-select-article nil nil nil (car articles)))) ;; Read the newsgroup name. (when (and (not to-newsgroup) (not select-method)) + (if (and gnus-move-split-methods + (not + (and (memq gnus-current-article articles) + (gnus-buffer-live-p gnus-original-article-buffer)))) + ;; When `gnus-move-split-methods' is non-nil, we have to + ;; select an article to give `gnus-read-move-group-name' an + ;; opportunity to suggest an appropriate default. However, + ;; we needn't render or mark the article. + (let ((gnus-display-mime-function nil) + (gnus-article-prepare-hook nil) + (gnus-mark-article-hook nil)) + (gnus-summary-select-article nil nil nil (car articles)))) (setq to-newsgroup (gnus-read-move-group-name (cadr (assq action names)) @@ -8442,6 +8569,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." (defun gnus-summary-copy-article (&optional n to-newsgroup select-method) "Move the current article to a different newsgroup. If TO-NEWSGROUP is string, do not prompt for a newsgroup to move to. +When called interactively, if TO-NEWSGROUP is nil, use the value of +the variable `gnus-move-split-methods' for finding a default target +newsgroup. If SELECT-METHOD is non-nil, do not move to a specific newsgroup, but re-spool using this method." (interactive "P") @@ -8626,12 +8756,10 @@ This will be the case if the article has both been mailed and posted." ;; really expired articles as nonexistent. (unless (eq es expirable) ;If nothing was expired, we don't mark. (let ((gnus-use-cache nil)) - (while expirable - (unless (memq (car expirable) es) - (when (gnus-data-find (car expirable)) - (gnus-summary-mark-article - (car expirable) gnus-canceled-mark))) - (setq expirable (cdr expirable)))))) + (dolist (article expirable) + (when (and (not (memq article es)) + (gnus-data-find article)) + (gnus-summary-mark-article article gnus-canceled-mark)))))) (gnus-message 6 "Expiring articles...done"))))) (defun gnus-summary-expire-articles-now () @@ -8811,10 +8939,7 @@ groups." (insert ".\n") (let ((nntp-server-buffer (current-buffer))) (setq header (car (gnus-get-newsgroup-headers - (save-excursion - (set-buffer gnus-summary-buffer) - gnus-newsgroup-dependencies) - t)))) + nil t)))) (save-excursion (set-buffer gnus-summary-buffer) (gnus-data-set-header @@ -9013,6 +9138,13 @@ the actual number of articles marked is returned." (interactive "p") (gnus-summary-mark-forward n gnus-expirable-mark)) +(defun gnus-summary-mark-as-spam (n) + "Mark N articles forward as spam. +If N is negative, mark backward instead. The difference between N and +the actual number of articles marked is returned." + (interactive "p") + (gnus-summary-mark-forward n gnus-spam-mark)) + (defun gnus-summary-mark-article-as-replied (article) "Mark ARTICLE as replied to and update the summary line. ARTICLE can also be a list of articles." @@ -9178,11 +9310,17 @@ Iff NO-EXPIRE, auto-expiry will be inhibited." (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)) (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads)) (cond ((= mark gnus-ticked-mark) - (push article gnus-newsgroup-marked)) + (setq gnus-newsgroup-marked + (gnus-add-to-sorted-list gnus-newsgroup-marked + article))) ((= mark gnus-dormant-mark) - (push article gnus-newsgroup-dormant)) + (setq gnus-newsgroup-dormant + (gnus-add-to-sorted-list gnus-newsgroup-dormant + article))) (t - (push article gnus-newsgroup-unreads))) + (setq gnus-newsgroup-unreads + (gnus-add-to-sorted-list gnus-newsgroup-unreads + article)))) (gnus-pull article gnus-newsgroup-reads) ;; See whether the article is to be put in the cache. @@ -9292,9 +9430,10 @@ Iff NO-EXPIRE, auto-expiry will be inhibited." "Enter ARTICLE in the pertinent lists and remove it from others." ;; Make the article expirable. (let ((mark (or mark gnus-del-mark))) - (if (= mark gnus-expirable-mark) - (push article gnus-newsgroup-expirable) - (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))) + (setq gnus-newsgroup-expirable + (if (= mark gnus-expirable-mark) + (gnus-add-to-sorted-list gnus-newsgroup-expirable article) + (delq article gnus-newsgroup-expirable))) ;; Remove from unread and marked lists. (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads)) (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked)) @@ -9322,11 +9461,14 @@ Iff NO-EXPIRE, auto-expiry will be inhibited." (gnus-dup-unsuppress-article article)) (cond ((= mark gnus-ticked-mark) - (push article gnus-newsgroup-marked)) + (setq gnus-newsgroup-marked + (gnus-add-to-sorted-list gnus-newsgroup-marked article))) ((= mark gnus-dormant-mark) - (push article gnus-newsgroup-dormant)) + (setq gnus-newsgroup-dormant + (gnus-add-to-sorted-list gnus-newsgroup-dormant article))) (t - (push article gnus-newsgroup-unreads))) + (setq gnus-newsgroup-unreads + (gnus-add-to-sorted-list gnus-newsgroup-unreads article)))) (gnus-pull article gnus-newsgroup-reads) t))) @@ -10286,7 +10428,8 @@ If REVERSE, save parts that do not match TYPE." (save-excursion (set-buffer gnus-article-buffer) (let ((handles (or gnus-article-mime-handles - (mm-dissect-buffer) (mm-uu-dissect)))) + (mm-dissect-buffer nil gnus-article-loose-mime) + (mm-uu-dissect)))) (when handles (gnus-summary-save-parts-1 type dir handles reverse) (unless gnus-article-mime-handles ;; Don't destroy this case. @@ -10373,7 +10516,9 @@ If REVERSE, save parts that do not match TYPE." (gnus-data-enter after-article gnus-reffed-article-number gnus-unread-mark b (car pslist) 0 (- e b)) - (push gnus-reffed-article-number gnus-newsgroup-unreads) + (setq gnus-newsgroup-unreads + (gnus-add-to-sorted-list gnus-newsgroup-unreads + gnus-reffed-article-number)) (setq gnus-reffed-article-number (1- gnus-reffed-article-number)) (setq pslist (cdr pslist))))))) @@ -10536,39 +10681,35 @@ If REVERSE, save parts that do not match TYPE." (defun gnus-summary-highlight-line () "Highlight current line according to `gnus-summary-highlight'." (let* ((list gnus-summary-highlight) - (p (point)) - (end (progn (end-of-line) (point))) - ;; now find out where the line starts and leave point there. - (beg (progn (beginning-of-line) (point))) + (beg (gnus-point-at-bol)) (article (gnus-summary-article-number)) (score (or (cdr (assq (or article gnus-current-article) gnus-newsgroup-scored)) gnus-summary-default-score 0)) (mark (or (gnus-summary-article-mark) gnus-unread-mark)) - (inhibit-read-only t)) + (inhibit-read-only t) + (default gnus-summary-default-score) + (default-high gnus-summary-default-high-score) + (default-low gnus-summary-default-low-score)) ;; Eval the cars of the lists until we find a match. - (let ((default gnus-summary-default-score) - (default-high gnus-summary-default-high-score) - (default-low gnus-summary-default-low-score)) - (while (and list - (not (eval (caar list)))) - (setq list (cdr list)))) + (while (and list + (not (eval (caar list)))) + (setq list (cdr list))) (let ((face (cdar list))) (unless (eq face (get-text-property beg 'face)) (gnus-put-text-property-excluding-characters-with-faces - beg end 'face + beg (gnus-point-at-eol) 'face (setq face (if (boundp face) (symbol-value face) face))) (when gnus-summary-highlight-line-function - (funcall gnus-summary-highlight-line-function article face)))) - (goto-char p))) + (funcall gnus-summary-highlight-line-function article face)))))) (defun gnus-update-read-articles (group unread &optional compute) - "Update the list of read articles in GROUP." + "Update the list of read articles in GROUP. +UNREAD is a sorted list." (let* ((active (or gnus-newsgroup-active (gnus-active group))) (entry (gnus-gethash group gnus-newsrc-hashtb)) (info (nth 2 entry)) (prev 1) - (unread (sort (copy-sequence unread) '<)) read) (if (or (not info) (not active)) ;; There is no info on this group if it was, in fact, @@ -10797,9 +10938,10 @@ returned." (defun gnus-summary-insert-articles (articles) (when (setq articles - (gnus-set-difference articles - (mapcar (lambda (h) (mail-header-number h)) - gnus-newsgroup-headers))) + (gnus-sorted-difference articles + (mapcar (lambda (h) + (mail-header-number h)) + gnus-newsgroup-headers))) (setq gnus-newsgroup-headers (merge 'list gnus-newsgroup-headers @@ -10837,45 +10979,51 @@ If ALL is non-nil, already read articles become readable. If ALL is a number, fetch this number of articles." (interactive "P") (prog1 - (let ((old (mapcar 'car gnus-newsgroup-data)) - (i (car gnus-newsgroup-active)) + (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<)) older len) - (while (<= i (cdr gnus-newsgroup-active)) - (or (memq i old) (push i older)) - (incf i)) + (setq older + (gnus-sorted-difference + (gnus-uncompress-range (list gnus-newsgroup-active)) + old)) (setq len (length older)) (cond ((null older) nil) ((numberp all) (if (< all len) - (setq older (subseq older 0 all)))) + (setq older (last older all)))) (all nil) (t (if (and (numberp gnus-large-newsgroup) (> len gnus-large-newsgroup)) - (let ((input - (read-string - (format - "How many articles from %s (default %d): " - (gnus-limit-string - (gnus-group-decoded-name gnus-newsgroup-name) 35) - len)))) + (let* ((cursor-in-echo-area nil) + (initial (gnus-parameter-large-newsgroup-initial + gnus-newsgroup-name)) + (input + (read-string + (format + "How many articles from %s (%s %d): " + (gnus-limit-string + (gnus-group-decoded-name gnus-newsgroup-name) 35) + (if initial "max" "default") + len) + (if initial + (cons (number-to-string initial) + 0))))) (unless (string-match "^[ \t]*$" input) (setq all (string-to-number input)) (if (< all len) - (setq older (subseq older 0 all)))))))) + (setq older (last older all)))))))) (if (not older) (message "No old news.") - (let ((gnus-fetch-old-headers t)) - (gnus-summary-insert-articles older)) - (gnus-summary-limit (gnus-union older old)))) + (gnus-summary-insert-articles older) + (gnus-summary-limit (gnus-sorted-nunion old older)))) (gnus-summary-position-point))) (defun gnus-summary-insert-new-articles () "Insert all new articles in this group." (interactive) (prog1 - (let ((old (mapcar 'car gnus-newsgroup-data)) + (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<)) (old-active gnus-newsgroup-active) (nnmail-fetched-sources (list t)) i new) @@ -10890,8 +11038,8 @@ If ALL is a number, fetch this number of articles." (setq new (nreverse new)) (gnus-summary-insert-articles new) (setq gnus-newsgroup-unreads - (append gnus-newsgroup-unreads new)) - (gnus-summary-limit (gnus-union old new)))) + (gnus-sorted-nunion gnus-newsgroup-unreads new)) + (gnus-summary-limit (gnus-sorted-nunion old new)))) (gnus-summary-position-point))) (gnus-summary-make-all-marking-commands) diff --git a/lisp/gnus-topic.el b/lisp/gnus-topic.el index 1c493c6..b4a4042 100644 --- a/lisp/gnus-topic.el +++ b/lisp/gnus-topic.el @@ -61,7 +61,7 @@ with some simple extensions. %a Number of unread articles in the groups in the topic. %A Number of unread articles in the groups in the topic and its subtopics. -General format specifiers can also be used. +General format specifiers can also be used. See (gnus)Formatting Variables." :link '(custom-manual "(gnus)Formatting Variables") :type 'string @@ -1134,7 +1134,7 @@ articles in the topic and its subtopics." (setq gnus-group-change-level-function 'gnus-topic-change-level) (setq gnus-goto-missing-group-function 'gnus-topic-goto-missing-group) (make-local-hook 'gnus-check-bogus-groups-hook) - (add-hook 'gnus-check-bogus-groups-hook 'gnus-topic-clean-alist + (add-hook 'gnus-check-bogus-groups-hook 'gnus-topic-clean-alist nil 'local) (setq gnus-topology-checked-p nil) ;; We check the topology. diff --git a/lisp/gnus-util.el b/lisp/gnus-util.el index 1213225..887d7a6 100644 --- a/lisp/gnus-util.el +++ b/lisp/gnus-util.el @@ -38,6 +38,7 @@ (defvar nnmail-pathname-coding-system)) (require 'nnheader) (require 'time-date) +(require 'netrc) (eval-and-compile (autoload 'message-fetch-field "message") @@ -62,6 +63,11 @@ (setq start (- (length string) tail)))) string)))) +;;; bring in the netrc functions as aliases +(defalias 'gnus-netrc-get 'netrc-get) +(defalias 'gnus-netrc-machine 'netrc-machine) +(defalias 'gnus-parse-netrc 'netrc-parse) + (defun gnus-boundp (variable) "Return non-nil if VARIABLE is bound and non-nil." (and (boundp variable) @@ -172,7 +178,7 @@ (string-match (concat "[ \t]*<" (regexp-quote address) ">") from) (and (setq name (substring from 0 (match-beginning 0))) ;; Strip any quotes from the name. - (string-match "\".*\"" name) + (string-match "^\".*\"$" name) (setq name (substring name 1 (1- (match-end 0)))))) ;; If not, then "address (name)" is used. (or name @@ -469,7 +475,7 @@ jabbering all the time." "Return a list of Message-IDs in REFERENCES." (let ((beg 0) ids) - (while (string-match "<[^> \t]+>" references beg) + (while (string-match "<[^<]+[^< \t]" references beg) (push (substring references (match-beginning 0) (setq beg (match-end 0))) ids)) (nreverse ids))) @@ -484,8 +490,8 @@ If N, return the Nth ancestor instead." (while (nthcdr n ids) (setq ids (cdr ids))) (car ids)) - (when (string-match "<[^> \t]+>\\'" references) - (match-string 0 references))))) + (when (string-match "\\(<[^<]+>\\)[ \t]*\\'" references) + (match-string 1 references))))) (defun gnus-buffer-live-p (buffer) "Say whether BUFFER is alive or not." @@ -900,93 +906,6 @@ ARG is passed to the first function." (apply 'run-hooks funcs) (set-buffer buf)))) -;;; -;;; .netrc and .authinforc parsing -;;; - -(defun gnus-parse-netrc (file) - "Parse FILE and return an list of all entries in the file." - (when (file-exists-p file) - (with-temp-buffer - (let ((tokens '("machine" "default" "login" - "password" "account" "macdef" "force" - "port")) - alist elem result pair) - (insert-file-contents file) - (goto-char (point-min)) - ;; Go through the file, line by line. - (while (not (eobp)) - (narrow-to-region (point) (gnus-point-at-eol)) - ;; For each line, get the tokens and values. - (while (not (eobp)) - (skip-chars-forward "\t ") - ;; Skip lines that begin with a "#". - (if (eq (char-after) ?#) - (goto-char (point-max)) - (unless (eobp) - (setq elem - (if (= (following-char) ?\") - (read (current-buffer)) - (buffer-substring - (point) (progn (skip-chars-forward "^\t ") - (point))))) - (cond - ((equal elem "macdef") - ;; We skip past the macro definition. - (widen) - (while (and (zerop (forward-line 1)) - (looking-at "$"))) - (narrow-to-region (point) (point))) - ((member elem tokens) - ;; Tokens that don't have a following value are ignored, - ;; except "default". - (when (and pair (or (cdr pair) - (equal (car pair) "default"))) - (push pair alist)) - (setq pair (list elem))) - (t - ;; Values that haven't got a preceding token are ignored. - (when pair - (setcdr pair elem) - (push pair alist) - (setq pair nil))))))) - (when alist - (push (nreverse alist) result)) - (setq alist nil - pair nil) - (widen) - (forward-line 1)) - (nreverse result))))) - -(defun gnus-netrc-machine (list machine &optional port defaultport) - "Return the netrc values from LIST for MACHINE or for the default entry. -If PORT specified, only return entries with matching port tokens. -Entries without port tokens default to DEFAULTPORT." - (let ((rest list) - result) - (while list - (when (equal (cdr (assoc "machine" (car list))) machine) - (push (car list) result)) - (pop list)) - (unless result - ;; No machine name matches, so we look for default entries. - (while rest - (when (assoc "default" (car rest)) - (push (car rest) result)) - (pop rest))) - (when result - (setq result (nreverse result)) - (while (and result - (not (equal (or port defaultport "nntp") - (or (gnus-netrc-get (car result) "port") - defaultport "nntp")))) - (pop result)) - (car result)))) - -(defun gnus-netrc-get (alist type) - "Return the value of token TYPE from ALIST." - (cdr (assoc type alist))) - ;;; Various (defvar gnus-group-buffer) ; Compiler directive @@ -1132,7 +1051,9 @@ Return the modified alist." (string-equal (downcase x) (downcase y))))) (defcustom gnus-use-byte-compile t - "If non-nil, byte-compile crucial run-time codes." + "If non-nil, byte-compile crucial run-time codes. +Setting it to `nil' has no effect after first time running +`gnus-byte-compile'." :type 'boolean :version "21.1" :group 'gnus-various) @@ -1141,6 +1062,10 @@ Return the modified alist." "Byte-compile FORM if `gnus-use-byte-compile' is non-nil." (if gnus-use-byte-compile (progn + (condition-case nil + ;; Work around a bug in XEmacs 21.4 + (require 'byte-optimize) + (error)) (require 'bytecomp) (defalias 'gnus-byte-compile 'byte-compile) (byte-compile form)) @@ -1217,7 +1142,7 @@ forbidden in URL encoding." SPEC is a predicate specifier that contains stuff like `or', `and', `not', lists and functions. The functions all take one parameter." `(lambda (elem) ,(gnus-make-predicate-1 spec))) - + (defun gnus-make-predicate-1 (spec) (cond ((symbolp spec) @@ -1238,7 +1163,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and', (list 'local-map map)))) (defun gnus-completing-read (prompt table &optional predicate require-match - history inherit-input-method) + history) (when (and history (not (boundp history))) (set history nil)) @@ -1251,8 +1176,93 @@ SPEC is a predicate specifier that contains stuff like `or', `and', require-match nil history - (car (symbol-value history)) - inherit-input-method)) + (car (symbol-value history)))) + +(defun gnus-graphic-display-p () + (or (and (fboundp 'display-graphic-p) + (display-graphic-p)) + ;;;!!!This is bogus. Fixme! + (and (featurep 'xemacs) + t))) + +(put 'gnus-parse-without-error 'lisp-indent-function 0) +(put 'gnus-parse-without-error 'edebug-form-spec '(body)) + +(defmacro gnus-parse-without-error (&rest body) + "Allow continuing onto the next line even if an error occurs." + `(while (not (eobp)) + (condition-case () + (progn + ,@body + (goto-char (point-max))) + (error + (gnus-error 4 "Invalid data on line %d" + (count-lines (point-min) (point))) + (forward-line 1))))) + +(defun gnus-cache-file-contents (file variable function) + "Cache the contents of FILE in VARIABLE. The contents come from FUNCTION." + (let ((time (nth 5 (file-attributes file))) + contents value) + (if (or (null (setq value (symbol-value variable))) + (not (equal (car value) file)) + (not (equal (nth 1 value) time))) + (progn + (setq contents (funcall function file)) + (set variable (list file time contents)) + contents) + (nth 2 value)))) + +(defun gnus-multiple-choice (prompt choice &optional idx) + "Ask user a multiple choice question. +CHOICE is a list of the choice char and help message at IDX." + (let (tchar buf) + (save-window-excursion + (save-excursion + (while (not tchar) + (message "%s (%s?): " + prompt + (mapconcat (lambda (s) (char-to-string (car s))) + choice "")) + (setq tchar (read-char)) + (when (not (assq tchar choice)) + (setq tchar nil) + (setq buf (get-buffer-create "*Gnus Help*")) + (pop-to-buffer buf) + (fundamental-mode) ; for Emacs 20.4+ + (buffer-disable-undo) + (erase-buffer) + (insert prompt ":\n\n") + (let ((max -1) + (list choice) + (alist choice) + (idx (or idx 1)) + (i 0) + n width pad format) + ;; find the longest string to display + (while list + (setq n (length (nth idx (car list)))) + (unless (> max n) + (setq max n)) + (setq list (cdr list))) + (setq max (+ max 4)) ; %c, `:', SPACE, a SPACE at end + (setq n (/ (1- (window-width)) max)) ; items per line + (setq width (/ (1- (window-width)) n)) ; width of each item + ;; insert `n' items, each in a field of width `width' + (while alist + (if (< i n) + () + (setq i 0) + (delete-char -1) ; the `\n' takes a char + (insert "\n")) + (setq pad (- width 3)) + (setq format (concat "%c: %-" (int-to-string pad) "s")) + (insert (format format (caar alist) (nth idx (car alist)))) + (setq alist (cdr alist)) + (setq i (1+ i)))))))) + (if (buffer-live-p buf) + (kill-buffer buf)) + tchar)) (provide 'gnus-util) diff --git a/lisp/gnus-uu.el b/lisp/gnus-uu.el index 676c6f0..646da71 100644 --- a/lisp/gnus-uu.el +++ b/lisp/gnus-uu.el @@ -1,6 +1,6 @@ ;;; gnus-uu.el --- extract (uu)encoded files in Gnus ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000, -;; 2001 Free Software Foundation, Inc. +;; 2001, 2002 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Created: 2 Oct 1993 @@ -321,7 +321,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defvar gnus-uu-saved-article-name nil) -(defvar gnus-uu-begin-string "^begin[ \t]+[0-7][0-7][0-7][ \t]+\\(.*\\)$") +(defvar gnus-uu-begin-string "^begin[ \t]+0?[0-7][0-7][0-7][ \t]+\\(.*\\)$") (defvar gnus-uu-end-string "^end[ \t]*$") (defvar gnus-uu-body-line "^M") @@ -336,7 +336,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defvar gnus-uu-shar-file-name nil) (defvar gnus-uu-shar-name-marker - "begin [0-7][0-7][0-7][ \t]+\\(\\(\\w\\|\\.\\)*\\b\\)") + "begin 0?[0-7][0-7][0-7][ \t]+\\(\\(\\w\\|[.\\:]\\)*\\b\\)") (defvar gnus-uu-postscript-begin-string "^%!PS-") (defvar gnus-uu-postscript-end-string "^%%EOF$") @@ -353,56 +353,6 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (defvar gnus-uu-digest-from-subject nil) (defvar gnus-uu-digest-buffer nil) -;; Keymaps - -(gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map) - "p" gnus-summary-mark-as-processable - "u" gnus-summary-unmark-as-processable - "U" gnus-summary-unmark-all-processable - "v" gnus-uu-mark-over - "s" gnus-uu-mark-series - "r" gnus-uu-mark-region - "g" gnus-uu-unmark-region - "R" gnus-uu-mark-by-regexp - "G" gnus-uu-unmark-by-regexp - "t" gnus-uu-mark-thread - "T" gnus-uu-unmark-thread - "a" gnus-uu-mark-all - "b" gnus-uu-mark-buffer - "S" gnus-uu-mark-sparse - "k" gnus-summary-kill-process-mark - "y" gnus-summary-yank-process-mark - "w" gnus-summary-save-process-mark - "i" gnus-uu-invert-processable) - -(gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map) - ;;"x" gnus-uu-extract-any - "m" gnus-summary-save-parts - "u" gnus-uu-decode-uu - "U" gnus-uu-decode-uu-and-save - "s" gnus-uu-decode-unshar - "S" gnus-uu-decode-unshar-and-save - "o" gnus-uu-decode-save - "O" gnus-uu-decode-save - "b" gnus-uu-decode-binhex - "B" gnus-uu-decode-binhex - "p" gnus-uu-decode-postscript - "P" gnus-uu-decode-postscript-and-save) - -(gnus-define-keys - (gnus-uu-extract-view-map "v" gnus-uu-extract-map) - "u" gnus-uu-decode-uu-view - "U" gnus-uu-decode-uu-and-save-view - "s" gnus-uu-decode-unshar-view - "S" gnus-uu-decode-unshar-and-save-view - "o" gnus-uu-decode-save-view - "O" gnus-uu-decode-save-view - "b" gnus-uu-decode-binhex-view - "B" gnus-uu-decode-binhex-view - "p" gnus-uu-decode-postscript-view - "P" gnus-uu-decode-postscript-and-save-view) - - ;; Commands. (defun gnus-uu-decode-uu (&optional n) @@ -457,7 +407,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." gnus-uu-default-dir gnus-uu-default-dir)))) (setq gnus-uu-binhex-article-name - (make-temp-name (concat gnus-uu-work-dir "binhex"))) + (mm-make-temp-file (expand-file-name "binhex" gnus-uu-work-dir))) (gnus-uu-decode-with-method 'gnus-uu-binhex-article n dir)) (defun gnus-uu-decode-uu-view (&optional n) @@ -510,7 +460,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." (read-file-name "Unbinhex, view and save in dir: " gnus-uu-default-dir gnus-uu-default-dir))) (setq gnus-uu-binhex-article-name - (make-temp-name (concat gnus-uu-work-dir "binhex"))) + (mm-make-temp-file (expand-file-name "binhex" gnus-uu-work-dir))) (let ((gnus-view-pseudos (or gnus-view-pseudos 'automatic))) (gnus-uu-decode-binhex n file))) @@ -521,7 +471,7 @@ didn't work, and overwrite existing files. Otherwise, ask each time." "Digests and forwards all articles in this series." (interactive "P") (let ((gnus-uu-save-in-digest t) - (file (make-temp-name (nnheader-concat gnus-uu-tmp-dir "forward"))) + (file (mm-make-temp-file (nnheader-concat gnus-uu-tmp-dir "forward"))) (message-forward-as-mime message-forward-as-mime) (mail-parse-charset gnus-newsgroup-charset) (mail-parse-ignored-charsets gnus-newsgroup-ignored-charsets) @@ -1025,7 +975,8 @@ When called interactively, prompt for REGEXP." (if (looking-at gnus-uu-binhex-begin-line) (progn (setq state (list 'begin)) - (write-region 1 1 gnus-uu-binhex-article-name)) + (write-region (point-min) (point-min) + gnus-uu-binhex-article-name)) (setq state (list 'middle))) (goto-char (point-max)) (re-search-backward (concat gnus-uu-binhex-body-line "\\|" @@ -1137,7 +1088,7 @@ When called interactively, prompt for REGEXP." (while (re-search-forward "[ \t]+" nil t) (replace-match "[ \t]+" t t)) - (buffer-substring 1 (point-max)))) + (buffer-substring (point-min) (point-max)))) (defun gnus-uu-get-list-of-articles (n) ;; If N is non-nil, the article numbers of the N next articles @@ -1229,10 +1180,11 @@ When called interactively, prompt for REGEXP." ;; Expand numbers. (goto-char (point-min)) (while (re-search-forward "[0-9]+" nil t) - (replace-match - (format "%06d" - (string-to-int (buffer-substring - (match-beginning 0) (match-end 0)))))) + (ignore-errors + (replace-match + (format "%06d" + (string-to-int (buffer-substring + (match-beginning 0) (match-end 0))))))) (setq string (buffer-substring 1 (point-max))) (setcar (car string-list) string) (setq string-list (cdr string-list)))) @@ -1801,8 +1753,7 @@ Gnus might fail to display all of it.") gnus-uu-tmp-dir))) (setq gnus-uu-work-dir - (make-temp-name (concat gnus-uu-tmp-dir "gnus"))) - (gnus-make-directory gnus-uu-work-dir) + (mm-make-temp-file (concat gnus-uu-tmp-dir "gnus") 'dir)) (set-file-modes gnus-uu-work-dir 448) (setq gnus-uu-work-dir (file-name-as-directory gnus-uu-work-dir)) (push (cons gnus-newsgroup-name gnus-uu-work-dir) @@ -1972,7 +1923,7 @@ The user will be asked for a file name." (goto-char (point-min)) (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$")) (forward-line -1) - (narrow-to-region 1 (point)) + (narrow-to-region (point-min) (point)) (unless (mail-fetch-field "mime-version") (widen) (insert "MIME-Version: 1.0\n")) @@ -2062,7 +2013,7 @@ If no file has been included, the user will be asked for a file." (erase-buffer) (insert-buffer-substring post-buf beg-binary end-binary) (goto-char (point-min)) - (setq length (count-lines 1 (point-max))) + (setq length (count-lines (point-min) (point-max))) (setq parts (/ length gnus-uu-post-length)) (unless (< (% length gnus-uu-post-length) 4) (incf parts))) @@ -2075,7 +2026,7 @@ If no file has been included, the user will be asked for a file." (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$") nil t) (beginning-of-line) - (setq header (buffer-substring 1 (point))) + (setq header (buffer-substring (point-min) (point))) (goto-char (point-min)) (when gnus-uu-post-separate-description diff --git a/lisp/gnus-win.el b/lisp/gnus-win.el index 9ac4c28..570c27c 100644 --- a/lisp/gnus-win.el +++ b/lisp/gnus-win.el @@ -198,7 +198,7 @@ See the Gnus manual for an explanation of the syntax used.") (defcustom gnus-configure-windows-hook nil "*A hook called when configuring windows." - :group 'gnus-windowns + :group 'gnus-windows :type 'hook) ;;; Internal variables. @@ -557,7 +557,7 @@ should have point." (delq lowest-buf bufs))))) (eval-and-compile - (cond + (cond ((fboundp 'frames-on-display-list) (defalias 'gnus-frames-on-display-list 'frames-on-display-list)) ((and (featurep 'xemacs) (fboundp 'frame-device)) @@ -569,9 +569,9 @@ should have point." (defun gnus-get-buffer-window (buffer &optional frame) (cond ((and (null gnus-use-frames-on-any-display) (memq frame '(t 0 visible))) - (car + (car (let ((frames (gnus-frames-on-display-list))) - (gnus-delete-if (lambda (win) (not (memq (window-frame win) + (gnus-delete-if (lambda (win) (not (memq (window-frame win) frames))) (get-buffer-window-list buffer nil frame))))) (t diff --git a/lisp/gnus-xmas.el b/lisp/gnus-xmas.el index 188fb97..c3371d3 100644 --- a/lisp/gnus-xmas.el +++ b/lisp/gnus-xmas.el @@ -388,9 +388,9 @@ call it with the value of the `gnus-data' text property." (defalias 'gnus-put-text-property 'gnus-xmas-put-text-property) (defalias 'gnus-deactivate-mark 'ignore) (defalias 'gnus-window-edges 'window-pixel-edges) - + (if (and (<= emacs-major-version 19) - (< emacs-minor-version 14)) + (< emacs-minor-version 14)) (defalias 'gnus-set-text-properties 'gnus-xmas-set-text-properties)) (unless (boundp 'standard-display-table) @@ -427,11 +427,11 @@ call it with the value of the `gnus-data' text property." (defalias 'gnus-group-startup-message 'gnus-xmas-group-startup-message) (defalias 'gnus-tree-minimize 'gnus-xmas-tree-minimize) (defalias 'gnus-appt-select-lowest-window - 'gnus-xmas-appt-select-lowest-window) + 'gnus-xmas-appt-select-lowest-window) (defalias 'gnus-mail-strip-quoted-names 'gnus-xmas-mail-strip-quoted-names) (defalias 'gnus-character-to-event 'character-to-event) (defalias 'gnus-mode-line-buffer-identification - 'gnus-xmas-mode-line-buffer-identification) + 'gnus-xmas-mode-line-buffer-identification) (defalias 'gnus-key-press-event-p 'key-press-event-p) (defalias 'gnus-region-active-p 'region-active-p) (defalias 'gnus-annotation-in-region-p 'gnus-xmas-annotation-in-region-p) @@ -441,6 +441,11 @@ call it with the value of the `gnus-data' text property." (defalias 'gnus-create-image 'gnus-xmas-create-image) (defalias 'gnus-remove-image 'gnus-xmas-remove-image) + (when (or (< emacs-major-version 21) + (and (= emacs-major-version 21) + (< emacs-minor-version 3))) + (defalias 'gnus-completing-read 'gnus-xmas-completing-read)) + ;; These ones are not defcutom'ed, sometimes not even defvar'ed. They ;; probably should. If that is done, the code below should then be moved ;; where each variable is defined, in order not to mess with user settings. @@ -789,9 +794,8 @@ XEmacs compatibility workaround." gnus-mailing-list-menu)) (defun gnus-xmas-image-type-available-p (type) - (when (eq type 'pbm) - (setq type 'xbm)) - (featurep type)) + (and window-system + (featurep (if (eq type 'pbm) 'xbm type)))) (defun gnus-xmas-create-image (file &optional type data-p &rest props) (let ((type (if type @@ -817,7 +821,7 @@ XEmacs compatibility workaround." (insert file) (insert-file-contents file)) (make-glyph - (vector + (vector (or (intern type) (mm-image-type-from-buffer)) :data (buffer-string)))))) @@ -832,7 +836,7 @@ Warning: Don't insert text immediately after the image." extent) (if (and (bobp) (not string)) (setq string " ")) - (if string + (if string (insert string) (setq begin (1- begin))) (setq extent (make-extent begin (point))) @@ -852,6 +856,21 @@ Warning: Don't insert text immediately after the image." nil) nil nil nil nil nil 'gnus-image)) +(defun gnus-xmas-completing-read (prompt table &optional + predicate require-match history) + (when (and history + (not (boundp history))) + (set history nil)) + (completing-read + (if (symbol-value history) + (concat prompt " (" (car (symbol-value history)) "): ") + (concat prompt ": ")) + table + predicate + require-match + nil + history)) + (provide 'gnus-xmas) ;;; gnus-xmas.el ends here diff --git a/lisp/gnus.el b/lisp/gnus.el index 2b17690..505930f 100644 --- a/lisp/gnus.el +++ b/lisp/gnus.el @@ -277,7 +277,7 @@ is restarted, and sometimes reloaded." :link '(custom-manual "(gnus)Exiting Gnus") :group 'gnus) -(defconst gnus-version-number "0.05" +(defconst gnus-version-number "0.06" "Version number for this version of Gnus.") (defconst gnus-version (format "Oort Gnus v%s" gnus-version-number) @@ -1085,8 +1085,8 @@ used to 899, you would say something along these lines: This variable should be a list, where the first element is how the news is to be fetched, the second is the address. -For instance, if you want to get your news via NNTP from -\"flab.flab.edu\", you could say: +For instance, if you want to get your news via \"flab.flab.edu\" using +NNTP, you could say: \(setq gnus-select-method '(nntp \"flab.flab.edu\")) @@ -1154,7 +1154,7 @@ variable instead." This is a list where each element is a complete select method (see `gnus-select-method'). -If, for instance, you want to read your mail with the nnml backend, +If, for instance, you want to read your mail with the nnml back end, you could set this variable: \(setq gnus-secondary-select-methods '((nnml \"\")))" @@ -1195,15 +1195,15 @@ It can also be a list of select methods, as well as the special symbol list, Gnus will try all the methods in the list until it finds a match." :group 'gnus-server :type '(choice (const :tag "default" nil) - (const :tag "DejaNews" (nnweb "refer" (nnweb-type dejanews))) + (const :tag "Google" (nnweb "refer" (nnweb-type google))) gnus-select-method (repeat :menu-tag "Try multiple" :tag "Multiple" - :value (current (nnweb "refer" (nnweb-type dejanews))) + :value (current (nnweb "refer" (nnweb-type google))) (choice :tag "Method" (const current) - (const :tag "DejaNews" - (nnweb "refer" (nnweb-type dejanews))) + (const :tag "Google" + (nnweb "refer" (nnweb-type google))) gnus-select-method)))) (defcustom gnus-group-faq-directory @@ -1429,6 +1429,7 @@ slower." ("nnfolder" mail respool address) ("nngateway" post-mail address prompt-address physical-address) ("nnweb" none) + ("nngoogle" post) ("nnslashdot" post) ("nnultimate" none) ("nnrss" none) @@ -1437,7 +1438,8 @@ slower." ("nnlistserv" none) ("nnagent" post-mail) ("nnimap" post-mail address prompt-address physical-address) - ("nnmaildir" mail respool address)) + ("nnmaildir" mail respool address) + ("nnnil" none)) "*An alist of valid select methods. The first element of each list lists should be a string with the name of the select method. The other elements may be the category of @@ -1609,8 +1611,7 @@ Use with caution.") ("\\(^\\|:\\)han\\>" euc-kr) ("\\(^\\|:\\)alt.chinese.text.big5\\>" chinese-big5) ("\\(^\\|:\\)soc.culture.vietnamese\\>" vietnamese-viqr) - ("\\(^\\|:\\)\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1) - (".*" iso-8859-1)) + ("\\(^\\|:\\)\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)) :variable-document "Alist of regexps (to match group names) and default charsets to be used when reading." :variable-group gnus-charset @@ -1641,6 +1642,23 @@ posting an article." :parameter-document "Posting method for this group.") +(gnus-define-group-parameter + large-newsgroup-initial + :type integer + :function-document + "Return GROUP's initial input of the number of articles." + :variable-document + "*Alist of group regexps and its initial input of the number of articles." + :parameter-type '(choice :tag "Initial Input for Large Newsgroup" + (const :tag "All" nil) + (integer)) + :parameter-document "\ + +This number will be prompted as the initial value of the number of +articles to list when the group is a large newsgroup (see +`gnus-large-newsgroup'). If it is `nil', the default value is the +total number of articles in the group.") + (defcustom gnus-group-uncollapsed-levels 1 "Number of group name elements to leave alone when making a short group name." :group 'gnus-group-visual @@ -1764,10 +1782,13 @@ face." (defvar gnus-plugged t "Whether Gnus is plugged or not.") -(defvar gnus-agent-cache t - "Whether Gnus use agent cache.") +(defcustom gnus-agent-cache t + "Whether Gnus use agent cache." + :version "21.3" + :group 'gnus-agent + :type 'boolean) -(defcustom gnus-default-charset 'iso-8859-1 +(defcustom gnus-default-charset (mm-guess-mime-charset) "Default charset assumed to be used when viewing non-ASCII characters. This variable is overridden on a group-to-group basis by the gnus-group-charset-alist variable and is only used on groups not @@ -1775,6 +1796,13 @@ covered by that variable." :type 'symbol :group 'gnus-charset) +(defcustom gnus-agent nil + "Whether we want to use the Gnus agent or not. +Putting (gnus-agentize) in ~/.gnus is obsolete by (setq gnus-agent t)." + :version "21.3" + :group 'gnus-agent + :type 'boolean) + ;;; Internal variables @@ -1785,9 +1813,7 @@ covered by that variable." (defvar gnus-original-article-buffer " *Original Article*") (defvar gnus-newsgroup-name nil) (defvar gnus-ephemeral-servers nil) - -(defvar gnus-agent nil - "Whether we want to use the Gnus agent or not.") +(defvar gnus-server-method-cache nil) (defvar gnus-agent-fetching nil "Whether Gnus agent is in fetching mode.") @@ -1795,7 +1821,7 @@ covered by that variable." (defvar gnus-agent-covered-methods nil) (defvar gnus-command-method nil - "Dynamically bound variable that says what the current backend is.") + "Dynamically bound variable that says what the current back end is.") (defvar gnus-current-select-method nil "The current method for selecting a newsgroup.") @@ -1856,12 +1882,13 @@ covered by that variable." ;; `download' is a agent flag private to each gnus installation ;; `unsend' are for nndraft groups only ;; `score' is not a proper mark +;; `bookmark': don't propagated it, or fix the bug in update-mark. (defconst gnus-article-unpropagated-mark-lists - '(seen cache download unsend score) - "Marks that shouldn't be propagated to backends. -Typical marks are those that make no sense in a standalone backend, + '(seen cache download unsend score bookmark) + "Marks that shouldn't be propagated to back ends. +Typical marks are those that make no sense in a standalone back end, such as a mark that says whether an article is stored in the cache -(which doesn't make sense in a standalone backend).") +\(which doesn't make sense in a standalone back end).") (defvar gnus-headers-retrieved-by nil) (defvar gnus-article-reply nil) @@ -2102,6 +2129,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.") gnus-article-de-base64-unreadable gnus-article-decode-HZ gnus-article-wash-html + gnus-article-unsplit-urls gnus-article-hide-pgp gnus-article-hide-pem gnus-article-hide-signature gnus-article-strip-leading-blank-lines gnus-article-date-local @@ -2203,8 +2231,8 @@ possible. This restriction may disappear in later versions of Gnus. -General format specifiers can also be used. -See (gnus)Formatting Variables." +General format specifiers can also be used. +See `(gnus)Formatting Variables'." :link '(custom-manual "(gnus)Formatting Variables") :type 'string :group 'gnus-summary-format) @@ -2376,11 +2404,13 @@ with a `subscribed' parameter." (dolist (entry (cdr gnus-newsrc-alist)) (setq group (car entry)) (when (gnus-group-find-parameter group 'subscribed) - (setq address (or (gnus-group-fast-parameter group 'to-address) - (gnus-group-fast-parameter group 'to-list))) + (setq address (mail-strip-quoted-names + (or (gnus-group-fast-parameter group 'to-address) + (gnus-group-fast-parameter group 'to-list)))) (when address (push address addresses)))) - (list (mapconcat 'regexp-quote addresses "\\|")))) + (when addresses + (list (mapconcat 'regexp-quote addresses "\\|"))))) (defmacro gnus-string-or (&rest strings) "Return the first element of STRINGS that is a non-blank string. @@ -2662,6 +2692,36 @@ that that variable is buffer-local to the summary buffers." (nth 1 method)))) method))) +(defsubst gnus-server-to-method (server) + "Map virtual server names to select methods." + (or (and server (listp server) server) + (cdr (assoc server gnus-server-method-cache)) + (let ((result + (or + ;; Perhaps this is the native server? + (and (equal server "native") gnus-select-method) + ;; It should be in the server alist. + (cdr (assoc server gnus-server-alist)) + ;; It could be in the predefined server alist. + (cdr (assoc server gnus-predefined-server-alist)) + ;; If not, we look through all the opened server + ;; to see whether we can find it there. + (let ((opened gnus-opened-servers)) + (while (and opened + (not (equal server (format "%s:%s" (caaar opened) + (cadaar opened))))) + (pop opened)) + (caar opened)) + ;; It could be a named method, search all servers + (let ((servers gnus-secondary-select-methods)) + (while (and servers + (not (equal server (format "%s:%s" (caar servers) + (cadar servers))))) + (pop servers)) + (car servers))))) + (push (cons server result) gnus-server-method-cache) + result))) + (defsubst gnus-server-get-method (group method) ;; Input either a server name, and extended server name, or a ;; select method, and return a select method. @@ -2679,33 +2739,6 @@ that that variable is buffer-local to the summary buffers." (t (gnus-server-add-address method)))) -(defun gnus-server-to-method (server) - "Map virtual server names to select methods." - (or - ;; Is this a method, perhaps? - (and server (listp server) server) - ;; Perhaps this is the native server? - (and (equal server "native") gnus-select-method) - ;; It should be in the server alist. - (cdr (assoc server gnus-server-alist)) - ;; It could be in the predefined server alist. - (cdr (assoc server gnus-predefined-server-alist)) - ;; If not, we look through all the opened server - ;; to see whether we can find it there. - (let ((opened gnus-opened-servers)) - (while (and opened - (not (equal server (format "%s:%s" (caaar opened) - (cadaar opened))))) - (pop opened)) - (caar opened)) - ;; It could be a named method, search all servers - (let ((servers gnus-secondary-select-methods)) - (while (and servers - (not (equal server (format "%s:%s" (caar servers) - (cadar servers))))) - (pop servers)) - (car servers)))) - (defmacro gnus-method-equal (ss1 ss2) "Say whether two servers are equal." `(let ((s1 ,ss1) @@ -2918,7 +2951,7 @@ The function `gnus-group-find-parameter' will do that for you." symbol allow-list)) (when result ;; Expand if necessary. - (if (and (stringp result) (string-match "\\\\" result)) + (if (and (stringp result) (string-match "\\\\[0-9&]" result)) (setq result (gnus-expand-group-parameter (car head) result group))) ;; Exit the loop early. @@ -3177,7 +3210,7 @@ If NEWSGROUP is nil, return the global kill file name instead." (address (nth 1 server))) (if (and address (not (zerop (length address)))) - (format "%s via %s" address (car server)) + (format "%s using %s" address (car server)) (format "%s" (car server))))) (defun gnus-find-method-for-group (group &optional info) diff --git a/lisp/hex-util.el b/lisp/hex-util.el index ddf154d..6936bf3 100644 --- a/lisp/hex-util.el +++ b/lisp/hex-util.el @@ -49,7 +49,7 @@ (aset dst idx (+ (* (hex-char-to-num (aref string pos)) 16) (hex-char-to-num (aref string (1+ pos))))) (setq idx (1+ idx) - pos (+ 2 pos))) + pos (+ 2 pos))) dst)) (defun encode-hex-string (string) @@ -65,7 +65,7 @@ ;;; (aset dst idx (num-to-hex-char (logand (aref string pos) 15))) (aset dst idx (num-to-hex-char (% (aref string pos) 16))) (setq idx (1+ idx) - pos (1+ pos))) + pos (1+ pos))) dst)) (provide 'hex-util) diff --git a/lisp/html2text.el b/lisp/html2text.el new file mode 100644 index 0000000..22ae79b --- /dev/null +++ b/lisp/html2text.el @@ -0,0 +1,568 @@ +;;; html2text.el --- a simple html to plain text converter + +;; Copyright (C) 2002 Free Software Foundation, Inc. + +;; Author: Joakim Hove + +;; 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: + +;; These functions provide a simple way to wash/clean html infected +;; mails. Definitely do not work in all cases, but some improvement +;; in readability is generally obtained. Formatting is only done in +;; the buffer, so the next time you enter the article it will be +;; "re-htmlized". +;; +;; The main function is "html2text" + +;;; Code: + +;; +;; +;; + +(eval-when-compile + (require 'cl)) + +(defvar html2text-format-single-element-list '(("hr" . html2text-clean-hr))) + +(defvar html2text-replace-list + '((" " . " ") (">" . ">") ("<" . "<") (""" . "\"")) + "The map of entity to text. + +This is an alist were each element is a dotted pair consisting of an +old string, and a replacement string. This replacement is done by the +function \"html2text-substitute\" which basically performs a +replace-string operation for every element in the list. This is +completely verbatim - without any use of REGEXP.") + +(defvar html2text-remove-tag-list + '("html" "body" "p" "img" "dir" "head" "div" "br" "font" "title" "meta") + "A list of removable tags. + +This is a list of tags which should be removed, without any +formatting. Observe that if you the tags in the list are presented +*without* any \"<\" or \">\". All occurences of a tag appearing in +this list are removed, irrespective of whether it is a closing or +opening tag, or if the tag has additional attributes. The actual +deletion is done by the function \"html2text-remove-tags\". + +For instance the text: + +\"Here comes something big .\" + +will be reduced to: + +\"Here comes something big.\" + +If this list contains the element \"font\".") + +(defvar html2text-format-tag-list + '(("b" . html2text-clean-bold) + ("u" . html2text-clean-underline) + ("i" . html2text-clean-italic) + ("blockquote" . html2text-clean-blockquote) + ("a" . html2text-clean-anchor) + ("ul" . html2text-clean-ul) + ("ol" . html2text-clean-ol) + ("dl" . html2text-clean-dl) + ("center" . html2text-clean-center)) + "An alist of tags and processing functions. + +This is an alist where each dotted pair consists of a tag, and then +the name of a function to be called when this tag is found. The +function is called with the arguments p1, p2, p3 and p4. These are +demontrated below: + +\" This is bold text \" + ^ ^ ^ ^ + | | | | +p1 p2 p3 p4 + +Then the called function will typically format the text somewhat and +remove the tags.") + +(defvar html2text-remove-tag-list2 '("li" "dt" "dd" "meta") + "Another list of removable tags. + +This is a list of tags which are removed similarly to the list +`html2text-remove-tag-list' - but these tags are retained for the +formatting, and then moved afterward.") + +;; +;; +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; +;; + +(defun html2text-buffer-head () + (if (string= mode-name "Article") + (beginning-of-buffer) + (beginning-of-buffer) + ) + ) + +(defun html2text-replace-string (from-string to-string p1 p2) + (goto-char p1) + (let ((delta (- (string-width to-string) (string-width from-string))) + (change 0)) + (while (search-forward from-string p2 t) + (replace-match to-string) + (setq change (+ change delta)) + ) + change + ) + ) + +;; +;; +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; i.e. +;; + +(defun html2text-attr-value (attr-list attr) + (nth 1 (assoc attr attr-list)) + ) + +(defun html2text-get-attr (p1 p2 tag) + (goto-char p1) + (re-search-forward " +[^ ]" p2 t) + (let* ((attr-string (buffer-substring-no-properties (1- (point)) (1- p2))) + (tmp-list (split-string attr-string)) + (attr-list) + (counter 0) + (prev (car tmp-list)) + (this (nth 1 tmp-list)) + (next (nth 2 tmp-list)) + (index 1)) + + (cond + ;; size=3 + ((string-match "[^ ]=[^ ]" prev) + (let ((attr (nth 0 (split-string prev "="))) + (value (nth 1 (split-string prev "=")))) + (setq attr-list (cons (list attr value) attr-list)) + ) + ) + ;; size= 3 + ((string-match "[^ ]=\\'" prev) + (setq attr-list (cons (list (substring prev 0 -1) this) attr-list)) + ) + ) + + (while (< index (length tmp-list)) + (cond + ;; size=3 + ((string-match "[^ ]=[^ ]" this) + (let ((attr (nth 0 (split-string this "="))) + (value (nth 1 (split-string this "=")))) + (setq attr-list (cons (list attr value) attr-list)) + ) + ) + ;; size =3 + ((string-match "\\`=[^ ]" this) + (setq attr-list (cons (list prev (substring this 1)) attr-list))) + + ;; size= 3 + ((string-match "[^ ]=\\'" this) + (setq attr-list (cons (list (substring this 0 -1) next) attr-list)) + ) + + ;; size = 3 + ((string= "=" this) + (setq attr-list (cons (list prev next) attr-list)) + ) + ) + (setq index (1+ index)) + (setq prev this) + (setq this next) + (setq next (nth (1+ index) tmp-list)) + ) + + ;; + ;; Tags with no accompanying "=" i.e. value=nil + ;; + (setq prev (car tmp-list)) + (setq this (nth 1 tmp-list)) + (setq next (nth 2 tmp-list)) + (setq index 1) + + (if (not (string-match "=" prev)) + (progn + (if (not (string= (substring this 0 1) "=")) + (setq attr-list (cons (list prev nil) attr-list)) + ) + ) + ) + + (while (< index (1- (length tmp-list))) + (if (not (string-match "=" this)) + (if (not (or (string= (substring next 0 1) "=") + (string= (substring prev -1) "="))) + (setq attr-list (cons (list this nil) attr-list)) + ) + ) + (setq index (1+ index)) + (setq prev this) + (setq this next) + (setq next (nth (1+ index) tmp-list)) + ) + + (if this + (progn + (if (not (string-match "=" this)) + (progn + (if (not (string= (substring prev -1) "=")) + (setq attr-list (cons (list this nil) attr-list)) + ) + ) + ) + ) + ) + attr-list ;; return - value + ) + ) + +;; +;; +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; +;; +(defun html2text-clean-list-items (p1 p2 list-type) + (goto-char p1) + (let ((item-nr 0) + (items 0)) + (while (re-search-forward "
  • " p2 t) + (setq items (1+ items))) + (goto-char p1) + (while (< item-nr items) + (setq item-nr (1+ item-nr)) + (re-search-forward "
  • " (point-max) t) + (cond + ((string= list-type "ul") (insert " o ")) + ((string= list-type "ol") (insert (format " %s: " item-nr))) + (t (insert " x "))) + ) + ) + ) + +(defun html2text-clean-dtdd (p1 p2) + (goto-char p1) + (let ((items 0) + (item-nr 0)) + (while (re-search-forward "
    " p2 t) + (setq items (1+ items))) + (goto-char p1) + (while (< item-nr items) + (setq item-nr (1+ item-nr)) + (re-search-forward "
    \\([ ]*\\)" (point-max) t) + (if (match-string 1) + (kill-region (point) (- (point) (string-width (match-string 1)))) + ) + (let ((def-p1 (point)) + (def-p2 0)) + (re-search-forward "\\([ ]*\\)\\(
    \\|
    \\)" (point-max) t) + (if (match-string 1) + (progn + (let* ((mw1 (string-width (match-string 1))) + (mw2 (string-width (match-string 2))) + (mw (+ mw1 mw2))) + (goto-char (- (point) mw)) + (kill-region (point) (+ (point) mw1)) + (setq def-p2 (point)) + ) + ) + (setq def-p2 (- (point) (string-width (match-string 2))))) + (put-text-property def-p1 def-p2 'face 'bold) + ) + ) + ) + ) + +(defun html2text-delete-tags (p1 p2 p3 p4) + (kill-region p1 p2) + (kill-region (- p3 (- p2 p1)) (- p4 (- p2 p1))) + ) + +(defun html2text-delete-single-tag (p1 p2) + (kill-region p1 p2) + ) + +(defun html2text-clean-hr (p1 p2) + (html2text-delete-single-tag p1 p2) + (goto-char p1) + (newline 1) + (insert (make-string fill-column ?-)) + ) + +(defun html2text-clean-ul (p1 p2 p3 p4) + (html2text-delete-tags p1 p2 p3 p4) + (html2text-clean-list-items p1 (- p3 (- p1 p2)) "ul") + ) + +(defun html2text-clean-ol (p1 p2 p3 p4) + (html2text-delete-tags p1 p2 p3 p4) + (html2text-clean-list-items p1 (- p3 (- p1 p2)) "ol") + ) + +(defun html2text-clean-dl (p1 p2 p3 p4) + (html2text-delete-tags p1 p2 p3 p4) + (html2text-clean-dtdd p1 (- p3 (- p1 p2))) + ) + +(defun html2text-clean-center (p1 p2 p3 p4) + (html2text-delete-tags p1 p2 p3 p4) + (center-region p1 (- p3 (- p2 p1))) + ) + +(defun html2text-clean-bold (p1 p2 p3 p4) + (put-text-property p2 p3 'face 'bold) + (html2text-delete-tags p1 p2 p3 p4) + ) + +(defun html2text-clean-title (p1 p2 p3 p4) + (put-text-property p2 p3 'face 'bold) + (html2text-delete-tags p1 p2 p3 p4) + ) + +(defun html2text-clean-underline (p1 p2 p3 p4) + (put-text-property p2 p3 'face 'underline) + (html2text-delete-tags p1 p2 p3 p4) + ) + +(defun html2text-clean-italic (p1 p2 p3 p4) + (put-text-property p2 p3 'face 'italic) + (html2text-delete-tags p1 p2 p3 p4) + ) + +(defun html2text-clean-font (p1 p2 p3 p4) + (html2text-delete-tags p1 p2 p3 p4) + ) + +(defun html2text-clean-blockquote (p1 p2 p3 p4) + (html2text-delete-tags p1 p2 p3 p4) + ) + +(defun html2text-clean-anchor (p1 p2 p3 p4) + ;; If someone can explain how to make the URL clickable I will + ;; surely improve upon this. + (let* ((attr-list (html2text-get-attr p1 p2 "a")) + (href (html2text-attr-value attr-list "href"))) + (kill-region p1 p4) + (when href + (goto-char p1) + (insert (substring href 1 -1 )) + (put-text-property p1 (point) 'face 'bold)))) + +;; +;; +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; +;; + +(defun html2text-fix-paragraph (p1 p2) + (goto-char p1) + (let ((has-br-line) + (refill-start) + (refill-stop)) + (if (re-search-forward "
    $" p2 t) + (setq has-br-line t) + ) + (if has-br-line + (progn + (goto-char p1) + (if (re-search-forward ".+[^<][^b][^r][^>]$" p2 t) + (progn + (beginning-of-line) + (setq refill-start (point)) + (goto-char p2) + (re-search-backward ".+[^<][^b][^r][^>]$" refill-start t) + (next-line 1) + (end-of-line) + ;; refill-stop should ideally be adjusted to + ;; accomodate the "
    " strings which are removed + ;; between refill-start and refill-stop. Can simply + ;; be returned from my-replace-string + (setq refill-stop (+ (point) + (html2text-replace-string + "
    " "" + refill-start (point)))) + ;; (message "Point = %s refill-stop = %s" (point) refill-stop) + ;; (sleep-for 4) + (fill-region refill-start refill-stop) + ) + ) + ) + ) + ) + (html2text-replace-string "
    " "" p1 p2) + ) + +;; +;; This one is interactive ... +;; +(defun html2text-fix-paragraphs () + "This _tries_ to fix up the paragraphs - this is done in quite a ad-hook +fashion, quite close to pure guess-work. It does work in some cases though." + (interactive) + (html2text-buffer-head) + (replace-regexp "^
    $" "") + ;; Removing lonely
    on a single line, if they are left intact we + ;; dont have any paragraphs at all. + (html2text-buffer-head) + (while (< (point) (point-max)) + (let ((p1 (point))) + (forward-paragraph 1) + ;;(message "Kaller fix med p1=%s p2=%s " p1 (1- (point))) (sleep-for 5) + (html2text-fix-paragraph p1 (1- (point))) + (goto-char p1) + (if (< (point) (point-max)) + (forward-paragraph 1)) + ) + ) + ) + +;; +;;
    +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; +;; + +(defun html2text-remove-tags (tag-list) + "Removes the tags listed in the list \"html2text-remove-tag-list\". +See the documentation for that variable." + (interactive) + (dolist (tag tag-list) + (html2text-buffer-head) + (while (re-search-forward (format "\\(]*>\\)" tag) (point-max) t) + (let ((p1 (point))) + (search-backward "<") + (kill-region (point) p1) + ) + ) + ) + ) + +(defun html2text-format-tags () + "See the variable \"html2text-format-tag-list\" for documentation" + (interactive) + (dolist (tag-and-function html2text-format-tag-list) + (let ((tag (car tag-and-function)) + (function (cdr tag-and-function))) + (html2text-buffer-head) + (while (re-search-forward (format "\\(<%s\\( [^>]*\\)?>\\)" tag) + (point-max) t) + (let ((p1) + (p2 (point)) + (p3) (p4) + (attr (match-string 1))) + (search-backward "<" (point-min) t) + (setq p1 (point)) + (re-search-forward (format "" tag) (point-max) t) + (setq p4 (point)) + (search-backward "]*\\)?>\\)" tag) + (point-max) t) + (let ((p1) + (p2 (point))) + (search-backward "<" (point-min) t) + (setq p1 (point)) + (funcall function p1 p2) + ) + ) + ) + ) + ) + +;; +;; Main function +;; + +;;;###autoload +(defun html2text () + "Convert HTML to plain text in the current buffer." + (interactive) + (save-excursion + (let ((case-fold-search t) + (buffer-read-only)) + (html2text-remove-tags html2text-remove-tag-list) + (html2text-format-tags) + (html2text-remove-tags html2text-remove-tag-list2) + (html2text-substitute) + (html2text-format-single-elements) + (html2text-fix-paragraphs)))) + +;; +;; +;; + +;;; html2text.el ends here diff --git a/lisp/ietf-drums.el b/lisp/ietf-drums.el index e1b19a9..9c79e91 100644 --- a/lisp/ietf-drums.el +++ b/lisp/ietf-drums.el @@ -67,6 +67,11 @@ (modify-syntax-entry ?* " " table) (modify-syntax-entry ?\; " " table) (modify-syntax-entry ?\' " " table) + (if (featurep 'xemacs) + (let ((i 128)) + (while (< i 256) + (modify-syntax-entry i "w" table) + (setq i (1+ i))))) table)) (defun ietf-drums-token-to-list (token) @@ -216,7 +221,7 @@ ((eq c ?,) (setq address (condition-case nil - (ietf-drums-parse-address + (ietf-drums-parse-address (buffer-substring beg (point))) (error nil))) (if address (push address pairs)) @@ -226,7 +231,7 @@ (forward-char 1)))) (setq address (condition-case nil - (ietf-drums-parse-address + (ietf-drums-parse-address (buffer-substring beg (point))) (error nil))) (if address (push address pairs)) diff --git a/lisp/imap.el b/lisp/imap.el index 15894ff..082c83c 100644 --- a/lisp/imap.el +++ b/lisp/imap.el @@ -528,7 +528,7 @@ If ARGS, PROMPT is used as an argument to `format'." (not (string-match "failed" response)))) (setq done process) (if (memq (process-status process) '(open run)) - (imap-send-command-wait "LOGOUT")) + (imap-send-command "LOGOUT")) (delete-process process) nil))))) done)) @@ -588,7 +588,7 @@ If ARGS, PROMPT is used as an argument to `format'." (not (string-match "failed" response)))) (setq done process) (if (memq (process-status process) '(open run)) - (imap-send-command-wait "LOGOUT")) + (imap-send-command "LOGOUT")) (delete-process process) nil))))) done)) @@ -766,7 +766,7 @@ Returns t if login was successful, nil otherwise." (while (or (not user) (not passwd)) (setq user (or imap-username (read-from-minibuffer - (concat "IMAP username for " imap-server + (concat "IMAP username for " imap-server " (using stream `" (symbol-name imap-stream) "'): ") (or user imap-default-user)))) @@ -852,7 +852,7 @@ Returns t if login was successful, nil otherwise." t) (defun imap-anonymous-auth (buffer) - (message "imap: Loging in anonymously...") + (message "imap: Logging in anonymously...") (with-current-buffer buffer (imap-ok-p (imap-send-command-wait (concat "LOGIN anonymous \"" (concat (user-login-name) "@" @@ -957,15 +957,15 @@ necessery. If nil, the buffer name is generated." (imap-disable-multibyte) (buffer-disable-undo) (setq imap-server (or server imap-server)) - (setq imap-port imap-port) - (setq imap-auth imap-auth) + (setq imap-port (or port imap-port)) + (setq imap-auth (or auth imap-auth)) (message "imap: Reconnecting with stream `%s'..." stream) (if (null (let ((imap-stream stream)) (imap-open-1 (current-buffer)))) (progn (kill-buffer (current-buffer)) - (message - "imap: Reconnecting with stream `%s'...failed" + (message + "imap: Reconnecting with stream `%s'...failed" stream)) ;; We're done, kill the first connection (imap-close buffer) @@ -983,7 +983,7 @@ necessery. If nil, the buffer name is generated." (setq streams nil)))))) (when (imap-opened buffer) (setq imap-mailbox-data (make-vector imap-mailbox-prime 0))) - (when imap-stream + (when imap-stream buffer)))) (defun imap-opened (&optional buffer) @@ -1012,7 +1012,7 @@ password is remembered in the buffer." (if user (setq imap-username user)) (if passwd (setq imap-password passwd)) (if imap-auth - (and (funcall (nth 2 (assq imap-auth + (and (funcall (nth 2 (assq imap-auth imap-authenticator-alist)) buffer) (setq imap-state 'auth)) ;; Choose authenticator. @@ -1318,6 +1318,20 @@ returned, if ITEMS is a symbol only it's value is returned." items) (imap-mailbox-get items mailbox))))) +(defun imap-mailbox-status-asynch (mailbox items &optional buffer) + "Send status item request ITEM on MAILBOX to server in BUFFER. +ITEMS can be a symbol or a list of symbols, valid symbols are one of +the STATUS data items -- ie 'messages, 'recent, 'uidnext, 'uidvalidity +or 'unseen. The IMAP command tag is returned." + (with-current-buffer (or buffer (current-buffer)) + (imap-send-command (list "STATUS \"" + (imap-utf7-encode mailbox) + "\" " + (format "%s" + (if (listp items) + items + (list items))))))) + (defun imap-mailbox-acl-get (&optional mailbox buffer) "Get ACL on mailbox from server in BUFFER." (let ((mailbox (imap-utf7-encode mailbox))) @@ -1955,7 +1969,7 @@ Return nil if no complete line has arrived." ;; resp-cond-bye = "BYE" SP resp-text ;; ;; mailbox-data = "FLAGS" SP flag-list / -;; "LIST" SP mailbox-list / +;; "LIST" SP mailbox-list / ;; "LSUB" SP mailbox-list / ;; "SEARCH" *(SP nz-number) / ;; "STATUS" SP mailbox SP "(" @@ -2060,7 +2074,7 @@ Return nil if no complete line has arrived." ;; [flag-perm *(SP flag-perm)] ")" / ;; "READ-ONLY" / ;; "READ-WRITE" / -;; "TRYCREATE" / +;; "TRYCREATE" / ;; "UIDNEXT" SP nz-number / ;; "UIDVALIDITY" SP nz-number / ;; "UNSEEN" SP nz-number / @@ -2114,8 +2128,8 @@ Return nil if no complete line has arrived." (imap-forward) (cond ((search-forward "PERMANENTFLAGS " nil t) (imap-mailbox-put 'permanentflags (imap-parse-flag-list))) - ((search-forward "UIDNEXT " nil t) - (imap-mailbox-put 'uidnext (read (current-buffer)))) + ((search-forward "UIDNEXT \\([0-9]+\\)" nil t) + (imap-mailbox-put 'uidnext (match-string 1))) ((search-forward "UNSEEN " nil t) (imap-mailbox-put 'unseen (read (current-buffer)))) ((looking-at "UIDVALIDITY \\([0-9]+\\)") @@ -2288,7 +2302,9 @@ Return nil if no complete line has arrived." ((eq token 'RECENT) (imap-mailbox-put 'recent (read (current-buffer)) mailbox)) ((eq token 'UIDNEXT) - (imap-mailbox-put 'uidnext (read (current-buffer)) mailbox)) + (and (looking-at " \\([0-9]+\\)") + (imap-mailbox-put 'uidnext (match-string 1) mailbox) + (goto-char (match-end 1)))) ((eq token 'UIDVALIDITY) (and (looking-at " \\([0-9]+\\)") (imap-mailbox-put 'uidvalidity (match-string 1) mailbox) diff --git a/lisp/lpath.el b/lisp/lpath.el index 3879b1f..1bc8013 100644 --- a/lisp/lpath.el +++ b/lisp/lpath.el @@ -21,7 +21,9 @@ find-coding-systems-string image-size image-type-available-p insert-image image-type-from-file-header + make-symbolic-link make-temp-file message-xmas-redefine + mail-abbrev-in-expansion-header-p mail-aliases-setup mm-copy-tree mule-write-region-no-coding-system put-image ring-elements @@ -31,13 +33,15 @@ frames-on-display-list make-mode-line-mouse-map rmail-select-summary rmail-summary-exists rmail-update-summary - rmail-toggle-header + rmail-msg-is-pruned rmail-msg-restore-non-pruned-header sc-cite-regexp set-font-family set-font-size temp-directory string-as-multibyte tool-bar-add-item tool-bar-add-item-from-menu + unix-sync url-view-url vcard-pretty-print url-insert-file-contents w3-coding-system-for-mime-charset w3-prepare-buffer w3-region + w3m-charset-to-coding-system w3m-region widget-make-intangible x-defined-colors)) (maybe-bind '(adaptive-fill-first-line-regexp @@ -47,16 +51,20 @@ display-time-mail-function imap-password mail-mode-hook filladapt-mode mc-pgp-always-sign + gnus-message-group-art gpg-unabbrev-trust-alist nnoo-definition-alist - current-language-environment + current-language-environment language-info-alist url-current-callback-func url-be-asynchronous url-current-callback-data url-working-buffer url-current-mime-headers w3-meta-charset-content-type-regexp - rmail-enable-mime-composing - rmail-insert-mime-forwarded-message-function - w3-meta-content-type-charset-regexp)) + rmail-enable-mime-composing + rmail-insert-mime-forwarded-message-function + w3-meta-content-type-charset-regexp + w3m-cid-retrieve-function-alist w3m-current-buffer + w3m-meta-content-type-charset-regexp w3m-mode-map + url-package-version url-package-name)) (if (featurep 'xemacs) (progn @@ -82,7 +90,8 @@ url-retrieve w3-form-encode-xwfu window-at window-edges x-color-values x-popup-menu browse-url frame-char-height frame-char-width - url-generic-parse-url xml-parse-region)) + url-generic-parse-url xml-parse-region + make-network-process)) (maybe-bind '(buffer-display-table buffer-file-coding-system font-lock-defaults global-face-data gnus-article-x-face-too-ugly @@ -113,7 +122,7 @@ specifier-instance url-generic-parse-url valid-image-instantiator-format-p w3-do-setup window-pixel-height window-pixel-width - xml-parse-region))) + xml-parse-region make-network-process))) (require 'custom) diff --git a/lisp/mail-source.el b/lisp/mail-source.el index 982db42..73891cd 100644 --- a/lisp/mail-source.el +++ b/lisp/mail-source.el @@ -1,5 +1,5 @@ ;;; mail-source.el --- functions for fetching mail -;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; Keywords: news, mail @@ -291,6 +291,9 @@ Common keywords should be listed here.") (:path (or (getenv "MAIL") (expand-file-name (user-login-name) rmail-spool-directory)))) (directory + (:prescript) + (:prescript-delay) + (:postscript) (:path) (:suffix ".spool") (:predicate identity)) @@ -378,7 +381,7 @@ the `mail-source-keyword-map' variable." ,@body)) (put 'mail-source-bind 'lisp-indent-function 1) -(put 'mail-source-bind 'edebug-form-spec '(form body)) +(put 'mail-source-bind 'edebug-form-spec '(sexp body)) (defun mail-source-set-1 (source) (let* ((type (pop source)) @@ -421,7 +424,7 @@ See `mail-source-bind'." ,@body)) (put 'mail-source-bind-common 'lisp-indent-function 1) -(put 'mail-source-bind-common 'edebug-form-spec '(form body)) +(put 'mail-source-bind-common 'edebug-form-spec '(sexp body)) (defun mail-source-value (value) "Return the value of VALUE." @@ -461,17 +464,21 @@ Return the number of files that were found." (funcall function source callback) (error (unless (yes-or-no-p - (format "Mail source error (%s). Continue? " err)) + (format "Mail source error (%s). Continue? " + (cadr err))) (error "Cannot get new mail")) 0))))))))) -(defun mail-source-make-complex-temp-name (prefix) - (let ((newname (make-temp-name prefix)) - (newprefix prefix)) - (while (file-exists-p newname) - (setq newprefix (concat newprefix "x")) - (setq newname (make-temp-name newprefix))) - newname)) +(eval-and-compile + (if (fboundp 'make-temp-file) + (defalias 'mail-source-make-complex-temp-name 'make-temp-file) + (defun mail-source-make-complex-temp-name (prefix) + (let ((newname (make-temp-name prefix)) + (newprefix prefix)) + (while (file-exists-p newname) + (setq newprefix (concat newprefix "x")) + (setq newname (make-temp-name newprefix))) + newname)))) (defun mail-source-callback (callback info) "Call CALLBACK on the mail file, and then remove the mail file. @@ -590,7 +597,7 @@ If ARGS, PROMPT is used as an argument to `format'." (defun mail-source-fetch-with-program (program) (zerop (call-process shell-file-name nil nil nil - shell-command-switch program))) + shell-command-switch program))) (defun mail-source-run-script (script spec &optional delay) (when script @@ -630,6 +637,9 @@ If ARGS, PROMPT is used as an argument to `format'." (defun mail-source-fetch-directory (source callback) "Fetcher for directory sources." (mail-source-bind (directory source) + (mail-source-run-script + prescript (format-spec-make ?t path) + prescript-delay) (let ((found 0) (mail-source-string (format "directory:%s" path))) (dolist (file (directory-files @@ -638,6 +648,8 @@ If ARGS, PROMPT is used as an argument to `format'." (funcall predicate file) (mail-source-movemail file mail-source-crash-box)) (incf found (mail-source-callback callback file)))) + (mail-source-run-script + postscript (format-spec-make ?t path)) found))) (defun mail-source-fetch-pop (source callback) @@ -854,13 +866,13 @@ This only works when `display-time' is enabled." (with-temp-file mail-source-crash-box (insert-file-contents file) (goto-char (point-min)) -;;; ;; Unix mail format -;;; (unless (looking-at "\n*From ") -;;; (insert "From maildir " -;;; (current-time-string) "\n")) -;;; (while (re-search-forward "^From " nil t) -;;; (replace-match ">From ")) -;;; (goto-char (point-max)) +;;; ;; Unix mail format +;;; (unless (looking-at "\n*From ") +;;; (insert "From maildir " +;;; (current-time-string) "\n")) +;;; (while (re-search-forward "^From " nil t) +;;; (replace-match ">From ")) +;;; (goto-char (point-max)) ;;; (insert "\n\n") ;; MMDF mail format (insert "\001\001\001\001\n")) diff --git a/lisp/mailcap.el b/lisp/mailcap.el index 52e5c9a..89fd7dc 100644 --- a/lisp/mailcap.el +++ b/lisp/mailcap.el @@ -1,5 +1,5 @@ ;;; mailcap.el --- MIME media types configuration -;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: William M. Perry ;; Lars Magne Ingebrigtsen @@ -87,6 +87,9 @@ ("emacs-lisp" (viewer . mailcap-maybe-eval) (type . "application/emacs-lisp")) + ("x-emacs-lisp" + (viewer . mailcap-maybe-eval) + (type . "application/x-emacs-lisp")) ("x-tar" (viewer . mailcap-save-binary-file) (non-viewer . t) @@ -223,7 +226,7 @@ (viewer . fundamental-mode) (type . "text/plain")) ("enriched" - (viewer . enriched-decode-region) + (viewer . enriched-decode) (test . (fboundp 'enriched-decode)) (type . "text/enriched")) ("html" @@ -640,18 +643,18 @@ to supply to the test." (setq mailcap-mime-data (cons (cons major (list (cons minor info))) mailcap-mime-data)) - (let ((cur-minor (assoc minor old-major))) - (cond - ((or (null cur-minor) ; New minor area, or - (assq 'test info)) ; Has a test, insert at beginning - (setcdr old-major (cons (cons minor info) (cdr old-major)))) - ((and (not (assq 'test info)) ; No test info, replace completely - (not (assq 'test cur-minor)) + (let ((cur-minor (assoc minor old-major))) + (cond + ((or (null cur-minor) ; New minor area, or + (assq 'test info)) ; Has a test, insert at beginning + (setcdr old-major (cons (cons minor info) (cdr old-major)))) + ((and (not (assq 'test info)) ; No test info, replace completely + (not (assq 'test cur-minor)) (equal (assq 'viewer info) ; Keep alternative viewer (assq 'viewer cur-minor))) - (setcdr cur-minor info)) - (t - (setcdr old-major (cons (cons minor info) (cdr old-major)))))) + (setcdr cur-minor info)) + (t + (setcdr old-major (cons (cons minor info) (cdr old-major)))))) ))) (defun mailcap-add (type viewer &optional test) diff --git a/lisp/message-utils.el b/lisp/message-utils.el new file mode 100644 index 0000000..8b8d455 --- /dev/null +++ b/lisp/message-utils.el @@ -0,0 +1,375 @@ +;;; message-utils.el -- utils for message-mode + +;; Copyright (C) 2002 Free Software Foundation, Inc. + +;; Author: Holger Schauer +;; Keywords: utils message + +;; 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 of the License, or +;; (at your option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; 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: + +;; This file contains some small additions to message mode: +;; * inserting files in a message and explicit marking it +;; as something somebody else has created, +;; * change Subject: header and add (was: ) +;; * strip (was: ) from Subject: headers +;; * add a X-No-Archieve: Yes header and a note in the body +;; * a function for cross-post and followup-to messages +;; * replace To: header with contents of Cc: or Bcc: header. +;; + +;; This file is adopt from the link below when the revision is 0.8. +;; http://www.coling.uni-freiburg.de/~schauer/resources/emacs/message-utils.el.gz + +;;; Installation: (TODO: merge into message.el) + +;; .. is easy as in most cases. Add +;; (autoload 'message-mark-inserted-region "message-utils" nil t) +;; (autoload 'message-mark-insert-file "message-utils" nil t) +;; (autoload 'message-strip-subject-was "message-utils" nil t) +;; (autoload 'message-change-subject "message-utils" nil t) +;; (autoload 'message-xpost-fup2 "message-utils" nil t) +;; (autoload 'message-add-archive-header "message-utils" nil t) +;; (autoload 'message-reduce-to-to-cc "message-utils" nil t) +;; as well as some keybindings like +;; (define-key message-mode-map '[(control c) m] 'message-mark-inserted-region) +;; (define-key message-mode-map '[(control c) f] 'message-mark-insert-file) +;; (define-key message-mode-map '[(control c) x] 'message-xpost-fup2) +;; (define-key message-mode-map '[(control c) s] 'message-change-subject) +;; (define-key message-mode-map '[(control c) a] 'message-add-archive-header) +;; (define-key message-mode-map '[(control c) t] 'message-reduce-to-to-cc) +;; (add-hook 'message-header-setup-hook 'message-strip-subject-was) +;; to your .gnus or to your .emacs. +;; You might also want to add something along the following lines: +;; (defun message-utils-setup () +;; "Add menu-entries for message-utils." +;; (easy-menu-add-item nil '("Message") +;; ["Insert Region Marked" message-mark-inserted-region t] "Spellcheck") +;; (easy-menu-add-item nil '("Message") +;; ["Insert File Marked" message-mark-insert-file t] "Spellcheck") +;; (easy-menu-add-item nil '("Field") +;; ["Crosspost / Followup" message-xpost-fup2 t] "----") +;; (easy-menu-add-item nil '("Field") +;; ["New Subject" message-change-subject t] "----") +;; (easy-menu-add-item nil '("Field") +;; ["Reduce To: to Cc:" message-reduce-to-to-cc t] "----") +;; (easy-menu-add-item nil '("Field") +;; [ "X-No-Archive:" message-add-archive-header t ])) +;; (add-hook 'message-mode-hook 'message-utils-setup) + +;;; Code: + +(require 'message) + +;;; ************** +;;; Inserting and marking ... + +; We try to hook the vars into the message customize group + +(defcustom message-begin-inserted-text-mark +"--8<------------------------schnipp------------------------->8---\n" +"How to mark the beginning of some inserted text." + :type 'string + :group 'message-various) + +(defcustom message-end-inserted-text-mark +"--8<------------------------schnapp------------------------->8---\n" +"How to mark the end of some inserted text." + :type 'string + :group 'message-various) + +;;;###autoload +(defun message-mark-inserted-region (beg end) + "Mark some region in the current article with enclosing tags. +See `message-begin-inserted-text-mark' and `message-end-inserted-text-mark'." + (interactive "r") + (save-excursion + ; add to the end of the region first, otherwise end would be invalid + (goto-char end) + (insert message-end-inserted-text-mark) + (goto-char beg) + (insert message-begin-inserted-text-mark))) + +;;;###autoload +(defun message-mark-insert-file (file) + "Inserts FILE at point, marking it with enclosing tags. +See `message-begin-inserted-text-mark' and `message-end-inserted-text-mark'." + (interactive "fFile to insert: ") + ;; reverse insertion to get correct result. + (let ((p (point))) + (insert message-end-inserted-text-mark) + (goto-char p) + (insert-file-contents file) + (goto-char p) + (insert message-begin-inserted-text-mark))) + +;;; ************** +;;; Subject mangling + +(defcustom message-subject-was-regexp + "[ \t]*\\((*[Ww][Aa][SsRr]:[ \t]*.*)\\)" + "*Regexp matching \"(was: )\" in the subject line." + :group 'message-various + :type 'regexp) + +;;;###autoload +(defun message-strip-subject-was () + "Remove trailing \"(Was: )\" from subject lines." + (message-narrow-to-head) + (let* ((subject (message-fetch-field "Subject")) + (pos)) + (cond (subject + (setq pos (or (string-match message-subject-was-regexp subject) 0)) + (cond ((> pos 0) + (message-goto-subject) + (message-delete-line) + (insert (concat "Subject: " + (substring subject 0 pos) "\n"))))))) + (widen)) + +;;; Suggested by Jonas Steverud @ www.dtek.chalmers.se/~d4jonas/ +;;;###autoload +(defun message-change-subject (new-subject) + "Ask for new Subject: header, append (was: )." + (interactive + (list + (read-from-minibuffer "New subject: "))) + (cond ((and (not (or (null new-subject) ; new subject not empty + (zerop (string-width new-subject)) + (string-match "^[ \t]*$" new-subject)))) + (save-excursion + (let ((old-subject (message-fetch-field "Subject"))) + (cond ((not (string-match + (concat "^[ \t]*" + (regexp-quote new-subject) + " \t]*$") + old-subject)) ; yes, it really is a new subject + ;; delete eventual Re: prefix + (setq old-subject + (message-strip-subject-re old-subject)) + (message-goto-subject) + (message-delete-line) + (insert (concat "Subject: " + new-subject + " (was: " + old-subject ")\n"))))))))) + + +;;; ************** +;;; X-Archive-Header: No + +(defcustom message-archive-header + "X-No-Archive: Yes\n" + "Header to insert when you don't want your article to be archived by deja.com." + :type 'string + :group 'message-various) + +(defcustom message-archive-note + "X-No-Archive: Yes - save http://deja.com/" + "Note to insert why you wouldn't want this posting archived." + :type 'string + :group 'message-various) + +(defun message-add-archive-header () + "Insert \"X-No-Archive: Yes\" in the header and a note in the body. +When called with a prefix argument, ask for a text to insert." + (interactive) + (if current-prefix-arg + (setq message-archive-note + (read-from-minibuffer "Reason for No-Archive: " + (cons message-archive-note 0)))) + (save-excursion + (insert message-archive-note) + (newline) + (message-add-header message-archive-header) + (message-sort-headers))) + +;;; ************** +;;; Crossposts and Followups + +; inspired by JoH-followup-to by Jochem Huhman +; new suggestions by R. Weikusat + +(defvar message-xpost-old-target nil + "Old target for cross-posts or follow-ups.") +(make-variable-buffer-local 'message-xpost-old-target) + +(defcustom message-xpost-default t + "When non-nil `mesage-xpost-fup2' will normally perform a crosspost. +If nil, `message-xpost-fup2' will only do a followup. Note that you +can explicitly override this setting by calling `message-xpost-fup2' +with a prefix." + :type 'boolean + :group 'message-various) + +(defun message-xpost-fup2-header (target-group) + "Mangles FollowUp-To and Newsgroups header to point to TARGET-GROUP. +With prefix-argument just set Follow-Up, don't cross-post." + (interactive + (list ; Completion based on Gnus + (completing-read "Follwup To: " + (if (boundp 'gnus-newsrc-alist) + gnus-newsrc-alist) + nil nil '("poster" . 0) + (if (boundp 'gnus-group-history) + 'gnus-group-history)))) + (message-remove-header "Follow[Uu]p-[Tt]o" t) + (message-goto-newsgroups) + (beginning-of-line) + ;; if we already did a crosspost before, kill old target + (if (and message-xpost-old-target + (re-search-forward + (regexp-quote (concat "," message-xpost-old-target)) + nil t)) + (replace-match "")) + ;; unless (followup is to poster or user explicitly asked not + ;; to cross-post, or target-group is already in Newsgroups) + ;; add target-group to Newsgroups line. + (cond ((and (or (and message-xpost-default (not current-prefix-arg)) ; def: xpost, req:no + (and (not message-xpost-default) current-prefix-arg)) ; def: no-xpost, req:yes + (not (string-match "poster" target-group)) + (not (string-match (regexp-quote target-group) + (message-fetch-field "Newsgroups")))) + (end-of-line) + (insert-string (concat "," target-group)))) + (end-of-line) ; ensure Followup: comes after Newsgroups: + ;; unless new followup would be identical to Newsgroups line + ;; make a new Followup-To line + (if (not (string-match (concat "^[ \t]*" + target-group + "[ \t]*$") + (message-fetch-field "Newsgroups"))) + (insert (concat "\nFollowup-To: " target-group))) + (setq message-xpost-old-target target-group)) + + +(defcustom message-xpost-note + "Crosspost & Followup-To: " + "Note to insert before signature to notify of xpost and follow-up." + :type 'string + :group 'message-various) + +(defcustom message-fup2-note + "Followup-To: " + "Note to insert before signature to notify of follow-up only." + :type 'string + :group 'message-various) + +(defun message-xpost-insert-note (target-group xpost in-old old-groups) + "Insert a in message body note about a set Followup or Crosspost. +If there have been previous notes, delete them. TARGET-GROUP specifies the +group to Followup-To. When XPOST is t, insert note about +crossposting. IN-OLD specifies whether TARGET-GROUP is a member of +OLD-GROUPS. OLD-GROUPS lists the old-groups the posting would have +been made to before the user asked for a Crosspost." + ;; start scanning body for previous uses + (message-goto-signature) + (let ((head (re-search-backward + (concat "^" mail-header-separator) + nil t))) ; just search in body + (message-goto-signature) + (while (re-search-backward + (concat "^" (regexp-quote message-xpost-note) ".*") + head t) + (message-delete-line)) + (message-goto-signature) + (while (re-search-backward + (concat "^" (regexp-quote message-fup2-note) ".*") + head t) + (message-delete-line)) + ;; insert new note + (message-goto-signature) + (previous-line 2) + (open-line 1) + (if (or in-old + (not xpost) + (string-match "^[ \t]*poster[ \t]*$" target-group)) + (insert (concat message-fup2-note target-group "\n")) + (insert (concat message-xpost-note target-group "\n"))))) + +(defcustom message-xpost-note-function + 'message-xpost-insert-note + "Function to use to insert note about Crosspost or Followup-To. +The function will be called with four arguments. The function should not +only insert a note, but also ensure old notes are deleted. See the +documentation for `message-xpost-insert-note'. " + :type 'function + :group 'message-various) + +;;;###autoload +(defun message-xpost-fup2 (target-group) + "Crossposts message and sets Followup-To to TARGET-GROUP. +With prefix-argument just set Follow-Up, don't cross-post." + (interactive + (list ; Completion based on Gnus + (completing-read "Follwup To: " + (if (boundp 'gnus-newsrc-alist) + gnus-newsrc-alist) + nil nil '("poster" . 0) + (if (boundp 'gnus-group-history) + 'gnus-group-history)))) + (cond ((not (or (null target-group) ; new subject not empty + (zerop (string-width target-group)) + (string-match "^[ \t]*$" target-group))) + (save-excursion + (let* ((old-groups (message-fetch-field "Newsgroups")) + (in-old (string-match + (regexp-quote target-group) old-groups))) + ;; check whether target exactly matches old Newsgroups + (cond ((or (not in-old) + (not (string-match + (concat "^[ \t]*" + (regexp-quote target-group) + "[ \t]*$") + old-groups))) + ;; yes, Newsgroups line must change + (message-xpost-fup2-header target-group) + ;; insert note whether we do xpost or fup2 + (funcall message-xpost-note-function + target-group + (if (or (and message-xpost-default (not current-prefix-arg)) + (and (not message-xpost-default) current-prefix-arg)) + t) + in-old old-groups)))))))) + + +;;; ************** +;;; Reduce To: to Cc: or Bcc: header + +(defun message-reduce-to-to-cc () + "Replace contents of To: header with contents of Cc: or Bcc: header." + (interactive) + (let ((cc-content (message-fetch-field "cc")) + (bcc nil)) + (if (and (not cc-content) + (setq cc-content (message-fetch-field "bcc"))) + (setq bcc t)) + (cond (cc-content + (save-excursion + (message-goto-to) + (message-delete-line) + (insert (concat "To: " cc-content "\n")) + (message-remove-header (if bcc + "bcc" + "cc"))))))) + +;;; provide ourself +(provide 'message-utils) + +;;; message-utils.el ends here diff --git a/lisp/message.el b/lisp/message.el index 2365e6d..d6dc3c9 100644 --- a/lisp/message.el +++ b/lisp/message.el @@ -36,9 +36,12 @@ (require 'canlock) (require 'mailheader) (require 'nnheader) -;; This is apparently necessary even though things are autoloaded: +;; This is apparently necessary even though things are autoloaded. +;; Because we dynamically bind mail-abbrev-mode-regexp, we'd better +;; require mailabbrev here. (if (featurep 'xemacs) - (require 'mail-abbrevs)) + (require 'mail-abbrevs) + (require 'mailabbrev)) (require 'mail-parse) (require 'mml) (require 'rfc822) @@ -165,7 +168,14 @@ Otherwise, most addresses look like `angles', but they look like (const default)) :group 'message-headers) -(defcustom message-syntax-checks nil +(defcustom message-insert-canlock t + "Whether to insert a Cancel-Lock header in news postings." + :version "21.3" + :group 'message-headers + :type 'boolean) + +(defcustom message-syntax-checks + (if message-insert-canlock '((sender . disabled)) nil) ;; Guess this one shouldn't be easy to customize... "*Controls what syntax checks should not be performed on outgoing posts. To disable checking of long signatures, for instance, add @@ -231,7 +241,8 @@ any confusion." :group 'message-interface :type 'regexp) -(defcustom message-subject-re-regexp "^[ \t]*\\([Rr][Ee]:[ \t]*\\)*[ \t]*" +(defcustom message-subject-re-regexp + "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*" "*Regexp matching \"Re: \" in the subject line." :group 'message-various :type 'regexp) @@ -350,7 +361,20 @@ The provided functions are: (if (string-match "[[:digit:]]" "1") ;; support POSIX? "\\([ \t]*[-_.[:word:]]+>+\\|[ \t]*[]>»|:}+]\\)+" ;; ?-, ?_ or ?. MUST NOT be in syntax entry w. - "\\([ \t]*\\(\\w\\|[-_.]\\)+>+\\|[ \t]*[]>»|:}+]\\)+") + (let ((old-table (syntax-table)) + non-word-constituents) + (set-syntax-table text-mode-syntax-table) + (setq non-word-constituents + (concat + (if (string-match "\\w" "-") "" "-") + (if (string-match "\\w" "_") "" "_") + (if (string-match "\\w" ".") "" "."))) + (set-syntax-table old-table) + (if (equal non-word-constituents "") + "\\([ \t]*\\(\\w\\)+>+\\|[ \t]*[]>»|:}+]\\)+" + (concat "\\([ \t]*\\(\\w\\|[" + non-word-constituents + "]\\)+>+\\|[ \t]*[]>»|:}+]\\)+")))) "*Regexp matching the longest possible citation prefix on a line." :group 'message-insertion :type 'regexp) @@ -489,13 +513,15 @@ Doing so would be even more evil than leaving it out." (defcustom message-qmail-inject-args nil "Arguments passed to qmail-inject programs. -This should be a list of strings, one string for each argument. +This should be a list of strings, one string for each argument. It +may also be a function. For e.g., if you wish to set the envelope sender address so that bounces go to the right place or to deal with listserv's usage of that address, you might set this variable to '(\"-f\" \"you@some.where\")." :group 'message-sending - :type '(repeat string)) + :type '(choice (function) + (repeat string))) (defvar message-cater-to-broken-inn t "Non-nil means Gnus should not fold the `References' header. @@ -625,8 +651,6 @@ point and mark around the citation text as modified." :type 'function :group 'message-insertion) -(defvar message-abbrevs-loaded nil) - ;;;###autoload (defcustom message-signature t "*String to be inserted at the end of the message buffer. @@ -668,7 +692,10 @@ If stringp, use this; if non-nil, use no host name (user name only)." (sexp :tag "none" :format "%t" t))) (defvar message-reply-buffer nil) -(defvar message-reply-headers nil) +(defvar message-reply-headers nil + "The headers of the current replied article. +It is a vector of the following headers: +\[number subject from date id references chars lines xref extra].") (defvar message-newsreader nil) (defvar message-mailer nil) (defvar message-sent-message-via nil) @@ -772,14 +799,6 @@ If nil, Message won't auto-save." :group 'message-buffers :type '(choice directory (const :tag "Don't auto-save" nil))) -(defcustom message-buffer-naming-style 'unique - "*The way new message buffers are named. -Valid valued are `unique' and `unsent'." - :version "21.1" - :group 'message-buffers - :type '(choice (const :tag "unique" unique) - (const :tag "unsent" unsent))) - (defcustom message-default-charset (and (not (mm-multibyte-p)) 'iso-8859-1) "Default charset used in non-MULE Emacsen. @@ -805,8 +824,9 @@ feet of Good Net-Keeping Seal of Approval. The following are foot candidates: `empty-article' Allow you to post an empty article; `quoted-text-only' Allow you to post quoted text only; -`multiple-copies' Allow you to post multiple copies.") -;; `cancel-messages' Allow you to cancel or supersede others' messages. +`multiple-copies' Allow you to post multiple copies; +`cancel-messages' Allow you to cancel or supersede messages from + your other email addresses.") (defsubst message-gnksa-enable-p (feature) (or (not (listp message-shoot-gnksa-feet)) @@ -970,7 +990,7 @@ candidates: nil) (,(concat "^\\(" message-cite-prefix-regexp "\\).*") (0 'message-cited-text-face)) - ("<#/?\\(multipart\\|part\\|external\\|mml\\).*>" + ("<#/?\\(multipart\\|part\\|external\\|mml\\|secure\\)[^>]*>" (0 'message-mml-face)))) "Additional expressions to highlight in Message mode.") @@ -1031,6 +1051,19 @@ The first matched address (not primary one) is used in the From field." :type '(choice (const :tag "Always use primary" nil) regexp)) +(defcustom message-hierarchical-addresses nil + "A list of hierarchical mail address definitions. + +Inside each entry, the first address is the \"top\" address, and +subsequent addresses are subaddresses; this is used to indicate that +mail sent to the first address will automatically be delivered to the +subaddresses. So if the first address appears in the recipient list +for a message, the subaddresses will be removed (if present) before +the mail is sent. All addresses in this structure should be +downcased." + :group 'message-headers + :type '(repeat (repeat string))) + (defcustom message-mail-user-agent nil "Like `mail-user-agent'. Except if it is nil, use Gnus native MUA; if it is t, use @@ -1058,11 +1091,7 @@ If this variable is non-nil, pose the question \"Reply to all recipients?\" before a wide reply to multiple recipients. If the user answers yes, reply to all recipients as usual. If the user answers no, only reply back to the author." - :group 'message-headers - :type 'boolean) - -(defcustom message-insert-canlock t - "Whether to insert a Cancel-Lock header in news postings." + :version "21.3" :group 'message-headers :type 'boolean) @@ -1100,7 +1129,7 @@ no, only reply back to the author." ;; can be removed, e.g. ;; From: joe@y.z (Joe K ;; User) - ;; can yield `From joe@y.z (Joe K Fri Mar 22 08:11:15 1996', and + ;; can yield `From joe@y.z (Joe K Fri Mar 22 08:11:15 1996', and ;; From: Joe User ;; ;; can yield `From Joe User Fri Mar 22 08:11:15 1996'. @@ -1182,7 +1211,6 @@ no, only reply back to the author." (autoload 'gnus-point-at-bol "gnus-util") (autoload 'gnus-output-to-rmail "gnus-util") (autoload 'gnus-output-to-mail "gnus-util") - (autoload 'mail-abbrev-in-expansion-header-p "mailabbrev") (autoload 'nndraft-request-associate-buffer "nndraft") (autoload 'nndraft-request-expire-articles "nndraft") (autoload 'gnus-open-server "gnus-int") @@ -1529,11 +1557,13 @@ Point is left at the beginning of the narrowed-to region." (define-key message-mode-map "\C-c\C-f\C-k" 'message-goto-keywords) (define-key message-mode-map "\C-c\C-f\C-u" 'message-goto-summary) (define-key message-mode-map "\C-c\C-f\C-i" 'message-insert-or-toggle-importance) + (define-key message-mode-map "\C-c\C-f\C-a" 'message-gen-unsubscribed-mft) (define-key message-mode-map "\C-c\C-b" 'message-goto-body) (define-key message-mode-map "\C-c\C-i" 'message-goto-signature) (define-key message-mode-map "\C-c\C-t" 'message-insert-to) (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups) + (define-key message-mode-map "\C-c\C-l" 'message-to-list-only) (define-key message-mode-map "\C-c\C-u" 'message-insert-or-toggle-importance) (define-key message-mode-map "\C-c\M-n" 'message-insert-disposition-notification-to) @@ -1560,7 +1590,7 @@ Point is left at the beginning of the narrowed-to region." ;;(define-key message-mode-map "\M-q" 'message-fill-paragraph) (define-key message-mode-map "\C-c\C-a" 'mml-attach-file) - + (define-key message-mode-map "\C-a" 'message-beginning-of-line) (define-key message-mode-map "\t" 'message-tab) (define-key message-mode-map "\M-;" 'comment-region)) @@ -1585,7 +1615,7 @@ Point is left at the beginning of the narrowed-to region." ["Flag As Unimportant" message-insert-importance-low ,@(if (featurep 'xemacs) '(t) '(:help "Mark this message as unimportant"))] - ["Request Receipt" + ["Request Receipt" message-insert-disposition-notification-to ,@(if (featurep 'xemacs) '(t) '(:help "Request a Disposition Notification of this article"))] @@ -1636,7 +1666,7 @@ Point is left at the beginning of the narrowed-to region." ;; ;; We use `after-change-functions' to keep special text properties ;; that interfer with the normal function of message mode out of the -;; buffer. +;; buffer. (defcustom message-strip-special-text-properties t "Strip special properties from the message buffer. @@ -1650,13 +1680,13 @@ message composition doesn't break too bad." :group 'message-various :type 'boolean) -(defconst message-forbidden-properties +(defconst message-forbidden-properties ;; No reason this should be clutter up customize. We make it a ;; property list (rather than a list of property symbols), to be ;; directly useful for `remove-text-properties'. - '(field nil read-only nil intangible nil invisible nil + '(field nil read-only nil intangible nil invisible nil mouse-face nil modification-hooks nil insert-in-front-hooks nil - insert-behind-hooks nil point-entered nil point-left nil) + insert-behind-hooks nil point-entered nil point-left nil) ;; Other special properties: ;; category, face, display: probably doesn't do any harm. ;; fontified: is used by font-lock. @@ -1699,10 +1729,12 @@ C-c C-f move to a header field (and create it if there isn't): C-c C-f C-w move to Fcc C-c C-f C-r move to Reply-To C-c C-f C-u move to Summary C-c C-f C-n move to Newsgroups C-c C-f C-k move to Keywords C-c C-f C-d move to Distribution + C-c C-f C-o move to From (\"Originator\") C-c C-f C-f move to Followup-To C-c C-f C-m move to Mail-Followup-To C-c C-f C-i cycle through Importance values C-c C-t `message-insert-to' (add a To header to a news followup) +C-c C-l `message-to-list-only' (removes all but list address in to/cc) C-c C-n `message-insert-newsgroups' (add a Newsgroup header to a news reply) C-c C-b `message-goto-body' (move to beginning of message text). C-c C-i `message-goto-signature' (move to the beginning of the signature). @@ -1717,6 +1749,7 @@ C-c C-a `mml-attach-file' (attach a file as MIME). C-c C-u `message-insert-or-toggle-importance' (insert or cycle importance). C-c M-n `message-insert-disposition-notification-to' (request receipt). M-RET `message-newline-and-reformat' (break the line and reformat)." + (setq local-abbrev-table text-mode-abbrev-table) (set (make-local-variable 'message-reply-buffer) nil) (make-local-variable 'message-send-actions) (make-local-variable 'message-exit-actions) @@ -1751,18 +1784,22 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (easy-menu-add message-mode-menu message-mode-map) (easy-menu-add message-mode-field-menu message-mode-map) ;; make-local-hook is harmless though obsolete in Emacs 21. - ;; Emacs 20 and XEmacs need make-local-hook. + ;; Emacs 20 and XEmacs need make-local-hook. (make-local-hook 'after-change-functions) ;; Mmmm... Forbidden properties... - (add-hook 'after-change-functions 'message-strip-forbidden-properties + (add-hook 'after-change-functions 'message-strip-forbidden-properties nil 'local) ;; Allow mail alias things. (when (eq message-mail-alias-type 'abbrev) (if (fboundp 'mail-abbrevs-setup) (mail-abbrevs-setup) (mail-aliases-setup))) - (message-set-auto-save-file-name) - (mm-enable-multibyte) + (unless buffer-file-name + (message-set-auto-save-file-name)) + (unless (buffer-base-buffer) + ;; Don't enable multibyte on an indirect buffer. Maybe enabling + ;; multibyte is not necessary at all. -- zsh + (mm-enable-multibyte)) (set (make-local-variable 'indent-tabs-mode) nil) ;No tabs for indentation. (mml-mode)) @@ -1908,6 +1945,26 @@ return nil." (goto-char (point-max)) nil)) +(defun message-gen-unsubscribed-mft (&optional include-cc) + "Insert a reasonable MFT header in a post to an unsubscribed list. +When making original posts to a mailing list you are not subscribed to, +you have to type in a MFT header by hand. The contents, usually, are +the addresses of the list and your own address. This function inserts +such a header automatically. It fetches the contents of the To: header +in the current mail buffer, and appends the current user-mail-address. + +If the optional argument `include-cc' is non-nil, the addresses in the +Cc: header are also put into the MFT." + + (interactive "P") + (message-remove-header "Mail-Followup-To") + (let* ((cc (and include-cc (message-fetch-field "Cc"))) + (tos (if cc + (concat (message-fetch-field "To") "," cc) + (message-fetch-field "To")))) + (message-goto-mail-followup-to) + (insert (concat tos ", " user-mail-address)))) + (defun message-insert-to (&optional force) @@ -2335,8 +2392,8 @@ However, if `message-yank-prefix' is non-nil, insert that prefix on each line." (while (< (point) (mark t)) (if (or (looking-at ">") (looking-at "^$")) (insert message-yank-cited-prefix) - (insert message-yank-prefix)) - (forward-line 1)))) + (insert message-yank-prefix)) + (forward-line 1)))) (goto-char start))) (defun message-yank-original (&optional arg) @@ -2511,7 +2568,8 @@ The text will also be indented the normal way." t))) (defun message-dont-send () - "Don't send the message you have been editing." + "Don't send the message you have been editing. +Instead, just auto-save the buffer and then bury it." (interactive) (set-buffer-modified-p t) (save-buffer) @@ -2662,14 +2720,61 @@ It should typically alter the sending method in some way or other." '(invisible nil highlight t))) (unless (yes-or-no-p "Invisible text found and made visible; continue posting? ") - (error "Invisible text found and made visible")))))) + (error "Invisible text found and made visible"))))) + (message-check 'illegible-text + (let (found choice) + (message-goto-body) + (skip-chars-forward mm-7bit-chars) + (while (not (eobp)) + (when (let ((char (char-after))) + (or (< (mm-char-int char) 128) + (and (mm-multibyte-p) + (memq (char-charset char) + '(eight-bit-control eight-bit-graphic + control-1))))) + (add-text-properties (point) (1+ (point)) '(highlight t)) + (setq found t)) + (forward-char) + (skip-chars-forward mm-7bit-chars)) + (when found + (setq choice + (gnus-multiple-choice + "Illegible text found. Continue posting? " + '((?d "Remove and continue posting") + (?r "Replace with dots and continue posting") + (?i "Ignore and continue posting") + (?e "Continue editing")))) + (if (eq choice ?e) + (error "Illegible text found")) + (message-goto-body) + (skip-chars-forward mm-7bit-chars) + (while (not (eobp)) + (when (let ((char (char-after))) + (or (< (mm-char-int char) 128) + (and (mm-multibyte-p) + (memq (char-charset char) + '(eight-bit-control eight-bit-graphic + control-1))))) + (if (eq choice ?i) + (remove-text-properties (point) (1+ (point)) '(highlight t)) + (delete-char 1) + (if (eq choice ?r) + (insert ".")))) + (forward-char) + (skip-chars-forward mm-7bit-chars)))))) (defun message-add-action (action &rest types) "Add ACTION to be performed when doing an exit of type TYPES." + (while types + (add-to-list (intern (format "message-%s-actions" (pop types))) + action))) + +(defun message-delete-action (action &rest types) + "Delete ACTION from lists of actions performed when doing an exit of type TYPES." (let (var) (while types (set (setq var (intern (format "message-%s-actions" (pop types)))) - (nconc (symbol-value var) (list action)))))) + (delq action (symbol-value var)))))) (defun message-do-actions (actions) "Perform all actions in ACTIONS." @@ -2828,7 +2933,27 @@ It should typically alter the sending method in some way or other." (message-insert-courtesy-copy)) (if (or (not message-send-mail-partially-limit) (< (point-max) message-send-mail-partially-limit) - (not (y-or-n-p "Message exceeds message-send-mail-partially-limit, send in parts? "))) + (not (message-y-or-n-p + "The message size is too large, split? " + t + "\ +The message size, " (/ (point-max) 1000) "KB, is too large. + +Some mail gateways (MTA's) bounce large messages. To avoid the +problem, answer `y', and the message will be split into several +smaller pieces, the size of each is about " +(/ message-send-mail-partially-limit 1000) +"KB except the last +one. + +However, some mail readers (MUA's) can't read split messages, i.e., +mails in message/partially format. Answer `n', and the message will be +sent in one piece. + +The size limit is controlled by `message-send-mail-partially-limit'. +If you always want Gnus to send messages in one piece, set +`message-send-mail-partially-limit' to `nil'. +"))) (mm-with-unibyte-current-buffer (message "Sending via mail...") (funcall (or message-send-mail-real-function @@ -2936,7 +3061,9 @@ to find out how to use this." ;; free for -inject-arguments -- a big win for the user and for us ;; since we don't have to play that double-guessing game and the user ;; gets full control (no gestapo'ish -f's, for instance). --sj - message-qmail-inject-args)) + (if (message-functionp message-qmail-inject-args) + (funcall message-qmail-inject-args) + message-qmail-inject-args))) ;; qmail-inject doesn't say anything on it's stdout/stderr, ;; we have to look at the retval instead (0 nil) @@ -3002,7 +3129,7 @@ Otherwise, generate and save a value for `canlock-password' first." ;; -- Per Abrahamsen 2001-10-08. (group-field-charset (gnus-group-name-charset method newsgroups-field)) - (followup-field-charset + (followup-field-charset (gnus-group-name-charset method (or followup-field ""))) (rfc2047-header-encoding-alist (append (when group-field-charset @@ -3075,7 +3202,7 @@ Otherwise, generate and save a value for `canlock-password' first." (backward-char 1)) (run-hooks 'message-send-news-hook) (gnus-open-server method) - (message "Sending news with %s..." (gnus-server-string method)) + (message "Sending news via %s..." (gnus-server-string method)) (setq result (let ((mail-header-separator "")) (gnus-request-post method)))) (kill-buffer tembuf)) @@ -3222,7 +3349,7 @@ Otherwise, generate and save a value for `canlock-password' first." ;; KLUDGE to handle nnvirtual groups. Doing this right ;; would probably involve a new nnoo function. ;; -- Per Abrahamsen , 2001-10-17. - (method (if (and (consp post-method) + (method (if (and (consp post-method) (eq (car post-method) 'nnvirtual) gnus-message-group-art) (let ((group (car (nnvirtual-find-group-art @@ -3232,7 +3359,7 @@ Otherwise, generate and save a value for `canlock-password' first." post-method)) (known-groups (mapcar (lambda (n) - (gnus-group-name-decode + (gnus-group-name-decode (gnus-group-real-name n) (gnus-group-name-charset method n))) (gnus-groups-from-server method))) @@ -3812,9 +3939,24 @@ give as trustworthy answer as possible." (or mail-host-address (message-make-fqdn))) -(defun message-make-mft () - "Return the Mail-Followup-To header." - (let* ((msg-recipients (message-options-get 'message-recipients)) +(defun message-to-list-only () + (interactive) + (let ((listaddr (message-make-mft t))) + (when listaddr + (save-excursion + (message-remove-header "to") + (message-remove-header "cc") + (message-position-on-field "To" "X-Draft-From") + (insert listaddr))))) + +(defun message-make-mft (&optional only-show-subscribed) + "Return the Mail-Followup-To header. If passed the optional +argument `only-show-subscribed' only return the subscribed address (and +not the additional To and Cc header contents)." + (let* ((case-fold-search t) + (to (message-fetch-field "To")) + (cc (message-fetch-field "cc")) + (msg-recipients (concat to (and to cc ", ") cc)) (recipients (mapcar 'mail-strip-quoted-names (message-tokenize-header msg-recipients))) @@ -3840,16 +3982,16 @@ give as trustworthy answer as possible." (mapcar 'funcall message-subscribed-address-functions)))) (save-match-data - (when (eval (apply 'append '(or) - (mapcar - (function (lambda (regexp) - (mapcar - (function (lambda (recipient) - `(string-match ,regexp - ,recipient))) - recipients))) - mft-regexps))) - msg-recipients)))) + (let ((subscribed-lists nil) + (list + (loop for recipient in recipients + when (loop for regexp in mft-regexps + when (string-match regexp recipient) return t) + return recipient))) + (when list + (if only-show-subscribed + list + msg-recipients)))))) (defun message-generate-headers (headers) "Prepare article HEADERS. @@ -4343,9 +4485,9 @@ than 988 characters long, and if they are not, trim them until they are." (setq message-draft-article (nndraft-request-associate-buffer "drafts")) (setq buffer-file-name (expand-file-name - (if (memq system-type - '(ms-dos ms-windows windows-nt - cygwin32 win32 w32 + (if (memq system-type + '(ms-dos ms-windows windows-nt + cygwin32 win32 w32 mswindows)) "message" "*message*") @@ -4488,16 +4630,34 @@ responses here are directed to other addresses."))) ;; Perhaps "Mail-Copies-To: never" removed the only address? (if (string-equal recipients "") (setq recipients author)) - ;; Convert string to a list of (("foo@bar" . "Name ") ...). + ;; Convert string to a list of (("foo@bar" . "Name ") ...). (setq recipients (mapcar (lambda (addr) - (cons (mail-strip-quoted-names addr) addr)) + (cons (downcase (mail-strip-quoted-names addr)) addr)) (message-tokenize-header recipients))) ;; Remove first duplicates. (Why not all duplicates? Is this a bug?) (let ((s recipients)) (while s (setq recipients (delq (assoc (car (pop s)) s) recipients)))) + + ;; Remove hierarchical lists that are contained within each other, + ;; if message-hierarchical-addresses is defined. + (when message-hierarchical-addresses + (let ((plain-addrs (mapcar 'car recipients)) + subaddrs recip) + (while plain-addrs + (setq subaddrs (assoc (car plain-addrs) + message-hierarchical-addresses) + plain-addrs (cdr plain-addrs)) + (when subaddrs + (setq subaddrs (cdr subaddrs)) + (while subaddrs + (setq recip (assoc (car subaddrs) recipients) + subaddrs (cdr subaddrs)) + (if recip + (setq recipients (delq recip recipients)))))))) + ;; Build the header alist. Allow the user to be asked whether ;; or not to reply to all recipients in a wide reply. (setq follow-to (list (cons 'To (cdr (pop recipients))))) @@ -4959,16 +5119,19 @@ Optional DIGEST will use digest to forward." (not message-forward-decoded-p)) (insert (with-temp-buffer - (mm-disable-multibyte-mule4) ;; Must copy buffer in unibyte mode + (if (with-current-buffer forward-buffer + (mm-multibyte-p)) + (insert-buffer-substring forward-buffer) + (mm-disable-multibyte-mule4) (insert (with-current-buffer forward-buffer (mm-string-as-unibyte (buffer-string)))) - (mm-enable-multibyte-mule4) - (mime-to-mml) - (goto-char (point-min)) - (when (looking-at "From ") - (replace-match "X-From-Line: ")) - (buffer-string))) + (mm-enable-multibyte-mule4)) + (mime-to-mml) + (goto-char (point-min)) + (when (looking-at "From ") + (replace-match "X-From-Line: ")) + (buffer-string))) (save-restriction (narrow-to-region (point) (point)) (mml-insert-buffer forward-buffer) @@ -5005,8 +5168,10 @@ Optional DIGEST will use digest to forward." (defun message-forward-rmail-make-body (forward-buffer) (save-window-excursion (set-buffer forward-buffer) - (let (rmail-enable-mime) - (rmail-toggle-header 0))) + ;; Rmail doesn't have rmail-msg-restore-non-pruned-header in Emacs + ;; 20. FIXIT, or we drop support for rmail in Emacs 20. + (if (rmail-msg-is-pruned) + (rmail-msg-restore-non-pruned-header))) (message-forward-make-body forward-buffer)) ;;;###autoload @@ -5014,7 +5179,7 @@ Optional DIGEST will use digest to forward." "Let RMAIL uses message to forward." (interactive) (setq rmail-enable-mime-composing t) - (setq rmail-insert-mime-forwarded-message-function + (setq rmail-insert-mime-forwarded-message-function 'message-forward-rmail-make-body)) ;;;###autoload @@ -5213,35 +5378,37 @@ which specify the range to operate on." (defun message-tool-bar-map () (or message-tool-bar-map (setq message-tool-bar-map - (and (fboundp 'tool-bar-add-item-from-menu) - tool-bar-mode - (let ((tool-bar-map (copy-keymap tool-bar-map)) - (load-path (mm-image-load-path))) - ;; Zap some items which aren't so relevant and take - ;; up space. - (dolist (key '(print-buffer kill-buffer save-buffer - write-file dired open-file)) - (define-key tool-bar-map (vector key) nil)) - (tool-bar-add-item-from-menu - 'message-send-and-exit "mail_send" message-mode-map) - (tool-bar-add-item-from-menu - 'message-kill-buffer "close" message-mode-map) - (tool-bar-add-item-from-menu + (and + (condition-case nil (require 'tool-bar) (error nil)) + (fboundp 'tool-bar-add-item-from-menu) + tool-bar-mode + (let ((tool-bar-map (copy-keymap tool-bar-map)) + (load-path (mm-image-load-path))) + ;; Zap some items which aren't so relevant and take + ;; up space. + (dolist (key '(print-buffer kill-buffer save-buffer + write-file dired open-file)) + (define-key tool-bar-map (vector key) nil)) + (tool-bar-add-item-from-menu + 'message-send-and-exit "mail_send" message-mode-map) + (tool-bar-add-item-from-menu + 'message-kill-buffer "close" message-mode-map) + (tool-bar-add-item-from-menu 'message-dont-send "cancel" message-mode-map) - (tool-bar-add-item-from-menu - 'mml-attach-file "attach" mml-mode-map) - (tool-bar-add-item-from-menu - 'ispell-message "spell" message-mode-map) - (tool-bar-add-item-from-menu - 'message-insert-importance-high "important" - message-mode-map) - (tool-bar-add-item-from-menu - 'message-insert-importance-low "unimportant" - message-mode-map) - (tool-bar-add-item-from-menu - 'message-insert-disposition-notification-to "receipt" + (tool-bar-add-item-from-menu + 'mml-attach-file "attach" mml-mode-map) + (tool-bar-add-item-from-menu + 'ispell-message "spell" message-mode-map) + (tool-bar-add-item-from-menu + 'message-insert-importance-high "important" message-mode-map) - tool-bar-map))))) + (tool-bar-add-item-from-menu + 'message-insert-importance-low "unimportant" + message-mode-map) + (tool-bar-add-item-from-menu + 'message-insert-disposition-notification-to "receipt" + message-mode-map) + tool-bar-map))))) ;;; Group name completion. diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index 54f61ec..64d935b 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -1,5 +1,5 @@ ;;; mm-decode.el --- Functions for decoding MIME things -;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; MORIOKA Tomohiko @@ -22,14 +22,6 @@ ;;; Commentary: -;; Jaap-Henk Hoepman (jhh@xs4all.nl): -;; -;; Added support for delayed destroy of external MIME viewers. All external -;; viewers for mime types in mm-keep-viewer-alive-types will remain active -;; after switching articles or groups, and will only be removed when exiting -;; gnus. -;; - ;;; Code: (require 'mail-parse) @@ -39,6 +31,7 @@ (require 'term)) (eval-and-compile + (autoload 'executable-find "executable") (autoload 'mm-inline-partial "mm-partial") (autoload 'mm-inline-external-body "mm-extern") (autoload 'mm-insert-inline "mm-view")) @@ -103,6 +96,50 @@ `(list ,buffer ,type ,encoding ,undisplayer ,disposition ,description ,cache ,id)) +(defcustom mm-text-html-renderer + (cond ((locate-library "w3") 'w3) + ((locate-library "w3m") 'w3m) + ((executable-find "links") 'links) + ((executable-find "lynx") 'lynx) + (t 'html2text)) + "Render of HTML contents. +It is one of defined renderer types, or a rendering function. +The defined renderer types are: +`w3' : using Emacs/W3; +`w3m' : using emacs-w3m; +`links': using links; +`lynx' : using lynx; +`html2text' : using html2text; +`nil' : using external viewer." + :type '(choice (const w3) + (const w3m) + (const links) + (const lynx) + (const html2text) + (const nil) + (function)) + :version "21.3" + :group 'mime-display) + +(defvar mm-inline-text-html-renderer nil + "Function used for rendering inline HTML contents. +It is suggested to customize `mm-text-html-renderer' instead.") + +(defcustom mm-inline-text-html-with-images nil + "If non-nil, Gnus will allow retrieving images in the HTML contents +with tags. It has no effect on Emacs/w3. For emacs-w3m, the +value of the option `w3m-display-inline-images' will be bound with +this value. In addition, the variable `w3m-safe-url-regexp' will be +bound with the value nil if it is non-nil to make emacs-w3m show all +images, however this behavior may be changed in the future." + :type 'boolean + :group 'mime-display) + +(defcustom mm-inline-text-html-with-w3m-keymap t + "If non-nil, use emacs-w3m command keys in the article buffer." + :type 'boolean + :group 'mime-display) + (defcustom mm-inline-media-tests '(("image/jpeg" mm-inline-image @@ -153,11 +190,12 @@ ("application/emacs-lisp" mm-display-elisp-inline identity) ("application/x-emacs-lisp" mm-display-elisp-inline identity) ("text/html" - mm-inline-text + mm-inline-text-html (lambda (handle) - (locate-library "w3"))) + (or mm-inline-text-html-renderer + mm-text-html-renderer))) ("text/x-vcard" - mm-inline-text + mm-inline-text-vcard (lambda (handle) (or (featurep 'vcard) (locate-library "vcard")))) @@ -197,6 +235,7 @@ (defcustom mm-inlined-types '("image/.*" "text/.*" "message/delivery-status" "message/rfc822" "message/partial" "message/external-body" "application/emacs-lisp" + "application/x-emacs-lisp" "application/pgp-signature" "application/x-pkcs7-signature" "application/pkcs7-signature" "application/x-pkcs7-mime" "application/pkcs7-mime") @@ -218,7 +257,8 @@ when selecting a different article." '("text/plain" "text/enriched" "text/richtext" "text/html" "text/x-vcard" "image/.*" "message/delivery-status" "multipart/.*" "message/rfc822" "text/x-patch" "application/pgp-signature" - "application/emacs-lisp" "application/x-pkcs7-signature" + "application/emacs-lisp" "application/x-emacs-lisp" + "application/x-pkcs7-signature" "application/pkcs7-signature" "application/x-pkcs7-mime" "application/pkcs7-mime") "A list of MIME types to be displayed automatically." @@ -421,13 +461,14 @@ for types in mm-keep-viewer-alive-types." (message "Destroying external MIME viewers") (mm-destroy-parts mm-postponed-undisplay-list))) -(defun mm-dissect-buffer (&optional no-strict-mime) +(defun mm-dissect-buffer (&optional no-strict-mime loose-mime) "Dissect the current buffer and return a list of MIME handles." (save-excursion (let (ct ctl type subtype cte cd description id result from) (save-restriction (mail-narrow-to-head) (when (or no-strict-mime + loose-mime (mail-fetch-field "mime-version")) (setq ct (mail-fetch-field "content-type") ctl (ignore-errors (mail-header-parse-content-type ct)) @@ -531,7 +572,9 @@ for types in mm-keep-viewer-alive-types." (save-restriction (narrow-to-region start (point)) (setq parts (nconc (list (mm-dissect-buffer t)) parts))))) - (forward-line 2) + (end-of-line 2) + (or (looking-at boundary) + (forward-line 1)) (setq start (point))) (when (and start (< start end)) (save-excursion @@ -622,13 +665,13 @@ external if displayed external." (mm-handle-set-undisplayer handle mm))))) ;; The function is a string to be executed. (mm-insert-part handle) - (let* ((dir (make-temp-name - (expand-file-name "emm." mm-tmp-directory))) - (filename (or + (let* ((dir (mm-make-temp-file + (expand-file-name "emm." mm-tmp-directory) 'dir)) + (filename (or (mail-content-type-get (mm-handle-disposition handle) 'filename) - (mail-content-type-get - (mm-handle-type handle) 'name))) + (mail-content-type-get + (mm-handle-type handle) 'name))) (mime-info (mailcap-mime-info (mm-handle-media-type handle) t)) (needsterm (or (assoc "needsterm" mime-info) @@ -636,12 +679,13 @@ external if displayed external." (copiousoutput (assoc "copiousoutput" mime-info)) file buffer) ;; We create a private sub-directory where we store our files. - (make-directory dir) (set-file-modes dir 448) (if filename - (setq file (expand-file-name (file-name-nondirectory filename) - dir)) - (setq file (make-temp-name (expand-file-name "mm." dir)))) + (setq file (expand-file-name + (gnus-map-function mm-file-name-rewrite-functions + (file-name-nondirectory filename)) + dir)) + (setq file (mm-make-temp-file (expand-file-name "mm." dir)))) (let ((coding-system-for-write mm-binary-coding-system)) (write-region (point-min) (point-max) file nil 'nomesg)) (message "Viewing with %s" method) @@ -971,9 +1015,8 @@ like underscores." (file-name-nondirectory filename)))) (setq file (read-file-name "Save MIME part to: " - (expand-file-name - (or filename name "") - (or mm-default-directory default-directory)))) + (or mm-default-directory default-directory) + nil nil (or filename name ""))) (setq mm-default-directory (file-name-directory file)) (and (or (not (file-exists-p file)) (yes-or-no-p (format "File %s already exists; overwrite? " @@ -1107,7 +1150,7 @@ be determined." ;; Avoid testing `make-glyph' since W3 may define ;; a bogus version of it. (if (fboundp 'create-image) - (create-image (buffer-string) + (create-image (buffer-string) (or (mm-image-type-from-buffer) (intern type)) 'data-p) @@ -1122,7 +1165,7 @@ be determined." ;; (without a ton of work) is to write them ;; out to a file, and then create a file ;; specifier. - (let ((file (make-temp-name + (let ((file (mm-make-temp-file (expand-file-name "emm.xbm" mm-tmp-directory)))) (unwind-protect @@ -1133,11 +1176,11 @@ be determined." (delete-file file))))) (t (make-glyph - (vector + (vector (or (mm-image-type-from-buffer) (intern type)) :data (buffer-string)))))) - + (defun mm-image-fit-p (handle) "Say whether the image in HANDLE will fit the current window." (let ((image (mm-get-image handle))) diff --git a/lisp/mm-partial.el b/lisp/mm-partial.el index 216340c..b24bfda 100644 --- a/lisp/mm-partial.el +++ b/lisp/mm-partial.el @@ -1,5 +1,5 @@ ;;; mm-partial.el --- showing message/partial -;; Copyright (C) 2000, 2001 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu ;; Keywords: message partial @@ -42,7 +42,8 @@ (gnus-request-article-this-buffer (aref header 0) gnus-newsgroup-name) (when (search-forward id nil t) - (let ((nhandles (mm-dissect-buffer)) nid) + (let ((nhandles (mm-dissect-buffer + nil gnus-article-loose-mime)) nid) (if (consp (car nhandles)) (mm-destroy-parts nhandles) (setq nid (cdr (assq 'id diff --git a/lisp/mm-url.el b/lisp/mm-url.el index 89072f7..561f89a 100644 --- a/lisp/mm-url.el +++ b/lisp/mm-url.el @@ -1,5 +1,5 @@ ;;; mm-url.el --- a wrapper of url functions/commands for Gnus -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2002 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu @@ -32,10 +32,10 @@ (eval-when-compile (require 'cl)) (require 'mm-util) +(require 'gnus) (eval-and-compile - (autoload 'executable-find "executable") - (autoload 'url-insert-file-contents "url-handlers")) + (autoload 'executable-find "executable")) (defgroup mm-url nil "A wrapper of url package and external url command for Gnus." @@ -43,7 +43,7 @@ (defcustom mm-url-use-external (not (condition-case nil - (require 'url-handlers) + (require 'url) (error nil))) "*If not-nil, use external grab program `mm-url-program'." :type 'boolean @@ -51,18 +51,21 @@ (defvar mm-url-predefined-programs '((wget "wget" "-q" "-O" "-") + (w3m "w3m" "-dump_source") (lynx "lynx" "-source") (curl "curl"))) -(defcustom mm-url-program +(defcustom mm-url-program (cond ((executable-find "wget") 'wget) + ((executable-find "w3m") 'w3m) ((executable-find "lynx") 'lynx) ((executable-find "curl") 'curl) (t "GET")) "The url grab program." - :type '(choice + :type '(choice (symbol :tag "wget" wget) + (symbol :tag "w3m" w3m) (symbol :tag "lynx" lynx) (symbol :tag "curl" curl) (string :tag "other")) @@ -73,6 +76,16 @@ :type '(repeat string) :group 'mm-url) + +;;; Internal variables + +(defvar mm-url-package-name + (gnus-replace-in-string + (gnus-replace-in-string gnus-version " v.*$" "") + " " "-")) + +(defvar mm-url-package-version gnus-version-number) + ;; Stolen from w3. (defvar mm-url-html-entities '( @@ -246,15 +259,32 @@ "A list of characters that are _NOT_ reserved in the URL spec. This is taken from RFC 2396.") +(defun mm-url-load-url () + "Load `url-insert-file-contents'." + (unless (condition-case () + (require 'url-handlers) + (error nil)) + ;; w3-4.0pre0.46 or earlier version. + (require 'w3-vars) + (require 'url))) + (defun mm-url-insert-file-contents (url) (if mm-url-use-external (if (string-match "^file:/+" url) (insert-file-contents (substring url (1- (match-end 0)))) (mm-url-insert-file-contents-external url)) - (require 'url-handlers) - (let ((name buffer-file-name)) + (mm-url-load-url) + (let ((name buffer-file-name) + (url-package-name (or mm-url-package-name + url-package-name)) + (url-package-version (or mm-url-package-version + url-package-version))) (prog1 (url-insert-file-contents url) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "\r 1000\r ?" nil t) + (replace-match ""))) (setq buffer-file-name name))))) (defun mm-url-insert-file-contents-external (url) @@ -344,7 +374,7 @@ spaces. Die Die Die." (defun mm-url-fetch-form (url pairs) "Fetch a form from URL with PAIRS as the data using the POST method." - (require 'url-handlers) + (mm-url-load-url) (let ((url-request-data (mm-url-encode-www-form-urlencoded pairs)) (url-request-method "POST") (url-request-extra-headers @@ -354,7 +384,7 @@ spaces. Die Die Die." t) (defun mm-url-fetch-simple (url content) - (require 'url-handlers) + (mm-url-load-url) (let ((url-request-data content) (url-request-method "POST") (url-request-extra-headers diff --git a/lisp/mm-util.el b/lisp/mm-util.el index e64e325..18bf4d7 100644 --- a/lisp/mm-util.el +++ b/lisp/mm-util.el @@ -121,7 +121,7 @@ '((iso-8859-15 . iso-8859-1))) ;; Windows-1252 is actually a superset of Latin-1. See also ;; `gnus-article-dumbquotes-map'. - ,@(unless (mm-coding-system-p 'windows-1252) + ,@(unless (mm-coding-system-p 'windows-1252) (if (mm-coding-system-p 'cp1252) '((windows-1252 . cp1252)) '((windows-1252 . iso-8859-1)))) @@ -245,7 +245,7 @@ Valid elements include: `iso-2022-jp-2' convert ISO-2022-jp to ISO-2022-jp-2 if ISO-2022-jp-2 exists." ) -(defvar mm-iso-8859-15-compatible +(defvar mm-iso-8859-15-compatible '((iso-8859-1 "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE") (iso-8859-9 "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xD0\xDD\xDE\xF0\xFD\xFE")) "ISO-8859-15 exchangeable coding systems and inconvertible characters.") @@ -253,16 +253,16 @@ Valid elements include: (defvar mm-iso-8859-x-to-15-table (and (fboundp 'coding-system-p) (mm-coding-system-p 'iso-8859-15) - (mapcar + (mapcar (lambda (cs) (if (mm-coding-system-p (car cs)) - (let ((c (string-to-char + (let ((c (string-to-char (decode-coding-string "\341" (car cs))))) (cons (char-charset c) (cons - (- (string-to-char + (- (string-to-char (decode-coding-string "\341" 'iso-8859-15)) c) - (string-to-list (decode-coding-string (car (cdr cs)) + (string-to-list (decode-coding-string (car (cdr cs)) (car cs)))))) '(gnus-charset 0))) mm-iso-8859-15-compatible)) @@ -283,7 +283,10 @@ prefer iso-2022-jp to japanese-shift-jis: (defvar mm-use-find-coding-systems-region (fboundp 'find-coding-systems-region) - "Use `find-coding-systems-region' to find proper coding systems.") + "Use `find-coding-systems-region' to find proper coding systems. + +Setting it to nil is useful on Emacsen supporting Unicode if sending +mail with multiple parts is preferred to sending a Unicode one.") ;;; Internal variables: @@ -358,7 +361,7 @@ used as the line break code type of the coding system." default-enable-multibyte-characters (fboundp 'set-buffer-multibyte)) "Emacs mule.") - + (defvar mm-mule4-p (and mm-emacs-mule (fboundp 'charsetp) (not (charsetp 'eight-bit-control))) @@ -385,7 +388,7 @@ This is a no-op in XEmacs." Only used in Emacs Mule 4." (set-buffer-multibyte t)) (defalias 'mm-enable-multibyte-mule4 'ignore)) - + (if mm-mule4-p (defun mm-disable-multibyte-mule4 () "Disable multibyte in the current buffer. @@ -478,15 +481,15 @@ If the charset is `composition', return the actual one." (goto-char (point-min)) (skip-chars-forward "\0-\177") (while (not (eobp)) - (cond - ((not (setq item (assq (char-charset (setq c (char-after))) + (cond + ((not (setq item (assq (char-charset (setq c (char-after))) mm-iso-8859-x-to-15-table))) (forward-char)) ((memq c (cdr (cdr item))) (setq inconvertible t) (forward-char)) (t - (insert-before-markers (prog1 (+ c (car (cdr item))) + (insert-before-markers (prog1 (+ c (car (cdr item))) (delete-char 1)))) (skip-chars-forward "\0-\177")))) (not inconvertible)))) @@ -507,7 +510,7 @@ charset, and a longer list means no appropriate charset." ;; system that has one. (let ((systems (find-coding-systems-region b e))) (when mm-coding-system-priorities - (setq systems + (setq systems (sort systems 'mm-sort-coding-systems-predicate))) ;; Fixme: The `mime-charset' (`x-ctext') of `compound-text' ;; is not in the IANA list. @@ -521,7 +524,7 @@ charset, and a longer list means no appropriate charset." charsets)) ;; Otherwise we're not multibyte, XEmacs or a single coding ;; system won't cover it. - (setq charsets + (setq charsets (mm-delete-duplicates (mapcar 'mm-mime-charset (delq 'ascii @@ -550,8 +553,8 @@ Also bind `default-enable-multibyte-characters' to nil. Equivalent to `progn' in XEmacs" (let ((multibyte (make-symbol "multibyte")) (buffer (make-symbol "buffer"))) - `(if mm-emacs-mule - (let ((,multibyte enable-multibyte-characters) + `(if mm-emacs-mule + (let ((,multibyte enable-multibyte-characters) (,buffer (current-buffer))) (unwind-protect (let (default-enable-multibyte-characters) @@ -570,7 +573,7 @@ Mule4 only." (let ((multibyte (make-symbol "multibyte")) (buffer (make-symbol "buffer"))) `(if mm-mule4-p - (let ((,multibyte enable-multibyte-characters) + (let ((,multibyte enable-multibyte-characters) (,buffer (current-buffer))) (unwind-protect (let (default-enable-multibyte-characters) @@ -752,6 +755,45 @@ If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." (let ((cs (mm-detect-coding-region start end))) cs))) +(defun mm-guess-mime-charset () + "Guess the default MIME charset from the language environment." + (let ((language-info + (and (boundp 'current-language-environment) + (assoc current-language-environment + language-info-alist))) + item) + (cond + ((null language-info) + 'iso-8859-1) + ((setq item + (cadr + (or (assq 'coding-priority language-info) + (assq 'coding-system language-info)))) + (if (fboundp 'coding-system-get) + (or (coding-system-get item 'mime-charset) + item) + item)) + ((setq item (car (last (assq 'charset language-info)))) + (if (eq item 'ascii) + 'iso-8859-1 + (mm-mime-charset item))) + (t + 'iso-8859-1)))) + +;; It is not a MIME function, but some MIME functions use it. +(defalias 'mm-make-temp-file + (if (fboundp 'make-temp-file) + 'make-temp-file + (lambda (prefix &optional dir-flag) + (let ((file (expand-file-name + (make-temp-name prefix) + (if (fboundp 'temp-directory) + (temp-directory) + temporary-file-directory)))) + (if dir-flag + (make-directory file)) + file)))) + (provide 'mm-util) ;;; mm-util.el ends here diff --git a/lisp/mm-uu.el b/lisp/mm-uu.el index f36a5fd..b3f2877 100644 --- a/lisp/mm-uu.el +++ b/lisp/mm-uu.el @@ -1,5 +1,5 @@ ;;; mm-uu.el --- Return uu stuff as mm handles -;; Copyright (c) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +;; Copyright (c) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu ;; Keywords: postscript uudecode binhex shar forward gnatsweb pgp @@ -80,7 +80,7 @@ This can be either \"inline\" or \"attachment\".") mm-uu-postscript-extract nil) (uu - "^begin[ \t]+[0-7][0-7][0-7][ \t]+" + "^begin[ \t]+0?[0-7][0-7][0-7][ \t]+" "^end[ \t]*$" mm-uu-uu-extract mm-uu-uu-filename) diff --git a/lisp/mm-view.el b/lisp/mm-view.el index 06a6c71..7bf1cb1 100644 --- a/lisp/mm-view.el +++ b/lisp/mm-view.el @@ -34,9 +34,34 @@ (autoload 'vcard-parse-string "vcard") (autoload 'vcard-format-string "vcard") (autoload 'fill-flowed "flow-fill") + (autoload 'html2text "html2text") (unless (fboundp 'diff-mode) (autoload 'diff-mode "diff-mode" "" t nil))) +(defvar mm-text-html-renderer-alist + '((w3 . mm-inline-text-html-render-with-w3) + (w3m . mm-inline-text-html-render-with-w3m) + (links mm-inline-render-with-file + mm-links-remove-leading-blank + "links" "-dump" file) + (lynx mm-inline-render-with-stdin nil + "lynx" "-dump" "-force_html" "-stdin") + (html2text mm-inline-render-with-function html2text)) + "The attributes of renderer types for text/html.") + +(defvar mm-text-html-washer-alist + '((w3 . gnus-article-wash-html-with-w3) + (w3m . gnus-article-wash-html-with-w3m) + (links mm-inline-wash-with-file + mm-links-remove-leading-blank + "links" "-dump" file) + (lynx mm-inline-wash-with-stdin nil + "lynx" "-dump" "-force_html" "-stdin") + (html2text html2text)) + "The attributes of washer types for text/html.") + +;;; Internal variables. + ;;; ;;; Functions for displaying various formats inline ;;; @@ -81,124 +106,315 @@ (require 'url-vars) (setq mm-w3-setup t))) -(defun mm-inline-text (handle) - (let ((type (mm-handle-media-subtype handle)) - text buffer-read-only) - (cond - ((equal type "html") - (mm-setup-w3) - (setq text (mm-get-part handle)) - (let ((b (point)) - (url-standalone-mode t) - (w3-honor-stylesheets nil) - (w3-delay-image-loads t) - (url-current-object - (url-generic-parse-url (format "cid:%s" (mm-handle-id handle)))) - (width (window-width)) - (charset (mail-content-type-get - (mm-handle-type handle) 'charset))) - (save-excursion - (insert text) +(defun mm-inline-text-html-render-with-w3 (handle) + (mm-setup-w3) + (let ((text (mm-get-part handle)) + (b (point)) + (url-standalone-mode t) + (url-gateway-unplugged t) + (w3-honor-stylesheets nil) + (url-current-object + (url-generic-parse-url (format "cid:%s" (mm-handle-id handle)))) + (width (window-width)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset))) + (save-excursion + (insert text) + (save-restriction + (narrow-to-region b (point)) + (goto-char (point-min)) + (if (or (and (boundp 'w3-meta-content-type-charset-regexp) + (re-search-forward + w3-meta-content-type-charset-regexp nil t)) + (and (boundp 'w3-meta-charset-content-type-regexp) + (re-search-forward + w3-meta-charset-content-type-regexp nil t))) + (setq charset + (or (let ((bsubstr (buffer-substring-no-properties + (match-beginning 2) + (match-end 2)))) + (if (fboundp 'w3-coding-system-for-mime-charset) + (w3-coding-system-for-mime-charset bsubstr) + (mm-charset-to-coding-system bsubstr))) + charset))) + (delete-region (point-min) (point-max)) + (insert (mm-decode-string text charset)) + (save-window-excursion (save-restriction - (narrow-to-region b (point)) - (goto-char (point-min)) - (if (or (and (boundp 'w3-meta-content-type-charset-regexp) - (re-search-forward - w3-meta-content-type-charset-regexp nil t)) - (and (boundp 'w3-meta-charset-content-type-regexp) - (re-search-forward - w3-meta-charset-content-type-regexp nil t))) - (setq charset - (or (let ((bsubstr (buffer-substring-no-properties - (match-beginning 2) - (match-end 2)))) - (if (fboundp 'w3-coding-system-for-mime-charset) - (w3-coding-system-for-mime-charset bsubstr) - (mm-charset-to-coding-system bsubstr))) - charset))) - (delete-region (point-min) (point-max)) - (insert (mm-decode-string text charset)) - (save-window-excursion - (save-restriction - (let ((w3-strict-width width) - ;; Don't let w3 set the global version of - ;; this variable. - (fill-column fill-column) - (w3-honor-stylesheets nil) - (w3-delay-image-loads t) - (url-standalone-mode t)) - (condition-case var - (w3-region (point-min) (point-max)) - (error - (delete-region (point-min) (point-max)) - (let ((b (point)) - (charset (mail-content-type-get - (mm-handle-type handle) 'charset))) - (if (or (eq charset 'gnus-decoded) - (eq mail-parse-charset 'gnus-decoded)) - (save-restriction - (narrow-to-region (point) (point)) - (mm-insert-part handle) - (goto-char (point-max))) - (insert (mm-decode-string (mm-get-part handle) - charset)))) - (message - "Error while rendering html; showing as text/plain")))))) - (mm-handle-set-undisplayer - handle - `(lambda () - (let (buffer-read-only) - (if (functionp 'remove-specifier) - (mapcar (lambda (prop) - (remove-specifier - (face-property 'default prop) - (current-buffer))) - '(background background-pixmap foreground))) - (delete-region ,(point-min-marker) - ,(point-max-marker))))))))) - ((equal type "x-vcard") - (mm-insert-inline + (let ((w3-strict-width width) + ;; Don't let w3 set the global version of + ;; this variable. + (fill-column fill-column)) + (if (or debug-on-error debug-on-quit) + (w3-region (point-min) (point-max)) + (condition-case () + (w3-region (point-min) (point-max)) + (error + (delete-region (point-min) (point-max)) + (let ((b (point)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset))) + (if (or (eq charset 'gnus-decoded) + (eq mail-parse-charset 'gnus-decoded)) + (save-restriction + (narrow-to-region (point) (point)) + (mm-insert-part handle) + (goto-char (point-max))) + (insert (mm-decode-string (mm-get-part handle) + charset)))) + (message + "Error while rendering html; showing as text/plain"))))))) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (if (functionp 'remove-specifier) + (mapcar (lambda (prop) + (remove-specifier + (face-property 'default prop) + (current-buffer))) + '(background background-pixmap foreground))) + (delete-region ,(point-min-marker) + ,(point-max-marker))))))))) + +(defvar mm-w3m-mode-map nil + "Local keymap for inlined text/html part rendered by emacs-w3m. It will +be different from `w3m-mode-map' to use in the article buffer.") + +(defvar mm-w3m-mode-command-alist + '((backward-char) + (describe-mode) + (forward-char) + (goto-line) + (next-line) + (previous-line) + (w3m-antenna) + (w3m-antenna-add-current-url) + (w3m-bookmark-add-current-url) + (w3m-bookmark-add-this-url) + (w3m-bookmark-view) + (w3m-close-window) + (w3m-copy-buffer) + (w3m-delete-buffer) + (w3m-dtree) + (w3m-edit-current-url) + (w3m-edit-this-url) + (w3m-gohome) + (w3m-goto-url) + (w3m-goto-url-new-session) + (w3m-history) + (w3m-history-restore-position) + (w3m-history-store-position) + (w3m-namazu) + (w3m-next-buffer) + (w3m-previous-buffer) + (w3m-quit) + (w3m-redisplay-with-charset) + (w3m-reload-this-page) + (w3m-scroll-down-or-previous-url) + (w3m-scroll-up-or-next-url) + (w3m-search) + (w3m-select-buffer) + (w3m-switch-buffer) + (w3m-view-header) + (w3m-view-parent-page) + (w3m-view-previous-page) + (w3m-view-source) + (w3m-weather)) + "Alist of commands to use for emacs-w3m in the article buffer. Each +element looks like (FROM-COMMAND . TO-COMMAND); FROM-COMMAND should be +registered in `w3m-mode-map' which will be substituted by TO-COMMAND +in `mm-w3m-mode-map'. If TO-COMMAND is nil, an article command key +will not be substituted.") + +(defvar mm-w3m-mode-dont-bind-keys (list [up] [right] [left] [down]) + "List of keys which should not be bound for the emacs-w3m commands.") + +(defvar mm-w3m-setup nil + "Whether gnus-article-mode has been setup to use emacs-w3m.") + +(defun mm-setup-w3m () + "Setup gnus-article-mode to use emacs-w3m." + (unless mm-w3m-setup + (require 'w3m) + (unless mm-w3m-mode-map + (setq mm-w3m-mode-map (copy-keymap w3m-mode-map)) + (dolist (def mm-w3m-mode-command-alist) + (condition-case nil + (substitute-key-definition (car def) (cdr def) mm-w3m-mode-map) + (error))) + (dolist (key mm-w3m-mode-dont-bind-keys) + (condition-case nil + (define-key mm-w3m-mode-map key nil) + (error)))) + (unless (assq 'gnus-article-mode w3m-cid-retrieve-function-alist) + (push (cons 'gnus-article-mode 'mm-w3m-cid-retrieve) + w3m-cid-retrieve-function-alist)) + (setq mm-w3m-setup t))) + +(defun mm-w3m-cid-retrieve (url &rest args) + "Insert a content pointed by URL if it has the cid: scheme." + (when (string-match "\\`cid:" url) + (setq url (concat "<" (substring url (match-end 0)) ">")) + (catch 'found-handle + (dolist (handle (with-current-buffer w3m-current-buffer + gnus-article-mime-handles)) + (when (and (listp handle) + (equal url (mm-handle-id handle))) + (mm-insert-part handle) + (throw 'found-handle (mm-handle-media-type handle))))))) + +(defun mm-inline-text-html-render-with-w3m (handle) + "Render a text/html part using emacs-w3m." + (mm-setup-w3m) + (let ((text (mm-get-part handle)) + (b (point)) + (charset (mail-content-type-get (mm-handle-type handle) 'charset))) + (save-excursion + (insert text) + (save-restriction + (narrow-to-region b (point)) + (goto-char (point-min)) + (when (re-search-forward w3m-meta-content-type-charset-regexp nil t) + (setq charset (or (w3m-charset-to-coding-system (match-string 2)) + charset))) + (when charset + (delete-region (point-min) (point-max)) + (insert (mm-decode-string text charset))) + (let ((w3m-safe-url-regexp (if mm-inline-text-html-with-images + nil + "\\`cid:")) + (w3m-display-inline-images mm-inline-text-html-with-images) + w3m-force-redisplay) + (w3m-region (point-min) (point-max))) + (when mm-inline-text-html-with-w3m-keymap + (add-text-properties + (point-min) (point-max) + (append '(mm-inline-text-html-with-w3m t) + (gnus-local-map-property mm-w3m-mode-map))))) + (mm-handle-set-undisplayer handle - (concat "\n-- \n" - (ignore-errors - (if (fboundp 'vcard-pretty-print) - (vcard-pretty-print (mm-get-part handle)) - (vcard-format-string - (vcard-parse-string (mm-get-part handle) - 'vcard-standard-filter))))))) + `(lambda () + (let (buffer-read-only) + (if (functionp 'remove-specifier) + (mapcar (lambda (prop) + (remove-specifier + (face-property 'default prop) + (current-buffer))) + '(background background-pixmap foreground))) + (delete-region ,(point-min-marker) + ,(point-max-marker)))))))) + +(defun mm-links-remove-leading-blank () + ;; Delete the annoying three spaces preceding each line of links + ;; output. + (goto-char (point-min)) + (while (re-search-forward "^ " nil t) + (delete-region (match-beginning 0) (match-end 0)))) + +(defun mm-inline-wash-with-file (post-func cmd &rest args) + (let ((file (mm-make-temp-file + (expand-file-name "mm" mm-tmp-directory)))) + (let ((coding-system-for-write 'binary)) + (write-region (point-min) (point-max) file nil 'silent)) + (delete-region (point-min) (point-max)) + (unwind-protect + (apply 'call-process cmd nil t nil (mapcar 'eval args)) + (delete-file file)) + (and post-func (funcall post-func)))) + +(defun mm-inline-wash-with-stdin (post-func cmd &rest args) + (let ((coding-system-for-write 'binary)) + (apply 'call-process-region (point-min) (point-max) + cmd t t nil args)) + (and post-func (funcall post-func))) + +(defun mm-inline-render-with-file (handle post-func cmd &rest args) + (let ((source (mm-get-part handle))) + (mm-insert-inline + handle + (mm-with-unibyte-buffer + (insert source) + (apply 'mm-inline-wash-with-file post-func cmd args) + (buffer-string))))) + +(defun mm-inline-render-with-stdin (handle post-func cmd &rest args) + (let ((source (mm-get-part handle))) + (mm-insert-inline + handle + (mm-with-unibyte-buffer + (insert source) + (apply 'mm-inline-wash-with-stdin post-func cmd args) + (buffer-string))))) + +(defun mm-inline-render-with-function (handle func &rest args) + (let ((source (mm-get-part handle))) + (mm-insert-inline + handle + (mm-with-unibyte-buffer + (insert source) + (apply func args) + (buffer-string))))) + +(defun mm-inline-text-html (handle) + (let* ((func (or mm-inline-text-html-renderer mm-text-html-renderer)) + (entry (assq func mm-text-html-renderer-alist)) + buffer-read-only) + (if entry + (setq func (cdr entry))) + (cond + ((gnus-functionp func) + (funcall func handle)) (t - (let ((b (point)) - (charset (mail-content-type-get - (mm-handle-type handle) 'charset))) - (if (or (eq charset 'gnus-decoded) - ;; This is probably not entirely correct, but - ;; makes rfc822 parts with embedded multiparts work. - (eq mail-parse-charset 'gnus-decoded)) - (save-restriction - (narrow-to-region (point) (point)) - (mm-insert-part handle) - (goto-char (point-max))) - (insert (mm-decode-string (mm-get-part handle) charset))) - (when (and (equal type "plain") - (equal (cdr (assoc 'format (mm-handle-type handle))) - "flowed")) - (save-restriction - (narrow-to-region b (point)) - (goto-char b) - (fill-flowed) - (goto-char (point-max)))) + (apply (car func) handle (cdr func)))))) + +(defun mm-inline-text-vcard (handle) + (let (buffer-read-only) + (mm-insert-inline + handle + (concat "\n-- \n" + (ignore-errors + (if (fboundp 'vcard-pretty-print) + (vcard-pretty-print (mm-get-part handle)) + (vcard-format-string + (vcard-parse-string (mm-get-part handle) + 'vcard-standard-filter)))))))) + +(defun mm-inline-text (handle) + (let ((b (point)) + (type (mm-handle-media-subtype handle)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset)) + buffer-read-only) + (if (or (eq charset 'gnus-decoded) + ;; This is probably not entirely correct, but + ;; makes rfc822 parts with embedded multiparts work. + (eq mail-parse-charset 'gnus-decoded)) (save-restriction - (narrow-to-region b (point)) - (set-text-properties (point-min) (point-max) nil) - (when (or (equal type "enriched") - (equal type "richtext")) - (enriched-decode (point-min) (point-max))) - (mm-handle-set-undisplayer - handle - `(lambda () - (let (buffer-read-only) - (delete-region ,(point-min-marker) - ,(point-max-marker))))))))))) + (narrow-to-region (point) (point)) + (mm-insert-part handle) + (goto-char (point-max))) + (insert (mm-decode-string (mm-get-part handle) charset))) + (when (and (equal type "plain") + (equal (cdr (assoc 'format (mm-handle-type handle))) + "flowed")) + (save-restriction + (narrow-to-region b (point)) + (goto-char b) + (fill-flowed) + (goto-char (point-max)))) + (save-restriction + (narrow-to-region b (point)) + (set-text-properties (point-min) (point-max) nil) + (when (or (equal type "enriched") + (equal type "richtext")) + (enriched-decode (point-min) (point-max))) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (delete-region ,(point-min-marker) + ,(point-max-marker)))))))) (defun mm-insert-inline (handle text) "Insert TEXT inline from HANDLE." @@ -220,8 +436,8 @@ (defun mm-w3-prepare-buffer () (require 'w3) (let ((url-standalone-mode t) - (w3-honor-stylesheets nil) - (w3-delay-image-loads t)) + (url-gateway-unplugged t) + (w3-honor-stylesheets nil)) (w3-prepare-buffer))) (defun mm-view-message () @@ -333,7 +549,7 @@ ?\x7c ?\x82 ?\x2e ?\x2e ?\x5c ?\x7c ?\x83 ?\x2e ?\x2e ?\x2e ?\x5c ?\x29 ?\x06 ?\x09 ?\x5c ?\x2a ?\x86 ?\x48 ?\x86 ?\xf7 ?\x0d ?\x01 ?\x07 ?\x02))))) - + ;; id-envelopedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) ;; us(840) rsadsi(113549) pkcs(1) pkcs7(7) 3 } (defvar mm-pkcs7-enveloped-magic @@ -344,7 +560,7 @@ ?\x7c ?\x82 ?\x2e ?\x2e ?\x5c ?\x7c ?\x83 ?\x2e ?\x2e ?\x2e ?\x5c ?\x29 ?\x06 ?\x09 ?\x5c ?\x2a ?\x86 ?\x48 ?\x86 ?\xf7 ?\x0d ?\x01 ?\x07 ?\x03))))) - + (defun mm-view-pkcs7-get-type (handle) (mm-with-unibyte-buffer (mm-insert-part handle) @@ -358,8 +574,25 @@ (defun mm-view-pkcs7 (handle) (case (mm-view-pkcs7-get-type handle) (enveloped (mm-view-pkcs7-decrypt handle)) + (signed (mm-view-pkcs7-verify handle)) (otherwise (error "Unknown or unimplemented PKCS#7 type")))) +(defun mm-view-pkcs7-verify (handle) + ;; A bogus implementation of PKCS#7. FIXME:: + (mm-insert-part handle) + (goto-char (point-min)) + (if (search-forward "Content-Type: " nil t) + (delete-region (point-min) (match-beginning 0))) + (goto-char (point-max)) + (if (re-search-backward "--\r?\n?" nil t) + (delete-region (match-end 0) (point-max))) + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (message "Verify signed PKCS#7 message is unimplemented.") + (sit-for 1) + t) + (defun mm-view-pkcs7-decrypt (handle) (insert-buffer (mm-handle-buffer handle)) (goto-char (point-min)) @@ -370,10 +603,15 @@ (if (= (length smime-keys) 1) (cadar smime-keys) (smime-get-key-by-email - (completing-read "Decrypt this part with which key? " - smime-keys nil nil - (and (listp (car-safe smime-keys)) - (caar smime-keys))))))) + (completing-read + (concat "Decipher using which key? " + (if smime-keys (concat "(default " (caar smime-keys) ") ") + "")) + smime-keys nil nil nil nil (car-safe (car-safe smime-keys)))))) + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n")) + (goto-char (point-min))) (provide 'mm-view) diff --git a/lisp/mml-sec.el b/lisp/mml-sec.el index 3d30602..09fec43 100644 --- a/lisp/mml-sec.el +++ b/lisp/mml-sec.el @@ -1,5 +1,5 @@ ;;; mml-sec.el --- A package with security functions for MML documents -;; Copyright (C) 2000 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Simon Josefsson ;; This file is not part of GNU Emacs, but the same permissions apply. @@ -127,6 +127,69 @@ (interactive) (mml-secure-part "smime")) +;; defuns that add the proper <#secure ...> tag to the top of the message body +(defun mml-secure-message (method &optional modesym) + (let ((mode (prin1-to-string modesym)) + insert-loc) + (mml-unsecure-message) + (save-excursion + (goto-char (point-min)) + (cond ((re-search-forward + (concat "^" (regexp-quote mail-header-separator) "\n") nil t) + (goto-char (setq insert-loc (match-end 0))) + (unless (looking-at "<#secure") + (mml-insert-tag + 'secure 'method method 'mode mode))) + (t (error + "The message is corrupted. No mail header separator")))) + (when (eql insert-loc (point)) + (forward-line 1)))) + +(defun mml-unsecure-message () + "Remove security related MML tags from message." + (interactive) + (save-excursion + (goto-char (point-max)) + (when (re-search-backward "^<#secure.*>\n" nil t) + (kill-region (match-beginning 0) (match-end 0))))) + +(defun mml-secure-message-sign-smime () + "Add MML tag to encrypt/sign the entire message." + (interactive) + (mml-secure-message "smime" 'sign)) + +(defun mml-secure-message-sign-pgp () + "Add MML tag to encrypt/sign the entire message." + (interactive) + (mml-secure-message "pgp" 'sign)) + +(defun mml-secure-message-sign-pgpmime () + "Add MML tag to encrypt/sign the entire message." + (interactive) + (mml-secure-message "pgpmime" 'sign)) + +(defun mml-secure-message-encrypt-smime (&optional dontsign) + "Add MML tag to encrypt and sign the entire message. +If called with a prefix argument, only encrypt (do NOT sign)." + (interactive "P") + (mml-secure-message "smime" (if dontsign 'encrypt 'signencrypt))) + +;;; NOTE: this should be switched to use signencrypt +;;; once it does something sensible +(defun mml-secure-message-encrypt-pgp (&optional dontsign) + "Add MML tag to encrypt and sign the entire message. +If called with a prefix argument, only encrypt (do NOT sign)." + (interactive "P") + (mml-secure-message "pgp" (if dontsign 'encrypt 'encrypt))) + +;;; NOTE: this should be switched to use signencrypt +;;; once it does something sensible +(defun mml-secure-message-encrypt-pgpmime (&optional dontsign) + "Add MML tag to encrypt and sign the entire message. +If called with a prefix argument, only encrypt (do NOT sign)." + (interactive "P") + (mml-secure-message "pgpmime" (if dontsign 'encrypt 'encrypt))) + (provide 'mml-sec) ;;; mml-sec.el ends here diff --git a/lisp/mml-smime.el b/lisp/mml-smime.el index d5baf3f..2eec919 100644 --- a/lisp/mml-smime.el +++ b/lisp/mml-smime.el @@ -45,7 +45,8 @@ (if (not (and (not (file-exists-p tmp)) (get-buffer tmp))) (push tmp certfiles) - (setq file (make-temp-name mm-tmp-directory)) + (setq file (mm-make-temp-file (expand-file-name "mml." + mm-tmp-directory))) (with-current-buffer tmp (write-region (point-min) (point-max) file)) (push file certfiles) diff --git a/lisp/mml.el b/lisp/mml.el index eb43ea2..1554513 100644 --- a/lisp/mml.el +++ b/lisp/mml.el @@ -65,7 +65,7 @@ NAME is a string containing the name of the TWEAK parameter in the MML handle. FUNCTION is a Lisp function which is called with the MML handle to tweak the part.") -(defvar mml-tweak-sexp-alist +(defvar mml-tweak-sexp-alist '((mml-externalize-attachments . mml-tweak-externalize-attachments)) "A list of (SEXP . FUNCTION) for tweaking MML parts. SEXP is a s-expression. If the evaluation of SEXP is non-nil, FUNCTION @@ -143,6 +143,40 @@ one charsets.") (while (and (not (eobp)) (not (looking-at "<#/multipart"))) (cond + ((looking-at "<#secure") + ;; The secure part is essentially a meta-meta tag, which + ;; expands to either a part tag if there are no other parts in + ;; the document or a multipart tag if there are other parts + ;; included in the message + (let* (secure-mode + (taginfo (mml-read-tag)) + (recipients (cdr (assq 'recipients taginfo))) + (location (cdr (assq 'tag-location taginfo))) + (mode (cdr (assq 'mode taginfo))) + (method (cdr (assq 'method taginfo))) + tags) + (save-excursion + (if + (re-search-forward + "<#\\(/\\)?\\(multipart\\|part\\|external\\|mml\\)." nil t) + (setq secure-mode "multipart") + (setq secure-mode "part"))) + (save-excursion + (goto-char location) + (re-search-forward "<#secure[^\n]*>\n")) + (delete-region (match-beginning 0) (match-end 0)) + (cond ((string= mode "sign") + (setq tags (list "sign" method))) + ((string= mode "encrypt") + (setq tags (list "encrypt" method))) + ((string= mode "signencrypt") + (setq tags (list "sign" method "encrypt" method)))) + (eval `(mml-insert-tag ,secure-mode + ,@tags + ,(if recipients 'recipients) + ,recipients)) + ;; restart the parse + (goto-char location))) ((looking-at "<#multipart") (push (nconc (mml-read-tag) (mml-parse-1)) struct)) ((looking-at "<#external") @@ -165,7 +199,7 @@ one charsets.") (list (intern (downcase (cdr (assq 'charset tag)))))) (t - (mm-find-mime-charset-region point (point) + (mm-find-mime-charset-region point (point) mm-hack-charsets)))) (when (and (not raw) (memq nil charsets)) (if (or (memq 'unknown-encoding mml-confirmation-set) @@ -407,7 +441,8 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." (let (use-hard-newlines) (when (and (string= type "text/plain") (or (null (assq 'format cont)) - (string= (assq 'format cont) "flowed")) + (string= (cdr (assq 'format cont)) + "flowed")) (setq use-hard-newlines (text-property-any (point-min) (point-max) 'hard 't))) @@ -750,12 +785,13 @@ If HANDLES is non-nil, use it instead reparsing the buffer." (encrypt (make-sparse-keymap)) (map (make-sparse-keymap)) (main (make-sparse-keymap))) - (define-key sign "p" 'mml-secure-sign-pgpmime) - (define-key sign "o" 'mml-secure-sign-pgp) - (define-key sign "s" 'mml-secure-sign-smime) - (define-key encrypt "p" 'mml-secure-encrypt-pgpmime) - (define-key encrypt "o" 'mml-secure-encrypt-pgp) - (define-key encrypt "s" 'mml-secure-encrypt-smime) + (define-key sign "p" 'mml-secure-message-sign-pgpmime) + (define-key sign "o" 'mml-secure-message-sign-pgp) + (define-key sign "s" 'mml-secure-message-sign-smime) + (define-key encrypt "p" 'mml-secure-message-encrypt-pgpmime) + (define-key encrypt "o" 'mml-secure-message-encrypt-pgp) + (define-key encrypt "s" 'mml-secure-message-encrypt-smime) + (define-key map "\C-n" 'mml-unsecure-message) (define-key map "f" 'mml-attach-file) (define-key map "b" 'mml-attach-buffer) (define-key map "e" 'mml-attach-external) @@ -782,12 +818,13 @@ If HANDLES is non-nil, use it instead reparsing the buffer." ["Attach External" mml-attach-external t] ["Insert Part" mml-insert-part t] ["Insert Multipart" mml-insert-multipart t] - ["PGP/MIME Sign" mml-secure-sign-pgpmime t] - ["PGP/MIME Encrypt" mml-secure-encrypt-pgpmime t] - ["PGP Sign" mml-secure-sign-pgp t] - ["PGP Encrypt" mml-secure-encrypt-pgp t] - ["S/MIME Sign" mml-secure-sign-smime t] - ["S/MIME Encrypt" mml-secure-encrypt-smime t] + ["PGP/MIME Sign" mml-secure-message-sign-pgpmime t] + ["PGP/MIME Encrypt" mml-secure-message-encrypt-pgpmime t] + ["PGP Sign" mml-secure-message-sign-pgp t] + ["PGP Encrypt" mml-secure-message-encrypt-pgp t] + ["S/MIME Sign" mml-secure-message-sign-smime t] + ["S/MIME Encrypt" mml-secure-message-encrypt-smime t] + ["Encrypt/Sign off" mml-unsecure-message t] ;;["Narrow" mml-narrow-to-part t] ["Quote MML" mml-quote-region t] ["Validate MML" mml-validate t] @@ -947,42 +984,43 @@ TYPE is the MIME type to use." "Display current buffer with Gnus, in a new buffer. If RAW, don't highlight the article." (interactive "P") - (let* ((buf (current-buffer)) - (message-options message-options) - (message-this-is-news (message-news-p)) - (message-posting-charset (or (gnus-setup-posting-charset - (save-restriction - (message-narrow-to-headers-or-head) - (message-fetch-field "Newsgroups"))) - message-posting-charset))) - (message-options-set-recipient) - (switch-to-buffer (generate-new-buffer - (concat (if raw "*Raw MIME preview of " - "*MIME preview of ") (buffer-name)))) - (erase-buffer) - (insert-buffer buf) - (if (re-search-forward - (concat "^" (regexp-quote mail-header-separator) "\n") nil t) - (replace-match "\n")) - (let ((mail-header-separator "")) ;; mail-header-separator is removed. - (mml-to-mime)) - (if raw - (when (fboundp 'set-buffer-multibyte) - (let ((s (buffer-string))) - ;; Insert the content into unibyte buffer. - (erase-buffer) - (mm-disable-multibyte) - (insert s))) - (let ((gnus-newsgroup-charset (car message-posting-charset)) - gnus-article-prepare-hook gnus-original-article-buffer) - (run-hooks 'gnus-article-decode-hook) - (let ((gnus-newsgroup-name "dummy")) - (gnus-article-prepare-display)))) - ;; Disable article-mode-map. - (use-local-map nil) - (setq buffer-read-only t) - (local-set-key "q" (lambda () (interactive) (kill-buffer nil))) - (goto-char (point-min)))) + (save-excursion + (let* ((buf (current-buffer)) + (message-options message-options) + (message-this-is-news (message-news-p)) + (message-posting-charset (or (gnus-setup-posting-charset + (save-restriction + (message-narrow-to-headers-or-head) + (message-fetch-field "Newsgroups"))) + message-posting-charset))) + (message-options-set-recipient) + (switch-to-buffer (generate-new-buffer + (concat (if raw "*Raw MIME preview of " + "*MIME preview of ") (buffer-name)))) + (erase-buffer) + (insert-buffer buf) + (if (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "\n") nil t) + (replace-match "\n")) + (let ((mail-header-separator ""));; mail-header-separator is removed. + (mml-to-mime)) + (if raw + (when (fboundp 'set-buffer-multibyte) + (let ((s (buffer-string))) + ;; Insert the content into unibyte buffer. + (erase-buffer) + (mm-disable-multibyte) + (insert s))) + (let ((gnus-newsgroup-charset (car message-posting-charset)) + gnus-article-prepare-hook gnus-original-article-buffer) + (run-hooks 'gnus-article-decode-hook) + (let ((gnus-newsgroup-name "dummy")) + (gnus-article-prepare-display)))) + ;; Disable article-mode-map. + (use-local-map nil) + (setq buffer-read-only t) + (local-set-key "q" (lambda () (interactive) (kill-buffer nil))) + (goto-char (point-min))))) (defun mml-validate () "Validate the current MML document." @@ -1019,7 +1057,7 @@ If RAW, don't highlight the article." (defun mml-tweak-externalize-attachments (cont) "Tweak attached files as external parts." (let (filename-cons) - (when (and (eq (car cont) 'part) + (when (and (eq (car cont) 'part) (not (cdr (assq 'buffer cont))) (and (setq filename-cons (assq 'filename cont)) (not (equal (cdr (assq 'nofile cont)) "yes")))) diff --git a/lisp/mml1991.el b/lisp/mml1991.el index d91fb05..5ee1f4f 100644 --- a/lisp/mml1991.el +++ b/lisp/mml1991.el @@ -24,7 +24,7 @@ ;;; Commentary: -;; RCS: $Id: mml1991.el,v 1.1.1.1 2002-01-06 22:11:33 yamaoka Exp $ +;; RCS: $Id: mml1991.el,v 1.1.1.2 2002-05-06 23:49:24 yamaoka Exp $ ;;; Code: @@ -48,15 +48,15 @@ (defun mml1991-mailcrypt-sign (cont) (let ((text (current-buffer)) - headers signature - (result-buffer (get-buffer-create "*GPG Result*"))) + headers signature + (result-buffer (get-buffer-create "*GPG Result*"))) ;; Save MIME Content[^ ]+: headers from signing (goto-char (point-min)) (while (looking-at "^Content[^ ]+:") (forward-line)) (if (> (point) (point-min)) - (progn - (setq headers (buffer-substring (point-min) (point))) - (kill-region (point-min) (point)))) + (progn + (setq headers (buffer-substring (point-min) (point))) + (kill-region (point-min) (point)))) (goto-char (point-max)) (unless (bolp) (insert "\n")) @@ -83,13 +83,13 @@ (defun mml1991-mailcrypt-encrypt (cont) (let ((text (current-buffer)) cipher - (result-buffer (get-buffer-create "*GPG Result*"))) + (result-buffer (get-buffer-create "*GPG Result*"))) ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED (goto-char (point-min)) (while (looking-at "^Content[^ ]+:") (forward-line)) (if (> (point) (point-min)) - (progn - (kill-region (point-min) (point)))) + (progn + (kill-region (point-min) (point)))) (mm-with-unibyte-current-buffer-mule4 (with-temp-buffer (setq cipher (current-buffer)) @@ -110,10 +110,10 @@ (while (re-search-forward "\r+$" nil t) (replace-match "" t t)) (set-buffer text) - (kill-region (point-min) (point-max)) + (kill-region (point-min) (point-max)) ;;(insert "Content-Type: application/pgp-encrypted\n\n") ;;(insert "Version: 1\n\n") - (insert "\n") + (insert "\n") (insert-buffer cipher) (goto-char (point-max)))))) @@ -124,24 +124,24 @@ (defun mml1991-gpg-sign (cont) (let ((text (current-buffer)) - headers signature - (result-buffer (get-buffer-create "*GPG Result*"))) + headers signature + (result-buffer (get-buffer-create "*GPG Result*"))) ;; Save MIME Content[^ ]+: headers from signing (goto-char (point-min)) (while (looking-at "^Content[^ ]+:") (forward-line)) (if (> (point) (point-min)) - (progn - (setq headers (buffer-substring (point-min) (point))) - (kill-region (point-min) (point)))) + (progn + (setq headers (buffer-substring (point-min) (point))) + (kill-region (point-min) (point)))) (goto-char (point-max)) (unless (bolp) (insert "\n")) (quoted-printable-decode-region (point-min) (point-max)) (with-temp-buffer (unless (gpg-sign-cleartext text (setq signature (current-buffer)) - result-buffer - nil - (message-options-get 'message-sender)) + result-buffer + nil + (message-options-get 'message-sender)) (unless (> (point-max) (point-min)) (pop-to-buffer result-buffer) (error "Sign error"))) @@ -159,13 +159,13 @@ (defun mml1991-gpg-encrypt (cont) (let ((text (current-buffer)) cipher - (result-buffer (get-buffer-create "*GPG Result*"))) + (result-buffer (get-buffer-create "*GPG Result*"))) ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED (goto-char (point-min)) (while (looking-at "^Content[^ ]+:") (forward-line)) (if (> (point) (point-min)) - (progn - (kill-region (point-min) (point)))) + (progn + (kill-region (point-min) (point)))) (mm-with-unibyte-current-buffer-mule4 (with-temp-buffer (unless (gpg-sign-encrypt @@ -187,10 +187,10 @@ (while (re-search-forward "\r+$" nil t) (replace-match "" t t)) (set-buffer text) - (kill-region (point-min) (point-max)) + (kill-region (point-min) (point-max)) ;;(insert "Content-Type: application/pgp-encrypted\n\n") ;;(insert "Version: 1\n\n") - (insert "\n") + (insert "\n") (insert-buffer cipher) (goto-char (point-max)))))) diff --git a/lisp/mml2015.el b/lisp/mml2015.el index 5c88821..5e3fa2d 100644 --- a/lisp/mml2015.el +++ b/lisp/mml2015.el @@ -1,5 +1,5 @@ ;;; mml2015.el --- MIME Security with Pretty Good Privacy (PGP) -;; Copyright (C) 2000, 2001 Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu ;; Keywords: PGP MIME MML @@ -126,7 +126,11 @@ by you.") (setq handles (mm-dissect-buffer t))) (mm-destroy-parts handle) (mm-set-handle-multipart-parameter - mm-security-handle 'gnus-info "OK") + mm-security-handle 'gnus-info + (concat "OK" + (let ((sig (with-current-buffer mml2015-result-buffer + (mml2015-gpg-extract-signature-details)))) + (concat ", Signer: " sig)))) (if (listp (car handles)) handles (list handles))))) @@ -390,9 +394,9 @@ by you.") (defun mml2015-gpg-pretty-print-fpr (fingerprint) (let* ((result "") - (fpr-length (string-width fingerprint)) - (n-slice 0) - slice) + (fpr-length (string-width fingerprint)) + (n-slice 0) + slice) (setq fingerprint (string-to-list fingerprint)) (while fingerprint (setq fpr-length (- fpr-length 4)) @@ -400,13 +404,13 @@ by you.") (setq fingerprint (nthcdr 4 fingerprint)) (setq n-slice (1+ n-slice)) (setq result - (concat - result - (case n-slice - (1 slice) - (otherwise (concat " " slice)))))) + (concat + result + (case n-slice + (1 slice) + (otherwise (concat " " slice)))))) result)) - + (defun mml2015-gpg-extract-signature-details () (goto-char (point-min)) (if (boundp 'gpg-unabbrev-trust-alist) @@ -414,15 +418,17 @@ by you.") "^\\[GNUPG:\\] GOODSIG [0-9A-Za-z]* \\(.*\\)$" nil t) (match-string 1))) - (fprint (and (re-search-forward - "^\\[GNUPG:\\] VALIDSIG \\([0-9a-zA-Z]*\\) " - nil t) - (match-string 1))) - (trust (and (re-search-forward "^\\[GNUPG:\\] \\(TRUST_.*\\)$" nil t) - (match-string 1))) - (trust-good-enough-p - (cdr (assoc (cdr (assoc trust gpg-unabbrev-trust-alist)) - mml2015-trust-boundaries-alist)))) + (fprint (and (re-search-forward + "^\\[GNUPG:\\] VALIDSIG \\([0-9a-zA-Z]*\\) " + nil t) + (match-string 1))) + (trust (and (re-search-forward + "^\\[GNUPG:\\] \\(TRUST_.*\\)$" + nil t) + (match-string 1))) + (trust-good-enough-p + (cdr (assoc (cdr (assoc trust gpg-unabbrev-trust-alist)) + mml2015-trust-boundaries-alist)))) (if (and signer trust fprint) (concat signer (unless trust-good-enough-p @@ -475,20 +481,20 @@ by you.") (error (mm-set-handle-multipart-parameter mm-security-handle 'gnus-details (mml2015-format-error err)) - (mm-set-handle-multipart-parameter - mm-security-handle 'gnus-info "Error.") - (setq info-is-set-p t) + (mm-set-handle-multipart-parameter + mm-security-handle 'gnus-info "Error.") + (setq info-is-set-p t) nil) (quit (mm-set-handle-multipart-parameter mm-security-handle 'gnus-details "Quit.") - (mm-set-handle-multipart-parameter - mm-security-handle 'gnus-info "Quit.") - (setq info-is-set-p t) + (mm-set-handle-multipart-parameter + mm-security-handle 'gnus-info "Quit.") + (setq info-is-set-p t) nil)) - (unless info-is-set-p - (mm-set-handle-multipart-parameter - mm-security-handle 'gnus-info "Failed")) + (unless info-is-set-p + (mm-set-handle-multipart-parameter + mm-security-handle 'gnus-info "Failed")) (throw 'error handle))) (mm-set-handle-multipart-parameter mm-security-handle 'gnus-info diff --git a/lisp/netrc.el b/lisp/netrc.el new file mode 100644 index 0000000..3bfc76d --- /dev/null +++ b/lisp/netrc.el @@ -0,0 +1,128 @@ +;;; netrc.el --- .netrc parsing functionality +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +;; Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Modularizer: Ted Zlatanov +;; Keywords: news + +;; 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: + +;; Just the .netrc parsing functionality, abstracted so other packages +;; besides Gnus can use it. + +;;; Code: + +;;; +;;; .netrc and .authinforc parsing +;;; + +(eval-and-compile + (defalias 'netrc-point-at-eol + (if (fboundp 'point-at-eol) + 'point-at-eol + 'line-end-position))) + +(defun netrc-parse (file) + "Parse FILE and return an list of all entries in the file." + (when (file-exists-p file) + (with-temp-buffer + (let ((tokens '("machine" "default" "login" + "password" "account" "macdef" "force" + "port")) + alist elem result pair) + (insert-file-contents file) + (goto-char (point-min)) + ;; Go through the file, line by line. + (while (not (eobp)) + (narrow-to-region (point) (netrc-point-at-eol)) + ;; For each line, get the tokens and values. + (while (not (eobp)) + (skip-chars-forward "\t ") + ;; Skip lines that begin with a "#". + (if (eq (char-after) ?#) + (goto-char (point-max)) + (unless (eobp) + (setq elem + (if (= (following-char) ?\") + (read (current-buffer)) + (buffer-substring + (point) (progn (skip-chars-forward "^\t ") + (point))))) + (cond + ((equal elem "macdef") + ;; We skip past the macro definition. + (widen) + (while (and (zerop (forward-line 1)) + (looking-at "$"))) + (narrow-to-region (point) (point))) + ((member elem tokens) + ;; Tokens that don't have a following value are ignored, + ;; except "default". + (when (and pair (or (cdr pair) + (equal (car pair) "default"))) + (push pair alist)) + (setq pair (list elem))) + (t + ;; Values that haven't got a preceding token are ignored. + (when pair + (setcdr pair elem) + (push pair alist) + (setq pair nil))))))) + (when alist + (push (nreverse alist) result)) + (setq alist nil + pair nil) + (widen) + (forward-line 1)) + (nreverse result))))) + +(defun netrc-machine (list machine &optional port defaultport) + "Return the netrc values from LIST for MACHINE or for the default entry. +If PORT specified, only return entries with matching port tokens. +Entries without port tokens default to DEFAULTPORT." + (let ((rest list) + result) + (while list + (when (equal (cdr (assoc "machine" (car list))) machine) + (push (car list) result)) + (pop list)) + (unless result + ;; No machine name matches, so we look for default entries. + (while rest + (when (assoc "default" (car rest)) + (push (car rest) result)) + (pop rest))) + (when result + (setq result (nreverse result)) + (while (and result + (not (equal (or port defaultport "nntp") + (or (netrc-get (car result) "port") + defaultport "nntp")))) + (pop result)) + (car result)))) + +(defun netrc-get (alist type) + "Return the value of token TYPE from ALIST." + (cdr (assoc type alist))) + +(provide 'netrc) + +;;; netrc.el ends here diff --git a/lisp/nnagent.el b/lisp/nnagent.el index c77b91f..21b9f97 100644 --- a/lisp/nnagent.el +++ b/lisp/nnagent.el @@ -130,30 +130,35 @@ (deffoo nnagent-retrieve-headers (articles &optional group server fetch-old) (let ((file (gnus-agent-article-name ".overview" group)) - arts n) + arts n first) (save-excursion (gnus-agent-load-alist group) - (setq arts (gnus-set-difference articles - (mapcar 'car gnus-agent-article-alist))) + (setq arts (gnus-sorted-difference + articles (mapcar 'car gnus-agent-article-alist))) + ;; Assume that articles with smaller numbers than the first one + ;; Agent knows are gone. + (setq first (caar gnus-agent-article-alist)) + (when first + (while (and arts (< (car arts) first)) + (pop arts))) (set-buffer nntp-server-buffer) (erase-buffer) - (nnheader-insert-file-contents file) - (goto-char (point-min)) - (while (and arts (not (eobp))) - (cond - ((looking-at "[0-9]") + (nnheader-insert-nov-file file (car articles)) + (goto-char (point-min)) + (gnus-parse-without-error + (while (and arts (not (eobp))) (setq n (read (current-buffer))) - (if (> n (car arts)) - (beginning-of-line)) + (when (> n (car arts)) + (beginning-of-line)) (while (and arts (> n (car arts))) - (insert (format + (insert (format "%d\t[Undownloaded article %d]\tGnus Agent\t\t\t\n" (car arts) (car arts))) (pop arts)) - (if (and arts (= n (car arts))) - (pop arts)))) - (forward-line 1)) - (while (and arts) + (when (and arts (= n (car arts))) + (pop arts)) + (forward-line 1))) + (while arts (insert (format "%d\t[Undownloaded article %d]\tGnus Agent\t\t\t\n" (car arts) (car arts))) @@ -168,6 +173,9 @@ t) 'nov))) +(deffoo nnagent-request-expire-articles (articles group &optional server force) + articles) + (deffoo nnagent-request-group (group &optional server dont-check) (nnoo-parent-function 'nnagent 'nnml-request-group (list group (nnagent-server server) dont-check))) @@ -192,10 +200,6 @@ (nnoo-parent-function 'nnagent 'nnml-request-delete-group (list group force (nnagent-server server)))) -(deffoo nnagent-request-expire-articles (articles group &optional server force) - (nnoo-parent-function 'nnagent 'nnml-request-expire-articles - (list articles group (nnagent-server server) force))) - (deffoo nnagent-request-list (&optional server) (nnoo-parent-function 'nnagent 'nnml-request-list (list (nnagent-server server)))) diff --git a/lisp/nnbabyl.el b/lisp/nnbabyl.el index b9acfe6..e4dbed2 100644 --- a/lisp/nnbabyl.el +++ b/lisp/nnbabyl.el @@ -4,7 +4,7 @@ ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news, mail ;; This file is part of GNU Emacs. diff --git a/lisp/nndoc.el b/lisp/nndoc.el index 0f73e10..51d83ef 100644 --- a/lisp/nndoc.el +++ b/lisp/nndoc.el @@ -1,9 +1,9 @@ ;;; nndoc.el --- single file access for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news ;; This file is part of GNU Emacs. @@ -44,7 +44,7 @@ One of `mbox', `babyl', `digest', `news', `rnews', `mmdf', `forward', `rfc934', `rfc822-forward', `mime-parts', `standard-digest', `slack-digest', `clari-briefs', `nsmail', `outlook', `oe-dbx', -`mailman' or `guess'.") +`mailman', `exim-bounce', or `guess'.") (defvoo nndoc-post-type 'mail "*Whether the nndoc group is `mail' or `post'.") @@ -58,6 +58,9 @@ from the document.") `((mmdf (article-begin . "^\^A\^A\^A\^A\n") (body-end . "^\^A\^A\^A\^A\n")) + (exim-bounce + (article-begin . "^------ This is a copy of the message, including all the headers. ------\n\n") + (body-end-function . nndoc-exim-bounce-body-end-function)) (nsmail (article-begin . "^From - ")) (news @@ -120,8 +123,8 @@ from the document.") (head-begin . "^Paper.*:") (head-end . "\\(^\\\\\\\\.*\n\\|-----------------\\)") (body-begin . "") - (body-end . "-------------------------------------------------") - (file-end . "^Title: Recent Seminal") + (body-end . "\\(-------------------------------------------------\\|%-%-%-%-%-%-%-%-%-%-%-%-%-%-\\|%%--%%--%%--%%--%%--%%--%%--%%--\\|%%%---%%%---%%%---%%%---\\)") + (file-end . "\\(^Title: Recent Seminal\\|%%%---%%%---%%%---%%%---\\)") (generate-head-function . nndoc-generate-lanl-gov-head) (article-transform-function . nndoc-transform-lanl-gov-announce) (subtype preprints guess)) @@ -139,6 +142,8 @@ from the document.") (article-begin . "^-+ \\(Start of \\)?forwarded message.*\n+") (body-end . "^-+ End \\(of \\)?forwarded message.*$") (prepare-body-function . nndoc-unquote-dashes)) + (mail-in-mail ;; Wild guess on mailer daemon's messages or others + (article-begin-function . nndoc-mail-in-mail-article-begin)) (guess (guess . t) (subtype nil)) @@ -229,7 +234,7 @@ from the document.") (set-buffer buffer) (erase-buffer) (when entry - (cond + (cond ((stringp article) nil) (nndoc-generate-article-function (funcall nndoc-generate-article-function article)) @@ -547,6 +552,13 @@ from the document.") (insert "From: " "clari@clari.net (" (or from "unknown") ")" "\nSubject: " (or subject "(no subject)") "\n"))) +(defun nndoc-exim-bounce-type-p () + (and (re-search-forward "^------ This is a copy of the message, including all the headers. ------" nil t) + t)) + +(defun nndoc-exim-bounce-body-end-function () + (goto-char (point-max))) + (defun nndoc-mime-digest-type-p () (let ((case-fold-search t) @@ -585,35 +597,54 @@ from the document.") (defun nndoc-lanl-gov-announce-type-p () (when (let ((case-fold-search nil)) - (re-search-forward "^\\\\\\\\\nPaper: [a-z-]+/[0-9]+" nil t)) + (re-search-forward "^\\\\\\\\\nPaper\\( (\\*cross-listing\\*)\\)?: [a-zA-Z-\\.]+/[0-9]+" nil t)) t)) (defun nndoc-transform-lanl-gov-announce (article) (goto-char (point-max)) - (when (re-search-backward "^\\\\\\\\ +(\\([^ ]*\\) , *\\([^ ]*\\))" nil t) - (replace-match "\n\nGet it at \\1 (\\2)" t nil))) + (when (re-search-backward "^\\\\\\\\ +( *\\([^ ]*\\) , *\\([^ ]*\\))" nil t) + (replace-match "\n\nGet it at \\1 (\\2)" t nil)) + (goto-char (point-min)) + (while (re-search-forward "^\\\\\\\\$" nil t) + (replace-match "" t nil)) + (goto-char (point-min)) + (when (re-search-forward "^replaced with revised version +\\(.*[^ ]\\) +" nil t) + (replace-match "Date: \\1 (revised) " t nil)) + (goto-char (point-min)) + (unless (re-search-forward "^From" nil t) + (goto-char (point-min)) + (when (re-search-forward "^Authors?: \\(.*\\)" nil t) + (goto-char (point-min)) + (insert "From: " (match-string 1) "\n")))) (defun nndoc-generate-lanl-gov-head (article) (let ((entry (cdr (assq article nndoc-dissection-alist))) - (e-mail "no address given") - subject from) + (from "") + subject date) (save-excursion (set-buffer nndoc-current-buffer) (save-restriction - (narrow-to-region (car entry) (nth 1 entry)) - (goto-char (point-min)) - (when (looking-at "^Paper.*: \\([a-z-]+/[0-9]+\\)") - (setq subject (concat " (" (match-string 1) ")")) - (when (re-search-forward "^From: \\([^ ]+\\)" nil t) - (setq e-mail (match-string 1))) - (when (re-search-forward "^Title: \\([^\f]*\\)\nAuthors?: \\(.*\\)" - nil t) - (setq subject (concat (match-string 1) subject)) - (setq from (concat (match-string 2) " <" e-mail ">")))))) + (narrow-to-region (car entry) (nth 1 entry)) + (goto-char (point-min)) + (when (looking-at "^Paper.*: \\([a-zA-Z-\\.]+/[0-9]+\\)") + (setq subject (concat " (" (match-string 1) ")")) + (when (re-search-forward "^From: \\(.*\\)" nil t) + (setq from (concat "<" + (cadr (funcall gnus-extract-address-components + (match-string 1))) ">"))) + (if (re-search-forward "^Date: +\\([^(]*\\)" nil t) + (setq date (match-string 1)) + (when (re-search-forward "^replaced with revised version +\\([^(]*\\)" nil t) + (setq date (match-string 1)))) + (when (re-search-forward "^Title: \\([^\f]*\\)\nAuthors?: \\(.*\\)" + nil t) + (setq subject (concat (match-string 1) subject)) + (setq from (concat (match-string 2) " " from)))))) (while (and from (string-match "(\[^)\]*)" from)) (setq from (replace-match "" t t from))) (insert "From: " (or from "unknown") - "\nSubject: " (or subject "(no subject)") "\n"))) + "\nSubject: " (or subject "(no subject)") "\n") + (if date (insert "Date: " date)))) (defun nndoc-nsmail-type-p () (when (looking-at "From - ") @@ -693,6 +724,37 @@ from the document.") (defun nndoc-oe-dbx-generate-head (article) (nndoc-oe-dbx-generate-article article 'head)) +(defun nndoc-mail-in-mail-type-p () + (let (found) + (save-excursion + (catch 'done + (while (re-search-forward "\n\n[-A-Za-z0-9]+:" nil t) + (setq found 0) + (forward-line) + (while (looking-at "[ \t]\\|[-A-Za-z0-9]+:") + (if (looking-at "[-A-Za-z0-9]+:") + (setq found (1+ found))) + (forward-line)) + (if (and (> found 0) (looking-at "\n")) + (throw 'done 9999))) + nil)))) + +(defun nndoc-mail-in-mail-article-begin () + (let (point found) + (if (catch 'done + (while (re-search-forward "\n\n\\([-A-Za-z0-9]+:\\)" nil t) + (setq found 0) + (setq point (match-beginning 1)) + (forward-line) + (while (looking-at "[ \t]\\|[-A-Za-z0-9]+:") + (if (looking-at "[-A-Za-z0-9]+:") + (setq found (1+ found))) + (forward-line)) + (if (and (> found 0) (looking-at "\n")) + (throw 'done t))) + nil) + (goto-char point)))) + (deffoo nndoc-request-accept-article (group &optional server last) nil) @@ -830,6 +892,10 @@ PARENT is the message-ID of the parent summary line, or nil for none." (unless article-insert (setq article-insert (buffer-substring (point-min) (point-max)) head-end head-begin)) + ;; Fix MIME-Version + (unless (string-match "MIME-Version:" article-insert) + (setq article-insert + (concat article-insert "MIME-Version: 1.0\n"))) (setq summary-insert article-insert) ;; - summary Subject. (setq summary-insert diff --git a/lisp/nneething.el b/lisp/nneething.el index 9c30970..e013acb 100644 --- a/lisp/nneething.el +++ b/lisp/nneething.el @@ -4,7 +4,7 @@ ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news, mail ;; This file is part of GNU Emacs. @@ -64,7 +64,6 @@ included.") (defvoo nneething-status-string "") -(defvoo nneething-message-id-number 0) (defvoo nneething-work-buffer " *nneething work*") (defvoo nneething-group nil) @@ -289,7 +288,7 @@ included.") (let ((pos 0) buf) (setq file (mm-encode-coding-string file (or coding-system nnmail-pathname-coding-system))) - (while (string-match "[^-a-zA-Z_:/.]" file pos) + (while (string-match "[^-0-9a-zA-Z_:/.]" file pos) (setq buf (cons (format "%%%02x" (aref file (match-beginning 0))) (cons (substring file pos (match-beginning 0)) buf)) pos (match-end 0))) @@ -310,7 +309,7 @@ included.") (defun nneething-get-file-name (id) "Extract the file name from the message ID string." - (when (string-match "\\`\\'" id) + (when (string-match "\\`\\'" id) (nneething-decode-file-name (match-string 1 id)))) (defun nneething-make-head (file &optional buffer extra-msg @@ -319,9 +318,7 @@ included.") (let ((atts (file-attributes file))) (insert "Subject: " (file-name-nondirectory file) (or extra-msg "") "\n" - "Message-ID: \n" (if (equal '(0 0) (nth 5 atts)) "" (concat "Date: " (current-time-string (nth 5 atts)) "\n")) @@ -425,7 +422,7 @@ included.") (if (numberp article) (if (setq fname (cadr (assq article nneething-map))) (expand-file-name fname dir) - (make-temp-name (expand-file-name "nneething" dir))) + (mm-make-temp-file (expand-file-name "nneething" dir))) (expand-file-name article dir)))) (provide 'nneething) diff --git a/lisp/nnfolder.el b/lisp/nnfolder.el index 0715110..36826ac 100644 --- a/lisp/nnfolder.el +++ b/lisp/nnfolder.el @@ -1,12 +1,12 @@ ;;; nnfolder.el --- mail folder access for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Simon Josefsson (adding MARKS) ;; ShengHuo Zhu (adding NOV) ;; Scott Byer ;; Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: mail ;; This file is part of GNU Emacs. @@ -428,7 +428,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") (nnfolder-save-buffer) (nnfolder-adjust-min-active newsgroup) (nnfolder-save-active nnfolder-group-alist nnfolder-active-file) - (gnus-sorted-complement articles (nreverse deleted-articles))))) + (gnus-sorted-difference articles (nreverse deleted-articles))))) (deffoo nnfolder-request-move-article (article group server accept-form &optional last) @@ -473,6 +473,8 @@ the group. Then the marks file will be regenerated properly by Gnus.") result art-group) (goto-char (point-min)) (when (looking-at "X-From-Line: ") + (save-match-data + (mail-header-unfold-field)) (replace-match "From ")) (with-temp-buffer (let ((nnmail-file-coding-system nnfolder-active-file-coding-system) @@ -513,15 +515,13 @@ the group. Then the marks file will be regenerated properly by Gnus.") (save-excursion (set-buffer buffer) (goto-char (point-min)) - (let (xfrom) - (while (re-search-forward "^X-From-Line: \\(.*\\)$" nil t) - (setq xfrom (match-string 1)) - (gnus-delete-line)) - (goto-char (point-min)) - (if xfrom - (insert "From " xfrom "\n") - (unless (looking-at "From ") - (insert "From nobody " (current-time-string) "\n")))) + (if (not (looking-at "X-From-Line: ")) + (insert "From nobody " (current-time-string) "\n") + (replace-match "From ") + (forward-line 1) + (while (looking-at "[ \t]") + (delete-char -1) + (forward-line 1))) (nnfolder-normalize-buffer) (set-buffer nnfolder-current-buffer) (goto-char (point-min)) @@ -547,12 +547,12 @@ the group. Then the marks file will be regenerated properly by Gnus.") (if (not force) () ; Don't delete the articles. ;; Delete the file that holds the group. - (ignore-errors - (delete-file (nnfolder-group-pathname group)) - (when (file-exists-p (nnfolder-group-nov-pathname group)) - (delete-file (nnfolder-group-nov-pathname group))) - (when (file-exists-p (nnfolder-group-marks-pathname group)) - (delete-file (nnfolder-group-marks-pathname group))))) + (let ((data (nnfolder-group-pathname group)) + (nov (nnfolder-group-nov-pathname group)) + (mrk (nnfolder-group-marks-pathname group))) + (ignore-errors (delete-file data)) + (ignore-errors (delete-file nov)) + (ignore-errors (delete-file mrk)))) ;; Remove the group from all structures. (setq nnfolder-group-alist (delq (assoc group nnfolder-group-alist) nnfolder-group-alist) @@ -711,7 +711,8 @@ deleted. Point is left where the deleted region was." (let ((nnmail-file-coding-system (or nnfolder-file-coding-system-for-write nnfolder-file-coding-system-for-write))) - (nnmail-write-region 1 1 file t 'nomesg))) + (nnmail-write-region (point-min) (point-min) + file t 'nomesg))) (when (setq nnfolder-current-buffer (nnfolder-read-folder group)) (set-buffer nnfolder-current-buffer) (push (list group nnfolder-current-buffer) @@ -1214,7 +1215,7 @@ This command does not work if you use short group names." (if (file-exists-p file) (condition-case err (with-temp-buffer - (gnus-sethash file (nth 5 (file-attributes file)) + (gnus-sethash file (nth 5 (file-attributes file)) nnfolder-marks-modtime) (nnheader-insert-file-contents file) (setq nnfolder-marks (read (current-buffer))) @@ -1234,7 +1235,8 @@ This command does not work if you use short group names." (push (cons 'read (gnus-info-read info)) nnfolder-marks) (dolist (el gnus-article-unpropagated-mark-lists) (setq nnfolder-marks (gnus-remassoc el nnfolder-marks))) - (nnfolder-save-marks group server))))) + (nnfolder-save-marks group server) + (nnheader-message 7 "Bootstrapping marks for %s...done" group))))) (provide 'nnfolder) diff --git a/lisp/nnheader.el b/lisp/nnheader.el index bbcc672..ee93eec 100644 --- a/lisp/nnheader.el +++ b/lisp/nnheader.el @@ -1,11 +1,11 @@ ;;; nnheader.el --- header access macros for Gnus and its backends ;; Copyright (C) 1987, 1988, 1989, 1990, 1993, 1994, 1995, 1996, -;; 1997, 1998, 2000, 2001 +;; 1997, 1998, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Masanobu UMEDA -;; Lars Magne Ingebrigtsen +;; Lars Magne Ingebrigtsen ;; Keywords: news ;; This file is part of GNU Emacs. @@ -40,7 +40,8 @@ (eval-and-compile (autoload 'gnus-sorted-intersection "gnus-range") (autoload 'gnus-intersection "gnus-range") - (autoload 'gnus-sorted-complement "gnus-range")) + (autoload 'gnus-sorted-complement "gnus-range") + (autoload 'gnus-sorted-difference "gnus-range")) (defcustom gnus-verbose-backends 7 "Integer that says how verbose the Gnus backends should be. @@ -399,6 +400,22 @@ on your system, you could say something like: (delete-char 1)) (forward-line 1))) +(defun nnheader-parse-overview-file (file) + "Parse FILE and return a list of headers." + (mm-with-unibyte-buffer + (nnheader-insert-file-contents file) + (goto-char (point-min)) + (let (headers) + (while (not (eobp)) + (push (nnheader-parse-nov) headers) + (forward-line 1)) + (nreverse headers)))) + +(defun nnheader-write-overview-file (file headers) + "Write HEADERS to FILE." + (with-temp-file file + (mapcar 'nnheader-insert-nov headers))) + (defun nnheader-insert-header (header) (insert "Subject: " (or (mail-header-subject header) "(none)") "\n" @@ -859,6 +876,25 @@ find-file-hooks, etc. (let ((coding-system-for-read nnheader-file-coding-system)) (mm-insert-file-contents filename visit beg end replace))) +(defun nnheader-insert-nov-file (file first) + (let ((size (nth 7 (file-attributes file))) + (cutoff (* 32 1024))) + (if (< size cutoff) + ;; If the file is small, we just load it. + (nnheader-insert-file-contents file) + ;; We start on the assumption that FIRST is pretty recent. If + ;; not, we just insert the rest of the file as well. + (let (current) + (nnheader-insert-file-contents file nil (- size cutoff) size) + (goto-char (point-min)) + (delete-region (point) (or (search-forward "\n" nil 'move) (point))) + (setq current (ignore-errors (read (current-buffer)))) + (if (and (numberp current) + (< current first)) + t + (delete-region (point-min) (point-max)) + (nnheader-insert-file-contents file)))))) + (defun nnheader-find-file-noselect (&rest args) (let ((format-alist nil) (auto-mode-alist (mm-auto-mode-alist)) diff --git a/lisp/nnimap.el b/lisp/nnimap.el index 0d9fd9b..b089e16 100644 --- a/lisp/nnimap.el +++ b/lisp/nnimap.el @@ -172,7 +172,7 @@ group/function elements." (nnimap-strict-function :tag "User-defined function")) (repeat :menu-tag "Multi-server (extended)" :tag "Multi-server list" - (list (regexp :tag "Server regexp") + (list (regexp :tag "Server regexp") (list (regexp :tag "Incoming Mailbox regexp") (repeat :tag "Rules for matching server(s) and mailbox(es)" (list (string :tag "Destination mailbox") @@ -190,7 +190,7 @@ RFC2060 section 6.4.4." :type 'string) (defcustom nnimap-split-fancy nil - "Like `nnmail-split-fancy', which see." + "Like the variable `nnmail-split-fancy', which see." :group 'nnimap :type 'sexp) @@ -212,6 +212,18 @@ the same mailbox will be faster though." :type 'boolean :group 'nnimap) +(defcustom nnimap-retrieve-groups-asynchronous t + "Send asynchronous STATUS commands for each mailbox before checking mail. +If you have mailboxes that rarely receives mail, this speeds up new +mail checking. It works by first sending STATUS commands for each +mailbox, and then only checking groups which has a modified UIDNEXT +more carefully for new mail. + +In summary, the default is O((1-p)*k+p*n) and changing it to nil makes +it O(n). If p is small, then the default is probably faster." + :type 'boolean + :group 'nnimap) + (defvoo nnimap-need-unselect-to-notice-new-mail nil "Unselect mailboxes before looking for new mail in them. Some servers seem to need this under some circumstances.") @@ -365,6 +377,7 @@ restrict visible folders.") ;; Internal variables: +(defvoo nnimap-mailbox-info (gnus-make-hashtable 997)) (defvar nnimap-debug nil "Name of buffer to record debugging info. For example: (setq nnimap-debug \"*nnimap-debug*\")") @@ -657,7 +670,7 @@ If EXAMINE is non-nil the group is selected read-only." (nnimap-retrieve-headers-from-server (cons (1+ (cdr cached)) high) group server)) (when nnimap-prune-cache - ;; remove nov's for articles which has expired on server + ;; remove nov's for articles which has expired on server (goto-char (point-min)) (dolist (uid (gnus-set-difference articles uids)) (when (re-search-forward (format "^%d\t" uid) nil t) @@ -667,8 +680,8 @@ If EXAMINE is non-nil the group is selected read-only." (cons low high) group server)) (when (buffer-modified-p) (nnmail-write-region - 1 (point-max) (nnimap-group-overview-filename group server) - nil 'nomesg)) + (point-min) (point-max) + (nnimap-group-overview-filename group server) nil 'nomesg)) (nnheader-nov-delete-outside-range low high)))) 'nov))) @@ -925,24 +938,74 @@ function is generally only called when Gnus is shutting down." ;; Optional backend functions +(defun nnimap-string-lessp-numerical (s1 s2) + "Return t if first arg string is less than second in numerical order." + (cond ((string= s1 s2) + nil) + ((> (length s1) (length s2)) + nil) + ((< (length s1) (length s2)) + t) + ((< (string-to-number (substring s1 0 1)) + (string-to-number (substring s2 0 1))) + t) + ((> (string-to-number (substring s1 0 1)) + (string-to-number (substring s2 0 1))) + nil) + (t + (nnimap-string-lessp-numerical (substring s1 1) (substring s2 1))))) + (deffoo nnimap-retrieve-groups (groups &optional server) (when (nnimap-possibly-change-server server) (gnus-message 5 "nnimap: Checking mailboxes...") (with-current-buffer nntp-server-buffer (erase-buffer) (nnimap-before-find-minmax-bugworkaround) - (dolist (group groups) - (gnus-message 7 "nnimap: Checking mailbox %s" group) - (or (member "\\NoSelect" - (imap-mailbox-get 'list-flags group nnimap-server-buffer)) - (let ((info (nnimap-find-minmax-uid group 'examine))) - (when (> (or (imap-mailbox-get 'recent group - nnimap-server-buffer) 0) - 0) - (push (list (cons group 0)) nnmail-split-history)) - (insert (format "\"%s\" %d %d y\n" group - (or (nth 2 info) 0) - (max 1 (or (nth 1 info) 1)))))))) + (let (asyncgroups slowgroups) + (if (null nnimap-retrieve-groups-asynchronous) + (setq slowgroups groups) + (dolist (group groups) + (gnus-message 7 "nnimap: Checking mailbox %s" group) + (add-to-list (if (gnus-gethash-safe group nnimap-mailbox-info) + 'asyncgroups + 'slowgroups) + (list group (imap-mailbox-status-asynch + group 'uidnext nnimap-server-buffer)))) + (dolist (asyncgroup asyncgroups) + (let ((group (nth 0 asyncgroup)) + (tag (nth 1 asyncgroup)) + new old) + (when (imap-ok-p (imap-wait-for-tag tag nnimap-server-buffer)) + (if (nnimap-string-lessp-numerical + (car (gnus-gethash group nnimap-mailbox-info)) + (imap-mailbox-get 'uidnext group nnimap-server-buffer)) + (push (list group) slowgroups) + (insert (cdr (gnus-gethash group nnimap-mailbox-info)))))))) + (dolist (group slowgroups) + (if nnimap-retrieve-groups-asynchronous + (setq group (car group))) + (gnus-message 7 "nnimap: Rechecking mailbox %s" group) + (imap-mailbox-put 'uidnext nil group nnimap-server-buffer) + (or (member "\\NoSelect" (imap-mailbox-get 'list-flags group + nnimap-server-buffer)) + (let* ((info (nnimap-find-minmax-uid group 'examine)) + (str (format "\"%s\" %d %d y\n" group + (or (nth 2 info) 0) + (max 1 (or (nth 1 info) 1))))) + (when (> (or (imap-mailbox-get 'recent group + nnimap-server-buffer) 0) + 0) + (push (list (cons group 0)) nnmail-split-history)) + (insert str) + (when nnimap-retrieve-groups-asynchronous + (gnus-sethash + group + (cons (or (imap-mailbox-get + 'uidnext group nnimap-server-buffer) + (imap-mailbox-status + group 'uidnext nnimap-server-buffer)) + str) + nnimap-mailbox-info))))))) (gnus-message 5 "nnimap: Checking mailboxes...done") 'active)) @@ -991,7 +1054,7 @@ function is generally only called when Gnus is shutting down." gnus-article-mark-lists) (when nnimap-importantize-dormant - ;; nnimap mark dormant article as ticked too (for other clients) + ;; nnimap mark dormant article as ticked too (for other clients) ;; so we remove that mark for gnus since we support dormant (gnus-info-set-marks info @@ -1062,7 +1125,7 @@ function is generally only called when Gnus is shutting down." nil) (defun nnimap-split-fancy () - "Like nnmail-split-fancy, but uses nnimap-split-fancy." + "Like the function `nnmail-split-fancy', but uses `nnimap-split-fancy'." (let ((nnmail-split-fancy nnimap-split-fancy)) (nnmail-split-fancy))) @@ -1087,7 +1150,7 @@ function is generally only called when Gnus is shutting down." (setq regrepp (string-match "\\\\[0-9&]" group)) (re-search-forward regexp nil t)) (funcall regexp group)) - ;; Don't enter the article into the same group twice. + ;; Don't enter the article into the same group twice. (not (assoc group to-groups))) (push (if regrepp (nnmail-expand-newtext group) @@ -1141,6 +1204,10 @@ function is generally only called when Gnus is shutting down." (message "IMAP split moved %s:%s:%d to %s" server inbox article to-group) (setq removeorig t) + (when nnmail-cache-accepted-message-ids + (with-current-buffer nntp-server-buffer + (nnmail-cache-insert (nnmail-fetch-field + "message-id") to-group))) ;; Add the group-art list to the history list. (push (list (cons to-group 0)) nnmail-split-history)) (t @@ -1154,6 +1221,8 @@ function is generally only called when Gnus is shutting down." ;; todo: UID EXPUNGE (if available) to remove splitted articles (imap-mailbox-expunge) (imap-mailbox-close))) + (when nnmail-cache-accepted-message-ids + (nnmail-cache-close)) t)))) (deffoo nnimap-request-scan (&optional group server) @@ -1214,7 +1283,6 @@ function is generally only called when Gnus is shutting down." (gnus-message 5 "nnimap: Marking article %d for deletion..." imap-current-message)) - (defun nnimap-expiry-target (arts group server) (unless (eq nnmail-expiry-target 'delete) (with-temp-buffer @@ -1293,7 +1361,7 @@ function is generally only called when Gnus is shutting down." (let (uid) (if (setq uid (if (string= nnimap-current-server nnimap-current-move-server) - ;; moving article within same server, speed it up... + ;; moving article within same server, speed it up... (and (nnimap-possibly-change-group nnimap-current-move-group) (imap-message-copy (number-to-string @@ -1302,13 +1370,17 @@ function is generally only called when Gnus is shutting down." nnimap-server-buffer)) (with-current-buffer (current-buffer) (goto-char (point-min)) - ;; remove any 'From blabla' lines, some IMAP servers + ;; remove any 'From blabla' lines, some IMAP servers ;; reject the entire message otherwise. (when (looking-at "^From[^:]") (kill-region (point) (progn (forward-line) (point)))) ;; turn into rfc822 format (\r\n eol's) (while (search-forward "\n" nil t) - (replace-match "\r\n"))) + (replace-match "\r\n")) + (when nnmail-cache-accepted-message-ids + (nnmail-cache-insert (nnmail-fetch-field "message-id")))) + (when (and last nnmail-cache-accepted-message-ids) + (nnmail-cache-close)) ;; this 'or' is for Cyrus server bug (or (null (imap-current-mailbox nnimap-server-buffer)) (imap-mailbox-unselect nnimap-server-buffer)) diff --git a/lisp/nnkiboze.el b/lisp/nnkiboze.el index bc33cf9..110cc7c 100644 --- a/lisp/nnkiboze.el +++ b/lisp/nnkiboze.el @@ -1,6 +1,6 @@ ;;; nnkiboze.el --- select virtual news access for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -114,6 +114,7 @@ (gnus-request-article num group buffer))))) (deffoo nnkiboze-request-scan (&optional group server) + (nnkiboze-possibly-change-group group) (nnkiboze-generate-group (concat "nnkiboze:" group))) (deffoo nnkiboze-request-group (group &optional server dont-check) @@ -249,108 +250,110 @@ Finds out what articles are to be part of the nnkiboze groups." (unless info (error "No such group: %s" group)) ;; Load the kiboze newsrc file for this group. - (when (file-exists-p newsrc-file) - (load newsrc-file)) - (let ((coding-system-for-write nnkiboze-file-coding-system)) - (gnus-make-directory (file-name-directory nov-file)) - (with-temp-file nov-file - (when (file-exists-p nov-file) - (insert-file-contents nov-file)) - (setq nov-buffer (current-buffer)) - ;; Go through the active hashtb and add new all groups that match the - ;; kiboze regexp. - (mapatoms - (lambda (group) - (and (string-match nnkiboze-regexp - (setq gname (symbol-name group))) ; Match - (not (assoc gname nnkiboze-newsrc)) ; It isn't registered - (numberp (car (symbol-value group))) ; It is active - (or (> nnkiboze-level 7) - (and (setq glevel (nth 1 (nth 2 (gnus-gethash - gname gnus-newsrc-hashtb)))) - (>= nnkiboze-level glevel))) - (not (string-match "^nnkiboze:" gname)) ; Exclude kibozes - (push (cons gname (1- (car (symbol-value group)))) - nnkiboze-newsrc))) - gnus-active-hashtb) - ;; `newsrc' is set to the list of groups that possibly are - ;; component groups to this kiboze group. This list has elements - ;; on the form `(GROUP . NUMBER)', where NUMBER is the highest - ;; number that has been kibozed in GROUP in this kiboze group. - (setq newsrc nnkiboze-newsrc) - (while newsrc - (if (not (setq active (gnus-gethash - (caar newsrc) gnus-active-hashtb))) - ;; This group isn't active after all, so we remove it from - ;; the list of component groups. - (setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc)) - (setq lowest (cdar newsrc)) - ;; Ok, we have a valid component group, so we jump to it. - (switch-to-buffer gnus-group-buffer) - (gnus-group-jump-to-group (caar newsrc)) - (gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc)) - (setq ginfo (gnus-get-info (gnus-group-group-name)) - orig-info (gnus-copy-sequence ginfo) - num-unread (car (gnus-gethash (caar newsrc) - gnus-newsrc-hashtb))) - (unwind-protect - (progn - ;; We set all list of article marks to nil. Since we operate - ;; on copies of the real lists, we can destroy anything we - ;; want here. - (when (nth 3 ginfo) - (setcar (nthcdr 3 ginfo) nil)) - ;; We set the list of read articles to be what we expect for - ;; this kiboze group -- either nil or `(1 . LOWEST)'. - (when ginfo - (setcar (nthcdr 2 ginfo) - (and (not (= lowest 1)) (cons 1 lowest)))) - (when (and (or (not ginfo) - (> (length (gnus-list-of-unread-articles - (car ginfo))) - 0)) - (progn - (ignore-errors - (gnus-group-select-group nil)) - (eq major-mode 'gnus-summary-mode))) - ;; We are now in the group where we want to be. - (setq method (gnus-find-method-for-group - gnus-newsgroup-name)) - (when (eq method gnus-select-method) - (setq method nil)) - ;; We go through the list of scored articles. - (while gnus-newsgroup-scored - (when (> (caar gnus-newsgroup-scored) lowest) - ;; If it has a good score, then we enter this article - ;; into the kiboze group. - (nnkiboze-enter-nov - nov-buffer - (gnus-summary-article-header - (caar gnus-newsgroup-scored)) - gnus-newsgroup-name)) - (setq gnus-newsgroup-scored (cdr gnus-newsgroup-scored))) - ;; That's it. We exit this group. - (when (eq major-mode 'gnus-summary-mode) - (kill-buffer (current-buffer))))) - ;; Restore the proper info. - (when ginfo - (setcdr ginfo (cdr orig-info))) - (setcar (gnus-gethash (caar newsrc) gnus-newsrc-hashtb) - num-unread))) - (setcdr (car newsrc) (car active)) - (gnus-message 3 "nnkiboze: Checking %s...done" (caar newsrc)) - (setq newsrc (cdr newsrc))))) - ;; We save the kiboze newsrc for this group. - (gnus-make-directory (file-name-directory newsrc-file)) - (with-temp-file newsrc-file - (insert "(setq nnkiboze-newsrc '") - (gnus-prin1 nnkiboze-newsrc) - (insert ")\n"))) + (mm-with-unibyte + (when (file-exists-p newsrc-file) + (load newsrc-file)) + (let ((coding-system-for-write nnkiboze-file-coding-system)) + (gnus-make-directory (file-name-directory nov-file)) + (with-temp-file nov-file + (when (file-exists-p nov-file) + (insert-file-contents nov-file)) + (setq nov-buffer (current-buffer)) + ;; Go through the active hashtb and add new all groups that match the + ;; kiboze regexp. + (mapatoms + (lambda (group) + (and (string-match nnkiboze-regexp + (setq gname (symbol-name group))) ; Match + (not (assoc gname nnkiboze-newsrc)) ; It isn't registered + (numberp (car (symbol-value group))) ; It is active + (or (> nnkiboze-level 7) + (and (setq glevel + (nth 1 (nth 2 (gnus-gethash + gname gnus-newsrc-hashtb)))) + (>= nnkiboze-level glevel))) + (not (string-match "^nnkiboze:" gname)) ; Exclude kibozes + (push (cons gname (1- (car (symbol-value group)))) + nnkiboze-newsrc))) + gnus-active-hashtb) + ;; `newsrc' is set to the list of groups that possibly are + ;; component groups to this kiboze group. This list has elements + ;; on the form `(GROUP . NUMBER)', where NUMBER is the highest + ;; number that has been kibozed in GROUP in this kiboze group. + (setq newsrc nnkiboze-newsrc) + (while newsrc + (if (not (setq active (gnus-gethash + (caar newsrc) gnus-active-hashtb))) + ;; This group isn't active after all, so we remove it from + ;; the list of component groups. + (setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc)) + (setq lowest (cdar newsrc)) + ;; Ok, we have a valid component group, so we jump to it. + (switch-to-buffer gnus-group-buffer) + (gnus-group-jump-to-group (caar newsrc)) + (gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc)) + (setq ginfo (gnus-get-info (gnus-group-group-name)) + orig-info (gnus-copy-sequence ginfo) + num-unread (car (gnus-gethash (caar newsrc) + gnus-newsrc-hashtb))) + (unwind-protect + (progn + ;; We set all list of article marks to nil. Since we operate + ;; on copies of the real lists, we can destroy anything we + ;; want here. + (when (nth 3 ginfo) + (setcar (nthcdr 3 ginfo) nil)) + ;; We set the list of read articles to be what we expect for + ;; this kiboze group -- either nil or `(1 . LOWEST)'. + (when ginfo + (setcar (nthcdr 2 ginfo) + (and (not (= lowest 1)) (cons 1 lowest)))) + (when (and (or (not ginfo) + (> (length (gnus-list-of-unread-articles + (car ginfo))) + 0)) + (progn + (ignore-errors + (gnus-group-select-group nil)) + (eq major-mode 'gnus-summary-mode))) + ;; We are now in the group where we want to be. + (setq method (gnus-find-method-for-group + gnus-newsgroup-name)) + (when (eq method gnus-select-method) + (setq method nil)) + ;; We go through the list of scored articles. + (while gnus-newsgroup-scored + (when (> (caar gnus-newsgroup-scored) lowest) + ;; If it has a good score, then we enter this article + ;; into the kiboze group. + (nnkiboze-enter-nov + nov-buffer + (gnus-summary-article-header + (caar gnus-newsgroup-scored)) + gnus-newsgroup-name)) + (setq gnus-newsgroup-scored (cdr gnus-newsgroup-scored))) + ;; That's it. We exit this group. + (when (eq major-mode 'gnus-summary-mode) + (kill-buffer (current-buffer))))) + ;; Restore the proper info. + (when ginfo + (setcdr ginfo (cdr orig-info))) + (setcar (gnus-gethash (caar newsrc) gnus-newsrc-hashtb) + num-unread))) + (setcdr (car newsrc) (cdr active)) + (gnus-message 3 "nnkiboze: Checking %s...done" (caar newsrc)) + (setq newsrc (cdr newsrc))))) + ;; We save the kiboze newsrc for this group. + (gnus-make-directory (file-name-directory newsrc-file)) + (with-temp-file newsrc-file + (insert "(setq nnkiboze-newsrc '") + (gnus-prin1 nnkiboze-newsrc) + (insert ")\n"))) (unless inhibit-list-groups (save-excursion (set-buffer gnus-group-buffer) (gnus-group-list-groups))) - t) + t)) (defun nnkiboze-enter-nov (buffer header group) (save-excursion diff --git a/lisp/nnmail.el b/lisp/nnmail.el index 334d37f..9538167 100644 --- a/lisp/nnmail.el +++ b/lisp/nnmail.el @@ -189,7 +189,7 @@ The return value should be `delete' or a group name (a string)." (function :format "%v" nnmail-) string)) -(defcustom nnmail-fancy-expiry-targets nil +(defcustom nnmail-fancy-expiry-targets nil "Determine expiry target based on articles using fancy techniques. This is a list of (\"HEADER\" \"REGEXP\" \"TARGET\") entries. If @@ -219,8 +219,8 @@ everything else will be expired to \"nnfolder:Archive-YYYY\"." :type '(repeat (list (choice :tag "Match against" (string :tag "Header") (const to-from)) - regexp - (string :tag "Target group format string")))) + regexp + (string :tag "Target group format string")))) (defcustom nnmail-cache-accepted-message-ids nil "If non-nil, put Message-IDs of Gcc'd articles into the duplicate cache. @@ -342,11 +342,12 @@ discarded after running the split process." :type 'hook) (defcustom nnmail-large-newsgroup 50 - "*The number of the articles which indicates a large newsgroup. + "*The number of the articles which indicates a large newsgroup or nil. If the number of the articles is greater than the value, verbose messages will be shown to indicate the current status." :group 'nnmail-various - :type 'integer) + :type '(choice (const :tag "infinite" nil) + (number :tag "count"))) (defcustom nnmail-split-fancy "mail.misc" "Incoming mail can be split according to this fancy variable. @@ -381,8 +382,8 @@ GROUP: Mail will be stored in GROUP (a string). junk: Mail will be deleted. Use with care! Do not submerge in water! Example: (setq nnmail-split-fancy - '(| (\"Subject\" \"MAKE MONEY FAST\" junk) - ...other.rules.omitted...)) + '(| (\"Subject\" \"MAKE MONEY FAST\" junk) + ...other.rules.omitted...)) FIELD must match a complete field name. VALUE must match a complete word according to the `nnmail-split-fancy-syntax-table' syntax table. @@ -478,6 +479,11 @@ parameter. It should return nil, `warn' or `delete'." :group 'nnmail :type 'integer) +(defcustom nnmail-mail-splitting-charset nil + "Default charset to be used when splitting incoming mail." + :group 'nnmail + :type 'symbol) + ;;; Internal variables. (defvar nnmail-article-buffer " *nnmail incoming*" @@ -993,6 +999,9 @@ FUNC will be called with the group name to determine the article number." (erase-buffer) ;; Copy the headers into the work buffer. (insert-buffer-substring obuf beg end) + ;; Decode MIME headers and charsets. + (let ((mail-parse-charset nnmail-mail-splitting-charset)) + (mail-decode-encoded-word-region (point-min) (point-max))) ;; Fold continuation lines. (goto-char (point-min)) (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t) @@ -1022,8 +1031,8 @@ FUNC will be called with the group name to determine the article number." (or (funcall nnmail-split-methods) '("bogus")) (error - (nnheader-message 5 - "Error in `nnmail-split-methods'; using `bogus' mail group") + (nnheader-message + 5 "Error in `nnmail-split-methods'; using `bogus' mail group") (sit-for 1) '("bogus"))))) (setq split (gnus-remove-duplicates split)) @@ -1075,7 +1084,8 @@ FUNC will be called with the group name to determine the article number." (nnheader-set-temp-buffer "*Split Trace*") (gnus-add-buffer) (dolist (trace (nreverse nnmail-split-trace)) - (insert trace "\n")) + (prin1 trace (current-buffer)) + (insert "\n")) (goto-char (point-min)) (gnus-configure-windows 'split-trace) (set-buffer restore))) @@ -1222,7 +1232,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." ;; A group name. Do the \& and \N subs into the string. ((stringp split) (when nnmail-split-tracing - (push (format "\"%s\"" split) nnmail-split-trace)) + (push split nnmail-split-trace)) (list (nnmail-expand-newtext split))) ;; Junk the message. @@ -1261,7 +1271,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (while (and (goto-char end-point) (re-search-backward (cdr cached-pair) nil t)) (when nnmail-split-tracing - (push (cdr cached-pair) nnmail-split-trace)) + (push split nnmail-split-trace)) (let ((split-rest (cddr split)) (end (match-end 0)) ;; The searched regexp is \(\(FIELD\).*\)\(VALUE\). @@ -1291,7 +1301,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (let ((value (nth 1 split))) (if (symbolp value) (setq value (cdr (assq value nnmail-split-abbrev-alist)))) - ;; Someone might want to do a \N sub on this match, so get the + ;; Someone might want to do a \N sub on this match, so get the ;; correct match positions. (re-search-backward value start-of-value)) (dolist (sp (nnmail-split-it (car split-rest))) @@ -1446,7 +1456,7 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." (defvar group) (defvar group-art-list) (defvar group-art) -(defun nnmail-cache-insert (id) +(defun nnmail-cache-insert (id &optional grp) (when nnmail-treat-duplicates ;; Store some information about the group this message is written ;; to. This function might have been called from various places. @@ -1457,7 +1467,9 @@ See the documentation for the variable `nnmail-split-fancy' for documentation." ;; the car of a pair is a group name. Should we check that the ;; length of the list is equal to 1? -- kai (let ((g nil)) - (cond ((and (boundp 'group) group) + (cond (grp + (setq g grp)) + ((and (boundp 'group) group) (setq g group)) ((and (boundp 'group-art-list) group-art-list (listp group-art-list)) diff --git a/lisp/nnmaildir.el b/lisp/nnmaildir.el index 9525854..2c01d2b 100644 --- a/lisp/nnmaildir.el +++ b/lisp/nnmaildir.el @@ -1,6 +1,5 @@ ;;; nnmaildir.el --- maildir backend for Gnus -;; Copyright (c) 2001, 2002 Free Software Foundation, Inc. -;; Copyright (c) 2000, 2001 Paul Jarc +;; Public domain. ;; Author: Paul Jarc @@ -24,24 +23,24 @@ ;;; Commentary: ;; Maildir format is documented in the maildir(5) man page from qmail -;; and at . nnmaildir also -;; stores extra information in the .nnmaildir/ directory within a -;; maildir. +;; (available at ) and at +;; . nnmaildir also stores +;; extra information in the .nnmaildir/ directory within a maildir. ;; ;; Some goals of nnmaildir: ;; * Everything Just Works, and correctly. E.g., stale NOV data is ;; ignored; no need for -generate-nov-databases. ;; * Perfect reliability: [C-g] will never corrupt its data in memory, ;; and SIGKILL will never corrupt its data in the filesystem. -;; * We make it easy to manipulate marks, etc., from outside Gnus. +;; * We use the filesystem as a database, so that, e.g., it's easy to +;; manipulate marks from outside Gnus. ;; * All information about a group is stored in the maildir, for easy ;; backup, copying, restoring, etc. -;; * We use the filesystem as a database. ;; ;; Todo: ;; * Don't force article renumbering, so nnmaildir can be used with ;; the cache and agent. Alternatively, completely rewrite the Gnus -;; backend interface, which would have other advantages. +;; backend interface, which would have other advantages as well. ;; ;; See also until that ;; information is added to the Gnus manual. @@ -77,529 +76,501 @@ by nnmaildir-request-article.") ;; An obarry containing symbols whose names are server names and whose values ;; are servers: (defvar nnmaildir--servers (make-vector 3 0)) -;; A server which has not necessarily been added to nnmaildir--servers, or nil: -(defvar nnmaildir--tmp-server nil) ;; The current server: (defvar nnmaildir--cur-server nil) -;; A server is a vector: -["server-name" - select-method - "/expanded/path/to/directory/containing/symlinks/to/maildirs/" - directory-files-function - group-name-transformation-function - ;; An obarray containing symbols whose names are group names and whose values - ;; are groups: - group-hash - ;; A group which has not necessarily been added to the group hash, or nil: - tmp-group - current-group ;; or nil - "Last error message, or nil" - directory-modtime - get-new-mail-p ;; Should we split mail from mail-sources? - "new/group/creation/directory"] - -;; A group is a vector: -["group.name" - "prefixed:group.name" - ;; Modification times of the "new", and "cur" directories: - new-modtime - cur-modtime - ;; A vector containing lists of articles: - [;; A list of articles, with article numbers in descending order, ending with - ;; article 1: - article-list - ;; An obarray containing symbols whose names are filename prefixes and whose - ;; values are articles: - file-hash - ;; Same as above, but keyed on Message-ID: - msgid-hash - ;; An article which has not necessarily been added to the file and msgid - ;; hashes, or nil: - tmp-article] - ;; A vector containing nil, or articles with NOV data: - nov-cache - ;; The index of the next nov-cache entry to be replaced: - nov-cache-index - ;; An obarray containing symbols whose names are mark names and whose values - ;; are modtimes of mark directories: - mark-modtime-hash] - -;; An article is a vector: -["file.name.prefix" - ":2,suffix" ;; or 'expire if expired - number - "msgid" - ;; A NOV data vector, or nil: - ["subject\tfrom\tdate" - "references\tchars\lines" - "extra" - article-file-modtime - ;; The value of nnmail-extra-headers when this NOV data was parsed: - (to in-reply-to)]] - -(defmacro nnmaildir--srv-new () '(make-vector 11 nil)) -(defmacro nnmaildir--srv-get-name (server) `(aref ,server 0)) -(defmacro nnmaildir--srv-get-method (server) `(aref ,server 1)) -(defmacro nnmaildir--srv-get-dir (server) `(aref ,server 2)) -(defmacro nnmaildir--srv-get-ls (server) `(aref ,server 3)) -(defmacro nnmaildir--srv-get-groups (server) `(aref ,server 4)) -(defmacro nnmaildir--srv-get-tmpgrp (server) `(aref ,server 5)) -(defmacro nnmaildir--srv-get-curgrp (server) `(aref ,server 6)) -(defmacro nnmaildir--srv-get-error (server) `(aref ,server 7)) -(defmacro nnmaildir--srv-get-mtime (server) `(aref ,server 8)) -(defmacro nnmaildir--srv-get-gnm (server) `(aref ,server 9)) -(defmacro nnmaildir--srv-get-create-dir (server) `(aref ,server 10)) -(defmacro nnmaildir--srv-set-name (server val) `(aset ,server 0 ,val)) -(defmacro nnmaildir--srv-set-method (server val) `(aset ,server 1 ,val)) -(defmacro nnmaildir--srv-set-dir (server val) `(aset ,server 2 ,val)) -(defmacro nnmaildir--srv-set-ls (server val) `(aset ,server 3 ,val)) -(defmacro nnmaildir--srv-set-groups (server val) `(aset ,server 4 ,val)) -(defmacro nnmaildir--srv-set-tmpgrp (server val) `(aset ,server 5 ,val)) -(defmacro nnmaildir--srv-set-curgrp (server val) `(aset ,server 6 ,val)) -(defmacro nnmaildir--srv-set-error (server val) `(aset ,server 7 ,val)) -(defmacro nnmaildir--srv-set-mtime (server val) `(aset ,server 8 ,val)) -(defmacro nnmaildir--srv-set-gnm (server val) `(aset ,server 9 ,val)) -(defmacro nnmaildir--srv-set-create-dir (server val) `(aset ,server 10 ,val)) - -(defmacro nnmaildir--grp-new () '(make-vector 8 nil)) -(defmacro nnmaildir--grp-get-name (group) `(aref ,group 0)) -(defmacro nnmaildir--grp-get-pname (group) `(aref ,group 1)) -(defmacro nnmaildir--grp-get-new (group) `(aref ,group 2)) -(defmacro nnmaildir--grp-get-cur (group) `(aref ,group 3)) -(defmacro nnmaildir--grp-get-lists (group) `(aref ,group 4)) -(defmacro nnmaildir--grp-get-cache (group) `(aref ,group 5)) -(defmacro nnmaildir--grp-get-index (group) `(aref ,group 6)) -(defmacro nnmaildir--grp-get-mmth (group) `(aref ,group 7)) -(defmacro nnmaildir--grp-set-name (group val) `(aset ,group 0 ,val)) -(defmacro nnmaildir--grp-set-pname (group val) `(aset ,group 1 ,val)) -(defmacro nnmaildir--grp-set-new (group val) `(aset ,group 2 ,val)) -(defmacro nnmaildir--grp-set-cur (group val) `(aset ,group 3 ,val)) -(defmacro nnmaildir--grp-set-lists (group val) `(aset ,group 4 ,val)) -(defmacro nnmaildir--grp-set-cache (group val) `(aset ,group 5 ,val)) -(defmacro nnmaildir--grp-set-index (group val) `(aset ,group 6 ,val)) -(defmacro nnmaildir--grp-set-mmth (group val) `(aset ,group 7 ,val)) - -(defmacro nnmaildir--lists-new () '(make-vector 4 nil)) -(defmacro nnmaildir--lists-get-nlist (lists) `(aref ,lists 0)) -(defmacro nnmaildir--lists-get-flist (lists) `(aref ,lists 1)) -(defmacro nnmaildir--lists-get-mlist (lists) `(aref ,lists 2)) -(defmacro nnmaildir--lists-get-tmpart (lists) `(aref ,lists 3)) -(defmacro nnmaildir--lists-set-nlist (lists val) `(aset ,lists 0 ,val)) -(defmacro nnmaildir--lists-set-flist (lists val) `(aset ,lists 1 ,val)) -(defmacro nnmaildir--lists-set-mlist (lists val) `(aset ,lists 2 ,val)) -(defmacro nnmaildir--lists-set-tmpart (lists val) `(aset ,lists 3 ,val)) - -(defmacro nnmaildir--nlist-last-num (list) - `(if ,list (nnmaildir--art-get-num (car ,list)) 0)) -(defmacro nnmaildir--nlist-art (list num) - `(and ,list - (>= (nnmaildir--art-get-num (car ,list)) ,num) - (nth (- (nnmaildir--art-get-num (car ,list)) ,num) ,list))) +;; A copy of nnmail-extra-headers +(defvar nnmaildir--extra nil) + +;; A disk NOV structure (must be prin1-able, so no defstruct) looks like this: +["subject\tfrom\tdate" + "references\tchars\lines" + "To: you\tIn-Reply-To: " + (12345 67890) ;; modtime of the corresponding article file + (to in-reply-to)] ;; contemporary value of nnmail-extra-headers +(defconst nnmaildir--novlen 5) +(defmacro nnmaildir--nov-new (beg mid end mtime extra) + `(vector ,beg ,mid ,end ,mtime ,extra)) +(defmacro nnmaildir--nov-get-beg (nov) `(aref ,nov 0)) +(defmacro nnmaildir--nov-get-mid (nov) `(aref ,nov 1)) +(defmacro nnmaildir--nov-get-end (nov) `(aref ,nov 2)) +(defmacro nnmaildir--nov-get-mtime (nov) `(aref ,nov 3)) +(defmacro nnmaildir--nov-get-extra (nov) `(aref ,nov 4)) +(defmacro nnmaildir--nov-set-beg (nov value) `(aset ,nov 0 ,value)) +(defmacro nnmaildir--nov-set-mid (nov value) `(aset ,nov 1 ,value)) +(defmacro nnmaildir--nov-set-end (nov value) `(aset ,nov 2 ,value)) +(defmacro nnmaildir--nov-set-mtime (nov value) `(aset ,nov 3 ,value)) +(defmacro nnmaildir--nov-set-extra (nov value) `(aset ,nov 4 ,value)) + +(defstruct nnmaildir--art + (prefix nil :type string) ;; "time.pid.host" + (suffix nil :type string) ;; ":2,flags" + (num nil :type natnum) ;; article number + (msgid nil :type string) ;; "" + (nov nil :type vector)) ;; cached nov structure, or nil + +(defstruct nnmaildir--lists + (nlist nil :type list) ;; list of articles, ordered descending by number + (flist nil :type vector) ;; obarray mapping filename prefix->article + (mlist nil :type vector)) ;; obarray mapping message-id->article + +(defstruct nnmaildir--grp + (name nil :type string) ;; "group.name" + (new nil :type list) ;; new/ modtime + (cur nil :type list) ;; cur/ modtime + (lists nil :type nnmaildir--lists) ;; lists of articles in this group + (cache nil :type vector) ;; nov cache + (index nil :type natnum) ;; index of next cache entry to replace + (mmth nil :type vector)) ;; obarray mapping mark name->dir modtime + +(defstruct nnmaildir--srv + (address nil :type string) ;; server address string + (method nil :type list) ;; (nnmaildir "address" ...) + (prefix nil :type string) ;; "nnmaildir+address:" + (dir nil :type string) ;; "/expanded/path/to/server/dir/" + (ls nil :type function) ;; directory-files function + (groups nil :type vector) ;; obarray mapping group names->groups + (curgrp nil :type nnmaildir--grp) ;; current group, or nil + (error nil :type string) ;; last error message, or nil + (mtime nil :type list) ;; modtime of dir + (gnm nil) ;; flag: split from mail-sources? + (create-dir nil :type string)) ;; group creation directory + +(defmacro nnmaildir--nlist-last-num (nlist) + `(let ((nlist ,nlist)) + (if nlist (nnmaildir--art-num (car nlist)) 0))) +(defmacro nnmaildir--nlist-art (nlist num) ;;;; evals args multiple times + `(and ,nlist + (>= (nnmaildir--art-num (car ,nlist)) ,num) + (nth (- (nnmaildir--art-num (car ,nlist)) ,num) ,nlist))) (defmacro nnmaildir--flist-art (list file) `(symbol-value (intern-soft ,file ,list))) (defmacro nnmaildir--mlist-art (list msgid) `(symbol-value (intern-soft ,msgid ,list))) -(defmacro nnmaildir--art-new () '(make-vector 5 nil)) -(defmacro nnmaildir--art-get-prefix (article) `(aref ,article 0)) -(defmacro nnmaildir--art-get-suffix (article) `(aref ,article 1)) -(defmacro nnmaildir--art-get-num (article) `(aref ,article 2)) -(defmacro nnmaildir--art-get-msgid (article) `(aref ,article 3)) -(defmacro nnmaildir--art-get-nov (article) `(aref ,article 4)) -(defmacro nnmaildir--art-set-prefix (article val) `(aset ,article 0 ,val)) -(defmacro nnmaildir--art-set-suffix (article val) `(aset ,article 1 ,val)) -(defmacro nnmaildir--art-set-num (article val) `(aset ,article 2 ,val)) -(defmacro nnmaildir--art-set-msgid (article val) `(aset ,article 3 ,val)) -(defmacro nnmaildir--art-set-nov (article val) `(aset ,article 4 ,val)) - -(defmacro nnmaildir--nov-new () '(make-vector 5 nil)) -(defmacro nnmaildir--nov-get-beg (nov) `(aref ,nov 0)) -(defmacro nnmaildir--nov-get-mid (nov) `(aref ,nov 1)) -(defmacro nnmaildir--nov-get-end (nov) `(aref ,nov 2)) -(defmacro nnmaildir--nov-get-mtime (nov) `(aref ,nov 3)) -(defmacro nnmaildir--nov-get-neh (nov) `(aref ,nov 4)) -(defmacro nnmaildir--nov-set-beg (nov val) `(aset ,nov 0 ,val)) -(defmacro nnmaildir--nov-set-mid (nov val) `(aset ,nov 1 ,val)) -(defmacro nnmaildir--nov-set-end (nov val) `(aset ,nov 2 ,val)) -(defmacro nnmaildir--nov-set-mtime (nov val) `(aset ,nov 3 ,val)) -(defmacro nnmaildir--nov-set-neh (nov val) `(aset ,nov 4 ,val)) - -(defmacro nnmaildir--srv-grp-dir (srv-dir gname) - `(file-name-as-directory (concat ,srv-dir ,gname))) - -(defun nnmaildir--param (prefixed-group-name param) - (setq param - (gnus-group-find-parameter prefixed-group-name param 'allow-list) - param (if (vectorp param) (aref param 0) param)) +(defun nnmaildir--pgname (server gname) + (let ((prefix (nnmaildir--srv-prefix server))) + (if prefix (concat prefix gname) + (setq gname (gnus-group-prefixed-name gname + (nnmaildir--srv-method server))) + (setf (nnmaildir--srv-prefix server) (gnus-group-real-prefix gname)) + gname))) + +(defun nnmaildir--param (pgname param) + (setq param (gnus-group-find-parameter pgname param 'allow-list) + param (if (vectorp param) (aref param 0) param)) (eval param)) -(defmacro nnmaildir--unlink (file) - `(if (file-attributes ,file) (delete-file ,file))) - -(defmacro nnmaildir--tmp (dir) `(file-name-as-directory (concat ,dir "tmp"))) -(defmacro nnmaildir--new (dir) `(file-name-as-directory (concat ,dir "new"))) -(defmacro nnmaildir--cur (dir) `(file-name-as-directory (concat ,dir "cur"))) -(defmacro nnmaildir--nndir (dir) - `(file-name-as-directory (concat ,dir ".nnmaildir"))) - -(defun nnmaildir--lists-fix (lists) - (let ((tmp (nnmaildir--lists-get-tmpart lists))) - (when tmp - (set (intern (nnmaildir--art-get-prefix tmp) - (nnmaildir--lists-get-flist lists)) - tmp) - (set (intern (nnmaildir--art-get-msgid tmp) - (nnmaildir--lists-get-mlist lists)) - tmp) - (nnmaildir--lists-set-tmpart lists nil)))) +(defmacro nnmaildir--with-nntp-buffer (&rest body) + `(save-excursion + (set-buffer nntp-server-buffer) + ,@body)) +(defmacro nnmaildir--with-work-buffer (&rest body) + `(save-excursion + (set-buffer (get-buffer-create " *nnmaildir work*")) + ,@body)) +(defmacro nnmaildir--with-nov-buffer (&rest body) + `(save-excursion + (set-buffer (get-buffer-create " *nnmaildir nov*")) + ,@body)) +(defmacro nnmaildir--with-move-buffer (&rest body) + `(save-excursion + (set-buffer (get-buffer-create " *nnmaildir move*")) + ,@body)) + +(defmacro nnmaildir--subdir (dir subdir) + `(file-name-as-directory (concat ,dir ,subdir))) +(defmacro nnmaildir--srvgrp-dir (srv-dir gname) + `(nnmaildir--subdir ,srv-dir ,gname)) +(defmacro nnmaildir--tmp (dir) `(nnmaildir--subdir ,dir "tmp")) +(defmacro nnmaildir--new (dir) `(nnmaildir--subdir ,dir "new")) +(defmacro nnmaildir--cur (dir) `(nnmaildir--subdir ,dir "cur")) +(defmacro nnmaildir--nndir (dir) `(nnmaildir--subdir ,dir ".nnmaildir")) +(defmacro nnmaildir--nov-dir (dir) `(nnmaildir--subdir ,dir "nov")) +(defmacro nnmaildir--marks-dir (dir) `(nnmaildir--subdir ,dir "marks")) + +(defmacro nnmaildir--unlink (file-arg) + `(let ((file ,file-arg)) + (if (file-attributes file) (delete-file file)))) +(defun nnmaildir--mkdir (dir) + (or (file-exists-p (file-name-as-directory dir)) + (make-directory-internal (directory-file-name dir)))) (defun nnmaildir--prepare (server group) (let (x groups) (catch 'return - (setq x nnmaildir--tmp-server) - (when x - (set (intern (nnmaildir--srv-get-name x) nnmaildir--servers) x) - (setq nnmaildir--tmp-server nil)) (if (null server) - (or (setq server nnmaildir--cur-server) - (throw 'return nil)) - (or (setq server (intern-soft server nnmaildir--servers)) - (throw 'return nil)) - (setq server (symbol-value server) - nnmaildir--cur-server server)) - (setq groups (nnmaildir--srv-get-groups server)) - (if groups nil (throw 'return nil)) - (if (nnmaildir--srv-get-method server) nil - (setq x (concat "nnmaildir:" (nnmaildir--srv-get-name server)) - x (gnus-server-to-method x)) - (if x nil (throw 'return nil)) - (nnmaildir--srv-set-method server x)) - (setq x (nnmaildir--srv-get-tmpgrp server)) - (when x - (set (intern (nnmaildir--grp-get-name x) groups) x) - (nnmaildir--srv-set-tmpgrp server nil)) + (or (setq server nnmaildir--cur-server) + (throw 'return nil)) + (or (setq server (intern-soft server nnmaildir--servers)) + (throw 'return nil)) + (setq server (symbol-value server) + nnmaildir--cur-server server)) + (or (setq groups (nnmaildir--srv-groups server)) + (throw 'return nil)) + (if (nnmaildir--srv-method server) nil + (setq x (concat "nnmaildir:" (nnmaildir--srv-address server)) + x (gnus-server-to-method x)) + (or x (throw 'return nil)) + (setf (nnmaildir--srv-method server) x)) (if (null group) - (or (setq group (nnmaildir--srv-get-curgrp server)) - (throw 'return nil)) - (setq group (intern-soft group groups)) - (if group nil (throw 'return nil)) - (setq group (symbol-value group))) - (nnmaildir--lists-fix (nnmaildir--grp-get-lists group)) + (or (setq group (nnmaildir--srv-curgrp server)) + (throw 'return nil)) + (or (setq group (intern-soft group groups)) + (throw 'return nil)) + (setq group (symbol-value group))) group))) -(defun nnmaildir--update-nov (srv-dir group article) +(defun nnmaildir--update-nov (server group article) (let ((nnheader-file-coding-system 'binary) - dir gname pgname msgdir prefix suffix file attr mtime novdir novfile - nov msgid nov-beg nov-mid nov-end field pos extra val old-neh new-neh - deactivate-mark) + (srv-dir (nnmaildir--srv-dir server)) + dir gname pgname msgdir prefix suffix file attr mtime novdir novfile + nov msgid nov-beg nov-mid nov-end field pos extra val old-extra + new-extra deactivate-mark) (catch 'return - (setq suffix (nnmaildir--art-get-suffix article)) + (setq suffix (nnmaildir--art-suffix article)) (if (stringp suffix) nil - (nnmaildir--art-set-nov article nil) - (throw 'return nil)) - (setq gname (nnmaildir--grp-get-name group) - pgname (nnmaildir--grp-get-pname group) - dir (nnmaildir--srv-grp-dir srv-dir gname) - msgdir (if (nnmaildir--param pgname 'read-only) - (nnmaildir--new dir) (nnmaildir--cur dir)) - prefix (nnmaildir--art-get-prefix article) - file (concat msgdir prefix suffix) - attr (file-attributes file)) + (setf (nnmaildir--art-nov article) nil) + (throw 'return nil)) + (setq gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname server gname) + dir (nnmaildir--srvgrp-dir srv-dir gname) + msgdir (if (nnmaildir--param pgname 'read-only) + (nnmaildir--new dir) (nnmaildir--cur dir)) + prefix (nnmaildir--art-prefix article) + file (concat msgdir prefix suffix) + attr (file-attributes file)) (if attr nil - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil) - (throw 'return nil)) + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil) + (throw 'return nil)) (setq mtime (nth 5 attr) - attr (nth 7 attr) - nov (nnmaildir--art-get-nov article) - novdir (concat (nnmaildir--nndir dir) "nov") - novdir (file-name-as-directory novdir) - novfile (concat novdir prefix)) - (save-excursion - (set-buffer (get-buffer-create " *nnmaildir nov*")) - (when (file-exists-p novfile) ;; If not, force reparsing the message. - (if nov nil ;; It's already in memory. - ;; Else read the data from the NOV file. - (erase-buffer) - (nnheader-insert-file-contents novfile) - (setq nov (read (current-buffer))) - (nnmaildir--art-set-msgid article (car nov)) - (setq nov (cadr nov))) - ;; If the NOV's modtime matches the file's current modtime, - ;; and it has the right length (i.e., it wasn't produced by - ;; a too-much older version of nnmaildir), then we may use - ;; this NOV data rather than parsing the message file, - ;; unless nnmail-extra-headers has been augmented since this - ;; data was last parsed. - (when (and (equal mtime (nnmaildir--nov-get-mtime nov)) - (= (length nov) (length (nnmaildir--nov-new)))) - ;; This NOV data is potentially up-to-date. - (setq old-neh (nnmaildir--nov-get-neh nov) - new-neh nnmail-extra-headers) - (if (equal new-neh old-neh) (throw 'return nov)) ;; Common case. - ;; They're not equal, but maybe the new is a subset of the old... - (if (null new-neh) (throw 'return nov)) - (while new-neh - (if (memq (car new-neh) old-neh) - (progn - (setq new-neh (cdr new-neh)) - (if new-neh nil (throw 'return nov))) - (setq new-neh nil))))) - ;; Parse the NOV data out of the message. - (erase-buffer) - (nnheader-insert-file-contents file) - (insert "\n") - (goto-char (point-min)) - (save-restriction - (if (search-forward "\n\n" nil 'noerror) - (progn - (setq nov-mid (count-lines (point) (point-max))) - (narrow-to-region (point-min) (1- (point)))) - (setq nov-mid 0)) - (goto-char (point-min)) - (delete-char 1) - (nnheader-fold-continuation-lines) - (setq nov (nnheader-parse-head 'naked) - field (or (mail-header-lines nov) 0))) - (if (or (zerop field) (nnmaildir--param pgname 'distrust-Lines:)) nil - (setq nov-mid field)) - (setq nov-mid (number-to-string nov-mid) - nov-mid (concat (number-to-string attr) "\t" nov-mid) - field (or (mail-header-references nov) "") - pos 0) - (save-match-data - (while (string-match "\t" field pos) - (aset field (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq nov-mid (concat field "\t" nov-mid) - extra (mail-header-extra nov) - nov-end "") - (while extra - (setq field (car extra) extra (cdr extra) - val (cdr field) field (symbol-name (car field)) - pos 0) - (while (string-match "\t" field pos) - (aset field (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq pos 0) - (while (string-match "\t" val pos) - (aset val (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq nov-end (concat nov-end "\t" field ": " val))) - (setq nov-end (if (zerop (length nov-end)) "" (substring nov-end 1)) - field (or (mail-header-subject nov) "") - pos 0) - (while (string-match "\t" field pos) - (aset field (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq nov-beg field - field (or (mail-header-from nov) "") - pos 0) - (while (string-match "\t" field pos) - (aset field (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq nov-beg (concat nov-beg "\t" field) - field (or (mail-header-date nov) "") - pos 0) - (while (string-match "\t" field pos) - (aset field (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq nov-beg (concat nov-beg "\t" field) - field (mail-header-id nov) - pos 0) - (while (string-match "\t" field pos) - (aset field (match-beginning 0) ? ) - (setq pos (match-end 0))) - (setq msgid field)) - (if (or (null msgid) (nnheader-fake-message-id-p msgid)) - (setq msgid (concat "<" prefix "@nnmaildir>"))) - (erase-buffer) - (setq nov (nnmaildir--nov-new)) - (nnmaildir--nov-set-beg nov nov-beg) - (nnmaildir--nov-set-mid nov nov-mid) - (nnmaildir--nov-set-end nov nov-end) - (nnmaildir--nov-set-mtime nov mtime) - (nnmaildir--nov-set-neh nov (copy-sequence nnmail-extra-headers)) - (prin1 (list msgid nov) (current-buffer)) - (setq file (concat novfile ":")) - (nnmaildir--unlink file) - (write-region (point-min) (point-max) file nil 'no-message)) + attr (nth 7 attr) + nov (nnmaildir--art-nov article) + novdir (nnmaildir--nov-dir (nnmaildir--nndir dir)) + novfile (concat novdir prefix)) + (or (equal nnmaildir--extra nnmail-extra-headers) + (setq nnmaildir--extra (copy-sequence nnmail-extra-headers))) + (nnmaildir--with-nov-buffer + (when (file-exists-p novfile) ;; If not, force reparsing the message. + (if nov nil ;; It's already in memory. + ;; Else read the data from the NOV file. + (erase-buffer) + (nnheader-insert-file-contents novfile) + (setq nov (read (current-buffer))) + (setf (nnmaildir--art-msgid article) (car nov)) + (setq nov (cadr nov))) + ;; If the NOV's modtime matches the file's current modtime, and it + ;; has the right structure (i.e., it wasn't produced by a too-much + ;; older version of nnmaildir), then we may use this NOV data + ;; rather than parsing the message file, unless + ;; nnmail-extra-headers has been augmented since this data was last + ;; parsed. + (when (and (equal mtime (nnmaildir--nov-get-mtime nov)) + (= (length nov) nnmaildir--novlen) + (stringp (nnmaildir--nov-get-beg nov)) + (stringp (nnmaildir--nov-get-mid nov)) + (stringp (nnmaildir--nov-get-end nov)) + (listp (nnmaildir--nov-get-mtime nov)) + (listp (nnmaildir--nov-get-extra nov))) + ;; this NOV data is potentially up-to-date; now check extra headers + (setq old-extra (nnmaildir--nov-get-extra nov)) + (when (equal nnmaildir--extra old-extra) ;; common case + (nnmaildir--nov-set-extra nov nnmaildir--extra) ;; save memory + (throw 'return nov)) + ;; They're not equal, but maybe the new is a subset of the old... + (if (null nnmaildir--extra) (throw 'return nov)) + (setq new-extra nnmaildir--extra) + (while new-extra + (if (memq (car new-extra) old-extra) + (progn + (setq new-extra (cdr new-extra)) + (if new-extra nil (throw 'return nov))) + (setq new-extra nil))))) ;;found one not in old-extra;quit loop + ;; Parse the NOV data out of the message. + (erase-buffer) + (nnheader-insert-file-contents file) + (insert "\n") + (goto-char (point-min)) + (save-restriction + (if (search-forward "\n\n" nil 'noerror) + (progn + (setq nov-mid (count-lines (point) (point-max))) + (narrow-to-region (point-min) (1- (point)))) + (setq nov-mid 0)) + (goto-char (point-min)) + (delete-char 1) + (nnheader-fold-continuation-lines) + (setq nov (nnheader-parse-head 'naked) + field (or (mail-header-lines nov) 0))) + (if (or (zerop field) (nnmaildir--param pgname 'distrust-Lines:)) nil + (setq nov-mid field)) + (setq nov-mid (number-to-string nov-mid) + nov-mid (concat (number-to-string attr) "\t" nov-mid) + field (or (mail-header-references nov) "") + pos 0) + (save-match-data + (while (string-match "\t" field pos) + (aset field (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq nov-mid (concat field "\t" nov-mid) + extra (mail-header-extra nov) + nov-end "") + (while extra + (setq field (car extra) extra (cdr extra) + val (cdr field) field (symbol-name (car field)) + pos 0) + (while (string-match "\t" field pos) + (aset field (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq pos 0) + (while (string-match "\t" val pos) + (aset val (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq nov-end (concat nov-end "\t" field ": " val))) + (setq nov-end (if (zerop (length nov-end)) "" (substring nov-end 1)) + field (or (mail-header-subject nov) "") + pos 0) + (while (string-match "\t" field pos) + (aset field (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq nov-beg field + field (or (mail-header-from nov) "") + pos 0) + (while (string-match "\t" field pos) + (aset field (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq nov-beg (concat nov-beg "\t" field) + field (or (mail-header-date nov) "") + pos 0) + (while (string-match "\t" field pos) + (aset field (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq nov-beg (concat nov-beg "\t" field) + field (mail-header-id nov) + pos 0) + (while (string-match "\t" field pos) + (aset field (match-beginning 0) ? ) + (setq pos (match-end 0))) + (setq msgid field)) + (if (or (null msgid) (nnheader-fake-message-id-p msgid)) + (setq msgid (concat "<" prefix "@nnmaildir>"))) + (setq nov (nnmaildir--nov-new nov-beg nov-mid nov-end mtime + nnmaildir--extra)) + (erase-buffer) + (prin1 (list msgid nov) (current-buffer)) + (setq file (concat novfile ":")) + (nnmaildir--unlink file) + (write-region (point-min) (point-max) file nil 'no-message)) (rename-file file novfile 'replace) - (nnmaildir--art-set-msgid article msgid) + (setf (nnmaildir--art-msgid article) msgid) nov))) (defun nnmaildir--cache-nov (group article nov) - (let ((cache (nnmaildir--grp-get-cache group)) - (index (nnmaildir--grp-get-index group)) - goner) - (if (nnmaildir--art-get-nov article) nil + (let ((cache (nnmaildir--grp-cache group)) + (index (nnmaildir--grp-index group)) + goner) + (if (nnmaildir--art-nov article) nil (setq goner (aref cache index)) - (if goner (nnmaildir--art-set-nov goner nil)) + (if goner (setf (nnmaildir--art-nov goner) nil)) (aset cache index article) - (nnmaildir--grp-set-index group (% (1+ index) (length cache)))) - (nnmaildir--art-set-nov article nov))) + (setf (nnmaildir--grp-index group) (% (1+ index) (length cache)))) + (setf (nnmaildir--art-nov article) nov))) -(defun nnmaildir--grp-add-art (srv-dir group article) - (let ((nov (nnmaildir--update-nov srv-dir group article)) - old-lists new-lists) +(defun nnmaildir--grp-add-art (server group article) + (let ((nov (nnmaildir--update-nov server group article)) + old-lists new-lists) (when nov - (setq old-lists (nnmaildir--grp-get-lists group) - new-lists (nnmaildir--lists-new)) - (nnmaildir--lists-set-nlist - new-lists (cons article (nnmaildir--lists-get-nlist old-lists))) - (nnmaildir--lists-set-flist new-lists - (nnmaildir--lists-get-flist old-lists)) - (nnmaildir--lists-set-mlist new-lists - (nnmaildir--lists-get-mlist old-lists)) - (nnmaildir--lists-set-tmpart new-lists article) - (nnmaildir--grp-set-lists group new-lists) - (nnmaildir--lists-fix new-lists) + (setq old-lists (nnmaildir--grp-lists group) + new-lists (copy-nnmaildir--lists old-lists)) + (setf (nnmaildir--lists-nlist new-lists) + (cons article (nnmaildir--lists-nlist new-lists))) + (let ((inhibit-quit t)) + (setf (nnmaildir--grp-lists group) new-lists) + (set (intern (nnmaildir--art-prefix article) + (nnmaildir--lists-flist new-lists)) + article) + (set (intern (nnmaildir--art-msgid article) + (nnmaildir--lists-mlist new-lists)) + article)) (nnmaildir--cache-nov group article nov) t))) -(defun nnmaildir--mkdir (dir) - (or (file-exists-p (file-name-as-directory dir)) - (make-directory-internal (directory-file-name dir)))) +(defun nnmaildir--group-ls (server pgname) + (or (nnmaildir--param pgname 'directory-files) + (nnmaildir--srv-ls server))) (defun nnmaildir--article-count (group) (let ((ct 0) - (min 0)) - (setq group (nnmaildir--grp-get-lists group) - group (nnmaildir--lists-get-nlist group)) + (min 1)) + (setq group (nnmaildir--grp-lists group) + group (nnmaildir--lists-nlist group)) (while group - (if (stringp (nnmaildir--art-get-suffix (car group))) - (setq ct (1+ ct) - min (nnmaildir--art-get-num (car group)))) + (if (stringp (nnmaildir--art-suffix (car group))) + (setq ct (1+ ct) + min (nnmaildir--art-num (car group)))) (setq group (cdr group))) (cons ct min))) (defun nnmaildir-article-number-to-file-name - (number group-name server-address-string) + (number group-name server-address-string) (let ((group (nnmaildir--prepare server-address-string group-name)) - list article suffix dir filename) + list article suffix dir filename pgname) (catch 'return (if (null group) - ;; The given group or server does not exist. - (throw 'return nil)) - (setq list (nnmaildir--grp-get-lists group) - list (nnmaildir--lists-get-nlist list) - article (nnmaildir--nlist-art list number)) + ;; The given group or server does not exist. + (throw 'return nil)) + (setq list (nnmaildir--grp-lists group) + list (nnmaildir--lists-nlist list) + article (nnmaildir--nlist-art list number)) (if (null article) - ;; The given article number does not exist in this group. - (throw 'return nil)) - (setq suffix (nnmaildir--art-get-suffix article)) + ;; The given article number does not exist in this group. + (throw 'return nil)) + (setq suffix (nnmaildir--art-suffix article)) (if (not (stringp suffix)) - ;; The article has expired. - (throw 'return nil)) - (setq dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir dir group-name) - group (if (nnmaildir--param (nnmaildir--grp-get-pname group) - 'read-only) - (nnmaildir--new dir) (nnmaildir--cur dir)) - filename (concat group (nnmaildir--art-get-prefix article) suffix)) + ;; The article has expired. + (throw 'return nil)) + (setq dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir dir group-name) + pgname (nnmaildir--pgname nnmaildir--cur-server group-name) + group (if (nnmaildir--param pgname 'read-only) + (nnmaildir--new dir) (nnmaildir--cur dir)) + filename (concat group (nnmaildir--art-prefix article) suffix)) (if (file-exists-p filename) - filename - ;; The article disappeared out from under us. - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil) - nil)))) + filename + ;; The article disappeared out from under us. + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil) + nil)))) + +(defun nnmaildir-article-number-to-base-name + (number group-name server-address-string) + (let ((group (nnmaildir--prepare server-address-string group-name)) + list article suffix dir filename) + (catch 'return + (if (null group) + ;; The given group or server does not exist. + (throw 'return nil)) + (setq list (nnmaildir--grp-lists group) + list (nnmaildir--lists-nlist list) + article (nnmaildir--nlist-art list number)) + (if (null article) + ;; The given article number does not exist in this group. + (throw 'return nil)) + (setq suffix (nnmaildir--art-suffix article)) + (if (not (stringp suffix)) + ;; The article has expired. + (throw 'return nil)) + (cons (nnmaildir--art-prefix article) suffix)))) + +(defun nnmaildir-base-name-to-article-number + (base-name group-name server-address-string) + (let ((group (nnmaildir--prepare server-address-string group-name)) + list article suffix dir filename) + (catch 'return + (if (null group) + ;; The given group or server does not exist. + (throw 'return nil)) + (setq list (nnmaildir--grp-lists group) + list (nnmaildir--lists-flist list) + article (nnmaildir--flist-art list base-name)) + (if (null article) + ;; The given article number does not exist in this group. + (throw 'return nil)) + (nnmaildir--art-num article)))) (defun nnmaildir-request-type (group &optional article) 'mail) (defun nnmaildir-status-message (&optional server) (nnmaildir--prepare server nil) - (nnmaildir--srv-get-error nnmaildir--cur-server)) + (nnmaildir--srv-error nnmaildir--cur-server)) (defun nnmaildir-server-opened (&optional server) (and nnmaildir--cur-server (if server - (string-equal server - (nnmaildir--srv-get-name nnmaildir--cur-server)) - t) - (nnmaildir--srv-get-groups nnmaildir--cur-server) + (string-equal server (nnmaildir--srv-address nnmaildir--cur-server)) + t) + (nnmaildir--srv-groups nnmaildir--cur-server) t)) (defun nnmaildir-open-server (server &optional defs) (let ((x server) - dir size) + dir size) (catch 'return (setq server (intern-soft x nnmaildir--servers)) (if server - (and (setq server (symbol-value server)) - (nnmaildir--srv-get-groups server) - (setq nnmaildir--cur-server server) - (throw 'return t)) - (setq server (nnmaildir--srv-new)) - (nnmaildir--srv-set-name server x) - (setq nnmaildir--tmp-server server) - (set (intern x nnmaildir--servers) server) - (setq nnmaildir--tmp-server nil)) + (and (setq server (symbol-value server)) + (nnmaildir--srv-groups server) + (setq nnmaildir--cur-server server) + (throw 'return t)) + (setq server (make-nnmaildir--srv :address x)) + (let ((inhibit-quit t)) + (set (intern x nnmaildir--servers) server))) (setq dir (assq 'directory defs)) (if dir nil - (nnmaildir--srv-set-error - server "You must set \"directory\" in the select method") - (throw 'return nil)) + (setf (nnmaildir--srv-error server) + "You must set \"directory\" in the select method") + (throw 'return nil)) (setq dir (cadr dir) - dir (eval dir) - dir (expand-file-name dir) - dir (file-name-as-directory dir)) + dir (eval dir) + dir (expand-file-name dir) + dir (file-name-as-directory dir)) (if (file-exists-p dir) nil - (nnmaildir--srv-set-error server (concat "No such directory: " dir)) - (throw 'return nil)) - (nnmaildir--srv-set-dir server dir) + (setf (nnmaildir--srv-error server) (concat "No such directory: " dir)) + (throw 'return nil)) + (setf (nnmaildir--srv-dir server) dir) (setq x (assq 'directory-files defs)) (if (null x) - (setq x (symbol-function (if nnheader-directory-files-is-safe - 'directory-files - 'nnheader-directory-files-safe))) - (setq x (cadr x)) - (if (functionp x) nil - (nnmaildir--srv-set-error - server (concat "Not a function: " (prin1-to-string x))) - (throw 'return nil))) - (nnmaildir--srv-set-ls server x) + (setq x (symbol-function (if nnheader-directory-files-is-safe + 'directory-files + 'nnheader-directory-files-safe))) + (setq x (cadr x)) + (if (functionp x) nil + (setf (nnmaildir--srv-error server) + (concat "Not a function: " (prin1-to-string x))) + (throw 'return nil))) + (setf (nnmaildir--srv-ls server) x) (setq x (funcall x dir nil "\\`[^.]" 'nosort) - x (length x) - size 1) + x (length x) + size 1) (while (<= size x) (setq size (* 2 size))) (if (/= size 1) (setq size (1- size))) (and (setq x (assq 'get-new-mail defs)) - (setq x (cdr x)) - (car x) - (nnmaildir--srv-set-gnm server t) - (require 'nnmail)) + (setq x (cdr x)) + (car x) + (setf (nnmaildir--srv-gnm server) t) + (require 'nnmail)) (setq x (assq 'create-directory defs)) (when x - (setq x (cadr x) - x (eval x)) - (nnmaildir--srv-set-create-dir server x)) - (nnmaildir--srv-set-groups server (make-vector size 0)) + (setq x (cadr x) + x (eval x)) + (setf (nnmaildir--srv-create-dir server) x)) + (setf (nnmaildir--srv-groups server) (make-vector size 0)) (setq nnmaildir--cur-server server) t))) (defun nnmaildir--parse-filename (file) (let ((prefix (car file)) - timestamp len) + timestamp len) (if (string-match - "\\`\\([0-9]+\\)\\.\\([0-9]+\\)\\(_\\([0-9]+\\)\\)?\\(\\..*\\)\\'" - prefix) - (progn - (setq timestamp (concat "0000" (match-string 1 prefix)) - len (- (length timestamp) 4)) - (vector (string-to-number (substring timestamp 0 len)) - (string-to-number (substring timestamp len)) - (string-to-number (match-string 2 prefix)) - (string-to-number (or (match-string 4 prefix) "-1")) - (match-string 5 prefix) - file)) + "\\`\\([0-9]+\\)\\.\\([0-9]+\\)\\(_\\([0-9]+\\)\\)?\\(\\..*\\)\\'" + prefix) + (progn + (setq timestamp (concat "0000" (match-string 1 prefix)) + len (- (length timestamp) 4)) + (vector (string-to-number (substring timestamp 0 len)) + (string-to-number (substring timestamp len)) + (string-to-number (match-string 2 prefix)) + (string-to-number (or (match-string 4 prefix) "-1")) + (match-string 5 prefix) + file)) file))) (defun nnmaildir--sort-files (a b) (catch 'return (if (consp a) - (throw 'return (and (consp b) (string-lessp (car a) (car b))))) + (throw 'return (and (consp b) (string-lessp (car a) (car b))))) (if (consp b) (throw 'return t)) (if (< (aref a 0) (aref b 0)) (throw 'return t)) (if (> (aref a 0) (aref b 0)) (throw 'return nil)) @@ -614,201 +585,195 @@ by nnmaildir-request-article.") (defun nnmaildir--scan (gname scan-msgs groups method srv-dir srv-ls) (catch 'return (let ((36h-ago (- (car (current-time)) 2)) - absdir nndir tdir ndir cdir nattr cattr isnew pgname read-only ls - files file num dir flist group x) - (setq absdir (file-name-as-directory (concat srv-dir gname)) - nndir (nnmaildir--nndir absdir)) - (if (file-attributes absdir) nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such directory: " absdir)) - (throw 'return nil)) + absdir nndir tdir ndir cdir nattr cattr isnew pgname read-only ls + files file num dir flist group x) + (setq absdir (nnmaildir--srvgrp-dir srv-dir gname) + nndir (nnmaildir--nndir absdir)) + (if (file-exists-p absdir) nil + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such directory: " absdir)) + (throw 'return nil)) (setq tdir (nnmaildir--tmp absdir) - ndir (nnmaildir--new absdir) - cdir (nnmaildir--cur absdir) - nattr (file-attributes ndir) - cattr (file-attributes cdir)) + ndir (nnmaildir--new absdir) + cdir (nnmaildir--cur absdir) + nattr (file-attributes ndir) + cattr (file-attributes cdir)) (if (and (file-exists-p tdir) nattr cattr) nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Not a maildir: " absdir)) - (throw 'return nil)) - (setq group (nnmaildir--prepare nil gname)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Not a maildir: " absdir)) + (throw 'return nil)) + (setq group (nnmaildir--prepare nil gname) + pgname (nnmaildir--pgname nnmaildir--cur-server gname)) (if group - (setq isnew nil - pgname (nnmaildir--grp-get-pname group)) - (setq isnew t - group (nnmaildir--grp-new) - pgname (gnus-group-prefixed-name gname method)) - (nnmaildir--grp-set-name group gname) - (nnmaildir--grp-set-pname group pgname) - (nnmaildir--grp-set-lists group (nnmaildir--lists-new)) - (nnmaildir--grp-set-index group 0) - (nnmaildir--mkdir nndir) - (nnmaildir--mkdir (concat nndir "nov")) - (nnmaildir--mkdir (concat nndir "marks")) - (write-region "" nil (concat nndir "markfile") nil 'no-message)) + (setq isnew nil) + (setq isnew t + group (make-nnmaildir--grp :name gname :index 0 + :lists (make-nnmaildir--lists))) + (nnmaildir--mkdir nndir) + (nnmaildir--mkdir (nnmaildir--nov-dir nndir)) + (nnmaildir--mkdir (nnmaildir--marks-dir nndir)) + (write-region "" nil (concat nndir "markfile") nil 'no-message)) (setq read-only (nnmaildir--param pgname 'read-only) - ls (or (nnmaildir--param pgname 'directory-files) srv-ls)) + ls (or (nnmaildir--param pgname 'directory-files) srv-ls)) (if read-only nil - (setq x (nth 11 (file-attributes tdir))) - (if (and (= x (nth 11 nattr)) (= x (nth 11 cattr))) nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Maildir spans filesystems: " - absdir)) - (throw 'return nil)) - (setq files (funcall ls tdir 'full "\\`[^.]" 'nosort)) - (while files - (setq file (car files) files (cdr files) - x (file-attributes file)) - (if (or (< 1 (cadr x)) (> 36h-ago (car (nth 4 x)))) - (delete-file file)))) + (setq x (nth 11 (file-attributes tdir))) + (if (and (= x (nth 11 nattr)) (= x (nth 11 cattr))) nil + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Maildir spans filesystems: " absdir)) + (throw 'return nil)) + (setq files (funcall ls tdir 'full "\\`[^.]" 'nosort)) + (while files + (setq file (car files) files (cdr files) + x (file-attributes file)) + (if (or (< 1 (cadr x)) (> 36h-ago (car (nth 4 x)))) + (delete-file file)))) (or scan-msgs - isnew - (throw 'return t)) + isnew + (throw 'return t)) (setq nattr (nth 5 nattr)) - (if (equal nattr (nnmaildir--grp-get-new group)) - (setq nattr nil)) + (if (equal nattr (nnmaildir--grp-new group)) + (setq nattr nil)) (if read-only (setq dir (and (or isnew nattr) ndir)) - (when (or isnew nattr) - (setq files (funcall ls ndir nil "\\`[^.]" 'nosort)) - (while files - (setq file (car files) files (cdr files)) - (rename-file (concat ndir file) (concat cdir file ":2,"))) - (nnmaildir--grp-set-new group nattr)) - (setq cattr (file-attributes cdir) - cattr (nth 5 cattr)) - (if (equal cattr (nnmaildir--grp-get-cur group)) - (setq cattr nil)) - (setq dir (and (or isnew cattr) cdir))) + (when (or isnew nattr) + (setq files (funcall ls ndir nil "\\`[^.]" 'nosort)) + (while files + (setq file (car files) files (cdr files)) + (rename-file (concat ndir file) (concat cdir file ":2,"))) + (setf (nnmaildir--grp-new group) nattr)) + (setq cattr (nth 5 (file-attributes cdir))) + (if (equal cattr (nnmaildir--grp-cur group)) + (setq cattr nil)) + (setq dir (and (or isnew cattr) cdir))) (if dir nil (throw 'return t)) (setq files (funcall ls dir nil "\\`[^.]" 'nosort)) (when isnew - (setq x (length files) - num 1) - (while (<= num x) (setq num (* 2 num))) - (if (/= num 1) (setq num (1- num))) - (setq x (nnmaildir--grp-get-lists group)) - (nnmaildir--lists-set-flist x (make-vector num 0)) - (nnmaildir--lists-set-mlist x (make-vector num 0)) - (nnmaildir--grp-set-mmth group (make-vector 1 0)) - (setq num (nnmaildir--param pgname 'nov-cache-size)) - (if (numberp num) (if (< num 1) (setq num 1)) - (setq x files - num 16 - cdir (file-name-as-directory (concat nndir "marks")) - ndir (file-name-as-directory (concat cdir "tick")) - cdir (file-name-as-directory (concat cdir "read"))) - (while x - (setq file (car x) x (cdr x)) - (string-match "\\`\\([^:]*\\)\\(\\(:.*\\)?\\)\\'" file) - (setq file (match-string 1 file)) - (if (or (not (file-exists-p (concat cdir file))) - (file-exists-p (concat ndir file))) - (setq num (1+ num))))) - (nnmaildir--grp-set-cache group (make-vector num nil)) - (nnmaildir--srv-set-tmpgrp nnmaildir--cur-server group) - (set (intern gname groups) group) - (nnmaildir--srv-set-tmpgrp nnmaildir--cur-server nil) - (or scan-msgs (throw 'return t))) - (setq flist (nnmaildir--grp-get-lists group) - num (nnmaildir--lists-get-nlist flist) - flist (nnmaildir--lists-get-flist flist) - num (nnmaildir--nlist-last-num num) - x files - files nil) + (setq x (length files) + num 1) + (while (<= num x) (setq num (* 2 num))) + (if (/= num 1) (setq num (1- num))) + (setq x (nnmaildir--grp-lists group)) + (setf (nnmaildir--lists-flist x) (make-vector num 0)) + (setf (nnmaildir--lists-mlist x) (make-vector num 0)) + (setf (nnmaildir--grp-mmth group) (make-vector 1 0)) + (setq num (nnmaildir--param pgname 'nov-cache-size)) + (if (numberp num) (if (< num 1) (setq num 1)) + (setq x files + num 16 + cdir (nnmaildir--marks-dir nndir) + ndir (nnmaildir--subdir cdir "tick") + cdir (nnmaildir--subdir cdir "read")) + (while x + (setq file (car x) x (cdr x)) + (string-match "\\`\\([^:]*\\)\\(\\(:.*\\)?\\)\\'" file) + (setq file (match-string 1 file)) + (if (or (not (file-exists-p (concat cdir file))) + (file-exists-p (concat ndir file))) + (setq num (1+ num))))) + (setf (nnmaildir--grp-cache group) (make-vector num nil)) + (let ((inhibit-quit t)) + (set (intern gname groups) group)) + (or scan-msgs (throw 'return t))) + (setq flist (nnmaildir--grp-lists group) + num (nnmaildir--lists-nlist flist) + flist (nnmaildir--lists-flist flist) + num (nnmaildir--nlist-last-num num) + x files + files nil) (while x - (setq file (car x) x (cdr x)) - (string-match "\\`\\([^:]*\\)\\(\\(:.*\\)?\\)\\'" file) - (setq file (cons (match-string 1 file) (match-string 2 file))) - (if (nnmaildir--flist-art flist (car file)) nil - (setq files (cons file files)))) + (setq file (car x) x (cdr x)) + (string-match "\\`\\([^:]*\\)\\(\\(:.*\\)?\\)\\'" file) + (setq file (cons (match-string 1 file) (match-string 2 file))) + (if (nnmaildir--flist-art flist (car file)) nil + (setq files (cons file files)))) (setq files (mapcar 'nnmaildir--parse-filename files) - files (sort files 'nnmaildir--sort-files)) + files (sort files 'nnmaildir--sort-files)) (while files - (setq file (car files) files (cdr files) - file (if (consp file) file (aref file 5)) - x (nnmaildir--art-new)) - (nnmaildir--art-set-prefix x (car file)) - (nnmaildir--art-set-suffix x (cdr file)) - (nnmaildir--art-set-num x (1+ num)) - (if (nnmaildir--grp-add-art srv-dir group x) - (setq num (1+ num)))) - (if read-only (nnmaildir--grp-set-new group nattr) - (nnmaildir--grp-set-cur group cattr))) + (setq file (car files) files (cdr files) + file (if (consp file) file (aref file 5)) + x (make-nnmaildir--art :prefix (car file) :suffix(cdr file) + :num (1+ num))) + (if (nnmaildir--grp-add-art nnmaildir--cur-server group x) + (setq num (1+ num)))) + (if read-only (setf (nnmaildir--grp-new group) nattr) + (setf (nnmaildir--grp-cur group) cattr))) t)) (defun nnmaildir-request-scan (&optional scan-group server) (let ((coding-system-for-write nnheader-file-coding-system) - (buffer-file-coding-system nil) - (file-coding-system-alist nil) - (nnmaildir-get-new-mail t) - (nnmaildir-group-alist nil) - (nnmaildir-active-file nil) - x srv-ls srv-dir method groups group dirs grp-dir seen deactivate-mark) + (buffer-file-coding-system nil) + (file-coding-system-alist nil) + (nnmaildir-get-new-mail t) + (nnmaildir-group-alist nil) + (nnmaildir-active-file nil) + x srv-ls srv-dir method groups group dirs grp-dir seen deactivate-mark) (nnmaildir--prepare server nil) - (setq srv-ls (nnmaildir--srv-get-ls nnmaildir--cur-server) - srv-dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - method (nnmaildir--srv-get-method nnmaildir--cur-server) - groups (nnmaildir--srv-get-groups nnmaildir--cur-server)) - (save-excursion - (set-buffer (get-buffer-create " *nnmaildir work*")) + (setq srv-ls (nnmaildir--srv-ls nnmaildir--cur-server) + srv-dir (nnmaildir--srv-dir nnmaildir--cur-server) + method (nnmaildir--srv-method nnmaildir--cur-server) + groups (nnmaildir--srv-groups nnmaildir--cur-server)) + (nnmaildir--with-work-buffer (save-match-data - (if (stringp scan-group) - (if (nnmaildir--scan scan-group t groups method srv-dir srv-ls) - (if (nnmaildir--srv-get-gnm nnmaildir--cur-server) - (nnmail-get-new-mail 'nnmaildir nil nil scan-group)) - (unintern scan-group groups)) - (setq x (nth 5 (file-attributes srv-dir))) - (if (equal x (nnmaildir--srv-get-mtime nnmaildir--cur-server)) - (if scan-group nil - (mapatoms (lambda (sym) - (nnmaildir--scan (symbol-name sym) t groups - method srv-dir srv-ls)) - groups)) - (setq dirs (funcall srv-ls srv-dir nil "\\`[^.]" 'nosort) - x (length dirs) - seen 1) - (while (<= seen x) (setq seen (* 2 seen))) - (if (/= seen 1) (setq seen (1- seen))) - (setq seen (make-vector seen 0) - scan-group (null scan-group)) - (while dirs - (setq grp-dir (car dirs) dirs (cdr dirs)) - (if (nnmaildir--scan grp-dir scan-group groups method srv-dir - srv-ls) - (intern grp-dir seen))) - (setq x nil) - (mapatoms (lambda (group) - (setq group (symbol-name group)) - (if (intern-soft group seen) nil - (setq x (cons group x)))) - groups) - (while x - (unintern (car x) groups) - (setq x (cdr x))) - (nnmaildir--srv-set-mtime nnmaildir--cur-server - (nth 5 (file-attributes srv-dir)))) - (if (nnmaildir--srv-get-gnm nnmaildir--cur-server) - (nnmail-get-new-mail 'nnmaildir nil nil)))))) + (if (stringp scan-group) + (if (nnmaildir--scan scan-group t groups method srv-dir srv-ls) + (if (nnmaildir--srv-gnm nnmaildir--cur-server) + (nnmail-get-new-mail 'nnmaildir nil nil scan-group)) + (unintern scan-group groups)) + (setq x (nth 5 (file-attributes srv-dir)) + scan-group (null scan-group)) + (if (equal x (nnmaildir--srv-mtime nnmaildir--cur-server)) + (if scan-group + (mapatoms (lambda (sym) + (nnmaildir--scan (symbol-name sym) t groups + method srv-dir srv-ls)) + groups)) + (setq dirs (funcall srv-ls srv-dir nil "\\`[^.]" 'nosort) + x (length dirs) + seen 1) + (while (<= seen x) (setq seen (* 2 seen))) + (if (/= seen 1) (setq seen (1- seen))) + (setq seen (make-vector seen 0)) + (while dirs + (setq grp-dir (car dirs) dirs (cdr dirs)) + (if (nnmaildir--scan grp-dir scan-group groups method srv-dir + srv-ls) + (intern grp-dir seen))) + (setq x nil) + (mapatoms (lambda (group) + (setq group (symbol-name group)) + (if (intern-soft group seen) nil + (setq x (cons group x)))) + groups) + (while x + (unintern (car x) groups) + (setq x (cdr x))) + (setf (nnmaildir--srv-mtime nnmaildir--cur-server) + (nth 5 (file-attributes srv-dir)))) + (and scan-group + (nnmaildir--srv-gnm nnmaildir--cur-server) + (nnmail-get-new-mail 'nnmaildir nil nil)))))) t) (defun nnmaildir-request-list (&optional server) (nnmaildir-request-scan 'find-new-groups server) (let (pgname ro ct-min deactivate-mark) (nnmaildir--prepare server nil) - (save-excursion - (set-buffer nntp-server-buffer) + (nnmaildir--with-nntp-buffer (erase-buffer) (mapatoms (lambda (group) - (setq group (symbol-value group) - ro (nnmaildir--param (nnmaildir--grp-get-pname group) - 'read-only) - ct-min (nnmaildir--article-count group)) - (insert (nnmaildir--grp-get-name group) " ") - (princ (car ct-min) nntp-server-buffer) - (insert " ") - (princ (cdr ct-min) nntp-server-buffer) - (insert " " (if ro "n" "y") "\n")) - (nnmaildir--srv-get-groups nnmaildir--cur-server)))) + (setq pgname (symbol-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server pgname) + group (symbol-value group) + ro (nnmaildir--param pgname 'read-only) + ct-min (nnmaildir--article-count group)) + (insert (nnmaildir--grp-name group) " ") + (princ (nnmaildir--nlist-last-num + (nnmaildir--lists-nlist + (nnmaildir--grp-lists group))) + nntp-server-buffer) + (insert " ") + (princ (cdr ct-min) nntp-server-buffer) + (insert " " (if ro "n" "y") "\n")) + (nnmaildir--srv-groups nnmaildir--cur-server)))) t) (defun nnmaildir-request-newgroups (date &optional server) @@ -817,430 +782,416 @@ by nnmaildir-request-article.") (defun nnmaildir-retrieve-groups (groups &optional server) (let (gname group ct-min deactivate-mark) (nnmaildir--prepare server nil) - (save-excursion - (set-buffer nntp-server-buffer) + (nnmaildir--with-nntp-buffer (erase-buffer) (while groups - (setq gname (car groups) groups (cdr groups)) - (nnmaildir-request-scan gname server) - (setq group (nnmaildir--prepare nil gname)) - (if (null group) (insert "411 no such news group\n") - (setq ct-min (nnmaildir--article-count group)) - (insert "211 ") - (princ (car ct-min) nntp-server-buffer) - (insert " ") - (princ (cdr ct-min) nntp-server-buffer) - (insert " ") - (princ (nnmaildir--nlist-last-num - (nnmaildir--lists-get-nlist - (nnmaildir--grp-get-lists group))) - nntp-server-buffer) - (insert " " gname "\n"))))) + (setq gname (car groups) groups (cdr groups)) + (setq group (nnmaildir--prepare nil gname)) + (if (null group) (insert "411 no such news group\n") + (setq ct-min (nnmaildir--article-count group)) + (insert "211 ") + (princ (car ct-min) nntp-server-buffer) + (insert " ") + (princ (cdr ct-min) nntp-server-buffer) + (insert " ") + (princ (nnmaildir--nlist-last-num + (nnmaildir--lists-nlist + (nnmaildir--grp-lists group))) + nntp-server-buffer) + (insert " " gname "\n"))))) 'group) (defun nnmaildir-request-update-info (gname info &optional server) - (nnmaildir-request-scan gname server) (let ((group (nnmaildir--prepare server gname)) - srv-ls pgname nlist flist last always-marks never-marks old-marks - dotfile num dir markdirs marks mark ranges articles article read end - new-marks ls old-mmth new-mmth mtime mark-sym deactivate-mark) + pgname nlist flist last always-marks never-marks old-marks dotfile num + dir markdirs marks mark ranges articles article read end new-marks ls + old-mmth new-mmth mtime mark-sym deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) - (setq srv-ls (nnmaildir--srv-get-ls nnmaildir--cur-server) - gname (nnmaildir--grp-get-name group) - pgname (nnmaildir--grp-get-pname group) - nlist (nnmaildir--grp-get-lists group) - flist (nnmaildir--lists-get-flist nlist) - nlist (nnmaildir--lists-get-nlist nlist)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) + (setq gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server gname) + nlist (nnmaildir--grp-lists group) + flist (nnmaildir--lists-flist nlist) + nlist (nnmaildir--lists-nlist nlist)) (if nlist nil - (gnus-info-set-read info nil) - (gnus-info-set-marks info nil 'extend) - (throw 'return info)) + (gnus-info-set-read info nil) + (gnus-info-set-marks info nil 'extend) + (throw 'return info)) (setq old-marks (cons 'read (gnus-info-read info)) - old-marks (cons old-marks (gnus-info-marks info)) - last (nnmaildir--nlist-last-num nlist) - always-marks (nnmaildir--param pgname 'always-marks) - never-marks (nnmaildir--param pgname 'never-marks) - dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir dir gname) - dir (nnmaildir--nndir dir) - dir (concat dir "marks") - dir (file-name-as-directory dir) - ls (nnmaildir--param pgname 'directory-files) - ls (or ls srv-ls) - markdirs (funcall ls dir nil "\\`[^.]" 'nosort) - num (length markdirs) - new-mmth 1) + old-marks (cons old-marks (gnus-info-marks info)) + last (nnmaildir--nlist-last-num nlist) + always-marks (nnmaildir--param pgname 'always-marks) + never-marks (nnmaildir--param pgname 'never-marks) + dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir dir gname) + dir (nnmaildir--nndir dir) + dir (nnmaildir--marks-dir dir) + ls (nnmaildir--group-ls nnmaildir--cur-server pgname) + markdirs (funcall ls dir nil "\\`[^.]" 'nosort) + num (length markdirs) + new-mmth 1) (while (<= new-mmth num) (setq new-mmth (* 2 new-mmth))) (if (/= new-mmth 1) (setq new-mmth (1- new-mmth))) (setq new-mmth (make-vector new-mmth 0) - old-mmth (nnmaildir--grp-get-mmth group)) + old-mmth (nnmaildir--grp-mmth group)) (while markdirs - (setq mark (car markdirs) markdirs (cdr markdirs) - articles (concat dir mark) - articles (file-name-as-directory articles) - mark-sym (intern mark) - ranges nil) - (catch 'got-ranges - (if (memq mark-sym never-marks) (throw 'got-ranges nil)) - (when (memq mark-sym always-marks) - (setq ranges (list (cons 1 last))) - (throw 'got-ranges nil)) - (setq mtime (file-attributes articles) - mtime (nth 5 mtime)) - (set (intern mark new-mmth) mtime) - (when (equal mtime (symbol-value (intern-soft mark old-mmth))) - (setq ranges (assq mark-sym old-marks)) - (if ranges (setq ranges (cdr ranges))) - (throw 'got-ranges nil)) - (setq articles (funcall ls articles nil "\\`[^.]" 'nosort)) - (while articles - (setq article (car articles) articles (cdr articles) - article (nnmaildir--flist-art flist article)) - (if article - (setq num (nnmaildir--art-get-num article) - ranges (gnus-add-to-range ranges (list num)))))) - (if (eq mark-sym 'read) (setq read ranges) - (if ranges (setq marks (cons (cons mark-sym ranges) marks))))) + (setq mark (car markdirs) markdirs (cdr markdirs) + articles (nnmaildir--subdir dir mark) + mark-sym (intern mark) + ranges nil) + (catch 'got-ranges + (if (memq mark-sym never-marks) (throw 'got-ranges nil)) + (when (memq mark-sym always-marks) + (setq ranges (list (cons 1 last))) + (throw 'got-ranges nil)) + (setq mtime (nth 5 (file-attributes articles))) + (set (intern mark new-mmth) mtime) + (when (equal mtime (symbol-value (intern-soft mark old-mmth))) + (setq ranges (assq mark-sym old-marks)) + (if ranges (setq ranges (cdr ranges))) + (throw 'got-ranges nil)) + (setq articles (funcall ls articles nil "\\`[^.]" 'nosort)) + (while articles + (setq article (car articles) articles (cdr articles) + article (nnmaildir--flist-art flist article)) + (if article + (setq num (nnmaildir--art-num article) + ranges (gnus-add-to-range ranges (list num)))))) + (if (eq mark-sym 'read) (setq read ranges) + (if ranges (setq marks (cons (cons mark-sym ranges) marks))))) (gnus-info-set-read info read) (gnus-info-set-marks info marks 'extend) - (nnmaildir--grp-set-mmth group new-mmth) + (setf (nnmaildir--grp-mmth group) new-mmth) info))) (defun nnmaildir-request-group (gname &optional server fast) - (nnmaildir-request-scan gname server) (let ((group (nnmaildir--prepare server gname)) - ct-min deactivate-mark) - (save-excursion - (set-buffer nntp-server-buffer) + ct-min deactivate-mark) + (nnmaildir--with-nntp-buffer (erase-buffer) (catch 'return - (if group nil - (insert "411 no such news group\n") - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) - (nnmaildir--srv-set-curgrp nnmaildir--cur-server group) - (if fast (throw 'return t)) - (setq ct-min (nnmaildir--article-count group)) - (insert "211 ") - (princ (car ct-min) nntp-server-buffer) - (insert " ") - (princ (cdr ct-min) nntp-server-buffer) - (insert " ") - (princ (nnmaildir--nlist-last-num - (nnmaildir--lists-get-nlist - (nnmaildir--grp-get-lists group))) - nntp-server-buffer) - (insert " " gname "\n") - t)))) + (if group nil + (insert "411 no such news group\n") + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) + (setf (nnmaildir--srv-curgrp nnmaildir--cur-server) group) + (if fast (throw 'return t)) + (setq ct-min (nnmaildir--article-count group)) + (insert "211 ") + (princ (car ct-min) nntp-server-buffer) + (insert " ") + (princ (cdr ct-min) nntp-server-buffer) + (insert " ") + (princ (nnmaildir--nlist-last-num + (nnmaildir--lists-nlist + (nnmaildir--grp-lists group))) + nntp-server-buffer) + (insert " " gname "\n") + t)))) (defun nnmaildir-request-create-group (gname &optional server args) (nnmaildir--prepare server nil) (catch 'return - (let ((create-dir (nnmaildir--srv-get-create-dir nnmaildir--cur-server)) - srv-dir dir groups) + (let ((create-dir (nnmaildir--srv-create-dir nnmaildir--cur-server)) + srv-dir dir groups) (when (zerop (length gname)) - (nnmaildir--srv-set-error nnmaildir--cur-server - "Invalid (empty) group name") - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Invalid (empty) group name") + (throw 'return nil)) (when (eq (aref "." 0) (aref gname 0)) - (nnmaildir--srv-set-error nnmaildir--cur-server - "Group names may not start with \".\"") - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Group names may not start with \".\"") + (throw 'return nil)) (when (save-match-data (string-match "[\0/\t]" gname)) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Illegal characters (null, tab, or /) in group name: " - gname)) - (throw 'return nil)) - (setq groups (nnmaildir--srv-get-groups nnmaildir--cur-server)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Illegal characters (null, tab, or /) in group name: " + gname)) + (throw 'return nil)) + (setq groups (nnmaildir--srv-groups nnmaildir--cur-server)) (when (intern-soft gname groups) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Group already exists: " gname)) - (throw 'return nil)) - (setq srv-dir (nnmaildir--srv-get-dir nnmaildir--cur-server)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Group already exists: " gname)) + (throw 'return nil)) + (setq srv-dir (nnmaildir--srv-dir nnmaildir--cur-server)) (if (file-name-absolute-p create-dir) - (setq dir (expand-file-name create-dir)) - (setq dir srv-dir - dir (file-truename dir) - dir (concat dir create-dir))) - (setq dir (file-name-as-directory dir) - dir (concat dir gname)) + (setq dir (expand-file-name create-dir)) + (setq dir srv-dir + dir (file-truename dir) + dir (concat dir create-dir))) + (setq dir (nnmaildir--subdir (file-name-as-directory dir) gname)) (nnmaildir--mkdir dir) - (setq dir (file-name-as-directory dir)) - (nnmaildir--mkdir (concat dir "tmp")) - (nnmaildir--mkdir (concat dir "new")) - (nnmaildir--mkdir (concat dir "cur")) + (nnmaildir--mkdir (nnmaildir--tmp dir)) + (nnmaildir--mkdir (nnmaildir--new dir)) + (nnmaildir--mkdir (nnmaildir--cur dir)) (setq create-dir (file-name-as-directory create-dir)) (make-symbolic-link (concat create-dir gname) (concat srv-dir gname)) (nnmaildir-request-scan 'find-new-groups)))) (defun nnmaildir-request-rename-group (gname new-name &optional server) (let ((group (nnmaildir--prepare server gname)) - (coding-system-for-write nnheader-file-coding-system) - (buffer-file-coding-system nil) - (file-coding-system-alist nil) - srv-dir x groups) + (coding-system-for-write nnheader-file-coding-system) + (buffer-file-coding-system nil) + (file-coding-system-alist nil) + srv-dir x groups) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) (when (zerop (length new-name)) - (nnmaildir--srv-set-error nnmaildir--cur-server - "Invalid (empty) group name") - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Invalid (empty) group name") + (throw 'return nil)) (when (eq (aref "." 0) (aref new-name 0)) - (nnmaildir--srv-set-error nnmaildir--cur-server - "Group names may not start with \".\"") - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Group names may not start with \".\"") + (throw 'return nil)) (when (save-match-data (string-match "[\0/\t]" new-name)) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Illegal characters (null, tab, or /) in group name: " - new-name)) - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Illegal characters (null, tab, or /) in group name: " + new-name)) + (throw 'return nil)) (if (string-equal gname new-name) (throw 'return t)) (when (intern-soft new-name - (nnmaildir--srv-get-groups nnmaildir--cur-server)) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Group already exists: " new-name)) - (throw 'return nil)) - (setq srv-dir (nnmaildir--srv-get-dir nnmaildir--cur-server)) + (nnmaildir--srv-groups nnmaildir--cur-server)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Group already exists: " new-name)) + (throw 'return nil)) + (setq srv-dir (nnmaildir--srv-dir nnmaildir--cur-server)) (condition-case err - (rename-file (concat srv-dir gname) - (concat srv-dir new-name)) - (error - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Error renaming link: " - (prin1-to-string err))) - (throw 'return nil))) - (setq x (nnmaildir--srv-get-groups nnmaildir--cur-server) - groups (make-vector (length x) 0)) + (rename-file (concat srv-dir gname) + (concat srv-dir new-name)) + (error + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Error renaming link: " (prin1-to-string err))) + (throw 'return nil))) + (setq x (nnmaildir--srv-groups nnmaildir--cur-server) + groups (make-vector (length x) 0)) (mapatoms (lambda (sym) - (if (eq (symbol-value sym) group) nil - (set (intern (symbol-name sym) groups) - (symbol-value sym)))) - x) + (if (eq (symbol-value sym) group) nil + (set (intern (symbol-name sym) groups) + (symbol-value sym)))) + x) (setq group (copy-sequence group)) - (nnmaildir--grp-set-name group new-name) + (setf (nnmaildir--grp-name group) new-name) (set (intern new-name groups) group) - (nnmaildir--srv-set-groups nnmaildir--cur-server groups) + (setf (nnmaildir--srv-groups nnmaildir--cur-server) groups) t))) (defun nnmaildir-request-delete-group (gname force &optional server) (let ((group (nnmaildir--prepare server gname)) - pgname grp-dir dir dirs files ls deactivate-mark) + pgname grp-dir dir dirs files ls deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) - (if (eq group (nnmaildir--srv-get-curgrp nnmaildir--cur-server)) - (nnmaildir--srv-set-curgrp nnmaildir--cur-server nil)) - (setq gname (nnmaildir--grp-get-name group) - pgname (nnmaildir--grp-get-pname group)) - (unintern gname (nnmaildir--srv-get-groups nnmaildir--cur-server)) - (setq grp-dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - grp-dir (nnmaildir--srv-grp-dir grp-dir gname)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) + (if (eq group (nnmaildir--srv-curgrp nnmaildir--cur-server)) + (setf (nnmaildir--srv-curgrp nnmaildir--cur-server) nil)) + (setq gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server gname)) + (unintern gname (nnmaildir--srv-groups nnmaildir--cur-server)) + (setq grp-dir (nnmaildir--srv-dir nnmaildir--cur-server) + grp-dir (nnmaildir--srvgrp-dir grp-dir gname)) (if (not force) (setq grp-dir (directory-file-name grp-dir)) - (if (nnmaildir--param pgname 'read-only) - (progn (delete-directory (nnmaildir--tmp grp-dir)) - (nnmaildir--unlink (nnmaildir--new grp-dir)) - (delete-directory (nnmaildir--cur grp-dir))) - (save-excursion - (set-buffer (get-buffer-create " *nnmaildir work*")) - (erase-buffer) - (setq ls (or (nnmaildir--param pgname 'directory-files) - (nnmaildir--srv-get-ls nnmaildir--cur-server)) - files (funcall ls (nnmaildir--tmp grp-dir) 'full "\\`[^.]" - 'nosort)) - (while files - (delete-file (car files)) - (setq files (cdr files))) - (delete-directory (concat grp-dir "tmp")) - (setq files (funcall ls (nnmaildir--new grp-dir) 'full "\\`[^.]" - 'nosort)) - (while files - (delete-file (car files)) - (setq files (cdr files))) - (delete-directory (concat grp-dir "new")) - (setq files (funcall ls (nnmaildir--cur grp-dir) 'full "\\`[^.]" - 'nosort)) - (while files - (delete-file (car files)) - (setq files (cdr files))) - (delete-directory (concat grp-dir "cur")))) - (setq dir (nnmaildir--nndir grp-dir) - dirs (cons (concat dir "nov") - (funcall ls (concat dir "marks") 'full "\\`[^.]" - 'nosort))) - (while dirs - (setq dir (car dirs) dirs (cdr dirs) - files (funcall ls dir 'full "\\`[^.]" 'nosort)) - (while files - (delete-file (car files)) - (setq files (cdr files))) - (delete-directory dir)) - (setq dir (nnmaildir--nndir grp-dir) - files (concat dir "markfile")) - (nnmaildir--unlink files) - (delete-directory (concat dir "marks")) - (delete-directory dir) - (setq grp-dir (directory-file-name grp-dir) - dir (car (file-attributes grp-dir))) - (if (eq (aref "/" 0) (aref dir 0)) nil - (setq dir (concat (file-truename - (nnmaildir--srv-get-dir nnmaildir--cur-server)) - dir))) - (delete-directory dir)) + (if (nnmaildir--param pgname 'read-only) + (progn (delete-directory (nnmaildir--tmp grp-dir)) + (nnmaildir--unlink (nnmaildir--new grp-dir)) + (delete-directory (nnmaildir--cur grp-dir))) + (nnmaildir--with-work-buffer + (erase-buffer) + (setq ls (nnmaildir--group-ls nnmaildir--cur-server pgname) + files (funcall ls (nnmaildir--tmp grp-dir) 'full "\\`[^.]" + 'nosort)) + (while files + (delete-file (car files)) + (setq files (cdr files))) + (delete-directory (nnmaildir--tmp grp-dir)) + (setq files (funcall ls (nnmaildir--new grp-dir) 'full "\\`[^.]" + 'nosort)) + (while files + (delete-file (car files)) + (setq files (cdr files))) + (delete-directory (nnmaildir--new grp-dir)) + (setq files (funcall ls (nnmaildir--cur grp-dir) 'full "\\`[^.]" + 'nosort)) + (while files + (delete-file (car files)) + (setq files (cdr files))) + (delete-directory (nnmaildir--cur grp-dir)))) + (setq dir (nnmaildir--nndir grp-dir) + dirs (cons (nnmaildir--nov-dir dir) + (funcall ls (nnmaildir--marks-dir dir) 'full "\\`[^.]" + 'nosort))) + (while dirs + (setq dir (car dirs) dirs (cdr dirs) + files (funcall ls dir 'full "\\`[^.]" 'nosort)) + (while files + (delete-file (car files)) + (setq files (cdr files))) + (delete-directory dir)) + (setq dir (nnmaildir--nndir grp-dir)) + (nnmaildir--unlink (concat dir "markfile")) + (nnmaildir--unlink (concat dir "markfile{new}")) + (delete-directory (nnmaildir--marks-dir dir)) + (delete-directory dir) + (setq grp-dir (directory-file-name grp-dir) + dir (car (file-attributes grp-dir))) + (if (eq (aref "/" 0) (aref dir 0)) nil + (setq dir (concat (file-truename + (nnmaildir--srv-dir nnmaildir--cur-server)) + dir))) + (delete-directory dir)) (nnmaildir--unlink grp-dir) t))) (defun nnmaildir-retrieve-headers (articles &optional gname server fetch-old) (let ((group (nnmaildir--prepare server gname)) - srv-dir dir nlist mlist article num stop nov nlist2 deactivate-mark) + srv-dir dir nlist mlist article num stop nov nlist2 deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (if gname (concat "No such group: " gname) - "No current group")) - (throw 'return nil)) - (save-excursion - (set-buffer nntp-server-buffer) - (erase-buffer) - (setq nlist (nnmaildir--grp-get-lists group) - mlist (nnmaildir--lists-get-mlist nlist) - nlist (nnmaildir--lists-get-nlist nlist) - gname (nnmaildir--grp-get-name group) - srv-dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir srv-dir gname)) - (cond - ((null nlist)) - ((and fetch-old (not (numberp fetch-old))) - (while nlist - (setq article (car nlist) nlist (cdr nlist) - nov (nnmaildir--update-nov srv-dir group article)) - (when nov - (nnmaildir--cache-nov group article nov) - (setq num (nnmaildir--art-get-num article)) - (princ num nntp-server-buffer) - (insert "\t" (nnmaildir--nov-get-beg nov) "\t" - (nnmaildir--art-get-msgid article) "\t" - (nnmaildir--nov-get-mid nov) "\tXref: nnmaildir " gname - ":") - (princ num nntp-server-buffer) - (insert "\t" (nnmaildir--nov-get-end nov) "\n") - (goto-char (point-min))))) - ((null articles)) - ((stringp (car articles)) - (while articles - (setq article (car articles) articles (cdr articles) - article (nnmaildir--mlist-art mlist article)) - (when (and article - (setq nov (nnmaildir--update-nov srv-dir group - article))) - (nnmaildir--cache-nov group article nov) - (setq num (nnmaildir--art-get-num article)) - (princ num nntp-server-buffer) - (insert "\t" (nnmaildir--nov-get-beg nov) "\t" - (nnmaildir--art-get-msgid article) "\t" - (nnmaildir--nov-get-mid nov) "\tXref: nnmaildir " gname - ":") - (princ num nntp-server-buffer) - (insert "\t" (nnmaildir--nov-get-end nov) "\n")))) - (t - (if fetch-old - ;; Assume the article range is sorted ascending - (setq stop (car articles) - num (car (last articles)) - stop (if (numberp stop) stop (car stop)) - num (if (numberp num) num (cdr num)) - stop (- stop fetch-old) - stop (if (< stop 1) 1 stop) - articles (list (cons stop num)))) - (while articles - (setq stop (car articles) articles (cdr articles)) - (while (eq stop (car articles)) - (setq articles (cdr articles))) - (if (numberp stop) (setq num stop) - (setq num (cdr stop) stop (car stop))) - (setq nlist2 (nthcdr (- (nnmaildir--art-get-num (car nlist)) num) - nlist)) - (while (and nlist2 - (setq article (car nlist2) - num (nnmaildir--art-get-num article)) - (>= num stop)) - (setq nlist2 (cdr nlist2) - nov (nnmaildir--update-nov srv-dir group article)) - (when nov - (nnmaildir--cache-nov group article nov) - (princ num nntp-server-buffer) - (insert "\t" (nnmaildir--nov-get-beg nov) "\t" - (nnmaildir--art-get-msgid article) "\t" - (nnmaildir--nov-get-mid nov) "\tXref: nnmaildir " gname - ":") - (princ num nntp-server-buffer) - (insert "\t" (nnmaildir--nov-get-end nov) "\n") - (goto-char (point-min))))))) - (sort-numeric-fields 1 (point-min) (point-max)) - 'nov)))) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (if gname (concat "No such group: " gname) "No current group")) + (throw 'return nil)) + (nnmaildir--with-nntp-buffer + (erase-buffer) + (setq nlist (nnmaildir--grp-lists group) + mlist (nnmaildir--lists-mlist nlist) + nlist (nnmaildir--lists-nlist nlist) + gname (nnmaildir--grp-name group) + srv-dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir srv-dir gname)) + (cond + ((null nlist)) + ((and fetch-old (not (numberp fetch-old))) + (while nlist + (setq article (car nlist) nlist (cdr nlist) + nov (nnmaildir--update-nov nnmaildir--cur-server group + article)) + (when nov + (nnmaildir--cache-nov group article nov) + (setq num (nnmaildir--art-num article)) + (princ num nntp-server-buffer) + (insert "\t" (nnmaildir--nov-get-beg nov) "\t" + (nnmaildir--art-msgid article) "\t" + (nnmaildir--nov-get-mid nov) "\tXref: nnmaildir " gname + ":") + (princ num nntp-server-buffer) + (insert "\t" (nnmaildir--nov-get-end nov) "\n") + (goto-char (point-min))))) + ((null articles)) + ((stringp (car articles)) + (while articles + (setq article (car articles) articles (cdr articles) + article (nnmaildir--mlist-art mlist article)) + (when (and article + (setq nov (nnmaildir--update-nov nnmaildir--cur-server + group article))) + (nnmaildir--cache-nov group article nov) + (setq num (nnmaildir--art-num article)) + (princ num nntp-server-buffer) + (insert "\t" (nnmaildir--nov-get-beg nov) "\t" + (nnmaildir--art-msgid article) "\t" + (nnmaildir--nov-get-mid nov) "\tXref: nnmaildir " gname + ":") + (princ num nntp-server-buffer) + (insert "\t" (nnmaildir--nov-get-end nov) "\n")))) + (t + (if fetch-old + ;; Assume the article range is sorted ascending + (setq stop (car articles) + num (car (last articles)) + stop (if (numberp stop) stop (car stop)) + num (if (numberp num) num (cdr num)) + stop (- stop fetch-old) + stop (if (< stop 1) 1 stop) + articles (list (cons stop num)))) + (while articles + (setq stop (car articles) articles (cdr articles)) + (while (eq stop (car articles)) + (setq articles (cdr articles))) + (if (numberp stop) (setq num stop) + (setq num (cdr stop) stop (car stop))) + (setq nlist2 (nthcdr (- (nnmaildir--art-num (car nlist)) num) + nlist)) + (while (and nlist2 + (setq article (car nlist2) + num (nnmaildir--art-num article)) + (>= num stop)) + (setq nlist2 (cdr nlist2) + nov (nnmaildir--update-nov nnmaildir--cur-server group + article)) + (when nov + (nnmaildir--cache-nov group article nov) + (princ num nntp-server-buffer) + (insert "\t" (nnmaildir--nov-get-beg nov) "\t" + (nnmaildir--art-msgid article) "\t" + (nnmaildir--nov-get-mid nov) "\tXref: nnmaildir " gname + ":") + (princ num nntp-server-buffer) + (insert "\t" (nnmaildir--nov-get-end nov) "\n") + (goto-char (point-min))))))) + (sort-numeric-fields 1 (point-min) (point-max)) + 'nov)))) (defun nnmaildir-request-article (num-msgid &optional gname server to-buffer) (let ((group (nnmaildir--prepare server gname)) - (case-fold-search t) - list article suffix dir deactivate-mark) + (case-fold-search t) + list article suffix dir pgname deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (if gname (concat "No such group: " gname) - "No current group")) - (throw 'return nil)) - (setq list (nnmaildir--grp-get-lists group)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (if gname (concat "No such group: " gname) "No current group")) + (throw 'return nil)) + (setq list (nnmaildir--grp-lists group)) (if (numberp num-msgid) - (setq list (nnmaildir--lists-get-nlist list) - article (nnmaildir--nlist-art list num-msgid)) - (setq list (nnmaildir--lists-get-mlist list) - article (nnmaildir--mlist-art list num-msgid)) - (if article (setq num-msgid (nnmaildir--art-get-num article)) - (catch 'found - (mapatoms + (setq list (nnmaildir--lists-nlist list) + article (nnmaildir--nlist-art list num-msgid)) + (setq list (nnmaildir--lists-mlist list) + article (nnmaildir--mlist-art list num-msgid)) + (if article (setq num-msgid (nnmaildir--art-num article)) + (catch 'found + (mapatoms (lambda (grp) (setq group (symbol-value grp) - list (nnmaildir--grp-get-lists group) - list (nnmaildir--lists-get-mlist list) + list (nnmaildir--grp-lists group) + list (nnmaildir--lists-mlist list) article (nnmaildir--mlist-art list num-msgid)) (when article - (setq num-msgid (nnmaildir--art-get-num article)) + (setq num-msgid (nnmaildir--art-num article)) (throw 'found nil))) - (nnmaildir--srv-get-groups nnmaildir--cur-server))))) + (nnmaildir--srv-groups nnmaildir--cur-server))))) (if article nil - (nnmaildir--srv-set-error nnmaildir--cur-server "No such article") - (throw 'return nil)) - (if (stringp (setq suffix (nnmaildir--art-get-suffix article))) nil - (nnmaildir--srv-set-error nnmaildir--cur-server "Article has expired") - (throw 'return nil)) - (setq gname (nnmaildir--grp-get-name group) - dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir dir gname) - group (if (nnmaildir--param (nnmaildir--grp-get-pname group) - 'read-only) - (nnmaildir--new dir) (nnmaildir--cur dir)) - nnmaildir-article-file-name (concat group - (nnmaildir--art-get-prefix - article) - suffix)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) "No such article") + (throw 'return nil)) + (if (stringp (setq suffix (nnmaildir--art-suffix article))) nil + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Article has expired") + (throw 'return nil)) + (setq gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server gname) + dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir dir gname) + group (if (nnmaildir--param pgname 'read-only) + (nnmaildir--new dir) (nnmaildir--cur dir)) + nnmaildir-article-file-name (concat group + (nnmaildir--art-prefix + article) + suffix)) (if (file-exists-p nnmaildir-article-file-name) nil - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil) - (nnmaildir--srv-set-error nnmaildir--cur-server "Article has expired") - (throw 'return nil)) + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Article has expired") + (throw 'return nil)) (save-excursion - (set-buffer (or to-buffer nntp-server-buffer)) - (erase-buffer) - (nnheader-insert-file-contents nnmaildir-article-file-name)) + (set-buffer (or to-buffer nntp-server-buffer)) + (erase-buffer) + (nnheader-insert-file-contents nnmaildir-article-file-name)) (cons gname num-msgid)))) (defun nnmaildir-request-post (&optional server) @@ -1249,426 +1200,419 @@ by nnmaildir-request-article.") (defun nnmaildir-request-replace-article (article gname buffer) (let ((group (nnmaildir--prepare nil gname)) - (coding-system-for-write nnheader-file-coding-system) - (buffer-file-coding-system nil) - (file-coding-system-alist nil) - file dir suffix tmpfile deactivate-mark) + (coding-system-for-write nnheader-file-coding-system) + (buffer-file-coding-system nil) + (file-coding-system-alist nil) + file dir suffix tmpfile deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) - (when (nnmaildir--param (nnmaildir--grp-get-pname group) 'read-only) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Read-only group: " group)) - (throw 'return nil)) - (setq dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir dir gname) - file (nnmaildir--grp-get-lists group) - file (nnmaildir--lists-get-nlist file) - file (nnmaildir--nlist-art file article)) - (if (and file (stringp (setq suffix (nnmaildir--art-get-suffix file)))) - nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (format "No such article: %d" article)) - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) + (when (nnmaildir--param (nnmaildir--pgname nnmaildir--cur-server gname) + 'read-only) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Read-only group: " group)) + (throw 'return nil)) + (setq dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir dir gname) + file (nnmaildir--grp-lists group) + file (nnmaildir--lists-nlist file) + file (nnmaildir--nlist-art file article)) + (if (and file (stringp (setq suffix (nnmaildir--art-suffix file)))) + nil + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (format "No such article: %d" article)) + (throw 'return nil)) (save-excursion - (set-buffer buffer) - (setq article file - file (nnmaildir--art-get-prefix article) - tmpfile (concat (nnmaildir--tmp dir) file)) - (when (file-exists-p tmpfile) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "File exists: " tmpfile)) - (throw 'return nil)) - (write-region (point-min) (point-max) tmpfile nil 'no-message nil - 'confirm-overwrite)) ;; error would be preferred :( + (set-buffer buffer) + (setq article file + file (nnmaildir--art-prefix article) + tmpfile (concat (nnmaildir--tmp dir) file)) + (when (file-exists-p tmpfile) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "File exists: " tmpfile)) + (throw 'return nil)) + (write-region (point-min) (point-max) tmpfile nil 'no-message nil + 'confirm-overwrite)) ;; error would be preferred :( (unix-sync) ;; no fsync :( (rename-file tmpfile (concat (nnmaildir--cur dir) file suffix) 'replace) t))) (defun nnmaildir-request-move-article (article gname server accept-form - &optional last) + &optional last) (let ((group (nnmaildir--prepare server gname)) - pgname list suffix result nnmaildir--file deactivate-mark) + pgname list suffix result nnmaildir--file deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) - (setq gname (nnmaildir--grp-get-name group) - pgname (nnmaildir--grp-get-pname group) - list (nnmaildir--grp-get-lists group) - list (nnmaildir--lists-get-nlist list) - article (nnmaildir--nlist-art list article)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) + (setq gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server gname) + list (nnmaildir--grp-lists group) + list (nnmaildir--lists-nlist list) + article (nnmaildir--nlist-art list article)) (if article nil - (nnmaildir--srv-set-error nnmaildir--cur-server "No such article") - (throw 'return nil)) - (if (stringp (setq suffix (nnmaildir--art-get-suffix article))) nil - (nnmaildir--srv-set-error nnmaildir--cur-server "Article has expired") - (throw 'return nil)) - (setq nnmaildir--file (nnmaildir--srv-get-dir nnmaildir--cur-server) - nnmaildir--file (nnmaildir--srv-grp-dir nnmaildir--file gname) - nnmaildir--file (if (nnmaildir--param pgname 'read-only) - (nnmaildir--new nnmaildir--file) - (nnmaildir--cur nnmaildir--file)) - nnmaildir--file (concat nnmaildir--file - (nnmaildir--art-get-prefix article) - suffix)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) "No such article") + (throw 'return nil)) + (if (stringp (setq suffix (nnmaildir--art-suffix article))) nil + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Article has expired") + (throw 'return nil)) + (setq nnmaildir--file (nnmaildir--srv-dir nnmaildir--cur-server) + nnmaildir--file (nnmaildir--srvgrp-dir nnmaildir--file gname) + nnmaildir--file (if (nnmaildir--param pgname 'read-only) + (nnmaildir--new nnmaildir--file) + (nnmaildir--cur nnmaildir--file)) + nnmaildir--file (concat nnmaildir--file + (nnmaildir--art-prefix article) + suffix)) (if (file-exists-p nnmaildir--file) nil - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil) - (nnmaildir--srv-set-error nnmaildir--cur-server "Article has expired") - (throw 'return nil)) - (save-excursion - (set-buffer (get-buffer-create " *nnmaildir move*")) - (erase-buffer) - (nnheader-insert-file-contents nnmaildir--file) - (setq result (eval accept-form))) + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + "Article has expired") + (throw 'return nil)) + (nnmaildir--with-move-buffer + (erase-buffer) + (nnheader-insert-file-contents nnmaildir--file) + (setq result (eval accept-form))) (if (or (null result) (nnmaildir--param pgname 'read-only)) nil - (nnmaildir--unlink nnmaildir--file) - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil)) + (nnmaildir--unlink nnmaildir--file) + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil)) result))) (defun nnmaildir-request-accept-article (gname &optional server last) (let ((group (nnmaildir--prepare server gname)) - (coding-system-for-write nnheader-file-coding-system) - (buffer-file-coding-system nil) - (file-coding-system-alist nil) - srv-dir dir file tmpfile curfile 24h num article) + (coding-system-for-write nnheader-file-coding-system) + (buffer-file-coding-system nil) + (file-coding-system-alist nil) + srv-dir dir file tmpfile curfile 24h num article) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (throw 'return nil)) - (setq gname (nnmaildir--grp-get-name group)) - (when (nnmaildir--param (nnmaildir--grp-get-pname group) 'read-only) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Read-only group: " gname)) - (throw 'return nil)) - (setq srv-dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir srv-dir gname) - file (format-time-string "%s" nil)) - (if (string= nnmaildir--delivery-time file) nil - (setq nnmaildir--delivery-time file - nnmaildir--delivery-ct 0)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (throw 'return nil)) + (setq gname (nnmaildir--grp-name group)) + (when (nnmaildir--param (nnmaildir--pgname nnmaildir--cur-server gname) + 'read-only) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Read-only group: " gname)) + (throw 'return nil)) + (setq srv-dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir srv-dir gname) + file (format-time-string "%s" nil)) + (if (string-equal nnmaildir--delivery-time file) nil + (setq nnmaildir--delivery-time file + nnmaildir--delivery-ct 0)) (setq file (concat file "." nnmaildir--delivery-pid)) (if (zerop nnmaildir--delivery-ct) nil - (setq file (concat file "_" - (number-to-string nnmaildir--delivery-ct)))) + (setq file (concat file "_" + (number-to-string nnmaildir--delivery-ct)))) (setq file (concat file "." (system-name)) - tmpfile (concat (nnmaildir--tmp dir) file) - curfile (concat (nnmaildir--cur dir) file ":2,")) + tmpfile (concat (nnmaildir--tmp dir) file) + curfile (concat (nnmaildir--cur dir) file ":2,")) (when (file-exists-p tmpfile) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "File exists: " tmpfile)) - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "File exists: " tmpfile)) + (throw 'return nil)) (when (file-exists-p curfile) - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "File exists: " curfile)) - (throw 'return nil)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "File exists: " curfile)) + (throw 'return nil)) (setq nnmaildir--delivery-ct (1+ nnmaildir--delivery-ct) - 24h (run-with-timer 86400 nil - (lambda () - (nnmaildir--unlink tmpfile) - (nnmaildir--srv-set-error - nnmaildir--cur-server - "24-hour timer expired") - (throw 'return nil)))) + 24h (run-with-timer 86400 nil + (lambda () + (nnmaildir--unlink tmpfile) + (setf (nnmaildir--srv-error + nnmaildir--cur-server) + "24-hour timer expired") + (throw 'return nil)))) (condition-case nil - (add-name-to-file nnmaildir--file tmpfile) - (error - (write-region (point-min) (point-max) tmpfile nil 'no-message nil - 'confirm-overwrite) ;; error would be preferred :( - (unix-sync))) ;; no fsync :( + (add-name-to-file nnmaildir--file tmpfile) + (error + (write-region (point-min) (point-max) tmpfile nil 'no-message nil + 'confirm-overwrite) ;; error would be preferred :( + (unix-sync))) ;; no fsync :( (cancel-timer 24h) (condition-case err - (add-name-to-file tmpfile curfile) - (error - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "Error linking: " - (prin1-to-string err))) - (nnmaildir--unlink tmpfile) - (throw 'return nil))) + (add-name-to-file tmpfile curfile) + (error + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "Error linking: " (prin1-to-string err))) + (nnmaildir--unlink tmpfile) + (throw 'return nil))) (nnmaildir--unlink tmpfile) - (setq article (nnmaildir--art-new) - num (nnmaildir--grp-get-lists group) - num (nnmaildir--lists-get-nlist num) - num (1+ (nnmaildir--nlist-last-num num))) - (nnmaildir--art-set-prefix article file) - (nnmaildir--art-set-suffix article ":2,") - (nnmaildir--art-set-num article num) - (if (nnmaildir--grp-add-art srv-dir group article) (cons gname num))))) + (setq num (nnmaildir--grp-lists group) + num (nnmaildir--lists-nlist num) + num (1+ (nnmaildir--nlist-last-num num)) + article (make-nnmaildir--art :prefix file :suffix ":2," :num num)) + (if (nnmaildir--grp-add-art nnmaildir--cur-server group article) + (cons gname num))))) (defun nnmaildir-save-mail (group-art) (catch 'return (if group-art nil (throw 'return nil)) (let ((ret group-art) - ga gname x groups nnmaildir--file deactivate-mark) + ga gname x groups nnmaildir--file deactivate-mark) (save-excursion - (goto-char (point-min)) - (save-match-data - (while (looking-at "From ") - (replace-match "X-From-Line: ") - (forward-line 1)))) - (setq groups (nnmaildir--srv-get-groups nnmaildir--cur-server) - ga (car group-art) group-art (cdr group-art) - gname (car ga)) + (goto-char (point-min)) + (save-match-data + (while (looking-at "From ") + (replace-match "X-From-Line: ") + (forward-line 1)))) + (setq groups (nnmaildir--srv-groups nnmaildir--cur-server) + ga (car group-art) group-art (cdr group-art) + gname (car ga)) (or (intern-soft gname groups) - (nnmaildir-request-create-group gname) - (throw 'return nil)) ;; not that nnmail bothers to check :( + (nnmaildir-request-create-group gname) + (throw 'return nil)) ;; not that nnmail bothers to check :( (if (nnmaildir-request-accept-article gname) nil - (throw 'return nil)) + (throw 'return nil)) (setq x (nnmaildir--prepare nil gname) - nnmaildir--file (nnmaildir--srv-get-dir nnmaildir--cur-server) - nnmaildir--file (concat nnmaildir--file - (nnmaildir--grp-get-name x)) - nnmaildir--file (file-name-as-directory nnmaildir--file) - x (nnmaildir--grp-get-lists x) - x (nnmaildir--lists-get-nlist x) - x (car x) - nnmaildir--file (concat nnmaildir--file - (nnmaildir--art-get-prefix x) - (nnmaildir--art-get-suffix x))) + nnmaildir--file (nnmaildir--srv-dir nnmaildir--cur-server) + nnmaildir--file (nnmaildir--subdir nnmaildir--file + (nnmaildir--grp-name x)) + x (nnmaildir--grp-lists x) + x (nnmaildir--lists-nlist x) + x (car x) + nnmaildir--file (concat nnmaildir--file + (nnmaildir--art-prefix x) + (nnmaildir--art-suffix x))) (while group-art - (setq ga (car group-art) group-art (cdr group-art) - gname (car ga)) - (if (and (or (intern-soft gname groups) - (nnmaildir-request-create-group gname)) - (nnmaildir-request-accept-article gname)) nil - (setq ret (delq ga ret)))) ;; We'll still try the other groups + (setq ga (car group-art) group-art (cdr group-art) + gname (car ga)) + (if (and (or (intern-soft gname groups) + (nnmaildir-request-create-group gname)) + (nnmaildir-request-accept-article gname)) nil + (setq ret (delq ga ret)))) ;; We'll still try the other groups ret))) (defun nnmaildir-active-number (group) (let ((x (nnmaildir--prepare nil group))) (catch 'return (if x nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " group)) - (throw 'return nil)) - (setq x (nnmaildir--grp-get-lists x) - x (nnmaildir--lists-get-nlist x)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " group)) + (throw 'return nil)) + (setq x (nnmaildir--grp-lists x) + x (nnmaildir--lists-nlist x)) (if x - (setq x (car x) - x (nnmaildir--art-get-num x) - x (1+ x)) - 1)))) + (setq x (car x) + x (nnmaildir--art-num x) + x (1+ x)) + 1)))) (defun nnmaildir-request-expire-articles (ranges &optional gname server force) (let ((no-force (not force)) - (group (nnmaildir--prepare server gname)) - pgname time boundary time-iter bound-iter high low target dir nlist - stop number article didnt suffix nnmaildir--file - nnmaildir-article-file-name deactivate-mark) + (group (nnmaildir--prepare server gname)) + pgname time boundary time-iter bound-iter high low target dir nlist + stop number article didnt suffix nnmaildir--file + nnmaildir-article-file-name deactivate-mark) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (if gname (concat "No such group: " gname) - "No current group")) - (throw 'return (gnus-uncompress-range ranges))) - (setq gname (nnmaildir--grp-get-name group) - pgname (nnmaildir--grp-get-pname group)) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (if gname (concat "No such group: " gname) "No current group")) + (throw 'return (gnus-uncompress-range ranges))) + (setq gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server gname)) (if (nnmaildir--param pgname 'read-only) - (throw 'return (gnus-uncompress-range ranges))) - (setq time (or (nnmaildir--param pgname 'expire-age) 604800)) + (throw 'return (gnus-uncompress-range ranges))) + (setq time (or (nnmaildir--param pgname 'expire-age) + (* 86400 ;; seconds per day + (or (and nnmail-expiry-wait-function + (funcall nnmail-expiry-wait-function gname)) + nnmail-expiry-wait)))) (if (or force (integerp time)) nil - (throw 'return (gnus-uncompress-range ranges))) + (throw 'return (gnus-uncompress-range ranges))) (setq boundary (current-time) - high (- (car boundary) (/ time 65536)) - low (- (cadr boundary) (% time 65536))) + high (- (car boundary) (/ time 65536)) + low (- (cadr boundary) (% time 65536))) (if (< low 0) - (setq low (+ low 65536) - high (1- high))) + (setq low (+ low 65536) + high (1- high))) (setcar (cdr boundary) low) (setcar boundary high) - (setq dir (nnmaildir--srv-get-dir nnmaildir--cur-server) - dir (nnmaildir--srv-grp-dir dir gname) - dir (nnmaildir--cur dir) - nlist (nnmaildir--grp-get-lists group) - nlist (nnmaildir--lists-get-nlist nlist) - ranges (reverse ranges)) - (save-excursion - (set-buffer (get-buffer-create " *nnmaildir move*")) - (while ranges - (setq number (car ranges) ranges (cdr ranges)) - (while (eq number (car ranges)) - (setq ranges (cdr ranges))) - (if (numberp number) (setq stop number) - (setq stop (car number) number (cdr number))) - (setq nlist (nthcdr (- (nnmaildir--art-get-num (car nlist)) number) - nlist)) - (while (and nlist - (setq article (car nlist) - number (nnmaildir--art-get-num article)) - (>= number stop)) - (setq nlist (cdr nlist) - suffix (nnmaildir--art-get-suffix article)) - (catch 'continue - (if (stringp suffix) nil - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil) - (throw 'continue nil)) - (setq nnmaildir--file (nnmaildir--art-get-prefix article) - nnmaildir--file (concat dir nnmaildir--file suffix) - time (file-attributes nnmaildir--file)) - (if time nil - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil) - (throw 'continue nil)) - (setq time (nth 5 time) - time-iter time - bound-iter boundary) - (if (and no-force - (progn - (while (and bound-iter time-iter - (= (car bound-iter) (car time-iter))) - (setq bound-iter (cdr bound-iter) - time-iter (cdr time-iter))) - (and bound-iter time-iter - (car-less-than-car bound-iter time-iter)))) - (setq didnt (cons number didnt)) - (save-excursion - (setq nnmaildir-article-file-name nnmaildir--file - target (nnmaildir--param pgname 'expire-group))) - (when (and (stringp target) - (not (string-equal target pgname))) ;; Move it. - (erase-buffer) - (nnheader-insert-file-contents nnmaildir--file) - (gnus-request-accept-article target nil nil 'no-encode)) - (if (equal target pgname) - (setq didnt (cons number didnt)) ;; Leave it here. - (nnmaildir--unlink nnmaildir--file) - (nnmaildir--art-set-suffix article 'expire) - (nnmaildir--art-set-nov article nil)))))) - (erase-buffer)) + (setq dir (nnmaildir--srv-dir nnmaildir--cur-server) + dir (nnmaildir--srvgrp-dir dir gname) + dir (nnmaildir--cur dir) + nlist (nnmaildir--grp-lists group) + nlist (nnmaildir--lists-nlist nlist) + ranges (reverse ranges)) + (nnmaildir--with-move-buffer + (while ranges + (setq number (car ranges) ranges (cdr ranges)) + (while (eq number (car ranges)) + (setq ranges (cdr ranges))) + (if (numberp number) (setq stop number) + (setq stop (car number) number (cdr number))) + (setq nlist (nthcdr (- (nnmaildir--art-num (car nlist)) number) + nlist)) + (while (and nlist + (setq article (car nlist) + number (nnmaildir--art-num article)) + (>= number stop)) + (setq nlist (cdr nlist) + suffix (nnmaildir--art-suffix article)) + (catch 'continue + (if (stringp suffix) nil + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil) + (throw 'continue nil)) + (setq nnmaildir--file (nnmaildir--art-prefix article) + nnmaildir--file (concat dir nnmaildir--file suffix) + time (file-attributes nnmaildir--file)) + (if time nil + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil) + (throw 'continue nil)) + (setq time (nth 5 time) + time-iter time + bound-iter boundary) + (if (and no-force + (progn + (while (and bound-iter time-iter + (= (car bound-iter) (car time-iter))) + (setq bound-iter (cdr bound-iter) + time-iter (cdr time-iter))) + (and bound-iter time-iter + (car-less-than-car bound-iter time-iter)))) + (setq didnt (cons number didnt)) + (save-excursion + (setq nnmaildir-article-file-name nnmaildir--file + target (nnmaildir--param pgname 'expire-group))) + (when (and (stringp target) + (not (string-equal target pgname))) ;; Move it. + (erase-buffer) + (nnheader-insert-file-contents nnmaildir--file) + (gnus-request-accept-article target nil nil 'no-encode)) + (if (equal target pgname) + (setq didnt (cons number didnt)) ;; Leave it here. + (nnmaildir--unlink nnmaildir--file) + (setf (nnmaildir--art-suffix article) 'expire) + (setf (nnmaildir--art-nov article) nil)))))) + (erase-buffer)) didnt))) (defun nnmaildir-request-set-mark (gname actions &optional server) (let ((group (nnmaildir--prepare server gname)) - (coding-system-for-write nnheader-file-coding-system) - (buffer-file-coding-system nil) - (file-coding-system-alist nil) - del-mark add-marks marksdir markfile action group-nlist nlist ranges - begin end article all-marks todo-marks did-marks marks form mdir mfile - deactivate-mark) + (coding-system-for-write nnheader-file-coding-system) + (buffer-file-coding-system nil) + (file-coding-system-alist nil) + del-mark add-marks marksdir markfile action group-nlist nlist ranges + begin end article all-marks todo-marks did-marks marks form mdir mfile + pgname ls markfilenew deactivate-mark) (setq del-mark - (lambda () - (setq mfile (car marks) - mfile (symbol-name mfile) - mfile (concat marksdir mfile) - mfile (file-name-as-directory mfile) - mfile (concat mfile (nnmaildir--art-get-prefix article))) - (nnmaildir--unlink mfile)) - add-marks - (lambda () - (while marks - (setq mdir (concat marksdir (symbol-name (car marks))) - mfile (concat (file-name-as-directory mdir) - (nnmaildir--art-get-prefix article))) - (if (memq (car marks) did-marks) nil - (nnmaildir--mkdir mdir) - (setq did-marks (cons (car marks) did-marks))) - (if (file-exists-p mfile) nil - (condition-case nil - (add-name-to-file markfile mfile) - (file-error ;; too many links, probably - (if (file-exists-p mfile) nil - (nnmaildir--unlink markfile) - (write-region "" nil markfile nil 'no-message) - (add-name-to-file markfile mfile - 'ok-if-already-exists))))) - (setq marks (cdr marks))))) + (lambda () + (setq mfile (nnmaildir--subdir marksdir (symbol-name (car marks))) + mfile (concat mfile (nnmaildir--art-prefix article))) + (nnmaildir--unlink mfile)) + add-marks + (lambda () + (while marks + (setq mdir (nnmaildir--subdir marksdir (symbol-name (car marks))) + mfile (concat mdir (nnmaildir--art-prefix article))) + (if (memq (car marks) did-marks) nil + (nnmaildir--mkdir mdir) + (setq did-marks (cons (car marks) did-marks))) + (if (file-exists-p mfile) nil + (condition-case nil + (add-name-to-file markfile mfile) + (file-error + (if (file-exists-p mfile) nil + ;; too many links, maybe + (write-region "" nil markfilenew nil 'no-message) + (add-name-to-file markfilenew mfile 'ok-if-already-exists) + (rename-file markfilenew markfile 'replace))))) + (setq marks (cdr marks))))) (catch 'return (if group nil - (nnmaildir--srv-set-error nnmaildir--cur-server - (concat "No such group: " gname)) - (while actions - (setq ranges (gnus-range-add ranges (caar actions)) - actions (cdr actions))) - (throw 'return ranges)) - (setq group-nlist (nnmaildir--grp-get-lists group) - group-nlist (nnmaildir--lists-get-nlist group-nlist) - marksdir (nnmaildir--srv-get-dir nnmaildir--cur-server) - marksdir (nnmaildir--srv-grp-dir marksdir gname) - marksdir (nnmaildir--nndir marksdir) - markfile (concat marksdir "markfile") - marksdir (concat marksdir "marks") - marksdir (file-name-as-directory marksdir) - gname (nnmaildir--grp-get-name group) - all-marks (nnmaildir--grp-get-pname group) - all-marks (or (nnmaildir--param all-marks 'directory-files) - (nnmaildir--srv-get-ls nnmaildir--cur-server)) - all-marks (funcall all-marks marksdir nil "\\`[^.]" 'nosort) - marks all-marks) + (setf (nnmaildir--srv-error nnmaildir--cur-server) + (concat "No such group: " gname)) + (while actions + (setq ranges (gnus-range-add ranges (caar actions)) + actions (cdr actions))) + (throw 'return ranges)) + (setq group-nlist (nnmaildir--grp-lists group) + group-nlist (nnmaildir--lists-nlist group-nlist) + marksdir (nnmaildir--srv-dir nnmaildir--cur-server) + marksdir (nnmaildir--srvgrp-dir marksdir gname) + marksdir (nnmaildir--nndir marksdir) + markfile (concat marksdir "markfile") + markfilenew (concat markfile "{new}") + marksdir (nnmaildir--marks-dir marksdir) + gname (nnmaildir--grp-name group) + pgname (nnmaildir--pgname nnmaildir--cur-server gname) + ls (nnmaildir--group-ls nnmaildir--cur-server pgname) + all-marks (funcall ls marksdir nil "\\`[^.]" 'nosort) + marks all-marks) (while marks - (setcar marks (intern (car marks))) - (setq marks (cdr marks))) + (setcar marks (intern (car marks))) + (setq marks (cdr marks))) (while actions - (setq action (car actions) actions (cdr actions) - nlist group-nlist - ranges (car action) - todo-marks (caddr action) - marks todo-marks) - (while marks - (if (memq (car marks) all-marks) nil - (setq all-marks (cons (car marks) all-marks))) - (setq marks (cdr marks))) - (setq form - (cond - ((eq 'del (cadr action)) - '(while marks - (funcall del-mark) - (setq marks (cdr marks)))) - ((eq 'add (cadr action)) '(funcall add-marks)) - (t - '(progn - (funcall add-marks) - (setq marks all-marks) - (while marks - (if (memq (car marks) todo-marks) nil - (funcall del-mark)) - (setq marks (cdr marks))))))) - (if (numberp (cdr ranges)) (setq ranges (list ranges)) - (setq ranges (reverse ranges))) - (while ranges - (setq begin (car ranges) ranges (cdr ranges)) - (while (eq begin (car ranges)) - (setq ranges (cdr ranges))) - (if (numberp begin) (setq end begin) - (setq end (cdr begin) begin (car begin))) - (setq nlist (nthcdr (- (nnmaildir--art-get-num (car nlist)) end) - nlist)) - (while (and nlist - (setq article (car nlist)) - (>= (nnmaildir--art-get-num article) begin)) - (setq nlist (cdr nlist)) - (when (stringp (nnmaildir--art-get-suffix article)) - (setq marks todo-marks) - (eval form))))) + (setq action (car actions) actions (cdr actions) + nlist group-nlist + ranges (car action) + todo-marks (caddr action) + marks todo-marks) + (while marks + (if (memq (car marks) all-marks) nil + (setq all-marks (cons (car marks) all-marks))) + (setq marks (cdr marks))) + (setq form + (cond + ((eq 'del (cadr action)) + '(while marks + (funcall del-mark) + (setq marks (cdr marks)))) + ((eq 'add (cadr action)) '(funcall add-marks)) + (t + '(progn + (funcall add-marks) + (setq marks all-marks) + (while marks + (if (memq (car marks) todo-marks) nil + (funcall del-mark)) + (setq marks (cdr marks))))))) + (if (numberp (cdr ranges)) (setq ranges (list ranges)) + (setq ranges (reverse ranges))) + (while ranges + (setq begin (car ranges) ranges (cdr ranges)) + (while (eq begin (car ranges)) + (setq ranges (cdr ranges))) + (if (numberp begin) (setq end begin) + (setq end (cdr begin) begin (car begin))) + (setq nlist (nthcdr (- (nnmaildir--art-num (car nlist)) end) + nlist)) + (while (and nlist + (setq article (car nlist)) + (>= (nnmaildir--art-num article) begin)) + (setq nlist (cdr nlist)) + (when (stringp (nnmaildir--art-suffix article)) + (setq marks todo-marks) + (eval form))))) nil))) (defun nnmaildir-close-group (group &optional server) t) (defun nnmaildir-close-server (&optional server) - (let (srv-ls flist ls dirs dir files file x) + (let (flist ls dirs dir files file x) (nnmaildir--prepare server nil) (setq server nnmaildir--cur-server) (when server - (setq nnmaildir--cur-server nil - srv-ls (nnmaildir--srv-get-ls server)) + (setq nnmaildir--cur-server nil) (save-match-data - (mapatoms + (mapatoms (lambda (group) - (setq group (symbol-value group) - x (nnmaildir--grp-get-pname group) - ls (nnmaildir--param x 'directory-files) - ls (or ls srv-ls) - dir (nnmaildir--srv-get-dir server) - dir (nnmaildir--srv-grp-dir - dir (nnmaildir--grp-get-name group)) + (setq x (nnmaildir--pgname server (symbol-name group)) + group (symbol-value group) + ls (nnmaildir--group-ls server x) + dir (nnmaildir--srv-dir server) + dir (nnmaildir--srvgrp-dir dir (nnmaildir--grp-name group)) x (nnmaildir--param x 'read-only) x (if x (nnmaildir--new dir) (nnmaildir--cur dir)) files (funcall ls x nil "\\`[^.]" 'nosort) @@ -1682,9 +1626,9 @@ by nnmaildir-request-article.") (string-match "\\`\\([^:]*\\)\\(:.*\\)?\\'" file) (intern (match-string 1 file) flist)) (setq dir (nnmaildir--nndir dir) - dirs (cons (concat dir "nov") - (funcall ls (concat dir "marks") 'full "\\`[^.]" - 'nosort))) + dirs (cons (nnmaildir--nov-dir dir) + (funcall ls (nnmaildir--marks-dir dir) 'full + "\\`[^.]" 'nosort))) (while dirs (setq dir (car dirs) dirs (cdr dirs) files (funcall ls dir nil "\\`[^.]" 'nosort) @@ -1694,15 +1638,15 @@ by nnmaildir-request-article.") (if (intern-soft file flist) nil (setq file (concat dir file)) (delete-file file))))) - (nnmaildir--srv-get-groups server))) - (unintern (nnmaildir--srv-get-name server) nnmaildir--servers))) + (nnmaildir--srv-groups server))) + (unintern (nnmaildir--srv-address server) nnmaildir--servers))) t) (defun nnmaildir-request-close () (let (servers buffer) (mapatoms (lambda (server) - (setq servers (cons (symbol-name server) servers))) - nnmaildir--servers) + (setq servers (cons (symbol-name server) servers))) + nnmaildir--servers) (while servers (nnmaildir-close-server (car servers)) (setq servers (cdr servers))) @@ -1714,6 +1658,28 @@ by nnmaildir-request-article.") (if buffer (kill-buffer buffer))) t) +(defun nnmaildir--edit-prep () + (let ((extras '(mapcar mapatoms)) + name) + (mapatoms + (lambda (sym) + (when (or (memq sym extras) + (and (fboundp sym) + (setq name (symbol-name sym)) + (>= (length name) 10) + (or (string-equal "nnmaildir-" (substring name 0 10)) + (and (>= (length name) 15) + (string-equal "make-nnmaildir-" + (substring name 0 15)))))) + (put sym 'lisp-indent-function 0)))) + 'done)) + (provide 'nnmaildir) +;; Local Variables: +;; indent-tabs-mode: t +;; fill-column: 77 +;; eval: (progn (require 'nnmaildir) (nnmaildir--edit-prep)) +;; End: + ;;; nnmaildir.el ends here diff --git a/lisp/nnmbox.el b/lisp/nnmbox.el index 72e144f..e1e6989 100644 --- a/lisp/nnmbox.el +++ b/lisp/nnmbox.el @@ -1,10 +1,10 @@ ;;; nnmbox.el --- mail mbox access for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news, mail ;; This file is part of GNU Emacs. @@ -602,7 +602,8 @@ nnmbox-file-coding-system)) (dir (file-name-directory nnmbox-mbox-file))) (and dir (gnus-make-directory dir)) - (nnmail-write-region 1 1 nnmbox-mbox-file t 'nomesg)))) + (nnmail-write-region (point-min) (point-min) + nnmbox-mbox-file t 'nomesg)))) (defun nnmbox-read-mbox () (nnmail-activate 'nnmbox) diff --git a/lisp/nnmh.el b/lisp/nnmh.el index d3f164a..0ab8767 100644 --- a/lisp/nnmh.el +++ b/lisp/nnmh.el @@ -4,7 +4,7 @@ ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news, mail ;; This file is part of GNU Emacs. diff --git a/lisp/nnml.el b/lisp/nnml.el index 6ebfb6a..76ca820 100644 --- a/lisp/nnml.el +++ b/lisp/nnml.el @@ -4,7 +4,7 @@ ;; Author: Simon Josefsson (adding MARKS) ;; Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news, mail ;; This file is part of GNU Emacs. @@ -75,17 +75,14 @@ corresponding marks file (usually named `.marks' in the nnml group directory, but see `nnml-marks-file-name') for the group. Then the marks file will be regenerated properly by Gnus.") -(defvoo nnml-filenames-are-evil t - "If non-nil, Gnus will not assume that the articles file name -is the same as the article number listed in the nov database. This -variable should be set if any of the files are compressed.") - (defvoo nnml-prepare-save-mail-hook nil "Hook run narrowed to an article before saving.") (defvoo nnml-inhibit-expiry nil "If non-nil, inhibit expiry.") +(defvoo nnml-use-compressed-files nil + "If non-nil, allow using compressed message files.") @@ -302,7 +299,8 @@ variable should be set if any of the files are compressed.") (setq articles (gnus-sorted-intersection articles active-articles)) (while (and articles is-old) - (if (and (setq article (nnml-article-to-file (setq number (pop articles)))) + (if (and (setq article (nnml-article-to-file + (setq number (pop articles)))) (setq mod-time (nth 5 (file-attributes article))) (nnml-deletable-article-p group number) (setq is-old (nnmail-expired-article-p group mod-time force @@ -517,16 +515,19 @@ variable should be set if any of the files are compressed.") (defun nnml-article-to-file (article) (nnml-update-file-alist) (let (file) - (if (setq file (cdr (assq article nnml-article-file-alist))) + (if (setq file + (if nnml-use-compressed-files + (cdr (assq article nnml-article-file-alist)) + (number-to-string article))) (expand-file-name file nnml-current-directory) - (if (not nnheader-directory-files-is-safe) - ;; Just to make sure nothing went wrong when reading over NFS -- - ;; check once more. - (when (file-exists-p - (setq file (expand-file-name (number-to-string article) - nnml-current-directory))) - (nnml-update-file-alist t) - file))))) + (when (not nnheader-directory-files-is-safe) + ;; Just to make sure nothing went wrong when reading over NFS -- + ;; check once more. + (when (file-exists-p + (setq file (expand-file-name (number-to-string article) + nnml-current-directory))) + (nnml-update-file-alist t) + file))))) (defun nnml-deletable-article-p (group article) "Say whether ARTICLE in GROUP can be deleted." @@ -739,8 +740,8 @@ variable should be set if any of the files are compressed.") (when (buffer-name (cdar nnml-nov-buffer-alist)) (set-buffer (cdar nnml-nov-buffer-alist)) (when (buffer-modified-p) - (nnmail-write-region 1 (point-max) nnml-nov-buffer-file-name - nil 'nomesg)) + (nnmail-write-region (point-min) (point-max) + nnml-nov-buffer-file-name nil 'nomesg)) (set-buffer-modified-p nil) (kill-buffer (current-buffer))) (setq nnml-nov-buffer-alist (cdr nnml-nov-buffer-alist))))) @@ -829,7 +830,7 @@ variable should be set if any of the files are compressed.") (progn (re-search-forward "\n\r?\n" nil t) (setq chars (- (point-max) (point))) - (max 1 (1- (point))))) + (max (point-min) (1- (point))))) (unless (zerop (buffer-size)) (goto-char (point-min)) (setq headers (nnml-parse-head chars (caar files))) @@ -841,7 +842,7 @@ variable should be set if any of the files are compressed.") (setq files (cdr files))) (save-excursion (set-buffer nov-buffer) - (nnmail-write-region 1 (point-max) nov nil 'nomesg) + (nnmail-write-region (point-min) (point-max) nov nil 'nomesg) (kill-buffer (current-buffer)))))) (defun nnml-nov-delete-article (group article) @@ -861,10 +862,11 @@ variable should be set if any of the files are compressed.") t)) (defun nnml-update-file-alist (&optional force) - (when (or (not nnml-article-file-alist) - force) - (setq nnml-article-file-alist - (nnml-current-group-article-to-file-alist)))) + (when nnml-use-compressed-files + (when (or (not nnml-article-file-alist) + force) + (setq nnml-article-file-alist + (nnml-current-group-article-to-file-alist))))) (defun nnml-directory-articles (dir) "Return a list of all article files in a directory. @@ -891,9 +893,8 @@ Use the nov database for that directory if available." (defun nnml-current-group-article-to-file-alist () "Return an alist of article/file pairs in the current group. Use the nov database for the current group if available." - (if (or gnus-nov-is-evil + (if (or gnus-nov-is-evil nnml-nov-is-evil - nnml-filenames-are-evil (not (file-exists-p (expand-file-name nnml-nov-file-name nnml-current-directory)))) @@ -901,8 +902,8 @@ Use the nov database for the current group if available." ;; build list from .overview if available (save-excursion (let ((alist nil) - art - (buffer (nnml-get-nov-buffer nnml-current-group))) + (buffer (nnml-get-nov-buffer nnml-current-group)) + art) (set-buffer buffer) (goto-char (point-min)) (while (not (eobp)) @@ -984,8 +985,8 @@ Use the nov database for the current group if available." (error "Cannot write to %s (%s)" err)))))) (defun nnml-open-marks (group server) - (let ((file (expand-file-name - nnml-marks-file-name + (let ((file (expand-file-name + nnml-marks-file-name (nnmail-group-pathname group nnml-directory)))) (if (file-exists-p file) (condition-case err @@ -1010,7 +1011,8 @@ Use the nov database for the current group if available." (push (cons 'read (gnus-info-read info)) nnml-marks) (dolist (el gnus-article-unpropagated-mark-lists) (setq nnml-marks (gnus-remassoc el nnml-marks))) - (nnml-save-marks group server))))) + (nnml-save-marks group server) + (nnheader-message 7 "Bootstrapping marks for %s...done" group))))) (provide 'nnml) diff --git a/lisp/nnnil.el b/lisp/nnnil.el new file mode 100644 index 0000000..08a097d --- /dev/null +++ b/lisp/nnnil.el @@ -0,0 +1,81 @@ +;;; nnnil.el --- empty backend for Gnus +;; Public domain. + +;; Author: Paul Jarc + +;; 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: + +;; nnnil is a Gnus backend that provides no groups or articles. It's useful +;; as a primary select method when you want all your real select methods to +;; be secondary or foreign. + +;;; Code: + +(eval-and-compile + (require 'nnheader)) + +(defvar nnnil-status-string "") + +(defun nnnil-retrieve-headers (articles &optional group server fetch-old) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer)) + 'nov) + +(defun nnnil-open-server (server &optional definitions) + t) + +(defun nnnil-close-server (&optional server) + t) + +(defun nnnil-request-close () + t) + +(defun nnnil-server-opened (&optional server) + t) + +(defun nnnil-status-message (&optional server) + nnnil-status-string) + +(defun nnnil-request-article (article &optional group server to-buffer) + (setq nnnil-status-string "No such group") + nil) + +(defun nnnil-request-group (group &optional server fast) + (let (deactivate-mark) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (insert "411 no such news group\n"))) + (setq nnnil-status-string "No such group") + nil) + +(defun nnnil-close-group (group &optional server) + t) + +(defun nnnil-request-list (&optional server) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer)) + t) + +(defun nnnil-request-post (&optional server) + (setq nnnil-status-string "Read-only server") + nil) + +(provide 'nnnil) diff --git a/lisp/nnoo.el b/lisp/nnoo.el index 8a360d9..028af25 100644 --- a/lisp/nnoo.el +++ b/lisp/nnoo.el @@ -201,8 +201,8 @@ (while (setq def (pop defs)) (unless (assq (car def) bvariables) (nconc bvariables - (list (cons (car def) (and (boundp (car def)) - (symbol-value (car def))))))) + (list (cons (car def) (and (boundp (car def)) + (symbol-value (car def))))))) (if (equal server "*internal-non-initialized-backend*") (set (car def) (symbol-value (cadr def))) (set (car def) (cadr def))))) diff --git a/lisp/nnrss.el b/lisp/nnrss.el index 1ffff53..c8adc36 100644 --- a/lisp/nnrss.el +++ b/lisp/nnrss.el @@ -1,5 +1,5 @@ ;;; nnrss.el --- interfacing with RSS -;; Copyright (C) 2001 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2002 Free Software Foundation, Inc. ;; Author: Shenghuo Zhu ;; Keywords: RSS @@ -39,7 +39,6 @@ (eval-when-compile (ignore-errors (require 'xml))) -;; Report failure to find w3 at load time if appropriate. (eval '(require 'xml)) (nnoo-declare nnrss) @@ -174,6 +173,12 @@ To use the description in headers, put this name into `nnmail-extra-headers'.") "Field name used for URL. To use the description in headers, put this name into `nnmail-extra-headers'.") +(defvar nnrss-content-function nil + "A function which is called in `nnrss-request-article'. +The arguments are (ENTRY GROUP ARTICLE). +ENTRY is the record of the current headline. GROUP is the group name. +ARTICLE is the article number of the current headline.") + (nnoo-define-basics nnrss) ;;; Interface functions @@ -265,7 +270,9 @@ To use the description in headers, put this name into `nnmail-extra-headers'.") (insert "\n\n") (fill-region point (point)))) (if (nth 2 e) - (insert (nth 2 e) "\n"))))) + (insert (nth 2 e) "\n")) + (if nnrss-content-function + (funcall nnrss-content-function e group article))))) (cond (err (nnheader-report 'nnrss err)) diff --git a/lisp/nnslashdot.el b/lisp/nnslashdot.el index 21156e9..250349d 100644 --- a/lisp/nnslashdot.el +++ b/lisp/nnslashdot.el @@ -91,7 +91,7 @@ (entry (assoc group nnslashdot-groups)) (sid (nth 2 entry)) (first-comments t) - headers article subject score from date lines parent point cid + headers article subject score from date lines parent point cid s startats changed) (save-excursion (set-buffer nnslashdot-buffer) @@ -189,7 +189,7 @@ (while (and articles (<= (car articles) article)) (pop articles)) (setq article (1+ article))) - (if nnslashdot-threaded + (if nnslashdot-threaded (progn (setq start (pop startats)) (if start (setq start (+ start 2)))) @@ -244,7 +244,7 @@ (when (numberp article) (if (= article 1) (progn - (re-search-forward + (re-search-forward "Posted by") (search-forward "
    ") (setq contents @@ -252,9 +252,9 @@ (point) (progn (re-search-forward - "< [ \t\r\n]*\\|\\|< [ \t\r\n]*" cid)) (setq contents diff --git a/lisp/nnsoup.el b/lisp/nnsoup.el index d68794c..f8d9b38 100644 --- a/lisp/nnsoup.el +++ b/lisp/nnsoup.el @@ -1,10 +1,10 @@ ;;; nnsoup.el --- SOUP access for Gnus -;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news, mail ;; This file is part of GNU Emacs. @@ -337,7 +337,7 @@ backend for the messages.") (delete-file (nnsoup-file prefix t))) t) (setcdr (cdr total-infolist) (delq info (cddr total-infolist))) - (setq articles (gnus-sorted-complement articles range-list)))) + (setq articles (gnus-sorted-difference articles range-list)))) (when (not mod-time) (setcdr (cdr total-infolist) (delq info (cddr total-infolist))))) (if (cddr total-infolist) diff --git a/lisp/nnspool.el b/lisp/nnspool.el index e20d355..d8709ec 100644 --- a/lisp/nnspool.el +++ b/lisp/nnspool.el @@ -1,11 +1,11 @@ ;;; nnspool.el --- spool access for GNU Emacs ;; Copyright (C) 1988, 1989, 1990, 1993, 1994, 1995, 1996, 1997, 1998, -;; 2000, 2002 +;; 2000, 2002 ;; Free Software Foundation, Inc. ;; Author: Masanobu UMEDA -;; Lars Magne Ingebrigtsen +;; Lars Magne Ingebrigtsen ;; Keywords: news ;; This file is part of GNU Emacs. @@ -364,7 +364,7 @@ there.") (let ((nov (nnheader-group-pathname nnspool-current-group nnspool-nov-directory ".overview")) (arts articles) - (nnheader-file-coding-system nnspool-file-coding-system) + (nnheader-file-coding-system nnspool-file-coding-system) last) (if (not (file-exists-p nov)) () diff --git a/lisp/nntp.el b/lisp/nntp.el index 3e57e1e..92560b6 100644 --- a/lisp/nntp.el +++ b/lisp/nntp.el @@ -389,42 +389,52 @@ noticing asynchronous data.") (set-buffer nntp-server-buffer) (erase-buffer))) (let* ((command (mapconcat 'identity strings " ")) - (buffer (process-buffer (nntp-find-connection nntp-server-buffer))) - (pos (with-current-buffer buffer (point)))) - (prog1 - (nntp-retrieve-data command - nntp-address nntp-port-number nntp-server-buffer - wait-for nnheader-callback-function) - ;; If nothing to wait for, still remove possibly echo'ed commands - (unless wait-for - (nntp-accept-response) - (save-excursion - (set-buffer buffer) - (goto-char pos) - (if (looking-at (regexp-quote command)) - (delete-region pos (progn (forward-line 1) (gnus-point-at-bol)))) - ))) - )) + (process (nntp-find-connection nntp-server-buffer)) + (buffer (and process (process-buffer process))) + (pos (and buffer (with-current-buffer buffer (point))))) + (if process + (prog1 + (nntp-retrieve-data command + nntp-address nntp-port-number + nntp-server-buffer + wait-for nnheader-callback-function) + ;; If nothing to wait for, still remove possibly echo'ed commands + (unless wait-for + (nntp-accept-response) + (save-excursion + (set-buffer buffer) + (goto-char pos) + (if (looking-at (regexp-quote command)) + (delete-region pos (progn (forward-line 1) + (gnus-point-at-bol)))) + ))) + (nnheader-report 'nntp "Couldn't open connection to %s." + nntp-address)))) (defun nntp-send-command-nodelete (wait-for &rest strings) "Send STRINGS to server and wait until WAIT-FOR returns." (let* ((command (mapconcat 'identity strings " ")) - (buffer (process-buffer (nntp-find-connection nntp-server-buffer))) - (pos (with-current-buffer buffer (point)))) - (prog1 - (nntp-retrieve-data command - nntp-address nntp-port-number nntp-server-buffer - wait-for nnheader-callback-function) - ;; If nothing to wait for, still remove possibly echo'ed commands - (unless wait-for - (nntp-accept-response) - (save-excursion - (set-buffer buffer) - (goto-char pos) - (if (looking-at (regexp-quote command)) - (delete-region pos (progn (forward-line 1) (gnus-point-at-bol)))) - ))) - )) + (process (nntp-find-connection nntp-server-buffer)) + (buffer (and process (process-buffer process))) + (pos (and buffer (with-current-buffer buffer (point))))) + (if process + (prog1 + (nntp-retrieve-data command + nntp-address nntp-port-number + nntp-server-buffer + wait-for nnheader-callback-function) + ;; If nothing to wait for, still remove possibly echo'ed commands + (unless wait-for + (nntp-accept-response) + (save-excursion + (set-buffer buffer) + (goto-char pos) + (if (looking-at (regexp-quote command)) + (delete-region pos (progn (forward-line 1) + (gnus-point-at-bol)))) + ))) + (nnheader-report 'nntp "Couldn't open connection to %s." + nntp-address)))) (defun nntp-send-command-and-decode (wait-for &rest strings) "Send STRINGS to server and wait until WAIT-FOR returns." @@ -434,22 +444,26 @@ noticing asynchronous data.") (set-buffer nntp-server-buffer) (erase-buffer))) (let* ((command (mapconcat 'identity strings " ")) - (buffer (process-buffer (nntp-find-connection nntp-server-buffer))) - (pos (with-current-buffer buffer (point)))) - (prog1 - (nntp-retrieve-data command - nntp-address nntp-port-number nntp-server-buffer - wait-for nnheader-callback-function t) - ;; If nothing to wait for, still remove possibly echo'ed commands - (unless wait-for - (nntp-accept-response) - (save-excursion + (process (nntp-find-connection nntp-server-buffer)) + (buffer (and process (process-buffer process))) + (pos (and buffer (with-current-buffer buffer (point))))) + (if process + (prog1 + (nntp-retrieve-data command + nntp-address nntp-port-number + nntp-server-buffer + wait-for nnheader-callback-function t) + ;; If nothing to wait for, still remove possibly echo'ed commands + (unless wait-for + (nntp-accept-response) + (save-excursion (set-buffer buffer) (goto-char pos) (if (looking-at (regexp-quote command)) (delete-region pos (progn (forward-line 1) (gnus-point-at-bol)))) ))) - )) + (nnheader-report 'nntp "Couldn't open connection to %s." + nntp-address)))) (defun nntp-send-buffer (wait-for) @@ -577,6 +591,10 @@ noticing asynchronous data.") (command (if nntp-server-list-active-group "LIST ACTIVE" "GROUP"))) (while groups + ;; Timeout may have killed the buffer. + (unless (gnus-buffer-live-p buf) + (nnheader-report 'nntp "Connection to %s is closed." server) + (throw 'done nil)) ;; Send the command to the server. (nntp-send-command nil command (pop groups)) (incf count) @@ -1394,7 +1412,7 @@ password contained in '~/.nntp-authinfo'." ;; If there is only one group in the Newsgroups ;; header, then it seems quite likely that this ;; article comes from that group, I'd say. - ((and (setq newsgroups + ((and (setq newsgroups (mail-fetch-field "newsgroups")) (not (string-match "," newsgroups))) newsgroups) @@ -1408,20 +1426,20 @@ password contained in '~/.nntp-authinfo'." ;; life. ((and (setq xref (mail-fetch-field "xref")) number - (string-match + (string-match (format "\\([^ :]+\\):%d" number) xref)) (match-string 1 xref)) (t ""))) (cond ((and (setq xref (mail-fetch-field "xref")) - (string-match + (string-match (if group (concat "\\(" (regexp-quote group) "\\):\\([0-9]+\\)") "\\([^ :]+\\):\\([0-9]+\\)") xref)) (setq group (match-string 1 xref) number (string-to-int (match-string 2 xref)))) - ((and (setq newsgroups + ((and (setq newsgroups (mail-fetch-field "newsgroups")) (not (string-match "," newsgroups))) (setq group newsgroups)) diff --git a/lisp/nnultimate.el b/lisp/nnultimate.el index a71425d..bab703b 100644 --- a/lisp/nnultimate.el +++ b/lisp/nnultimate.el @@ -172,25 +172,25 @@ datel nil)) (pop datel)) (when date - (setq date (delete "" (split-string - date "[-, \n\t\r    ]"))) - (if (or (member "AM" date) - (member "PM" date)) - (setq date (format - "%s %s %s %s" - (nth 1 date) - (if (and (>= (length (nth 0 date)) 3) - (assoc (downcase - (substring (nth 0 date) 0 3)) - parse-time-months)) - (substring (nth 0 date) 0 3) - (car (rassq (string-to-number (nth 0 date)) - parse-time-months))) - (nth 2 date) (nth 3 date))) - (setq date (format "%s %s %s %s" - (car (rassq (string-to-number (nth 1 date)) - parse-time-months)) - (nth 0 date) (nth 2 date) (nth 3 date))))) + (setq date (delete "" (split-string date "[-, \n\t\r    ]"))) + (setq date + (if (or (member "AM" date) + (member "PM" date)) + (format + "%s %s %s %s" + (nth 1 date) + (if (and (>= (length (nth 0 date)) 3) + (assoc (downcase + (substring (nth 0 date) 0 3)) + parse-time-months)) + (substring (nth 0 date) 0 3) + (car (rassq (string-to-number (nth 0 date)) + parse-time-months))) + (nth 2 date) (nth 3 date)) + (format "%s %s %s %s" + (car (rassq (string-to-number (nth 1 date)) + parse-time-months)) + (nth 0 date) (nth 2 date) (nth 3 date))))) (push (cons article diff --git a/lisp/nnvirtual.el b/lisp/nnvirtual.el index 046c470..6099937 100644 --- a/lisp/nnvirtual.el +++ b/lisp/nnvirtual.el @@ -4,7 +4,7 @@ ;; Author: David Moore ;; Lars Magne Ingebrigtsen -;; Masanobu UMEDA +;; Masanobu UMEDA ;; Keywords: news ;; This file is part of GNU Emacs. diff --git a/lisp/nnwarchive.el b/lisp/nnwarchive.el index e7134fd..e05ae78 100644 --- a/lisp/nnwarchive.el +++ b/lisp/nnwarchive.el @@ -589,7 +589,7 @@ (let (p refs url mime e from subject date id done - (case-fold-serch t)) + (case-fold-search t)) (save-restriction (goto-char (point-min)) (when (search-forward "X-Head-End" nil t) diff --git a/lisp/nnweb.el b/lisp/nnweb.el index fe32198..f747ab4 100644 --- a/lisp/nnweb.el +++ b/lisp/nnweb.el @@ -1,5 +1,5 @@ ;;; nnweb.el --- retrieving articles via web search engines -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 ;; Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen @@ -37,6 +37,9 @@ (require 'nnmail) (require 'mm-util) (require 'mm-url) +(eval-and-compile + (ignore-errors + (require 'url))) (autoload 'w3-parse-buffer "w3-parse") (nnoo-declare nnweb) @@ -50,13 +53,9 @@ Valid types include `google', `dejanews', `dejanewsold', `reference', and `altavista'.") (defvar nnweb-type-definition - '( - (google - ;;(article . nnweb-google-wash-article) - ;;(id . "http://groups.google.com/groups?as_umsgid=%s") + '((google (article . ignore) (id . "http://groups.google.com/groups?selm=%s&output=gplain") - ;;(reference . nnweb-google-reference) (reference . identity) (map . nnweb-google-create-mapping) (search . nnweb-google-search) @@ -73,19 +72,6 @@ and `altavista'.") (search . nnweb-google-search) (address . "http://groups.google.com/groups") (identifier . nnweb-google-identity)) -;;; (dejanews -;;; (article . ignore) -;;; (id . "http://search.dejanews.com/msgid.xp?MID=%s&fmt=text") -;;; (map . nnweb-dejanews-create-mapping) -;;; (search . nnweb-dejanews-search) -;;; (address . "http://www.deja.com/=dnc/qs.xp") -;;; (identifier . nnweb-dejanews-identity)) -;;; (dejanewsold -;;; (article . ignore) -;;; (map . nnweb-dejanews-create-mapping) -;;; (search . nnweb-dejanewsold-search) -;;; (address . "http://www.deja.com/dnquery.xp") -;;; (identifier . nnweb-dejanews-identity)) (reference (article . nnweb-reference-wash-article) (map . nnweb-reference-create-mapping) @@ -748,7 +734,7 @@ and `altavista'.") (while (re-search-forward "a href=/groups\\(\\?[^ \">]*selm=\\([^ &\">]+\\)\\)" nil t) (setq mid (match-string 2) - url (format + url (format "http://groups.google.com/groups?selm=%s&output=gplain" mid)) (narrow-to-region (search-forward ">" nil t) (search-forward "" nil t)) @@ -771,9 +757,11 @@ and `altavista'.") (widen) (skip-chars-forward "- \t")) (when (looking-at - "\\([0-9]+[/ ][A-Za-z]+[/ ][0-9]+\\)[ \t]*by[ \t]*\\([^<]*\\) - @@ -258,7 +258,9 @@ If NOW, use that time instead." ;; should be ;; Tue Jul 9 09:04:21 1996 (setq date - (cond ((string-match "[A-Z]" (nth 0 date)) + (cond ((not date) + "Tue Jan 1 00:00:0 1900") + ((string-match "[A-Z]" (nth 0 date)) (format "%s %s %s %s %s" (nth 0 date) (nth 2 date) (nth 1 date) (nth 4 date) (nth 3 date))) @@ -335,7 +337,7 @@ If NOW, use that time instead." t (current-buffer) nil) ;; The meaningful output is the first 32 characters. ;; Don't return the newline that follows them! - (buffer-substring 1 33))))) + (buffer-substring (point-min) (+ 32 (point-min))))))) (defun pop3-stat (process) "Return the number of messages in the maildrop and the maildrop's size." diff --git a/lisp/qp.el b/lisp/qp.el index 8c3b828..3a4d492 100644 --- a/lisp/qp.el +++ b/lisp/qp.el @@ -35,7 +35,10 @@ (defun quoted-printable-decode-region (from to &optional coding-system) "Decode quoted-printable in the region between FROM and TO, per RFC 2045. If CODING-SYSTEM is non-nil, decode bytes into characters with that -coding-system." +coding-system. + +Interactively, you can supply the CODING-SYSTEM argument +with \\[universal-coding-system-argument]." (interactive ;; Let the user determine the coding system with "C-x RET c". (list (region-beginning) (region-end) coding-system-for-read)) diff --git a/lisp/rfc2047.el b/lisp/rfc2047.el index 948e168..1947b9e 100644 --- a/lisp/rfc2047.el +++ b/lisp/rfc2047.el @@ -184,7 +184,7 @@ Should be called narrowed to the head of the message." ;; left the old code commented out below. ;; -- Per Abrahamsen Date: 2001-10-07. ((null method) - (when (delq 'ascii + (when (delq 'ascii (mm-find-charset-region (point-min) (point-max))) (rfc2047-encode-region (point-min) (point-max)))) ;;; ((null method) @@ -433,18 +433,15 @@ The buffer may be narrowed." (let ((bol (save-restriction (widen) (gnus-point-at-bol))) - (eol (gnus-point-at-eol)) - leading) + (eol (gnus-point-at-eol))) (forward-line 1) (while (not (eobp)) - (looking-at "[ \t]*") - (setq leading (- (match-end 0) (match-beginning 0))) - (if (< (- (gnus-point-at-eol) bol leading) 76) - (progn - (goto-char eol) - (delete-region eol (progn - (skip-chars-forward " \t\n\r") - (1- (point))))) + (if (and (looking-at "[ \t]") + (< (- (gnus-point-at-eol) bol) 76)) + (delete-region eol (progn + (goto-char eol) + (skip-chars-forward "\r\n") + (point))) (setq bol (gnus-point-at-bol))) (setq eol (gnus-point-at-eol)) (forward-line 1))))) @@ -522,6 +519,7 @@ The buffer may be narrowed." (delete-region (match-beginning 0) (match-end 0))))) (when (and (mm-multibyte-p) mail-parse-charset + (not (eq mail-parse-charset 'us-ascii)) (not (eq mail-parse-charset 'gnus-decoded))) (mm-decode-coding-region b e mail-parse-charset)) (setq b (point))) @@ -529,8 +527,7 @@ The buffer may be narrowed." mail-parse-charset (not (eq mail-parse-charset 'us-ascii)) (not (eq mail-parse-charset 'gnus-decoded))) - (mm-decode-coding-region b (point-max) mail-parse-charset)) - (rfc2047-unfold-region (point-min) (point-max)))))) + (mm-decode-coding-region b (point-max) mail-parse-charset)))))) (defun rfc2047-decode-string (string) "Decode the quoted-printable-encoded STRING and return the results." @@ -543,7 +540,7 @@ The buffer may be narrowed." (inline (rfc2047-decode-region (point-min) (point-max))) (buffer-string)) - (if (and m + (if (and m mail-parse-charset (not (eq mail-parse-charset 'us-ascii)) (not (eq mail-parse-charset 'gnus-decoded))) diff --git a/lisp/rfc2231.el b/lisp/rfc2231.el index dd391b1..4d1994c 100644 --- a/lisp/rfc2231.el +++ b/lisp/rfc2231.el @@ -1,6 +1,6 @@ ;;; rfc2231.el --- Functions for decoding rfc2231 headers -;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; This file is part of GNU Emacs. @@ -112,10 +112,11 @@ The list will be on the form (setq value (buffer-substring (1+ (point)) (progn (forward-sexp 1) (1- (point)))))) - ((and (memq c ttoken) + ((and (or (memq c ttoken) + (> c ?\177)) ;; EXTENSION: Support non-ascii chars. (not (memq c stoken))) (setq value (buffer-substring - (point) (progn (forward-sexp 1) (point))))) + (point) (progn (forward-sexp) (point))))) (t (error "Invalid header: %s" string))) (when encoded diff --git a/lisp/sha1-el.el b/lisp/sha1-el.el index 0c94c2d..4e2da43 100644 --- a/lisp/sha1-el.el +++ b/lisp/sha1-el.el @@ -71,7 +71,7 @@ If this variable is set to nil, use internal function only.") "*Name of program to compute SHA1. It must be a string \(program name\) or list of strings \(name and its args\).") -(defvar sha1-use-external +(defvar sha1-use-external (executable-find (car sha1-program)) "*Use external sh1 program. If this variable is set to nil, use internal function only.") diff --git a/lisp/sieve-manage.el b/lisp/sieve-manage.el index f99aa39..584adce 100644 --- a/lisp/sieve-manage.el +++ b/lisp/sieve-manage.el @@ -65,7 +65,7 @@ ;; ;; 2001-10-31 Committed to Oort Gnus. ;; -;; $Id: sieve-manage.el,v 1.1.1.1 2002-01-06 22:11:34 yamaoka Exp $ +;; $Id: sieve-manage.el,v 1.1.1.2 2002-05-06 23:49:27 yamaoka Exp $ ;;; Code: @@ -116,7 +116,7 @@ stream.") (defcustom sieve-manage-authenticators '(cram-md5 plain) "Priority of authenticators to consider when authenticating to server.") -(defcustom sieve-manage-authenticator-alist +(defcustom sieve-manage-authenticator-alist '((cram-md5 sieve-manage-cram-md5-p sieve-manage-cram-md5-auth) (plain sieve-manage-plain-p sieve-manage-plain-auth)) "Definition of authenticators. @@ -196,13 +196,13 @@ Returns t if login was successful, nil otherwise." ;; (condition-case () (while (or (not user) (not passwd)) (setq user (or sieve-manage-username - (read-from-minibuffer + (read-from-minibuffer (concat "Managesieve username for " sieve-manage-server ": ") (or user sieve-manage-default-user)))) (setq passwd (or sieve-manage-password (sieve-manage-read-passwd - (concat "Managesieve password for " user "@" + (concat "Managesieve password for " user "@" sieve-manage-server ": ")))) (when (and user passwd) (if (funcall loginfunc user passwd) @@ -319,7 +319,7 @@ Returns t if login was successful, nil otherwise." (sieve-manage-send (concat "AUTHENTICATE \"PLAIN\" \"" (base64-encode-string (concat (char-to-string 0) - user + user (char-to-string 0) passwd)) "\"")) @@ -395,7 +395,7 @@ to work in." (if (funcall (nth 1 (assq stream sieve-manage-stream-alist)) buffer) (setq stream-changed - (not (eq (or sieve-manage-stream + (not (eq (or sieve-manage-stream sieve-manage-default-stream) stream)) sieve-manage-stream stream @@ -409,14 +409,14 @@ to work in." (if (sieve-manage-open-1 buffer) (message "sieve: Reconnecting with stream `%s'...done" sieve-manage-stream) - (message "sieve: Reconnecting with stream `%s'...failed" + (message "sieve: Reconnecting with stream `%s'...failed" sieve-manage-stream)) (setq sieve-manage-capability nil)) (if (sieve-manage-opened buffer) ;; Choose authenticator (when (and (null sieve-manage-auth) (not (eq sieve-manage-state 'auth))) - (let ((auths sieve-manage-authenticators)) + (let ((auths sieve-manage-authenticators)) (while (setq auth (pop auths)) (if (funcall (nth 1 (assq auth diff --git a/lisp/sieve-mode.el b/lisp/sieve-mode.el index 7c17146..d901e4c 100644 --- a/lisp/sieve-mode.el +++ b/lisp/sieve-mode.el @@ -45,7 +45,7 @@ ;; added keymap and menubar to hook into sieve-manage ;; 2001-10-31 version 1.2 committed to Oort Gnus ;; -;; $Id: sieve-mode.el,v 1.1.1.1 2002-01-06 22:11:34 yamaoka Exp $ +;; $Id: sieve-mode.el,v 1.1.1.2 2002-05-06 23:49:27 yamaoka Exp $ ;;; Code: @@ -69,7 +69,7 @@ (defvar sieve-control-commands-face 'sieve-control-commands-face "Face name used for Sieve Control Commands.") -(defface sieve-control-commands-face +(defface sieve-control-commands-face '((((type tty) (class color)) (:foreground "blue" :weight light)) (((class grayscale) (background light)) (:foreground "LightGray" :bold t)) (((class grayscale) (background dark)) (:foreground "DimGray" :bold t)) @@ -91,7 +91,7 @@ (defvar sieve-test-commands-face 'sieve-test-commands-face "Face name used for Sieve Test Commands.") -(defface sieve-test-commands-face +(defface sieve-test-commands-face '((((type tty) (class color)) (:foreground "magenta")) (((class grayscale) (background light)) (:foreground "LightGray" :bold t :underline t)) @@ -128,7 +128,7 @@ (cons (regexp-opt '("address" "allof" "anyof" "exists" "false" "true" "header" "not" "size" "envelope")) 'sieve-test-commands-face) - (cons "\\Sw+:\\sw+" + (cons "\\Sw+:\\sw+" 'sieve-tagged-arguments-face)))) ;; Syntax table @@ -158,7 +158,7 @@ ;; Key map definition -(defvar sieve-mode-map +(defvar sieve-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-l" 'sieve-upload) (define-key map "\C-c\C-m" 'sieve-manage) @@ -188,7 +188,7 @@ Turning on Sieve mode runs `sieve-mode-hook'." (set (make-local-variable 'comment-start-skip) "#+ *") (unless (featurep 'xemacs) (set (make-local-variable 'font-lock-defaults) - '(sieve-font-lock-keywords nil nil ((?_ . "w"))))) + '(sieve-font-lock-keywords nil nil ((?_ . "w"))))) (easy-menu-add-item nil nil sieve-mode-menu)) ;; Menu diff --git a/lisp/sieve.el b/lisp/sieve.el index 857804d..9d0b97e 100644 --- a/lisp/sieve.el +++ b/lisp/sieve.el @@ -34,7 +34,7 @@ ;; ;; 2001-10-31 Committed to Oort Gnus. ;; -;; $Id: sieve.el,v 1.1.1.1 2002-01-06 22:11:34 yamaoka Exp $ +;; $Id: sieve.el,v 1.1.1.2 2002-05-06 23:49:27 yamaoka Exp $ ;; ;; Todo: ;; @@ -144,7 +144,7 @@ require \"fileinto\"; ["Activate script" sieve-activate t] ["Deactivate script" sieve-deactivate t])) -;; This is necessary to allow correct handling of \\[cvs-mode-diff-map] +;; This is necessary to allow correct handling of \\[cvs-mode-diff-map] ;; in substitute-command-keys. ;(fset 'sieve-manage-mode-map sieve-manage-mode-map) diff --git a/lisp/smiley.el b/lisp/smiley.el index afc5b21..5edb176 100644 --- a/lisp/smiley.el +++ b/lisp/smiley.el @@ -1,10 +1,9 @@ ;;; smiley.el --- displaying smiley faces -;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -;; Free Software Foundation, Inc. +;; Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. -;; Author: Wes Hardaker -;; Keywords: fun +;; Author: Dave Love +;; Keywords: news mail multimedia ;; This file is part of GNU Emacs. @@ -25,418 +24,137 @@ ;;; Commentary: -;; -;; comments go here. -;; +;; A re-written, simplified version of Wes Hardaker's XEmacs smiley.el +;; which might be merged back to smiley.el if we get an assignment for +;; that. We don't have assignments for the images smiley.el uses, but +;; I'm not sure we need that degree of rococoness and defaults like a +;; yellow background. Also, using PBM means we can display the images +;; more generally. -- fx -;;; Test smileys: :-] :-o :-) ;-) :-\ :-| :-d :-P 8-| :-( - -;; To use: -;; (require 'smiley) -;; (setq gnus-treat-display-smileys t) - -;; The smilies were drawn by Joe Reiss . +;;; Test smileys: :-) :-\ :-( :-/ ;;; Code: -(require 'cl) -(require 'custom) - -(eval-and-compile - (when (featurep 'xemacs) - (require 'annotations) - (require 'messagexmas))) +(eval-when-compile (require 'cl)) +(require 'nnheader) +(require 'gnus-art) (defgroup smiley nil "Turn :-)'s into real images." :group 'gnus-visual) -;; FIXME: Where is the directory when using Emacs? -(defcustom smiley-data-directory - (if (featurep 'xemacs) - (message-xmas-find-glyph-directory "smilies") - "/usr/local/lib/xemacs/xemacs-packages/etc/smilies") +;; Maybe this should go. +(defcustom smiley-data-directory (nnheader-find-etc-directory "smilies") "*Location of the smiley faces files." :type 'directory :group 'smiley) -;; Notice the subtle differences in the regular expressions in the -;; two alists below. - -(defcustom smiley-deformed-regexp-alist - '(("\\(\\^_\\^;;;\\)\\W" 1 "WideFaceAse3.xbm") - ("\\(\\^_\\^;;\\)\\W" 1 "WideFaceAse2.xbm") - ("\\(\\^_\\^;\\)\\W" 1 "WideFaceAse1.xbm") - ("\\(\\^_\\^\\)\\W" 1 "WideFaceSmile.xbm") - ("\\(;_;\\)\\W" 1 "WideFaceWeep.xbm") - ("\\(T_T\\)\\W" 1 "WideFaceWeep.xbm") - ("\\(:-*[<«]+\\)\\W" 1 "FaceAngry.xpm") - ("\\(:-+\\]+\\)\\W" 1 "FaceGoofy.xpm") - ("\\(:-*D\\)\\W" 1 "FaceGrinning.xpm") - ("\\(:-*[)>}»]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(=[)»]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(:-*[/\\\"]\\)[^/]\\W" 1 "FaceIronic.xpm") - ("[^.0-9]\\([8|]-*[|Oo%]\\)\\W" 1 "FaceKOed.xpm") - ("\\([:|]-*#+\\)\\W" 1 "FaceNyah.xpm") - ("\\(:-*[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(=[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(:-*[Oo\*]\\)\\W" 1 "FaceStartled.xpm") - ("\\(:-*|\\)\\W" 1 "FaceStraight.xpm") - ("\\(:-*p\\)\\W" 1 "FaceTalking.xpm") - ("\\(:-*d\\)\\W" 1 "FaceTasty.xpm") - ("\\(;-*[>)}»]+\\)\\W" 1 "FaceWinking.xpm") - ("\\(:-*[Vvµ]\\)\\W" 1 "FaceWry.xpm") - ("\\([:|]-*P\\)\\W" 1 "FaceYukky.xpm")) - "*Normal and deformed faces for smilies." - :type '(repeat (list regexp - (integer :tag "Match") - (string :tag "Image"))) - :group 'smiley) - -(defcustom smiley-nosey-regexp-alist - '(("\\(:-+[<«]+\\)\\W" 1 "FaceAngry.xpm") - ("\\(:-+\\]+\\)\\W" 1 "FaceGoofy.xpm") - ("\\(:-+D\\)\\W" 1 "FaceGrinning.xpm") - ("\\(:-+[}»]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(:-*)+\\)\\W" 1 "FaceHappy.xpm") - ("\\(=[)]+\\)\\W" 1 "FaceHappy.xpm") - ("\\(:-+[/\\\"]+\\)\\W" 1 "FaceIronic.xpm") - ("\\([8|]-+[|Oo%]\\)\\W" 1 "FaceKOed.xpm") - ("\\([:|]-+#+\\)\\W" 1 "FaceNyah.xpm") - ("\\(:-+[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(=[({]+\\)\\W" 1 "FaceSad.xpm") - ("\\(:-+[Oo\*]\\)\\W" 1 "FaceStartled.xpm") - ("\\(:-+|\\)\\W" 1 "FaceStraight.xpm") - ("\\(:-+p\\)\\W" 1 "FaceTalking.xpm") - ("\\(:-+d\\)\\W" 1 "FaceTasty.xpm") - ("\\(;-+[>)}»]+\\)\\W" 1 "FaceWinking.xpm") - ("\\(:-+[Vvµ]\\)\\W" 1 "FaceWry.xpm") - ("\\(][:8B]-[)>]\\)\\W" 1 "FaceDevilish.xpm") - ("\\([:|]-+P\\)\\W" 1 "FaceYukky.xpm")) - "*Smileys with noses. These get less false matches." +;; The XEmacs version has a baroque, if not rococo, set of these. +(defcustom smiley-regexp-alist + '(("\\(:-?)\\)\\W" 1 "smile") + ("\\(;-?)\\)\\W" 1 "blink") + ("\\(:-]\\)\\W" 1 "forced") + ("\\(8-)\\)\\W" 1 "braindamaged") + ("\\(:-|\\)\\W" 1 "indifferent") + ("\\(:-[/\\]\\)\\W" 1 "wry") + ("\\(:-(\\)\\W" 1 "sad") + ("\\(:-{\\)\\W" 1 "frown")) + "*A list of regexps to map smilies to images. +The elements are (REGEXP MATCH FILE), where MATCH is the submatch in +regexp to replace with IMAGE. IMAGE is the name of a PBM file in +`smiley-data-directory'." :type '(repeat (list regexp - (integer :tag "Match") - (string :tag "Image"))) - :group 'smiley) - -(defcustom smiley-regexp-alist smiley-deformed-regexp-alist - "*A list of regexps to map smilies to real images. -Defaults to the contents of `smiley-deformed-regexp-alist'. -An alternative is `smiley-nosey-regexp-alist' that matches less -aggressively. -If this is a symbol, take its value." - :type '(radio (variable-item smiley-deformed-regexp-alist) - (variable-item smiley-nosey-regexp-alist) - symbol - (repeat (list regexp - (integer :tag "Match") - (string :tag "Image")))) - :group 'smiley) - -(defcustom smiley-flesh-color "yellow" - "*Flesh color." - :type 'string - :group 'smiley) - -(defcustom smiley-features-color "black" - "*Features color." - :type 'string + (integer :tag "Regexp match number") + (string :tag "Image name"))) + :set (lambda (symbol value) + (set-default symbol value) + (smiley-update-cache)) + :initialize 'custom-initialize-default :group 'smiley) -(defcustom smiley-tongue-color "red" - "*Tongue color." - :type 'string +(defcustom gnus-smiley-file-types + (let ((types (list "pbm"))) + (when (gnus-image-type-available-p 'xpm) + (push "xpm" types)) + types) + "*List of suffixes on picon file names to try." + :type '(repeat string) :group 'smiley) -(defcustom smiley-circle-color "black" - "*Circle color." - :type 'string - :group 'smiley) - -(defcustom smiley-mouse-face 'highlight - "*Face used for mouse highlighting in the smiley buffer. - -Smiley buttons will be displayed in this face when the cursor is -above them." - :type 'face - :group 'smiley) - -(defvar smiley-glyph-cache nil) - -(defvar smiley-map (make-sparse-keymap "smiley-keys") - "Keymap to toggle smiley states.") - -(define-key smiley-map [(button2)] 'smiley-toggle-extent) -(define-key smiley-map [(button3)] 'smiley-popup-menu) - -(defun smiley-popup-menu (e) - (interactive "e") - (popup-menu - `("Smilies" - ["Toggle This Smiley" (smiley-toggle-extent ,e) t] - ["Toggle All Smilies" (smiley-toggle-extents ,e) t]))) - -(defun smiley-create-glyph (smiley pixmap) - (or - (cdr-safe (assoc pixmap smiley-glyph-cache)) - (let* ((xpm-color-symbols - (and (featurep 'xpm) - (append `(("flesh" ,smiley-flesh-color) - ("features" ,smiley-features-color) - ("tongue" ,smiley-tongue-color)) - xpm-color-symbols))) - (glyph (make-glyph - (list - (cons (if (featurep 'gtk) 'gtk 'x) - (expand-file-name pixmap smiley-data-directory)) - (cons 'mswindows - (expand-file-name pixmap smiley-data-directory)) - (cons 'tty smiley))))) - (setq smiley-glyph-cache (cons (cons pixmap glyph) smiley-glyph-cache)) - (set-glyph-face glyph 'default) - glyph))) - -(defun smiley-create-glyph-ems (smiley pixmap) - (condition-case e - (create-image (expand-file-name pixmap smiley-data-directory)) - (error nil))) - +(defvar smiley-cached-regexp-alist nil) + +(defun smiley-update-cache () + (dolist (elt (if (symbolp smiley-regexp-alist) + (symbol-value smiley-regexp-alist) + smiley-regexp-alist)) + (let ((types gnus-smiley-file-types) + file type) + (while (and (not file) + (setq type (pop types))) + (unless (file-exists-p + (setq file (expand-file-name (concat (nth 2 elt) "." type) + smiley-data-directory))) + (setq file nil))) + (when type + (let ((image (gnus-create-image file (intern type) nil + :ascent 'center))) + (when image + (push (list (car elt) (cadr elt) image) + smiley-cached-regexp-alist))))))) + +(defvar smiley-mouse-map + (let ((map (make-sparse-keymap))) + (define-key map [down-mouse-2] 'ignore) ; override widget + (define-key map [mouse-2] + 'smiley-mouse-toggle-buffer) + map)) ;;;###autoload -(defun smiley-region (beg end) - "Smilify the region between point and mark." +(defun smiley-region (start end) + "Replace in the region `smiley-regexp-alist' matches with corresponding images. +A list of images is returned." (interactive "r") - (smiley-buffer (current-buffer) beg end)) - -(defun smiley-toggle-extent (event) - "Toggle smiley at given point." - (interactive "e") - (let* ((ant (event-glyph-extent event)) - (pt (event-closest-point event)) - ext) - (if (annotationp ant) - (when (extentp (setq ext (extent-property ant 'smiley-extent))) - (set-extent-property ext 'invisible nil) - (hide-annotation ant)) - (when pt - (while (setq ext (extent-at pt (event-buffer event) nil ext 'at)) - (when (annotationp (setq ant - (extent-property ext 'smiley-annotation))) - (reveal-annotation ant) - (set-extent-property ext 'invisible t))))))) - -;; FIXME:: -(defun smiley-toggle-extent-ems (event) - "Toggle smiley at given point. -Note -- this function hasn't been implemented yet." - (interactive "e") - (error "This function hasn't been implemented yet")) - -(defun smiley-toggle-extents (e) - (interactive "e") - (map-extents - (lambda (e void) - (let (ant) - (if (annotationp (setq ant (extent-property e 'smiley-annotation))) - (if (eq (extent-property e 'invisible) nil) - (progn - (reveal-annotation ant) - (set-extent-property e 'invisible t) - ) - (hide-annotation ant) - (set-extent-property e 'invisible nil))) - nil)) - (event-buffer e))) - -;; FIXME:: -(defun smiley-toggle-extents-ems (e) - (interactive "e") - (error "This function hasn't been implemented yet")) - -;;;###autoload -(defun smiley-buffer (&optional buffer st nd) - (interactive) - (when (featurep '(or x gtk mswindows)) - (save-excursion - (when buffer - (set-buffer buffer)) - (let ((buffer-read-only nil) - (alist (if (symbolp smiley-regexp-alist) - (symbol-value smiley-regexp-alist) - smiley-regexp-alist)) - (case-fold-search nil) - entry regexp beg group file) - (map-extents - (lambda (e void) - (when (or (extent-property e 'smiley-extent) - (extent-property e 'smiley-annotation)) - (delete-extent e))) - buffer st nd) - (goto-char (or st (point-min))) - (setq beg (point)) - ;; loop through alist - (while (setq entry (pop alist)) - (setq regexp (car entry) - group (cadr entry) - file (caddr entry)) - (goto-char beg) - (while (re-search-forward regexp nd t) - (let* ((start (match-beginning group)) - (end (match-end group)) - (glyph (smiley-create-glyph (buffer-substring start end) - file))) - (when glyph - (mapcar 'delete-annotation (annotations-at end)) - (let ((ext (make-extent start end)) - (ant (make-annotation glyph end 'text))) - ;; set text extent params - (set-extent-property ext 'end-open t) - (set-extent-property ext 'start-open t) - (set-extent-property ext 'invisible t) - (set-extent-property ext 'keymap smiley-map) - (set-extent-property ext 'mouse-face smiley-mouse-face) - (set-extent-property ext 'intangible t) - ;; set annotation params - (set-extent-property ant 'mouse-face smiley-mouse-face) - (set-extent-property ant 'keymap smiley-map) - ;; remember each other - (set-extent-property ant 'smiley-extent ext) - (set-extent-property ext 'smiley-annotation ant) - ;; Help - (set-extent-property - ext 'help-echo - "button2 toggles smiley, button3 pops up menu") - (set-extent-property - ant 'help-echo - "button2 toggles smiley, button3 pops up menu") - (set-extent-property ext 'balloon-help - "Mouse button2 - toggle smiley -Mouse button3 - menu") - (set-extent-property ant 'balloon-help - "Mouse button2 - toggle smiley -Mouse button3 - menu")) - (when (smiley-end-paren-p start end) - (make-annotation ")" end 'text)) - (goto-char end))))))))) - -;; FIXME: No popup menu, no customized color -(defun smiley-buffer-ems (&optional buffer st nd) - (interactive) - (when window-system + (when (gnus-graphic-display-p) + (unless smiley-cached-regexp-alist + (smiley-update-cache)) (save-excursion - (when buffer - (set-buffer buffer)) - (let ((buffer-read-only nil) - (alist (if (symbolp smiley-regexp-alist) - (symbol-value smiley-regexp-alist) - smiley-regexp-alist)) - (case-fold-search nil) - entry regexp beg group file) - (dolist (overlay (overlays-in (or st (point-min)) - (or nd (point-max)))) - (when (overlay-get overlay 'smiley) - (remove-text-properties (overlay-start overlay) - (overlay-end overlay) '(display)) - (delete-overlay overlay))) - (goto-char (or st (point-min))) - (setq beg (point)) - ;; loop through alist - (while (setq entry (pop alist)) - (setq regexp (car entry) - group (cadr entry) - file (caddr entry)) + (let ((beg (or start (point-min))) + group image images string) + (dolist (entry smiley-cached-regexp-alist) + (setq group (nth 1 entry) + image (nth 2 entry)) (goto-char beg) - (while (re-search-forward regexp nd t) - (let* ((start (match-beginning group)) - (end (match-end group)) - (glyph (smiley-create-glyph nil file)) - (overlay (make-overlay start end))) - (when glyph - (add-text-properties start end - `(display ,glyph)) - (overlay-put overlay 'smiley glyph) - (goto-char end))))))))) - -(defun smiley-end-paren-p (start end) - "Try to guess whether the current smiley is an end-paren smiley." - (save-excursion - (goto-char start) - (when (and (re-search-backward "[()]" nil t) - (eq (char-after) ?\() - (goto-char end) - (or (not (re-search-forward "[()]" nil t)) - (eq (char-after (1- (point))) ?\())) - t))) - -(defun smiley-toggle-buffer (&optional arg buffer st nd) - "Toggle displaying smiley faces. + (while (re-search-forward (car entry) end t) + (setq string (match-string group)) + (goto-char (match-end group)) + (delete-region (match-beginning group) (match-end group)) + (when image + (push image images) + (gnus-add-wash-type 'smiley) + (gnus-add-image 'smiley image) + (gnus-put-image image string)))) + images)))) + +(defun smiley-toggle-buffer (&optional arg) + "Toggle displaying smiley faces in article buffer. With arg, turn displaying on if and only if arg is positive." (interactive "P") - (let (on off) - (map-extents - (lambda (e void) - (let (ant) - (if (annotationp (setq ant (extent-property e 'smiley-annotation))) - (if (eq (extent-property e 'invisible) nil) - (setq off (cons (cons ant e) off)) - (setq on (cons (cons ant e) on))))) - nil) - buffer st nd) - (if (and (not (and (numberp arg) (< arg 0))) - (or (and (numberp arg) (> arg 0)) - (null on))) - (if off - (while off - (reveal-annotation (caar off)) - (set-extent-property (cdar off) 'invisible t) - (setq off (cdr off))) - (smiley-buffer)) - (while on - (hide-annotation (caar on)) - (set-extent-property (cdar on) 'invisible nil) - (setq on (cdr on)))))) - -;; Simply removing all smiley if existing. -;; FIXME: make it work as the one in XEmacs. -(defun smiley-toggle-buffer-ems (&optional arg buffer st nd) + (gnus-with-article-buffer + (if (if (numberp arg) + (> arg 0) + (not (memq 'smiley gnus-article-wash-types))) + (smiley-region (point-min) (point-max)) + (gnus-delete-images 'smiley)))) + +(defun smiley-mouse-toggle-buffer (event) "Toggle displaying smiley faces. With arg, turn displaying on if and only if arg is positive." - (interactive "P") - (save-excursion - (when buffer - (set-buffer buffer)) - (let (found) - (dolist (overlay (overlays-in (or st (point-min)) - (or nd (point-max)))) - (when (overlay-get overlay 'smiley) - (remove-text-properties (overlay-start overlay) - (overlay-end overlay) '(display)) - (setq found t))) - (unless found - (smiley-buffer buffer st nd))))) - -(unless (featurep 'xemacs) - (defalias 'smiley-create-glyph 'smiley-create-glyph-ems) - (defalias 'smiley-toggle-extent 'smiley-toggle-extent-ems) - (defalias 'smiley-toggle-extents 'smiley-toggle-extents-ems) - (defalias 'smiley-buffer 'smiley-buffer-ems) - (defalias 'smiley-toggle-buffer 'smiley-toggle-buffer-ems)) - -(defvar gnus-article-buffer) -;;;###autoload -(defun gnus-smiley-display (&optional arg) - "Display \"smileys\" as small graphical icons. -With arg, turn displaying on if and only if arg is positive." - (interactive "P") + (interactive "e") (save-excursion - (article-goto-body) - (let (buffer-read-only) - (smiley-toggle-buffer arg (current-buffer) (point) (point-max))))) + (save-window-excursion + (mouse-set-point event) + (smiley-toggle-buffer)))) (provide 'smiley) -;; Local Variables: -;; coding: iso-8859-1 -;; End: - ;;; smiley.el ends here diff --git a/lisp/smime.el b/lisp/smime.el index 49fabbc..2c38de6 100644 --- a/lisp/smime.el +++ b/lisp/smime.el @@ -140,7 +140,7 @@ certificates to be sent with every message to each address." Directory should contain files (in PEM format) named to the X.509 hash of the certificate. This can be done using OpenSSL such as: -$ ln -s ca.pem `openssl x509 -noout -hash -in ca.pem` +$ ln -s ca.pem `openssl x509 -noout -hash -in ca.pem`.0 where `ca.pem' is the file containing a PEM encoded X.509 CA certificate." @@ -201,7 +201,9 @@ If nil, use system defaults." (lambda (prefix &optional dir-flag) ;; Simple implementation (expand-file-name (make-temp-name prefix) - temporary-file-directory))))) + (if (fboundp 'temp-directory) + (temp-directory) + temporary-file-directory)))))) ;; Password dialog function @@ -232,15 +234,17 @@ If nil, use system defaults." ;; Sign+encrypt region -(defun smime-sign-region (b e keyfiles) - "Sign region with certified key in KEYFILES. +(defun smime-sign-region (b e keyfile) + "Sign region with certified key in KEYFILE. If signing fails, the buffer is not modified. Region is assumed to -have proper MIME tags. KEYFILES is expected to contain a PEM encoded -private key and certificate as its car, and a list of additional certificates -to include in its caar." +have proper MIME tags. KEYFILE is expected to contain a PEM encoded +private key and certificate as its car, and a list of additional +certificates to include in its caar. If no additional certificates is +included, KEYFILE may be the file containing the PEM encoded private +key and certificate itself." (smime-new-details-buffer) - (let ((keyfile (car keyfiles)) - (certfiles (and (cdr keyfiles) (cadr keyfiles))) + (let ((keyfile (or (car-safe keyfile) keyfile)) + (certfiles (and (cdr-safe keyfile) (cadr keyfile))) (buffer (generate-new-buffer (generate-new-buffer-name " *smime*"))) (passphrase (smime-ask-passphrase)) (tmpfile (smime-make-temp-file "smime"))) @@ -307,11 +311,13 @@ KEYFILE should contain a PEM encoded key and certificate." (smime-sign-region (point-min) (point-max) (if keyfile - (list keyfile (smime-get-certfiles keyfile smime-keys)) + keyfile (smime-get-key-by-email - (completing-read "Sign using which signature? " smime-keys nil nil - (and (listp (car-safe smime-keys)) - (cdr smime-keys)))))))) + (completing-read + (concat "Sign using which key? " + (if smime-keys (concat "(default " (caar smime-keys) ") ") + "")) + smime-keys nil nil (car-safe (car-safe smime-keys)))))))) (defun smime-encrypt-buffer (&optional certfiles buffer) "S/MIME encrypt BUFFER for recipients specified in CERTFILES. @@ -428,9 +434,11 @@ in the buffer specified by `smime-details-buffer'." (expand-file-name (or keyfile (smime-get-key-by-email - (completing-read "Decrypt with which key? " smime-keys nil nil - (and (listp (car-safe smime-keys)) - (caar smime-keys))))))))) + (completing-read + (concat "Decipher using which key? " + (if smime-keys (concat "(default " (caar smime-keys) ") ") + "")) + smime-keys nil nil (car-safe (car-safe smime-keys))))))))) ;; Various operations @@ -459,7 +467,7 @@ in the buffer specified by `smime-details-buffer'." "Get email addresses contained in certificate between points B and E. A string or a list of strings is returned." (smime-new-details-buffer) - (when (smime-call-openssl-region + (when (smime-call-openssl-region b e smime-details-buffer "x509" "-email" "-noout") (delete-region b e) (insert-buffer-substring smime-details-buffer) diff --git a/lisp/spam.el b/lisp/spam.el new file mode 100644 index 0000000..98a4151 --- /dev/null +++ b/lisp/spam.el @@ -0,0 +1,128 @@ +;;; spam.el --- Identifying spam +;; Copyright (C) 2002 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: network + +;; 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: + +;;; Code: + +(require 'dns) +(require 'message) + +;;; Blackholes + +(defvar spam-blackhole-servers + '("bl.spamcop.net" "relays.ordb.org" "dev.null.dk" + "relays.visi.com" "rbl.maps.vix.com") + "List of blackhole servers.") + +(defun spam-check-blackholes () + "Check the Recevieved headers for blackholed relays." + (let ((headers (message-fetch-field "received")) + ips matches) + (with-temp-buffer + (insert headers) + (goto-char (point-min)) + (while (re-search-forward + "\\[\\([0-9]+.[0-9]+.[0-9]+.[0-9]+\\)\\]" nil t) + (push (mapconcat 'identity + (nreverse (split-string (match-string 1) "\\.")) + ".") + ips))) + (dolist (server spam-blackhole-servers) + (dolist (ip ips) + (when (query-dns (concat ip "." server)) + (push (list ip server (query-dns (concat ip "." server) 'TXT)) + matches)))) + matches)) + +;;; Black- and white-lists + +(defvar spam-directory "~/News/spam/" + "When spam files are kept.") + +(defvar spam-whitelist (expand-file-name "whitelist" spam-directory) + "The location of the whitelist. +The file format is one regular expression per line. +The regular expression is matched against the address.") + +(defvar spam-blacklist (expand-file-name "blacklist" spam-directory) + "The location of the blacklist. +The file format is one regular expression per line. +The regular expression is matched against the address.") + +(defvar spam-whitelist-cache nil) +(defvar spam-blacklist-cache nil) + +(defun spam-enter-whitelist (address &optional blacklist) + "Enter ADDRESS into the whitelist. +Optional arg BLACKLIST, if non-nil, means to enter in the blacklist instead." + (interactive "sAddress: ") + (let ((file (if blacklist spam-blacklist spam-whitelist))) + (unless (file-exists-p (file-name-directory file)) + (make-directory (file-name-directory file) t)) + (save-excursion + (set-buffer + (find-file-noselect file)) + (goto-char (point-max)) + (unless (bobp) + (insert "\n")) + (insert address "\n") + (save-buffer)))) + +(defun spam-enter-blacklist (address) + "Enter ADDRESS into the blacklist." + (interactive "sAddress: ") + (spam-enter-whitelist address t)) + +(defun spam-parse-whitelist (&optional blacklist) + (let ((file (if blacklist spam-blacklist spam-whitelist)) + contents address) + (when (file-exists-p file) + (with-temp-buffer + (insert-file-contents file) + (while (not (eobp)) + (setq address (buffer-substring (point) (point-at-eol))) + (forward-line 1) + (unless (zerop (length address)) + (setq address (regexp-quote address)) + (while (string-match "\\\\\\*" address) + (setq address (replace-match ".*" t t address))) + (push address contents)))) + (nreverse contents)))) + +(defun spam-refresh-list-cache () + (setq spam-whitelist-cache (spam-parse-whitelist)) + (setq spam-blacklist-cache (spam-parse-whitelist t))) + +(defun spam-address-whitelisted-p (address &optional blacklist) + (let ((cache (if blacklist spam-blacklist-cache spam-whitelist-cache)) + found) + (while (and (not found) + cache) + (when (string-match (pop cache) address) + (setq found t))) + found)) + +(provide 'spam) + +;;; spam.el ends here diff --git a/lisp/time-date.el b/lisp/time-date.el index 3ec6d96..e9babce 100644 --- a/lisp/time-date.el +++ b/lisp/time-date.el @@ -32,7 +32,7 @@ ;;;###autoload (defun date-to-time (date) - "Convert DATE into time." + "Parse a string that represents a date-time and return a time value." (condition-case () (apply 'encode-time (parse-time-string @@ -46,25 +46,29 @@ (error (error "Invalid date: %s" date)))) (defun time-to-seconds (time) - "Convert TIME to a floating point number." + "Convert time value TIME to a floating point number. +You can use `float-time' instead." (+ (* (car time) 65536.0) (cadr time) (/ (or (nth 2 time) 0) 1000000.0))) +;;;###autoload (defun seconds-to-time (seconds) - "Convert SECONDS (a floating point number) to an Emacs time structure." + "Convert SECONDS (a floating point number) to a time value." (list (floor seconds 65536) (floor (mod seconds 65536)) (floor (* (- seconds (ffloor seconds)) 1000000)))) +;;;###autoload (defun time-less-p (t1 t2) - "Say whether time T1 is less than time T2." + "Say whether time value T1 is less than time value T2." (or (< (car t1) (car t2)) (and (= (car t1) (car t2)) (< (nth 1 t1) (nth 1 t2))))) +;;;###autoload (defun days-to-time (days) - "Convert DAYS into time." + "Convert DAYS into a time value." (let* ((seconds (* 1.0 days 60 60 24)) (rest (expt 2 16)) (ms (condition-case nil (floor (/ seconds rest)) @@ -72,8 +76,10 @@ (list ms (condition-case nil (round (- seconds (* ms rest))) (range-error (expt 2 16)))))) +;;;###autoload (defun time-since (time) - "Return the time since TIME, which is either an internal time or a date." + "Return the time elapsed since TIME. +TIME should be either a time value or a date-time string." (when (stringp time) ;; Convert date strings to internal time. (setq time (date-to-time time))) @@ -83,26 +89,65 @@ (list (- (+ (car current) (if rest -1 0)) (car time)) (- (+ (or rest 0) (nth 1 current)) (nth 1 time))))) -(defun subtract-time (t1 t2) - "Subtract two internal times." +;;;###autoload +(defalias 'subtract-time 'time-subtract) + +;;;###autoload +(defun time-subtract (t1 t2) + "Subtract two time values. +Return the difference in the format of a time value." (let ((borrow (< (cadr t1) (cadr t2)))) (list (- (car t1) (car t2) (if borrow 1 0)) (- (+ (if borrow 65536 0) (cadr t1)) (cadr t2))))) +;;;###autoload +(defun time-add (t1 t2) + "Add two time values. One should represent a time difference." + (let ((high (car t1)) + (low (if (consp (cdr t1)) (nth 1 t1) (cdr t1))) + (micro (if (numberp (car-safe (cdr-safe (cdr t1)))) + (nth 2 t1) + 0)) + (high2 (car t2)) + (low2 (if (consp (cdr t2)) (nth 1 t2) (cdr t2))) + (micro2 (if (numberp (car-safe (cdr-safe (cdr t2)))) + (nth 2 t2) + 0))) + ;; Add + (setq micro (+ micro micro2)) + (setq low (+ low low2)) + (setq high (+ high high2)) + + ;; Normalize + ;; `/' rounds towards zero while `mod' returns a positive number, + ;; so we can't rely on (= a (+ (* 100 (/ a 100)) (mod a 100))). + (setq low (+ low (/ micro 1000000) (if (< micro 0) -1 0))) + (setq micro (mod micro 1000000)) + (setq high (+ high (/ low 65536) (if (< low 0) -1 0))) + (setq low (logand low 65535)) + + (list high low micro))) + +;;;###autoload (defun date-to-day (date) - "Return the number of days between year 1 and DATE." + "Return the number of days between year 1 and DATE. +DATE should be a date-time string." (time-to-days (date-to-time date))) +;;;###autoload (defun days-between (date1 date2) - "Return the number of days between DATE1 and DATE2." + "Return the number of days between DATE1 and DATE2. +DATE1 and DATE2 should be date-time strings." (- (date-to-day date1) (date-to-day date2))) +;;;###autoload (defun date-leap-year-p (year) "Return t if YEAR is a leap year." (or (and (zerop (% year 4)) (not (zerop (% year 100)))) (zerop (% year 400)))) +;;;###autoload (defun time-to-day-in-year (time) "Return the day number within the year of the date month/day/year." (let* ((tim (decode-time time)) @@ -116,14 +161,16 @@ (setq day-of-year (1+ day-of-year)))) day-of-year)) +;;;###autoload (defun time-to-days (time) "The number of days between the Gregorian date 0001-12-31bce and TIME. +TIME should be a time value. The Gregorian date Sunday, December 31, 1bce is imaginary." (let* ((tim (decode-time time)) (month (nth 4 tim)) (day (nth 3 tim)) (year (nth 5 tim))) - (+ (time-to-day-in-year time) ; Days this year + (+ (time-to-day-in-year time) ; Days this year (* 365 (1- year)) ; + Days in prior years (/ (1- year) 4) ; + Julian leap years (- (/ (1- year) 100)) ; - century years @@ -136,8 +183,8 @@ The number of days will be returned as a floating point number." ;;;###autoload (defun safe-date-to-time (date) - "Parse DATE and return a time structure. -If DATE is malformed, a zero time will be returned." + "Parse a string that represents a date-time and return a time value. +If DATE is malformed, return a time value of zeros." (condition-case () (date-to-time date) (error '(0 0)))) diff --git a/lisp/uudecode.el b/lisp/uudecode.el index 8e2fd66..8ef210a 100644 --- a/lisp/uudecode.el +++ b/lisp/uudecode.el @@ -48,7 +48,7 @@ input and write the converted data to its standard output." :group 'gnus-extract :type '(repeat string)) -(defcustom uudecode-use-external +(defcustom uudecode-use-external (executable-find uudecode-decoder-program) "*Use external uudecode program." :group 'gnus-extract @@ -166,8 +166,8 @@ If FILE-NAME is non-nil, save the result to FILE-NAME." (setq counter (1+ counter) inputpos (1+ inputpos)) (cond ((= counter 4) - (setq result (cons - (concat + (setq result (cons + (concat (char-to-string (lsh bits -16)) (char-to-string (logand (lsh bits -8) 255)) (char-to-string (logand bits 255))) @@ -183,13 +183,13 @@ If FILE-NAME is non-nil, save the result to FILE-NAME." ;;(error "uucode ends unexpectly") (setq done t)) ((= counter 3) - (setq result (cons - (concat + (setq result (cons + (concat (char-to-string (logand (lsh bits -16) 255)) (char-to-string (logand (lsh bits -8) 255))) result))) ((= counter 2) - (setq result (cons + (setq result (cons (char-to-string (logand (lsh bits -10) 255)) result)))) (skip-chars-forward non-data-chars end)) @@ -206,7 +206,7 @@ If FILE-NAME is non-nil, save the result to FILE-NAME." (defun uudecode-decode-region (start end &optional file-name) "Uudecode region between START and END. If FILE-NAME is non-nil, save the result to FILE-NAME." - (if uudecode-use-external + (if uudecode-use-external (uudecode-decode-region-external start end file-name) (uudecode-decode-region-internal start end file-name))) diff --git a/texi/.cvsignore b/texi/.cvsignore index b323d1e..764f2c7 100644 --- a/texi/.cvsignore +++ b/texi/.cvsignore @@ -3,6 +3,7 @@ emacs-mime gnus gnus-[0-9]* message +message-[0-9]* sieve gnustmp.texi *.dvi @@ -33,3 +34,4 @@ smiley.tex gnusconfig.tex old thumb* +auto diff --git a/texi/ChangeLog b/texi/ChangeLog index eb55f64..b30398c 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,310 @@ +2002-05-01 Lars Magne Ingebrigtsen + + * message.texi (Message Headers): Remove colon from index + entries. + +2002-05-01 Simon Josefsson + + * gnus.texi (Group Mail Splitting): Fix example. + (Article Buttons): Document that REGEXP can be a variable as well. + + * message.texi (Message Headers): Fix example. + +2002-04-26 Steve Youngs + + * Makefile.in (infodir): Set to '@info_dir@' so we can separate + defaults for XEmacs and Emacs. + +2002-04-27 Jesper Harder + + * emacs-mime.texi (Customization): Update info on HTML renderers. + + * gnus.texi (Article Washing): Update information on HTML washing. + Fix typos. + +2002-04-09 Paul Jarc + + * .cvsignore: added message-[0-9]* + +2002-04-08 Paul Jarc + + * gnus.texi (Group Parameters): Point to the message manual for a + full explanation of MFT. + * message.texi (Mailing Lists): Mention + message-gen-unsubscribed-mft. + From Karra . + +2002-04-05 Kai Gro,A_(Bjohann + + * gnus.texi (Saving Articles): Add xref to Mail Group Commands + because people might be interested in `B c' for saving articles. + (Archived Messages): Ditto. + +2002-04-01 Jesper Harder + + * gnus.texi (Sorting Groups): Add gnus-group-sort-selected-groups. + (Article Washing): Fix typo. + + * message.texi (Various Commands): Index message-elide-ellipsis. + Add message-sort-headers. + (Mail Variables): Add message-qmail-inject-args, + message-mailer-swallows-blank-line, message-sendmail-f-is-evil, + message-qmail-inject-program. + (Various Message Variables): Add message-auto-save-directory, + message-strip-special-text-properties, message-cancel-hook. + (News Headers): Index message-user-organization etc. + (Forwarding): Add message-forward-before-signature. + (Mailing Lists): Index message-subscribed-address-file. + (Wide Reply): Add message-wide-reply-confirm-recipients. + (Canceling News): Add message-cancel-message. + (Sending Variables): Add message-interactive. + +2002-03-25 Simon Josefsson + + * gnus.texi (Mail Spool): Add cindex for marks. + (Mail Folders): Add cindex for marks. + +2002-03-24 Raymond Scholz + + * gnus.texi (Summary Buffer Lines): Fix doc. + +2002-03-24 ShengHuo ZHU + + * Makefile.in (booklet.dvi, booklet.pdf): Support booklet. + +2002-03-24 Felix Natter + + * booklet.tex, bk-at.tex, bk-lt.tex, gnuslog-booklet.eps: New file. + * gnusref.tex, refcard.tex: Support booklet. + +2002-03-24 Jesper Harder + + * gnusref.tex: Addition. + + * gnus.texi: Don't use @sc in headings. + (Article Display): Fix. + (Signing and encrypting): Add mml-unsecure-message. + (IMAP): Remove @. to make texi2latex work. + (Thread Commands): Fix. + (Unavailable Servers): Add gnus-server-offline-server. + (Topic Sorting): Add gnus-topic-sort-groups. + (Limiting): Fix. + (Article Washing): Fix gnus-article-strip-headers-in-body, add + gnus-article-outlook-deuglify-article. + (Article Header): Add gnus-article-remove-leading-whitespace. + (Customizing Articles): Add gnus-treat-leading-whitespace. + (Summary Score Commands): Add gnus-score-find-favourite-words. + (Mailing List): Index gnus-mailing-list-insinuate. + (Mail Group Commands): Add gnus-article-encrypt-body, + gnus-summary-create-article. Don't use @var if not + metasyntactic. Index gnus-summary-edit-article-done. + + * message.texi (Security): Add mml-unsecure-message. + (Mailing Lists): Index message-goto-mail-followup-to. + +2002-03-23 Jesper Harder + + * gnusref.tex, refcard.tex: Addition. + +2002-03-21 ShengHuo ZHU + + * message.texi (Sending Variables): Fix typo. + Trivial change from Raymond Scholz + +2002-03-09 ShengHuo ZHU + + * gnus.texi (Other Marks): Remove duplication. + Trivial change from David Aspinwall + +2002-03-09 Paul Jarc + + * gnus.texi: Mention nnmaildir where appropriate; fix some typos. + +2002-03-01 Paul Jarc + + * message.texi (Mailing Lists): 'use is the default for + message-use-mail-followup-to, not nil; 'use is also not t. + Mention why an unsubscribed list poster might use MFT, and how to + disable MFT for a single message. + +2002-02-25 Katsumi Yamaoka + + * gnus.texi (Splitting Mail): Addition. + +2002-02-23 ShengHuo ZHU + + * gnusref.tex (subsection*{Notes}): Addition. + Suggested by Felix Natter + +2002-02-22 ShengHuo ZHU + + * gnus.texi (Splitting Mail): Addition. + +2002-02-20 ShengHuo ZHU + + * gnus.texi (Slave Gnusae): Addition. + From David S. Goldberg + +2002-02-18 ShengHuo ZHU + + * emacs-mime.texi (mailcap): Addition. + + * gnus.texi (Using MIME): Rename functions. Addition. + +2002-02-16 Simon Josefsson + + * gnus.texi (Top): Change description of Posting Server node. + (Composing Messages): Ditto. + (Posting Server): Add some mail stuff. + (IMAP): Terminate @, from Emacs Gnus manual. + (Thwarting Email Spam): Use @sc. + +2002-02-16 ShengHuo ZHU + + * gnusref.tex (subsection*{Notes}): Update. + From: Felix Natter + +2002-02-14 ShengHuo ZHU + + * gnus.texi (Document Groups): Addition. + +2002-02-13 Katsumi Yamaoka + + * message.texi (Security): Fix @findex for the key `C-c C-m s p'. + +2002-02-13 ShengHuo ZHU + + Reinstate some changes to make latexpdf work. + + * message.texi (Security): Don't use @key. + (Various Commands): Don't use @point. + + * gnus.texi (Mail Source Specifiers): Use @uref. + +2002-02-13 Jesper Harder + + * message.texi, gnus.texi, emacs-mime.texi: Use small caps + consistently. MIME, NOV, NNTP, HTML, IMAP are written with @sc + most places -- it looks better if it's the same *everywhere*. + @kbd instead of @code for key sequences. @file instead of @code + for files. + + * message.texi (Various Commands): use the proper @point glyph. + + * gnus.texi (Summary Mail Commands): ,A_(B doesn't work. A German + spelling reform changed the correct spelling to "muss" anyway (I + think). + + * gnus.texi (Mail sources): ,A'(B doesn't work. Use "section" instead. + + * gnus.texi (Mail Source Specifiers): use @url. + + * message.texi, emacs-mime.texi: update copyright year. + +2002-02-12 Paul Jarc + + * gnus.texi (Required Back End Functions): specify the lowest and + highest article numbers for empty groups for nnchoke-request-list + and nnchoke-request-group. + +2002-02-12 ShengHuo ZHU + + * message.texi (Sending Variables): Addition. + + * gnus.texi (Group Parameters): Add unread, not read. + (Archived Messages): Addition. + +2002-02-09 ShengHuo ZHU + + * gnus.texi (Group Parameters): Addition. + From: Steinar Bang + +2002-02-08 ShengHuo ZHU + + * gnus.texi (Article Washing): Addition. + From: Michael Cook + +2002-02-06 ShengHuo ZHU + + * gnus.texi (Gnus Unplugged): Use (setq gnus-agent t). + (Example Setup): Ditto. + (Category Syntax): Require gnus-agent. + +2002-02-06 Lars Magne Ingebrigtsen + + * gnus.texi (Posting Styles): Addition. + +2002-02-05 ShengHuo ZHU + + * message.texi (Mailing Lists): Addition. + * gnus.texi (Group Parameters): Addition. + From Sriram Karra . + +2002-02-03 Karl Kleinpaste + + * gnus.texi (Summary Score Commands): Added detail on "extra" + header scoring. + (Score File Format): ditto + +2002-02-01 Katsumi Yamaoka + + * emacs-mime.texi (Customization): Addition. + +2002-01-31 ShengHuo ZHU + + * gnus.texi (Posting Styles): Addition. Suggested by + Michael Cook . + +2002-01-30 Katsumi Yamaoka + + * emacs-mime.texi (Customization): Move emacs-w3m stuff backward; + added documentation for `mm-inline-text-html-with-w3m-keymap'. + +2002-01-28 ShengHuo ZHU + + * gnus.texi (Agent Expiry): Addition. + +2002-01-28 Katsumi Yamaoka + + * emacs-mime.texi (Customization): Added documentation for + `mm-inline-text-html-with-images'. + + * gnus.texi (Article Washing): Replace w3m to emacs-w3m. + +2002-01-26 Lars Magne Ingebrigtsen + + * gnus.texi (Mail Spool): Addition. + +2002-01-24 Katsumi Yamaoka + + * emacs-mime.texi (Customization): Added documentation for + `mm-inline-text-html-renderer'. + +2002-01-23 Katsumi Yamaoka + + * gnus.texi (Article Washing): Add URL about w3m. + +2002-01-22 Josh Huber + + * emacs-mime.texi (MML Definition): Added a few words about the + recipients option. + * message.texi (Security): Changed documentation to reflect use of + the new secure tag. + +2002-01-21 Lars Magne Ingebrigtsen + + * gnus.texi (Article Washing): Addition. + +2002-01-20 Lars Magne Ingebrigtsen + + * gnus.texi (Document Groups): Added info on more doc types. + (More Threading): Move documentation here. + +2002-01-20 Simon Josefsson + + * message.texi (Mailing Lists): Fix. From Love + . + 2002-01-20 Patric Mueller * gnus.texi (Group Timestamp): Typo fix. @@ -9,7 +316,7 @@ 2002-01-19 Lars Magne Ingebrigtsen * gnus.texi (Mail Spool): Note that the .marks files can be - removed. + removed. 2002-01-17 Paul Jarc @@ -41,7 +348,7 @@ 2002-01-11 ShengHuo ZHU * message.texi (Mailing Lists): Addition. - * gnus.texi (Group Parameters): Addition. + * gnus.texi (Group Parameters): Addition. From Sriram Karra . 2002-01-10 Colin Marquardt @@ -98,7 +405,7 @@ 2002-01-02 Lars Magne Ingebrigtsen * gnus.texi (Group Timestamp): Addition. Example from Andras - BALI. + BALI. (X-Face): Addition. (Advanced Formatting): Add example. diff --git a/texi/Makefile.in b/texi/Makefile.in index 934b1fa..d2ba870 100644 --- a/texi/Makefile.in +++ b/texi/Makefile.in @@ -1,4 +1,4 @@ -infodir = @infodir@ +infodir = @info_dir@ prefix = @prefix@ srcdir = @srcdir@ subdir = texi @@ -60,6 +60,25 @@ refcard.pdf: refcard.tex gnuslogo-refcard.eps gnusref.tex epstopdf $(srcdir)/gnuslogo-refcard.eps --outfile=gnuslogo-refcard.pdf TEXINPUTS=$(srcdir):$$TEXINPUTS $(PDFLATEX) refcard.tex +booklet.dvi: booklet.tex gnuslogo-refcard.eps gnusref.tex + if [ "$(PAPERTYPE)" == a4 ]; then \ + TEXINPUTS=$(srcdir):$$TEXINPUTS $(LATEX) bk-a4.tex && \ + mv bk-a4.dvi booklet.dvi ;\ + else \ + TEXINPUTS=$(srcdir):$$TEXINPUTS $(LATEX) bk-lt.tex && \ + mv bk-lt.dvi booklet.dvi;\ + fi + +booklet.pdf: booklet.tex gnuslogo-refcard.eps gnusref.tex + epstopdf $(srcdir)/gnuslogo-booklet.eps --outfile=gnuslogo-booklet.pdf + if [ "$(PAPERTYPE)" == a4 ]; then \ + TEXINPUTS=$(srcdir):$$TEXINPUTS $(PDFLATEX) bk-a4.tex &&\ + mv bk-a4.pdf booklet.pdf ;\ + else \ + TEXINPUTS=$(srcdir):$$TEXINPUTS $(PDFLATEX) bk-lt.tex &&\ + mv bk-lt.pdf booklet.pdf ;\ + fi + clean: rm -f *.[cgk]idx *.aux *.cp *.cps *.dvi *.dvi-x *.fn *.ky \ *.kys *.latexi *.log *.orig *.pdf *.pdf-x *.pg *.rej \ diff --git a/texi/bk-a4.tex b/texi/bk-a4.tex new file mode 100644 index 0000000..20d13ab --- /dev/null +++ b/texi/bk-a4.tex @@ -0,0 +1,20 @@ +% Reference Booklet for (ding) Gnus, A4 format. +% To be processed with latex 2e +\documentclass{article} + +\usepackage{supertabular} + +\newlength{\logowidth} \setlength{\logowidth}{6.861in} +\newlength{\logoheight} \setlength{\logoheight}{7.013in} + +\def\Guide{Card}\def\guide{card} +\def\logoscale{0.25} + +\usepackage{epsfig} + +\textwidth 4.9in \textheight 7.35in \topmargin -1.0in +\oddsidemargin -0.5in \evensidemargin -0.5in +\begin{document} +\small%\footnotesize +\input{booklet} +\end{document} diff --git a/texi/bk-lt.tex b/texi/bk-lt.tex new file mode 100644 index 0000000..0329059 --- /dev/null +++ b/texi/bk-lt.tex @@ -0,0 +1,20 @@ +% Reference Booklet for (ding) Gnus, Letter format. +% To be processed with latex 2e +\documentclass{article} + +\usepackage{supertabular} + +\newlength{\logowidth} \setlength{\logowidth}{6.861in} +\newlength{\logoheight} \setlength{\logoheight}{7.013in} + +\def\Guide{Card}\def\guide{card} +\def\logoscale{0.25} + +\usepackage{epsfig} + +\textwidth 4.5in \textheight 7.5in \topmargin -1.0in +\oddsidemargin -0.5in \evensidemargin -0.5in +\begin{document} +\small%\footnotesize +\input{booklet} +\end{document} diff --git a/texi/booklet.tex b/texi/booklet.tex new file mode 100644 index 0000000..5ae0821 --- /dev/null +++ b/texi/booklet.tex @@ -0,0 +1,166 @@ +% include file for the Reference Booklet (16 pages). +\def\Guide{Booklet}\def\guide{booklet} +\def\logoscale{0.5} +\def\sec{\section} +\def\subsec{\subsection} +\def\subsubsec{\subsubsection} +\def\blankpage{\vspace*{\fill}\par +%\centerline{(This page intentionally left blank.)} +\par\vspace*{\fill}\pagebreak} + +\input{gnusref} + +\setcounter{page}{0} +\thispagestyle{empty} +\vspace*{\fill} +\Title +\vspace{0.4in} +\Logo{booklet} +\vspace*{\fill} +\pagebreak + +% TODO: how does this work ? +%\tableofcontents + +\Notes +% +\section*{Group-Mode} +\GroupModeGeneral + \subsection*{Group Subscribedness-Levels} + \GroupLevels + \subsection*{List Groups} + \ListGroups + \subsection*{Create/Edit Foreign Groups} + \CreateEditGroups + \subsection*{Unsubscribe, Kill and Yank Groups} + \SubscribeKillYankGroups + \subsection*{Mark Groups} + \MarkGroups + \subsection*{Group-Unplugged} + \GroupUnplugged +% topics in group-mode + \subsection*{Group Topics} + \GroupTopicsGeneral + \subsubsection*{Topic Sorting} + \TopicSorting +% +% summary-mode +\section*{Summary-Mode} +\SummaryModeGeneral + \subsection*{Select Articles} + \SelectArticles +% + \subsection*{Threading} + \Threading +% + \subsection*{Limiting} + \Limiting + \subsection*{Sort the Summary-Buffer} + \SortSummary + \subsection*{Score (Value) Commands} + \Scoring +% + \subsection*{MIME operations from the Summary-Buffer} + \MIMESummary + \subsection*{Extract Series (Uudecode etc)} + \ExtractSeries + \subsection*{Output Articles} + \OutputArticles +% + \subsection*{Post, Followup, Reply, Forward, Cancel} + \PostReplyetc + \subsection*{Message-Composition} + \MsgCompositionGeneral + \subsubsection*{Jumping in message-buffer} + \MsgCompositionMovementArticle + \subsubsection*{Attachments/MML} + \MsgCompositionMML +% marking articles + \subsection*{Mark Articles} + \MarkArticlesGeneral + \subsubsection*{Mark Based on Score} + \MarkByScore + \subsubsection*{The Process Mark} + \ProcessMark + \subsubsection*{Mark Indication-Characters} + \MarkCharacters +% + \subsection*{Summary-Unplugged} + \SummaryUnplugged + \subsection*{Mail-Group Commands} + \MailGroups + \subsection*{Draft-Group Commands} + \DraftGroup +% exiting + \subsection*{Exit the Summary-Buffer} + \ExitSummary +% +% +\section*{Article Mode (reading)} +\ArticleModeGeneral + \subsection*{Wash the Article-Buffer} + \WashArticle + \subsection*{Hide/Highlight Parts of the Article} + \HideHighlightArticle + \subsection*{MIME operations from the Article-Buffer (reading)} + \MIMEArticleMode +% +% +\section*{Server Mode} +\ServerMode + \subsection*{Unplugged-Server} + \ServerUnplugged +% +% +\section*{Browse Server Mode} +\BrowseServer + +%\pagebreak +\vspace*{\fill} +\Copyright + +%% \pagebreak +%% \Notes +%% \GroupLevels +%% \Marks +%% \General +%% \ServerMode +%% \BrowseServer +%% \ArticleMode +%% \pagebreak + +%% \GroupMode +%% \ListGroups +%% \CreateGroups +%% \SortGroups +%% \SOUP +%% \MarkGroups +%% \Unsubscribe +%% \GroupTopics +%% \SummaryMode +%% \SortSummary +%% \Article +%% \MailGroup +%% \Limit +%% \GotoArticle +%% \MarkArticles +%% \MarkScore +%% \ProcessMark +%% \OutputArticles +%% \Send +%% \Exit +%% \Thread +%% \Score +%% \Wash +%% \Hide +%% \Highlight +%% \Extract +%% \PickAndRead + +%% %\pagebreak +%% %\sec{Personal Notes} +%% %\blankpage + +%% \thispagestyle{empty} +%% \vspace*{\fill} +%% \CopyRight diff --git a/texi/emacs-mime.texi b/texi/emacs-mime.texi index 12a4862..1283422 100644 --- a/texi/emacs-mime.texi +++ b/texi/emacs-mime.texi @@ -47,7 +47,8 @@ license to the document, as described in section 6 of the license. @page @vskip 0pt plus 1filll -Copyright @copyright{} 1998, 1999, 2000 Free Software Foundation, Inc. +Copyright @copyright{} 1998, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or @@ -92,7 +93,7 @@ read at least RFC2045 and RFC2047. * Interface Functions:: An abstraction over the basic functions. * Basic Functions:: Utility and basic parsing functions. * Decoding and Viewing:: A framework for decoding and viewing. -* Composing:: MML; a language for describing MIME parts. +* Composing:: MML; a language for describing @sc{mime} parts. * Standards:: A summary of RFCs and working documents used. * Index:: Function and variable index. @end menu @@ -119,16 +120,16 @@ both the old syntax as well as the new syntax, and if there is only one library, one must choose between the old version of the library and the new version of the library. -The Emacs MIME library takes a different tack. It defines a series of -low-level libraries (@file{rfc2047.el}, @file{rfc2231.el} and so on) -that parses strictly according to the corresponding standard. However, -normal programs would not use the functions provided by these libraries -directly, but instead use the functions provided by the -@code{mail-parse} library. The functions in this library are just -aliases to the corresponding functions in the latest low-level -libraries. Using this scheme, programs get a consistent interface they -can use, and library developers are free to create write code that -handles new standards. +The Emacs @sc{mime} library takes a different tack. It defines a +series of low-level libraries (@file{rfc2047.el}, @file{rfc2231.el} +and so on) that parses strictly according to the corresponding +standard. However, normal programs would not use the functions +provided by these libraries directly, but instead use the functions +provided by the @code{mail-parse} library. The functions in this +library are just aliases to the corresponding functions in the latest +low-level libraries. Using this scheme, programs get a consistent +interface they can use, and library developers are free to create +write code that handles new standards. The following functions are defined by this library: @@ -241,7 +242,7 @@ at the beginning of the narrowed buffer. @item mail-header-narrow-to-field @findex mail-header-narrow-to-field Narrow the buffer to the header under point. Understands continuation -headers. +headers. @item mail-header-fold-field @findex mail-header-fold-field @@ -647,7 +648,7 @@ Take a year number and say whether it's a leap year. @item time-to-day-in-year Take a time and return the day number within the year that the time is -in. +in. @end table @@ -795,10 +796,12 @@ Here's an example file: @example image/*; gimp -8 %s audio/wav; wavplayer %s +application/msword; catdoc %s ; copiousoutput ; nametemplate=%s.doc @end example -This says that all image files should be displayed with @code{gimp}, and -that WAVE audio files should be played by @code{wavplayer}. +This says that all image files should be displayed with @code{gimp}, +that WAVE audio files should be played by @code{wavplayer}, and that +MS-WORD files should be inlined by @code{catdoc}. The @code{mailcap} library parses this file, and provides functions for matching types. @@ -856,10 +859,10 @@ descend the message, following the structure, and return a tree of @node Non-MIME @section Non-MIME -Gnus also understands some non-MIME attachments, such as postscript, -uuencode, binhex, shar, forward, gnatsweb, pgp. Each of these features -can be disabled by add an item into @code{mm-uu-configure-list}. -For example, +Gnus also understands some non-@sc{mime} attachments, such as +postscript, uuencode, binhex, shar, forward, gnatsweb, pgp. Each of +these features can be disabled by add an item into +@code{mm-uu-configure-list}. For example, @lisp (require 'mm-uu) @@ -1003,7 +1006,7 @@ Prompt for a mailcap method to use to view the part. @item mm-inline-media-tests This is an alist where the key is a @sc{mime} type, the second element -is a function to display the part @dfn{inline} (i.e., inside Emacs), and +is a function to display the part @dfn{inline} (i.e., inside Emacs), and the third element is a form to be @code{eval}ed to say whether the part can be displayed inline. @@ -1023,7 +1026,7 @@ be displayed automatically. @item mm-attachment-override-types Some @sc{mime} agents create parts that have a content-disposition of -@samp{attachment}. This variable allows overriding that disposition and +@samp{attachment}. This variable allows overriding that disposition and displaying the part inline. (Note that the disposition is only overridden if we are able to, and want to, display the part inline.) @@ -1062,6 +1065,29 @@ list containing that type. For example assuming @code{mm-inlined-types} includes @samp{text/.*}, then including @samp{text/html} in this variable will cause @samp{text/html} parts to be treated as attachments. +@item mm-inline-text-html-renderer +This selects the function used to render @sc{html}. The predefined +renderers are selected by the symbols @code{w3}, +@code{w3m}@footnote{See @uref{http://emacs-w3m.namazu.org/} for more +information about emacs-w3m}, @code{links}, @code{lynx} or +@code{html2text}. You can also specify a function, which will be +called with a @sc{mime} handle as the argument. + +@item mm-inline-text-html-with-images +Some @sc{html} mails might have the trick of spammers using +@samp{} tags. It is likely to be intended to verify whether you +have read the mail. You can prevent your personal informations from +leaking by setting this option to @code{nil} (which is the default). +It is currently ignored by Emacs/w3. For emacs-w3m, you may use the +command @kbd{t} on the image anchor to show an image even if it is +@code{nil}.@footnote{The command @kbd{T} will load all images. If you +have set the option @code{w3m-key-binding} to @code{info}, use @kbd{i} +or @kbd{I} instead.} + +@item mm-inline-text-html-with-w3m-keymap +You can use emacs-w3m command keys in the inlined text/html part by +setting this option to non-@code{nil}. The default value is @code{t}. + @end table @@ -1082,7 +1108,7 @@ Here's an example viewer for displaying @code{text/enriched} inline: @end lisp We see that the function takes a @sc{mime} handle as its parameter. It -then goes to a temporary buffer, inserts the text of the part, does some +then goes to a temporary buffer, inserts the text of the part, does some work on the text, stores the result, goes back to the buffer it was called from and inserts the result. @@ -1114,7 +1140,7 @@ string containing the @sc{mime} message. * Simple MML Example:: An example MML document. * MML Definition:: All valid MML elements. * Advanced MML Example:: Another example MML document. -* Charset Translation:: How charsets are mapped from @sc{mule} to MIME. +* Charset Translation:: How charsets are mapped from @sc{mule} to @sc{mime}. * Conversion:: Going from @sc{mime} to MML and vice versa. * Flowed text:: Soft and hard newlines. @end menu @@ -1216,6 +1242,10 @@ RFC822 date when the part was modified (@code{Content-Disposition}). @item read-date RFC822 date when the part was read (@code{Content-Disposition}). +@item recipients +Who to encrypt/sign the part to. This field is used to override any +auto-detection based on the To/CC headers. + @item size The size (in octets) of the part (@code{Content-Disposition}). @@ -1377,7 +1407,7 @@ given by @code{mail-parse-charset} (a symbol) is used. (Never set this variable directly, though. If you want to change the default charset, please consult the documentation of the package which you use to process @sc{mime} messages. -@xref{Various Message Variables, , Various Message Variables, message, +@xref{Various Message Variables, , Various Message Variables, message, Message Manual}, for example.) If there are only ASCII characters, the @sc{mime} charset US-ASCII is used, of course. @@ -1482,7 +1512,7 @@ Registration Procedures Conformance Criteria and Examples @item RFC2231 -MIME Parameter Value and Encoded Word Extensions: Character Sets, +@sc{mime} Parameter Value and Encoded Word Extensions: Character Sets, Languages, and Continuations @item RFC1843 @@ -1493,7 +1523,7 @@ ASCII characters Draft for the successor of RFC822 @item RFC2112 -The MIME Multipart/Related Content-type +The @sc{mime} Multipart/Related Content-type @item RFC1892 The Multipart/Report Content Type for the Reporting of Mail System diff --git a/texi/gnus.texi b/texi/gnus.texi index c000d91..faa1ceb 100644 --- a/texi/gnus.texi +++ b/texi/gnus.texi @@ -33,7 +33,7 @@ \makeindex \begin{document} -\newcommand{\gnusversionname}{Oort Gnus v0.05} +\newcommand{\gnusversionname}{Oort Gnus v0.06} \newcommand{\gnuschaptername}{} \newcommand{\gnussectionname}{} @@ -382,7 +382,7 @@ can be gotten by any nefarious means you can think of---@sc{nntp}, local spool or your mbox file. All at the same time, if you want to push your luck. -This manual corresponds to Oort Gnus v0.05 +This manual corresponds to Oort Gnus v0.06. @end ifinfo @@ -624,7 +624,7 @@ Article Buffer Composing Messages * Mail:: Mailing and replying. -* Posting Server:: What server should you post via? +* Posting Server:: What server should you post and mail via? * Mail and Post:: Mailing and posting at the same time. * Archived Messages:: Where Gnus stores the messages you've sent. * Posting Styles:: An easier way to specify who you are. @@ -1117,6 +1117,11 @@ they were created, so the latest changes will have precedence.) Information from the slave files has, of course, precedence over the information in the normal (i.e., master) @code{.newsrc} file. +If the @code{.newsrc*} files have not been saved in the master when the +slave starts, you may be prompted as to whether to read an auto-save +file. If you answer "yes", the unsaved changes to the master will be +incorporated into the slave. If you answer "no", the slave may see some +messages as unread that have been read in the master. @node Fetching a Group @section Fetching a Group @@ -1305,8 +1310,9 @@ thought it would be nice to have two of these. This variable is more meant for setting some ground rules, while the other variable is used more for user fiddling. By default this variable makes all new groups that come from mail back ends (@code{nnml}, @code{nnbabyl}, -@code{nnfolder}, @code{nnmbox}, and @code{nnmh}) subscribed. If you -don't like that, just set this variable to @code{nil}. +@code{nnfolder}, @code{nnmbox}, @code{nnmh}, and @code{nnmaildir}) +subscribed. If you don't like that, just set this variable to +@code{nil}. New groups that match this regexp are subscribed using @code{gnus-subscribe-options-newsgroup-method}. @@ -1756,13 +1762,13 @@ Number of read articles. Estimated total number of articles. (This is really @var{max-number} minus @var{min-number} plus 1.) -Gnus uses this estimation because the NNTP protocol provides efficient -access to @var{max-number} and @var{min-number} but getting the true -unread message count is not possible efficiently. For hysterical -raisins, even the mail back ends, where the true number of unread -messages might be available efficiently, use the same limited -interface. To remove this restriction from Gnus means that the -back end interface has to be changed, which is not an easy job. If you +Gnus uses this estimation because the @sc{nntp} protocol provides +efficient access to @var{max-number} and @var{min-number} but getting +the true unread message count is not possible efficiently. For +hysterical raisins, even the mail back ends, where the true number of +unread messages might be available efficiently, use the same limited +interface. To remove this restriction from Gnus means that the back +end interface has to be changed, which is not an easy job. If you want to work on this, please contact the Gnus mailing list. @item y @@ -2678,13 +2684,15 @@ entering summary buffer. See also @code{gnus-parameter-to-list-alist}. +@anchor{subscribed} @item subscribed @cindex subscribed If this parameter is set to @code{t}, Gnus will consider the to-address and to-list parameters for this group as addresses of -mailing lists you are subscribed to. Giving Gnus this information -will help it to generate correct Mail-Followup-To headers for your -posts to these lists. +mailing lists you are subscribed to. Giving Gnus this information is +(only) a first step in getting it to generate correct Mail-Followup-To +headers for your posts to these lists. Look here @pxref{(message)Mailing +Lists} for a complete treatment of available MFT support. See also @code{gnus-find-subscribed-addresses}, the function that directly uses this group parameter. @@ -2723,7 +2731,9 @@ composed messages will be @code{Gcc}'d to the current group. If generated, if @code{(gcc-self . "string")} is present, this string will be inserted literally as a @code{gcc} header. This parameter takes precedence over any default @code{Gcc} rules as described later -(@pxref{Archived Messages}). +(@pxref{Archived Messages}). CAVEAT:: It yields an error putting +@code{(gcc-self . t)} in groups of a @code{nntp} server or so, because +a @code{nntp} server doesn't accept artciles. @item auto-expire @cindex auto-expire @@ -2794,8 +2804,8 @@ Display articles that satisfy a predicate. Here are some examples: @table @code -@item [read] -Display only read articles. +@item [unread] +Display only unread articles. @item [not expire] Display everything except expirable articles. @@ -2807,9 +2817,9 @@ responded to. The available operators are @code{not}, @code{and} and @code{or}. Predicates include @code{tick}, @code{unsend}, @code{undownload}, -@code{read}, @code{dormant}, @code{expire}, @code{reply}, +@code{unread}, @code{dormant}, @code{expire}, @code{reply}, @code{killed}, @code{bookmark}, @code{score}, @code{save}, -@code{cache}, @code{forward}, @code{seen} and @code{recent}. +@code{cache}, @code{forward}, @code{unseen} and @code{recent}. @end table @@ -2884,9 +2894,9 @@ translating the group parameter into a Sieve script (@pxref{Sieve Commands}) the following Sieve code is generated: @example - if address \"sender\" \"sieve-admin@@extundo.com\" @{ - fileinto \"INBOX.list.sieve\"; - @} +if address \"sender\" \"sieve-admin@@extundo.com\" @{ + fileinto \"INBOX.list.sieve\"; +@} @end example The Sieve language is described in RFC 3028. @xref{Top, , Top, sieve, @@ -2900,6 +2910,16 @@ that group. @code{gnus-show-threads} will be made into a local variable in the summary buffer you enter, and the form @code{nil} will be @code{eval}ed there. +@vindex gnus-list-identifiers +A use for this feature, is to remove a mailing list identifier tag in +the subject fields of articles. E.g. if the news group +@samp{nntp+news.gnus.org:gmane.text.docbook.apps} has the tag +@samp{DOC-BOOK-APPS:} in the subject of all articles, this tag can be +removed from the article subjects in the summary buffer for the group by +putting @code{(gnus-list-identifiers "DOCBOOK-APPS:")} into the group +parameters for the group. + + This can also be used as a group-specific hook function, if you'd like. If you want to hear a beep when you enter a group, you could put something like @code{(dummy-variable (ding))} in the parameters of that @@ -3212,6 +3232,11 @@ Sort the groups by group rank Sort the groups alphabetically by back end name (@code{gnus-group-sort-selected-groups-by-method}). +@item G P s +@kindex G P s (Group) +@findex gnus-group-sort-selected-groups +Sort the groups according to @code{gnus-group-sort-function}. + @end table And finally, note that you can use @kbd{C-k} and @kbd{C-y} to manually @@ -3742,9 +3767,18 @@ Sort the current topic alphabetically by back end name Sort the current topic alphabetically by server name (@code{gnus-topic-sort-groups-by-server}). +@item T S s +@kindex T S s +@findex gnus-topic-sort-groups +Sort the current topic according to the function(s) given by the +@code{gnus-group-sort-function} variable +(@code{gnus-topic-sort-groups}). + @end table -@xref{Sorting Groups}, for more information about group sorting. +When given a prefix argument, all these commands will sort in reverse +order. @xref{Sorting Groups}, for more information about group +sorting. @node Topic Topology @@ -4330,7 +4364,7 @@ possible to change this. Just write a new function @code{gnus-goto-colon} which does whatever you like with the cursor.) @xref{Positioning Point}. -The default string is @samp{%U%R%z%I%(%[%4L: %-23,23n%]%) %s\n}. +The default string is @samp{%U%R%z%I%(%[%4L: %-23,23f%]%) %s\n}. The following format specification characters and extended format specification(s) are understood: @@ -5023,11 +5057,12 @@ Forward the current article to some other person is forwarded according to the value of (@code{message-forward-as-mime}) and (@code{message-forward-show-mml}); if the prefix is 1, decode the message and forward directly inline; if the prefix is 2, forward message -as an rfc822 MIME section; if the prefix is 3, decode message and -forward as an rfc822 MIME section; if the prefix is 4, forward message +as an rfc822 @sc{mime} section; if the prefix is 3, decode message and +forward as an rfc822 @sc{mime} section; if the prefix is 4, forward message directly inline; otherwise, the message is forwarded as no prefix given but use the flipped value of (@code{message-forward-as-mime}). By -default, the message is decoded and forwarded as an rfc822 MIME section. +default, the message is decoded and forwarded as an rfc822 @sc{mime} +section. @item S m @itemx m @@ -5083,7 +5118,7 @@ This command is mainly used if you have several accounts and want to ship a mail to a different account of yours. (If you're both @code{root} and @code{postmaster} and get a mail for @code{postmaster} to the @code{root} account, you may want to resend it to -@code{postmaster}. Ordnung muß sein! +@code{postmaster}. Ordnung muss sein! This command understands the process/prefix convention (@pxref{Process/Prefix}). @@ -5175,11 +5210,11 @@ Forward the current article to a newsgroup of (@code{message-forward-as-mime}) and (@code{message-forward-show-mml}); if the prefix is 1, decode the message and forward directly inline; if the prefix is 2, forward message -as an rfc822 MIME section; if the prefix is 3, decode message and -forward as an rfc822 MIME section; if the prefix is 4, forward message +as an rfc822 @sc{mime} section; if the prefix is 3, decode message and +forward as an rfc822 @sc{mime} section; if the prefix is 4, forward message directly inline; otherwise, the message is forwarded as no prefix given but use the flipped value of (@code{message-forward-as-mime}). By -default, the message is decoded and forwarded as an rfc822 MIME section. +default, the message is decoded and forwarded as an rfc822 @sc{mime} section. @item S O p @kindex S O p (Summary) @@ -5537,15 +5572,11 @@ All articles that you have replied to or made a followup to (i.e., have answered) will be marked with an @samp{A} in the second column (@code{gnus-replied-mark}). +@item @vindex gnus-forwarded-mark All articles that you have forwarded will be marked with an @samp{F} in the second column (@code{gnus-forwarded-mark}). -@vindex gnus-recent-mark -Articles that are ``recently'' arrived in the group will be marked -with an @samp{N} in the second column (@code{gnus-recent-mark}). Most -back end doesn't support the mark, in which case it's not shown. - @item @vindex gnus-cached-mark Articles stored in the article cache will be marked with an @samp{*} in @@ -5562,7 +5593,7 @@ religiously) are marked with an @samp{S} in the second column Articles that according to the back end haven't been seen by the user before are marked with a @samp{N} in the second column (@code{gnus-recent-mark}). Note that not all back ends support this -mark, in which case it simply never appear. +mark, in which case it simply never appears. @item @vindex gnus-unseen-mark @@ -5981,10 +6012,10 @@ score (@code{gnus-summary-limit-to-score}). @item / p @kindex / p (Summary) -@findex gnus-summary-limit-to-display-parameter +@findex gnus-summary-limit-to-display-predicate Limit the summary buffer to articles that satisfy the @code{display} group parameter predicate -(@code{gnus-summary-limit-to-display-parameter}). See @pxref{Group +(@code{gnus-summary-limit-to-display-predicate}). See @pxref{Group Parameters} for more on this predicate. @item / E @@ -6311,9 +6342,10 @@ connect as many loose threads as possible, you should set this variable to @code{some} or a number. If you set it to a number, no more than that number of extra old headers will be fetched. In either case, fetching old headers only works if the back end you are using carries -overview files---this would normally be @code{nntp}, @code{nnspool} and -@code{nnml}. Also remember that if the root of the thread has been -expired by the server, there's not much Gnus can do about that. +overview files---this would normally be @code{nntp}, @code{nnspool}, +@code{nnml}, and @code{nnmaildir}. Also remember that if the root of +the thread has been expired by the server, there's not much Gnus can do +about that. This variable can also be set to @code{invisible}. This won't have any visible effects, but is useful if you use the @kbd{A T} command a lot @@ -6365,6 +6397,22 @@ slower and more awkward. If non-@code{nil}, all threads will be hidden when the summary buffer is generated. +This can also be a predicate specifier (@pxref{Predicate Specifiers}). +Avaliable predicates are @code{gnus-article-unread-p} and +@code{gnus-article-unseen-p}). + +Here's an example: + +@lisp +(setq gnus-thread-hide-subtree + '(or gnus-article-unread-p + gnus-article-unseen-p)) +@end lisp + +(It's a pretty nonsensical example, since all unseen articles are also +unread, but you get my drift.) + + @item gnus-thread-expunge-below @vindex gnus-thread-expunge-below All threads that have a total score (as defined by @@ -6528,7 +6576,7 @@ understand the numeric prefix. @item T n @kindex T n (Summary) -@itemx C-M-n +@itemx C-M-f @kindex C-M-n (Summary) @itemx M-down @kindex M-down (Summary) @@ -6537,7 +6585,7 @@ Go to the next thread (@code{gnus-summary-next-thread}). @item T p @kindex T p (Summary) -@itemx C-M-p +@itemx C-M-b @kindex C-M-p (Summary) @itemx M-up @kindex M-up (Summary) @@ -6920,6 +6968,10 @@ processing of the article is done before it is saved). For a different approach (uudecoding, unsharing) you should use @code{gnus-uu} (@pxref{Decoding Articles}). +For the commands listed here, the target is a file. If you want to +save to a group, see the @kbd{B c} (@code{gnus-summary-copy-article}) +command (@pxref{Mail Group Commands}). + @vindex gnus-save-all-headers If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete unwanted headers before saving the article. @@ -8025,9 +8077,9 @@ Toggle whether to display all headers in the article buffer @item W v @kindex W v (Summary) -@findex gnus-summary-verbose-header +@findex gnus-summary-verbose-headers Toggle whether to display all headers in the article buffer permanently -(@code{gnus-summary-verbose-header}). +(@code{gnus-summary-verbose-headers}). @item W o @kindex W o (Summary) @@ -8052,6 +8104,13 @@ an attempt to provide more quoting characters. If you see something like @code{\222} or @code{\264} where you're expecting some kind of apostrophe or quotation mark, then try this wash. +@item W k +@kindex W k (Summary) +@findex gnus-article-outlook-deuglify-article +@cindex Outlook Express +Deuglify broken Outlook (Express) articles and redisplay +(@code{gnus-article-outlook-deuglify-article}). + @item W w @kindex W w (Summary) @findex gnus-article-fill-cited-article @@ -8086,7 +8145,7 @@ Treat quoted-printable (@code{gnus-article-de-quoted-unreadable}). Quoted-Printable is one common @sc{mime} encoding employed when sending non-ASCII (i. e., 8-bit) articles. It typically makes strings like @samp{déjà vu} look like @samp{d=E9j=E0 vu}, which doesn't look very -readable to me. Note that the this is usually done automatically by +readable to me. Note that this is usually done automatically by Gnus if the message in question has a @code{Content-Transfer-Encoding} header that says that this encoding has been done. If a prefix is given, a charset will be asked for. @@ -8096,7 +8155,7 @@ If a prefix is given, a charset will be asked for. @findex gnus-article-de-base64-unreadable Treat base64 (@code{gnus-article-de-base64-unreadable}). Base64 is one common @sc{mime} encoding employed when sending non-ASCII -(i. e., 8-bit) articles. Note that the this is usually done +(i. e., 8-bit) articles. Note that this is usually done automatically by Gnus if the message in question has a @code{Content-Transfer-Encoding} header that says that this encoding has been done. @@ -8109,15 +8168,49 @@ Treat HZ or HZP (@code{gnus-article-decode-HZ}). HZ (or HZP) is one common encoding employed when sending Chinese articles. It typically makes strings look like @samp{~@{<:Ky2;S@{#,NpJ)l6HK!#~@}}. +@item W u +@kindex W u (Summary) +@findex gnus-article-unsplit-urls +Remove newlines from within URLs. Some mailers insert newlines into +outgoing email messages to keep lines short. This reformatting can +split long URLs onto multiple lines. Repair those URLs by removing +the newlines (@code{gnus-article-unsplit-urls}). + @item W h @kindex W h (Summary) @findex gnus-article-wash-html -Treat HTML (@code{gnus-article-wash-html}). -Note that the this is usually done automatically by Gnus if the message -in question has a @code{Content-Type} header that says that this type -has been done. +Treat @sc{html} (@code{gnus-article-wash-html}). Note that this is +usually done automatically by Gnus if the message in question has a +@code{Content-Type} header that says that the message is @sc{html}. + If a prefix is given, a charset will be asked for. +@vindex gnus-article-wash-function +The default is to use the function specified by +@code{mm-inline-text-html-renderer} (@pxref{Customization, , , emacs-mime}) +to convert the @sc{html}, but this is controlled by the +@code{gnus-article-wash-function} variable. Pre-defined functions you +can use include: + +@table @code +@item w3 +Use Emacs/w3. + +@item w3m +Use emacs-w3m (see @uref{http://emacs-w3m.namazu.org/} for more +information). + +@item links +Use Links (see @uref{http://artax.karlin.mff.cuni.cz/~mikulas/links/}). + +@item lynx +Use Lynx (see @uref{http://lynx.browser.org/}). + +@item html2text +Use html2text -- a simple @sc{html} converter included with Gnus. + +@end table + @item W b @kindex W b (Summary) @findex gnus-article-add-buttons @@ -8143,14 +8236,14 @@ message.@footnote{PGP keys for many hierarchies are available at @item W s @kindex W s (Summary) @findex gnus-summary-force-verify-and-decrypt -Verify a signed (PGP, PGP/MIME or S/MIME) message +Verify a signed (PGP, @sc{pgp/mime} or @sc{s/mime}) message (@code{gnus-summary-force-verify-and-decrypt}). @xref{Security}. -@item W W H -@kindex W W H (Summary) -@findex gnus-article-strip-headers-from-body +@item W a +@kindex W a (Summary) +@findex gnus-article-strip-headers-in-body Strip headers like the @code{X-No-Archive} header from the beginning of -article bodies (@code{gnus-article-strip-headers-from-body}). +article bodies (@code{gnus-article-strip-headers-in-body}). @item W E l @kindex W E l (Summary) @@ -8224,6 +8317,12 @@ Fold the @code{Newsgroups} and @code{Followup-To} headers Fold all the message headers (@code{gnus-article-treat-fold-headers}). +@item W E w +@kindex W E w +@findex gnus-article-remove-leading-whitespace +Remove excessive whitespace from all headers +(@code{gnus-article-remove-leading-whitespace}). + @end table @@ -8256,7 +8355,8 @@ This is an alist where each entry has this form: @item regexp All text that match this regular expression will be considered an external reference. Here's a typical regexp that matches embedded URLs: -@samp{]*\\)>}. +@samp{]*\\)>}. This can also be a variable containing a +regexp, useful variables to use include @code{gnus-button-url-regexp}. @item button-par Gnus has to know which parts of the matches is to be highlighted. This @@ -8431,7 +8531,7 @@ Display an @code{X-Face} in the @code{From} header. @item W D s @kindex W D s (Summary) -@findex gnus-smiley-smiley +@findex gnus-treat-smiley Display smileys (@code{gnus-treat-smiley}). @item W D f @@ -8449,7 +8549,7 @@ Piconify all mail headers (i. e., @code{Cc}, @code{To}) @kindex W D n (Summary) @findex gnus-treat-newsgroups-picon Piconify all news headers (i. e., @code{Newsgroups} and -@code{Followup-To}) (@code{gnus-treat-from-picon}). +@code{Followup-To}) (@code{gnus-treat-newsgroups-picon}). @item W D D @kindex W D D (Summary) @@ -8537,7 +8637,7 @@ Translate the article from one language to another @node MIME Commands -@section @sc{mime} Commands +@section MIME Commands @cindex MIME decoding @cindex attachments @cindex viewing attachments @@ -8617,9 +8717,9 @@ Decode encoded article bodies as well as charsets This command looks in the @code{Content-Type} header to determine the charset. If there is no such header in the article, you can give it a prefix, which will prompt for the charset to decode as. In regional -groups where people post using some common encoding (but do not include -MIME headers), you can set the @code{charset} group/topic parameter to -the required charset (@pxref{Group Parameters}). +groups where people post using some common encoding (but do not +include @sc{mime} headers), you can set the @code{charset} group/topic +parameter to the required charset (@pxref{Group Parameters}). @item W M v @kindex W M v (Summary) @@ -8980,12 +9080,12 @@ then ask Deja if that fails: @end lisp Most of the mail back ends support fetching by @code{Message-ID}, but -do not do a particularly excellent job at it. That is, @code{nnmbox} -and @code{nnbabyl} are able to locate articles from any groups, while -@code{nnml}, @code{nnfolder} and @code{nnimap}1 are only able to locate -articles that have been posted to the current group. (Anything else -would be too time consuming.) @code{nnmh} does not support this at -all. +do not do a particularly excellent job at it. That is, @code{nnmbox}, +@code{nnbabyl}, and @code{nnmaildir} are able to locate articles from +any groups, while @code{nnml}, @code{nnfolder}, and @code{nnimap} are +only able to locate articles that have been posted to the current group. +(Anything else would be too time consuming.) @code{nnmh} does not +support this at all. @node Alternative Approaches @@ -9296,7 +9396,7 @@ disk forever and ever, never to return again.'' Use with caution. @vindex gnus-preserve-marks Move the article from one mail group to another (@code{gnus-summary-move-article}). Marks will be preserved if -@var{gnus-preserve-marks} is non-@code{nil} (which is the default). +@code{gnus-preserve-marks} is non-@code{nil} (which is the default). @item B c @kindex B c (Summary) @@ -9305,7 +9405,7 @@ Move the article from one mail group to another @c @icon{gnus-summary-mail-copy} Copy the article from one group (mail group or not) to a mail group (@code{gnus-summary-copy-article}). Marks will be preserved if -@var{gnus-preserve-marks} is non-@code{nil} (which is the default). +@code{gnus-preserve-marks} is non-@code{nil} (which is the default). @item B B @kindex B B (Summary) @@ -9323,6 +9423,13 @@ Import an arbitrary file into the current mail newsgroup (@code{gnus-summary-import-article}). You will be prompted for a file name, a @code{From} header and a @code{Subject} header. +@item B I +@kindex B I (Summary) +@findex gnus-summary-create-article +Create an empty article in the current mail newsgroups +(@code{gnus-summary-create-article}). You will be prompted for a +@code{From} header and a @code{Subject} header. + @item B r @kindex B r (Summary) @findex gnus-summary-respool-article @@ -9330,7 +9437,7 @@ Respool the mail article (@code{gnus-summary-respool-article}). @code{gnus-summary-respool-default-method} will be used as the default select method when respooling. This variable is @code{nil} by default, which means that the current group select method will be used instead. -Marks will be preserved if @var{gnus-preserve-marks} is non-@code{nil} +Marks will be preserved if @code{gnus-preserve-marks} is non-@code{nil} (which is the default). @item B w @@ -9339,9 +9446,10 @@ Marks will be preserved if @var{gnus-preserve-marks} is non-@code{nil} @kindex e (Summary) @findex gnus-summary-edit-article @kindex C-c C-c (Article) +@findex gnus-summary-edit-article-done Edit the current article (@code{gnus-summary-edit-article}). To finish editing and make the changes permanent, type @kbd{C-c C-c} -(@kbd{gnus-summary-edit-article-done}). If you give a prefix to the +(@code{gnus-summary-edit-article-done}). If you give a prefix to the @kbd{C-c C-c} command, Gnus won't re-highlight the article. @item B q @@ -9371,6 +9479,14 @@ it didn't find the article, it may have been posted anyway---mail propagation is much faster than news propagation, and the news copy may just not have arrived yet. +@item K E +@kindex K E (Summary) +@findex gnus-article-encrypt-body +@vindex gnus-article-encrypt-protocol +Encrypt the body of an article (@code{gnus-article-encrypt-body}). +The body is encrypted with the encryption protocol specified by the +variable @code{gnus-article-encrypt-protocol}. + @end table @vindex gnus-move-split-methods @@ -9879,8 +9995,8 @@ to you to figure out, I think. @section Security Gnus is able to verify signed messages or decrypt encrypted messages. -The formats that are supported are PGP, PGP/MIME and S/MIME, however -you need some external programs to get things to work: +The formats that are supported are PGP, @sc{pgp/mime} and @sc{s/mime}, +however you need some external programs to get things to work: @enumerate @item @@ -9888,7 +10004,7 @@ To handle PGP messages, you have to install mailcrypt or gpg.el as well as a OpenPGP implementation (such as GnuPG). @item -To handle S/MIME message, you need to install OpenSSL. OpenSSL 0.9.6 +To handle @sc{s/mime} message, you need to install OpenSSL. OpenSSL 0.9.6 or newer is recommended. @end enumerate @@ -9914,9 +10030,12 @@ protocols. Otherwise, ask user. @node Mailing List @section Mailing List +@kindex A M (summary) +@findex gnus-mailing-list-insinuate Gnus understands some mailing list fields of RFC 2369. To enable it, either add a `to-list' group parameter (@pxref{Group Parameters}), -possibly using @kbd{A M} in the summary buffer, or say: +possibly using @kbd{A M} (@code{gnus-mailing-list-insinuate}) in the +summary buffer, or say: @lisp (add-hook 'gnus-summary-mode-hook 'turn-on-gnus-mailing-list-mode) @@ -10086,7 +10205,7 @@ Remove the @code{To} header if it is very long. Remove all @code{To} headers if there are more than one. @end table -To include these three elements, you could say something like; +To include these three elements, you could say something like: @lisp (setq gnus-boring-article-headers @@ -10126,7 +10245,10 @@ The following commands are available when you have placed point over a @kindex RET (Article) @itemx BUTTON-2 (Article) Toggle displaying of the @sc{mime} object -(@code{gnus-article-press-button}). +(@code{gnus-article-press-button}). If builtin viewers can not display +the object, Gnus resorts to external viewers in the @file{mailcap} +files. If a viewer has the @samp{copiousoutput} specification, the +object is displayed inline. @findex gnus-mime-view-part @item M-RET (Article) @@ -10186,18 +10308,18 @@ do semi-manual charset stuff (see @code{gnus-summary-show-article-charset-alist} in @pxref{Paging the Article}). -@findex gnus-mime-internalize-part +@findex gnus-mime-view-part-internally @item E (Article) @kindex E (Article) View the @sc{mime} object with an internal viewer. If no internal viewer is available, use an external viewer -(@code{gnus-mime-internalize-part}). +(@code{gnus-mime-view-part-internally}). -@findex gnus-mime-externalize-part +@findex gnus-mime-view-part-externally @item e (Article) @kindex e (Article) View the @sc{mime} object with an external viewer. -(@code{gnus-mime-externalize-part}). +(@code{gnus-mime-view-part-externally}). @findex gnus-mime-pipe-part @item | (Article) @@ -10213,8 +10335,8 @@ Interactively run an action on the @sc{mime} object @end table Gnus will display some @sc{mime} objects automatically. The way Gnus -determines which parts to do this with is described in the Emacs MIME -manual. +determines which parts to do this with is described in the Emacs +@sc{mime} manual. It might be best to just use the toggling functions from the article buffer to avoid getting nasty surprises. (For instance, you enter the @@ -10316,6 +10438,7 @@ possible but those listed are probably sufficient for most people. @item gnus-treat-strip-pem (t, last, integer) @item gnus-treat-strip-pgp (t, last, integer) @item gnus-treat-strip-trailing-blank-lines (t, last, integer) +@item gnus-treat-unsplit-urls (t, integer) @xref{Article Washing}. @@ -10373,7 +10496,9 @@ is controlled by @code{gnus-body-boundary-delimiter}. @item gnus-treat-unfold-headers (head) @item gnus-treat-fold-headers (head) @item gnus-treat-fold-newsgroups (head) +@item gnus-treat-leading-whitespace (head) +@xref{Article Header}. @end table @@ -10578,7 +10703,7 @@ on your setup (@pxref{Posting Server}). @menu * Mail:: Mailing and replying. -* Posting Server:: What server should you post via? +* Posting Server:: What server should you post and mail via? * Mail and Post:: Mailing and posting at the same time. * Archived Messages:: Where Gnus stores the messages you've sent. * Posting Styles:: An easier way to specify who you are. @@ -10618,15 +10743,18 @@ When you press those magical @kbd{C-c C-c} keys to ship off your latest Thank you for asking. I hate you. -@vindex gnus-post-method +It can be quite complicated. -It can be quite complicated. Normally, Gnus will post using the same -select method as you're reading from (which might be convenient if -you're reading lots of groups from different private servers). -However. If the server you're reading from doesn't allow posting, -just reading, you probably want to use some other server to post your -(extremely intelligent and fabulously interesting) articles. You can -then set the @code{gnus-post-method} to some other method: +@vindex gnus-post-method +When posting news, Message usually invokes @code{message-send-news} +(@pxref{News Variables, , News Variables, message, Message Manual}). +Normally, Gnus will post using the same select method as you're +reading from (which might be convenient if you're reading lots of +groups from different private servers). However. If the server +you're reading from doesn't allow posting, just reading, you probably +want to use some other server to post your (extremely intelligent and +fabulously interesting) articles. You can then set the +@code{gnus-post-method} to some other method: @lisp (setq gnus-post-method '(nnspool "")) @@ -10647,6 +10775,23 @@ for posting. Finally, if you want to always post using the native select method, you can set this variable to @code{native}. +When sending mail, Message invokes @code{message-send-mail-function}. +The default function, @code{message-send-mail-with-sendmail}, pipes +your article to the @code{sendmail} binary for further queuing and +sending. When your local system is not configured for sending mail +using @code{sendmail}, and you have access to a remote @sc{smtp} +server, you can set @code{message-send-mail-function} to +@code{smtpmail-send-it} and make sure to setup the @code{smtpmail} +package correctly. An example: + +@lisp +(setq message-send-mail-function 'smtpmail-send-it + smtpmail-default-smtp-server "YOUR SMTP HOST") +@end lisp + +Other possible choises for @code{message-send-mail-function} includes +@code{message-send-mail-with-mh}, @code{message-send-mail-with-qmail}, +and @code{feedmail-send-it}. @node Mail and Post @section Mail and Post @@ -10709,6 +10854,10 @@ store the messages. If you want to disable this completely, the @code{gnus-message-archive-group} variable should be @code{nil}, which is the default. +For archiving interesting messages in a group you read, see the +@kbd{B c} (@code{gnus-summary-copy-article}) command (@pxref{Mail +Group Commands}). + @vindex gnus-message-archive-method @code{gnus-message-archive-method} says what virtual server Gnus is to use to store sent messages. The default is: @@ -10844,6 +10993,14 @@ but the latter is the preferred method. @vindex gnus-gcc-mark-as-read If non-@code{nil}, automatically mark @code{Gcc} articles as read. +@item gnus-gcc-externalize-attachments +@vindex gnus-gcc-externalize-attachments +If @code{nil}, attach files as normal parts in Gcc copies; if a regexp +and matches the Gcc group name, attach files as external parts; if it is +@code{all}, attach local files as external parts; if it is other +non-@code{nil}, the behavior is the same as @code{all}, but it may be +changed in the future. + @end table @@ -10887,30 +11044,36 @@ signature and the @samp{What me?} @code{Organization} header. The first element in each style is called the @code{match}. If it's a string, then Gnus will try to regexp match it against the group name. -If it is the symbol @code{header}, then Gnus will look for header (the -next element in the match) in the original article , and compare that to -the last regexp in the match. If it's a function symbol, that function -will be called with no arguments. If it's a variable symbol, then the -variable will be referenced. If it's a list, then that list will be -@code{eval}ed. In any case, if this returns a non-@code{nil} value, -then the style is said to @dfn{match}. - -Each style may contain a arbitrary amount of @dfn{attributes}. Each +If it is the form @code{(header MATCH REGEXP)}, then Gnus will look in +the original article for a header whose name is MATCH and compare that +REGEXP. MATCH and REGEXP are strings. If it's a function symbol, that +function will be called with no arguments. If it's a variable symbol, +then the variable will be referenced. If it's a list, then that list +will be @code{eval}ed. In any case, if this returns a non-@code{nil} +value, then the style is said to @dfn{match}. + +Each style may contain an arbitrary amount of @dfn{attributes}. Each attribute consists of a @code{(@var{name} @var{value})} pair. The attribute name can be one of @code{signature}, @code{signature-file}, -@code{organization}, @code{address}, @code{name} or @code{body}. The -attribute name can also be a string. In that case, this will be used as -a header name, and the value will be inserted in the headers of the -article; if the value is @code{nil}, the header name will be removed. -If the attribute name is @code{eval}, the form is evaluated, and the -result is thrown away. +@code{x-face-file}, @code{address} (overriding +@code{user-mail-address}), @code{name} (overriding +@code{(user-full-name)}) or @code{body}. The attribute name can also +be a string or a symbol. In that case, this will be used as a header +name, and the value will be inserted in the headers of the article; if +the value is @code{nil}, the header name will be removed. If the +attribute name is @code{eval}, the form is evaluated, and the result +is thrown away. The attribute value can be a string (used verbatim), a function with zero arguments (the return value will be used), a variable (its value will be used) or a list (it will be @code{eval}ed and the return value will be used). The functions and sexps are called/@code{eval}ed in the message buffer that is being set up. The headers of the current article -are available through the @code{message-reply-headers} variable. +are available through the @code{message-reply-headers} variable, which +is a vector of the following headers: number subject from date id +references chars lines xref extra. + +@vindex message-reply-headers If you wish to check whether the message you are about to compose is meant to be a news article or a mail message, you can check the values @@ -10930,13 +11093,16 @@ So here's a new example: (organization "People's Front Against MWM")) ("^rec.humor" (signature my-funny-signature-randomizer)) - ((equal (system-name) "gnarly") + ((equal (system-name) "gnarly") ;; A form (signature my-quote-randomizer)) - ((message-news-p) + (message-news-p ;; A function symbol (signature my-news-signature)) - (header "to" "larsi.*org" - (Organization "Somewhere, Inc.")) - ((posting-from-work-p) + (window-system ;; A value symbol + ("X-Window-System" (format "%s" window-system))) + ;; If I'm replying to Larsi, set the Organization header. + ((header "to" "larsi.*org") + (Organization "Somewhere, Inc.")) + ((posting-from-work-p) ;; A user defined function (signature-file "~/.work-signature") (address "user@@bar.foo") (body "You are fired.\n\nSincerely, your boss.") @@ -11052,17 +11218,17 @@ typically enter that group and send all the articles off. @cindex using smime Gnus can digitally sign and encrypt your messages, using vanilla PGP -format or PGP/MIME or S/MIME. For decoding such messages, see the -@code{mm-verify-option} and @code{mm-decrypt-option} options +format or @sc{pgp/mime} or @sc{s/mime}. For decoding such messages, +see the @code{mm-verify-option} and @code{mm-decrypt-option} options (@pxref{Security}). For PGP, Gnus supports two external libraries, @sc{gpg.el} and -@sc{Mailcrypt}, you need to install at least one of them. The S/MIME -support in Gnus requires the external program OpenSSL. +@sc{Mailcrypt}, you need to install at least one of them. The +@sc{s/mime} support in Gnus requires the external program OpenSSL. -Instructing MML to perform security operations on a MIME part is done -using the @code{C-c C-m s} key map for signing and the @code{C-c C-m -c} key map for encryption, as follows. +Instructing MML to perform security operations on a @sc{mime} part is +done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c +C-m c} key map for encryption, as follows. @table @kbd @@ -11070,37 +11236,42 @@ c} key map for encryption, as follows. @kindex C-c C-m s s @findex mml-secure-sign-smime -Digitally sign current MIME part using S/MIME. +Digitally sign current @sc{mime} part using @sc{s/mime}. @item C-c C-m s o @kindex C-c C-m s o @findex mml-secure-sign-pgp -Digitally sign current MIME part using PGP. +Digitally sign current @sc{mime} part using PGP. @item C-c C-m s p @kindex C-c C-m s p @findex mml-secure-sign-pgp -Digitally sign current MIME part using PGP/MIME. +Digitally sign current @sc{mime} part using @sc{pgp/mime}. @item C-c C-m c s @kindex C-c C-m c s @findex mml-secure-encrypt-smime -Digitally encrypt current MIME part using S/MIME. +Digitally encrypt current @sc{mime} part using @sc{s/mime}. @item C-c C-m c o @kindex C-c C-m c o @findex mml-secure-encrypt-pgp -Digitally encrypt current MIME part using PGP. +Digitally encrypt current @sc{mime} part using PGP. @item C-c C-m c p @kindex C-c C-m c p @findex mml-secure-encrypt-pgpmime -Digitally encrypt current MIME part using PGP/MIME. +Digitally encrypt current @sc{mime} part using @sc{pgp/mime}. + +@item C-c C-m C-n +@kindex C-c C-m C-n +@findex mml-unsecure-message +Remove security related MML tags from message. @end table @@ -11522,6 +11693,11 @@ Close the connections to all servers in the buffer Remove all marks to whether Gnus was denied connection from any servers (@code{gnus-server-remove-denials}). +@item L +@kindex L (Server) +@findex gnus-server-offline-server +Set server status to offline (@code{gnus-server-offline-server}). + @end table @@ -11541,7 +11717,7 @@ or it can read from a local spool. @node NNTP -@subsection @sc{nntp} +@subsection NNTP @cindex nntp Subscribing to a foreign group from an @sc{nntp} server is rather easy. @@ -12093,7 +12269,7 @@ mail, is that the transport mechanism has very little to do with how they want to treat a message. Many people subscribe to several mailing lists. These are transported -via SMTP, and are therefore mail. But we might go for weeks without +via @sc{smtp}, and are therefore mail. But we might go for weeks without answering, or even reading these messages very carefully. We may not need to save them because if we should need to read one again, they are archived somewhere else. @@ -12240,6 +12416,11 @@ where re-spooling messages would put the messages, you can use @code{gnus-summary-respool-trace} and related commands (@pxref{Mail Group Commands}). +@vindex nnmail-split-header-length-limit +Header lines longer than the value of +@code{nnmail-split-header-length-limit} are excluded from the split +function. + Gnus gives you all the opportunity you could possibly want for shooting yourself in the foot. Let's say you create a group that will contain all the mail you get from your boss. And then you accidentally @@ -12593,13 +12774,13 @@ UNDELETED}, is probably the best choice for most people, but if you sometimes peek in your mailbox with a @sc{imap} client and mark some articles as read (or; SEEN) you might want to set this to @samp{nil}. Then all articles in the mailbox is fetched, no matter what. For a -complete list of predicates, see RFC 2060 §6.4.4. +complete list of predicates, see RFC 2060 section 6.4.4. @item :fetchflag How to flag fetched articles on the server, the default @samp{\Deleted} will mark them as deleted, an alternative would be @samp{\Seen} which would simply mark them as read. These are the two most likely choices, -but more flags are defined in RFC 2060 §2.3.2. +but more flags are defined in RFC 2060 section 2.3.2. @item :dontexpunge If non-nil, don't remove all articles marked as deleted in the mailbox @@ -12616,10 +12797,11 @@ An example @sc{imap} mail source: @end lisp @item webmail -Get mail from a webmail server, such as www.hotmail.com, -webmail.netscape.com, www.netaddress.com, www.my-deja.com. +Get mail from a webmail server, such as @uref{www.hotmail.com}, +@uref{webmail.netscape.com}, @uref{www.netaddress.com}, +@uref{www.my-deja.com}. -NOTE: Now mail.yahoo.com provides POP3 service, so @sc{pop} mail source +NOTE: Now @uref{mail.yahoo.com} provides POP3 service, so @sc{pop} mail source is suggested. NOTE: Webmail largely depends cookies. A "one-line-cookie" patch is @@ -13120,7 +13302,7 @@ may use it for only some of them, by using @code{nnmail-split-fancy} splits like this: @lisp -(: gnus-mlsplt-fancy GROUPS NO-CROSSPOST CATCH-ALL) +(: gnus-group-split-fancy GROUPS NO-CROSSPOST CATCH-ALL) @end lisp @var{groups} may be a regular expression or a list of group names whose @@ -13684,10 +13866,11 @@ to trudge through a big mbox file just to read your new mail. @code{nnml} is probably the slowest back end when it comes to article splitting. It has to create lots of files, and it also generates -@sc{nov} databases for the incoming mails. This makes it the fastest -back end when it comes to reading mail. +@sc{nov} databases for the incoming mails. This makes it possibly the +fastest back end when it comes to reading mail. @cindex self contained nnml servers +@cindex marks When the marks file is used (which it is by default), @code{nnml} servers have the property that you may backup them using @code{tar} or similar, and later be able to restore them into Gnus (by adding the @@ -13746,7 +13929,12 @@ default is @code{nil}. @item nnml-marks-file-name @vindex nnml-marks-file-name -The name of the @sc{marks} files. The default is @file{.marks}. +The name of the @dfn{marks} files. The default is @file{.marks}. + +@item nnml-use-compressed-files +@vindex nnml-use-compressed-files +If non-@code{nil}, @code{nnml} will allow using compressed message +files. @end table @@ -13807,6 +13995,7 @@ will add extra headers to keep track of article numbers and arrival dates. @cindex self contained nnfolder servers +@cindex marks When the marks file is used (which it is by default), @code{nnfolder} servers have the property that you may backup them using @code{tar} or similar, and later be able to restore them into Gnus (by adding the @@ -14134,30 +14323,33 @@ leisure from your local disk. No more World Wide Wait for you. @cindex archiving mail @cindex backup of mail -Some of the back ends, notably nnml and nnfolder, now actually store -the article marks with each group. For these servers, archiving and -restoring a group while preserving marks is fairly simple. +Some of the back ends, notably @code{nnml}, @code{nnfolder}, and +@code{nnmaildir}, now actually store the article marks with each group. +For these servers, archiving and restoring a group while preserving +marks is fairly simple. (Preserving the group level and group parameters as well still -requires ritual dancing and sacrifices to the @code{.newsrc.eld} deity +requires ritual dancing and sacrifices to the @file{.newsrc.eld} deity though.) -To archive an entire @code{nnml} or @code{nnfolder} server, take a -recursive copy of the server directory. There is no need to shut down -Gnus, so archiving may be invoked by @code{cron} or similar. You -restore the data by restoring the directory tree, and adding a server -definition pointing to that directory in Gnus. The @ref{Article -Backlog}, @ref{Asynchronous Fetching} and other things might interfer -with overwriting data, so you may want to shut down Gnus before you -restore the data. - -It is also possible to archive individual @code{nnml} or -@code{nnfolder} groups, while preserving marks. For @code{nnml}, you -copy all files in the group's directory. For @code{nnfolder} you need -to copy both the base folder file itself (@code{FOO}, say), and the -marks file (@code{FOO.mrk} in this example). Restoring the group is -done with @kbd{G m} from the Group buffer. The last step makes Gnus -notice the new directory. +To archive an entire @code{nnml}, @code{nnfolder}, or @code{nnmaildir} +server, take a recursive copy of the server directory. There is no need +to shut down Gnus, so archiving may be invoked by @code{cron} or +similar. You restore the data by restoring the directory tree, and +adding a server definition pointing to that directory in Gnus. The +@ref{Article Backlog}, @ref{Asynchronous Fetching} and other things +might interfer with overwriting data, so you may want to shut down Gnus +before you restore the data. + +It is also possible to archive individual @code{nnml}, +@code{nnfolder}, or @code{nnmaildir} groups, while preserving marks. +For @code{nnml} or @code{nnmaildir}, you copy all files in the group's +directory. For @code{nnfolder} you need to copy both the base folder +file itself (@file{FOO}, say), and the marks file (@file{FOO.mrk} in +this example). Restoring the group is done with @kbd{G m} from the Group +buffer. The last step makes Gnus notice the new directory. +@code{nnmaildir} notices the new directory automatically, so @kbd{G m} +is unnecessary in that case. @node Web Searches @subsection Web Searches @@ -14493,7 +14685,7 @@ follow the link. @node IMAP -@section @sc{imap} +@section IMAP @cindex nnimap @cindex @sc{imap} @@ -14593,7 +14785,7 @@ Example server specification: @vindex nnimap-stream The type of stream used to connect to your server. By default, nnimap will detect and automatically use all of the below, with the exception -of SSL/TLS. (IMAP over SSL/TLS is being replaced by STARTTLS, which +of SSL/TLS. (@sc{imap} over SSL/TLS is being replaced by STARTTLS, which can be automatically detected, but it's not widely deployed yet.) Example server specification: @@ -14613,10 +14805,10 @@ Please note that the value of @code{nnimap-stream} is a symbol! @dfn{kerberos4:} Connect with Kerberos 4. Requires the @samp{imtest} program. @item @dfn{starttls:} Connect via the STARTTLS extension (similar to -SSL). Requires the external library @samp{starttls.el} and program +SSL). Requires the external library @samp{starttls.el} and program @samp{starttls}. @item -@dfn{ssl:} Connect through SSL. Requires OpenSSL (the program +@dfn{ssl:} Connect through SSL. Requires OpenSSL (the program @samp{openssl}) or SSLeay (@samp{s_client}) as well as the external library @samp{ssl.el}. @item @@ -14631,7 +14823,7 @@ using @samp{imtest} from Cyrus IMAPD < 2.0.14 (which includes version 1.5.x and 1.6.x) you need to frob @code{imap-process-connection-type} to make @code{imap.el} use a pty instead of a pipe when communicating with @samp{imtest}. You will then suffer from a line length -restrictions on IMAP commands, which might make Gnus seem to hang +restrictions on @sc{imap} commands, which might make Gnus seem to hang indefinitely if you have many articles in a mailbox. The variable @code{imap-kerberos4-program} contain parameters to pass to the imtest program. @@ -14723,11 +14915,11 @@ articles or not. @item nnimap-importantize-dormant @vindex nnimap-importantize-dormant -If non-nil, marks dormant articles as ticked (as well), for other IMAP -clients. Within Gnus, dormant articles will naturally still (only) be -marked as ticked. This is to make dormant articles stand out, just -like ticked articles, in other IMAP clients. (In other words, Gnus has -two ``Tick'' marks and IMAP has only one.) +If non-nil, marks dormant articles as ticked (as well), for other +@sc{imap} clients. Within Gnus, dormant articles will naturally still +(only) be marked as ticked. This is to make dormant articles stand +out, just like ticked articles, in other @sc{imap} clients. (In other +words, Gnus has two ``Tick'' marks and @sc{imap} has only one.) Probably the only reason for frobing this would be if you're trying enable per-user persistant dormant flags, using something like: @@ -14746,7 +14938,7 @@ as ticked for other users. @cindex Expunging @vindex nnimap-expunge-search-string -This variable contain the IMAP search command sent to server when +This variable contain the @sc{imap} search command sent to server when searching for articles eligible for expiring. The default is @code{"UID %s NOT SINCE %s"}, where the first @code{%s} is replaced by UID set and the second @code{%s} is replaced by a date. @@ -14775,7 +14967,7 @@ variable @code{nntp-authinfo-file} for exact syntax; also see @node Splitting in IMAP -@subsection Splitting in @sc{imap} +@subsection Splitting in IMAP @cindex splitting imap mail Splitting is something Gnus users has loved and used for years, and now @@ -14930,7 +15122,7 @@ Nnmail equivalent: @code{nnmail-split-fancy}. @end table @node Editing IMAP ACLs -@subsection Editing @sc{imap} ACLs +@subsection Editing IMAP ACLs @cindex editing imap acls @cindex Access Control Lists @cindex Editing @sc{imap} ACLs @@ -15126,13 +15318,46 @@ Forwarded articles. Netscape mail boxes. @item mime-parts -MIME multipart messages. +@sc{mime} multipart messages. @item standard-digest The standard (RFC 1153) digest format. +@item mime-digest +A @sc{mime} digest of messages. + +@item lanl-gov-announce +Announcement messages from LANL Gov Announce. + +@item rfc822-forward +A message forwarded according to RFC822. + +@item outlook +The Outlook mail box. + +@item oe-dbx +The Outlook Express dbx mail box. + +@item exim-bounce +A bounce message from the Exim MTA. + +@item forward +A message forwarded according to informal rules. + +@item rfc934 +An RFC934-forwarded message. + +@item mailman +A mailman digest. + +@item clari-briefs +A digest of Clarinet brief news items. + @item slack-digest Non-standard digest format---matches most things, but does it badly. + +@item mail-in-mail +The last resort. @end table You can also use the special ``file type'' @code{guess}, which means @@ -15163,8 +15388,8 @@ Virtual server variables: This should be one of @code{mbox}, @code{babyl}, @code{digest}, @code{news}, @code{rnews}, @code{mmdf}, @code{forward}, @code{rfc934}, @code{rfc822-forward}, @code{mime-parts}, @code{standard-digest}, -@code{slack-digest}, @code{clari-briefs}, @code{nsmail}, -@code{outlook}, @code{oe-dbx}, and @code{mailman} or @code{guess}. +@code{slack-digest}, @code{clari-briefs}, @code{nsmail}, @code{outlook}, +@code{oe-dbx}, @code{mailman}, and @code{mail-in-mail} or @code{guess}. @item nndoc-post-type @vindex nndoc-post-type @@ -15488,7 +15713,7 @@ Regular expression matching @sc{soup} reply packets in @node SOUP Groups -@subsubsection @sc{soup} Groups +@subsubsection SOUP Groups @cindex nnsoup @code{nnsoup} is the back end for reading @sc{soup} packets. It will @@ -15846,11 +16071,11 @@ that has full connection to the net. Go ahead. I'll still be waiting here. @item -Then, put the following magical incantation at the end of your -@file{.gnus.el} file: +Then, put the following magical incantation in your @file{.gnus.el} +file: @lisp -(gnus-agentize) +(setq gnus-agent t) @end lisp @end itemize @@ -16080,10 +16305,10 @@ with the predicate then defined as: or you could append your predicate to the predefined @code{gnus-category-predicate-alist} in your @file{~/.gnus.el} or -wherever. (Note: this would have to be at a point *after* -@code{gnus-agent} has been loaded via @code{(gnus-agentize)}) +wherever. @lisp +(require 'gnus-agent) (setq gnus-category-predicate-alist (append gnus-category-predicate-alist '((old . my-article-old-p)))) @@ -16496,11 +16721,15 @@ If you use the list form, the last element must always be the default method---it must always match all groups. @vindex gnus-agent-expire-all -if @code{gnus-agent-expire-all} is non-@code{nil}, this command will +If @code{gnus-agent-expire-all} is non-@code{nil}, this command will expire all articles---unread, read, ticked and dormant. If @code{nil} (which is the default), only read articles are eligible for expiry, and unread, ticked and dormant articles will be kept indefinitely. +@findex gnus-agent-regenerate +If you find that some articles eligible for expiry are never expired, +perhaps some Gnus Agent files are corrupted. There's a special +@code{gnus-agent-regenerate} command to fix possible problems. @node Agent and IMAP @subsection Agent and IMAP @@ -16600,7 +16829,7 @@ Hook run when after finishing fetching articles. @item gnus-agent-cache @vindex gnus-agent-cache -Variable to control whether use the locally stored NOV and articles when +Variable to control whether use the locally stored @sc{nov} and articles when plugged. @item gnus-agent-go-online @@ -16635,7 +16864,8 @@ setup, you may be able to use something like the following as your (setq gnus-secondary-select-methods '((nnml ""))) ;;; Make Gnus into an offline newsreader. -(gnus-agentize) +;;; (gnus-agentize) ; The obsolete setting. +(setq gnus-agent t) @end lisp That should be it, basically. Put that in your @file{~/.gnus.el} file, @@ -16780,6 +17010,11 @@ Display the score of the current article Display all score rules that have been used on the current article (@code{gnus-score-find-trace}). +@item V w +@kindex V w (Summary) +@findex gnus-score-find-favourite-words +List words used in scoring (@code{gnus-score-find-favourite-words}). + @item V R @kindex V R (Summary) @findex gnus-summary-rescore @@ -16876,6 +17111,10 @@ Score on the number of lines. @item i Score on the @code{Message-ID} header. +@item e +Score on an "extra" header, that is, one of those in gnus-extra-headers, +if your @sc{nntp} server tracks additional header data in overviews. + @item f Score on followups---this matches the author name, and adds scores to the followups to this author. (Using this key leads to the creation of @@ -16944,9 +17183,10 @@ Greater than number. @end table @item -The fourth and final key says whether this is a temporary (i.e., expiring) -score entry, or a permanent (i.e., non-expiring) score entry, or whether -it is to be done immediately, without adding to the score file. +The fourth and usually final key says whether this is a temporary (i.e., +expiring) score entry, or a permanent (i.e., non-expiring) score entry, +or whether it is to be done immediately, without adding to the score +file. @table @kbd @item t @@ -16959,6 +17199,11 @@ Permanent score entry. Immediately scoring. @end table +@item +If you are scoring on `e' (extra) headers, you will then be prompted for +the header name on which you wish to score. This must be a header named +in gnus-extra-headers, and @samp{TAB} completion is available. + @end enumerate So, let's say you want to increase the score on the current author with @@ -17276,6 +17521,18 @@ one-letter types are really just abbreviations for the @code{regexp}, @code{string}, @code{exact}, and @code{word} types, which you can use instead, if you feel like. +@item Extra +Just as for the standard string overview headers, if you are using +gnus-extra-headers, you can score on these headers' values. In this +case, there is a 5th element in the score entry, being the name of the +header to be scored. The following entry is useful in your +@file{all.SCORE} file in case of spam attacks from a single origin host, +if your @sc{nntp} server tracks NNTP-Posting-Host in overviews: + +@lisp +("111.222.333.444" -1000 nil s "NNTP-Posting-Host") +@end lisp + @item Lines, Chars These two headers use different match types: @code{<}, @code{>}, @code{=}, @code{>=} and @code{<=}. @@ -20404,7 +20661,7 @@ This says that all mail to this address is suspect, but if it has a header, it's probably ok. All the rest goes to the @samp{spam} group. (This idea probably comes from Tim Pierce.) -In addition, many mail spammers talk directly to your @code{smtp} server +In addition, many mail spammers talk directly to your @sc{smtp} server and do not include your email address explicitly in the @code{To} header. Why they do this is unknown---perhaps it's to thwart this thwarting scheme? In any case, this is trivial to deal with---you just @@ -20834,7 +21091,7 @@ look into implementing the changes when the draft is accepted as an RFC. @item MIME - RFC 2045-2049 etc @cindex MIME -All the various MIME RFCs are supported. +All the various @sc{mime} RFCs are supported. @item Disposition Notifications - RFC 2298 Message Mode is able to request notifications from the receiver. @@ -20844,25 +21101,25 @@ Message Mode is able to request notifications from the receiver. @cindex RFC 2440 RFC 1991 is the original PGP message specification, published as a Information RFC. RFC 2440 was the follow-up, now called Open PGP, and -put on the Standards Track. Both document a non-MIME aware PGP +put on the Standards Track. Both document a non-@sc{mime} aware PGP format. Gnus supports both encoding (signing and encryption) and decoding (verification and decryption). @item PGP/MIME - RFC 2015/3156 RFC 2015 (superceded by 3156 which references RFC 2440 instead of RFC -1991) describes the MIME-wrapping around the RF 1991/2440 format. +1991) describes the @sc{mime}-wrapping around the RF 1991/2440 format. Gnus supports both encoding and decoding. @item S/MIME - RFC 2633 -RFC 2633 describes the S/MIME format. +RFC 2633 describes the @sc{s/mime} format. @item IMAP - RFC 1730/2060, RFC 2195, RFC 2086, RFC 2359, RFC 2595, RFC 1731 -RFC 1730 is IMAP version 4, updated somewhat by RFC 2060 (IMAP 4 -revision 1). RFC 2195 describes CRAM-MD5 authentication for IMAP. RFC -2086 describes access control lists (ACLs) for IMAP. RFC 2359 -describes a IMAP protocol enhancement. RFC 2595 describes the proper -TLS integration (STARTTLS) with IMAP. RFC 1731 describes the -GSSAPI/Kerberos4 mechanisms for IMAP. +RFC 1730 is @sc{imap} version 4, updated somewhat by RFC 2060 (@sc{imap} 4 +revision 1). RFC 2195 describes CRAM-MD5 authentication for @sc{imap}. RFC +2086 describes access control lists (ACLs) for @sc{imap}. RFC 2359 +describes a @sc{imap} protocol enhancement. RFC 2595 describes the proper +TLS integration (STARTTLS) with @sc{imap}. RFC 1731 describes the +GSSAPI/Kerberos4 mechanisms for @sc{imap}. @end table @@ -21950,7 +22207,7 @@ More information is available in the info doc at Select Methods -> Getting Mail -> Mail Sources @item -Gnus is now a MIME-capable reader. This affects many parts of +Gnus is now a @sc{mime}-capable reader. This affects many parts of Gnus, and adds a slew of new commands. See the manual for details. @item @@ -21963,7 +22220,7 @@ called to position point. @item The user can now decide which extra headers should be included in -summary buffers and NOV files. +summary buffers and @sc{nov} files. @item @code{gnus-article-display-hook} has been removed. Instead, a number @@ -21979,7 +22236,7 @@ New web-based back ends have been added: @code{nnslashdot}, again, to keep up with ever-changing layouts. @item -Gnus can now read IMAP mail via @code{nnimap}. +Gnus can now read @sc{imap} mail via @code{nnimap}. @end itemize @@ -22276,7 +22533,7 @@ for some quite common situations. @node Slow/Expensive Connection -@subsection Slow/Expensive @sc{nntp} Connection +@subsection Slow/Expensive NNTP Connection If you run Emacs on a machine locally, and get your news from a machine over some very thin strings, you want to cut down on the amount of data @@ -22336,21 +22593,6 @@ want to read them anyway. If this is non-@code{nil}, all threads in the summary buffer will be hidden initially. -This can also be a predicate specifier (@pxref{Predicate Specifiers}). -Avaliable predicates are @code{gnus-article-unread-p} and -@code{gnus-article-unseen-p}). - -Here's an example: - -@lisp -(setq gnus-thread-hide-subtree - '(or gnus-article-unread-p - gnus-article-unseen-p)) -@end lisp - -(It's a pretty nonsensical example, since all unseen articles are also -unread, but you get my drift.) - @item gnus-updated-mode-lines If this is @code{nil}, Gnus will not put information in the buffer mode @@ -22731,10 +22973,10 @@ In the examples and definitions I will refer to the imaginary back end sequences (lists) of article numbers, and most back ends do not support retrieval of @code{Message-ID}s. But they should try for both. -The result data should either be HEADs or NOV lines, and the result +The result data should either be HEADs or @sc{nov} lines, and the result value should either be @code{headers} or @code{nov} to reflect this. This might later be expanded to @code{various}, which will be a mixture -of HEADs and NOV lines, but this is currently not supported by Gnus. +of HEADs and @sc{nov} lines, but this is currently not supported by Gnus. If @var{fetch-old} is non-@code{nil} it says to try fetching "extra headers", in some meaning of the word. This is generally done by @@ -22880,7 +23122,9 @@ number of articles may be less than one might think while just considering the highest and lowest article numbers, but some articles may have been canceled. Gnus just discards the total-number, so whether one should take the bother to generate it properly (if that is a -problem) is left as an exercise to the reader. +problem) is left as an exercise to the reader. If the group contains no +articles, the lowest article number should be reported as 1 and the +highest as 0. @example group-status = [ error / info ] eol @@ -22910,7 +23154,9 @@ ifi.discussion 3324 3300 n @end example On each line we have a group name, then the highest article number in -that group, the lowest article number, and finally a flag. +that group, the lowest article number, and finally a flag. If the group +contains no articles, the lowest article number should be reported as 1 +and the highest as 0. @example active-file = *active-line @@ -23088,9 +23334,9 @@ It is okay for this function to return `too many' groups; some back ends might find it cheaper to return the full list of groups, rather than just the new groups. But don't do this for back ends with many groups. Normally, if the user creates the groups herself, there won't be too -many groups, so nnml and the like are probably safe. But for back ends -like nntp, where the groups have been created by the server, it is quite -likely that there can be many groups. +many groups, so @code{nnml} and the like are probably safe. But for +back ends like @code{nntp}, where the groups have been created by the +server, it is quite likely that there can be many groups. @item (nnchoke-request-create-group GROUP &optional SERVER) @@ -23425,9 +23671,9 @@ The user should be prompted for an address when doing commands like @subsubsection Mail-like Back Ends One of the things that separate the mail back ends from the rest of the -back ends is the heavy dependence by the mail back ends on common -functions in @file{nnmail.el}. For instance, here's the definition of -@code{nnml-request-scan}: +back ends is the heavy dependence by most of the mail back ends on +common functions in @file{nnmail.el}. For instance, here's the +definition of @code{nnml-request-scan}: @lisp (deffoo nnml-request-scan (&optional group server) diff --git a/texi/gnuslogo-booklet.eps b/texi/gnuslogo-booklet.eps new file mode 100644 index 0000000..95408ba --- /dev/null +++ b/texi/gnuslogo-booklet.eps @@ -0,0 +1,1055 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: gnuslogo1.ps +%%Creator: XV Version 3.00 Rev: 3/30/93 - by John Bradley +%%BoundingBox: 0 0 493 505 +%%Pages: 1 +%%DocumentFonts: +%%EndComments +%%EndProlog + +%%Page: 1 1 + +% remember original state +/origstate save def + +% build a temporary dictionary +20 dict begin + +% define string to hold a scanline's worth of data +/pix 62 string def + +% lower left corner +0 0 translate + +% size of image (on paper, in 1/72inch coords) +493.0 505.0 scale + +% dimensions of data +493 505 1 + +% mapping matrix +[493 0 0 -505 0 505] + +{currentfile pix readhexstring pop} +image +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff01fffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff8003ffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff0000ffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff8000007ffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff0000003ffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffe0000000ffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffff000000003fff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffff000000000fff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffc0000000007ff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffff80000000003ff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffff00000000001ff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffe00000000000ff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffc00000000000ff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffff8000000000007f8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffff0000000000003f8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffff0000000000003f8 +fffffffffffffffffffffffffff800ffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffe0000000000001f8 +fffffffffffffffffffffffffff0001fffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffc0000000000000f8 +ffffffffffffffffffffffffffc00007ffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffc0000000000000f8 +ffffffffffffffffffffffffff000001ffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffff8000000000000078 +fffffffffffffffffffffffffe0000003ffffffffffff0001fffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffff0000000000000038 +fffffffffffffffffffffffffc0000001fffffffffffe00007ffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffe0000000000000038 +fffffffffffffffffffffffff800000007ffffffffff800001ffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffe0000000000000038 +fffffffffffffffffffffffff000000003fffffffffe0000003fffffffffffffffffffff +fffffffffffffffffffffffffffffffffffc0000000000000018 +ffffffffffffffffffffffffe000000001fffffffff80000000fffffffffffffffffffff +fffffffffffffffffffffffffffffffffffc0000000000000018 +ffffffffffffffffffffffffc000000000ffffffffe000000003ffffffffffffffffffff +fffffffffffffffffffffffffffffffffff80000000000000018 +ffffffffffffffffffffffff80000000007fffffff8000000000ffffffffffffffffffff +fffffffffffffffffffffffffffffffffff80000000000000008 +ffffffffffffffffffffffff00000000003fffffff00000000007fffffffffffffffffff +fffffffffffffffffffffffffffffffffff00000000000000008 +fffffffffffffffffffffffe00000000001ffffffe00000000001fffffffffffffffffff +fffffffffffffffffffffffffffffffffff00000000000000008 +fffffffffffffffffffffffc00000000000ffffff8000000000007ffffffffffffffffff +ffffffffffffffffffffffffffffffffffe00000000000000008 +fffffffffffffffffffffff8000000000007fffff0000000000007ffffffffffffffffff +ffffffffffffffffffffffffffffffffffe00000000000000008 +fffffffffffffffffffffff0000000000001ffffe0000000000000ffffffffffffffffff +ffffffffffffffffffffffffffffffffffc00000000000000000 +ffffffffffffffffffffffe0000000000000ffffc00000000000007fffffffffffffffff +ffffffffffffffffffffffffffffffffffc00000000000000000 +ffffffffffffffffffffffc00000000000007fff800000000000001fffffffffffffffff +ffffffffffffffffffffffffffffffffff800000000000000000 +ffffffffffffffffffffff800000000000003fff000000000000000fffffffffffffffff +ffffffffffffffffffffffffffffffffff800000000000000000 +ffffffffffffffffffffff000000000000003fff0000000000000007ffffffffffffffff +ffffffffffffffffffffffffffffffffff000040000000000000 +fffffffffffffffffffffe000000000000000ffe0000000000000001ffffffffffffffff +ffffffffffffffffffffffffffffffffff0007ffc00000000000 +fffffffffffffffffffffc000000000000000ffc0000000000000000ffffffffffffffff +fffffffffffffffffffffffffffffffffe001ffffc0000000000 +fffffffffffffffffffffc0000000000000007fc00000000000000007fffffffffffffff +fffffffffffffffffffffffffffffffffc003ffffe0000000000 +fffffffffffffffffffff80000000000000007f800000000000000003fffffffffffffff +fffffffffffffffffffffffffffffffffc007fffffc000000000 +fffffffffffffffffffff00000000000000001f000000000000000001fffffffffffffff +fffffffffffffffffffffffffffffffff800fffffff000000000 +ffffffffffffffffffffe00000000000000001f000000000000000000fffffffffffffff +fffffffffffffffffffffffffffffffff801fffffff800000000 +ffffffffffffffffffffc00000000000000000e0000000000000000007ffffffffffffff +fffffffffffffffffffffffffffffffff003ffffffff00000000 +ffffffffffffffffffff800000000000000000c0000000000000000003ffffffffffffff +fffffffffffffffffffffffffffffffff007ffffffff00000000 +ffffffffffffffffffff00000000000000000000000000000000000000ffffffffffffff +ffffffffffffffffffffffffffffffffe00fffffffff80000000 +fffffffffffffffffffe00000000000000000000000000000000000000ffffffffffffff +ffffffffffffffffffffffffffffffffe01fffffffffc0000008 +fffffffffffffffffffc000000000000000000000000000000000000007fffffffffffff +ffffffffffffffffffffffffffffffffc03fffffffffc0000008 +fffffffffffffffffff8000000000000000000000000000000000000001fffffffffffff +ffffffffffffffffffffffffffffffffc07ffffffffff0000000 +fff9fffffffffffffff800000fe00000000000000000000000000000001fffffffffffff +ffffffffffffffffffffffffffffffff807ffffffffff0000000 +fff9fffffffffffffff000001ff80000000000000000000000000000000fffffffffffff +ffffffffffffffffffffffffffffffff80fffffffffff0000008 +fff0ffffffffffffffc000007ffc00000000000000000000000000000007ffffffffffff +ffffffffffffffffffffffffffffffff81fffffffffff8000008 +fff0ffffffffffffffc00000fffc00000000000000000000000000000003ffffffffffff +ffffffffffffffffffffffffffffffff01fffffffffff8000008 +ffe07fffffffffffff800001ffff00000000000000000000000000000001ffffffffffff +ffffffffffffffffffffffffffffffff03fffffffffffc000008 +ffe07fffffffffffff00000fffffc0000000000000000000000000000000ffffffffffff +fffffffffffffffffffffffffffffffe03fffffffffffc000008 +ffe03ffffffffffffc00001fffffe00000000000000000000000000000007fffffffffff +fffffffffffffffffffffffffffffffe07fffffffffffe000008 +ffe03ffffffffffff800003ffffff00000000000000000000000000000003fffffffffff +fffffffffffffffffffffffffffffffe07fffffffffffe000008 +ffc03ffffffffffff000007ffffff80000000000000f80000000000000003fffffffffff +fffffffffffffffffffffffffffffffe0ffffffffffffe000008 +ffc01fffffffffffe00001fffffffe000000000000fffe000000000000001fffffffffff +fffffffffffffffffffffffffffffffc0ffffffffffffe000008 +ffc00fffffffffffc00003ffffffff000000000001ffff800000000000000fffffffffff +fffffffffffffffffffffffffffffffc1fffffffffffff000008 +ff800fffffffffff800003ffffffff800000000007ffffc000000000000007ffffffffff +fffffffffffffffffffffffffffffffc3fffffffffffff000008 +ff8007fffffffffe00000fffffffffc0000000001ffffffc00000000000003ffffffffff +fffffffffffffffffffffffffffffff87fffffffffffff000008 +ff8007fffffffffc00000fffffffffe0000000005ffffffe00000000000001ffffffffff +fffffffffffffffffffffffffffffff87fffffffffffff000008 +ff8003fffffffff800001ffffffffff000000000ffffffffc0000000000000ffffffffff +fffffffffffffffffffffffffffffff87fffffffffffff000008 +ff0001fffffffff000003ffffffffffc00000007fffffffff80000000000007fffffffff +fffffffffffffffffffffffffffffff8ffffffffffffff000008 +ff0000ffffffffe000003ffffffffffc0000000ffffffffffc0000000000007fffffffff +fffffffffffffffffffffffffffffffcffffffffffffff000008 +fe00007fffffff800000ffffffffffff0000001ffffffffffe0000000000001fffffffff +ffffffffffffffffffffffffffffe7fdffffffffffffff000008 +fe00007fffffff000001ffffffffffff8000003fffffffffff0000000000001fffffffff +ffffffffffffffffffffffffffffe7fdffffffffffffff000008 +fc00001ffffffc000003ffffffffffffc000007fffffffffffe0000000000007ffffffff +ffffffffffffffffffffffffffffc7ffffffffffffffff000008 +fc00001ffffff0000003ffffffffffffe00000fffffffffffff0000000000007ffffffff +fffffffffeffffffffffffffffff87ffffffffffffffff000008 +f800000fffffe0000007fffffffffffff00000fffffffffffff8000000000003ffffffff +fffffffffcffffffffffffffffff87ffffffffffffffff000008 +f8000003ffff0000000ffffffffffffff80001fffffffffffffc000000000001ffffffff +fffffffff8ffffffffffffffffff07ffffffffffffffff000008 +f8000001fffe0000001ffffffffffffff80001ffffffffffffff000000000000ffffffff +fffffffff8fffffffffffffffffe0fffffffffffffffff000008 +f0000000fff00000003ffffffffffffffc0001ffffffffffffff8000000000007fffffff +fffffffff0fffffffffffffffffe0fffffffffffffffff000018 +e00000001a000000007ffffffffffffffe0003ffffffffffffffc000000000003fffffff +fffffffff0fffffffffffffffffc0fffffffffffffffff000018 +e000000000000000007fffffffffffffff0003ffffffffffffffc000000000003fffffff +ffffffffe0fffffffffffffffffc1fffffffffffffffff000018 +c00000000000000000ffffffffffffffff0007ffffffffffffffe000000000001fffffff +ffffffffe0fffffffffffffffff81fffffffffffffffff000018 +c00000000000000001ffffffffffffffff0007fffffffffffffff0000000000007ffffff +ffffffffc0fffffffffffffffff83fffffffffffffffff000018 +800000000000000007ffffffffffffffff800ffffffffffffffffc000000000003ffffff +ffffffff01fffffffffffffffff03fffffffffffffffff000038 +800000000000000007ffffffffffffffff800ffffffffffffffffe000000000001ffffff +ffffffff01fffffffffffffffff03fffffffffffffffff800038 +00000000000000000fffffffffffffffffc00fffffffffffffffff000000000000ffffff +fffffffe03ffffffffffffffffe07fffffffffffffffff800038 +00000000000000001fffffffffffffffffc01fffffffffffffffff8000000000007fffff +fffffffc03ffffffffffffffffe07fffffffffffffffff800038 +00000000000000003fffffffffffffffffe03fffffffffffffffffc000000000003fffff +fffffff803ffffffffffffffffc07fffffffffffffffff800038 +00000000000000007ffffffffffffffffff03fffffffffffffffffe000000000000fffff +fffffff007ffffffffffffffffc0ffffffffffffffffff800038 +0000000000000000fffffffffffffffffff07ffffffffffffffffff000000000000fffff +fffffff007ffffffffffffffff80ffffffffffffffffff800078 +0000000000000003ffffffffffffffff8ff87ffffffffffffffffff8000000000001ffff +ffffffc00fffffffffffffffff81ffffffffffffffffff800078 +8000000000000007ffffffffffffffff0ff8fffffffffffffffffffc000000000000ffff +ffffffc00fffffffffffffffff01ffffffffffffffffff8000f8 +8000000000000007fffffffffffffffe0ffffffffffffffffffffffe0000000000007fff +ffffff801fffffffffffffffff03ffffffffffffffffff8000f8 +c00000000000001ffffffffffffffffc0fffffffffffffffffffffff0000000000001fff +fffffe001ffffffffffffffffe07ffffffffffffffffff8000f8 +e00000000000007ffffffffffffffff83fffffffffffffffffffffffc0000000000007ff +fffff8003ffffffffffffffffc07ffffffffffffffffff8000f8 +f00000000000007ffffffffffffffff03fffffffffffffffffffffffc0000000000001ff +fffff0003ffffffffffffffff80fffffffffffffffffff8000f8 +f0000000000000fffffffffffffffff07fffffffffffffffffffffffe0000000000000ff +ffffe0003ffffffffffffffff00fffffffffffffffffff8001f8 +f8000000000003ffffffffffffffffe07ffffffffffffffffffffffff00000000000000f +ffff00007fffffffffffffffe01fffffffffffffffffff0001f8 +fc000000000007ffffffffffffffffc07ffffffffffffffffffffffff800000000000007 +fffc00007fffffffffffffffc01fffffffffffffffffff0001f8 +fc000000000007ffffffffffffffffc0fffffffffffffffffffffffff800000000000000 +ffe000007ffffbffffffffff801fffffffffffffffffff0001f8 +fe00000000001fffffffffffffffff03fffffffffffffffffffffffffe00000000000000 +00000000fffff3ffffffffff003fffffffffffffffffff0001f8 +fe00000000003fffffffffffffffff03ffffffffffffffffffffffffff00000000000000 +00000001fffff1fffffffffe003fffffffffffffffffff0003f8 +ff00000000007ffffffffffffffffe03ffffffffffffffffffffffffff00000000000000 +00000001ffffe1fffffffffc007fffffffffffffffffff0003f8 +ff8000000001fffffffffffffffffc07ffffffffffffffffffffffffff80000000000000 +00000003ffffe0fffffffff0007fffffffffffffffffff0003f8 +ffc000000003fffffffffffffffffc0fffffffffffffffffffffffffffc0000000000000 +00000003ffffc0ffffffffe0007fffffffffffffffffff0003f8 +ffe00000000ffffffffffffffffff81fffffffffffffffffffffffffffe0000000000000 +00000007ffffc07fffffff8000ffffffffffffffffffff0003f8 +fff00000003ffffffffffffffffff01ffffffffffffffffffffffffffff0000000000000 +00000007ffff803fffffff0000fffffffffffffffffffe0007f8 +fff8000000ffffffffffffffffffe03ffffffffffffffffffffffffffff8000000000000 +00000007ffff801ffffffc0001fffffffffffffffffffe0007f8 +fffc000001ffffffffffffffffffe07ffffffffffffffffffffffffffffc000000000000 +0000000fffff000ffffff80003fffffffffffffffffffe0007f8 +fffe00000fffffffffffffffffffc07ffffffffffffffffffffffffffffc000000000000 +0000000fffff0007ffffe00003fffffffffffffffffffe0007f8 +ffff80007fffffffffffffffffff80fffffffffffffffffffffffffffffe000000000000 +0000001ffffe0001ffff800007fffffffffffffffffffe000ff8 +ffffe007ffffffffffffffffffff80ffffffffffffffffffffffffffffff000000000000 +0000001ffffe0000fffc000007fffffffffffffffffffe000ff8 +ffffffffffffffffffffffffffff01ffffffffffffffffffffffffffffff800000000000 +0000003ffffe0000000000000ffffffffffffffffffffe000ff8 +fffffffffffffffffffffffffffe03ffffffffffffffffffffffffffffffc00000000000 +0000003ffffc0000000000000ffffffffffffffffffffe000ff8 +fffffffffffffffffffffffffffe03ffffffffffffffffffffffffffffffe00000000000 +0000007ffff80000000000001ffffffffffffffffffffe001ff8 +fffffffffffffffffffffffffffc07fffffffffffffffffffffffffffffff00000000000 +0000007ffff80000000000001ffffffffffffffffffffe001ff8 +fffffffffffffffffffffffffff807fffffffffffffffffffffffffffffff80000000000 +000000fffff80000000000003ffffffffffffffffffffc001ff8 +fffffffffffffffffffffffffff80ffffffffffffffffffffffffffffffffc0000000000 +000003fffff00000000000007ffffffffffffffffffffc001ff8 +fffffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffe0000000000 +000007ffffe00000000000007ffffffffffffffffffffe003ff8 +fffffffffffffffffffffffffff01fffffffffffffffffffffffffffffffff0000000000 +000007ffffe0000000000000fffffffffffffffffffffc003ff8 +ffffffffffffffffffffffffffc07fffffffffffffffffffffffffffffffff8000000000 +00001fffffc0000000000001fffffffffffffffffffffc003ff8 +ffffffffffffffffffffffffffc07fffffffffffffffffffffffffffffffffe000000000 +00001fffffc0000000000003fffffffffffffffffffffc003ff8 +ffffffffffffffffffffffffffc07ffffffffffffffffffffffffffffffffff000000000 +00003fffff80000000000003fffffffffffffffffffffc007ff8 +ffffffffffffffffffffffffff01fffffffffffffffffffffffffffffffffff800000000 +00007fffff80000000000007fffffffffffffffffffffc007ff8 +ffffffffffffffffffffffffff03fffffffffffffffffffffffffffffffffffc00000000 +0000ffffff0000000000000ffffffffffffffffffffffc007ff8 +fffffffffffffffffffffffffe03fffffffffffffffffffffffffffffffffffc00000000 +0001ffffff0000000000001ffffffffffffffffffffffc007ff8 +fffffffffffffffffffffffffc07ffffffffffffffffffffffffffffffffffff00000000 +0003fffffe0000000000001ffffffffffffffffffffff800fff8 +fffffffffffffffffffffffff80fffffffffffffffffffffffffffffffffffff80000000 +0007fffffe0000000000003ffffffffffffffffffffff800fff8 +fffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffffffff0000000 +001ffffffc0000000000007ffffffffffffffffffffff800fff8 +fffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffff8000000 +003ffffffc000000000000fffffffffffffffffffffff800fff8 +ffffffffffffffffffffffffe07ffffffffffffffffffffffffffffffffffffffe000000 +00fffffff8000000000003fffffffffffffffffffffff001fff8 +ffffffffffffffffffffffffe07fffffffffffffffffffffffffffffffffffffff800000 +03fffffff8000000000003fffffffffffffffffffffff001fff8 +ffffffffffffffffffffffffc0ffffffffffffffffffffffffffffffffffffffffc00000 +07fffffff0000000000007fffffffffffffffffffffff001fff8 +ffffffffffffffffffffffff80fffffffffffffffffffffffffffffffffffffffffc0000 +3ffffffff000000000000ffffffffffffffffffffffff003fff8 +ffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffffffffffffe03f +fffffffff000000000003ffffffffffffffffffffffff003fff8 +ffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffffffffffffffff +fffffffff800000000007ffffffffffffffffffffffff003fff8 +fffffffffffffffffffffffe03ffffffffffffffffffffffffffffffffffffffffffffff +fffffffff80000000000ffffffffffffffffffffffffe003fff8 +fffffffffffffffffffffffc07ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffc0000000003ffffffffffffffffffffffffe007fff8 +fffffffffffffffffffffffc0fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffe0000000007ffffffffffffffffffffffffe007fff8 +fffffffffffffffffffffff81fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffe000000000fffffffffffffffffffffffffe00ffff8 +fffffffffffffffffffffff01fffffffffffffffffffffffffffffffffffffffffffffff +ffffffffff000000001fffffffffffffffffffffffffe00ffff8 +ffffffffffffffffffffffe03ffffffffffffffffffffffffbffffffffffffffffffffff +ffffffffff800000007fffffffffffffffffffffffffc00ffff8 +ffffffffffffffffffffffe07ffffffffffffffffffdfffff1ffffffffffffffffffffff +ffffffffffc0000000ffffffffffffffffffffffffffc00ffff8 +ffffffffffffffffffffffe07ffffffffffffffffff9fffff07fffffffffffffffffffff +ffffffffffe0000001ffffffffffffffffffffffffffc00ffff8 +ffffffffffffffffffffffc0ffffffffffffffffffe3ffffe03fffffffffffffffffffff +fffffffffff800001fffffffffffffffffffffffffffc01ffff8 +ffffffffffffffffffffff81ffffffffffffffffffc7ffffc00fffffffffffffffffffff +fffffffffffe00007fffffffffffffffffffffffffffc01ffff8 +ffffffffffffffffffffff81ffffffffffffffffff87ffffc007ffffffffffffffffffff +ffffffffffff8003ffffffffffffffffffffffffffff801ffff8 +ffffffffffffffffffffff03ffffffffffffffffff0fffff8007ffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff803ffff8 +fffffffffffffffffffffe07fffffffffffffffffe0fffff8001ffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff803ffff8 +fffffffffffffffffffffe07fffffffffffffffffc1fffff0000ffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff803ffff8 +fffffffffffffffffffffc0ffffffffffffffffff83ffffe00007fffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff007ffff8 +fffffffffffffffffffff81fffffffffffffffffe03ffffe00007fffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff007ffff8 +fffffffffffffffffffff83fffffffffffffffffc07ffffc00003fffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff007ffff8 +fffffffffffffffffffff03fffffffffffffffff80fffff800001fffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffe00fffff8 +ffffffffffffffffffffe07fffffffffffffffff00fffff800000fffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffe00fffff8 +ffffffffffffffffffffe0fffffffffffffffffe01fffff0000007ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffe00fffff8 +ffffffffffffffffffffc0fffffffffffffffffc01ffffe0000003ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffe00fffff8 +ffffffffffffffffffff81fffffffffffffffff803ffffe0000003ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffe01fffff8 +ffffffffffffffffffff81ffffffffffffffffe007ffffc0000003ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffc01fffff8 +ffffffffffffffffffff83ffffffffffffffffe007ffffc0000001ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffc01fffff8 +ffffffffffffffffffff07ffffffffffffffff800fffff80000000ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffc01fffff8 +fffffffffffffffffffe07ffffffffffffffff800fffff00000000ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffc03fffff8 +fffffffffffffffffffc0ffffffffffffffffe001fffff00000000ffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff803fffff8 +fffffffffffffffffffc0ffffffffffffffffc003ffffe000000007fffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff803fffff8 +fffffffffffffffffff81ffffffffffffffff0003ffffc000000007fffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff007fffff8 +fffffffffffffffffff01fffffffffffffffe0007ffffc000000003fffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff007fffff8 +fffffffffffffffffff03fffffffffffffffe000fffff8000000001fffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff007fffff8 +ffffffffffffffffffe07fffffffffffffff8000fffff0000000001fffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffe00ffffff8 +ffffffffffffffffffc07fffffffffffffff0001fffff0000000001fffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffe00ffffff8 +ffffffffffffffffffc0fffffffffffffffe0001ffffe0000000000fffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffe00ffffff8 +ffffffffffffffffff80fffffffffffffff80003ffffe0000000000fffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffe01ffffff8 +ffffffffffffffffff81fffffffffffffff00007ffffc0000000000fffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffc01ffffff8 +ffffffffffffffffff81ffffffffffffffe00007ffffc00000000007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffc01ffffff8 +ffffffffffffffffff03ffffffffffffffc0000fffffc00000000007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffc03ffffff8 +fffffffffffffffffe03ffffffffffffff00000fffffe00000000007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff803ffffff8 +fffffffffffffffffc07fffffffffffffe00001ffffff00000000007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff803ffffff8 +fffffffffffffffffc07fffffffffffffc00007ffffffc0000000007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff807ffffff8 +fffffffffffffffff807fffffffffffff00001fffffffe0000000003ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff807ffffff8 +fffffffffffffffff807ffffffffffffe00003ffffffff0000000003ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff007ffffff8 +fffffffffffffffff00fffffffffffff800007ffffffff8000000003ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff00fffffff8 +fffffffffffffffff00fffffffffffff00000fffffffffc000000001ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff00fffffff8 +ffffffffffffffffe00ffffffffffffc00003fffffffffe000000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffe01fffffff8 +ffffffffffffffffe00ffffffffffff800007ffffffffff000000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffe01fffffff8 +ffffffffffffffffc00ffffffffffff00000fffffffffff800000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffe01fffffff8 +ffffffffffffffff800fffffffffffc00001fffffffffffc00000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffe03fffffff8 +ffffffffffffffff800fffffffffff000007fffffffffffe00000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffe03fffffff8 +ffffffffffffffff001ffffffffffe00000fffffffffffff00000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffc07fffffff8 +ffffffffffffffff001ffffffffffc00001fffffffffffff80000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffc07fffffff8 +fffffffffffffffe000fffffffffe000003fffffffffffff80000001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff807fffffff8 +fffffffffffffffe000fffffffffc000007fffffffffffffc0000000ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff807fffffff8 +fffffffffffffffc000fffffffff800000ffffffffffffffe0000000ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff80ffffffff8 +fffffffffffffffc0007fffffffe000001fffffffffffffff0000000ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff80ffffffff8 +fffffffffffffffc0003fffffffc000003fffffffffffffff0000000ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff01ffffffff8 +fffffffffffffff80001fffffff8000007fffffffffffffff8000000ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff01ffffffff8 +fffffffffffffff80000ffffffc000001ffffffffffffffff8000000ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff01ffffffff8 +fffffffffffffff800003fffff0000003ffffffffffffffffc000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffe01ffffffff8 +fffffffffffffff000000000000000007ffffffffffffffffc000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffe03ffffffff8 +ffffffffffffffe00000000000000000fffffffffffffffffe000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffe03ffffffff8 +ffffffffffffffe00000000000000001fffffffffffffffffe000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffc07ffffffff8 +ffffffffffffffc00000000000000003fffffffffffffffffe000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffc07ffffffff8 +ffffffffffffffc00000000000000007ffffffffffffffffff000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffc07ffffffff8 +ffffffffffffffc0000000000000000fffffffffffffffffff000000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffc0fffffffff8 +ffffffffffffff80000000000000003fffffffffffffffffff800000ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffc0fffffffff8 +ffffffffffffff80000000000000007fffffffffffffffffff800001ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff80fffffffff8 +ffffffffffffff8000000000000001ffffffffffffffffffff800001ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff81fffffffff8 +ffffffffffffff8000000000000001ffffffffffffffffffffc00001ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff81fffffffff8 +ffffffffffffff8000000000000003ffffffffffffffffffffe00001ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff01fffffffff8 +ffffffffffffff000000000000000fffffffffffffffffffffe00001ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff03fffffffff8 +ffffffffffffff000000000000001ffffffffffffffffffffff00001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffe03fffffffff8 +fffffffffffffe000000000000003ffffffffffffffffffffff00001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffe03fffffffff8 +fffffffffffffe000000000000007ffffffffffffffffffffff00001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffe03fffffffff8 +fffffffffffffc00000000000001fffffffffffffffffffffff00001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffe07fffffffff8 +fffffffffffffc00000000000007fffffffffffffffffffffff00001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffc07fffffffff8 +fffffffffffffc00000000000007fffffffffffffffffffffff00001ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffc07fffffffff8 +fffffffffffffc0000000000003ffffffffffffffffffffffff80003ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffc0ffffffffff8 +fffffffffffffc0000000000007ffffffffffffffffffffffff80003ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffc0ffffffffff8 +fffffffffffffc000000000000fffffffffffffffffffffffff80003ffffffffffffffff +fffffffffffffffffffffffffffffffffffffff80ffffffffff8 +fffffffffffffc000000000003fffffffffffffffffffffffff80003ffffffffffffffff +fffffffffffffffffffffffffffffffffffffff80ffffffffff8 +fffffffffffffc000000000007fffffffffffffffffffffffff80003ffffffffffffffff +fffffffffffffffffffffffffffffffffffffff00ffffffffff8 +fffffffffffffc00000000001ffffffffffffffffffffffffff80007ffffffffffffffff +fffffffffffffffffffffffffffffffffffffff01ffffffffff8 +fffffffffffffe00000000001ffffffffffffffffffffffffff80007ffffffffffffffff +fffffffffffffffffffffffffffffffffffffff01ffffffffff8 +fffffffffffffe0000000000fffffffffffffffffffffffffff80007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffe01ffffffffff8 +ffffffffffffff0000000001fffffffffffffffffffffffffff80007ffffffffffffffff +ffffffffffffffffffffffffffffffffffffffe03ffffffffff8 +ffffffffffffff000000000ffffffffffffffffffffffffffff80007ffffffffffffffff +fffffffffffffffffffdffffffffffffffffffe03ffffffffff8 +ffffffffffffff800000003ffffffffffffffffffffffffffff80007ffffffffffffffff +fffffffffffffffffff9ffffffffffffffffffc03ffffffffff8 +ffffffffffffffe0000001fffffffffffffffffffffffffffff80007ffffffffffffffff +fffffffffffffffffff1ffffffffffffffffff807ffffffffff8 +fffffffffffffff0000001fffffffffffffffffffffffffffff8000fffffffffffffffff +fffffffffffffffffff1ffffffffffffffffff807ffffffffff8 +fffffffffffffff800000ffffffffffffffffffffffffffffffc000fffffffffffffffff +fffffffffffffffffff1ffffffffffffffffff807ffffffffff8 +fffffffffffffffe0003fffffffffffffffffffffffffffffffc000fffffffffffffffff +ffffffffffffffffffe1ffffffffffffffffff807ffffffffff8 +ffffffffffffffff4007fffffffffffffffffffffffffffffffc001fffffffffffffffff +ffffffffffffffffffc1ffffffffffffffffff00fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc001fffffffffffffffff +ffffffffffffffffff83ffffffffffffffffff00fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc001fffffffffffffffff +ffffffffffffffffff83ffffffffffffffffff00fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc001fffffffffffffffff +ffffffffffffffffff03ffffffffffffffffff00fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc001fffffffffffffffff +ffffffffffffffffff03ffffffffffffffffff01fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc003fffffffffffffffff +ffffffffffffffffff07ffffffffffffffffff01fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc003fffffffffffffffff +fffffffffffffffffe07fffffffffffffffffe01fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc003fffffffffffffffff +fffffffffffffffffc07fffffffffffffffffe03fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc007fffffffffffffffff +fffffffffffffffffc07fffffffffffffffffc03fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc007fffffffffffffffff +fffffffffffffffff80ffffffffffffffffffc03fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe007fffffffffffffffff +fffffffffffffffff80ffffffffffffffffffc03fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe007fffffffffffffffff +fffffffffffffffff80ffffffffffffffffffc03fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe00ffffffffffffffffff +fffffffffffffffff03ffffffffffffffffff807fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe00ffffffffffffffffff +ffffffffffffffffe01ffffffffffffffffff807fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe01ffffffffffffffffff +ffffffffffffffffe03ffffffffffffffffff807fffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe01ffffffffffffffffff +ffffffffffffffffc07ffffffffffffffffff00ffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe03ffffffffffffffffff +ffffffffffffffffc07ffffffffffffffffff00ffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe03ffffffffffffffffff +ffffffffffffffff80fffffffffffffffffff00ffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe07ffffffffffffffffff +ffffffffffffffff80fffffffffffffffffff00ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff07ffffffffffffffffff +ffffffffffffffff00ffffffffffffffffffe01ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff07ffffffffffffffffff +fffffffffffffffe00ffffffffffffffffffe01ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff0fffffffffffffffffff +fffffffffffffffe00ffffffffffffffffffe01ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff0fffffffffffffffffff +fffffffffffffffc01ffffffffffffffffffc01ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff1fffffffffffffffffff +fffffffffffffffc03ffffffffffffffffffc01ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff3fffffffffffffffffff +fffffffffffffffc03ffffffffffffffffffc03ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffff +fffffffffffffff807ffffffffffffffffffc03ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffff807ffffffffffffffffff803ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffff00fffffffffffffffffff803ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffff00fffffffffffffffffff807ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffe01fffffffffffffffffff807ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffe03fffffffffffffffffff807ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffc03fffffffffffffffffff807ffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffff807fffffffffffffffffff00fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffff807fffffffffffffffffff00fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffff00ffffffffffffffffffff00fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffff00fffffffffffffffffffe00fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffe01fffffffffffffffffffe01fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffe03fffffffffffffffffffe01fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffc03fffffffffffffffffffc01fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffc07fffffffffffffffffffc01fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffff807fffffffffffffffffffc03fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffff00ffffffffffffffffffffc03fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffff00ffffffffffffffffffff803fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffe01ffffffffffffffffffff803fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffe01ffffffffffffffffffff803fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffc03ffffffffffffffffffff807fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffc03ffffffffffffffffffff007fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffff807ffffffffffffffffffff007fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffff807ffffffffffffffffffff007fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffff00fffffffffffffffffffff007fffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffe00ffffffffffffffffffffe00ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffe01ffffffffffffffffffffe00ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9fffffffffffff +fffffffffffc01ffffffffffffffffffffe00ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1fffffffffffff +fffffffffffc03ffffffffffffffffffffe00ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1fffffffffffff +fffffffffff803ffffffffffffffffffffc00ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1fffffffffffff +fffffffffff807ffffffffffffffffffffc00ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1fffffffffffff +fffffffffff00fffffffffffffffffffffc01ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3fffffffffffff +fffffffffff00fffffffffffffffffffffc01ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffff83fffffffffffff +ffffffffffc01fffffffffffffffffffffc01ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fffffffffffff +ffffffffffc01fffffffffffffffffffffc01ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fffffffffffff +ffffffffff801fffffffffffffffffffff801ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fffffffffffff +ffffffffff803fffffffffffffffffffff801ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffff +ffffffffff003fffffffffffffffffffff803ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0ffffffffffffff +fffffffffe007fffffffffffffffffffff803ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1ffffffffffffff +fffffffffc007fffffffffffffffffffff003ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff81ffffffffffffff +fffffffffc00ffffffffffffffffffffff003ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffffffffffffff +fffffffff800ffffffffffffffffffffff003ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffffffffffffff +fffffffff801ffffffffffffffffffffff003ffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffff +fffffffff803ffffffffffffffffffffff007ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffe07ffffffffffffff +fffffffff003fffffffffffffffffffffe007ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffffc07ffffffffffffff +ffffffffe007fffffffffffffffffffffe007ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffff807ffffffffffffff +ffffffffc007fffffffffffffffffffffe007ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffff007ffffffffffffff +ffffffffc007fffffffffffffffffffffe007ffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffff00fffffffffffffff +ffffffff800ffffffffffffffffffffffe00fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffff00fffffffffffffff +ffffffff000ffffffffffffffffffffffe00fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffe00fffffffffffffff +fffffffe001ffffffffffffffffffffffe00fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffc01fffffffffffffff +fffffffc003ffffffffffffffffffffffe00fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffffc01fffffffffffffff +9ffffffc003ffffffffffffffffffffffe00fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffff803fffffffffffffff +0ffffff8003ffffffffffffffffffffffc01fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffff003ffffffffffffffe +07fffff0007ffffffffffffffffffffffc01fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffff003ffffffffffffffe +07ffffe000fffffffffffffffffffffffc01fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffe007ffffffffffffff8 +03ffffc000fffffffffffffffffffffffc01fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffe007ffffffffffffff0 +03ffff8001fffffffffffffffffffffff801fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffffc007ffffffffffffff0 +01ffff0003fffffffffffffffffffffff803fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffff800ffffffffffffffe0 +00fffe0003fffffffffffffffffffffff803fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffff800ffffffffffffffe0 +00fffe0003fffffffffffffffffffffff803fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffff001ffffffffffffffc0 +003ffc0007fffffffffffffffffffffff003fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffe003ffffffffffffff80 +001fe0001ffffffffffffffffffffffff003fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffe003ffffffffffffff00 +000fc0001ffffffffffffffffffffffff007fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffffc007fffffffffffffe00 +000000001ffffffffffffffffffffffff007fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff8007fffffffffffffe00 +000000003ffffffffffffffffffffffff007fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff800ffffffffffffffc00 +000000003ffffffffffffffffffffffff007fffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffff000ffffffffffffff800 +000000007fffffffffffffffffffffffe007fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe001ffffffffffffff800 +000000007fffffffffffffffffffffffe007fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffe001ffffffffffffff000 +00000001ffffffffffffffffffffffffe007fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc003ffffffffffffff000 +00000001ffffffffffffffffffffffffe007fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffffc007fffffffffffffe000 +00000001ffffffffffffffffffffffffe007fffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffff0007fffffffffffffc000 +00000003ffffffffffffffffffffffffc00ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffff000ffffffffffffffc000 +00000003ffffffffffffffffffffffffc00ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffe000ffffffffffffff8000 +00000007ffffffffffffffffffffffffc00ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffc001ffffffffffffff0000 +0000000fffffffffffffffffffffffffc01ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffffc003ffffffffffffff0000 +0000001fffffffffffffffffffffffffc01ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffff8003fffffffffffffe0000 +0000001fffffffffffffffffffffffffc01ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffff0007fffffffffffffe0000 +0000003fffffffffffffffffffffffffc01ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffe000ffffffffffffffc0000 +0000007fffffffffffffffffffffffff801ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffe000ffffffffffffff80000 +0000007fffffffffffffffffffffffff801ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffffc001ffffffffffffff80000 +000000ffffffffffffffffffffffffff801ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffff8001ffffffffffffff00000 +000001ffffffffffffffffffffffffff801ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffff0003ffffffffffffff00000 +000001ffffffffffffffffffffffffff801ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffff0003ffffffffffffff00000 +000003ffffffffffffffffffffffffff801ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffe0007fffffffffffffe00000 +000003ffffffffffffffffffffffffff801ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffe000ffffffffffffffe00000 +000007ffffffffffffffffffffffffff803ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffffc000ffffffffffffffc00000 +00000fffffffffffffffffffffffffff003ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffff8001ffffffffffffff800000 +00000fffffffffffffffffffffffffff803ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffff0003ffffffffffffff800000 +00001fffffffffffffffffffffffffff803ffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffff0007ffffffffffffff000200 +00003fffffffffffffffffffffffffff007ffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffe0007fffffffffffffe000700 +00007fffffffffffffffffffffffffff00fffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffffc000ffffffffffffffe001f80 +0000ffffffffffffffffffffffffffff00fffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffff8000ffffffffffffffe001f80 +0001ffffffffffffffffffffffffffff00fffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffff8000ffffffffffffffc003fc0 +0001ffffffffffffffffffffffffffff00fffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffff0001ffffffffffffff8007fe0 +0003ffffffffffffffffffffffffffff01fffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffe0003ffffffffffffff0007fe0 +0007ffffffffffffffffffffffffffff01fffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffe0007ffffffffffffff000fff0 +0007ffffffffffffffffffffffffffff01fffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffffc000ffffffffffffffe003fff8 +001fffffffffffffffffffffffffffff07fffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffff8000ffffffffffffffe003fffc +007fffffffffffffffffffffffffffff07fffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffff8000ffffffffffffffe003fffe +00ffffffffffffffffffffffffffffff07fffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffff0001ffffffffffffffc007ffff +dfffffffffffffffffffffffffffffff0ffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffe0003ffffffffffffff800fffff +fffffffffffffffffffffffffffffffe1ffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffc0007ffffffffffffff800fffff +fffffffffffffffffffffffffffffffe1ffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffffc0007ffffffffffffff001fffff +fffffffffffffffffffffffffffffffe1ffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffff8000fffffffffffffff003fffff +fffffffffffffffffffffffffffffffe3ffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffe003fffff +ffffffffffffffffffffffffffffffff3ffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffe0001ffffffffffffffc007fffff +ffffffffffffffffffffffffffffffff3ffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffe0003ffffffffffffffc007fffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffffc0007ffffffffffffffc00ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffff8000fffffffffffffff800ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffff8000fffffffffffffff801ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffe0000fffffffffffffff001ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffc0001fffffffffffffff003ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffffc0003ffffffffffffffe007ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffff80007ffffffffffffffe007ffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffff0000fffffffffffffffc00fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffff0000fffffffffffffffc00fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffe0001fffffffffffffffc00fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffc0001fffffffffffffff801fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffffc0003fffffffffffffff801fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffff80003fffffffffffffff003fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffff007fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffe0000ffffffffffffffff007fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffc0001fffffffffffffffc007fffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffffc0001fffffffffffffffc00ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffff80003fffffffffffffffc01ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffff801ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffe0001ffffffffffffffff801ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffc0001ffffffffffffffff803ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffffc0003ffffffffffffffff803ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffff80003fffffffffffffffe007ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffff80007fffffffffffffffe007ffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffe00fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffff0000ffffffffffffffffc00fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffffc0001ffffffffffffffff801fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffff80003ffffffffffffffff803fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffff80003ffffffffffffffff003fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffff00007ffffffffffffffff003fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffe0000ffffffffffffffffe007fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffe0000ffffffffffffffffc007fffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffffc0001ffffffffffffffffc00ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffff80007ffffffffffffffffc00ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffff00007ffffffffffffffff801ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffff00007ffffffffffffffff801ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffe0000fffffffffffffffff003ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffffc0001fffffffffffffffff003ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffff80003ffffffffffffffffe007ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffff80003ffffffffffffffffe007ffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffe00007ffffffffffffffffc00fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffe0000fffffffffffffffffc00fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffffe0000fffffffffffffffffc00fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffff80001fffffffffffffffff801fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffff00003fffffffffffffffff801fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffff00007fffffffffffffffff003fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffe00007fffffffffffffffff007fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffc0000ffffffffffffffffff007fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffffc0001fffffffffffffffffc007fffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffff80003fffffffffffffffffc00ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffff80007fffffffffffffffffc01ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffff00007fffffffffffffffff801ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffff0000ffffffffffffffffff801ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffffc0001ffffffffffffffffff803ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffff80003ffffffffffffffffff803ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffff00007ffffffffffffffffff007ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffff00007ffffffffffffffffff007ffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffe0000ffffffffffffffffffe00fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffc0000ffffffffffffffffffe00fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffffc0001ffffffffffffffffffe01fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffff80003ffffffffffffffffffc03fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffff00007ffffffffffffffffffc03fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffe00007ffffffffffffffffffc03fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffe00007ffffffffffffffffffc07fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffffc0001fffffffffffffffffff807fffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffff80003fffffffffffffffffff80ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffff80003fffffffffffffffffff80ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffff00007fffffffffffffffffff81ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffe0000ffffffffffffffffffff01ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffe0001ffffffffffffffffffff03ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffffc0003ffffffffffffffffffff03ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffff80003fffffffffffffffffffe07ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffff00007fffffffffffffffffffe07ffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffe00007fffffffffffffffffffe0fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffe0000ffffffffffffffffffffc0fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffe0000ffffffffffffffffffffc1fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffffc0001ffffffffffffffffffffc1fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffff80007ffffffffffffffffffff83fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffff00007ffffffffffffffffffff83fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffe00007ffffffffffffffffffff83fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffe0000fffffffffffffffffffff87fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffc0001fffffffffffffffffffff87fffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffffc0001fffffffffffffffffffff0ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffff80003fffffffffffffffffffff0ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffff00007fffffffffffffffffffff0ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffff0000ffffffffffffffffffffff1ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffe0000fffffffffffffffffffffe1ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffffc0001fffffffffffffffffffffe3ffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffff80003fffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffff00007fffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffe0001ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffe0001ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffc0003ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffffc0007ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffff0000fffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffff0000fffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffe0001fffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffc0003fffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffc0003fffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffffc0007fffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffff8000ffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffff8001ffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffff0001ffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffff0003ffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffff0003ffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffe0007ffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffffc000fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffff8001fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffff8001fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffff8003fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffff8007fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffff8007fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffff0007fffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffe000ffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffe001ffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffc001ffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffc007ffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffc00fffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffffc01fffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffff801fffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffff003fffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffff003fffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffe00ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffe01ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffc03ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffffc03ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffff807ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffff807ffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffff80fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffff00fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +fffffffffffffffffffffff01fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffe03fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffe07fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffe07fffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffc1ffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffc1ffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffffc3ffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff83ffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff87ffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 +ffffffffffffffffffffff3fffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffff8 + + +showpage + +% stop using temporary dictionary +end + +% restore original state +origstate restore + +%%Trailer diff --git a/texi/gnusref.tex b/texi/gnusref.tex index b8b270f..bc904a5 100644 --- a/texi/gnusref.tex +++ b/texi/gnusref.tex @@ -1,4 +1,9 @@ %% include file for the Gnus refcard and booklet + +\def\progver{5.10}\def\refver{5.10-1} % program and refcard versions +\def\date{Oct 13th, 2001} +\def\author{Gnus Bugfixing Girls + Boys $<$bugs@gnus.org$>$} + %% \newlength{\keycolwidth} \newenvironment{keys}[1]% #1 is the widest key @@ -32,7 +37,7 @@ Copyright \copyright\ 1995 Vladimir Alexiev $<$vladimir@cs.ualberta.ca$>$.\\* Copyright \copyright\ 2000 Felix Natter $<$fnatter@gmx.net$>$.\\* - Copyright \copyright\ 2001 \author.\\* + Copyright \copyright\ 2001, 2002 \author.\\* Created from the Gnus manual Copyright \copyright\ 1994 Lars Magne Ingebrigtsen.\\* and the Emacs Help Bindings feature (C-h b).\\* @@ -166,8 +171,10 @@ \# & (\#, M \#, M P p) Processable (will be affected by the next operation). [2]\\ A & {\bf Answered} (followed-up or replied). [2]\\ - * & Cached. [2]\\ + $\ast$ & Cached. [2]\\ S & Saved. [2]\\ + N & Recently arrived. [2]\\ + . & Unseen. [2]\\ + & Over default score. [3]\\ $-$ & Under default score. [3]\\ $=$ & Has children (thread underneath it). Add `\%e' to @@ -191,15 +198,17 @@ $>$ & Go to the end of the Group buffer.\\ , & Jump to the lowest-level group with unread articles.\\ . & Jump to the first group with unread articles.\\ - xx & Enter the Server buffer mode.\\ - a & Post an {\bf article} to a group.\\ + \^{} & Enter the Server buffer mode.\\ + a & Post an {\bf article} to a group + [Prefix: use group under point to find posting-style].\\ b & Find {\bf bogus} groups and delete them.\\ c & Mark all unticked articles in this group as read ({\bf catch-up}). [p/p]\\ g & Check the server for new articles ({\bf get}). [level]\\ M-g & Check the server for new articles in this group ({\bf get}). [p/p]\\ j & {\bf Jump} to a group.\\ - m & {\bf Mail} a message to someone.\\ + m & {\bf Mail} a message to someone + [Prefix: use group under point to find posting-style].\\ n & Go to the {\bf next} group with unread articles. [distance]\\ M-n & Go to the {\bf next} group on the same or lower level. [distance]\\ @@ -233,19 +242,19 @@ H d & (C-c C-d) Show the {\bf description} of this group [Prefix: re-read from server].\\ M-d & {\bf Describe} all groups. [Prefix: re-read from server]\\ + D g & Regenerate a Sieve script from group parameters.\\ + D u & Regenerate Sieve script and {\bf upload} to server.\\ \end{keys} } \newcommand{\ListGroups}{% {\esamepage \begin{keys}{A M} - A d & List all groups whose names or {\bf descriptions} match a regexp.\\ + A d & (C-c C-M-a) List all groups whose names or {\bf descriptions} match a regexp.\\ A k & (C-c C-l) List all {\bf killed} groups. [Prefix: look at active-file from server]\\ A l & List all groups on a specific level. [Prefix: also list groups with no unread articles]\\ - A d & List all groups that have names or {\bf descriptions} matching - a regexp.\\ A a & (C-c C-a) List all groups whose names match a regexp ({\bf apropos}).\\ A A & List the server's active-file.\\ @@ -257,6 +266,8 @@ A u & (L) List all groups (including read and {\bf unsubscribed}). [level; 7 and lower is the default]\\ A z & List all {\bf zombie} groups.\\ + A c & List all groups with cached articles. [level]\\ + A ? & List all groups with dormant articles. [level]\\ \end{keys} } @@ -284,6 +295,8 @@ G w & Create ephemeral group based on web-search. [Prefix: make solid group instead]\\ G DEL & {\bf Delete} group [Prefix: delete all articles as well].\\ + G x & Expunge all deleted articles in an nnimap mailbox.\\ + G l & Edit ACL (Access Control {\bf List}) for an nnimap mailbox.\\ \end{keys} You can also create mail-groups and read your mail with Gnus (very useful if you are subscribed to mailing lists), using one of the methods @@ -308,7 +321,8 @@ M u & (M-\#) Remove the process mark from this group ({\bf unmark}). [scope]\\ M U & Remove the process mark from all groups (\textbf{umark all}).\\ - M w & Mark all groups in the current region.\\ + M w & Mark all groups in the current region. [prefix: unmark]\\ + M b & Mark all groups in the {\bf buffer}. [prefix: unmark]\\ \end{keys}} \newcommand{\GroupTopicsGeneral}{% @@ -331,11 +345,15 @@ T TAB & (TAB) Indent current topic [Prefix: unindent].\\ M-TAB & Unindent the current topic.\\ RET & (SPC) Either unfold topic or enter group [level].\\ + T s & {\bf Show} the current topic. [Prefix: show permanently]\\ + T h & {\bf Hide} the current topic. [Prefix: hide permanently]\\ C-c C-x & Expire all articles in current group or topic.\\ C-k & {\bf Kill} a group or topic.\\ C-y & {\bf Yank} a group or topic.\\ A T & List active-file using {\bf topics}.\\ G p & Edit topic-{\bf parameters}.\\ + T M-n & Go to {\bf next} topic. [distance]\\ + T M-p & Go to {\bf previous} topic. [distance]\\ \end{keys} } } @@ -349,7 +367,10 @@ T S v & Sort by group score ({\bf value}).\\ T S r & Sort by group {\bf rank}.\\ T S m & Sort by {\bf method}.\\ + T S e & Sort by {\bf server} name.\\ + T S s & Sort according to `gnus-group-sort-function'.\\ \end{keys} + With a prefix these commands will sort in reverse order. } } @@ -374,8 +395,8 @@ SPC & (A SPC, A n) Select an article, scroll it one page, move to the next one.\\ DEL & (A DEL, A p, b) Scroll this article one page back. [distance]\\ - RET & Scroll this article one line forward. [distance]\\ - M-RET & Scroll this article one line backward. [distance]\\ + RET & (A RET) Scroll this article one line forward. [distance]\\ + M-RET & (A M-RET) Scroll this article one line backward. [distance]\\ = & Expand the Summary window (fullsize). [Prefix: shrink to display article window]\\ % @@ -420,9 +441,11 @@ A t & {\bf Translate} this article.\\ A R & Fetch all articles mentioned in the {\bf References}-header.\\ A T & Fetch full \textbf{thread} in which the current article appears.\\ - M-\^{} & Fetch the article with a given Message-ID.\\ + M-\^{} & Fetch the article with a given Message-ID.\\ S y & {\bf Yank} the current article into an existing message-buffer. [p/p]\\ + A M & Setup group parameters for {\bf mailing} lists from + headers. [Prefix: replace old settings]\\ \end{keys} } } @@ -434,7 +457,7 @@ MIME button in the article buffer, use the corresponding bindings for the article buffer instead. \begin{keys}{W M w} - K v & (b) {\bf View} the MIME-part.\\ + K v & (b, W M b) {\bf View} the MIME-part.\\ K o & {\bf Save} the MIME part.\\ K c & {\bf Copy} the MIME part.\\ K e & View the MIME part {\bf externally}.\\ @@ -442,6 +465,7 @@ K $\mid$ & Pipe the MIME part to an external command.\\ K b & Make all the MIME parts have buttons in front of them.\\ K m & Try to repair {\bf multipart-headers}.\\ + K C & View the MIME part using a differenct {\bf charset}.\\ X m & Save all parts matching a MIME type to a directory. [p/p]\\ M-t & Toggle the buttonized display of the article buffer.\\ W M w & Decode RFC2047-encoded words in the article headers.\\ @@ -457,11 +481,13 @@ C-c C-s C-a & Sort the summary-buffer by {\bf author}.\\ C-c C-s C-d & Sort the summary-buffer by {\bf date}.\\ C-c C-s C-i & Sort the summary-buffer by article score.\\ - C-c C-s C-l & Sort the summary-buffer by amount of lines.\\ + C-c C-s C-l & Sort the summary-buffer by amount of {\bf lines}.\\ C-c C-s C-c & Sort the summary-buffer by length.\\ C-c C-s C-n & Sort the summary-buffer by article {\bf number}.\\ C-c C-s C-s & Sort the summary-buffer by {\bf subject}.\\ + C-c C-s C-o & Sort the summary-buffer using the default method.\\ \end{keys} + With a prefix these functions sort in reverse order. } } @@ -475,14 +501,16 @@ B c & {\bf Copy} this article from any group to a mail group. [p/p]\\ B e & {\bf Expire} all expirable articles in this group. [p/p]\\ B i & {\bf Import} a random file into this group.\\ + B I & Create an empty article in this group.\\ B m & {\bf Move} the article from one mail group to another. [p/p]\\ - B p & Query whether the article was posted as well.\\ + B p & Query whether the article was {\bf posted} as well.\\ B q & {\bf Query} where the article will end up after fancy splitting\\ B r & {\bf Respool} this mail article. [p/p]\\ B t & {\bf Trace} the fancy splitting patterns applied to this article.\\ B w & (e) Edit this article.\\ B M-C-e & {\bf Expunge} (delete from disk) all expirable articles in this group (!). [p/p]\\ + K E & {\bf Encrypt} article body. [p/p]\\ \end{keys} } } @@ -546,25 +574,41 @@ \newcommand{\WashArticle}{% formerly \Wsubmap {\esamepage \begin{keys}{W W H} + W 6 & Translate a base64 article.\\ + W a & Strip certain {\bf headers} from body.\\ W b & Make Message-IDs and URLs in the article mouse-clickable {\bf buttons}.\\ - W l & (w) Remove page breaks ({\bf\^{}L}) from the article.\\ W c & Translate CRLF-pairs to LF and then the remaining CR's to LF's.\\ W d & Treat {\bf dumbquotes}.\\ - W f & Look for and display any X-{\bf Face} headers.\\ + W e & Treat {\bf emphasized} text.\\ + W h & Treat {\bf HTML}.\\ + W k & Deuglify broken Outlook (Express) articles and redisplay.\\ + W l & (w) Remove page breaks ({\bf\^{}L}) from the article.\\ W m & Toggle {\bf MIME} processing.\\ W o & Treat {\bf overstrike} or underline (\^{}H\_) in the article.\\ + W p & Verify X-{\bf PGP}-Sig header.\\ W q & Treat {\bf quoted}-printable in the article.\\ W r & (C-c C-r) Do a Caesar {\bf rotate} (rot13) on the article.\\ + W s & Verify (and decrypt) a {\bf signed} message.\\ W t & (t) {\bf Toggle} display of all headers.\\ + W u & {\bf Unsplit} broken URLs.\\ W v & (v) Toggle permanent {\bf verbose} displaying of all headers.\\ W w & Do word {\bf wrap} in the article.\\ W B & Add clickable {\bf buttons} to the article headers.\\ W C & {\bf Capitalize} first word in each sentence.\\ W Q & Fill long lines.\\ + W Z & Translate a HZ-encoded article.\\ % - W W H & Strip certain {\bf headers} from body.\\ - % + W G u & {\bf Unfold} folded header lines.\\ + W G f & {\bf Fold} all header lines.\\ + W G n & Unfold {\bf Newsgroups:} and Follow-Up-To:.\\ + \end{keys} + } + } + + \newcommand{\BlankAndWhitespace}{% + {\esamepage + \begin{keys}{W E w} W E l & Strip blank {\bf lines} from the beginning of the article.\\ W E m & Replace blank lines with empty lines and remove {\bf multiple} blank lines.\\ @@ -574,13 +618,35 @@ W E A & Strip {\bf all} blank lines.\\ W E s & Strip leading blank lines from the article body.\\ W E e & Strip trailing blank lines from the article body.\\ - % + W E w & Remove leading {\bf whitespace} from all headers.\\ + \end{keys} + } + } + + \newcommand{\Picons}{% + {\esamepage + \begin{keys}{W D D} + W D s & (W g) Display {\bf smilies}.\\ + W D x & (W f) Look for and display any X-{\bf Face} headers.\\ + W D n & Toggle picons in {\bf Newsgroups} and Followup-To.\\ + W D m & Toggle picons in {\bf mail} headers (To and Cc).\\ + W D f & Toggle picons in {\bf From}.\\ + W D D & Remove all images from the article buffer.\\ + \end{keys} + } + } + + \newcommand{\TimeAndDate}{% + {\esamepage + \begin{keys}{W T u} W T u & (W T z) Display the article timestamp in GMT ({\bf UT, ZULU}).\\ W T i & Display the article timestamp in {\bf ISO} 8601.\\ W T l & Display the article timestamp in the {\bf local} timezone.\\ W T s & Display according to `gnus-article-time-format'.\\ W T e & Display the time {\bf elapsed} since it was sent.\\ W T o & Display the {\bf original} timestamp.\\ + W T p & Display the date in format that's {\bf + pronounceable} in English.\\ \end{keys} } } @@ -617,9 +683,16 @@ RET & (BUTTON-2) Toggle display of the MIME object.\\ v & (M-RET) Prompt for a method and then view object using this method.\\ o & Prompt for a filename and save the MIME object.\\ + C-o & Prompt for a filename to save the MIME object to and remove it.\\ c & {\bf Copy} the MIME object to a new buffer and display this buffer.\\ + i & Display the MIME object in this buffer.\\ + C & Copy the MIME object to a new buffer and display this buffer using {\bf Charset} \\ + E & View internally. \\ + e & View {\bf externally}. \\ t & View the MIME object as a different {\bf type}.\\ + p & {\bf Print} the MIME object.\\ $\mid$ & Pipe the MIME object to a process.\\ + . & Take action on the MIME object.\\ \end{keys} } } @@ -688,17 +761,21 @@ M P u & (M-\#, M M-\#) \textbf{unmark} this article.\\ M P b & Mark all articles in {\bf buffer}.\\ M P r & Mark all articles in the {\bf region}.\\ + M P g & Unmark all articles in the region.\\ M P R & Mark all articles matching a {\bf regexp}.\\ + M P G & Unmark all articles matching a regexp.\\ M P t & Mark all articles in this (sub){\bf thread}.\\ + M P T & Unmark all articles in this (sub){\bf thread}.\\ M P s & Mark all articles in the current {\bf series}.\\ M P S & Mark all {\bf series} that already contain a marked article.\\ M P a & Mark {\bf all} articles (in series order).\\ M P U & \textbf{unmark} all articles.\\ - % M P i & {\bf Invert} the list of process-marked articles.\\ M P k & Push the current process-mark set onto stack and unmark all articles.\\ M P y & Pop process-mark set from stack and restore it.\\ + M P w & Push process-mark set on the stack.\\ + M P v & Mark all articles with score over the default score. [Prefix: score]\\ \end{keys} } } @@ -728,6 +805,9 @@ /c & Exclude all dormant articles that have no children from the limit.\\ /C & Mark all excluded unread articles as read. [Prefix: also mark ticked and dormant articles]\\ + /o & Insert all {\bf old} articles. [Prefix: how many]\\ + /N & Insert all {\bf new} articles.\\ + /p & Limit to articles {\bf predicated} in the `display' group parameter.\\ \end{keys} } } @@ -743,7 +823,8 @@ O m & Save this article in {\bf mail} format. [p/p]\\ O r & Save this article in {\bf rmail} format. [p/p]\\ O v & Save this article in {\bf vm} format. [p/p]\\ - O p & ($\mid$) Pipe this article to a shell command. [p/p]\\ + O p & ($\mid$) {\bf Pipe} this article to a shell command. [p/p]\\ + O P & \textbf{Print} this article using Muttprint. [p/p]\\ \end{keys} } } @@ -760,27 +841,32 @@ S p & (a) {\bf Post} an article to this group.\\ S f & (f) Post a {\bf followup} to this article.\\ S F & (F) Post a {\bf followup} and include the original. [p/p]\\ - S o p & Forward this article as a {\bf post} to a newsgroup. - [Prefix: include all headers]\\ + S o p & Forward this article as a {\bf post} to a newsgroup.\\ S M-c & Send a complaint about excessive crossposting to the author of this article. [p/p]\\ % - S m & (m) Send {\bf a} mail to some other person.\\ + S m & (m) Send a {\bf mail} to some other person.\\ S r & (r) Mail a {\bf reply} to the author of this article.\\ S R & (R) Mail a {\bf reply} and include the original. [p/p]\\ + S B r & Like S r but ignore the Reply-To: header.\\ + S B R & Like S R but ignore the Reply-To: header.\\ S w & Mail a {\bf wide} reply to this article.\\ - S W & Mail a {\bf wide} reply to this article.\\ - S o m & (C-c C-f) Forward this article by {\bf mail} to a person. - [Prefix: include all headers]\\ + S W & Mail a {\bf wide} reply to this article and include + the original.\\ + S v & Mail a {\bf very} wide reply to this article.\\ + S V & Mail a {\bf very} wide reply to this article and include the original.\\ + S o m & (C-c C-f) Forward this article by {\bf mail} to a person.\\ S D b & Resend {\bf bounced} mail.\\ S D r & {\bf Resend} mail to a different person.\\ + S D e & {\bf Edit} and resend.\\ % S n & Post a followup via {\bf news} even if you got the message through mail.\\ S N & Post a followup via {\bf news} and include the original mail. [p/p]\\ % - S c & (C) {\bf Cancel} this article (only works if it is your own).\\ + S c & (C) {\bf Cancel} this article (only works if it is + your own). [p/p]\\ S s & {\bf Supersede} this article with a new one (only for own articles).\\ % @@ -802,9 +888,10 @@ T M-\# & Remove process-marks from this thread.\\ % T t & Re-{\bf thread} the current article's thread.\\ + T \^{} & Make the current article child of the marked (or previous) article.\\ % movement - T n & (M-C-f) Go to the {\bf next} thread. [distance]\\ - T p & (M-C-b) Go to the {\bf previous} thread. [distance]\\ + T n & (M-C-f, M-down) Go to the {\bf next} thread. [distance]\\ + T p & (M-C-b, M-up) Go to the {\bf previous} thread. [distance]\\ T d & {\bf Descend} this thread. [distance]\\ T u & Ascend this thread ({\bf up}-thread). [distance]\\ T o & Go to the top of this thread.\\ @@ -836,9 +923,12 @@ V m & {\bf Mark} all articles below a given score as read.\\ V s & Set the {\bf score} of this article.\\ V t & Display all score rules applied to this article ({\bf track}).\\ + W w & List {\bf words} used in scoring.\\ V x & {\bf Expunge} all low-scored articles. [score]\\ V C & {\bf Customize} the current score file through a user-friendly - interface.\\ + interface.\\ + V F & {\bf Flush} the cache of score files.\\ + V R & {\bf Re-score} the summary buffer.\\ V S & Display the {\bf score} of this article.\\ \bf A p m l& Make a scoring entry based on this article.\\ \end{keys} @@ -928,8 +1018,6 @@ C-c C-m & {\bf Mail} reply to the address near point. [Prefix: include the original]\\ % modify headers/body - C-c C-t & Paste the recipient's address into \textbf{To:}-field.\\ - C-c C-n & Insert a \textbf{Newsgroups:}-header.\\ C-c C-o & Sort headers.\\ C-c C-e & \textbf{Elide} region.\\ C-c C-v & Kill everything outside region.\\ @@ -938,6 +1026,10 @@ C-c C-z & Kill everything up to signature.\\ C-c C-y & \textbf{Yank} original message.\\ C-c C-q & Fill the yanked message.\\ + C-c M-C-y & \textbf{Yank} a buffer and quote it.\\ + M-RET & Insert four newlines and format quoted text. [Prefix: + justify as well]\\ + C-c M-r & \textbf{Rename} message buffer. [Prefix: ask for new name]\\ \end{keys} } } @@ -948,17 +1040,24 @@ \begin{keys}{C-c C-f C-u} C-c TAB & Move to \textbf{signature}.\\ C-c C-b & Move to \textbf{body}.\\ - C-c C-f C-t & Move to \textbf{To:}.\\ + C-c C-f C-t & (C-c C-t) Move to \textbf{To:}.\\ C-c C-f C-c & Move to \textbf{Cc:}.\\ C-c C-f C-b & Move to \textbf{Bcc:}.\\ C-c C-f C-w & Move to \textbf{Fcc:}.\\ C-c C-f C-s & Move to \textbf{Subject:}.\\ C-c C-f C-r & Move to \textbf{Reply-To:}.\\ C-c C-f C-f & Move to \textbf{Followup-To:}.\\ - C-c C-f C-n & Move to \textbf{Newsgroups:}.\\ + C-c C-f C-n & (C-c C-n) Move to \textbf{Newsgroups:}.\\ C-c C-f C-u & Move to \textbf{Summary:}.\\ C-c C-f C-k & Move to \textbf{Keywords:}.\\ C-c C-f C-d & Move to \textbf{Distribution:}.\\ + C-c C-f C-m & Move to \textbf{Mail-Followup-To:}.\\ + C-c C-f C-o & Move to \textbf{From:}.\\ + C-c C-f C-a & Insert a resonable \textbf{Mail-Followup-To:} for + an unsubscribed list. [Prefix: include addresses in \textbf{Cc:}]\\ + C-c C-f TAB & (C-c C-u) Move to \textbf{Importance:}.\\ + C-c M-n & Insert \textbf{Disposition-Notification-To:} + (request receipt).\\ \end{keys} } } @@ -969,11 +1068,19 @@ C-c C-m f & (C-c C-a) Attach \textbf{file}.\\ C-c C-m b & Attach contents of \textbf{buffer}.\\ C-c C-m e & Attach \textbf{external} file (ftp..).\\ - C-c C-m P & Create MIME-\textbf{preview} (new buffer).\\ + C-c C-m P & Create MIME-\textbf{preview} (new + buffer). [Prefix: show raw MIME preview]\\ C-c C-m v & \textbf{Validate} article.\\ C-c C-m p & Insert \textbf{part}.\\ C-c C-m m & Insert \textbf{multi}-part.\\ C-c C-m q & \textbf{Quote} region.\\ + C-c C-m c s & Encrypt message using \textbf{S/MIME}.\\ + C-c C-m c o & Encrypt message usging PGP.\\ + C-c C-m c p & Encrypt message using \textbf{PGP/MIME}.\\ + C-c C-m s s & Sign message using \textbf{S/MIME}.\\ + C-c C-m s o & Sign message using PGP.\\ + C-c C-m s p & Sign message using \textbf{PGP/MIME}.\\ + C-c C-m C-n & Remove security related MML tags from message.\\ % TODO: narrow headers (C-c C-m n) ? \end{keys} } @@ -982,7 +1089,7 @@ %% TODO: \newcommand{\ServerMode}{% {\esamepage - To enter this mode, press `\^' while in Group mode.\\* + To enter this mode, press \^{} while in Group mode.\\* \begin{keys}{SPC} SPC & (RET) Browse this server.\\ a & {\bf Add} a new server.\\ @@ -994,6 +1101,13 @@ s & Request that the server scan its sources for new articles.\\ g & Request that the server regenerate its data.\\ y & {\bf Yank} the previously killed server.\\ + O & Try to {\bf open} a connection to this server.\\ + C & {\bf Close} connection to this server.\\ + D & Mark this server as unreachable ({\bf deny}).\\ + M-o & {\bf Open} the connection to all servers.\\ + M-c & {\bf Close} the connection to all servers.\\ + R & Make all denied servers into closed servers.\\ + L & Set server status to offline.\\ \end{keys} } } @@ -1017,13 +1131,14 @@ {\esamepage \begin{keys}{J S} J j & Toggle plugged-state.\\ - J s & Fetch articles from current group.\\ J s & Fetch articles from all groups for offline-reading.\\ + J u & Fetch all eligible articles from this group.\\ J S & \textbf{Send} all sendable messages in the drafts group.\\ % J c & Enter \textbf{category} buffer.\\ J a & \textbf{Add} this group to an Agent category [p/p].\\ J r & \textbf{Remove} this group from its Agent category [p/p].\\ + J Y & Synchronize flags changed while unplugged with remote server.\\ \end{keys} } } @@ -1035,6 +1150,7 @@ J M-\# & \textbf{Unmark} the article for downloading.\\ @ & \textbf{Toggle} whether to download the article.\\ J c & Mark all undownloaded articles as read (\textbf{catch-up}).\\ + J u & Download all downloadable articles from group.\\ \end{keys} } } diff --git a/texi/message.texi b/texi/message.texi index 0f31710..e053124 100644 --- a/texi/message.texi +++ b/texi/message.texi @@ -47,7 +47,7 @@ license to the document, as described in section 6 of the license. @page @vskip 0pt plus 1filll -Copyright @copyright{} 1996, 1997, 1998, 1999, 2000 +Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document @@ -192,10 +192,14 @@ but you can change the behavior to suit your needs by fiddling with the @code{message-wide-reply-to-function}. It is used in the same way as @code{message-reply-to-function} (@pxref{Reply}). -@findex message-dont-reply-to-names +@vindex message-dont-reply-to-names Addresses that match the @code{message-dont-reply-to-names} regular expression will be removed from the @code{Cc} header. +@vindex message-wide-reply-confirm-recipients +If @code{message-wide-reply-confirm-recipients} is non-@code{nil} you +will be asked to confirm that you want to reply to multiple +recipients. The default is @code{nil}. @node Followup @section Followup @@ -225,6 +229,11 @@ it is @code{nil}, don't use the value. The @code{message-cancel-news} command cancels the article in the current buffer. +@vindex message-cancel-message +The value of @code{message-cancel-message} is inserted in the body of +the cancel message. The default is @samp{I am canceling my own +article.}. + @node Superseding @section Superseding @@ -282,9 +291,14 @@ constructed. The default value is @code{nil}. @item message-forward-as-mime @vindex message-forward-as-mime If this variable is @code{t} (the default), forwarded messages are -included as inline MIME RFC822 parts. If it's @code{nil}, forwarded +included as inline @sc{mime} RFC822 parts. If it's @code{nil}, forwarded messages will just be copied inline to the new message, like previous, -non MIME-savvy versions of gnus would do. +non @sc{mime}-savvy versions of gnus would do. + +@item message-forward-before-signature +@vindex message-forward-before-signature +If non-@code{nil}, put forwarded message before signature, else after. + @end table @@ -325,13 +339,18 @@ followups to the post to specific places. The Mail-Followup-To (MFT) was created to enable just this. Two example scenarios where this is useful: -@itemize +@itemize @bullet @item A mailing list poster can use MFT to express that responses should be sent to just the list, and not the poster as well. This will happen if the poster is already subscribed to the list. @item +A mailing list poster can use MFT to express that responses should be +sent to the list and the poster as well. This will happen if the poster +is not subscribed to the list. + +@item If a message is posted to several mailing lists, MFT may also be used to direct the following discussion to one list only, because discussions that are spread over several lists tend to be fragmented @@ -358,6 +377,7 @@ way. The following variables would come in handy. @table @code +@vindex message-subscribed-addresses @item message-subscribed-addresses This should be a list of addresses the user is subscribed to. Its default value is @code{nil}. Example: @@ -366,20 +386,34 @@ default value is @code{nil}. Example: '("ding@@gnus.org" "bing@@noose.org")) @end lisp +@vindex message-subscribed-regexps @item message-subscribed-regexps This should be a list of regexps denoting the addresses of mailing lists subscribed to. Default value is @code{nil}. Example: If you want to achieve the same result as above: @lisp (setq message-subscribed-regexps - '("[bd]ing@@\\(gnus\\|noose\\)\\.org")) + '("\\(ding@@gnus\\)\\|\\(bing@@noose\\)\\.org") @end lisp +@vindex message-subscribed-address-functions @item message-subscribed-address-functions This can be a list of functions to be called (one at a time!!) to determine the value of MFT headers. It is advisable that these functions not take any arguments. Default value is @code{nil}. +There is a pre-defined function in Gnus that is a good candidate for +this variable. @code{gnus-find-subscribed-addresses} is a function +that returns a list of addresses corresponding to the groups that have +the @code{subscribed} (@pxref{(gnus)subscribed}) +group parameter set to a non-nil value. This is how you would do it. + +@lisp +(setq message-subscribed-address-functions + '(gnus-find-subscribed-addresses)) +@end lisp + +@vindex message-subscribed-address-file @item message-subscribed-address-file You might be one organised human freak and have a list of addresses of all subscribed mailing lists in a separate file! Then you can just @@ -390,39 +424,50 @@ set this variable to the name of the file and life would be good. You can use one or more of the above variables. All their values are ``added'' in some way that works :-) -Now you are all set. Just start composing a message as you normally -do. And just send it; as always. Just before the message is sent -out, Gnus' MFT generation thingy kicks in and checks if the message -already has a MFT header. If there is one, the header is left alone. -If not then the list of recipient addresses (in the To: and Cc: -headers) is checked to see if one of them is a list address you are -subscribed to. If none of them is a list address, then no MFT is -generated; otherwise, a MFT is added to the other headers and set to -the value of all addresses in To: and Cc: - +Now you are all set. Just start composing a message as you normally do. +And just send it; as always. Just before the message is sent out, Gnus' +MFT generation thingy kicks in and checks if the message already has a +MFT field. If there is one, it is left alone. (Except if it's empty - +in that case, the field is removed and is not replaced with an +automatically generated one. This lets you disable MFT generation on a +per-message basis.) If there is none, then the list of recipient +addresses (in the To: and Cc: headers) is checked to see if one of them +is a list address you are subscribed to. If none of them is a list +address, then no MFT is generated; otherwise, a MFT is added to the +other headers and set to the value of all addresses in To: and Cc: + +@kindex C-c C-f C-a +@findex message-gen-unsubscribed-mft +@kindex C-c C-f C-m +@findex message-goto-mail-followup-to Hm. ``So'', you ask, ``what if I send an email to a list I am not -subscribed to?'' Well, the kind folks at Gnus Towers are working on a -database of all known mailing list addresses that can be used for this -purpose. Till then, you could, like, insert a MFT header manually, -with the help of @kbd{C-c C-f m} !! +subscribed to? I want my MFT to say that I want an extra copy.'' +(This is supposed to be interpreted by others the same way as if there +were no MFT, but you can use an explicit MFT to override someone +else's to-address group parameter.) The function +@code{message-gen-unsubscribed-mft} might come in handy. It is bound +to @kbd{C-c C-f C-a} by default. In any case, you can insert a MFT of +your own choice; @kbd{C-c C-f C-m} +(@code{message-goto-mail-followup-to}) will help you get started. @c @node Honoring an MFT post @subsection Honoring an MFT post +@vindex message-use-mail-followup-to When you followup to a post on a mailing list, and the post has a MFT header, Gnus' action will depend on the value of the variable @code{message-use-mail-followup-to}. This variable can be one of: @table @code -@item t +@item use Always honor MFTs. The To: and Cc: headers in your followup will be - derived from the MFT header of the original post. + derived from the MFT header of the original post. This is the default. @item nil Always dishonor MFTs (just ignore the darned thing) @item ask -Gnus will prompt you for an action. This is the default. +Gnus will prompt you for an action. @end table @@ -648,7 +693,7 @@ automatically add the @code{Content-Type} and The most typical thing users want to use the multipart things in @sc{mime} for is to add ``attachments'' to mail they send out. This can -be done with the @code{C-c C-a} command, which will prompt for a file +be done with the @kbd{C-c C-a} command, which will prompt for a file name and a @sc{mime} type. You can also create arbitrarily complex multiparts using the MML @@ -663,72 +708,84 @@ Manual}). @cindex PGP/MIME @cindex sign @cindex encrypt +@cindex secure Using the MML language, Message is able to create digitally signed and digitally encrypted messages. Message (or rather MML) currently -support PGP (RFC 1991), PGP/MIME (RFC 2015/3156) and S/MIME. -Instructing MML to perform security operations on a MIME part is done -using the @code{C-c C-m s} key map for signing and the @code{C-c C-m -c} key map for encryption, as follows. +support PGP (RFC 1991), @sc{pgp/mime} (RFC 2015/3156) and @sc{s/mime}. +Instructing MML to perform security operations on a @sc{mime} part is +done using the @kbd{C-c C-m s} key map for signing and the @kbd{C-c +C-m c} key map for encryption, as follows. @table @kbd @item C-c C-m s s @kindex C-c C-m s s -@findex mml-secure-sign-smime +@findex mml-secure-message-sign-smime -Digitally sign current MIME part using S/MIME. +Digitally sign current message using @sc{s/mime}. @item C-c C-m s o @kindex C-c C-m s o -@findex mml-secure-sign-pgp +@findex mml-secure-message-sign-pgp -Digitally sign current MIME part using PGP. +Digitally sign current message using PGP. @item C-c C-m s p @kindex C-c C-m s p -@findex mml-secure-sign-pgp +@findex mml-secure-message-sign-pgpmime -Digitally sign current MIME part using PGP/MIME. +Digitally sign current message using @sc{pgp/mime}. @item C-c C-m c s @kindex C-c C-m c s -@findex mml-secure-encrypt-smime +@findex mml-secure-message-encrypt-smime -Digitally encrypt current MIME part using S/MIME. +Digitally encrypt current message using @sc{s/mime}. @item C-c C-m c o @kindex C-c C-m c o -@findex mml-secure-encrypt-pgp +@findex mml-secure-message-encrypt-pgp -Digitally encrypt current MIME part using PGP. +Digitally encrypt current message using PGP. @item C-c C-m c p @kindex C-c C-m c p -@findex mml-secure-encrypt-pgpmime +@findex mml-secure-message-encrypt-pgpmime + +Digitally encrypt current message using @sc{pgp/mime}. -Digitally encrypt current MIME part using PGP/MIME. +@item C-c C-m C-n +@kindex C-c C-m C-n +@findex mml-unsecure-message +Remove security related MML tags from message. @end table These commands do not immediately sign or encrypt the message, they -merely insert proper MML tags to instruct the MML engine to perform that -operation when the message is actually sent. They may perform other -operations too, such as locating and retrieving a S/MIME certificate of -the person you wish to send encrypted mail to. +merely insert the proper MML secure tag to instruct the MML engine to +perform that operation when the message is actually sent. They may +perform other operations too, such as locating and retrieving a +@sc{s/mime} certificate of the person you wish to send encrypted mail +to. When the mml parsing engine converts your MML into a properly +encoded @sc{mime} message, the secure tag will be replaced with either +a part or a multipart tag. If your message contains other mml parts, +a multipart tag will be used; if no other parts are present in your +message a single part tag will be used. This way, message mode will +do the Right Thing (TM) with signed/encrypted multipart messages. Since signing and especially encryption often is used when sensitive information is sent, you may want to have some way to ensure that your mail is actually signed or encrypted. After invoking the above sign/encrypt commands, it is possible to preview the raw article by -using @code{C-u C-m P} (@code{mml-preview}). Then you can verify that -your long rant about what your ex-significant other or whomever actually -did with that funny looking person at that strange party the other -night, actually will be sent encrypted. +using @kbd{C-u C-c RET P} (@code{mml-preview}). Then you can +verify that your long rant about what your ex-significant other or +whomever actually did with that funny looking person at that strange +party the other night, actually will be sent encrypted. -@emph{Note!} Neither PGP/MIME nor S/MIME encrypt/signs RFC822 headers. -They only operate on the MIME object. Keep this in mind before sending -mail with a sensitive Subject line. +@emph{Note!} Neither @sc{pgp/mime} nor @sc{s/mime} encrypt/signs +RFC822 headers. They only operate on the @sc{mime} object. Keep this +in mind before sending mail with a sensitive Subject line. Actually using the security commands above is not very difficult. At least not compared with making sure all involved programs talk with each @@ -738,52 +795,54 @@ programs are required to make things work, and some small general hints. @subsection Using S/MIME @emph{Note!} This section assume you have a basic familiarity with -modern cryptography, S/MIME, various PKCS standards, OpenSSL and so on. - -The S/MIME support in Message (and MML) require OpenSSL. OpenSSL -perform the actual S/MIME sign/encrypt operations. OpenSSL can be found -at @uref{http://www.openssl.org/}. OpenSSL 0.9.6 and later should work. -Version 0.9.5a cannot extract mail addresses from certificates, and it -insert a spurious CR character into MIME separators so you may wish to -avoid it if you would like to avoid being regarded as someone who send -strange mail. (Although by sending S/MIME messages you've probably -already lost that contest.) +modern cryptography, @sc{s/mime}, various PKCS standards, OpenSSL and +so on. + +The @sc{s/mime} support in Message (and MML) require OpenSSL. OpenSSL +perform the actual @sc{s/mime} sign/encrypt operations. OpenSSL can +be found at @uref{http://www.openssl.org/}. OpenSSL 0.9.6 and later +should work. Version 0.9.5a cannot extract mail addresses from +certificates, and it insert a spurious CR character into @sc{mime} +separators so you may wish to avoid it if you would like to avoid +being regarded as someone who send strange mail. (Although by sending +@sc{s/mime} messages you've probably already lost that contest.) To be able to send encrypted mail, a personal certificate is not required. Message (MML) need a certificate for the person to whom you wish to communicate with though. You're asked for this when you type -@code{C-c C-m c s}. Currently there are two ways to retrieve this -certificate, from a local file or from DNS. If you chose a local file, -it need to contain a X.509 certificate in PEM format. If you chose DNS, -you're asked for the domain name where the certificate is stored, the -default is a good guess. To my belief, Message (MML) is the first mail -agent in the world to support retrieving S/MIME certificates from DNS, -so you're not likely to find very many certificates out there. At least -there should be one, stored at the domain @code{simon.josefsson.org}. -LDAP is a more popular method of distributing certificates, support for -it is planned. (Meanwhile, you can use @code{ldapsearch} from the -command line to retrieve a certificate into a file and use it.) +@kbd{C-c C-m c s}. Currently there are two ways to retrieve this +certificate, from a local file or from DNS. If you chose a local +file, it need to contain a X.509 certificate in PEM format. If you +chose DNS, you're asked for the domain name where the certificate is +stored, the default is a good guess. To my belief, Message (MML) is +the first mail agent in the world to support retrieving @sc{s/mime} +certificates from DNS, so you're not likely to find very many +certificates out there. At least there should be one, stored at the +domain @code{simon.josefsson.org}. LDAP is a more popular method of +distributing certificates, support for it is planned. (Meanwhile, you +can use @code{ldapsearch} from the command line to retrieve a +certificate into a file and use it.) As for signing messages, OpenSSL can't perform signing operations without some kind of configuration. Especially, you need to tell it where your private key and your certificate is stored. MML uses an -Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain -a @code{custom} group used for this configuration. So, try @code{M-x -customize-group RET smime RET} and look around. - -Currently there is no support for talking to a CA (or RA) to create your -own certificate. None is planned either. You need to do this manually -with OpenSSL or using some other program. I used Netscape and got a -free S/MIME certificate from one of the big CA's on the net. Netscape -is able to export your private key and certificate in PKCS #12 format. -Use OpenSSL to convert this into a plain X.509 certificate in PEM format -as follows. +Emacs interface to OpenSSL, aptly named @code{smime.el}, and it +contain a @code{custom} group used for this configuration. So, try +@kbd{M-x customize-group RET smime RET} and look around. + +Currently there is no support for talking to a CA (or RA) to create +your own certificate. None is planned either. You need to do this +manually with OpenSSL or using some other program. I used Netscape +and got a free @sc{s/mime} certificate from one of the big CA's on the +net. Netscape is able to export your private key and certificate in +PKCS #12 format. Use OpenSSL to convert this into a plain X.509 +certificate in PEM format as follows. @example $ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem @end example -The @code{key+cert.pem} file should be pointed to from the +The @file{key+cert.pem} file should be pointed to from the @code{smime-keys} variable. You should now be able to send signed mail. @emph{Note!} Your private key is store unencrypted in the file, so take @@ -791,9 +850,9 @@ care in handling it. @subsection Using PGP/MIME -PGP/MIME requires an external OpenPGP implementation, such as GNU -Privacy Guard (@uref{http://www.gnupg.org/}). It also requires an Emacs -interface to it, such as Mailcrypt (available from +@sc{pgp/mime} requires an external OpenPGP implementation, such as GNU +Privacy Guard (@uref{http://www.gnupg.org/}). It also requires an +Emacs interface to it, such as Mailcrypt (available from @uref{http://www.nb.net/~lbudney/linux/software/mailcrypt.html}) or Florian Weimer's @code{gpg.el}. @@ -820,6 +879,7 @@ many places to rotate the text. The default is 13. @item C-c C-e @kindex C-c C-e @findex message-elide-region +@vindex message-elide-ellipsis Elide the text between point and mark (@code{message-elide-region}). The text is killed and replaced with the contents of the variable @code{message-elide-ellipsis}. The default value is to use an ellipsis @@ -874,6 +934,13 @@ Insert a @code{Newsgroups} header that reflects the @code{Followup-To} or @code{Newsgroups} header of the article you're replying to (@code{message-insert-newsgroups}). +@item C-c C-o +@kindex C-c C-o +@findex message-sort-headers +@vindex message-header-format-alist +Sort headers according to @code{message-header-format-alist} +(@code{message-sort-headers}). + @item C-c M-r @kindex C-c M-r @findex message-rename-buffer @@ -1065,9 +1132,9 @@ buffers. @item message-subject-re-regexp @vindex message-subject-re-regexp -@cindex Aw: -@cindex Sv: -@cindex Re: +@cindex Aw +@cindex Sv +@cindex Re Responses to messages have subjects that start with @samp{Re: }. This is @emph{not} an abbreviation of the English word ``response'', but is Latin, and means ``in response to''. Some illiterate nincompoops have @@ -1083,7 +1150,7 @@ responding to a message: @lisp (setq message-subject-re-regexp - "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)) + "^\\(\\(\\([Rr][Ee]\\|[Ss][Vv]\\|[Aa][Ww]\\): *\\)+\\)") @end lisp @item message-alternative-emails @@ -1141,6 +1208,34 @@ the default), these headers will be removed before mailing when sending messages via MH. Set it to @code{nil} if your MH can handle these headers. +@item message-qmail-inject-program +@vindex message-qmail-inject-program +@cindex qmail +Location of the qmail-inject program. + +@item message-qmail-inject-args +@vindex message-qmail-inject-args +Arguments passed to qmail-inject programs. +This should be a list of strings, one string for each argument. It +may also be a function. + +For e.g., if you wish to set the envelope sender address so that bounces +go to the right place or to deal with listserv's usage of that address, you +might set this variable to @code{'("-f" "you@@some.where")}. + +@item message-sendmail-f-is-evil +@vindex message-sendmail-f-is-evil +@cindex sendmail +Non-@code{nil} means don't add @samp{-f username} to the sendmail +command line. Doing so would be even more evil than leaving it out. + +@item message-mailer-swallows-blank-line +@vindex message-mailer-swallows-blank-line +Set this to non-@code{nil} if the system's mailer runs the header and +body together. (This problem exists on Sunos 4 when sendmail is run +in remote mode.) The value should be an expression to test whether +the problem will actually occur. + @item message-send-mail-partially-limit @vindex message-send-mail-partially-limit The limitation of messages sent as message/partial. @@ -1180,6 +1275,8 @@ to. If it isn't present already, it will be prompted for. @item Organization @cindex organization +@vindex message-user-organization +@vindex message-user-organization-file This optional header will be filled out depending on the @code{message-user-organization} variable. @code{message-user-organization-file} will be used if this variable is @@ -1213,18 +1310,21 @@ header of the article being replied to. @item Expires @cindex Expires +@vindex message-expires This extremely optional header will be inserted according to the @code{message-expires} variable. It is highly deprecated and shouldn't be used unless you know what you're doing. @item Distribution @cindex Distribution +@vindex message-distribution-function This optional header is filled out according to the @code{message-distribution-function} variable. It is a deprecated and much misunderstood header. @item Path @cindex path +@vindex message-user-path This extremely optional header should probably never be used. However, some @emph{very} old servers require that this header is present. @code{message-user-path} further controls how this @@ -1439,7 +1539,7 @@ If this variable is @code{nil}, no signature will be inserted at all. @item message-signature-file @vindex message-signature-file File containing the signature to be inserted at the end of the buffer. -The default is @samp{~/.signature}. +The default is @file{~/.signature}. @end table @@ -1483,6 +1583,11 @@ follows this line--} by default. @vindex message-directory Directory used by many mailey things. The default is @file{~/Mail/}. +@item message-auto-save-directory +@vindex message-auto-save-directory +Directory where Message auto-saves buffers if Gnus isn't running. If +@code{nil}, Message won't auto-save. The default is @file{~/Mail/drafts/}. + @item message-signature-setup-hook @vindex message-signature-setup-hook Hook run when initializing the message buffer. It is run after the @@ -1542,10 +1647,23 @@ Hook run before sending news messages. @vindex message-sent-hook Hook run after sending messages. +@item message-cancel-hook +@vindex message-cancel-hook +Hook run when cancelling news articles. + @item message-mode-syntax-table @vindex message-mode-syntax-table Syntax table used in message mode buffers. +@item message-strip-special-text-properties +@vindex message-strip-special-text-properties +Emacs has a number of special text properties which can break message +composing in various ways. If this option is set, message will strip +these properties from the message composition buffer. However, some +packages requires these properties to be present in order to work. If +you use one of these packages, turn this option off, and hope the +message composition doesn't break too bad. + @item message-send-method-alist @vindex message-send-method-alist @@ -1599,6 +1717,16 @@ this variable is @code{nil}, no such courtesy message will be added. The default value is @samp{"The following message is a courtesy copy of an article\\nthat has been posted to %s as well.\\n\\n"}. +@item message-fcc-externalize-attachments +@vindex message-fcc-externalize-attachments +If @code{nil}, attach files as normal parts in Fcc copies; if it is +non-@code{nil}, attach local files as external parts. + +@item message-interactive +@vindex message-interactive +If non-@code{nil} wait for and display errors when sending a message; +if @code{nil} let the mailer mail back a message to report errors. + @end table @@ -1690,7 +1818,7 @@ a form to be @code{eval}ed. Message uses virtually only its own variables---older @code{mail-} variables aren't consulted. To force Message to take those variables -into account, you can put the following in your @code{.emacs} file: +into account, you can put the following in your @file{.emacs} file: @lisp (require 'messcompat) diff --git a/texi/refcard.tex b/texi/refcard.tex index 3ef0339..cf72fb3 100644 --- a/texi/refcard.tex +++ b/texi/refcard.tex @@ -5,21 +5,25 @@ \def\Guide{Card}\def\guide{card} \def\logoscale{0.25} +\newlength{\logowidth} \setlength{\logowidth}{6.861in} +\newlength{\logoheight} \setlength{\logoheight}{7.013in} + +\raggedbottom\raggedright + +\usepackage{epsfig} + \setlength{\textwidth}{7.26in} \setlength{\textheight}{10in} \setlength{\topmargin}{-1.0in} % the same settings work for A4, although there is a bit of space at the % top and bottom of the page. \setlength{\oddsidemargin}{-0.5in} \setlength{\evensidemargin}{-0.5in} -\usepackage{epsfig} -% README: -% *** purpose -% this was originally thought of as a reference card (but as it is now 5+ -% pages long, it may not be more useful than the online-help). It helps -% to get an overview for the Gnus-functionality. +% README (for refcard + booklet) +% This is a 5+ page reference card. In addition there is a booklet +% (bk-a4.tex for A4 and bk-lt.tex for Letter). % -% *** files +% *** files for the refcard % refcard.tex (this file), gnusref.tex ("include"-file) and % gnuslogo-refcard.eps (Gnus logo). % @@ -33,53 +37,33 @@ % $xdvi refcard.dvi [C-c C-v] % and print using something like % $dvips refcard.dvi -% which creates refcard.ps (print using 'lpr refcard.ps') +% +% If you want to print the booklet, you need to use `pstops' from the +% `psutils' package (TODO: somebody write a howto ?) % % *** customization: + % the part following \begin{document} in this file consists of a macro for % each section and section-headers (\section*{..}). It should be easy to % reorder things and/or remove sections (put '%' at the beginning of the line). -% (i.e. you might want to omit \notes in the printed version ?) +% (i.e. you might want to omit \notes in the printed version) +% The same goes for the booklet: Its contents are defined in booklet.tex. % If you think that the order is not logical and you have ideas for % improvements, please send mail to the current maintainer. -% -% *** ChangeLog: -% 2000-03-26 Felix Natter : -% refcard updated for Gnus 5.8.x: please send corrections or suggestions -% to the above email-address -% changes since 2000-03-26: -% o Create/Edit Foreign Groups: remove S b and S B (not available in 5.8.3) -% o Send/Reply etc.: remove w and W (the only bindings are S w and S W) -% Mon Apr 3 18:41:09 2000: -% o added C-c C-n and C-c C-t (Article) -% o C-c C-a as alias for M-m f (Article) + some other M-m *-bindings -% o added section for ``jumping'' in article-mode -% o now there's a difference between ``reading'' and ``composition'' -% (article-modes) -% Apr 24th, 2000: -% o added D s, D S and D t for nndraft -% o group-mode: i.e. C-u RET does not actually fetch fewer articles; also ,=>; -% Fri Jul 14 23:15:43 2000: -% o added README-section -% Thu Jul 27 20:51:01 2000: -% o added Unplugged-commands -% + % *** TODO: -% o (LaTeX) how can you get 'tabular' to wrap around pages ? % o some things might not be updated: scoring and server modes, maybe more % o Gnus Unplugged category-buffer commands need to be written \begin{document} -\newlength{\logowidth} \setlength{\logowidth}{6.861in} -\newlength{\logoheight} \setlength{\logoheight}{7.013in} \def\progver{5.10}\def\refver{5.10-1} % program and refcard versions -\def\date{Oct 13th, 2001} +\def\date{Mar 23rd, 2002} \def\author{Gnus Bugfixing Girls + Boys $<$bugs@gnus.org$>$} \raggedbottom\raggedright \twocolumn -% use \tiny to shrink it to 4 pages (needs a high-resaoultion printer, though) +% use \tiny to shrink it to 4 pages (needs a high-resolution printer though) %\tiny \scriptsize \pagestyle{plain} @@ -129,13 +113,12 @@ \SortSummary \subsection*{Score (Value) Commands} \Scoring -% - \subsection*{MIME operations from the Summary-Buffer} - \MIMESummary \subsection*{Extract Series (Uudecode etc)} \ExtractSeries \subsection*{Output Articles} \OutputArticles + \subsection*{MIME operations from the Summary-Buffer} + \MIMESummary % \subsection*{Post, Followup, Reply, Forward, Cancel} \PostReplyetc @@ -157,6 +140,7 @@ % \subsection*{Summary-Unplugged} \SummaryUnplugged +\pagebreak \subsection*{Mail-Group Commands} \MailGroups \subsection*{Draft-Group Commands} @@ -170,6 +154,12 @@ \ArticleModeGeneral \subsection*{Wash the Article-Buffer} \WashArticle + \subsubsection*{Blank Lines and Whitespace} + \BlankAndWhitespace + \subsubsection*{Picons, X-faces, Smileys} + \Picons + \subsubsection*{Time and Date} + \TimeAndDate \subsection*{Hide/Highlight Parts of the Article} \HideHighlightArticle \subsection*{MIME operations from the Article-Buffer (reading)} diff --git a/todo b/todo index 5fa540a..92ff87e 100644 --- a/todo +++ b/todo @@ -1,6 +1,20 @@ ;; Also know as the "wish list". Some are done. For the others, no ;; promise when to be implemented. +* gnus-topic-kill-region + From Colin Marquardt + + I noticed that when re-arranging topics, C-k yanks a topic just fine + (runs gnus-topic-kill-group). + + However, my habit is to do marking and the yanking the region, so I + would run C-w on the marked topic. But C-w runs + gnus-group-kill-region and doesn't yank the topic (for groups it + works fine). + + So could we have a gnus-topic-kill-region, or a + gnus-group-kill-region which handles topics as well? + * Speed up sorting in summary buffer if there is a limit. Suggested by Daniel Ortmann .