This commit was generated by cvs2svn to compensate for changes in r4336,
authoryamaoka <yamaoka>
Thu, 11 Jan 2001 22:33:47 +0000 (22:33 +0000)
committeryamaoka <yamaoka>
Thu, 11 Jan 2001 22:33:47 +0000 (22:33 +0000)
which included commits to RCS files with non-trunk default branches.

30 files changed:
README
aclocal.m4
configure
configure.in
etc/gnus-tut.txt
lisp/gnus-audio.el
lisp/gnus-cite.el
lisp/gnus-mlspl.el
lisp/gnus-picon.el
lisp/gnus-vm.el
lisp/imap.el
lisp/mail-source.el
lisp/nnimap.el
lisp/nnslashdot.el
lisp/nnultimate.el
lisp/rfc2045.el
lisp/rfc2104.el
lisp/utf7.el
lisp/webmail.el
mkinstalldirs
texi/gnusref.tex
texi/pagestyle.sty [new file with mode: 0644]
texi/pixidx.sty [new file with mode: 0644]
texi/postamble.tex
texi/ps/gnus-big-logo.eps [new file with mode: 0644]
texi/ps/gnus-head.eps [new file with mode: 0644]
texi/refcard.tex
texi/splitindex [new file with mode: 0755]
texi/xemacs.mak [new file with mode: 0644]
xemacs.mak [new file with mode: 0644]

diff --git a/README b/README
index d99625f..5104634 100644 (file)
--- a/README
+++ b/README
@@ -21,11 +21,13 @@ in your .emacs file, or wherever you keep such things.
 
 To enable reading the Gnus manual, you could say something like:
 
