[net.sources] another hack to bib

colonel@sunybcs.UUCP (01/23/87)

The following hack makes bib understand some ditroff escapes when
processing sort and citation templates.  Specifically, it will do
good things with overstruck accents; e.g., if your references are

	%A Gorgeous George
	%T Advanced Nuclear Physics
	%D 1987

	%A Kurt G\o'\(..o'del
	%T Gone with the Wind
	%D 1937

and your citation template is A3\ D, you'll get

Geo 1987		G. George, _Advanced Nuclear Physics,_ 1987.

G<o-umlaut>d 1937	K. G<o-umlaut>del, _Gone with the Wind,_ 1937.

in that order.  Without this hack, "G\o" will come before "Geo", and
the citation will be "G\o 1937", which will cross up ditroff.

This hack does not understand strings--how could it?  If you use
something like \*v (for a Czech hacek) in an overstrike, it will
be treated as a v.  And the citation builder is capable of breaking
in the middle of an overstrike; that's a bug, folks.

I may not post all of bibargs.c.  Here are the changes in context:

----------------------------------------------------------------------
 ...
            if (isupper(field2[0]))
               field2[0] -= 'A' - 'a';
            }
/*
         res = strcmp(field1, field2);
 */
/*
 *	Use a special comparison that ignores diacriticals.
 */
         res = tstrcmp(field1, field2);
         }
      if (neg)
 ...

/*
 *	Compare two strings, ignoring diacritical marks.
 */
int
tstrcmp(str1, str2)
char *str1, *str2;
{
	char hold1[101], hold2[101];
	deldiacr(hold1, str1);
	deldiacr(hold2, str2);
	return strcmp(hold1, hold2);
}

/*
 *	deldiacr - delete diacritical marks and other ditroff escapes.
 */

deldiacr(snew, sold)
char *snew, *sold;
{
	char delim='\0';
	while (*sold) {
		if ('\\'==*sold) {
/*
 *	Transparent newline - abort.
 */
			if (!sold[1]) break;
/*
 *	Matching delimiter on overstrike, but bash-escaped - pass it.
 */
			else if (delim==sold[1]) {
				*snew++ = delim;
				sold+=2;
				continue;
			}
			else switch(*++sold) {
/*
 *	Bash-bash.
 */
			case '\\':
			case 'e':
				*snew++ = '\\';
				sold++;
				break;
			case 'o':
/*
 *	Premature end of line?
 */
				if (!(delim = *++sold)) break;
				sold++;
				break;
/*
 *	Special character.
 */
			case '(':
/*
 *	Within overstrike - ignore it.
 */
				if (delim) {
					if (*++sold && *++sold) sold++;
				}
/*
 *	Otherwise just let it be.
 */
				else *snew++ = *sold++;
				break;
			}
		}
		else if (delim==*sold) {
/*
 *	Matching delimiter on overstrike.
 */
			delim=0;
			sold++;
		}
/*
 *	If within overstrike, accept letters only.
 */
		else {
			if (!delim || isalpha(*sold)) *snew++ = *sold;
			sold++;
		}
	}
	*snew = '\0';
}

/* makecites - make standard citation strings, using citetemplate currently in effect */
   makecites()
 ...
      for (i = 0; field[i] = field[i+n]; i++)
         ;
      }
/*
 *	Use deldiacr to kluge the length. --Col. S., 1987
 */
   else if (isdigit(*ptr)) {
	char hold[101];			/* For checking with deldiacr */
      for (; isdigit(*ptr); ptr++)
         n = 10 * n + (*ptr - '0');
      if (n > len)
         n = len;
/*
      field[n] = 0;
 */
	while (deldiacr(hold,field),strlen(hold)>n) field[--len]='\0';
/*
 *	How was that for a one-liner? --Col. S.
 */
      }

   if (*ptr == 'u') {
 ...
-- 
Col. G. L. Sicherman
UU: ...{rocksvax|decvax}!sunybcs!colonel
CS: colonel@buffalo-cs
BI: colonel@sunybcs, csdsiche@ubvms