Date: Tue 6 Jan 87 17:39:42-PST From: Eric Muller To: texhax@Score.Stanford.EDU Subject: How to cite all the keys of a bibtex database. I have made a simple modification to Bibtex so that it can behave as if all the entries of a (set of) bibliography file had been cited. Namely, I have added a ".aux" file command, "\citeall{}" which is equivalent to the list all "\citation{xxx}" commands where xxx is replaced by the cite-key of each entry. In conjunction with a bst-format that produces "\nocite{xxx}" as the bibliographic entry, where xxx is the cite-key of the entry (instead of the normal LaTeX commands to format the entry) and a ".aux" file of the form : \relax \bibdata{cs} % the name of the .bib file \citeall{} % to get all the entries of it \bibstyle{cite-all} % to produce a \nocite for each entry what you get after processing by Bibtex is a list of all the "\nocite" commands in the ".bbl" file, which you can then \input where you want. I also have a "author-index.bst" format that will produce a list of "\index" commands, one for each author in each entry, the text of the index entry being the author name and the "page number" replaced by the cite-key of the entry. You can also use a standard format in the "\bibstyle". The reason for the two step process (with the cite-all format) is linked to the memory allocation scheme of Bibtex I did not want to change too much. That is, if the format you want to use utilizes less than a certain number of fields in the entries (if think it is 20) then everything is fine; otherwise use the two step process. The rest of this message is the files mentioned above, starting with the change file for bibtex (I am running the modified version on a Tops-20 system, so that these may have to be merged with changes for your system), and the two format files. Files are separated by "@@@@@@@ " line. If you need any help, just send me mail. There may be a bug in these modifications : the last entry in the database may no appear; just add a dummy entry at the end (or find the bug !). Last detail : the modified bibtex will do whatever the old one does, it just has one additional command; the code for the modification is not really clean (especially on the Web side); you can forward this to anyone interested. Good luck, Eric Muller (em@score.stanford.edu) @@@@@@@ bibtex.ch @x @d n_aux_bibdata = 0 {\.{\\bibdata}} @d n_aux_bibstyle = 1 {\.{\\bibstyle}} @d n_aux_citation = 2 {\.{\\citation}} @d n_aux_input = 3 {\.{\\@@input}} @y @d n_aux_bibdata = 0 {\.{\\bibdata}} @d n_aux_bibstyle = 1 {\.{\\bibstyle}} @d n_aux_citation = 2 {\.{\\citation}} @d n_aux_input = 3 {\.{\\@@input}} @d n_aux_citeall = 4 {\.{\\citeall}} @z @x @= pre_define('\citation ',9,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_citation; pre_define('\bibdata ',8,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_bibdata; pre_define('\bibstyle ',9,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_bibstyle; pre_define('\@@input ',7,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_input; @y @= pre_define('\citation ',9,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_citation; pre_define('\bibdata ',8,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_bibdata; pre_define('\bibstyle ',9,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_bibstyle; pre_define('\@@input ',7,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_input; pre_define('\citeall ',8,aux_command_ilk); ilk_info[pre_def_loc] := n_aux_citeall; @z @x case command_num of n_aux_bibdata : aux_bib_data_command; n_aux_bibstyle : aux_bib_style_command; n_aux_citation : aux_citation_command; n_aux_input : aux_input_command; @y case command_num of n_aux_bibdata : aux_bib_data_command; n_aux_bibstyle : aux_bib_style_command; n_aux_citation : aux_citation_command; n_aux_input : aux_input_command; n_aux_citeall : aux_citeall_command; @z @x procedure aux_citation_command; label exit; begin @y procedure aux_citation_command; label exit; begin if citeall_seen then aux_err ('illegal, \citation after a \citeall'); @z @x That's it for processing \.{.aux} commands, except for finishing the procedural gymnastics. @= @ @y That's it for processing \.{.aux} commands, except for finishing the procedural gymnastics. @= @ @ @z @x num_cites := cite_ptr; {record the number of distinct cite keys} num_bib_files := bib_ptr; {and the number of \.{.bib} files} if (not citation_seen) then aux_end_err ('I found no \citation commands') else if (num_cites = 0) then aux_end_err ('I found no \cite keys'); @y if citeall_seen then num_cites := max_cites else num_cites := cite_ptr; num_bib_files := bib_ptr; {and the number of \.{.bib} files} if (not citeall_seen) and (not citation_seen) then aux_end_err ('I found no \citeall nor \citation commands') else if (citation_seen) and (num_cites = 0) then aux_end_err ('I found no \cite keys'); @z @x trace_pr_ln ('finished reading the database file(s)'); ecart@/ @; @y trace_pr_ln ('finished reading the database file(s)'); ecart@/ if citeall_seen then num_cites := real_num_cites else begin @; end; @z @x @= trace trace_pr_token; trace_pr_ln (' is a database key'); ecart@/ tmp_ptr := buf_ptr1; while (tmp_ptr < buf_ptr2) do begin sv_buf2[tmp_ptr] := buffer[tmp_ptr]; incr(tmp_ptr); end; lower_case (sv_buf2, buf_ptr1, token_len); {convert to `canonical' form} lc_cite_loc := str_lookup(sv_buf2,buf_ptr1,token_len,lc_cite_ilk,dont_insert); if (not hash_found) then store_entry := false {no such cite key read on |cite_list|} else begin store_entry := true; @; end; @y @= trace trace_pr_token; trace_pr_ln (' is a database key'); ecart@/ tmp_ptr := buf_ptr1; while (tmp_ptr < buf_ptr2) do begin sv_buf2[tmp_ptr] := buffer[tmp_ptr]; incr(tmp_ptr); end; lower_case (sv_buf2, buf_ptr1, token_len); {convert to `canonical' form} lc_cite_loc := str_lookup(sv_buf2,buf_ptr1,token_len,lc_cite_ilk,dont_insert); if citeall_seen then begin if not hash_found then begin lc_cite_loc := str_lookup(sv_buf2,buf_ptr1, token_len,lc_cite_ilk,do_insert); trace trace_pr_newline; ecart@/ if (real_num_cites = max_cites) then overflow('number of \cite keys ',max_cites); cite_loc := str_lookup(buffer,buf_ptr1,token_len,cite_ilk,do_insert); if (hash_found) then aux_err ('this can''t happen---cite hash error'); cite_list[real_num_cites] := hash_text[cite_loc]; ilk_info[cite_loc] := real_num_cites; ilk_info[lc_cite_loc] := real_num_cites; incr(real_num_cites); end; store_entry := true; @; end else if (not hash_found) then store_entry := false {no such cite key read on |cite_list|} else begin store_entry := true; @; end; @z @x @* System-dependent changes. @^system dependencies@> This section should be replaced, if necessary, by changes to the program that are necessary to make \BibTeX\ work at a particular installation. It is usually best to design your change file so that all changes to previous sections preserve the section numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new sections, can be inserted here; then only the index itself will get a new section number. @y @ Here are the new modules for the citation of all entries. We need a global variable to remember that we must cite all entries, and another to count the real number of entries : @= citeall_seen : boolean; real_num_cites : cite_number; @ Of course, this needs some initialization. @= citeall_seen := false; real_num_cites := 0; @ Currently, we do not process arguments of the \.{\\citeall} command, but skip over them. However, the \.{\{} and \.{\}} must be there. @= procedure aux_citeall_command; label exit; begin if citeall_seen then aux_err ('illegal, another \citeall command'); if citation_seen then aux_err ('illegal, \citall command after some \citation command'); citeall_seen := true; incr(buf_ptr2); if (not scan1 (right_brace)) then aux_err ('no "',xchr[right_brace],'" for \citeall command'); if (last > buf_ptr2 + 1) then aux_err ('stuff after "', xchr[right_brace], '" for \citeall command'); exit: end; @* System-dependent changes. @^system dependencies@> This section should be replaced, if necessary, by changes to the program that are necessary to make \BibTeX\ work at a particular installation. It is usually best to design your change file so that all changes to previous sections preserve the section numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new sections, can be inserted here; then only the index itself will get a new section number. @z @@@@@@@ cite-all.bst ENTRY {none} {} {} FUNCTION {default.type} { newline$ "\nocite{" write$ cite$ write$ "}" write$ } FUNCTION {article} { default.type } FUNCTION {book} { default.type } FUNCTION {booklet} { default.type } FUNCTION {inbook} { default.type } FUNCTION {incollection} { default.type } FUNCTION {inproceedings} { default.type } FUNCTION {conference} { default.type } FUNCTION {manual} { default.type } FUNCTION {mastersthesis} { default.type } FUNCTION {misc} { default.type } FUNCTION {phdthesis} { default.type } FUNCTION {proceedings} { default.type } FUNCTION {techreport} { default.type } FUNCTION {unpublished} { default.type } READ ITERATE {call.type$} @@@@@@@ author-index.bst ENTRY { author editor } {} {label} STRINGS { s t } INTEGERS { nameptr namesleft numnames } FUNCTION {format.names} { 's swap$ := 'nameptr #1 := 'numnames s num.names$ := 'namesleft numnames := { namesleft #0 > } { "\index{" write$ s nameptr "{vv~}{ll}{ jj}{, ff}" format.name$ write$ "}{\cite{" write$ cite$ write$ "}}" write$ newline$ 'nameptr nameptr #1 + := 'namesleft namesleft #1 - := } while$ } FUNCTION {default.type} { author missing$ { editor missing$ { skip$ } { editor format.names } if$ } { author format.names } if$ } FUNCTION {article} { default.type } FUNCTION {book} { default.type } FUNCTION {booklet} { default.type } FUNCTION {inbook} { default.type } FUNCTION {incollection} { default.type } FUNCTION {inproceedings} { default.type } FUNCTION {conference} { default.type } FUNCTION {manual} { default.type } FUNCTION {mastersthesis} { default.type } FUNCTION {misc} { default.type } FUNCTION {phdthesis} { default.type } FUNCTION {proceedings} { default.type } FUNCTION {techreport} { default.type } FUNCTION {unpublished} { default.type } READ ITERATE {call.type$} -------