Thanks Richard for such detailed reply. And his style function does sort all types of entries chronically. In contrast the plainyr.bst from Internet puts all Articles in a block, followed by all Books, and then Proceedings, etc., and sort within each block chronically. I am satisfied with the result. Thanks again.
Michael Chen On 11/3/06, Richard Heck <[EMAIL PROTECTED]> wrote:
Michael Chen wrote: > Thanks very much for your info, Richard. I found that somebody has > done the hack, > http://www.tug.org/tex-archive/biblio/bibtex/contrib/misc/plainyr.bst > this .bst sorts entries by year (ascendant), author and title. If it > is possible, would you please show me how to sort decently? That file sorts very strangely. You may be getting the results you want, but probably not for the right reason. I just ran it on a file and, yes, I got all the articles sorted by year. But then after the articles, I got all the books, sorted by author. Fields that aren't book, inbook, proceedings, or manual will get sorted by year; but those get sorted by author or editor or whatever. If you don't have any of those, then you'll get the results you want, indeed. But you may want to try the one I sent you before: FUNCTION {presort} { type$ "book" = type$ "inbook" = or 'author.editor.sort { type$ "proceedings" = 'editor.organization.sort { type$ "manual" = 'author.organization.sort 'author.sort if$ } if$ } if$ " " * year field.or.null sortify " " * swap$ * title field.or.null sort.format.title * #1 entry.max$ substring$ 'sort.key$ := } This will sort on year, ascending, unless there's no year, in which case it sorts by author or whatever. To get a descending sort, we'll have to hack a bit more. In fact, we'll have to hack a lot more. The obvious thing to do is to subtract the year from 10000 and then sort on that. But the problem is that year is a string field, not an integer, so I think BibTeX will choke if we try to subtract it from something. And, so far as I can see, BibTeX itself provides us with no way to convert a string to an integer, though we can go the other way. We can work around this by writing a routine that will attempt to convert a 4-digit year to an integer, roughly: INTEGERS { iterator, year.desc } FUNCTION year.to.int { #0 'year.desc := #1 'iterator := { iterator #10000 < } #while (iterator < 10000) { iterator int.to.str$ year purify$ = if$ { iterator 'year.desc := %success... #10000 'iterator := %end the iteration } 'skip$ } year.desc } So we leave the empty string on the stack if it wasn't an integer (less than 10000). I've not tested that, and don't have time to do so right now. And note: It may take a while to do this for every entry! So, well, we've got that. Now, we can re-write presort: FUNCTION year.desc { year.to.int duplicate$ if$ { #10000 - int.to.str$ { "Warning: Problem with year field in " cite$ * warning$ pop$ "" %You might want to push "9999", to get yearless things at the end } } And then, in the routine above, replace the line "year field.or.null sortify" with "year.desc". Again, I've not tested this. Actually, a better way to do year.to.int it would be (i) to use text.length$ to check that year is four characters; (ii) use substring$ to extract the characters from year one by one, and then use chr.to.int to convert them, one at a time, to the corresponding ASCII integers; (iii) make sure we're between 48 (ASCII '0') and 57 (ASCII '9'), i.e., that we have a digit, and then substract 48 to get the actual integer; (iv) reconstruct the integer for the year from those: 1000 * year[1] + 100 * year[2], etc. That'd be much faster. But I'd better go do some actual work right now.... Richard
