[comp.emacs] GNU Emacs math character bug

olsen@ll-xn.ARPA (Jim Olsen) (11/17/86)

GNU Emacs version 17.64 has a bug in its handling of `math' (i.e., TeX
$) characters.  It appears that the bug still exists in version 18.26.

This bug manifests itself when the tex-mode commands validate-
TeX-buffer or TeX-terminate-paragraph are invoked.  The TeX syntax
check fails (i.e., indicates an error when the syntax is actually
correct) in two situations:

	1. Whenever a paragraph contains two or more math statements, e.g.,
	   ``Add $x$ and $y$ together.''

	2. When single-$ and double-$ signs are nested, as in this example
	   from the TeXbook:
	   ``$$|x|=\cases{x,&if $x\ge0$;\cr -x,&otherwise.\cr}$$.''

The bug is in the function scan_lists in the syntax.c source file.  I have
fixed the bug, and added code to distinguish between single and double math
characters.  The modified code works in both cases outlined above.  Here
is a context diff from the version 17.64 syntax.c file (N.B., this code has
been tried only on a VAX-4.3BSD system):

*** syntax.c	Fri Nov 14 11:08:22 1986
--- syntax.c.old	Fri Nov 14 11:08:22 1986
***************
*** 428,435 ****
--- 428,434 ----
    register int c;
    char stringterm;
    int quoted;
!<  int singlemath = 0;
!<  int doublemath = 0;
    register enum syntaxcode code;
    int min_depth = depth;    /* Err out if depth gets less than this. */
  
---------------
    register int c;
    char stringterm;
    int quoted;
!>  int mathexit = 0;
    register enum syntaxcode code;
    int min_depth = depth;    /* Err out if depth gets less than this. */
  
***************
*** 507,522 ****
--- 506,514 ----
  	      if (!sexpflag)
  		break;
  	      if (from != stop && c == CharAt (from))
!<		{
!<		  from++;
!<		  if (doublemath) { doublemath = 0; goto close1;}
!<		  doublemath=1;
!<		}
!<	      else
!<		{
!<		  if (singlemath) { singlemath = 0; goto close1;}
!<		  singlemath = 1;
!<		}
  
  	    case Sopen:
  	      if (!++depth) goto done;
---------------
  	      if (!sexpflag)
  		break;
  	      if (from != stop && c == CharAt (from))
!>		from++;
!>	      if (mathexit) goto close1;
!>	      mathexit = 1;
  
  	    case Sopen:
  	      if (!++depth) goto done;
***************
*** 605,620 ****
--- 597,605 ----
  	      if (!sexpflag)
  		break;
  	      if (from != stop && c == CharAt (from - 1))
!<		{
!<		  from--;
!<		  if (doublemath) { doublemath = 0; goto open2;}
!<		  doublemath = 1;
!<		}
!<	      else
!<		{
!<		  if (singlemath) { singlemath = 0; goto open2;}
!<		  singlemath = 1;
!<		}
  
  	    case Sclose:
  	      if (!++depth) goto done2;
---------------
  	      if (!sexpflag)
  		break;
  	      if (from != stop && c == CharAt (from - 1))
!>		from--;
!>	      if (mathexit) goto open2;
!>	      mathexit = 1;
  
  	    case Sclose:
  	      if (!++depth) goto done2;
-- 
Jim Olsen	olsen@ll-xn.ARPA  or  olsen@xn.ll.mit.edu  or
		...!{caip,decvax,lll-crg,mit-eddie,seismo}!ll-xn!olsen