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