+  (require 'info)
   (setq Info-default-directory-list 
         (cons "~/gnus-5.6.53/texi" Info-default-directory-list))
 
 or
 
+  (require 'info)
   (setq Info-directory-list 
         (cons "~/gnus-5.6.53/texi" Info-directory-list))
 
index 1b62c54..2a7b8d0 100644 (file)
@@ -29,3 +29,116 @@ AC_DEFUN(AM_PATH_LISPDIR,
     AC_MSG_RESULT($lispdir)
   fi
   AC_SUBST(lispdir)])
+
+dnl AC_EMACS_LIST AC_XEMACS_P AC_PATH_LISPDIR and AC_EMACS_CHECK_LIB
+dnl are stolen from w3.
+dnl AC_PATH_LISPDIR obsoletes AM_PATH_LISPDIR.
+
+AC_DEFUN(AC_EMACS_LISP, [
+elisp="$2"
+if test -z "$3"; then
+       AC_MSG_CHECKING(for $1)
+fi
+AC_CACHE_VAL(EMACS_cv_SYS_$1,[
+       OUTPUT=./conftest-$$
+       echo ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x) (prin1-to-string x)) nil \"${OUTPUT}\"))" >& AC_FD_CC 2>&1  
+       ${EMACS} -batch -eval "(let ((x ${elisp})) (write-region (if (stringp x) (princ x 'ignore) (prin1-to-string x)) nil \"${OUTPUT}\"nil 5))" >& AC_FD_CC 2>&1
+       retval=`cat ${OUTPUT}`
+       echo "=> ${retval}" >& AC_FD_CC 2>&1
+       rm -f ${OUTPUT}
+       EMACS_cv_SYS_$1=$retval
+])
+$1=${EMACS_cv_SYS_$1}
+if test -z "$3"; then
+       AC_MSG_RESULT($$1)
+fi
+])
+
+AC_DEFUN(AC_XEMACS_P, [
+  AC_MSG_CHECKING([if $EMACS is really XEmacs])
+  AC_EMACS_LISP(xemacsp,(if (string-match \"XEmacs\" emacs-version) \"yes\" \"no\") ,"noecho")
+  XEMACS=${EMACS_cv_SYS_xemacsp}
+  EMACS_FLAVOR=emacs
+  if test "$XEMACS" = "yes"; then
+     EMACS_FLAVOR=xemacs
+  fi
+  AC_MSG_RESULT($XEMACS)
+  AC_SUBST(XEMACS)
+  AC_SUBST(EMACS_FLAVOR)
+])
+
+AC_DEFUN(AC_PATH_LISPDIR, [
+  AC_XEMACS_P
+  if test "$prefix" = "NONE"; then
+       AC_MSG_CHECKING([prefix for your Emacs])
+       AC_EMACS_LISP(prefix,(expand-file-name \"..\" invocation-directory),"noecho")
+       prefix=${EMACS_cv_SYS_prefix}
+       AC_MSG_RESULT($prefix)
+  fi
+  AC_ARG_WITH(lispdir,[  --with-lispdir=DIR      Where to install lisp files], lispdir=${withval})
+  AC_MSG_CHECKING([where .elc files should go])
+  if test -z "$lispdir"; then
+    dnl Set default value
+    theprefix=$prefix
+    if test "x$theprefix" = "xNONE"; then
+       theprefix=$ac_default_prefix
+    fi
+    lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp"
+    for thedir in share lib; do
+       potential=
+       if test -d ${theprefix}/${thedir}/${EMACS_FLAVOR}/site-lisp; then
+          lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-lisp"
+          break
+       fi
+    done
+  fi
+  AC_MSG_RESULT($lispdir)
+  AC_SUBST(lispdir)
+])
+
+dnl
+dnl Check whether a function exists in a library
+dnl All '_' characters in the first argument are converted to '-'
+dnl
+AC_DEFUN(AC_EMACS_CHECK_LIB, [
+if test -z "$3"; then
+       AC_MSG_CHECKING(for $2 in $1)
+fi
+library=`echo $1 | tr _ -`
+AC_EMACS_LISP($1,(progn (fmakunbound '$2) (condition-case nil (progn (require '$library) (fboundp '$2)) (error (prog1 nil (message \"$library not found\"))))),"noecho")
+if test "${EMACS_cv_SYS_$1}" = "nil"; then
+       EMACS_cv_SYS_$1=no
+fi
+if test "${EMACS_cv_SYS_$1}" = "t"; then
+       EMACS_cv_SYS_$1=yes
+fi
+HAVE_$1=${EMACS_cv_SYS_$1}
+AC_SUBST(HAVE_$1)
+if test -z "$3"; then
+       AC_MSG_RESULT($HAVE_$1)
+fi
+])
+
+dnl
+dnl Perform sanity checking and try to locate the W3 package
+dnl
+AC_DEFUN(AC_CHECK_W3, [
+AC_MSG_CHECKING(for acceptable W3 version)
+AC_CACHE_VAL(EMACS_cv_ACCEPTABLE_W3,[
+AC_EMACS_CHECK_LIB(w3_forms, w3-form-encode-xwfu,"noecho")
+if test "${HAVE_w3_forms}" = "yes"; then
+       EMACS_cv_ACCEPTABLE_W3=yes
+else
+       EMACS_cv_ACCEPTABLE_W3=no
+fi
+
+if test "${EMACS_cv_ACCEPTABLE_W3}" = "yes"; then
+       AC_EMACS_LISP(w3_dir,(file-name-directory (locate-library \"w3-forms\")),"noecho")
+       EMACS_cv_ACCEPTABLE_W3=$EMACS_cv_SYS_w3_dir
+fi
+])
+   AC_ARG_WITH(w3,[  --with-w3=DIR           Specify where to find the w3 package], [ EMACS_cv_ACCEPTABLE_W3=`( cd $withval && pwd || echo "$withval" ) 2> /dev/null` ])
+   W3=${EMACS_cv_ACCEPTABLE_W3}
+   AC_SUBST(W3)
+   AC_MSG_RESULT("${W3}")
+])
index 41263dc..66b39e6 100755 (executable)
--- a/configure
+++ b/configure
 ac_help=
 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-w3=DIR           Specify where to find the w3 package"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -519,7 +527,7 @@ fi
 
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:523: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:531: 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
@@ -575,7 +583,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # 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:579: checking for a BSD compatible install" >&5
+echo "configure:587: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -624,97 +632,275 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-# If set to t, that means we are running in a shell under Emacs.
-  # If you have an Emacs named "t", then use the full path.
-  test "$EMACS" = t && EMACS=
-  # Extract the first word of "emacs xemacs", so it can be a program name with args.
-set dummy emacs xemacs; ac_word=$2
+
+if test "${EMACS}" = "t"; then
+   EMACS=""
+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
+
+# 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
+
+# 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:634: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_EMACS'+set}'`\" = set"; then
+echo "configure:656: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  case "$EMACS" in
-  /*)
-  ac_cv_path_EMACS="$EMACS" # Let the user override the test with a path.
-  ;;
-  *)
+  if test -n "$MAKEINFO"; then
+  ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test.
+else
   IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
   for ac_dir in $PATH; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
-      ac_cv_path_EMACS="$ac_dir/$ac_word"
+      ac_cv_prog_MAKEINFO="makeinfo"
       break
     fi
   done
   IFS="$ac_save_ifs"
-  test -z "$ac_cv_path_EMACS" && ac_cv_path_EMACS="no"
-  ;;
-esac
+  test -z "$ac_cv_prog_MAKEINFO" && ac_cv_prog_MAKEINFO="no"
 fi
-EMACS="$ac_cv_path_EMACS"
-if test -n "$EMACS"; then
-  echo "$ac_t""$EMACS" 1>&6
+fi
+MAKEINFO="$ac_cv_prog_MAKEINFO"
+if test -n "$MAKEINFO"; then
+  echo "$ac_t""$MAKEINFO" 1>&6
 else
   echo "$ac_t""no" 1>&6
 fi
 
-  if test $EMACS != "no"; then
-    echo $ac_n "checking where .elc files should go""... $ac_c" 1>&6
-echo "configure:665: checking where .elc files should go" >&5
-        lispdir="\$(datadir)/emacs/site-lisp"
-    if test "x$prefix" = "xNONE"; then
-      if test -d $ac_default_prefix/share/emacs/site-lisp; then
-       lispdir="\$(prefix)/share/emacs/site-lisp"
-      else
-       if test -d $ac_default_prefix/lib/emacs/site-lisp; then
-         lispdir="\$(prefix)/lib/emacs/site-lisp"
-       fi
-      fi
-    else
-      if test -d $prefix/share/emacs/site-lisp; then
-       lispdir="\$(prefix)/share/emacs/site-lisp"
-      else
-       if test -d $prefix/lib/emacs/site-lisp; then
-         lispdir="\$(prefix)/lib/emacs/site-lisp"
-       fi
-      fi
-    fi
-    echo "$ac_t""$lispdir" 1>&6
-  fi
-  
-# Extract the first word of "makeinfo", so it can be a program name with args.
-set dummy makeinfo; ac_word=$2
+
+# 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:690: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_MAKEINFO'+set}'`\" = set"; then
+echo "configure:686: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_EMACS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  case "$MAKEINFO" in
-  /*)
-  ac_cv_path_MAKEINFO="$MAKEINFO" # Let the user override the test with a path.
-  ;;
-  *)
+  if test -n "$EMACS"; then
+  ac_cv_prog_EMACS="$EMACS" # Let the user override the test.
+else
   IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
   for ac_dir in $PATH; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
-      ac_cv_path_MAKEINFO="$ac_dir/$ac_word"
+      ac_cv_prog_EMACS="emacs"
       break
     fi
   done
   IFS="$ac_save_ifs"
-  test -z "$ac_cv_path_MAKEINFO" && ac_cv_path_MAKEINFO="no"
-  ;;
-esac
+  test -z "$ac_cv_prog_EMACS" && ac_cv_prog_EMACS="xemacs"
 fi
-MAKEINFO="$ac_cv_path_MAKEINFO"
-if test -n "$MAKEINFO"; then
-  echo "$ac_t""$MAKEINFO" 1>&6
+fi
+EMACS="$ac_cv_prog_EMACS"
+if test -n "$EMACS"; then
+  echo "$ac_t""$EMACS" 1>&6
 else
   echo "$ac_t""no" 1>&6
 fi
 
+
+
+  
+  echo $ac_n "checking if $EMACS is really XEmacs""... $ac_c" 1>&6
+echo "configure:716: 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:721: checking for xemacsp" >&5
+fi
+if eval "test \"`echo '$''{'EMACS_cv_SYS_xemacsp'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&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  
+       ${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
+       rm -f ${OUTPUT}
+       EMACS_cv_SYS_xemacsp=$retval
+
+fi
+
+xemacsp=${EMACS_cv_SYS_xemacsp}
+if test -z ""noecho""; then
+       echo "$ac_t""$xemacsp" 1>&6
+fi
+
+  XEMACS=${EMACS_cv_SYS_xemacsp}
+  EMACS_FLAVOR=emacs
+  if test "$XEMACS" = "yes"; then
+     EMACS_FLAVOR=xemacs
+  fi
+  echo "$ac_t""$XEMACS" 1>&6
+  
+  
+
+  if test "$prefix" = "NONE"; then
+       echo $ac_n "checking prefix for your Emacs""... $ac_c" 1>&6
+echo "configure:753: checking prefix for your Emacs" >&5
+       
+elisp="(expand-file-name \"..\" invocation-directory)"
+if test -z ""noecho""; then
+       echo $ac_n "checking for prefix""... $ac_c" 1>&6
+echo "configure:758: checking for prefix" >&5
+fi
+if eval "test \"`echo '$''{'EMACS_cv_SYS_prefix'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&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  
+       ${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
+       rm -f ${OUTPUT}
+       EMACS_cv_SYS_prefix=$retval
+
+fi
+
+prefix=${EMACS_cv_SYS_prefix}
+if test -z ""noecho""; then
+       echo "$ac_t""$prefix" 1>&6
+fi
+
+       prefix=${EMACS_cv_SYS_prefix}
+       echo "$ac_t""$prefix" 1>&6
+  fi
+  # 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:789: checking where .elc files should go" >&5
+  if test -z "$lispdir"; then
+        theprefix=$prefix
+    if test "x$theprefix" = "xNONE"; then
+       theprefix=$ac_default_prefix
+    fi
+    lispdir="\$(datadir)/${EMACS_FLAVOR}/site-lisp"
+    for thedir in share lib; do
+       potential=
+       if test -d ${theprefix}/${thedir}/${EMACS_FLAVOR}/site-lisp; then
+          lispdir="\$(prefix)/${thedir}/${EMACS_FLAVOR}/site-lisp"
+          break
+       fi
+    done
+  fi
+  echo "$ac_t""$lispdir" 1>&6
+  
+
+
+echo $ac_n "checking for acceptable W3 version""... $ac_c" 1>&6
+echo "configure:809: 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
+else
+  
+
+if test -z ""noecho""; then
+       echo $ac_n "checking for w3-form-encode-xwfu in w3_forms""... $ac_c" 1>&6
+echo "configure:817: checking for w3-form-encode-xwfu in w3_forms" >&5
+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:824: checking for w3_forms" >&5
+fi
+if eval "test \"`echo '$''{'EMACS_cv_SYS_w3_forms'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&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  
+       ${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
+       rm -f ${OUTPUT}
+       EMACS_cv_SYS_w3_forms=$retval
+
+fi
+
+w3_forms=${EMACS_cv_SYS_w3_forms}
+if test -z ""noecho""; then
+       echo "$ac_t""$w3_forms" 1>&6
+fi
+
+if test "${EMACS_cv_SYS_w3_forms}" = "nil"; then
+       EMACS_cv_SYS_w3_forms=no
+fi
+if test "${EMACS_cv_SYS_w3_forms}" = "t"; then
+       EMACS_cv_SYS_w3_forms=yes
+fi
+HAVE_w3_forms=${EMACS_cv_SYS_w3_forms}
+
+if test -z ""noecho""; then
+       echo "$ac_t""$HAVE_w3_forms" 1>&6
+fi
+
+if test "${HAVE_w3_forms}" = "yes"; then
+       EMACS_cv_ACCEPTABLE_W3=yes
+else
+       EMACS_cv_ACCEPTABLE_W3=no
+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:868: checking for w3_dir" >&5
+fi
+if eval "test \"`echo '$''{'EMACS_cv_SYS_w3_dir'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&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  
+       ${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
+       rm -f ${OUTPUT}
+       EMACS_cv_SYS_w3_dir=$retval
+
+fi
+
+w3_dir=${EMACS_cv_SYS_w3_dir}
+if test -z ""noecho""; then
+       echo "$ac_t""$w3_dir" 1>&6
+fi
+
+       EMACS_cv_ACCEPTABLE_W3=$EMACS_cv_SYS_w3_dir
+fi
+
+fi
+
+   # 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
+
+   W3=${EMACS_cv_ACCEPTABLE_W3}
+   
+   echo "$ac_t"""${W3}"" 1>&6
+
+
 trap '' 1 2 15
 cat > confcache <<\EOF
 # This file is a shell script that caches the results of configure
@@ -861,9 +1047,13 @@ s%@mandir@%$mandir%g
 s%@SET_MAKE@%$SET_MAKE%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%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%@MAKEINFO@%$MAKEINFO%g
+s%@HAVE_w3_forms@%$HAVE_w3_forms%g
+s%@W3@%$W3%g
 
 CEOF
 EOF
index 675635b..a3610f6 100644 (file)
@@ -1,6 +1,24 @@
 AC_INIT(lisp/gnus.el)
 AC_SET_MAKE
 AC_PROG_INSTALL
-AM_PATH_LISPDIR
-AC_PATH_PROG(MAKEINFO, makeinfo, no)
+
+dnl
+dnl Apparently, if you run a shell window in Emacs, it sets the EMACS
+dnl environment variable to 't'.  Lets undo the damage.
+dnl
+if test "${EMACS}" = "t"; then
+   EMACS=""
+fi
+
+AC_ARG_WITH(xemacs,[  --with-xemacs           Use XEmacs to build], 
+       [ if test "${withval}" = "yes"; then EMACS=xemacs; else EMACS=${withval}; fi ])
+AC_ARG_WITH(emacs,[  --with-emacs            Use Emacs to build], 
+       [ if test "${withval}" = "yes"; then EMACS=emacs; else EMACS=${withval}; fi ])
+AC_CHECK_PROG(MAKEINFO, makeinfo, makeinfo, no)
+
+AC_CHECK_PROG(EMACS, emacs, emacs, xemacs)
+
+AC_PATH_LISPDIR
+AC_CHECK_W3
+
 AC_OUTPUT(Makefile lisp/Makefile texi/Makefile)
index 94e9500..50f90f8 100644 (file)
@@ -1,5 +1,5 @@
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: So you want to use the new Gnus
 Message-ID: <lars-doc1@eyesore.no>
@@ -47,7 +47,7 @@ heart's delight at <URL:http://www.ifi.uio.no/~larsi/larsi.html>.
 ;; Boston, MA 02111-1307, USA.
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: Starting up
 Message-ID: <lars-doc2@eyesore.no>
@@ -76,7 +76,7 @@ the "Foreign groups" article for that.
 
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: Where are all the groups, then?
 Message-ID: <lars-doc3@eyesore.no>
@@ -109,7 +109,7 @@ prompted for groups to subscribe to.)
 
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: I want to read my mail!
 Message-ID: <lars-doc4@eyesore.no>
@@ -147,7 +147,7 @@ these variables and re-start Gnus.
 
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: Foreign newsgroups
 Message-ID: <lars-doc5@eyesore.no>
@@ -170,7 +170,7 @@ the info pages to find out more.
 
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: Low level changes in GNUS, or, Wrong type argument: stringp, nil
 Message-ID: <lars-doc6@eyesore.no>
@@ -198,7 +198,7 @@ with Emacs 18.  It won't even work on Emacsen older than Emacs
 
        
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: How do I re-scan my mail groups?
 Message-ID: <lars-doc8@eyesore.no>
@@ -212,7 +212,7 @@ You can also re-scan all the mail groups by putting them on level 1
 
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: How do I set up virtual newsgroups?
 Message-ID: <lars-doc9@eyesore.no>
@@ -266,7 +266,7 @@ the lines of:
 
 
 From lars Thu Feb 23 23:20:38 1995
-From: larsi@ifi.uio.no (ding)
+From: larsi@gnus.org (ding)
 Date: Fri Feb 24 13:40:45 1995
 Subject: Bugs & stuff
 Message-ID: <lars-doc7@eyesore.no>
@@ -286,9 +286,9 @@ report.
 If I am not able to reproduce the bug, I won't be able to fix it.
 
 I would, of course, prefer that you locate the bug, fix it, and mail
-me the patches, but one can't have everything.
+me the patches, but one can't have everything. 
 
-If you have any questions on usage, the "ding@ifi.uio.no" mailing list
+If you have any questions on usage, the "ding@gnus.org" mailing list
 is where to post the questions.
 
 
index e84c1df..ac959e7 100644 (file)
@@ -1,7 +1,8 @@
 ;;; gnus-audio.el --- Sound effects for Gnus
-;; Copyright (C) 1996 Free Software Foundation
+;; Copyright (C) 1996, 2000 Free Software Foundation
 
 ;; Author: Steven L. Baur <steve@miranova.com>
+;; Keywords: news, mail, multimedia
 
 ;; This file is part of GNU Emacs.
 
 ;; Boston, MA 02111-1307, USA.
 
 ;;; Commentary:
+
 ;; This file provides access to sound effects in Gnus.
-;; Prerelease:  This file is partially stripped to support earcons.el
-;; You can safely ignore most of it until Red Gnus.  **Evil Laugh**
-;;; Code:
+;; This file is partially stripped to support earcons.el.
 
-(when (null (boundp 'running-xemacs))
-  (defvar running-xemacs (string-match "XEmacs\\|Lucid" emacs-version)))
+;;; Code:
 
 (require 'nnheader)
-(eval-when-compile (require 'cl))
 
-(defvar gnus-audio-inline-sound
-  (and (fboundp 'device-sound-enabled-p)
-       (device-sound-enabled-p))
-  "When t, we will not spawn a subprocess to play sounds.")
+(defgroup gnus-audio nil
+  "Playing sound in Gnus."
+  :group 'gnus-visual
+  :group 'multimedia)
 
-(defvar gnus-audio-directory (nnheader-find-etc-directory "sounds")
-  "The directory containing the Sound Files.")
-
-(defvar gnus-audio-au-player "/usr/bin/showaudio"
-  "Executable program for playing sun AU format sound files.")
-
-(defvar gnus-audio-wav-player "/usr/local/bin/play"
-  "Executable program for playing WAV files.")
+(defvar gnus-audio-inline-sound
+  (or (if (fboundp 'device-sound-enabled-p)
+         (device-sound-enabled-p))     ; XEmacs
+      (fboundp 'play-sound))           ; Emacs 21
+  "Non-nil means try to play sounds without using an external program.")
+
+(defcustom gnus-audio-directory (nnheader-find-etc-directory "sounds")
+  "The directory containing the Sound Files."
+  :type '(choice directory (const nil))
+  :group 'gnus-audio)
+
+(defcustom gnus-audio-au-player "/usr/bin/showaudio"
+  "Executable program for playing sun AU format sound files."
+  :group 'gnus-audio
+  :type 'string)
+
+(defcustom gnus-audio-wav-player "/usr/local/bin/play"
+  "Executable program for playing WAV files."
+  :group 'gnus-audio
+  :type 'string)
 
 ;;; The following isn't implemented yet.  Wait for Millennium Gnus.
 ;;(defvar gnus-audio-effects-enabled t
 
 ;;;###autoload
 (defun gnus-audio-play (file)
-  "Play a sound through the speaker."
+  "Play a sound FILE through the speaker."
   (interactive)
   (let ((sound-file (if (file-exists-p file)
                        file
-                     (concat gnus-audio-directory file))))
+                     (expand-file-name file gnus-audio-directory))))
     (when (file-exists-p sound-file)
-      (if gnus-audio-inline-sound
-         (play-sound-file sound-file)
-       (cond ((string-match "\\.wav$" sound-file)
-              (call-process gnus-audio-wav-player
-                            sound-file
-                            0
-                            nil
-                            sound-file))
-             ((string-match "\\.au$" sound-file)
-              (call-process gnus-audio-au-player
-                            sound-file
-                            0
-                            nil
-                            sound-file)))))))
+      (cond ((and gnus-audio-inline-sound
+                (condition-case nil
+                    ;; Even if we have audio, we may fail with the
+                    ;; wrong sort of sound file.
+                    (progn (play-sound-file sound-file)
+                           t)
+                  (error nil))))
+           ;; If we don't have built-in sound, or playing it failed,
+           ;; try with external program.
+           ((equal "wav" (file-name-extension sound-file))
+            (call-process gnus-audio-wav-player
+                          sound-file
+                          0
+                          nil
+                          sound-file))
+           ((equal "au" (file-name-extension sound-file))
+            (call-process gnus-audio-au-player
+                          sound-file
+                          0
+                          nil
+                          sound-file))))))
 
 
 ;;; The following isn't implemented yet, wait for Red Gnus
index 0b7f42f..8bca531 100644 (file)
@@ -1,8 +1,13 @@
-;;; gnus-cite.el --- parse citations in articles for Gnus
+;;; gnus-cite.el --- parse citations in articles for Gnus  -*- coding: iso-latin-1 -*-
+
 ;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
 ;;        Free Software Foundation, Inc.
 
-;; Author: Per Abhiddenware; you can redistribute it and/or modify
+;; Author: Per Abhiddenware
+
+;; 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.
@@ -462,57 +467,63 @@ always hide."
   (gnus-set-format 'cited-closed-text-button t)
   (save-excursion
     (set-buffer gnus-article-buffer)
-    (cond
-     ((gnus-article-check-hidden-text 'cite arg)
-      t)
-     ((gnus-article-text-type-exists-p 'cite)
-      (let ((buffer-read-only nil))
-       (gnus-article-hide-text-of-type 'cite)))
-     (t
       (let ((buffer-read-only nil)
-           (marks (gnus-dissect-cited-text))
+           marks
            (inhibit-point-motion-hooks t)
            (props (nconc (list 'article-type 'cite)
                          gnus-hidden-properties))
-           beg end start)
-       (while marks
-         (setq beg nil
-               end nil)
-         (while (and marks (string= (cdar marks) ""))
-           (setq marks (cdr marks)))
-         (when marks
-           (setq beg (caar marks)))
-         (while (and marks (not (string= (cdar marks) "")))
-           (setq marks (cdr marks)))
-         (when marks
+           (point (point-min))
+           found beg end start)
+       (while (setq point 
+                    (text-property-any point (point-max) 
+                                       'gnus-callback
+                                       'gnus-article-toggle-cited-text))
+         (setq found t)
+         (goto-char point)
+         (gnus-article-toggle-cited-text
+          (get-text-property point 'gnus-data) arg)
+         (forward-line 1)
+         (setq point (point)))
+       (unless found
+         (setq marks (gnus-dissect-cited-text))
+         (while marks
+           (setq beg nil
+                 end nil)
+           (while (and marks (string= (cdar marks) ""))
+             (setq marks (cdr marks)))
+           (when marks
+             (setq beg (caar marks)))
+           (while (and marks (not (string= (cdar marks) "")))
+             (setq marks (cdr marks)))
+           (when marks
            (setq end (caar marks)))
-         ;; Skip past lines we want to leave visible.
-         (when (and beg end gnus-cited-lines-visible)
-           (goto-char beg)
-           (forward-line (if (consp gnus-cited-lines-visible)
-                             (car gnus-cited-lines-visible)
-                           gnus-cited-lines-visible))
-           (if (>= (point) end)
-               (setq beg nil)
-             (setq beg (point-marker))
-             (when (consp gnus-cited-lines-visible)
-               (goto-char end)
-               (forward-line (- (cdr gnus-cited-lines-visible)))
-               (if (<= (point) beg)
-                   (setq beg nil)
+           ;; Skip past lines we want to leave visible.
+           (when (and beg end gnus-cited-lines-visible)
+             (goto-char beg)
+             (forward-line (if (consp gnus-cited-lines-visible)
+                               (car gnus-cited-lines-visible)
+                             gnus-cited-lines-visible))
+             (if (>= (point) end)
+                 (setq beg nil)
+               (setq beg (point-marker))
+               (when (consp gnus-cited-lines-visible)
+                 (goto-char end)
+                 (forward-line (- (cdr gnus-cited-lines-visible)))
+                 (if (<= (point) beg)
+                     (setq beg nil)
                  (setq end (point-marker))))))
-         (when (and beg end)
-           ;; We use markers for the end-points to facilitate later
-           ;; wrapping and mangling of text.
-           (setq beg (set-marker (make-marker) beg)
-                 end (set-marker (make-marker) end))
-           (gnus-add-text-properties beg end props)
-           (goto-char beg)
-           (unless (save-excursion (search-backward "\n\n" nil t))
-             (insert "\n"))
-           (put-text-property
-            (setq start (point-marker))
-            (progn
+           (when (and beg end)
+             ;; We use markers for the end-points to facilitate later
+             ;; wrapping and mangling of text.
+             (setq beg (set-marker (make-marker) beg)
+                   end (set-marker (make-marker) end))
+             (gnus-add-text-properties-when 'article-type nil beg end props)
+             (goto-char beg)
+             (unless (save-excursion (search-backward "\n\n" nil t))
+               (insert "\n"))
+             (put-text-property
+              (setq start (point-marker))
+              (progn
               (gnus-article-add-button
                (point)
                (progn (eval gnus-cited-closed-text-button-line-format-spec)
@@ -520,42 +531,51 @@ always hide."
                `gnus-article-toggle-cited-text
                (list (cons beg end) start))
               (point))
-            'article-type 'annotation)
-           (set-marker beg (point)))))))))
+              'article-type 'annotation)
+             (set-marker beg (point))))))))
 
-(defun gnus-article-toggle-cited-text (args)
-  "Toggle hiding the text in REGION."
+(defun gnus-article-toggle-cited-text (args &optional arg)
+  "Toggle hiding the text in REGION.
+ARG can be nil or a number.  Positive means hide, negative
+means show, nil means toggle."
   (let* ((region (car args))
         (beg (car region))
         (end (cdr region))
         (start (cadr args))
         (hidden
-         (text-property-any
-          beg (1- end)
-          (car gnus-hidden-properties) (cadr gnus-hidden-properties)))
+         (text-property-any beg (1- end) 'article-type 'cite))
         (inhibit-point-motion-hooks t)
         buffer-read-only)
-    (funcall
-     (if hidden
-        'remove-text-properties 'gnus-add-text-properties)
-     beg end gnus-hidden-properties)
-    (save-excursion
-      (goto-char start)
-      (gnus-delete-line)
-      (put-text-property
-       (point)
-       (progn
-        (gnus-article-add-button
-         (point)
-         (progn (eval
-                 (if hidden
-                     gnus-cited-opened-text-button-line-format-spec
-                   gnus-cited-closed-text-button-line-format-spec))
-                (point))
-         `gnus-article-toggle-cited-text
-         args)
-        (point))
-       'article-type 'annotation))))
+    (when (or (null arg)
+             (zerop arg)
+             (and (> arg 0) (not hidden))
+             (and (< arg 0) hidden))
+      (if hidden
+         (gnus-remove-text-properties-when
+          'article-type 'cite beg end 
+          (cons 'article-type (cons 'cite
+                                    gnus-hidden-properties)))
+       (gnus-add-text-properties-when
+        'article-type nil beg end 
+        (cons 'article-type (cons 'cite
+                                  gnus-hidden-properties))))
+      (save-excursion
+       (goto-char start)
+       (gnus-delete-line)
+       (put-text-property
+        (point)
+        (progn
+          (gnus-article-add-button
+           (point)
+           (progn (eval
+                   (if hidden
+                       gnus-cited-opened-text-button-line-format-spec
+                     gnus-cited-closed-text-button-line-format-spec))
+                  (point))
+           `gnus-article-toggle-cited-text
+           args)
+          (point))
+        'article-type 'annotation)))))
 
 (defun gnus-article-hide-citation-maybe (&optional arg force)
   "Toggle hiding of cited text that has an attribution line.
index 73c7e16..46ccc99 100644 (file)
 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
+(eval-when-compile (require 'cl))
 (require 'gnus)
 (require 'gnus-sum)
 (require 'gnus-group)
 (require 'nnmail)
 
 (defvar gnus-group-split-updated-hook nil
-  "Hook called just after nnmail-split-fancy is updated by gnus-group-split-update.")
+  "Hook called just after nnmail-split-fancy is updated by
+gnus-group-split-update.")
 
 (defvar gnus-group-split-default-catch-all-group "mail.misc"
-  "Group used by gnus-group-split and gnus-group-split-update as default catch-all group.")
+  "Group name (or arbitrary fancy split) with default splitting rules.
+Used by gnus-group-split and gnus-group-split-update as a fallback
+split, in case none of the group-based splits matches.")
 
 ;;;###autoload
 (defun gnus-group-split-setup (&optional auto-update catch-all)
@@ -41,7 +45,18 @@ group parameters.
 If AUTO-UPDATE is non-nil (prefix argument accepted, if called
 interactively), it makes sure nnmail-split-fancy is re-computed before
 getting new mail, by adding gnus-group-split-update to
-nnmail-pre-get-new-mail-hook."
+nnmail-pre-get-new-mail-hook.
+
+A non-nil CATCH-ALL replaces the current value of
+gnus-group-split-default-catch-all-group.  This variable is only used
+by gnus-group-split-update, and only when its CATCH-ALL argument is
+nil.  This argument may contain any fancy split, that will be added as
+the last split in a `|' split produced by gnus-group-split-fancy,
+unless overridden by any group marked as a catch-all group.  Typical
+uses are as simple as the name of a default mail group, but more
+elaborate fancy splits may also be useful to split mail that doesn't
+match any of the group-specified splitting rules.  See
+gnus-group-split-fancy for details."
   (interactive "P")
   (setq nnmail-split-methods 'nnmail-split-fancy)
   (when catch-all
@@ -52,12 +67,16 @@ nnmail-pre-get-new-mail-hook."
 
 ;;;###autoload
 (defun gnus-group-split-update (&optional catch-all)
-  "Computes nnmail-split-fancy from group params.
-It does this by calling \(gnus-group-split-fancy nil nil DEFAULTGROUP)."
+  "Computes nnmail-split-fancy from group params and CATCH-ALL, by
+calling (gnus-group-split-fancy nil nil CATCH-ALL).
+
+If CATCH-ALL is nil, gnus-group-split-default-catch-all-group is used
+instead.  This variable is set by gnus-group-split-setup."
   (interactive)
   (setq nnmail-split-fancy
        (gnus-group-split-fancy
-        nil nil (or catch-all gnus-group-split-default-catch-all-group)))
+        nil (null nnmail-crosspost)
+        (or catch-all gnus-group-split-default-catch-all-group)))
   (run-hooks 'gnus-group-split-updated-hook))
 
 ;;;###autoload
@@ -65,13 +84,9 @@ It does this by calling \(gnus-group-split-fancy nil nil DEFAULTGROUP)."
   "Uses information from group parameters in order to split mail.
 See gnus-group-split-fancy for more information.
 
-If no group is defined as catch-all, the value of
-gnus-group-split-default-catch-all-group is used.
-
 gnus-group-split is a valid value for nnmail-split-methods."
   (let (nnmail-split-fancy)
-    (gnus-group-split-update
-     gnus-group-split-default-catch-all-group)
+    (gnus-group-split-update)
     (nnmail-split-fancy)))
 
 ;;;###autoload
@@ -90,11 +105,6 @@ if NO-CROSSPOST is ommitted or nil, a & split will be returned,
 otherwise, a | split, that does not allow crossposting, will be
 returned.
 
-if CATCH-ALL is not nil, and there is no selected group whose
-SPLIT-REGEXP matches the empty string, nor is there a selected group
-whose SPLIT-SPEC is 'catch-all, this group name will be appended to
-the returned SPLIT list, as the last element in a '| SPLIT.
-
 For each selected group, a SPLIT is composed like this: if SPLIT-SPEC
 is specified, this split is returned as-is (unless it is nil: in this
 case, the group is ignored).  Otherwise, if TO-ADDRESS, TO-LIST and/or
@@ -104,6 +114,13 @@ SPLIT-REGEXP is specified, the regexp will be extended so that it
 matches this regexp too, and if SPLIT-EXCLUDE is specified, RESTRICT
 clauses will be generated.
 
+If CATCH-ALL is nil, no catch-all handling is performed, regardless of
+catch-all marks in group parameters.  Otherwise, if there is no
+selected group whose SPLIT-REGEXP matches the empty string, nor is
+there a selected group whose SPLIT-SPEC is 'catch-all, this fancy
+split (say, a group name) will be appended to the returned SPLIT list,
+as the last element of a '| SPLIT.
+
 For example, given the following group parameters:
 
 nnml:mail.bar:
@@ -179,8 +196,12 @@ Calling (gnus-group-split-fancy nil nil \"mail.misc\") returns:
                         (list 'any split-regexp)
                         ;; Generate RESTRICTs for SPLIT-EXCLUDEs.
                         (if (listp split-exclude)
-                            (mapcon (lambda (arg) (cons '- arg))
-                                    split-exclude)
+                            (let ((seq split-exclude)
+                                  res)
+                              (while seq
+                                (push (cons '- (pop seq))
+                                      res))
+                              (apply #'nconc (nreverse res)))
                           (list '- split-exclude))
                         (list group-clean))
                        split)
@@ -189,7 +210,7 @@ Calling (gnus-group-split-fancy nil nil \"mail.misc\") returns:
                    (setq catch-all nil)))))))))
     ;; Add catch-all if not crossposting
     (if (and catch-all no-crosspost)
-       (push split catch-all))
+       (push catch-all split))
     ;; Move it to the tail, while arranging that SPLITs appear in the
     ;; same order as groups.
     (setq split (reverse split))
index c0163fc..856c5f3 100644 (file)
@@ -1,5 +1,7 @@
 ;;; gnus-picon.el --- displaying pretty icons in Gnus
-;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
+
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;;      Free Software Foundation, Inc.
 
 ;; Author: Wes Hardaker <hardaker@ece.ucdavis.edu>
 ;; Keywords: news xpm annotation glyph faces
index c611582..53b741f 100644 (file)
@@ -1,5 +1,7 @@
 ;;; gnus-vm.el --- vm interface for Gnus
-;; Copyright (C) 1994,95,96,97,98,99 Free Software Foundation, Inc.
+
+;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000
+;;     Free Software Foundation, Inc.
 
 ;; Author: Per Persson <pp@gnu.ai.mit.edu>
 ;; Keywords: news, mail
@@ -82,6 +84,7 @@ If N is a negative number, save the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
+  (require 'gnus-art)
   (let ((gnus-default-article-saver 'gnus-summary-save-in-vm))
     (gnus-summary-save-article arg)))
 
index 7aff9c5..dcd3c4b 100644 (file)
 ;;
 ;; imap.el support RFC1730/2060 (IMAP4/IMAP4rev1), implemented IMAP
 ;; extensions are RFC2195 (CRAM-MD5), RFC2086 (ACL), RFC2342
-;; (NAMESPACE), RFC2359 (UIDPLUS), the IMAP-part of RFC2595 (STARTTLS)
-;; (with use of external library starttls.el and program starttls) and
-;; the GSSAPI / kerberos V4 sections of RFC1731 (with use of external
-;; program `imtest').  It also take advantage the UNSELECT extension
-;; in Cyrus IMAPD.
+;; (NAMESPACE), RFC2359 (UIDPLUS), the IMAP-part of RFC2595 (STARTTLS,
+;; LOGINDISABLED) (with use of external library starttls.el and
+;; program starttls) and the GSSAPI / kerberos V4 sections of RFC1731
+;; (with use of external program `imtest').  It also take advantage
+;; the UNSELECT extension in Cyrus IMAPD.
 ;;
 ;; Without the work of John McClary Prevost and Jim Radford this library
 ;; would not have seen the light of day.  Many thanks.
   (autoload 'utf7-encode "utf7")
   (autoload 'utf7-decode "utf7")
   (autoload 'format-spec "format-spec")
-  (autoload 'format-spec-make "format-spec"))
+  (autoload 'format-spec-make "format-spec")
+  ;; Avoid use gnus-point-at-eol so we're independent of Gnus.  These
+  ;; days we have point-at-eol anyhow.
+  (if (fboundp 'point-at-eol)
+      (defalias 'imap-point-at-eol 'point-at-eol)
+    (defun imap-point-at-eol ()
+      (save-excursion
+       (end-of-line)
+       (point)))))
 
 ;; User variables.
 
-(defvar imap-kerberos4-program '("imtest -m kerberos_v4 -u %l -p %p %s"
-                                "imtest -kp %s %p")
+(defgroup imap nil
+  "Low-level IMAP issues."
+  :group 'mail)
+
+(defcustom imap-kerberos4-program '("imtest -m kerberos_v4 -u %l -p %p %s"
+                                   "imtest -kp %s %p")
   "List of strings containing commands for Kerberos 4 authentication.
 %s is replaced with server hostname, %p with port to connect to, and
 %l with the value of `imap-default-user'.  The program should accept
-IMAP commands on stdin and return responses to stdout.")
+IMAP commands on stdin and return responses to stdout.  Each entry in
+the list is tried until a successful connection is made."
+  :group 'imap
+  :type '(repeat string))
 
-(defvar imap-gssapi-program '("imtest -m gssapi -u %l -p %p %s")
+(defcustom imap-gssapi-program '("imtest -m gssapi -u %l -p %p %s")
   "List of strings containing commands for GSSAPI (krb5) authentication.
 %s is replaced with server hostname, %p with port to connect to, and
 %l with the value of `imap-default-user'.  The program should accept
-IMAP commands on stdin and return responses to stdout.")
-
-(defvar imap-ssl-program '("openssl s_client -ssl3 -connect %s:%p"
-                          "openssl s_client -ssl2 -connect %s:%p"
-                          "s_client -ssl3 -connect %s:%p"
-                          "s_client -ssl2 -connect %s:%p")
+IMAP commands on stdin and return responses to stdout.  Each entry in
+the list is tried until a successful connection is made."
+  :group 'imap
+  :type '(repeat string))
+
+(defcustom imap-ssl-program '("openssl s_client -ssl3 -connect %s:%p"
+                             "openssl s_client -ssl2 -connect %s:%p"
+                             "s_client -ssl3 -connect %s:%p"
+                             "s_client -ssl2 -connect %s:%p")
   "A string, or list of strings, containing commands for SSL connections.
 Within a string, %s is replaced with the server address and %p with
 port number on server.  The program should accept IMAP commands on
-stdin and return responses to stdout.")
+stdin and return responses to stdout.  Each entry in the list is tried
+until a successful connection is made."
+  :group 'imap
+  :type '(choice string
+                (repeat string)))
+
+(defcustom imap-shell-program '("ssh %s imapd"
+                               "rsh %s imapd"
+                               "ssh %g ssh %s imapd"
+                               "rsh %g rsh %s imapd")
+  "A list of strings, containing commands for IMAP connection.
+Within a string, %s is replaced with the server address, %p with port
+number on server, %g with `imap-shell-host', and %l with
+`imap-default-user'.  The program should read IMAP commands from stdin
+and write IMAP response to stdout. Each entry in the list is tried
+until a successful connection is made."
+  :group 'imap
+  :type '(repeat string))
+
+(defvar imap-shell-host "gateway"
+  "Hostname of rlogin proxy.")
 
 (defvar imap-default-user (user-login-name)
   "Default username to use.")
@@ -189,7 +227,7 @@ stdin and return responses to stdout.")
 (defvar imap-fetch-data-hook nil
   "Hooks called after receiving each FETCH response.")
 
-(defvar imap-streams '(gssapi kerberos4 starttls ssl network)
+(defvar imap-streams '(gssapi kerberos4 starttls ssl network shell)
   "Priority of streams to consider when opening connection to server.")
 
 (defvar imap-stream-alist
@@ -197,6 +235,7 @@ stdin and return responses to stdout.")
     (kerberos4 imap-kerberos4-stream-p imap-kerberos4-open)
     (ssl       imap-ssl-p              imap-ssl-open)
     (network   imap-network-p          imap-network-open)
+    (shell     imap-shell-p            imap-shell-open)
     (starttls  imap-starttls-p         imap-starttls-open))
   "Definition of network streams.
 
@@ -215,7 +254,7 @@ stream.")
   "Priority of authenticators to consider when authenticating to server.")
 
 (defvar imap-authenticator-alist 
-  '((gssapi     imap-gssapi-auth-p    imap-gssapia-auth)
+  '((gssapi     imap-gssapi-auth-p    imap-gssapi-auth)
     (kerberos4  imap-kerberos4-auth-p imap-kerberos4-auth)
     (cram-md5   imap-cram-md5-p       imap-cram-md5-auth)
     (login      imap-login-p          imap-login-auth)
@@ -260,6 +299,7 @@ encoded mailboxes which doesn't translate into ISO-8859-1.")
                                 imap-failed-tags
                                 imap-tag
                                 imap-process
+                                imap-calculate-literal-size-first
                                 imap-mailbox-data))
 
 ;; Internal variables.
@@ -270,6 +310,7 @@ encoded mailboxes which doesn't translate into ISO-8859-1.")
 (defvar imap-port nil)
 (defvar imap-username nil)
 (defvar imap-password nil)
+(defvar imap-calculate-literal-size-first nil)
 (defvar imap-state 'closed 
   "IMAP state.
 Valid states are `closed', `initial', `nonauth', `auth', `selected'
@@ -328,10 +369,12 @@ human readable response text (a string).")
 The actually value is really the text on the continuation line.")
 
 (defvar imap-log nil
-  "Imap session trace.")
+  "Name of buffer for imap session trace.
+For example: (setq imap-log \"*imap-log*\")")
 
 (defvar imap-debug nil                 ;"*imap-debug*"
-  "Random debug spew.")
+  "Name of buffer for random debug spew.
+For example: (setq imap-debug \"*imap-debug*\")")
 
 \f
 ;; Utility functions:
@@ -400,6 +443,7 @@ If ARGS, PROMPT is used as an argument to `format'."
        cmd done)
     (while (and (not done) (setq cmd (pop cmds)))
       (message "Opening Kerberos 4 IMAP connection with `%s'..." cmd)
+      (erase-buffer)
       (let* ((port (or port imap-default-port))
             (coding-system-for-read imap-coding-system-for-read)
             (coding-system-for-write imap-coding-system-for-write)
@@ -414,7 +458,8 @@ If ARGS, PROMPT is used as an argument to `format'."
             response)
        (when process
          (with-current-buffer buffer
-           (setq imap-client-eol "\n")
+           (setq imap-client-eol "\n"
+                 imap-calculate-literal-size-first t)
            (while (and (memq (process-status process) '(open run))
                        (goto-char (point-min))
                         ;; cyrus 1.6.x (13? < x <= 22) queries capabilities
@@ -442,7 +487,8 @@ If ARGS, PROMPT is used as an argument to `format'."
                   (goto-char (point-max))
                   (insert-buffer-substring buffer)))
            (erase-buffer)
-           (message "Kerberos 4 IMAP connection: %s" (or response "failed"))
+           (message "Opening Kerberos 4 IMAP connection with `%s'...%s" cmd
+                    (if response (concat "done, " response) "failed"))
            (if (and response (let ((case-fold-search nil))
                                (not (string-match "failed" response))))
                (setq done process)
@@ -477,6 +523,10 @@ If ARGS, PROMPT is used as an argument to `format'."
            (setq imap-client-eol "\n")
            (while (and (memq (process-status process) '(open run))
                        (goto-char (point-min))
+                        ;; cyrus 1.6.x (13? < x <= 22) queries capabilities
+                       (or (while (looking-at "^C:")
+                             (forward-line))
+                           t)
                        ;; cyrus 1.6 imtest print "S: " before server greeting
                        (or (not (looking-at "S: "))
                            (forward-char 3)
@@ -548,7 +598,7 @@ If ARGS, PROMPT is used as an argument to `format'."
        (progn
          (message "imap: Opening SSL connection with `%s'...done" cmd)
          done)
-      (message "imap: Failed opening SSL connection")
+         (message "imap: Opening SSL connection with `%s'...failed" cmd)
       nil)))
 
 (defun imap-network-p (buffer)
@@ -574,17 +624,64 @@ If ARGS, PROMPT is used as an argument to `format'."
       (when (memq (process-status process) '(open run))
        process))))
 
+(defun imap-shell-p (buffer)
+  nil)
+
+(defun imap-shell-open (name buffer server port)
+  (let ((cmds imap-shell-program)
+       cmd done)
+    (while (and (not done) (setq cmd (pop cmds)))
+      (message "imap: Opening IMAP connection with `%s'..." cmd)
+      (setq imap-client-eol "\n")
+      (let* ((port (or port imap-default-port))
+            (coding-system-for-read imap-coding-system-for-read)
+            (coding-system-for-write imap-coding-system-for-write)
+            (process (start-process 
+                      name buffer shell-file-name shell-command-switch
+                      (format-spec
+                       cmd
+                       (format-spec-make
+                        ?s server
+                        ?g imap-shell-host
+                        ?p (number-to-string port)
+                        ?l imap-default-user)))))
+       (when process
+         (while (and (memq (process-status process) '(open run))
+                     (goto-char (point-min))
+                     (not (imap-parse-greeting)))
+           (accept-process-output process 1)
+           (sit-for 1))
+         (erase-buffer)
+         (and imap-log
+              (with-current-buffer (get-buffer-create imap-log)
+                (imap-disable-multibyte)
+                (buffer-disable-undo)
+                (goto-char (point-max))
+                (insert-buffer-substring buffer)))
+         (when (memq (process-status process) '(open run))
+           (setq done process)))))
+    (if done
+       (progn
+         (message "imap: Opening IMAP connection with `%s'...done" cmd)
+         done)
+         (message "imap: Opening IMAP connection with `%s'...failed" cmd)
+      nil)))
+
 (defun imap-starttls-p (buffer)
-  (and (condition-case ()
-          (require 'starttls)
-        (error nil))
-       (imap-capability 'STARTTLS buffer)))
+  (and (imap-capability 'STARTTLS buffer)
+       (condition-case ()
+          (progn
+            (require 'starttls)
+            (call-process "starttls"))
+        (error nil))))
 
 (defun imap-starttls-open (name buffer server port)
   (let* ((port (or port imap-default-port))
         (coding-system-for-read imap-coding-system-for-read)
         (coding-system-for-write imap-coding-system-for-write)
-        (process (starttls-open-stream name buffer server port)))
+        (process (starttls-open-stream name buffer server port))
+        done)
+    (message "imap: Connecting with STARTTLS...")
     (when process
       (while (and (memq (process-status process) '(open run))
                  (goto-char (point-min))
@@ -605,7 +702,13 @@ If ARGS, PROMPT is used as an argument to `format'."
                (starttls-negotiate imap-process)))
          (set-process-filter imap-process nil)))
       (when (memq (process-status process) '(open run))
-       process))))
+       (setq done process)))
+    (if done
+       (progn
+         (message "imap: Connecting with STARTTLS...done")
+         done)
+      (message "imap: Connecting with STARTTLS...failed")
+      nil)))
   
 ;; Server functions; authenticator stuff:
 
@@ -651,12 +754,16 @@ Returns t if login was successful, nil otherwise."
   (imap-capability 'AUTH=GSSAPI buffer))
 
 (defun imap-gssapi-auth (buffer)
+  (message "imap: Authenticating using GSSAPI...%s"
+          (if (eq imap-stream 'gssapi) "done" "failed"))
   (eq imap-stream 'gssapi))
 
 (defun imap-kerberos4-auth-p (buffer)
   (imap-capability 'AUTH=KERBEROS_V4 buffer))
 
 (defun imap-kerberos4-auth (buffer)
+  (message "imap: Authenticating using Kerberos 4...%s"
+          (if (eq imap-stream 'kerberos4) "done" "failed"))
   (eq imap-stream 'kerberos4))
 
 (defun imap-cram-md5-p (buffer)
@@ -664,25 +771,33 @@ Returns t if login was successful, nil otherwise."
 
 (defun imap-cram-md5-auth (buffer)
   "Login to server using the AUTH CRAM-MD5 method."
-  (imap-interactive-login
-   buffer
-   (lambda (user passwd)
-     (imap-ok-p
-      (imap-send-command-wait
-       (list
-       "AUTHENTICATE CRAM-MD5"
-       (lambda (challenge)
-         (let* ((decoded (base64-decode-string challenge))
-                (hash (rfc2104-hash 'md5 64 16 passwd decoded))
-                (response (concat user " " hash))
-                (encoded (base64-encode-string response)))
-           encoded))))))))
+  (message "imap: Authenticating using CRAM-MD5...")
+  (let ((done (imap-interactive-login
+              buffer
+              (lambda (user passwd)
+                (imap-ok-p
+                 (imap-send-command-wait
+                  (list
+                   "AUTHENTICATE CRAM-MD5"
+                   (lambda (challenge)
+                     (let* ((decoded (base64-decode-string challenge))
+                            (hash (rfc2104-hash 'md5 64 16 passwd decoded))
+                            (response (concat user " " hash))
+                            (encoded (base64-encode-string response)))
+                       encoded)))))))))
+    (if done
+       (message "imap: Authenticating using CRAM-MD5...done")
+      (message "imap: Authenticating using CRAM-MD5...failed"))))
+      
+  
 
 (defun imap-login-p (buffer)
-  (not (imap-capability 'X-LOGIN-CMD-DISABLED buffer)))
+  (and (not (imap-capability 'LOGINDISABLED buffer))
+       (not (imap-capability 'X-LOGIN-CMD-DISABLED buffer))))
 
 (defun imap-login-auth (buffer)
   "Login to server using the LOGIN command."
+  (message "imap: Plaintext authentication...")
   (imap-interactive-login buffer 
                          (lambda (user passwd)
                            (imap-ok-p (imap-send-command-wait 
@@ -693,19 +808,21 @@ Returns t if login was successful, nil otherwise."
   t)
 
 (defun imap-anonymous-auth (buffer)
+  (message "imap: Loging in anonymously...")
   (with-current-buffer buffer
     (imap-ok-p (imap-send-command-wait
                (concat "LOGIN anonymous \"" (concat (user-login-name) "@" 
                                                     (system-name)) "\"")))))
 
 (defun imap-digest-md5-p (buffer)
-  (and (condition-case ()
+  (and (imap-capability 'AUTH=DIGEST-MD5 buffer)
+       (condition-case ()
           (require 'digest-md5)
-        (error nil))
-       (imap-capability 'AUTH=DIGEST-MD5 buffer)))
+        (error nil))))
 
 (defun imap-digest-md5-auth (buffer)
   "Login to server using the AUTH DIGEST-MD5 method."
+  (message "imap: Authenticating using DIGEST-MD5...")
   (imap-interactive-login
    buffer
    (lambda (user passwd)
@@ -776,37 +893,44 @@ necessery.  If nil, the buffer name is generated."
     (setq imap-port (or port imap-port))
     (setq imap-auth (or auth imap-auth))
     (setq imap-stream (or stream imap-stream))
-    (when (let ((imap-stream (or imap-stream imap-default-stream)))
-           (imap-open-1 buffer))
-      ;; Choose stream.
-      (let (stream-changed)
-       (when (null imap-stream)
-         (let ((streams imap-streams))
-           (while (setq stream (pop streams))
-             (if (funcall (nth 1 (assq stream imap-stream-alist)) buffer)
-                 (setq stream-changed (not (eq (or imap-stream 
-                                                   imap-default-stream)
-                                               stream))
-                       imap-stream stream
-                       streams nil)))
-           (unless imap-stream
-             (error "Couldn't figure out a stream for server"))))
-       (when stream-changed
-         (message "Reconnecting with %s..." imap-stream)
-         (imap-close buffer)
-         (imap-open-1 buffer)
-         (setq imap-capability nil)))
-      (if (imap-opened buffer)
-         ;; Choose authenticator
-         (when (null imap-auth)
-           (let ((auths imap-authenticators))
-             (while (setq auth (pop auths))
-               (if (funcall (nth 1 (assq auth imap-authenticator-alist)) 
-                            buffer)
-                   (setq imap-auth auth
-                         auths nil)))
-             (unless imap-auth
-               (error "Couldn't figure out authenticator for server"))))))
+    (message "imap: Connecting to %s..." imap-server)
+    (if (let ((imap-stream (or imap-stream imap-default-stream)))
+         (imap-open-1 buffer))
+       ;; Choose stream.
+       (let (stream-changed)
+         (message "imap: Connecting to %s...done" imap-server)
+         (when (null imap-stream)
+           (let ((streams imap-streams))
+             (while (setq stream (pop streams))
+               (if (funcall (nth 1 (assq stream imap-stream-alist)) buffer)
+                   (setq stream-changed (not (eq (or imap-stream 
+                                                     imap-default-stream)
+                                                 stream))
+                         imap-stream stream
+                         streams nil)))
+             (unless imap-stream
+               (error "Couldn't figure out a stream for server"))))
+         (when stream-changed
+           (message "imap: Reconnecting with stream `%s'..." imap-stream)
+           (imap-close buffer)
+           (if (imap-open-1 buffer)
+               (message "imap: Reconnecting with stream `%s'...done"
+                        imap-stream)
+             (message "imap: Reconnecting with stream `%s'...failed" 
+                      imap-stream))
+           (setq imap-capability nil))
+         (if (imap-opened buffer)
+             ;; Choose authenticator
+             (when (and (null imap-auth) (not (eq imap-state 'auth)))
+               (let ((auths imap-authenticators))
+                 (while (setq auth (pop auths))
+                   (if (funcall (nth 1 (assq auth imap-authenticator-alist)) 
+                                buffer)
+                       (setq imap-auth auth
+                             auths nil)))
+                 (unless imap-auth
+                   (error "Couldn't figure out authenticator for server"))))))
+      (message "imap: Connecting to %s...failed" imap-server))
     (when (imap-opened buffer)
       (setq imap-mailbox-data (make-vector imap-mailbox-prime 0))
       buffer)))
@@ -828,7 +952,10 @@ user and optionally stored in the buffer.  If USER and/or PASSWD is
 specified, the user will not be questioned and the username and/or
 password is remembered in the buffer."
   (with-current-buffer (or buffer (current-buffer))
-    (when (eq imap-state 'nonauth)
+    (if (not (eq imap-state 'nonauth))
+       (or (eq imap-state 'auth)
+           (eq imap-state 'select)
+           (eq imap-state 'examine))
       (make-variable-buffer-local 'imap-username)
       (make-variable-buffer-local 'imap-password)
       (if user (setq imap-username user))
@@ -1151,6 +1278,18 @@ returned, if ITEMS is a symbol only it's value is returned."
               (list list))
             ","))
 
+(defun imap-range-to-message-set (range)
+  (mapconcat
+   (lambda (item)
+     (if (consp item)
+         (format "%d:%d"
+                 (car item) (cdr item))
+       (format "%d" item)))
+   (if (and (listp range) (not (listp (cdr range))))
+       (list range) ;; make (1 . 2) into ((1 . 2))
+     range)
+   ","))
+
 (defun imap-fetch-asynch (uids props &optional nouidfetch buffer)
   (with-current-buffer (or buffer (current-buffer))
     (imap-send-command (format "%sFETCH %s %s" (if nouidfetch "" "UID ")
@@ -1364,7 +1503,6 @@ on failure."
   "Return number of lines in article by looking at the mime bodystructure BODY."
   (if (listp body)
       (if (stringp (car body))
-          ;; upcase for bug in courier imap server
          (cond ((and (string= (upcase (car body)) "TEXT")
                      (numberp (nth 7 body)))
                 (nth 7 body))
@@ -1408,9 +1546,21 @@ on failure."
        (cond ((stringp cmd)
               (setq cmdstr (concat cmdstr cmd)))
              ((bufferp cmd)
-              (setq cmdstr 
-                    (concat cmdstr (format "{%d}" (with-current-buffer cmd
-                                                    (buffer-size)))))
+              (let ((eol imap-client-eol)
+                    (calcfirst imap-calculate-literal-size-first)
+                    size)
+                (with-current-buffer cmd
+                  (if calcfirst
+                      (setq size (buffer-size)))
+                  (when (not (equal eol "\r\n"))
+                    ;; XXX modifies buffer!
+                    (goto-char (point-min))
+                    (while (search-forward "\r\n" nil t)
+                      (replace-match eol)))
+                  (if (not calcfirst)
+                      (setq size (buffer-size))))
+                (setq cmdstr 
+                      (concat cmdstr (format "{%d}" size))))
               (unwind-protect
                   (progn
                     (imap-send-command-1 cmdstr)
@@ -1421,11 +1571,6 @@ on failure."
                             (stream imap-stream)
                             (eol imap-client-eol))
                         (with-current-buffer cmd
-                          (when (not (equal eol "\r\n"))
-                            ;; XXX modifies buffer!
-                            (goto-char (point-min))
-                            (while (search-forward "\r\n" nil t)
-                              (replace-match eol)))
                           (and imap-log
                                (with-current-buffer (get-buffer-create
                                                      imap-log)
@@ -1458,7 +1603,12 @@ on failure."
                (< imap-reached-tag tag))
       (or (and (not (memq (process-status imap-process) '(open run)))
               (sit-for 1))
-         (accept-process-output imap-process 1)))
+         (let ((len (/ (point-max) 1024))
+               message-log-max)
+           (unless (< len 10)
+             (message "imap read: %dk" len))
+           (accept-process-output imap-process 1))))
+    (message "")
     (or (assq tag imap-failed-tags)
        (if imap-continuation
            'INCOMPLETE
@@ -1855,6 +2005,9 @@ Return nil if no complete line has arrived."
 ;;   resp-text-atom  = 1*<any ATOM-CHAR except "]">
 
 (defun imap-parse-resp-text-code ()
+  ;; xxx next line for stalker communigate pro 3.3.1 bug
+  (when (looking-at " \\[")
+    (imap-forward))
   (when (eq (char-after) ?\[)
     (imap-forward)
     (cond ((search-forward "PERMANENTFLAGS " nil t)
@@ -2075,11 +2228,15 @@ Return nil if no complete line has arrived."
 ;;                       ; revisions of this specification.
 
 (defun imap-parse-flag-list ()
-  (let ((str (buffer-substring (point) (search-forward ")" nil t)))
-       pos)
-    (while (setq pos (string-match "\\\\" str (and pos (+ 2 pos))))
-      (setq str (replace-match "\\\\" nil t str)))
-    (mapcar 'symbol-name (read str))))
+  (let (flag-list start)
+    (assert (eq (char-after) ?\())
+    (while (and (not (eq (char-after) ?\)))
+               (setq start (progn (imap-forward) (point)))
+               (> (skip-chars-forward "^ )" (imap-point-at-eol)) 0))
+      (push (buffer-substring start (point)) flag-list))
+    (assert (eq (char-after) ?\)))
+    (imap-forward)
+    (nreverse flag-list)))
 
 ;;   envelope        = "(" env-date SP env-subject SP env-from SP env-sender SP
 ;;                     env-reply-to SP env-to SP env-cc SP env-bcc SP
@@ -2137,7 +2294,10 @@ Return nil if no complete line has arrived."
           (imap-forward)
           (while (setq str (imap-parse-string))
             (push str strlist)
-            (imap-forward))
+            ;; buggy stalker communigate pro 3.0 doesn't print SPC
+            ;; between body-fld-param's sometimes
+            (or (eq (char-after) ?\")
+                (imap-forward)))
           (nreverse strlist)))
        ((imap-parse-nil)
         nil)))
@@ -2268,6 +2428,11 @@ Return nil if no complete line has arrived."
          (let (subbody)
            (while (and (eq (char-after) ?\()
                        (setq subbody (imap-parse-body)))
+             ;; buggy stalker communigate pro 3.0 insert a SPC between
+             ;; parts in multiparts
+             (when (and (eq (char-after) ?\ )
+                        (eq (char-after (1+ (point))) ?\())
+               (imap-forward))
              (push subbody body))
            (imap-forward)
            (push (imap-parse-string) body);; media-subtype
@@ -2296,7 +2461,10 @@ Return nil if no complete line has arrived."
        (imap-forward)
        (push (imap-parse-nstring) body);; body-fld-desc
        (imap-forward)
-       (push (imap-parse-string) body);; body-fld-enc
+       ;; next `or' for Sun SIMS bug, it regard body-fld-enc as a
+       ;; nstring and return NIL instead of defaulting back to 7BIT
+       ;; as the standard says.
+       (push (or (imap-parse-nstring) "7BIT") body);; body-fld-enc
        (imap-forward)
        (push (imap-parse-number) body);; body-fld-octets
 
@@ -2317,12 +2485,16 @@ Return nil if no complete line has arrived."
                   (push (imap-parse-envelope) body);; envelope
                   (imap-forward)
                   (push (imap-parse-body) body);; body
-                  (imap-forward)
-                  (push (imap-parse-number) body));; body-fld-lines
-                 ((setq lines (imap-parse-number));; body-type-text:
-                  (push lines body));; body-fld-lines
+                  ;; buggy stalker communigate pro 3.0 doesn't print
+                  ;; number of lines in message/rfc822 attachment
+                  (if (eq (char-after) ?\))
+                      (push 0 body)
+                    (imap-forward)
+                    (push (imap-parse-number) body))) ;; body-fld-lines
+                 ((setq lines (imap-parse-number))    ;; body-type-text:
+                  (push lines body))                  ;; body-fld-lines
                  (t
-                  (backward-char)))));; no match...
+                  (backward-char)))))                 ;; no match...
 
        ;; ...and then parse the third one here...
 
index be0cea4..0f3f7a7 100644 (file)
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
+(eval-when-compile
+  (require 'cl)
+  (require 'imap)
+  (eval-when-compile (defvar display-time-mail-function)))
 (eval-and-compile
   (autoload 'pop3-movemail "pop3")
-  (autoload 'pop3-get-message-count "pop3"))
+  (autoload 'pop3-get-message-count "pop3")
+  (autoload 'nnheader-cancel-timer "nnheader")
+  (autoload 'nnheader-run-at-time "nnheader"))
 (require 'format-spec)
+(require 'mm-util)
 
 (defgroup mail-source nil
   "The mail-fetching library."
   :group 'gnus)
 
+;; Define these at compile time to avoid dragging in imap always.
+(defconst mail-source-imap-authenticators
+  (eval-when-compile
+    (mapcar (lambda (a)
+             (list 'const (car a)))
+     imap-authenticator-alist)))
+(defconst mail-source-imap-streams
+  (eval-when-compile
+    (mapcar (lambda (a)
+             (list 'const (car a)))
+     imap-stream-alist)))
+
 (defcustom mail-sources nil
   "*Where the mail backends will look for incoming mail.
-This variable is a list of mail source specifiers."
+This variable is a list of mail source specifiers.
+See Info node `(gnus)Mail Source Specifiers'."
   :group 'mail-source
-  :type 'sexp)
+  :type `(repeat
+         (choice :format "%[Value Menu%] %v"
+                 :value (file)
+                 (cons :tag "Spool file"
+                       (const :format "" file)
+                       (checklist :tag "Options" :greedy t
+                                  (group :inline t
+                                         (const :format "" :value :path)
+                                         file)))
+                 (cons :tag "Several files in a directory"
+                       (const :format "" directory)
+                       (checklist :tag "Options" :greedy t
+                                  (group :inline t
+                                         (const :format "" :value :path)
+                                         (directory :tag "Path"))
+                                  (group :inline t
+                                         (const :format "" :value :suffix)
+                                         (string :tag "Suffix"))
+                                  (group :inline t
+                                         (const :format "" :value :predicate)
+                                         (function :tag "Predicate"))
+                                  (group :inline t
+                                         (const :format "" :value :prescript)
+                                         (string :tag "Prescript"))
+                                  (group :inline t
+                                         (const :format "" :value :postscript)
+                                         (string :tag "Postscript"))
+                                  (group :inline t
+                                         (const :format "" :value :plugged)
+                                         (boolean :tag "Plugged"))))
+                 (cons :tag "POP3 server"
+                       (const :format "" pop)
+                       (checklist :tag "Options" :greedy t
+                                  (group :inline t
+                                         (const :format "" :value :server) 
+                                         (string :tag "Server"))
+                                  (group :inline t
+                                         (const :format "" :value :port) 
+                                         (choice :tag "Port"
+                                                 :value "pop3" 
+                                                 (number :format "%v")
+                                                 (string :format "%v")))
+                                  (group :inline t
+                                         (const :format "" :value :user)
+                                         (string :tag "User"))
+                                  (group :inline t
+                                         (const :format "" :value :password)
+                                         (string :tag "Password"))
+                                  (group :inline t
+                                         (const :format "" :value :program)
+                                         (string :tag "Program"))
+                                  (group :inline t
+                                         (const :format "" :value :prescript)
+                                         (string :tag "Prescript"))
+                                  (group :inline t
+                                         (const :format "" :value :postscript)
+                                         (string :tag "Postscript"))
+                                  (group :inline t
+                                         (const :format "" :value :function)
+                                         (function :tag "Function"))
+                                  (group :inline t
+                                         (const :format "" 
+                                                :value :authentication)
+                                         (choice :tag "Authentication"
+                                                 :value apop
+                                                 (const password)
+                                                 (const apop)))
+                                  (group :inline t
+                                         (const :format "" :value :plugged)
+                                         (boolean :tag "Plugged"))))
+                 (cons :tag "Maildir (qmail, postfix...)"
+                       (const :format "" maildir)
+                       (checklist :tag "Options" :greedy t
+                                  (group :inline t
+                                         (const :format "" :value :path)
+                                         (directory :tag "Path"))
+                                  (group :inline t
+                                         (const :format "" :value :plugged)
+                                         (boolean :tag "Plugged"))))
+                 (cons :tag "IMAP server"
+                       (const :format "" imap)
+                       (checklist :tag "Options" :greedy t
+                                  (group :inline t
+                                         (const :format "" :value :server)
+                                         (string :tag "Server"))
+                                  (group :inline t
+                                         (const :format "" :value :port)
+                                         (choice :tag "Port" 
+                                                 :value 143 
+                                                 number string))
+                                  (group :inline t
+                                         (const :format "" :value :user)
+                                         (string :tag "User"))
+                                  (group :inline t
+                                         (const :format "" :value :password)
+                                         (string :tag "Password"))
+                                  (group :inline t
+                                         (const :format "" :value :stream)
+                                         (choice :tag "Stream"
+                                                 :value network
+                                                 ,@mail-source-imap-streams))
+                                  (group :inline t
+                                         (const :format ""
+                                                :value :authenticator)
+                                         (choice :tag "Authenticator"
+                                                 :value login
+                                                 ,@mail-source-imap-authenticators))
+                                  (group :inline t
+                                         (const :format "" :value :mailbox)
+                                         (string :tag "Mailbox"
+                                                 :value "INBOX"))
+                                  (group :inline t
+                                         (const :format "" :value :predicate)
+                                         (string :tag "Predicate" 
+                                                 :value "UNSEEN UNDELETED"))
+                                  (group :inline t
+                                         (const :format "" :value :fetchflag)
+                                         (string :tag "Fetchflag"
+                                                 :value  "\\Deleted"))
+                                  (group :inline t
+                                         (const :format ""
+                                                :value :dontexpunge)
+                                         (boolean :tag "Dontexpunge"))
+                                  (group :inline t
+                                         (const :format "" :value :plugged)
+                                         (boolean :tag "Plugged"))))
+                 (cons :tag "Webmail server"
+                       (const :format "" webmail)
+                       (checklist :tag "Options" :greedy t
+                                  (group :inline t 
+                                        (const :format "" :value :subtype)
+                                        ;; Should be generated from
+                                        ;; `webmail-type-definition', but we
+                                        ;; can't require webmail without W3.
+                                        (choice :tag "Subtype"
+                                                :value hotmail
+                                                (const hotmail)
+                                                (const yahoo)
+                                                (const netaddress)
+                                                (const netscape)
+                                                (const my-deja)))
+                                  (group :inline t
+                                         (const :format "" :value :user)
+                                         (string :tag "User"))
+                                  (group :inline t
+                                         (const :format "" :value :password)
+                                         (string :tag "Password"))
+                                  (group :inline t
+                                         (const :format ""
+                                                :value :dontexpunge)
+                                         (boolean :tag "Dontexpunge"))
+                                  (group :inline t
+                                         (const :format "" :value :plugged)
+                                         (boolean :tag "Plugged")))))))
 
 (defcustom mail-source-primary-source nil
   "*Primary source for incoming mail.
@@ -62,11 +234,16 @@ If non-nil, this maildrop will be checked periodically for new mail."
   :group 'mail-source
   :type 'integer)
 
-(defcustom mail-source-delete-incoming nil
+(defcustom mail-source-delete-incoming t
   "*If non-nil, delete incoming files after handling."
   :group 'mail-source
   :type 'boolean)
 
+(defcustom mail-source-incoming-file-prefix "Incoming"
+  "Prefix for file name for storing incoming mail"
+  :group 'mail-source
+  :type 'string)
+
 (defcustom mail-source-report-new-mail-interval 5
   "Interval in minutes between checks for new mail."
   :group 'mail-source
@@ -97,7 +274,7 @@ Common keywords should be listed here.")
        (:prescript-delay)
        (:postscript)
        (:path (or (getenv "MAIL")
-                 (concat "/usr/spool/mail/" (user-login-name)))))
+                 (expand-file-name (user-login-name) rmail-spool-directory))))
       (directory
        (:path)
        (:suffix ".spool")
@@ -296,7 +473,8 @@ Pass INFO on to CALLBACK."
          (let ((incoming
                 (mail-source-make-complex-temp-name
                  (expand-file-name
-                  "Incoming" mail-source-directory))))
+                  mail-source-incoming-file-prefix
+                  mail-source-directory))))
            (unless (file-exists-p (file-name-directory incoming))
              (make-directory (file-name-directory incoming) t))
            (rename-file mail-source-crash-box incoming t)))))))
@@ -391,7 +569,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
@@ -478,7 +656,15 @@ If ARGS, PROMPT is used as an argument to `format'."
                    (pop3-port port)
                    (pop3-authentication-scheme
                     (if (eq authentication 'apop) 'apop 'pass)))
-               (save-excursion (pop3-movemail mail-source-crash-box))))))
+               (condition-case err
+                   (save-excursion (pop3-movemail mail-source-crash-box))
+                 (error
+                  ;; We nix out the password in case the error
+                  ;; was because of a wrong password being given.
+                  (setq mail-source-password-cache
+                        (delq (assoc from mail-source-password-cache)
+                              mail-source-password-cache))
+                  (signal (car err) (cdr err))))))))
       (if result
          (progn
            (when (eq authentication 'password)
@@ -529,7 +715,15 @@ If ARGS, PROMPT is used as an argument to `format'."
                    (pop3-port port)
                    (pop3-authentication-scheme
                     (if (eq authentication 'apop) 'apop 'pass)))
-               (save-excursion (pop3-get-message-count))))))
+               (condition-case err
+                   (save-excursion (pop3-get-message-count))
+                 (error
+                  ;; We nix out the password in case the error
+                  ;; was because of a wrong password being given.
+                  (setq mail-source-password-cache
+                        (delq (assoc from mail-source-password-cache)
+                              mail-source-password-cache))
+                  (signal (car err) (cdr err))))))))
       (if result
          ;; Inform display-time that we have new mail.
          (setq mail-source-new-mail-available (> result 0))
@@ -550,7 +744,10 @@ If ARGS, PROMPT is used as an argument to `format'."
 (defvar mail-source-report-new-mail-timer nil)
 (defvar mail-source-report-new-mail-idle-timer nil)
 
-(eval-when-compile (require 'timer))
+(eval-when-compile 
+  (if (featurep 'xemacs)
+      (require 'itimer)
+    (require 'timer)))
 
 (defun mail-source-start-idle-timer ()
   ;; Start our idle timer if necessary, so we delay the check until the
@@ -561,8 +758,8 @@ If ARGS, PROMPT is used as an argument to `format'."
           mail-source-idle-time-delay
           nil
           (lambda ()
-            (setq mail-source-report-new-mail-idle-timer nil)
-            (mail-source-check-pop mail-source-primary-source))))
+            (mail-source-check-pop mail-source-primary-source)
+            (setq mail-source-report-new-mail-idle-timer nil))))
     ;; Since idle timers created when Emacs is already in the idle
     ;; state don't get activated until Emacs _next_ becomes idle, we
     ;; need to force our timer to be considered active now.  We do
@@ -581,19 +778,22 @@ This only works when `display-time' is enabled."
              (> (prefix-numeric-value arg) 0))))
     (setq mail-source-report-new-mail on)
     (and mail-source-report-new-mail-timer
-        (cancel-timer mail-source-report-new-mail-timer))
+        (nnheader-cancel-timer mail-source-report-new-mail-timer))
     (and mail-source-report-new-mail-idle-timer
-        (cancel-timer mail-source-report-new-mail-idle-timer))
+        (nnheader-cancel-timer mail-source-report-new-mail-idle-timer))
     (setq mail-source-report-new-mail-timer nil)
     (setq mail-source-report-new-mail-idle-timer nil)
     (if on
        (progn
          (require 'time)
+         ;; display-time-mail-function is an Emacs 21 feature.
          (setq display-time-mail-function #'mail-source-new-mail-p)
          ;; Set up the main timer.
          (setq mail-source-report-new-mail-timer
-               (run-at-time t (* 60 mail-source-report-new-mail-interval)
-                            #'mail-source-start-idle-timer))
+               (nnheader-run-at-time
+                (* 60 mail-source-report-new-mail-interval)
+                (* 60 mail-source-report-new-mail-interval)
+                #'mail-source-start-idle-timer))
          ;; When you get new mail, clear "Mail" from the mode line.
          (add-hook 'nnmail-post-get-new-mail-hook
                    'display-time-event-handler)
@@ -624,13 +824,16 @@ This only works when `display-time' is enabled."
                                (with-temp-file mail-source-crash-box
                                  (insert-file-contents file)
                                  (goto-char (point-min))
-                                 (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"))
+;;;                               ;; 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"))
                                (delete-file file)))))
              (incf found (mail-source-callback callback file))))))
       found)))
@@ -647,8 +850,12 @@ This only works when `display-time' is enabled."
   (autoload 'imap-error-text "imap")
   (autoload 'imap-message-flags-add "imap")
   (autoload 'imap-list-to-message-set "imap")
+  (autoload 'imap-range-to-message-set "imap")
   (autoload 'nnheader-ms-strip-cr "nnheader"))
 
+(defvar mail-source-imap-file-coding-system 'binary
+  "Coding system for the crashbox made by `mail-source-fetch-imap'.")
+
 (defun mail-source-fetch-imap (source callback)
   "Fetcher for imap sources."
   (mail-source-bind (imap source)
@@ -662,8 +869,12 @@ This only works when `display-time' is enabled."
                user (or (cdr (assoc from mail-source-password-cache))
                         password) buf)
               (imap-mailbox-select mailbox nil buf))
-         (let (str (coding-system-for-write 'binary))
+         (let ((coding-system-for-write mail-source-imap-file-coding-system)
+               str)
            (with-temp-file mail-source-crash-box
+             ;; Avoid converting 8-bit chars from inserted strings to
+             ;; multibyte.
+             (mm-disable-multibyte)
              ;; remember password
              (with-current-buffer buf
                (when (or imap-password
@@ -683,7 +894,8 @@ This only works when `display-time' is enabled."
            (incf found (mail-source-callback callback server))
            (when (and remove fetchflag)
              (imap-message-flags-add
-              (imap-list-to-message-set remove) fetchflag nil buf))
+              (imap-range-to-message-set (gnus-compress-sequence remove))
+              fetchflag nil buf))
            (if dontexpunge
                (imap-mailbox-unselect buf)
              (imap-mailbox-close buf))
index 699ef5d..917f994 100644 (file)
 ;;     .newsrc.eld)
 ;;   o What about Gnus's article editing, can we support it?  NO!
 ;;   o Use \Draft to support the draft group??
+;;   o Duplicate suppression
 
 ;;; Code:
 
 (eval-and-compile
+  (require 'cl)
   (require 'imap))
 
 (require 'nnoo)
@@ -90,7 +92,7 @@ If nil, the first match found will be used.")
   "*Name of mailbox to split mail from.
 
 Mail is read from this mailbox and split according to rules in
-`nnimap-split-rules'.
+`nnimap-split-rule'.
 
 This can be a string or a list of strings.")
 
@@ -281,7 +283,9 @@ restrict visible folders.")
 
 ;; Internal variables:
 
-(defvar nnimap-debug nil);; "*nnimap-debug*")
+(defvar nnimap-debug nil
+  "Name of buffer to record debugging info.
+For example: (setq nnimap-debug \"*nnimap-debug*\")")
 (defvar nnimap-current-move-server nil)
 (defvar nnimap-current-move-group nil)
 (defvar nnimap-current-move-article nil)
@@ -319,15 +323,39 @@ If SERVER is nil, uses the current server."
                     group (gnus-server-to-method
                            (format "nnimap:%s" server))))
         (new-uidvalidity (imap-mailbox-get 'uidvalidity))
-        (old-uidvalidity (gnus-group-get-parameter gnusgroup 'uidvalidity)))
+        (old-uidvalidity (gnus-group-get-parameter gnusgroup 'uidvalidity))
+        (dir (file-name-as-directory (expand-file-name nnimap-directory)))
+         (nameuid (nnheader-translate-file-chars
+                   (concat nnimap-nov-file-name
+                           (if (equal server "")
+                               "unnamed"
+                             server) "." group "." old-uidvalidity
+                             nnimap-nov-file-name-suffix) t))
+         (file (if (or nnmail-use-long-file-names
+                      (file-exists-p (expand-file-name nameuid dir)))
+                  (expand-file-name nameuid dir)
+                (expand-file-name
+                 (mm-encode-coding-string
+                  (nnheader-replace-chars-in-string nameuid ?. ?/)
+                  nnmail-pathname-coding-system)
+                 dir))))
     (if old-uidvalidity
        (if (not (equal old-uidvalidity new-uidvalidity))
-           nil ;; uidvalidity clash
+           ;; uidvalidity clash
+           (gnus-delete-file file)
          (gnus-group-set-parameter gnusgroup 'uidvalidity new-uidvalidity)
          t)
       (gnus-group-add-parameter gnusgroup (cons 'uidvalidity new-uidvalidity))
       t)))
 
+(defun nnimap-before-find-minmax-bugworkaround ()
+  "Function called before iterating through mailboxes with
+`nnimap-find-minmax-uid'."
+  ;; XXX this is for UoW imapd problem, it doesn't notice new mail in
+  ;; currently selected mailbox without a re-select/examine.
+  (or (null (imap-current-mailbox nnimap-server-buffer))
+      (imap-mailbox-unselect nnimap-server-buffer)))
+
 (defun nnimap-find-minmax-uid (group &optional examine)
   "Find lowest and highest active article nummber in GROUP.
 If EXAMINE is non-nil the group is selected read-only."
@@ -385,11 +413,12 @@ If EXAMINE is non-nil the group is selected read-only."
       (with-current-buffer nnimap-server-buffer
        (setq uid imap-current-message
              mbx imap-current-mailbox
-             headers (if (imap-capability 'IMAP4rev1)
-                         ;; xxx don't just use car? alist doesn't contain
-                         ;; anything else now, but it might...
-                         (nth 2 (car (imap-message-get uid 'BODYDETAIL)))
-                       (imap-message-get uid 'RFC822.HEADER))
+             headers (nnimap-demule
+                      (if (imap-capability 'IMAP4rev1)
+                          ;; xxx don't just use car? alist doesn't contain
+                          ;; anything else now, but it might...
+                          (nth 2 (car (imap-message-get uid 'BODYDETAIL)))
+                        (imap-message-get uid 'RFC822.HEADER)))
              lines (imap-body-lines (imap-message-body imap-current-message))
              chars (imap-message-get imap-current-message 'RFC822.SIZE)))
       (nnheader-insert-nov
@@ -413,7 +442,7 @@ If EXAMINE is non-nil the group is selected read-only."
     (if (numberp (car-safe articles))
        (imap-search
         (concat "UID "
-                (nnimap-range-to-string
+                (imap-range-to-message-set
                  (gnus-compress-sequence
                   (append (gnus-uncompress-sequence
                            (and fetch-old
@@ -424,23 +453,53 @@ If EXAMINE is non-nil the group is selected read-only."
                           articles)))))
       (mapcar (lambda (msgid)
                (imap-search
-                (format "HEADER Message-Id %s" msgid)))
+                (format "HEADER Message-Id \"%s\"" msgid)))
              articles))))
 
 (defun nnimap-group-overview-filename (group server)
   "Make pathname for GROUP on SERVER."
-  (let ((dir (file-name-as-directory (expand-file-name nnimap-directory)))
-       (file (nnheader-translate-file-chars
-              (concat nnimap-nov-file-name
-                      (if (equal server "")
-                          "unnamed"
-                        server) "." group nnimap-nov-file-name-suffix) t)))
-    (if (or nnmail-use-long-file-names
-           (file-exists-p (concat dir file)))
-       (concat dir file)
-      (concat dir (mm-encode-coding-string
-                  (nnheader-replace-chars-in-string file ?. ?/)
-                  nnmail-pathname-coding-system)))))
+  (let* ((dir (file-name-as-directory (expand-file-name nnimap-directory)))
+         (uidvalidity (gnus-group-get-parameter
+                       (gnus-group-prefixed-name
+                        group (gnus-server-to-method
+                               (format "nnimap:%s" server)))
+                       'uidvalidity))
+         (name (nnheader-translate-file-chars
+                (concat nnimap-nov-file-name
+                        (if (equal server "")
+                            "unnamed"
+                          server) "." group nnimap-nov-file-name-suffix) t))
+         (nameuid (nnheader-translate-file-chars
+                   (concat nnimap-nov-file-name
+                           (if (equal server "")
+                               "unnamed"
+                             server) "." group "." uidvalidity
+                             nnimap-nov-file-name-suffix) t))
+         (oldfile (if (or nnmail-use-long-file-names
+                          (file-exists-p (expand-file-name name dir)))
+                      (expand-file-name name dir)
+                    (expand-file-name
+                     (mm-encode-coding-string
+                      (nnheader-replace-chars-in-string name ?. ?/)
+                      nnmail-pathname-coding-system)
+                     dir)))
+         (newfile (if (or nnmail-use-long-file-names
+                          (file-exists-p (expand-file-name nameuid dir)))
+                      (expand-file-name nameuid dir)
+                    (expand-file-name
+                     (mm-encode-coding-string
+                      (nnheader-replace-chars-in-string nameuid ?. ?/)
+                      nnmail-pathname-coding-system)
+                     dir))))
+    (when (and (file-exists-p oldfile) (not (file-exists-p newfile)))
+      (message "nnimap: Upgrading novcache filename...")
+      (sit-for 1)
+      (gnus-make-directory (file-name-directory newfile))
+      (unless (ignore-errors (rename-file oldfile newfile) t)
+       (if (ignore-errors (copy-file oldfile newfile) t)
+           (delete-file oldfile)
+         (error "Can't rename `%s' to `%s'" oldfile newfile))))
+    newfile))
 
 (defun nnimap-retrieve-headers-from-file (group server)
   (with-current-buffer nntp-server-buffer
@@ -448,13 +507,11 @@ If EXAMINE is non-nil the group is selected read-only."
       (when (file-exists-p nov)
        (mm-insert-file-contents nov)
        (set-buffer-modified-p nil)
-       (let ((min (progn (goto-char (point-min))
-                         (when (not (eobp))
-                           (read (current-buffer)))))
-             (max (progn (goto-char (point-max))
-                         (forward-line -1)
-                         (when (not (bobp))
-                           (read (current-buffer))))))
+       (let ((min (ignore-errors (goto-char (point-min))
+                                 (read (current-buffer))))
+             (max (ignore-errors (goto-char (point-max))
+                                 (forward-line -1)
+                                 (read (current-buffer)))))
          (if (and (numberp min) (numberp max))
              (cons min max)
            ;; junk, remove it, it's saved later
@@ -466,7 +523,7 @@ If EXAMINE is non-nil the group is selected read-only."
     (let ((imap-fetch-data-hook '(nnimap-retrieve-headers-progress))
          (nnimap-length (gnus-range-length articles))
          (nnimap-counter 0))
-      (imap-fetch (nnimap-range-to-string articles)
+      (imap-fetch (imap-range-to-message-set articles)
                  (concat "(UID RFC822.SIZE BODY "
                          (let ((headers
                                 (append '(Subject From Date Message-Id
@@ -541,8 +598,9 @@ If EXAMINE is non-nil the group is selected read-only."
           (port (if nnimap-server-port
                     (int-to-string nnimap-server-port)
                   "imap"))
-          (alist (or (gnus-netrc-machine list server port "imap")
-                     (gnus-netrc-machine list nnimap-address port "imap")))
+          (alist (gnus-netrc-machine list (or nnimap-server-address 
+                                               nnimap-address server)
+                                      port "imap"))
           (user (gnus-netrc-get alist "login"))
           (passwd (gnus-netrc-get alist "password")))
       (if (imap-authenticate user passwd nnimap-server-buffer)
@@ -568,6 +626,8 @@ If EXAMINE is non-nil the group is selected read-only."
                      (cadr (assq 'nnimap-server-address defs))) defs)
        (push (list 'nnimap-address server) defs)))
     (nnoo-change-server 'nnimap server defs)
+    (with-current-buffer (get-buffer-create nnimap-server-buffer)
+      (nnoo-change-server 'nnimap server defs))
     (or (and nnimap-server-buffer
             (imap-opened nnimap-server-buffer))
        (nnimap-open-connection server))))
@@ -636,11 +696,11 @@ function is generally only called when Gnus is shutting down."
   (when (nnimap-possibly-change-group group server)
     (let ((article (if (stringp article)
                       (car-safe (imap-search
-                                 (format "HEADER Message-Id %s" article)
+                                 (format "HEADER Message-Id \"%s\"" article)
                                  nnimap-server-buffer))
                     article)))
       (when article
-       (gnus-message 9 "nnimap: Fetching (part of) article %d..." article)
+       (gnus-message 10 "nnimap: Fetching (part of) article %d..." article)
        (if (not nnheader-callback-function)
            (with-current-buffer (or to-buffer nntp-server-buffer)
              (erase-buffer)
@@ -650,7 +710,7 @@ function is generally only called when Gnus is shutting down."
                                            (nth 2 (car data))
                                          data))))
               (nnheader-ms-strip-cr)
-             (gnus-message 9 "nnimap: Fetching (part of) article %d...done"
+             (gnus-message 10 "nnimap: Fetching (part of) article %d...done"
                            article)
              (if (bobp)
                  (nnheader-report 'nnimap "No such article: %s"
@@ -693,6 +753,7 @@ function is generally only called when Gnus is shutting down."
                   group (gnus-server-to-method (format "nnimap:%s" server))))
    server)
   (when (nnimap-possibly-change-group group server)
+    (nnimap-before-find-minmax-bugworkaround)
     (let (info)
       (cond (fast group)
            ((null (setq info (nnimap-find-minmax-uid group t)))
@@ -736,6 +797,7 @@ function is generally only called when Gnus is shutting down."
       (erase-buffer))
     (gnus-message 5 "nnimap: Generating active list%s..."
                  (if (> (length server) 0) (concat " for " server) ""))
+    (nnimap-before-find-minmax-bugworkaround)
     (with-current-buffer nnimap-server-buffer
       (dolist (pattern (nnimap-pattern-to-list-arguments nnimap-list-pattern))
        (dolist (mbx (funcall nnimap-request-list-method
@@ -777,6 +839,7 @@ function is generally only called when Gnus is shutting down."
     (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"
@@ -830,6 +893,18 @@ function is generally only called when Gnus is shutting down."
                      (gnus-info-marks info))
                     t)))
                gnus-article-mark-lists)
+
+       ;; 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 
+        (nnimap-update-alist-soft
+         'tick
+         (gnus-remove-from-range
+          (cdr-safe (assoc 'tick (gnus-info-marks info)))
+          (cdr-safe (assoc 'dormant (gnus-info-marks info))))
+         (gnus-info-marks info))
+        t)
        
        (gnus-message 5 "nnimap: Updating info for %s...done"
                      (gnus-info-group info))
@@ -865,15 +940,15 @@ function is generally only called when Gnus is shutting down."
            (when (and range marks)
              (cond ((eq what 'del)
                     (imap-message-flags-del
-                     (nnimap-range-to-string range)
+                     (imap-range-to-message-set range)
                      (nnimap-mark-to-flag marks nil t)))
                    ((eq what 'add)
                     (imap-message-flags-add
-                     (nnimap-range-to-string range)
+                     (imap-range-to-message-set range)
                      (nnimap-mark-to-flag marks nil t)))
                    ((eq what 'set)
                     (imap-message-flags-set
-                     (nnimap-range-to-string range)
+                     (imap-range-to-message-set range)
                      (nnimap-mark-to-flag marks nil t)))))))
        (gnus-message 7 "nnimap: Setting marks in %s...done" group))))
   nil)
@@ -922,7 +997,9 @@ function is generally only called when Gnus is shutting down."
     element))
 
 (defun nnimap-split-find-rule (server inbox)
-  (if (listp (cadar nnimap-split-rule)) ;; extended format?
+  (if (and (listp nnimap-split-rule) (listp (car nnimap-split-rule))
+           (list (cdar nnimap-split-rule)) (listp (cadar nnimap-split-rule)))
+      ;; extended format
       (cadr (nnimap-assoc-match inbox (cdr (nnimap-assoc-match 
                                            server nnimap-split-rule))))
     nnimap-split-rule))
@@ -976,14 +1053,17 @@ function is generally only called when Gnus is shutting down."
       (gnus-message 5 "nnimap: Listing subscribed mailboxes%s%s..."
                    (if (> (length server) 0) " on " "") server)
       (erase-buffer)
+      (nnimap-before-find-minmax-bugworkaround)
       (dolist (pattern (nnimap-pattern-to-list-arguments
                        nnimap-list-pattern))
        (dolist (mbx (imap-mailbox-lsub "*" (car pattern) nil 
                                        nnimap-server-buffer))
-         (or (member-if (lambda (mailbox)
-                          (string= (downcase mailbox) "\\noselect"))
-                        (imap-mailbox-get 'list-flags mbx
-                                          nnimap-server-buffer))
+         (or (catch 'found
+               (dolist (mailbox (imap-mailbox-get 'list-flags mbx
+                                                  nnimap-server-buffer))
+                 (if (string= (downcase mailbox) "\\noselect")
+                     (throw 'found t)))
+               nil)
              (let ((info (nnimap-find-minmax-uid mbx 'examine)))
                (when info
                  (insert (format "\"%s\" %d %d y\n"
@@ -1027,25 +1107,25 @@ function is generally only called when Gnus is shutting down."
       (with-current-buffer nnimap-server-buffer
        (if force
            (and (imap-message-flags-add
-                 (nnimap-range-to-string artseq) "\\Deleted")
+                 (imap-range-to-message-set artseq) "\\Deleted")
                 (setq articles nil))
          (let ((days (or (and nnmail-expiry-wait-function
                               (funcall nnmail-expiry-wait-function group))
                          nnmail-expiry-wait)))
            (cond ((eq days 'immediate)
                   (and (imap-message-flags-add
-                        (nnimap-range-to-string artseq) "\\Deleted")
+                        (imap-range-to-message-set artseq) "\\Deleted")
                        (setq articles nil)))
                  ((numberp days)
                   (let ((oldarts (imap-search
                                   (format "UID %s NOT SINCE %s"
-                                          (nnimap-range-to-string artseq)
+                                          (imap-range-to-message-set artseq)
                                           (nnimap-date-days-ago days))))
                         (imap-fetch-data-hook
                          '(nnimap-request-expire-articles-progress)))
                     (and oldarts
                          (imap-message-flags-add
-                          (nnimap-range-to-string
+                          (imap-range-to-message-set
                            (gnus-compress-sequence oldarts))
                           "\\Deleted")
                          (setq articles (gnus-set-difference
@@ -1085,9 +1165,13 @@ function is generally only called when Gnus is shutting down."
                                             nnimap-current-move-article)
                                            group 'dontcreate nil
                                            nnimap-server-buffer))
-                 ;; turn into rfc822 format (\r\n eol's)
                  (with-current-buffer (current-buffer)
                    (goto-char (point-min))
+                   ;; 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")))
                   ;; this 'or' is for Cyrus server bug
@@ -1117,7 +1201,8 @@ function is generally only called when Gnus is shutting down."
 
 (defun nnimap-acl-get (mailbox server)
   (when (nnimap-possibly-change-server server)
-    (imap-mailbox-acl-get mailbox nnimap-server-buffer)))
+    (and (imap-capability 'ACL nnimap-server-buffer)
+        (imap-mailbox-acl-get mailbox nnimap-server-buffer))))
 
 (defun nnimap-acl-edit (mailbox method old-acls new-acls)
   (when (nnimap-possibly-change-server (cadr method))
@@ -1230,18 +1315,6 @@ sure of changing the value of `foo'."
       (cons (cons key value) (nnimap-remassoc key alist))
     (nnimap-remassoc key alist)))
 
-(defun nnimap-range-to-string (range)
-  (mapconcat
-   (lambda (item)
-     (if (consp item)
-         (format "%d:%d"
-                 (car item) (cdr item))
-       (format "%d" item)))
-   (if (and (listp range) (not (listp (cdr range))))
-       (list range);; make (1 . 2) into ((1 . 2))
-     range)
-   ","))
-
 (when nnimap-debug
   (require 'trace)
   (buffer-disable-undo (get-buffer-create nnimap-debug))
@@ -1250,6 +1323,7 @@ sure of changing the value of `foo'."
          nnimap-possibly-change-server
          nnimap-verify-uidvalidity
          nnimap-find-minmax-uid
+         nnimap-before-find-minmax-bugworkaround
          nnimap-possibly-change-group
          ;;nnimap-replace-whitespace
          nnimap-retrieve-headers-progress
@@ -1303,7 +1377,6 @@ sure of changing the value of `foo'."
          nnimap-mark-permanent-p
          nnimap-remassoc
          nnimap-update-alist-soft
-         nnimap-range-to-string
           )))
 
 (provide 'nnimap)
index 15f1ed6..3762927 100644 (file)
@@ -90,7 +90,7 @@
             (nnslashdot-threaded-retrieve-headers articles group)
           (nnslashdot-sane-retrieve-headers articles group)))
     (search-failed (nnslashdot-lose why))))
-  
+
 (deffoo nnslashdot-threaded-retrieve-headers (articles group)
   (let ((last (car (last articles)))
        (did nil)
          (search-forward " on ")
          (setq date (nnslashdot-date-to-date
                      (buffer-substring (point) (1- (search-forward "<")))))
-         (forward-line 2)
-         (setq lines (count-lines
-                      (point)
-                      (re-search-forward
-                       "A href=\"\\(http://slashdot.org\\)?/article" nil t)))
+         (setq lines (/ (- (point)
+                           (progn (forward-line 1) (point)))
+                        60))
          (push
           (cons
            1
            (forward-line 1)
            (if (looking-at
                 "by <a[^>]+>\\([^<]+\\)</a>[ \t\n]*.*(\\([^)]+\\))")
-               (setq from (concat (nnweb-decode-entities-string (match-string 1))
-                                  " <" (match-string 2) ">"))
-             (looking-at "by \\(.+\\) on ")
-             (setq from (nnweb-decode-entities-string (match-string 1))))
-           (goto-char (- (match-end 0) 5))
+               (progn
+                 (goto-char (- (match-end 0) 5))
+                 (setq from (concat 
+                             (nnweb-decode-entities-string (match-string 1))
+                             " <" (match-string 2) ">")))
+             (setq from "")
+             (when (looking-at "by \\(.+\\) on ")
+               (goto-char (- (match-end 0) 5))
+               (setq from (nnweb-decode-entities-string (match-string 1)))))
            (search-forward " on ")
            (setq date
                  (nnslashdot-date-to-date
     (save-excursion
       (set-buffer nntp-server-buffer)
       (erase-buffer)
-      (dolist (header nnslashdot-headers)
-       (nnheader-insert-nov (cdr header))))
+      (mm-with-unibyte-current-buffer
+       (dolist (header nnslashdot-headers)
+        (nnheader-insert-nov (cdr header)))))
     'nov))
 
 (deffoo nnslashdot-sane-retrieve-headers (articles group)
          (forward-line 1)
          (if (looking-at
               "by <a[^>]+>\\([^<]+\\)</a>[ \t\n]*.*(\\([^)]+\\))")
-             (setq from (concat (nnweb-decode-entities-string (match-string 1))
-                                 " <" (match-string 2) ">"))
-           (looking-at "by \\(.+\\) on ")
-           (setq from (nnweb-decode-entities-string (match-string 1))))
-         (goto-char (- (match-end 0) 5))
+             (progn
+               (goto-char (- (match-end 0) 5))
+               (setq from (concat 
+                           (nnweb-decode-entities-string (match-string 1))
+                           " <" (match-string 2) ">")))
+           (setq from "")
+           (when (looking-at "by \\(.+\\) on ")
+             (goto-char (- (match-end 0) 5))
+             (setq from (nnweb-decode-entities-string (match-string 1)))))
          (search-forward " on ")
          (setq date
                (nnslashdot-date-to-date
     (save-excursion
       (set-buffer nntp-server-buffer)
       (erase-buffer)
-      (dolist (header nnslashdot-headers)
-       (nnheader-insert-nov (cdr header))))
+      (mm-with-unibyte-current-buffer
+       (dolist (header nnslashdot-headers)
+         (nnheader-insert-nov (cdr header)))))
     'nov))
 
 (deffoo nnslashdot-request-group (group &optional server dont-check)
       (save-excursion
        (set-buffer (or buffer nntp-server-buffer))
        (erase-buffer)
-       (insert contents)
-       (goto-char (point-min))
-       (while (re-search-forward "\\(<br>\r?\\)+" nil t)
-         (replace-match "<p>" t t))
-       (goto-char (point-min))
-       (insert "Content-Type: text/html\nMIME-Version: 1.0\n")
-       (insert "Newsgroups: " (caddr (assoc group nnslashdot-groups))
-               "\n")
-       (let ((header (cdr (assq article nnslashdot-headers))))
-         (nnheader-insert-header header))
-       (nnheader-report 'nnslashdot "Fetched article %s" article)
+       (mm-with-unibyte-current-buffer
+         (insert contents)
+         (goto-char (point-min))
+         (while (re-search-forward "\\(<br>\r?\\)+" nil t)
+           (replace-match "<p>" t t))
+         (goto-char (point-min))
+         (insert "Content-Type: text/html\nMIME-Version: 1.0\n")
+         (insert "Newsgroups: " (caddr (assoc group nnslashdot-groups))
+                 "\n")
+         (let ((header (cdr (assq article nnslashdot-headers))))
+           (nnheader-insert-header header))
+         (nnheader-report 'nnslashdot "Fetched article %s" article))
        (cons group article)))))
 
 (deffoo nnslashdot-close-server (&optional server)
                                nnslashdot-groups))
   (nnslashdot-write-groups))
 
+(deffoo nnslashdot-request-close ()
+  (setq nnslashdot-headers nil
+       nnslashdot-groups nil))
+
 (nnoo-define-skeleton nnslashdot)
 
 ;;; Internal functions
 (defun nnslashdot-lose (why)
   (error "Slashdot HTML has changed; please get a new version of nnslashdot"))
 
-(defun nnslashdot-sid-strip (sid)
-  (if (string-match "^00/" sid)
-      (substring sid (match-end 0))
-    sid))
+;(defun nnslashdot-sid-strip (sid)
+;  (if (string-match "^00/" sid)
+;      (substring sid (match-end 0))
+;    sid))
+
+(defalias 'nnslashdot-sid-strip 'identity)
 
 (provide 'nnslashdot)
 
index bf8fcb9..baaf17c 100644 (file)
@@ -1,4 +1,4 @@
-;;; nnultimate.el --- interfacing with the Ultimate Bulletin Board system
+;;; nnultimate.el --- interfacing with the Ultimate Bulletin Board system -*- coding: iso-latin-1 -*-
 ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -56,6 +56,8 @@
 (defvoo nnultimate-groups nil)
 (defvoo nnultimate-headers nil)
 (defvoo nnultimate-articles nil)
+(defvar nnultimate-table-regexp 
+  "postings.*editpost\\|forumdisplay\\|Forum[0-9]+/HTML\\|getbio")
 
 ;;; Interface functions
 
@@ -74,6 +76,8 @@
           (old-total (or (nth 6 entry) 1))
           (furl "forumdisplay.cgi?action=topics&number=%d&DaysPrune=1000")
           (furls (list (concat nnultimate-address (format furl sid))))
+          (nnultimate-table-regexp
+           "postings.*editpost\\|forumdisplay\\|getbio")
           headers article subject score from date lines parent point
           contents tinfo fetchers map elem a href garticles topic old-max
           inc datel table string current-page total-contents pages
              (setq date (substring (car datel) (match-end 0))
                    datel nil))
            (pop datel))
-         (setq date (delete "" (split-string date "[- \n\t\r Â Â Â ]")))
+         (setq date (delete "" (split-string date "[- \n\t\r \81 \81 \81 ]")))
          (if (or (member "AM" date)
                  (member "PM" date))
              (setq date (format "%s %s %s %s"
        "211 %d %d %d %s\n" (cadr elem) 1 (cadr elem)
        (prin1-to-string group))))))
 
+(deffoo nnultimate-request-close ()
+  (setq nnultimate-groups-alist nil
+       nnultimate-groups nil))
+
 (deffoo nnultimate-request-article (article &optional group server buffer)
   (nnultimate-possibly-change-server group server)
   (let ((contents (cdr (assq article nnultimate-articles))))
       ;; the group is entered, there's 2 new articles in topic one
       ;; and 1 in topic three.  Then Gnus article number 8-9 be 5-6
       ;; in topic one and 10 will be the 2 in topic three.
-      (dolist (row (reverse forum-contents))
+      (dolist (row (nreverse forum-contents))
        (setq row (nth 2 row))
        (when (setq a (nnweb-parse-find 'a row))
          (setq subject (car (last (nnweb-text a)))
                     (nth 2 parse))))
     (let ((href (cdr (assq 'href (nth 1 (nnweb-parse-find 'a parse 20)))))
          case-fold-search)
-      (when (and href (string-match
-                      "postings\\|forumdisplay\\|Forum[0-9]+/HTML\\|getbio"
-                      href))
+      (when (and href (string-match nnultimate-table-regexp href))
        t))))
 
 (provide 'nnultimate)
index 1a5950d..70c8c39 100644 (file)
@@ -1,5 +1,6 @@
 ;;; rfc2045.el --- Functions for decoding rfc2045 headers
-;; Copyright (C) 1998,99 Free Software Foundation, Inc.
+
+;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; This file is part of GNU Emacs.
@@ -18,6 +19,9 @@
 ;; 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.
+  
+;; RFC 2045 is: "Multipurpose Internet Mail Extensions (MIME) Part
+;; One:  Format of Internet Message Bodies".
 
 ;;; Commentary:
 
index c7ce5ab..3d45982 100644 (file)
@@ -1,5 +1,5 @@
 ;;; rfc2104.el --- RFC2104 Hashed Message Authentication Codes
-;; Copyright (C) 1998,1999 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <jas@pdc.kth.se>
 ;; Keywords: mail
 ;;; (rfc2104-hash 'md5 64 16 "Jefe" "what do ya want for nothing?")
 ;;; "750c783e6ab0b503eaa86e310a5db738"
 ;;;
+;;; (require 'sha-1)
+;;; (rfc2104-hash 'sha1-encode 64 20 "Jefe" "what do ya want for nothing?")
+;;; "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"
+;;;
 ;;; 64 is block length of hash function (64 for MD5 and SHA), 16 is
 ;;; resulting hash length (16 for MD5, 20 for SHA).
 ;;;
 ;;; Tested with Emacs 20.2 and XEmacs 20.3.
+;;;
+;;; Test case reference: RFC 2202.
 
 ;;; Release history:
 ;;;
@@ -43,6 +49,8 @@
 ;;; 1998-08-26  don't require hexl
 ;;; 1998-09-25  renamed from hmac.el to rfc2104.el, also renamed functions
 ;;; 1999-10-23  included in pgnus
+;;; 2000-08-15  `rfc2104-hexstring-to-bitstring'
+;;; 2000-05-12  added sha-1 example, added test case reference
  
 (eval-when-compile (require 'cl))
 
        (rfc2104-hex-to-int (reverse (append str nil))))
     0))
 
+(defun rfc2104-hexstring-to-bitstring (str)
+  (let (out)
+    (while (< 0 (length str))
+      (push (rfc2104-hex-to-int (substring str -2)) out)
+      (setq str (substring str 0 -2)))
+    (concat out)))
+
 (defun rfc2104-hash (hash block-length hash-length key text)
   (let* (;; if key is longer than B, reset it to HASH(key)
         (key (if (> (length key) block-length) 
     ;; XOR key with ipad/opad into k_ipad/k_opad
     (setq k_ipad (mapcar (lambda (c) (logxor c rfc2104-ipad)) k_ipad))
     (setq k_opad (mapcar (lambda (c) (logxor c rfc2104-opad)) k_opad))
-    ;; perform inner hash
-    (let ((first-round (funcall hash (concat k_ipad text)))
-         de-hexed)
-      (while (< 0 (length first-round))
-       (push (rfc2104-hex-to-int (substring first-round -2)) de-hexed)
-       (setq first-round (substring first-round 0 -2)))
-      ;; perform outer hash
-      (funcall hash (concat k_opad de-hexed)))))
+    ;; perform outer hash
+    (funcall hash (concat k_opad (rfc2104-hexstring-to-bitstring
+                                 ;; perform inner hash
+                                 (funcall hash (concat k_ipad text)))))))
 
 (provide 'rfc2104)
 
index 06416e9..2a5e752 100644 (file)
@@ -4,7 +4,7 @@
 ;; Author: Jon K Hellan <hellan@acm.org>
 ;; Keywords: mail
 
-;; This file is part of GNU Emacs, but the same permissions apply
+;; 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
 ;;; Commentary:
 ;;; UTF-7 - A Mail-Safe Transformation Format of Unicode - RFC 2152
 ;;; This is a transformation format of Unicode that contains only 7-bit
-;;; ASCII octets and is intended to be readable by humans in the limiting 
+;;; ASCII octets and is intended to be readable by humans in the limiting
 ;;; case that the document consists of characters from the US-ASCII
 ;;; repertoire.
-;;; In short, runs of characters outside US-ASCII are encoded as base64 
+;;; In short, runs of characters outside US-ASCII are encoded as base64
 ;;; inside delimiters.
 ;;; A variation of UTF-7 is specified in IMAP 4rev1 (RFC 2060) as the way
 ;;; to represent characters outside US-ASCII in mailbox names in IMAP.
 ;;; This library supports both variants, but the IMAP variation was the
-;;; reason I wrote it. 
-;;; The routines convert UTF-7 -> UTF-16 (16 bit encoding of Unicode) 
-;;; -> current character set, and vice versa. 
+;;; reason I wrote it.
+;;; The routines convert UTF-7 -> UTF-16 (16 bit encoding of Unicode)
+;;; -> current character set, and vice versa.
 ;;; However, until Emacs supports Unicode, the only Emacs character set
 ;;; supported here is ISO-8859.1, which can trivially be converted to/from
 ;;; Unicode.
 ;;; When decoding results in a character outside the Emacs character set,
-;;; an error is thrown. It is up to the application to recover.
+;;; an error is thrown.  It is up to the application to recover.
 
 ;;; Code:
 
 (require 'base64)
+(eval-when-compile (require 'cl))
 
-(defvar utf7-direct-encoding-chars " -%'-*,-[]-}" 
-  "Characters ranges which do not need escaping in UTF-7")
+(defvar utf7-direct-encoding-chars " -%'-*,-[]-}"
+  "Character ranges which do not need escaping in UTF-7.")
 
-(defvar utf7-imap-direct-encoding-chars 
+(defvar utf7-imap-direct-encoding-chars
   (concat utf7-direct-encoding-chars "+\\~")
-  "Characters ranges which do not need escaping in the IMAP variant of UTF-7")
+  "Character ranges which do not need escaping in the IMAP variant of UTF-7.")
 
-(defsubst utf7-imap-get-pad-length (len modulus)         
+(defsubst utf7-imap-get-pad-length (len modulus)
   "Return required length of padding for IMAP modified base64 fragment."
   (mod (- len) modulus))
 
@@ -64,7 +65,7 @@ Use IMAP modification if FOR-IMAP is non-nil."
     (narrow-to-region start end)
     (goto-char start)
     (let ((esc-char (if for-imap ?& ?+))
-         (direct-encoding-chars 
+         (direct-encoding-chars
           (if for-imap utf7-imap-direct-encoding-chars
             utf7-direct-encoding-chars)))
       (while (not (eobp))
@@ -73,7 +74,7 @@ Use IMAP modification if FOR-IMAP is non-nil."
          (insert esc-char)
          (let ((p (point))
                (fc (following-char))
-               (run-length 
+               (run-length
                 (skip-chars-forward (concat "^" direct-encoding-chars))))
            (if (and (= fc esc-char)
                     (= run-length 1))  ; Lone esc-char?
@@ -90,7 +91,7 @@ Use IMAP modification if FOR-IMAP is non-nil."
     (base64-encode-region start (point-max))
     (goto-char start)
     (let ((pm (point-max)))
-      (when for-imap 
+      (when for-imap
        (while (search-forward "/" nil t)
          (replace-match ",")))
       (skip-chars-forward "^= \t\n" pm)
@@ -103,7 +104,7 @@ Use IMAP modification if FOR-IMAP is non-nil."
        (end (point-max)))
     (goto-char start)
     (let* ((esc-pattern (concat "^" (char-to-string (if for-imap ?& ?+))))
-          (base64-chars (concat "A-Za-z0-9+" 
+          (base64-chars (concat "A-Za-z0-9+"
                                 (char-to-string (if for-imap ?, ?/)))))
       (while (not (eobp))
        (skip-chars-forward esc-pattern)
@@ -159,7 +160,7 @@ Characters are in raw byte pairs in narrowed buffer."
     (forward-char)))
 
 (defun utf7-encode (string &optional for-imap)
-  "Encode UTF-7 string. Use IMAP modification if FOR-IMAP is non-nil."
+  "Encode UTF-7 STRING.  Use IMAP modification if FOR-IMAP is non-nil."
   (let ((default-enable-multibyte-characters nil))
     (with-temp-buffer
       (insert string)
@@ -167,7 +168,7 @@ Characters are in raw byte pairs in narrowed buffer."
       (buffer-string))))
 
 (defun utf7-decode (string &optional for-imap)
-  "Decode UTF-7 string. Use IMAP modification if FOR-IMAP is non-nil."
+  "Decode UTF-7 STRING.  Use IMAP modification if FOR-IMAP is non-nil."
   (let ((default-enable-multibyte-characters nil))
     (with-temp-buffer
       (insert string)
index 2110624..d947ca0 100644 (file)
@@ -77,8 +77,8 @@
      (login-url
       "http://%s/cgi-bin/dologin?login=%s&passwd=%s&enter=Sign+in&sec=no&curmbox=ACTIVE&_lang=&js=yes&id=2&tw=-10000&beta="
       webmail-aux user password)
-     (login-snarf . webmail-hotmail-login)
-     (list-url "%s" webmail-aux)
+     ;;(login-snarf . webmail-hotmail-login)
+     ;;(list-url "%s" webmail-aux)
      (list-snarf . webmail-hotmail-list)
      (article-snarf . webmail-hotmail-article)
      (trash-url 
      (login-url
       content 
       ("http://ureg.netscape.com/iiop/UReg2/login/loginform")
-      "%s&U2_USERNAME=%s&U2_PASSWORD=%s"
-      webmail-aux user password)
+      "U2_USERNAME=%s&U2_PASSWORD=%s%s"
+      user password webmail-aux)
      (login-snarf . webmail-netaddress-login)
      (list-url 
       "http://webmail.netscape.com/tpl/Mail/%s/List?FolderID=-4&SortUseCase=True"
     (my-deja
      (paranoid cookie post)
      (address . "www.my-deja.com")
-     (open-url "http://www.my-deja.com/")
+     (open-url "http://www.deja.com/my/pr.xp")
      (open-snarf . webmail-my-deja-open)
      (login-url
       content 
      (list-url "http://www.deja.com/rg_gotomail.xp")
      (list-snarf . webmail-my-deja-list)
      (article-snarf . webmail-my-deja-article)
-     (trash-url 
-      "%s/gmm_multiplex.femail?%%2Fgmm_domovemesg_top.femail=Move+to%%3A&folder_top=%s%%3Azzz%%3A%%7E6trash%%3AF%%3A0&docid=%s"
-      webmail-aux user id))))
+     (trash-url webmail-aux id))))
 
 (defvar webmail-variables
   '(address article-snarf article-url list-snarf list-url 
 (defun webmail-error (str)
   (if webmail-error-function
       (funcall webmail-error-function str))
-  (message "%s HTML has changed; please get a new version of webmail (%s)"
+  (message "%s HTML has changed or your w3 package is too old.(%s)"
           webmail-type str)
-  (error "%s HTML has changed; please get a new version of webmail (%s)"
+  (error "%s HTML has changed or your w3 package is too old.(%s)"
         webmail-type str))
 
 (defun webmail-setdefault (type)
       (webmail-fetch-form (car xurl) (webmail-eval (cdr xurl))))
      (t
       (nnweb-insert (apply 'format (webmail-eval xurl)))))))
-  
+
 (defun webmail-init ()
   "Initialize buffers and such."
   (if (gnus-buffer-live-p webmail-buffer)
       (set-buffer webmail-buffer)
     (setq webmail-buffer
-         (mm-with-unibyte
-           (nnheader-set-temp-buffer " *webmail*")))))
+         (nnheader-set-temp-buffer " *webmail*"))
+    (mm-disable-multibyte)))
 
 (defvar url-package-name)
 (defvar url-package-version)
   "Redirect refresh url in META."
   (goto-char (point-min))
   (while (re-search-forward 
-         "HTTP-EQUIV=\"Refresh\"[^>]*URL=\\([^\"]+\\)\""
+         "<meta[ \t\r\n]*http-equiv=\"Refresh\"[^>]*URL=\\([^\"]+\\)\""
          nil t)
     (let ((url (match-string 1)))
       (erase-buffer)
          (url-confirmation-func (if (memq 'post webmail-paranoid)
                                     'webmail-url-confirmation-func
                                   url-confirmation-func))
+         (url-http-silence-on-insecure-redirection t)
          url-cookie-storage url-cookie-secure-storage
          url-cookie-confirmation
          item id (n 0))
       (webmail-error "login@1"))
     (goto-char (point-min))
     (if (re-search-forward 
-        "\\(/cgi-bin/HoTMaiL\\?[^\"]*curmbox=ACTIVE[^\"]*\\)" nil t)
+        "\\(/cgi-bin/HoTMaiL\\?[^\"]*a=b[^\"]*\\)" nil t)
        (setq webmail-aux (concat "http://" site (match-string 1)))
       (webmail-error "login@2"))))
 
 (defun webmail-hotmail-list ()
-  (let (site url newp)
-    (goto-char (point-min))
-    (if (re-search-forward "[0-9]+ new" nil t) 
-       (message "Found %s" (match-string 0))
-      (webmail-error "maybe your w3 version is too old"))
-    (goto-char (point-min))
-    (if (re-search-forward 
+  (goto-char (point-min))
+  (skip-chars-forward " \t\n\r")
+  (let (site url newp (total "0"))
+    (if (eobp)
+       (setq total "0")
+      (if (re-search-forward "\\([0-9]+\\) *<b>(\\([0-9]+\\) new)" nil t) 
+         (message "Found %s (%s new)" (setq total (match-string 1)) 
+                  (match-string 2))
+       (if (re-search-forward "\\([0-9]+\\) new" nil t) 
+           (message "Found %s new" (setq total (match-string 1)))
+         (webmail-error "list@0"))))
+    (unless (equal total "0")
+      (goto-char (point-min))
+      (if (re-search-forward 
         "https?://\\([^/]+hotmail\\.msn\\.com\\)/cgi-bin/" nil t)
-       (setq site (match-string 1))
-      (webmail-error "list@1"))
-    (goto-char (point-min))
-    (if (re-search-forward "disk=\\([^&]+\\)&" nil t)
-       (setq webmail-aux 
-             (concat "http://" site "/cgi-bin/HoTMaiL?disk=" 
-                     (match-string 1)))
-      (webmail-error "list@2"))
-    (goto-char (point-max))
-    (while (re-search-backward 
-           "newmail\\.gif\\|href=\"\\(/cgi-bin/getmsg\\?[^\"]+\\)\"" 
-           nil t)
-      (if (setq url (match-string 1))
-         (progn
-           (if (or newp (not webmail-newmail-only))
-               (let (id)
-                 (if (string-match "msg=\\([^&]+\\)" url)
-                     (setq id (match-string 1 url)))
-                 (push (cons id (concat "http://" site url "&raw=0")) 
-                       webmail-articles)))
-           (setq newp nil))
-       (setq newp t)))))
+         (setq site (match-string 1))
+       (webmail-error "list@1"))
+      (goto-char (point-min))
+      (if (re-search-forward "disk=\\([^&]*\\)&" nil t)
+         (setq webmail-aux 
+               (concat "http://" site "/cgi-bin/HoTMaiL?disk=" 
+                       (match-string 1)))
+       (webmail-error "list@2"))
+      (goto-char (point-max))
+      (while (re-search-backward 
+             "newmail\\.gif\\|href=\"\\(/cgi-bin/getmsg\\?[^\"]+\\)\"" 
+             nil t)
+       (if (setq url (match-string 1))
+           (progn
+             (if (or newp (not webmail-newmail-only))
+                 (let (id)
+                   (if (string-match "msg=\\([^&]+\\)" url)
+                       (setq id (match-string 1 url)))
+                   (push (cons id (concat "http://" site url "&raw=0")) 
+                         webmail-articles)))
+             (setq newp nil))
+         (setq newp t))))))
 
 ;; Thank victor@idaccr.org (Victor S. Miller) for raw=0
 
 (defun webmail-hotmail-article (file id)
   (goto-char (point-min))
-  (if (not (search-forward "<pre>" nil t))
-      (webmail-error "article@3"))
-  (skip-chars-forward "\n\r\t ")
-  (delete-region (point-min) (point))
-  (if (not (search-forward "</pre>" nil t))
-      (webmail-error "article@3.1"))
-  (delete-region (match-beginning 0) (point-max))
-  (nnweb-remove-markup)
-  (let ((w3-html-entities (cons '(nbsp . 32) w3-html-entities)))
-    (nnweb-decode-entities))
-  (goto-char (point-min))
-  (while (re-search-forward "\r\n?" nil t)
-    (replace-match "\n"))
-  (goto-char (point-min))
-  (insert "\n\n")
-  (if (not (looking-at "\n*From "))
-      (insert "From nobody " (current-time-string) "\n"))
-  (mm-append-to-file (point-min) (point-max) file))
+  (skip-chars-forward " \t\n\r")
+  (unless (eobp) 
+    (if (not (search-forward "<pre>" nil t))
+       (webmail-error "article@3"))
+    (skip-chars-forward "\n\r\t ")
+    (delete-region (point-min) (point))
+    (if (not (search-forward "</pre>" nil t))
+       (webmail-error "article@3.1"))
+    (delete-region (match-beginning 0) (point-max))
+    (nnweb-remove-markup)
+    (let ((w3-html-entities (cons '(nbsp . 32) w3-html-entities)))
+      (nnweb-decode-entities))
+    (goto-char (point-min))
+    (while (re-search-forward "\r\n?" nil t)
+      (replace-match "\n"))
+    (goto-char (point-min))
+    (insert "\n\n")
+    (if (not (looking-at "\n*From "))
+       (insert "From nobody " (current-time-string) "\n")
+      (forward-line))
+    (insert "X-Gnus-Webmail: " (symbol-value 'user)
+           "@" (symbol-name webmail-type) "\n")
+    (mm-append-to-file (point-min) (point-max) file)))
 
 (defun webmail-hotmail-article-old (file id)
   (let (p attachment count mime hotmail-direct)
       (goto-char (point-min))
       ;; Some blank line to seperate mails.
       (insert "\n\nFrom nobody " (current-time-string) "\n")
+      (insert "X-Gnus-Webmail: " (symbol-value 'user)
+             "@" (symbol-name webmail-type) "\n")
       (if id
-         (insert (format "Message-ID: <%s@hotmail.com>\n" id)))
+         (insert (format "X-Message-ID: <%s@hotmail.com>\n" id)))
       (unless (looking-at "$") 
        (if (search-forward "\n\n" nil t)
            (forward-line -1)
       (goto-char (point-min))
       ;; Some blank line to seperate mails.
       (insert "\n\nFrom nobody " (current-time-string) "\n")
+      (insert "X-Gnus-Webmail: " (symbol-value 'user)
+             "@" (symbol-name webmail-type) "\n")
       (if id
-         (insert (format "Message-ID: <%s@yahoo.com>\n" id)))
+         (insert (format "X-Message-ID: <%s@yahoo.com>\n" id)))
       (unless (looking-at "$") 
        (if (search-forward "\n\n" nil t)
            (forward-line -1)
 
 (defun webmail-netscape-open ()
   (goto-char (point-min))
-  (if (re-search-forward "login/hint\\?\\([^\"]+\\)\"" nil t)
-      (setq webmail-aux (match-string 1))
-    (webmail-error "open@1")))
+  (setq webmail-aux "")
+  (while (re-search-forward 
+         "TYPE=hidden *NAME=\\([^ ]+\\) *VALUE=\"\\([^\"]+\\)" 
+         nil t)
+    (setq webmail-aux (concat webmail-aux "&" (match-string 1) "="
+                             (match-string 2)))))
 
 (defun webmail-netaddress-open ()
   (goto-char (point-min))
       (goto-char (point-min))
       ;; Some blank line to seperate mails.
       (insert "\n\nFrom nobody " (current-time-string) "\n")
+      (insert "X-Gnus-Webmail: " (symbol-value 'user)
+             "@" (symbol-name webmail-type) "\n")
       (if id
-         (insert (format "Message-ID: <%s@%s>\n" id webmail-address)))
+         (insert (format "X-Message-ID: <%s@%s>\n" id webmail-address)))
       (unless (looking-at "$") 
        (if (search-forward "\n\n" nil t)
            (forward-line -1)
       (goto-char (point-min))
       ;; Some blank line to seperate mails.
       (insert "\n\nFrom nobody " (current-time-string) "\n")
+      (insert "X-Gnus-Webmail: " (symbol-value 'user)
+             "@" (symbol-name webmail-type) "\n")
       (if id
-         (insert (format "Message-ID: <%s@%s>\n" id webmail-address)))
+         (insert (format "X-Message-ID: <%s@%s>\n" id webmail-address)))
       (unless (looking-at "$") 
        (if (search-forward "\n\n" nil t)
            (forward-line -1)
     (webmail-error "open@1")))
 
 (defun webmail-my-deja-list ()
-  (let (item id newp)
+  (let (item id newp base)
+    (goto-char (point-min))
+    (when (re-search-forward "href=\"\\(\\([^\"]*\\)/mailnf\\.[^\"]*\\)\"" 
+                            nil t)
+      (let ((url (match-string 1)))
+       (setq base (match-string 2))
+       (erase-buffer)
+       (nnweb-insert url)))
     (goto-char (point-min))
     (when (re-search-forward 
-          "(\\([0-9]+\\) message(s), \\([0-9]+\\) new, \\([0-9]+\\)&nbsp;k )"
+          "(\\([0-9]+\\) Message.?-[^>]*\\([0-9]+\\) New"
           nil t) 
-      (message "Found %s mail(s), %s unread, total size %s K" 
-              (match-string 1) (match-string 2) (match-string 3)))
+      (message "Found %s mail(s), %s unread" 
+              (match-string 1) (match-string 2)))
     (goto-char (point-min))
     (while (re-search-forward 
-           "&#149; &nbsp;&nbsp;\\|\\(http:[^\"]+\\)/display_seemesg\\.femail\\?docid=\\([^&\"]+\\)"
+           "newmail\\.gif\\|href=\"[^\"]*\\(mailnf\\.[^\"]+act=view[^\"]+mid=\\([^\"&]+\\)[^\"]+\\)\""
            nil t)
       (if (setq id (match-string 2))
-         (when (or newp (not webmail-newmail-only))
-           (push
-            (cons id (format "%s/gmm_multiplex.femail?docid=%s&femail_page_name=display_page&bool_next_on_disp_pg=true&bool_prev_on_disp_pg=false&display_all_headers=false&%%2Fgmm_save.femail=Download&femail_page_name=display_page&bool_next_on_disp_pg=true&bool_prev_on_disp_pg=false&display_all_headers=false"
-                             (match-string 1) id))
-            webmail-articles)
-           (setq webmail-aux (match-string 1))
+         (when (and (or newp (not webmail-newmail-only))
+                    (not (assoc id webmail-articles)))
+           (push (cons id (setq webmail-aux 
+                                (concat base "/" (match-string 1))))
+                 webmail-articles)
            (setq newp nil))
        (setq newp t)))
     (setq webmail-articles (nreverse webmail-articles))))
 
+(defun webmail-my-deja-article-part (base)
+  (let (p)
+    (cond 
+     ((looking-at "[\t\040\r\n]*<!--[^>]*>")
+      (replace-match ""))
+     ((looking-at "[\t\040\r\n]*</PRE>")
+      (replace-match ""))
+     ((looking-at "[\t\040\r\n]*<PRE>")
+      ;; text/plain
+      (replace-match "")
+      (save-restriction
+       (narrow-to-region (point)
+                         (if (re-search-forward "</?PRE>" nil t)
+                             (match-beginning 0)
+                           (point-max)))
+       (goto-char (point-min))
+       (nnweb-remove-markup)
+       (let ((w3-html-entities (cons '(nbsp . 32) w3-html-entities)))
+         (nnweb-decode-entities))
+       (goto-char (point-max))))
+     ((looking-at "[\t\040\r\n]*<TABLE")
+      (save-restriction
+       (narrow-to-region (point)
+                         (if (search-forward "</TABLE>" nil t 2)
+                             (point)
+                           (point-max)))
+       (goto-char (point-min))
+       (let (name type url bufname)
+         (if (and (search-forward "File Name:" nil t)
+                  (re-search-forward "<FONT[^>]+>\\([^<]+\\)" nil t))
+             (setq name (match-string 1)))
+         (if (and (search-forward "File Type:" nil t)
+                  (re-search-forward "<FONT[^>]+>\\([^<]+\\)" nil t))
+             (setq type (match-string 1)))
+         (unless (re-search-forward "action=\"getattach\\.cgi/\\([^\"]+\\)" 
+                                    nil t)
+           (webmail-error "article@5"))
+         (setq url (concat base "/getattach.cgi/" (match-string 1)
+                           "?sm=Download"))
+         (while (re-search-forward 
+                 "type=hidden name=\"\\([^\"]+\\)\" value=\"\\([^\"]+\\)" 
+                 nil t)
+           (setq url (concat url "&" (match-string 1) "="
+                                 (match-string 2))))
+         (delete-region (point-min) (point-max))
+         (save-excursion
+           (set-buffer (generate-new-buffer " *webmail-att*"))
+           (nnweb-insert url)
+           (push (current-buffer) webmail-buffer-list)
+           (setq bufname (buffer-name)))
+         (insert "<#part type=\"" type "\"")
+         (if name (insert " filename=\"" name "\""))
+         (insert " buffer=\"" bufname "\"")
+         (insert " disposition=inline><#/part>"))))
+     (t
+      (insert "<#part type=\"text/html\" disposition=inline>")
+      (goto-char (point-max))
+      (insert "<#/part>")))))
+
 (defun webmail-my-deja-article (file id)
-  (let (url)
+  (let (base)
     (goto-char (point-min))
-    (unless (re-search-forward "\\(http:[^\"]+/attachment/entire_message.txt[^\"]+\\)" nil t)
+    (unless (string-match "\\([^\"]+\\)/mail" webmail-aux)
+      (webmail-error "article@0"))
+    (setq base (match-string 1 webmail-aux))
+    (when (re-search-forward 
+          "href=\"[^\"]*\\(mailnf\\.[^\"]+act=move[^\"]+mid=\\([^\"&]+\\)[^\"]+\\)\""
+          nil t)
+      (setq webmail-aux (concat base "/" (match-string 1)))
+      (string-match "mid=[^\"&]+" webmail-aux)
+      (setq webmail-aux (replace-match "mid=%s" nil nil webmail-aux)))
+    (unless (search-forward "<HR noshade>" nil t)
       (webmail-error "article@1"))
-    (setq url (match-string 1))
-    (erase-buffer)
-    (mm-with-unibyte-current-buffer
-      (nnweb-insert url))
-    (goto-char (point-min))
-    (while (search-forward "\r\n" nil t)
-      (replace-match "\n"))
+    (delete-region (point-min) (point))
+    (unless (search-forward "<HR noshade>" nil t)
+      (webmail-error "article@2"))
+    (save-restriction
+      (narrow-to-region (point-min) (point))
+      (while (search-forward "\r\n" nil t)
+       (replace-match "\n"))
+      (nnweb-remove-markup)
+      (let ((w3-html-entities (cons '(nbsp . 32) w3-html-entities)))
+       (nnweb-decode-entities))
+      (goto-char (point-min))
+      (while (re-search-forward "\n\n+" nil t)
+       (replace-match "\n"))
+      (goto-char (point-max)))
+    (save-restriction
+      (narrow-to-region (point) (point-max))
+      (goto-char (point-max))
+      (unless (search-backward "<HR noshade>" nil t)
+       (webmail-error "article@3"))
+      (unless (search-backward "</TT>" nil t)
+       (webmail-error "article@4"))
+      (delete-region (point) (point-max))
+      (goto-char (point-min))
+      (while (not (eobp)) 
+       (webmail-my-deja-article-part base))
+      (insert "MIME-Version: 1.0\n"
+             (prog1
+                 (mml-generate-mime)
+               (delete-region (point-min) (point-max)))))
     (goto-char (point-min))
     (insert "\n\nFrom nobody " (current-time-string) "\n")
+    (insert "X-Gnus-Webmail: " (symbol-value 'user)
+           "@" (symbol-name webmail-type) "\n")
+    (if (eq (char-after) ?\n)
+       (delete-char 1))
     (mm-append-to-file (point-min) (point-max) file)))
 
 (provide 'webmail)
index 31f90a0..cb94284 100644 (file)
@@ -4,7 +4,7 @@
 # Created: 1993-05-16
 # Public domain
 
-# $Id: mkinstalldirs,v 1.8 1997/06/25 17:03:22 meyering Exp $
+# $Id: mkinstalldirs,v 5.1 1998/08/31 20:15:04 larsi Exp $
 
 errstatus=0
 
index da186fe..b8e863d 100644 (file)
-% include file for the Gnus refcard and booklet
-\def\progver{5.0}\def\refver{5.0} % program and refcard versions
-\def\date{16 September 1995}
-\def\author{Vladimir Alexiev $<$vladimir@cs.ualberta.ca$>$}
-\raggedbottom\raggedright
-\newlength{\logowidth}\setlength{\logowidth}{6.861in}
-\newlength{\logoheight}\setlength{\logoheight}{7.013in}
+% -*- mode: latex; TeX-master: "refcard.tex" -*-
+                                % include file for the Gnus refcard and booklet
 \newlength{\keycolwidth}
 \newenvironment{keys}[1]% #1 is the widest key
-  {\nopagebreak%\noindent%
-   \settowidth{\keycolwidth}{#1}%
-   \addtolength{\keycolwidth}{\tabcolsep}%
-   \addtolength{\keycolwidth}{-\columnwidth}%
-   \begin{tabular}{@{}l@{\hspace{\tabcolsep}}p{-\keycolwidth}@{}}}%
+{\nopagebreak%\noindent%
+  \settowidth{\keycolwidth}{#1}%
+  \addtolength{\keycolwidth}{\tabcolsep}%
+  \addtolength{\keycolwidth}{-\columnwidth}%
+  \begin{tabular}{@{}l@{\hspace{\tabcolsep}}p{-\keycolwidth}@{}}}%
   {\end{tabular}\\}
-\catcode`\^=12 % allow ^ to be typed literally
-\newcommand{\B}[1]{{\bf#1})}    % bold l)etter
-
-\def\Title{
-\begin{center}
-{\bf\LARGE Gnus \progver\ Reference \Guide\\}
-%{\normalsize \Guide\ version \refver}
-\end{center}
-}
-
-\newcommand\Logo[1]{\centerline{
-\makebox[\logoscale\logowidth][l]{\vbox to \logoscale\logoheight
-{\vfill\special{psfile=gnuslogo.#1}}\vspace{-\baselineskip}}}}
-
-\def\CopyRight{
-\begin{center}
-Copyright \copyright\ 1995 Free Software Foundation, Inc.\\*
-Copyright \copyright\ 1995 \author.\\*
-Created from the Gnus manual Copyright \copyright\ 1994 Lars Magne
-Ingebrigtsen.\\*
-and the Emacs Help Bindings feature (C-h b).\\*
-Gnus logo copyright \copyright\ 1995 Luis Fernandes.\\*
-\end{center}
-
-Permission is granted to make and distribute copies of this reference
-\guide{} provided the copyright notice and this permission are preserved on
-all copies.  Please send corrections, additions and suggestions to the
-above email address. \Guide{} last edited on \date.
-}
-
-\def\Notes{
-\subsec{Notes}
-{\samepage
-Gnus is complex. Currently it has some 346 interactive (user-callable)
-functions. Of these 279 are in the two major modes (Group and
-Summary/Article). Many of these functions have more than one binding, some
-have 3 or even 4 bindings. The total number of keybindings is 389. So in
-order to save 40\% space, every function is listed only once on this
-\guide, under the ``more logical'' binding. Alternative bindings are given
-in parentheses in the beginning of the description.
-
-Many Gnus commands are affected by the numeric prefix. Normally you enter a
-prefix by holding the Meta key and typing a number, but in most Gnus modes
-you don't need to use Meta since the digits are not self-inserting. The
-prefixed behavior of commands is given in [brackets]. Often the prefix is
-used to specify:
-
-\quad [distance] How many objects to move the point over.
-
-\quad [scope] How many objects to operate on (including the current one).
-
-\quad [p/p] The ``Process/Prefix Convention'': If a prefix is given then it
-determines how many objects to operate on. Else if there are some objects
-marked with the process mark \#, these are operated on. Else only the
-current object is affected.
-
-\quad [level] A group subscribedness level. Only groups with a lower or
-equal level will be affected by the operation. If no prefix is given,
-`gnus-group-default-list-level' is used.  If
-`gnus-group-use-permanent-levels', then a prefix to the `g' and `l'
-commands will also set the default level.
-
-\quad [score] An article score. If no prefix is given,
-`gnus-summary-default-score' is used.
-%Some functions were not yet documented at the time of creating this
-%\guide and are clearly indicated as such.
-\\*[\baselineskip]
-\begin{keys}{C-c C-i}
-C-c C-i & Go to the Gnus online {\bf info}.\\
-C-c C-b & Send a Gnus {\bf bug} report.\\
-\end{keys}
-}}
-
-\def\GroupLevels{
-\subsec{Group Subscribedness Levels}
-The table below assumes that you use the default Gnus levels.
-Fill your user-specific levels in the blank cells.\\[1\baselineskip]
-
-\begin{tabular}{|c|l|l|}
-\hline
-Level & Groups & Status \\
-\hline
-1 & mail groups   &              \\
-2 & mail groups   &              \\
-3 &               & subscribed   \\
-4 &               &              \\
-5 & default list level &         \\
-\hline
-6 &               & unsubscribed \\
-7 &               &              \\
-\hline
-8 &               & zombies      \\
-\hline
-9 &               & killed       \\
-\hline
-\end{tabular}
-}
-
-\def\Marks{
-\subsec{Mark Indication Characters}
-{\samepage If a command directly sets a mark, it is shown in parentheses.\\*
-\newlength{\markcolwidth}
-\settowidth{\markcolwidth}{` '}% widest character
-\addtolength{\markcolwidth}{4\tabcolsep}
-\addtolength{\markcolwidth}{-\columnwidth}
-\newlength{\markdblcolwidth}
-\setlength{\markdblcolwidth}{\columnwidth}
-\addtolength{\markdblcolwidth}{-2\tabcolsep}
-\begin{tabular}{|c|p{-\markcolwidth}|}
-\hline
-\multicolumn{2}{|p{\markdblcolwidth}|}{{\bf ``Read'' Marks.}
-  All these marks appear in the first column of the summary line, and so
-  are mutually exclusive.}\\ 
-\hline
-` ' & (M-u, M SPC, M c) Not read.\\
-!   & (!, M !, M t) Ticked (interesting).\\
-?   & (?, M ?) Dormant (only followups are interesting).\\
-C   & (C, S c) {\bf Canceled} (only for your own articles).\\
-E   & (E, M e, M x) {\bf Expirable}. Only has effect in mail groups.\\
-\hline\hline
-\multicolumn{2}{|p{\markdblcolwidth}|}{The marks below mean that the article
-  is read (killed, uninteresting), and have more or less the same effect.
-  Some commands however explicitly differentiate between them (e.g.\ M
-  M-C-r, adaptive scoring).}\\
-\hline
-r   & (d, M d, M r) Deleted (marked as {\bf read}).\\
-C   & (M C; M C-c; M H; c, Z c; Z n; Z C) Killed by {\bf catch-up}.\\
-O   & {\bf Old} (marked read in a previous session).\\
-K   & (k, M k; C-k, M K) {\bf Killed}.\\
-R   & {\bf Read} (viewed in actuality).\\
-X   & Killed by a kill file.\\
-Y   & Killed due to low score.\\
-\hline\multicolumn{2}{c}{\vspace{1ex}}\\\hline
-\multicolumn{2}{|p{\markdblcolwidth}|}{{\bf Other marks}}\\
-\hline
-\#  & (\#, M \#, M P p) Processable (will be affected by the next operation).\\
-A   & {\bf Answered} (followed-up or replied).\\
-+   & Over default score.\\
-$-$ & Under default score.\\
-=   & Has children (thread underneath it). Add `\%e' to
-      `gnus-summary-line-format'.\\
-\hline
-\end{tabular}
-}}
-
-\def\GroupMode{
-\sec{Group Mode}
-\begin{keys}{C-c M-C-x}
-RET     & (=) Select this group. [Prefix: how many (read) articles to fetch.
-Positive: newest articles, negative: oldest ones.]\\
-SPC     & Select this group and display the first unread article. [Same
-prefix as above.]\\ 
-?       & Give a very short help message.\\
-$<$     & Go to the beginning of the Group buffer.\\
-$>$     & 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.\\
-^       & Enter the Server buffer mode.\\
-a       & Post an {\bf article} to a group.\\
-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]\\
-j       & {\bf Jump} to a group.\\
-m       & {\bf Mail} a message to someone.\\
-n       & Go to the {\bf next} group with unread articles. [distance]\\
-p       & (DEL) Go to the {\bf previous} group with unread articles.
-[distance]\\ 
-q       & {\bf Quit} Gnus.\\
-r       & Read the init file ({\bf reset}).\\
-s       & {\bf Save} the `.newsrc.eld' file (and `.newsrc' if
-`gnus-save-newsrc-file').\\ 
-z       & Suspend (kill all buffers of) Gnus.\\
-B       & {\bf Browse} a foreign server.\\
-C       & Mark all articles in this group as read ({\bf Catch-up}). [p/p]\\
-F       & {\bf Find} new groups and process them.\\
-N       & Go to the {\bf next} group. [distance]\\
-P       & Go to the {\bf previous} group. [distance]\\
-Q       & {\bf Quit} Gnus without saving any startup (.newsrc) files.\\
-R       & {\bf Restart} Gnus.\\
-V       & Display the Gnus {\bf version} number.\\
-Z       & Clear the dribble buffer.\\
-C-c C-d & Show the {\bf description} of this group. [Prefix: re-read it
-from the server.]\\ 
-C-c C-s & {\bf Sort} the groups by name, number of unread articles, or level
-(depending on `gnus-group-sort-function').\\
-C-c C-x & Run all expirable articles in this group through the {\bf expiry} 
-process.\\
-C-c M-C-x & Run all articles in all groups through the {\bf expiry} process.\\
-C-x C-t & {\bf Transpose} two groups.\\
-M-d     & {\bf Describe} ALL groups. [Prefix: re-read the description from the
-server.]\\
-M-f     & Fetch this group's {\bf FAQ} (using ange-ftp).\\
-M-g     & Check the server for new articles in this group ({\bf get}). [p/p]\\
-M-n     & Go to the {\bf previous} unread group on the same or lower level.
-[distance]\\ 
-M-p     & Go to the {\bf next} unread group on the same or lower level.
-[distance]\\ 
-\end{keys}
-}
-
-\def\GroupCommands{
-\subsec{List Groups}
-{\samepage
-\begin{keys}{A m}
-A a     & (C-c C-a) List all groups whose names match a regexp ({\bf
-apropos}).\\ 
-A d     & List all groups whose names or {\bf descriptions} match a regexp.\\ 
-A k     & (C-c C-l) List all {\bf killed} groups.\\
-A m     & List groups that {\bf match} a regexp and have unread articles.
-[level]\\ 
-A s     & (l) List {\bf subscribed} groups with unread articles. [level]\\
-A u     & (L) List all groups (including {\bf unsubscribed}). [If no prefix
-is given, level 7 is the default]\\ 
-A z     & List the {\bf zombie} groups.\\
-A M     & List groups that {\bf match} a regexp.\\
-\end{keys}
-}
-
-\subsec{Create/Edit Foreign Groups}
-{\samepage
-The select methods are indicated in parentheses.\\*
-\begin{keys}{G m}
-G a     & Make the Gnus list {\bf archive} group. (nndir over ange-ftp)\\
-G d     & Make a {\bf directory} group (every file must be a posting and files
-must have numeric names). (nndir)\\
-G e     & (M-e) {\bf Edit} this group's select method.\\
-G f     & Make a group based on a {\bf file}. (nndoc)\\
-G h     & Make the Gnus {\bf help} (documentation) group. (nndoc)\\
-G k     & Make a {\bf kiboze} group. (nnkiboze)\\
-G m     & {\bf Make} a new group.\\
-G p     & Edit this group's {\bf parameters}.\\
-G v     & Add this group to a {\bf virtual} group. [p/p]\\
-G D     & Enter a {\bf directory} as a (temporary) group. (nneething without
-recording articles read.)\\
-G E     & {\bf Edit} this group's info (select method, articles read, etc).\\
-G V     & Make a new empty {\bf virtual} group. (nnvirtual)\\
-\end{keys}
-You can also create mail-groups and read your mail with Gnus (very useful
-if you are subscribed to any mailing lists), using one of the methods
-nnmbox, nnbabyl, nnml, nnmh, or nnfolder. Read about it in the online info
-(C-c C-i g Reading Mail RET).
-}
-
-%\subsubsec{Soup Commands}
-%\begin{keys}{G s w}
-%G s b   & gnus-group-brew-soup: not documented.\\
-%G s p   & gnus-soup-pack-packet: not documented.\\
-%G s r   & nnsoup-pack-replies: not documented.\\
-%G s s   & gnus-soup-send-replies: not documented.\\
-%G s w   & gnus-soup-save-areas: not documented.\\
-%\end{keys}
-
-\subsec{Mark Groups}
-\begin{keys}{M m}
-M m     & (\#) Set the process {\bf mark} on this group. [scope]\\
-M u     & (M-\#) Remove the process mark from this group ({\bf unmark}).
-[scope]\\ 
-M w     & Mark all groups in the current region.\\
-\end{keys}
-
-\subsec{Unsubscribe, Kill and Yank Groups}
-\begin{keys}{S w}
-S k     & (C-k) {\bf Kill} this group.\\
-S l     & Set the {\bf level} of this group. [p/p]\\
-S s     & (U) Prompt for a group and toggle its {\bf subscription}.\\
-S t     & (u) {\bf Toggle} subscription to this group. [p/p]\\
-S w     & (C-w) Kill all groups in the region.\\
-S y     & (C-y) {\bf Yank} the last killed group.\\
-S z     & Kill all {\bf zombie} groups.\\
-\end{keys}
-}
-
-\def\SummaryMode{
-\sec{Summary Mode}  %{Summary and Article Modes}
-\begin{keys}{SPC}
-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]\\
-=       & Expand the Summary window. [Prefix: shrink it to display the
-Article window]\\
-$<$     & (A $<$, A b) Scroll to the beginning of this article.\\
-$>$     & (A $>$, A e) Scroll to the end of this article.\\
-\&      & Execute a command on all articles matching a regexp.
-[Prefix: move backwards.]\\
-j       & (G g) Ask for an article number and then {\bf jump} to that summary
-line.\\ 
-C-t     & Toggle {\bf truncation} of summary lines.\\
-M-\&    & Execute a command on all articles having the process mark.\\
-M-k     & Edit this group's {\bf kill} file.\\
-M-n     & (G M-n) Go to the {\bf next} summary line of an unread article.
-[distance]\\ 
-M-p     & (G M-p) Go to the {\bf previous} summary line of an unread article. 
-[distance]\\ 
-M-r     & Search through all previous articles for a regexp.\\
-M-s     & {\bf Search} through all subsequent articles for a regexp.\\
-M-K     & Edit the general {\bf kill} file.\\
-\end{keys}
-}
-
-\def\SortSummary{
-\subsec{Sort the Summary Buffer}
-\begin{keys}{C-c C-s C-a}
-C-c C-s C-a & Sort the summary by {\bf author}.\\
-C-c C-s C-d & Sort the summary by {\bf date}.\\
-C-c C-s C-i & Sort the summary by article score.\\
-C-c C-s C-n & Sort the summary by article {\bf number}.\\
-C-c C-s C-s & Sort the summary by {\bf subject}.\\
-\end{keys}
-}
-
-\def\Asubmap{
-\subsec{Article Buffer Commands}
-\begin{keys}{A m}
-A g     & (g) (Re)fetch this article ({\bf get}). [Prefix: just show the
-article.]\\ 
-A r     & (^, A ^) Go to the parent of this article (the {\bf References}
-header).\\ 
-M-^     & Fetch the article with a given Message-ID.\\
-A s     & (s) Perform an i{\bf search} in the article buffer.\\
-A D     & (C-d) Un{\bf digestify} this article into a separate group.\\
-\end{keys}
-}
-
-\def\Bsubmap{
-\subsec{Mail-Group Commands}
-{\samepage
-These commands (except `B c') are only valid in a mail group.\\*
-\begin{keys}{B M-C-e}
-B DEL   & {\bf Delete} the mail article from disk (!). [p/p]\\
-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 m     & {\bf Move} the article from one mail group to another. [p/p]\\
-B q     & {\bf Query} where will the article go during fancy splitting\\
-B r     & {\bf Respool} this mail article. [p/p]\\
-B w     & (e) Edit this article.\\
-B M-C-e & {\bf Expunge} (delete from disk) all expirable articles in this group
-(!). [p/p]\\ 
-\end{keys}
-}}
-
-\def\Gsubmap{
-\subsec{Select Articles}
-{\samepage
-These commands select the target article. They do not understand the prefix.\\*
-\begin{keys}{G C-n}
-G b     & (,) Go to the {\bf best} article (the one with highest score).\\
-G f     & (.) Go to the {\bf first} unread article.\\
-G l     & (l) Go to the {\bf last} article read.\\
-G n     & (n) Go to the {\bf next} unread article.\\
-p       & Go to the {\bf previous} unread article.\\
-G p     & {\bf Pop} an article off the summary history and go to it.\\
-G N     & (N) Go to {\bf the} next article.\\
-G P     & (P) Go to the {\bf previous} article.\\
-G C-n   & (M-C-n) Go to the {\bf next} article with the same subject.\\
-G C-p   & (M-C-p) Go to the {\bf previous} article with the same subject.\\
-\end{keys}
-}}
-
-\def\Hsubmap{
-\subsec{Help Commands}
-\begin{keys}{H d}
-H d     & (C-c C-d) {\bf Describe} this group. [Prefix: re-read the description
-from the server.]\\
-H f     & Try to fetch the {\bf FAQ} for this group using ange-ftp.\\
-H h     & Give a very short {\bf help} message.\\
-H i     & (C-c C-i) Go to the Gnus online {\bf info}.\\
-H v     & Display the Gnus {\bf version} number.\\
-\end{keys}
-}
-
-\def\Msubmap{
-\subsec{Mark Articles}
-\begin{keys}{M M-C-r}
-d       & (M d, M r) Mark this article as read and move to the next one.
-[scope]\\ 
-D       & Mark this article as read and move to the previous one. [scope]\\
-u       & (!, M !, M t) Tick this article (mark it as interesting) and move
-to the next one. [scope]\\
-U       & Tick this article and move to the previous one. [scope]\\ 
-M-u     & (M SPC, M c) Clear all marks from this article and move to the next
-one. [scope]\\ 
-M-U     & Clear all marks from this article and move to the previous one.
-[scope]\\ 
-M ?     & (?) Mark this article as dormant (only followups are
-interesting). [scope]\\ 
-M b     & Set a {\bf bookmark} in this article.\\
-M e     & (E, M x) Mark this article as {\bf expirable}. [scope]\\
-M k     & (k) {\bf Kill} all articles with the same subject then select the
-next one.\\ 
-M B     & Remove the {\bf bookmark} from this article.\\
-M C     & {\bf Catch-up} the articles that are not ticked.\\
-M D     & Show all {\bf dormant} articles (normally they are hidden unless they
-have any followups).\\
-M H     & Catch-up (mark read) this group to point ({\bf here}).\\
-M K     & (C-k) {\bf Kill} all articles with the same subject as this one.\\
-C-w     & Mark all articles between point and mark as read.\\
-M S     & (C-c M-C-s) {\bf Show} all expunged articles.\\
-M C-c   & {\bf Catch-up} all articles in this group.\\
-M M-r   & (x) Expunge all {\bf read} articles from this group.\\
-M M-D   & Hide all {\bf dormant} articles.\\
-M M-C-r & Expunge all articles having a given mark.\\
-\end{keys}
-
-\subsubsec{Mark Based on Score}
-\begin{keys}{M s m}
-M V c   & {\bf Clear} all marks from all high-scored articles. [score]\\
-M V k   & {\bf Kill} all low-scored articles. [score]\\
-M V m   & Mark all high-scored articles with a given {\bf mark}. [score]\\
-M V u   & Mark all high-scored articles as interesting (tick them). [score]\\
-\end{keys}
-
-\subsubsec{The Process Mark}
-{\samepage 
-These commands set and remove the process mark \#. You only need to use
-it if the set of articles you want to operate on is non-contiguous. Else
-use a numeric prefix.\\*
-\begin{keys}{M P R}
-M P a   & Mark {\bf all} articles (in series order).\\
-M P p   & (\#, M \#) Mark this article.\\
-M P r   & Mark all articles in the {\bf region}.\\
-M P s   & Mark all articles in the current {\bf series}.\\
-M P t   & Mark all articles in this (sub){\bf thread}.\\
-M P u   & (M-\#, M M-\#) {\bf Unmark} this article.\\
-M P R   & Mark all articles matching a {\bf regexp}.\\
-M P S   & Mark all {\bf series} that already contain a marked article.\\
-M P U   & {\bf Unmark} all articles.\\
-\end{keys}
-}}
-
-\def\Osubmap{
-\subsec{Output Articles}
-\begin{keys}{O m}
-O f     & Save this article in plain {\bf file} format. [p/p]\\
-O h     & Save this article in {\bf mh} folder format. [p/p]\\
-O m     & Save this article in {\bf mail} format. [p/p]\\
-O o     & (o, C-o) Save this article using the default article saver. [p/p]\\
-O p     & ($\mid$) Pipe this article to a shell command. [p/p]\\
-O r     & Save this article in {\bf rmail} format. [p/p]\\
-O v     & Save this article in {\bf vm} format. [p/p]\\
-\end{keys}
-}
-
-\def\Ssubmap{
-\subsec{Post, Followup, Reply, Forward, Cancel}
-{\samepage
-These commands put you in a separate post or mail buffer. After
-editing the article, send it by pressing C-c C-c.  If you are in a
-foreign group and want to post the article using the foreign server, give
-a prefix to C-c C-c.\\* 
-\begin{keys}{S O m}
-S b     & {\bf Both} post a followup to this article, and send a reply.\\
-S c     & (C) {\bf Cancel} this article (only works if it is your own).\\
-S f     & (f) Post a {\bf followup} to this article.\\
-S m     & (m) Send {\bf a} mail to some other person.\\
-S o m   & (C-c C-f) Forward this article by {\bf mail} to a person.\\
-S o p   & Forward this article as a {\bf post} to a newsgroup.\\
-S p     & (a) {\bf Post} an article to this group.\\
-S r     & (r) Mail a {\bf reply} to the author of this article.\\
-S s     & {\bf Supersede} this article with a new one (only for own
-articles).\\ 
-S u     & {\bf Uuencode} a file and post it as a series.\\
-S B     & {\bf Both} post a followup, send a reply, and include the
-original. [p/p]\\ 
-S F     & (F) Post a {\bf followup} and include the original. [p/p]\\
-S O m   & Digest these series and forward by {\bf mail}. [p/p]\\
-S O p   & Digest these series and forward as a {\bf post} to a newsgroup.
-[p/p]\\ 
-S R     & (R) Mail a {\bf reply} and include the original. [p/p]\\
-\end{keys}
-If you want to cancel or supersede an article you just posted (before it
-has appeared on the server), go to the *post-news* buffer, change
-`Message-ID' to `Cancel' or `Supersedes' and send it again with C-c C-c.
-}}
-
-\def\Tsubmap{
-\subsec{Thread Commands}
-\begin{keys}{T \#}
-T \#    & Mark this thread with the process mark.\\
-T d     & Move to the next article in this thread ({\bf down}). [distance]\\
-T h     & {\bf Hide} this (sub)thread.\\
-T i     & {\bf Increase} the score of this thread.\\
-T k     & (M-C-k) {\bf Kill} the current (sub)thread. [Negative prefix:
-tick it, positive prefix: unmark it.]\\
-T l     & (M-C-l) {\bf Lower} the score of this thread.\\
-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 s     & {\bf Show} the thread hidden under this article.\\
-T u     & Move to the previous article in this thread ({\bf up}). [distance]\\
-T H     & {\bf Hide} all threads.\\
-T S     & {\bf Show} all hidden threads.\\
-T T     & (M-C-t) {\bf Toggle} threading.\\
-\end{keys}
-}
-
-\def\Vsubmap{
-\subsec{Score (Value) Commands}
-{\samepage
-Read about Adaptive Scoring in the online info.\\*
-\begin{keys}{\bf A p m l}
-V a     & {\bf Add} a new score entry, specifying all elements.\\
-V c     & Specify a new score file as {\bf current}.\\
-V e     & {\bf Edit} the current score alist.\\
-V f     & Edit a score {\bf file} and make it the current one.\\
-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}).\\
-V x     & {\bf Expunge} all low-scored articles. [score]\\
-V C     & {\bf Customize} the current score file through a user-friendly
-interface.\\ 
-V S     & Display the {\bf score} of this article.\\
-\bf A p m l& Make a scoring entry based on this article.\\
-\end{keys}
-
-The four letters stand for:\\*
-\quad \B{A}ction: I)ncrease, L)ower;\\*
-\quad \B{p}art: a)utor (from), s)ubject, x)refs (cross-posting), d)ate, l)ines,
-message-i)d, t)references (parent), f)ollowup, b)ody, h)ead (all headers);\\*
-\quad \B{m}atch type:\\*
-\qquad string: s)ubstring, e)xact, r)egexp, f)uzzy,\\*
-\qquad date: b)efore, a)t, n)this,\\*
-\qquad number: $<$, =, $>$;\\*
-\quad \B{l}ifetime: t)emporary, p)ermanent, i)mmediate.
-
-If you type the second letter in uppercase, the remaining two are assumed
-to be s)ubstring and t)emporary. 
-If you type the third letter in uppercase, the last one is assumed to be 
-t)emporary.
-
-\quad Extra keys for manual editing of a score file:\\*
-\begin{keys}{C-c C-c}
-C-c C-c & Finish editing the score file.\\
-C-c C-d & Insert the current {\bf date} as number of days.\\
-\end{keys}
-}}
-
-\def\Wsubmap{
-\subsec{Wash the Article Buffer}
-\begin{keys}{W C-c}
-W b     & Make Message-IDs and URLs in the article to mouse-clickable {\bf
-  buttons}.\\  
-W c     & Remove extra {\bf CRs} (^M) from the article.\\
-W f     & Look for and display any X-{\bf Face} headers.\\
-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 q     & Treat {\bf quoted}-printable in the article.\\
-W r     & (C-c C-r) Do a Caesar {\bf rotate} (rot13) on the article.\\
-W t     & (t) {\bf Toggle} the displaying of all headers.\\
-v       & Toggle permanent {\bf verbose} displaying of all headers.\\
-W w     & Do word {\bf wrap} in the article.\\
-W T e   & Convert the article timestamp to time {\bf elapsed} since sent.\\
-W T l   & Convert the article timestamp to the {\bf local} timezone.\\
-W T u   & (W T z) Convert the article timestamp to {\bf UTC} ({\bf Zulu},
-GMT).\\ 
-\end{keys}
-
-\subsubsec{Hide/Highlight Parts of the Article}
-\begin{keys}{W W C-c}
-W W a   & Hide {\bf all} unwanted parts. Calls W W h, W W s, W W C-c.\\
-W W c   & Hide article {\bf citation}.\\
-W W h   & Hide article {\bf headers}.\\
-W W s   & Hide article {\bf signature}.\\
-W W C-c & Hide article {\bf citation} using a more intelligent algorithm.\\
-%\end{keys}
-%
-%\subsubsec{Highlight Parts of the Article}
-%\begin{keys}{W H A}
-W H a   & Highlight {\bf all} parts. Calls W b, W H c, W H h, W H s.\\
-W H c   & Highlight article {\bf citation}.\\
-W H h   & Highlight article {\bf headers}.\\
-W H s   & Highlight article {\bf signature}.\\
-\end{keys}
-}
-
-\def\Xsubmap{
-\subsec{Extract Series (Uudecode etc)}
-{\samepage
-Gnus recognizes if the current article is part of a series (multipart
-posting whose parts are identified by numbers in their subjects, e.g.{}
-1/10\dots10/10) and processes the series accordingly. You can mark and
-process more than one series at a time. If the posting contains any
-archives, they are expanded and gathered in a new group.\\*
-\begin{keys}{X p}
-X b     & Un-{\bf binhex} these series. [p/p]\\
-X o     & Simply {\bf output} these series (no decoding). [p/p]\\ 
-X p     & Unpack these {\bf postscript} series. [p/p]\\
-X s     & Un-{\bf shar} these series. [p/p]\\
-X u     & {\bf Uudecode} these series. [p/p]\\
-\end{keys}
-
-Each one of these commands has four variants:\\*
-\begin{keys}{X v \bf Z}
-X   \bf z & Decode these series. [p/p]\\
-X   \bf Z & Decode and save these series. [p/p]\\
-X v \bf z & Decode and view these series. [p/p]\\
-X v \bf Z & Decode, save and view these series. [p/p]\\
-\end{keys}
-where {\bf z} or {\bf Z} identifies the decoding method (b, o, p, s, u).
-
-An alternative binding for the most-often used of these commands is\\*
-\begin{keys}{C-c C-v C-v}
-C-c C-v C-v & (X v u) Uudecode and view these series. [p/p]\\
-\end{keys}
-}}
-
-\def\Zsubmap{
-\subsec{Exit the Current Group}
-\begin{keys}{Z G}
-Z c     & (c) Mark all unticked articles as read ({\bf catch-up}) and exit.\\
-Z n     & Mark all articles as read and go to the {\bf next} group.\\
-Z C     & Mark all articles as read ({\bf catch-up}) and exit.\\
-Z E     & (Q) {\bf Exit} without updating the group information.\\
-Z G     & (M-g) Check for new articles in this group ({\bf get}).\\
-Z N     & Exit and go to {\bf the} next group.\\
-Z P     & Exit and go to the {\bf previous} group.\\
-Z R     & Exit this group, and then enter it again ({\bf reenter}).
-[Prefix: select all articles, read and unread.]\\
-Z Z     & (q, Z Q) Exit this group.\\
-\end{keys}
-}
-
-\def\ArticleMode{
-\sec{Article Mode}
-{\samepage
-% All keys for Summary mode also work in Article mode.
-The normal navigation keys work in Article mode.
-Some additional keys are:\\*
-\begin{keys}{C-c C-m}
-RET     & (middle mouse button) Activate the button at point to follow
-an URL or Message-ID.\\
-TAB     & Move the point to the next button.\\
-h       & (s) Go to the {\bf header} line of the article in the {\bf
-summary} buffer.\\ 
-C-c ^   & Get the article with the Message-ID near point.\\
-C-c C-m & {\bf Mail} reply to the address near point (prefix: include the
-original).\\ 
-\end{keys}
-}}
-
-\def\ServerMode{
-\sec{Server Mode}
-{\samepage
-To enter this mode, press `^' while in Group mode.\\*
-\begin{keys}{SPC}
-SPC     & (RET) Browse this server.\\
-a       & {\bf Add} a new server.\\
-c       & {\bf Copy} this server.\\
-e       & {\bf Edit} a server.\\
-k       & {\bf Kill} this server. [scope]\\
-l       & {\bf List} all servers.\\
-q       & Return to the group buffer ({\bf quit}).\\
-y       & {\bf Yank} the previously killed server.\\
-\end{keys}
-}}
-
-\def\BrowseServer{
-\sec{Browse Server Mode}
-{\samepage
-To enter this mode, press `B' while in Group mode.\\*
-\begin{keys}{RET}
-RET     & Enter the current group.\\
-SPC     & Enter the current group and display the first article.\\
-?       & Give a very short help message.\\
-n       & Go to the {\bf next} group. [distance]\\
-p       & Go to the {\bf previous} group. [distance]\\
-q       & (l) {\bf Quit} browse mode.\\
-u       & Subscribe to the current group. [scope]\\
-\end{keys}
-}}
+
+                                % uncomment the first definition if you do not want pagebreaks in maps
+                                %\newcommand{\esamepage}{\samepage}
+\newcommand{\esamepage}{}
+
+\newcommand*{\B}[1]{{\bf#1})}    % bold l)etter
+
+\newcommand{\Title}{%
+  \begin{center}
+    {\bf\LARGE Gnus \progver\ Reference \Guide\\}
+                                %{\normalsize \Guide\ version \refver}
+  \end{center}
+  }
+
+\newcommand*{\Logo}[1]{\centerline{%
+    \makebox[\logoscale\logowidth][l]{\vbox to \logoscale\logoheight
+      {\vfill\special{psfile=gnuslogo.#1}}\vspace{-\baselineskip}}}}
+
+\newcommand{\Copyright}{%
+  \begin{center}
+    Copyright \copyright\ 1995 Free Software Foundation, Inc.\\*
+    Copyright \copyright\ 1995 \author.\\*
+    Copyright \copyright\ 2000 Felix Natter $<$fnatter@gmx.net$>$.\\*
+    Created from the Gnus manual Copyright \copyright\ 1994 Lars Magne
+    Ingebrigtsen.\\*
+    and the Emacs Help Bindings feature (C-h b).\\*
+    Gnus logo copyright \copyright\ 1995 Luis Fernandes.\\*
+  \end{center}
+
+  Permission is granted to make and distribute copies of this reference
+  \guide{} provided the copyright notice and this permission are preserved on
+  all copies.  Please send corrections, additions and suggestions to the
+  current maintainer's email address. \Guide{} last edited on \date.
+  }
+
+\newcommand{\Notes}{%
+  \subsection*{Notes}
+  {\esamepage
+    Gnus is complex. Currently it has some 346 interactive (user-callable)
+    functions. Of these 279 are in the two major modes (Group and
+    Summary/Article). Many of these functions have more than one binding, some
+    have 3 or even 4 bindings. The total number of keybindings is 389. So in
+    order to save 40\% space, every function is listed only once on this
+    \guide, under the ``more logical'' binding. Alternative bindings are given
+    in parentheses in the beginning of the description.
+
+    Many Gnus commands are affected by the numeric prefix. Normally you enter a
+    prefix by holding the Meta key and typing a number, but in most Gnus modes
+    you don't need to use Meta since the digits are not self-inserting. The
+    prefixed behavior of commands is given in [brackets]. Often the prefix is
+    used to specify:
+
+    \quad [distance] How many objects to move the point over.
+
+    \quad [scope] How many objects to operate on (including the current one).
+
+    \quad [p/p] The ``Process/Prefix Convention'': If a prefix is given then it
+    determines how many objects to operate on. Else if there are some objects
+    marked with the process mark \#, these are operated on. Else only the
+    current object is affected.
+
+    \quad [level] A group subscribedness level. Only groups with a lower or
+    equal level will be affected by the operation. If no prefix is given,
+    `gnus-group-default-list-level' is used.  If
+    `gnus-group-use-permanent-levels', then a prefix to the `g' and `l'
+    commands will also set the default level.
+
+    \quad [score] An article score. If no prefix is given,
+    `gnus-summary-default-score' is used. \\*[\baselineskip]
+                                % some keys
+    \begin{keys}{C-c C-i}
+      M-x gnus           & start Gnus. \\
+      M-x gnus-no-server & start Gnus without trying to connect to server
+      (i.e. to read mail). \\
+      M-x gnus-unplugged & start Gnus in \texttt{unplugged}-mode
+      (first see the manual, C-c C-i g Gnus Unplugged RET).\\
+                                %
+      C-c C-i & Go to the Gnus online {\bf info}.\\
+      C-c C-b & Send a Gnus {\bf bug} report.\\
+    \end{keys}
+    }}
+
+\newcommand{\GroupLevels}{%
+  The table below assumes that you use the default Gnus levels.
+  Fill your user-specific levels in the blank cells.\\[1\baselineskip]
+  \begin{tabular}{|c|l|l|}
+    \hline
+    Level & Groups & Status \\
+    \hline
+    1 & draft/mail groups   &              \\
+    2 & mail groups         &              \\
+    3 &                     & subscribed   \\
+    4 &                     &              \\
+    5 & default list level  &              \\
+    \hline
+    6 &                     & unsubscribed \\
+    7 &                     &              \\
+    \hline
+    8 &                     & zombies      \\
+    \hline
+    9 &                     & killed       \\
+    \hline
+  \end{tabular}}
+
+\newcommand{\MarkCharacters}{%
+  {\esamepage If a command directly sets a mark, it is shown in parentheses.\\*
+    \newlength{\markcolwidth}
+    \settowidth{\markcolwidth}{` '}% widest character
+    \addtolength{\markcolwidth}{4\tabcolsep}
+    \addtolength{\markcolwidth}{-\columnwidth}
+    \newlength{\markdblcolwidth}
+    \setlength{\markdblcolwidth}{\columnwidth}
+    \addtolength{\markdblcolwidth}{-2\tabcolsep}
+    \begin{tabular}{|c|p{-\markcolwidth}|}
+      \hline
+      \multicolumn{2}{|p{\markdblcolwidth}|}{{\bf ``Read'' Marks.}
+        All these marks appear in the first column of the summary line, and so
+        are mutually exclusive.}\\ 
+      \hline
+      ` ' & (M-u, M SPC, M c) Not read.\\
+      !   & (!, M !, M t) Ticked (interesting).\\
+      ?   & (?, M ?) Dormant (only followups are interesting).\\
+      E   & (E, M e, M x) {\bf Expirable}. Only has effect in mail groups.\\
+      G   & (C, B DEL) Canceled article (or deleted in mailgroups).\\
+      \hline\hline
+      \multicolumn{2}{|p{\markdblcolwidth}|}
+      {The marks below mean that the article
+        is read (killed, uninteresting), and have more or less the same effect.
+        Some commands however explicitly differentiate between them (e.g.\ M
+        M-C-r, adaptive scoring).}\\
+      \hline
+      r   & (d, M d, M r) Deleted (marked as {\bf read}).\\
+      C   & (M C; M C-c; M H; c, Z c; Z n; Z C) Killed by {\bf catch-up}.\\
+      F   & SOUPed article. See the manual.\\
+      O   & {\bf Old} (read in a previous session).\\
+      K   & (k, M k; C-k, M K) {\bf Killed}.\\
+      M   & Article marked as read by duplicate suppression.\\
+      Q   & Article is part of a sparse thread (see ``Threading''
+      in the manual).\\
+      R   & {\bf Read} (viewed in actuality).\\
+      X   & Killed by a kill file.\\
+      Y   & Killed due to low score.\\
+      \hline\multicolumn{2}{c}{\vspace{1ex}}\\\hline
+      \multicolumn{2}{|p{\markdblcolwidth}|}
+      {{\bf Marks not affecting visibility}}\\
+      \hline
+      \#  & (\#, M \#, M P p) Processable (will be affected by the next operation).
+      [2]\\
+      A   & {\bf Answered} (followed-up or replied). [2]\\
+      *   & Cached. [2]\\
+      S   & Saved. [2]\\
+      +   & Over default score. [3]\\
+      $-$ & Under default score. [3]\\
+      $=$ & Has children (thread underneath it). Add `\%e' to
+      `gnus-summary-line-format'. [3]\\
+      \hline
+    \end{tabular}
+    }}
+
+\newcommand{\GroupModeGeneral}{%
+  \begin{keys}{C-c M-C-x}
+    RET     & (=) Enter this group. [Prefix: how many (read) articles to fetch.
+    Positive: newest articles, negative: oldest ones; non-numerical:
+    view all articles, not just unread]\\
+    M-RET   & Enter group quickly.\\
+    M-SPC   & Same as RET but does not expunge and hide dormants.\\
+    M-C-RET & Enter group without any processing, changes will not be permanent.\\
+    SPC     & Select this group and display the first (unread) article. [Same
+    prefix as above.]\\
+    ?       & Give a very short help message.\\
+    $<$     & Go to the beginning of the Group buffer.\\
+    $>$     & 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.\\
+    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.\\
+    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]\\ 
+    p       & (DEL) Go to the {\bf previous} group with unread articles.
+    [distance]\\ 
+    M-p     & Go to the {\bf previous} group on the same or lower level. [distance]\\ 
+    q       & {\bf Quit} Gnus.\\
+    r       & Re-read the init file ({\bf reset}).\\
+    s       & {\bf Save} the `.newsrc.eld' file (and `.newsrc' if
+    `gnus-save-newsrc-file').\\ 
+    z       & Suspend (kill all buffers of) Gnus.\\
+    B       & {\bf Browse} a foreign server.\\
+    C       & Mark all articles in this group as read ({\bf Catch-up}). [p/p]\\
+    F       & {\bf Find} new groups and process them.\\
+    N       & Go to the {\bf next} group. [distance]\\
+    P       & Go to the {\bf previous} group. [distance]\\
+    Q       & {\bf Quit} Gnus without saving any startup (.newsrc) files.\\
+    R       & {\bf Restart} Gnus.\\
+    Z       & Clear the dribble buffer.\\
+    M-c     & Clear data from group (marks and list of read articles). \\
+    C-c C-s & {\bf Sort} the groups by name, number of unread articles, or level
+    (depending on `gnus-group-sort-function').\\
+    C-c C-x & Run all expirable articles in this group through the {\bf expiry} 
+    process.\\
+    C-c M-C-x & Run all articles in all groups through the {\bf expiry} process.\\
+    C-c M-g & Activate all {\bf groups}.\\
+    C-c C-i & Gnus online-manual ({\bf info}).\\
+    C-x C-t & {\bf Transpose} two groups.\\
+    H f     & Fetch this group's {\bf FAQ} (using ange-ftp).\\
+    H v     & (V) Display the Gnus {\bf version} number.\\
+    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]\\
+  \end{keys}
+  }
+
+\newcommand{\ListGroups}{%
+  {\esamepage
+    \begin{keys}{A M}
+      A d     & 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.\\
+      A M     & List groups that {\bf match} a regexp.\\
+      A m     & List groups that {\bf match} a regexp and have unread articles. 
+      [level]\\ 
+      A s     & (l) List all {\bf subscribed} groups with unread articles.
+      [level; 5 and lower is the default]\\
+      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.\\
+    \end{keys}
+    }
+
+  \newcommand{\CreateEditGroups}{%
+    {\esamepage
+      The select methods are indicated in parentheses.\\*
+      \begin{keys}{G DEL}
+        G a     & Make the Gnus list {\bf archive} group. (nndir over ange-ftp)\\
+        G c     & {\bf Customize} this group's parameters.\\
+        G d     & Make a {\bf directory} group (every file must be a posting and files
+        must have numeric names). (nndir)\\
+        G D     & Enter a {\bf directory} as a (temporary) group.
+        (nneething without recording articles read)\\
+        G e     & (M-e) {\bf Edit} this group's select method.\\
+        G E     & {\bf Edit} this group's info (select method, articles read, etc).\\
+        G f     & Make a group based on a {\bf file}. (nndoc)\\
+        G h     & Make the Gnus {\bf help} (documentation) group. (nndoc)\\
+        G k     & Make a {\bf kiboze} group. (nnkiboze)\\
+        G m     & {\bf Make} a new group.\\
+        G p     & Edit this group's {\bf parameters}.\\
+        G r     & Rename this group (does not work with read-only groups!).\\
+        G u     & Create one of the groups mentioned in gnus-{\bf useful}-groups.\\
+        G v     & Add this group to a {\bf virtual} group. [p/p]\\
+        G V     & Make a new empty {\bf virtual} group. (nnvirtual)\\
+        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].\\
+      \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
+      nnmbox, nnbabyl, nnml, nnmh, or nnfolder. Read about it in the online info
+      (C-c C-i g Reading Mail RET).
+      }}
+
+                                % TODO:
+  \newcommand{\SoupCommands}{%
+    \begin{keys}{G s w}
+      G s b   & gnus-group-brew-soup: not documented.\\
+      G s p   & gnus-soup-pack-packet: not documented.\\
+      G s r   & nnsoup-pack-replies: not documented.\\
+      G s s   & gnus-soup-send-replies: not documented.\\
+      G s w   & gnus-soup-save-areas: not documented.\\
+    \end{keys}}
+
+  \newcommand{\MarkGroups}{%
+    \begin{keys}{M m}
+      M m     & (\#) Set the process {\bf mark} on this group. [scope]\\
+      M r     & Mark all groups matching regular expression.\\
+      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.\\
+    \end{keys}}
+
+  \newcommand{\GroupTopicsGeneral}{%
+    {\esamepage
+      Topics are ``categories'' for groups. Press t in the group-buffer to
+      toggle gnus-topic-mode (C-c C-i g Group Topics RET).
+      \begin{keys}{C-c C-x}
+        T n     & Prompt for topic {\bf name} and create it.\\
+        T m     & {\bf Move} the current group to some other topic [p/p].\\
+        T j     & {\bf Jump} to a topic.\\
+        T c     & {\bf Copy} the current group to some other topic [p/p].\\
+        T D     & Remove (not delete) the current group [p/p].\\
+        T M     & {\bf Move} all groups matching a regexp to a topic.\\
+        T C     & {\bf Copy} all groups matching a regexp to a topic.\\
+        T H     & Toggle {\bf hiding} of empty topics.\\
+        T r     & {\bf Rename} a topic.\\
+        T DEL   & Delete an empty topic.\\
+        T \#    & Mark all groups in the current topic with the process-mark.\\
+        T M-\#  & Remove the process-mark from all groups in the current topic.\\
+        T TAB   & (TAB) Indent current topic [Prefix: unindent].\\ 
+        M-TAB   & Unindent the current topic.\\
+        RET     & (SPC) Either unfold topic or enter group [level].\\
+        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}.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\TopicSorting}{%
+    {\esamepage
+      \begin{keys}{T S m}
+        T S a  & Sort {\bf alphabetically}.\\
+        T S u  & Sort by number of {\bf unread} articles.\\
+        T S l  & Sort by group {\bf level}.\\
+        T S v  & Sort by group score ({\bf value}).\\
+        T S r  & Sort by group {\bf rank}.\\
+        T S m  & Sort by {\bf method}.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\SubscribeKillYankGroups}{%
+    {\esamepage
+      \begin{keys}{S C-k}
+        S k     & (C-k) {\bf Kill} this group.\\
+        S l     & Set the {\bf level} of this group. [p/p]\\
+        S s     & (U) Prompt for a group and toggle its {\bf subscription}.\\
+        S t     & (u) {\bf Toggle} subscription to this group. [p/p]\\
+        S w     & (C-w) Kill all groups in the region.\\
+        S y     & (C-y) {\bf Yank} the last killed group.\\
+        S z     & Kill all {\bf zombie} groups.\\
+        S C-k   & Kill all groups on a certain level.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\SummaryModeGeneral}{%
+    {\esamepage
+      \begin{keys}{M-RET}
+        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]\\
+        =       & Expand the Summary window (fullsize).
+        [Prefix: shrink to display article window]\\
+                                %
+        \&      & Execute a command on all articles whose header matches a regexp.
+        [Prefix: move backwards]\\
+        M-\&    & Execute a command on all articles having the process mark.\\
+                                %
+        M-n     & (G M-n) Go to the {\bf next} summary line of an unread article.
+        [distance]\\ 
+        M-p     & (G M-p) Go to the {\bf previous} summary line of an unread article. 
+        [distance]\\ 
+        M-s     & {\bf Search} through all subsequent articles for a regexp.\\
+        M-r     & Search through all previous articles for a regexp.\\
+                                %
+        A P     & {\bf Postscript}-print current buffer.\\
+                                %
+        M-k     & Edit this group's {\bf kill} file.\\
+        M-K     & Edit the general {\bf kill} file.\\
+                                %
+        C-t     & Toggle {\bf truncation} of summary lines.\\
+        Y g     & Regenerate the summary-buffer.\\
+        Y c     & Insert all cached articles into the summary-buffer.\\
+                                %
+        M-C-e   & {\bf Edit} the group-parameters.\\
+        M-C-g   & Customize the group-parameters.\\
+                                %
+                                % article handling
+                                %
+        A $<$   & ($<$, A b) Scroll to the beginning of this article.\\
+        A $>$   & ($>$, A e) Scroll to the end of this article.\\
+        A s     & (s) Perform an i{\bf search} in the article buffer.\\
+                                %
+        A D     & (C-d) Un{\bf digestify} this article into a separate group.
+        [Prefix: force digest]\\
+        M-C-d   & Like C-d, but open several documents in nndoc-groups, wrapped
+        in an nnvirtual group [p/p]\\
+                                %
+        A g     & (g) (Re)fetch this article ({\bf get}). [Prefix: get raw version]\\ 
+        A r     & (\^{}, A \^{}) Fetch the parent(s) of this article.
+        [Prefix: if positive fetch \textit{n} ancestors;
+        negative: fetch only the \textit{n}th ancestor]\\
+        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.\\
+        S y     & {\bf Yank} the current article into an existing message-buffer.
+        [p/p]\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\MIMESummary}{%
+    {\esamepage
+      For the commands operating on one MIME part (a subset of gnus-article-*), a
+      prefix selects which part to operate on. If the point is placed over a
+      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 o      & {\bf Save} the MIME part.\\
+        K c      & {\bf Copy} the MIME part.\\
+        K e      & View the MIME part {\bf externally}.\\
+        K i      & View the MIME part {\bf internally}.\\
+        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}.\\
+        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.\\
+        W M c    & Decode encoded article bodies. [Prefix: prompt for charset]\\
+        W M v    & View all MIME parts in the current article.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\SortSummary}{%
+    {\esamepage
+      \begin{keys}{C-c C-s C-a}
+        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-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}.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\MailGroups}{% formerly \Bsubmap
+    {\esamepage
+      These commands (except `B c') are only valid in a mail group.\\*
+      \begin{keys}{B M-C-e}
+        B DEL   & (B backspace, B delete) {\bf Delete} the mail article from disk (!).
+        [p/p]\\
+        B B     & Crosspost this article to another group.\\
+        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 m     & {\bf Move} the article from one mail group to another. [p/p]\\
+        B p     & Query whether the article was 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]\\ 
+      \end{keys}
+      }
+    }
+
+  \newcommand{\DraftGroup}{% formerly \Dsubmap
+    {\esamepage
+      The ``drafts''-group contains messages that have been saved but not sent
+      and rejected articles. \\*
+      \begin{keys}{B DEL}
+        D e      & \textbf{edit} message.\\
+        D s      & \textbf{Send} message. [p/p]\\
+        D S      & \textbf{Send} all messages.\\
+        D t      & \textbf{Toggle} sending (mark as unsendable).\\
+        B DEL    & \textbf{Delete} message (like in mailgroup).\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\SelectArticles}{% formerly \Gsubmap
+    {\esamepage
+      These commands select the target article. They do not understand the prefix.\\*
+      \begin{keys}{G C-n}
+        h       & Enter article-buffer.\\
+        G b     & (,) Go to the {\bf best} article (the one with highest score).\\
+        G f     & (.) Go to the {\bf first} unread article.\\
+        G n     & (n) Go to the {\bf next} unread article.\\
+        G p     & (p) Go to the {\bf previous} unread article.\\
+                                %
+        G N     & (N) Go to {\bf the} next article.\\
+        G P     & (P) Go to the {\bf previous} article.\\
+                                %
+        G C-n   & (M-C-n) Go to the {\bf next} article with the same subject.\\
+        G C-p   & (M-C-p) Go to the {\bf previous} article with the same subject.\\
+                                %
+        G l     & (l) Go to the previously read article ({\bf last-read-article}).\\
+        G o     & Pop an article off the summary history and go to it.\\
+                                %
+        G g     & Search an article via subject.\\
+        G j     & (j) Search an article via Message-Id or subject.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\ArticleModeGeneral}{%
+    {\esamepage
+      The normal navigation keys work in Article mode. Some additional keys are:\\*
+      \begin{keys}{C-c RET}
+        C-c \^{} & Get the article with the Message-ID near point.\\
+        C-c RET & Send reply to address near point.\\
+        h       & Go to the \textbf{header}-line of the article in the
+        summary-buffer.\\
+        s       & Go to \textbf{summary}-buffer.\\
+        RET     & (middle mouse button) Activate the button at point to follow
+        an URL or Message-ID.\\
+        TAB     & Move the point to the next button.\\
+        M-TAB   & Move point to previous button.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\WashArticle}{% formerly \Wsubmap
+    {\esamepage
+      \begin{keys}{W W H}
+        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 m     & Toggle {\bf MIME} processing.\\
+        W o     & Treat {\bf overstrike} or underline (\^{}H\_) in the article.\\
+        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 t     & (t) {\bf Toggle} display of all headers.\\
+        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 W H   & Strip certain {\bf headers} from body.\\
+                                %
+        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.\\
+        W E t   & Remove {\bf trailing} blank lines.\\
+        W E a   & Strip blank lines at the beginning and the end
+        (W E l, W E m and W E t).\\
+        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 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.\\
+      \end{keys}
+      }
+    }
+
+  \newcommand{\HideHighlightArticle}{%
+    {\esamepage
+      \begin{keys}{W W C-c}
+        W W a   & Hide {\bf all} unwanted parts. Calls W W h, W W s, W W C-c.\\
+        W W h   & Hide article {\bf headers}.\\
+        W W b   & Hide {\bf boring} headers.\\
+        W W s   & Hide {\bf signature}.\\
+        W W l   & Hide {\bf list} identifiers in subject-header.\\
+        W W p   & Hide {\bf PGP}-signatures.\\
+        W W P   & Hide {\bf PEM} (privacy enhanced messages).\\
+        W W B   & Hide banner specified by group parameter.\\
+        W W c   & Hide {\bf citation}.\\
+        W W C-c & Hide {\bf citation} using a more intelligent algorithm.\\
+        W W C   & Hide cited text in articles that aren't roots.\\
+                                %
+        W e     & {\bf Emphasize} article.\\
+                                %
+        W H a   & Highlight {\bf all} parts. Calls W b, W H c, W H h, W H s.\\
+        W H c   & Highlight article {\bf citations}.\\
+        W H h   & Highlight article {\bf headers}.\\
+        W H s   & Highlight article {\bf signature}.\\
+      \end{keys}
+      For all hiding-commands: A positive prefix always hides, and a negative
+      prefix will show what was previously hidden.
+      }}
+
+  \newcommand{\MIMEArticleMode}{%
+    {\esamepage
+      \begin{keys}{M-RET}
+        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       & {\bf Copy} the MIME object to a new buffer and display this buffer.\\
+        t       & View the MIME object as a different {\bf type}.\\
+        $\mid$  & Pipe the MIME object to a process.\\
+      \end{keys}
+      }
+    }
+
+  %% end of article mode for reading ..........................................
+
+  \newcommand{\MarkArticlesGeneral}{% formerly \Msubmap
+    {\esamepage
+      \begin{keys}{M M-C-r}
+        d       & (M d, M r) Mark this article as read and move to the next one.
+        [scope]\\ 
+        D       & Mark this article as read and move to the previous one. [scope]\\
+        !       & (u, M !, M t) Tick this article (mark it as interesting) and move
+        to the next one. [scope]\\
+        U       & Tick this article and move to the previous one. [scope]\\ 
+        M ?     & (?) Mark this article as dormant (only followups are
+        interesting). [scope]\\ 
+        M D     & Show all {\bf dormant} articles (normally they are hidden unless they
+        have any followups).\\
+        M M-D   & Hide all {\bf dormant} articles.\\
+        C-w     & Mark all articles between point and mark as read.\\
+        M-u     & (M SPC, M c) Clear all marks from this article and move to the next
+        one. [scope]\\ 
+        M-U     & Clear all marks from this article and move to the previous one.
+        [scope]\\
+                                %
+        M e     & (E, M x) Mark this article as {\bf expirable}. [scope]\\
+                                %
+        M k     & (k) {\bf Kill} all articles with the same subject then select the
+        next unread one.\\ 
+        M K     & (C-k) {\bf Kill} all articles with the same subject as this one.\\
+                                %
+        M C     & {\bf Catch-up} the articles that are not ticked and not dormant.\\
+        M C-c   & {\bf Catch-up} all articles in this group.\\
+        M H     & {\bf Catch-up} (mark read) this group to point (to-{\bf here}).\\
+                                %
+        M b     & Set a {\bf bookmark} in this article.\\
+        M B     & Remove the {\bf bookmark} from this article.\\
+                                %
+        M M-r   & (x) Expunge all {\bf read} articles from this group.\\
+        M M-C-r & Expunge all articles having a given mark.\\
+        M S     & (C-c M-C-s) {\bf Show} all expunged articles.\\
+        M M C-h & Displays some more keys doing ticking slightly differently.\\
+      \end{keys}
+      The variable `gnus-summary-goto-unread' controls what happens after a mark
+      has been set (C-x C-i g Setting Marks RET)
+      }}
+
+  \newcommand{\MarkByScore}{%
+    \begin{keys}{M V m}
+      M V c   & {\bf Clear} all marks from all high-scored articles. [score]\\
+      M V k   & {\bf Kill} all low-scored articles. [score]\\
+      M V m   & Mark all high-scored articles with a given {\bf mark}. [score]\\
+      M V u   & Mark all high-scored articles as interesting (tick them). [score]\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\ProcessMark}{%
+  {\esamepage 
+    These commands set and remove the process mark (\#). You only need to use
+    it if the set of articles you want to operate on is non-contiguous. Else
+    use a numeric prefix.\\*
+    \begin{keys}{M P R}
+      M P p   & (\#, M \#) Mark this article.\\
+      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 R   & Mark all articles matching a {\bf regexp}.\\
+      M P t   & Mark 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.\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\Limiting}{%
+  {\esamepage
+    \begin{keys}{/M}
+      //   & (/s) Limit the summary-buffer to articles matching {\bf subject}.\\
+      /a   & Limit the summary-buffer to articles matching {\bf author}.\\
+      /x   & Limit depending on ``extra'' headers.\\
+      /u   & (x) Limit to {\bf unread} articles.
+      [Prefix: also exclude ticked and dormant articles]\\
+      /m   & Limit to articles marked with specified {\bf mark}.\\
+      /t   & Ask for a number and exclude articles younger than that many days.
+      [Prefix: exclude older articles]\\
+      /n   & Limit to current article. [p/p]\\
+      /w   & Pop the previous limit off the stack and restore it.
+      [Prefix: pop all limits]\\
+      /v   & Limit to score. [score]\\
+      /E   & (M S) Include all expunged articles in the limit.\\
+      /D   & Include all dormant articles in the limit.\\
+      /*   & Include all cached articles in the limit.\\
+      /d   & Exclude all dormant articles from the limit.\\
+      /M   & Exclude all marked articles.\\
+      /T   & Include all articles from the current thread in the limit.\\
+      /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]\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\OutputArticles}{% formerly \Osubmap
+  {\esamepage
+    \begin{keys}{O m}
+      O o     & (o, C-o) Save this article using the default article saver. [p/p]\\
+      O b     & Save this article's {\bf body} in plain file format [p/p]\\
+      O f     & Save this article in plain {\bf file} format. [p/p]\\
+      O F     & like O f, but overwrite file's contents. [p/p]\\
+      O h     & Save this article in {\bf mh} folder format. [p/p]\\
+      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]\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\PostReplyetc}{% formerly \Ssubmap
+  {\esamepage
+    These commands put you in a separate news or mail buffer. See the section
+    about composing messages for more information.
+                                %After
+                                %editing the article, send it by pressing C-c C-c.  If you are in a
+                                %foreign group and want to post the article using the foreign server, give
+                                %a prefix to C-c C-c.\\* 
+    \begin{keys}{S O m}
+      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 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 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 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 D b   & Resend {\bf bounced} mail.\\
+      S D r   & {\bf Resend} mail to a different person.\\
+                                %
+      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 s     & {\bf Supersede} this article with a new one (only for own
+      articles).\\
+                                %
+      S O m   & Digest these series and forward by {\bf mail}. [p/p]\\
+      S O p   & Digest these series and forward as a {\bf post} to a newsgroup.
+      [p/p]\\ 
+                                %
+      S u     & {\bf Uuencode} a file and post it as a series.\\
+    \end{keys}
+    If you want to cancel or supersede an article you just posted (before it
+    has appeared on the server), go to the *post-news* buffer, change
+    `Message-ID' to `Cancel' or `Supersedes' and send it again with C-c C-c.
+    }}
+
+\newcommand{\Threading}{% formerly \Tsubmap
+  {\esamepage
+    \begin{keys}{T M-\#}
+      T \#    & Mark this thread with the process mark.\\
+      T M-\#  & Remove process-marks from this thread.\\
+                                %
+      T t     & Re-{\bf thread} the current article's thread.\\
+                                % 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 d     & {\bf Descend} this thread. [distance]\\
+      T u     & Ascend this thread ({\bf up}-thread). [distance]\\
+      T o     & Go to the top of this thread.\\
+                                %
+      T s     & {\bf Show} the thread hidden under this article.\\
+      T h     & {\bf Hide} this (sub)thread.\\
+                                %
+      T i     & {\bf Increase} the score of this thread.\\
+      T l     & (M-C-l) {\bf Lower} the score of this thread.\\
+                                %
+      T k     & (M-C-k) {\bf Kill} the current (sub)thread. [Negative prefix:
+      tick it, positive prefix: unmark it.]\\
+                                %
+      T H     & {\bf Hide} all threads.\\
+      T S     & {\bf Show} all hidden threads.\\
+      T T     & (M-C-t) {\bf Toggle} threading.\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\Scoring}{% formerly \Vsubmap
+  {\esamepage
+    Read about Adaptive Scoring in the online info.\\*
+    \begin{keys}{\bf A p m l}
+      V a     & {\bf Add} a new score entry, specifying all elements.\\
+      V c     & Specify a new score file as {\bf current}.\\
+      V e     & {\bf Edit} the current score alist.\\
+      V f     & Edit a score {\bf file} and make it the current one.\\
+      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}).\\
+      V x     & {\bf Expunge} all low-scored articles. [score]\\
+      V C     & {\bf Customize} the current score file through a user-friendly
+      interface.\\ 
+      V S     & Display the {\bf score} of this article.\\
+      \bf A p m l& Make a scoring entry based on this article.\\
+    \end{keys}
+    The four letters stand for:\\*
+    \quad \B{A}ction: I)ncrease, L)ower;\\*
+    \quad \B{p}art: a)utor (from), s)ubject, x)refs (cross-posting), d)ate, l)ines,
+    message-i)d, t)references (parent), f)ollowup, b)ody, h)ead (all headers);\\*
+    \quad \B{m}atch type:\\*
+    \qquad string: s)ubstring, e)xact, r)egexp, f)uzzy,\\*
+    \qquad date: b)efore, a)t, n)this,\\*
+    \qquad number: $<$, =, $>$;\\*
+    \quad \B{l}ifetime: t)emporary, p)ermanent, i)mmediate.
+
+    If you type the second letter in uppercase, the remaining two are assumed
+    to be s)ubstring and t)emporary. 
+    If you type the third letter in uppercase, the last one is assumed to be 
+    t)emporary.
+
+    \quad Extra keys for manual editing of a score file:\\*
+    \begin{keys}{C-c C-c}
+      C-c C-c & Finish editing the score file.\\
+      C-c C-d & Insert the current {\bf date} as number of days.\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\ExtractSeries}{% formerly \Xsubmap
+  {\esamepage
+    Gnus recognizes if the current article is part of a series (multipart
+    posting whose parts are identified by numbers in their subjects, e.g.{}
+    1/10\dots10/10) and processes the series accordingly. You can mark and
+    process more than one series at a time. If the posting contains any
+    archives, they are expanded and gathered in a new group.\\*
+    \begin{keys}{X p}
+      X b     & Un-{\bf binhex} these series. [p/p]\\
+      X o     & Simply {\bf output} these series (no decoding). [p/p]\\ 
+      X p     & Unpack these {\bf postscript} series. [p/p]\\
+      X s     & Un-{\bf shar} these series. [p/p]\\
+      X u     & {\bf Uudecode} these series. [p/p]\\
+    \end{keys}
+
+    Each one of these commands has four variants:\\*
+    \begin{keys}{X v \bf Z}
+      X   \bf z & Decode these series. [p/p]\\
+      X   \bf Z & Decode and save these series. [p/p]\\
+      X v \bf z & Decode and view these series. [p/p]\\
+      X v \bf Z & Decode, save and view these series. [p/p]\\
+    \end{keys}
+    where {\bf z} or {\bf Z} identifies the decoding method (b, o, p, s, u).
+
+    An alternative binding for the most-often used of these commands is\\*
+    \begin{keys}{C-c C-v C-v}
+      C-c C-v C-v & (X v u) Uudecode and view these series. [p/p]\\
+    \end{keys}
+    }}
+
+\newcommand{\ExitSummary}{% formerly \Zsubmap
+  {\esamepage
+    \begin{keys}{Z G}
+      Z Z     & (q, Z Q) Exit this group.\\
+      Z E     & (Q) {\bf Exit} without updating the group information.\\
+                                %
+      Z c     & (c) Mark all unticked articles as read ({\bf catch-up}) and exit.\\
+      Z C     & Mark all articles as read ({\bf catch-up}) and exit.\\
+                                %
+      Z n     & Mark all articles as read and go to the {\bf next} group.\\
+      Z N     & Exit and go to {\bf the} next group.\\
+      Z P     & Exit and go to the {\bf previous} group.\\
+                                %
+      Z G     & (M-g) Check for new articles in this group ({\bf get}).\\
+      Z R     & Exit this group, and then enter it again ({\bf reenter}).
+      [Prefix: select all articles, read and unread.]\\
+      Z s     & Update and save the dribble buffer. [Prefix: save .newsrc* as well]\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\MsgCompositionGeneral}{%
+  Press C-c ? in the composition-buffer to get this information.
+  {\esamepage
+    \begin{keys}{C-c C-m}
+                                % sending
+      C-c C-c & Send message and exit. [Prefix: send via foreign server]\\
+      C-c C-s & Send message. [Prefix: send via foreign server]\\
+      C-c C-d & Don't send message (save as \textbf{draft}).\\
+      C-c C-k & \textbf{Kill} message-buffer.\\
+      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.\\
+      C-c C-r & Do a \textbf{Rot-13} on the body.\\
+      C-c C-w & Insert signature (from `message-signature-file').\\
+      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.\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\MsgCompositionMovementArticle}{%
+  The following functions create the header-field if necessary.
+  {\esamepage
+    \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-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-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:}.\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\MsgCompositionMML}{%
+  {\esamepage
+    \begin{keys}{M-m P}
+      M-m f   & (C-c C-a) Attach \textbf{file}.\\
+      M-m b   & Attach contents of \textbf{buffer}.\\
+      M-m e   & Attach \textbf{external} file (ftp..).\\
+      M-m P   & Create MIME-\textbf{preview} (new buffer).\\
+      M-m v   & \textbf{Validate} article.\\
+      M-m p   & Insert \textbf{part}.\\
+      M-m m   & Insert \textbf{multi}-part.\\
+      M-m q   & \textbf{Quote} region.\\
+                                % TODO: narrow headers (M-m n) ?
+    \end{keys}
+    }
+  }
+
+%% TODO:
+\newcommand{\ServerMode}{%
+  {\esamepage
+    To enter this mode, press `\^' while in Group mode.\\*
+    \begin{keys}{SPC}
+      SPC     & (RET) Browse this server.\\
+      a       & {\bf Add} a new server.\\
+      c       & {\bf Copy} this server.\\
+      e       & {\bf Edit} a server.\\
+      k       & {\bf Kill} this server. [scope]\\
+      l       & {\bf List} all servers.\\
+      q       & Return to the group buffer ({\bf quit}).\\
+      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.\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\BrowseServer}{%
+  {\esamepage
+    To enter this mode, press `B' while in Group mode.\\*
+    \begin{keys}{RET}
+      RET     & Enter the current group.\\
+      SPC     & Enter the current group and display the first article.\\
+      ?       & Give a very short help message.\\
+      n       & Go to the {\bf next} group. [distance]\\
+      p       & Go to the {\bf previous} group. [distance]\\
+      q       & (l) {\bf Quit} browse mode.\\
+      u       & Subscribe to the current group. [scope]\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\GroupUnplugged}{%
+  {\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 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].\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\SummaryUnplugged}{%
+  {\esamepage
+    \begin{keys}{J M-\#}
+      J \#   & \textbf{Mark} the article for downloading.\\
+      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}).\\
+    \end{keys}
+    }
+  }
+
+\newcommand{\ServerUnplugged}{%
+  {\esamepage
+    \begin{keys}{J a}
+      J a & \textbf{Add} the current server to the list of servers covered
+      by the agent.\\
+      J r & \textbf{Remove} the current server from the list of servers covered
+      by the agent.\\
+    \end{keys}
+    }
+  }
diff --git a/texi/pagestyle.sty b/texi/pagestyle.sty
new file mode 100644 (file)
index 0000000..ffd4529
--- /dev/null
@@ -0,0 +1,85 @@
+\def\verbatim@font{\fontencoding{OT1}\fontfamily{pcr}\fontsize{10pt}{10}\selectfont}
+
+\catcode `\÷ = \active
+\def Ã·{\penalty10000\hskip0.001pt-\penalty\hyphenpenalty\hskip0.001pt\relax}
+
+\def \newpagestyle#1#2#3{\@namedef{ps@#1}{\def\@oddhead{#2}\def\@oddfoot{#3}%
+       \let\@evenhead\@oddhead \let\@evenfoot\@oddfoot}}
+\def \newdoublepagestyle#1#2#3#4#5{\@namedef{ps@#1}{\def\@evenhead{#2}%
+       \def\@oddhead{#3}%
+       \def\@evenfoot{#4}%
+       \def\@oddfoot{#5}}}
+
+\newlength{\headtextwidth}
+\setlength{\headtextwidth}{\textwidth}
+\addtolength{\headtextwidth}{2cm}
+\newlength{\headetextwidth}
+\setlength{\headetextwidth}{\headtextwidth}
+\addtolength{\headetextwidth}{-0.5cm}
+\newlength{\headotextwidth}
+\setlength{\headotextwidth}{\headtextwidth}
+\addtolength{\headotextwidth}{-0.35cm}
+\def\outputpage{%
+  \let \protect \noexpand
+  \shipout \vbox{%
+    \set@typeset@protect
+    \aftergroup\set@typeset@protect
+    \@shipoutsetup
+    \@begindvi
+    \vskip \topmargin
+    \moveright\@themargin \vbox {%
+      \setbox\@tempboxa \vbox to\headheight{%
+        \vfil
+        \color@hbox
+          \normalcolor
+          \hb@xt@ \headtextwidth {%
+            \let \label \@gobble
+            \let \index \@gobble
+            \let \glossary \@gobble %% 21 Jun 91
+            \@thehead
+            }%
+        \color@endbox
+        }%                        %% 22 Feb 87
+      \ifodd\c@page
+         \dp\@tempboxa \z@
+         \box\@tempboxa \mbox{} \\
+        \ifx \@oddhead\@empty\else
+   %      \rule{\headotextwidth}{0.5pt}
+         \fi
+      \else
+        \hskip -2.2cm
+         \dp\@tempboxa \z@
+         \box\@tempboxa \mbox{}
+       \\\mbox{}
+        \vskip 2pt
+        \hskip -2.0cm 
+        \ifx \@oddhead\@empty\else
+    %     \rule{\headetextwidth}{0.5pt}
+         \fi
+      \fi  
+      \vskip \headsep
+      \box\@outputbox
+      \baselineskip \footskip
+      \color@hbox
+        \normalcolor
+        \hb@xt@\textwidth{%
+          \let \label \@gobble
+          \let \index \@gobble      %% 22 Feb 87
+          \let \glossary \@gobble   %% 21 Jun 91
+          \@thefoot
+          }%
+      \color@endbox
+      }%
+    }%
+  \global \@colht \textheight
+  \stepcounter{page}%
+  \let\firstmark\botmark
+}
+
+\def\@makechapterhead#1{\gnuspagechapter{#1}}
+
+\setcounter{tocdepth}{3}
+\setcounter{secnumdepth}{3}
+
+\def\verbatim@font{\fontfamily{bcr}\fontsize{10pt}{10}\selectfont}
diff --git a/texi/pixidx.sty b/texi/pixidx.sty
new file mode 100644 (file)
index 0000000..13be2e5
--- /dev/null
@@ -0,0 +1,229 @@
+% SHOWIDX DOCUMENT-STYLE OPTION - released 16 June 1991
+%    for LaTeX version 2.09
+% Copyright (C) 1985, 1988, 1989, 1991 by Leslie Lamport
+% Modified by Lars Ingebrigtsen 1993
+%
+% Prints \index entries in outer margin. For use with book or report
+% style.  Note: makes \flushbottom the default.
+
+\typeout{Document style option `showidx' - released 16 June 1991}
+\typeout{Modified for use in eyesore.}
+
+\newbox\eye@boxa
+\newbox\eye@boxb
+\newbox\eye@boxc
+\newbox\eye@boxd
+\newbox\eye@boxe
+\newbox\eye@boxf
+\newbox\eye@boxg
+\newbox\eye@box
+\newbox\new@box
+
+  \global \setbox \eye@boxa \hbox{}
+  \global \setbox \eye@boxb \hbox{}
+  \global \setbox \eye@boxc \hbox{}
+  \global \setbox \eye@boxd \hbox{}
+  \global \setbox \eye@boxe \hbox{}
+  \global \setbox \eye@boxf \hbox{}
+  \global \setbox \eye@boxg \hbox{}
+
+\newdimen\eye@boxadim \global\eye@boxadim\z@
+\newdimen\eye@boxbdim \global\eye@boxbdim\z@
+\newdimen\eye@boxcdim \global\eye@boxcdim\z@
+\newdimen\eye@boxddim \global\eye@boxddim\z@
+\newdimen\eye@boxedim \global\eye@boxedim\z@
+\newdimen\eye@boxfdim \global\eye@boxfdim\z@
+\newdimen\eye@boxgdim \global\eye@boxgdim\z@
+
+\newdimen\gnus@horiz \global\gnus@horiz\z@
+\newdimen\gnus@vert \global\gnus@vert\z@
+
+
+\newdimen\eye@height
+\global\eye@height\textheight
+% \global\advance\eye@height 8cm
+
+\newdimen\eyeins@height
+\global\eyeins@height\z@
+
+\newdimen\eye@adjust
+\global\eye@adjust 0cm
+
+\newinsert\indexbox
+\dimen\indexbox=\maxdimen
+
+\newinsert\gnusbox
+\dimen\gnusbox=\maxdimen
+
+\newdimen\eye@dim
+\newdimen\new@dim
+\newdimen\doinsert
+
+\newdimen\eye@strutd
+\def\eye@strut#1{%
+  \eye@strutd#1
+  \advance\eye@strutd\eye@adjust
+  \advance\eye@strutd -1mm
+  \raisebox{-\eye@strutd}[0pt][0pt]{\rule{1mm}{\eye@strutd}}
+}
+
+\newdimen\eye@tmpd
+\newbox\eye@tmpba
+\newbox\eye@tmpbb
+\def\eye@insbox#1#2#3{%
+  \eye@dim#2
+  \advance\eye@dim\ht#3
+  \advance\eye@dim\eye@adjust
+  \ifdim \eye@dim < \eye@height 
+    \global#2\eye@dim
+    \global\setbox#1
+       \hbox{\unhbox#1
+%             \eye@strut{\ht#3}
+             \unhbox#3
+             \vrule \@height 1cm \@width\z@}
+    \setbox #3 \hbox{}
+  \fi}
+
+\def\@showidx#1{
+  \setbox\new@box\hbox{#1}
+  % \typeout{Vi er i showidx.}
+  \new@dim\z@
+  \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxa\eye@boxadim\new@box 
+    \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxb\eye@boxbdim\new@box 
+    \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxc\eye@boxcdim\new@box 
+    \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxd\eye@boxddim\new@box 
+    \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxe\eye@boxedim\new@box 
+    \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxf\eye@boxfdim\new@box 
+    \ifdim \ht\new@box > \z@
+    \eye@insbox\eye@boxg\eye@boxgdim\new@box 
+    \ifdim \ht\new@box > \z@
+    \else
+      \typeout{Discarding index.}
+    \fi\fi\fi\fi\fi\fi\fi
+  \fi
+
+    \doinsert \z@
+    \ifdim \eyeins@height > \z@
+      \eye@dim\eyeins@height
+      \advance\eye@dim\eye@boxadim
+      \ifdim \eye@dim < \eye@height 
+         \global\eyeins@height\eye@dim
+         \doinsert 1pt
+      \fi
+   \else
+     \doinsert 1pt
+     \global\eyeins@height\eye@boxadim
+   \fi
+
+  \ifdim \ht\eye@boxa > \z@
+  
+    \ifdim \doinsert > \z@
+%      \typeout{Vi inserter i indexbox.}
+      \insert\indexbox{
+         \small
+         \hsize\marginparwidth
+         \hangindent\marginparsep 
+         \parindent\z@
+         \parfillskip\@flushglue
+         \everypar{}\let\par\@@par 
+         \lineskip\normallineskip
+         \baselineskip .8\normalbaselineskip
+         \ifodd\c@page\raggedleft\else\raggedright\fi
+         \leavevmode
+         \relax
+         \unhbox\eye@boxa
+         \relax
+      }
+      \global \setbox \eye@boxa \copy\eye@boxb
+      \global \setbox \eye@boxb \copy\eye@boxc
+      \global \setbox \eye@boxc \copy\eye@boxd
+      \global \setbox \eye@boxd \copy\eye@boxe
+      \global \setbox \eye@boxe \copy\eye@boxf
+      \global \setbox \eye@boxf \copy\eye@boxg
+      \global \setbox \eye@boxg \hbox{}
+      \global \eye@boxadim\eye@boxbdim
+      \global \eye@boxbdim\eye@boxcdim
+      \global \eye@boxcdim\eye@boxddim
+      \global \eye@boxddim\eye@boxedim
+      \global \eye@boxedim\eye@boxfdim
+      \global \eye@boxfdim\eye@boxgdim
+      \global \eye@boxgdim\z@
+    \fi
+  \fi
+
+}
+
+\def\@rightidx{\hskip\columnwidth \hskip\marginparsep}
+\def\@leftidx{\hskip-\marginparsep \hskip-\marginparwidth}
+
+\def\@mkidx{
+
+%  \typeout{Vi er i mkidx 1.}
+
+  \vbox to \z@{
+    \vskip \gnus@vert
+    \hbox{
+      \hskip \gnus@horiz
+      \box\gnusbox
+    }\vss
+  }
+  \vbox to \z@{ 
+    \ifdim \eyeins@height < \textheight
+      \eye@dim \textheight
+      \advance \eye@dim -\eyeins@height
+%      \vskip \eye@dim
+    \else 
+      \eye@dim \eye@height
+      \advance \eye@dim -3cm
+      \ifdim \eyeins@height > \eye@dim
+      %   \vskip -3cm
+    \fi\fi
+    \hbox{
+      \ifodd\c@page \@rightidx \else \@leftidx \fi
+      \box\indexbox
+    }\vss
+  }
+
+  \global\eyeins@height\z@
+
+}
+
+\def\raggedbottom{\def\@textbottom{\vskip
+      \z@ plus.0001fil}\let\@texttop\@mkidx}
+\def\flushbottom{\let\@textbottom\relax \let\@texttop\@mkidx}
+
+\def\margindex#1{\@bsphack
+\begingroup\@sanitize\catcode32=10\relax\@showidx{#1}
+ \endgroup\@esphack}
+
+\def\@gnusfig#1{
+  \insert\gnusbox{
+     \small
+     \hsize\textwidth
+     \hangindent\marginparsep 
+     \parindent\z@
+     \parfillskip\@flushglue
+     \everypar{}\let\par\@@par 
+     \lineskip\normallineskip
+     \baselineskip .8\normalbaselineskip
+     \ifodd\c@page\raggedleft\else\raggedright\fi
+     \leavevmode
+     \relax
+     #1
+     \relax
+  }
+}
+
+\def\gnusfig#1#2#3{\@bsphack
+\begingroup\@sanitize\catcode32=10\relax\@gnusfig{#3}\global\gnus@horiz#1 \global\gnus@vert#2
+ \endgroup\@esphack}
+
+\flushbottom
+
+\endinput
index 3b5f803..a7d0a5c 100644 (file)
 \thispagestyle{empty}
 \vfill
 
-\begin{picture}(10,10)
-\put(90,-10){\makebox(0,0)[tr]{\epsfig{figure=tmp/larsi.ps,height=3cm}}}
-\end{picture}
-
-\hspace*{4cm}\parbox[t]{10cm}{
-This manual was written by Lars Magne Ingebrigtsen (b. 1968) who
+This manual was written by Lars Magne Ingebrigtsen (1968 --- ) who
 resides in Oslo, Norway and poses as a student, but doesn't get much
 studying done, for some strange reason or other.  When not worshipping
 at the altar of Emacs, he can often be found slouching on his couch
 reading while bopping his head gently to some obscure music.  He does
 not have a cat.
 
-Graphics by Luis Fernandes.  Set in Bembo and Futura.
-}
+\marginpar[\vspace*{-2.5cm}\epsfig{figure=tmp/larsi.ps,height=2cm}]{\vspace*{-2.2cm}\epsfig{figure=tmp/larsi.ps,height=2.5cm}}
+
+Graphics by Luis Fernandes.  Set in Adobe Bembo, Adobe Futura and
+Bitstream Courier.
 
 \clearpage
 \mbox{}
diff --git a/texi/ps/gnus-big-logo.eps b/texi/ps/gnus-big-logo.eps
new file mode 100644 (file)
index 0000000..88ea3b8
--- /dev/null
@@ -0,0 +1,213 @@
+%!PS-Adobe-2.0 EPSF-1.2
+%%Creator: Adobe Illustrator 88(TM) format generated by CorelTRACE Version 2.0C
+%%Title:  /home/menja/c/larsi/rgnus/texi/ps/eegnu.eps
+%%BoundingBox: 0 0 890.3 909.7
+%%CreationDate: Fri Oct 11 14:59:05 1996
+%%DocumentFonts:
+%%ColorUsage: B & W
+%%TileBox: 0 0 890.3 909.7
+%%EndComments
+%%BeginProcSet:Adobe_Illustrator_1.1 0 0
+% Copyright 1992 Corel Corporation.
+
+% All rights reserved.
+/wPSMDict 150 dict def
+wPSMDict begin
+/bd {bind def} bind def
+/ld {load def} bd
+/xd {exch def} bd
+/_ null def
+/$c 0 def
+/$m 0 def
+/$y 0 def
+/$k 0 def
+/$t 1 def
+/$n _ def
+/$o 0 def
+/$C 0 def
+/$M 0 def
+/$Y 0 def
+/$K 0 def
+/$T 1 def
+/$N _ def
+/$O 0 def
+/$h false def
+/$al 0 def
+/$tr 0 def
+/$le 0 def
+/$lx 0 def
+/$ly 0 def
+/$ctm matrix currentmatrix def
+/@cp /closepath ld
+/@gs /gsave ld
+/@gr /grestore ld
+/@MN {2 copy le{pop}{exch pop}ifelse}bd
+/setcmykcolor where {pop}{/setcmykcolor{4 1 roll
+3 {3 index add 1 @MN 1 exch sub 3 1 roll} repeat
+setrgbcolor
+pop}bd}ifelse
+/@tc{dup 1 ge{pop}{4 {dup
+6 -1 roll
+mul
+exch}repeat
+pop}ifelse}bd
+/@scc{$c $m $y $k $t @tc setcmykcolor true}bd
+/@SCC{$C $M $Y $K $T @tc setcmykcolor true}bd
+/@sm{/$ctm $ctm currentmatrix def}bd
+/x {/$t xd /$n xd
+/$k xd /$y xd /$m xd /$c xd}bd
+/X {/$T xd /$N xd
+/$K xd /$Y xd /$M xd /$C xd}bd
+/g {1 exch sub 0 0 0
+4 -1 roll
+_ 1 x}bd
+/G {1 exch sub 0 0 0
+4 -1 roll
+_ 1 X}bd
+/k {_ 1 x}bd
+/K {_ 1 X}bd
+/d /setdash ld
+/i {dup 0 ne {setflat} {pop} ifelse}bd
+/j /setlinejoin ld
+/J /setlinecap ld
+/M /setmiterlimit ld
+/w /setlinewidth ld
+/O {/$o xd}bd
+/R {/$O xd}bd
+/c /curveto ld
+/C /c ld
+/l /lineto ld
+/L /l ld
+/m /moveto ld
+/n /newpath ld
+/N /newpath ld
+/F {@scc{eofill}if n} bd
+/f {@cp F}bd
+/S {@SCC{stroke}if n} bd
+/s {@cp
+S}bd
+/B {@gs F @gr
+S}bd
+/b {@cp B }bd
+/u {}bd
+/U {}bd
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+1 i
+2 J
+0 j
+4 M
+[]0 d
+
+%%Note: traced as Normal_Outline
+0 g
+163.4 2.9 m
+197.1 51.5 223.7 94.3 251.6 130.7 C
+283.4 176.1 312.0 216.3 342.8 256.8 C
+373.2 303.2 401.1 342.1 420.0 396.9 C
+421.2 403.1 425.1 408.9 424.5 413.5 C
+395.6 371.6 368.4 326.2 337.2 285.0 C
+306.1 247.4 276.3 199.4 244.5 161.5 C
+212.1 116.7 182.9 79.1 168.6 20.4 C
+166.3 13.9 164.7 8.1 162.4 2.2 C
+162.4 2.2 163.4 2.9 163.4 2.9 C
+f
+0 g
+428.1 170.2 m
+428.1 170.2 429.7 170.2 430.0 170.5 C
+454.7 211.4 474.8 275.6 504.0 301.9 C
+512.1 300.6 515.0 280.8 527.3 283.1 C
+534.8 284.4 536.4 284.1 542.9 288.9 C
+571.4 331.1 600.3 374.5 623.6 423.2 C
+640.2 454.7 661.6 492.9 663.5 517.6 C
+660.3 515.6 L
+633.7 468.6 613.2 419.6 582.4 378.4 C
+572.1 367.1 566.5 352.8 550.7 348.3 C
+543.2 348.3 536.1 354.4 530.5 363.8 C
+528.9 367.1 528.9 368.1 525.4 369.7 C
+495.5 333.7 466.7 282.8 446.5 233.5 C
+436.2 206.2 433.2 190.0 427.4 170.5 C
+427.4 170.5 428.1 170.2 428.1 170.2 C
+f
+0 g
+754.7 271.7 m
+783.8 345.7 780.3 386.2 794.2 447.5 C
+806.2 497.1 819.2 543.8 843.5 614.9 C
+869.5 690.4 875.0 731.0 888.0 787.1 C
+892.5 826.7 892.8 865.9 869.5 898.7 C
+853.9 908.7 841.9 912.3 822.1 909.4 C
+785.5 890.2 764.1 846.4 749.8 799.7 C
+750.4 793.6 750.8 791.3 755.0 788.1 C
+755.6 788.1 756.9 788.1 757.9 788.1 C
+772.8 803.3 773.8 842.9 796.8 849.0 C
+817.6 849.0 826.3 847.7 840.3 834.8 C
+855.8 799.7 856.2 789.4 858.1 755.0 C
+855.2 687.5 836.7 643.7 819.8 576.9 C
+801.7 513.7 781.9 454.3 772.8 406.7 C
+766.3 361.6 755.0 332.4 754.0 271.7 C
+754.0 271.7 754.7 271.7 754.7 271.7 C
+f
+0 g
+383.0 484.8 m
+421.2 539.0 420.6 593.1 405.4 650.9 C
+395.0 674.5 382.7 683.6 367.7 695.0 C
+354.8 681.0 339.2 664.2 330.1 640.2 C
+330.1 640.2 330.1 638.5 330.4 638.2 C
+351.5 628.8 372.3 592.2 378.1 567.2 C
+381.0 544.5 378.8 505.2 382.3 484.8 C
+382.3 484.8 383.0 484.8 383.0 484.8 C
+f
+0 g
+120.6 509.8 m
+171.2 511.7 215.0 550.7 255.8 589.6 C
+283.4 609.7 302.2 627.8 315.8 663.5 C
+280.8 636.9 238.3 595.7 192.6 571.7 C
+179.6 566.2 162.4 565.6 147.8 570.4 C
+139.4 578.2 136.2 580.5 136.5 588.6 C
+144.6 635.3 192.3 684.3 217.6 724.8 C
+223.4 738.1 235.7 745.9 238.3 758.9 C
+204.3 726.8 174.1 677.1 147.5 634.3 C
+127.1 600.3 95.3 560.1 102.1 520.5 C
+107.0 510.8 111.8 513.7 120.6 509.8 C
+f
+0 g
+621.7 657.7 m
+669.0 661.2 703.4 716.1 724.8 769.6 C
+730.7 779.0 728.7 785.5 731.3 792.9 C
+711.8 758.5 695.0 728.4 656.7 720.9 C
+638.2 720.3 635.0 721.9 624.9 732.6 C
+621.7 736.5 620.4 739.4 618.1 744.3 C
+588.6 683.0 L
+593.1 671.6 598.3 665.5 608.1 661.9 C
+612.0 661.6 617.8 659.0 621.7 657.7 C
+f
+0 g
+502.0 681.0 m
+526.7 680.4 547.7 694.7 565.2 716.1 C
+576.0 734.9 583.1 755.0 592.2 775.4 C
+592.2 779.6 591.5 783.2 592.8 786.8 C
+582.4 775.7 571.4 752.7 549.7 746.5 C
+520.8 736.2 500.7 751.4 481.6 766.7 C
+440.4 802.3 416.7 847.7 366.8 868.5 C
+346.3 878.2 335.0 875.6 319.1 869.5 C
+300.3 862.7 292.8 850.7 279.2 833.8 C
+285.0 838.3 271.7 828.6 277.2 833.5 C
+268.5 845.8 244.2 875.3 220.8 881.1 C
+168.6 888.3 147.5 809.8 96.3 789.4 C
+83.3 784.8 72.0 776.7 61.2 781.6 C
+41.5 794.2 38.2 804.6 27.5 824.1 C
+2.2 764.7 L
+9.0 751.1 16.8 730.3 32.1 725.1 C
+45.0 720.3 55.1 721.6 68.1 727.1 C
+91.1 745.2 116.4 758.9 132.0 779.3 C
+140.1 789.4 146.5 797.5 157.6 808.5 C
+166.3 816.6 176.1 823.1 187.7 827.0 C
+219.2 813.0 240.6 789.7 259.1 759.5 C
+275.3 782.5 284.7 815.0 321.4 810.1 C
+373.9 801.4 405.0 751.7 443.6 715.1 C
+462.8 694.7 478.3 687.2 502.0 681.0 C
+f
+%%Trailer
+end
+showpage
diff --git a/texi/ps/gnus-head.eps b/texi/ps/gnus-head.eps
new file mode 100644 (file)
index 0000000..82206f8
--- /dev/null
@@ -0,0 +1,150 @@
+%!PS-Adobe-2.0 EPSF-1.2
+%%Creator: Adobe Illustrator 88(TM) format generated by CorelTRACE Version 2.0C
+%%Title:  /home/menja/c/larsi/gnus-head.eps
+%%BoundingBox: 0 0 430.6 312.5
+%%CreationDate: Sat Feb  3 13:06:12 1996
+%%DocumentFonts:
+%%ColorUsage: B & W
+%%TileBox: 0 0 430.6 312.5
+%%EndComments
+%%BeginProcSet:Adobe_Illustrator_1.1 0 0
+% Copyright 1992 Corel Corporation.
+
+% All rights reserved.
+/wPSMDict 150 dict def
+wPSMDict begin
+/bd {bind def} bind def
+/ld {load def} bd
+/xd {exch def} bd
+/_ null def
+/$c 0 def
+/$m 0 def
+/$y 0 def
+/$k 0 def
+/$t 1 def
+/$n _ def
+/$o 0 def
+/$C 0 def
+/$M 0 def
+/$Y 0 def
+/$K 0 def
+/$T 1 def
+/$N _ def
+/$O 0 def
+/$h false def
+/$al 0 def
+/$tr 0 def
+/$le 0 def
+/$lx 0 def
+/$ly 0 def
+/$ctm matrix currentmatrix def
+/@cp /closepath ld
+/@gs /gsave ld
+/@gr /grestore ld
+/@MN {2 copy le{pop}{exch pop}ifelse}bd
+/setcmykcolor where {pop}{/setcmykcolor{4 1 roll
+3 {3 index add 1 @MN 1 exch sub 3 1 roll} repeat
+setrgbcolor
+pop}bd}ifelse
+/@tc{dup 1 ge{pop}{4 {dup
+6 -1 roll
+mul
+exch}repeat
+pop}ifelse}bd
+/@scc{$c $m $y $k $t @tc setcmykcolor true}bd
+/@SCC{$C $M $Y $K $T @tc setcmykcolor true}bd
+/@sm{/$ctm $ctm currentmatrix def}bd
+/x {/$t xd /$n xd
+/$k xd /$y xd /$m xd /$c xd}bd
+/X {/$T xd /$N xd
+/$K xd /$Y xd /$M xd /$C xd}bd
+/g {1 exch sub 0 0 0
+4 -1 roll
+_ 1 x}bd
+/G {1 exch sub 0 0 0
+4 -1 roll
+_ 1 X}bd
+/k {_ 1 x}bd
+/K {_ 1 X}bd
+/d /setdash ld
+/i {dup 0 ne {setflat} {pop} ifelse}bd
+/j /setlinejoin ld
+/J /setlinecap ld
+/M /setmiterlimit ld
+/w /setlinewidth ld
+/O {/$o xd}bd
+/R {/$O xd}bd
+/c /curveto ld
+/C /c ld
+/l /lineto ld
+/L /l ld
+/m /moveto ld
+/n /newpath ld
+/N /newpath ld
+/F {@scc{eofill}if n} bd
+/f {@cp F}bd
+/S {@SCC{stroke}if n} bd
+/s {@cp
+S}bd
+/B {@gs F @gr
+S}bd
+/b {@cp B }bd
+/u {}bd
+/U {}bd
+%%EndProlog
+%%BeginSetup
+%%EndSetup
+1 i
+2 J
+0 j
+4 M
+[]0 d
+
+%%Note: traced as Normal_Outline
+0 g
+267.8 10.0 m
+291.8 50.8 294.2 95.0 278.8 136.8 C
+270.2 147.3 264.9 154.5 252.4 156.9 C
+227.0 119.5 L
+256.3 98.8 267.3 63.3 264.0 12.4 C
+264.4 10.5 265.9 9.1 265.9 9.1 C
+265.9 9.1 267.8 10.0 267.8 10.0 C
+f
+0 g
+79.2 40.3 m
+116.6 43.6 150.2 75.3 180.9 103.6 C
+197.2 121.4 204.0 133.4 217.9 150.7 C
+216.4 151.2 215.0 152.1 213.1 152.1 C
+178.0 128.6 147.3 81.1 102.2 86.8 C
+98.4 88.8 95.0 89.2 92.6 92.1 C
+87.3 120.4 126.2 159.8 141.1 182.8 C
+148.8 193.4 159.3 203.0 159.8 217.4 C
+131.0 190.0 98.8 140.6 71.5 90.7 C
+65.2 76.3 58.0 67.6 63.3 53.7 C
+68.6 45.1 70.5 43.2 79.2 40.3 C
+f
+0 g
+355.6 161.2 m
+376.3 159.3 388.3 171.8 404.6 184.3 C
+412.3 201.1 422.4 223.2 423.3 237.6 C
+416.6 234.2 410.8 229.4 405.1 217.4 C
+399.8 211.6 386.8 206.8 378.7 207.8 C
+334.0 206.4 308.1 288.4 252.4 297.1 C
+236.1 299.5 229.9 291.8 214.5 285.6 C
+203.0 270.2 L
+193.4 281.7 175.2 306.7 147.8 303.3 C
+115.2 279.8 101.2 238.5 57.6 230.8 C
+42.7 235.2 26.8 240.9 21.1 253.4 C
+19.6 257.7 19.6 260.1 16.8 262.5 C
+14.4 259.2 12.9 257.7 11.5 253.4 C
+20.1 231.8 12.4 207.8 31.6 190.5 C
+45.6 184.8 60.4 188.1 74.8 201.6 C
+103.6 220.3 113.2 256.3 142.5 259.2 C
+164.1 248.1 178.5 237.1 189.1 214.0 C
+208.8 241.9 L
+225.6 253.4 243.8 250.0 262.0 241.4 C
+294.2 215.0 325.9 167.5 355.6 161.2 C
+f
+%%Trailer
+end
+showpage
index f5ce217..5e5731f 100644 (file)
@@ -1,5 +1,5 @@
 % -*- latex -*-
-% Reference Card for (ding) Gnus: to be processed with LaTeX2e
+% Reference Card for (ding) Gnus 5.8.x: to be processed with LaTeX2e
 \documentclass{article}
 \def\Guide{Card}\def\guide{card}
 \def\logoscale{0.25}
@@ -8,41 +8,77 @@
 % top and bottom of the page. 
 \oddsidemargin -0.5in \evensidemargin -0.5in
 
-% TODO:
-% - how can you get 'tabular' to wrap around pages ?
-% - some things might not be updated: scoring and server modes, maybe more
+% README:
+% *** purpose
+% this was originally thought of as a reference card, but as it is now 5+
+% pages long, I doubt that it is more useful than the online-help. It helped
+% to get an overview for the Gnus-functionality.
+%
+% *** files
+% refcard.tex (this file), gnusref.tex ("include"-file) and gnuslogo.refcard
+% (Gnus logo).
+%
+% *** printing (about 5 pages now: write me if you can make it shorter..)
+% if you are using latex-mode, you do C-c C-f (process with latex),
+% C-c C-v (view using xdvi/dvi2tty) and C-c C-p (print)
+% the original author has set up the page dimensions cleverly so that this
+% should print on both letter and a4 (see note above)
+% $latex refcard.tex
+% this creates a file refcard.dvi which you can preview using
+% $xdvi refcard.dvi [C-c C-v]
+% and print using something like
+% $dvips refcard.dvi 
+% which creates refcard.ps (print using 'lpr refcard.ps')
+%
+% *** 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 ?)
+% 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  <fnatter@gmx.net>:
+% 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}
+\newlength{\logowidth} \setlength{\logowidth}{6.861in}
+\newlength{\logoheight} \setlength{\logoheight}{7.013in}
 
-\def\progver{5.8}\def\refver{5.8} % program and refcard versions
-\def\date{26th of March 2000}
+\def\progver{5.8}\def\refver{5.8-4} % program and refcard versions
+\def\date{July 27th, 2000}
 \def\author{Vladimir Alexiev $<$vladimir@cs.ualberta.ca$>$}
 \raggedbottom\raggedright
-%
-% 2000-03-26  Felix Natter  <f.natter@ndh.net>:
-% refcard updated for Gnus 5.8.3: please send corrections or suggestions
-% to the above email-address
-
-% changes since 2000-03-26:
-% - Create/Edit Foreign Groups: remove S b and S B (not there in 5.8.3)
-% - Send/Reply etc.: remove w and W (the only bindings are S w and S W)
-% Mon Apr  3 18:41:09 2000:
-% - added C-c C-n and C-c C-t (Article)
-% - C-c C-a as alias for M-m f (Article) + some other M-m *-bindings
-% - added section for ``jumping'' in article-mode
-% - now there's a difference between ``reading'' and ``composition''
-% article-modes
 
 \twocolumn
 %\tiny
 \scriptsize
 \pagestyle{plain}
 
-% this contains a set of commands containing the actual key-sequences
+% this contains a set of commands containing the actual sections
 % (and some explanations).
 \input{gnusref}
 
 %
 \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 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
+    \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*{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
+    \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*{Mail-Group Commands}
-       \MailGroups
-       \subsection*{Draft-Group Commands}
-       \DraftGroup
+    \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
+    \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
+    \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}
 
 \end{document}
 
-% \SummaryMode
-% \Gsubmap
-% \Bsubmap
-% \Dsubmap
-% \Tsubmap
-% %\pagebreak
-% % page 2, right column
-% \Msubmap
-% \Marks
-% %\pagebreak
-% \Limiting
-% % page 3
-% \Osubmap
-% \Ssubmap
-% \Xsubmap
-% \Vsubmap
-% \SortSummary
-% \Zsubmap
-% \ArticleMode
-% \ServerMode
-% % page 4
-% \BrowseServer
 
diff --git a/texi/splitindex b/texi/splitindex
new file mode 100755 (executable)
index 0000000..956ad3d
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+match='M-x |(Group)|(Summary)|(Article)|(Server)|(Browse)|(Post)|(Mail)|(Score)|(Binary)|(Topic)|(Pick)'
+fun='{gnus-|{nn.*-|{grouplens-'
+egrep "$match" gnus.idx > gnus.kidx
+egrep "$fun" gnus.idx > gnus.gidx
+egrep -v "$match|$fun" gnus.idx > gnus.cidx
diff --git a/texi/xemacs.mak b/texi/xemacs.mak
new file mode 100644 (file)
index 0000000..2d06450
--- /dev/null
@@ -0,0 +1,57 @@
+############################################################################
+# Subsidiary makefile to install Gnus under Windows NT using nmake.
+# Adrian Aichner, aichner@ecf.teradyne.com, Teradyne GmbH, 1999-07-14.
+############################################################################
+# Do not change anything below this line.
+# No spaces are allowed due to inference rule limitation:
+MAKEINFO="$(XEMACS)" $(FLAGS) -l texinfmt -f batch-texinfo-format
+
+!if "$(XEMACS)" == ""
+!message Please use $(MAKEDIR)\..\xemacs.mak instead.
+!error
+!endif
+
+!if ["$(XEMACS)" $(FLAGS) -eval \
+"(condition-case nil (require (quote texinfo)) (t (kill-emacs 1)))"]
+!message Install `texinfo' in XEmacs from Options->Manage Packages->List & Install.
+!message Without it Gnus info documentation cannot be built by XEmacs!
+!error Cannot build `info' without `texinfo'.
+!endif
+
+all: gnus message emacs-mime
+
+gnus: gnus.texi
+       $(MAKEINFO) "$**"
+
+message: message.texi
+       $(MAKEINFO) "$**"
+
+emacs-mime: emacs-mime.texi
+       $(MAKEINFO) "$**"
+
+clean:
+       del gnus.*.bak *.ky *.cp *.fn *.cps *.kys *.log *.aux *.dvi *.vr \
+       *.tp *.toc *.pg gnus.latexi *.aux *.[cgk]idx \
+       gnus.ilg gnus.ind gnus.[cgk]ind gnus.idx \
+       gnus.tmptexi *.tmplatexi gnus.tmplatexi1 texput.log *.orig *.rej \
+       gnus.latexi*~* xface.tex picons.tex smiley.tex *.latexi
+
+makeinfo: all
+
+veryclean:
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) clean
+       del /f gnus.dvi gnus.ps texi2latex.elc
+
+distclean:
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) clean
+       del /f *.orig *.rej *.elc *~ gnus gnus-?? Makefile
+       del /f message
+       del /f emacs-mime
+
+install: all
+       -mkdir "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\dir" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\gnus" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\gnus-??" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\message" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\emacs-mime" "$(INFODIR)"
diff --git a/xemacs.mak b/xemacs.mak
new file mode 100644 (file)
index 0000000..495ce7f
--- /dev/null
@@ -0,0 +1,143 @@
+############################################################################
+# Makefile to install Gnus under Windows NT using nmake.
+# Adrian Aichner, aichner@ecf.teradyne.com, Teradyne GmbH, 1999-07-14.
+#
+# Please specify path to the Gnus sources here, if $(MAKEDIR) is
+# inappropriate:
+#
+GNUSDIR=$(MAKEDIR)
+#
+# Please specify the path where you want Gnus installed:
+#
+# INSTALLDIR=c:\XEmacs\site-packages\pgnus-0.98
+#
+# Please specify the path to the XEmacs executable here:
+#
+# XEMACS=c:\XEmacs\XEmacs-21.1.8\i386-pc-win32\xemacs.exe
+#
+# Specify wheter you want to use XEmacs mail-lib package with UIDL support.
+#
+USE_XEMACS_MAIL_LIB=0
+#
+############################################################################
+# Do not change anything below this line.
+MANDIR=$(GNUSDIR)\texi
+LISPDIR=$(GNUSDIR)\lisp
+INFODIR=$(INSTALLDIR)\info
+FLAGS=-batch -q -no-site-file
+VARDEFS=XEMACS="$(XEMACS)" INFODIR="$(INFODIR)" MANDIR="$(MANDIR)" FLAGS="$(FLAGS)"
+
+!if !exist("$(XEMACS)")
+!error Please set XEMACS to point to XEmacs executable, "$(XEMACS)" does not exist.
+!endif
+
+!if "$(INSTALLDIR)" == ""
+!error Please specify INSTALLDIR.
+!endif
+
+all: lick info
+
+lick:
+#      protect paths containing whitespace
+       cd "$(LISPDIR)"
+!if $(USE_XEMACS_MAIL_LIB) != 0
+!if exist("$(LISPDIR)\pop3.el")
+       rename pop3.el pop3-not-used.el
+!endif
+!if exist("$(LISPDIR)\pop3.elc")
+       rename pop3.elc pop3-not-used.elc
+!endif
+       @echo Gnus pop3.el not used, verify you have XEmacs mail-lib package.
+!else
+       @echo Consider using XEmacs mail-lib package by setting USE_XEMACS_MAIL_LIB.
+!endif
+       "$(XEMACS)" $(FLAGS) -l ./dgnushack.el -f dgnushack-compile
+
+install-without-info: lick
+       -rmdir /s /q "$(INSTALLDIR)"
+       xcopy /i "$(LISPDIR)\*.el" "$(INSTALLDIR)\lisp"
+       xcopy /i "$(LISPDIR)\*.elc" "$(INSTALLDIR)\lisp"
+       xcopy /i /s "$(GNUSDIR)\etc" "$(INSTALLDIR)\etc"
+
+install: install-without-info info
+       cd "$(MANDIR)"
+#      protect paths containing whitespace
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) install
+
+info:
+#      protect paths containing whitespace
+       cd "$(MANDIR)"
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) all
+
+clean:
+       del *.orig *.rej
+
+elclean:
+       del "$(LISPDIR)\*.elc"
+
+distclean:
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) clean
+       del *~
+#      protect paths containing whitespace
+       cd "$(LISPDIR)"
+       del "*.orig" "*.rej" "*.elc" "*~"
+#      protect paths containing whitespace
+       cd "$(MANDIR)"
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) distclean
+############################################################################
+# Subsidiary makefile to install Gnus under Windows NT using nmake.
+# Adrian Aichner, aichner@ecf.teradyne.com, Teradyne GmbH, 1999-07-14.
+############################################################################
+# Do not change anything below this line.
+# No spaces are allowed due to inference rule limitation:
+MAKEINFO="$(XEMACS)" $(FLAGS) -l texinfmt -f batch-texinfo-format
+
+!if "$(XEMACS)" == ""
+!message Please use $(MAKEDIR)\..\xemacs.mak instead.
+!error
+!endif
+
+!if ["$(XEMACS)" $(FLAGS) -eval \
+"(condition-case nil (require (quote texinfo)) (t (kill-emacs 1)))"]
+!message Install `texinfo' in XEmacs from Options->Manage Packages->List & Install.
+!message Without it Gnus info documentation cannot be built by XEmacs!
+!error Cannot build `info' without `texinfo'.
+!endif
+
+all: gnus message emacs-mime
+
+gnus: gnus.texi
+       $(MAKEINFO) "$**"
+
+message: message.texi
+       $(MAKEINFO) "$**"
+
+emacs-mime: emacs-mime.texi
+       $(MAKEINFO) "$**"
+
+clean:
+       del gnus.*.bak *.ky *.cp *.fn *.cps *.kys *.log *.aux *.dvi *.vr \
+       *.tp *.toc *.pg gnus.latexi *.aux *.[cgk]idx \
+       gnus.ilg gnus.ind gnus.[cgk]ind gnus.idx \
+       gnus.tmptexi *.tmplatexi gnus.tmplatexi1 texput.log *.orig *.rej \
+       gnus.latexi*~* xface.tex picons.tex smiley.tex *.latexi
+
+makeinfo: all
+
+veryclean:
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) clean
+       del /f gnus.dvi gnus.ps texi2latex.elc
+
+distclean:
+       $(MAKE) /$(MAKEFLAGS) /f xemacs.mak $(VARDEFS) clean
+       del /f *.orig *.rej *.elc *~ gnus gnus-?? Makefile
+       del /f message
+       del /f emacs-mime
+
+install: all
+       -mkdir "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\dir" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\gnus" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\gnus-??" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\message" "$(INFODIR)"
+       xcopy /i /s "$(MANDIR)\emacs-mime" "$(INFODIR)"