diff options
Diffstat (limited to 'Build/extra/bibtex')
-rw-r--r-- | Build/extra/bibtex/Makefile | 67 | ||||
-rw-r--r-- | Build/extra/bibtex/README | 36 | ||||
-rw-r--r-- | Build/extra/bibtex/abbrv.bst | 1097 | ||||
-rw-r--r-- | Build/extra/bibtex/acm.bst | 1140 | ||||
-rw-r--r-- | Build/extra/bibtex/alpha.bst | 1257 | ||||
-rw-r--r-- | Build/extra/bibtex/apalike.bst | 1105 | ||||
-rw-r--r-- | Build/extra/bibtex/apalike.sty | 72 | ||||
-rw-r--r-- | Build/extra/bibtex/apalike.tex | 87 | ||||
-rw-r--r-- | Build/extra/bibtex/bibtex.web | 11679 | ||||
-rw-r--r-- | Build/extra/bibtex/btxbst.doc | 2530 | ||||
-rw-r--r-- | Build/extra/bibtex/btxdoc.bib | 93 | ||||
-rw-r--r-- | Build/extra/bibtex/btxdoc.pdf | bin | 187656 -> 0 bytes | |||
-rw-r--r-- | Build/extra/bibtex/btxdoc.tex | 1120 | ||||
-rw-r--r-- | Build/extra/bibtex/btxhak.pdf | bin | 166659 -> 0 bytes | |||
-rw-r--r-- | Build/extra/bibtex/btxhak.tex | 626 | ||||
-rw-r--r-- | Build/extra/bibtex/ieeetr.bst | 976 | ||||
-rw-r--r-- | Build/extra/bibtex/plain.bst | 1097 | ||||
-rw-r--r-- | Build/extra/bibtex/siam.bst | 1041 | ||||
-rw-r--r-- | Build/extra/bibtex/unsrt.bst | 951 | ||||
-rw-r--r-- | Build/extra/bibtex/xampl.bib | 361 |
20 files changed, 0 insertions, 25335 deletions
diff --git a/Build/extra/bibtex/Makefile b/Build/extra/bibtex/Makefile deleted file mode 100644 index 44a6e34a4e5..00000000000 --- a/Build/extra/bibtex/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# (Public domain. Originally written by Karl Berry, 2010.) -# This is just about creating the derived bst files, checking for -# changes, making the distribution for CTAN, etc. It does not actually -# build a BibTeX executable. So we keep it in the source repository. -# We're using the TL repo (source/extra/bibtex) purely for convenience. - -all: pdf bst - -############################################################################# -# documentation -# -pdflatex = pdflatex --file-line-error -bibtex = bibtex - -%.pdf: %.tex %.bbl - $(pdflatex) '\nonstopmode \input $<' - -%.bbl: %.tex %.aux btxdoc.bib - $(bibtex) $* - $(pdflatex) '\nonstopmode \input $<' - -%.aux: %.tex - $(pdflatex) '\nonstopmode \input $<' - -pdf: btxdoc.pdf btxhak.pdf - -.PRECIOUS: %.bbl - -############################################################################# -# -# bst files -# -bst: plain.bst unsrt.bst alpha.bst abbrv.bst - -%.bst: btxbst.doc -# First line, substitute in bare style name. - echo "% BibTeX standard bibliography style \``basename $@ .bst`'" >$@ -# -# About this cpp invocation: -# -traditional so bst integers #1, etc., don't get preprocessed away. -# -w since we know that we have unterminated ', ec. -# -P since we don't want #line in the output. -# -DBSTNAME taken from the target. -# -# Then we grep away the comments without leading whitespace, -# and fold multiple blank lines into one. - cpp -traditional -w -P -D`basename $@ .bst|tr a-z A-Z` btxbst.doc \ - | grep -v '^%' \ - | uniq \ - >>$@ -# -# For diff purposes, expand the original (which might have tabs) -# to the result (which shouldn't have any). - -grep ' ' $@ - -expand ORIG/$@ | diff - $@ - -############################################################################# -check: - -grep ' ' [a-z]* - -dist: all - rm -f *.blg *.log bibtex.tar.gz - tar --exclude=\*.aux --exclude=\*.bbl -cvzf bibtex.tar.gz README *.* - -clean: - rm -f *.blg *.log *.aux *.bbl bibtex.tar.gz - rm -f abbrv.bst alpha.bst plain.bst unsrt.bst diff --git a/Build/extra/bibtex/README b/Build/extra/bibtex/README deleted file mode 100644 index 53e7cdb4d9f..00000000000 --- a/Build/extra/bibtex/README +++ /dev/null @@ -1,36 +0,0 @@ -The intent is for the BibTeX program to be distributed under the same -terms as Knuth's TeX program, and for the BibTeX support files -to be distributed under the same terms as Knuth's support files. - -If questions or problems, please write to biblio@tug.org, the general -mailing list for BibTeX (and other TeX/bibliography systems). For -archives and subscription information, see http://lists.tug.org/biblio. - -Files distributed here: -bibtex.web the source file for BibTeX -btxdoc.tex documentation, and also sample input for BibTeX implementors -btxdoc.pdf generated output for browsing -btxhak.tex documentation for style designers -btxdoc.bib the bibliography database file for btxdoc.tex -btxhak.pdf generated output for browsing -xampl.bib a database file with an example of every standard entry type - -btxbst.doc the documentation and template for the four standard - bibliography styles: -abbrv.bst abbreviated -alpha.bst alphabetic -plain.bst plain -unsrt.bst unsorted - -The four semi-standard bibliography styles: -acm.bst ACM Transactions -apalike.bst APA-like -ieeetr.bst IEEE Transactions -siam.bst SIAM - -Support files for apalike: -apalike.sty LaTeX support for apalike.bst -apalike.tex Plain TeX support for apalike.bst (uses btxmac.tex) - ---Karl Berry and Oren Patashnik (written 2010). -(This file is public domain.) diff --git a/Build/extra/bibtex/abbrv.bst b/Build/extra/bibtex/abbrv.bst deleted file mode 100644 index 23fae1a28cc..00000000000 --- a/Build/extra/bibtex/abbrv.bst +++ /dev/null @@ -1,1097 +0,0 @@ -% BibTeX standard bibliography style `abbrv' - % Version 0.99b (8-Dec-10 release) for BibTeX versions 0.99a or later. - % Copyright (C) 1984, 1985, 1988, 2010 Howard Trickey and Oren Patashnik. - % Unlimited copying and redistribution of this file are permitted as long as - % it is unmodified. Modifications (and redistribution of modified versions) - % are also permitted, but only if the resulting file is renamed to something - % besides btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. - % This restriction helps ensure that all standard styles are identical. - % The file btxbst.doc has the documentation for this style. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - key empty$ not and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ - { organization publisher new.sentence.checkb - organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - organization output - } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"Jan."} - -MACRO {feb} {"Feb."} - -MACRO {mar} {"Mar."} - -MACRO {apr} {"Apr."} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"Aug."} - -MACRO {sep} {"Sept."} - -MACRO {oct} {"Oct."} - -MACRO {nov} {"Nov."} - -MACRO {dec} {"Dec."} - -MACRO {acmcs} {"ACM Comput. Surv."} - -MACRO {acta} {"Acta Inf."} - -MACRO {cacm} {"Commun. ACM"} - -MACRO {ibmjrd} {"IBM J. Res. Dev."} - -MACRO {ibmsj} {"IBM Syst.~J."} - -MACRO {ieeese} {"IEEE Trans. Softw. Eng."} - -MACRO {ieeetc} {"IEEE Trans. Comput."} - -MACRO {ieeetcad} - {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} - -MACRO {ipl} {"Inf. Process. Lett."} - -MACRO {jacm} {"J.~ACM"} - -MACRO {jcss} {"J.~Comput. Syst. Sci."} - -MACRO {scp} {"Sci. Comput. Programming"} - -MACRO {sicomp} {"SIAM J. Comput."} - -MACRO {tocs} {"ACM Trans. Comput. Syst."} - -MACRO {tods} {"ACM Trans. Database Syst."} - -MACRO {tog} {"ACM Trans. Gr."} - -MACRO {toms} {"ACM Trans. Math. Softw."} - -MACRO {toois} {"ACM Trans. Office Inf. Syst."} - -MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} - -MACRO {tcs} {"Theoretical Comput. Sci."} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ - s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -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 - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/acm.bst b/Build/extra/bibtex/acm.bst deleted file mode 100644 index 5e52a0d6382..00000000000 --- a/Build/extra/bibtex/acm.bst +++ /dev/null @@ -1,1140 +0,0 @@ -% Copyright (C) 1986, 1988, 2010 Howard Trickey and Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted as long as -% it is unmodified. Modifications (and redistribution of modified versions) -% are also permitted, but only if the resulting file is renamed. -% -% ACM Transactions bibliography style (8-Dec-10 version) -% A lot like abbrv.bst, but names come out "Last, initials", and in \sc. -% Some dates are parenthesized. -% -% History -% 2/ 6/86 (HWT) Original version, by Howard Trickey. -% 3/ 5/86 (HWT) Put in pp. everywhere but articles, as per ACM style. -% 1/24/88 (OP&HWT) Updated for BibTeX version 0.99a, Oren Patashnik; -% corrected the abbreviations to "Mar." and "Sept."; -% THIS `acm' VERSION DOES NOT WORK WITH BIBTEX 0.98i. -% 12/ 8/10 (OP&HWT) Clarify license. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -FUNCTION {emphasizeic} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "\/}" * } - if$ -} - -FUNCTION {scapify} -{ duplicate$ empty$ - { pop$ "" } - { "{\sc " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{vv~}{ll}{, jj}{, f.}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { t "others" = - { ", et~al." * } - { ", and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -% For names inside entries (e.g., editors of an "In ..."); -% this is exactly ABBRV.BST's `format.names' function. -FUNCTION {format.innames} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names scapify } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names scapify - editor num.names$ #1 > - { ", Eds." * } - { ", Ed." * } - if$ - } - if$ -} - -FUNCTION {format.ineditors} -{ editor empty$ - { "" } - { editor format.innames - editor num.names$ #1 > - { ", Eds." * } - { ", Ed." * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "vol.~" volume * - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "no.~" } - { "No.~" } - if$ - number * - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ "~ed." * } - { edition "t" change.case$ "~ed." * } - if$ - } - if$ -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages n.dashify } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pp.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pp.~" pages n.dashify * } - { "p.~" pages * } - if$ - } - if$ -} - -FUNCTION {format.journal.vol.num.date} -{ journal empty$ - { "empty journal in " cite$ * warning$ - "" - } - { journal - volume empty$ - 'skip$ - { " " * volume * } - if$ - number empty$ - 'emphasizeic - { emphasize ", " * number * } - if$ - year empty$ - { "empty year in " cite$ * warning$ } - { " (" * format.date * ")" * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pp.pages - { type empty$ - { "ch.~" chapter * } - { type "l" change.case$ chapter tie.or.space.connect } - if$ - pages empty$ - 'skip$ - { ", " * format.pp.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { "In " booktitle emphasize * - editor empty$ - 'skip$ - { ", " * format.ineditors * } - if$ - } - if$ -} - -% The proceedings title (it's on the stack) gets an (address, date) appended -FUNCTION {format.proc.date} -{ duplicate$ empty$ - { pop$ "" } - { year empty$ - { "empty year in " cite$ * warning$ - address empty$ - 'emphasize - { emphasizeic - " (" * address * ")" * - } - if$ - } - { emphasizeic - " (" * - address empty$ - 'skip$ - { address * ", " * } - if$ - format.date * - ")" * - } - if$ - } - if$ -} - -FUNCTION {format.in.proc.date} -{ booktitle empty$ - { "" } - { "In " booktitle format.proc.date * } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - key empty$ not and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Tech. Rep." } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Vol.~" volume * - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.journal.vol.num.date output - format.pages output - } - { format.article.crossref output.nonnull - format.pp.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - format.edition output - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - format.edition output - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.date "year" output.check - format.chapter.pages "chapter and pages" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.edition output - format.bvolume output - format.number.series output - new.sentence - publisher "publisher" output.check - address output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull } - if$ - format.chapter.pages output - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.proc.date "booktitle" output.check - format.ineditors output - format.bvolume output - format.number.series output - organization output - publisher output - } - { format.incoll.inproc.crossref output.nonnull } - if$ - format.pp.pages output - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization scapify output } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.edition output - author empty$ - { address new.block.checka } - { organization address new.block.checkb - organization output - } - if$ - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization scapify output } - { format.editors output.nonnull } - if$ - new.block - title format.proc.date "title" output.check - format.bvolume output - format.number.series output - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"Jan."} - -MACRO {feb} {"Feb."} - -MACRO {mar} {"Mar."} - -MACRO {apr} {"Apr."} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"Aug."} - -MACRO {sep} {"Sept."} - -MACRO {oct} {"Oct."} - -MACRO {nov} {"Nov."} - -MACRO {dec} {"Dec."} - -MACRO {acmcs} {"ACM Comput. Surv."} - -MACRO {acta} {"Acta Inf."} - -MACRO {cacm} {"Commun. ACM"} - -MACRO {ibmjrd} {"IBM J. Res. Dev."} - -MACRO {ibmsj} {"IBM Syst.~J."} - -MACRO {ieeese} {"IEEE Trans. Softw. Eng."} - -MACRO {ieeetc} {"IEEE Trans. Comput."} - -MACRO {ieeetcad} - {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} - -MACRO {ipl} {"Inf. Process. Lett."} - -MACRO {jacm} {"J.~ACM"} - -MACRO {jcss} {"J.~Comput. Syst. Sci."} - -MACRO {scp} {"Sci. Comput. Programming"} - -MACRO {sicomp} {"SIAM J. Comput."} - -MACRO {tocs} {"ACM Trans. Comput. Syst."} - -MACRO {tods} {"ACM Trans. Database Syst."} - -MACRO {tog} {"ACM Trans. Gr."} - -MACRO {toms} {"ACM Trans. Math. Softw."} - -MACRO {toois} {"ACM Trans. Office Inf. Syst."} - -MACRO {toplas} {"ACM Trans. Program. Lang. Syst."} - -MACRO {tcs} {"Theoretical Comput. Sci."} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ - s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -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 - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/alpha.bst b/Build/extra/bibtex/alpha.bst deleted file mode 100644 index e59a2ebb7f9..00000000000 --- a/Build/extra/bibtex/alpha.bst +++ /dev/null @@ -1,1257 +0,0 @@ -% BibTeX standard bibliography style `alpha' - % Version 0.99b (8-Dec-10 release) for BibTeX versions 0.99a or later. - % Copyright (C) 1984, 1985, 1988, 2010 Howard Trickey and Oren Patashnik. - % Unlimited copying and redistribution of this file are permitted as long as - % it is unmodified. Modifications (and redistribution of modified versions) - % are also permitted, but only if the resulting file is renamed to something - % besides btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. - % This restriction helps ensure that all standard styles are identical. - % The file btxbst.doc has the documentation for this style. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label extra.label sort.label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem[" write$ - label write$ - "]{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - key empty$ not and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ - { organization publisher new.sentence.checkb - organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - organization output - } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"January"} - -MACRO {feb} {"February"} - -MACRO {mar} {"March"} - -MACRO {apr} {"April"} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"August"} - -MACRO {sep} {"September"} - -MACRO {oct} {"October"} - -MACRO {nov} {"November"} - -MACRO {dec} {"December"} - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications of the ACM"} - -MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -MACRO {ibmsj} {"IBM Systems Journal"} - -MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -MACRO {ieeetc} {"IEEE Transactions on Computers"} - -MACRO {ieeetcad} - {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"Journal of the ACM"} - -MACRO {jcss} {"Journal of Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM Journal on Computing"} - -MACRO {tocs} {"ACM Transactions on Computer Systems"} - -MACRO {tods} {"ACM Transactions on Database Systems"} - -MACRO {tog} {"ACM Transactions on Graphics"} - -MACRO {toms} {"ACM Transactions on Mathematical Software"} - -MACRO {toois} {"ACM Transactions on Office Information Systems"} - -MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -INTEGERS { et.al.char.used } - -FUNCTION {initialize.et.al.char.used} -{ #0 'et.al.char.used := -} - -EXECUTE {initialize.et.al.char.used} - -FUNCTION {format.lab.names} -{ 's := - s num.names$ 'numnames := - numnames #1 > - { numnames #4 > - { #3 'namesleft := } - { numnames 'namesleft := } - if$ - #1 'nameptr := - "" - { namesleft #0 > } - { nameptr numnames = - { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { "{\etalchar{+}}" * - #1 'et.al.char.used := - } - { s nameptr "{v{}}{l{}}" format.name$ * } - if$ - } - { s nameptr "{v{}}{l{}}" format.name$ * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ - numnames #4 > - { "{\etalchar{+}}" * - #1 'et.al.char.used := - } - 'skip$ - if$ - } - { s #1 "{v{}}{l{}}" format.name$ - duplicate$ text.length$ #2 < - { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } - 'skip$ - if$ - } - if$ -} - -FUNCTION {author.key.label} -{ author empty$ - { key empty$ - { cite$ #1 #3 substring$ } - { key #3 text.prefix$ } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {author.editor.key.label} -{ author empty$ - { editor empty$ - { key empty$ - { cite$ #1 #3 substring$ } - { key #3 text.prefix$ } - if$ - } - { editor format.lab.names } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {author.key.organization.label} -{ author empty$ - { key empty$ - { organization empty$ - { cite$ #1 #3 substring$ } - { "The " #4 organization chop.word #3 text.prefix$ } - if$ - } - { key #3 text.prefix$ } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {editor.key.organization.label} -{ editor empty$ - { key empty$ - { organization empty$ - { cite$ #1 #3 substring$ } - { "The " #4 organization chop.word #3 text.prefix$ } - if$ - } - { key #3 text.prefix$ } - if$ - } - { editor format.lab.names } - if$ -} - -FUNCTION {calc.label} -{ type$ "book" = - type$ "inbook" = - or - 'author.editor.key.label - { type$ "proceedings" = - 'editor.key.organization.label - { type$ "manual" = - 'author.key.organization.label - 'author.key.label - if$ - } - if$ - } - if$ - duplicate$ - year field.or.null purify$ #-1 #2 substring$ - * - 'label := - year field.or.null purify$ #-1 #4 substring$ - * - sortify 'sort.label := -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ - s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -FUNCTION {presort} -{ calc.label - sort.label - " " - * - 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 - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT - -STRINGS { longest.label last.sort.label next.extra } - -INTEGERS { longest.label.width last.extra.num } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #0 int.to.chr$ 'last.sort.label := - "" 'next.extra := - #0 'longest.label.width := - #0 'last.extra.num := -} - -FUNCTION {forward.pass} -{ last.sort.label sort.label = - { last.extra.num #1 + 'last.extra.num := - last.extra.num int.to.chr$ 'extra.label := - } - { "a" chr.to.int$ 'last.extra.num := - "" 'extra.label := - sort.label 'last.sort.label := - } - if$ -} - -FUNCTION {reverse.pass} -{ next.extra "b" = - { "a" 'extra.label := } - 'skip$ - if$ - label extra.label * 'label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ - extra.label 'next.extra := -} - -EXECUTE {initialize.longest.label} - -ITERATE {forward.pass} - -REVERSE {reverse.pass} - -FUNCTION {begin.bib} -{ et.al.char.used - { "\newcommand{\etalchar}[1]{$^{#1}$}" write$ newline$ } - 'skip$ - if$ - preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/apalike.bst b/Build/extra/bibtex/apalike.bst deleted file mode 100644 index 15df7f7668d..00000000000 --- a/Build/extra/bibtex/apalike.bst +++ /dev/null @@ -1,1105 +0,0 @@ -% BibTeX `apalike' bibliography style (version 0.99a, 8-Dec-10), adapted from -% the `alpha' style, version 0.99a; for BibTeX version 0.99a. -% -% Copyright (C) 1988, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted as long as -% it is unmodified. Modifications (and redistribution of modified versions) -% are also permitted, but only if the resulting file is renamed. -% -% Differences between this style and `alpha' are generally heralded by a `%'. -% The file btxbst.doc has the documentation for alpha.bst. -% -% This style should be used with the `apalike' LaTeX style (apalike.sty). -% \cite's come out like "(Jones, 1986)" in the text but there are no labels -% in the bibliography, and something like "(1986)" comes out immediately -% after the author. Author (and editor) names appear as last name, comma, -% initials. A `year' field is required for every entry, and so is either -% an author (or in some cases, an editor) field or a key field. -% -% Editorial note: -% Many journals require a style like `apalike', but I strongly, strongly, -% strongly recommend that you not use it if you have a choice---use something -% like `plain' instead. Mary-Claire van Leunen (A Handbook for Scholars, -% Knopf, 1979) argues convincingly that a style like `plain' encourages better -% writing than one like `apalike'. Furthermore the strongest arguments for -% using an author-date style like `apalike'---that it's "the most practical" -% (The Chicago Manual of Style, University of Chicago Press, thirteenth -% edition, 1982, pages 400--401)---fall flat on their face with the new -% computer-typesetting technology. For instance page 401 anachronistically -% states "The chief disadvantage of [a style like `plain'] is that additions -% or deletions cannot be made after the manuscript is typed without changing -% numbers in both text references and list." LaTeX sidesteps the disadvantage. -% -% History: -% 15-sep-86 (OP) Original version by Oren Patashnik, ideas from Susan King. -% 10-nov-86 (OP) Truncated the sort.key$ string to the correct length -% in bib.sort.order to eliminate error message. -% 24-jan-88 (OP) Updated for BibTeX version 0.99a, from alpha.bst 0.99a; -% apalike now sorts by author, then year, then title; -% THIS `apalike' VERSION DOES NOT WORK WITH BIBTEX 0.98i. -% 8-dec-10 (OP) Still version 0.99a, as the code itself was unchanged; -% this release clarified the license. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key -% month not used in apalike - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label extra.label sort.label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -% apalike needs this function because -% the year has special punctuation; -% apalike ignores the month -FUNCTION {output.year.check} -{ year empty$ - { "empty year in " cite$ * warning$ } - { write$ - " (" year * extra.label * ")" * - mid.sentence 'output.state := - } - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem[" write$ - label write$ - "]{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{vv~}{ll}{, jj}{, f.}" format.name$ 't := % last name first - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.key} % this function is just for apalike -{ empty$ - { key field.or.null } - { "" } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ "In" % this is for apalike - " \cite{" * crossref * "}" * -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - "\cite{" * crossref * "}" * % this is for apalike -} - -FUNCTION {format.incoll.inproc.crossref} -{ "In" % this is for apalike - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check - editor format.key output - } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - output.year.check % special for apalike - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - howpublished output - address output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check - editor format.key output - } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - output.year.check % special for apalike - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address output % for apalike - new.sentence % there's no year - organization output % here so things - publisher output % are simpler - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - format.authors output - author format.key output % special for - output.year.check % apalike - new.block - format.btitle "title" output.check - organization address new.block.checkb - organization output - address output - format.edition output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - author format.key output % special for - output.year.check % apalike - new.block - format.title output - new.block - howpublished output - new.block - note output - fin.entry -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - format.editors output - editor format.key output % special for - output.year.check % apalike - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address output % for apalike - new.sentence % we always output - organization output % a nonempty organization - publisher output % here - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - author format.key output % special for - output.year.check % apalike - new.block - format.title "title" output.check - new.block - note "note" output.check - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"January"} - -MACRO {feb} {"February"} - -MACRO {mar} {"March"} - -MACRO {apr} {"April"} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"August"} - -MACRO {sep} {"September"} - -MACRO {oct} {"October"} - -MACRO {nov} {"November"} - -MACRO {dec} {"December"} - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications of the ACM"} - -MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -MACRO {ibmsj} {"IBM Systems Journal"} - -MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -MACRO {ieeetc} {"IEEE Transactions on Computers"} - -MACRO {ieeetcad} - {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"Journal of the ACM"} - -MACRO {jcss} {"Journal of Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM Journal on Computing"} - -MACRO {tocs} {"ACM Transactions on Computer Systems"} - -MACRO {tods} {"ACM Transactions on Database Systems"} - -MACRO {tog} {"ACM Transactions on Graphics"} - -MACRO {toms} {"ACM Transactions on Mathematical Software"} - -MACRO {toois} {"ACM Transactions on Office Information Systems"} - -MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -% There are three apalike cases: one person (Jones), -% two (Jones and de~Bruijn), and more (Jones et~al.). -% This function is much like format.crossref.editors. -% -FUNCTION {format.lab.names} -{ 's := - s #1 "{vv~}{ll}" format.name$ - s num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * s #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {author.key.label} -{ author empty$ - { key empty$ - { cite$ #1 #3 substring$ } - 'key % apalike uses the whole key - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {author.editor.key.label} -{ author empty$ - { editor empty$ - { key empty$ - { cite$ #1 #3 substring$ } - 'key % apalike uses the whole key - if$ - } - { editor format.lab.names } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {editor.key.label} -{ editor empty$ - { key empty$ - { cite$ #1 #3 substring$ } - 'key % apalike uses the whole key, no organization - if$ - } - { editor format.lab.names } - if$ -} - -FUNCTION {calc.label} -{ type$ "book" = - type$ "inbook" = - or - 'author.editor.key.label - { type$ "proceedings" = - 'editor.key.label % apalike ignores organization - 'author.key.label % for labeling and sorting - if$ - } - if$ - ", " % these three lines are - * % for apalike, which - year field.or.null purify$ #-1 #4 substring$ % uses all four digits - * - 'label := -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ % apalike uses initials - s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := % <= here - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.sort} -{ editor empty$ - { key empty$ - { "to sort, need editor or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ -} - -% apalike uses two sorting passes; the first one sets the -% labels so that the `a's, `b's, etc. can be computed; -% the second pass puts the references in "correct" order. -% The presort function is for the first pass. It computes -% label, sort.label, and title, and then concatenates. -FUNCTION {presort} -{ calc.label - label sortify - " " - * - type$ "book" = - type$ "inbook" = - or - 'author.editor.sort - { type$ "proceedings" = - 'editor.sort - 'author.sort - if$ - } - if$ - #1 entry.max$ substring$ % for - 'sort.label := % apalike - sort.label % style - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT % by label, sort.label, title---for final label calculation - -STRINGS { last.label next.extra } % apalike labels are only for the text; - -INTEGERS { last.extra.num } % there are none in the bibliography - -FUNCTION {initialize.extra.label.stuff} % and hence there is no `longest.label' -{ #0 int.to.chr$ 'last.label := - "" 'next.extra := - #0 'last.extra.num := -} - -FUNCTION {forward.pass} -{ last.label label = - { last.extra.num #1 + 'last.extra.num := - last.extra.num int.to.chr$ 'extra.label := - } - { "a" chr.to.int$ 'last.extra.num := - "" 'extra.label := - label 'last.label := - } - if$ -} - -FUNCTION {reverse.pass} -{ next.extra "b" = - { "a" 'extra.label := } - 'skip$ - if$ - label extra.label * 'label := - extra.label 'next.extra := -} - -EXECUTE {initialize.extra.label.stuff} - -ITERATE {forward.pass} - -REVERSE {reverse.pass} - -% Now that the label is right we sort for real, -% on sort.label then year then title. This is -% for the second sorting pass. -FUNCTION {bib.sort.order} -{ sort.label - " " - * - year field.or.null sortify - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {bib.sort.order} - -SORT % by sort.label, year, title---giving final bibliography order - -FUNCTION {begin.bib} -{ preamble$ empty$ % no \etalchar in apalike - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{}" write$ newline$ % no labels in apalike -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/apalike.sty b/Build/extra/bibtex/apalike.sty deleted file mode 100644 index e6b6d88bb0e..00000000000 --- a/Build/extra/bibtex/apalike.sty +++ /dev/null @@ -1,72 +0,0 @@ -% apalike.sty style, used in conjunction with apalike.bst, -% will produce an apa-like bibliography style. -% -% Copyright (C) 1986, 1987, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted as long as -% it is unmodified. Modifications (and redistribution of modified versions) -% are also permitted, but only if the resulting file is renamed. -% -% 1) Bibliography entries formatted alphabetically, last name -% first, each entry having a hanging indentation and no label. -% 2) References in the following formats: -% (Author, 1986) -% (Author and Author, 1986) -% (Author et al., 1986). -% 3) Multiple references in the form (Author1, 1986; Author2, 1987) -% -% To be used as an optional argument to the \documentstyle command; for example -% \documentstyle[11pt,apalike]{book} -% -% History: -% 16-Sep-86, original version by Oren Patashnik, ideas from Susan King. -% 13-Oct-87 changes: -% Fixed bug in last line by adding the {} that disappeard when -% the \hbox{} was removed from the pre-APALIKE definition; -% added club and widow penalties; -% patched the \newblock LaTeX bug from `-.07em' to simply `.07em'; -% and made this work for document styles that don't define `chapter'. -% Undated changes by Karl Berry and/or Oren Patashnik: -% 1) use \refname and \bibname instead of hardwiring -% the strings "References" and "Bibliography"; this change was first -% made in the apalike.sty in the germbib package. -% 2) do not define \bibhang if it is already defined. -% Karl Berry contributes his changes to the public domain. -% 8-Dec-10, clarify license. - -% Use parens instead of brackets for \cite, and no label in the bibliography -% -\def\@cite#1#2{(#1\if@tempswa , #2\fi)} -\def\@biblabel#1{} - -% Set length of hanging indentation for bibliography entries -% -\ifx\bibhang\@thisisundefined \newlength{\bibhang} \fi -\setlength{\bibhang}{2em} - -% \thebibliography environment depends on whether or not `chapter's can exist -% -\@ifundefined{chapter}{\def\thebibliography#1{\section*{\refname\@mkboth - {\sl\uppercase{\refname}}{\sl\uppercase{\refname}}}\list - {\relax}{\setlength{\labelsep}{0em} - \setlength{\itemindent}{-\bibhang} - \setlength{\leftmargin}{\bibhang}} - \def\newblock{\hskip .11em plus .33em minus .07em} - \sloppy\clubpenalty4000\widowpenalty4000 - \sfcode`\.=1000\relax}}% -{\def\thebibliography#1{\chapter*{\bibname\@mkboth - {\sl\uppercase{\bibname}}{\sl\uppercase{\bibname}}}\list - {\relax}{\setlength{\labelsep}{0em} - \setlength{\itemindent}{-\bibhang} - \setlength{\leftmargin}{\bibhang}} - \def\newblock{\hskip .11em plus .33em minus .07em} - \sloppy\clubpenalty4000\widowpenalty4000 - \sfcode`\.=1000\relax}} - -% `; ' goes between cites, and there's no \hbox around individual cites -% -\def\@citex[#1]#2{\if@filesw\immediate\write\@auxout{\string\citation{#2}}\fi - \def\@citea{}\@cite{\@for\@citeb:=#2\do - {\@citea\def\@citea{; }\@ifundefined - {b@\@citeb}{{\bf ?}\@warning - {Citation `\@citeb' on page \thepage \space undefined}}% -{\csname b@\@citeb\endcsname}}}{#1}} diff --git a/Build/extra/bibtex/apalike.tex b/Build/extra/bibtex/apalike.tex deleted file mode 100644 index 9ff4ec8bce4..00000000000 --- a/Build/extra/bibtex/apalike.tex +++ /dev/null @@ -1,87 +0,0 @@ -% apalike.tex, version 0.99b (8-Dec-10), for btxmac 0.99i, BibTeX 0.99c, -% TeX 3.0 or later. -% -% Copyright (C) 1990, 1991, 1992, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted as long as -% it is unmodified. Modifications (and redistribution of modified versions) -% are also permitted, but only if the resulting file is renamed. -% -% This file, apalike.tex, contains TeX macros that let you use the -% apalike bibliography style with plain TeX. In essence, this file -% provides the TeX counterpart to apalike.sty, the LaTeX style file -% required for using the apalike bibliography style. Please report any -% bugs (outright goofs, misfeatures, or unclear documentation) to -% biblio@tug.org. These macros will become frozen -% shortly after BibTeX version 1.00 is released. -% -% AMS-TEX WARNING: This style (apalike) doesn't work with AmS-TeX's -% `amsppt' style, because AmS-TeX redefines the tie character `~' of -% plain TeX, and the `amsppt' style redefines plain TeX's `\nobreak' -% macro, so that a multiple-author reference for which `apalike' -% automatically produces an in-text citation like `(Jones et~al., 1992)' -% will throw AmS-TeX's `amsppt' style into an infinite loop, exceeding -% its input stack size. (I've checked no other AmS-TeX styles for this -% problem.) The AmS-TeX warning of btxmac.tex gives more information. -% END OF AMS-TEX WARNING. -% -% Editorial note (i.e., flame): -% Many journals require a style like `apalike', but I recommend that you -% not use it if you have a choice---use something like `plain' instead. -% Mary-Claire van Leunen (A Handbook for Scholars, Knopf, 1979) argues -% convincingly that a style like `plain' encourages better writing than -% one like `apalike'. Furthermore the best argument for using an -% author-date style like `apalike'---that it's "the most practical" -% (The Chicago Manual of Style, University of Chicago Press, thirteenth -% edition, 1982, pages 400--401)---falls flat on its face with the new -% computer-typesetting technology. For instance page 401 of the Chicago -% Manual anachronistically states "The chief disadvantage of [a style -% like `plain'] is that additions or deletions cannot be made after the -% manuscript is typed without changing numbers in both text references -% and list." With (La)TeX the disadvantage obviously evaporates. -% Moreover, apalike indulges in what I think is a shortsighted practice: -% automatically abbreviating first names. Abbreviating may occasionally -% make the work a page shorter, but at the cost of a less useful -% reference list; that's too high a cost for such a marginal benefit. -% The offense isn't egregious for a name like `Donald E. Knuth'---at -% least among those familiar with his field---since there aren't many -% other `D. E. Knuth's floating around. But referring to `D. E. Smith' -% in a field having more than one can be quite confusing. Moreover, -% with the proliferation of computers and citation indexes nowadays, -% it's important to indicate in the reference list an author's name -% exactly as it appears in the work cited. Automatically abbreviating -% first names is simply bad scholarship. (End of flame.) -% -% To use these macros you need the btxmac.tex macros, which let you use -% BibTeX with plain TeX (rather than with LaTeX); the file btxmac.tex -% explains those macros in detail, and gives examples. You simply -% \input apalike right after you \input btxmac to invoke these macros. -% -% -% HISTORY -% -% Oren Patashnik wrote the original version of these macros in December -% 1990, for use with btxmac.tex. -% -% 12-Dec-90 Version 0.99a, first general release. -% 29-Feb-92 0.99b, changed `\biblabelextrahang' to `\biblabelextraspace', -% to keep up with btxmac.tex version 0.99i. -% 8-Dec-10 Still version 0.99b, as the code itself was unchanged; -% this release clarified the license. -% -% Here, finally (I swear, I thought he was never gonna stop), are the -% macros. The first bunch makes the label empty and sets 2em of -% hanging indentation (via \biblabelextraspace) for each entry. -% -\def\biblabelprint#1{\noindent}% -\def\biblabelcontents#1{}% -\def\bblhook{\biblabelextraspace = 2em }% -% -% -% And the last bunch formats an in-text citation: parens around the -% entire citation; semicolons separating individual references; and a -% comma between a reference and its note (like `page 41') if it exists. -% -\def\printcitestart{(}% left paren -\def\printcitefinish{)}% right parent -\def\printbetweencitations{; }% semicolon, space -\def\printcitenote#1{, #1}% comma, space, note (if it exists) diff --git a/Build/extra/bibtex/bibtex.web b/Build/extra/bibtex/bibtex.web deleted file mode 100644 index 543467df4c4..00000000000 --- a/Build/extra/bibtex/bibtex.web +++ /dev/null @@ -1,11679 +0,0 @@ -% This program is copyright (C) 1985, 1988, 2010 by Oren Patashnik; -% all rights are reserved. -% -% This program, BibTeX, is available under the same terms as -% Donald Knuth's TeX program. -% -% (Request to implementors: The WEB system provides for alterations via -% an auxiliary file; the master file should stay intact.) -% -% See Appendix H of the WEB manual for hints on how to install this program. - -% Version 0.98f was released in March 1985. -% Version 0.98g was released in April; it removed some system dependencies -% (introducing term_in and term_out in place of just tty, and removing -% some nonlocal goto's) and it gave context for certain parsing errors. -% Version 0.98h was released in April; it patched a bug in the output -% line-breaking routine that can arise with some nonstandard style files. -% Version 0.98i was released in May; its main change split up the main program -% and some procedures to help certain compilers cope with size -% limitations, among other things changing error and warning macros so -% they'd produce (much) less inline code; it also redefined the class of -% legal style-file identifiers---although this affects only the bizarre -% ones, it makes BibTeX's error messages more coherent; and it had many -% minor changes, including about a 15% speed-up on TOPS-20. -% Version 0.99a was released in January 1988. Its main changes: allowed the -% inclusion of entire .bib files (rather than just those entries -% \cited or \nocited); made the sorting algorithm stable; eliminated -% any case conversion for file names; allowed concatenation in database -% fields and string definitions; handled hyphenated names properly; -% handled accented characters properly; implemented new empty$, -% preamble$, text.length$, text.prefix$, and warning$ built-in functions; -% allowed a new cross-referencing feature; and made many minor fixes, -% including about a 40% speed-up on TOPS-20. -% Version 0.99b was released in February 1988. It changed text.length$ and -% text.prefix$ to not count braces as text characters, and it changed -% text.prefix$ to add any necessary matching right braces. -% Version 0.99c was released in February 1988. It removed two begin-end pairs -% that, for convention only, surrounded entire modules, but that elicited -% label-related complaints from some compilers. -% Version 0.99d was released in March 2010. It made output lines breakable -% only at white_space (so that, for example, URLs would not be broken). -% Other known bugs (all minor) will be fixed in a subsequent release. -% Updated bibtex.web was released on 8 December 2010. Still version -% 0.99d; this release clarified the license. - -% Please report any bugs to biblio@@tug.org - -% Although considerable effort has been expended to make the BibTeX program -% correct and reliable, no warranty is implied; the author disclaims any -% obligation or liability for damages, including but not limited to -% special, indirect, or consequential damages arising out of or in -% connection with the use or performance of this software. - -% This program was written by Oren Patashnik, in consultation with Leslie -% Lamport, to be used with Lamport's LaTeX document preparation system. -% Some modules were taken from Knuth's TeX and TeXware with his permission. - -% Here is TeX material that gets inserted after \input webmac -\def\hang{\hangindent 3em\indent\ignorespaces} -\font\ninerm=cmr9 -\let\mc=\ninerm % medium caps for names like PASCAL -\def\PASCAL{{\mc PASCAL}} -\def\ph{{\mc PASCAL-H}} -\def\<#1>{$\langle#1\rangle$} -\def\section{\mathhexbox278} - -\def\(#1){} % this is used to make section names sort themselves better -\def\9#1{} % this is used for sort keys in the index via @@:sort key}{entry@@> - -% Note: WEAVE will typeset an upper-case `E' in a PASCAL identifier a -% bit strangely so that the `TeX' in the name of this program is typeset -% correctly; if this becomes a problem remove these three lines to get -% normal upper-case `E's in PASCAL identifiers -\def\drop{\kern-.1667em\lower.5ex\hbox{E}\kern-.125em} % middle of TeX -\catcode`E=13 \uppercase{\def E{e}} -\def\\#1{\hbox{\let E=\drop\it#1\/\kern.05em}} % italic type for identifiers - -\font\sc=cmcsc10 - -\def\BibTeX{{\rm B\kern-.05em{\sc i\kern-.025em b}\kern-.08em - T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}} - -\def\LaTeX{{\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em - T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}} - -\def\title{\BibTeX\ } -\def\today{\ifcase\month\or - January\or February\or March\or April\or May\or June\or - July\or August\or September\or October\or November\or December\fi - \space\number\day, \number\year} -\def\topofcontents{\null\vfill - \def\titlepage{F} - \centerline{\:\titlefont The {\:\ttitlefont \BibTeX} preprocessor} - \vskip 15pt \centerline{(Version 0.99d---\today)} \vfill} -\pageno=\contentspagenumber \advance\pageno by 1 - - - -@* Introduction. -@^documentation@> -@^space savings@> -@^system dependencies@> -@^wizard@> -@!@:BibTeX}{\BibTeX@> -@!@:BibTeX documentation}{\BibTeX\ documentation@> -@:LaTeX}{\LaTeX@> -\BibTeX\ is a preprocessor (with elements of postprocessing as -explained below) for the \LaTeX\ document-preparation system. It -handles most of the formatting decisions required to produce a -reference list, outputting a \.{.bbl} file that a user can edit to add -any finishing touches \BibTeX\ isn't designed to handle (in practice, -such editing almost never is needed); with this file \LaTeX\ actually -produces the reference list. - -Here's how \BibTeX\ works. It takes as input (a)~an \.{.aux} file -produced by \LaTeX\ on an earlier run; (b)~a \.{.bst} file (the style -file), which specifies the general reference-list style and specifies -how to format individual entries, and which is written by a style -designer (called a wizard throughout this program) in a -special-purpose language described in the \BibTeX\ documentation---see -the file {\.{btxdoc.tex}}; and (c)~\.{.bib} file(s) constituting a -database of all reference-list entries the user might ever hope to -use. \BibTeX\ chooses from the \.{.bib} file(s) only those entries -specified by the \.{.aux} file (that is, those given by \LaTeX's -\.{\\cite} or \.{\\nocite} commands), and creates as output a \.{.bbl} -file containing these entries together with the formatting commands -specified by the \.{.bst} file (\BibTeX\ also creates a \.{.blg} log -file, which includes any error or warning messages, but this file -isn't used by any program). \LaTeX\ will use the \.{.bbl} file, -perhaps edited by the user, to produce the reference list. - -Many modules of \BibTeX\ were taken from Knuth's \TeX\ and \TeX ware, -with his permission. All known system-dependent modules are marked in -the index entry ``system dependencies''; Dave Fuchs helped exorcise -unwanted ones. In addition, a few modules that can be changed to make -\BibTeX\ smaller are marked in the index entry ``space savings''. - -Megathanks to Howard Trickey, for whose suggestions future users and -style writers would be eternally grateful, if only they knew. - -The |banner| string defined here should be changed whenever \BibTeX\ -gets modified. - -@d banner=='This is BibTeX, Version 0.99d' {printed when the program starts} - - -@ -@^system dependencies@> -Terminal output goes to the file |term_out|, while terminal input -comes from |term_in|. On our system, these (system-dependent) files -are already opened at the beginning of the program, and have the same -real name. - -@d term_out == tty -@d term_in == tty - - -@ -@^system dependencies@> -This program uses the term |print| instead of |write| when writing on -both the |log_file| and (system-dependent) |term_out| file, and it -uses |trace_pr| when in |trace| mode, for which it writes on just the -|log_file|. If you want to change where either set of macros writes -to, you should also change the other macros in this program for that -set; each such macro begins with |print_| or |trace_pr_|. - -@d print(#) == begin write(log_file,#); write(term_out,#); end -@d print_ln(#) == begin write_ln(log_file,#); write_ln(term_out,#); end -@d print_newline == print_a_newline - {making this a procedure saves a little space} -@# -@d trace_pr(#) == begin write(log_file,#); end -@d trace_pr_ln(#) == begin write_ln(log_file,#); end -@d trace_pr_newline == begin write_ln(log_file); end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_a_newline; -begin -write_ln(log_file); -write_ln(term_out); -end; - - -@ -@^debugging@> -@^statistics@> -Some of the code below is intended to be used only when diagnosing the -strange behavior that sometimes occurs when \BibTeX\ is being -installed or when system wizards are fooling around with \BibTeX\ -without quite knowing what they are doing. Such code will not normally -be compiled; it is delimited by the codewords -`$|debug|\ldots|gubed|$', with apologies to people who wish to -preserve the purity of English. Similarly, there is some conditional -code delimited by `$|stat|\ldots|tats|$' that is intended only for use -when statistics are to be kept about \BibTeX's memory/cpu usage, -and there is conditional code delimited by `$|trace|\ldots|ecart|$' -that is intended to be a trace facility for use mainly when debugging -\.{.bst} files. - -@d debug == @{ { remove the `|@{|' when debugging } -@d gubed == @t@>@} { remove the `|@}|' when debugging } -@f debug == begin -@f gubed == end -@# -@d stat == @{ { remove the `|@{|' when keeping statistics } -@d tats == @t@>@} { remove the `|@}|' when keeping statistics } -@f stat == begin -@f tats == end -@# -@d trace == @{ { remove the `|@{|' when in |trace| mode } -@d ecart == @t@>@} { remove the `|@}|' when in |trace| mode } -@f trace == begin -@f ecart == end - - -@ -@^system dependencies@> -We assume that |case| statements may include a -default case that applies if no matching label is found, -since most \PASCAL\ compilers have plugged this hole in the language by -incorporating some sort of default mechanism. For example, the \ph\ -compiler allows `|others|:' as a default label, and other \PASCAL s allow -syntaxes like `\ignorespaces|else|\unskip' or `\\{otherwise}' or -`\\{otherwise}:', etc. The definitions of |othercases| and |endcases| -should be changed to agree with local conventions. Note that no semicolon -appears before |endcases| in this program, so the definition of |endcases| -should include a semicolon if the compiler wants one. (Of course, if no -default mechanism is available, the |case| statements of \BibTeX\ will have -to be laboriously extended by listing all remaining cases. People who are -stuck with such \PASCAL s have in fact done this, successfully but not -happily!) - -@d othercases == others: {default for cases not listed explicitly} -@d endcases == @+end {follows the default case in an extended |case| statement} -@f othercases == else -@f endcases == end - - -@ -Labels are given symbolic names by the following definitions, so that -occasional |goto| statements will be meaningful. We insert the label -`|exit|:' just before the `\ignorespaces|end|\unskip' of a procedure -in which we have used the `|return|' statement defined below (and this -is the only place `|exit|:' appears). This label is sometimes used -for exiting loops that are set up with the |loop| construction defined -below. Another generic label is `|loop_exit|:'; it appears -immediately after a loop. - -Incidentally, this program never declares a label that isn't actually used, -because some fussy \PASCAL\ compilers will complain about redundant labels. - -@d exit=10 {go here to leave a procedure} -@d loop_exit=15 {go here to leave a loop within a procedure} -@d loop1_exit=16 {the first generic label for a procedure with two} -@d loop2_exit=17 {the second} - - -@ -@^for loops@> -And |while| we're discussing loops: This program makes into |while| -loops many that would otherwise be |for| loops because of Standard -\PASCAL\ limitations (it's a bit complicated---standard \PASCAL\ -doesn't allow a global variable as the index of a |for| loop inside a -procedure; furthermore, many compilers have fairly severe limitations -on the size of a block, including the main block of the program; so -most of the code in this program occurs inside procedures, and since -for other reasons this program must use primarily global variables, it -doesn't use many |for| loops). - - -@ -@^program conventions@> -This program uses this convention: If there are several quantities in -a boolean expression, they are ordered by expected frequency (except -perhaps when an error message results) so that execution will be -fastest; this is more an attempt to understand the program than to -make it faster. - - -@ -Here are some macros for common programming idioms. - -@d incr(#) == #:=#+1 {increase a variable by unity} -@d decr(#) == #:=#-1 {decrease a variable by unity} -@d loop == @+ while true do@+ {repeat over and over until a |goto| happens} -@f loop == xclause - {\.{WEB}'s |xclause| acts like `\ignorespaces|while true do|\unskip'} -@d do_nothing == {empty statement} -@d return == goto exit {terminate a procedure call} -@f return == nil -@d empty=0 {symbolic name for a null constant} -@d any_value=0 {this appeases \PASCAL's boolean-evaluation scheme} - - - -@* The main program. -@^system dependencies@> -@:LaTeX}{\LaTeX@> -This program first reads the \.{.aux} file that \LaTeX\ produces, -(\romannumeral1) determining which \.{.bib} file(s) and \.{.bst} file -to read and (\romannumeral2) constructing a list of cite keys in order -of occurrence. The \.{.aux} file may have other \.{.aux} files nested -within. Second, it reads and executes the \.{.bst} file, -(\romannumeral1) determining how and in which order to process the -database entries in the \.{.bib} file(s) corresponding to those cite -keys in the list (or in some cases, to all the entries in the \.{.bib} -file(s)), (\romannumeral2) determining what text to be output for each -entry and determining any additional text to be output, and -(\romannumeral3) actually outputting this text to the \.{.bbl} file. -In addition, the program sends error messages and other remarks to the -|log_file| and terminal. - -@d close_up_shop=9998 {jump here after fatal errors} -@d exit_program=9999 {jump here if we couldn't even get started} - -@p -@t\4@>@<Compiler directives@>@/ -program BibTEX; {all files are opened dynamically} -label close_up_shop,@!exit_program @<Labels in the outer block@>; -const @<Constants in the outer block@> -type @<Types in the outer block@> -var @<Globals in the outer block@>@; -@<Procedures and functions for about everything@>@; -@<The procedure |initialize|@> -@# -begin -initialize; -print_ln(banner);@/ -@<Read the \.{.aux} file@>; -@<Read and execute the \.{.bst} file@>; -close_up_shop: -@<Clean up and leave@>; -exit_program: -end. - - -@ -@^overflow in arithmetic@> -@^system dependencies@> -If the first character of a \PASCAL\ comment is a dollar sign, -\ph\ treats the comment as a list of ``compiler directives'' that will -affect the translation of this program into machine language. The -directives shown below specify full checking and inclusion of the \PASCAL\ -debugger when \BibTeX\ is being debugged, -but they cause range checking and other -redundant code to be eliminated when the production system is being generated. -Arithmetic overflow will be detected in all cases. - -@<Compiler directives@>= -@{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} -@!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} - - -@ -@^bottom up@> -@^gymnastics@> -@^mooning@> -All procedures in this program (except for |initialize|) are grouped -into one of the seven classes below, and these classes are dispersed -throughout the program. However: Much of this program is written top -down, yet \PASCAL\ wants its procedures bottom up. Since mooning is -neither a technically nor a socially acceptable solution to the -bottom-up problem, this section instead performs the topological -gymnastics that \.{WEB} allows, ordering these classes to satisfy -\PASCAL\ compilers. There are a few procedures still out of place -after this ordering, though, and the other modules that complete the -task have ``gymnastics'' as an index entry. - -@<Procedures and functions for about everything@>= -@<Procedures and functions for all file I/O, error messages, and such@>@; -@<Procedures and functions for file-system interacting@>@; -@<Procedures and functions for handling numbers, characters, and strings@>@; -@<Procedures and functions for input scanning@>@; -@<Procedures and functions for name-string processing@>@; -@<Procedures and functions for style-file function execution@>@; -@<Procedures and functions for the reading and processing of input files@> - - -@ -This procedure gets things started properly. - -@<The procedure |initialize|@>= -procedure initialize; -var @<Local variables for initialization@> -begin -@<Check the ``constant'' values for consistency@>; -if (bad > 0) then - begin - write_ln (term_out,bad:0,' is a bad bad'); - goto exit_program; - end; -@<Set initial values of key variables@>; -pre_def_certain_strings;@/ -get_the_top_level_aux_file_name; -end; - - -@ -@^space savings@> -@^system dependencies@> -These parameters can be changed at compile time to extend or reduce -\BibTeX's capacity. They are set to accommodate about 750 cites when -used with the standard styles, although |pool_size| is usually the -first limitation to be a problem, often when there are 500 cites. - -@<Constants in the outer block@>= -@!buf_size=1000; {maximum number of characters in an input line (or string)} -@!min_print_line=3; {minimum \.{.bbl} line length: must be |>=3|} -@!max_print_line=79; {the maximum: must be |>min_print_line| and |<buf_size|} -@!aux_stack_size=20; {maximum number of simultaneous open \.{.aux} files} -@!max_bib_files=20; {maximum number of \.{.bib} files allowed} -@!pool_size=65000; {maximum number of characters in strings} -@!max_strings=4000; {maximum number of strings, including pre-defined; - must be |<=hash_size|} -@!max_cites=750; {maximum number of distinct cite keys; must be - |<=max_strings|} -@!min_crossrefs=2; {minimum number of cross-refs required for automatic - |cite_list| inclusion} -@!wiz_fn_space=3000; {maximum amount of |wiz_defined|-function space} -@!single_fn_space=100; {maximum amount for a single |wiz_defined|-function} -@!max_ent_ints=3000; {maximum number of |int_entry_var|s - (entries $\times$ |int_entry_var|s)} -@!max_ent_strs=3000; {maximum number of |str_entry_var|s - (entries $\times$ |str_entry_var|s)} -@!ent_str_size=100; {maximum size of a |str_entry_var|; must be |<=buf_size|} -@!glob_str_size=1000; {maximum size of a |str_global_var|; - must be |<=buf_size|} -@!max_fields=17250; {maximum number of fields (entries $\times$ fields, - about |23*max_cites| for consistency)} -@!lit_stk_size=100; {maximum number of literal functions on the stack} - - -@ -@^space savings@> -@^system dependencies@> -These parameters can also be changed at compile time, but they're -needed to define some \.{WEB} numeric macros so they must be so -defined themselves. - -@d hash_size=5000 {must be |>= max_strings| and |>= hash_prime|} -@d hash_prime=4253 {a prime number about 85\% of |hash_size| and |>= 128| - and |< @t$2^{14}-2^6$@>|} -@d file_name_size=40 {file names shouldn't be longer than this} -@d max_glob_strs=10 {maximum number of |str_global_var| names} -@d max_glb_str_minus_1 = max_glob_strs-1 {to avoid wasting a |str_global_var|} - - -@ -In case somebody has inadvertently made bad settings of the ``constants,'' -\BibTeX\ checks them using a global variable called |bad|. - -This is the first of many sections of \BibTeX\ where global variables are -defined. - -@<Globals in the outer block@>= -@!bad:integer; {is some ``constant'' wrong?} - - -@ -Each digit-value of |bad| has a specific meaning. - -@<Check the ``constant'' values for consistency@>= -bad := 0; -if (min_print_line < 3) then bad:=1; -if (max_print_line <= min_print_line) then bad:=10*bad+2; -if (max_print_line >= buf_size) then bad:=10*bad+3; -if (hash_prime < 128) then bad:=10*bad+4; -if (hash_prime > hash_size) then bad:=10*bad+5; -if (hash_prime >= (16384-64)) then bad:=10*bad+6; -if (max_strings > hash_size) then bad:=10*bad+7; -if (max_cites > max_strings) then bad:=10*bad+8; -if (ent_str_size > buf_size) then bad:=10*bad+9; -if (glob_str_size > buf_size) then bad:=100*bad+11; - {well, almost each} - - -@ -A global variable called |history| will contain one of four values at -the end of every run: |spotless| means that no unusual messages were -printed; |warning_message| means that a message of possible interest -was printed but no serious errors were detected; |error_message| means -that at least one error was found; |fatal_message| means that the -program terminated abnormally. The value of |history| does not -influence the behavior of the program; it is simply computed for the -convenience of systems that might want to use such information. - -@d spotless=0 {|history| value for normal jobs} -@d warning_message=1 {|history| value when non-serious info was printed} -@d error_message=2 {|history| value when an error was noted} -@d fatal_message=3 {|history| value when we had to stop prematurely} - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure mark_warning; -begin -if (history = warning_message) then - incr(err_count) - else if (history = spotless) then - begin - history := warning_message; - err_count := 1; - end; -end; -@# -procedure mark_error; -begin -if (history < error_message) then - begin - history := error_message; - err_count := 1; - end - else {|history = error_message|} - incr(err_count); -end; -@# -procedure mark_fatal; -begin -history := fatal_message; -end; - - -@ -For the two states |warning_message| and |error_message| we keep track -of the number of messages given; but since |warning_message|s aren't -so serious, we ignore them once we've seen an |error_message|. Hence -we need just the single variable |err_count| to keep track. - - -@<Globals in the outer block@>= -@!history:spotless..fatal_message; {how bad was this run?} -@!err_count:integer; - - -@ -The |err_count| gets set or reset when |history| first changes to -|warning_message| or |error_message|, so we don't need to initialize -it. - -@<Set initial values of key variables@>= -history := spotless; - - - -@* The character set. -@^ASCII code@> -(The following material is copied (almost) verbatim from \TeX. -Thus, the same system-dependent changes should be made to both programs.) - -In order to make \TeX\ readily portable between a wide variety of -computers, all of its input text is converted to an internal seven-bit -code that is essentially standard ASCII, the ``American Standard Code for -Information Interchange.'' This conversion is done immediately when each -character is read in. Conversely, characters are converted from ASCII to -the user's external representation just before they are output to a -text file. - -Such an internal code is relevant to users of \TeX\ primarily because it -governs the positions of characters in the fonts. For example, the -character `\.A' has ASCII code $65=@'101$, and when \TeX\ typesets -this letter it specifies character number 65 in the current font. -If that font actually has `\.A' in a different position, \TeX\ doesn't -know what the real position is; the program that does the actual printing from -\TeX's device-independent files is responsible for converting from ASCII to -a particular font encoding. - -\TeX's internal code is relevant also with respect to constants -that begin with a reverse apostrophe. - - -@ -Characters of text that have been converted to \TeX's internal form -are said to be of type |ASCII_code|, which is a subrange of the integers. - -@<Types in the outer block@>= -@!ASCII_code=0..127; {seven-bit numbers} - - -@ -@^character set dependencies@> -@^system dependencies@> -The original \PASCAL\ compiler was designed in the late 60s, when six-bit -character sets were common, so it did not make provision for lower-case -letters. Nowadays, of course, we need to deal with both capital and small -letters in a convenient way, especially in a program for typesetting; -so the present specification of \TeX\ has been written under the assumption -that the \PASCAL\ compiler and run-time system permit the use of text files -with more than 64 distinguishable characters. More precisely, we assume that -the character set contains at least the letters and symbols associated -with ASCII codes @'40 through @'176; all of these characters are now -available on most computer terminals. - -Since we are dealing with more characters than were present in the first -\PASCAL\ compilers, we have to decide what to call the associated data -type. Some \PASCAL s use the original name |char| for the -characters in text files, even though there now are more than 64 such -characters, while other \PASCAL s consider |char| to be a 64-element -subrange of a larger data type that has some other name. - -In order to accommodate this difference, we shall use the name |text_char| -to stand for the data type of the characters that are converted to and -from |ASCII_code| when they are input and output. We shall also assume -that |text_char| consists of the elements |chr(first_text_char)| through -|chr(last_text_char)|, inclusive. The following definitions should be -adjusted if necessary. - -@d text_char == char {the data type of characters in text files} -@d first_text_char=0 {ordinal number of the smallest element of |text_char|} -@d last_text_char=127 {ordinal number of the largest element of |text_char|} - -@<Local variables for initialization@>= -i:0..last_text_char; {this is the first one declared} - - -@ -The \TeX\ processor converts between ASCII code and -the user's external character set by means of arrays |xord| and |xchr| -that are analogous to \PASCAL's |ord| and |chr| functions. - -@<Globals in the outer block@>= -@!xord: array [text_char] of ASCII_code; - {specifies conversion of input characters} -@!xchr: array [ASCII_code] of text_char; - {specifies conversion of output characters} - - -@ -@^character set dependencies@> -@^system dependencies@> -Since we are assuming that our \PASCAL\ system is able to read and write the -visible characters of standard ASCII (although not necessarily using the -ASCII codes to represent them), the following assignment statements initialize -most of the |xchr| array properly, without needing any system-dependent -changes. On the other hand, it is possible to implement \TeX\ with -less complete character sets, and in such cases it will be necessary to -change something here. - -@<Set initial values of key variables@>= -xchr[@'40]:=' '; -xchr[@'41]:='!'; -xchr[@'42]:='"'; -xchr[@'43]:='#'; -xchr[@'44]:='$'; -xchr[@'45]:='%'; -xchr[@'46]:='&'; -xchr[@'47]:='''';@/ -xchr[@'50]:='('; -xchr[@'51]:=')'; -xchr[@'52]:='*'; -xchr[@'53]:='+'; -xchr[@'54]:=','; -xchr[@'55]:='-'; -xchr[@'56]:='.'; -xchr[@'57]:='/';@/ -xchr[@'60]:='0'; -xchr[@'61]:='1'; -xchr[@'62]:='2'; -xchr[@'63]:='3'; -xchr[@'64]:='4'; -xchr[@'65]:='5'; -xchr[@'66]:='6'; -xchr[@'67]:='7';@/ -xchr[@'70]:='8'; -xchr[@'71]:='9'; -xchr[@'72]:=':'; -xchr[@'73]:=';'; -xchr[@'74]:='<'; -xchr[@'75]:='='; -xchr[@'76]:='>'; -xchr[@'77]:='?';@/ -xchr[@'100]:='@@'; -xchr[@'101]:='A'; -xchr[@'102]:='B'; -xchr[@'103]:='C'; -xchr[@'104]:='D'; -xchr[@'105]:='E'; -xchr[@'106]:='F'; -xchr[@'107]:='G';@/ -xchr[@'110]:='H'; -xchr[@'111]:='I'; -xchr[@'112]:='J'; -xchr[@'113]:='K'; -xchr[@'114]:='L'; -xchr[@'115]:='M'; -xchr[@'116]:='N'; -xchr[@'117]:='O';@/ -xchr[@'120]:='P'; -xchr[@'121]:='Q'; -xchr[@'122]:='R'; -xchr[@'123]:='S'; -xchr[@'124]:='T'; -xchr[@'125]:='U'; -xchr[@'126]:='V'; -xchr[@'127]:='W';@/ -xchr[@'130]:='X'; -xchr[@'131]:='Y'; -xchr[@'132]:='Z'; -xchr[@'133]:='['; -xchr[@'134]:='\'; -xchr[@'135]:=']'; -xchr[@'136]:='^'; -xchr[@'137]:='_';@/ -xchr[@'140]:='`'; -xchr[@'141]:='a'; -xchr[@'142]:='b'; -xchr[@'143]:='c'; -xchr[@'144]:='d'; -xchr[@'145]:='e'; -xchr[@'146]:='f'; -xchr[@'147]:='g';@/ -xchr[@'150]:='h'; -xchr[@'151]:='i'; -xchr[@'152]:='j'; -xchr[@'153]:='k'; -xchr[@'154]:='l'; -xchr[@'155]:='m'; -xchr[@'156]:='n'; -xchr[@'157]:='o';@/ -xchr[@'160]:='p'; -xchr[@'161]:='q'; -xchr[@'162]:='r'; -xchr[@'163]:='s'; -xchr[@'164]:='t'; -xchr[@'165]:='u'; -xchr[@'166]:='v'; -xchr[@'167]:='w';@/ -xchr[@'170]:='x'; -xchr[@'171]:='y'; -xchr[@'172]:='z'; -xchr[@'173]:='{'; -xchr[@'174]:='|'; -xchr[@'175]:='}'; -xchr[@'176]:='~';@/ -xchr[0]:=' '; xchr[@'177]:=' '; - {ASCII codes 0 and |@'177| do not appear in text} - - -@ -@^character set dependencies@> -@^system dependencies@> -Some of the ASCII codes without visible characters have been given symbolic -names in this program because they are used with a special meaning. The -|tab| character may be system dependent. - -@d null_code=@'0 {ASCII code that might disappear} -@d tab=@'11 {ASCII code treated as |white_space|} -@d space=@'40 {ASCII code treated as |white_space|} -@d invalid_code=@'177 {ASCII code that should not appear} - - -@ -@^character set dependencies@> -@^system dependencies@> -@:TeXbook}{\sl The \TeX book@> -The ASCII code is ``standard'' only to a certain extent, since many -computer installations have found it advantageous to have ready access -to more than 94 printing characters. Appendix~C of {\sl The \TeX book\/} -gives a complete specification of the intended correspondence between -characters and \TeX's internal representation. - -If \TeX\ is being used -on a garden-variety \PASCAL\ for which only standard ASCII -codes will appear in the input and output files, it doesn't really matter -what codes are specified in |xchr[1..@'37]|, but the safest policy is to -blank everything out by using the code shown below. - -However, other settings of |xchr| will make \TeX\ more friendly on -computers that have an extended character set, so that users can type things -like `\.^^Z' instead of `\.{\\ne}'. At MIT, for example, it would be more -appropriate to substitute the code -$$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$ -\TeX's character set is essentially the same as MIT's, even with respect to -characters less than~@'40. People with extended character sets can -assign codes arbitrarily, giving an |xchr| equivalent to whatever -characters the users of \TeX\ are allowed to have in their input files. -It is best to make the codes correspond to the intended interpretations as -shown in Appendix~C whenever possible; but this is not necessary. For -example, in countries with an alphabet of more than 26 letters, it is -usually best to map the additional letters into codes less than~@'40. - -@<Set initial values of key variables@>= -for i:=1 to @'37 do xchr[i]:=' '; -xchr[tab]:=chr(tab); - - -@ -This system-independent code makes the |xord| array contain a suitable -inverse to the information in |xchr|. Note that if |xchr[i]=xchr[j]| -where |i<j<@'177|, the value of |xord[xchr[i]]| will turn out to be -|j| or more; hence, standard ASCII code numbers will be used instead -of codes below @'40 in case there is a coincidence. - -@<Set initial values of key variables@>= -for i:=first_text_char to last_text_char do xord[chr(i)]:=invalid_code; -for i:=1 to @'176 do xord[xchr[i]]:=i; - - -@ -Also, various characters are given symbolic names; all the ones this -program uses are collected here. We use the sharp sign as the -|concat_char|, rather than something more natural (like an ampersand), -for uniformity of database syntax (ampersand is a valid character in -identifiers). - -@d double_quote = """" {delimits strings} -@d number_sign = "#" {marks an |int_literal|} -@d comment = "%" {ignore the rest of a \.{.bst} or \TeX\ line} -@d single_quote = "'" {marks a quoted function} -@d left_paren = "(" {optional database entry left delimiter} -@d right_paren = ")" {corresponding right delimiter} -@d comma = "," {separates various things} -@d minus_sign = "-" {for a negative number} -@d equals_sign = "=" {separates a field name from a field value} -@d at_sign = "@@" {the beginning of a database entry} -@d left_brace = "{" {left delimiter of many things} -@d right_brace = "}" {corresponding right delimiter} -@d period = "." {these are three} -@d question_mark = "?" {string-ending characters} -@d exclamation_mark = "!" {of interest in \.{add.period\$}} -@d tie = "~" {the default space char, in \.{format.name\$}} -@d hyphen = "-" {like |white_space|, in \.{format.name\$}} -@d star = "*" {for including entire database} -@d concat_char = "#" {for concatenating field tokens} -@d colon = ":" {for lower-casing (usually title) strings} -@d backslash = "\" {used to recognize accented characters} - - -@ -These arrays give a lexical classification for the |ASCII_code|s; -|lex_class| is used for general scanning and |id_class| is used for -scanning identifiers. - -@<Globals in the outer block@>= -@!lex_class: array [ASCII_code] of lex_type; -@!id_class: array [ASCII_code] of id_type; - - -@ -Every character has two types of the lexical classifications. The -first type is general, and the second type tells whether the character -is legal in identifiers. - -@d illegal = 0 {the unrecognized |ASCII_code|s} -@d white_space = 1 {things like |space|s that you can't see} -@d alpha = 2 {the upper- and lower-case letters} -@d numeric = 3 {the ten digits} -@d sep_char = 4 {things sometimes treated like |white_space|} -@d other_lex = 5 {when none of the above applies} -@d last_lex = 5 {the same number as on the line above} -@# -@d illegal_id_char = 0 {a few forbidden ones} -@d legal_id_char = 1 {most printing characters} - -@<Types in the outer block@>= -@!lex_type = 0..last_lex;@/ -@!id_type = 0..1; - - -@ -@^character set dependencies@> -@^system dependencies@> -Now we initialize the system-dependent |lex_class| array. The |tab| -character may be system dependent. Note that the order of these -assignments is important here. - -@<Set initial values of key variables@>= -for i:=0 to @'177 do lex_class[i] := other_lex; -for i:=0 to @'37 do lex_class[i] := illegal; -lex_class[invalid_code] := illegal; -lex_class[tab] := white_space; -lex_class[space] := white_space; -lex_class[tie] := sep_char; -lex_class[hyphen] := sep_char; -for i:=@'60 to @'71 do lex_class[i] := numeric; -for i:=@'101 to @'132 do lex_class[i] := alpha; -for i:=@'141 to @'172 do lex_class[i] := alpha; - - -@ -@^character set dependencies@> -@^system dependencies@> -And now the |id_class| array. - -@<Set initial values of key variables@>= -for i:=0 to @'177 do id_class[i] := legal_id_char; -for i:=0 to @'37 do id_class[i] := illegal_id_char; -id_class[space] := illegal_id_char; -id_class[tab] := illegal_id_char; -id_class[double_quote] := illegal_id_char; -id_class[number_sign] := illegal_id_char; -id_class[comment] := illegal_id_char; -id_class[single_quote] := illegal_id_char; -id_class[left_paren] := illegal_id_char; -id_class[right_paren] := illegal_id_char; -id_class[comma] := illegal_id_char; -id_class[equals_sign] := illegal_id_char; -id_class[left_brace] := illegal_id_char; -id_class[right_brace] := illegal_id_char; - - -@ -The array |char_width| gives relative printing widths of each -|ASCII_code|, and |string_width| will be used later to sum up -|char_width|s in a string. - -@<Globals in the outer block@>= -@!char_width : array [ASCII_code] of integer; -@!string_width : integer; - - -@ -@^character set dependencies@> -@^system dependencies@> -Now we initialize the system-dependent |char_width| array, for which -|space| is the only |white_space| character given a nonzero printing -width. The widths here are taken from Stanford's June~'87 -$cmr10$~font and represent hundredths of a point (rounded), but since -they're used only for relative comparisons, the units have no meaning. - -@d ss_width = 500 {character |@'31|'s width in the $cmr10$ font} -@d ae_width = 722 {character |@'32|'s width in the $cmr10$ font} -@d oe_width = 778 {character |@'33|'s width in the $cmr10$ font} -@d upper_ae_width = 903 {character |@'35|'s width in the $cmr10$ font} -@d upper_oe_width = 1014 {character |@'36|'s width in the $cmr10$ font} - -@<Set initial values of key variables@>= -for i:=0 to @'177 do char_width[i] := 0; -@# -char_width[@'40] := 278; -char_width[@'41] := 278; -char_width[@'42] := 500; -char_width[@'43] := 833; -char_width[@'44] := 500; -char_width[@'45] := 833; -char_width[@'46] := 778; -char_width[@'47] := 278; -char_width[@'50] := 389; -char_width[@'51] := 389; -char_width[@'52] := 500; -char_width[@'53] := 778; -char_width[@'54] := 278; -char_width[@'55] := 333; -char_width[@'56] := 278; -char_width[@'57] := 500; -char_width[@'60] := 500; -char_width[@'61] := 500; -char_width[@'62] := 500; -char_width[@'63] := 500; -char_width[@'64] := 500; -char_width[@'65] := 500; -char_width[@'66] := 500; -char_width[@'67] := 500; -char_width[@'70] := 500; -char_width[@'71] := 500; -char_width[@'72] := 278; -char_width[@'73] := 278; -char_width[@'74] := 278; -char_width[@'75] := 778; -char_width[@'76] := 472; -char_width[@'77] := 472; -char_width[@'100] := 778; -char_width[@'101] := 750; -char_width[@'102] := 708; -char_width[@'103] := 722; -char_width[@'104] := 764; -char_width[@'105] := 681; -char_width[@'106] := 653; -char_width[@'107] := 785; -char_width[@'110] := 750; -char_width[@'111] := 361; -char_width[@'112] := 514; -char_width[@'113] := 778; -char_width[@'114] := 625; -char_width[@'115] := 917; -char_width[@'116] := 750; -char_width[@'117] := 778; -char_width[@'120] := 681; -char_width[@'121] := 778; -char_width[@'122] := 736; -char_width[@'123] := 556; -char_width[@'124] := 722; -char_width[@'125] := 750; -char_width[@'126] := 750; -char_width[@'127] :=1028; -char_width[@'130] := 750; -char_width[@'131] := 750; -char_width[@'132] := 611; -char_width[@'133] := 278; -char_width[@'134] := 500; -char_width[@'135] := 278; -char_width[@'136] := 500; -char_width[@'137] := 278; -char_width[@'140] := 278; -char_width[@'141] := 500; -char_width[@'142] := 556; -char_width[@'143] := 444; -char_width[@'144] := 556; -char_width[@'145] := 444; -char_width[@'146] := 306; -char_width[@'147] := 500; -char_width[@'150] := 556; -char_width[@'151] := 278; -char_width[@'152] := 306; -char_width[@'153] := 528; -char_width[@'154] := 278; -char_width[@'155] := 833; -char_width[@'156] := 556; -char_width[@'157] := 500; -char_width[@'160] := 556; -char_width[@'161] := 528; -char_width[@'162] := 392; -char_width[@'163] := 394; -char_width[@'164] := 389; -char_width[@'165] := 556; -char_width[@'166] := 528; -char_width[@'167] := 722; -char_width[@'170] := 528; -char_width[@'171] := 528; -char_width[@'172] := 444; -char_width[@'173] := 500; -char_width[@'174] :=1000; -char_width[@'175] := 500; -char_width[@'176] := 500; - - - -@* Input and output. -The basic operations we need to do are -(1)~inputting and outputting of text characters to or from a file; -(2)~instructing the operating system to initiate (``open'') -or to terminate (``close'') input or output to or from a specified file; and -(3)~testing whether the end of an input file has been reached. - -@<Types in the outer block@>= -@!alpha_file=packed file of text_char; {files that contain textual data} - - -@ -@^system dependencies@> -Most of what we need to do with respect to input and output can be handled -by the I/O facilities that are standard in \PASCAL, i.e., the routines -called |get|, |put|, |eof|, and so on. But -standard \PASCAL\ does not allow file variables to be associated with file -names that are determined at run time, so it cannot be used to implement -\BibTeX; some sort of extension to \PASCAL's ordinary |reset| and |rewrite| -is crucial for our purposes. We shall assume that |name_of_file| is a variable -of an appropriate type such that the \PASCAL\ run-time system being used to -implement \BibTeX\ can open a file whose external name is specified by -|name_of_file|. \BibTeX\ does no case conversion for file names. - -@<Globals in the outer block@>= -@!name_of_file:packed array[1..file_name_size] of char; - {on some systems this is a \&{record} variable} -@!name_length:0..file_name_size; - {this many characters are relevant in |name_of_file| (the rest are blank)} -@!name_ptr:0..file_name_size+1; {index variable into |name_of_file|} - - -@ -@^system dependencies@> -@:PASCAL H}{\ph@> -The \ph\ compiler with which the present version of \TeX\ was prepared has -extended the rules of \PASCAL\ in a very convenient way. To open file~|f|, -we can write -$$\vbox{\halign{#\hfil\qquad&#\hfil\cr -|reset(f,@t\\{name}@>,'/O')|&for input;\cr -|rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$ -The `\\{name}' parameter, which is of type `\ignorespaces|packed -array[@t\<\\{any}>@>] of text_char|', stands for the name of -the external file that is being opened for input or output. -Blank spaces that might appear in \\{name} are ignored. - -The `\.{/O}' parameter tells the operating system not to issue its own -error messages if something goes wrong. If a file of the specified name -cannot be found, or if such a file cannot be opened for some other reason -(e.g., someone may already be trying to write the same file), we will have -|@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows -\TeX\ to undertake appropriate corrective action. - -\TeX's file-opening procedures return |false| if no file identified by -|name_of_file| could be opened. - -@d reset_OK(#)==erstat(#)=0 -@d rewrite_OK(#)==erstat(#)=0 - -@<Procedures and functions for file-system interacting@>= -function erstat(var f:file):integer; extern; {in the runtime library} -@#@t\2@> -function a_open_in(var f:alpha_file):boolean; {open a text file for input} -begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f); -end; -@# -function a_open_out(var f:alpha_file):boolean; {open a text file for output} -begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f); -end; - - -@ -@^system dependencies@> -Files can be closed with the \ph\ routine `|close(f)|', which should -be used when all input or output with respect to |f| has been -completed. This makes |f| available to be opened again, if desired; -and if |f| was used for output, the |close| operation makes the -corresponding external file appear on the user's area, ready to be -read. - -@<Procedures and functions for file-system interacting@>= -procedure a_close(var f:alpha_file); {close a text file} -begin close(f); -end; - - -@ -Text output is easy to do with the ordinary \PASCAL\ |put| procedure, -so we don't have to make any other special arrangements. -The treatment of text input is more difficult, however, because -of the necessary translation to |ASCII_code| values, and because -\TeX's conventions should be efficient and they should -blend nicely with the user's operating environment. - - -@ -Input from text files is read one line at a time, using a routine -called |input_ln|. This function is defined in terms of global -variables called |buffer| and |last|. The |buffer| array contains -|ASCII_code| values, and |last| is an index into this array marking -the end of a line of text. (Occasionally, |buffer| is used for -something else, in which case it is copied to a temporary array.) - -@<Globals in the outer block@>= -@!buffer:buf_type; {usually, lines of characters being read} -@!last:buf_pointer; {end of the line just input to |buffer|} - - -@ -@^save space@> -@^space savings@> -@^system dependencies@> -The type |buf_type| is used for |buffer|, for saved copies of it, or -for scratch work. It's not |packed| because otherwise the program -would run much slower on some systems (more than 25 percent slower, -for example, on a TOPS-20 operating system). But on systems that are -byte-addressable and that have a good compiler, packing |buf_type| -would save lots of space without much loss of speed. Other modules -that have packable arrays are also marked with a ``space savings'' -index entry. - -@<Types in the outer block@>= -@!buf_pointer = 0..buf_size; {an index into a |buf_type|} -@!buf_type = array[buf_pointer] of ASCII_code; {for various buffers} - - -@ -@^kludge@> -And while we're at it, we declare another buffer for general use. -Because buffers are not packed and can get large, we use |sv_buffer| -several purposes; this is a bit kludgy, but it helps make the stack -space not overflow on some machines. It's used when reading the -entire database file (in the \.{read} command) and when doing -name-handling (through the alias |name_buf|) in the |built_in| -functions \.{format.names\$} and \.{num.names\$}. - -@<Globals in the outer block@>= -@!sv_buffer : buf_type; -@!sv_ptr1 : buf_pointer; -@!sv_ptr2 : buf_pointer; -@!tmp_ptr,@!tmp_end_ptr : integer; {copy pointers only, usually for buffers} - - -@ -@.BibTeX capacity exceeded@> -When something in the program wants to be bigger or something out -there wants to be smaller, it's time to call it a run. Here's the -first of several macros that have associated procedures so that they -produce less inline code. - -@d overflow(#)==begin {fatal error---close up shop} - print_overflow; - print_ln(#:0); - goto close_up_shop; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_overflow; -begin -print ('Sorry---you''ve exceeded BibTeX''s '); -mark_fatal; -end; - - -@ -@.this can't happen@> -When something happens that the program thinks is impossible, -call the maintainer. - -@d confusion(#)==begin {fatal error---close up shop} - print (#); - print_confusion; - goto close_up_shop; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_confusion; -begin -print_ln ('---this can''t happen'); -print_ln ('*Please notify the BibTeX maintainer*'); -mark_fatal; -end; - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -When a buffer overflows, it's time to complain (and then quit). - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure buffer_overflow; -begin -overflow('buffer size ',buf_size); -end; - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -The |input_ln| function brings the next line of input from the -specified file into available positions of the buffer array and -returns the value |true|, unless the file has already been entirely -read, in which case it returns |false| and sets |last:=0|. In -general, the |ASCII_code| numbers that represent the next line of the -file are input into |buffer[0]|, |buffer[1]|, \dots, |buffer[last-1]|; -and the global variable |last| is set equal to the length of the line. -Trailing |white_space| characters are removed from the line -(|white_space| characters are explained in the character-set section% ----most likely they're blanks); thus, either |last=0| (in which case -the line was entirely blank) or |lex_class[buffer[last-1]]<>white_space|. -An overflow error is given if the normal actions of |input_ln| would -make |last>buf_size|. - -Standard \PASCAL\ says that a file should have |eoln| immediately -before |eof|, but \BibTeX\ needs only a weaker restriction: If |eof| -occurs in the middle of a line, the system function |eoln| should return -a |true| result (even though |f^| will be undefined). - -@<Procedures and functions for all file I/O, error messages, and such@>= -function input_ln(var f:alpha_file) : boolean; - {inputs the next line or returns |false|} -label loop_exit; -begin -last:=0; -if (eof(f)) then input_ln:=false -else - begin - while (not eoln(f)) do - begin - if (last >= buf_size) then - buffer_overflow; - buffer[last]:=xord[f^]; - get(f); incr(last); - end; - get(f); - while (last > 0) do {remove trailing |white_space|} - if (lex_class[buffer[last-1]] = white_space) then - decr(last) - else - goto loop_exit; -loop_exit: - input_ln:=true; - end; -end; - - - -@* String handling. -\BibTeX\ uses variable-length strings of seven-bit characters. -Since \PASCAL\ does not have a well-developed string mechanism, -\BibTeX\ does all its string processing by home-grown -(predominantly \TeX's) methods. -Unlike \TeX, however, \BibTeX\ does not use a |pool_file| for -string storage; it creates its few pre-defined strings at run-time. - -The necessary operations are handled with a simple data structure. -The array |str_pool| contains all the (seven-bit) ASCII codes in all -the strings \BibTeX\ must ever search for (generally identifiers -names), and the array |str_start| contains indices of the starting -points of each such string. Strings are referred to by integer -numbers, so that string number |s| comprises the characters -|str_pool[j]| for |str_start[s]<=j<str_start[s+1]|. Additional integer -variables |pool_ptr| and |str_ptr| indicate the number of entries used -so far in |str_pool| and |str_start|; locations |str_pool[pool_ptr]| -and |str_start[str_ptr]| are ready for the next string to be -allocated. Location |str_start[0]| is unused so that hashing will -work correctly. - -Elements of the |str_pool| array must be ASCII codes that can actually be -printed; i.e., they must have an |xchr| equivalent in the local -character set. - -@<Globals in the outer block@>= -@!str_pool : packed array[pool_pointer] of ASCII_code; {the characters} -@!str_start : packed array[str_number] of pool_pointer; {the starting pointers} -@!pool_ptr : pool_pointer; {first unused position in |str_pool|} -@!str_ptr : str_number; {start of the current string being created} -@!str_num : str_number; {general index variable into |str_start|} -@!p_ptr1,@!p_ptr2 : pool_pointer; {several procedures use these locally} - - -@ -Where |pool_pointer| and |str_number| are pointers into |str_pool| and -|str_start|. - -@<Types in the outer block@>= -@!pool_pointer = 0..pool_size; {for variables that point into |str_pool|} -@!str_number = 0..max_strings; {for variables that point into |str_start|} - - -@ -These macros send a string in |str_pool| to an output file. - -@d max_pop = 3 {---see the |built_in| functions section} -@# -@d print_pool_str(#) == print_a_pool_str(#) - {making this a procedure saves a little space} -@# -@d trace_pr_pool_str(#) == begin - out_pool_str(log_file,#); - end - - -@ -@^kludge@> -@^system dependencies@> -@:this can't happen}{\quad Illegal string number@> -And here are the associated procedures. Note: The |term_out| file is -system dependent. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure out_pool_str (var f:alpha_file; @!s:str_number); -var i:pool_pointer; -begin {allowing |str_ptr <= s < str_ptr+max_pop| is a \.{.bst}-stack kludge} -if ((s<0) or (s>=str_ptr+max_pop) or (s>=max_strings)) then - confusion ('Illegal string number:',s:0); -for i := str_start[s] to str_start[s+1]-1 do - write(f,xchr[str_pool[i]]); -end; -@# -procedure print_a_pool_str (@!s:str_number); -begin -out_pool_str(term_out,s); -out_pool_str(log_file,s); -end; - - -@ -@.WEB@> -Several of the elementary string operations are performed using \.{WEB} -macros instead of using \PASCAL\ procedures, because many of the -operations are done quite frequently and we want to avoid the -overhead of procedure calls. For example, here is -a simple macro that computes the length of a string. - -@d length(#) == (str_start[#+1]-str_start[#]) - {the number of characters in string number \#} - - -@ -@:BibTeX capacity exceeded}{\quad pool size@> -Strings are created by appending character codes to |str_pool|. -The macro called |append_char|, defined here, does not check to see if the -value of |pool_ptr| has gotten too high; this test is supposed to be -made before |append_char| is used. - -To test if there is room to append |l| more characters to |str_pool|, -we shall write |str_room(l)|, which aborts \BibTeX\ and gives an -error message if there isn't enough room. - -@d append_char(#) == {put |ASCII_code| \# at the end of |str_pool|} -begin str_pool[pool_ptr]:=#; incr(pool_ptr); -end -@# -@d str_room(#) == {make sure that the pool hasn't overflowed} - begin - if (pool_ptr+# > pool_size) then - pool_overflow; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure pool_overflow; -begin -overflow('pool size ',pool_size); -end; - - -@ -@:BibTeX capacity exceeded}{\quad number of strings@> -Once a sequence of characters has been appended to |str_pool|, it -officially becomes a string when the function |make_string| is called. -It returns the string number of the string it just made. - -@<Procedures and functions for handling numbers, characters, and strings@>= -function make_string : str_number; {current string enters the pool} -begin -if (str_ptr=max_strings) then - overflow('number of strings ',max_strings); -incr(str_ptr); -str_start[str_ptr]:=pool_ptr; -make_string := str_ptr - 1; -end; - - -@ -These macros destroy and recreate the string at the end of the pool. - -@d flush_string == begin - decr(str_ptr); - pool_ptr := str_start[str_ptr]; - end -@# -@d unflush_string == begin - incr(str_ptr); - pool_ptr := str_start[str_ptr]; - end - - -@ -This subroutine compares string |s| with another string that appears -in the buffer |buf| between positions |bf_ptr| and |bf_ptr+len-1|; the -result is |true| if and only if the strings are equal. - -@<Procedures and functions for handling numbers, characters, and strings@>= -function str_eq_buf (@!s:str_number; var buf:buf_type; - @!bf_ptr,@!len:buf_pointer) : boolean; - {test equality of strings} -label exit; -var i : buf_pointer; {running} -@!j : pool_pointer; {indices} -begin -if (length(s) <> len) then {strings of unequal length} - begin - str_eq_buf := false; - return; - end; -i := bf_ptr; -j := str_start[s]; -while (j < str_start[s+1]) do - begin - if (str_pool[j] <> buf[i]) then - begin - str_eq_buf := false; - return; - end; - incr(i); - incr(j); - end; -str_eq_buf := true; -exit: -end; - - -@ -This subroutine compares two |str_pool| strings and returns true -|true| if and only if the strings are equal. - -@<Procedures and functions for handling numbers, characters, and strings@>= -function str_eq_str (@!s1,@!s2:str_number) : boolean; -label exit; -begin -if (length(s1) <> length(s2)) then - begin - str_eq_str := false; - return; - end; -p_ptr1 := str_start[s1]; -p_ptr2 := str_start[s2]; -while (p_ptr1 < str_start[s1+1]) do - begin - if (str_pool[p_ptr1] <> str_pool[p_ptr2]) then - begin - str_eq_str := false; - return; - end; - incr(p_ptr1); - incr(p_ptr2); - end; -str_eq_str:=true; -exit: -end; - - -@ -@:BibTeX capacity exceeded}{\quad file name size@> -This procedure copies file name |file_name| into the beginning of -|name_of_file|, if it will fit. It also sets the global variable -|name_length| to the appropriate value. - -@<Procedures and functions for file-system interacting@>= -procedure start_name (@!file_name:str_number); -var p_ptr: pool_pointer; {running index} -begin -if (length(file_name) > file_name_size) then - begin - print ('File='); - print_pool_str (file_name); - print_ln (','); - file_nm_size_overflow; - end; -name_ptr := 1; -p_ptr := str_start[file_name]; -while (p_ptr < str_start[file_name+1]) do - begin - name_of_file[name_ptr] := chr (str_pool[p_ptr]); - incr(name_ptr); incr(p_ptr); - end; -name_length := length(file_name); -end; - - -@ -@:BibTeX capacity exceeded}{\quad file name size@> -Yet another complaint-before-quiting. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure file_nm_size_overflow; -begin -overflow('file name size ',file_name_size); -end; - - -@ -@:BibTeX capacity exceeded}{\quad file name size@> -This procedure copies file extension |ext| into the array -|name_of_file| starting at position |name_length+1|. It also sets the -global variable |name_length| to the appropriate value. - -@<Procedures and functions for file-system interacting@>= -procedure add_extension(@!ext:str_number); -var p_ptr: pool_pointer; {running index} -begin -if (name_length + length(ext) > file_name_size) then - begin - print ('File=',name_of_file,', extension='); - print_pool_str (ext); print_ln (','); - file_nm_size_overflow; - end; -name_ptr := name_length + 1; -p_ptr := str_start[ext]; -while (p_ptr < str_start[ext+1]) do - begin - name_of_file[name_ptr] := chr (str_pool[p_ptr]); - incr(name_ptr); incr(p_ptr); - end; -name_length := name_length + length(ext); -name_ptr := name_length+1; -while (name_ptr <= file_name_size) do {pad with blanks} - begin - name_of_file[name_ptr] := ' '; - incr(name_ptr); - end; -end; - - -@ -@:BibTeX capacity exceeded}{\quad file name size@> -This procedure copies the default logical area name |area| into the -array |name_of_file| starting at position 1, after shifting up the -rest of the filename. It also sets the global variable |name_length| -to the appropriate value. - -@<Procedures and functions for file-system interacting@>= -procedure add_area(@!area:str_number); -var p_ptr: pool_pointer; {running index} -begin -if (name_length + length(area) > file_name_size) then - begin - print ('File='); - print_pool_str (area); print (name_of_file,','); - file_nm_size_overflow; - end; -name_ptr := name_length; -while (name_ptr > 0) do {shift up name} - begin - name_of_file[name_ptr+length(area)] := name_of_file[name_ptr]; - decr(name_ptr); - end; -name_ptr := 1; -p_ptr := str_start[area]; -while (p_ptr < str_start[area+1]) do - begin - name_of_file[name_ptr] := chr (str_pool[p_ptr]); - incr(name_ptr); incr(p_ptr); - end; -name_length := name_length + length(area); -end; - - -@ -This system-independent procedure converts upper-case characters to -lower case for the specified part of |buf|. It is system independent -because it uses only the internal representation for characters. - -@d case_difference = "a" - "A" - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure lower_case (var buf:buf_type; @!bf_ptr,@!len:buf_pointer); -var i:buf_pointer; -begin -if (len > 0) then - for i := bf_ptr to bf_ptr+len-1 do - if ((buf[i]>="A") and (buf[i]<="Z")) then - buf[i] := buf[i] + case_difference; -end; - - -@ -This system-independent procedure is the same as the previous except -that it converts lower- to upper-case letters. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure upper_case (var buf:buf_type; @!bf_ptr,@!len:buf_pointer); -var i:buf_pointer; -begin -if (len > 0) then - for i := bf_ptr to bf_ptr+len-1 do - if ((buf[i]>="a") and (buf[i]<="z")) then - buf[i] := buf[i] - case_difference; -end; - - - -@* The hash table. -All static strings that \BibTeX\ might have to search for, generally -identifiers, are stored and retrieved by means of a fairly standard -hash-table algorithm (but slightly altered here) called the method of -``coalescing lists'' -(cf.\ Algorithm 6.4C in {\sl The Art of Computer Programming}). -Once a string enters the table, it is never removed. The actual -sequence of characters forming a string is stored in the |str_pool| -array. - -The hash table consists of the four arrays |hash_next|, |hash_text|, -|hash_ilk|, and |ilk_info|. The first array, |hash_next[p]|, points -to the next identifier belonging to the same coalesced list as the -identifier corresponding to~|p|. The second, |hash_text[p]|, points -to the |str_start| entry for |p|'s string. If position~|p| of the hash -table is empty, we have |hash_text[p]=0|; if position |p| is either -empty or the end of a coalesced hash list, we have -|hash_next[p]=empty|; an auxiliary pointer variable called |hash_used| -is maintained in such a way that all locations |p>=hash_used| are -nonempty. The third, |hash_ilk[p]|, tells how this string is used (as -ordinary text, as a variable name, as an \.{.aux} file command, etc). -The fourth, |ilk_info[p]|, contains information specific to the -corresponding |hash_ilk|---for |integer_ilk|s: the integer's value; -for |cite_ilk|s: a pointer into |cite_list|; for |lc_cite_ilk|s: a -pointer to a |cite_ilk| string; for |command_ilk|s: a constant to be -used in a |case| statement; for |bst_fn_ilk|s: function-specific -information; for |macro_ilk|s: a pointer to its definition string; for -|control_seq_ilk|s: a constant for use in a |case| statement; for all -other |ilk|s it contains no information. This |ilk|-specific -information is set in other parts of the program rather than here in -the hashing routine. - -@d hash_base = empty + 1 {lowest numbered hash-table location} -@d hash_max = hash_base + hash_size - 1 {highest numbered hash-table location} -@d hash_is_full == (hash_used=hash_base) {test if all positions are occupied} -@# -@d text_ilk = 0 {a string of ordinary text} -@d integer_ilk = 1 {an integer (possibly with a |minus_sign|)} -@d aux_command_ilk = 2 {an \.{.aux}-file command} -@d aux_file_ilk = 3 {an \.{.aux} file name} -@d bst_command_ilk = 4 {a \.{.bst}-file command} -@d bst_file_ilk = 5 {a \.{.bst} file name} -@d bib_file_ilk = 6 {a \.{.bib} file name} -@d file_ext_ilk = 7 {one of \.{.aux}, \.{.bst}, \.{.bib}, \.{.bbl}, - or \.{.blg}} -@d file_area_ilk = 8 {one of \.{texinputs:} or \.{texbib:}} -@d cite_ilk = 9 {a \.{\\citation} argument} -@d lc_cite_ilk = 10 {a \.{\\citation} argument converted to lower case} -@d bst_fn_ilk = 11 {a \.{.bst} function name} -@d bib_command_ilk = 12 {a \.{.bib}-file command} -@d macro_ilk = 13 {a \.{.bst} macro or a \.{.bib} string} -@d control_seq_ilk = 14 {a control sequence specifying a foreign character} -@d last_ilk = 14 {the same number as on the line above} - -@<Types in the outer block@>= -@!hash_loc=hash_base..hash_max; {a location within the hash table} -@!hash_pointer=empty..hash_max; {either |empty| or a |hash_loc|} -@# -@!str_ilk=0..last_ilk; {the legal string types} - - -@ -@<Globals in the outer block@>= -@!hash_next : packed array[hash_loc] of hash_pointer; {coalesced-list link} -@!hash_text : packed array[hash_loc] of str_number; {pointer to a string} -@!hash_ilk : packed array[hash_loc] of str_ilk; {the type of string} -@!ilk_info : packed array[hash_loc] of integer; {|ilk|-specific info} -@!hash_used : hash_base..hash_max+1; {allocation pointer for hash table} -@!hash_found : boolean; {set to |true| if it's already in the hash table} -@!dummy_loc : hash_loc; {receives |str_lookup| value whenever it's useless} - - -@ -@<Local variables for initialization@>= -@!k:hash_loc; - - -@ -Now it's time to initialize the hash table; note that |str_start[0]| -must be unused if |hash_text[k] := 0| is to have the desired effect. - -@<Set initial values of key variables@>= -for k:=hash_base to hash_max do - begin - hash_next[k] := empty; - hash_text[k] := 0; {thus, no need to initialize |hash_ilk| or |ilk_info|} - end; -hash_used := hash_max + 1; {nothing in table initially} - - -@ -Here is the subroutine that searches the hash table for a -(string,~|str_ilk|) pair, where the string is of length |l>=0| and -appears in |buffer[j..(j+l-1)]|. If it finds the pair, it returns the -corresponding hash-table location and sets the global variable -|hash_found| to |true|. Otherwise it sets |hash_found| to |false|, -and if the parameter |insert_it| is |true|, it inserts the pair into -the hash table, inserts the string into |str_pool| if not previously -encountered, and returns its location. Note that two different pairs -can have the same string but different |str_ilk|s, in which case the -second pair encountered, if |insert_it| were |true|, would be inserted -into the hash table though its string wouldn't be inserted into -|str_pool| because it would already be there. - -@d max_hash_value = hash_prime+hash_prime-2+127 {|h|'s maximum value} -@d do_insert == true {insert string if not found in hash table} -@d dont_insert == false {don't insert string} -@# -@d str_found = 40 {go here when you've found the string} -@d str_not_found = 45 {go here when you haven't} - -@<Procedures and functions for handling numbers, characters, and strings@>= -function str_lookup(var buf:buf_type; @!j,@!l:buf_pointer; @!ilk:str_ilk; - @!insert_it:boolean) : hash_loc; {search the hash table} -label str_found,@!str_not_found; -var h:0..max_hash_value; {hash code} -@!p:hash_loc; {index into |hash_| arrays} -@!k:buf_pointer; {index into |buf| array} -@!old_string:boolean; {set to |true| if it's an already encountered string} -@!str_num:str_number; {pointer to an already encountered string} -begin -@<Compute the hash code |h|@>; -p:=h+hash_base; {start searching here; note that |0<=h<hash_prime|} -hash_found := false; -old_string := false; -loop - begin - @<Process the string if we've already encountered it@>; - if (hash_next[p]=empty) then {location |p| may or may not be empty} - begin - if (not insert_it) then goto str_not_found; - @<Insert pair into hash table and make |p| point to it@>; - goto str_found; - end; - p:=hash_next[p]; {old and new locations |p| are not empty} - end; -str_not_found: do_nothing; {don't insert pair; function value meaningless} -str_found: str_lookup:=p; -end; - - -@ -@^for loops@> -@.WEB@> -The value of |hash_prime| should be roughly 85\% of |hash_size|, and -it should be a prime number -(it should also be less than $2^{14} + 2^{6} = 16320$ because of -\.{WEB}'s simple-macro bound). The theory of hashing tells us to expect -fewer than two table probes, on the average, when the search is -successful. - -@<Compute the hash code |h|@>= -begin -h := 0; {note that this works for zero-length strings} -k := j; -while (k < j+l) do {not a |for| loop in case |j = l = 0|} - begin - h:=h+h+buf[k]; - while (h >= hash_prime) do h:=h-hash_prime; - incr(k); - end; -end - - -@ -Here we handle the case in which we've already encountered this -string; note that even if we have, we'll still have to insert the pair -into the hash table if |str_ilk| doesn't match. - -@<Process the string if we've already encountered it@>= -begin -if (hash_text[p]>0) then {there's something here} - if (str_eq_buf(hash_text[p],buf,j,l)) then {it's the right string} - if (hash_ilk[p] = ilk) then {it's the right |str_ilk|} - begin - hash_found := true; - goto str_found; - end - else - begin {it's the wrong |str_ilk|} - old_string := true; - str_num := hash_text[p]; - end; -end - - -@ -@^for loops@> -@:BibTeX capacity exceeded}{\quad hash size@> -This code inserts the pair in the appropriate unused location. - -@<Insert pair into hash table and make |p| point to it@>= -begin -if (hash_text[p]>0) then {location |p| isn't empty} - begin - repeat if (hash_is_full) then overflow('hash size ',hash_size); - decr(hash_used); - until (hash_text[hash_used]=0); {search for an empty location} - hash_next[p]:=hash_used; - p:=hash_used; - end; {now location |p| is empty} -if (old_string) then {it's an already encountered string} - hash_text[p] := str_num - else - begin {it's a new string} - str_room(l); {make sure it'll fit in |str_pool|} - k := j; - while (k < j+l) do {not a |for| loop in case |j = l = 0|} - begin - append_char(buf[k]); - incr(k); - end; - hash_text[p] := make_string; {and make it official} - end; -hash_ilk[p] := ilk; -end - - -@ -@^string pool@> -Now that we've defined the hash-table workings we can initialize the -string pool. Unlike \TeX, \BibTeX\ does not use a |pool_file| for -string storage; instead it inserts its pre-defined strings into -|str_pool|---this makes one file fewer for the \BibTeX\ implementor -to deal with. This section initializes |str_pool|; the pre-defined -strings will be inserted into it shortly; and other strings are -inserted while processing the input files. - -@<Set initial values of key variables@>= -pool_ptr:=0; str_ptr:=1; {hash table must have |str_start[0]| unused} -str_start[str_ptr]:=pool_ptr; - - -@ -The longest pre-defined string determines type definitions used to -insert the pre-defined strings into |str_pool|. - -@d longest_pds=12 {the length of `\.{change.case\$}'} - -@<Types in the outer block@>= -@!pds_loc = 1..longest_pds; -@!pds_len = 0..longest_pds; -@!pds_type = packed array [pds_loc] of char; - - -@ -The variables in this program beginning with |s_| specify the -locations in |str_pool| for certain often-used strings. Those here -have to do with the file system; the next section will actually insert -them into |str_pool|. - -@<Globals in the outer block@>= -@!s_aux_extension : str_number; {\.{.aux}} -@!s_log_extension : str_number; {\.{.blg}} -@!s_bbl_extension : str_number; {\.{.bbl}} -@!s_bst_extension : str_number; {\.{.bst}} -@!s_bib_extension : str_number; {\.{.bib}} -@!s_bst_area : str_number; {\.{texinputs:}} -@!s_bib_area : str_number; {\.{texbib:}} - - -@ -@^important note@> -@^system dependencies@> -It's time to insert some of the pre-defined strings into |str_pool| -(and thus the hash table). These system-dependent strings should -contain no upper-case letters, and they must all be exactly -|longest_pds| characters long (even if fewer characters are actually -stored). The |pre_define| routine appears shortly. - -Important notes: These pre-definitions must not have any glitches or -the program may bomb because the |log_file| hasn't been opened yet, -and |text_ilk|s should be pre-defined later, for -\.{.bst}-function-execution purposes. - -@<Pre-define certain strings@>= -pre_define('.aux ',4,file_ext_ilk); -s_aux_extension := hash_text[pre_def_loc]; -pre_define('.bbl ',4,file_ext_ilk); -s_bbl_extension := hash_text[pre_def_loc]; -pre_define('.blg ',4,file_ext_ilk); -s_log_extension := hash_text[pre_def_loc]; -pre_define('.bst ',4,file_ext_ilk); -s_bst_extension := hash_text[pre_def_loc]; -pre_define('.bib ',4,file_ext_ilk); -s_bib_extension := hash_text[pre_def_loc]; -pre_define('texinputs: ',10,file_area_ilk); -s_bst_area := hash_text[pre_def_loc]; -pre_define('texbib: ',7,file_area_ilk); -s_bib_area := hash_text[pre_def_loc]; - - -@ -This global variable gives the hash-table location of pre-defined -strings generated by calls to |str_lookup|. - -@<Globals in the outer block@>= -@!pre_def_loc : hash_loc; - - -@ -This procedure initializes a pre-defined string of length at most -|longest_pds|. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure pre_define (@!pds:pds_type; @!len:pds_len; @!ilk:str_ilk); -var i : pds_len; -begin -for i:=1 to len do - buffer[i] := xord[pds[i]]; -pre_def_loc := str_lookup(buffer,1,len,ilk,do_insert); -end; - - -@ -These constants all begin with |n_| and are used for the |case| -statement that determines which command to execute. The variable -|command_num| is set to one of these and is used to do the branching, -but it must have the full |integer| range because at times it can -assume an arbitrary |ilk_info| value (though it will be one of the -values here when we actually use it). - -@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_bst_entry = 0 {\.{entry}} -@d n_bst_execute = 1 {\.{execute}} -@d n_bst_function = 2 {\.{function}} -@d n_bst_integers = 3 {\.{integers}} -@d n_bst_iterate = 4 {\.{iterate}} -@d n_bst_macro = 5 {\.{macro}} -@d n_bst_read = 6 {\.{read}} -@d n_bst_reverse = 7 {\.{reverse}} -@d n_bst_sort = 8 {\.{sort}} -@d n_bst_strings = 9 {\.{strings}} -@# -@d n_bib_comment = 0 {\.{comment}} -@d n_bib_preamble = 1 {\.{preamble}} -@d n_bib_string = 2 {\.{string}} - -@<Globals in the outer block@>= -@!command_num : integer; - - -@ -@^important note@> -Now we pre-define the command strings; they must all be exactly -|longest_pds| characters long. - -Important note: These pre-definitions must not have any glitches or -the program may bomb because the |log_file| hasn't been opened yet. - -@<Pre-define certain strings@>= -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('entry ',5,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_entry; -pre_define('execute ',7,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_execute; -pre_define('function ',8,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_function; -pre_define('integers ',8,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_integers; -pre_define('iterate ',7,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_iterate; -pre_define('macro ',5,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_macro; -pre_define('read ',4,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_read; -pre_define('reverse ',7,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_reverse; -pre_define('sort ',4,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_sort; -pre_define('strings ',7,bst_command_ilk); -ilk_info[pre_def_loc] := n_bst_strings; -@# -pre_define('comment ',7,bib_command_ilk); -ilk_info[pre_def_loc] := n_bib_comment; -pre_define('preamble ',8,bib_command_ilk); -ilk_info[pre_def_loc] := n_bib_preamble; -pre_define('string ',6,bib_command_ilk); -ilk_info[pre_def_loc] := n_bib_string; - - - -@* Scanning an input line. -This section describes the various |buffer| scanning routines. The -two global variables |buf_ptr1| and |buf_ptr2| are used in scanning an -input line. Between scans, |buf_ptr1| points to the first character -of the current token and |buf_ptr2| points to that of the next. The -global variable |last|, set by the function |input_ln|, marks the end -of the current line; it equals 0 at the end of the current file. All -the procedures and functions in this section will indicate an -end-of-line when it's the end of the file. - -@d token_len == (buf_ptr2 - buf_ptr1) {of the current token} -@d scan_char == buffer[buf_ptr2] {the current character} - -@<Globals in the outer block@>= -@!buf_ptr1:buf_pointer; {points to the first position of the current token} -@!buf_ptr2:buf_pointer; {used to find the end of the current token} - - -@ -These macros send the current token, in |buffer[buf_ptr1]| to -|buffer[buf_ptr2-1]|, to an output file. - -@d print_token == print_a_token {making this a procedure saves a little space} -@# -@d trace_pr_token == begin - out_token(log_file); - end - - -@ -@^system dependencies@> -And here are the associated procedures. Note: The |term_out| file is -system dependent. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure out_token (var f:alpha_file); -var i:buf_pointer; -begin -i := buf_ptr1; -while (i < buf_ptr2) do - begin - write(f,xchr[buffer[i]]); - incr(i); - end; -end; -@# -procedure print_a_token; -begin -out_token(term_out); -out_token(log_file); -end; - - -@ -This function scans the |buffer| for the next token, starting at the -global variable |buf_ptr2| and ending just before either the single -specified stop-character or the end of the current line, whichever -comes first, respectively returning |true| or |false|; afterward, -|scan_char| is the first character following this token. - -@<Procedures and functions for input scanning@>= -function scan1 (@!char1:ASCII_code) : boolean; -begin -buf_ptr1 := buf_ptr2; - {scan until end-of-line or the specified character} -while ((scan_char <> char1) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (buf_ptr2 < last) then - scan1 := true - else - scan1 := false; -end; - - -@ -This function is the same but stops at |white_space| characters as well. - -@<Procedures and functions for input scanning@>= -function scan1_white (@!char1:ASCII_code) : boolean; -begin -buf_ptr1 := buf_ptr2; - {scan until end-of-line, the specified character, or |white_space|} -while ((lex_class[scan_char] <> white_space) and (scan_char <> char1) and - (buf_ptr2 < last)) do - incr(buf_ptr2); -if (buf_ptr2 < last) then - scan1_white := true - else - scan1_white := false; -end; - - -@ -This function is similar to |scan1|, but stops at either of two -stop-characters as well as the end of the current line. - -@<Procedures and functions for input scanning@>= -function scan2 (@!char1,@!char2:ASCII_code) : boolean; -begin -buf_ptr1 := buf_ptr2; - {scan until end-of-line or the specified characters} -while ((scan_char <> char1) and (scan_char <> char2) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (buf_ptr2 < last) then - scan2 := true - else - scan2 := false; -end; - - -@ -This function is the same but stops at |white_space| characters as well. - -@<Procedures and functions for input scanning@>= -function scan2_white (@!char1,@!char2:ASCII_code) : boolean; -begin -buf_ptr1 := buf_ptr2; - {scan until end-of-line, the specified characters, or |white_space|} -while ((scan_char <> char1) and (scan_char <> char2) and - (lex_class[scan_char] <> white_space) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (buf_ptr2 < last) then - scan2_white := true - else - scan2_white := false; -end; - - -@ -This function is similar to |scan2|, but stops at either of three -stop-characters as well as the end of the current line. - -@<Procedures and functions for input scanning@>= -function scan3 (@!char1,@!char2,@!char3:ASCII_code) : boolean; -begin -buf_ptr1 := buf_ptr2; - {scan until end-of-line or the specified characters} -while ((scan_char <> char1) and (scan_char <> char2) and - (scan_char <> char3) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (buf_ptr2 < last) then - scan3 := true - else - scan3 := false; -end; - - -@ -This function scans for letters, stopping at the first nonletter; it -returns |true| if there is at least one letter. - -@<Procedures and functions for input scanning@>= -function scan_alpha : boolean; -begin -buf_ptr1 := buf_ptr2; - {scan until end-of-line or a nonletter} -while ((lex_class[scan_char] = alpha) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (token_len = 0) then - scan_alpha := false - else - scan_alpha := true; -end; - - -@ -These are the possible values for |scan_result|; they're set by the -|scan_identifier| procedure and are described in the next section. - -@d id_null = 0 -@d specified_char_adjacent = 1 -@d other_char_adjacent = 2 -@d white_adjacent = 3 - -@<Globals in the outer block@>= -@!scan_result : id_null..white_adjacent; - - -@ -This procedure scans for an identifier, stopping at the first -|illegal_id_char|, or stopping at the first character if it's -|numeric|. It sets the global variable |scan_result| to |id_null| if -the identifier is null, else to |white_adjacent| if it ended at a -|white_space| character or an end-of-line, else to -|specified_char_adjacent| if it ended at one of |char1| or |char2| or -|char3|, else to |other_char_adjacent| if it ended at a nonspecified, -non|white_space| |illegal_id_char|. By convention, when some calling -code really wants just one or two ``specified'' characters, it merely -repeats one of the characters. - -@<Procedures and functions for input scanning@>= -procedure scan_identifier (@!char1,@!char2,@!char3:ASCII_code); -begin -buf_ptr1 := buf_ptr2; -if (lex_class[scan_char] <> numeric) then - {scan until end-of-line or an |illegal_id_char|} - while ((id_class[scan_char] = legal_id_char) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (token_len = 0) then - scan_result := id_null -else if ((lex_class[scan_char] = white_space) or (buf_ptr2 = last)) then - scan_result := white_adjacent -else if ((scan_char = char1) or (scan_char = char2) or (scan_char = char3)) - then - scan_result := specified_char_adjacent -else - scan_result := other_char_adjacent; -end; - - -@ -The next two procedures scan for an integer, setting the global -variable |token_value| to the corresponding integer. - -@d char_value == (scan_char - "0") {the value of the digit being scanned} - -@<Globals in the outer block@>= -@!token_value : integer; {the numeric value of the current token} - - -@ -This function scans for a nonnegative integer, stopping at the first -nondigit; it sets the value of |token_value| accordingly. It returns -|true| if the token was a legal nonnegative integer (i.e., consisted -of one or more digits). - -@<Procedures and functions for input scanning@>= -function scan_nonneg_integer : boolean; -begin -buf_ptr1 := buf_ptr2; -token_value := 0; - {scan until end-of-line or a nondigit} -while ((lex_class[scan_char] = numeric) and (buf_ptr2 < last)) do - begin - token_value := token_value*10 + char_value; - incr(buf_ptr2); - end; -if (token_len = 0) then {there were no digits} - scan_nonneg_integer := false - else - scan_nonneg_integer := true; -end; - - -@ -This procedure scans for an integer, stopping at the first nondigit; -it sets the value of |token_value| accordingly. It returns |true| if -the token was a legal integer (i.e., consisted of an optional -|minus_sign| followed by one or more digits). - -@d negative == (sign_length = 1) {if this integer is negative} - -@<Procedures and functions for input scanning@>= -function scan_integer : boolean; -var sign_length : 0..1; {1 if there's a |minus_sign|, 0 if not} -begin -buf_ptr1 := buf_ptr2; -if (scan_char = minus_sign) then {it's a negative number} - begin - sign_length := 1; - incr(buf_ptr2); {skip over the |minus_sign|} - end - else - sign_length := 0; -token_value := 0; - {scan until end-of-line or a nondigit} -while ((lex_class[scan_char] = numeric) and (buf_ptr2 < last)) do - begin - token_value := token_value*10 + char_value; - incr(buf_ptr2); - end; -if (negative) then - token_value := -token_value; -if (token_len = sign_length) then {there were no digits} - scan_integer := false - else - scan_integer := true; -end; - - -@ -This function scans over |white_space| characters, stopping either at -the first nonwhite character or the end of the line, respectively -returning |true| or |false|. - -@<Procedures and functions for input scanning@>= -function scan_white_space : boolean; -begin - {scan until end-of-line or a nonwhite} -while ((lex_class[scan_char] = white_space) and (buf_ptr2 < last)) do - incr(buf_ptr2); -if (buf_ptr2 < last) then - scan_white_space := true - else - scan_white_space := false; -end; - - -@ -The |print_bad_input_line| procedure prints the current input line, -splitting it at the character being scanned: It prints |buffer[0]|, -|buffer[1]|, \dots, |buffer[buf_ptr2-1]| on one line and -|buffer[buf_ptr2]|, \dots, |buffer[last-1]| on the next (and both -lines start with a colon between two |space|s). Each |white_space| -character is printed as a |space|. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_bad_input_line; -var bf_ptr : buf_pointer; -begin -print (' : '); -bf_ptr := 0; -while (bf_ptr < buf_ptr2) do - begin - if (lex_class[buffer[bf_ptr]] = white_space) then - print (xchr[space]) - else - print (xchr[buffer[bf_ptr]]); - incr(bf_ptr); - end; -print_newline; -print (' : '); -bf_ptr := 0; -while (bf_ptr < buf_ptr2) do - begin - print (xchr[space]); - incr(bf_ptr); - end; -bf_ptr := buf_ptr2; -while (bf_ptr < last) do - begin - if (lex_class[buffer[bf_ptr]] = white_space) then - print (xchr[space]) - else - print (xchr[buffer[bf_ptr]]); - incr(bf_ptr); - end; -print_newline;@/ -bf_ptr := 0; -while ((bf_ptr < buf_ptr2) and (lex_class[buffer[bf_ptr]] = white_space)) do - incr(bf_ptr); -if (bf_ptr = buf_ptr2) then - print_ln ('(Error may have been on previous line)'); -mark_error; -end; - - -@ -This little procedure exists because it's used by at least two other -procedures and thus saves some space. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_skipping_whatever_remains; -begin -print ('I''m skipping whatever remains of this '); -end; - - - -@* Getting the top-level auxiliary file name. -@^system dependencies@> -These modules read the name of the top-level \.{.aux} file. Some -systems will try to find this on the command line; if it's not there -it will come from the user's terminal. In either case, the name goes -into the |char| array |name_of_file|, and the files relevant to this -name are opened. - -@d aux_found=41 {go here when the \.{.aux} name is legit} -@d aux_not_found=46 {go here when it's not} - -@<Globals in the outer block@>= -@!aux_name_length : 0..file_name_size+1; {\.{.aux} name sans extension} - - -@ -@^system dependencies@> -@^user abuse@> -I mean, this is truly disgraceful. A user has to type something in to -the terminal just once during the entire run. And it's not some -complicated string where you have to get every last punctuation mark -just right, and it's not some fancy list where you get nervous because -if you forget one item you have to type the whole thing again; it's -just a simple, ordinary, file name. Now you'd think a five-year-old -could do it; you'd think it's so simple a user should be able to do it -in his sleep. But noooooooooo. He had to sit there droning on and on -about who knows what until he exceeded the bounds of common sense, and -he probably didn't even realize it. Just pitiful. What's this world -coming to? We should probably just delete all his files and be done -with him. Note: The |term_out| file is system dependent. - -@d sam_you_made_the_file_name_too_long == begin - sam_too_long_file_name_print; - goto aux_not_found; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure sam_too_long_file_name_print; -begin -write (term_out,'File name `'); -name_ptr := 1; -while (name_ptr <= aux_name_length) do - begin - write (term_out,name_of_file[name_ptr]); - incr(name_ptr); - end; -write_ln (term_out,''' is too long'); -end; - - -@ -@^system dependencies@> -@^user abuse@> -We've abused the user enough for one section; suffice it to -say here that most of what we said last module still applies. -Note: The |term_out| file is system dependent. - -@d sam_you_made_the_file_name_wrong == begin - sam_wrong_file_name_print; - goto aux_not_found; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure sam_wrong_file_name_print; -begin -write (term_out,'I couldn''t open file name `'); -name_ptr := 1; -while (name_ptr <= name_length) do - begin - write (term_out,name_of_file[name_ptr]); - incr(name_ptr); - end; -write_ln (term_out,''''); -end; - - -@ -@^system dependencies@> -This procedure consists of a loop that reads and processes a (nonnull) -\.{.aux} file name. It's this module and the next two that must be -changed on those systems using command-line arguments. Note: The -|term_out| and |term_in| files are system dependent. - -@<Procedures and functions for the reading and processing of input files@>= -procedure get_the_top_level_aux_file_name; -label aux_found,@!aux_not_found; -var @<Variables for possible command-line processing@>@/ -begin -check_cmnd_line := false; {many systems will change this} -loop - begin - if (check_cmnd_line) then - @<Process a possible command line@> - else - begin - write (term_out,'Please type input file name (no extension)--'); - if (eoln(term_in)) then {so the first |read| works} - read_ln (term_in); - aux_name_length := 0; - while (not eoln(term_in)) do - begin - if (aux_name_length = file_name_size) then - begin - while (not eoln(term_in)) do {discard the rest of the line} - get(term_in); - sam_you_made_the_file_name_too_long; - end; - incr(aux_name_length); - name_of_file[aux_name_length] := term_in^; - get(term_in); - end; - end; - @<Handle this \.{.aux} name@>; -aux_not_found: - check_cmnd_line := false; - end; -aux_found: {now we're ready to read the \.{.aux} file} -end; - - -@ -@^system dependencies@> -The switch |check_cmnd_line| tells us whether we're to check for a -possible command-line argument. - -@<Variables for possible command-line processing@>= -@!check_cmnd_line : boolean; {|true| if we're to check the command line} - - -@ -@^system dependencies@> -Here's where we do the real command-line work. Those systems needing -more than a single module to handle the task should add the extras to -the ``System-dependent changes'' section. - -@<Process a possible command line@>= -begin -do_nothing; {the ``default system'' doesn't use the command line} -end - - -@ -Here we orchestrate this \.{.aux} name's handling: we add the various -extensions, try to open the files with the resulting name, and -store the name strings we'll need later. - -@<Handle this \.{.aux} name@>= -begin -if ((aux_name_length + length(s_aux_extension) > file_name_size) or@| - (aux_name_length + length(s_log_extension) > file_name_size) or@| - (aux_name_length + length(s_bbl_extension) > file_name_size)) then - sam_you_made_the_file_name_too_long; -@<Add extensions and open files@>; -@<Put this name into the hash table@>; -goto aux_found; -end - - -@ -Here we set up definitions and declarations for files opened in this -section. Each element in |aux_list| (except for -|aux_list[aux_stack_size]|, which is always unused) is a pointer to -the appropriate |str_pool| string representing the \.{.aux} file name. -The array |aux_file| contains the corresponding \PASCAL\ |file| -variables. - -@d cur_aux_str == aux_list[aux_ptr] {shorthand for the current \.{.aux} file} -@d cur_aux_file == aux_file[aux_ptr] {shorthand for the current |aux_file|} -@d cur_aux_line == aux_ln_stack[aux_ptr] {line number of current \.{.aux} file} - -@<Globals in the outer block@>= -@!aux_file : array[aux_number] of alpha_file; {open \.{.aux} |file| variables} -@!aux_list : array[aux_number] of str_number; {the open \.{.aux} file list} -@!aux_ptr : aux_number; {points to the currently open \.{.aux} file} -@!aux_ln_stack : array[aux_number] of integer; {open \.{.aux} line numbers} -@# -@!top_lev_str : str_number; {the top-level \.{.aux} file's name} -@# -@!log_file : alpha_file; {the |file| variable for the \.{.blg} file} -@!bbl_file : alpha_file; {the |file| variable for the \.{.bbl} file} - - -@ -Where |aux_number| is the obvious. - -@<Types in the outer block@>= -@!aux_number = 0..aux_stack_size; {gives the |aux_list| range} - - -@ -@^system dependencies@> -We must make sure the (top-level) \.{.aux}, \.{.blg}, and \.{.bbl} -files can be opened. - -@<Add extensions and open files@>= -begin -name_length := aux_name_length; {set to last used position} -add_extension (s_aux_extension); {this also sets |name_length|} -aux_ptr := 0; {initialize the \.{.aux} file stack} -if (not a_open_in(cur_aux_file)) then - sam_you_made_the_file_name_wrong; -@# -name_length := aux_name_length; -add_extension (s_log_extension); {this also sets |name_length|} -if (not a_open_out(log_file)) then - sam_you_made_the_file_name_wrong; -@# -name_length := aux_name_length; -add_extension (s_bbl_extension); {this also sets |name_length|} -if (not a_open_out(bbl_file)) then - sam_you_made_the_file_name_wrong; -end - - -@ -@:this can't happen}{\quad Already encountered auxiliary file@> -This code puts the \.{.aux} file name, both with and without the -extension, into the hash table, and it initializes |aux_list|. Note -that all previous top-level \.{.aux}-file stuff must have been -successful. - -@<Put this name into the hash table@>= -begin -name_length := aux_name_length; -add_extension (s_aux_extension); {this also sets |name_length|} -name_ptr := 1; -while (name_ptr <= name_length) do - begin - buffer[name_ptr] := xord[name_of_file[name_ptr]]; - incr(name_ptr); - end; -top_lev_str := hash_text[ - str_lookup(buffer,1,aux_name_length,text_ilk,do_insert)]; -cur_aux_str := hash_text[ - str_lookup(buffer,1,name_length,aux_file_ilk,do_insert)]; - {note that this has initialized |aux_list|} -if (hash_found) then - begin - trace - print_aux_name; - ecart@/ - confusion ('Already encountered auxiliary file'); - end; -cur_aux_line := 0; {this finishes initializing the top-level \.{.aux} file} -end - - -@ -Print the name of the current \.{.aux} file, followed by a |newline|. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_aux_name; -begin -print_pool_str (cur_aux_str); -print_newline; -end; - - - -@* Reading the auxiliary file(s). -@^auxiliary-file commands@> -Now it's time to read the \.{.aux} file. The only commands we handle -are \.{\\citation} (there can be arbitrarily many, each having -arbitrarily many arguments), \.{\\bibdata} (there can be just one, but -it can have arbitrarily many arguments), \.{\\bibstyle} (there can be -just one, and it can have just one argument), and \.{\\@@input} (there -can be arbitrarily many, each with one argument, and they can be -nested to a depth of |aux_stack_size|). Each of these commands is -assumed to be on just a single line. The rest of the \.{.aux} file is -ignored. - -@d aux_done=31 {go here when finished with the \.{.aux} files} - -@<Labels in the outer block@>= -,@!aux_done - - -@ -We keep reading and processing input lines until none left. This is -part of the main program; hence, because of the |aux_done| label, -there's no conventional |begin|-|end| pair surrounding the entire -module. - -@<Read the \.{.aux} file@>= -print ('The top-level auxiliary file: '); -print_aux_name; -loop - begin {|pop_the_aux_stack| will exit the loop} - incr(cur_aux_line); - if (not input_ln(cur_aux_file)) then {end of current \.{.aux} file} - pop_the_aux_stack - else - get_aux_command_and_process; - end; - trace - trace_pr_ln ('Finished reading the auxiliary file(s)'); - ecart@/ -aux_done: -last_check_for_aux_errors; - - -@ -When we find a bug, we print a message and flush the rest of the line. -This macro must be called from within a procedure that has an |exit| -label. - -@d aux_err_return == begin - aux_err_print; - return; {flush this input line} - end - -@d aux_err(#) == begin - print (#); - aux_err_return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure aux_err_print; -begin -print ('---line ',cur_aux_line:0,' of file '); -print_aux_name;@/ -print_bad_input_line; {this call does the |mark_error|} -print_skipping_whatever_remains; -print_ln ('command') -end; - - -@ -@:this can't happen}{\quad Illegal auxiliary-file command@> -Here are a bunch of macros whose print statements are used at least -twice. Thus we save space by making the statements procedures. This -macro complains when there's a repeated command that's to be used just -once. - -@d aux_err_illegal_another(#) == begin - aux_err_illegal_another_print (#); - aux_err_return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure aux_err_illegal_another_print (@!cmd_num : integer); -begin -print ('Illegal, another \bib'); -case (cmd_num) of - n_aux_bibdata : print ('data'); - n_aux_bibstyle : print ('style'); - othercases - confusion ('Illegal auxiliary-file command') -endcases; -print (' command'); -end; - - -@ -This one complains when a command is missing its |right_brace|. - -@d aux_err_no_right_brace == begin - aux_err_no_right_brace_print; - aux_err_return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure aux_err_no_right_brace_print; -begin -print ('No "',xchr[right_brace],'"'); -end; - - -@ -This one complains when a command has stuff after its |right_brace|. - -@d aux_err_stuff_after_right_brace == begin - aux_err_stuff_after_right_brace_print; - aux_err_return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure aux_err_stuff_after_right_brace_print; -begin -print ('Stuff after "',xchr[right_brace],'"'); -end; - - -@ -And this one complains when a command has |white_space| in its -argument. - -@d aux_err_white_space_in_argument == begin - aux_err_white_space_in_argument_print; - aux_err_return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure aux_err_white_space_in_argument_print; -begin -print ('White space in argument'); -end; - - -@ -@^auxiliary-file commands@> -@:this can't happen}{\quad Unknown auxiliary-file command@> -We're not at the end of an \.{.aux} file, so we see if the current -line might be a command of interest. A command of interest will be a -line without blanks, consisting of a command name, a |left_brace|, one -or more arguments separated by commas, and a |right_brace|. - -@<Scan for and process an \.{.aux} command@>= -procedure get_aux_command_and_process; -label exit; -begin -buf_ptr2 := 0; {mark the beginning of the next token} -if (not scan1(left_brace)) then {no |left_brace|---flush line} - return; -command_num := ilk_info[ - str_lookup(buffer,buf_ptr1,token_len,aux_command_ilk,dont_insert)]; -if (hash_found) then - 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; - othercases - confusion ('Unknown auxiliary-file command') - endcases; -exit: -end; - - -@ -Here we introduce some variables for processing a \.{\\bibdata} -command. Each element in |bib_list| (except for -|bib_list[max_bib_files]|, which is always unused) is a pointer to the -appropriate |str_pool| string representing the \.{.bib} file name. -The array |bib_file| contains the corresponding \PASCAL\ |file| -variables. - -@d cur_bib_str == bib_list[bib_ptr] {shorthand for current \.{.bib} file} -@d cur_bib_file == bib_file[bib_ptr] {shorthand for current |bib_file|} - -@<Globals in the outer block@>= -@!bib_list : array[bib_number] of str_number; {the \.{.bib} file list} -@!bib_ptr : bib_number; {pointer for the current \.{.bib} file} -@!num_bib_files : bib_number; {the total number of \.{.bib} files} -@!bib_seen : boolean; {|true| if we've already seen a \.{\\bibdata} command} -@!bib_file : array[bib_number] of alpha_file; {corresponding |file| variables} - - -@ -Where |bib_number| is the obvious. - -@<Types in the outer block@>= -@!bib_number = 0..max_bib_files; {gives the |bib_list| range} - - -@ -@<Set initial values of key variables@>= -bib_ptr := 0; {this makes |bib_list| empty} -bib_seen := false; {we haven't seen a \.{\\bibdata} command yet} - - -@ -@:auxiliary-file commands}{\quad \.{\\bibdata}@> -A \.{\\bibdata} command will have its arguments between braces and -separated by commas. There must be exactly one such command in the -\.{.aux} file(s). All upper-case letters are converted to lower case. - -@<Procedures and functions for the reading and processing of input files@>= -procedure aux_bib_data_command; -label exit; -begin -if (bib_seen) then - aux_err_illegal_another (n_aux_bibdata); -bib_seen := true; {now we've seen a \.{\\bibdata} command} -while (scan_char <> right_brace) do - begin - incr(buf_ptr2); {skip over the previous stop-character} - if (not scan2_white(right_brace,comma)) then - aux_err_no_right_brace; - if (lex_class[scan_char] = white_space) then - aux_err_white_space_in_argument; - if ((last > buf_ptr2+1) and (scan_char = right_brace)) then - aux_err_stuff_after_right_brace; - @<Open a \.{.bib} file@>; - end; -exit: -end; - - -@ -Here's a procedure we'll need shortly. It prints the name of the -current \.{.bib} file, followed by a |newline|. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_bib_name; -begin -print_pool_str (cur_bib_str); -print_pool_str (s_bib_extension); -print_newline; -end; - - -@ -This macro is similar to |aux_err| but it complains specifically about -opening a file for a \.{\\bibdata} command. - -@d open_bibdata_aux_err(#) == begin - print (#); - print_bib_name; - aux_err_return; {this does the |mark_error|} - end - - -@ -@:BibTeX capacity exceeded}{\quad number of \.{.bib} files@> -Now we add the just-found argument to |bib_list| if it hasn't already -been encountered as a \.{\\bibdata} argument and if, after appending -the |s_bib_extension| string, the resulting file name can be opened. - -@<Open a \.{.bib} file@>= -begin -if (bib_ptr = max_bib_files) then - overflow('number of database files ',max_bib_files); -cur_bib_str := hash_text[ - str_lookup(buffer,buf_ptr1,token_len,bib_file_ilk,do_insert)]; -if (hash_found) then {already encountered this as a \.{\\bibdata} argument} - open_bibdata_aux_err ('This database file appears more than once: '); -start_name (cur_bib_str); -add_extension (s_bib_extension); -if (not a_open_in(cur_bib_file)) then - begin - add_area (s_bib_area); - if (not a_open_in(cur_bib_file)) then - open_bibdata_aux_err ('I couldn''t open database file '); - end; - trace - trace_pr_pool_str (cur_bib_str); - trace_pr_pool_str (s_bib_extension); - trace_pr_ln (' is a bibdata file'); - ecart@/ -incr(bib_ptr); -end - - -@ -Here we introduce some variables for processing a \.{\\bibstyle} -command. - -@<Globals in the outer block@>= -@!bst_seen : boolean; {|true| if we've already seen a \.{\\bibstyle} command} -@!bst_str : str_number; {the string number for the \.{.bst} file} -@!bst_file : alpha_file; {the corresponding |file| variable} - - -@ -And we initialize. - -@<Set initial values of key variables@>= -bst_str := 0; {mark |bst_str| as unused} -bst_seen := false; {we haven't seen a \.{\\bibstyle} command yet} - - -@ -@:auxiliary-file commands}{\quad \.{\\bibstyle}@> -A \.{\\bibstyle} command will have exactly one argument, and it will -be between braces. There must be exactly one such command in the -\.{.aux} file(s). All upper-case letters are converted to lower case. - -@<Procedures and functions for the reading and processing of input files@>= -procedure aux_bib_style_command; -label exit; -begin -if (bst_seen) then - aux_err_illegal_another (n_aux_bibstyle); -bst_seen := true; {now we've seen a \.{\\bibstyle} command} -incr(buf_ptr2); {skip over the |left_brace|} -if (not scan1_white(right_brace)) then - aux_err_no_right_brace; -if (lex_class[scan_char] = white_space) then - aux_err_white_space_in_argument; -if (last > buf_ptr2+1) then - aux_err_stuff_after_right_brace; -@<Open the \.{.bst} file@>; -exit: -end; - - -@ -@:this can't happen}{\quad Already encountered style file@> -Now we open the file whose name is the just-found argument appended -with the |s_bst_extension| string, if possible. - -@<Open the \.{.bst} file@>= -begin -bst_str := hash_text[ - str_lookup(buffer,buf_ptr1,token_len,bst_file_ilk,do_insert)]; -if (hash_found) then - begin - trace - print_bst_name; - ecart@/ - confusion ('Already encountered style file'); - end; -start_name (bst_str); -add_extension (s_bst_extension); -if (not a_open_in(bst_file)) then - begin - add_area (s_bst_area); - if (not a_open_in(bst_file)) then - begin - print ('I couldn''t open style file '); - print_bst_name;@/ - bst_str := 0; {mark as unused again} - aux_err_return; - end; - end; -print ('The style file: '); -print_bst_name; -end - - -@ -Print the name of the \.{.bst} file, followed by a |newline|. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_bst_name; -begin -print_pool_str (bst_str); -print_pool_str (s_bst_extension); -print_newline; -end; - - -@ -Here we introduce some variables for processing a \.{\\citation} -command. Each element in |cite_list| (except for -|cite_list[max_cites]|, which is always unused) is a pointer to the -appropriate |str_pool| string. The cite-key list is kept in order of -occurrence with duplicates removed. - -@d cur_cite_str == cite_list[cite_ptr] {shorthand for the current cite key} - -@<Globals in the outer block@>= -@!cite_list : packed array[cite_number] of str_number; {the cite-key list} -@!cite_ptr : cite_number; {pointer for the current cite key} -@!entry_cite_ptr : cite_number; {cite pointer for the current entry} -@!num_cites : cite_number; {the total number of distinct cite keys} -@!old_num_cites : cite_number; {set to a previous |num_cites| value} -@!citation_seen : boolean; {|true| if we've seen a \.{\\citation} command} -@!cite_loc : hash_loc; {the hash-table location of a cite key} -@!lc_cite_loc : hash_loc; {and of its lower-case equivalent} -@!lc_xcite_loc : hash_loc; {a second |lc_cite_loc| variable} -@!cite_found : boolean; {|true| if we've already seen this cite key} -@!all_entries : boolean; {|true| if we're to use the entire database} -@!all_marker : cite_number; {we put the other entries in |cite_list| here} - - -@ -Where |cite_number| is the obvious. - -@<Types in the outer block@>= -@!cite_number = 0..max_cites; {gives the |cite_list| range} - - -@ -@<Set initial values of key variables@>= -cite_ptr := 0; {this makes |cite_list| empty} -citation_seen := false; {we haven't seen a \.{\\citation} command yet} -all_entries := false; {by default, use just the entries explicitly named} - - -@ -@^case mismatch@> -@^entire database inclusion@> -@^whole database inclusion@> -@:LaTeX}{\LaTeX@> -@:auxiliary-file commands}{\quad \.{\\citation}@> -A \.{\\citation} command will have its arguments between braces and -separated by commas. Upper/lower cases are considered to be different -for \.{\\citation} arguments, which is the same as the rest of \LaTeX\ -but different from the rest of \BibTeX. A cite key needn't exactly -case-match its corresponding database key to work, although two cite -keys that are case-mismatched will produce an error message. -(A {\sl case mismatch\/} is a mismatch, but only because of a case -difference.) - -A \.{\\citation} command having \.{*} as an argument indicates that -the entire database will be included (almost as if a \.{\\nocite} -command that listed every cite key in the database, in order, had been -given at the corresponding spot in the \.{.tex} file). - -@d next_cite = 23 {read the next argument} - -@<Procedures and functions for the reading and processing of input files@>= -procedure aux_citation_command; -label next_cite,@!exit; -begin -citation_seen := true; {now we've seen a \.{\\citation} command} -while (scan_char <> right_brace) do - begin - incr(buf_ptr2); {skip over the previous stop-character} - if (not scan2_white(right_brace,comma)) then - aux_err_no_right_brace; - if (lex_class[scan_char] = white_space) then - aux_err_white_space_in_argument; - if ((last > buf_ptr2+1) and (scan_char = right_brace)) then - aux_err_stuff_after_right_brace; - @<Check the cite key@>; -next_cite: - end; -exit: -end; - - -@ -@^kludge@> -We must check if (the lower-case version of) this cite key has been -previously encountered, and proceed accordingly. The alias kludge -helps make the stack space not overflow on some machines. - -@d ex_buf1== ex_buf {an alias, used only in this module} - -@<Check the cite key@>= -begin - trace - trace_pr_token; - trace_pr (' cite key encountered'); - ecart@/ -@<Check for entire database inclusion (and thus skip this cite key)@>; -tmp_ptr := buf_ptr1; -while (tmp_ptr < buf_ptr2) do - begin - ex_buf1[tmp_ptr] := buffer[tmp_ptr]; - incr(tmp_ptr); - end; -lower_case (ex_buf1, buf_ptr1, token_len); {convert to `canonical' form} -lc_cite_loc := str_lookup(ex_buf1,buf_ptr1,token_len,lc_cite_ilk,do_insert); -if (hash_found) then {already encountered this as a \.{\\citation} argument} - @<Cite seen, don't add a cite key@> - else - @<Cite unseen, add a cite key@>; - {it's a new cite key---add it to |cite_list|} -end - - -@ -Here we check for a \.{\\citation} command having \.{*} as an -argument, indicating that the entire database will be included. - -@<Check for entire database inclusion (and thus skip this cite key)@>= -begin -if (token_len = 1) then - if (buffer[buf_ptr1] = star) then - begin - trace - trace_pr_ln ('---entire database to be included'); - ecart@/ - if (all_entries) then - begin - print_ln ('Multiple inclusions of entire database'); - aux_err_return; - end - else - begin - all_entries := true; - all_marker := cite_ptr; - goto next_cite; - end; - end; -end - - -@ -@^case mismatch errors@> -We've previously encountered the lower-case version, so we check that -the actual version exactly matches the actual version of the -previously-encountered cite key(s). - -@<Cite seen, don't add a cite key@>= -begin - trace - trace_pr_ln (' previously'); - ecart@/ -dummy_loc := str_lookup(buffer,buf_ptr1,token_len,cite_ilk,dont_insert); -if (not hash_found) then {case mismatch error} - begin - print ('Case mismatch error between cite keys '); - print_token; - print (' and '); - print_pool_str (cite_list[ilk_info[ilk_info[lc_cite_loc]]]); - print_newline; - aux_err_return; - end; -end - - -@ -@:this can't happen}{\quad Cite hash error@> -Now we add the just-found argument to |cite_list| if there isn't -anything funny happening. - -@<Cite unseen, add a cite key@>= -begin - trace - trace_pr_newline; - ecart@/ -cite_loc := str_lookup(buffer,buf_ptr1,token_len,cite_ilk,do_insert); -if (hash_found) then - hash_cite_confusion; -check_cite_overflow (cite_ptr); -cur_cite_str := hash_text[cite_loc]; -ilk_info[cite_loc] := cite_ptr; -ilk_info[lc_cite_loc] := cite_loc; -incr(cite_ptr); -end - - -@ -@:this can't happen}{\quad Cite hash error@> -Here's a serious complaint (that is, a bug) concerning hash problems. -This is the first of several similar bug-procedures that exist only -because they save space. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure hash_cite_confusion; -begin -confusion ('Cite hash error'); -end; - - -@ -@^fetish@> -@:BibTeX capacity exceeded}{\quad number of cite keys@> -Complain if somebody's got a cite fetish. This procedure is called -when were about to add another cite key to |cite_list|. It assumes -that |cite_loc| gives the potential cite key's hash table location. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure check_cite_overflow (@!last_cite : cite_number); -begin -if (last_cite = max_cites) then - begin - print_pool_str (hash_text[cite_loc]); - print_ln (' is the key:'); - overflow('number of cite keys ',max_cites); - end; -end; - - -@ -@:auxiliary-file commands}{\quad \.{\\\AT!input}@> -An \.{\\@@input} command will have exactly one argument, it will -be between braces, and it must have the |s_aux_extension|. -All upper-case letters are converted to lower case. - -@<Procedures and functions for the reading and processing of input files@>= -procedure aux_input_command; -label exit; -var aux_extension_ok : boolean; {to check for a correct file extension} -begin -incr(buf_ptr2); {skip over the |left_brace|} -if (not scan1_white(right_brace)) then - aux_err_no_right_brace; -if (lex_class[scan_char] = white_space) then - aux_err_white_space_in_argument; -if (last > buf_ptr2+1) then - aux_err_stuff_after_right_brace; -@<Push the \.{.aux} stack@>; -exit: -end; - - -@ -@:BibTeX capacity exceeded}{\quad number of \.{.aux} files@> -We must check that this potential \.{.aux} file won't overflow the -stack, that it has the correct extension, that we haven't encountered -it before (to prevent, among other things, an infinite loop). - -@<Push the \.{.aux} stack@>= -begin -incr(aux_ptr); -if (aux_ptr = aux_stack_size) then - begin - print_token; print (': '); - overflow('auxiliary file depth ',aux_stack_size); - end; -aux_extension_ok := true; -if (token_len < length(s_aux_extension)) then@/ - aux_extension_ok := false {else |str_eq_buf| might bomb the program} -else if (not str_eq_buf(s_aux_extension, buffer, - buf_ptr2-length(s_aux_extension), length(s_aux_extension))) then - aux_extension_ok := false; -if (not aux_extension_ok) then - begin - print_token; - print (' has a wrong extension'); - decr(aux_ptr); - aux_err_return; - end; -cur_aux_str := hash_text[ - str_lookup(buffer,buf_ptr1,token_len,aux_file_ilk,do_insert)]; -if (hash_found) then - begin - print ('Already encountered file '); - print_aux_name; - decr(aux_ptr); - aux_err_return; - end; -@<Open this \.{.aux} file@>; -end - - -@ -We check that this \.{.aux} file can actually be opened, and then open it. - -@<Open this \.{.aux} file@>= -begin -start_name (cur_aux_str); {extension already there for \.{.aux} files} -name_ptr := name_length+1; -while (name_ptr <= file_name_size) do {pad with blanks} - begin - name_of_file[name_ptr] := ' '; - incr(name_ptr); - end; -if (not a_open_in(cur_aux_file)) then - begin - print ('I couldn''t open auxiliary file '); - print_aux_name; - decr(aux_ptr); - aux_err_return; - end; -print ('A level-',aux_ptr:0,' auxiliary file: '); -print_aux_name; -cur_aux_line := 0; -end - - -@ -Here we close the current-level \.{.aux} file and go back up a level, -if possible, by decrementing |aux_ptr|. - -@<Procedures and functions for the reading and processing of input files@>= -procedure pop_the_aux_stack; -begin -a_close (cur_aux_file); -if (aux_ptr=0) then - goto aux_done - else - decr(aux_ptr); -end; - - -@ -@^gymnastics@> -That's it for processing \.{.aux} commands, except for finishing the -procedural gymnastics. - -@<Procedures and functions for the reading and processing of input files@>= -@<Scan for and process an \.{.aux} command@> - - -@ -We must complain if anything's amiss. - -@d aux_end_err(#) == begin - aux_end1_err_print; - print (#); - aux_end2_err_print; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure aux_end1_err_print; -begin -print ('I found no '); -end; -@# -procedure aux_end2_err_print; -begin -print ('---while reading file '); -print_aux_name; -mark_error; -end; - - -@ -Before proceeding, we see if we have any complaints. - -@<Procedures and functions for the reading and processing of input files@>= -procedure last_check_for_aux_errors; -begin -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 ('\citation commands') - else if ((num_cites = 0) and (not all_entries)) then - aux_end_err ('cite keys'); -if (not bib_seen) then - aux_end_err ('\bibdata command') - else if (num_bib_files = 0) then - aux_end_err ('database files'); -if (not bst_seen) then - aux_end_err ('\bibstyle command') - else if (bst_str = 0) then - aux_end_err ('style file'); -end; - - - -@* Reading the style file. -This part of the program reads the \.{.bst} file, which consists of a -sequence of commands. Each \.{.bst} command consists of a name (for -which case differences are ignored) followed by zero or more -arguments, each enclosed in braces. - -@d bst_done=32 {go here when finished with the \.{.bst} file} -@d no_bst_file=9932 {go here when skipping the \.{.bst} file} - -@<Labels in the outer block@>= -,@!bst_done,@!no_bst_file - - -@ -The |bbl_line_num| gets initialized along with the |bst_line_num|, so -it's declared here too. - -@<Globals in the outer block@>= -@!bbl_line_num : integer; {line number of the \.{.bbl} (output) file} -@!bst_line_num : integer; {line number of the \.{.bst} file} - - -@ -This little procedure exists because it's used by at least two other -procedures and thus saves some space. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_ln_num_print; -begin -print ('--line ',bst_line_num:0,' of file '); -print_bst_name; -end; - - -@ -When there's a serious error parsing the \.{.bst} file, we flush the -rest of the current command; a blank line is assumed to mark the end -of a command (but for the purposes of error recovery only). Thus, -error recovery will be better if style designers leave blank lines -between \.{.bst} commands. This macro must be called from within a -procedure that has an |exit| label. - -@d bst_err_print_and_look_for_blank_line_return == - begin - bst_err_print_and_look_for_blank_line; - return; - end - -@d bst_err(#) == begin {serious error during \.{.bst} parsing} - print (#); - bst_err_print_and_look_for_blank_line_return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_err_print_and_look_for_blank_line; -begin -print ('-'); -bst_ln_num_print; -print_bad_input_line; {this call does the |mark_error|} -while (last <> 0) do {look for a blank input line} - if (not input_ln(bst_file)) then {or the end of the file} - goto bst_done - else - incr(bst_line_num); -buf_ptr2 := last; {to input the next line} -end; - - -@ -When there's a harmless error parsing the \.{.bst} file (harmless -syntactically, at least) we give just a |warning_message|. - -@d bst_warn(#) == begin {non-serious error during \.{.bst} parsing} - print (#); - bst_warn_print; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_warn_print; -begin -bst_ln_num_print; -mark_warning; -end; - - -@ -Here's the outer loop for reading the \.{.bst} file---it keeps reading -and processing \.{.bst} commands until none left. This is part of the -main program; hence, because of the |bst_done| label, there's no -conventional |begin|-|end| pair surrounding the entire module. - -@<Read and execute the \.{.bst} file@>= -if (bst_str = 0) then {there's no \.{.bst} file to read} - goto no_bst_file; {this is a |goto| so that |bst_done| is not in a block} -bst_line_num := 0; {initialize things} -bbl_line_num := 1; {best spot to initialize the output line number} -buf_ptr2 := last; {to get the first input line} -loop - begin - if (not eat_bst_white_space) then {the end of the \.{.bst} file} - goto bst_done; - get_bst_command_and_process; - end; -bst_done: a_close (bst_file); -no_bst_file: a_close (bbl_file); - - -@ -This \.{.bst}-specific scanning function skips over |white_space| -characters (and comments) until hitting a nonwhite character or the -end of the file, respectively returning |true| or |false|. It also -updates |bst_line_num|, the line counter. - -@<Procedures and functions for input scanning@>= -function eat_bst_white_space : boolean; -label exit; -begin -loop - begin - if (scan_white_space) then {hit a nonwhite character on this line} - if (scan_char <> comment) then {it's not a comment character; return} - begin - eat_bst_white_space := true; - return; - end; - if (not input_ln(bst_file)) then {end-of-file; return |false|} - begin - eat_bst_white_space := false; - return; - end; - incr(bst_line_num); - buf_ptr2 := 0; - end; -exit: -end; - - -@ -It's often illegal to end a \.{.bst} command in certain places, and -this is where we come to check. - -@d eat_bst_white_and_eof_check(#) == - begin - if (not eat_bst_white_space) then - begin - eat_bst_print; - bst_err (#); - end; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure eat_bst_print; -begin -print ('Illegal end of style file in command: '); -end; - - -@ -We must attend to a few details before getting to work on this -\.{.bst} command. - -@<Scan for and process a \.{.bst} command@>= -procedure get_bst_command_and_process; -label exit; -begin -if (not scan_alpha) then - bst_err ('"',xchr[scan_char],'" can''t start a style-file command'); -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -command_num := ilk_info[ - str_lookup(buffer,buf_ptr1,token_len,bst_command_ilk,dont_insert)]; -if (not hash_found) then - begin - print_token; - bst_err (' is an illegal style-file command'); - end; -@<Process the appropriate \.{.bst} command@>; -exit: -end; - - -@ -@^style-file commands@> -@:this can't happen}{\quad Unknown style-file command@> -Here we determine which \.{.bst} command we're about to process, and -then go to it. - -@<Process the appropriate \.{.bst} command@>= -case (command_num) of - n_bst_entry : bst_entry_command; - n_bst_execute : bst_execute_command; - n_bst_function : bst_function_command; - n_bst_integers : bst_integers_command; - n_bst_iterate : bst_iterate_command; - n_bst_macro : bst_macro_command; - n_bst_read : bst_read_command; - n_bst_reverse : bst_reverse_command; - n_bst_sort : bst_sort_command; - n_bst_strings : bst_strings_command; - othercases confusion ('Unknown style-file command') -endcases - - -@ -We need data structures for the function definitions, the entry -variables, the global variables, and the actual entries corresponding -to the cite-key list. First we define the classes of `function's -used. Functions in all classes are of |bst_fn_ilk| except for -|int_literal|s, which are of |integer_ilk|; and |str_literal|s, which -are of |text_ilk|. - -@d built_in = 0 {the `primitive' functions} -@d wiz_defined = 1 {defined in the \.{.bst} file} -@d int_literal = 2 {integer `constants'} -@d str_literal = 3 {string `constants'} -@d field = 4 {things like `author' and `title'} -@d int_entry_var = 5 {integer entry variable} -@d str_entry_var = 6 {string entry variable} -@d int_global_var = 7 {integer global variable} -@d str_global_var = 8 {string global variable} -@d last_fn_class = 8 {the same number as on the line above} - - -@ -@:this can't happen}{\quad Unknown function class@> -Here's another bug report. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure unknwn_function_class_confusion; -begin -confusion ('Unknown function class'); -end; - - -@ -@:this can't happen}{\quad Unknown function class@> -Occasionally we'll want to |print| the name of one of these function -classes. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_fn_class (@!fn_loc : hash_loc); -begin -case (fn_type[fn_loc]) of - built_in : print ('built-in'); - wiz_defined : print ('wizard-defined'); - int_literal : print ('integer-literal'); - str_literal : print ('string-literal'); - field : print ('field'); - int_entry_var : print ('integer-entry-variable'); - str_entry_var : print ('string-entry-variable'); - int_global_var : print ('integer-global-variable'); - str_global_var : print ('string-global-variable'); - othercases unknwn_function_class_confusion -endcases; -end; - - -@ -@:this can't happen}{\quad Unknown function class@> -This version is for printing when in |trace| mode. - -@<Procedures and functions for all file I/O, error messages, and such@>= - trace - procedure trace_pr_fn_class (@!fn_loc : hash_loc); - begin - case (fn_type[fn_loc]) of - built_in : trace_pr ('built-in'); - wiz_defined : trace_pr ('wizard-defined'); - int_literal : trace_pr ('integer-literal'); - str_literal : trace_pr ('string-literal'); - field : trace_pr ('field'); - int_entry_var : trace_pr ('integer-entry-variable'); - str_entry_var : trace_pr ('string-entry-variable'); - int_global_var : trace_pr ('integer-global-variable'); - str_global_var : trace_pr ('string-global-variable'); - othercases unknwn_function_class_confusion - endcases; - end; - ecart - - -@ -Besides the function classes, we have types based on \BibTeX's -capacity limitations and one based on what can go into the array -|wiz_functions| explained below. - -@d quote_next_fn = hash_base - 1 {special marker used in defining functions} -@d end_of_def = hash_max + 1 {another such special marker} - -@<Types in the outer block@>= -@!fn_class = 0..last_fn_class; {the \.{.bst} function classes} -@!wiz_fn_loc = 0..wiz_fn_space; {|wiz_defined|-function storage locations} -@!int_ent_loc = 0..max_ent_ints; {|int_entry_var| storage locations} -@!str_ent_loc = 0..max_ent_strs; {|str_entry_var| storage locations} -@!str_glob_loc = 0..max_glb_str_minus_1; {|str_global_var| storage locations} -@!field_loc = 0..max_fields; {individual field storage locations} -@!hash_ptr2 = quote_next_fn..end_of_def; {a special marker or a |hash_loc|} - - -@ -@^save space@> -@^space savings@> -@^system dependencies@> -We store information about the \.{.bst} functions in arrays the same -size as the hash-table arrays and in locations corresponding to their -hash-table locations. The two arrays |fn_info| (an alias of -|ilk_info| described earlier) and |fn_type| accomplish this: |fn_type| -specifies one of the above classes, and |fn_info| gives information -dependent on the class. - -Six other arrays give the contents of functions: The array -|wiz_functions| holds definitions for |wiz_defined| functions---each -such function consists of a sequence of pointers to hash-table -locations of other functions (with the two special-marker exceptions -above); the array |entry_ints| contains the current values of -|int_entry_var|s; the array |entry_strs| contains the current values -of |str_entry_var|s; an element of the array |global_strs| contains -the current value of a |str_global_var| if the corresponding -|glb_str_ptr| entry is empty, otherwise the nonempty entry is a -pointer to the string; and the array |field_info|, for each field of -each entry, contains either a pointer to the string or the special -value |missing|. - -The array |global_strs| isn't packed (that is, it isn't |array| \dots\ -|of packed array| \dots$\,$) to increase speed on some systems; -however, on systems that are byte-addressable and that have a good -compiler, packing |global_strs| would save lots of space without much -loss of speed. - -@d fn_info == ilk_info {an alias used with functions} -@# -@d missing = empty {a special pointer for missing fields} - -@<Globals in the outer block@>= -@!fn_loc : hash_loc; {the hash-table location of a function} -@!wiz_loc : hash_loc; {the hash-table location of a wizard function} -@!literal_loc : hash_loc; {the hash-table location of a literal function} -@!macro_name_loc : hash_loc; {the hash-table location of a macro name} -@!macro_def_loc : hash_loc; {the hash-table location of a macro definition} -@!fn_type : packed array[hash_loc] of fn_class; -@!wiz_def_ptr : wiz_fn_loc; {storage location for the next wizard function} -@!wiz_fn_ptr : wiz_fn_loc; {general |wiz_functions| location} -@!wiz_functions : packed array[wiz_fn_loc] of hash_ptr2; -@!int_ent_ptr : int_ent_loc; {general |int_entry_var| location} -@!entry_ints : array[int_ent_loc] of integer; -@!num_ent_ints : int_ent_loc; {the number of distinct |int_entry_var| names} -@!str_ent_ptr : str_ent_loc; {general |str_entry_var| location} -@!entry_strs : array[str_ent_loc] of - packed array[0..ent_str_size] of ASCII_code; -@!num_ent_strs : str_ent_loc; {the number of distinct |str_entry_var| names} -@!str_glb_ptr : 0..max_glob_strs; {general |str_global_var| location} -@!glb_str_ptr : array[str_glob_loc] of str_number; -@!global_strs : array[str_glob_loc] of array[0..glob_str_size] of ASCII_code; -@!glb_str_end : array[str_glob_loc] of 0..glob_str_size; {end markers} -@!num_glb_strs : 0..max_glob_strs; {number of distinct |str_global_var| names} -@!field_ptr : field_loc; {general |field_info| location} -@!field_parent_ptr,@!field_end_ptr : field_loc; {two more for doing cross-refs} -@!cite_parent_ptr,@!cite_xptr : cite_number; {two others for doing cross-refs} -@!field_info : packed array[field_loc] of str_number; -@!num_fields : field_loc; {the number of distinct field names} -@!num_pre_defined_fields : field_loc; {so far, just one: \.{crossref}} -@!crossref_num : field_loc; {the number given to \.{crossref}} -@!no_fields : boolean; {used for |tr_print|ing entry information} - - -@ -Now we initialize storage for the |wiz_defined| functions and we -initialize variables so that the first |str_entry_var|, -|int_entry_var|, |str_global_var|, and |field| name will be assigned -the number~0. Note: The variables |num_ent_strs| and |num_fields| -will also be set when pre-defining strings. - -@<Set initial values of key variables@>= -wiz_def_ptr := 0; -num_ent_ints := 0; -num_ent_strs := 0; -num_fields := 0; -str_glb_ptr := 0; -while (str_glb_ptr < max_glob_strs) do {make |str_global_var|s empty} - begin - glb_str_ptr[str_glb_ptr] := 0; - glb_str_end[str_glb_ptr] := 0; - incr(str_glb_ptr); - end; -num_glb_strs := 0; - - - -@* Style-file commands. -@^style-file commands@> -There are ten \.{.bst} commands: Five (\.{entry}, \.{function}, -\.{integers}, \.{macro}, and \.{strings}) declare and define -functions, one (\.{read}) reads in the \.{.bib}-file entries, and four -(\.{execute}, \.{iterate}, \.{reverse}, and \.{sort}) -manipulate the entries and produce output. - -The boolean variables |entry_seen| and |read_seen| indicate whether -we've yet encountered an \.{entry} and a \.{read} command. There must -be exactly one of each of these, and the \.{entry} command, as well as -any \.{macro} command, must precede the \.{read} command. -Furthermore, the \.{read} command must precede the four that -manipulate the entries and produce output. - -@<Globals in the outer block@>= -@!entry_seen : boolean; {|true| if we've already seen an \.{entry} command} -@!read_seen : boolean; {|true| if we've already seen a \.{read} command} -@!read_performed : boolean; {|true| if we started reading the database file(s)} -@!reading_completed : boolean; {|true| if we made it all the way through} -@!read_completed : boolean; {|true| if the database info didn't bomb \BibTeX} - - -@ -And we initialize them. - -@<Set initial values of key variables@>= -entry_seen := false; -read_seen := false; -read_performed := false; -reading_completed := false; -read_completed := false; - - -@ -@:this can't happen}{\quad Identifier scanning error@> -Here's another bug. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure id_scanning_confusion; -begin -confusion ('Identifier scanning error'); -end; - - -@ -@:this can't happen}{\quad Identifier scanning error@> -This macro is used to scan all \.{.bst} identifiers. The argument -supplies the \.{.bst} command name. The associated procedure simply -prints an error message. - -@d bst_identifier_scan(#) == - begin - scan_identifier (right_brace,comment,comment); - if ((scan_result = white_adjacent) or - (scan_result = specified_char_adjacent)) then - do_nothing - else - begin - bst_id_print; - bst_err (#); - end; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_id_print; -begin -if (scan_result = id_null) then - print ('"',xchr[scan_char],'" begins identifier, command: ') -else if (scan_result = other_char_adjacent) then - print ('"',xchr[scan_char],'" immediately follows identifier, command: ') -else - id_scanning_confusion; -end; - - -@ -This macro just makes sure we're at a |left_brace|. - -@d bst_get_and_check_left_brace(#) == - begin - if (scan_char <> left_brace) then - begin - bst_left_brace_print; - bst_err (#); - end; - incr(buf_ptr2); {skip over the |left_brace|} - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_left_brace_print; -begin -print ('"',xchr[left_brace],'" is missing in command: '); -end; - - -@ -And this one, a |right_brace|. - -@d bst_get_and_check_right_brace(#) == - begin - if (scan_char <> right_brace) then - begin - bst_right_brace_print; - bst_err (#); - end; - incr(buf_ptr2); {skip over the |right_brace|} - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_right_brace_print; -begin -print ('"',xchr[right_brace],'" is missing in command: '); -end; - - -@ -This macro complains if we've already encountered a function to be -inserted into the hash table. - -@d check_for_already_seen_function(#) == - begin - if (hash_found) then {already encountered this as a \.{.bst} function} - begin - already_seen_function_print (#); - return; - end; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure already_seen_function_print (@!seen_fn_loc : hash_loc); -label exit; {so the call to |bst_err| works} -begin -print_pool_str (hash_text[seen_fn_loc]); -print (' is already a type "'); -print_fn_class (seen_fn_loc); -print_ln ('" function name'); -bst_err_print_and_look_for_blank_line_return; -exit: -end; - - -@ -@:style-file commands}{\quad \.{entry}@> -An \.{entry} command has three arguments, each a (possibly empty) list -of function names between braces (the names are separated by one or -more |white_space| characters). All function names in this and other -commands must be legal \.{.bst} identifiers. Upper/lower cases are -considered to be the same for function names in these lists---all -upper-case letters are converted to lower case. These arguments give -lists of |field|s, |int_entry_var|s, and |str_entry_var|s. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_entry_command; -label exit; -begin -if (entry_seen) then - bst_err ('Illegal, another entry command'); -entry_seen := true; {now we've seen an \.{entry} command} -eat_bst_white_and_eof_check ('entry'); -@<Scan the list of |field|s@>; -eat_bst_white_and_eof_check ('entry'); -if (num_fields = num_pre_defined_fields) then - bst_warn ('Warning--I didn''t find any fields'); -@<Scan the list of |int_entry_var|s@>; -eat_bst_white_and_eof_check ('entry'); -@<Scan the list of |str_entry_var|s@>; -exit: -end; - - -@ -This module reads a |left_brace|, the list of |field|s, and a -|right_brace|. The |field|s are those like `author' and `title.' - -@<Scan the list of |field|s@>= -begin -bst_get_and_check_left_brace ('entry'); -eat_bst_white_and_eof_check ('entry'); -while (scan_char <> right_brace) do - begin - bst_identifier_scan ('entry'); - @<Insert a |field| into the hash table@>; - eat_bst_white_and_eof_check ('entry'); - end; -incr(buf_ptr2); {skip over the |right_brace|} -end - - -@ -@^secret agent man@> -Here we insert the just found field name into the hash table, record -it as a |field|, and assign it a number to be used in indexing into -the |field_info| array. - -@<Insert a |field| into the hash table@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a field'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,do_insert); -check_for_already_seen_function (fn_loc); -fn_type[fn_loc] := field;@/ -fn_info[fn_loc] := num_fields; {give this field a number (take away its name)} -incr(num_fields); -end - - -@ -This module reads a |left_brace|, the list of |int_entry_var|s, -and a |right_brace|. - -@<Scan the list of |int_entry_var|s@>= -begin -bst_get_and_check_left_brace ('entry'); -eat_bst_white_and_eof_check ('entry'); -while (scan_char <> right_brace) do - begin - bst_identifier_scan ('entry'); - @<Insert an |int_entry_var| into the hash table@>; - eat_bst_white_and_eof_check ('entry'); - end; -incr(buf_ptr2); {skip over the |right_brace|} -end - - -@ -Here we insert the just found |int_entry_var| name into the hash table -and record it as an |int_entry_var|. An |int_entry_var| is one that -the style designer wants a separate copy of for each entry. - -@<Insert an |int_entry_var| into the hash table@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is an integer entry-variable'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,do_insert); -check_for_already_seen_function (fn_loc); -fn_type[fn_loc] := int_entry_var;@/ -fn_info[fn_loc] := num_ent_ints; {give this |int_entry_var| a number} -incr(num_ent_ints); -end - - -@ -This module reads a |left_brace|, the list of |str_entry_var|s, and a -|right_brace|. A |str_entry_var| is one that the style designer wants -a separate copy of for each entry. - -@<Scan the list of |str_entry_var|s@>= -begin -bst_get_and_check_left_brace ('entry'); -eat_bst_white_and_eof_check ('entry'); -while (scan_char <> right_brace) do - begin - bst_identifier_scan ('entry'); - @<Insert a |str_entry_var| into the hash table@>; - eat_bst_white_and_eof_check ('entry'); - end; -incr(buf_ptr2); {skip over the |right_brace|} -end - - -@ -Here we insert the just found |str_entry_var| name into the hash -table, record it as a |str_entry_var|, and set its pointer into -|entry_strs|. - -@<Insert a |str_entry_var| into the hash table@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a string entry-variable'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,do_insert); -check_for_already_seen_function (fn_loc); -fn_type[fn_loc] := str_entry_var;@/ -fn_info[fn_loc] := num_ent_strs; {give this |str_entry_var| a number} -incr(num_ent_strs); -end - - -@ -A legal argument for an \.{execute}, \.{iterate}, or \.{reverse} -command must exist and be |built_in| or |wiz_defined|. -Here's where we check, returning |true| if the argument is illegal. - -@<Procedures and functions for the reading and processing of input files@>= -function bad_argument_token : boolean; -label exit; -begin -bad_argument_token := true; {now it's easy to exit if necessary} -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,dont_insert); -if (not hash_found) then {unknown \.{.bst} function} - begin - print_token; - bst_err (' is an unknown function'); - end -else if ((fn_type[fn_loc] <> built_in) and - (fn_type[fn_loc] <> wiz_defined)) then - begin - print_token; - print (' has bad function type '); - print_fn_class (fn_loc); - bst_err_print_and_look_for_blank_line_return; - end; -bad_argument_token := false; -exit: -end; - - -@ -@:style-file commands}{\quad \.{execute}@> -An \.{execute} command has one argument, a single |built_in| or -|wiz_defined| function name between braces. Upper/lower cases are -considered to be the same---all upper-case letters are converted to -lower case. Also, we must make sure we've already seen a \.{read} -command. - -This module reads a |left_brace|, a single function to be executed, -and a |right_brace|. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_execute_command; -label exit; -begin -if (not read_seen) then - bst_err ('Illegal, execute command before read command'); -eat_bst_white_and_eof_check ('execute'); -bst_get_and_check_left_brace ('execute'); -eat_bst_white_and_eof_check ('execute'); -bst_identifier_scan ('execute'); -@<Check the \.{execute}-command argument token@>; -eat_bst_white_and_eof_check ('execute'); -bst_get_and_check_right_brace ('execute'); -@<Perform an \.{execute} command@>; -exit: -end; - - -@ -Before executing the function, we must make sure it's a legal one. It -must exist and be |built_in| or |wiz_defined|. - -@<Check the \.{execute}-command argument token@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a to be executed function'); - ecart@/ -if (bad_argument_token) then - return; -end - - -@ -@:style-file commands}{\quad \.{function}@> -A \.{function} command has two arguments; the first is a -|wiz_defined| function name between braces. Upper/lower cases are -considered to be the same---all upper-case letters are converted to -lower case. The second argument defines this function. It consists -of a sequence of functions, between braces, separated by |white_space| -characters. Upper/lower cases are considered to be the same for -function names but not for |str_literal|s. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_function_command; -label exit; -begin -eat_bst_white_and_eof_check ('function'); -@<Scan the |wiz_defined| function name@>; -eat_bst_white_and_eof_check ('function'); -bst_get_and_check_left_brace ('function'); -scan_fn_def(wiz_loc); {this scans the function definition} -exit: -end; - - -@ -This module reads a |left_brace|, a |wiz_defined| function name, and -a |right_brace|. - -@<Scan the |wiz_defined| function name@>= -begin -bst_get_and_check_left_brace ('function'); -eat_bst_white_and_eof_check ('function'); -bst_identifier_scan ('function'); -@<Check the |wiz_defined| function name@>; -eat_bst_white_and_eof_check ('function'); -bst_get_and_check_right_brace ('function'); -end - - -@ -The function name must exist and be a new one; we mark it as -|wiz_defined|. Also, see if it's the default entry-type function. - -@<Check the |wiz_defined| function name@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a wizard-defined function'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -wiz_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,do_insert); -check_for_already_seen_function (wiz_loc); -fn_type[wiz_loc] := wiz_defined; -if (hash_text[wiz_loc] = s_default) then {we've found the default entry-type} - b_default := wiz_loc; {see the |built_in| functions for |b_default|} -end - - -@ -We're about to start scanning tokens in a function definition. When a -function token is illegal, we skip until it ends; a |white_space| -character, an end-of-line, a |right_brace|, or a |comment| marks the -end of the current token. - -@d next_token=25 {a bad function token; go read the next one} -@# -@d skip_token(#) == begin {not-so-serious error during \.{.bst} parsing} - print (#); - skip_token_print; {also, skip to the current token's end} - goto next_token; - end - -@<Procedures and functions for input scanning@>= -procedure skip_token_print; -begin -print ('-'); -bst_ln_num_print; -mark_error; -if (scan2_white(right_brace,comment)) then {ok if token ends line} - do_nothing; -end; - - -@ -@^commented-out code@> -@^for a good time, try comment-out code@> -This macro is similar to the last one but is specifically for -recursion in a |wiz_defined| function, which is illegal; it helps save -space. - -@d skip_recursive_token == begin - print_recursion_illegal; - goto next_token; - end - -@<Procedures and functions for input scanning@>= -procedure print_recursion_illegal; -begin - trace - trace_pr_newline; - ecart@/ -print_ln ('Curse you, wizard, before you recurse me:'); -print ('function '); -print_token; -print_ln (' is illegal in its own definition'); - @{ - print_recursion_illegal; - @}@/ -skip_token_print; {also, skip to the current token's end} -end; - - -@ -Here's another macro for saving some space when there's a problem with -a token. - -@d skip_token_unknown_function == begin - skp_token_unknown_function_print; - goto next_token; - end - -@<Procedures and functions for input scanning@>= -procedure skp_token_unknown_function_print; -begin -print_token; -print (' is an unknown function'); -skip_token_print; {also, skip to the current token's end} -end; - - -@ -And another. - -@d skip_token_illegal_stuff_after_literal == - begin - skip_illegal_stuff_after_token_print; - goto next_token; - end - -@<Procedures and functions for input scanning@>= -procedure skip_illegal_stuff_after_token_print; -begin -print ('"',xchr[scan_char],'" can''t follow a literal'); -skip_token_print; {also, skip to the current token's end} -end; - - -@ -This recursive function reads and stores the list of functions -(separated by |white_space| characters or ends-of-line) that define -this new function, and reads a |right_brace|. - -@<Procedures and functions for input scanning@>= -procedure scan_fn_def (@!fn_hash_loc : hash_loc); -label next_token,@!exit; -type @!fn_def_loc = 0..single_fn_space; {for a single |wiz_defined|-function} -var singl_function : packed array[fn_def_loc] of hash_ptr2; - @!single_ptr : fn_def_loc; {next storage location for this definition} - @!copy_ptr : fn_def_loc; {dummy variable} - @!end_of_num : buf_pointer; {the end of an implicit function's name} - @!impl_fn_loc : hash_loc; {an implicit function's hash-table location} -begin -eat_bst_white_and_eof_check ('function'); -single_ptr := 0; -while (scan_char <> right_brace) do - begin - @<Get the next function of the definition@>; -next_token: - eat_bst_white_and_eof_check ('function'); - end; -@<Complete this function's definition@>; -incr(buf_ptr2); {skip over the |right_brace|} -exit: -end; - - -@ -@:BibTeX capacity exceeded}{\quad single function space@> -This macro inserts a hash-table location (or one of the two -special markers |quote_next_fn| and |end_of_def|) into the -|singl_function| array, which will later be copied into the -|wiz_functions| array. - -@d insert_fn_loc(#) == begin - singl_function[single_ptr] := #; - if (single_ptr = single_fn_space) then - singl_fn_overflow; - incr(single_ptr); - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure singl_fn_overflow; -begin -overflow('single function space ',single_fn_space); -end; - - -@ -There are five possibilities for the first character of the token -representing the next function of the definition: If it's a -|number_sign|, the token is an |int_literal|; if it's a -|double_quote|, the token is a |str_literal|; if it's a -|single_quote|, the token is a quoted function; if it's a -|left_brace|, the token isn't really a token, but rather the start of -another function definition (which will result in a recursive call to -|scan_fn_def|); if it's anything else, the token is the name of an -already-defined function. Note: To prevent the wizard from using -recursion, we have to check that neither a quoted function nor an -already-defined-function is actually the currently-being-defined -function (which is stored at |wiz_loc|). - -@<Get the next function of the definition@>= -case (scan_char) of - number_sign : @<Scan an |int_literal|@>; - double_quote : @<Scan a |str_literal|@>; - single_quote : @<Scan a quoted function@>; - left_brace : @<Start a new function definition@>; - othercases @<Scan an already-defined function@> -endcases - - -@ -An |int_literal| is preceded by a |number_sign|, consists of an -integer (i.e., an optional |minus_sign| followed by one or more -|numeric| characters), and is followed either by a |white_space| -character, an end-of-line, or a |right_brace|. The array |fn_info| -contains the value of the integer for |int_literal|s. - -@<Scan an |int_literal|@>= -begin -incr(buf_ptr2); {skip over the |number_sign|} -if (not scan_integer) then - skip_token ('Illegal integer in integer literal'); - trace - trace_pr ('#'); - trace_pr_token; - trace_pr_ln (' is an integer literal with value ',token_value:0); - ecart@/ -literal_loc := str_lookup(buffer,buf_ptr1,token_len,integer_ilk,do_insert); -if (not hash_found) then - begin - fn_type[literal_loc] := int_literal; {set the |fn_class|} - fn_info[literal_loc] := token_value; {the value of this integer} - end; -if ((lex_class[scan_char]<>white_space) and (buf_ptr2<last) and - (scan_char<>right_brace) and@| (scan_char<>comment)) then - skip_token_illegal_stuff_after_literal; -insert_fn_loc (literal_loc); {add this function to |wiz_functions|} -end - - -@ -A |str_literal| is preceded by a |double_quote| and consists of all -characters on this line up to the next |double_quote|. Also, there -must be either a |white_space| character, an end-of-line, a -|right_brace|, or a |comment| following (since functions in the -definition must be separated by |white_space|). The array |fn_info| -contains nothing for |str_literal|s. - -@<Scan a |str_literal|@>= -begin -incr(buf_ptr2); {skip over the |double_quote|} -if (not scan1(double_quote)) then - skip_token ('No `',xchr[double_quote],''' to end string literal'); - trace - trace_pr ('"'); - trace_pr_token; - trace_pr ('"'); - trace_pr_ln (' is a string literal'); - ecart@/ -literal_loc := str_lookup(buffer,buf_ptr1,token_len,text_ilk,do_insert);@/ -fn_type[literal_loc] := str_literal; {set the |fn_class|} -incr(buf_ptr2); {skip over the |double_quote|} -if ((lex_class[scan_char]<>white_space) and (buf_ptr2<last) and - (scan_char<>right_brace) and@| (scan_char<>comment)) then - skip_token_illegal_stuff_after_literal; -insert_fn_loc (literal_loc); {add this function to |wiz_functions|} -end - - -@ -A quoted function is preceded by a |single_quote| and consists of all -characters up to the next |white_space| character, end-of-line, -|right_brace|, or |comment|. - -@<Scan a quoted function@>= -begin -incr(buf_ptr2); {skip over the |single_quote|} -if (scan2_white(right_brace,comment)) then {ok if token ends line} - do_nothing; - trace - trace_pr (''''); - trace_pr_token; - trace_pr (' is a quoted function '); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,dont_insert); -if (not hash_found) then {unknown \.{.bst} function} - skip_token_unknown_function -else - @<Check and insert the quoted function@>; -end - - -@ -Here we check that this quoted function is a legal one---the function -name must already exist, but it mustn't be the currently-being-defined -function (which is stored at |wiz_loc|). - -@<Check and insert the quoted function@>= -begin -if (fn_loc = wiz_loc) then - skip_recursive_token -else - begin - trace - trace_pr ('of type '); - trace_pr_fn_class (fn_loc); - trace_pr_newline; - ecart@/ - insert_fn_loc (quote_next_fn); {add special marker together with} - insert_fn_loc (fn_loc); {this function to |wiz_functions|} - end -end - - -@ -@^kludge@> -@:this can't happen}{\quad Already encountered implicit function@> -This module marks the implicit function as being quoted, generates a -name, and stores it in the hash table. This name is strictly internal -to this program, starts with a |single_quote| (since that will make -this function name unique), and ends with the variable |impl_fn_num| -converted to ASCII. The alias kludge helps make the stack space not -overflow on some machines. - -@d ex_buf2 == ex_buf {an alias, used only in this module} - -@<Start a new function definition@>= -begin -ex_buf2[0] := single_quote; -int_to_ASCII (impl_fn_num,ex_buf2,1,end_of_num); -impl_fn_loc := str_lookup(ex_buf2,0,end_of_num,bst_fn_ilk,do_insert); -if (hash_found) then - confusion ('Already encountered implicit function'); - trace - trace_pr_pool_str (hash_text[impl_fn_loc]); - trace_pr_ln (' is an implicit function'); - ecart@/ -incr(impl_fn_num); -fn_type[impl_fn_loc] := wiz_defined;@/ -insert_fn_loc (quote_next_fn); {all implicit functions are quoted} -insert_fn_loc (impl_fn_loc); {add it to |wiz_functions|} -incr(buf_ptr2); {skip over the |left_brace|} -scan_fn_def (impl_fn_loc); {this is the recursive call} -end - - -@ -The variable |impl_fn_num| counts the number of implicit functions -seen in the \.{.bst} file. - -@<Globals in the outer block@>= -@!impl_fn_num : integer; {the number of implicit functions seen so far} - - -@ -Now we initialize it. - -@<Set initial values of key variables@>= -impl_fn_num := 0; - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -This module appends a character to |int_buf| after checking to make -sure it will fit; for use in |int_to_ASCII|. - -@d append_int_char(#) == begin - if (int_ptr = buf_size) then - buffer_overflow; - int_buf[int_ptr]:=#; - incr(int_ptr); - end - - -@ -This procedure takes the integer |int|, copies the appropriate -|ASCII_code| string into |int_buf| starting at |int_begin|, and sets -the |var| parameter |int_end| to the first unused |int_buf| location. -The ASCII string will consist of decimal digits, the first of which -will be not be a~0 if the integer is nonzero, with a prepended minus -sign if the integer is negative. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure int_to_ASCII (@!int:integer; var int_buf:buf_type; - @!int_begin:buf_pointer; var int_end:buf_pointer); -var int_ptr,@!int_xptr : buf_pointer; {pointers into |int_buf|} - @!int_tmp_val : ASCII_code; {the temporary element in an exchange} -begin -int_ptr := int_begin; -if (int < 0) then {add the |minus_sign| and use the absolute value} - begin - append_int_char (minus_sign); - int := -int; - end; -int_xptr := int_ptr; -repeat {copy digits into |int_buf|} - append_int_char ("0" + (int mod 10)); - int := int div 10; - until (int = 0); -int_end := int_ptr; {set the string length} -decr(int_ptr); -while (int_xptr < int_ptr) do {and reorder (flip) the digits} - begin - int_tmp_val := int_buf[int_xptr]; - int_buf[int_xptr] := int_buf[int_ptr]; - int_buf[int_ptr] := int_tmp_val; - decr(int_ptr); - incr(int_xptr); - end -end; - - -@ -An already-defined function consists of all characters up to the next -|white_space| character, end-of-line, |right_brace|, or |comment|. -This function name must already exist, but it mustn't be the -currently-being-defined function (which is stored at |wiz_loc|). - -@<Scan an already-defined function@>= -begin -if (scan2_white(right_brace,comment)) then {ok if token ends line} - do_nothing; - trace - trace_pr_token; - trace_pr (' is a function '); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,dont_insert); -if (not hash_found) then {unknown \.{.bst} function} - skip_token_unknown_function -else if (fn_loc = wiz_loc) then - skip_recursive_token -else - begin - trace - trace_pr ('of type '); - trace_pr_fn_class (fn_loc); - trace_pr_newline; - ecart@/ - insert_fn_loc (fn_loc); {add this function to |wiz_functions|} - end; -end - - -@ -@:BibTeX capacity exceeded}{\quad wizard-defined function space@> -Now we add the |end_of_def| special marker, make sure this function will -fit into |wiz_functions|, and put it there. - -@<Complete this function's definition@>= -begin -insert_fn_loc (end_of_def); {add special marker ending the definition} -if (single_ptr + wiz_def_ptr > wiz_fn_space) then - begin - print (single_ptr + wiz_def_ptr : 0,': '); - overflow('wizard-defined function space ',wiz_fn_space); - end; -fn_info[fn_hash_loc] := wiz_def_ptr; {pointer into |wiz_functions|} -copy_ptr := 0; -while (copy_ptr < single_ptr) do {make this function official} - begin - wiz_functions[wiz_def_ptr] := singl_function[copy_ptr]; - incr(copy_ptr); - incr(wiz_def_ptr); - end; -end - - -@ -@:style-file commands}{\quad \.{integers}@> -An \.{integers} command has one argument, a list of function names -between braces (the names are separated by one or more |white_space| -characters). Upper/lower cases are considered to be the same for -function names in these lists---all upper-case letters are converted to -lower case. Each name in this list specifies an |int_global_var|. -There may be several \.{integers} commands in the \.{.bst} file. - -This module reads a |left_brace|, a list of |int_global_var|s, and a -|right_brace|. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_integers_command; -label exit; -begin -eat_bst_white_and_eof_check ('integers'); -bst_get_and_check_left_brace ('integers'); -eat_bst_white_and_eof_check ('integers'); -while (scan_char <> right_brace) do - begin - bst_identifier_scan ('integers'); - @<Insert an |int_global_var| into the hash table@>; - eat_bst_white_and_eof_check ('integers'); - end; -incr(buf_ptr2); {skip over the |right_brace|} -exit: -end; - - -@ -Here we insert the just found |int_global_var| name into the hash -table and record it as an |int_global_var|. Also, we initialize it by -setting |fn_info[fn_loc]| to 0. - -@<Insert an |int_global_var| into the hash table@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is an integer global-variable'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,do_insert); -check_for_already_seen_function (fn_loc); -fn_type[fn_loc] := int_global_var;@/ -fn_info[fn_loc] := 0; {initialize} -end - - -@ -@:style-file commands}{\quad \.{iterate}@> -An \.{iterate} command has one argument, a single |built_in| or -|wiz_defined| function name between braces. Upper/lower cases are -considered to be the same---all upper-case letters are converted to -lower case. Also, we must make sure we've already seen a \.{read} -command. - -This module reads a |left_brace|, a single function to be iterated, -and a |right_brace|. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_iterate_command; -label exit; -begin -if (not read_seen) then - bst_err ('Illegal, iterate command before read command'); -eat_bst_white_and_eof_check ('iterate'); -bst_get_and_check_left_brace ('iterate'); -eat_bst_white_and_eof_check ('iterate'); -bst_identifier_scan ('iterate'); -@<Check the \.{iterate}-command argument token@>; -eat_bst_white_and_eof_check ('iterate'); -bst_get_and_check_right_brace ('iterate'); -@<Perform an \.{iterate} command@>; -exit: -end; - - -@ -Before iterating the function, we must make sure it's a legal one. It -must exist and be |built_in| or |wiz_defined|. - -@<Check the \.{iterate}-command argument token@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a to be iterated function'); - ecart@/ -if (bad_argument_token) then - return; -end - - -@ -@:style-file commands}{\quad \.{macro}@> -A \.{macro} command, like a \.{function} command, has two arguments; -the first is a macro name between braces. The name must be a legal -\.{.bst} identifier. Upper/lower cases are considered to be the -same---all upper-case letters are converted to lower case. The second -argument defines this macro. It consists of a -|double_quote|-delimited string (which must be on a single line) -between braces, with optional |white_space| characters between the -braces and the |double_quote|s. This |double_quote|-delimited string -is parsed exactly as a |str_literal| is for the \.{function} command. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_macro_command; -label exit; -begin -if (read_seen) then - bst_err ('Illegal, macro command after read command'); -eat_bst_white_and_eof_check ('macro'); -@<Scan the macro name@>; -eat_bst_white_and_eof_check ('macro'); -@<Scan the macro's definition@>; -exit: -end; - - -@ -This module reads a |left_brace|, a macro name, and a |right_brace|. - -@<Scan the macro name@>= -begin -bst_get_and_check_left_brace ('macro'); -eat_bst_white_and_eof_check ('macro'); -bst_identifier_scan ('macro'); -@<Check the macro name@>; -eat_bst_white_and_eof_check ('macro'); -bst_get_and_check_right_brace ('macro'); -end - - -@ -The macro name must be a new one; we mark it as |macro_ilk|. - -@<Check the macro name@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a macro'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -macro_name_loc := str_lookup(buffer,buf_ptr1,token_len,macro_ilk,do_insert); -if (hash_found) then - begin - print_token; - bst_err (' is already defined as a macro'); - end; -ilk_info[macro_name_loc]:=hash_text[macro_name_loc]; {default in case of error} -end - - -@ -This module reads a |left_brace|, the |double_quote|-delimited string -that defines this macro, and a |right_brace|. - -@<Scan the macro's definition@>= -begin -bst_get_and_check_left_brace ('macro'); -eat_bst_white_and_eof_check ('macro'); -if (scan_char <> double_quote) then - bst_err ('A macro definition must be ',xchr[double_quote],'-delimited'); -@<Scan the macro definition-string@>; -eat_bst_white_and_eof_check ('macro'); -bst_get_and_check_right_brace ('macro'); -end - - -@ -A macro definition-string is preceded by a |double_quote| and consists -of all characters on this line up to the next |double_quote|. The -array |ilk_info| contains a pointer to this string for the macro name. - -@<Scan the macro definition-string@>= -begin -incr(buf_ptr2); {skip over the |double_quote|} -if (not scan1(double_quote)) then - bst_err ('There''s no `',xchr[double_quote],''' to end macro definition'); - trace - trace_pr ('"'); - trace_pr_token; - trace_pr ('"'); - trace_pr_ln (' is a macro string'); - ecart@/ -macro_def_loc := str_lookup(buffer,buf_ptr1,token_len,text_ilk,do_insert);@/ -fn_type[macro_def_loc] := str_literal; {set the |fn_class|} -ilk_info[macro_name_loc] := hash_text[macro_def_loc]; -incr(buf_ptr2); {skip over the |double_quote|} -end - - -@ -@^gymnastics@> -We need to include stuff for \.{.bib} reading here because that's done -by the \.{read} command. - -@<Procedures and functions for the reading and processing of input files@>= -@<Scan for and process a \.{.bib} command or database entry@> - - -@ -@:style-file commands}{\quad \.{read}@> -The \.{read} command has no arguments so there's no more parsing to -do. We must make sure we haven't seen a \.{read} command before and -we've already seen an \.{entry} command. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_read_command; -label exit; -begin -if (read_seen) then - bst_err ('Illegal, another read command'); -read_seen := true; {now we've seen a \.{read} command} -if (not entry_seen) then - bst_err ('Illegal, read command before entry command'); -sv_ptr1 := buf_ptr2; {save the contents of the \.{.bst} input line} -sv_ptr2 := last; -tmp_ptr := sv_ptr1; -while (tmp_ptr < sv_ptr2) do - begin - sv_buffer[tmp_ptr] := buffer[tmp_ptr]; - incr(tmp_ptr); - end; -@<Read the \.{.bib} file(s)@>; -buf_ptr2 := sv_ptr1; {and restore} -last := sv_ptr2; -tmp_ptr := buf_ptr2; -while (tmp_ptr < last) do - begin - buffer[tmp_ptr] := sv_buffer[tmp_ptr]; - incr(tmp_ptr); - end; -exit: -end; - - -@ -@:style-file commands}{\quad \.{reverse}@> -A \.{reverse} command has one argument, a single |built_in| or -|wiz_defined| function name between braces. Upper/lower cases are -considered to be the same---all upper-case letters are converted to -lower case. Also, we must make sure we've already seen a \.{read} -command. - -This module reads a |left_brace|, a single function to be iterated in -reverse, and a |right_brace|. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_reverse_command; -label exit; -begin -if (not read_seen) then - bst_err ('Illegal, reverse command before read command'); -eat_bst_white_and_eof_check ('reverse'); -bst_get_and_check_left_brace ('reverse'); -eat_bst_white_and_eof_check ('reverse'); -bst_identifier_scan ('reverse'); -@<Check the \.{reverse}-command argument token@>; -eat_bst_white_and_eof_check ('reverse'); -bst_get_and_check_right_brace ('reverse'); -@<Perform a \.{reverse} command@>; -exit: -end; - - -@ -Before iterating the function in reverse, we must make sure it's a -legal one. It must exist and be |built_in| or |wiz_defined|. - -@<Check the \.{reverse}-command argument token@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a to be iterated in reverse function'); - ecart@/ -if (bad_argument_token) then - return; -end - - -@ -@:style-file commands}{\quad \.{sort}@> -The \.{sort} command has no arguments so there's no more parsing to -do, but we must make sure we've already seen a \.{read} command. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_sort_command; -label exit; -begin -if (not read_seen) then - bst_err ('Illegal, sort command before read command'); -@<Perform a \.{sort} command@>; -exit: -end; - - -@ -@:style-file commands}{\quad \.{strings}@> -A \.{strings} command has one argument, a list of function names -between braces (the names are separated by one or more |white_space| -characters). Upper/lower cases are considered to be the same for -function names in these lists---all upper-case letters are converted to -lower case. Each name in this list specifies a |str_global_var|. -There may be several \.{strings} commands in the \.{.bst} file. - -This module reads a |left_brace|, a list of |str_global_var|s, -and a |right_brace|. - -@<Procedures and functions for the reading and processing of input files@>= -procedure bst_strings_command; -label exit; -begin -eat_bst_white_and_eof_check ('strings'); -bst_get_and_check_left_brace ('strings'); -eat_bst_white_and_eof_check ('strings'); -while (scan_char <> right_brace) do - begin - bst_identifier_scan ('strings'); - @<Insert a |str_global_var| into the hash table@>; - eat_bst_white_and_eof_check ('strings'); - end; -incr(buf_ptr2); {skip over the |right_brace|} -exit: -end; - - -@ -@:BibTeX capacity exceeded}{\quad number of string global-variables@> -Here we insert the just found |str_global_var| name into the hash -table, record it as a |str_global_var|, set its pointer into -|global_strs|, and initialize its value there to the null string. - -@d end_of_string = invalid_code {this illegal |ASCII_code| ends a string} - -@<Insert a |str_global_var| into the hash table@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a string global-variable'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -fn_loc := str_lookup(buffer,buf_ptr1,token_len,bst_fn_ilk,do_insert); -check_for_already_seen_function (fn_loc); -fn_type[fn_loc] := str_global_var;@/ -fn_info[fn_loc] := num_glb_strs; {pointer into |global_strs|} -if (num_glb_strs = max_glob_strs) then - overflow('number of string global-variables ',max_glob_strs); -incr(num_glb_strs); -end - - -@ -@^gymnastics@> -That's it for processing \.{.bst} commands, except for finishing the -procedural gymnastics. Note that this must topologically follow the -stuff for \.{.bib} reading, because that's done by the \.{.bst}'s -\.{read} command. - -@<Procedures and functions for the reading and processing of input files@>= -@<Scan for and process a \.{.bst} command@> - - - -@* Reading the database file(s). -This section reads the \.{.bib} file(s), each of which consists of a -sequence of entries (perhaps with a few \.{.bib} commands thrown in, -as explained later). Each entry consists of an |at_sign|, an entry -type, and, between braces or parentheses and separated by |comma|s, a -database key and a list of fields. Each field consists of a field -name, an |equals_sign|, and nonempty list of field tokens separated by -|concat_char|s. Each field token is either a nonnegative number, a -macro name (like `jan'), or a brace-balanced string delimited by -either |double_quote|s or braces. Finally, case differences are -ignored for all but delimited strings and database keys, and -|white_space| characters and ends-of-line may appear in all reasonable -places (i.e., anywhere except within entry types, database keys, field -names, and macro names); furthermore, comments may appear anywhere -between entries (or before the first or after the last) as long as -they contain no |at_sign|s. - - -@ -These global variables are used while reading the \.{.bib} file(s). -The elements of |type_list|, which indicate an entry's type (book, -article, etc.), point either to a |hash_loc| or are one of two special -markers: |empty|, from which |hash_base = empty + 1| was defined, -means we haven't yet encountered the \.{.bib} entry corresponding to -this cite key; and |undefined| means we've encountered it but it had -an unknown entry type. Thus the array |type_list| is of type -|hash_ptr2|, also defined earlier. An element of the boolean array -|entry_exists| whose corresponding entry in |cite_list| gets -overwritten (which happens only when |all_entries| is |true|) -indicates whether we've encountered that entry of |cite_list| while -reading the \.{.bib} file(s); this information is unused for entries -that aren't (or more precisely, that have no chance of being) -overwritten. When we're reading the database file, the array -|cite_info| contains auxiliary information for |cite_list|. Later, -|cite_info| will become |sorted_cites|, and this dual role imposes the -(not-very-imposing) restriction |max_strings >= max_cites|. - -@d undefined = hash_max + 1 {a special marker used for |type_list|} - -@<Globals in the outer block@>= -@!bib_line_num : integer; {line number of the \.{.bib} file} -@!entry_type_loc : hash_loc; {the hash-table location of an entry type} -@!type_list : packed array[cite_number] of hash_ptr2; -@!type_exists : boolean; {|true| if this entry type is \.{.bst}-defined} -@!entry_exists : packed array[cite_number] of boolean; -@!store_entry : boolean; {|true| if we're to store info for this entry} -@!field_name_loc : hash_loc; {the hash-table location of a field name} -@!field_val_loc : hash_loc; {the hash-table location of a field value} -@!store_field : boolean; {|true| if we're to store info for this field} -@!store_token : boolean; {|true| if we're to store this macro token} -@!right_outer_delim : ASCII_code; {either a |right_brace| or a |right_paren|} -@!right_str_delim : ASCII_code; {either a |right_brace| or a |double_quote|} -@!at_bib_command : boolean; {|true| for a command, false for an entry} -@!cur_macro_loc : hash_loc; {|macro_loc| for a \.{string} being defined} -@!cite_info : packed array[cite_number] of str_number; {extra |cite_list| info} -@!cite_hash_found : boolean; {set to a previous |hash_found| value} -@!preamble_ptr : bib_number; {pointer into the |s_preamble| array} -@!num_preamble_strings : bib_number; {counts the |s_preamble| strings} - - -@ -This little procedure exists because it's used by at least two other -procedures and thus saves some space. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_ln_num_print; -begin -print ('--line ',bib_line_num:0,' of file '); -print_bib_name; -end; - - -@ -When there's a serious error parsing a \.{.bib} file, we flush -everything up to the beginning of the next entry. - -@d bib_err(#) == begin {serious error during \.{.bib} parsing} - print (#); - bib_err_print; - return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_err_print; -begin -print ('-'); -bib_ln_num_print; -print_bad_input_line; {this call does the |mark_error|} -print_skipping_whatever_remains; -if (at_bib_command) then - print_ln ('command') - else - print_ln ('entry'); -end; - - -@ -When there's a harmless error parsing a \.{.bib} file, we just give a -warning message. This is always called after other stuff has been -printed out. - -@d bib_warn(#) == begin {non-serious error during \.{.bst} parsing} - print (#); - bib_warn_print; - end -@# -@d bib_warn_newline(#) == begin {same as above but with a newline} - print_ln (#); - bib_warn_print; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_warn_print; -begin -bib_ln_num_print; -mark_warning; -end; - - -@ -For all |num_bib_files| database files, we keep reading and processing -\.{.bib} entries until none left. - -@<Read the \.{.bib} file(s)@>= -begin -@<Final initialization for \.{.bib} processing@>; -read_performed := true; -bib_ptr := 0; -while (bib_ptr < num_bib_files) do - begin - print ('Database file #',bib_ptr+1:0,': '); - print_bib_name;@/ - bib_line_num := 0; {initialize to get the first input line} - buf_ptr2 := last; - while (not eof(cur_bib_file)) do - get_bib_command_or_entry_and_process; - a_close (cur_bib_file); - incr(bib_ptr); - end; -reading_completed := true; - trace - trace_pr_ln ('Finished reading the database file(s)'); - ecart@/ -@<Final initialization for processing the entries@>; -read_completed := true; -end - - -@ -We need to initialize the |field_info| array, and also various things -associated with the |cite_list| array (but not |cite_list| itself). - -@<Final initialization for \.{.bib} processing@>= -begin -@<Initialize the |field_info|@>; -@<Initialize things for the |cite_list|@>; -end - - -@ -This module initializes all fields of all entries to |missing|, the -value to which all fields are initialized. - -@<Initialize the |field_info|@>= -begin -check_field_overflow (num_fields*num_cites); -field_ptr := 0; -while (field_ptr < max_fields) do - begin - field_info[field_ptr] := missing; - incr(field_ptr); - end; -end - - -@ -@^fetish@> -@:BibTeX capacity exceeded}{\quad total number of fields@> -Complain if somebody's got a field fetish. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure check_field_overflow (@!total_fields : integer); -begin -if (total_fields > max_fields) then - begin - print_ln (total_fields:0,' fields:'); - overflow('total number of fields ',max_fields); - end; -end; - - -@ -We must initialize the |type_list| array so that we can detect -duplicate (or missing) entries for cite keys on |cite_list|. Also, -when we're to include the entire database, we use the array -|entry_exists| to detect those missing entries whose |cite_list| info -will (or to be more precise, might) be overwritten; and we use the -array |cite_info| to save the part of |cite_list| that will (might) be -overwritten. We also use |cite_info| for counting cross~references -when it's appropriate---when an entry isn't otherwise to be included -on |cite_list| (that is, the entry isn't \.{\\cite}d or -\.{\\nocite}d). Such an entry is included on the final |cite_list| if -it's cross~referenced at least |min_crossrefs| times. - -@<Initialize things for the |cite_list|@>= -begin -cite_ptr := 0; -while (cite_ptr < max_cites) do - begin - type_list[cite_ptr] := empty;@/ - cite_info[cite_ptr] := any_value; {to appeas \PASCAL's boolean evaluation} - incr(cite_ptr); - end; -old_num_cites := num_cites; -if (all_entries) then - begin - cite_ptr := all_marker; - while (cite_ptr < old_num_cites) do - begin - cite_info[cite_ptr] := cite_list[cite_ptr]; - entry_exists[cite_ptr] := false; - incr(cite_ptr); - end; - cite_ptr := all_marker; {we insert the ``other'' entries here} - end - else - begin - cite_ptr := num_cites; {we insert the cross-referenced entries here} - all_marker := any_value; {to appease \PASCAL's boolean evaluation} - end; -end - - -@ -Before we actually start the code for reading a database file, we must -define this \.{.bib}-specific scanning function. It skips over -|white_space| characters until hitting a nonwhite character or the end -of the file, respectively returning |true| or |false|. It also -updates |bib_line_num|, the line counter. - -@<Procedures and functions for input scanning@>= -function eat_bib_white_space : boolean; -label exit; -begin -while (not scan_white_space) do {no characters left; read another line} - begin - if (not input_ln(cur_bib_file)) then {end-of-file; return |false|} - begin - eat_bib_white_space := false; - return; - end; - incr(bib_line_num); - buf_ptr2 := 0; - end; -eat_bib_white_space := true; -exit: -end; - - -@ -It's often illegal to end a \.{.bib} command in certain places, and -this is where we come to check. - -@d eat_bib_white_and_eof_check == - begin - if (not eat_bib_white_space) then - begin - eat_bib_print; - return; - end; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure eat_bib_print; -label exit; {so the call to |bib_err| works} -begin -bib_err ('Illegal end of database file'); -exit: -end; - - -@ -And here are a bunch of error-message macros, each called more than -once, that thus save space as implemented. This one is for when one -of two possible characters is expected while scanning. - -@d bib_one_of_two_expected_err(#) == - begin - bib_one_of_two_print (#); - return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_one_of_two_print (@!char1,@!char2:ASCII_code); -label exit; {so the call to |bib_err| works} -begin -bib_err ('I was expecting a `',xchr[char1],''' or a `',xchr[char2],''''); -exit: -end; - - -@ -This one's for an expected |equals_sign|. - -@d bib_equals_sign_expected_err == - begin - bib_equals_sign_print; - return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_equals_sign_print; -label exit; {so the call to |bib_err| works} -begin -bib_err ('I was expecting an "',xchr[equals_sign],'"'); -exit: -end; - - -@ -This complains about unbalanced braces. - -@d bib_unbalanced_braces_err == - begin - bib_unbalanced_braces_print; - return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_unbalanced_braces_print; -label exit; {so the call to |bib_err| works} -begin -bib_err ('Unbalanced braces'); -exit: -end; - - -@ -And this one about an overly exuberant field. - -@d bib_field_too_long_err == - begin - bib_field_too_long_print; - return; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_field_too_long_print; -label exit; {so the call to |bib_err| works} -begin -bib_err ('Your field is more than ',buf_size:0,' characters'); -exit: -end; - - -@ -This one is just a warning, not an error. It's for when something -isn't (or might not be) quite right with a macro name. - -@d macro_name_warning(#) == - begin - macro_warn_print; - bib_warn_newline (#); - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure macro_warn_print; -begin -print ('Warning--string name "'); -print_token; -print ('" is '); -end; - - -@ -@:this can't happen}{\quad Identifier scanning error@> -This macro is used to scan all \.{.bib} identifiers. The argument -tells what was happening at the time. The associated procedure simply -prints an error message. - -@d bib_identifier_scan_check(#) == - begin - if ((scan_result = white_adjacent) or - (scan_result = specified_char_adjacent)) then - do_nothing - else - begin - bib_id_print; - bib_err (#); - end; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_id_print; -begin -if (scan_result = id_null) then - print ('You''re missing ') -else if (scan_result = other_char_adjacent) then - print ('"',xchr[scan_char],'" immediately follows ') -else - id_scanning_confusion; -end; - - -@ -This module either reads a database entry, whose three main components -are an entry type, a database key, and a list of fields, or it reads a -\.{.bib} command, whose structure is command dependent and explained -later. - -@d cite_already_set = 22 {this gets around \PASCAL\ limitations} -@d first_time_entry = 26 {for checking for repeated database entries} - -@<Scan for and process a \.{.bib} command or database entry@>= -procedure get_bib_command_or_entry_and_process; -label cite_already_set,@!first_time_entry,@!loop_exit,@!exit; -begin -at_bib_command := false;@/ -@<Skip to the next database entry or \.{.bib} command@>; -@<Scan the entry type or scan and process the \.{.bib} command@>; -eat_bib_white_and_eof_check; -@<Scan the entry's database key@>; -eat_bib_white_and_eof_check; -@<Scan the entry's list of fields@>; -exit: -end; - - -@ -This module skips over everything until hitting an |at_sign| or the -end of the file. It also updates |bib_line_num|, the line counter. - -@<Skip to the next database entry or \.{.bib} command@>= -while (not scan1(at_sign)) do {no |at_sign|; get next line} - begin - if (not input_ln(cur_bib_file)) then {end-of-file} - return; - incr(bib_line_num); - buf_ptr2 := 0; - end - - -@ -@:this can't happen}{\quad An at-sign disappeared@> -This module reads an |at_sign| and an entry type (like `book' or -`article') or a \.{.bib} command. If it's an entry type, it must be -defined in the \.{.bst} file if this entry is to be included in the -reference list. - -@<Scan the entry type or scan and process the \.{.bib} command@>= -begin -if (scan_char <> at_sign) then - confusion ('An "',xchr[at_sign],'" disappeared'); -incr(buf_ptr2); {skip over the |at_sign|} -eat_bib_white_and_eof_check; -scan_identifier (left_brace,left_paren,left_paren); -bib_identifier_scan_check ('an entry type'); - trace - trace_pr_token; - trace_pr_ln (' is an entry type or a database-file command'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -command_num := ilk_info[ - str_lookup(buffer,buf_ptr1,token_len,bib_command_ilk,dont_insert)]; -if (hash_found) then - @<Process a \.{.bib} command@> -else - begin {process an entry type} - entry_type_loc := str_lookup( - buffer,buf_ptr1,token_len,bst_fn_ilk,dont_insert); - if ((not hash_found) or (fn_type[entry_type_loc]<>wiz_defined)) then@/ - type_exists := false {no such entry type defined in the \.{.bst} file} - else - type_exists := true; - end; -end - - -@ -@^database-file commands@> -@:this can't happen}{\quad Unknown database-file command@> -Here we determine which \.{.bib} command we're about to process, then -go to it. - -@<Process a \.{.bib} command@>= -begin -at_bib_command := true; -case (command_num) of - n_bib_comment : @<Process a \.{comment} command@>; - n_bib_preamble : @<Process a \.{preamble} command@>; - n_bib_string : @<Process a \.{string} command@>; - othercases bib_cmd_confusion -endcases; -end - - -@ -@:this can't happen}{\quad Unknown database-file command@> -Here's another bug. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bib_cmd_confusion; -begin -confusion ('Unknown database-file command'); -end; - - -@ -@:database-file commands}{\quad \.{comment}@> -The \.{comment} command is implemented for SCRIBE compatibility. It's -not really needed because \BibTeX\ treats (flushes) everything not -within an entry as a comment anyway. - -@<Process a \.{comment} command@>= -begin -return; {flush comments} -end - - -@ -@:database-file commands}{\quad \.{preamble}@> -The \.{preamble} command lets a user have \TeX\ stuff inserted (by the -standard styles, at least) directly into the \.{.bbl} file. It is -intended primarily for allowing \TeX\ macro definitions used within -the bibliography entries (for better sorting, for example). One -\.{preamble} command per \.{.bib} file should suffice. - -A \.{preamble} command has either braces or parentheses as outer -delimiters. Inside is the preamble string, which has the same syntax -as a field value: a nonempty list of field tokens separated by -|concat_char|s. There are three types of field tokens---nonnegative -numbers, macro names, and delimited strings. - -This module does all the scanning (that's not subcontracted), but the -\.{.bib}-specific scanning function -|scan_and_store_the_field_value_and_eat_white| actually stores the -value. - -@<Process a \.{preamble} command@>= -begin -if (preamble_ptr = max_bib_files) then - bib_err ('You''ve exceeded ',max_bib_files:0,' preamble commands'); -eat_bib_white_and_eof_check; -if (scan_char = left_brace) then - right_outer_delim := right_brace -else if (scan_char = left_paren) then - right_outer_delim := right_paren -else - bib_one_of_two_expected_err (left_brace,left_paren); -incr(buf_ptr2); {skip over the left-delimiter} -eat_bib_white_and_eof_check; -store_field := true; -if (not scan_and_store_the_field_value_and_eat_white) then - return; -if (scan_char <> right_outer_delim) then - bib_err ('Missing "',xchr[right_outer_delim],'" in preamble command'); -incr(buf_ptr2); {skip over the |right_outer_delim|} -return; -end - - -@ -@:database-file commands}{\quad \.{string}@> -The \.{string} command is implemented both for SCRIBE compatibility -and for allowing a user: to override a \.{.bst}-file \.{macro} -command, to define one that the \.{.bst} file doesn't, or to engage in -good, wholesome, typing laziness. - -The \.{string} command does mostly the same thing as the -\.{.bst}-file's \.{macro} command (but the syntax is different and the -\.{string} command compresses |white_space|). In fact, later in this -program, the term ``macro'' refers to either a \.{.bst} ``macro'' or a -\.{.bib} ``string'' (when it's clear from the context that it's not -a \.{WEB} macro). - -A \.{string} command has either braces or parentheses as outer -delimiters. Inside is the string's name (it must be a legal -identifier, and case differences are ignored---all upper-case letters -are converted to lower case), then an |equals_sign|, and the string's -definition, which has the same syntax as a field value: a nonempty -list of field tokens separated by |concat_char|s. There are three -types of field tokens---nonnegative numbers, macro names, and -delimited strings. - -@<Process a \.{string} command@>= -begin -eat_bib_white_and_eof_check; -@<Scan the string's name@>; -eat_bib_white_and_eof_check; -@<Scan the string's definition field@>; -return; -end - - -@ -This module reads a left outer-delimiter and a string name. - -@<Scan the string's name@>= -begin -if (scan_char = left_brace) then - right_outer_delim := right_brace -else if (scan_char = left_paren) then - right_outer_delim := right_paren -else - bib_one_of_two_expected_err (left_brace,left_paren); -incr(buf_ptr2); {skip over the left-delimiter} -eat_bib_white_and_eof_check; -scan_identifier (equals_sign,equals_sign,equals_sign); -bib_identifier_scan_check ('a string name'); -@<Store the string's name@>; -end - - -@ -@^commented-out code@> -This module marks this string as |macro_ilk|; the commented-out code -will give a warning message when overwriting a previously defined -macro. - -@<Store the string's name@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a database-defined macro'); - ecart@/ -lower_case (buffer, buf_ptr1, token_len); {ignore case differences} -cur_macro_loc := str_lookup(buffer,buf_ptr1,token_len,macro_ilk,do_insert); -ilk_info[cur_macro_loc] := hash_text[cur_macro_loc]; {default in case of error} - @{ - if (hash_found) then {already seen macro} - macro_name_warning ('having its definition overwritten'); - @}@/ -end - - -@ -This module skips over the |equals_sign|, reads and stores the list of -field tokens that defines this macro (compressing |white_space|), and -reads a |right_outer_delim|. - -@<Scan the string's definition field@>= -begin -if (scan_char <> equals_sign) then - bib_equals_sign_expected_err; -incr(buf_ptr2); {skip over the |equals_sign|} -eat_bib_white_and_eof_check; -store_field := true; -if (not scan_and_store_the_field_value_and_eat_white) then - return; -if (scan_char <> right_outer_delim) then - bib_err ('Missing "',xchr[right_outer_delim],'" in string command'); -incr(buf_ptr2); {skip over the |right_outer_delim|} -end - - -@ -@^kludge@> -The variables for the function -|scan_and_store_the_field_value_and_eat_white| must be global since -the functions it calls use them too. The alias kludge helps make the -stack space not overflow on some machines. - -@d field_vl_str == ex_buf {aliases, used ``only'' for this function} -@d field_end == ex_buf_ptr {the end marker for the field-value string} -@d field_start == ex_buf_xptr {and the start marker} - -@<Globals in the outer block@>= -@!bib_brace_level : integer; {brace nesting depth (excluding |str_delim|s)} - - -@ -@^gymnastics@> -Since the function |scan_and_store_the_field_value_and_eat_white| -calls several other yet-to-be-described functions (one directly and -two indirectly), we must perform some topological gymnastics. - -@<Procedures and functions for input scanning@>= -@<The scanning function |compress_bib_white|@>@; -@<The scanning function |scan_balanced_braces|@>@; -@<The scanning function |scan_a_field_token_and_eat_white|@> - - -@ -This function scans the list of field tokens that define the field -value string. If |store_field| is |true| it accumulates (indirectly) -in |field_vl_str| the concatenation of all the field tokens, -compressing nonnull |white_space| to a single |space| and, if the -field value is for a field (rather than a string definition), removing -any leading or trailing |white_space|; when it's finished it puts the -string into the hash table. It returns |false| if there was a serious -syntax error. - -@<Procedures and functions for input scanning@>= -function scan_and_store_the_field_value_and_eat_white : boolean; -label exit; -begin -scan_and_store_the_field_value_and_eat_white := false; - {now it's easy to exit if necessary} -field_end := 0; -if (not scan_a_field_token_and_eat_white) then - return; -while (scan_char = concat_char) do {scan remaining field tokens} - begin - incr(buf_ptr2); {skip over the |concat_char|} - eat_bib_white_and_eof_check; - if (not scan_a_field_token_and_eat_white) then - return; - end; -if (store_field) then - @<Store the field value string@>; -scan_and_store_the_field_value_and_eat_white := true; -exit: -end; - - -@ -Each field token is either a nonnegative number, a macro name (like -`jan'), or a brace-balanced string delimited by either |double_quote|s -or braces. Thus there are four possibilities for the first character -of the field token: If it's a |left_brace| or a |double_quote|, the -token (with balanced braces, up to the matching |right_str_delim|) is -a string; if it's |numeric|, the token is a number; if it's anything -else, the token is a macro name (and should thus have been defined by -either the \.{.bst}-file's \.{macro} command or the \.{.bib}-file's -\.{string} command). This function returns |false| if there was a -serious syntax error. - -@<The scanning function |scan_a_field_token_and_eat_white|@>= -function scan_a_field_token_and_eat_white : boolean; -label exit; -begin -scan_a_field_token_and_eat_white := false; {now it's easy to exit if necessary} -case (scan_char) of - left_brace : - begin - right_str_delim := right_brace; - if (not scan_balanced_braces) then - return; - end; - double_quote : - begin - right_str_delim := double_quote; - if (not scan_balanced_braces) then - return; - end; - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" : - @<Scan a number@>; - othercases - @<Scan a macro name@> -endcases; -eat_bib_white_and_eof_check; -scan_a_field_token_and_eat_white := true; -exit: -end; - - -@ -Now we come to the stuff that actually accumulates the field value to -be stored. This module copies a character into |field_vl_str| if it -will fit; since it's so low level, it's implemented as a macro. - -@d copy_char(#) == begin - if (field_end = buf_size) then - bib_field_too_long_err - else - begin - field_vl_str[field_end] := #; - incr(field_end); - end; - end - - -@ -The \.{.bib}-specific scanning function |compress_bib_white| skips -over |white_space| characters within a string until hitting a nonwhite -character; in fact, it does everything |eat_bib_white_space| does, but -it also adds a |space| to |field_vl_str|. This function is never -called if there are no |white_space| characters (or ends-of-line) to -be scanned (though the associated macro might be). The function -returns |false| if there is a serious syntax error. - -@d check_for_and_compress_bib_white_space == - begin - if ((lex_class[scan_char]=white_space) or (buf_ptr2=last)) then - if (not compress_bib_white) then - return; - end - -@<The scanning function |compress_bib_white|@>= -function compress_bib_white : boolean; -label exit; -begin -compress_bib_white := false; {now it's easy to exit if necessary} -copy_char (space); -while (not scan_white_space) do {no characters left; read another line} - begin - if (not input_ln(cur_bib_file)) then {end-of-file; complain} - begin - eat_bib_print; - return; - end; - incr(bib_line_num); - buf_ptr2 := 0; - end; -compress_bib_white := true; -exit: -end; - - -@ -This \.{.bib}-specific function scans a string with balanced braces, -stopping just past the matching |right_str_delim|. How much work it -does depends on whether |store_field = true|. It returns |false| if -there was a serious syntax error. - -@<The scanning function |scan_balanced_braces|@>= -function scan_balanced_braces : boolean; -label loop_exit,@!exit; -begin -scan_balanced_braces := false; {now it's easy to exit if necessary} -incr(buf_ptr2); {skip over the left-delimiter} -check_for_and_compress_bib_white_space; -if (field_end > 1) then - if (field_vl_str[field_end-1] = space) then - if (field_vl_str[field_end-2] = space) then {remove wrongly added |space|} - decr(field_end); -bib_brace_level := 0; {and we're at a non|white_space| character} -if (store_field) then - @<Do a full brace-balanced scan@> - else - @<Do a quick brace-balanced scan@>; -incr(buf_ptr2); {skip over the |right_str_delim|} -scan_balanced_braces := true; -exit: -end; - - -@ -This module scans over a brace-balanced string without keeping track -of anything but the brace level. It starts with |bib_brace_level = 0| -and at a non|white_space| character. - -@<Do a quick brace-balanced scan@>= -begin -while (scan_char <> right_str_delim) do {we're at |bib_brace_level = 0|} - if (scan_char = left_brace) then - begin - incr(bib_brace_level); - incr(buf_ptr2); {skip over the |left_brace|} - eat_bib_white_and_eof_check; - while (bib_brace_level > 0) do - @<Do a quick scan with |bib_brace_level > 0|@>; - end - else if (scan_char = right_brace) then - bib_unbalanced_braces_err - else - begin - incr(buf_ptr2); {skip over some other character} - if (not scan3 (right_str_delim, left_brace, right_brace)) then - eat_bib_white_and_eof_check; - end -end - - -@ -This module does the same as above but, because |bib_brace_level > 0|, it -doesn't have to look for a |right_str_delim|. - -@<Do a quick scan with |bib_brace_level > 0|@>= -begin {top part of the |while| loop---we're always at a nonwhite character} -if (scan_char = right_brace) then - begin - decr(bib_brace_level); - incr(buf_ptr2); {skip over the |right_brace|} - eat_bib_white_and_eof_check; - end -else if (scan_char = left_brace) then - begin - incr(bib_brace_level); - incr(buf_ptr2); {skip over the |left_brace|} - eat_bib_white_and_eof_check; - end -else - begin - incr(buf_ptr2); {skip over some other character} - if (not scan2 (right_brace, left_brace)) then - eat_bib_white_and_eof_check; - end -end - - -@ -This module scans over a brace-balanced string, compressing multiple -|white_space| characters into a single |space|. It starts with -|bib_brace_level = 0| and starts at a non|white_space| character. - -@<Do a full brace-balanced scan@>= -begin -while (scan_char <> right_str_delim) do - case (scan_char) of - left_brace : - begin - incr(bib_brace_level); - copy_char (left_brace);@/ - incr(buf_ptr2); {skip over the |left_brace|} - check_for_and_compress_bib_white_space;@/ - @<Do a full scan with |bib_brace_level > 0|@>; - end; - right_brace : - bib_unbalanced_braces_err; - othercases - begin - copy_char (scan_char); - incr(buf_ptr2); {skip over some other character} - check_for_and_compress_bib_white_space; - end - endcases; -end - - -@ -This module is similar to the last but starts with |bib_brace_level > 0| -(and, like the last, it starts at a non|white_space| character). - -@<Do a full scan with |bib_brace_level > 0|@>= -begin -loop - case (scan_char) of - right_brace : - begin - decr(bib_brace_level); - copy_char (right_brace);@/ - incr(buf_ptr2); {skip over the |right_brace|} - check_for_and_compress_bib_white_space; - if (bib_brace_level = 0) then - goto loop_exit; - end; - left_brace : - begin - incr(bib_brace_level); - copy_char (left_brace);@/ - incr(buf_ptr2); {skip over the |left_brace|} - check_for_and_compress_bib_white_space; - end; - othercases - begin - copy_char (scan_char); - incr(buf_ptr2); {skip over some other character} - check_for_and_compress_bib_white_space; - end - endcases; -loop_exit: -end - - -@ -@:this can't happen}{\quad A digit disappeared@> -This module scans a nonnegative number and copies it to |field_vl_str| -if it's to store the field. - -@<Scan a number@>= -begin -if (not scan_nonneg_integer) then - confusion ('A digit disappeared'); -if (store_field) then - begin - tmp_ptr := buf_ptr1; - while (tmp_ptr < buf_ptr2) do - begin - copy_char (buffer[tmp_ptr]); - incr(tmp_ptr); - end; - end; -end - - -@ -This module scans a macro name and copies its string to |field_vl_str| -if it's to store the field, complaining if the macro is recursive or -undefined. - -@<Scan a macro name@>= -begin -scan_identifier (comma,right_outer_delim,concat_char); -bib_identifier_scan_check ('a field part'); -if (store_field) then - begin - lower_case (buffer, buf_ptr1, token_len); {ignore case differences} - macro_name_loc := str_lookup( - buffer,buf_ptr1,token_len,macro_ilk,dont_insert); - store_token := true; - if (at_bib_command) then - if (command_num = n_bib_string) then - if (macro_name_loc = cur_macro_loc) then - begin - store_token := false; - macro_name_warning ('used in its own definition'); - end; - if (not hash_found) then - begin - store_token := false; - macro_name_warning ('undefined'); - end; - if (store_token) then - @<Copy the macro string to |field_vl_str|@>; - end; -end - - -@ -The macro definition may have |white_space| that needs compressing, -because it may have been defined in the \.{.bst} file. - -@<Copy the macro string to |field_vl_str|@>= -begin -tmp_ptr := str_start[ilk_info[macro_name_loc]]; -tmp_end_ptr := str_start[ilk_info[macro_name_loc]+1]; -if (field_end = 0) then - if ((lex_class[str_pool[tmp_ptr]] = white_space) and (tmp_ptr < tmp_end_ptr)) - then - begin {compress leading |white_space| of first nonnull token} - copy_char (space); - incr(tmp_ptr); - while ((lex_class[str_pool[tmp_ptr]] = white_space) and - (tmp_ptr < tmp_end_ptr)) do - incr(tmp_ptr); - end; {the next remaining character is non|white_space|} -while (tmp_ptr < tmp_end_ptr) do - begin - if (lex_class[str_pool[tmp_ptr]] <> white_space) then - copy_char (str_pool[tmp_ptr]) - else if (field_vl_str[field_end-1] <> space) then - copy_char (space); - incr(tmp_ptr); - end; -end - - -@ -@^ham and eggs@> -Now it's time to store the field value in the hash table, and store an -appropriate pointer to it (depending on whether it's for a database -entry or command). But first, if necessary, we remove a trailing -|space| and a leading |space| if these exist. (Hey, if we had some -ham we could make ham-and-eggs if we had some eggs.) - -@<Store the field value string@>= -begin -if (not at_bib_command) then {chop trailing |space| for a field} - if (field_end > 0) then - if (field_vl_str[field_end-1] = space) then - decr(field_end); -if ((not at_bib_command) and (field_vl_str[0] = space) and (field_end > 0)) - then {chop leading |space| for a field} - field_start := 1 - else - field_start := 0; -field_val_loc := str_lookup(field_vl_str,field_start,field_end-field_start, - text_ilk,do_insert); -fn_type[field_val_loc] := str_literal; {set the |fn_class|} - trace - trace_pr ('"'); - trace_pr_pool_str (hash_text[field_val_loc]); - trace_pr_ln ('" is a field value'); - ecart@/ -if (at_bib_command) then {for a \.{preamble} or \.{string} command} - @<Store the field value for a command@> - else {for a database entry} - @<Store the field value for a database entry@>; -end - - -@ -@:this can't happen}{\quad Unknown database-file command@> -Here's where we store the goods when we're dealing with a command -rather than an entry. - -@<Store the field value for a command@>= -begin -case (command_num) of - n_bib_preamble : - begin - s_preamble[preamble_ptr] := hash_text[field_val_loc]; - incr(preamble_ptr); - end; - n_bib_string : - ilk_info[cur_macro_loc] := hash_text[field_val_loc]; - othercases bib_cmd_confusion -endcases; -end - - -@ -And here, an entry. - -@<Store the field value for a database entry@>= -begin -field_ptr := entry_cite_ptr * num_fields + fn_info[field_name_loc]; -if (field_info[field_ptr] <> missing) then - begin - print ('Warning--I''m ignoring '); - print_pool_str (cite_list[entry_cite_ptr]); - print ('''s extra "'); - print_pool_str (hash_text[field_name_loc]); - bib_warn_newline ('" field'); - end - else - begin {the field was empty, store its new value} - field_info[field_ptr] := hash_text[field_val_loc]; - if ((fn_info[field_name_loc] = crossref_num) and (not all_entries)) then - @<Add or update a cross reference on |cite_list| if necessary@>; - end; -end - - -@ -@^kludge@> -@:this can't happen}{\quad Cite hash error@> -If the cross-referenced entry isn't already on |cite_list| we add it -(at least temporarily); if it is already on |cite_list| we update the -cross-reference count, if necessary. Note that |all_entries| is -|false| here. The alias kludge helps make the stack space not -overflow on some machines. - -@d extra_buf == out_buf {an alias, used only in this module} - -@<Add or update a cross reference on |cite_list| if necessary@>= -begin -tmp_ptr := field_start; -while (tmp_ptr < field_end) do - begin - extra_buf[tmp_ptr] := field_vl_str[tmp_ptr]; - incr(tmp_ptr); - end; -lower_case (extra_buf, field_start, field_end-field_start); - {convert to `canonical' form} -lc_cite_loc := str_lookup(extra_buf,field_start,field_end-field_start, - lc_cite_ilk,do_insert); -if (hash_found) then - begin - cite_loc := ilk_info[lc_cite_loc]; {even if there's a case mismatch} - if (ilk_info[cite_loc] >= old_num_cites) then {a previous \.{crossref}} - incr(cite_info[ilk_info[cite_loc]]); - end - else - begin {it's a new \.{crossref}} - cite_loc := str_lookup(field_vl_str,field_start,field_end-field_start, - cite_ilk,do_insert); - if (hash_found) then - hash_cite_confusion; - add_database_cite (cite_ptr); {this increments |cite_ptr|} - cite_info[ilk_info[cite_loc]] := 1; {the first cross-ref for this cite key} - end; -end - - -@ -This procedure adds (or restores) to |cite_list| a cite key; it is -called only when |all_entries| is |true| or when adding -cross~references, and it assumes that |cite_loc| and |lc_cite_loc| are -set. It also increments its argument. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure add_database_cite (var new_cite : cite_number); -begin -check_cite_overflow (new_cite); {make sure this cite will fit} -check_field_overflow (num_fields*new_cite); -cite_list[new_cite] := hash_text[cite_loc]; -ilk_info[cite_loc] := new_cite; -ilk_info[lc_cite_loc] := cite_loc; -incr(new_cite); -end; - - -@ -And now, back to processing an entry (rather than a command). This -module reads a left outer-delimiter and a database key. - -@<Scan the entry's database key@>= -begin -if (scan_char = left_brace) then - right_outer_delim := right_brace -else if (scan_char = left_paren) then - right_outer_delim := right_paren -else - bib_one_of_two_expected_err (left_brace,left_paren); -incr(buf_ptr2); {skip over the left-delimiter} -eat_bib_white_and_eof_check; -if (right_outer_delim = right_paren) then {to allow it in a database key} - begin - if (scan1_white(comma)) then {ok if database key ends line} - do_nothing; - end - else - if (scan2_white(comma,right_brace)) then {|right_brace=right_outer_delim|} - do_nothing; -@<Check for a database key of interest@>; -end - - -@ -@^kludge@> -The lower-case version of this database key must correspond to one in -|cite_list|, or else |all_entries| must be |true|, if this entry is to -be included in the reference list. Accordingly, this module sets -|store_entry|, which determines whether the relevant information for -this entry is stored. The alias kludge helps make the stack space not -overflow on some machines. - -@d ex_buf3 == ex_buf {an alias, used only in this module} - -@<Check for a database key of interest@>= -begin - trace - trace_pr_token; - trace_pr_ln (' is a database key'); - ecart@/ -tmp_ptr := buf_ptr1; -while (tmp_ptr < buf_ptr2) do - begin - ex_buf3[tmp_ptr] := buffer[tmp_ptr]; - incr(tmp_ptr); - end; -lower_case (ex_buf3, buf_ptr1, token_len); {convert to `canonical' form} -if (all_entries) then - lc_cite_loc := str_lookup(ex_buf3,buf_ptr1,token_len,lc_cite_ilk,do_insert) - else - lc_cite_loc := str_lookup(ex_buf3,buf_ptr1,token_len,lc_cite_ilk, - dont_insert); -if (hash_found) then - begin - entry_cite_ptr := ilk_info[ilk_info[lc_cite_loc]]; - @<Check for a duplicate or \.{crossref}-matching database key@>; - end; -store_entry := true; {unless |(not hash_found) and (not all_entries)|} -if (all_entries) then - @<Put this cite key in its place@> - else if (not hash_found) then - store_entry := false; {no such cite key exists on |cite_list|} -if (store_entry) then - @<Make sure this entry is ok before proceeding@>; -end - - -@ -@:this can't happen}{\quad The cite list is messed up@> -It's illegal to have two (or more) entries with the same database key -(even if there are case differrences), and we skip the rest of the -entry for such a repeat occurrence. Also, we make this entry's -database key the official |cite_list| key if it's on |cite_list| only -because of cross references. - -@<Check for a duplicate or \.{crossref}-matching database key@>= -begin -if ((not all_entries) or (entry_cite_ptr < all_marker) - or (entry_cite_ptr >= old_num_cites)) then - begin - if (type_list[entry_cite_ptr] = empty) then - begin - @<Make sure this entry's database key is on |cite_list|@>; - goto first_time_entry; - end; - end -else if (not entry_exists[entry_cite_ptr]) then - begin - @<Find the lower-case equivalent of the |cite_info| key@>; - if (lc_xcite_loc = lc_cite_loc) then - goto first_time_entry; - end;@/ - {oops---repeated entry---issue a reprimand} -if (type_list[entry_cite_ptr] = empty) then - confusion ('The cite list is messed up'); -bib_err ('Repeated entry'); -first_time_entry: {note that when we leave normally, |hash_found| is |true|} -end - - -@ -An entry that's on |cite_list| only because of cross referencing must -have its database key (rather than one of the \.{crossref} keys) as -the official |cite_list| string. Here's where we assure that. The -variable |hash_found| is |true| upon entrance to and exit from this -module. - -@<Make sure this entry's database key is on |cite_list|@>= -begin -if ((not all_entries) and (entry_cite_ptr >= old_num_cites)) then - begin - cite_loc := str_lookup(buffer,buf_ptr1,token_len,cite_ilk,do_insert); - if (not hash_found) then - begin {it's not on |cite_list|---put it there} - ilk_info[lc_cite_loc] := cite_loc; - ilk_info[cite_loc] := entry_cite_ptr; - cite_list[entry_cite_ptr] := hash_text[cite_loc];@/ - hash_found := true; {restore this value for later use} - end; - end; -end - - -@ -@^kludge@> -@:this can't happen}{\quad A cite key disappeared@> -This module, a simpler version of the -|find_cite_locs_for_this_cite_key| function, exists primarily to -compute |lc_xcite_loc|. When this code is executed we have -|(all_entries) and (entry_cite_ptr >= all_marker) and (not -entry_exists[entry_cite_ptr])|. The alias kludge helps make the stack -space not overflow on some machines. - -@d ex_buf4 == ex_buf {aliases, used only} -@d ex_buf4_ptr == ex_buf_ptr {in this module} - -@<Find the lower-case equivalent of the |cite_info| key@>= -begin -ex_buf4_ptr := 0; -tmp_ptr := str_start[cite_info[entry_cite_ptr]]; -tmp_end_ptr := str_start[cite_info[entry_cite_ptr]+1]; -while (tmp_ptr < tmp_end_ptr) do - begin - ex_buf4[ex_buf4_ptr] := str_pool[tmp_ptr]; - incr(ex_buf4_ptr); - incr(tmp_ptr); - end; -lower_case (ex_buf4, 0, length(cite_info[entry_cite_ptr])); - {convert to `canonical' form} -lc_xcite_loc := str_lookup(ex_buf4,0,length(cite_info[entry_cite_ptr]), - lc_cite_ilk,dont_insert); -if (not hash_found) then - cite_key_disappeared_confusion; -end - - -@ -@:this can't happen}{\quad A cite key disappeared@> -Here's another bug complaint. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure cite_key_disappeared_confusion; -begin -confusion ('A cite key disappeared'); -end; - - -@ -@:this can't happen}{\quad Cite hash error@> -This module, which gets executed only when |all_entries| is |true|, -does one of three things, depending on whether or not, and where, the -cite key appears on |cite_list|: If it's on |cite_list| before -|all_marker|, there's nothing to be done; if it's after |all_marker|, -it must be reinserted (at the current place) and we must note that its -corresponding entry exists; and if it's not on |cite_list| at all, it -must be inserted for the first time. The |goto| construct must stay -as is, partly because some \PASCAL\ compilers might complain if -``|and|'' were to connect the two boolean expressions (since -|entry_cite_ptr| could be uninitialized when |hash_found| is |false|). - -@<Put this cite key in its place@>= -begin -if (hash_found) then - begin - if (entry_cite_ptr < all_marker) then - goto cite_already_set {that is, do nothing} - else - begin - entry_exists[entry_cite_ptr] := true; - cite_loc := ilk_info[lc_cite_loc]; - end; - end - else - begin {this is a new key} - cite_loc := str_lookup(buffer,buf_ptr1,token_len,cite_ilk,do_insert); - if (hash_found) then - hash_cite_confusion; - end;@/ -entry_cite_ptr := cite_ptr; -add_database_cite (cite_ptr); {this increments |cite_ptr|} -cite_already_set: -end - - -@ -@^case mismatch errors@> -@^commented-out code@> -We must give a warning if this entry~type doesn't exist. Also, we -point the appropriate entry of |type_list| to the entry type just read -above. - -For SCRIBE compatibility, the code to give a warning for a case -mismatch between a cite key and a database key has been commented out. -In fact, SCRIBE is the reason that it doesn't produce an error message -outright. (Note: Case mismatches between two cite keys produce -full-blown errors.) - -@<Make sure this entry is ok before proceeding@>= -begin - @{ - dummy_loc := str_lookup(buffer,buf_ptr1,token_len,cite_ilk,dont_insert); - if (not hash_found) then {give a warning if there is a case difference} - begin - print ('Warning--case mismatch, database key "'); - print_token; - print ('", cite key "'); - print_pool_str (cite_list[entry_cite_ptr]); - bib_warn_newline ('"'); - end; - @}@/ -if (type_exists) then - type_list[entry_cite_ptr] := entry_type_loc - else - begin - type_list[entry_cite_ptr] := undefined; - print ('Warning--entry type for "'); - print_token; - bib_warn_newline ('" isn''t style-file defined'); - end; -end - - -@ -This module reads a |comma| and a field as many times as it can, and -then reads a |right_outer_delim|, ending the current entry. - -@<Scan the entry's list of fields@>= -begin -while (scan_char <> right_outer_delim) do - begin - if (scan_char <> comma) then - bib_one_of_two_expected_err (comma,right_outer_delim); - incr(buf_ptr2); {skip over the |comma|} - eat_bib_white_and_eof_check; - if (scan_char = right_outer_delim) then - goto loop_exit; - @<Get the next field name@>; - eat_bib_white_and_eof_check; - if (not scan_and_store_the_field_value_and_eat_white) then - return; - end; -loop_exit: -incr(buf_ptr2); {skip over the |right_outer_delim|} -end - - -@ -This module reads a field name; its contents won't be stored unless it -was declared in the \.{.bst} file and |store_entry = true|. - -@<Get the next field name@>= -begin -scan_identifier (equals_sign,equals_sign,equals_sign); -bib_identifier_scan_check ('a field name'); - trace - trace_pr_token; - trace_pr_ln (' is a field name'); - ecart@/ -store_field := false; -if (store_entry) then - begin - lower_case (buffer, buf_ptr1, token_len); {ignore case differences} - field_name_loc := str_lookup( - buffer,buf_ptr1,token_len,bst_fn_ilk,dont_insert); - if (hash_found) then - if (fn_type[field_name_loc]=field) then@/ - store_field := true; {field name was pre-defined or \.{.bst}-declared} - end; -eat_bib_white_and_eof_check; -if (scan_char <> equals_sign) then - bib_equals_sign_expected_err; -incr(buf_ptr2); {skip over the |equals_sign|} -end - - -@ -This gets things ready for further \.{.bst} processing. - -@<Final initialization for processing the entries@>= -begin -num_cites := cite_ptr; {to include database and \.{crossref} cite keys, too} -num_preamble_strings := preamble_ptr; {number of \.{preamble} commands seen} -@<Add cross-reference information@>; -@<Subtract cross-reference information@>; -@<Remove missing entries or those cross referenced too few times@>; -@<Initialize the |int_entry_var|s@>; -@<Initialize the |str_entry_var|s@>; -@<Initialize the |sorted_cites|@>; -end - - -@ -@^child entry@> -@^cross references@> -@^nested cross references@> -@^parent entry@> -Now we update any entry (here called a {\it child\/} entry) that -cross~referenced another (here called a {\it parent\/} entry); this -cross~referencing occurs when the child's \.{crossref} field (value) -consists of the parent's database key. To do the update, we replace -the child's |missing| fields by the corresponding fields of the -parent. Also, we make sure the \.{crossref} field contains the -case-correct version. Finally, although it is technically illegal to -nest cross~references, and although we give a warning (a few modules -hence) when someone tries, we do what we can to accommodate the -attempt. - -@<Add cross-reference information@>= -begin -cite_ptr := 0; -while (cite_ptr < num_cites) do - begin - field_ptr := cite_ptr * num_fields + crossref_num; - if (field_info[field_ptr] <> missing) then - if (find_cite_locs_for_this_cite_key (field_info[field_ptr])) then - begin - cite_loc := ilk_info[lc_cite_loc]; - field_info[field_ptr] := hash_text[cite_loc]; - cite_parent_ptr := ilk_info[cite_loc]; - field_ptr := cite_ptr * num_fields + num_pre_defined_fields; - field_end_ptr := field_ptr - num_pre_defined_fields + num_fields; - field_parent_ptr := cite_parent_ptr * num_fields - + num_pre_defined_fields; - while (field_ptr < field_end_ptr) do - begin - if (field_info[field_ptr] = missing) then - field_info[field_ptr] := field_info[field_parent_ptr]; - incr(field_ptr); - incr(field_parent_ptr); - end; - end; - incr(cite_ptr); - end; -end - - -@ -@^kludge@> -@^raisin@> -Occasionally we need to figure out the hash-table location of a given -cite-key string and its lower-case equivalent. This function does -that. To perform the task it needs to borrow a buffer, a need that -gives rise to the alias kludge---it helps make the stack space not -overflow on some machines (and while it's at it, it'll borrow a -pointer, too). Finally, the function returns |true| if the cite key -exists on |cite_list|, and its sets |cite_hash_found| according to -whether or not it found the actual version (before |lower_case|ing) of -the cite key; however, its {\sl raison d'\^$\mkern-8mu$etre\/} -(literally, ``to eat a raisin'') is to compute |cite_loc| and -|lc_cite_loc|. - -@d ex_buf5 == ex_buf {aliases, used only} -@d ex_buf5_ptr == ex_buf_ptr {in this module} - -@<Procedures and functions for handling numbers, characters, and strings@>= -function find_cite_locs_for_this_cite_key (@!cite_str : str_number) : boolean; -begin -ex_buf5_ptr := 0; -tmp_ptr := str_start[cite_str]; -tmp_end_ptr := str_start[cite_str+1]; -while (tmp_ptr < tmp_end_ptr) do - begin - ex_buf5[ex_buf5_ptr] := str_pool[tmp_ptr]; - incr(ex_buf5_ptr); - incr(tmp_ptr); - end; -cite_loc := str_lookup(ex_buf5,0,length(cite_str),cite_ilk,dont_insert); -cite_hash_found := hash_found; -lower_case (ex_buf5, 0, length(cite_str)); {convert to `canonical' form} -lc_cite_loc := str_lookup(ex_buf5,0,length(cite_str),lc_cite_ilk,dont_insert); -if (hash_found) then - find_cite_locs_for_this_cite_key := true - else - find_cite_locs_for_this_cite_key := false; -end; - - -@ -@:this can't happen}{\quad Cite hash error@> -Here we remove the \.{crossref} field value for each child whose -parent was cross~referenced too few times. We also issue any -necessary warnings arising from a bad cross~reference. - -@<Subtract cross-reference information@>= -begin -cite_ptr := 0; -while (cite_ptr < num_cites) do - begin - field_ptr := cite_ptr * num_fields + crossref_num; - if (field_info[field_ptr] <> missing) then - if (not find_cite_locs_for_this_cite_key (field_info[field_ptr])) then - begin {the parent is not on |cite_list|} - if (cite_hash_found) then - hash_cite_confusion; - nonexistent_cross_reference_error; - field_info[field_ptr] := missing; {remove the \.{crossref} ptr} - end - else - begin {the parent exists on |cite_list|} - if (cite_loc <> ilk_info[lc_cite_loc]) then - hash_cite_confusion; - cite_parent_ptr := ilk_info[cite_loc]; - if (type_list[cite_parent_ptr] = empty) then - begin - nonexistent_cross_reference_error;@/ - field_info[field_ptr] := missing; {remove the \.{crossref} ptr} - end - else - begin {the parent exists in the database too} - field_parent_ptr := cite_parent_ptr * num_fields + crossref_num; - if (field_info[field_parent_ptr] <> missing) then - @<Complain about a nested cross reference@>; - if ((not all_entries) and (cite_parent_ptr >= old_num_cites) and - (cite_info[cite_parent_ptr] < min_crossrefs)) then@/ - field_info[field_ptr] := missing; {remove the \.{crossref} ptr} - end; - end; - incr(cite_ptr); - end; -end - - -@ -This procedure exists to save space, since it's used twice---once for -each of the two succeeding modules. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bad_cross_reference_print (@!s:str_number); -begin -print ('--entry "'); -print_pool_str (cur_cite_str); -print_ln ('"'); -print ('refers to entry "'); -print_pool_str (s); -end; - - -@ -When an entry being cross referenced doesn't exist on |cite_list|, we -complain. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure nonexistent_cross_reference_error; -begin -print ('A bad cross reference-'); -bad_cross_reference_print (field_info[field_ptr]); -print_ln ('", which doesn''t exist'); -mark_error; -end; - - -@ -We also complain when an entry being cross referenced has a -non|missing| \.{crossref} field itself, but this one is just a -warning, not a full-blown error. - -@<Complain about a nested cross reference@>= -begin -print ('Warning--you''ve nested cross references'); -bad_cross_reference_print (cite_list[cite_parent_ptr]); -print_ln ('", which also refers to something'); -mark_warning; -end - - -@ -We remove (and give a warning for) each cite key on the original -|cite_list| without a corresponding database entry. And we remove any -entry that was included on |cite_list| only because it was -cross~referenced, yet was cross~referenced fewer than |min_crossrefs| -times. Throughout this module, |cite_ptr| points to the next cite key -to be checked and |cite_xptr| points to the next permanent spot on -|cite_list|. - -@<Remove missing entries or those cross referenced too few times@>= -begin -cite_ptr := 0; -while (cite_ptr < num_cites) do - begin - if (type_list[cite_ptr] = empty) then - print_missing_entry (cur_cite_str) - else if ((all_entries) or (cite_ptr < old_num_cites) or - (cite_info[cite_ptr] >= min_crossrefs)) then - begin - if (cite_ptr > cite_xptr) then - @<Slide this cite key down to its permanent spot@>; - incr(cite_xptr); - end; - incr(cite_ptr); - end; -num_cites := cite_xptr; -if (all_entries) then - @<Complain about missing entries whose cite keys got overwritten@>; -end - - -@ -When a cite key on the original |cite_list| (or added to |cite_list| -because of cross~referencing) didn't appear in the database, complain. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_missing_entry (@!s:str_number); -begin -print ('Warning--I didn''t find a database entry for "'); -print_pool_str (s); -print_ln ('"'); -mark_warning; -end; - - -@ -@:this can't happen}{\quad A cite key disappeared@> -@:this can't happen}{\quad Cite hash error@> -We have to move to its final resting place all the entry information -associated with the exact location in |cite_list| of this cite key. - -@<Slide this cite key down to its permanent spot@>= -begin -cite_list[cite_xptr] := cite_list[cite_ptr]; -type_list[cite_xptr] := type_list[cite_ptr]; -if (not find_cite_locs_for_this_cite_key (cite_list[cite_ptr])) then - cite_key_disappeared_confusion; -if ((not cite_hash_found) or (cite_loc <> ilk_info[lc_cite_loc])) then - hash_cite_confusion; -ilk_info[cite_loc] := cite_xptr;@/ -field_ptr := cite_xptr * num_fields; -field_end_ptr := field_ptr + num_fields; -tmp_ptr := cite_ptr * num_fields; -while (field_ptr < field_end_ptr) do - begin - field_info[field_ptr] := field_info[tmp_ptr]; - incr(field_ptr); - incr(tmp_ptr); - end; -end - - -@ -We need this module only when we're including the whole database. -It's for missing entries whose cite key originally resided in -|cite_list| at a spot that another cite key (might have) claimed. - -@<Complain about missing entries whose cite keys got overwritten@>= -begin -cite_ptr := all_marker; -while (cite_ptr < old_num_cites) do - begin - if (not entry_exists[cite_ptr]) then - print_missing_entry (cite_info[cite_ptr]); - incr(cite_ptr); - end; -end - - -@ -@:BibTeX capacity exceeded}{\quad total number of integer entry-variables@> -This module initializes all |int_entry_var|s of all entries to 0, the -value to which all integers are initialized. - -@<Initialize the |int_entry_var|s@>= -begin -if (num_ent_ints*num_cites > max_ent_ints) then - begin - print (num_ent_ints*num_cites,': '); - overflow('total number of integer entry-variables ',max_ent_ints); - end; -int_ent_ptr := 0; -while (int_ent_ptr < num_ent_ints*num_cites) do - begin - entry_ints[int_ent_ptr] := 0; - incr(int_ent_ptr); - end; -end - - -@ -@:BibTeX capacity exceeded}{\quad total number of string entry-variables@> -This module initializes all |str_entry_var|s of all entries to the -null string, the value to which all strings are initialized. - -@<Initialize the |str_entry_var|s@>= -begin -if (num_ent_strs*num_cites > max_ent_strs) then - begin - print (num_ent_strs*num_cites,': '); - overflow('total number of string entry-variables ',max_ent_strs); - end; -str_ent_ptr := 0; -while (str_ent_ptr < num_ent_strs*num_cites) do - begin - entry_strs[str_ent_ptr][0] := end_of_string; - incr(str_ent_ptr); - end; -end - - -@ -The array |sorted_cites| initially specifies that the entries are to -be processed in order of cite-key occurrence. The \.{sort} command -may change this to whatever it likes (which, we hope, is whatever the -style-designer instructs it to like). We make |sorted_cites| an alias -to save space; this works fine because we're done with |cite_info|. - -@d sorted_cites == cite_info {an alias used for the rest of the program} - -@<Initialize the |sorted_cites|@>= -begin -cite_ptr := 0; -while (cite_ptr < num_cites) do - begin - sorted_cites[cite_ptr] := cite_ptr; - incr(cite_ptr); - end; -end - - - -@* Executing the style file. -This part of the program produces the output by executing the -\.{.bst}-file commands \.{execute}, \.{iterate}, \.{reverse}, and -\.{sort}. To do this it uses a stack (consisting of the two arrays -|lit_stack| and |lit_stk_type|) for storing literals, a buffer -|ex_buf| for manipulating strings, and an array |sorted_cites| -for holding pointers to the sorted cite keys (|sorted_cites| is an -alias of |cite_info|). - -@<Globals in the outer block@>= -@!lit_stack : array[lit_stk_loc] of integer; {the literal function stack} -@!lit_stk_type : array[lit_stk_loc] of stk_type; {their corresponding types} -@!lit_stk_ptr : lit_stk_loc; {points just above the top of the stack} -@!cmd_str_ptr : str_number; {stores value of |str_ptr| during execution} -@!ent_chr_ptr : 0..ent_str_size; {points at a |str_entry_var| character} -@!glob_chr_ptr : 0..glob_str_size; {points at a |str_global_var| character} -@!ex_buf : buf_type; {a buffer for manipulating strings} -@!ex_buf_ptr : buf_pointer; {general |ex_buf| location} -@!ex_buf_length : buf_pointer; {the length of the current string in |ex_buf|} -@!out_buf : buf_type; {the \.{.bbl} output buffer} -@!out_buf_ptr : buf_pointer; {general |out_buf| location} -@!out_buf_length : buf_pointer; {the length of the current string in |out_buf|} -@!mess_with_entries : boolean; {|true| if functions can use entry info} -@!sort_cite_ptr : cite_number; {a loop index for the sorted cite keys} -@!sort_key_num : str_ent_loc; {index for the |str_entry_var| \.{sort.key\$}} -@!brace_level : integer; {the brace nesting depth within a string} - - -@ -Where |lit_stk_loc| is a stack location, and where |stk_type| gives -one of the three types of literals (an integer, a string, or a -function) or a special marker. If a |lit_stk_type| element is a -|stk_int| then the corresponding |lit_stack| element is an integer; if -a |stk_str|, then a pointer to a |str_pool| string; and if a |stk_fn|, -then a pointer to the function's hash-table location. However, if the -literal should have been a |stk_str| that was the value of a field -that happened to be |missing|, then the special value -|stk_field_missing| goes on the stack instead; its corresponding -|lit_stack| element is a pointer to the field-name's string. Finally, -|stk_empty| is the type of a literal popped from an empty stack. - -@d stk_int = 0 {an integer literal} -@d stk_str = 1 {a string literal} -@d stk_fn = 2 {a function literal} -@d stk_field_missing = 3 {a special marker: a field value was missing} -@d stk_empty = 4 {another: the stack was empty when this was popped} -@d last_lit_type = 4 {the same number as on the line above} - -@<Types in the outer block@>= -@!lit_stk_loc = 0..lit_stk_size; {the stack range} -@!stk_type = 0..last_lit_type; {the literal types} - - -@ -And the first output line requires this initialization. - -@<Set initial values of key variables@>= -out_buf_length := 0; - - -@ -When there's an error while executing \.{.bst} functions, what we do -depends on whether the function is messing with the entries. -Furthermore this error is serious enough to classify as an -|error_message| instead of a |warning_message|. These messages (that -is, from |bst_ex_warn|) are meant both for the user and for the style -designer while debugging. - -@d bst_ex_warn(#) == begin {error while executing some function} - print (#); - bst_ex_warn_print; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_ex_warn_print; -begin -if (mess_with_entries) then - begin - print (' for entry '); - print_pool_str (cur_cite_str); - end; -print_newline; -print ('while executing-'); -bst_ln_num_print; -mark_error; -end; - - -@ -When an error is so harmless, we print a |warning_message| instead of -an |error_message|. - -@d bst_mild_ex_warn(#) == begin {error while executing some function} - print (#); - bst_mild_ex_warn_print; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_mild_ex_warn_print; -begin -if (mess_with_entries) then - begin - print (' for entry '); - print_pool_str (cur_cite_str); - end; -print_newline; -bst_warn ('while executing'); {This does the |mark_warning|} -end; - - -@ -It's illegal to mess with the entry information at certain times; -here's a complaint for these times. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_cant_mess_with_entries_print; -begin -bst_ex_warn ('You can''t mess with entries here'); -end; - - -@ -This module executes a single specified function once. It can't do -anything with the entries. - -@<Perform an \.{execute} command@>= -begin -init_command_execution; -mess_with_entries := false; -execute_fn (fn_loc); -check_command_execution; -end - - -@ -This module iterates a single specified function for all entries -specified by |cite_list|. - -@<Perform an \.{iterate} command@>= -begin -init_command_execution; -mess_with_entries := true; -sort_cite_ptr := 0; -while (sort_cite_ptr < num_cites) do - begin - cite_ptr := sorted_cites[sort_cite_ptr]; - trace - trace_pr_pool_str (hash_text[fn_loc]); - trace_pr (' to be iterated on '); - trace_pr_pool_str (cur_cite_str); - trace_pr_newline; - ecart@/ - execute_fn (fn_loc); - check_command_execution; - incr(sort_cite_ptr); - end; -end - - -@ -This module iterates a single specified function for all entries -specified by |cite_list|, but does it in reverse order. - -@<Perform a \.{reverse} command@>= -begin -init_command_execution; -mess_with_entries := true; -if (num_cites > 0) then - begin - sort_cite_ptr := num_cites; - repeat - decr(sort_cite_ptr); - cite_ptr := sorted_cites[sort_cite_ptr]; - trace - trace_pr_pool_str (hash_text[fn_loc]); - trace_pr (' to be iterated in reverse on '); - trace_pr_pool_str (cur_cite_str); - trace_pr_newline; - ecart@/ - execute_fn (fn_loc); - check_command_execution; - until (sort_cite_ptr = 0); - end; -end - - -@ -This module sorts the entries based on \.{sort.key\$}; it is a stable -sort. - -@<Perform a \.{sort} command@>= -begin - trace - trace_pr_ln ('Sorting the entries'); - ecart@/ -if (num_cites > 1) then - quick_sort (0, num_cites-1); - trace - trace_pr_ln ('Done sorting'); - ecart@/ -end - - -@ -These next two procedures (actually, one procedures and one function, -but who's counting) are subroutines for |quick_sort|, which follows. -The |swap| procedure exchanges the two elements its arguments point -to. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure swap (@!swap1,@!swap2 : cite_number); -var innocent_bystander : cite_number; {the temporary element in an exchange} -begin -innocent_bystander := sorted_cites[swap2]; -sorted_cites[swap2] := sorted_cites[swap1]; -sorted_cites[swap1] := innocent_bystander; -end; - - -@ -@:this can't happen}{\quad Duplicate sort key@> -The function |less_than| compares the two \.{sort.key\$}s indirectly -pointed to by its arguments and returns |true| if the first argument's -\.{sort.key\$} is lexicographically less than the second's (that is, -alphabetically earlier). In case of ties the function compares the -indices |arg1| and |arg2|, which are assumed to be different, and -returns |true| if the first is smaller. This function uses -|ASCII_code|s to compare, so it might give ``interesting'' results -when handling nonletters. - -@d compare_return(#) == begin {the compare is finished} - less_than := #; - return; - end - -@<Procedures and functions for handling numbers, characters, and strings@>= -function less_than (@!arg1,@!arg2 : cite_number) : boolean; -label exit; -var char_ptr : 0..ent_str_size; {character index into compared strings} - @!ptr1,@!ptr2 : str_ent_loc; {the two \.{sort.key\$} pointers} - @!char1,@!char2 : ASCII_code; {the two characters being compared} -begin -ptr1 := arg1*num_ent_strs + sort_key_num; -ptr2 := arg2*num_ent_strs + sort_key_num; -char_ptr := 0; -loop - begin - char1 := entry_strs[ptr1][char_ptr]; - char2 := entry_strs[ptr2][char_ptr]; - if (char1 = end_of_string) then - if (char2 = end_of_string) then - if (arg1 < arg2) then - compare_return (true) - else if (arg1 > arg2) then - compare_return (false) - else {|arg1 = arg2|} - confusion ('Duplicate sort key') - else {|char2 <> end_of_string|} - compare_return (true) - else {|char1 <> end_of_string|} - if (char2 = end_of_string) then - compare_return (false) - else if (char1 < char2) then - compare_return (true) - else if (char1 > char2) then - compare_return (false); - incr(char_ptr); - end; -exit: -end; - - -@ -The recursive procedure |quick_sort| sorts the entries indirectly -pointed to by the |sorted_cites| elements between |left_end| and -|right_end|, inclusive, based on the value of the |str_entry_var| -\.{sort.key\$}. It's a fairly standard quicksort (for example, see -Algorithm 5.2.2Q in {\sl The Art of Computer Programming}), but uses -the median-of-three method to choose the partition element just in -case the entries are already sorted (or nearly sorted---humans and -ASCII might have different ideas on lexicographic ordering); it is a -stable sort. This code generally prefers clarity to assembler-type -execution-time efficiency since |cite_list|s will rarely be huge. - -The value |short_list|, which must be at least |2*end_offset + 2| for -this code to work, tells us the list-length at which the list is small -enough to warrant switching over to straight insertion sort from the -recursive quicksort. The values here come from modest empirical tests -aimed at minimizing, for large |cite_list|s (five hundred or so), the -number of comparisons (between keys) plus the number of calls to -|quick_sort|. The value |end_offset| must be positive; this helps -avoid $n^2$ behavior observed when the list starts out nearly, but not -completely, sorted (and fairly frequently large |cite_list|s come from -entire databases, which fairly frequently are nearly sorted). - -@d short_list = 10 {use straight insertion sort at or below this length} -@d end_offset = 4 {the index end-offsets for choosing a median-of-three} - -@<Check the ``constant'' values for consistency@>= -if (short_list < 2*end_offset + 2) then bad:=100*bad+22; - - -@ -Here's the actual procedure. - -@d next_insert = 24 {now insert the next element} - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure quick_sort (@!left_end,@!right_end : cite_number); -label next_insert; -var left,@!right : cite_number; {two general |sorted_cites| pointers} - @!insert_ptr : cite_number; {the to-be-(straight)-inserted element} - @!middle : cite_number; {the |(left_end+right_end) div 2| element} - @!partition : cite_number; {the median-of-three partition element} -begin - trace - trace_pr_ln ('Sorting ',left_end:0,' through ',right_end:0); - ecart@/ -if (right_end - left_end < short_list) then - @<Do a straight insertion sort@> - else - begin - @<Draw out the median-of-three partition element@>; - @<Do the partitioning and the recursive calls@>; - end; -end; - - -@ -This code sorts the entries between |left_end| and |right_end| when -the difference is less than |short_list|. Each iteration of the outer -loop inserts the element indicated by |insert_ptr| into its proper -place among the (sorted) elements from |left_end| through -|insert_ptr-1|. - -@<Do a straight insertion sort@>= -begin -for insert_ptr := left_end+1 to right_end do - begin - for right := insert_ptr downto left_end+1 do - begin - if (less_than (sorted_cites[right-1], sorted_cites[right])) then - goto next_insert; - swap (right-1, right); - end; -next_insert: - end; -end - - -@ -Now we find the median of the three \.{sort.key\$}s to which the three -elements |sorted_cites[left_end+end_offset]|, -|sorted_cites[right_end]-end_offset|, and -|sorted_cites[(left_end+right_end) div 2]| point (a nonzero -|end_offset| avoids using as the leftmost of the three elements the -one that was swapped there when the old partition element was swapped -into its final spot; this turns out to avoid $n^2$ behavior when the -list is nearly sorted to start with). This code determines which of -the six possible permutations we're dealing with and moves the median -element to |left_end|. The comments next to the |swap| actions give -the known orderings of the corresponding elements of |sorted_cites| -before the action. - -@<Draw out the median-of-three partition element@>= -begin -left := left_end + end_offset; -middle := (left_end+right_end) div 2; -right := right_end - end_offset; -if (less_than (sorted_cites[left], sorted_cites[middle])) then - if (less_than (sorted_cites[middle], sorted_cites[right])) then - {|left < middle < right|} - swap(left_end,middle) - else if (less_than (sorted_cites[left], sorted_cites[right])) then - {|left < right < middle|} - swap(left_end,right) - else {|right < left < middle|} - swap(left_end,left) - else if (less_than (sorted_cites[right], sorted_cites[middle])) then - {|right < middle < left|} - swap(left_end,middle) - else if (less_than (sorted_cites[right], sorted_cites[left])) then - {|middle < right < left|} - swap(left_end,right) - else {|middle < left < right|} - swap(left_end,left); -end - - -@ -This module uses the median-of-three computed above to partition the -elements into those less than and those greater than the median. -Equal \.{sort.key\$}s are sorted by order of occurrence (in -|cite_list|). - -@<Do the partitioning and the recursive calls@>= -begin -partition := sorted_cites[left_end]; -left := left_end + 1; -right := right_end; -repeat - while (less_than (sorted_cites[left], partition)) do - incr(left); - while (less_than (partition, sorted_cites[right])) do - decr(right); - {now |sorted_cites[right] < partition < sorted_cites[left]|} - if (left < right) then - begin - swap (left,right); - incr(left); - decr(right); - end; -until (left = right+1); {pointers have crossed} -swap (left_end,right);{restoring the partition element to its |right|ful place} -quick_sort (left_end,right-1); -quick_sort (left,right_end); -end - - -@ -@:BibTeX capacity exceeded}{\quad literal-stack size@> -@:this can't happen}{\quad Unknown literal type@> -Ok, that's it for sorting; now we'll play with the literal stack. -This procedure pushes a literal onto the stack, checking for stack -overflow. - -@<Procedures and functions for style-file function execution@>= -procedure push_lit_stk (@!push_lt:integer; @!push_type:stk_type); - trace - var dum_ptr : lit_stk_loc; {used just as an index variable} - ecart@/ -begin -lit_stack[lit_stk_ptr] := push_lt; -lit_stk_type[lit_stk_ptr] := push_type; - trace - for dum_ptr := 0 to lit_stk_ptr do - trace_pr (' '); - trace_pr ('Pushing '); - case (lit_stk_type[lit_stk_ptr]) of - stk_int : trace_pr_ln (lit_stack[lit_stk_ptr]:0); - stk_str : begin - trace_pr ('"'); - trace_pr_pool_str (lit_stack[lit_stk_ptr]); - trace_pr_ln ('"'); - end; - stk_fn : begin - trace_pr ('`'); - trace_pr_pool_str (hash_text[lit_stack[lit_stk_ptr]]); - trace_pr_ln (''''); - end; - stk_field_missing : begin - trace_pr ('missing field `'); - trace_pr_pool_str (lit_stack[lit_stk_ptr]); - trace_pr_ln (''''); - end; - stk_empty : trace_pr_ln ('a bad literal--popped from an empty stack'); - othercases unknwn_literal_confusion - endcases; - ecart@/ -if (lit_stk_ptr = lit_stk_size) then - overflow('literal-stack size ',lit_stk_size); -incr(lit_stk_ptr); -end; - - -@ -@^push the literal stack@> -This macro pushes the last thing, necessarily a string, that was -popped. And this module, along with others that push the literal -stack without explicitly calling |push_lit_stack|, have an index entry -under ``push the literal stack''; these implicit pushes collectively -speed up the program by about ten percent. - -@d repush_string == begin - if (lit_stack[lit_stk_ptr] >= cmd_str_ptr) then - unflush_string; - incr(lit_stk_ptr); - end - - -@ -@:this can't happen}{\quad Nontop top of string stack@> -This procedure pops the stack, checking for, and trying to recover -from, stack underflow. (Actually, this procedure is really a -function, since it returns the two values through its |var| -parameters.) Also, if the literal being popped is a |stk_str| that's -been created during the execution of the current \.{.bst} command, pop -it from |str_pool| as well (it will be the string corresponding to -|str_ptr-1|). Note that when this happens, the string is no longer -`officially' available so that it must be used before anything else is -added to |str_pool|. - -@<Procedures and functions for style-file function execution@>= -procedure pop_lit_stk (var pop_lit:integer; var pop_type:stk_type); -begin -if (lit_stk_ptr = 0) then - begin - bst_ex_warn ('You can''t pop an empty literal stack');@/ - pop_type := stk_empty; {this is an error recovery attempt} - end - else - begin - decr(lit_stk_ptr); - pop_lit := lit_stack[lit_stk_ptr]; - pop_type := lit_stk_type[lit_stk_ptr]; - if (pop_type = stk_str) then - if (pop_lit >= cmd_str_ptr) then - begin - if (pop_lit <> str_ptr-1) then - confusion ('Nontop top of string stack'); - flush_string; - end; - end; -end; - - -@ -@:this can't happen}{\quad Illegal literal type@> -@:this can't happen}{\quad Unknown literal type@> -More bug complaints, this time about bad literals. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure illegl_literal_confusion; -begin -confusion ('Illegal literal type'); -end; -@# -procedure unknwn_literal_confusion; -begin -confusion ('Unknown literal type'); -end; - - -@ -@:this can't happen}{\quad Illegal literal type@> -@:this can't happen}{\quad Unknown literal type@> -Occasionally we'll want to know what's on the literal stack. Here we -print out a stack literal, giving its type. This procedure should -never be called after popping an empty stack. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_stk_lit (@!stk_lt:integer; @!stk_tp:stk_type); -begin -case (stk_tp) of - stk_int : print (stk_lt:0,' is an integer literal'); - stk_str : begin - print ('"'); - print_pool_str (stk_lt); - print ('" is a string literal'); - end; - stk_fn : begin - print ('`'); - print_pool_str (hash_text[stk_lt]); - print (''' is a function literal'); - end; - stk_field_missing : begin - print ('`'); - print_pool_str (stk_lt); - print (''' is a missing field'); - end; - stk_empty : illegl_literal_confusion; - othercases unknwn_literal_confusion -endcases; -end; - - -@ -@:this can't happen}{\quad Illegal literal type@> -@:this can't happen}{\quad Unknown literal type@> -This procedure appropriately chastises the style designer; however, if -the wrong literal came from popping an empty stack, the procedure -|pop_lit_stack| will have already done the chastising (because this -procedure is called only after popping the stack) so there's no need -for more. - -@<Procedures and functions for style-file function execution@>= -procedure print_wrong_stk_lit (@!stk_lt:integer; @!stk_tp1,@!stk_tp2:stk_type); -begin -if (stk_tp1 <> stk_empty) then - begin - print_stk_lit (stk_lt, stk_tp1); - case (stk_tp2) of - stk_int : print (', not an integer,'); - stk_str : print (', not a string,'); - stk_fn : print (', not a function,'); - stk_field_missing, - stk_empty : illegl_literal_confusion; - othercases unknwn_literal_confusion - endcases; - bst_ex_warn_print; - end; -end; - - -@ -@:this can't happen}{\quad Illegal literal type@> -@:this can't happen}{\quad Unknown literal type@> -This is similar to |print_stk_lit|, but here we don't give the -literal's type, and here we end with a new line. This procedure -should never be called after popping an empty stack. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure print_lit (@!stk_lt:integer; @!stk_tp:stk_type); -begin -case (stk_tp) of - stk_int : print_ln (stk_lt:0); - stk_str : begin - print_pool_str (stk_lt); - print_newline; - end; - stk_fn : begin - print_pool_str (hash_text[stk_lt]); - print_newline; - end; - stk_field_missing : begin - print_pool_str (stk_lt); - print_newline; - end; - stk_empty : illegl_literal_confusion; - othercases unknwn_literal_confusion -endcases; -end; - - -@ -This procedure pops and prints the top of the stack; when the stack is -empty the procedure |pop_lit_stk| complains. - -@<Procedures and functions for style-file function execution@>= -procedure pop_top_and_print; -var stk_lt : integer; - @!stk_tp : stk_type; -begin -pop_lit_stk (stk_lt,stk_tp); -if (stk_tp = stk_empty) then - print_ln ('Empty literal') - else - print_lit (stk_lt,stk_tp); -end; - - -@ -This procedure pops and prints the whole stack. - -@<Procedures and functions for style-file function execution@>= -procedure pop_whole_stack; -begin -while (lit_stk_ptr > 0) do - pop_top_and_print; -end; - - -@ -At the beginning of a \.{.bst}-command execution we make the stack -empty and record how much of |str_pool| has been used. - -@<Procedures and functions for style-file function execution@>= -procedure init_command_execution; -begin -lit_stk_ptr := 0; {make the stack empty} -cmd_str_ptr := str_ptr; {we'll check this when we finish command execution} -end; - - -@ -@:this can't happen}{\quad Nonempty empty string stack@> -At the end of a \.{.bst} command-execution we check that the stack and -|str_pool| are still in good shape. - -@<Procedures and functions for style-file function execution@>= -procedure check_command_execution; -begin -if (lit_stk_ptr<>0) then - begin - print_ln ('ptr=',lit_stk_ptr:0,', stack='); - pop_whole_stack; - bst_ex_warn ('---the literal stack isn''t empty'); - end; -if (cmd_str_ptr<>str_ptr) then - begin - trace - print_ln ('Pointer is ',str_ptr:0,' but should be ',cmd_str_ptr:0); - ecart@/ - confusion ('Nonempty empty string stack'); - end; -end; - - -@ -This procedure adds to |str_pool| the string from |ex_buf[0]| through -|ex_buf[ex_buf_length-1]| if it will fit. It assumes the global -variable |ex_buf_length| gives the length of the current string in -|ex_buf|. It then pushes this string onto the literal stack. - -@<Procedures and functions for style-file function execution@>= -procedure add_pool_buf_and_push; -begin -str_room (ex_buf_length); {make sure this string will fit} -ex_buf_ptr := 0; -while (ex_buf_ptr < ex_buf_length) do - begin - append_char (ex_buf[ex_buf_ptr]); - incr(ex_buf_ptr); - end; -push_lit_stk (make_string, stk_str); {and push it onto the stack} -end; - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -These macros append a character to |ex_buf|. Which is called depends -on whether the character is known to fit. - -@d append_ex_buf_char(#) == begin - ex_buf[ex_buf_ptr] := #; - incr(ex_buf_ptr); - end -@# -@d append_ex_buf_char_and_check(#) == - begin - if (ex_buf_ptr = buf_size) then - buffer_overflow; - append_ex_buf_char(#); - end - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -This procedure adds to the execution buffer the given string in -|str_pool| if it will fit. It assumes the global variable -|ex_buf_length| gives the length of the current string in |ex_buf|, -and thus also gives the location of the next character. - -@<Procedures and functions for style-file function execution@>= -procedure add_buf_pool (@!p_str : str_number); -begin -p_ptr1 := str_start[p_str]; -p_ptr2 := str_start[p_str+1]; -if (ex_buf_length+(p_ptr2-p_ptr1) > buf_size) then - buffer_overflow; -ex_buf_ptr := ex_buf_length; -while (p_ptr1 < p_ptr2) do - begin {copy characters into the buffer} - append_ex_buf_char (str_pool[p_ptr1]); - incr(p_ptr1); - end; -ex_buf_length := ex_buf_ptr; -end; - - -@ -This procedure actually writes onto the \.{.bbl}~file a line of output -(the characters from |out_buf[0]| to |out_buf[out_buf_length-1]|, -after removing trailing |white_space| characters). It also updates -|bbl_line_num|, the line counter. It writes a blank line if and only -if |out_buf| is empty. The program uses this procedure in such a way -that |out_buf| will be nonempty if there have been characters put in -it since the most recent \.{newline\$}. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure output_bbl_line; -label loop_exit,@!exit; -begin -if (out_buf_length <> 0) then {the buffer's not empty} - begin - while (out_buf_length > 0) do {remove trailing |white_space|} - if (lex_class[out_buf[out_buf_length-1]] = white_space) then - decr(out_buf_length) - else - goto loop_exit; -loop_exit: - if (out_buf_length = 0) then {ignore a line of just |white_space|} - return; - out_buf_ptr := 0; - while (out_buf_ptr < out_buf_length) do - begin - write (bbl_file, xchr[out_buf[out_buf_ptr]]); - incr(out_buf_ptr); - end; - end; -write_ln (bbl_file); -incr(bbl_line_num); {update line number} -out_buf_length := 0; {make the next line empty} -exit: -end; - - -@ -@:BibTeX capacity exceeded}{\quad output buffer size@> -This procedure adds to the output buffer the given string in -|str_pool|. It assumes the global variable |out_buf_length| gives the -length of the current string in |out_buf|, and thus also gives the -location for the next character. If there are enough characters -present in the output buffer, it writes one or more lines out to the -\.{.bbl} file. It breaks a line only at a |white_space| character, -and when it does, it adds two |space|s to the next output line. - -@<Procedures and functions for style-file function execution@>= -procedure add_out_pool (@!p_str : str_number); -label loop1_exit,loop2_exit; -var break_ptr : buf_pointer; {the first character following the line break} -@!end_ptr : buf_pointer; {temporary end-of-buffer pointer} -break_pt_found : boolean; {a suitable |white_space| character} -unbreakable_tail : boolean; {as it contains no |white_space| character} -begin -p_ptr1 := str_start[p_str]; -p_ptr2 := str_start[p_str+1]; -if (out_buf_length+(p_ptr2-p_ptr1) > buf_size) then - overflow('output buffer size ',buf_size); -out_buf_ptr := out_buf_length; -while (p_ptr1 < p_ptr2) do - begin {copy characters into the buffer} - out_buf[out_buf_ptr] := str_pool[p_ptr1]; - incr(p_ptr1); - incr(out_buf_ptr); - end; -out_buf_length := out_buf_ptr; -unbreakable_tail := false; -while ((out_buf_length > max_print_line) and (not unbreakable_tail)) do - @<Break that line@>; -end; - - -@ -Here we break the line by looking for a |white_space| character, -backwards from |out_buf[max_print_line]| until -|out_buf[min_print_line]|; we break at the |white_space| and indent -the next line two |space|s. The next module handles things when -there's no |white_space| character to break at. (It seems that the -annoyances to the average user of a warning message when there's an -output line longer than |max_print_line| outweigh the benefits, so we -don't issue such warnings in the current code.) - -@<Break that line@>= -begin -end_ptr := out_buf_length; -out_buf_ptr := max_print_line; -break_pt_found := false; -while ((lex_class[out_buf[out_buf_ptr]] <> white_space) and - (out_buf_ptr >= min_print_line)) do - decr(out_buf_ptr); -if (out_buf_ptr = min_print_line-1) then {no |white_space| character} - @<Break that unbreakably long line@> {(if |white_space| follows)} -else - break_pt_found := true; {hit a |white_space| character} -if (break_pt_found) then - begin - out_buf_length := out_buf_ptr; - break_ptr := out_buf_length + 1; - output_bbl_line; {output what we can} - out_buf[0] := space; - out_buf[1] := space; {start the next line with two |space|s} - out_buf_ptr := 2; - tmp_ptr := break_ptr; - while (tmp_ptr < end_ptr) do {and slide the rest down} - begin - out_buf[out_buf_ptr] := out_buf[tmp_ptr]; - incr(out_buf_ptr); - incr(tmp_ptr); - end; - out_buf_length := end_ptr - break_ptr + 2; - end; -end - - -@ -If there's no |white_space| character up through -|out_buf[max_print_line]|, we instead break the line at the first -following |white_space| character, if one exists. And if, starting -with that |white_space| character, there are multiple consecutive -|white_space| characters, |out_buf_ptr| points to the last of them. -If no |white_space| character exists, we haven't found a viable break -point, so we don't break the line (yet). - -@<Break that unbreakably long line@>= -begin -out_buf_ptr := max_print_line + 1; {|break_pt_found| is still |false|} -while (out_buf_ptr < end_ptr) do - if (lex_class[out_buf[out_buf_ptr]] <> white_space) then - incr(out_buf_ptr) - else - goto loop1_exit; -loop1_exit: -if (out_buf_ptr = end_ptr) then - unbreakable_tail := true {because no |white_space| character} -else {at |white_space|, and |out_buf_ptr < end_ptr|} - begin - break_pt_found := true; - while (out_buf_ptr+1 < end_ptr) do {look for more |white_space|} - if (lex_class[out_buf[out_buf_ptr+1]] = white_space) then - incr(out_buf_ptr) {which then points to |white_space|} - else - goto loop2_exit; -loop2_exit: - end; -end - - -@ -@^Tuesdays@> -@^windows@> -@:this can't happen}{\quad Unknown function class@> -This procedure executes a single specified function; it is the single -execution-primitive that does everything (except windows, and it takes -Tuesdays off). - -@<|execute_fn| itself@>= -procedure execute_fn (@!ex_fn_loc : hash_loc); -@<Declarations for executing |built_in| functions@> -@!wiz_ptr : wiz_fn_loc; {general |wiz_functions| location} -begin - trace - trace_pr ('execute_fn `'); - trace_pr_pool_str (hash_text[ex_fn_loc]); - trace_pr_ln (''''); - ecart@/ -case (fn_type[ex_fn_loc]) of - built_in : @<Execute a |built_in| function@>; - wiz_defined : @<Execute a |wiz_defined| function@>; - int_literal : push_lit_stk (fn_info[ex_fn_loc], stk_int); - str_literal : push_lit_stk (hash_text[ex_fn_loc], stk_str); - field : @<Execute a field@>; - int_entry_var : @<Execute an |int_entry_var|@>; - str_entry_var : @<Execute a |str_entry_var|@>; - int_global_var : push_lit_stk (fn_info[ex_fn_loc], stk_int); - str_global_var : @<Execute a |str_global_var|@>; - othercases unknwn_function_class_confusion -endcases; -end; - - -@ -To execute a |wiz_defined| function, we just execute all those -functions in its definition, except that the special marker -|quote_next_fn| means we push the next function onto the stack. - -@<Execute a |wiz_defined| function@>= -begin -wiz_ptr := fn_info[ex_fn_loc]; -while (wiz_functions[wiz_ptr] <> end_of_def) do - begin - if (wiz_functions[wiz_ptr] <> quote_next_fn) then - execute_fn (wiz_functions[wiz_ptr]) - else - begin - incr(wiz_ptr); - push_lit_stk (wiz_functions[wiz_ptr], stk_fn); - end; - incr(wiz_ptr); - end; -end - - -@ -This module pushes the string given by the field onto the literal -stack unless it's |missing|, in which case it pushes a special value -onto the stack. - -@<Execute a field@>= -begin -if (not mess_with_entries) then - bst_cant_mess_with_entries_print - else - begin - field_ptr := cite_ptr*num_fields + fn_info[ex_fn_loc]; - if (field_info[field_ptr] = missing) then - push_lit_stk (hash_text[ex_fn_loc], stk_field_missing) - else - push_lit_stk (field_info[field_ptr], stk_str); - end -end - - -@ -This module pushes the integer given by an |int_entry_var| onto the -literal stack. - -@<Execute an |int_entry_var|@>= -begin -if (not mess_with_entries) then - bst_cant_mess_with_entries_print - else - push_lit_stk (entry_ints[cite_ptr*num_ent_ints+fn_info[ex_fn_loc]], - stk_int); -end - - -@ -This module adds the string given by a |str_entry_var| to |str_pool| -via the execution buffer and pushes it onto the literal stack. - -@<Execute a |str_entry_var|@>= -begin -if (not mess_with_entries) then - bst_cant_mess_with_entries_print - else - begin - str_ent_ptr := cite_ptr*num_ent_strs + fn_info[ex_fn_loc];@/ - ex_buf_ptr := 0; {also serves as |ent_chr_ptr|} - while (entry_strs[str_ent_ptr][ex_buf_ptr] <> end_of_string) do - {copy characters into the buffer} - append_ex_buf_char (entry_strs[str_ent_ptr][ex_buf_ptr]); - ex_buf_length := ex_buf_ptr; - add_pool_buf_and_push; {push this string onto the stack} - end; -end - - -@ -This module pushes the string given by a |str_global_var| onto the -literal stack, but it copies the string to |str_pool| (character by -character) only if it has to---it {\it doesn't\/} have to if the -string is static (that is, if the string isn't at the top, temporary -part of the string pool). - -@<Execute a |str_global_var|@>= -begin -str_glb_ptr := fn_info[ex_fn_loc]; -if (glb_str_ptr[str_glb_ptr] > 0) then {we're dealing with a static string} - push_lit_stk (glb_str_ptr[str_glb_ptr],stk_str) - else - begin - str_room(glb_str_end[str_glb_ptr]); - glob_chr_ptr := 0; - while (glob_chr_ptr < glb_str_end[str_glb_ptr]) do {copy the string} - begin - append_char (global_strs[str_glb_ptr][glob_chr_ptr]); - incr(glob_chr_ptr); - end; - push_lit_stk (make_string, stk_str); {and push it onto the stack} - end; -end - - - -@* The built-in functions. -@^add a built-in function@> -@^biblical procreation@> -@^grade inflation@> -This section gives the all the code for all the built-in functions -(including pre-defined |field|s, |str_entry_var|s, and -|int_global_var|s, which technically aren't classified as |built_in|). -To modify or add one, we needn't go anywhere else (with one exception: -The constant |max_pop|, which gives the maximum number of literals -that any of these functions pops off the stack, is defined earlier -because it's needed earlier; thus, if we need to update it, which will -happen if some new |built_in| functions uses more than |max_pop| -literals from the stack, we'll have to go outside this section). -Adding a |built_in| function entails modifying (at least four of) the -five modules marked by ``add a built-in function'' in the index, in -addition to adding the code to execute the function. - -These variables all begin with |b_| and specify the hash-table -locations of the |built_in| functions, except that |b_default| is -pseudo-|built_in|---either it will point to the no-op \.{skip\$} or to -the \.{.bst}-defined function \.{default.type}; it's used when an -entry has a type that's not defined in the \.{.bst} file. - -@<Globals in the outer block@>= -@!b_equals : hash_loc; {\.{=}} -@!b_greater_than : hash_loc; {\.{>}} -@!b_less_than : hash_loc; {\.{<}} -@!b_plus : hash_loc; {\.{+} (this may be changed to an |a_minus|)} -@!b_minus : hash_loc; {\.{-}} -@!b_concatenate : hash_loc; {\.{*}} -@!b_gets : hash_loc; {\.{:=} (formerly, |b_gat|)} -@!b_add_period : hash_loc; {\.{add.period\$}} -@!b_call_type : hash_loc; {\.{call.type\$}} -@!b_change_case : hash_loc; {\.{change.case\$}} -@!b_chr_to_int : hash_loc; {\.{chr.to.int\$}} -@!b_cite : hash_loc; {\.{cite\$}} -@!b_duplicate : hash_loc; {\.{duplicate\$}} -@!b_empty : hash_loc; {\.{empty\$}} -@!b_format_name : hash_loc; {\.{format.name\$}} -@!b_if : hash_loc; {\.{if\$}} -@!b_int_to_chr : hash_loc; {\.{int.to.chr\$}} -@!b_int_to_str : hash_loc; {\.{int.to.str\$}} -@!b_missing : hash_loc; {\.{missing\$}} -@!b_newline : hash_loc; {\.{newline\$}} -@!b_num_names : hash_loc; {\.{num.names\$}} -@!b_pop : hash_loc; {\.{pop\$}} -@!b_preamble : hash_loc; {\.{preamble\$}} -@!b_purify : hash_loc; {\.{purify\$}} -@!b_quote : hash_loc; {\.{quote\$}} -@!b_skip : hash_loc; {\.{skip\$}} -@!b_stack : hash_loc; {\.{stack\$}} -@!b_substring : hash_loc; {\.{substring\$}} -@!b_swap : hash_loc; {\.{swap\$}} -@!b_text_length : hash_loc; {\.{text.length\$}} -@!b_text_prefix : hash_loc; {\.{text.prefix\$}} -@!b_top_stack : hash_loc; {\.{top\$}} -@!b_type : hash_loc; {\.{type\$}} -@!b_warning : hash_loc; {\.{warning\$}} -@!b_while : hash_loc; {\.{while\$}} -@!b_width : hash_loc; {\.{width\$}} -@!b_write : hash_loc; {\.{write\$}} -@!b_default : hash_loc; {either \.{skip\$} or \.{default.type}} -@# - stat - @!blt_in_loc : array[blt_in_range] of hash_loc; {for execution counts} - @!execution_count : array[blt_in_range] of integer; {the same} - @!total_ex_count : integer; {the sum of all |execution_count|s} - @!blt_in_ptr : blt_in_range; {a pointer into |blt_in_loc|} - tats@/ - - -@ -Where |blt_in_range| gives the legal |built_in| function numbers. - -@<Types in the outer block@>= -@!blt_in_range = 0..num_blt_in_fns; - - -@ -@^add a built-in function@> -These constants all begin with |n_| and are used for the |case| -statement that determines which |built_in| function to execute. - -@d n_equals = 0 {\.{=}} -@d n_greater_than = 1 {\.{>}} -@d n_less_than = 2 {\.{<}} -@d n_plus = 3 {\.{+}} -@d n_minus = 4 {\.{-}} -@d n_concatenate = 5 {\.{*}} -@d n_gets = 6 {\.{:=}} -@d n_add_period = 7 {\.{add.period\$}} -@d n_call_type = 8 {\.{call.type\$}} -@d n_change_case = 9 {\.{change.case\$}} -@d n_chr_to_int = 10 {\.{chr.to.int\$}} -@d n_cite = 11 {\.{cite\$} (this may start a riot)} -@d n_duplicate = 12 {\.{duplicate\$}} -@d n_empty = 13 {\.{empty\$}} -@d n_format_name = 14 {\.{format.name\$}} -@d n_if = 15 {\.{if\$}} -@d n_int_to_chr = 16 {\.{int.to.chr\$}} -@d n_int_to_str = 17 {\.{int.to.str\$}} -@d n_missing = 18 {\.{missing\$}} -@d n_newline = 19 {\.{newline\$}} -@d n_num_names = 20 {\.{num.names\$}} -@d n_pop = 21 {\.{pop\$}} -@d n_preamble = 22 {\.{preamble\$}} -@d n_purify = 23 {\.{purify\$}} -@d n_quote = 24 {\.{quote\$}} -@d n_skip = 25 {\.{skip\$}} -@d n_stack = 26 {\.{stack\$}} -@d n_substring = 27 {\.{substring\$}} -@d n_swap = 28 {\.{swap\$}} -@d n_text_length = 29 {\.{text.length\$}} -@d n_text_prefix = 30 {\.{text.prefix\$}} -@d n_top_stack = 31 {\.{top\$}} -@d n_type = 32 {\.{type\$}} -@d n_warning = 33 {\.{warning\$}} -@d n_while = 34 {\.{while\$}} -@d n_width = 35 {\.{width\$}} -@d n_write = 36 {\.{write\$}} - -@<Constants in the outer block@>= -@!num_blt_in_fns = 37; {one more than the previous number} - - -@ -@^add a built-in function@> -@^important note@> -It's time for us to insert more pre-defined strings into |str_pool| -(and thus the hash table) and to insert the |built_in| functions into -the hash table. The strings corresponding to these functions should -contain no upper-case letters, and they must all be exactly -|longest_pds| characters long. The |build_in| routine (to appear -shortly) does the work. - -Important note: These pre-definitions must not have any glitches or the -program may bomb because the |log_file| hasn't been opened yet. - -@<Pre-define certain strings@>= -build_in('= ',1,b_equals,n_equals); -build_in('> ',1,b_greater_than,n_greater_than); -build_in('< ',1,b_less_than,n_less_than); -build_in('+ ',1,b_plus,n_plus); -build_in('- ',1,b_minus,n_minus); -build_in('* ',1,b_concatenate,n_concatenate); -build_in(':= ',2,b_gets,n_gets); -build_in('add.period$ ',11,b_add_period,n_add_period); -build_in('call.type$ ',10,b_call_type,n_call_type); -build_in('change.case$',12,b_change_case,n_change_case); -build_in('chr.to.int$ ',11,b_chr_to_int,n_chr_to_int); -build_in('cite$ ',5,b_cite,n_cite); -build_in('duplicate$ ',10,b_duplicate,n_duplicate); -build_in('empty$ ',6,b_empty,n_empty); -build_in('format.name$',12,b_format_name,n_format_name); -build_in('if$ ',3,b_if,n_if); -build_in('int.to.chr$ ',11,b_int_to_chr,n_int_to_chr); -build_in('int.to.str$ ',11,b_int_to_str,n_int_to_str); -build_in('missing$ ',8,b_missing,n_missing); -build_in('newline$ ',8,b_newline,n_newline); -build_in('num.names$ ',10,b_num_names,n_num_names); -build_in('pop$ ',4,b_pop,n_pop); -build_in('preamble$ ',9,b_preamble,n_preamble); -build_in('purify$ ',7,b_purify,n_purify); -build_in('quote$ ',6,b_quote,n_quote); -build_in('skip$ ',5,b_skip,n_skip); -build_in('stack$ ',6,b_stack,n_stack); -build_in('substring$ ',10,b_substring,n_substring); -build_in('swap$ ',5,b_swap,n_swap); -build_in('text.length$',12,b_text_length,n_text_length); -build_in('text.prefix$',12,b_text_prefix,n_text_prefix); -build_in('top$ ',4,b_top_stack,n_top_stack); -build_in('type$ ',5,b_type,n_type); -build_in('warning$ ',8,b_warning,n_warning); -build_in('width$ ',6,b_width,n_width); -build_in('while$ ',6,b_while,n_while); -build_in('width$ ',6,b_width,n_width); -build_in('write$ ',6,b_write,n_write); - - -@ -This procedure inserts a |built_in| function into the hash table and -initializes the corresponding pre-defined string (of length at most -|longest_pds|). The array |fn_info| contains a number from 0 through -the number of |built_in| functions minus 1 (i.e., |num_blt_in_fns - 1| -if we're keeping statistics); this number is used by a |case| -statement to execute this function and is used for keeping execution -counts when keeping statistics. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure build_in (@!pds:pds_type; @!len:pds_len; var fn_hash_loc:hash_loc; - @!blt_in_num:blt_in_range); -begin -pre_define (pds,len,bst_fn_ilk);@/ -fn_hash_loc := pre_def_loc; {the |pre_define| routine sets |pre_def_loc|} -fn_type[fn_hash_loc] := built_in; -fn_info[fn_hash_loc] := blt_in_num; - stat - blt_in_loc[blt_in_num] := fn_hash_loc;@/ - execution_count[blt_in_num] := 0; {initialize the function-execution count} - tats@/ -end; - - -@ -This is a procedure so that |initialize| is smaller. - -@<Procedures and functions for handling numbers, characters, and strings@>= -procedure pre_def_certain_strings; -begin -@<Pre-define certain strings@>@; -end; - - -@ -These variables all begin with |s_| and specify the locations in -|str_pool| of certain often-used strings that the \.{.bst} commands -need. The |s_preamble| array is big enough to allow an average of one -\.{preamble\$} command per \.{.bib} file. - -@<Globals in the outer block@>= -@!s_null : str_number; {the null string} -@!s_default : str_number; {\.{default.type}, for unknown entry types} -@!s_t : str_number; {\.{t}, for |title_lowers| case conversion} -@!s_l : str_number; {\.{l}, for |all_lowers| case conversion} -@!s_u : str_number; {\.{u}, for |all_uppers| case conversion} -@!s_preamble : array[bib_number] of str_number; - {for the \.{preamble\$} |built_in| function} - - -@ -These constants all begin with |n_| and are used for the |case| -statement that determines which, if any, control sequence we're -dealing with; a control sequence of interest will be either one of the -undotted characters `\.{\\i}' or `\.{\\j}' or one of the foreign -characters in Table~3.2 of the \LaTeX\ manual. - -@d n_i = 0 {\.{i}, for the undotted character \.{\\i}} -@d n_j = 1 {\.{j}, for the undotted character \.{\\j}} -@d n_oe = 2 {\.{oe}, for the foreign character \.{\\oe}} -@d n_oe_upper = 3 {\.{OE}, for the foreign character \.{\\OE}} -@d n_ae = 4 {\.{ae}, for the foreign character \.{\\ae}} -@d n_ae_upper = 5 {\.{AE}, for the foreign character \.{\\AE}} -@d n_aa = 6 {\.{aa}, for the foreign character \.{\\aa}} -@d n_aa_upper = 7 {\.{AA}, for the foreign character \.{\\AA}} -@d n_o = 8 {\.{o}, for the foreign character \.{\\o}} -@d n_o_upper = 9 {\.{O}, for the foreign character \.{\\O}} -@d n_l = 10 {\.{l}, for the foreign character \.{\\l}} -@d n_l_upper = 11 {\.{L}, for the foreign character \.{\\L}} -@d n_ss = 12 {\.{ss}, for the foreign character \.{\\ss}} - - -@ -@^important note@> -@.default.type@> -Here we pre-define a few strings used in executing the \.{.bst} file: -the null string, which is sometimes pushed onto the stack; a string -used for default entry types; and some control sequences used to spot -foreign characters. We also initialize the |s_preamble| array to -empty. These pre-defined strings must all be exactly |longest_pds| -characters long. - -Important note: These pre-definitions must not have any glitches or -the program may bomb because the |log_file| hasn't been opened yet, -and |text_ilk|s should be pre-defined here, not earlier, for -\.{.bst}-function-execution purposes. - -@<Pre-define certain strings@>= -pre_define(' ',0,text_ilk); s_null := hash_text[pre_def_loc]; -fn_type[pre_def_loc] := str_literal;@/ -pre_define('default.type',12,text_ilk); s_default := hash_text[pre_def_loc]; -fn_type[pre_def_loc] := str_literal;@/ -b_default := b_skip; {this may be changed to the \.{default.type} function} -preamble_ptr := 0; {initialize the |s_preamble| array} -pre_define('i ',1,control_seq_ilk); -ilk_info[pre_def_loc] := n_i; -pre_define('j ',1,control_seq_ilk); -ilk_info[pre_def_loc] := n_j; -pre_define('oe ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_oe; -pre_define('OE ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_oe_upper; -pre_define('ae ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_ae; -pre_define('AE ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_ae_upper; -pre_define('aa ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_aa; -pre_define('AA ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_aa_upper; -pre_define('o ',1,control_seq_ilk); -ilk_info[pre_def_loc] := n_o; -pre_define('O ',1,control_seq_ilk); -ilk_info[pre_def_loc] := n_o_upper; -pre_define('l ',1,control_seq_ilk); -ilk_info[pre_def_loc] := n_l; -pre_define('L ',1,control_seq_ilk); -ilk_info[pre_def_loc] := n_l_upper; -pre_define('ss ',2,control_seq_ilk); -ilk_info[pre_def_loc] := n_ss; - - -@ -@^important note@> -@.crossref@> -@.entry.max\$@> -@.global.max\$@> -@.sort.key\$@> -Now we pre-define any built-in |field|s, |str_entry_var|s, and -|int_global_var|s; these strings must all be exactly |longest_pds| -characters long. Note that although these are built-in functions, we -classify them (in the |fn_type| array) otherwise. - -Important note: These pre-definitions must not have any glitches or -the program may bomb because the |log_file| hasn't been opened yet. - -@<Pre-define certain strings@>= -pre_define('crossref ',8,bst_fn_ilk); -fn_type[pre_def_loc] := field;@/ -fn_info[pre_def_loc] := num_fields; {give this |field| a number} -crossref_num := num_fields; -incr(num_fields);@/ -num_pre_defined_fields := num_fields; {that's it for pre-defined |field|s} -pre_define('sort.key$ ',9,bst_fn_ilk); -fn_type[pre_def_loc] := str_entry_var; -fn_info[pre_def_loc] := num_ent_strs; {give this |str_entry_var| a number} -sort_key_num := num_ent_strs; -incr(num_ent_strs);@/ -pre_define('entry.max$ ',10,bst_fn_ilk); -fn_type[pre_def_loc] := int_global_var; -fn_info[pre_def_loc] := ent_str_size; {initialize this |int_global_var|} -pre_define('global.max$ ',11,bst_fn_ilk); -fn_type[pre_def_loc] := int_global_var; -fn_info[pre_def_loc] := glob_str_size; {initialize this |int_global_var|} - - -@ -@^add a built-in function@> -@:this can't happen}{\quad Unknown built-in function@> -This module branches to the code for the appropriate |built_in| -function. Only three---{\.{call.type\$}}, {\.{if\$}}, and -{\.{while\$}}---do a recursive call. - -@<Execute a |built_in| function@>= -begin - stat {update this function's execution count} - incr(execution_count[fn_info[ex_fn_loc]]); - tats@/ -case (fn_info[ex_fn_loc]) of - n_equals : x_equals; - n_greater_than : x_greater_than; - n_less_than : x_less_than; - n_plus : x_plus; - n_minus : x_minus; - n_concatenate : x_concatenate; - n_gets : x_gets; - n_add_period : x_add_period; - n_call_type : @<|execute_fn|({\.{call.type\$}})@>; - n_change_case : x_change_case; - n_chr_to_int : x_chr_to_int; - n_cite : x_cite; - n_duplicate : x_duplicate; - n_empty : x_empty; - n_format_name : x_format_name; - n_if : @<|execute_fn|({\.{if\$}})@>; - n_int_to_chr : x_int_to_chr; - n_int_to_str : x_int_to_str; - n_missing : x_missing; - n_newline : @<|execute_fn|({\.{newline\$}})@>; - n_num_names : x_num_names; - n_pop : @<|execute_fn|({\.{pop\$}})@>; - n_preamble : x_preamble; - n_purify : x_purify; - n_quote : x_quote; - n_skip : @<|execute_fn|({\.{skip\$}})@>; - n_stack : @<|execute_fn|({\.{stack\$}})@>; - n_substring : x_substring; - n_swap : x_swap; - n_text_length : x_text_length; - n_text_prefix : x_text_prefix; - n_top_stack : @<|execute_fn|({\.{top\$}})@>; - n_type : x_type; - n_warning : x_warning; - n_while : @<|execute_fn|({\.{while\$}})@>; - n_width : x_width; - n_write : x_write; - othercases confusion ('Unknown built-in function') -endcases; -end - - -@ -@^add a built-in function@> -@^gymnastics@> -This extra level of module-pointing allows a uniformity of module -names for the |built_in| functions, regardless of whether they do a -recursive call to |execute_fn| or are trivial (a single statement). -Those that do a recursive call are left as part of |execute_fn|, -avoiding \PASCAL's forward procedure mechanism, and those that don't -(except for the single-statement ones) are made into procedures so -that |execute_fn| doesn't get too large. - -@<Procedures and functions for style-file function execution@>= -@<|execute_fn|({\.{=}})@>@; -@<|execute_fn|({\.{>}})@>@; -@<|execute_fn|({\.{<}})@>@; -@<|execute_fn|({\.{+}})@>@; -@<|execute_fn|({\.{-}})@>@; -@<|execute_fn|({\.{*}})@>@; -@<|execute_fn|({\.{:=}})@>@; -@<|execute_fn|({\.{add.period\$}})@>@; -@<|execute_fn|({\.{change.case\$}})@>@; -@<|execute_fn|({\.{chr.to.int\$}})@>@; -@<|execute_fn|({\.{cite\$}})@>@; -@<|execute_fn|({\.{duplicate\$}})@>@; -@<|execute_fn|({\.{empty\$}})@>@; -@<|execute_fn|({\.{format.name\$}})@>@; -@<|execute_fn|({\.{int.to.chr\$}})@>@; -@<|execute_fn|({\.{int.to.str\$}})@>@; -@<|execute_fn|({\.{missing\$}})@>@; -@<|execute_fn|({\.{num.names\$}})@>@; -@<|execute_fn|({\.{preamble\$}})@>@; -@<|execute_fn|({\.{purify\$}})@>@; -@<|execute_fn|({\.{quote\$}})@>@; -@<|execute_fn|({\.{substring\$}})@>@; -@<|execute_fn|({\.{swap\$}})@>@; -@<|execute_fn|({\.{text.length\$}})@>@; -@<|execute_fn|({\.{text.prefix\$}})@>@; -@<|execute_fn|({\.{type\$}})@>@; -@<|execute_fn|({\.{warning\$}})@>@; -@<|execute_fn|({\.{width\$}})@>@; -@<|execute_fn|({\.{write\$}})@>@; -@<|execute_fn| itself@> - - -@ -Now it's time to declare some things for executing |built_in| -functions only. These (and only these) variables are used -recursively, so they can't be global. - -@d end_while = 51 {stop executing the \.{while\$} function} - -@<Declarations for executing |built_in| functions@>= -label end_while; -var r_pop_lt1,@!r_pop_lt2 : integer; {stack literals for \.{while\$}} -@!r_pop_tp1,@!r_pop_tp2 : stk_type; {stack types for \.{while\$}} - - -@ -These are nonrecursive variables that |execute_fn| uses. Declaring -them here (instead of in the previous module) saves execution time and -stack space on most machines. - -@d name_buf == sv_buffer {an alias, a buffer for manipulating names} - -@<Globals in the outer block@>= -@!pop_lit1,@!pop_lit2,@!pop_lit3 : integer; {stack literals} -@!pop_typ1,@!pop_typ2,@!pop_typ3 : stk_type; {stack types} -@!sp_ptr : pool_pointer; {for manipulating |str_pool| strings} -@!sp_xptr1,@!sp_xptr2 : pool_pointer; {more of the same} -@!sp_end : pool_pointer; {marks the end of a |str_pool| string} -@!sp_length,sp2_length : pool_pointer; {lengths of |str_pool| strings} -@!sp_brace_level : integer; {for scanning |str_pool| strings} -@!ex_buf_xptr,@!ex_buf_yptr : buf_pointer; {extra |ex_buf| locations} -@!control_seq_loc : hash_loc; {hash-table loc of a control sequence} -@!preceding_white : boolean; {used in scanning strings} -@!and_found : boolean; {to stop the loop that looks for an ``and''} -@!num_names : integer; {for counting names} -@!name_bf_ptr : buf_pointer; {general |name_buf| location} -@!name_bf_xptr,@!name_bf_yptr : buf_pointer; {and two more} -@!nm_brace_level : integer; {for scanning |name_buf| strings} -@!name_tok : packed array[buf_pointer] of buf_pointer; {name-token ptr list} -@!name_sep_char : packed array[buf_pointer] of ASCII_code; {token-ending chars} -@!num_tokens : buf_pointer; {this counts name tokens} -@!token_starting : boolean; {used in scanning name tokens} -@!alpha_found : boolean; {used in scanning the format string} -@!double_letter,@!end_of_group,@!to_be_written : boolean; {the same} -@!first_start : buf_pointer; {start-ptr into |name_tok| for the first name} -@!first_end : buf_pointer; {end-ptr into |name_tok| for the first name} -@!last_end : buf_pointer; {end-ptr into |name_tok| for the last name} -@!von_start : buf_pointer; {start-ptr into |name_tok| for the von name} -@!von_end : buf_pointer; {end-ptr into |name_tok| for the von name} -@!jr_end : buf_pointer; {end-ptr into |name_tok| for the jr name} -@!cur_token,@!last_token : buf_pointer; {|name_tok| ptrs for outputting tokens} -@!use_default : boolean; {for the inter-token intra-name part string} -@!num_commas : buf_pointer; {used to determine the name syntax} -@!comma1,@!comma2 : buf_pointer; {ptrs into |name_tok|} -@!num_text_chars : buf_pointer; {special characters count as one} - - -@ -The |built_in| function {\.{=}} pops the top two (integer or string) -literals, compares them, and pushes the integer 1 if they're equal, 0 -otherwise. If they're not either both string or both integer, it -complains and pushes the integer 0. - -@<|execute_fn|({\.{=}})@>= -procedure x_equals; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> pop_typ2) then - begin - if ((pop_typ1 <> stk_empty) and (pop_typ2 <> stk_empty)) then - begin - print_stk_lit (pop_lit1,pop_typ1); - print (', '); - print_stk_lit (pop_lit2,pop_typ2); - print_newline; - bst_ex_warn ('---they aren''t the same literal types'); - end; - push_lit_stk (0, stk_int); - end -else if ((pop_typ1 <> stk_int) and (pop_typ1 <> stk_str)) then - begin - if (pop_typ1 <> stk_empty) then - begin - print_stk_lit (pop_lit1,pop_typ1); - bst_ex_warn (', not an integer or a string,'); - end; - push_lit_stk (0, stk_int); - end -else if (pop_typ1 = stk_int) then - if (pop_lit2 = pop_lit1) then - push_lit_stk (1, stk_int) - else - push_lit_stk (0, stk_int) -else - if (str_eq_str (pop_lit2,pop_lit1)) then - push_lit_stk (1, stk_int) - else - push_lit_stk (0, stk_int); -end; - - -@ -The |built_in| function {\.{>}} pops the top two (integer) literals, -compares them, and pushes the integer 1 if the second is greater than -the first, 0 otherwise. If either isn't an integer literal, it -complains and pushes the integer 0. - -@<|execute_fn|({\.{>}})@>= -procedure x_greater_than; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (0, stk_int); - end -else if (pop_typ2 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int); - push_lit_stk (0, stk_int); - end -else - if (pop_lit2 > pop_lit1) then - push_lit_stk (1, stk_int) - else - push_lit_stk (0, stk_int); -end; - - -@ -The |built_in| function {\.{<}} pops the top two (integer) literals, -compares them, and pushes the integer 1 if the second is less than the -first, 0 otherwise. If either isn't an integer literal, it complains -and pushes the integer 0. - -@<|execute_fn|({\.{<}})@>= -procedure x_less_than; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (0, stk_int); - end -else if (pop_typ2 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int); - push_lit_stk (0, stk_int); - end -else - if (pop_lit2 < pop_lit1) then - push_lit_stk (1, stk_int) - else - push_lit_stk (0, stk_int); -end; - - -@ -The |built_in| function {\.{+}} pops the top two (integer) literals -and pushes their sum. If either isn't an integer literal, it -complains and pushes the integer 0. - -@<|execute_fn|({\.{+}})@>= -procedure x_plus; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (0, stk_int); - end -else if (pop_typ2 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int); - push_lit_stk (0, stk_int); - end -else - push_lit_stk (pop_lit2+pop_lit1, stk_int); -end; - - -@ -The |built_in| function {\.{-}} pops the top two (integer) literals -and pushes their difference (the first subtracted from the second). -If either isn't an integer literal, it complains and pushes the -integer 0. - -@<|execute_fn|({\.{-}})@>= -procedure x_minus; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (0, stk_int); - end -else if (pop_typ2 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int); - push_lit_stk (0, stk_int); - end -else - push_lit_stk (pop_lit2-pop_lit1, stk_int); -end; - - -@ -The |built_in| function {\.{*}} pops the top two (string) literals, -concatenates them (in reverse order, that is, the order in which -pushed), and pushes the resulting string back onto the stack. If -either isn't a string literal, it complains and pushes the null -string. - -@<|execute_fn|({\.{*}})@>= -procedure x_concatenate; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ2 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_str); - push_lit_stk (s_null, stk_str); - end -else - @<Concatenate the two strings and push@>; -end; - - -@ -@^push the literal stack@> -Often both strings will be at the top of the string pool, in which -case we just move some pointers. Furthermore, it's worth doing some -special stuff in case either string is null, since empirically this -seems to happen about $20\%$ of the time. In any case, we don't need -the execution buffer---we simple move the strings around in the string -pool when necessary. - -@<Concatenate the two strings and push@>= -begin -if (pop_lit2 >= cmd_str_ptr) then - if (pop_lit1 >= cmd_str_ptr) then - begin - str_start[pop_lit1] := str_start[pop_lit1+1]; - unflush_string; - incr(lit_stk_ptr); - end - else if (length(pop_lit2) = 0) then - push_lit_stk (pop_lit1, stk_str) - else {|pop_lit2| is nonnull, only |pop_lit1| is below |cmd_str_ptr|} - begin - pool_ptr := str_start[pop_lit2+1]; - str_room (length(pop_lit1)); - sp_ptr := str_start[pop_lit1]; - sp_end := str_start[pop_lit1+1]; - while (sp_ptr < sp_end) do - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; - push_lit_stk (make_string, stk_str); {and push it onto the stack} - end -else - @<Concatenate them and push when |pop_lit2 < cmd_str_ptr|@>; -end - - -@ -@^push the literal stack@> -We simply continue the previous module. - -@<Concatenate them and push when |pop_lit2 < cmd_str_ptr|@>= -begin -if (pop_lit1 >= cmd_str_ptr) then - if (length(pop_lit2) = 0) then - begin - unflush_string; - lit_stack[lit_stk_ptr] := pop_lit1; - incr(lit_stk_ptr); - end - else if (length(pop_lit1) = 0) then - incr(lit_stk_ptr) - else {both strings nonnull, only |pop_lit2| is below |cmd_str_ptr|} - begin - sp_length := length(pop_lit1); - sp2_length := length(pop_lit2); - str_room (sp_length + sp2_length); - sp_ptr := str_start[pop_lit1+1]; - sp_end := str_start[pop_lit1]; - sp_xptr1 := sp_ptr + sp2_length; - while (sp_ptr > sp_end) do {slide up |pop_lit1|} - begin - decr(sp_ptr); - decr(sp_xptr1); - str_pool[sp_xptr1] := str_pool[sp_ptr]; - end; - sp_ptr := str_start[pop_lit2]; - sp_end := str_start[pop_lit2+1]; - while (sp_ptr < sp_end) do {slide up |pop_lit2|} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; - pool_ptr := pool_ptr + sp_length; - push_lit_stk (make_string, stk_str); {and push it onto the stack} - end -else - @<Concatenate them and push when |pop_lit1,pop_lit2 < cmd_str_ptr|@>; -end - - -@ -@^push the literal stack@> -Again, we simply continue the previous module. - -@<Concatenate them and push when |pop_lit1,pop_lit2 < cmd_str_ptr|@>= -begin -if (length(pop_lit1) = 0) then - incr(lit_stk_ptr) -else if (length(pop_lit2) = 0) then - push_lit_stk (pop_lit1, stk_str) -else {both strings are nonnull, and both are below |cmd_str_ptr|} - begin - str_room (length(pop_lit1) + length(pop_lit2)); - sp_ptr := str_start[pop_lit2]; - sp_end := str_start[pop_lit2+1]; - while (sp_ptr < sp_end) do {slide up |pop_lit2|} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; - sp_ptr := str_start[pop_lit1]; - sp_end := str_start[pop_lit1+1]; - while (sp_ptr < sp_end) do {slide up |pop_lit1|} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; - push_lit_stk (make_string, stk_str); {and push it onto the stack} - end; -end - - -@ -The |built_in| function {\.{:=}} pops the top two literals and assigns -to the first (which must be an |int_entry_var|, a |str_entry_var|, an -|int_global_var|, or a |str_global_var|) the value of the second; -it complains if the value isn't of the appropriate type. - -@<|execute_fn|({\.{:=}})@>= -procedure x_gets; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_fn) then - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_fn) -else if ((not mess_with_entries) and - ((fn_type[pop_lit1] = str_entry_var) or - (fn_type[pop_lit1] = int_entry_var))) then - bst_cant_mess_with_entries_print -else - case (fn_type[pop_lit1]) of - int_entry_var : @<Assign to an |int_entry_var|@>; - str_entry_var : @<Assign to a |str_entry_var|@>; - int_global_var : @<Assign to an |int_global_var|@>; - str_global_var : @<Assign to a |str_global_var|@>; - othercases begin - print ('You can''t assign to type '); - print_fn_class (pop_lit1); - bst_ex_warn (', a nonvariable function class'); - end - endcases; -end; - - -@ -This module checks that what we're about to assign is really an -integer, and then assigns. - -@<Assign to an |int_entry_var|@>= -if (pop_typ2 <> stk_int) then - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int) - else - entry_ints[cite_ptr*num_ent_ints+fn_info[pop_lit1]] := pop_lit2 - - -@ -@.String size exceeded@> -It's time for a complaint if either of the two (entry or global) -string lengths is exceeded. - -@d bst_string_size_exceeded(#) == begin - bst_1print_string_size_exceeded; - print (#); - bst_2print_string_size_exceeded; - end - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure bst_1print_string_size_exceeded; -begin -print ('Warning--you''ve exceeded '); -end; -@# -procedure bst_2print_string_size_exceeded; -begin -print ('-string-size,'); -bst_mild_ex_warn_print; -print_ln ('*Please notify the bibstyle designer*'); -end; - - -@ -@.entry string size exceeded@> -@:String size exceeded}{\quad entry string size@> -This module checks that what we're about to assign is really a -string, and then assigns. - -@<Assign to a |str_entry_var|@>= -begin -if (pop_typ2 <> stk_str) then - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_str) - else - begin - str_ent_ptr := cite_ptr*num_ent_strs + fn_info[pop_lit1]; - ent_chr_ptr := 0; - sp_ptr := str_start[pop_lit2]; - sp_xptr1 := str_start[pop_lit2+1]; - if (sp_xptr1-sp_ptr > ent_str_size) then - begin - bst_string_size_exceeded (ent_str_size:0,', the entry'); - sp_xptr1 := sp_ptr + ent_str_size; - end; - while (sp_ptr < sp_xptr1) do - begin {copy characters into |entry_strs|} - entry_strs[str_ent_ptr][ent_chr_ptr] := str_pool[sp_ptr]; - incr(ent_chr_ptr); - incr(sp_ptr); - end; - entry_strs[str_ent_ptr][ent_chr_ptr] := end_of_string; - end -end - - -@ -This module checks that what we're about to assign is really an -integer, and then assigns. - -@<Assign to an |int_global_var|@>= -if (pop_typ2 <> stk_int) then - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int) - else - fn_info[pop_lit1] := pop_lit2 - - -@ -@.global string size exceeded@> -@:String size exceeded}{\quad global string size@> -This module checks that what we're about to assign is really a -string, and then assigns. - -@<Assign to a |str_global_var|@>= -begin -if (pop_typ2 <> stk_str) then - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_str) - else - begin - str_glb_ptr := fn_info[pop_lit1]; - if (pop_lit2 < cmd_str_ptr) then - glb_str_ptr[str_glb_ptr] := pop_lit2 - else - begin - glb_str_ptr[str_glb_ptr] := 0; - glob_chr_ptr := 0; - sp_ptr := str_start[pop_lit2]; - sp_end := str_start[pop_lit2+1]; - if (sp_end - sp_ptr > glob_str_size) then - begin - bst_string_size_exceeded (glob_str_size:0,', the global'); - sp_end := sp_ptr + glob_str_size; - end; - while (sp_ptr < sp_end) do - begin {copy characters into |global_strs|} - global_strs[str_glb_ptr][glob_chr_ptr] := str_pool[sp_ptr]; - incr(glob_chr_ptr); - incr(sp_ptr); - end; - glb_str_end[str_glb_ptr] := glob_chr_ptr; - end; - end -end - - -@ -The |built_in| function {\.{add.period\$}} pops the top (string) -literal, adds a |period| to a nonnull string if its last -non|right_brace| character isn't a |period|, |question_mark|, or -|exclamation_mark|, and pushes this resulting string back onto the -stack. If the literal isn't a string, it complains and pushes the -null string. - -@<|execute_fn|({\.{add.period\$}})@>= -procedure x_add_period; -label loop_exit; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (s_null, stk_str); - end -else if (length(pop_lit1) = 0) then {don't add |period| to the null string} - push_lit_stk (s_null, stk_str) -else - @<Add the |period|, if necessary, and push@>; -end; - - -@ -@^push the literal stack@> -Here we scan backwards from the end of the string, skipping -non|right_brace| characters, to see if we have to add the |period|. - -@<Add the |period|, if necessary, and push@>= -begin -sp_ptr := str_start[pop_lit1+1]; -sp_end := str_start[pop_lit1]; -while (sp_ptr > sp_end) do {find a non|right_brace|} - begin - decr(sp_ptr); - if (str_pool[sp_ptr] <> right_brace) then - goto loop_exit; - end; -loop_exit: -case (str_pool[sp_ptr]) of - period, - question_mark, - exclamation_mark : - repush_string; - othercases - @<Add the |period| (it's necessary) and push@> -endcases; -end - - -@ -Ok guys, we really have to do it. - -@<Add the |period| (it's necessary) and push@>= -begin -if (pop_lit1 < cmd_str_ptr) then - begin - str_room (length(pop_lit1)+1); - sp_ptr := str_start[pop_lit1]; - sp_end := str_start[pop_lit1+1]; - while (sp_ptr < sp_end) do {slide |pop_lit1| atop the string pool} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; - end -else {the string is already there} - begin - pool_ptr := str_start[pop_lit1+1]; - str_room (1); - end; -append_char (period); -push_lit_stk (make_string, stk_str); -end - - -@ -The |built_in| function {\.{call.type\$}} executes the function -specified in |type_list| for this entry unless it's |undefined|, in -which case it executes the default function \.{default.type} defined -in the \.{.bst} file, or unless it's |empty|, in which case it does -nothing. - -@<|execute_fn|({\.{call.type\$}})@>= -begin -if (not mess_with_entries) then - bst_cant_mess_with_entries_print - else - if (type_list[cite_ptr] = undefined) then - execute_fn (b_default) - else if (type_list[cite_ptr] = empty) then - do_nothing - else - execute_fn (type_list[cite_ptr]); -end - - -@ -The |built_in| function {\.{change.case\$}} pops the top two (string) -literals; it changes the case of the second according to the -specifications of the first, as follows. (Note: The word `letters' in -the next sentence refers only to those at brace-level~0, the top-most -brace level; no other characters are changed, except perhaps for -special characters, described shortly.) If the first literal is the -string~\.{t}, it converts to lower case all letters except the very -first character in the string, which it leaves alone, and except the -first character following any |colon| and then nonnull |white_space|, -which it also leaves alone; if it's the string~\.{l}, it converts all -letters to lower case; if it's the string~\.{u}, it converts all -letters to upper case; and if it's anything else, it complains and -does no conversion. It then pushes this resulting string. If either -type is incorrect, it complains and pushes the null string; however, -if both types are correct but the specification string (i.e., the -first string) isn't one of the legal ones, it merely pushes the second -back onto the stack, after complaining. (Another note: It ignores -case differences in the specification string; for example, the strings -\.{t} and \.{T} are equivalent for the purposes of this |built_in| -function.) - -@d ok_pascal_i_give_up = 21 - -@<|execute_fn|({\.{change.case\$}})@>= -procedure x_change_case; -label ok_pascal_i_give_up; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ2 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_str); - push_lit_stk (s_null, stk_str); - end -else - begin - @<Determine the case-conversion type@>; - ex_buf_length := 0; - add_buf_pool (pop_lit2); - @<Perform the case conversion@>; - add_pool_buf_and_push; {push this string onto the stack} - end; -end; - - -@ -First we define a few variables for case conversion. The constant -definitions, to be used in |case| statements, are in order of probable -frequency. - -@d title_lowers = 0 {representing the string \.{t}} -@d all_lowers = 1 {representing the string \.{l}} -@d all_uppers = 2 {representing the string \.{u}} -@d bad_conversion = 3 {representing any illegal case-conversion string} - -@<Globals in the outer block@>= -@!conversion_type : 0..bad_conversion; {the possible cases} -@!prev_colon : boolean; {|true| if just past a |colon|} - - -@ -Now we determine which of the three case-conversion types we're -dealing with: \.{t},~\.{l}, or~\.{u}. - -@<Determine the case-conversion type@>= -begin -case (str_pool[str_start[pop_lit1]]) of - "t","T" : conversion_type := title_lowers; - "l","L" : conversion_type := all_lowers; - "u","U" : conversion_type := all_uppers; - othercases conversion_type := bad_conversion -endcases; -if ((length(pop_lit1) <> 1) or (conversion_type = bad_conversion)) then - begin - conversion_type := bad_conversion; - print_pool_str (pop_lit1); - bst_ex_warn (' is an illegal case-conversion string'); - end; -end - - -@ -This procedure complains if the just-encountered |right_brace| would -make |brace_level| negative. - -@<Procedures and functions for name-string processing@>= -procedure decr_brace_level (@!pop_lit_var : str_number); -begin -if (brace_level = 0) then - braces_unbalanced_complaint (pop_lit_var) - else - decr(brace_level); -end; - - -@ -This complaint often arises because the style designer has to type -lots of braces. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure braces_unbalanced_complaint (@!pop_lit_var : str_number); -begin -print ('Warning--"'); -print_pool_str (pop_lit_var); -bst_mild_ex_warn ('" isn''t a brace-balanced string'); -end; - - -@ -This one makes sure that |brace_level=0| (it's called at a point in a -string where braces must be balanced). - -@<Procedures and functions for name-string processing@>= -procedure check_brace_level (@!pop_lit_var : str_number); -begin -if (brace_level > 0) then - braces_unbalanced_complaint (pop_lit_var); -end; - - -@ -Here's where we actually go through the string and do the case -conversion. - -@<Perform the case conversion@>= -begin -brace_level := 0; {this is the top level} -ex_buf_ptr := 0; {we start with the string's first character} -while (ex_buf_ptr < ex_buf_length) do - begin - if (ex_buf[ex_buf_ptr] = left_brace) then - begin - incr(brace_level); - if (brace_level <> 1) then - goto ok_pascal_i_give_up; - if (ex_buf_ptr + 4 > ex_buf_length) then - goto ok_pascal_i_give_up - else if (ex_buf[ex_buf_ptr+1] <> backslash) then - goto ok_pascal_i_give_up; - if (conversion_type = title_lowers) then - if (ex_buf_ptr = 0) then - goto ok_pascal_i_give_up - else if ((prev_colon) and - (lex_class[ex_buf[ex_buf_ptr-1]] = white_space)) then - goto ok_pascal_i_give_up; - @<Convert a special character@>; -ok_pascal_i_give_up: - prev_colon := false; - end - else if (ex_buf[ex_buf_ptr] = right_brace) then - begin - decr_brace_level (pop_lit2); - prev_colon := false; - end - else - if (brace_level = 0) then - @<Convert a |brace_level = 0| character@>; - incr(ex_buf_ptr); - end; -check_brace_level (pop_lit2); -end - - -@ -@^special character@> -We're dealing with a special character (usually either an undotted -`\i' or `\j', or an accent like one in Table~3.1 of the \LaTeX\ -manual, or a foreign character like one in Table~3.2) if the first -character after the |left_brace| is a |backslash|; the special -character ends with the matching |right_brace|. How we handle what's -in between depends on the special character. In general, this code -will do reasonably well if there is other stuff, too, between braces, -but it doesn't try to do anything special with |colon|s. - -@<Convert a special character@>= -begin -incr(ex_buf_ptr); {skip over the |left_brace|} -while ((ex_buf_ptr < ex_buf_length) and (brace_level > 0)) do - begin - incr(ex_buf_ptr); {skip over the |backslash|} - ex_buf_xptr := ex_buf_ptr; - while ((ex_buf_ptr < ex_buf_length) and - (lex_class[ex_buf[ex_buf_ptr]] = alpha)) do - incr(ex_buf_ptr); {this scans the control sequence} - control_seq_loc := str_lookup(ex_buf,ex_buf_xptr,ex_buf_ptr-ex_buf_xptr, - control_seq_ilk,dont_insert); - if (hash_found) then - @<Convert the accented or foreign character, if necessary@>; - ex_buf_xptr := ex_buf_ptr; - while ((ex_buf_ptr < ex_buf_length) and (brace_level > 0) and - (ex_buf[ex_buf_ptr] <> backslash)) do - begin {this scans to the next control sequence} - if (ex_buf[ex_buf_ptr] = right_brace) then - decr(brace_level) - else if (ex_buf[ex_buf_ptr] = left_brace) then - incr(brace_level); - incr(ex_buf_ptr); - end; - @<Convert a noncontrol sequence@>; - end; -decr(ex_buf_ptr); {unskip the |right_brace|} -end - - -@ -@^control sequence@> -@:this can't happen}{\quad Unknown type of case conversion@> -A control sequence, for the purposes of this program, consists just of -the consecutive alphabetic characters following the |backslash|; it -might be empty (although ones in this section aren't). - -@<Convert the accented or foreign character, if necessary@>= -begin -case (conversion_type) of - title_lowers, - all_lowers : - case (ilk_info[control_seq_loc]) of - n_l_upper, - n_o_upper, - n_oe_upper, - n_ae_upper, - n_aa_upper : - lower_case (ex_buf, ex_buf_xptr, ex_buf_ptr-ex_buf_xptr); - othercases - do_nothing - endcases; - all_uppers : - case (ilk_info[control_seq_loc]) of - n_l, - n_o, - n_oe, - n_ae, - n_aa : - upper_case (ex_buf, ex_buf_xptr, ex_buf_ptr-ex_buf_xptr); - n_i, - n_j, - n_ss : - @<Convert, then remove the control sequence@>; - othercases - do_nothing - endcases; - bad_conversion : - do_nothing; - othercases - case_conversion_confusion -endcases; -end - - -@ -@:this can't happen}{\quad Unknown type of case conversion@> -Another bug complaint. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure case_conversion_confusion; -begin -confusion ('Unknown type of case conversion'); -end; - - -@ -After converting the control sequence, we need to remove the preceding -|backslash| and any following |white_space|. - -@<Convert, then remove the control sequence@>= -begin -upper_case (ex_buf, ex_buf_xptr, ex_buf_ptr-ex_buf_xptr); -while (ex_buf_xptr < ex_buf_ptr) do - begin {remove preceding |backslash| and shift down} - ex_buf[ex_buf_xptr-1] := ex_buf[ex_buf_xptr]; - incr(ex_buf_xptr); - end; -decr(ex_buf_xptr); -while ((ex_buf_ptr < ex_buf_length) and - (lex_class[ex_buf[ex_buf_ptr]] = white_space)) do - incr(ex_buf_ptr); {remove |white_space| trailing the control seq} -tmp_ptr := ex_buf_ptr; -while (tmp_ptr < ex_buf_length) do - begin {more shifting down} - ex_buf[tmp_ptr-(ex_buf_ptr-ex_buf_xptr)] := ex_buf[tmp_ptr]; - incr(tmp_ptr) - end; -ex_buf_length := tmp_ptr - (ex_buf_ptr - ex_buf_xptr); -ex_buf_ptr := ex_buf_xptr; -end - - -@ -@:this can't happen}{\quad Unknown type of case conversion@> -There are no control sequences in what we're about to convert, -so a straight conversion suffices. - -@<Convert a noncontrol sequence@>= -begin -case (conversion_type) of - title_lowers, - all_lowers : - lower_case (ex_buf, ex_buf_xptr, ex_buf_ptr-ex_buf_xptr); - all_uppers : - upper_case (ex_buf, ex_buf_xptr, ex_buf_ptr-ex_buf_xptr); - bad_conversion : - do_nothing; - othercases - case_conversion_confusion -endcases; -end - - -@ -@:this can't happen}{\quad Unknown type of case conversion@> -This code does any needed conversion for an ordinary character; it -won't touch nonletters. - -@<Convert a |brace_level = 0| character@>= -begin -case (conversion_type) of - title_lowers : - begin - if (ex_buf_ptr = 0) then - do_nothing - else if ((prev_colon) and - (lex_class[ex_buf[ex_buf_ptr-1]] = white_space)) then - do_nothing - else - lower_case (ex_buf, ex_buf_ptr, 1); - if (ex_buf[ex_buf_ptr] = colon) then - prev_colon := true - else if (lex_class[ex_buf[ex_buf_ptr]] <> white_space) then - prev_colon := false; - end; - all_lowers : - lower_case (ex_buf, ex_buf_ptr, 1); - all_uppers : - upper_case (ex_buf, ex_buf_ptr, 1); - bad_conversion : - do_nothing; - othercases - case_conversion_confusion -endcases; -end - - -@ -The |built_in| function {\.{chr.to.int\$}} pops the top (string) -literal, makes sure it's a single character, converts it to the -corresponding |ASCII_code| integer, and pushes this integer. If the -literal isn't an appropriate string, it complains and pushes the -integer~0. - -@<|execute_fn|({\.{chr.to.int\$}})@>= -procedure x_chr_to_int; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (0, stk_int); - end -else if (length(pop_lit1) <> 1) then - begin - print ('"'); - print_pool_str (pop_lit1); - bst_ex_warn ('" isn''t a single character'); - push_lit_stk (0, stk_int); - end -else - push_lit_stk (str_pool[str_start[pop_lit1]], stk_int); - {push the (|ASCII_code|) integer} -end; - - -@ -The |built_in| function {\.{cite\$}} pushes the appropriate string -from |cite_list| onto the stack. - -@<|execute_fn|({\.{cite\$}})@>= -procedure x_cite; -begin -if (not mess_with_entries) then - bst_cant_mess_with_entries_print - else - push_lit_stk (cur_cite_str, stk_str); -end; - - -@ -@^push the literal stack@> -The |built_in| function {\.{duplicate\$}} pops the top literal from -the stack and pushes two copies of it. - -@<|execute_fn|({\.{duplicate\$}})@>= -procedure x_duplicate; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - push_lit_stk (pop_lit1, pop_typ1); - push_lit_stk (pop_lit1, pop_typ1); - end - else - begin - repush_string; - if (pop_lit1 < cmd_str_ptr) then - push_lit_stk (pop_lit1, pop_typ1) - else - begin - str_room (length(pop_lit1)); - sp_ptr := str_start[pop_lit1]; - sp_end := str_start[pop_lit1+1]; - while (sp_ptr < sp_end) do - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; - push_lit_stk (make_string, stk_str); {and push it onto the stack} - end; - end; -end; - - -@ -The |built_in| function {\.{empty\$}} pops the top literal and pushes -the integer 1 if it's a missing field or a string having no -non|white_space| characters, 0 otherwise. If the literal isn't a -missing field or a string, it complains and pushes 0. - -@<|execute_fn|({\.{empty\$}})@>= -procedure x_empty; -label exit; -begin -pop_lit_stk (pop_lit1,pop_typ1); -case (pop_typ1) of - stk_str : @<Push 0 if the string has a non|white_space| char, else 1@>; - stk_field_missing : push_lit_stk (1, stk_int); - stk_empty : push_lit_stk (0, stk_int); - othercases - begin - print_stk_lit (pop_lit1,pop_typ1); - bst_ex_warn (', not a string or missing field,'); - push_lit_stk (0, stk_int); - end -endcases; -exit: -end; - - -@ -When we arrive here we're dealing with a legitimate string. If it has -no characters, or has nothing but |white_space| characters, we push~1, -otherwise we push~0. - -@<Push 0 if the string has a non|white_space| char, else 1@>= -begin -sp_ptr := str_start[pop_lit1]; -sp_end := str_start[pop_lit1+1]; -while (sp_ptr < sp_end) do - begin - if (lex_class[str_pool[sp_ptr]] <> white_space) then - begin - push_lit_stk (0, stk_int); - return; - end; - incr(sp_ptr); - end; -push_lit_stk (1, stk_int); -end - - -@ -The |built_in| function {\.{format.name\$}} pops the top three -literals (they are a string, an integer, and a string literal, in that -order). The last string literal represents a name list (each name -corresponding to a person), the integer literal specifies which name -to pick from this list, and the first string literal specifies how to -format this name, as described in the \BibTeX\ documentation. -Finally, this function pushes the formatted name. If any of the types -is incorrect, it complains and pushes the null string. - -@d von_found = 52 {for when a von token is found} - -@<|execute_fn|({\.{format.name\$}})@>= -procedure x_format_name; -label loop1_exit,@!loop2_exit,@!von_found; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -pop_lit_stk (pop_lit3,pop_typ3); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ2 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ3 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit3,pop_typ3,stk_str); - push_lit_stk (s_null, stk_str); - end -else - begin - ex_buf_length := 0; - add_buf_pool (pop_lit3); - @<Isolate the desired name@>; - @<Copy name and count |comma|s to determine syntax@>; - @<Find the parts of the name@>; - ex_buf_length := 0; - add_buf_pool (pop_lit1); - figure_out_the_formatted_name;@/ - add_pool_buf_and_push; {push the formatted string onto the stack} - end; -end; - - -@ -This module skips over undesired names in |pop_lit3| and it throws -away the ``and'' from the end of the name if it exists. When it's -done, |ex_buf_xptr| points to its first character and |ex_buf_ptr| -points just past its last. - -@<Isolate the desired name@>= -begin -ex_buf_ptr := 0; -num_names := 0; -while ((num_names < pop_lit2) and (ex_buf_ptr < ex_buf_length)) do - begin - incr(num_names); - ex_buf_xptr := ex_buf_ptr; - name_scan_for_and (pop_lit3); - end; -if (ex_buf_ptr < ex_buf_length) then {remove the ``and''} - ex_buf_ptr := ex_buf_ptr - 4; -if (num_names < pop_lit2) then - begin - if (pop_lit2 = 1) then - print ('There is no name in "') - else - print ('There aren''t ',pop_lit2:0,' names in "'); - print_pool_str (pop_lit3); - bst_ex_warn ('"'); - end -end - - -@ -This module, starting at |ex_buf_ptr|, looks in |ex_buf| for an -``and'' surrounded by nonnull |white_space|. It stops either at -|ex_buf_length| or just past the ``and'', whichever comes first, -setting |ex_buf_ptr| accordingly. Its parameter |pop_lit_var| is -either |pop_lit3| or |pop_lit1|, depending on whether -{\.{format.name\$}} or {\.{num.names\$}} calls it. - -@<Procedures and functions for name-string processing@>= -procedure name_scan_for_and (@!pop_lit_var : str_number); -begin -brace_level := 0; -preceding_white := false; -and_found := false; -while ((not and_found) and (ex_buf_ptr < ex_buf_length)) do - case (ex_buf[ex_buf_ptr]) of - "a", "A" : - begin - incr(ex_buf_ptr); - if (preceding_white) then - @<See if we have an ``and''@>; {if so, |and_found := true|} - preceding_white := false; - end; - left_brace : - begin - incr(brace_level); - incr(ex_buf_ptr); - @<Skip over |ex_buf| stuff at |brace_level > 0|@>; - preceding_white := false; - end; - right_brace : - begin - decr_brace_level (pop_lit_var); {this checks for an error} - incr(ex_buf_ptr); - preceding_white := false; - end; - othercases - if (lex_class[ex_buf[ex_buf_ptr]] = white_space) then - begin - incr(ex_buf_ptr); - preceding_white := true; - end - else - begin - incr(ex_buf_ptr); - preceding_white := false; - end - endcases; -check_brace_level (pop_lit_var); -end; - - -@ -When we come here |ex_buf_ptr| is just past the |left_brace|, and when -we leave it's either at |ex_buf_length| or just past the matching -|right_brace|. - -@<Skip over |ex_buf| stuff at |brace_level > 0|@>= -while ((brace_level > 0) and (ex_buf_ptr < ex_buf_length)) do - begin - if (ex_buf[ex_buf_ptr] = right_brace) then - decr(brace_level) - else if (ex_buf[ex_buf_ptr] = left_brace) then - incr(brace_level); - incr(ex_buf_ptr); - end - - -@ -When we come here |ex_buf_ptr| is just past the ``a'' or ``A'', and when -we leave it's either at the same place or, if we found an ``and'', at -the following |white_space| character. - -@<See if we have an ``and''@>= -begin -if (ex_buf_ptr <= (ex_buf_length - 3)) then {enough characters are left} - if ((ex_buf[ex_buf_ptr] = "n") or (ex_buf[ex_buf_ptr] = "N")) then - if ((ex_buf[ex_buf_ptr+1] = "d") or (ex_buf[ex_buf_ptr+1] = "D")) then - if (lex_class[ex_buf[ex_buf_ptr+2]] = white_space) then - begin - ex_buf_ptr := ex_buf_ptr + 2; - and_found := true; - end; -end - - -@ -When we arrive here, the desired name is in |ex_buf[ex_buf_xptr]| -through |ex_buf[ex_buf_ptr-1]|. This module does its thing for -characters only at |brace_level = 0|; the rest get processed verbatim. -It removes leading |white_space| (and |sep_char|s), and trailing -|white_space| (and |sep_char|s) and |comma|s, complaining for each -trailing |comma|. It then copies the name into |name_buf|, removing -all |white_space|, |sep_char|s and |comma|s, counting |comma|s, and -constructing a list of name tokens, which are sequences of characters -separated (at |brace_level=0|) by |white_space|, |sep_char|s or -|comma|s. Each name token but the first has an associated -|name_sep_char|, the character that separates it from the preceding -token. If there are too many (more than two) |comma|s, a complaint is -in order. - -@<Copy name and count |comma|s to determine syntax@>= -begin -@<Remove leading and trailing junk, complaining if necessary@>; -name_bf_ptr := 0; -num_commas := 0; -num_tokens := 0;@/ -token_starting := true; {to indicate that a name token is starting} -while (ex_buf_xptr < ex_buf_ptr) do - case (ex_buf[ex_buf_xptr]) of - comma : @<Name-process a |comma|@>; - left_brace : @<Name-process a |left_brace|@>; - right_brace : @<Name-process a |right_brace|@>; - othercases - case (lex_class[ex_buf[ex_buf_xptr]]) of - white_space : @<Name-process a |white_space|@>; - sep_char : @<Name-process a |sep_char|@>; - othercases @<Name-process some other character@> - endcases - endcases; -name_tok[num_tokens] := name_bf_ptr; {this is an end-marker} -end - - -@ -This module removes all leading |white_space| (and |sep_char|s), and -trailing |white_space| (and |sep_char|s) and |comma|s. It complains -for each trailing |comma|. - -@<Remove leading and trailing junk, complaining if necessary@>= -begin -while ((ex_buf_xptr < ex_buf_ptr) and - (lex_class[ex_buf[ex_buf_ptr]] = white_space) and - (lex_class[ex_buf[ex_buf_ptr]] = sep_char)) do - incr(ex_buf_xptr); {this removes leading stuff} -while (ex_buf_ptr > ex_buf_xptr) do {now remove trailing stuff} - case (lex_class[ex_buf[ex_buf_ptr-1]]) of - white_space, - sep_char : - decr(ex_buf_ptr); - othercases - if (ex_buf[ex_buf_ptr-1] = comma) then - begin - print ('Name ',pop_lit2:0,' in "'); - print_pool_str (pop_lit3); - print ('" has a comma at the end'); - bst_ex_warn_print; - decr(ex_buf_ptr); - end - else - goto loop1_exit - endcases; -loop1_exit: - -end - -@ -Here we mark the token number at which this comma has occurred. - -@<Name-process a |comma|@>= -begin -if (num_commas = 2) then - begin - print ('Too many commas in name ',pop_lit2:0,' of "'); - print_pool_str (pop_lit3); - print ('"'); - bst_ex_warn_print; - end - else - begin - incr(num_commas); - if (num_commas = 1) then - comma1 := num_tokens - else - comma2 := num_tokens; {|num_commas = 2|} - name_sep_char[num_tokens] := comma; - end; -incr(ex_buf_xptr); -token_starting := true; -end - - -@ -We copy the stuff up through the matching |right_brace| verbatim. - -@<Name-process a |left_brace|@>= -begin -incr(brace_level); -if (token_starting) then - begin - name_tok[num_tokens] := name_bf_ptr; - incr(num_tokens); - end; -name_buf[name_bf_ptr] := ex_buf[ex_buf_xptr]; -incr(name_bf_ptr); -incr(ex_buf_xptr); -while ((brace_level > 0) and (ex_buf_xptr < ex_buf_ptr)) do - begin - if (ex_buf[ex_buf_xptr] = right_brace) then - decr(brace_level) - else if (ex_buf[ex_buf_xptr] = left_brace) then - incr(brace_level); - name_buf[name_bf_ptr] := ex_buf[ex_buf_xptr]; - incr(name_bf_ptr); - incr(ex_buf_xptr); - end; -token_starting := false; -end - - -@ -We don't copy an extra |right_brace|; this code will almost never be -executed. - -@<Name-process a |right_brace|@>= -begin -if (token_starting) then - begin - name_tok[num_tokens] := name_bf_ptr; - incr(num_tokens); - end; -print ('Name ',pop_lit2:0,' of "'); -print_pool_str (pop_lit3); -bst_ex_warn ('" isn''t brace balanced'); -incr(ex_buf_xptr); -token_starting := false; -end - - -@ -A token will be starting soon in a buffer near you, one way$\ldots$ - -@<Name-process a |white_space|@>= -begin -if (not token_starting) then - name_sep_char[num_tokens] := space; -incr(ex_buf_xptr); -token_starting := true; -end - - -@ -@^user abuse@> -or another. If one of the valid |sep_char|s appears between tokens, -we usually use it instead of a |space|. If the user has been silly -enough to have multiple |sep_char|s, or to have both |white_space| and -a |sep_char|, we use the first such character. - -@<Name-process a |sep_char|@>= -begin -if (not token_starting) then - name_sep_char[num_tokens] := ex_buf[ex_buf_xptr]; -incr(ex_buf_xptr); -token_starting := true; -end - - -@ -For ordinary characters, we just copy the character. - -@<Name-process some other character@>= -begin -if (token_starting) then - begin - name_tok[num_tokens] := name_bf_ptr; - incr(num_tokens); - end; -name_buf[name_bf_ptr] := ex_buf[ex_buf_xptr]; -incr(name_bf_ptr); -incr(ex_buf_xptr); -token_starting := false; -end - - -@ -@:this can't happen}{\quad Illegal number of comma,s@> -Here we set all the pointers for the various parts of the name, -depending on which of the three possible syntaxes this name uses. - -@<Find the parts of the name@>= -begin -if (num_commas = 0) then - begin - first_start := 0; - last_end := num_tokens; - jr_end := last_end; - @<Determine where the first name ends and von name starts and ends@>; - end -else if (num_commas = 1) then - begin - von_start := 0; - last_end := comma1; - jr_end := last_end; - first_start := jr_end; - first_end := num_tokens; - von_name_ends_and_last_name_starts_stuff; - end -else if (num_commas = 2) then - begin - von_start := 0; - last_end := comma1; - jr_end := comma2; - first_start := jr_end; - first_end := num_tokens; - von_name_ends_and_last_name_starts_stuff; - end -else - confusion ('Illegal number of comma,s'); -end - - -@ -When there are no brace-level-0 |comma|s in the name, the von name -starts with the first nonlast token whose first brace-level-0 letter -is in lower case (for the purposes of this determination, an accented -or foreign character at brace-level-1 that's in lower case will do, as -well). A module following this one determines where the von name ends -and the last starts. - -@<Determine where the first name ends and von name starts and ends@>= -begin -von_start := 0; -while (von_start < last_end-1) do - begin - name_bf_ptr := name_tok[von_start]; - name_bf_xptr := name_tok[von_start+1]; - if (von_token_found) then - begin - von_name_ends_and_last_name_starts_stuff; - goto von_found; - end; - incr(von_start); - end; {there's no von name, so} -while (von_start > 0) do {backtrack if there are connected tokens} - begin - if ((lex_class[name_sep_char[von_start]] <> sep_char) or - (name_sep_char[von_start] = tie)) then - goto loop2_exit; - decr(von_start); - end; -loop2_exit: -von_end := von_start; -von_found: -first_end := von_start; -end - - -@ -@^special character@> -It's a von token if there exists a first brace-level-0 letter (or -brace-level-1 special character), and it's in lower case; in this case -we return |true|. The token is in |name_buf|, starting at -|name_bf_ptr| and ending just before |name_bf_xptr|. - -@d return_von_found == begin - von_token_found := true; - return; - end - -@<Procedures and functions for name-string processing@>= -function von_token_found : boolean; -label exit; -begin -nm_brace_level := 0; -von_token_found := false; {now it's easy to exit if necessary} -while (name_bf_ptr < name_bf_xptr) do - if ((name_buf[name_bf_ptr] >= "A") and - (name_buf[name_bf_ptr] <= "Z")) then - return - else if ((name_buf[name_bf_ptr] >= "a") and - (name_buf[name_bf_ptr] <= "z")) then - return_von_found - else if (name_buf[name_bf_ptr] = left_brace) then - begin - incr(nm_brace_level); - incr(name_bf_ptr); - if ((name_bf_ptr + 2 < name_bf_xptr) and - (name_buf[name_bf_ptr] = backslash)) then - @<Check the special character (and |return|)@> - else - @<Skip over |name_buf| stuff at |nm_brace_level > 0|@>; - end - else - incr(name_bf_ptr); -exit: -end; - - -@ -@^special character@> -When we come here |name_bf_ptr| is just past the |left_brace|, -but we always leave by |return|ing. - -@<Check the special character (and |return|)@>= -begin -incr(name_bf_ptr); {skip over the |backslash|} -name_bf_yptr := name_bf_ptr; -while ((name_bf_ptr < name_bf_xptr) and - (lex_class[name_buf[name_bf_ptr]] = alpha)) do - incr(name_bf_ptr); {this scans the control sequence} -control_seq_loc := str_lookup(name_buf,name_bf_yptr,name_bf_ptr-name_bf_yptr, - control_seq_ilk,dont_insert); -if (hash_found) then - @<Handle this accented or foreign character (and |return|)@>; -while ((name_bf_ptr < name_bf_xptr) and (nm_brace_level > 0)) do - begin - if ((name_buf[name_bf_ptr] >= "A") and - (name_buf[name_bf_ptr] <= "Z")) then - return - else if ((name_buf[name_bf_ptr] >= "a") and - (name_buf[name_bf_ptr] <= "z")) then - return_von_found - else if (name_buf[name_bf_ptr] = right_brace) then - decr(nm_brace_level) - else if (name_buf[name_bf_ptr] = left_brace) then - incr(nm_brace_level); - incr(name_bf_ptr); - end; -return; -end - - -@ -@:this can't happen}{\quad Control-sequence hash error@> -The accented or foreign character is either `\.{\\i}' or `\.{\\j}' or -one of the eleven alphabetic foreign characters in Table~3.2 of the -\LaTeX\ manual. - -@<Handle this accented or foreign character (and |return|)@>= -begin -case (ilk_info[control_seq_loc]) of - n_oe_upper, - n_ae_upper, - n_aa_upper, - n_o_upper, - n_l_upper : - return; - n_i, - n_j, - n_oe, - n_ae, - n_aa, - n_o, - n_l, - n_ss : - return_von_found; - othercases - confusion ('Control-sequence hash error') -endcases; -end - - -@ -When we come here |name_bf_ptr| is just past the |left_brace|; when we -leave it's either at |name_bf_xptr| or just past the matching -|right_brace|. - -@<Skip over |name_buf| stuff at |nm_brace_level > 0|@>= -while ((nm_brace_level > 0) and (name_bf_ptr < name_bf_xptr)) do - begin - if (name_buf[name_bf_ptr] = right_brace) then - decr(nm_brace_level) - else if (name_buf[name_bf_ptr] = left_brace) then - incr(nm_brace_level); - incr(name_bf_ptr); - end - - -@ -@^Casey Stengel would be proud@> -@^special character@> -@^Tuesdays@> -The last name starts just past the last token, before the first -|comma| (if there is no |comma|, there is deemed to be one at the end -of the string), for which there exists a first brace-level-0 letter -(or brace-level-1 special character), and it's in lower case, unless -this last token is also the last token before the |comma|, in which -case the last name starts with this token (unless this last token is -connected by a |sep_char| other than a |tie| to the previous token, in -which case the last name starts with as many tokens earlier as are -connected by non|tie|s to this last one (except on Tuesdays -$\ldots\,$), although this module never sees such a case). Note that -if there are any tokens in either the von or last names, then the last -name has at least one, even if it starts with a lower-case letter. - -@<Procedures and functions for name-string processing@>= -procedure von_name_ends_and_last_name_starts_stuff; -label exit; -begin {there may or may not be a von name} -von_end := last_end - 1; -while (von_end > von_start) do - begin - name_bf_ptr := name_tok[von_end-1]; - name_bf_xptr := name_tok[von_end]; - if (von_token_found) then - return; - decr(von_end); - end; -exit: -end; - - -@ -This module uses the information in |pop_lit1| to format the name. -Everything at |sp_brace_level = 0| is copied verbatim to the formatted -string; the rest is described in the succeeding modules. - -@<Figure out the formatted name@>= -begin -ex_buf_ptr := 0; -sp_brace_level := 0; -sp_ptr := str_start[pop_lit1]; -sp_end := str_start[pop_lit1+1]; -while (sp_ptr < sp_end) do - if (str_pool[sp_ptr] = left_brace) then - begin - incr(sp_brace_level); - incr(sp_ptr); - @<Format this part of the name@>; - end - else if (str_pool[sp_ptr] = right_brace) then - begin - braces_unbalanced_complaint (pop_lit1); - incr(sp_ptr); - end - else - begin - append_ex_buf_char_and_check (str_pool[sp_ptr]); - incr(sp_ptr); - end; -if (sp_brace_level > 0) then - braces_unbalanced_complaint (pop_lit1); -ex_buf_length := ex_buf_ptr; -end - - -@ -When we arrive here we're at |sp_brace_level = 1|, just past the -|left_brace|. Letters at this |sp_brace_level| other than those -denoting the parts of the name (i.e., the first letters of `first,' -`last,' `von,' and `jr,' ignoring case) are illegal. We do two passes -over this group; the first determines whether we're to output -anything, and, if we are, the second actually outputs it. - -@<Format this part of the name@>= -begin -sp_xptr1 := sp_ptr; -alpha_found := false; -double_letter := false; -end_of_group := false; -to_be_written := true; -while ((not end_of_group) and (sp_ptr < sp_end)) do - if (lex_class[str_pool[sp_ptr]] = alpha) then - begin - incr(sp_ptr); - @<Figure out what this letter means@>; - end - else if (str_pool[sp_ptr] = right_brace) then - begin - decr(sp_brace_level); - incr(sp_ptr); - end_of_group := true; - end - else if (str_pool[sp_ptr] = left_brace) then - begin - incr(sp_brace_level); - incr(sp_ptr); - skip_stuff_at_sp_brace_level_greater_than_one; - end - else - incr(sp_ptr); -if ((end_of_group) and (to_be_written)) then {do the second pass} - @<Finally format this part of the name@>; -end - - -@ -When we come here |sp_ptr| is just past the |left_brace|, and when we -leave it's either at |sp_end| or just past the matching |right_brace|. - -@<Procedures and functions for name-string processing@>= -procedure skip_stuff_at_sp_brace_level_greater_than_one; -begin -while ((sp_brace_level > 1) and (sp_ptr < sp_end)) do - begin - if (str_pool[sp_ptr] = right_brace) then - decr(sp_brace_level) - else if (str_pool[sp_ptr] = left_brace) then - incr(sp_brace_level); - incr(sp_ptr); - end; -end; - - -@ -We won't output anything for this part of the name if this is a second -occurrence of an |sp_brace_level = 1| letter, if it's an illegal -letter, or if there are no tokens corresponding to this part. We also -determine if we're we to output complete tokens (indicated by a double -letter). - -@<Figure out what this letter means@>= -begin -if (alpha_found) then - begin - brace_lvl_one_letters_complaint; - to_be_written := false; - end - else - begin - case (str_pool[sp_ptr-1]) of - "f","F" : @<Figure out what tokens we'll output for the `first' name@>; - "v","V" : @<Figure out what tokens we'll output for the `von' name@>; - "l","L" : @<Figure out what tokens we'll output for the `last' name@>; - "j","J" : @<Figure out what tokens we'll output for the `jr' name@>; - othercases - begin - brace_lvl_one_letters_complaint; - to_be_written := false; - end - endcases; - if (double_letter) then - incr(sp_ptr); - end; -alpha_found := true; -end - - -@ -At most one of the important letters, perhaps doubled, may appear at -|sp_brace_level = 1|. - -@<Procedures and functions for name-string processing@>= -procedure brace_lvl_one_letters_complaint; -begin -print ('The format string "'); -print_pool_str (pop_lit1); -bst_ex_warn ('" has an illegal brace-level-1 letter'); -end; - - -@ -Here we set pointers into |name_tok| and note whether we'll be dealing -with a full first-name tokens (|double_letter = true|) or -abbreviations (|double_letter = false|). - -@<Figure out what tokens we'll output for the `first' name@>= -begin -cur_token := first_start; -last_token := first_end; -if (cur_token = last_token) then - to_be_written := false; -if ((str_pool[sp_ptr] = "f") or (str_pool[sp_ptr] = "F")) then - double_letter := true; -end - - -@ -The same as above but for von-name tokens. - -@<Figure out what tokens we'll output for the `von' name@>= -begin -cur_token := von_start; -last_token := von_end; -if (cur_token = last_token) then - to_be_written := false; -if ((str_pool[sp_ptr] = "v") or (str_pool[sp_ptr] = "V")) then - double_letter := true; -end - - -@ -The same as above but for last-name tokens. - -@<Figure out what tokens we'll output for the `last' name@>= -begin -cur_token := von_end; -last_token := last_end; -if (cur_token = last_token) then - to_be_written := false; -if ((str_pool[sp_ptr] = "l") or (str_pool[sp_ptr] = "L")) then - double_letter := true; -end - - -@ -The same as above but for jr-name tokens. - -@<Figure out what tokens we'll output for the `jr' name@>= -begin -cur_token := last_end; -last_token := jr_end; -if (cur_token = last_token) then - to_be_written := false; -if ((str_pool[sp_ptr] = "j") or (str_pool[sp_ptr] = "J")) then - double_letter := true; -end - - -@ -This is the second pass over this part of the name; here we actually -write stuff out to |ex_buf|. - -@<Finally format this part of the name@>= -begin -ex_buf_xptr := ex_buf_ptr; -sp_ptr := sp_xptr1; -sp_brace_level := 1; -while (sp_brace_level > 0) do - if ((lex_class[str_pool[sp_ptr]] = alpha) and (sp_brace_level = 1)) then - begin - incr(sp_ptr); - @<Figure out how to output the name tokens, and do it@>; - end - else if (str_pool[sp_ptr] = right_brace) then - begin - decr(sp_brace_level); - incr(sp_ptr); - if (sp_brace_level > 0) then - append_ex_buf_char_and_check (right_brace); - end - else if (str_pool[sp_ptr] = left_brace) then - begin - incr(sp_brace_level); - incr(sp_ptr); - append_ex_buf_char_and_check (left_brace); - end - else - begin - append_ex_buf_char_and_check (str_pool[sp_ptr]); - incr(sp_ptr); - end; -if (ex_buf_ptr > 0) then - if (ex_buf[ex_buf_ptr-1] = tie) then - @<Handle a discretionary |tie|@>; -end - - -@ -When we come here, |sp_ptr| is just past the letter indicating the -part of the name for which we're about to output tokens. When we -leave, it's at the first character of the rest of the group. - -@<Figure out how to output the name tokens, and do it@>= -begin -if (double_letter) then - incr(sp_ptr); -use_default := true; -sp_xptr2 := sp_ptr; -if (str_pool[sp_ptr] = left_brace) then {find the inter-token string} - begin - use_default := false; - incr(sp_brace_level); - incr(sp_ptr); - sp_xptr1 := sp_ptr; - skip_stuff_at_sp_brace_level_greater_than_one; - sp_xptr2 := sp_ptr - 1; - end; -@<Finally output the name tokens@>; -if (not use_default) then - sp_ptr := sp_xptr2 + 1; -end - - -@ -Here, for each token in this part, we output either a full or an -abbreviated token and the inter-token string for all but the last -token of this part. - -@<Finally output the name tokens@>= -while (cur_token < last_token) do - begin - if (double_letter) then - @<Finally output a full token@> - else - @<Finally output an abbreviated token@>; - incr(cur_token); - if (cur_token < last_token) then - @<Finally output the inter-token string@>; - end - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -Here we output all the characters in the token, verbatim. - -@<Finally output a full token@>= -begin -name_bf_ptr := name_tok[cur_token]; -name_bf_xptr := name_tok[cur_token+1]; -if (ex_buf_length+(name_bf_xptr-name_bf_ptr) > buf_size) then - buffer_overflow; -while (name_bf_ptr < name_bf_xptr) do - begin - append_ex_buf_char (name_buf[name_bf_ptr]); - incr(name_bf_ptr); - end; -end - - -@ -@^special character@> -Here we output the first alphabetic or special character of the token; -brace level is irrelevant for an alphabetic (but not a special) -character. - -@<Finally output an abbreviated token@>= -begin -name_bf_ptr := name_tok[cur_token]; -name_bf_xptr := name_tok[cur_token+1]; -while (name_bf_ptr < name_bf_xptr) do - begin - if (lex_class[name_buf[name_bf_ptr]] = alpha) then - begin - append_ex_buf_char_and_check (name_buf[name_bf_ptr]); - goto loop_exit; - end - else if ((name_buf[name_bf_ptr] = left_brace) and - (name_bf_ptr + 1 < name_bf_xptr)) then - if (name_buf[name_bf_ptr+1] = backslash) then - @<Finally output a special character and exit loop@>; - incr(name_bf_ptr); - end; -loop_exit: -end - - -@ -@^special character@> -@^user abuse@> -@:BibTeX capacity exceeded}{\quad buffer size@> -We output a special character here even if the user has been silly -enough to make it nonalphabetic (and even if the user has been sillier -still by not having a matching |right_brace|). - -@<Finally output a special character and exit loop@>= -begin -if (ex_buf_ptr + 2 > buf_size) then - buffer_overflow; -append_ex_buf_char (left_brace); -append_ex_buf_char (backslash); -name_bf_ptr := name_bf_ptr + 2; -nm_brace_level := 1; -while ((name_bf_ptr < name_bf_xptr) and (nm_brace_level > 0)) do - begin - if (name_buf[name_bf_ptr] = right_brace) then - decr(nm_brace_level) - else if (name_buf[name_bf_ptr] = left_brace) then - incr(nm_brace_level); - append_ex_buf_char_and_check (name_buf[name_bf_ptr]); - incr(name_bf_ptr); - end; -goto loop_exit; -end - - -@ -@:BibTeX capacity exceeded}{\quad buffer size@> -Here we output either the \.{.bst} given string if it exists, or else -the \.{.bib} |sep_char| if it exists, or else the default string. A -|tie| is the default space character between the last two tokens of -the name part, and between the first two tokens if the first token is -short enough; otherwise, a |space| is the default. - -@d long_token = 3 {a token this length or longer is ``long''} - -@<Finally output the inter-token string@>= -begin -if (use_default) then - begin - if (not double_letter) then - append_ex_buf_char_and_check (period); - if (lex_class[name_sep_char[cur_token]] = sep_char) then - append_ex_buf_char_and_check (name_sep_char[cur_token]) - else if ((cur_token = last_token-1) or - (not enough_text_chars (long_token))) then - append_ex_buf_char_and_check (tie) - else - append_ex_buf_char_and_check (space); - end - else - begin - if (ex_buf_length+(sp_xptr2-sp_xptr1) > buf_size) then - buffer_overflow; - sp_ptr := sp_xptr1; - while (sp_ptr < sp_xptr2) do - begin - append_ex_buf_char (str_pool[sp_ptr]); - incr(sp_ptr); - end - end; -end - - -@ -@^special character@> -This function looks at the string in |ex_buf|, starting at -|ex_buf_xptr| and ending just before |ex_buf_ptr|, and it returns -|true| if there are |enough_chars|, where a special character (even if -it's missing its matching |right_brace|) counts as a single charcter. -This procedure is called only for strings that don't have too many -|right_brace|s. - -@<Procedures and functions for name-string processing@>= -function enough_text_chars (@!enough_chars : buf_pointer) : boolean; -begin -num_text_chars := 0; -ex_buf_yptr := ex_buf_xptr; -while ((ex_buf_yptr < ex_buf_ptr) and (num_text_chars < enough_chars)) do - begin - incr(ex_buf_yptr); - if (ex_buf[ex_buf_yptr-1] = left_brace) then - begin - incr(brace_level); - if ((brace_level = 1) and (ex_buf_yptr < ex_buf_ptr)) then - if (ex_buf[ex_buf_yptr] = backslash) then - begin - incr(ex_buf_yptr); {skip over the |backslash|} - while ((ex_buf_yptr < ex_buf_ptr) and (brace_level > 0)) do - begin - if (ex_buf[ex_buf_yptr] = right_brace) then - decr(brace_level) - else if (ex_buf[ex_buf_yptr] = left_brace) then - incr(brace_level); - incr(ex_buf_yptr); - end; - end; - end - else if (ex_buf[ex_buf_yptr-1] = right_brace) then - decr(brace_level); - incr(num_text_chars); - end; -if (num_text_chars < enough_chars) then - enough_text_chars := false - else - enough_text_chars := true; -end; - - -@ -If the last character output for this name part is a |tie| but the -previous character it isn't, we're dealing with a discretionary |tie|; -thus we replace it by a |space| if there are enough characters in the -rest of the name part. - -@d long_name = 3 {a name this length or longer is ``long''} - -@<Handle a discretionary |tie|@>= -begin -decr(ex_buf_ptr); {remove the previous |tie|} -if (ex_buf[ex_buf_ptr-1] = tie) then {it's not a discretionary |tie|} - do_nothing -else if (not enough_text_chars (long_name)) then {this is a short name part} - incr(ex_buf_ptr) {so restore the |tie|} -else {replace it by a |space|} - append_ex_buf_char (space); -end - - -@ -This is a procedure so that |x_format_name| is smaller. - -@<Procedures and functions for name-string processing@>= -procedure figure_out_the_formatted_name; -label loop_exit; -begin -@<Figure out the formatted name@>; -end; - - -@ -The |built_in| function {\.{if\$}} pops the top three literals (they -are two function literals and an integer literal, in that order); if -the integer is greater than 0, it executes the second literal, else it -executes the first. If any of the types is incorrect, it complains -but does nothing else. - -@<|execute_fn|({\.{if\$}})@>= -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -pop_lit_stk (pop_lit3,pop_typ3); -if (pop_typ1 <> stk_fn) then - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_fn) -else if (pop_typ2 <> stk_fn) then - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_fn) -else if (pop_typ3 <> stk_int) then - print_wrong_stk_lit (pop_lit3,pop_typ3,stk_int) -else - if (pop_lit3 > 0) then - execute_fn (pop_lit2) - else - execute_fn (pop_lit1); -end - - -@ -The |built_in| function {\.{int.to.chr\$}} pops the top (integer) -literal, interpreted as the |ASCII_code| of a single character, -converts it to the corresponding single-character string, and pushes -this string. If the literal isn't an appropriate integer, it -complains and pushes the null string. - -@<|execute_fn|({\.{int.to.chr\$}})@>= -procedure x_int_to_chr; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (s_null, stk_str); - end -else if ((pop_lit1 < 0) or (pop_lit1 > 127)) then - begin - bst_ex_warn (pop_lit1:0,' isn''t valid ASCII'); - push_lit_stk (s_null, stk_str); - end -else - begin - str_room(1); - append_char (pop_lit1); - push_lit_stk (make_string, stk_str); - end; -end; - - -@ -The |built_in| function {\.{int.to.str\$}} pops the top (integer) -literal, converts it to its (unique) string equivalent, and pushes -this string. If the literal isn't an integer, it complains and pushes -the null string. - -@<|execute_fn|({\.{int.to.str\$}})@>= -procedure x_int_to_str; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (s_null, stk_str); - end -else - begin - int_to_ASCII (pop_lit1, ex_buf, 0, ex_buf_length);@/ - add_pool_buf_and_push; {push this string onto the stack} - end; -end; - - -@ -The |built_in| function {\.{missing\$}} pops the top literal and -pushes the integer 1 if it's a missing field, 0 otherwise. If the -literal isn't a missing field or a string, it complains and pushes 0. -Unlike \.{empty\$}, this function should be called only when -|mess_with_entries| is true. - -@<|execute_fn|({\.{missing\$}})@>= -procedure x_missing; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (not mess_with_entries) then - bst_cant_mess_with_entries_print -else if ((pop_typ1 <> stk_str) and (pop_typ1 <> stk_field_missing)) then - begin - if (pop_typ1 <> stk_empty) then - begin - print_stk_lit (pop_lit1,pop_typ1); - bst_ex_warn (', not a string or missing field,'); - end; - push_lit_stk (0, stk_int); - end -else - if (pop_typ1 = stk_field_missing) then - push_lit_stk (1, stk_int) - else - push_lit_stk (0, stk_int); -end; - - -@ -The |built_in| function {\.{newline\$}} writes whatever has -accumulated in the output buffer |out_buf| onto the \.{.bbl} file. - -@<|execute_fn|({\.{newline\$}})@>= -begin -output_bbl_line; -end - - -@ -The |built_in| function {\.{num.names\$}} pops the top (string) -literal; it pushes the number of names the string represents---one -plus the number of occurrences of the substring ``and'' (ignoring case -differences) surrounded by nonnull |white_space| at the top brace -level. If the literal isn't a string, it complains and pushes the -value 0. - -@<|execute_fn|({\.{num.names\$}})@>= -procedure x_num_names; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (0, stk_int); - end -else - begin - ex_buf_length := 0; - add_buf_pool (pop_lit1); - @<Determine the number of names@>; - push_lit_stk (num_names, stk_int); - end; -end; - - -@ -This module, while scanning the list of names, counts the occurrences -of ``and'' (ignoring case differences) surrounded by nonnull -|white_space|, and adds 1. - -@<Determine the number of names@>= -begin -ex_buf_ptr := 0; -num_names := 0; -while (ex_buf_ptr < ex_buf_length) do - begin - name_scan_for_and (pop_lit1); - incr(num_names); - end; -end - - -@ -The |built_in| function {\.{pop\$}} pops the top of the stack but -doesn't print it. - -@<|execute_fn|({\.{pop\$}})@>= -begin -pop_lit_stk (pop_lit1,pop_typ1); -end - - -@ -The |built_in| function {\.{preamble\$}} pushes onto the stack the -concatenation of all the \.{preamble} strings read from the database -files. - -@<|execute_fn|({\.{preamble\$}})@>= -procedure x_preamble; -begin -ex_buf_length := 0; -preamble_ptr := 0; -while (preamble_ptr < num_preamble_strings) do - begin - add_buf_pool (s_preamble[preamble_ptr]); - incr(preamble_ptr); - end; -add_pool_buf_and_push; {push the concatenation string onto the stack} -end; - - -@ -@^special character@> -The |built_in| function {\.{purify\$}} pops the top (string) literal, -removes nonalphanumeric characters except for |white_space| and -|sep_char| characters (these get converted to a |space|) and removes -certain alphabetic characters contained in the control sequences -associated with a special character, and pushes the resulting string. -If the literal isn't a string, it complains and pushes the null -string. - -@<|execute_fn|({\.{purify\$}})@>= -procedure x_purify; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (s_null, stk_str); - end -else - begin - ex_buf_length := 0; - add_buf_pool (pop_lit1); - @<Perform the purification@>; - add_pool_buf_and_push; {push this string onto the stack} - end; -end; - - -@ -@^special character@> -The resulting string has nonalphanumeric characters removed, and each -|white_space| or |sep_char| character converted to a |space|. The next -module handles special characters. This code doesn't complain if the -string isn't brace balanced. - -@<Perform the purification@>= -begin -brace_level := 0; {this is the top level} -ex_buf_xptr := 0; {this pointer is for the purified string} -ex_buf_ptr := 0; {and this one is for the original string} -while (ex_buf_ptr < ex_buf_length) do - begin - case (lex_class[ex_buf[ex_buf_ptr]]) of - white_space, - sep_char : - begin - ex_buf[ex_buf_xptr] := space; - incr(ex_buf_xptr); - end; - alpha, - numeric : - begin - ex_buf[ex_buf_xptr] := ex_buf[ex_buf_ptr]; - incr(ex_buf_xptr); - end; - othercases - if (ex_buf[ex_buf_ptr] = left_brace) then - begin - incr(brace_level); - if ((brace_level = 1) and - (ex_buf_ptr + 1 < ex_buf_length)) then - if (ex_buf[ex_buf_ptr+1] = backslash) then - @<Purify a special character@>; - end - else if (ex_buf[ex_buf_ptr] = right_brace) then - if (brace_level > 0) then - decr(brace_level) - endcases; - incr(ex_buf_ptr); - end; -ex_buf_length := ex_buf_xptr; -end - - -@ -@^special character@> -Special characters (even without a matching |right_brace|) are -purified by removing the control sequences (but restoring the correct -thing for `\.{\\i}' and `\.{\\j}' as well as the eleven alphabetic -foreign characters in Table~3.2 of the \LaTeX\ manual) and removing -all nonalphanumeric characters (including |white_space| and -|sep_char|s). - -@<Purify a special character@>= -begin -incr(ex_buf_ptr); {skip over the |left_brace|} -while ((ex_buf_ptr < ex_buf_length) and (brace_level > 0)) do - begin - incr(ex_buf_ptr); {skip over the |backslash|} - ex_buf_yptr := ex_buf_ptr; {mark the beginning of the control sequence} - while ((ex_buf_ptr < ex_buf_length) and - (lex_class[ex_buf[ex_buf_ptr]] = alpha)) do@/ - incr(ex_buf_ptr); {this scans the control sequence} - control_seq_loc := str_lookup(ex_buf,ex_buf_yptr,ex_buf_ptr-ex_buf_yptr, - control_seq_ilk,dont_insert); - if (hash_found) then - @<Purify this accented or foreign character@>; - while ((ex_buf_ptr < ex_buf_length) and (brace_level > 0) and - (ex_buf[ex_buf_ptr] <> backslash)) do - begin {this scans to the next control sequence} - case (lex_class[ex_buf[ex_buf_ptr]]) of - alpha, - numeric : - begin - ex_buf[ex_buf_xptr] := ex_buf[ex_buf_ptr]; - incr(ex_buf_xptr); - end; - othercases - if (ex_buf[ex_buf_ptr] = right_brace) then - decr(brace_level) - else if (ex_buf[ex_buf_ptr] = left_brace) then - incr(brace_level) - endcases; - incr(ex_buf_ptr); - end; - end; -decr(ex_buf_ptr); {unskip the |right_brace| (or last character)} -end - - -@ -We consider the purified character to be either the first alphabetic -character of its control sequence, or perhaps both alphabetic -characters. - -@<Purify this accented or foreign character@>= -begin -ex_buf[ex_buf_xptr] := ex_buf[ex_buf_yptr]; {the first alphabetic character} -incr(ex_buf_xptr); -case (ilk_info[control_seq_loc]) of - n_oe, - n_oe_upper, - n_ae, - n_ae_upper, - n_ss : - begin {and the second} - ex_buf[ex_buf_xptr] := ex_buf[ex_buf_yptr+1]; - incr(ex_buf_xptr); - end; - othercases - do_nothing -endcases; -end - - -@ -The |built_in| function {\.{quote\$}} pushes the string consisting of -the |double_quote| character. - -@<|execute_fn|({\.{quote\$}})@>= -procedure x_quote; -begin -str_room(1); -append_char (double_quote); -push_lit_stk (make_string, stk_str); -end; - - -@ -The |built_in| function {\.{skip\$}} is a no-op. - -@<|execute_fn|({\.{skip\$}})@>= -begin -do_nothing; -end - - -@ -The |built_in| function {\.{stack\$}} pops and prints the whole stack; -it's meant to be used for style designers while debugging. - -@<|execute_fn|({\.{stack\$}})@>= -begin -pop_whole_stack; -end - - -@ -@^push the literal stack@> -The |built_in| function {\.{substring\$}} pops the top three literals -(they are the two integers literals |pop_lit1| and |pop_lit2| and a -string literal, in that order). It pushes the substring of the (at -most) |pop_lit1| consecutive characters starting at the |pop_lit2|th -character (assuming 1-based indexing) if |pop_lit2| is positive, and -ending at the |-pop_lit2|th character from the end if |pop_lit2| is -negative (where the first character from the end is the last -character). If any of the types is incorrect, it complain and pushes -the null string. - -@<|execute_fn|({\.{substring\$}})@>= -procedure x_substring; -label exit; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -pop_lit_stk (pop_lit3,pop_typ3); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ2 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_int); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ3 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit3,pop_typ3,stk_str); - push_lit_stk (s_null, stk_str); - end -else - begin - sp_length := length(pop_lit3); - if (pop_lit1 >= sp_length) then - if ((pop_lit2 = 1) or (pop_lit2 = -1)) then - begin - repush_string; - return; - end; - if ((pop_lit1 <= 0) or (pop_lit2 = 0) or (pop_lit2 > sp_length) or - (pop_lit2 < -sp_length)) then - begin - push_lit_stk (s_null, stk_str); - return; - end - else - @<Form the appropriate substring@>; - end; -exit: -end; - - -@ -@^push the literal stack@> -This module finds the substring as described in the last section, -and slides it into place in the string pool, if necessary. - -@<Form the appropriate substring@>= -begin -if (pop_lit2 > 0) then - begin - if (pop_lit1 > sp_length - (pop_lit2-1)) then - pop_lit1 := sp_length - (pop_lit2-1); - sp_ptr := str_start[pop_lit3] + (pop_lit2-1); - sp_end := sp_ptr + pop_lit1; - if (pop_lit2 = 1) then - if (pop_lit3 >= cmd_str_ptr) then {no shifting---merely change pointers} - begin - str_start[pop_lit3+1] := sp_end; - unflush_string; - incr(lit_stk_ptr); - return; - end; - end -else {|-ex_buf_length <= pop_lit2 < 0|} - begin - pop_lit2 := -pop_lit2; - if (pop_lit1 > sp_length - (pop_lit2-1)) then - pop_lit1 := sp_length - (pop_lit2-1); - sp_end := str_start[pop_lit3+1] - (pop_lit2-1); - sp_ptr := sp_end - pop_lit1; - end; -while (sp_ptr < sp_end) do {shift the substring} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; -push_lit_stk (make_string, stk_str); {and push it onto the stack} -end - - -@ -The |built_in| function {\.{swap\$}} pops the top two literals from -the stack and pushes them back swapped. - -@<|execute_fn|({\.{swap\$}})@>= -procedure x_swap; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if ((pop_typ1 <> stk_str) or (pop_lit1 < cmd_str_ptr)) then - begin - push_lit_stk (pop_lit1, pop_typ1); - if ((pop_typ2 = stk_str) and (pop_lit2 >= cmd_str_ptr)) then - unflush_string; - push_lit_stk (pop_lit2, pop_typ2); - end -else if ((pop_typ2 <> stk_str) or (pop_lit2 < cmd_str_ptr)) then - begin - unflush_string; {this is |pop_lit1|} - push_lit_stk (pop_lit1, stk_str); - push_lit_stk (pop_lit2, pop_typ2); - end -else {bummer, both are recent strings} - @<Swap the two strings (they're at the end of |str_pool|)@>; -end; - - -@ -We have to swap both (a)~the strings at the end of the string pool, -and (b)~their pointers on the literal stack. - -@<Swap the two strings (they're at the end of |str_pool|)@>= -begin -ex_buf_length := 0; -add_buf_pool (pop_lit2); {save the second string} -sp_ptr := str_start[pop_lit1]; -sp_end := str_start[pop_lit1+1]; -while (sp_ptr < sp_end) do {slide the first string down} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; -push_lit_stk (make_string, stk_str); {and push it onto the stack} -add_pool_buf_and_push; {push second string onto the stack} -end - - -@ -@^special character@> -The |built_in| function {\.{text.length\$}} pops the top (string) -literal, and pushes the number of text characters it contains, where -an accented character (more precisely, a ``special character''$\!$, -defined earlier) counts as a single text character, even if it's -missing its matching |right_brace|, and where braces don't count as -text characters. If the literal isn't a string, it complains and -pushes the null string. - -@<|execute_fn|({\.{text.length\$}})@>= -procedure x_text_length; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (s_null, stk_str); - end -else - begin - num_text_chars := 0; - @<Count the text characters@>; - push_lit_stk (num_text_chars, stk_int); {and push it onto the stack} - end; -end; - - -@ -@^special character@> -Here we determine the number of text characters in the string, where -an entire special character counts as a single text character (even if -it's missing its matching |right_brace|), and where braces don't count -as text characters. - -@<Count the text characters@>= -begin -sp_ptr := str_start[pop_lit1]; -sp_end := str_start[pop_lit1+1]; -sp_brace_level := 0; -while (sp_ptr < sp_end) do - begin - incr(sp_ptr); - if (str_pool[sp_ptr-1] = left_brace) then - begin - incr(sp_brace_level); - if ((sp_brace_level = 1) and (sp_ptr < sp_end)) then - if (str_pool[sp_ptr] = backslash) then - begin - incr(sp_ptr); {skip over the |backslash|} - while ((sp_ptr < sp_end) and (sp_brace_level > 0)) do - begin - if (str_pool[sp_ptr] = right_brace) then - decr(sp_brace_level) - else if (str_pool[sp_ptr] = left_brace) then - incr(sp_brace_level); - incr(sp_ptr); - end; - incr(num_text_chars); - end; - end - else if (str_pool[sp_ptr-1] = right_brace) then - begin - if (sp_brace_level > 0) then - decr(sp_brace_level); - end - else - incr(num_text_chars); - end; -end - - -@ -@^special character@> -The |built_in| function {\.{text.prefix\$}} pops the top two literals -(the integer literal |pop_lit1| and a string literal, in that order). -It pushes the substring of the (at most) |pop_lit1| consecutive text -characters starting from the beginning of the string. This function -is similar to {\.{substring\$}}, but this one considers an accented -character (or more precisely, a ``special character''$\!$, even if -it's missing its matching |right_brace|) to be a single text character -(rather than however many |ASCII_code| characters it actually -comprises), and this function doesn't consider braces to be text -characters; furthermore, this function appends any needed matching -|right_brace|s. If any of the types is incorrect, it complains and -pushes the null string. - -@<|execute_fn|({\.{text.prefix\$}})@>= -procedure x_text_prefix; -label exit; -begin -pop_lit_stk (pop_lit1,pop_typ1); -pop_lit_stk (pop_lit2,pop_typ2); -if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - push_lit_stk (s_null, stk_str); - end -else if (pop_typ2 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit2,pop_typ2,stk_str); - push_lit_stk (s_null, stk_str); - end -else if (pop_lit1 <= 0) then - begin - push_lit_stk (s_null, stk_str); - return; - end -else - @<Form the appropriate prefix@>; -exit: -end; - - -@ -@^push the literal stack@> -This module finds the prefix as described in the last section, and -appends any needed matching |right_brace|s. - -@<Form the appropriate prefix@>= -begin -sp_ptr := str_start[pop_lit2]; -sp_end := str_start[pop_lit2+1]; {this may change} -@<Scan the appropriate number of characters@>; -if (pop_lit2 >= cmd_str_ptr) then {no shifting---merely change pointers} - pool_ptr := sp_end -else - while (sp_ptr < sp_end) do {shift the substring} - begin - append_char (str_pool[sp_ptr]); - incr(sp_ptr); - end; -while (sp_brace_level > 0) do {add matching |right_brace|s} - begin - append_char (right_brace); - decr(sp_brace_level); - end; -push_lit_stk (make_string, stk_str); {and push it onto the stack} -end - - -@ -@^special character@> -This section scans |pop_lit1| text characters, where an entire special -character counts as a single text character (even if it's missing its -matching |right_brace|), and where braces don't count as text -characters. - -@<Scan the appropriate number of characters@>= -begin -num_text_chars := 0; -sp_brace_level := 0; -sp_xptr1 := sp_ptr; -while ((sp_xptr1 < sp_end) and (num_text_chars < pop_lit1)) do - begin - incr(sp_xptr1); - if (str_pool[sp_xptr1-1] = left_brace) then - begin - incr(sp_brace_level); - if ((sp_brace_level = 1) and (sp_xptr1 < sp_end)) then - if (str_pool[sp_xptr1] = backslash) then - begin - incr(sp_xptr1); {skip over the |backslash|} - while ((sp_xptr1 < sp_end) and (sp_brace_level > 0)) do - begin - if (str_pool[sp_xptr1] = right_brace) then - decr(sp_brace_level) - else if (str_pool[sp_xptr1] = left_brace) then - incr(sp_brace_level); - incr(sp_xptr1); - end; - incr(num_text_chars); - end; - end - else if (str_pool[sp_xptr1-1] = right_brace) then - begin - if (sp_brace_level > 0) then - decr(sp_brace_level); - end - else - incr(num_text_chars); - end; -sp_end := sp_xptr1; -end - - -@ -The |built_in| function {\.{top\$}} pops and prints the top of the -stack. - -@<|execute_fn|({\.{top\$}})@>= -begin -pop_top_and_print; -end - - -@ -The |built_in| function {\.{type\$}} pushes the appropriate string -from |type_list| onto the stack (unless either it's |undefined| or -|empty|, in which case it pushes the null string). - -@<|execute_fn|({\.{type\$}})@>= -procedure x_type; -begin -if (not mess_with_entries) then - bst_cant_mess_with_entries_print - else - if ((type_list[cite_ptr] = undefined) or - (type_list[cite_ptr] = empty)) then - push_lit_stk (s_null, stk_str) - else - push_lit_stk (hash_text[type_list[cite_ptr]], stk_str); -end; - - -@ -The |built_in| function {\.{warning\$}} pops the top (string) literal -and prints it following a warning message. This is implemented as a -special |built_in| function rather than using the {\.{top\$}} function -so that it can |mark_warning|. - -@<|execute_fn|({\.{warning\$}})@>= -procedure x_warning; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str) -else - begin - print ('Warning--'); - print_lit (pop_lit1,pop_typ1); - mark_warning; - end; -end; - - -@ -The |built_in| function {\.{while\$}} pops the top two (function) -literals, and keeps executing the second as long as the (integer) -value left on the stack by executing the first is greater than 0. If -either type is incorrect, it complains but does nothing else. - -@<|execute_fn|({\.{while\$}})@>= -begin -pop_lit_stk (r_pop_lt1,r_pop_tp1); -pop_lit_stk (r_pop_lt2,r_pop_tp2); -if (r_pop_tp1 <> stk_fn) then - print_wrong_stk_lit (r_pop_lt1,r_pop_tp1,stk_fn) -else if (r_pop_tp2 <> stk_fn) then - print_wrong_stk_lit (r_pop_lt2,r_pop_tp2,stk_fn) -else - loop - begin - execute_fn (r_pop_lt2); {this is the \.{while\$} test} - pop_lit_stk (pop_lit1,pop_typ1); - if (pop_typ1 <> stk_int) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_int); - goto end_while; - end - else - if (pop_lit1 > 0) then - execute_fn (r_pop_lt1) {this is the \.{while\$} body} - else - goto end_while; - end; -end_while: {justifies this |mean_while|} -end - - -@ -@^literal literal@> -@^special character@> -The |built_in| function {\.{width\$}} pops the top (string) literal -and pushes the integer that represents its width in units specified by -the |char_width| array. This function takes the literal literally; -that is, it assumes each character in the string is to be printed as -is, regardless of whether the character has a special meaning to \TeX, -except that special characters (even without their |right_brace|s) are -handled specially. If the literal isn't a string, it complains and -pushes~0. - -@<|execute_fn|({\.{width\$}})@>= -procedure x_width; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - begin - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str); - push_lit_stk (0, stk_int); - end -else - begin - ex_buf_length := 0; - add_buf_pool (pop_lit1); - string_width := 0; - @<Add up the |char_width|s in this string@>; - push_lit_stk (string_width, stk_int); - end -end; - - -@ -We use the natural width for all but special characters, and we -complain if the string isn't brace-balanced. - -@<Add up the |char_width|s in this string@>= -begin -brace_level := 0; {we're at the top level} -ex_buf_ptr := 0; {and the beginning of string} -while (ex_buf_ptr < ex_buf_length) do - begin - if (ex_buf[ex_buf_ptr] = left_brace) then - begin - incr(brace_level); - if ((brace_level = 1) and (ex_buf_ptr + 1 < ex_buf_length)) then - if (ex_buf[ex_buf_ptr+1] = backslash) then - @<Determine the width of this special character@> - else - string_width := string_width + char_width[left_brace] - else - string_width := string_width + char_width[left_brace]; - end - else if (ex_buf[ex_buf_ptr] = right_brace) then - begin - decr_brace_level (pop_lit1); - string_width := string_width + char_width[right_brace]; - end - else - string_width := string_width + char_width[ex_buf[ex_buf_ptr]]; - incr(ex_buf_ptr); - end; -check_brace_level (pop_lit1); -end - - -@ -@^special character@> -We use the natural widths of all characters except that some -characters have no width: braces, control sequences (except for the -usual 13 accented and foreign characters, whose widths are given in -the next module), and |white_space| following control sequences (even -a null control sequence). - -@<Determine the width of this special character@>= -begin -incr(ex_buf_ptr); {skip over the |left_brace|} -while ((ex_buf_ptr < ex_buf_length) and (brace_level > 0)) do - begin - incr(ex_buf_ptr); {skip over the |backslash|} - ex_buf_xptr := ex_buf_ptr; - while ((ex_buf_ptr < ex_buf_length) and - (lex_class[ex_buf[ex_buf_ptr]] = alpha)) do@/ - incr(ex_buf_ptr); {this scans the control sequence} - if ((ex_buf_ptr < ex_buf_length) and (ex_buf_ptr = ex_buf_xptr)) then - incr(ex_buf_ptr) {this skips a nonalpha control seq} - else - begin - control_seq_loc := str_lookup(ex_buf,ex_buf_xptr, - ex_buf_ptr-ex_buf_xptr,control_seq_ilk,dont_insert); - if (hash_found) then - @<Determine the width of this accented or foreign character@>; - end; - while ((ex_buf_ptr < ex_buf_length) and - (lex_class[ex_buf[ex_buf_ptr]] = white_space)) do - incr(ex_buf_ptr); {this skips following |white_space|} - while ((ex_buf_ptr < ex_buf_length) and (brace_level > 0) and - (ex_buf[ex_buf_ptr] <> backslash)) do - begin {this scans to the next control sequence} - if (ex_buf[ex_buf_ptr] = right_brace) then - decr(brace_level) - else if (ex_buf[ex_buf_ptr] = left_brace) then - incr(brace_level) - else - string_width := string_width + char_width[ex_buf[ex_buf_ptr]]; - incr(ex_buf_ptr); - end; - end; -decr(ex_buf_ptr); {unskip the |right_brace|} -end - - -@ -Five of the 13 possibilities resort to special information not present -in the |char_width| array; the other eight simply use |char_width|'s -information for the first letter of the control sequence. - -@<Determine the width of this accented or foreign character@>= -begin -case (ilk_info[control_seq_loc]) of - n_ss : string_width := string_width + ss_width; - n_ae : string_width := string_width + ae_width; - n_oe : string_width := string_width + oe_width; - n_ae_upper : string_width := string_width + upper_ae_width; - n_oe_upper : string_width := string_width + upper_oe_width; - othercases - string_width := string_width + char_width[ex_buf[ex_buf_xptr]] -endcases; -end - - -@ -The |built_in| function {\.{write\$}} pops the top (string) literal -and writes it onto the output buffer |out_buf| (which will result in -stuff being written onto the \.{.bbl} file if the buffer fills up). If -the literal isn't a string, it complains but does nothing else. - -@<|execute_fn|({\.{write\$}})@>= -procedure x_write; -begin -pop_lit_stk (pop_lit1,pop_typ1); -if (pop_typ1 <> stk_str) then - print_wrong_stk_lit (pop_lit1,pop_typ1,stk_str) -else - add_out_pool (pop_lit1); -end; - - - -@* Cleaning up. -@^clich\'e-\`a-trois@> -@^fat lady@> -@^turn out lights@> -@^Yogi@> -This section does any last-minute printing and ends the program. - -@<Clean up and leave@>= -begin -if ((read_performed) and (not reading_completed)) then - begin - print ('Aborted at line ',bib_line_num:0,' of file '); - print_bib_name; - end; -trace_and_stat_printing; -@<Print the job |history|@>; -a_close (log_file); -{turn out the lights, the fat lady has sung; it's over, Yogi} -end - - -@ -Here we print |trace| and/or |stat| information, if desired. - -@<Procedures and functions for all file I/O, error messages, and such@>= -procedure trace_and_stat_printing; -begin -@# - trace - @<Print all \.{.bib}- and \.{.bst}-file information@>; - @<Print all |cite_list| and entry information@>; - @<Print the |wiz_defined| functions@>; - @<Print the string pool@>; - ecart@/ -@# - stat - @<Print usage statistics@>; - tats@/ -@# -end; - - -@ -This prints information obtained from the \.{.aux} file about the -other files. - -@<Print all \.{.bib}- and \.{.bst}-file information@>= -begin -if (num_bib_files = 1) then - trace_pr_ln ('The 1 database file is') - else - trace_pr_ln ('The ',num_bib_files:0,' database files are'); -if (num_bib_files = 0) then - trace_pr_ln (' undefined') - else - begin - bib_ptr := 0; - while (bib_ptr < num_bib_files) do - begin - trace_pr (' '); - trace_pr_pool_str (cur_bib_str); - trace_pr_pool_str (s_bib_extension); - trace_pr_newline; - incr(bib_ptr); - end; - end; -trace_pr ('The style file is '); -if (bst_str = 0) then - trace_pr_ln ('undefined') - else - begin - trace_pr_pool_str (bst_str); - trace_pr_pool_str (s_bst_extension); - trace_pr_newline; - end; -end - - -@ -In entry-sorted order, this prints an entry's |cite_list| string and, -indirectly, its entry type and entry variables. - -@<Print all |cite_list| and entry information@>= -begin -if (all_entries) then - trace_pr ('all_marker=',all_marker:0,', '); -if (read_performed) then - trace_pr_ln ('old_num_cites=',old_num_cites:0) - else - trace_pr_newline; -trace_pr ('The ',num_cites:0); -if (num_cites = 1) then - trace_pr_ln (' entry:') - else - trace_pr_ln (' entries:'); -if (num_cites = 0) then - trace_pr_ln (' undefined') - else - begin - sort_cite_ptr := 0; - while (sort_cite_ptr < num_cites) do - begin - if (not read_completed) then {we didn't finish the \.{read} command} - cite_ptr := sort_cite_ptr - else - cite_ptr := sorted_cites[sort_cite_ptr]; - trace_pr_pool_str (cur_cite_str); - if (read_performed) then - @<Print entry information@> - else - trace_pr_newline; - incr(sort_cite_ptr); - end; - end; -end - - -@ -This prints information gathered while reading the \.{.bst} and -\.{.bib} files. - -@<Print entry information@>= -begin -trace_pr (', entry-type '); -if (type_list[cite_ptr] = undefined) then - undefined : trace_pr ('unknown') -else if (type_list[cite_ptr] = empty) then - trace_pr ('--- no type found') -else - trace_pr_pool_str (hash_text[type_list[cite_ptr]]); -trace_pr_ln (', has entry strings'); -@<Print entry strings@>; -trace_pr (' has entry integers'); -@<Print entry integers@>; -trace_pr_ln (' and has fields'); -@<Print fields@>; -end - - -@ -This prints, for the current entry, the strings declared by the -\.{entry} command. - -@<Print entry strings@>= -begin -if (num_ent_strs = 0) then - trace_pr_ln (' undefined') -else if (not read_completed) then - trace_pr_ln (' uninitialized') -else - begin - str_ent_ptr := cite_ptr * num_ent_strs; - while (str_ent_ptr < (cite_ptr+1)*num_ent_strs) do - begin - ent_chr_ptr := 0; - trace_pr (' "'); - while (entry_strs[str_ent_ptr][ent_chr_ptr] <> end_of_string) do - begin - trace_pr (xchr[entry_strs[str_ent_ptr][ent_chr_ptr]]); - incr(ent_chr_ptr); - end; - trace_pr_ln ('"'); - incr(str_ent_ptr); - end; - end; -end - - -@ -This prints, for the current entry, the integers declared by the -\.{entry} command. - -@<Print entry integers@>= -begin -if (num_ent_ints = 0) then - trace_pr (' undefined') -else if (not read_completed) then - trace_pr (' uninitialized') -else - begin - int_ent_ptr := cite_ptr*num_ent_ints; - while (int_ent_ptr < (cite_ptr+1)*num_ent_ints) do - begin - trace_pr (' ',entry_ints[int_ent_ptr]:0); - incr(int_ent_ptr); - end; - end; -trace_pr_newline; -end - - -@ -This prints the fields stored for the current entry. - -@<Print fields@>= -begin -if (not read_performed) then - trace_pr_ln (' uninitialized') - else - begin - field_ptr := cite_ptr * num_fields; - field_end_ptr := field_ptr + num_fields; - no_fields := true; - while (field_ptr < field_end_ptr) do - begin - if (field_info[field_ptr] <> missing) then - begin - trace_pr (' "'); - trace_pr_pool_str (field_info[field_ptr]); - trace_pr_ln ('"'); - no_fields := false; - end; - incr(field_ptr); - end; - if (no_fields) then - trace_pr_ln (' missing'); - end; -end - - -@ -This gives all the |wiz_defined| functions that appeared in the -\.{.bst} file. - -@<Print the |wiz_defined| functions@>= -begin -trace_pr_ln ('The wiz-defined functions are'); -if (wiz_def_ptr = 0) then - trace_pr_ln (' nonexistent') - else - begin - wiz_fn_ptr := 0; - while (wiz_fn_ptr < wiz_def_ptr) do - begin - if (wiz_functions[wiz_fn_ptr] = end_of_def) then - trace_pr_ln (wiz_fn_ptr:0,'--end-of-def--') - else if (wiz_functions[wiz_fn_ptr] = quote_next_fn) then - trace_pr (wiz_fn_ptr:0,' quote_next_function ') - else - begin - trace_pr (wiz_fn_ptr:0,' `'); - trace_pr_pool_str (hash_text[wiz_functions[wiz_fn_ptr]]); - trace_pr_ln (''''); - end; - incr(wiz_fn_ptr); - end; - end; -end - - -@ -This includes all the `static' strings (that is, those that are also -in the hash table), but none of the dynamic strings (that is, those -put on the stack while executing \.{.bst} commands). - -@<Print the string pool@>= -begin -trace_pr_ln ('The string pool is'); -str_num := 1; -while (str_num < str_ptr) do - begin - trace_pr (str_num:4, str_start[str_num]:6,' "'); - trace_pr_pool_str (str_num); - trace_pr_ln ('"'); - incr(str_num); - end; -end - - -@ -@^statistics@> -These statistics can help determine how large some of the constants -should be and can tell how useful certain |built_in| functions are. -They are written to the same files as tracing information. - -@d stat_pr == trace_pr -@d stat_pr_ln == trace_pr_ln -@d stat_pr_pool_str == trace_pr_pool_str - -@<Print usage statistics@>= -begin -stat_pr ('You''ve used ',num_cites:0); -if (num_cites = 1) then - stat_pr_ln (' entry,') - else - stat_pr_ln (' entries,'); -stat_pr_ln (' ',wiz_def_ptr:0,' wiz_defined-function locations,'); -stat_pr_ln (' ',str_ptr:0,' strings with ',str_start[str_ptr]:0, - ' characters,'); -blt_in_ptr := 0; -total_ex_count := 0; -while (blt_in_ptr < num_blt_in_fns) do - begin - total_ex_count := total_ex_count + execution_count[blt_in_ptr]; - incr(blt_in_ptr); - end; -stat_pr_ln ('and the built_in function-call counts, ', total_ex_count:0, - ' in all, are:'); -blt_in_ptr := 0; -while (blt_in_ptr < num_blt_in_fns) do - begin - stat_pr_pool_str (hash_text[blt_in_loc[blt_in_ptr]]); - stat_pr_ln (' -- ',execution_count[blt_in_ptr]:0); - incr(blt_in_ptr); - end; -end - - -@ -@^bunk, history@> -@^system dependencies@> -@:this can't happen}{\quad History is bunk@> -Some implementations may wish to pass the |history| value to the -operating system so that it can be used to govern whether or not other -programs are started. Here we simply report the history to the user. - -@<Print the job |history|@>= -case (history) of - spotless : do_nothing; - warning_message : begin - if (err_count = 1) then - print_ln ('(There was 1 warning)') - else - print_ln ('(There were ',err_count:0,' warnings)'); - end; - error_message : begin - if (err_count = 1) then - print_ln ('(There was 1 error message)') - else - print_ln ('(There were ',err_count:0, - ' error messages)'); - end; - fatal_message : print_ln ('(That was a fatal error)'); - othercases begin - print ('History is bunk'); - print_confusion; - end -endcases - - - -@* 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. - - - -@* Index. -@.this can't happen@> -Here is where you can find all uses of each identifier in the program, -with underlined entries pointing to where the identifier was defined. -If the identifier is only one letter long, however, you get to see only -the underlined entries. All references are to section numbers instead of -page numbers. - -This index also lists a few error messages and other aspects of the -program that you might want to look up some day. For example, the -entry for ``system dependencies'' lists all sections that should -receive special attention from people who are installing \TeX\ in a -new operating environment. A list of various things that can't happen -appears under ``this can't happen''$\!$. diff --git a/Build/extra/bibtex/btxbst.doc b/Build/extra/bibtex/btxbst.doc deleted file mode 100644 index 8cb9709de08..00000000000 --- a/Build/extra/bibtex/btxbst.doc +++ /dev/null @@ -1,2530 +0,0 @@ -% BibTeX `plain' family - % Version 0.99b (8-Dec-10 release) for BibTeX versions 0.99a or later. - % Copyright (C) 1984, 1985, 1988, 2010 Howard Trickey and Oren Patashnik. - % Unlimited copying and redistribution of this file are permitted as long as - % it is unmodified. Modifications (and redistribution of modified versions) - % are also permitted, but only if the resulting file is renamed to something - % besides btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. - % This restriction helps ensure that all standard styles are identical. - % The file btxbst.doc has the documentation for this style. -% Please notify biblio@tug.org of any bugs in -% these standard styles or in this documentation file. -% -% This is file btxbst.doc; it helps document bibliography styles, -% and is also a template file that you can use to make -% several different style files, if you have access to a C preprocessor. -% For example, the standard styles were made by doing something like -% cpp -P -DPLAIN btxbst.doc plain.txt -% cpp -P -DUNSRT btxbst.doc unsrt.txt -% cpp -P -DALPHA btxbst.doc alpha.txt -% cpp -P -DABBRV btxbst.doc abbrv.txt -% and then renaming after removing unwanted comments and blank lines. -% If you don't have access, -% you can edit this file by hand to imitate the preprocessor, -% with the following explanation of the C preprocessor constructs used here. -% -% The output of the preprocessor is the same as the input, except that certain -% lines will be excluded (and some blank lines will be added). The sequence -% #if VAR -% lines to be included when VAR is not zero -% #else -% lines to be included when VAR is zero -% #endif -% (with the #-signs appearing in column 1) means that one set or the other of -% the lines are to be included depending on the value of VAR. -% The #else part is optional. Comments can be added after #else and #endif. -% Variables can be set by -% #define VAR value -% and one can also use #ifdef VAR to see if VAR has any value, and #ifndef -% to see if it has none. -% Another #if form used in this file is #if !VAR, which includes the lines -% after the #if only if VAR is zero. -% -% Convention: Use all uppercase identifiers for these preprocessor variables -% so you can spot them easily -% -% The command line to the preprocessor should define one of PLAIN, UNSRT, ALPHA -% or ABBRV (though PLAIN will be used by default if none is given), -% and the following lines will set various boolean variables to control the -% various lines that are chosen from the rest of the file. -% Each boolean variable should be set true (1) or false (0) in each style. -% Here are the current variables, and their meanings: -% LAB_ALPH: an alphabetic label is used (if false then a numeric -% label is used) -% SORTED: the entries should be sorted by label (if nonnumeric) -% and other info, like authors (if false, then -% entries remain in order of occurrence) -% NAME_FULL: the authors, editors, etc., get the full names as -% given in the bibliography file (if false, the first -% names become initials) -% ATIT_LOWER: titles of non-"books" (e.g., articles) should be -% converted to lower-case, except the first letter or -% first letter after a colon -% (if false then they appear as in the database) -% MONTH_FULL: months are spelled out in full (if false, then -% they're abbreviated) -% JOUR_FULL: macro journal names are spelled out in full -% (if false then they are abbreviated, currently -% as they appear in ACM publications) -#ifndef UNSRT -# ifndef ALPHA -# ifndef ABBRV -# define PLAIN 1 -# endif -# endif -#endif -#ifdef PLAIN -% plain style (sorted numbers) -# define LAB_ALPH 0 -# define SORTED 1 -# define NAME_FULL 1 -# define ATIT_LOWER 1 -# define MONTH_FULL 1 -# define JOUR_FULL 1 -#endif -#ifdef UNSRT -% unsrt style (unsorted numbers) -# define LAB_ALPH 0 -# define SORTED 0 -# define NAME_FULL 1 -# define ATIT_LOWER 1 -# define MONTH_FULL 1 -# define JOUR_FULL 1 -#endif -#ifdef ALPHA -% alpha style (sorted short alphabetics) -# define LAB_ALPH 1 -# define SORTED 1 -# define NAME_FULL 1 -# define ATIT_LOWER 1 -# define MONTH_FULL 1 -# define JOUR_FULL 1 -#endif -#ifdef ABBRV -% abbrv style (sorted numbers, with abbreviations) -# define LAB_ALPH 0 -# define SORTED 1 -# define NAME_FULL 0 -# define ATIT_LOWER 1 -# define MONTH_FULL 0 -# define JOUR_FULL 0 -#endif -% -% Entry formatting: Similar to that recommended by Mary-Claire van Leunen -% in "A Handbook for Scholars". Book-like titles are italicized -% (emphasized) and non-book titles are converted to sentence -% capitilization (and not enclosed in quotes). -% This file outputs a \newblock between major blocks of an entry -% (the name \newblock is analogous to the names \newline and \newpage) -% so that the user can obtain an "open" format, which has a line break -% before each block and lines after the first are indented within blocks, -% by giving the optional \documentstyle argument `openbib'; -% The default is the "closed" format---blocks runs together. -% -% Citation alphabetic label format: -% [Knu73] for single author (or editor or key) -% [AHU83] (first letters of last names) for multiple authors -% -% Citation label numberic format: -% [number] -% -% Reference list ordering for sorted, alphabetic lables: -% alphabetical by citation label, then by author(s) or whatever -% passes for author in the absence of one, then by year, -% then title -% -% Reference list ordering for sorted, numeric lables: -% alphabetical by author(s) or whatever passes -% for author in the absence of one, then by year, then title -% -% Reference list ordering for unsorted: -% by the order cited in the text -% -% History -% 12/16/84 (HWT) Original `plain' version, by Howard Trickey. -% 12/23/84 (LL) Some comments made by Leslie Lamport. -% 2/16/85 (OP) Changes based on LL's comments, Oren Patashnik. -% 2/17/85 (HWT) Template file and other standard styles made. -% 3/28/85 (OP) First release, version 0.98b for BibTeX 0.98f. -% 5/ 9/85 (OP) Version 0.98c for BibTeX 0.98i: -% fixed Theoretical Computer Science macro name; -% fixed the format.vol.num.pages function. -% 1/24/88 (OP) Version 0.99a for BibTeX 0.99a, main changes: -% assignment operator (:=) arguments reversed; -% the preamble$ function outputs the database PREAMBLE; -% entry.max$ and global.max$ (built-in) variables replace -% entry.string.max and global.string.max functions; -% alphabetizing by year then title, not just title; -% many unnecessary ties removed; \it ==> \em; -% the `alpha' style uses a superscripted `+' instead of a -% `*' for unnamed names in constructing the label; -% the `abbrv' style now uses "Mar." and "Sept."; -% the functions calc.label and presort now look at just -% the fields they're supposed to; -% BOOKLET, MASTERSTHESIS, TECHREPORT use nonbook titles; -% INBOOK and INCOLLECTION take an optional type (e.g. -% type = "Section"), overriding the default "chapter"; -% BOOK, INBOOK, INCOLLECTION, and PROCEEDINGS now allow -% either volume or number, not just volume; -% INCOLLECTION now allows an edition and series field; -% PROCEEDINGS and INPROCEEDINGS now use the address field -% to tell where a conference was held; -% INPROCEEDINGS and PROCEEDINGS now allow either volume -% or number, and also a series field; -% MASTERSTHESIS and PHDTHESIS accept types other than -% "Master's thesis" and "PhD thesis"; -% UNPUBLISHED now outputs, in one block, note then date; -% MANUAL now prints out the organization in -% the first block if the author field is empty; -% MISC can't be empty---it requires some optional field. -% 3/23/88 (OP) Version 0.99b for BibTeX 0.99c---changed the three -% erroneous occurrences of `cite ' to `cite$ '; this -% change didn't affect the four standard styles, so the -% 0.99a versions of those styles are still current. -% 12/ 8/10 (OP) Still version 0.99b, as the code itself was unchanged; -% this release clarified the license. -% -% The ENTRY declaration -% Like Scribe's (according to pages 231-2 of the April '84 edition), -% but no fullauthor or editors fields because BibTeX does name handling. -% The annote field is commented out here because this family doesn't -% include an annotated bibliography style. And in addition to the fields -% listed here, BibTeX has a built-in crossref field, explained later. - -ENTRY -% Fields: - { address -% Usually the address of a publisher or other type of organization. -% Put information in this field only if it helps the reader find the -% thing---for example you should omit the address of a major -% publisher entirely. For a PROCEEDINGS or an INPROCEEDINGS, -% however, it's the address of the conference; for those two entry -% types, include the publisher's or organization's address, if -% necessary, in the publisher or organization field. -% annote -% Long annotation---for annotated bibliographies (begins sentence). - author -% Name(s) of author(s), in BibTeX name format. - booktitle -% Book title when the thing being referenced isn't the whole book. -% For book entries, the title field should be used instead. - chapter -% Chapter (or section or whatever) number. - edition -% Edition of a book---should be an ordinal (e.g., "Second"). - editor -% Name(s) of editor(s), in BibTeX name format. -% If there is also an author field, then the editor field should be -% for the book or collection that the work appears in. - howpublished -% How something strange has been published (begins sentence). - institution -% Sponsoring institution of a technical report. - journal -% Journal name (macros are provided for many). - key -% Alphabetizing, labeling, and cross-referencing key -% (needed when an entry has no author or editor). - month -% Month (macros are provided). - note -% To help the reader find a reference (begins sentence). - number -% Number of a journal or technical report, or of a work in a series. - organization -% Organization sponsoring a conference (or publishing a manual); if -% the editor (or author) is empty, and if the organization produces -% an awkward label or cross reference, you should put appropriately -% condensed organization information in the key field as well. - pages -% Page number or numbers (use `--' to separate a range, use `+' -% to indicate pages following that don't form a simple range). - publisher -% Publisher name. - school -% School name (for theses). - series -% The name of a series or set of books. -% An individual book will will also have it's own title. - title -% The title of the thing you're referred to. - type -% Type of a Techreport (e.g., "Research Note") to be used instead of -% the default "Technical Report"; or, similarly, the type of a -% thesis; or of a part of a book. - volume -% The volume number of a journal or multivolume work. - year -% The year should contain only numerals (technically, it should end -% with four numerals, after purification; doesn't a begin sentence). - } -% There are no integer entry variables - {} -% These string entry variables are used to form the citation label. -% In a storage pinch, sort.label can be easily computed on the fly. -#if LAB_ALPH -#if SORTED - { label extra.label sort.label } -#else !SORTED -% It doesn't seem like a good idea to use an order-of-citation -% reference list when using alphabetic labels, but when this happens -% we do things a little differently - { label } -#endif SORTED -#else !LAB_ALPH - { label } -#endif LAB_ALPH - -% Each entry function starts by calling output.bibitem, to write the -% \bibitem and its arguments to the .BBL file. Then the various fields -% are formatted and printed by output or output.check. Those functions -% handle the writing of separators (commas, periods, \newblock's), -% taking care not to do so when they are passed a null string. -% Finally, fin.entry is called to add the final period and finish the -% entry. -% -% A bibliographic reference is formatted into a number of `blocks': -% in the open format, a block begins on a new line and subsequent -% lines of the block are indented. A block may contain more than -% one sentence (well, not a grammatical sentence, but something to -% be ended with a sentence ending period). The entry functions should -% call new.block whenever a block other than the first is about to be -% started. They should call new.sentence whenever a new sentence is -% to be started. The output functions will ensure that if two -% new.sentence's occur without any non-null string being output between -% them then there won't be two periods output. Similarly for two -% successive new.block's. -% -% The output routines don't write their argument immediately. -% Instead, by convention, that argument is saved on the stack to be -% output next time (when we'll know what separator needs to come -% after it). Meanwhile, the output routine has to pop the pending -% output off the stack, append any needed separator, and write it. -% -% To tell which separator is needed, we maintain an output.state. -% It will be one of these values: -% before.all just after the \bibitem -% mid.sentence in the middle of a sentence: comma needed -% if more sentence is output -% after.sentence just after a sentence: period needed -% after.block just after a block (and sentence): -% period and \newblock needed. -% Note: These styles don't use after.sentence -% -% VAR: output.state : INTEGER -- state variable for output -% -% The output.nonnull function saves its argument (assumed to be nonnull) -% on the stack, and writes the old saved value followed by any needed -% separator. The ordering of the tests is decreasing frequency of -% occurrence. -% -% output.nonnull(s) == -% BEGIN -% s := argument on stack -% if output.state = mid.sentence then -% write$(pop() * ", ") -% -- "pop" isn't a function: just use stack top -% else -% if output.state = after.block then -% write$(add.period$(pop())) -% newline$ -% write$("\newblock ") -% else -% if output.state = before.all then -% write$(pop()) -% else -- output.state should be after.sentence -% write$(add.period$(pop()) * " ") -% fi -% fi -% output.state := mid.sentence -% fi -% push s on stack -% END -% -% The output function calls output.nonnull if its argument is non-empty; -% its argument may be a missing field (thus, not necessarily a string) -% -% output(s) == -% BEGIN -% if not empty$(s) then output.nonnull(s) -% fi -% END -% -% The output.check function is the same as the output function except that, if -% necessary, output.check warns the user that the t field shouldn't be empty -% (this is because it probably won't be a good reference without the field; -% the entry functions try to make the formatting look reasonable even when -% such fields are empty). -% -% output.check(s,t) == -% BEGIN -% if empty$(s) then -% warning$("empty " * t * " in " * cite$) -% else output.nonnull(s) -% fi -% END -% -% The output.bibitem function writes the \bibitem for the current entry -% (the label should already have been set up), and sets up the separator -% state for the output functions. And, it leaves a string on the stack -% as per the output convention. -% -% output.bibitem == -% BEGIN -% newline$ -% write$("\bibitem[") % for alphabetic labels, -% write$(label) % these three lines -% write$("]{") % are used -% write$("\bibitem{") % this line for numeric labels -% write$(cite$) -% write$("}") -% push "" on stack -% output.state := before.all -% END -% -% The fin.entry function finishes off an entry by adding a period to the -% string remaining on the stack. If the state is still before.all -% then nothing was produced for this entry, so the result will look bad, -% but the user deserves it. (We don't omit the whole entry because the -% entry was cited, and a bibitem is needed to define the citation label.) -% -% fin.entry == -% BEGIN -% write$(add.period$(pop())) -% newline$ -% END -% -% The new.block function prepares for a new block to be output, and -% new.sentence prepares for a new sentence. -% -% new.block == -% BEGIN -% if output.state <> before.all then -% output.state := after.block -% fi -% END -% -% new.sentence == -% BEGIN -% if output.state <> after.block then -% if output.state <> before.all then -% output.state := after.sentence -% fi -% fi -% END -% - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -% the variables s and t are temporary string holders - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ -#if LAB_ALPH - "\bibitem[" write$ - label write$ - "]{" write$ -#else - "\bibitem{" write$ -#endif LAB_ALPH - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -% This function finishes all entries. - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -% These three functions pop one or two (integer) arguments from the stack -% and push a single one, either 0 or 1. -% The 'skip$ in the `and' and `or' functions are used because -% the corresponding if$ would be idempotent - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -% Sometimes we begin a new block only if the block will be big enough. The -% new.block.checka function issues a new.block if its argument is nonempty; -% new.block.checkb does the same if either of its TWO arguments is nonempty. - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -% The new.sentence.check functions are analogous. - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -% Here are some functions for formatting chunks of an entry. -% By convention they either produce a string that can be followed by -% a comma or period (using add.period$, so it is OK to end in a period), -% or they produce the null string. -% -% A useful utility is the field.or.null function, which checks if the -% argument is the result of pushing a `missing' field (one for which no -% assignment was made when the current entry was read in from the database) -% or the result of pushing a string having no non-white-space characters. -% It returns the null string if so, otherwise it returns the field string. -% Its main (but not only) purpose is to guarantee that what's left on the -% stack is a string rather than a missing field. -% -% field.or.null(s) == -% BEGIN -% if empty$(s) then return "" -% else return s -% END -% -% Another helper function is emphasize, which returns the argument emphazised, -% if that is non-empty, otherwise it returns the null string. Italic -% corrections aren't used, so this function should be used when punctation -% will follow the result. -% -% emphasize(s) == -% BEGIN -% if empty$(s) then return "" -% else return "{\em " * s * "}" -% -% The format.names function formats the argument (which should be in -% BibTeX name format) into "First Von Last, Junior", separated by commas -% and with an "and" before the last (but ending with "et~al." if the last -% of multiple authors is "others"). This function's argument should always -% contain at least one name. -% -% VAR: nameptr, namesleft, numnames: INTEGER -% pseudoVAR: nameresult: STRING (it's what's accumulated on the stack) -% -% format.names(s) == -% BEGIN -% nameptr := 1 -% numnames := num.names$(s) -% namesleft := numnames -% while namesleft > 0 -% do -% % for full names: -% t := format.name$(s, nameptr, "{ff~}{vv~}{ll}{, jj}") -% % for abbreviated first names: -% t := format.name$(s, nameptr, "{f.~}{vv~}{ll}{, jj}") -% if nameptr > 1 then -% if namesleft > 1 then nameresult := nameresult * ", " * t -% else if numnames > 2 -% then nameresult := nameresult * "," -% fi -% if t = "others" -% then nameresult := nameresult * " et~al." -% else nameresult := nameresult * " and " * t -% fi -% fi -% else nameresult := t -% fi -% nameptr := nameptr + 1 -% namesleft := namesleft - 1 -% od -% return nameresult -% END -% -% The format.authors function returns the result of format.names(author) -% if the author is present, or else it returns the null string -% -% format.authors == -% BEGIN -% if empty$(author) then return "" -% else return format.names(author) -% fi -% END -% -% Format.editors is like format.authors, but it uses the editor field, -% and appends ", editor" or ", editors" -% -% format.editors == -% BEGIN -% if empty$(editor) then return "" -% else -% if num.names$(editor) > 1 then -% return format.names(editor) * ", editors" -% else -% return format.names(editor) * ", editor" -% fi -% fi -% END -% -% Other formatting functions are similar, so no "comment version" will be -% given for them. -% -% The `pop$' in this function gets rid of the duplicate `empty' value and -% the `skip$' returns the duplicate field value - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } -#if NAME_FULL - { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := -#else - { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := -#endif NAME_FULL - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -% The format.title function is used for non-book-like titles. -% For most styles we convert to lowercase (except for the very first letter, -% and except for the first one after a colon (followed by whitespace)), -% and hope the user has brace-surrounded words that need to stay capitilized; -% for some styles, however, we leave it as it is in the database. - -FUNCTION {format.title} -{ title empty$ - { "" } -#if ATIT_LOWER - { title "t" change.case$ } -#else - 'title -#endif ATIT_LOWER - if$ -} - -% By default, BibTeX sets the global integer variable global.max$ to the BibTeX -% constant glob_str_size, the maximum length of a global string variable. -% Analogously, BibTeX sets the global integer variable entry.max$ to -% ent_str_size, the maximum length of an entry string variable. -% The style designer may change these if necessary (but this is unlikely) - -% The n.dashify function makes each single `-' in a string a double `--' -% if it's not already -% -% pseudoVAR: pageresult: STRING (it's what's accumulated on the stack) -% -% n.dashify(s) == -% BEGIN -% t := s -% pageresult := "" -% while (not empty$(t)) -% do -% if (first character of t = "-") -% then -% if (next character isn't) -% then -% pageresult := pageresult * "--" -% t := t with the "-" removed -% else -% while (first character of t = "-") -% do -% pageresult := pageresult * "-" -% t := t with the "-" removed -% od -% fi -% else -% pageresult := pageresult * the first character -% t := t with the first character removed -% fi -% od -% return pageresult -% END - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -% The format.date function is for the month and year, but we give a warning if -% there's an empty year but the month is there, and we return the empty string -% if they're both empty. - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -% The format.btitle is for formatting the title field when it is a book-like -% entry---the style used here keeps it in uppers-and-lowers and emphasizes it. - -FUNCTION {format.btitle} -{ title emphasize -} - -% For several functions we'll need to connect two strings with a -% tie (~) if the second one isn't very long (fewer than 3 characters). -% The tie.or.space.connect function does that. It concatenates the two -% strings on top of the stack, along with either a tie or space between -% them, and puts this concatenation back onto the stack: -% -% tie.or.space.connect(str1,str2) == -% BEGIN -% if text.length$(str2) < 3 -% then return the concatenation of str1, "~", and str2 -% else return the concatenation of str1, " ", and str2 -% END - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -% The either.or.check function complains if both fields or an either-or pair -% are nonempty. -% -% either.or.check(t,s) == -% BEGIN -% if empty$(s) then -% warning$(can't use both " * t * " fields in " * cite$) -% fi -% END - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -% The format.bvolume function is for formatting the volume and perhaps -% series name of a multivolume work. If both a volume and a series field -% are there, we assume the series field is the title of the whole multivolume -% work (the title field should be the title of the thing being referred to), -% and we add an "of <series>". This function is called in mid-sentence. - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -% The format.number.series function is for formatting the series name -% and perhaps number of a work in a series. This function is similar to -% format.bvolume, although for this one the series must exist (and the -% volume must not exist). If the number field is empty we output either -% the series field unchanged if it exists or else the null string. -% If both the number and series fields are there we assume the series field -% gives the name of the whole series (the title field should be the title -% of the work being one referred to), and we add an "in <series>". -% We capitilize Number when this function is used at the beginning of a block. - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -% The format.edition function appends " edition" to the edition, if present. -% We lowercase the edition (it should be something like "Third"), because -% this doesn't start a sentence. - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -% The format.pages function is used for formatting a page range in a book -% (and in rare circumstances, an article). -% -% The multi.page.check function examines the page field for a "-" or "," or "+" -% so that format.pages can use "page" instead of "pages" if none exists. -% Note: global.max$ here means "take the rest of the string" -% -% VAR: multiresult: INTEGER (actually, a boolean) -% -% multi.page.check(s) == -% BEGIN -% t := s -% multiresult := false -% while ((not multiresult) and (not empty$(t))) -% do -% if (first character of t = "-" or "," or "+") -% then multiresult := true -% else t := t with the first character removed -% fi -% od -% return multiresult -% END - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -% This function doesn't begin a sentence so "pages" isn't capitalized. -% Other functions that use this should keep that in mind. - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -% The format.vol.num.pages function is for the volume, number, and page range -% of a journal article. We use the format: vol(number):pages, with some -% variations for empty fields. This doesn't begin a sentence. - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - - -% The format.chapter.pages, if the chapter is present, puts whatever is in the -% type field (or else "chapter" if type is empty) in front of a chapter number. -% It then appends the pages, if present. This doesn't begin a sentence. - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -% The format.in.ed.booktitle function is used for starting out a sentence -% that begins "In <booktitle>", putting an editor before the title if one -% exists. - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -% The function empty.misc.check complains if all six fields are empty, and -% if there's been no sorting or alphabetic-label complaint. - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and -#if SORTED - key empty$ not and -#else !SORTED -#if LAB_ALPH - key empty$ not and -#endif LAB_ALPH -#endif SORTED - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -% The function format.thesis.type returns either the (case-changed) type field, -% if it is defined, or else the default string already on the stack -% (like "Master's thesis" or "PhD thesis"). - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -% The function format.tr.number makes a string starting with "Technical Report" -% (or type, if that field is defined), followed by the number if there is one; -% it returns the starting part (with a case change) even if there is no number. -% This is used at the beginning of a sentence. - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -% Now come the cross-referencing functions (these are invoked because -% one entry in the database file(s) cross-references another, by giving -% the other entry's database key in a `crossref' field). This feature -% allows one or more titled things that are part of a larger titled -% thing to cross-reference the larger thing. These styles allow for -% five posibilities: (1) an ARTICLE may cross-reference an ARTICLE; -% (2) a BOOK, (3) INBOOK, or (4) INCOLLECTION may cross-reference a BOOK; -% or (5) an INPROCEEDINGS may cross-reference a PROCEEDINGS. -% Each of these is explained in more detail later. -% -% An ARTICLE entry type may cross reference another ARTICLE (this is -% intended for when an entire journal is devoted to a single topic--- -% but since there is no JOURNAL entry type, the journal, too, should be -% classified as an ARTICLE but without the author and title fields). -% This will result in two warning messages for the journal's entry -% if it's included in the reference list, but such is life. -% -% format.article.crossref == -% BEGIN -% if empty$(key) then -% if empty$(journal) then -% warning$("need key or journal for " * cite$ * -% " to crossref " * crossref) -% return(" \cite{" * crossref * "}") -% else -% return("In " * emphazise.correct (journal) * -% " \cite{" * crossref * "}") -% fi -% else -% return("In " * key * " \cite{" * crossref * "}") -% fi -% END -% -% The other cross-referencing functions are similar, so no "comment version" -% will be given for them. - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -% We use just the last names of editors for a cross reference: either -% "editor", or "editor1 and editor2", or "editor1 et~al." depending on -% whether there are one, or two, or more than two editors. - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -% A BOOK (or INBOOK) entry type (assumed to be for a single volume in a -% multivolume work) may cross reference another BOOK (the entire multivolume). -% Usually there will be an editor, in which case we use that to construct the -% cross reference; otherwise we use a nonempty key field or else the series -% field (since the series gives the title of the multivolume work). - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -% An INCOLLECTION entry type may cross reference a BOOK (assumed to be the -% collection), or an INPROCEEDINGS may cross reference a PROCEEDINGS. -% Often there will be an editor, in which case we use that to construct -% the cross reference; otherwise we use a nonempty key field or else -% the booktitle field (which gives the cross-referenced work's title). - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -% Now we define the type functions for all entry types that may appear -% in the .BIB file---e.g., functions like `article' and `book'. These -% are the routines that actually generate the .BBL-file output for -% the entry. These must all precede the READ command. In addition, the -% style designer should have a function `default.type' for unknown types. -% Note: The fields (within each list) are listed in order of appearance, -% except as described for an `inbook' or a `proceedings'. -% -% The article function is for an article in a journal. An article may -% CROSSREF another article. -% Required fields: author, title, journal, year -% Optional fields: volume, number, pages, month, note -% -% article == -% BEGIN -% output.bibitem -% output.check(format.authors,"author") -% new.block -% output.check(format.title,"title") -% new.block -% if missing$(crossref) then -% output.check(emphasize(journal),"journal") -% output(format.vol.num.pages) -% output.check(format.date,"year") -% else -% output.nonnull(format.article.crossref) -% output(format.pages) -% fi -% new.block -% output(note) -% fin.entry -% END -% -% The book function is for a whole book. A book may CROSSREF another book. -% Required fields: author or editor, title, publisher, year -% Optional fields: volume or number, series, address, edition, month, -% note -% -% book == -% BEGIN -% if empty$(author) then output.check(format.editors,"author and editor") -% else output.check(format.authors,"author") -% if missing$(crossref) then -% either.or.check("author and editor",editor) -% fi -% fi -% new.block -% output.check(format.btitle,"title") -% if missing$(crossref) then -% output(format.bvolume) -% new.block -% output(format.number.series) -% new.sentence -% output.check(publisher,"publisher") -% output(address) -% else -% new.block -% output.nonnull(format.book.crossref) -% fi -% output(format.edition) -% output.check(format.date,"year") -% new.block -% output(note) -% fin.entry -% END -% -% The other entry functions are all quite similar, so no "comment version" -% will be given for them. - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -% A booklet is a bound thing without a publisher or sponsoring institution. -% Required: title -% Optional: author, howpublished, address, month, year, note - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -% For the conference entry type, see inproceedings. - -% An inbook is a piece of a book: either a chapter and/or a page range. -% It may CROSSREF a book. If there's no volume field, the type field -% will come before number and series. -% Required: author or editor, title, chapter and/or pages, publisher,year -% Optional: volume or number, series, type, address, edition, month, note - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -% An incollection is like inbook, but where there is a separate title -% for the referenced thing (and perhaps an editor for the whole). -% An incollection may CROSSREF a book. -% Required: author, title, booktitle, publisher, year -% Optional: editor, volume or number, series, type, chapter, pages, -% address, edition, month, note - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -% An inproceedings is an article in a conference proceedings, and it may -% CROSSREF a proceedings. If there's no address field, the month (& year) -% will appear just before note. -% Required: author, title, booktitle, year -% Optional: editor, volume or number, series, pages, address, month, -% organization, publisher, note - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ - { organization publisher new.sentence.checkb - organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -% The conference function is included for Scribe compatibility. - -FUNCTION {conference} { inproceedings } - -% A manual is technical documentation. -% Required: title -% Optional: author, organization, address, edition, month, year, note - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - note output - fin.entry -} - -% A mastersthesis is a Master's thesis. -% Required: author, title, school, year -% Optional: type, address, month, note - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -% A misc is something that doesn't fit elsewhere. -% Required: at least one of the `optional' fields -% Optional: author, title, howpublished, month, year, note - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -% A phdthesis is like a mastersthesis. -% Required: author, title, school, year -% Optional: type, address, month, note - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -% A proceedings is a conference proceedings. -% If there is an organization but no editor field, the organization will -% appear as the first optional field (we try to make the first block nonempty); -% if there's no address field, the month (& year) will appear just before note. -% Required: title, year -% Optional: editor, volume or number, series, address, month, -% organization, publisher, note - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - organization output - } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - note output - fin.entry -} - -% A techreport is a technical report. -% Required: author, title, institution, year -% Optional: type, number, address, month, note - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -% An unpublished is something that hasn't been published. -% Required: author, title, note -% Optional: month, year - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -% We use entry type `misc' for an unknown type; BibTeX gives a warning. - -FUNCTION {default.type} { misc } - -% Here are macros for common things that may vary from style to style. -% Users are encouraged to use these macros. -% -% Months are either written out in full or abbreviated - -#if MONTH_FULL - -MACRO {jan} {"January"} - -MACRO {feb} {"February"} - -MACRO {mar} {"March"} - -MACRO {apr} {"April"} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"August"} - -MACRO {sep} {"September"} - -MACRO {oct} {"October"} - -MACRO {nov} {"November"} - -MACRO {dec} {"December"} - -#else !MONTH_FULL - -MACRO {jan} {"Jan."} - -MACRO {feb} {"Feb."} - -MACRO {mar} {"Mar."} - -MACRO {apr} {"Apr."} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"Aug."} - -MACRO {sep} {"Sept."} - -MACRO {oct} {"Oct."} - -MACRO {nov} {"Nov."} - -MACRO {dec} {"Dec."} - -#endif MONTH_FULL - -% Journals are either written out in full or abbreviated; -% the abbreviations are like those found in ACM publications. -% -% To get a completely different set of abbreviations, it may be best to make -% a separate .bib file with nothing but those abbreviations; users could then -% include that file name as the first argument to the \bibliography command - -#if JOUR_FULL - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications of the ACM"} - -MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -MACRO {ibmsj} {"IBM Systems Journal"} - -MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -MACRO {ieeetc} {"IEEE Transactions on Computers"} - -MACRO {ieeetcad} - {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"Journal of the ACM"} - -MACRO {jcss} {"Journal of Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM Journal on Computing"} - -MACRO {tocs} {"ACM Transactions on Computer Systems"} - -MACRO {tods} {"ACM Transactions on Database Systems"} - -MACRO {tog} {"ACM Transactions on Graphics"} - -MACRO {toms} {"ACM Transactions on Mathematical Software"} - -MACRO {toois} {"ACM Transactions on Office Information Systems"} - -MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -#else !JOUR_FULL - -MACRO {acmcs} {"ACM Comput. Surv."} - -MACRO {acta} {"Acta Inf."} - -MACRO {cacm} {"Commun. ACM"} - -MACRO {ibmjrd} {"IBM J. Res. Dev."} - -MACRO {ibmsj} {"IBM Syst.~J."} - -MACRO {ieeese} {"IEEE Trans. Softw. Eng."} - -MACRO {ieeetc} {"IEEE Trans. Comput."} - -MACRO {ieeetcad} - {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} - -MACRO {ipl} {"Inf. Process. Lett."} - -MACRO {jacm} {"J.~ACM"} - -MACRO {jcss} {"J.~Comput. Syst. Sci."} - -MACRO {scp} {"Sci. Comput. Programming"} - -MACRO {sicomp} {"SIAM J. Comput."} - -MACRO {tocs} {"ACM Trans. Comput. Syst."} - -MACRO {tods} {"ACM Trans. Database Syst."} - -MACRO {tog} {"ACM Trans. Gr."} - -MACRO {toms} {"ACM Trans. Math. Softw."} - -MACRO {toois} {"ACM Trans. Office Inf. Syst."} - -MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} - -MACRO {tcs} {"Theoretical Comput. Sci."} - -#endif JOUR_FULL - -% Now we read in the .BIB entries. - -READ - -% The sortify function converts to lower case after purify$ing; it's -% used in sorting and in computing alphabetic labels after sorting -% -% The chop.word(w,len,s) function returns either s or, if the first len -% letters of s equals w (this comparison is done in the third line of the -% function's definition), it returns that part of s after w. - -#if SORTED - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -#else !SORTED -#if LAB_ALPH - -% We need the chop.word stuff for the dubious unsorted-list-with-labels case. - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -#endif LAB_ALPH -#endif SORTED - -% This long comment applies only to alphabetic labels -% -% The format.lab.names function makes a short label by using the initials of -% the von and Last parts of the names (but if there are more than four names, -% (i.e., people) it truncates after three and adds a superscripted "+"; -% it also adds such a "+" if the last of multiple authors is "others"). -% If there is only one name, and its von and Last parts combined have just -% a single name-token ("Knuth" has a single token, "Brinch Hansen" has two), -% we take the first three letters of the last name. The boolean -% et.al.char.used tells whether we've used a superscripted "+", so that we -% know whether to include a LaTeX macro for it. -% -% format.lab.names(s) == -% BEGIN -% numnames := num.names$(s) -% if numnames > 1 then -% if numnames > 4 then -% namesleft := 3 -% else -% namesleft := numnames -% nameptr := 1 -% nameresult := "" -% while namesleft > 0 -% do -% if (name_ptr = numnames) and -% format.name$(s, nameptr, "{ff }{vv }{ll}{ jj}") = "others" -% then nameresult := nameresult * "{\etalchar{+}}" -% et.al.char.used := true -% else nameresult := nameresult * -% format.name$(s, nameptr, "{v{}}{l{}}") -% nameptr := nameptr + 1 -% namesleft := namesleft - 1 -% od -% if numnames > 4 then -% nameresult := nameresult * "{\etalchar{+}}" -% et.al.char.used := true -% else -% t := format.name$(s, 1, "{v{}}{l{}}") -% if text.length$(t) < 2 then % there's just one name-token -% nameresult := text.prefix$(format.name$(s,1,"{ll}"),3) -% else -% nameresult := t -% fi -% fi -% return nameresult -% END -% -% Exactly what fields we look at in constructing the primary part of the label -% depends on the entry type; this selectivity (as opposed to, say, always -% looking at author, then editor, then key) helps ensure that "ignored" fields, -% as described in the LaTeX book, really are ignored. Note that MISC is part -% of the deepest `else' clause in the nested part of calc.label; thus, any -% unrecognized entry type in the database is handled correctly. -% -% There is one auxiliary function for each of the four different sequences of -% fields we use. The first of these functions looks at the author field, and -% then, if necessary, the key field. The other three functions, which might -% look at two fields and the key field, are similar, except that the key field -% takes precedence over the organization field (for labels---not for sorting). -% -% The calc.label function calculates the preliminary label of an entry, which -% is formed by taking three letters of information from the author or editor or -% key or organization field (depending on the entry type and on what's empty, -% but ignoring a leading "The " in the organization), and appending the last -% two characters (digits) of the year. It is an error if the appropriate fields -% among author, editor, organization, and key are missing, and we use -% the first three letters of the cite$ in desperation when this happens. -% The resulting label has the year part, but not the name part, purify$ed -% (purify$ing the year allows some sorting shenanigans by the user). -% -% This function also calculates the version of the label to be used in sorting. -% -% The final label may need a trailing 'a', 'b', etc., to distinguish it from -% otherwise identical labels, but we can't calculated those "extra.label"s -% until after sorting. -% -% calc.label == -% BEGIN -% if type$ = "book" or "inbook" then -% author.editor.key.label -% else if type$ = "proceedings" then -% editor.key.organization.label -% else if type$ = "manual" then -% author.key.organization.label -% else -% author.key.label -% fi fi fi -% label := label * substring$(purify$(field.or.null(year)), -1, 2) -% % assuming we will also sort, we calculate a sort.label -% sort.label := sortify(label), but use the last four, not two, digits -% END - -#if LAB_ALPH - -INTEGERS { et.al.char.used } - -FUNCTION {initialize.et.al.char.used} -{ #0 'et.al.char.used := -} - -EXECUTE {initialize.et.al.char.used} - -FUNCTION {format.lab.names} -{ 's := - s num.names$ 'numnames := - numnames #1 > - { numnames #4 > - { #3 'namesleft := } - { numnames 'namesleft := } - if$ - #1 'nameptr := - "" - { namesleft #0 > } - { nameptr numnames = - { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { "{\etalchar{+}}" * - #1 'et.al.char.used := - } - { s nameptr "{v{}}{l{}}" format.name$ * } - if$ - } - { s nameptr "{v{}}{l{}}" format.name$ * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ - numnames #4 > - { "{\etalchar{+}}" * - #1 'et.al.char.used := - } - 'skip$ - if$ - } - { s #1 "{v{}}{l{}}" format.name$ - duplicate$ text.length$ #2 < - { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } - 'skip$ - if$ - } - if$ -} - -FUNCTION {author.key.label} -{ author empty$ - { key empty$ -#if SORTED - { cite$ #1 #3 substring$ } -#else !SORTED % need warning here because we won't give it later - { "for label, need author or key in " cite$ * warning$ - cite$ #1 #3 substring$ - } -#endif SORTED - { key #3 text.prefix$ } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {author.editor.key.label} -{ author empty$ - { editor empty$ - { key empty$ -#if SORTED - { cite$ #1 #3 substring$ } -#else !SORTED % need warning here because we won't give it later - { "for label, need author, editor, or key in " cite$ * warning$ - cite$ #1 #3 substring$ - } -#endif SORTED - { key #3 text.prefix$ } - if$ - } - { editor format.lab.names } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {author.key.organization.label} -{ author empty$ - { key empty$ - { organization empty$ -#if SORTED - { cite$ #1 #3 substring$ } -#else !SORTED % need warning here because we won't give it later - { "for label, need author, key, or organization in " cite$ * - warning$ - cite$ #1 #3 substring$ - } -#endif SORTED - { "The " #4 organization chop.word #3 text.prefix$ } - if$ - } - { key #3 text.prefix$ } - if$ - } - { author format.lab.names } - if$ -} - -FUNCTION {editor.key.organization.label} -{ editor empty$ - { key empty$ - { organization empty$ -#if SORTED - { cite$ #1 #3 substring$ } -#else !SORTED % need warning here because we won't give it later - { "for label, need editor, key, or organization in " cite$ * - warning$ - cite$ #1 #3 substring$ - } -#endif SORTED - { "The " #4 organization chop.word #3 text.prefix$ } - if$ - } - { key #3 text.prefix$ } - if$ - } - { editor format.lab.names } - if$ -} - -FUNCTION {calc.label} -{ type$ "book" = - type$ "inbook" = - or - 'author.editor.key.label - { type$ "proceedings" = - 'editor.key.organization.label - { type$ "manual" = - 'author.key.organization.label - 'author.key.label - if$ - } - if$ - } - if$ - duplicate$ - year field.or.null purify$ #-1 #2 substring$ - * - 'label := - year field.or.null purify$ #-1 #4 substring$ - * - sortify 'sort.label := -} - -% It doesn't seem like a particularly good idea to use an order-of-citation -% reference list when using alphabetic labels, but we need to have a -% special pass to calculate labels when this happens. - -#if !SORTED - -ITERATE {calc.label} - -#endif !SORTED - -#endif LAB_ALPH - -% When sorting, we compute the sortkey by executing "presort" on each entry. -% The presort key contains a number of "sortify"ed strings, concatenated -% with multiple blanks between them. This makes things like "brinch per" -% come before "brinch hansen per". -% -% The fields used here are: the sort.label for alphabetic labels (as set by -% calc.label), followed by the author names (or editor names or organization -% (with a leading "The " removed) or key field, depending on entry type and on -% what's empty), followed by year, followed by the first bit of the title -% (chopping off a leading "The ", "A ", or "An "). -% Names are formatted: Von Last First Junior. -% The names within a part will be separated by a single blank -% (such as "brinch hansen"), two will separate the name parts themselves -% (except the von and last), three will separate the names, -% four will separate the names from year (and from label, if alphabetic), -% and four will separate year from title. -% -% The sort.format.names function takes an argument that should be in -% BibTeX name format, and returns a string containing " "-separated -% names in the format described above. The function is almost the same -% as format.names. - -#if SORTED - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ -#if NAME_FULL - s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := -#else - s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := -#endif NAME_FULL - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -% The sort.format.title function returns the argument, -% but first any leading "A "'s, "An "'s, or "The "'s are removed. -% The chop.word function uses s, so we need another string variable, t - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -% The auxiliary functions here, for the presort function, are analogous to -% the ones for calc.label; the same comments apply, except that the -% organization field takes precedence here over the key field. For sorting -% purposes, we still remove a leading "The " from the organization field. - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -% There is a limit, entry.max$, on the length of an entry string variable -% (which is what its sort.key$ is), so we take at most that many characters -% of the constructed key, and hope there aren't many references that match -% to that many characters! - -FUNCTION {presort} -#if LAB_ALPH -{ calc.label - sort.label - " " - * - type$ "book" = -#else !LAB_ALPH -{ type$ "book" = -#endif LAB_ALPH - type$ "inbook" = - or - 'author.editor.sort - { type$ "proceedings" = - 'editor.organization.sort - { type$ "manual" = - 'author.organization.sort - 'author.sort - if$ - } - if$ - } - if$ -#if LAB_ALPH - * -#endif LAB_ALPH - " " - * - year field.or.null sortify - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -% And now we can sort - -SORT - -#endif SORTED - -% This long comment applies only to alphabetic labels, when sorted -% -% Now comes the final computation for alphabetic labels, putting in the 'a's -% and 'b's and so forth if required. This involves two passes: a forward -% pass to put in the 'b's, 'c's and so on, and a backwards pass -% to put in the 'a's (we don't want to put in 'a's unless we know there -% are 'b's). -% We have to keep track of the longest (in width$ terms) label, for use -% by the "thebibliography" environment. -% -% VAR: longest.label, last.sort.label, next.extra: string -% longest.label.width, last.extra.num: integer -% -% initialize.longest.label == -% BEGIN -% longest.label := "" -% last.sort.label := int.to.chr$(0) -% next.extra := "" -% longest.label.width := 0 -% last.extra.num := 0 -% END -% -% forward.pass == -% BEGIN -% if last.sort.label = sort.label then -% last.extra.num := last.extra.num + 1 -% extra.label := int.to.chr$(last.extra.num) -% else -% last.extra.num := chr.to.int$("a") -% extra.label := "" -% last.sort.label := sort.label -% fi -% END -% -% reverse.pass == -% BEGIN -% if next.extra = "b" then -% extra.label := "a" -% fi -% label := label * extra.label -% if width$(label) > longest.label.width then -% longest.label := label -% longest.label.width := width$(label) -% fi -% next.extra := extra.label -% END - -#if LAB_ALPH - -#if SORTED - -STRINGS { longest.label last.sort.label next.extra } - -INTEGERS { longest.label.width last.extra.num } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #0 int.to.chr$ 'last.sort.label := - "" 'next.extra := - #0 'longest.label.width := - #0 'last.extra.num := -} - -FUNCTION {forward.pass} -{ last.sort.label sort.label = - { last.extra.num #1 + 'last.extra.num := - last.extra.num int.to.chr$ 'extra.label := - } - { "a" chr.to.int$ 'last.extra.num := - "" 'extra.label := - sort.label 'last.sort.label := - } - if$ -} - -FUNCTION {reverse.pass} -{ next.extra "b" = - { "a" 'extra.label := } - 'skip$ - if$ - label extra.label * 'label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ - extra.label 'next.extra := -} - -EXECUTE {initialize.longest.label} - -ITERATE {forward.pass} - -REVERSE {reverse.pass} - -#else !SORTED - -% It still doesn't seem like a good idea to use an order-of-citation -% reference list when using alphabetic labels, but when this happens we -% must compute the longest label - -STRINGS { longest.label } - -INTEGERS { longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -#endif SORTED - -#else !LAB_ALPH - -% Now comes the computation for numeric labels. -% We use either the sorted order or original order. -% We still have to keep track of the longest (in width$ terms) label, for use -% by the "thebibliography" environment. - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -#endif LAB_ALPH - -% Now we're ready to start writing the .BBL file. -% We begin, if necessary, with a LaTeX macro for unnamed names in an alphabetic -% label; next comes stuff from the `preamble' command in the database files. -% Then we give an incantation containing the command -% \begin{thebibliography}{...} -% where the `...' is the longest label. -% -% We also call init.state.consts, for use by the output routines. - -FUNCTION {begin.bib} -#if LAB_ALPH -{ et.al.char.used - { "\newcommand{\etalchar}[1]{$^{#1}$}" write$ newline$ } - 'skip$ - if$ - preamble$ empty$ -#else !LAB_ALPH -{ preamble$ empty$ -#endif LAB_ALPH - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -% Now we produce the output for all the entries - -ITERATE {call.type$} - -% Finally, we finish up by writing the `\end{thebibliography}' command. - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/btxdoc.bib b/Build/extra/bibtex/btxdoc.bib deleted file mode 100644 index 5a30c68d693..00000000000 --- a/Build/extra/bibtex/btxdoc.bib +++ /dev/null @@ -1,93 +0,0 @@ -% Copyright (C) 1988, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted if it -% is unmodified. Modifications (and their redistribution) are also -% permitted, as long as the resulting file is renamed. - -@COMMENT(You may put a comment in a `comment' command, - the way you would with SCRIBE.) - -Or you may dispense with the command and simply give the comment, -as long as it's not within an entry. - -If you really want to put a comment inside an entry, simply -make up a never-to-be-used field. - -@FAKE-ENTRY - {fake-database-key, - never-to-be-used-field = "Even if this were a real entry, - I could still have a comment inside an entry - by making up a fake field" - } - -@string (SCRIBE-NOTE = {Chapter twelve and appendices E8 through E10 deal - with bibliographies}) - -The next entry shows some of the syntactically legal things that -those with the inclination may use.@ - -MaNuAl (scribe, - TITLE="Scribe Document Production System - - - User Manual", - ORGANIZATION = {Unilogic,}#" Ltd"# {. - }, - ADDRESS = "Pittsburgh", - MONTH -=aPR - ,YEAR=1984, - note = scribe-note, -) May the inclination not be with you. - - -@MISC{prime-number-theorem, - author = "Charles Louis Xavier Joseph de la Vall{\'e}e Poussin", - note = "A strong form of the prime number theorem, 19th century" } - -@INBOOK{chicago, - title = "The Chicago Manual of Style", - publisher = "University of Chicago Press", - edition = "Thirteenth", - year = 1982, - pages = "400--401", - key = "Chicago" } - -@BOOK{texbook, - author = "Donald E. Knuth", - title= "The {{\TeX}book}", - publisher = "Addison-Wesley", - year = 1984 } - -@BOOK{latex, - author = "Leslie Lamport", - title = "{\LaTeX \rm:} {A} Document Preparation System", - publisher = "Addison-Wesley", - year = 1986 } - -@UNPUBLISHED{btxdoc, - author = "Oren Patashnik", - title = "{{\BibTeX ing}}", - note = "Documentation for general {\BibTeX} users", - month = "8~" # feb, - year = 1988 } - -@UNPUBLISHED{btxhak, - author = "Oren Patashnik", - title = "Designing {\BibTeX} Styles", - note = "The part of \BibTeX's documentation - that's not meant for general users", - month = "8~" # feb, - year = 1988 } - -@BOOK{strunk-and-white, - author = "Strunk, Jr., William and E. B. White", - title = "The Elements of Style", - publisher = "Macmillan", - edition = "Third", - year = 1979 } - -@BOOK{van-leunen, - title = "A Handbook for Scholars", - author = "Mary-Claire van Leunen", - publisher = "Knopf", - year = 1979 } diff --git a/Build/extra/bibtex/btxdoc.pdf b/Build/extra/bibtex/btxdoc.pdf Binary files differdeleted file mode 100644 index 1b5227d76a3..00000000000 --- a/Build/extra/bibtex/btxdoc.pdf +++ /dev/null diff --git a/Build/extra/bibtex/btxdoc.tex b/Build/extra/bibtex/btxdoc.tex deleted file mode 100644 index b41318fa1c1..00000000000 --- a/Build/extra/bibtex/btxdoc.tex +++ /dev/null @@ -1,1120 +0,0 @@ -% Copyright (C) 1988, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted if it -% is unmodified. Modifications (and their redistribution) are also -% permitted, as long as the resulting file is renamed. - -\def\BibTeX{{\rm B\kern-.05em{\sc i\kern-.025em b}\kern-.08em - T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}} - -\title{B\kern-.05em{\large I}\kern-.025em{\large B}\kern-.08em\TeX ing} -\author{Oren Patashnik} -\date{February 8, 1988} - -\documentstyle{article} -\begin{document} - -\maketitle - -\section{Overview} - -[This document will be expanded when \BibTeX\ version 1.00 comes out. -Please report typos, omissions, inaccuracies, -and especially unclear explanations -to {\tt biblio@tug.org} ({\tt http://lists.tug.org/biblio}). -Suggestions for improvements are wanted and welcome.] - -This documentation, for \BibTeX\ version 0.99b, -is meant for general \BibTeX\ users; -bibliography-style designers should read this document -and then read ``Designing \BibTeX\ Styles''~\cite{btxhak}, -which is meant for just them. - -This document has three parts: -Section~\ref{differences} -describes the differences between versions 0.98i and 0.99b -of \BibTeX\ and between the corresponding versions of the standard styles; -Section~\ref{latex-appendix} -updates Appendix~B.2 of the \LaTeX\ book~\cite{latex}; -and Section~\ref{odds-and-ends} -gives some general and specific tips -that aren't documented elsewhere. -It's assumed throughout that you're familiar with -the relevant sections of the \LaTeX\ book. - -This documentation also serves as sample input to help -\BibTeX\ implementors get it running. -For most documents, this one included, you produce the reference list by: -running \LaTeX\ on the document (to produce the {\tt aux} file(s)), -then running \BibTeX\ (to produce the {\tt bbl} file), -then \LaTeX\ twice more (first to find the information in the {\tt bbl} file -and then to get the forward references correct). -In very rare circumstances you may need an extra \BibTeX/\LaTeX\ run. - -\BibTeX\ version 0.99b should be used with \LaTeX\ version 2.09, -for which the closed bibliography format is the default; -to get the open format, use the optional document style {\tt openbib} -(in an open format there's a line break between major blocks of a -reference-list entry; in a closed format the blocks run together).] - -Note: \BibTeX\ 0.99b is not compatible with the old style files; -nor is \BibTeX\ 0.98i compatible with the new ones -(the new \BibTeX, however, is compatible with old database files). - -Note for implementors: \BibTeX\ provides logical-area names -\hbox{\tt TEXINPUTS:} for bibliography-style files and -\hbox{\tt TEXBIB:} for database files it can't otherwise find. - - -\section{Changes} -\label{differences} - -This section describes the differences between -\BibTeX\ versions 0.98i and 0.99b, and also between -the corresponding standard styles. -There were a lot of differences; -there will be a lot fewer between 0.99 and 1.00. - - -\subsection{New \BibTeX\ features} -\label{features} - -The following list explains \BibTeX's new features and how to use them. -\begin{enumerate} - -\item -With the single command `\hbox{\verb|\nocite{*}|}' -you can now include in the reference list -every entry in the database files, without having to explicitly -\verb|\cite| or \hbox{\verb|\nocite|} each entry. -Giving this command, in essence, -\hbox{\verb|\nocite|}s -all the enties in the database, in database order, -at the very spot in your document -where you give the command. - -\item -\label{concat} -You can now have as a field value (or an {\tt @STRING} definition) -the concatenation of several strings. -For example if you've defined -\begin{verbatim} - @STRING( WGA = " World Gnus Almanac" ) -\end{verbatim} -then it's easy to produce nearly-identical -{\tt title} fields for different entries: -\begin{verbatim} - @BOOK(almanac-66, - title = 1966 # WGA, - . . . - @BOOK(almanac-67, - title = 1967 # WGA, -\end{verbatim} -and so on. Or, you could have a field like -\begin{verbatim} - month = "1~" # jan, -\end{verbatim} -which would come out something like -`\hbox{\verb|1~January|}' or `\hbox{\verb|1~Jan.|}' in the {\tt bbl} file, -depending on how your bibliography style defines -the {\tt jan} abbreviation. -You may concatenate as many strings as you like -(except that there's a limit to the overall length -of the resulting field); -just be sure to put the concatenation character `{\tt\#}'$\!$, -surrounded by optional spaces or newlines, -between each successive pair of strings. - -\item -\BibTeX\ has a new cross-referencing feature, -explained by an example. -Suppose you say \hbox{\verb|\cite{no-gnats}|} in your document, -and suppose you have these two entries in your database file: -\begin{verbatim} - @INPROCEEDINGS(no-gnats, - crossref = "gg-proceedings", - author = "Rocky Gneisser", - title = "No Gnats Are Taken for Granite", - pages = "133-139") - . . . - @PROCEEDINGS(gg-proceedings, - editor = "Gerald Ford and Jimmy Carter", - title = "The Gnats and Gnus 1988 Proceedings", - booktitle = "The Gnats and Gnus 1988 Proceedings") -\end{verbatim} -Two things happen. -First, the special \hbox{\tt crossref} field tells \BibTeX\ -that the \hbox{\tt no-gnats} entry should inherit -any fields it's missing from -the entry it cross references, \hbox{\tt gg-proceedings}. -In this case it in inherits the two fields -\hbox{\tt editor} and \hbox{\tt booktitle}. -Note that, in the standard styles at least, -the \hbox{\tt booktitle} field is irrelevant -for the \hbox{\tt PROCEEDINGS} entry type. -The \hbox{\tt booktitle} field appears here -in the \hbox{\tt gg-proceedings} entry -only so that the entries that cross reference it -may inherit the field. -No matter how many papers from this meeting exist in the database, -this \hbox{\tt booktitle} field need only appear once. - -The second thing that happens: -\BibTeX\ automatically puts the entry \hbox{\tt gg-proceedings} -into the reference list if it's cross -referenced by two or more entries that you -\verb|\cite| or \hbox{\verb|\nocite|}, -even if you don't \verb|\cite| or \hbox{\verb|\nocite|} -the \hbox{\tt gg-proceedings} entry itself. -So \hbox{\tt gg-proceedings} will automatically appear -on the reference list if one other entry -besides \hbox{\tt no-gnats} cross references it. - -To guarantee that this scheme works, however, -a cross-referenced entry must occur later in the database files -than every entry that cross-references it. -Thus, putting all cross-referenced entries at the end makes sense. -(Moreover, you may not reliably nest cross references; -that is, a cross-referenced entry may -not itself reliably cross reference an entry. -This is almost certainly not something you'd -want to do, though.) - -One final note: -This cross-referencing feature is completely unrelated -to the old \BibTeX's cross referencing, -which is still allowed. -Thus, having a field like -\begin{verbatim} - note = "Jones \cite{jones-proof} improves the result" -\end{verbatim} -is not affected by the new feature. - -\item -\BibTeX\ now handles accented characters. -For example if you have an entry with the two fields -\begin{verbatim} - author = "Kurt G{\"o}del", - year = 1931, -\end{verbatim} -and if you're using the \hbox{\tt alpha} bibliography style, -then \BibTeX\ will construct the label -\hbox{[G{\"o}d31]} for this entry, which is what you'd want. -To get this feature to work you must place the entire accented -character in braces; -in this case either \hbox{\verb|{\"o}|} -or \hbox{\verb|{\"{o}}|} will do. -Furthermore these braces must not themselves be -enclosed in braces (other than the ones that might delimit -the entire field or the entire entry); -and there must be a backslash -as the very first character inside the braces. -Thus neither \hbox{\verb|{G{\"{o}}del}|} -nor \hbox{\verb|{G\"{o}del}|} will work for this example. - -This feature handles all the accented characters and -all but the nonbackslashed foreign symbols found in Tables -3.1 and~3.2 of the \LaTeX\ book. -This feature behaves similarly for ``accents'' you might define; -we'll see an example shortly. -For the purposes of counting letters in labels, -\BibTeX\ considers everything contained inside the braces -as a single letter. - -\item -\BibTeX\ also handles hyphenated names. -For example if you have an entry with -\begin{verbatim} - author = "Jean-Paul Sartre", -\end{verbatim} -and if you're using the \hbox{\tt abbrv} style, -then the result is `J.-P. Sartre'$\!$. - -\item -\label{preamble} -There's now an \hbox{\verb|@PREAMBLE|} command -for the database files. -This command's syntax is just like \hbox{\verb|@STRING|}'s, -except that there is no name or equals-sign, just the string. -Here's an example: -\begin{verbatim} - @PREAMBLE{ "\newcommand{\noopsort}[1]{} " - # "\newcommand{\singleletter}[1]{#1} " } -\end{verbatim} -(note the use of concatenation here, too). -The standard styles output whatever information you give this command -(\LaTeX\ macros most likely) directly to the {\tt bbl} file. -We'll look at one possible use of this command, -based on the \hbox{\verb|\noopsort|} command just defined. - -The issue here is sorting (alphabetizing). -\BibTeX\ does a pretty good job, -but occasionally weird circumstances conspire to confuse \BibTeX: -Suppose that you have entries in your database for -the two books in a two-volume set by the same author, -and that you'd like volume~1 to appear -just before volume~2 in your reference list. -Further suppose that there's now a second edition of volume~1, -which came out in 1973, say, -but that there's still just one edition of volume~2, -which came out in 1971. -Since the {\tt plain} standard style -sorts by author and then year, -it will place volume~2 first -(because its edition came out two years earlier) -unless you help \BibTeX. -You can do this by using the {\tt year} fields below -for the two volumes: -\begin{verbatim} - year = "{\noopsort{a}}1973" - . . . - year = "{\noopsort{b}}1971" -\end{verbatim} -According to the definition of \hbox{\verb|\noopsort|}, -\LaTeX\ will print nothing but the true year for these fields. -But \BibTeX\ will be perfectly happy pretending that -\hbox{\verb|\noopsort|} specifies some fancy accent -that's supposed to adorn the `a' and the~`b'; -thus when \BibTeX\ sorts it will pretend that -`a1973' and `b1971' are the real years, -and since `a' comes before~`b'$\!$, it will place volume~1 before volume~2, -just what you wanted. -By the way, if this author has any other works included -in your database, you'd probably want to use instead something like -\hbox{\verb|{\noopsort{1968a}}1973|} and -\hbox{\verb|{\noopsort{1968b}}1971|}, -so that these two books would come out in a reasonable spot -relative to the author's other works -(this assumes that 1968 results in a reasonable spot, -say because that's when the first edition of volume~1 appeared). - -There is a limit to the number of \hbox{\verb|@PREAMBLE|} commands -you may use, but you'll never exceed this limit if -you restrict yourself to one per database file; -this is not a serious restriction, -given the concatenation feature (item~\ref{concat}). - -\item -\BibTeX's sorting algorithm is now stable. -This means that if two entries have identical sort keys, -those two entries will appear in citation order. -(The bibliography styles construct these sort keys---% -usually the author information followed by the year and the title.) - -\item -\BibTeX\ no longer does case conversion for file names; -this will make \BibTeX\ easier to install on Unix systems, for example. - -\item -It's now easier to add code for processing a -command-line {\tt aux}-file name. - -\end{enumerate} - - -\subsection{Changes to the standard styles} - -This section describes changes to the standard styles -({\tt plain}, {\tt unsrt}, {\tt alpha}, {\tt abbrv}) -that affect ordinary users. -Changes that affect style designers appear in -the document ``Designing \BibTeX\ Styles''~\cite{btxhak}. -\begin{enumerate} - -\item -In general, sorting is now by ``author''$\!$, then year, then title---% -the old versions didn't use the year field. -(The {\tt alpha} style, however, sorts first by label, -then ``author''$\!$, year, and title.) -The quotes around author mean that some entry types -might use something besides the author, like the editor or organization. - -\item -Many unnecessary ties (\verb|~|) have been removed. -\LaTeX\ thus will produce slightly fewer -`\hbox{\tt Underfull} \verb|\hbox|' messages -when it's formatting the reference list. - -\item -Emphasizing (\hbox{\verb|{\em ...}|}) -has replaced italicizing (\hbox{\verb|{\it ...}|}). -This will almost never result in a difference -between the old output and the new. - -\item -The {\tt alpha} style now uses a superscripted~`$^{+}$' instead of a~`*' -to represent names omitted in constructing the label. -If you really liked it the way it was, however, -or if you want to omit the character entirely, -you don't have to modify the style file---% -you can override the~`$^{+}$' by -redefining the \hbox{\verb|\etalchar|} command -that the {\tt alpha} style writes onto the {\tt bbl} file -(just preceding the \hbox{\verb|\thebibliography|} environment); -use \LaTeX's \hbox{\verb|\renewcommand|} inside -a database \hbox{\tt @PREAMBLE} command, -described in the previous subsection's item~\ref{preamble}. - -\item -The {\tt abbrv} style now uses `Mar.' and `Sept.'\ -for those months rather than `March' and `Sep.' - -\item -The standard styles use \BibTeX's new cross-referencing feature -by giving a \verb|\cite| of the cross-referenced entry and by -omitting from the cross-referencing entry -(most of the) information that appears -in the cross-referenced entry. -These styles do this when -a titled thing (the cross-referencing entry) -is part of a larger titled thing (the cross-referenced entry). -There are five such situations: -when (1)~an \hbox{\tt INPROCEEDINGS} -(or \hbox{\tt CONFERENCE}, which is the same) -cross references a \hbox{\tt PROCEEDINGS}; -when (2)~a {\tt BOOK}, (3)~an \hbox{\tt INBOOK}, -or (4)~an \hbox{\tt INCOLLECTION} -cross references a {\tt BOOK} -(in these cases, the cross-referencing entry is a single -volume in a multi-volume work); -and when (5)~an \hbox{\tt ARTICLE} -cross references an \hbox{\tt ARTICLE} -(in this case, the cross-referenced entry is really a journal, -but there's no \hbox{\tt JOURNAL} entry type; -this will result in warning messages about -an empty \hbox{\tt author} and \hbox{\tt title} for the journal---% -you should just ignore these warnings). - -\item -The \hbox{\tt MASTERSTHESIS} and \hbox{\tt PHDTHESIS} -entry types now take an optional {\tt type} field. -For example you can get the standard styles to -call your reference a `Ph.D.\ dissertation' -instead of the default `PhD thesis' by including a -\begin{verbatim} - type = "{Ph.D.} dissertation" -\end{verbatim} -in your database entry. - -\item -Similarly, the \hbox{\tt INBOOK} and \hbox{\tt INCOLLECTION} -entry types now take an optional {\tt type} field, -allowing `section~1.2' instead of the default `chapter~1.2'$\!$. -You get this by putting -\begin{verbatim} - chapter = "1.2", - type = "Section" -\end{verbatim} -in your database entry. - -\item -The \hbox{\tt BOOKLET}, \hbox{\tt MASTERSTHESIS}, -and \hbox{\tt TECHREPORT} entry types now format -their \hbox{\tt title} fields as if they were -\hbox{\tt ARTICLE} \hbox{\tt title}s -rather than \hbox{\tt BOOK} \hbox{\tt title}s. - -\item -The \hbox{\tt PROCEEDINGS} and \hbox{\tt INPROCEEDINGS} -entry types now use the \hbox{\tt address} field -to tell where a conference was held, -rather than to give the address -of the publisher or organization. -If you want to include the -publisher's or organization's address, -put it in the \hbox{\tt publisher} -or \hbox{\tt organization} field. - -\item -The \hbox{\tt BOOK}, \hbox{\tt INBOOK}, \hbox{\tt INCOLLECTION}, -and \hbox{\tt PROCEEDINGS} entry types now allow either -\hbox{\tt volume} or \hbox{\tt number} (but not both), -rather than just \hbox{\tt volume}. - -\item -The \hbox{\tt INCOLLECTION} entry type now allows -a \hbox{\tt series} and an \hbox{\tt edition} field. - -\item -The \hbox{\tt INPROCEEDINGS} and \hbox{\tt PROCEEDINGS} -entry types now allow either a \hbox{\tt volume} or \hbox{\tt number}, -and also a \hbox{\tt series} field. - -\item -The \hbox{\tt UNPUBLISHED} entry type now outputs, -in one block, the \hbox{\tt note} field -followed by the date information. - -\item -The \hbox{\tt MANUAL} entry type now prints out -the \hbox{\tt organization} in the first block -if the \hbox{\tt author} field is empty. - -\item -The {\tt MISC} entry type now issues a warning -if all the optional fields are empty -(that is, if the entire entry is empty). - -\end{enumerate} - - -\section{The Entries} -\label{latex-appendix} - -This section is simply a corrected version of -Appendix~B.2 of the \LaTeX\ book~\cite{latex}, -\copyright~1986, by Addison-Wesley. -The basic scheme is the same, only a few details have changed. - - -\subsection{Entry Types} - -When entering a reference in the database, the first thing to decide -is what type of entry it is. No fixed classification scheme can be -complete, but \BibTeX\ provides enough entry types to handle almost -any reference reasonably well. - -References to different types of publications contain different -information; a reference to a journal article might include the volume -and number of the journal, which is usually not meaningful for a book. -Therefore, database entries of different types have different fields. -For each entry type, the fields are divided into three classes: -\begin{description} - -\item[required] -Omitting the field will produce a warning message -and, rarely, a badly formatted bibliography entry. -If the required information is not meaningful, -you are using the wrong entry type. -However, if the required information is meaningful -but, say, already included is some other field, -simply ignore the warning. - -\item[optional] -The field's information will be used if present, -but can be omitted without causing any formatting problems. -You should include the optional field if it will help the reader. - -\item[ignored] -The field is ignored. -\BibTeX\ ignores any field that is not required or optional, so you can include -any fields you want in a \hbox{\tt bib} file entry. It's a good idea -to put all relevant information about -a reference in its \hbox{\tt bib} file entry---even information that -may never appear in the bibliography. For example, if you want to -keep an abstract of a paper in a computer file, put it in an \hbox{\tt -abstract} field in the paper's \hbox{\tt bib} file entry. The -\hbox{\tt bib} file is likely to be as good a place as any for the -abstract, and it is possible to design a bibliography style for -printing selected abstracts. -Note: Misspelling a field name will -result in its being ignored, -so watch out for typos -(especially for optional fields, -since \BibTeX\ won't warn you when those are missing). - -\end{description} - -The following are the standard entry types, along with their required -and optional fields, that are used by the standard bibliography styles. -The fields within each class (required or optional) -are listed in order of occurrence in the output, -except that a few entry types may perturb the order slightly, -depending on what fields are missing. -These entry types are similar to those adapted by Brian Reid -from the classification scheme of van~Leunen~\cite{van-leunen} -for use in the {\em Scribe\/} system. -The meanings of the individual fields are explained in the next section. -Some nonstandard bibliography styles may ignore some optional fields -in creating the reference. -Remember that, when used in the \hbox{\tt bib} -file, the entry-type name is preceded by an \hbox{\tt @} character. - -\begin{description} -\sloppy - -\item[article\hfill] An article from a journal or magazine. -Required fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt journal}, -\hbox{\tt year}. -Optional fields: \hbox{\tt volume}, \hbox{\tt number}, -\hbox{\tt pages}, \hbox{\tt month}, \hbox{\tt note}. - -\item[book\hfill] A book with an explicit publisher. -Required fields: \hbox{\tt author} or \hbox{\tt editor}, -\hbox{\tt title}, \hbox{\tt publisher}, \hbox{\tt year}. -Optional fields: \hbox{\tt volume} or \hbox{\tt number}, \hbox{\tt series}, -\hbox{\tt address}, \hbox{\tt edition}, \hbox{\tt month}, -\hbox{\tt note}. - -\item[booklet\hfill] A work that is printed and bound, -but without a named publisher or sponsoring institution. -Required field: \hbox{\tt title}. -Optional fields: \hbox{\tt author}, \hbox{\tt howpublished}, -\hbox{\tt address}, \hbox{\tt month}, \hbox{\tt year}, \hbox{\tt note}. - -\item[conference\hfill] The same as {\tt INPROCEEDINGS}, -included for {\em Scribe\/} compatibility. - -\item[inbook\hfill] A part of a book, -which may be a chapter (or section or whatever) and/or a range of pages. -Required fields: \hbox{\tt author} or \hbox{\tt editor}, \hbox{\tt title}, -\hbox{\tt chapter} and/or \hbox{\tt pages}, \hbox{\tt publisher}, -\hbox{\tt year}. -Optional fields: \hbox{\tt volume} or \hbox{\tt number}, \hbox{\tt series}, -\hbox{\tt type}, \hbox{\tt address}, -\hbox{\tt edition}, \hbox{\tt month}, \hbox{\tt note}. - -\item[incollection\hfill] A part of a book having its own title. -Required fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt booktitle}, -\hbox{\tt publisher}, \hbox{\tt year}. -Optional fields: \hbox{\tt editor}, \hbox{\tt volume} or \hbox{\tt number}, -\hbox{\tt series}, \hbox{\tt type}, \hbox{\tt chapter}, \hbox{\tt pages}, -\hbox{\tt address}, \hbox{\tt edition}, \hbox{\tt month}, \hbox{\tt note}. - -\item[inproceedings\hfill] An article in a conference proceedings. -Required fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt booktitle}, -\hbox{\tt year}. -Optional fields: \hbox{\tt editor}, \hbox{\tt volume} or \hbox{\tt number}, -\hbox{\tt series}, \hbox{\tt pages}, \hbox{\tt address}, \hbox{\tt month}, -\hbox{\tt organization}, \hbox{\tt publisher}, \hbox{\tt note}. - -\item[manual\hfill] Technical documentation. Required field: \hbox{\tt title}. -Optional fields: \hbox{\tt author}, \hbox{\tt organization}, -\hbox{\tt address}, \hbox{\tt edition}, \hbox{\tt month}, \hbox{\tt year}, -\hbox{\tt note}. - -\item[mastersthesis\hfill] A Master's thesis. -Required fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt school}, -\hbox{\tt year}. -Optional fields: \hbox{\tt type}, \hbox{\tt address}, \hbox{\tt month}, -\hbox{\tt note}. - -\item[misc\hfill] Use this type when nothing else fits. -Required fields: none. -Optional fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt howpublished}, -\hbox{\tt month}, \hbox{\tt year}, \hbox{\tt note}. - -\item[phdthesis\hfill] A PhD thesis. -Required fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt school}, -\hbox{\tt year}. -Optional fields: \hbox{\tt type}, \hbox{\tt address}, \hbox{\tt month}, -\hbox{\tt note}. - -\item[proceedings\hfill] The proceedings of a conference. -Required fields: \hbox{\tt title}, \hbox{\tt year}. -Optional fields: \hbox{\tt editor}, \hbox{\tt volume} or \hbox{\tt number}, -\hbox{\tt series}, \hbox{\tt address}, \hbox{\tt month}, -\hbox{\tt organization}, \hbox{\tt publisher}, \hbox{\tt note}. - - -\item[techreport\hfill] A report published by a school or other institution, -usually numbered within a series. -Required fields: \hbox{\tt author}, -\hbox{\tt title}, \hbox{\tt institution}, \hbox{\tt year}. -Optional fields: \hbox{\tt type}, \hbox{\tt number}, \hbox{\tt address}, -\hbox{\tt month}, \hbox{\tt note}. - -\item[unpublished\hfill] A document having an author and title, -but not formally published. -Required fields: \hbox{\tt author}, \hbox{\tt title}, \hbox{\tt note}. -Optional fields: \hbox{\tt month}, \hbox{\tt year}. - -\end{description} - -In addition to the fields listed above, each entry type also has an -optional \hbox{\tt key} field, used in some styles -for alphabetizing, for cross referencing, -or for forming a \hbox{\verb|\bibitem|} label. -You should include a \hbox{\tt key} field for any entry whose -``author'' information is missing; -the ``author'' information is usually the \hbox{\tt author} field, -but for some entry types it can be the \hbox{\tt editor} -or even the \hbox{\tt organization} field -(Section~\ref{odds-and-ends} describes this in more detail). -Do not confuse the \hbox{\tt key} field with the key that appears in the -\hbox{\verb|\cite|} command and at the beginning of the database entry; -this field is named ``key'' only for compatibility with {\it Scribe}. - - -\subsection{Fields} - -Below is a description of all fields -recognized by the standard bibliography styles. -An entry can also contain other fields, which are ignored by those styles. -\begin{description} - -\item[address\hfill] -Usually the address of the \hbox{\tt publisher} or other type -of institution. -For major publishing houses, -van~Leunen recommends omitting the information entirely. -For small publishers, on the other hand, you can help the -reader by giving the complete address. - -\item[annote\hfill] -An annotation. -It is not used by the standard bibliography styles, -but may be used by others that produce an annotated bibliography. - -\item[author\hfill] -The name(s) of the author(s), -in the format described in the \LaTeX\ book. - -\item[booktitle\hfill] -Title of a book, part of which is being cited. -See the \LaTeX\ book for how to type titles. -For book entries, use the \hbox{\tt title} field instead. - -\item[chapter\hfill] -A chapter (or section or whatever) number. - -\item[crossref\hfill] -The database key of the entry being cross referenced. - -\item[edition\hfill] -The edition of a book---for example, ``Second''$\!$. -This should be an ordinal, and -should have the first letter capitalized, as shown here; -the standard styles convert to lower case when necessary. - -\item[editor\hfill] -Name(s) of editor(s), typed as indicated in the \LaTeX\ book. -If there is also an \hbox{\tt author} field, then -the \hbox{\tt editor} field gives the editor of the book or collection -in which the reference appears. - -\item[howpublished\hfill] -How something strange has been published. -The first word should be capitalized. - -\item[institution\hfill] -The sponsoring institution of a technical report. - -\item[journal\hfill] -A journal name. -Abbreviations are provided for many journals; see the {\it Local Guide}. - -\item[key\hfill] -Used for alphabetizing, cross referencing, and creating a label when -the ``author'' information -(described in Section~\ref{odds-and-ends}) is missing. -This field should not be confused with the key that appears in the -\hbox{\verb|\cite|} command and at the beginning of the database entry. - -\item[month\hfill] -The month in which the work was -published or, for an unpublished work, in which it was written. -You should use the standard three-letter abbreviation, -as described in Appendix B.1.3 of the \LaTeX\ book. - -\item[note\hfill] -Any additional information that can help the reader. -The first word should be capitalized. - -\item[number\hfill] -The number of a journal, magazine, technical report, -or of a work in a series. -An issue of a journal or magazine is usually -identified by its volume and number; -the organization that issues a -technical report usually gives it a number; -and sometimes books are given numbers in a named series. - -\item[organization\hfill] -The organization that sponsors a conference or that publishes a \hbox{manual}. - -\item[pages\hfill] -One or more page numbers or range of numbers, -such as \hbox{\tt 42--111} or \hbox{\tt 7,41,73--97} or \hbox{\tt 43+} -(the `{\tt +}' in this last example indicates pages following -that don't form a simple range). -To make it easier to maintain {\em Scribe\/}-compatible databases, -the standard styles convert a single dash (as in \hbox{\tt 7-33}) -to the double dash used in \TeX\ to denote number ranges -(as in \hbox{\tt 7--33}). - -\item[publisher\hfill] -The publisher's name. - -\item[school\hfill] -The name of the school where a thesis was written. - -\item[series\hfill] -The name of a series or set of books. -When citing an entire book, the the \hbox{\tt title} field -gives its title and an optional \hbox{\tt series} field gives the -name of a series or multi-volume set -in which the book is published. - -\item[title\hfill] -The work's title, typed as explained in the \LaTeX\ book. - -\item[type\hfill] -The type of a technical report---for example, -``Research Note''$\!$. - -\item[volume\hfill] -The volume of a journal or multivolume book. - -\item[year\hfill] -The year of publication or, for -an unpublished work, the year it was written. -Generally it should consist of four numerals, such as {\tt 1984}, -although the standard styles can handle any {\tt year} whose -last four nonpunctuation characters are numerals, -such as `\hbox{(about 1984)}'$\!$. - -\end{description} - - -\section{Helpful Hints} -\label{odds-and-ends} - -This section gives some random tips -that aren't documented elsewhere, -at least not in this detail. -They are, roughly, in order -of least esoteric to most. -First, however, a brief spiel. - -I understand that there's often little choice in choosing -a bibliography style---journal~$X$ says you must use style~$Y$ -and that's that. -If you have a choice, however, I strongly recommend that you -choose something like the {\tt plain} standard style. -Such a style, van~Leunen~\cite{van-leunen} argues convincingly, -encourages better writing than the alternatives---% -more concrete, more vivid. - -{\em The Chicago Manual of Style\/}~\cite{chicago}, -on the other hand, -espouse the author-date system, -in which the citation might appear in the text as `(Jones, 1986)'$\!$. -I argue that this system, -besides cluttering up the -text with information that may or may not be relevant, -encourages the passive voice and vague writing. -Furthermore the strongest arguments for -using the author-date system---like ``it's the most practical''---% -fall flat on their face with the advent -of computer-typesetting technology. -For instance the {\em Chicago Manual\/} contains, -right in the middle of page~401, this anachronism: -``The chief disadvantage of [a style like {\tt plain}] is that additions -or deletions cannot be made after the manuscript is typed without changing -numbers in both text references and list.'' -\LaTeX, obviously, sidesteps the disadvantage. - -Finally, the logical deficiencies of the author-date style -are quite evident once you've written a program to implement it. -For example, in a large bibliography, -using the standard alphabetizing scheme, -the entry for `(Aho et~al., 1983b)' -might be half a page later than the one for `(Aho et~al., 1983a)'$\!$. -Fixing this problem results in even worse ones. -What a mess. -(I have, unfortunately, programmed such a style, -and if you're saddled with an unenlightened publisher -or if you don't buy my propaganda, -it's available from the Rochester style collection.) - -Ok, so the spiel wasn't very brief; -but it made me feel better, -and now my blood pressure is back to normal. -Here are the tips for using \BibTeX\ -with the standard styles -(although many of them hold for nonstandard styles, too). -\begin{enumerate} - -\item -With \BibTeX's style-designing language -you can program general database manipulations, -in addition to bibliography styles. -For example it's a fairly easy task for someone familiar with the language -to produce a database-key/author index of all the entries in a database. -Consult the {\em Local Guide\/} to see -what tools are available on your system. - -\item -The standard style's thirteen entry types -do reasonably well at formatting most entries, -but no scheme with just thirteen formats -can do everything perfectly. -Thus, you should feel free to be creative -in how you use these entry types -(but if you have to be too creative, -there's a good chance you're using the wrong entry type). - -\item -Don't take the field names too seriously. -Sometimes, for instance, you might have to include -the publisher's address along with the publisher's name -in the \hbox{\tt publisher} field, -rather than putting it in the \hbox{\tt address} field. -Or sometimes, difficult entries work best when you -make judicious use of the {\tt note} field. - -\item -Don't take the warning messages too seriously. -Sometimes, for instance, the year appears in the title, -as in {\em The 1966 World Gnus Almanac}. -In this case it's best to omit the {\tt year} field -and to ignore \BibTeX's warning message. - -\item -If you have too many names to list in an -\hbox{\tt author} or \hbox{\tt editor} field, -you can end the list with ``and others''; -the standard styles appropriately append an ``et~al.'' - -\item -In general, if you want to keep \BibTeX\ from changing -something to lower case, you enclose it in braces. -You might not get the effect you want, however, -if the very first character after the left brace is a backslash. -The ``special characters'' item later in this section explains. - -\item -For {\em Scribe\/} compatibility, the database files -allow an \hbox{\tt @COMMENT} command; it's not really -needed because \BibTeX\ allows in the database files -any comment that's not within an entry. -If you want to comment out an entry, -simply remove the `{\tt @}' character preceding the entry type. - -\item -The standard styles have journal abbreviations that are -computer-science oriented; -these are in the style files primarily for the example. -If you have a different set of journal abbreviations, -it's sensible to put them in \hbox{\tt @STRING} commands -in their own database file and to list this database file -as an argument to \LaTeX's \hbox{\verb|\bibliography|} command -(but you should list this argument before the ones that -specify real database entries). - -\item -It's best to use the three-letter abbreviations for the month, -rather than spelling out the month yourself. -This lets the bibliography style be consistent. -And if you want to include information for the day of the month, -the {\tt month} field is usually the best place. -For example -\begin{verbatim} - month = jul # "~4," -\end{verbatim} -will probably produce just what you want. - -\item -If you're using the \hbox{\tt unsrt} style -(references are listed in order of citation) -along with the \hbox{\verb|\nocite{*}|} feature -(all entries in the database are included), -the placement of the \hbox{\verb|\nocite{*}|} command -within your document file will determine the reference order. -According to the rule given in Section~\ref{features}: -If the command is placed at the beginning of the document, -the entries will be listed in exactly the order -they occur in the database; -if it's placed at the end, -the entries that you explicitly -\hbox{\verb|\cite|} or \hbox{\verb|\nocite|} -will occur in citation order, -and the remaining database entries will be in database order. - -\item -For theses, van Leunen recommends not giving -the school's department after the name of the degree, -since schools, not departments, issue degrees. -If you really think that giving the department information -will help the reader find the thesis, -put that information in the \hbox{\tt address} field. - -\item -The \hbox{\tt MASTERSTHESIS} and \hbox{\tt PHDTHESIS} entry types -are so named for {\em Scribe\/} compatibility; -\hbox{\tt MINORTHESIS} and \hbox{\tt MAJORTHESIS} -probably would have been better names. -Keep this in mind when trying to classify -a non-U.S.\ thesis. - -\item -Here's yet another suggestion for what to do when an author's -name appears slightly differently in two publications. -Suppose, for example, two journals articles use these fields. -\begin{verbatim} - author = "Donald E. Knuth" - . . . - author = "D. E. Knuth" -\end{verbatim} -There are two possibilities. -You could (1)~simply leave them as is, -or (2)~assuming you know for sure that -these authors are one and the same person, -you could list both in the form that the author prefers -(say, `Donald~E.\ Knuth'). -In the first case, the entries might be alphabetized incorrectly, -and in the second, the slightly altered name might -foul up somebody's electronic library search. -But there's a third possibility, which is the one I prefer. -You could convert the second journal's field to -\begin{verbatim} - author = "D[onald] E. Knuth" -\end{verbatim} -This avoids the pitfalls of the previous two solutions, -since \BibTeX\ alphabetizes this as if the brackets weren't there, -and since the brackets clue the reader in that a full first name -was missing from the original. -Of course it introduces another pitfall---`D[onald]~E.\ Knuth' looks ugly---% -but in this case I think the increase in accuracy outweighs -the loss in aesthetics. - -\item -\LaTeX's comment character `{\tt\%}' is not a comment character -in the database files. - -\item -Here's a more complete description of -the ``author'' information referred to in previous sections. -For most entry types the ``author'' information -is simply the \hbox{\tt author} field. -However: -For the \hbox{\tt BOOK} and \hbox{\tt INBOOK} entry types -it's the \hbox{\tt author} field, but if there's no author -then it's the \hbox{\tt editor} field; -for the \hbox{\tt MANUAL} entry type -it's the \hbox{\tt author} field, but if there's no author -then it's the \hbox{\tt organization} field; -and for the \hbox{\tt PROCEEDINGS} entry type -it's the \hbox{\tt editor} field, but if there's no editor -then it's the \hbox{\tt organization} field. - -\item -When creating a label, -the \hbox{\tt alpha} style uses the ``author'' information described above, -but with a slight change---% -for the \hbox{\tt MANUAL} and \hbox{\tt PROCEEDINGS} entry types, -the {\tt key} field takes precedence over the \hbox{\tt organization} field. -Here's a situation where this is useful. -\begin{verbatim} - organization = "The Association for Computing Machinery", - key = "ACM" -\end{verbatim} -Without the {\tt key} field, the \hbox{\tt alpha} style -would make a label from the first three letters of information -in the \hbox{\tt organization} field; -\hbox{\tt alpha} knows to strip off the `\hbox{\tt The }'$\!$, -but it would still form a label like `\hbox{[Ass86]}'$\!$, -which, however intriguing, is uninformative. -Including the {\tt key} field, as above, -would yield the better label `\hbox{[ACM86]}'$\!$. - -You won't always need the {\tt key} field to override the -\hbox{\tt organization}, though: -With -\begin{verbatim} - organization = "Unilogic, Ltd.", -\end{verbatim} -for instance, the \hbox{\tt alpha} style would -form the perfectly reasonable label `\hbox{[Uni86]}'$\!$. - -\item -Section~\ref{features} discusses accented characters. -To \BibTeX, an accented character is really a special case -of a ``special character''$\!$, -which consists of everything from a left brace at the top-most level, -immediately followed by a backslash, -up through the matching right brace. -For example in the field -\begin{verbatim} - author = "\AA{ke} {Jos{\'{e}} {\'{E}douard} G{\"o}del" -\end{verbatim} -there are just two special characters, -`\hbox{\verb|{\'{E}douard}|}' and `\hbox{\verb|{\"o}|}' -(the same would be true if the pair of double quotes -delimiting the field were braces instead). -In general, \BibTeX\ will not do any processing -of a \TeX\ or \LaTeX\ control sequence inside a special character, -but it {\em will\/} process other characters. -Thus a style that converts all titles to lower case -would convert -\begin{verbatim} - The {\TeX BOOK\NOOP} Experience -\end{verbatim} -to -\begin{verbatim} - The {\TeX book\NOOP} experience -\end{verbatim} -(the `{\tt The}' is still capitalized -because it's the first word of the title). - -This special-character scheme is useful for handling accented characters, -for getting \BibTeX's alphabetizing to do what you want, -and, since \BibTeX\ counts an entire special character as just one letter, -for stuffing extra characters inside labels. -The file \hbox{\tt XAMPL.BIB} distributed with \BibTeX\ -gives examples of all three uses. - -\item -This final item of the section describes \BibTeX's names -(which appear in the \hbox{\tt author} or \hbox{\tt editor} field) -in slightly more detail than what -appears in Appendix~B of the \LaTeX\ book. -In what follows, a ``name'' corresponds to a person. -(Recall that you separate multiple names in a single field -with the word ``and''$\!$, surrounded by spaces, -and not enclosed in braces. -This item concerns itself with the structure of a single name.) - -Each name consists of four parts: First, von, Last, and~Jr; -each part consists of a (possibly empty) list of name-tokens. -The Last part will be nonempty if any part is, -so if there's just one token, it's always a Last token. - -Recall that Per Brinch~Hansen's name should be typed -\begin{verbatim} - "Brinch Hansen, Per" -\end{verbatim} -The First part of his name has the single token ``Per''; -the Last part has two tokens, ``Brinch'' and ``Hansen''; -and the von and Jr parts are empty. -If you had typed -\begin{verbatim} - "Per Brinch Hansen" -\end{verbatim} -instead, \BibTeX\ would (erroneously) think ``Brinch'' were a First-part token, -just as ``Paul'' is a First-part token in ``John~Paul Jones''$\!$, -so this erroneous form would have two First tokens and one Last token. - -Here's another example: -\begin{verbatim} - "Charles Louis Xavier Joseph de la Vall{\'e}e Poussin" -\end{verbatim} -This name has four tokens in the First part, two in the von, and -two in the Last. -Here \BibTeX\ knows where one part ends and the other begins because -the tokens in the von part begin with lower-case letters. - -In general, it's a von token if the first letter at brace-level~0 -is in lower case. -Since technically everything -in a ``special character'' is at brace-level~0, -you can trick \BibTeX\ into thinking that -a token is or is not a von token by prepending a dummy -special character whose first letter past the \TeX\ control sequence -is in the desired case, upper or lower. - -To summarize, \BibTeX\ allows three possible forms for the name: -\begin{verbatim} - "First von Last" - "von Last, First" - "von Last, Jr, First" -\end{verbatim} -You may almost always use the first form; -you shouldn't if either there's a Jr part, -or the Last part has multiple tokens but there's no von part. - -\end{enumerate} - -\bibliography{btxdoc} -\bibliographystyle{plain} -\end{document} diff --git a/Build/extra/bibtex/btxhak.pdf b/Build/extra/bibtex/btxhak.pdf Binary files differdeleted file mode 100644 index 1b825c3cdcf..00000000000 --- a/Build/extra/bibtex/btxhak.pdf +++ /dev/null diff --git a/Build/extra/bibtex/btxhak.tex b/Build/extra/bibtex/btxhak.tex deleted file mode 100644 index e91c8a81ab4..00000000000 --- a/Build/extra/bibtex/btxhak.tex +++ /dev/null @@ -1,626 +0,0 @@ -% Copyright (C) 1988, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted if it -% is unmodified. Modifications (and their redistribution) are also -% permitted, as long as the resulting file is renamed. - -\def\BibTeX{{\rm B\kern-.05em{\sc i\kern-.025em b}\kern-.08em - T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}} - -\title{Designing B\kern-.05em{\large I}\kern-.025em{\large B}\kern-.08em\TeX\ - Styles} -\author{Oren Patashnik} -\date{February 8, 1988} - -\documentstyle{article} -\begin{document} - -\maketitle - -\setcounter{section}{4} -\section{Bibliography-style hacking} -\label{style} - -This document starts (and ends) with Section~\ref{style}, -because in reality it is the final section of ``\BibTeX ing''~\cite{btxdoc}, -the general documentation for \BibTeX. -But that document was meant for all \BibTeX\ users, -while this one is just for style designers, -so the two are physically separate. -Still, you should be completely familiar with ``\BibTeX ing''$\!$, -and all references in this document -to sections and section numbers -assume that the two documents are one. - -This section, -along with the standard-style documentation file \hbox{\tt btxbst.doc}, -should explain how to modify -existing style files and to produce new ones. -If you're a serious style hacker you should be familiar -with van~Leunen~\cite{van-leunen} for points of style, -with Lamport~\cite{latex} and Knuth~\cite{texbook} for formatting matters, -and perhaps with {\em Scribe\/}~\cite{scribe} for compatibility details. -And while you're at it, if you don't read the great little book by Strunk and -White~\cite{strunk-and-white}, you should at least look at its -entries in the database and the reference list -to see how \BibTeX\ handles multiple names. - -To create a new style, -it's best to start with an existing style that's close to yours, -and then modify that. -This is true even if you're simply updating an old style -for \BibTeX\ version 0.99 -(I've updated four nonstandard styles, -so I say this with some experience). -If you want to insert into a new style -some function you'd written for an old (version 0.98i) style, -keep in mind that the order of the arguments to -the assignment ({\tt :=}) function has been reversed. -When you're finished with your style, -you may want to try running it on the entire \hbox{\tt XAMPL.BIB} database -to make sure it handles all the standard entry types. - -If you find any bugs in the standard styles, -or if there are things you'd like to do -with bibliography-style files but can't, -please complain to Oren Patashnik. - - -\subsection{General description} - -You write bibliography styles in a postfix stack language. It's -not too hard to figure out how by looking at the standard-style documentation, -but this description fills in a few details (it will fill in more -details if there's a demand for it). - -Basically the style file is a program, written in an unnamed language, that -tells \BibTeX\ how to format the entries that will go in the reference list -(henceforth ``the entries'' will be ``the entry list'' -or simply ``the list''$\!$, context permitting). -This programming language has ten commands, described in the next subsection. -These commands manipulate the language's objects: -constants, variables, functions, the stack, and the entry list. -(Warning: The terminology in this documentation, -chosen for ease of explanation, is slightly different from \BibTeX's. -For example, this documentation's ``variables'' and ``functions'' -are both ``functions'' to \BibTeX. -Keep this in mind when interpreting \BibTeX's error messages.) - -There are two types of functions: {\it built-in\/} ones that \BibTeX\ provides -(these are described in Section~\ref{built-in-fns}), and ones you define -using either the \hbox{\tt MACRO} or \hbox{\tt FUNCTION} command. - -Your most time-consuming task, as a style designer, -will be creating or modifying functions -using the \hbox{\tt FUNCTION} command -(actually, becoming familiar with the references listed above will be -more time consuming, but assume for the moment that that's done). - -Let's look at a sample function fragment. -Suppose you have a string variable named \hbox{\tt label} -and an integer variable named \hbox{\tt lab.width}, -and suppose you want to append the character `{\tt a}' to \hbox{\tt label} -and to increment \hbox{\tt lab.width}: -\begin{verbatim} - . . . - label "a" * 'label := % label := label * "a" - lab.width #1 + 'lab.width := % lab.width := lab.width + 1 - . . . -\end{verbatim} -In the first line, -\hbox{\tt label} pushes that variable's value onto the stack. -Next, the {\tt "a"} pushes the string constant `{\tt a}' onto the stack. -Then the built-in function {\tt *} pops the top two strings and -pushes their concatenation. -The \hbox{\tt 'label} pushes that variable's name onto the stack. -And finally, the built-in function {\tt :=} pops -the variable name and the concatenation and performs the assignment. -\BibTeX\ treats the stuff following the {\tt \%} as a comment -in the style file. -The second line is similar except that it uses {\tt \#1}, -with no spaces intervening between the `{\tt \#}' and the `{\tt 1}'$\!$, -to push this integer constant. - -The nonnull spacing here is arbitrary: multiple spaces, tabs, or newlines -are equivalent to a single one (except that you're probably better off -not having blank lines within commands, as explained shortly). - -For string constants, absolutely any printing character -is legal between two consecutive double quotes, but \BibTeX\ here -(and only here) treats upper- and lower-case equivalents as different. -Furthermore, spacing {\em is\/} relevant within a string constant, -and you mustn't split a string constant across lines -(that is, the beginning and ending double quotes must be on the same line). - -Variable and function names may not begin with a numeral and -may not contain any of the ten restricted characters -on page~143 of the \LaTeX\ book, -but may otherwise contain any printing characters. -Also, \BibTeX\ considers upper- and lower-case equivalents to be the same. - -Integers and strings are the only value types for constants and variables -(booleans are implemented simply as 0-or-1 integers). -There are three kinds of variables: -\begin{description} - -\item[global variables\hfill] These are either integer- or string-valued, -declared using an \hbox{\tt INTEGERS} or \hbox{\tt STRINGS} command. - -\item[entry variables\hfill] These are either integer- or string-valued, -declared using the \hbox{\tt ENTRY} command. -Each has a value for each entry on the list -(example: a variable \hbox{\tt label} might store -the label string you'll use for the entry). - -\item[fields\hfill] These are string-valued, read-only variables -that store the information from the database file; -their values are set by the \hbox{\tt READ} command. -As with entry variables, each has a value for each entry. -\end{description} - - -\subsection{Commands} - -There are ten style-file commands: -Five (\hbox{\tt ENTRY}, \hbox{\tt FUNCTION}, \hbox{\tt INTEGERS}, -\hbox{\tt MACRO}, and \hbox{\tt STRINGS}) -declare and define variables and functions; -one (\hbox{\tt READ}) reads in the database information; -and four (\hbox{\tt EXECUTE}, \hbox{\tt ITERATE}, \hbox{\tt REVERSE}, -and \hbox{\tt SORT}) manipulate the entries and produce output. -Although the command names appear here in upper case, -\BibTeX\ ignores case differences. - -Some restrictions: -There must be exactly one \hbox{\tt ENTRY} and one \hbox{\tt READ} command; -the \hbox{\tt ENTRY} command, all \hbox{\tt MACRO} commands, -and certain \hbox{\tt FUNCTION} commands -(see next subsection's description of \hbox{\tt call.type\$}) -must precede the \hbox{\tt READ} command; -and the \hbox{\tt READ} command must precede the four that -manipulate the entries and produce output. - -Also it's best (but not essential) to leave at least one blank line -between commands and to leave no blank lines within a command; -this helps \BibTeX\ recover from any syntax errors you make. - -You must enclose each argument of every command in braces. -Look at the standard-style documentation -for syntactic issues not described in this section. -Here are the ten commands: -\begin{description} - -\item[\hbox{\tt ENTRY}\hfill] -Declares the fields and entry variables. -It has three arguments, each a (possibly empty) list of variable names. -The three lists are of: -fields, integer entry variables, and string entry variables. -There is an additional field that \BibTeX\ automatically -declares, \hbox{\tt crossref}, used for cross referencing. -And there is an additional string entry variable automatically declared, -\hbox{\tt sort.key\$}, used by the \hbox{\tt SORT} command. -Each of these variables has a value for each entry on the list. - -\item[\hbox{\tt EXECUTE}\hfill] -Executes a single function. -It has one argument, the function name. - -\item[\hbox{\tt FUNCTION}\hfill] -Defines a new function. -It has two arguments; the first is the function's name and the -second is its definition. -You must define a function before using it; -recursive functions are thus illegal. - -\item[\hbox{\tt INTEGERS}\hfill] -Declares global integer variables. -It has one argument, a list of variable names. -There are two such automatically-declared variables, -\hbox{\tt entry.max\$} and \hbox{\tt global.max\$}, -used for limiting the lengths of string variables. -You may have any number of these commands, but a variable's declaration -must precede its use. - -\item[\hbox{\tt ITERATE}\hfill] -Executes a single function, once -for each entry in the list, in the list's current order -(initially the list is in citation order, but the \hbox{\tt SORT} -command may change this). -It has one argument, the function name. - -\item[\hbox{\tt MACRO}\hfill] -Defines a string macro. -It has two arguments; the first is the macro's name, which is treated like -any other variable or function name, -and the second is its definition, which must be double-quote-delimited. -You must have one for each three-letter month abbreviation; -in addition, you should have one for common journal names. -The user's database may override any definition you define using this command. -If you want to define a string the user can't touch, -use the \hbox{\tt FUNCTION} command, which has a compatible syntax. - -\item[\hbox{\tt READ}\hfill] -Dredges up from the database file -the field values for each entry in the list. -It has no arguments. -If a database entry doesn't have a value for a field -(and probably no database entry will have a value for every field), -that field variable is marked as missing for the entry. - -\item[\hbox{\tt REVERSE}\hfill] -Exactly the same as the -\hbox{\tt ITERATE} command except that it executes the function -on the entry list in reverse order. - -\item[\hbox{\tt SORT}\hfill] -Sorts the entry list using -the values of the string entry variable \hbox{\tt sort.key\$}. -It has no arguments. - -\item[\hbox{\tt STRINGS}\hfill] -Declares global string variables. -It has one argument, a list of variable names. -You may have any number of these commands, but a variable's declaration -must precede its use. -\end{description} - - -\subsection{The built-in functions} -\label{built-in-fns} - -Before we get to the built-in functions, -a few words about some other built-in objects. -There is one built-in string entry variable, \hbox{\tt sort.key\$}, -which the style program must set if the style is to do sorting. -There is one built-in field, \hbox{\tt crossref}, -used for the cross referencing feature -described in Section~4. -And there are two built-in integer global variables, -\hbox{\tt entry.max\$} and \hbox{\tt global.max\$}, -which are set by default to some internal \BibTeX\ constants; -you should truncate strings to these lengths before -you assign to string variables, -so as to not generate any \BibTeX\ warning messages. - -There are currently 37 built-in functions. -Every built-in function with a letter in its name ends with a `{\tt \$}'$\!$. -In what follows, ``first''$\!$, ``second''$\!$, -and so on refer to the order popped. -A ``literal'' is an element on the stack, and it will be either -an integer value, a string value, a variable or function name, -or a special value denoting a missing field. -If any popped literal has an incorrect type, \BibTeX\ complains and pushes -the integer 0 or the null string, depending on whether the function -was supposed to push an integer or string. -\begin{description} - -\item[\hbox{\tt >}\hfill] -Pops the top two (integer) literals, -compares them, and pushes the integer 1 if the second is greater than -the first, 0 otherwise. - -\item[\hbox{\tt <}\hfill] -Analogous. - -\item[\hbox{\tt =}\hfill] -Pops the top two (both integer or both string) literals, -compares them, -and pushes the integer 1 if they're equal, 0 otherwise. - -\item[\hbox{\tt +}\hfill] -Pops the top two (integer) literals and pushes their sum. - -\item[\hbox{\tt -}\hfill] -Pops the top two (integer) literals and pushes their difference -(the first subtracted from the second). - -\item[\hbox{\tt *}\hfill] -Pops the top two (string) literals, -concatenates them (in reverse order, that is, the order in which -pushed), and pushes the resulting string. - -\item[\hbox{\tt :=}\hfill] -Pops the top two literals and assigns -to the first (which must be a global or entry variable) -the value of the second. - -\item[\hbox{\tt add.period\$}\hfill] -Pops the top (string) literal, -adds a `{\tt .}' to it if the last non`{\tt \}}' character -isn't a `{\tt .}'$\!$, `{\tt ?}', or `{\tt !}'$\!$, -and pushes this resulting string. - -\item[\hbox{\tt call.type\$}\hfill] -Executes the function whose name is the entry type of an entry. -For example if an entry is of type {\tt book}, this function executes -the {\tt book} function. -When given as an argument to the \hbox{\tt ITERATE} command, -\hbox{\tt call.type\$} actually produces the output for the entries. -For an entry with an unknown type, -it executes the function \hbox{\tt default.type}. -Thus you should define (before the \hbox{\tt READ} command) one function -for each standard entry type as well as a \hbox{\tt default.type} function. - -\item[\hbox{\tt change.case\$}\hfill] -Pops the top two (string) literals; -it changes the case of the second according to the -specifications of the first, as follows. (Note: The word `letters' in -the next sentence refers only to those at brace-level~0, the top-most -brace level; no other characters are changed, except perhaps for -``special characters''$\!$, described in Section~4.) -If the first literal is the -string~`{\tt t}'$\!$, it converts to lower case all letters except the very -first character in the string, which it leaves alone, and except the -first character following any colon and then nonnull white space, -which it also leaves alone; if it's the string~`{\tt l}'$\!$, it converts all -letters to lower case; and if it's the string~`{\tt u}'$\!$, it converts all -letters to upper case. -It then pushes this resulting string. If either -type is incorrect, it complains and pushes the null string; however, -if both types are correct but the specification string (i.e., the -first string) isn't one of the legal ones, it merely pushes the second -back onto the stack, after complaining. (Another note: It ignores -case differences in the specification string; for example, the strings -{\tt t} and {\tt T} are equivalent for the purposes of this built-in -function.) - -\item[\hbox{\tt chr.to.int\$}\hfill] -Pops the top (string) literal, -makes sure it's a single character, converts it to the -corresponding ASCII integer, and pushes this integer. - -\item[\hbox{\tt cite\$}\hfill] -Pushes the string that was the -\hbox{\verb|\cite|}-command argument for this entry. - -\item[\hbox{\tt duplicate\$}\hfill] -Pops the top literal from the stack and pushes two copies of it. - -\item[\hbox{\tt empty\$}\hfill] -Pops the top literal and pushes -the integer 1 if it's a missing field or a string having no -non-white-space characters, 0 otherwise. - -\item[\hbox{\tt format.name\$}\hfill] -Pops the top three literals -(they are a string, an integer, and a string literal). -The last string literal represents a name list (each name -corresponding to a person), the integer literal specifies which name -to pick from this list, and the first string literal specifies how to -format this name, as explained in the next subsection. -Finally, this function pushes the formatted name. - -\item[\hbox{\tt if\$}\hfill] -Pops the top three literals (they -are two function literals and an integer literal, in that order); -if the integer is greater than 0, it executes the second literal, -else it executes the first. - -\item[\hbox{\tt int.to.chr\$}\hfill] -Pops the top (integer) literal, -interpreted as the ASCII integer value of a single character, -converts it to the corresponding single-character string, and pushes -this string. - -\item[\hbox{\tt int.to.str\$}\hfill] -Pops the top (integer) literal, -converts it to its (unique) string equivalent, and pushes this string. - -\item[\hbox{\tt missing\$}\hfill] -Pops the top literal and -pushes the integer 1 if it's a missing field, 0~otherwise. - -\item[\hbox{\tt newline\$}\hfill] -Writes onto the {\tt bbl} file -what's accumulated in the output buffer. -It writes a blank line if and only if the output buffer is empty. -Since \hbox{\tt write\$} does reasonable line breaking, you should use -this function only when you want a blank line or an explicit line break. - -\item[\hbox{\tt num.names\$}\hfill] -Pops the top (string) literal -and pushes the number of names the string represents---one plus -the number of occurrences of the substring ``and'' (ignoring case differences) -surrounded by nonnull white-space at the top brace level. - -\item[\hbox{\tt pop\$}\hfill] -Pops the top of the stack but -doesn't print it; this gets rid of an unwanted stack literal. - -\item[\hbox{\tt preamble\$}\hfill] -Pushes onto the stack the concatenation of all the -\hbox{\tt @PREAMBLE} strings read from the database files. - -\item[\hbox{\tt purify\$}\hfill] -Pops the top (string) literal, -removes nonalphanumeric characters except for white-space characters and -hyphens and ties (these all get converted to a space), removes -certain alphabetic characters contained in the control sequences -associated with a ``special character''$\!$, and pushes the resulting string. - -\item[\hbox{\tt quote\$}\hfill] -Pushes the string consisting of the double-quote character. - -\item[\hbox{\tt skip\$}\hfill] -Is a no-op. - -\item[\hbox{\tt stack\$}\hfill] -Pops and prints the whole stack; -it's meant to be used for style designers while debugging. - -\item[\hbox{\tt substring\$}\hfill] -Pops the top three literals -(they are the two integers literals {\it len\/} and {\it start}, and a -string literal, in that order). -It pushes the substring of the (at most) {\it len\/} consecutive characters -starting at the {\it start\/}th character (assuming 1-based indexing) -if {\it start\/} is positive, and ending at the $-${\it start\/}th character -from the end if {\it start\/} is negative -(where the first character from the end is the last character). - -\item[\hbox{\tt swap\$}\hfill] -Swaps the top two literals on the stack. - -\item[\hbox{\tt text.length\$}\hfill] -Pops the top (string) literal, -and pushes the number of text characters it contains, where an -accented character (more precisely, a ``special character''$\!$, -defined in Section~4) -counts as a single text character, even if it's missing -its matching right brace, and where braces don't count as -text characters. - -\item[\hbox{\tt text.prefix\$}\hfill] -Pops the top two literals -(the integer literal {\it len\/} and a string literal, in that order). -It pushes the substring of the (at most) {\it len\/} consecutive text -characters starting from the beginning of the string. This function -is similar to \hbox{\tt substring\$}, but this one considers -a ``special character''$\!$, even if -it's missing its matching right brace, to be a single text character -(rather than however many ASCII characters it actually comprises), -and this function doesn't consider braces to be text characters; -furthermore, this function appends any needed matching right braces. - -\item[\hbox{\tt top\$}\hfill] -Pops and prints the top of the stack on the terminal and log file. -It's useful for debugging. - -\item[\hbox{\tt type\$}\hfill] -Pushes the current entry's type (book, article, etc.), -but pushes the null string -if the type is either unknown or undefined. - -\item[\hbox{\tt warning\$}\hfill] -Pops the top (string) literal -and prints it following a warning message. -This also increments a count of the number of warning messages issued. - -\item[\hbox{\tt while\$}\hfill] -Pops the top two (function) literals, -and keeps executing the second as long as the (integer) -literal left on the stack by executing the first is greater than 0. - -\item[\hbox{\tt width\$}\hfill] -Pops the top (string) literal -and pushes the integer that represents its width in some relative units -(currently, hundredths of a point, as specified by the June 1987 version -of the $cmr10$ font; the only white-space character with nonzero width -is the space). -This function takes the literal literally; -that is, it assumes each character in the string is to be printed as -is, regardless of whether the character has a special meaning to \TeX, -except that ``special characters'' (even without their right braces) are -handled specially. -This is meant to be used for comparing widths of label strings. - -\item[\hbox{\tt write\$}\hfill] -Pops the top (string) literal -and writes it on the output buffer (which will result in -stuff being written onto the {\tt bbl} file when the buffer fills up). - -\end{description} - -Note that the built-in functions \hbox{\tt while\$} and \hbox{\tt if\$} -require two function literals on the stack. -You get them there either by immediately preceding the name of a function -by a single quote, or, if you don't feel like defining a new function with -the \hbox{\tt FUNCTION} command, -by simply giving its definition (that is, giving what would be the second -argument to the \hbox{\tt FUNCTION} command, including the surrounding braces). -For example the following function fragment appends the character `{\tt a}' -if the string variable named \hbox{\tt label} is nonnull: -\begin{verbatim} - . . . - label "" = - 'skip$ - { label "a" * 'label := } - if$ - . . . -\end{verbatim} -A function whose name you quote needn't be built in -like \hbox{\tt skip\$} above---it may, for example, -be a field name or a function you've defined earlier. - - -\subsection{Name formatting} - -What's in a name? -Section~4 pretty much describes this. -Each name consists of four parts: First, von, Last, and Jr; -each consists of a list of name-tokens, -and any list but Last's may be empty for a nonnull name. -This subsection describes the format string you must supply to -the built-in function \hbox{\tt format.name\$}. - -Let's look at an example of a very long name. -Suppose a database entry~\cite{prime-number-theorem} has the field -\begin{verbatim} - author = "Charles Louis Xavier Joseph de la Vall{\'e}e Poussin" -\end{verbatim} -and suppose you want this formatted ``last name comma initials''$\!$. -If you use the format string -\begin{verbatim} - "{vv~}{ll}{, jj}{, f}?" -\end{verbatim} -\BibTeX\ will produce -\begin{verbatim} - de~la Vall{\'e}e~Poussin, C.~L. X.~J? -\end{verbatim} -as the formatted string. - -Let's look at this example in detail. -There are four brace-level~1 {\em pieces\/} to this format string, -one for each part of a name. -If the corresponding part of a name isn't present (the Jr part for this name), -everything in that piece is ignored. -Anything at brace-level~0 is output verbatim -(the presumed typo `{\tt ?}' for this name is at brace-level~0), -but you probably won't use this feature much. - -Within each piece a double letter tells \BibTeX\ to use whole tokens, and -a single letter, to abbreviate them (these letters must be at brace-level~1); -everything else within the piece is used verbatim -(well, almost everything---read on). -The tie at the end of the von part (in \hbox{\verb|{vv~}|}) -is a discretionary tie---\BibTeX\ will output a tie at that point -if it thinks there's a need for one; -otherwise it will output a space. -If you really, really, want a tie there, -regardless of what \BibTeX\ thinks, use two of them -(only one will be output); that is, use \hbox{\verb|{vv~~}|}. -A tie is discretionary only if it's the last character of the piece; -anywhere else it's treated as an ordinary character. - -\BibTeX\ puts default strings {\em between\/} tokens of a name part: -For whole tokens it uses either a space or a tie, -depending on which one it thinks is best, -and for abbreviated tokens it uses a period followed by -either a space or a tie. -However it doesn't use this default string after the last token in a list; -hence there's no period following the `J' for our example. -You should have used -\begin{verbatim} - "{vv~}{ll}{, jj}{, f.}" -\end{verbatim} -to get \BibTeX\ to produce the same formatted string but with the question -mark replaced by a period. -Note that the period should go inside the First-name piece, -rather than where the question mark was, in case a name has no First part. - -If you want to override \BibTeX's default between-token strings, you -must explicitly specify a string. -For example suppose you want a label to contain the first letter from each -token in the von and Last parts, with no spaces; -you should use the format string -\begin{verbatim} - "{v{}}{l{}}" -\end{verbatim} -so that \BibTeX\ will produce `{\tt dlVP}' as the formatted string. -You must give a string for each piece whose default you want overridden -(the example here uses the null string for both pieces), and this string -must immediately follow either the single or double letter for the piece. -You may not have any other letters at brace-level~1 in the format string. - -\bibliography{btxdoc} -\bibliographystyle{plain} -\end{document} diff --git a/Build/extra/bibtex/ieeetr.bst b/Build/extra/bibtex/ieeetr.bst deleted file mode 100644 index b8cacb51f6f..00000000000 --- a/Build/extra/bibtex/ieeetr.bst +++ /dev/null @@ -1,976 +0,0 @@ -% Copyright (C) 1985, 1988, 2010 Howard Trickey and Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted as long as -% it is unmodified. Modifications (and redistribution of modified versions) -% are also permitted, but only if the resulting file is renamed. -% -% IEEE Transactions bibliography style (8-Dec-10 version) -% numeric labels, order-of-reference, IEEE abbreviations, -% quotes around article titles, commas separate all fields -% except after book titles and before "notes". Otherwise, -% much like the "plain" family, from which this is adapted. -% -% History -% 9/30/85 (HWT) Original version, by Howard Trickey. -% 1/29/88 (OP&HWT) Updated for BibTeX version 0.99a, Oren Patashnik; -% THIS `ieeetr' VERSION DOES NOT WORK WITH BIBTEX 0.98i. -% 12/ 8/10 (OP&HWT) Clarify license. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.quote after.sentence - after.quoted.block after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.quote := - #3 'after.sentence := - #4 'after.quoted.block := - #5 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.quote = - { " " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { output.state after.quoted.block = - { write$ - newline$ - "\newblock " write$ - } - { add.period$ " " * write$ } - if$ - } - if$ - } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {blank.sep} -{ after.quote 'output.state := -} - -FUNCTION {fin.entry} -{ output.state after.quoted.block = - 'skip$ - 'add.period$ - if$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { output.state after.quote = - { after.quoted.block 'output.state := } - { after.block 'output.state := } - if$ - } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " {\em et~al.}" * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", eds." * } - { ", ed." * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { "``" title "t" change.case$ * ",''" * } - if$ -} - -FUNCTION {format.title.p} -{ title empty$ - { "" } - { "``" title "t" change.case$ * ".''" * } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "vol.~" volume * - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "no.~" } - { "No.~" } - if$ - number * - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { edition "l" change.case$ "~ed." * } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pp.~" pages n.dashify * } - { "p.~" pages * } - if$ - } - if$ -} - -FUNCTION {format.volume} -{ volume empty$ - { "" } - { "vol.~" volume * } - if$ -} - -FUNCTION {format.number} -{ number empty$ - { "" } - { "no.~" number * } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "ch.~" chapter * } - { type "l" change.case$ chapter tie.or.space.connect } - if$ - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { "in " booktitle emphasize * - editor empty$ - 'skip$ - { " (" * format.editors * ")" * } - if$ - } - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - output.state after.block = - { type "t" change.case$ } - { type "l" change.case$ } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Tech. Rep." } - 'type - if$ - number empty$ - { "l" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.addr.pub} -{ publisher empty$ - { "" } - { address empty$ - { "" } - { address ": " * } - if$ - publisher * - } - if$ -} - -FUNCTION {format.paddress} -{ address empty$ - { "" } - { "(" address * ")" * } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "in {\em " journal * "\/}" * } - if$ - } - { "in " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " {\em et~al.}" * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " {\em et~al.}" * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Vol.~" volume * - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "in {\em " booktitle * "\/}" * } - if$ - } - { "in " key * } - if$ - } - { "in " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - blank.sep - crossref missing$ - { journal emphasize "journal" output.check - format.volume output - month empty$ - { format.number output } - 'skip$ - if$ - format.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - format.addr.pub "publisher" output.check - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - title empty$ - { "empty title in " cite$ * warning$ - howpublished new.sentence.checka - } - { howpublished empty$ not - address empty$ month empty$ year empty$ and and - or - { format.title.p output.nonnull } - { format.title output.nonnull } - if$ - blank.sep - } - if$ - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - format.addr.pub "publisher" output.check - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - blank.sep - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - format.addr.pub "publisher" output.check - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - blank.sep - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.paddress output - format.pages output - organization output - publisher output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - blank.sep - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title empty$ - { howpublished new.sentence.checka } - { howpublished empty$ not - month empty$ year empty$ and - or - { format.title.p output.nonnull } - { format.title output.nonnull } - if$ - blank.sep - } - if$ - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - format.btitle "title" output.check - format.bvolume output - format.number.series output - format.paddress output - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - blank.sep - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - format.title.p "title" output.check - blank.sep - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"Jan."} - -MACRO {feb} {"Feb."} - -MACRO {mar} {"Mar."} - -MACRO {apr} {"Apr."} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"Aug."} - -MACRO {sep} {"Sept."} - -MACRO {oct} {"Oct."} - -MACRO {nov} {"Nov."} - -MACRO {dec} {"Dec."} - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications ACM"} - -MACRO {ibmjrd} {"IBM J. Research and Development"} - -MACRO {ibmsj} {"IBM Systems~J."} - -MACRO {ieeese} {"IEEE Trans. Software Engineering"} - -MACRO {ieeetc} {"IEEE Trans. Computers"} - -MACRO {ieeetcad} - {"IEEE Trans. Computer-Aided Design"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"J.~ACM"} - -MACRO {jcss} {"J.~Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM J. Computing"} - -MACRO {tocs} {"ACM Trans. Computer Systems"} - -MACRO {tods} {"ACM Trans. Database Systems"} - -MACRO {tog} {"ACM Trans. Graphics"} - -MACRO {toms} {"ACM Trans. Mathematical Software"} - -MACRO {toois} {"ACM Trans. Office Information Systems"} - -MACRO {toplas} {"ACM Trans. Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -READ - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/plain.bst b/Build/extra/bibtex/plain.bst deleted file mode 100644 index 7adf4bb0a34..00000000000 --- a/Build/extra/bibtex/plain.bst +++ /dev/null @@ -1,1097 +0,0 @@ -% BibTeX standard bibliography style `plain' - % Version 0.99b (8-Dec-10 release) for BibTeX versions 0.99a or later. - % Copyright (C) 1984, 1985, 1988, 2010 Howard Trickey and Oren Patashnik. - % Unlimited copying and redistribution of this file are permitted as long as - % it is unmodified. Modifications (and redistribution of modified versions) - % are also permitted, but only if the resulting file is renamed to something - % besides btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. - % This restriction helps ensure that all standard styles are identical. - % The file btxbst.doc has the documentation for this style. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - key empty$ not and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ - { organization publisher new.sentence.checkb - organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - organization output - } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"January"} - -MACRO {feb} {"February"} - -MACRO {mar} {"March"} - -MACRO {apr} {"April"} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"August"} - -MACRO {sep} {"September"} - -MACRO {oct} {"October"} - -MACRO {nov} {"November"} - -MACRO {dec} {"December"} - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications of the ACM"} - -MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -MACRO {ibmsj} {"IBM Systems Journal"} - -MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -MACRO {ieeetc} {"IEEE Transactions on Computers"} - -MACRO {ieeetcad} - {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"Journal of the ACM"} - -MACRO {jcss} {"Journal of Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM Journal on Computing"} - -MACRO {tocs} {"ACM Transactions on Computer Systems"} - -MACRO {tods} {"ACM Transactions on Database Systems"} - -MACRO {tog} {"ACM Transactions on Graphics"} - -MACRO {toms} {"ACM Transactions on Mathematical Software"} - -MACRO {toois} {"ACM Transactions on Office Information Systems"} - -MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ - s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -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 - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/siam.bst b/Build/extra/bibtex/siam.bst deleted file mode 100644 index ce88b41e416..00000000000 --- a/Build/extra/bibtex/siam.bst +++ /dev/null @@ -1,1041 +0,0 @@ -% Copyright (C) 1986, 1987, 1988, 2010 Howard Trickey and Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted as long as -% it is unmodified. Modifications (and redistribution of modified versions) -% are also permitted, but only if the resulting file is renamed. -% -% SIAM bibliography style (8-Dec-10 version) -% numeric labels, alphabetic order, Mathematical Reviews abbreviations, -% names in \sc, titles in italics, book titles mixed upper-lower and article -% titles lowercase, commas separate all fields except before "notes". -% -% History -% 1/30/86 (HWT) Original version, by Howard Trickey. -% 6/15/87 (HWT) Fix format.editors---Martin Costabel. -% 1/29/88 (OP&HWT) Updated for BibTeX version 0.99a, Oren Patashnik; -% THIS `siam' VERSION DOES NOT WORK WITH BIBTEX 0.98i. -% 12/ 8/10 (OP&HWT) Clarify license. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - 'write$ - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -FUNCTION {scapify} -{ duplicate$ empty$ - { pop$ "" } - { "{\sc " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -STRINGS { last.authors } - -FUNCTION {init.last.authors} -{ "" 'last.authors := -} - -FUNCTION {format.authors} -{ author empty$ - { "" 'last.authors := - "" - } - { author last.authors = - { "\leavevmode\vrule height 2pt depth -1.6pt width 23pt" } - { author format.names scapify } - if$ - author 'last.authors := - } - if$ -} - -FUNCTION {format.organization} -{ organization empty$ - { "" 'last.authors := - "" - } - { organization last.authors = - { "\leavevmode\vrule height 2pt depth -1.6pt width 23pt" } - { organization scapify } - if$ - organization 'last.authors := - } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" 'last.authors := - "" - } - { editor last.authors = - { "\leavevmode\vrule height 2pt depth -1.6pt width 23pt" } - { editor format.names scapify } - if$ - editor num.names$ #1 > - { ", eds." * } - { ", ed." * } - if$ - editor 'last.authors := - } - if$ -} - -FUNCTION {format.ineditors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", eds." * } - { ", ed." * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ emphasize } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "vol.~" volume * - series empty$ - 'skip$ - { " of " * series * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { "no.~" number * - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { edition "l" change.case$ "~ed." * } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pp.~" pages n.dashify * } - { "p.~" pages * } - if$ - } - if$ -} - -FUNCTION {format.vol.year} -{ volume field.or.null - year empty$ - { "empty year in " cite$ * warning$ } - { " (" year * ")" * * } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "ch.~" chapter * } - { type "l" change.case$ chapter tie.or.space.connect } - if$ - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "in " booktitle * } - { "in " booktitle * ", " * format.ineditors * } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - key empty$ not and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "l" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Tech. Rep." } - 'type - if$ - number empty$ - { "l" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "in " journal * } - if$ - } - { "in " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "in " - } - { "vol.~" volume * - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { series * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "in " booktitle * } - if$ - } - { "in " key * } - if$ - } - { "in " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - crossref missing$ - { journal "journal" output.check - format.vol.year output - } - { format.article.crossref output.nonnull } - if$ - format.pages output - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.number.series output - publisher "publisher" output.check - address output - } - { format.book.crossref output.nonnull } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - format.title "title" output.check - howpublished new.block.checka - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.number.series output - publisher "publisher" output.check - address output - } - { format.book.crossref output.nonnull } - if$ - format.edition output - format.date "year" output.check - format.chapter.pages "chapter and pages" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull } - if$ - format.chapter.pages output - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - address empty$ - { organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull } - if$ - format.pages output - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { format.organization output } - { format.authors output.nonnull } - if$ - format.btitle "title" output.check - author empty$ - 'skip$ - { organization output } - if$ - address output - format.edition output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - format.btitle "title" output.check - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { format.organization output } - { format.editors output.nonnull } - if$ - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - 'skip$ - { organization output } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"Jan."} - -MACRO {feb} {"Feb."} - -MACRO {mar} {"Mar."} - -MACRO {apr} {"Apr."} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"Aug."} - -MACRO {sep} {"Sept."} - -MACRO {oct} {"Oct."} - -MACRO {nov} {"Nov."} - -MACRO {dec} {"Dec."} - -MACRO {acmcs} {"ACM Comput. Surveys"} - -MACRO {acta} {"Acta Inf."} - -MACRO {cacm} {"Comm. ACM"} - -MACRO {ibmjrd} {"IBM J. Res. Dev."} - -MACRO {ibmsj} {"IBM Syst.~J."} - -MACRO {ieeese} {"IEEE Trans. Softw. Eng."} - -MACRO {ieeetc} {"IEEE Trans. Comput."} - -MACRO {ieeetcad} - {"IEEE Trans. Comput.-Aided Design Integrated Circuits"} - -MACRO {ipl} {"Inf. Process. Lett."} - -MACRO {jacm} {"J.~Assoc. Comput. Mach."} - -MACRO {jcss} {"J.~Comput. System Sci."} - -MACRO {scp} {"Sci. Comput. Programming"} - -MACRO {sicomp} {"SIAM J. Comput."} - -MACRO {tocs} {"ACM Trans. Comput. Syst."} - -MACRO {tods} {"ACM Trans. Database Syst."} - -MACRO {tog} {"ACM Trans. Gr."} - -MACRO {toms} {"ACM Trans. Math. Softw."} - -MACRO {toois} {"ACM Trans. Office Inf. Syst."} - -MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."} - -MACRO {tcs} {"Theoretical Comput. Sci."} - -READ - -FUNCTION {sortify} -{ purify$ - "l" change.case$ -} - -INTEGERS { len } - -FUNCTION {chop.word} -{ 's := - 'len := - s #1 len substring$ = - { s len #1 + global.max$ substring$ } - 's - if$ -} - -FUNCTION {sort.format.names} -{ 's := - #1 'nameptr := - "" - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { nameptr #1 > - { " " * } - 'skip$ - if$ - s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't := - nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {sort.format.title} -{ 't := - "A " #2 - "An " #3 - "The " #4 t chop.word - chop.word - chop.word - sortify - #1 global.max$ substring$ -} - -FUNCTION {author.sort} -{ author empty$ - { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.editor.sort} -{ author empty$ - { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {author.organization.sort} -{ author empty$ - { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { author sort.format.names } - if$ -} - -FUNCTION {editor.organization.sort} -{ editor empty$ - { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } - if$ - } - { editor sort.format.names } - if$ -} - -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 - * - " " - * - title field.or.null - sort.format.title - * - #1 entry.max$ substring$ - 'sort.key$ := -} - -ITERATE {presort} - -SORT - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -EXECUTE {init.last.authors} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/unsrt.bst b/Build/extra/bibtex/unsrt.bst deleted file mode 100644 index 4be323eea0e..00000000000 --- a/Build/extra/bibtex/unsrt.bst +++ /dev/null @@ -1,951 +0,0 @@ -% BibTeX standard bibliography style `unsrt' - % Version 0.99b (8-Dec-10 release) for BibTeX versions 0.99a or later. - % Copyright (C) 1984, 1985, 1988, 2010 Howard Trickey and Oren Patashnik. - % Unlimited copying and redistribution of this file are permitted as long as - % it is unmodified. Modifications (and redistribution of modified versions) - % are also permitted, but only if the resulting file is renamed to something - % besides btxbst.doc, plain.bst, unsrt.bst, alpha.bst, and abbrv.bst. - % This restriction helps ensure that all standard styles are identical. - % The file btxbst.doc has the documentation for this style. - -ENTRY - { address - author - booktitle - chapter - edition - editor - howpublished - institution - journal - key - month - note - number - organization - pages - publisher - school - series - title - type - volume - year - } - {} - { label } - -INTEGERS { output.state before.all mid.sentence after.sentence after.block } - -FUNCTION {init.state.consts} -{ #0 'before.all := - #1 'mid.sentence := - #2 'after.sentence := - #3 'after.block := -} - -STRINGS { s t } - -FUNCTION {output.nonnull} -{ 's := - output.state mid.sentence = - { ", " * write$ } - { output.state after.block = - { add.period$ write$ - newline$ - "\newblock " write$ - } - { output.state before.all = - 'write$ - { add.period$ " " * write$ } - if$ - } - if$ - mid.sentence 'output.state := - } - if$ - s -} - -FUNCTION {output} -{ duplicate$ empty$ - 'pop$ - 'output.nonnull - if$ -} - -FUNCTION {output.check} -{ 't := - duplicate$ empty$ - { pop$ "empty " t * " in " * cite$ * warning$ } - 'output.nonnull - if$ -} - -FUNCTION {output.bibitem} -{ newline$ - "\bibitem{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} -{ add.period$ - write$ - newline$ -} - -FUNCTION {new.block} -{ output.state before.all = - 'skip$ - { after.block 'output.state := } - if$ -} - -FUNCTION {new.sentence} -{ output.state after.block = - 'skip$ - { output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ - } - if$ -} - -FUNCTION {not} -{ { #0 } - { #1 } - if$ -} - -FUNCTION {and} -{ 'skip$ - { pop$ #0 } - if$ -} - -FUNCTION {or} -{ { pop$ #1 } - 'skip$ - if$ -} - -FUNCTION {new.block.checka} -{ empty$ - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.block.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.block - if$ -} - -FUNCTION {new.sentence.checka} -{ empty$ - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {new.sentence.checkb} -{ empty$ - swap$ empty$ - and - 'skip$ - 'new.sentence - if$ -} - -FUNCTION {field.or.null} -{ duplicate$ empty$ - { pop$ "" } - 'skip$ - if$ -} - -FUNCTION {emphasize} -{ duplicate$ empty$ - { pop$ "" } - { "{\em " swap$ * "}" * } - if$ -} - -INTEGERS { nameptr namesleft numnames } - -FUNCTION {format.names} -{ 's := - #1 'nameptr := - s num.names$ 'numnames := - numnames 'namesleft := - { namesleft #0 > } - { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := - nameptr #1 > - { namesleft #1 > - { ", " * t * } - { numnames #2 > - { "," * } - 'skip$ - if$ - t "others" = - { " et~al." * } - { " and " * t * } - if$ - } - if$ - } - 't - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } - while$ -} - -FUNCTION {format.authors} -{ author empty$ - { "" } - { author format.names } - if$ -} - -FUNCTION {format.editors} -{ editor empty$ - { "" } - { editor format.names - editor num.names$ #1 > - { ", editors" * } - { ", editor" * } - if$ - } - if$ -} - -FUNCTION {format.title} -{ title empty$ - { "" } - { title "t" change.case$ } - if$ -} - -FUNCTION {n.dashify} -{ 't := - "" - { t empty$ not } - { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } - if$ - } - while$ -} - -FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } - if$ - } - { month empty$ - 'year - { month " " * year * } - if$ - } - if$ -} - -FUNCTION {format.btitle} -{ title emphasize -} - -FUNCTION {tie.or.space.connect} -{ duplicate$ text.length$ #3 < - { "~" } - { " " } - if$ - swap$ * * -} - -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -FUNCTION {format.bvolume} -{ volume empty$ - { "" } - { "volume" volume tie.or.space.connect - series empty$ - 'skip$ - { " of " * series emphasize * } - if$ - "volume and number" number either.or.check - } - if$ -} - -FUNCTION {format.number.series} -{ volume empty$ - { number empty$ - { series field.or.null } - { output.state mid.sentence = - { "number" } - { "Number" } - if$ - number tie.or.space.connect - series empty$ - { "there's a number but no series in " cite$ * warning$ } - { " in " * series * } - if$ - } - if$ - } - { "" } - if$ -} - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { output.state mid.sentence = - { edition "l" change.case$ " edition" * } - { edition "t" change.case$ " edition" * } - if$ - } - if$ -} - -INTEGERS { multiresult } - -FUNCTION {multi.page.check} -{ 't := - #0 'multiresult := - { multiresult not - t empty$ not - and - } - { t #1 #1 substring$ - duplicate$ "-" = - swap$ duplicate$ "," = - swap$ "+" = - or or - { #1 'multiresult := } - { t #2 global.max$ substring$ 't := } - if$ - } - while$ - multiresult -} - -FUNCTION {format.pages} -{ pages empty$ - { "" } - { pages multi.page.check - { "pages" pages n.dashify tie.or.space.connect } - { "page" pages tie.or.space.connect } - if$ - } - if$ -} - -FUNCTION {format.vol.num.pages} -{ volume field.or.null - number empty$ - 'skip$ - { "(" number * ")" * * - volume empty$ - { "there's a number but no volume in " cite$ * warning$ } - 'skip$ - if$ - } - if$ - pages empty$ - 'skip$ - { duplicate$ empty$ - { pop$ format.pages } - { ":" * pages n.dashify * } - if$ - } - if$ -} - -FUNCTION {format.chapter.pages} -{ chapter empty$ - 'format.pages - { type empty$ - { "chapter" } - { type "l" change.case$ } - if$ - chapter tie.or.space.connect - pages empty$ - 'skip$ - { ", " * format.pages * } - if$ - } - if$ -} - -FUNCTION {format.in.ed.booktitle} -{ booktitle empty$ - { "" } - { editor empty$ - { "In " booktitle emphasize * } - { "In " format.editors * ", " * booktitle emphasize * } - if$ - } - if$ -} - -FUNCTION {empty.misc.check} -{ author empty$ title empty$ howpublished empty$ - month empty$ year empty$ note empty$ - and and and and and - { "all relevant fields are empty in " cite$ * warning$ } - 'skip$ - if$ -} - -FUNCTION {format.thesis.type} -{ type empty$ - 'skip$ - { pop$ - type "t" change.case$ - } - if$ -} - -FUNCTION {format.tr.number} -{ type empty$ - { "Technical Report" } - 'type - if$ - number empty$ - { "t" change.case$ } - { number tie.or.space.connect } - if$ -} - -FUNCTION {format.article.crossref} -{ key empty$ - { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "In {\em " journal * "\/}" * } - if$ - } - { "In " key * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.crossref.editor} -{ editor #1 "{vv~}{ll}" format.name$ - editor num.names$ duplicate$ - #2 > - { pop$ " et~al." * } - { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " et~al." * } - { " and " * editor #2 "{vv~}{ll}" format.name$ * } - if$ - } - if$ - } - if$ -} - -FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "In " - } - { "Volume" volume tie.or.space.connect - " of " * - } - if$ - editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "{\em " * series * "\/}" * } - if$ - } - { key * } - if$ - } - { format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {format.incoll.inproc.crossref} -{ editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "In {\em " booktitle * "\/}" * } - if$ - } - { "In " key * } - if$ - } - { "In " format.crossref.editor * } - if$ - " \cite{" * crossref * "}" * -} - -FUNCTION {article} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { journal emphasize "journal" output.check - format.vol.num.pages output - format.date "year" output.check - } - { format.article.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {book} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {booklet} -{ output.bibitem - format.authors output - new.block - format.title "title" output.check - howpublished address new.block.checkb - howpublished output - address output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {inbook} -{ output.bibitem - author empty$ - { format.editors "author and editor" output.check } - { format.authors output.nonnull - crossref missing$ - { "author and editor" editor either.or.check } - 'skip$ - if$ - } - if$ - new.block - format.btitle "title" output.check - crossref missing$ - { format.bvolume output - format.chapter.pages "chapter and pages" output.check - new.block - format.number.series output - new.sentence - publisher "publisher" output.check - address output - } - { format.chapter.pages "chapter and pages" output.check - new.block - format.book.crossref output.nonnull - } - if$ - format.edition output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {incollection} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.chapter.pages output - new.sentence - publisher "publisher" output.check - address output - format.edition output - format.date "year" output.check - } - { format.incoll.inproc.crossref output.nonnull - format.chapter.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {inproceedings} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - crossref missing$ - { format.in.ed.booktitle "booktitle" output.check - format.bvolume output - format.number.series output - format.pages output - address empty$ - { organization publisher new.sentence.checkb - organization output - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - organization output - publisher output - } - if$ - } - { format.incoll.inproc.crossref output.nonnull - format.pages output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {conference} { inproceedings } - -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - 'skip$ - { organization output.nonnull - address output - } - if$ - } - { format.authors output.nonnull } - if$ - new.block - format.btitle "title" output.check - author empty$ - { organization empty$ - { address new.block.checka - address output - } - 'skip$ - if$ - } - { organization address new.block.checkb - organization output - address output - } - if$ - format.edition output - format.date output - new.block - note output - fin.entry -} - -FUNCTION {mastersthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - "Master's thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {misc} -{ output.bibitem - format.authors output - title howpublished new.block.checkb - format.title output - howpublished new.block.checka - howpublished output - format.date output - new.block - note output - fin.entry - empty.misc.check -} - -FUNCTION {phdthesis} -{ output.bibitem - format.authors "author" output.check - new.block - format.btitle "title" output.check - new.block - "PhD thesis" format.thesis.type output.nonnull - school "school" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {proceedings} -{ output.bibitem - editor empty$ - { organization output } - { format.editors output.nonnull } - if$ - new.block - format.btitle "title" output.check - format.bvolume output - format.number.series output - address empty$ - { editor empty$ - { publisher new.sentence.checka } - { organization publisher new.sentence.checkb - organization output - } - if$ - publisher output - format.date "year" output.check - } - { address output.nonnull - format.date "year" output.check - new.sentence - editor empty$ - 'skip$ - { organization output } - if$ - publisher output - } - if$ - new.block - note output - fin.entry -} - -FUNCTION {techreport} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - format.tr.number output.nonnull - institution "institution" output.check - address output - format.date "year" output.check - new.block - note output - fin.entry -} - -FUNCTION {unpublished} -{ output.bibitem - format.authors "author" output.check - new.block - format.title "title" output.check - new.block - note "note" output.check - format.date output - fin.entry -} - -FUNCTION {default.type} { misc } - -MACRO {jan} {"January"} - -MACRO {feb} {"February"} - -MACRO {mar} {"March"} - -MACRO {apr} {"April"} - -MACRO {may} {"May"} - -MACRO {jun} {"June"} - -MACRO {jul} {"July"} - -MACRO {aug} {"August"} - -MACRO {sep} {"September"} - -MACRO {oct} {"October"} - -MACRO {nov} {"November"} - -MACRO {dec} {"December"} - -MACRO {acmcs} {"ACM Computing Surveys"} - -MACRO {acta} {"Acta Informatica"} - -MACRO {cacm} {"Communications of the ACM"} - -MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -MACRO {ibmsj} {"IBM Systems Journal"} - -MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -MACRO {ieeetc} {"IEEE Transactions on Computers"} - -MACRO {ieeetcad} - {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -MACRO {ipl} {"Information Processing Letters"} - -MACRO {jacm} {"Journal of the ACM"} - -MACRO {jcss} {"Journal of Computer and System Sciences"} - -MACRO {scp} {"Science of Computer Programming"} - -MACRO {sicomp} {"SIAM Journal on Computing"} - -MACRO {tocs} {"ACM Transactions on Computer Systems"} - -MACRO {tods} {"ACM Transactions on Database Systems"} - -MACRO {tog} {"ACM Transactions on Graphics"} - -MACRO {toms} {"ACM Transactions on Mathematical Software"} - -MACRO {toois} {"ACM Transactions on Office Information Systems"} - -MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"} - -MACRO {tcs} {"Theoretical Computer Science"} - -READ - -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - -FUNCTION {initialize.longest.label} -{ "" 'longest.label := - #1 'number.label := - #0 'longest.label.width := -} - -FUNCTION {longest.label.pass} -{ number.label int.to.str$ 'label := - number.label #1 + 'number.label := - label width$ longest.label.width > - { label 'longest.label := - label width$ 'longest.label.width := - } - 'skip$ - if$ -} - -EXECUTE {initialize.longest.label} - -ITERATE {longest.label.pass} - -FUNCTION {begin.bib} -{ preamble$ empty$ - 'skip$ - { preamble$ write$ newline$ } - if$ - "\begin{thebibliography}{" longest.label * "}" * write$ newline$ -} - -EXECUTE {begin.bib} - -EXECUTE {init.state.consts} - -ITERATE {call.type$} - -FUNCTION {end.bib} -{ newline$ - "\end{thebibliography}" write$ newline$ -} - -EXECUTE {end.bib} diff --git a/Build/extra/bibtex/xampl.bib b/Build/extra/bibtex/xampl.bib deleted file mode 100644 index 85ee5cb703e..00000000000 --- a/Build/extra/bibtex/xampl.bib +++ /dev/null @@ -1,361 +0,0 @@ -% Copyright (C) 1988, 2010 Oren Patashnik. -% Unlimited copying and redistribution of this file are permitted if it -% is unmodified. Modifications (and their redistribution) are also -% permitted, as long as the resulting file is renamed. - -@preamble{ "\newcommand{\noopsort}[1]{} " - # "\newcommand{\printfirst}[2]{#1} " - # "\newcommand{\singleletter}[1]{#1} " - # "\newcommand{\switchargs}[2]{#2#1} " } - -@ARTICLE{article-minimal, - author = {L[eslie] A. Aamport}, - title = {The Gnats and Gnus Document Preparation System}, - journal = {\mbox{G-Animal's} Journal}, - year = 1986, -} - -@ARTICLE{article-full, - author = {L[eslie] A. Aamport}, - title = {The Gnats and Gnus Document Preparation System}, - journal = {\mbox{G-Animal's} Journal}, - year = 1986, - volume = 41, - number = 7, - pages = "73+", - month = jul, - note = "This is a full ARTICLE entry", -} - -The KEY field is here to override the KEY field in the journal being -cross referenced (so is the NOTE field, in addition to its imparting -information). - -@ARTICLE{article-crossref, - crossref = {WHOLE-JOURNAL}, - key = "", - author = {L[eslie] A. Aamport}, - title = {The Gnats and Gnus Document Preparation System}, - pages = "73+", - note = "This is a cross-referencing ARTICLE entry", -} - -@ARTICLE{whole-journal, - key = "GAJ", - journal = {\mbox{G-Animal's} Journal}, - year = 1986, - volume = 41, - number = 7, - month = jul, - note = {The entire issue is devoted to gnats and gnus - (this entry is a cross-referenced ARTICLE (journal))}, -} - -@INBOOK{inbook-minimal, - author = "Donald E. Knuth", - title = "Fundamental Algorithms", - publisher = "Addison-Wesley", - year = "{\noopsort{1973b}}1973", - chapter = "1.2", -} - -@INBOOK{inbook-full, - author = "Donald E. Knuth", - title = "Fundamental Algorithms", - volume = 1, - series = "The Art of Computer Programming", - publisher = "Addison-Wesley", - address = "Reading, Massachusetts", - edition = "Second", - month = "10~" # jan, - year = "{\noopsort{1973b}}1973", - type = "Section", - chapter = "1.2", - pages = "10--119", - note = "This is a full INBOOK entry", -} - -@INBOOK{inbook-crossref, - crossref = "whole-set", - title = "Fundamental Algorithms", - volume = 1, - series = "The Art of Computer Programming", - edition = "Second", - year = "{\noopsort{1973b}}1973", - type = "Section", - chapter = "1.2", - note = "This is a cross-referencing INBOOK entry", -} - -@BOOK{book-minimal, - author = "Donald E. Knuth", - title = "Seminumerical Algorithms", - publisher = "Addison-Wesley", - year = "{\noopsort{1973c}}1981", -} - -@BOOK{book-full, - author = "Donald E. Knuth", - title = "Seminumerical Algorithms", - volume = 2, - series = "The Art of Computer Programming", - publisher = "Addison-Wesley", - address = "Reading, Massachusetts", - edition = "Second", - month = "10~" # jan, - year = "{\noopsort{1973c}}1981", - note = "This is a full BOOK entry", -} - -@BOOK{book-crossref, - crossref = "whole-set", - title = "Seminumerical Algorithms", - volume = 2, - series = "The Art of Computer Programming", - edition = "Second", - year = "{\noopsort{1973c}}1981", - note = "This is a cross-referencing BOOK entry", -} - -@BOOK{whole-set, - author = "Donald E. Knuth", - publisher = "Addison-Wesley", - title = "The Art of Computer Programming", - series = "Four volumes", - year = "{\noopsort{1973a}}{\switchargs{--90}{1968}}", - note = "Seven volumes planned (this is a cross-referenced set of BOOKs)", -} - -@BOOKLET{booklet-minimal, - key = "Kn{\printfirst{v}{1987}}", - title = "The Programming of Computer Art", -} - -@BOOKLET{booklet-full, - author = "Jill C. Knvth", - title = "The Programming of Computer Art", - howpublished = "Vernier Art Center", - address = "Stanford, California", - month = feb, - year = 1988, - note = "This is a full BOOKLET entry", -} - -@INCOLLECTION{incollection-minimal, - author = "Daniel D. Lincoll", - title = "Semigroups of Recurrences", - booktitle = "High Speed Computer and Algorithm Organization", - publisher = "Academic Press", - year = 1977, -} - -@INCOLLECTION{incollection-full, - author = "Daniel D. Lincoll", - title = "Semigroups of Recurrences", - editor = "David J. Lipcoll and D. H. Lawrie and A. H. Sameh", - booktitle = "High Speed Computer and Algorithm Organization", - number = 23, - series = "Fast Computers", - chapter = 3, - type = "Part", - pages = "179--183", - publisher = "Academic Press", - address = "New York", - edition = "Third", - month = sep, - year = 1977, - note = "This is a full INCOLLECTION entry", -} - -@INCOLLECTION{incollection-crossref, - crossref = "whole-collection", - author = "Daniel D. Lincoll", - title = "Semigroups of Recurrences", - pages = "179--183", - note = "This is a cross-referencing INCOLLECTION entry", -} - -@BOOK{whole-collection, - editor = "David J. Lipcoll and D. H. Lawrie and A. H. Sameh", - title = "High Speed Computer and Algorithm Organization", - booktitle = "High Speed Computer and Algorithm Organization", - number = 23, - series = "Fast Computers", - publisher = "Academic Press", - address = "New York", - edition = "Third", - month = sep, - year = 1977, - note = "This is a cross-referenced BOOK (collection) entry", -} - -@MANUAL{manual-minimal, - key = "Manmaker", - title = "The Definitive Computer Manual", -} - -@MANUAL{manual-full, - author = "Larry Manmaker", - title = "The Definitive Computer Manual", - organization = "Chips-R-Us", - address = "Silicon Valley", - edition = "Silver", - month = apr # "-" # may, - year = 1986, - note = "This is a full MANUAL entry", -} - -@MASTERSTHESIS{mastersthesis-minimal, - author = "{\'{E}}douard Masterly", - title = "Mastering Thesis Writing", - school = "Stanford University", - year = 1988, -} - -@MASTERSTHESIS{mastersthesis-full, - author = "{\'{E}}douard Masterly", - title = "Mastering Thesis Writing", - school = "Stanford University", - type = "Master's project", - address = "English Department", - month = jun # "-" # aug, - year = 1988, - note = "This is a full MASTERSTHESIS entry", -} - -@MISC{misc-minimal, - key = "Missilany", - note = "This is a minimal MISC entry", -} - -@MISC{misc-full, - author = "Joe-Bob Missilany", - title = "Handing out random pamphlets in airports", - howpublished = "Handed out at O'Hare", - month = oct, - year = 1984, - note = "This is a full MISC entry", -} - -@STRING{STOC-key = "OX{\singleletter{stoc}}"} - -@STRING{ACM = "The OX Association for Computing Machinery"} - -@STRING{STOC = " Symposium on the Theory of Computing"} - -@INPROCEEDINGS{inproceedings-minimal, - author = "Alfred V. Oaho and Jeffrey D. Ullman and Mihalis Yannakakis", - title = "On Notions of Information Transfer in {VLSI} Circuits", - booktitle = "Proc. Fifteenth Annual ACM" # STOC, - year = 1983, -} - -@INPROCEEDINGS{inproceedings-full, - author = "Alfred V. Oaho and Jeffrey D. Ullman and Mihalis Yannakakis", - title = "On Notions of Information Transfer in {VLSI} Circuits", - editor = "Wizard V. Oz and Mihalis Yannakakis", - booktitle = "Proc. Fifteenth Annual ACM" # STOC, - number = 17, - series = "All ACM Conferences", - pages = "133--139", - month = mar, - year = 1983, - address = "Boston", - organization = ACM, - publisher = "Academic Press", - note = "This is a full INPROCEDINGS entry", -} - -@INPROCEEDINGS{inproceedings-crossref, - crossref = "whole-proceedings", - author = "Alfred V. Oaho and Jeffrey D. Ullman and Mihalis Yannakakis", - title = "On Notions of Information Transfer in {VLSI} Circuits", - organization = "", - pages = "133--139", - note = "This is a cross-referencing INPROCEEDINGS entry", -} - -@PROCEEDINGS{proceedings-minimal, - key = STOC-key, - title = "Proc. Fifteenth Annual" # STOC, - year = 1983, -} - -@PROCEEDINGS{proceedings-full, - editor = "Wizard V. Oz and Mihalis Yannakakis", - title = "Proc. Fifteenth Annual" # STOC, - number = 17, - series = "All ACM Conferences", - month = mar, - year = 1983, - address = "Boston", - organization = ACM, - publisher = "Academic Press", - note = "This is a full PROCEEDINGS entry", -} - -@PROCEEDINGS{whole-proceedings, - key = STOC-key, - organization = ACM, - title = "Proc. Fifteenth Annual" # STOC, - address = "Boston", - year = 1983, - booktitle = "Proc. Fifteenth Annual ACM" # STOC, - note = "This is a cross-referenced PROCEEDINGS", -} - -@PHDTHESIS{phdthesis-minimal, - author = "F. Phidias Phony-Baloney", - title = "Fighting Fire with Fire: Festooning {F}rench Phrases", - school = "Fanstord University", - year = 1988, -} - -@PHDTHESIS{phdthesis-full, - author = "F. Phidias Phony-Baloney", - title = "Fighting Fire with Fire: Festooning {F}rench Phrases", - school = "Fanstord University", - type = "{PhD} Dissertation", - address = "Department of French", - month = jun # "-" # aug, - year = 1988, - note = "This is a full PHDTHESIS entry", -} - -@TECHREPORT{techreport-minimal, - author = "Tom Terrific", - title = "An {$O(n \log n / \! \log\log n)$} Sorting Algorithm", - institution = "Fanstord University", - year = 1988, -} - -@TECHREPORT{techreport-full, - author = "Tom T{\'{e}}rrific", - title = "An {$O(n \log n / \! \log\log n)$} Sorting Algorithm", - institution = "Fanstord University", - type = "Wishful Research Result", - number = "7", - address = "Computer Science Department, Fanstord, California", - month = oct, - year = 1988, - note = "This is a full TECHREPORT entry", -} - -@UNPUBLISHED{unpublished-minimal, - author = "Ulrich {\"{U}}nderwood and Ned {\~N}et and Paul {\={P}}ot", - title = "Lower Bounds for Wishful Research Results", - note = "Talk at Fanstord University (this is a minimal UNPUBLISHED entry)", -} - -@UNPUBLISHED{unpublished-full, - author = "Ulrich {\"{U}}nderwood and Ned {\~N}et and Paul {\={P}}ot", - title = "Lower Bounds for Wishful Research Results", - month = nov # ", " # dec, - year = 1988, - note = "Talk at Fanstord University (this is a full UNPUBLISHED entry)", -} - -@MISC{random-note-crossref, - key = {Volume-2}, - note = "Volume~2 is listed under Knuth \cite{book-full}" -} |