├── .gitattributes ├── .gitignore ├── .travis.yml ├── README.md ├── affils.sty ├── docs └── yahapj.md ├── examples.txt ├── pwterse-ay.bst ├── pwterse.bst ├── scgraphic.sty ├── tests ├── run-all.sh └── yahapj │ ├── .gitignore │ ├── expected.bbl │ ├── samples.bib │ ├── scaffold.tex │ └── test.sh ├── yahapj.bst └── yansf.bst /.gitattributes: -------------------------------------------------------------------------------- 1 | yahapj.bst ident 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Peter Williams 2 | # Licensed under the MIT License 3 | 4 | # We test on macOS since it's the easiest way to install the Tectonic binary 5 | # that we need! Hmmm ... 6 | 7 | matrix: 8 | include: 9 | - os: osx 10 | osx_image: xcode10.2 11 | 12 | # Don't build branches besides master -- note that PR's still get built! This 13 | # prevents PRs being built twice in the standard workflow. 14 | 15 | branches: 16 | only: 17 | - master 18 | 19 | addons: 20 | homebrew: 21 | packages: 22 | - tectonic 23 | 24 | cache: 25 | directories: 26 | - $HOME/Library/Caches/Homebrew 27 | - $HOME/Library/Caches/Tectonic 28 | 29 | before_cache: 30 | - brew cleanup 31 | 32 | script: 33 | - ./tests/run-all.sh 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tex-stuff 2 | ========= 3 | 4 | Peter Williams' helpful LaTeX files. These include: 5 | 6 | - [yahapj.bst](docs/yahapj.md), an ApJ-like BibTeX style that properly shows 7 | Arxiv identifiers and hyperlinks to DOI or ADS pages. 8 | - *affils.sty*, a package for auto-numbering affiliations in long author 9 | lists. Note that AASTeX versions 6.2 and later have comparable 10 | functionality; see 11 | [its documentation](https://journals.aas.org/authors/aastex/aasguide.html) 12 | for information on the new `\affiliation` command. 13 | - *scgraphic.sty*, a package for quickly and configurably making a figure with 14 | a caption to its side. 15 | 16 | Less fascinatingly cool files include: 17 | 18 | - *pwterse-ay.bst*, a terse author-year BibTeX style (useful for proposals). 19 | - *pwterse.bst*, a terse numbered BibTeX style (for proposals where you're 20 | really trying to save as much space as you possibly can). 21 | - *yansf.bst*, a NSF-compatible BibTeX style that inserts hyperlinks and Arxiv 22 | information like [yahapj.bst](docs/yahapj.md). 23 | 24 | If you’re interested in a standalone `deluxetable` style file, use 25 | [the one maintained by the AAS Journals folks](https://github.com/AASJournals/deluxetable.sty). 26 | -------------------------------------------------------------------------------- /affils.sty: -------------------------------------------------------------------------------- 1 | % affils.sty -- automatically number affiliations 2 | % Copyright 2016-2018 Peter Williams 3 | % Licensed under the MIT License. 4 | % 5 | % NOTE: AASTeX versions 6.2 and later provide similar functionality 6 | % automatically; see its documentation 7 | % (https://journals.aas.org/authors/aastex/aasguide.html) for information on 8 | % the new `\affiliation` command. 9 | % 10 | % To use: 11 | % 12 | % 1. Save this file next to your .tex file and add \usepackage{affils} at its top. 13 | % 14 | % 2. Before your author list, write: 15 | % 16 | % \DeclareAffil{nickname}{Full text to appear.} 17 | % 18 | % for each affiliation that might be used. Order doesn't matter. For example, 19 | % 20 | % \DeclareAffil{cfa}{Harvard-Smithsonian Center for Astrophysics, 21 | % 60 Garden Street, Cambridge, Massachusetts 02138, USA} 22 | % \DeclareAffil{nice}{All-Around Nice Fellow} 23 | % 24 | % 3. Instead of the \author command, use a new modified version like so: 25 | % 26 | % \affilauthorlist{ 27 | % P.~K.~G. Williams\affils{cfa,nice}, 28 | % Your Name Here\affils{nice}, 29 | % } 30 | % 31 | % 4. Enjoy! Affiliations will automatically be numbered and be listed in the order 32 | % used in the author list. 33 | 34 | \NeedsTeXFormat{LaTeX2e} 35 | \ProvidesPackage{affils}[2016/03/11 v0.1 affils (PKGW)] 36 | \RequirePackage{kvsetkeys} 37 | 38 | \newcounter{pkgwaffil@nextnum} 39 | \setcounter{pkgwaffil@nextnum}{1} 40 | 41 | \newtoks\pkgwaffil@texts 42 | \pkgwaffil@texts={} 43 | 44 | \newcommand\DeclareAffil[2]{\expandafter\newcommand\csname pkgwaffil@#1@text\endcsname{#2}} 45 | 46 | \newcommand\affils@process@one[1]{% 47 | \expandafter\ifx\csname pkgwaffil@#1@text\endcsname\relax% 48 | \textbf{[unknown affiliation code #1!]}% 49 | \else% 50 | \expandafter\ifx\csname pkgwaffil@#1@num\endcsname\relax% 51 | % No number assigned -- do so and add to the list to emit 52 | \expandafter\xdef\csname pkgwaffil@#1@num\endcsname{\arabic{pkgwaffil@nextnum}}% 53 | \global\pkgwaffil@texts=\expandafter{\the\pkgwaffil@texts 54 | \altaffiltext{\csname pkgwaffil@#1@num\endcsname}{\csname pkgwaffil@#1@text\endcsname}}% 55 | \stepcounter{pkgwaffil@nextnum}% 56 | \fi 57 | % Add affil's number to the current list. 58 | \ifx\pkgwaffil@cur@numbers\relax 59 | \edef\pkgwaffil@cur@numbers{\csname pkgwaffil@#1@num\endcsname}% 60 | \else 61 | \edef\pkgwaffil@cur@numbers{\pkgwaffil@cur@numbers,\csname pkgwaffil@#1@num\endcsname}% 62 | \fi 63 | \fi% 64 | } 65 | 66 | \newcommand\affils[1]{% 67 | \let\pkgwaffil@cur@numbers\relax 68 | \comma@parse{#1}\affils@process@one 69 | \expandafter\altaffilmark\expandafter{\pkgwaffil@cur@numbers}% 70 | } 71 | 72 | % The trickiest part is that \author{} is not evaluated right off the bat, so 73 | % \affils@process@one isn't actually called until the first piece of body text 74 | % is encountered, which is too late for us to run the \altaffiltext commands. 75 | % Therefore, we're gross and expand the author text into \@tempboxa, where we 76 | % can evaluate the macros but not actually generate any text. 77 | % 78 | % We could just overwrite the \author command here, but I'm more comfortable 79 | % explicitly giving it a new name. 80 | 81 | \newcommand\affilauthorlist[1]{% 82 | \setbox\@tempboxa\vbox{#1}% 83 | \author{#1}% 84 | \edef\pkgwaffil@temp{\the\pkgwaffil@texts}% 85 | \pkgwaffil@temp 86 | } 87 | -------------------------------------------------------------------------------- /docs/yahapj.md: -------------------------------------------------------------------------------- 1 | yahapj.bst: yet another hacked ApJ bibtex style 2 | =============================================== 3 | 4 | This Git repository contains `yahapj.bst`, a BibTeX style file for creating 5 | bibliographies in the format used by the Astrophysical Journal. It largely 6 | operates like `apj.bst`, in that your bibliography will closely resemble what 7 | is required for articles in the Astrophysical Journal. However it has a few 8 | nice new features: 9 | 10 | + ArXiV identifiers and links are included for those entries 11 | that don't contain any more formal reference information. 12 | + DOI links are embedded if available. 13 | + Trailing plus signs in page numbers are removed. 14 | + Automatic compatibility with the [jabbrv] journal name abbreviation package. 15 | + Maintenance in Git makes it easy to stay updated. 16 | 17 | [jabbrv]: http://www.compholio.com/latex/jabbrv/ 18 | 19 | 20 | How to Use It 21 | ------------- 22 | 23 | 1. Use BibTeX for your bibliography. Help with this is beyond the scope of 24 | this file. 25 | 2. Download [yahapj.bst] and save it in the directory containing your LaTeX 26 | file. 27 | 3. Make sure your LaTeX file uses the [hyperref] package. For attractive 28 | links, we suggest: 29 | 30 | ``` 31 | \usepackage[breaklinks,colorlinks, 32 | urlcolor=blue,citecolor=blue,linkcolor=blue]{hyperref} 33 | ``` 34 | 4. For your `\bibliographystyle{}` command, put: 35 | 36 | ``` 37 | \bibliographystyle{yahapj} 38 | ``` 39 | 40 | That’s all there is to it! If you're really adventurous, [see 41 | below](#year-only-links) about optionally tweaking link formatting with deep 42 | LaTeX magic. 43 | 44 | [yahapj.bst]: https://raw.githubusercontent.com/pkgw/yahapj/master/yahapj.bst 45 | [hyperref]: http://www.ctan.org/pkg/hyperref 46 | 47 | 48 | Making & Sharing Improvements 49 | ----------------------------- 50 | 51 | The style file is derived from the venerable `apj.bst` and adds some features 52 | which are mostly cribbed from other hacked versions of this file, especially 53 | the `hapj.bst` provided by ArXiv. We hope that by importing a version of this 54 | file into Git, improvements can be shared more easily. 55 | 56 | If you make changes to this file that you'd like to share, just clone the Git 57 | repository and commit away! At least one incarnation of the Git repository is 58 | accessible on GitHub, with all of the social coding features that that 59 | entails, at https://github.com/pkgw/yahapj/. 60 | 61 | If you'd like to make changes to the style file, you may run into the minor 62 | problem that BibTeX style files are implemented in a bizarre nonce language. 63 | The best reference I've been able to find is “[Tame the BeaST][tame],” by 64 | [Nicolas Markey][markey]. 65 | 66 | [tame]: http://www.lsv.ens-cachan.fr/~markey/BibTeX/doc/ttb_en.pdf 67 | [markey]: http://www.lsv.ens-cachan.fr/~markey/ 68 | 69 | 70 | Provenance 71 | ---------- 72 | 73 | The history of recent changes to the style file should be discovered by 74 | consulting the Git history. 75 | 76 | The seed file for the Git repository is based upon revision 1.7 of `apj.bst` 77 | from the [astronat] package provided by the NASA [Astrophysics Data 78 | System][ads]. That file was originally generated from `merlin.mbs`, which was 79 | written by Patrick W. Daly. Subsequent changes were contributed by Jonathan E. 80 | Baker, Tim Robishaw, Craig Wiegert, Andrew R. Marble, Stephan Fegan, and 81 | Alberto Accomazzi. 82 | 83 | The seed file adds in the changes in [hapj.bst] provided by 84 | [arxiv.org][arxiv], which were added by Varendra (Alvin) Das. The version of 85 | the file provided by arxiv.org is based on what is effectively revision 1.5 of 86 | the ADS `apj.bst`. 87 | 88 | It also incorporates new-style arxiv identifiers from Jacques Distler's 89 | [utphys.bst]. 90 | 91 | These changes were collected and some further cleanups were made by Peter K. 92 | G. Williams. 93 | 94 | [ads]: http://adsabs.harvard.edu/ 95 | [arxiv]: http://arxiv.org/ 96 | [astronat]: http://ads.harvard.edu/pubs/bibtex/astronat/ 97 | [hapj.bst]: http://arxiv.org/hypertex/bibstyles/ 98 | [utphys.bst]: http://golem.ph.utexas.edu/~distler/TeXstuff/utphys.bst 99 | 100 | 101 | Year-Only Links 102 | --------------- 103 | 104 | Because this style requires [hyperref], your manuscript will be filled with 105 | active links from your `\cite` command to the references. If you compare with 106 | the actual published ApJ, however, you'll note that in your PDF the entire 107 | reference (e.g., “Jones et al. 2013”) is a link, whereas in ApJ only the year 108 | is. 109 | 110 | If you want to get really hard-core — or if the full-reference links give too 111 | much blue text on each page for your tastes — here is some magic LaTeX code to 112 | hack the `\cite` commands to look like ApJ. This is blindly copied off of 113 | [this StackExchange answer] by ["Audrey"], and I have no freaking idea how it 114 | works. But it works for me. 115 | 116 | % In preamble: 117 | \usepackage{etoolbox} 118 | 119 | \makeatletter 120 | 121 | % Patch case where name and year are separated by aysep 122 | \patchcmd{\NAT@citex} 123 | {\@citea\NAT@hyper@{% 124 | \NAT@nmfmt{\NAT@nm}% 125 | \hyper@natlinkbreak{\NAT@aysep\NAT@spacechar}{\@citeb\@extra@b@citeb}% 126 | \NAT@date}} 127 | {\@citea\NAT@nmfmt{\NAT@nm}% 128 | \NAT@aysep\NAT@spacechar\NAT@hyper@{\NAT@date}}{}{} 129 | 130 | % Patch case where name and year are separated by opening bracket 131 | \patchcmd{\NAT@citex} 132 | {\@citea\NAT@hyper@{% 133 | \NAT@nmfmt{\NAT@nm}% 134 | \hyper@natlinkbreak{\NAT@spacechar\NAT@@open\if*#1*\else#1\NAT@spacechar\fi}% 135 | {\@citeb\@extra@b@citeb}% 136 | \NAT@date}} 137 | {\@citea\NAT@nmfmt{\NAT@nm}% 138 | \NAT@spacechar\NAT@@open\if*#1*\else#1\NAT@spacechar\fi\NAT@hyper@{\NAT@date}} 139 | {}{} 140 | 141 | \makeatother 142 | 143 | I presume that if you include this kind of code in the LaTeX files you 144 | actually send to the journal, they'll freak out at you. But you can put it in 145 | your Arxiv submissions to make them look classy. 146 | 147 | [this StackExchange answer]: http://tex.stackexchange.com/a/27311 148 | ["Audrey"]: http://tex.stackexchange.com/users/4483/audrey 149 | 150 | Alternatively, it appears that [biblatex] has built-in support for this, but 151 | then you wouldn't be using this package! 152 | 153 | [biblatex]: http://www.ctan.org/pkg/biblatex 154 | 155 | 156 | Copyright Status of `yahapj.bst` 157 | -------------------------------- 158 | 159 | The original `merlin.mbs` claimed copyright from 1994-1998 for Patrick W. 160 | Daly. Subsequent files have been copied and modified by numerous parties all 161 | over the Internet. In assembling this repository, I have deemed it fair to 162 | dedicate the style file to the public domain. 163 | 164 | Note that the original file did come with the following notice from within 165 | `merlin.mbs`: 166 | 167 | > This file may be used for non-profit purposes. It may not be distributed in 168 | > exchange for money, other than distribution costs. The author provides it 169 | > “as is” and does not guarantee it in any way. 170 | 171 | It is not clear to me (Peter Williams) if this clause applies to the generated 172 | BibTeX style file, or only the source `merlin.mbs` file. If the notice does 173 | not apply to `yahapj.bst`, or `yahapj.bst` is treated as being in the public 174 | domain, the “non-profit” clause is inoperative, and you may attempt to 175 | distribute it in exchange for money. Have fun with that. 176 | 177 | 178 | Copyright Status of This File 179 | ----------------------------- 180 | 181 | This README file is also dedicated to the public domain. You have unlimited 182 | permission to copy, distribute, and modify it. 183 | 184 | 185 | Contributors 186 | ------------ 187 | 188 | + Alberto Accomazzi (aaccomazzi@cfa.harvard.edu) 189 | + Jonathan E. Baker (jbaker@astro.berkeley.edu) 190 | + Patrick W. Daly (daly@linmpi.mpg.de) 191 | + Varendra (Alvin) Das (alvin@iiap.res.in) 192 | + Jacques Distler (distler@golem.ph.utexas.edu) 193 | + Stephen Fegan (sfegan@llr.in2p3.fr) 194 | + Andrew R. Marble (amarble@as.arizona.edu) 195 | + Tim Robishaw (robishaw@astro.berkeley.edu) 196 | + Tim van Werkhoven (werkhoven@strw.leidenuniv.nl) 197 | + Craig Wiegert (cwiegert@alumni.uchicago.edu) 198 | + Peter K. G. Williams (peter@newton.cx) 199 | -------------------------------------------------------------------------------- /examples.txt: -------------------------------------------------------------------------------- 1 | Journal paper: 2 | 3 | Martín, E. L., Rebolo, R., & Zapatero Osorio, M. R. 1996, ApJ, 469, 706 4 | @article: author year journal volume pages(eid) 5 | 6 | Aguirre, J. E., et al. 2011, ApJS, 192, 4 7 | 8 | Book: 9 | 10 | Donat, W., III, & Boksenberg, A. J. 1993, The Astronomical Almanac 11 | for the Year 1994, Vol. 2 (2nd ed.; Washington, DC: GPO) 12 | @book: author year title volume edition address 13 | publisher [url (see Instr Doc)] 14 | 15 | Proceedings (@inproceedings; 1993ASPC...36..345S; ADS record 16 | does not contain sufficient information): 17 | 18 | Salpeter, E. E., & Wasserman, I. M. 1993, in ASP Conf. Ser. 36, 19 | Planets around Pulsars, ed. J. A. Phillips, S. E. Thorsett, & 20 | S. R. Kulkarni (San Francisco, CA: ASP), 345 21 | @inproceedings: author year booktitle(series?) [volume] editor [edition] 22 | address(location?) publisher(organization?) pages(eid) 23 | 24 | Electronic-only proceedings (@inproceedings): 25 | 26 | Gomez, M. 2000, in Cosmology 2000, ed. M.C. Bento, O. Bertolami, & 27 | L. Teodoro (Lisbon: Inst. Superio Tecnico), 57, 28 | http://alfa.ist.utl.pt/~bento/cosmo2000/proc/proceedings.html 29 | @inproceedings: author year booktitle(series?) [volume] editor [edition] 30 | location(address?) organization(publisher?) pages url 31 | 32 | "Paper or Chapter in an Edited Collection" (@incollection): 33 | 34 | Huchra, J. P. 1986, in Inner Space/Outer Space, ed. E. W. Kolb et al. 35 | (Chicago, IL: Univ. Chicago Press), 65 36 | @incollection: author year booktitle(series?) [volume] editor [edition] 37 | address publisher pages 38 | 39 | Star Catalogs (appears compatible with @book, which is what ADS returns, 40 | with publishing metadata in 'booktitle' field rather than broken down 41 | correctly; 1982bsc..book.....H): 42 | 43 | Hoffleit, D. 1982, The Bright Star Catalogue (New Haven, CT: Yale 44 | Univ. Obs.) 45 | 46 | Electronic Newsletters (ADS returns ATels and GCNs as @article; does 47 | not provide the url, and lists the number as the volume, with pages = 1; 48 | 2004GCN..2544....1B): 49 | 50 | Hermoso, D. 1996, ESA IUE Electron. Newsl. 46, 51 | http://www.vilspa.esa.es/iue/nl/newsl_46.html 52 | Bersier, D., et al. 2004, GCN Circ. 2544, 53 | http://gcn.gsfc.nasa.gov/gcn/gcn3/2544.gcn3 54 | @article: author year journal(series?) [ads:volume] url 55 | 56 | Instrument Documentation (appears compatible with @book): 57 | 58 | Gussenhoven, M. S., Mullen, E. G., & Sagalyn, R. C. 1985, 59 | CRRES/SPACERAD Instrument Description, Document 60 | AFGL-TR-85-0017 (Hanscom, MA: Air Force Geophys. Lab.) 61 | {\it Spitzer} Science Center. 2004, {\it Spitzer} Observers' 62 | Manual (Pasadena, CA: SSC), http://sirtf.caltech.edu/SSC/obs/ 63 | 64 | Preprints (@article; ADS -> journal = "ArXiv e-prints"): 65 | 66 | Smith, A. B. 1999, arXiv:astro-ph/9812345 67 | Smith, A. B. 2007, arXiv:0702.1234 68 | Lockwood, G. W., & Skiff, B. A. 1988, Air Force Geophys. 69 | Lab. preprint (AFGL-TR-88-0221) 70 | Smith, A. B. 1999, AJ, in press (arXiv:astro-ph/9912345)) 71 | @article: author year [note] archive archivePrefix eprint 72 | 73 | Submitted / in press (@article): 74 | 75 | Wolk, S. J., & Walter, F. M. 1999, AJ, submitted 76 | Wolk, S. J., & Walter, F. M. 1999, AJ, in press 77 | Smith, A. B. 1999, AJ, in press (arXiv:astro-ph/9912345)) 78 | @article: author year note [archive archivePrefix eprint] 79 | -------------------------------------------------------------------------------- /pwterse-ay.bst: -------------------------------------------------------------------------------- 1 | % Copyright 2014 Peter Williams 2 | % Licensed under the MIT License. 3 | 4 | % Terse bibliography format that (unlike plain pwterse.bst) allows author-year 5 | % citations. Based on yahapj.bst. 6 | 7 | ENTRY 8 | { address 9 | archive 10 | archivePrefix 11 | author 12 | booktitle 13 | chapter 14 | doi 15 | edition 16 | editor 17 | eprint 18 | howpublished 19 | institution 20 | journal 21 | key 22 | month 23 | note 24 | number 25 | organization 26 | pages 27 | primaryClass 28 | publisher 29 | school 30 | series 31 | title 32 | type 33 | url 34 | volume 35 | year 36 | } 37 | {} 38 | { label extra.label sort.label short.list } 39 | 40 | INTEGERS { output.state before.all mid.sentence after.sentence after.block work.strlen } 41 | 42 | FUNCTION {init.state.consts} 43 | { #0 'before.all := 44 | #1 'mid.sentence := 45 | #2 'after.sentence := 46 | #3 'after.block := 47 | } 48 | 49 | STRINGS { s t } 50 | 51 | FUNCTION {output.nonnull.comma} 52 | % input: stack -1: string (assumed nonempty) 53 | % input: stack -2: string 54 | % output: stack -1: same as on input 55 | % write -2, possibly following it with "," or ".". 56 | % state is mid.sentence when done. 57 | { 's := 58 | output.state mid.sentence = 59 | { ", " * write$ } 60 | { output.state after.sentence = 61 | { add.period$ write$ 62 | newline$ 63 | } 64 | 'write$ % <- before.all case 65 | if$ 66 | mid.sentence 'output.state := 67 | } 68 | if$ 69 | s 70 | } 71 | 72 | FUNCTION {output.nonnull.nocomma} 73 | % as above, except no comma if mid.sentence. 74 | { 's := 75 | output.state mid.sentence = 76 | { " " * write$ } 77 | { output.state after.sentence = 78 | { add.period$ write$ 79 | newline$ 80 | } 81 | 'write$ % <- before.all case 82 | if$ 83 | mid.sentence 'output.state := 84 | } 85 | if$ 86 | s 87 | } 88 | 89 | FUNCTION {output.skipempty.comma} 90 | % input: stack -1: string 91 | % input: stack -2: string 92 | % output: stack -1: same as on input 93 | % Do nothing if -1 is empty. Otherwise, write -2, possibly following it with "," or ".". 94 | % If -1 is not empty, state is mid.sentence when done. 95 | { duplicate$ empty$ 96 | 'pop$ 97 | 'output.nonnull.comma 98 | if$ 99 | } 100 | 101 | FUNCTION {output.skipempty.nocomma} 102 | % as above, except no comma if mid.sentence 103 | { duplicate$ empty$ 104 | 'pop$ 105 | 'output.nonnull.nocomma 106 | if$ 107 | } 108 | 109 | FUNCTION {output.check.comma} 110 | % input: stack -1: description of item 111 | % input: stack -2: string (shouldn't be empty; warns if yes) 112 | % input: stack -3: string 113 | % output: stack -1: = input -3 114 | % like output, but warns if empty. 115 | { 't := 116 | duplicate$ empty$ 117 | { pop$ "empty " t * " in " * cite$ * warning$ } 118 | 'output.nonnull.comma 119 | if$ 120 | } 121 | 122 | FUNCTION {output.check.nocomma} 123 | % as above, except no comma if mid.sentence 124 | { 't := 125 | duplicate$ empty$ 126 | { pop$ "empty " t * " in " * cite$ * warning$ } 127 | 'output.nonnull.nocomma 128 | if$ 129 | } 130 | 131 | 132 | FUNCTION {new.sentence} 133 | % stack-agnostic 134 | % set output state to after.sentence, unless it is before.all 135 | { output.state before.all = 136 | 'skip$ 137 | { after.sentence 'output.state := } 138 | if$ 139 | } 140 | 141 | FUNCTION {begin.entry} 142 | % input: nothing on stack 143 | % output: stack -1: "" 144 | % sets output state to before.all. 145 | { newline$ 146 | "\bibitem{" write$ 147 | cite$ write$ 148 | "}" write$ 149 | newline$ 150 | "" 151 | before.all 'output.state := 152 | } 153 | 154 | FUNCTION {finish.entry} 155 | % input: stack -1: string 156 | % output: empty stack 157 | { add.period$ 158 | write$ 159 | newline$ 160 | } 161 | 162 | 163 | 164 | FUNCTION {add.blank} 165 | { " " * before.all 'output.state := 166 | } 167 | 168 | FUNCTION {not} 169 | { { #0 } 170 | { #1 } 171 | if$ 172 | } 173 | 174 | FUNCTION {and} 175 | { 'skip$ 176 | { pop$ #0 } 177 | if$ 178 | } 179 | 180 | FUNCTION {or} 181 | { { pop$ #1 } 182 | 'skip$ 183 | if$ 184 | } 185 | 186 | FUNCTION {field.or.null} 187 | { duplicate$ empty$ 188 | { pop$ "" } 189 | 'skip$ 190 | if$ 191 | } 192 | 193 | FUNCTION {capitalize} 194 | { "u" change.case$ "t" change.case$ } 195 | 196 | FUNCTION {space.word} 197 | { " " swap$ * " " * } 198 | 199 | % Here's how BibTeX does internationalization: 200 | 201 | FUNCTION {bbl.and} 202 | { "and"} 203 | 204 | FUNCTION {bbl.editors} 205 | { "eds." } 206 | 207 | FUNCTION {bbl.editor} 208 | { "ed." } 209 | 210 | FUNCTION {bbl.edby} 211 | { "edited by" } 212 | 213 | FUNCTION {bbl.edition} 214 | { "edn." } 215 | 216 | FUNCTION {bbl.volume} 217 | { "Vol." } 218 | 219 | FUNCTION {bbl.of} 220 | { "of" } 221 | 222 | FUNCTION {bbl.number} 223 | { "no." } 224 | 225 | FUNCTION {bbl.nr} 226 | { "no." } 227 | 228 | FUNCTION {bbl.in} 229 | { "in" } 230 | 231 | FUNCTION {bbl.pages} 232 | { "" } 233 | 234 | FUNCTION {bbl.page} 235 | { "" } 236 | 237 | FUNCTION {bbl.chapter} 238 | { "Ch." } 239 | 240 | FUNCTION {bbl.techrep} 241 | { "Tech. Rep." } 242 | 243 | FUNCTION {bbl.mthesis} 244 | { "Master's thesis" } 245 | 246 | FUNCTION {bbl.phdthesis} 247 | { "PhD thesis" } 248 | 249 | FUNCTION {bbl.first} 250 | { "1st" } 251 | 252 | FUNCTION {bbl.second} 253 | { "2nd" } 254 | 255 | FUNCTION {bbl.third} 256 | { "3rd" } 257 | 258 | FUNCTION {bbl.fourth} 259 | { "4th" } 260 | 261 | FUNCTION {bbl.fifth} 262 | { "5th" } 263 | 264 | FUNCTION {bbl.st} 265 | { "st" } 266 | 267 | FUNCTION {bbl.nd} 268 | { "nd" } 269 | 270 | FUNCTION {bbl.rd} 271 | { "rd" } 272 | 273 | FUNCTION {bbl.th} 274 | { "th" } 275 | 276 | MACRO {jan} {"Jan."} 277 | 278 | MACRO {feb} {"Feb."} 279 | 280 | MACRO {mar} {"Mar."} 281 | 282 | MACRO {apr} {"Apr."} 283 | 284 | MACRO {may} {"May"} 285 | 286 | MACRO {jun} {"Jun."} 287 | 288 | MACRO {jul} {"Jul."} 289 | 290 | MACRO {aug} {"Aug."} 291 | 292 | MACRO {sep} {"Sep."} 293 | 294 | MACRO {oct} {"Oct."} 295 | 296 | MACRO {nov} {"Nov."} 297 | 298 | MACRO {dec} {"Dec."} 299 | 300 | FUNCTION {eng.ord} 301 | { duplicate$ "1" swap$ * 302 | #-2 #1 substring$ "1" = 303 | { bbl.th * } 304 | { duplicate$ #-1 #1 substring$ 305 | duplicate$ "1" = 306 | { pop$ bbl.st * } 307 | { duplicate$ "2" = 308 | { pop$ bbl.nd * } 309 | { "3" = 310 | { bbl.rd * } 311 | { bbl.th * } 312 | if$ 313 | } 314 | if$ 315 | } 316 | if$ 317 | } 318 | if$ 319 | } 320 | 321 | INTEGERS { nameptr namesleft numnames numtrunc } 322 | 323 | FUNCTION {format.names} 324 | { 's := 325 | #0 'numtrunc := 326 | #1 'nameptr := 327 | s num.names$ 'numnames := 328 | numnames 'namesleft := 329 | numnames #2 > 330 | { #1 'numtrunc := } 331 | {} 332 | if$ 333 | { namesleft #0 > } 334 | { s nameptr 335 | "{vv~}{ll}{~jj}{~f{}}" format.name$ 336 | 't := 337 | nameptr #1 > 338 | { 339 | nameptr #1 - numtrunc = 340 | { 341 | #1 'namesleft := 342 | "others" 't := 343 | } 344 | {} 345 | if$ 346 | 347 | namesleft #1 > 348 | { ", " * t * } 349 | { 350 | numnames #1 > 351 | { "," * } 352 | 'skip$ 353 | if$ 354 | s nameptr "{ll}" format.name$ duplicate$ "others" = 355 | { 't := } 356 | { pop$ } 357 | if$ 358 | t "others" = 359 | { 360 | " et~al." * 361 | } 362 | { " \& " * t * } 363 | if$ 364 | } 365 | if$ 366 | } 367 | 't 368 | if$ 369 | nameptr #1 + 'nameptr := 370 | namesleft #1 - 'namesleft := 371 | } 372 | while$ 373 | } 374 | 375 | FUNCTION {format.key} 376 | { empty$ 377 | { key field.or.null } 378 | { "" } 379 | if$ 380 | } 381 | 382 | FUNCTION {format.authors} 383 | % input: agnostic 384 | % output: stack -1: formatted author names (or "") 385 | { author empty$ 386 | { "" } 387 | { author format.names } 388 | if$ 389 | } 390 | 391 | FUNCTION {format.editors} 392 | % input: agnostic 393 | % output: stack -1: formatted editor names (or "") 394 | { editor empty$ 395 | { "" } 396 | { editor format.names 397 | editor num.names$ #1 > 398 | { ", eds." * } 399 | { ", ed." * } 400 | if$ 401 | } 402 | if$ 403 | } 404 | 405 | FUNCTION {format.in.editors} 406 | { editor empty$ 407 | { "" } 408 | { editor format.names 409 | } 410 | if$ 411 | } 412 | 413 | FUNCTION {format.note} 414 | { note empty$ 415 | { "" } 416 | { note #1 #1 substring$ 417 | duplicate$ "{" = 418 | 'skip$ 419 | { output.state mid.sentence = 420 | { "l" } 421 | { "u" } 422 | if$ 423 | change.case$ 424 | } 425 | if$ 426 | note #2 global.max$ substring$ * 427 | } 428 | if$ 429 | } 430 | 431 | FUNCTION {format.title} 432 | { title empty$ 433 | { "" } 434 | { title 435 | } 436 | if$ 437 | } 438 | 439 | FUNCTION {format.full.names} 440 | {'s := 441 | #1 'nameptr := 442 | s num.names$ 'numnames := 443 | numnames 'namesleft := 444 | { namesleft #0 > } 445 | { s nameptr 446 | "{vv~}{ll}" format.name$ 447 | 't := 448 | nameptr #1 > 449 | { 450 | namesleft #1 > 451 | { ", " * t * } 452 | { 453 | numnames #2 > 454 | { "," * } 455 | 'skip$ 456 | if$ 457 | s nameptr "{ll}" format.name$ duplicate$ "others" = 458 | { 't := } 459 | { pop$ } 460 | if$ 461 | t "others" = 462 | { 463 | " et~al." * 464 | } 465 | { " \& " * t * } 466 | if$ 467 | } 468 | if$ 469 | } 470 | 't 471 | if$ 472 | nameptr #1 + 'nameptr := 473 | namesleft #1 - 'namesleft := 474 | } 475 | while$ 476 | } 477 | 478 | FUNCTION {author.editor.key.full} 479 | { author empty$ 480 | { editor empty$ 481 | { key empty$ 482 | { cite$ #1 #3 substring$ } 483 | 'key 484 | if$ 485 | } 486 | { editor format.full.names } 487 | if$ 488 | } 489 | { author format.full.names } 490 | if$ 491 | } 492 | 493 | FUNCTION {author.key.full} 494 | { author empty$ 495 | { key empty$ 496 | { cite$ #1 #3 substring$ } 497 | 'key 498 | if$ 499 | } 500 | { author format.full.names } 501 | if$ 502 | } 503 | 504 | FUNCTION {editor.key.full} 505 | { editor empty$ 506 | { key empty$ 507 | { cite$ #1 #3 substring$ } 508 | 'key 509 | if$ 510 | } 511 | { editor format.full.names } 512 | if$ 513 | } 514 | 515 | FUNCTION {make.full.names} 516 | { type$ "book" = 517 | type$ "inbook" = 518 | or 519 | 'author.editor.key.full 520 | { type$ "proceedings" = 521 | 'editor.key.full 522 | 'author.key.full 523 | if$ 524 | } 525 | if$ 526 | } 527 | 528 | FUNCTION {output.bibitem} 529 | { newline$ 530 | "\bibitem[{" write$ 531 | label write$ 532 | ")" make.full.names duplicate$ short.list = 533 | { pop$ } 534 | { * } 535 | if$ 536 | "}]{" * write$ 537 | cite$ write$ 538 | "}" write$ 539 | newline$ 540 | "" 541 | before.all 'output.state := 542 | } 543 | 544 | FUNCTION {format.archive} 545 | { archivePrefix empty$ 546 | { "" } 547 | { archivePrefix ":" *} 548 | if$ 549 | } 550 | 551 | FUNCTION {format.primaryClass} 552 | { primaryClass empty$ 553 | { "" } 554 | { " [" primaryClass * "]" *} 555 | if$ 556 | } 557 | 558 | FUNCTION {format.eprint} 559 | % Only print eprint info if no page info and no booktitle info -- 560 | % what we're really going for is print the eprint info only if there's 561 | % no "official" reference info to work with. 562 | { eprint empty$ 563 | pages empty$ not 564 | booktitle empty$ not or or 565 | { "" } 566 | { archive empty$ 567 | {"\href{http://arxiv.org/abs/" eprint * "}" * 568 | "{{\sffamily " * format.archive * eprint * 569 | format.primaryClass * "}}" *} 570 | {"\href{" archive * "/" * eprint * "}" * 571 | "{{\sffamily " * format.archive * eprint * 572 | format.primaryClass * "}}" *} 573 | if$ 574 | } 575 | if$ 576 | } 577 | 578 | 579 | FUNCTION {n.dashify} 580 | { 581 | 't := 582 | "" 583 | { t empty$ not } 584 | { t #1 #1 substring$ "-" = 585 | { t #1 #2 substring$ "--" = not 586 | { "--" * 587 | t #2 global.max$ substring$ 't := 588 | } 589 | { { t #1 #1 substring$ "-" = } 590 | { "-" * 591 | t #2 global.max$ substring$ 't := 592 | } 593 | while$ 594 | } 595 | if$ 596 | } 597 | { t #1 #1 substring$ * 598 | t #2 global.max$ substring$ 't := 599 | } 600 | if$ 601 | } 602 | while$ 603 | } 604 | 605 | FUNCTION {word.in} 606 | { bbl.in 607 | " " * } 608 | 609 | FUNCTION {format.date} 610 | { year duplicate$ empty$ 611 | { "empty year in " cite$ * "; set to ????" * warning$ 612 | pop$ "????" } 613 | 'skip$ 614 | if$ 615 | extra.label * 616 | before.all 'output.state := 617 | after.sentence 'output.state := 618 | } 619 | 620 | FUNCTION {format.btitle} 621 | { title 622 | } 623 | 624 | FUNCTION {tie.or.space.connect} 625 | { duplicate$ text.length$ #3 < 626 | { "~" } 627 | { " " } 628 | if$ 629 | swap$ * * 630 | } 631 | 632 | FUNCTION {either.or.check} 633 | { empty$ 634 | 'pop$ 635 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 636 | if$ 637 | } 638 | 639 | FUNCTION {format.bvolume} 640 | { volume empty$ 641 | { "" } 642 | { bbl.volume volume tie.or.space.connect 643 | series empty$ 644 | 'skip$ 645 | { bbl.of space.word * series * } 646 | if$ 647 | "volume and number" number either.or.check 648 | } 649 | if$ 650 | } 651 | 652 | FUNCTION {format.number.series} 653 | { volume empty$ 654 | { number empty$ 655 | { series field.or.null } 656 | { output.state mid.sentence = 657 | { bbl.number } 658 | { bbl.number capitalize } 659 | if$ 660 | number tie.or.space.connect 661 | series empty$ 662 | { "there's a number but no series in " cite$ * warning$ } 663 | { bbl.in space.word * series * } 664 | if$ 665 | } 666 | if$ 667 | } 668 | { "" } 669 | if$ 670 | } 671 | 672 | FUNCTION {is.num} 673 | { chr.to.int$ 674 | duplicate$ "0" chr.to.int$ < not 675 | swap$ "9" chr.to.int$ > not and 676 | } 677 | 678 | FUNCTION {extract.num} 679 | { duplicate$ 't := 680 | "" 's := 681 | { t empty$ not } 682 | { t #1 #1 substring$ 683 | t #2 global.max$ substring$ 't := 684 | duplicate$ is.num 685 | { s swap$ * 's := } 686 | { pop$ "" 't := } 687 | if$ 688 | } 689 | while$ 690 | s empty$ 691 | 'skip$ 692 | { pop$ s } 693 | if$ 694 | } 695 | 696 | FUNCTION {convert.edition} 697 | { edition extract.num "l" change.case$ 's := 698 | s "first" = s "1" = or 699 | { bbl.first 't := } 700 | { s "second" = s "2" = or 701 | { bbl.second 't := } 702 | { s "third" = s "3" = or 703 | { bbl.third 't := } 704 | { s "fourth" = s "4" = or 705 | { bbl.fourth 't := } 706 | { s "fifth" = s "5" = or 707 | { bbl.fifth 't := } 708 | { s #1 #1 substring$ is.num 709 | { s eng.ord 't := } 710 | { edition 't := } 711 | if$ 712 | } 713 | if$ 714 | } 715 | if$ 716 | } 717 | if$ 718 | } 719 | if$ 720 | } 721 | if$ 722 | t 723 | } 724 | 725 | FUNCTION {format.edition} 726 | { edition empty$ 727 | { "" } 728 | { output.state mid.sentence = 729 | { convert.edition "l" change.case$ " " * bbl.edition * } 730 | { convert.edition "t" change.case$ " " * bbl.edition * } 731 | if$ 732 | } 733 | if$ 734 | } 735 | 736 | INTEGERS { multiresult } 737 | 738 | FUNCTION {multi.page.check} 739 | { 't := 740 | #0 'multiresult := 741 | { multiresult not 742 | t empty$ not 743 | and 744 | } 745 | { t #1 #1 substring$ 746 | duplicate$ "-" = 747 | swap$ duplicate$ "," = 748 | swap$ "+" = 749 | or or 750 | { #1 'multiresult := } 751 | { t #2 global.max$ substring$ 't := } 752 | if$ 753 | } 754 | while$ 755 | multiresult 756 | } 757 | 758 | FUNCTION {string.length} 759 | { % Copied from "Taming the BeaST", by Nicolas Markey, Fig 4 760 | #1 'work.strlen := 761 | { duplicate$ duplicate$ #1 work.strlen substring$ = not } 762 | { work.strlen #1 + 'work.strlen := } 763 | while$ 764 | pop$ work.strlen 765 | } 766 | 767 | FUNCTION {first.page} 768 | { 't := 769 | "" 770 | { t empty$ not t #1 #1 substring$ "-" = not and } 771 | { t #1 #1 substring$ * 772 | t #2 global.max$ substring$ 't := 773 | } 774 | while$ 775 | % remove possible trailing plus sign 776 | duplicate$ duplicate$ string.length #1 substring$ "+" = 777 | { duplicate$ string.length #1 - #1 swap$ substring$ } 778 | { } 779 | if$ 780 | } 781 | 782 | FUNCTION {format.pages} 783 | { pages empty$ 784 | { "" } 785 | { pages first.page } 786 | if$ 787 | } 788 | 789 | FUNCTION {format.journal.pages} 790 | { pages empty$ 791 | 'skip$ 792 | { duplicate$ empty$ 793 | { pop$ format.pages } 794 | { 795 | " " * 796 | pages first.page * 797 | } 798 | if$ 799 | } 800 | if$ 801 | } 802 | 803 | FUNCTION {format.vol.num.pages} 804 | { volume field.or.null 805 | } 806 | 807 | FUNCTION {format.chapter.pages} 808 | { chapter empty$ 809 | { "" } 810 | { type empty$ 811 | { bbl.chapter } 812 | { type "l" change.case$ } 813 | if$ 814 | chapter tie.or.space.connect 815 | } 816 | if$ 817 | } 818 | 819 | FUNCTION {format.in.ed.booktitle} 820 | { booktitle empty$ 821 | { "" } 822 | { editor empty$ 823 | { word.in booktitle * } 824 | { word.in booktitle * 825 | ", " * 826 | editor num.names$ #1 > 827 | { bbl.editors } 828 | { bbl.editor } 829 | if$ 830 | * " " * 831 | format.in.editors * 832 | } 833 | if$ 834 | } 835 | if$ 836 | } 837 | 838 | FUNCTION {format.thesis.type} 839 | { type empty$ 840 | 'skip$ 841 | { pop$ 842 | type "t" change.case$ 843 | } 844 | if$ 845 | } 846 | 847 | FUNCTION {format.tr.number} 848 | { type empty$ 849 | { bbl.techrep } 850 | 'type 851 | if$ 852 | number empty$ 853 | { "t" change.case$ } 854 | { number tie.or.space.connect } 855 | if$ 856 | } 857 | 858 | FUNCTION {format.article.crossref} 859 | { 860 | word.in 861 | " \cite{" * crossref * "}" * 862 | } 863 | 864 | FUNCTION {format.book.crossref} 865 | { volume empty$ 866 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 867 | word.in 868 | } 869 | { bbl.volume volume tie.or.space.connect 870 | bbl.of space.word * 871 | } 872 | if$ 873 | " \cite{" * crossref * "}" * 874 | } 875 | 876 | FUNCTION {format.incoll.inproc.crossref} 877 | { 878 | word.in 879 | " \cite{" * crossref * "}" * 880 | } 881 | 882 | FUNCTION {format.publisher} 883 | { publisher empty$ 884 | { "empty publisher in " cite$ * warning$ } 885 | 'skip$ 886 | if$ 887 | "" 888 | address empty$ publisher empty$ and 889 | 'skip$ 890 | { 891 | add.blank "(" * 892 | address empty$ 893 | 'skip$ 894 | { address * } 895 | if$ 896 | publisher empty$ 897 | 'skip$ 898 | { address empty$ 899 | 'skip$ 900 | { ": " * } 901 | if$ 902 | publisher * 903 | } 904 | if$ 905 | ")" * 906 | } 907 | if$ 908 | output.skipempty.nocomma 909 | } 910 | 911 | STRINGS {oldname} 912 | 913 | FUNCTION {format.edn.btitle} % Title should be on stack. 914 | { duplicate$ empty$ edition empty$ or 915 | 'skip$ 916 | { ", " * format.edition * } 917 | if$ 918 | } 919 | 920 | FUNCTION {format.ed.booktitle} % The title should be on the stack. 921 | { duplicate$ empty$ 922 | { "no book title in " cite$ * warning$ "" pop$ } 923 | { editor empty$ 924 | author empty$ or % Empty author means editor already given. 925 | 'format.edn.btitle 926 | { format.edn.btitle ", " * bbl.editor * " " * format.in.editors * } 927 | if$ 928 | } 929 | if$ 930 | } 931 | 932 | FUNCTION {format.full.book.spec} % The title should be on the stack. 933 | { series empty$ 934 | { format.ed.booktitle 935 | volume empty$ 936 | { number empty$ 937 | 'skip$ 938 | { " there's a number but no series in " cite$ * warning$ 939 | " No." number tie.or.space.connect * } 940 | if$ 941 | } 942 | { ", Vol." volume tie.or.space.connect * 943 | number empty$ 944 | 'skip$ 945 | {"Both volume and number fields in " * cite$ * warning$ } 946 | if$ 947 | } 948 | if$ 949 | } 950 | { volume empty$ 951 | { format.ed.booktitle ", " * series * 952 | number empty$ 953 | 'skip$ 954 | { " No." number tie.or.space.connect * } 955 | if$ 956 | } 957 | { series ", Vol." volume tie.or.space.connect * 958 | ", " * swap$ format.ed.booktitle * 959 | number empty$ 960 | 'skip$ 961 | {"Both volume and number fields in " * cite$ * warning$ } 962 | if$ 963 | } 964 | if$ 965 | } 966 | if$ 967 | } 968 | 969 | FUNCTION {maybe.doi.link.prepend} 970 | { % Expects some citation text to be on the stack 971 | doi empty$ 972 | { url empty$ 973 | { } 974 | { "\href{" url * "}{" * swap$ * } 975 | if$ 976 | } 977 | { "\href{http://dx.doi.org/" doi * "}{" * swap$ * } 978 | if$ 979 | } 980 | 981 | FUNCTION {maybe.doi.link.end} 982 | { % Expects some citation text to be on the stack 983 | doi empty$ url empty$ and 984 | { } 985 | { "}" * } 986 | if$ 987 | } 988 | 989 | FUNCTION {format.journal} 990 | { 991 | journal empty$ 992 | { "" } % warning will be issued by output.check 993 | { "\JournalTitle{" journal * "}" * } 994 | if$ 995 | } 996 | 997 | FUNCTION {article} 998 | { output.bibitem 999 | format.authors "author" output.check.comma 1000 | author format.key output.skipempty.nocomma 1001 | format.date "year" output.check.nocomma 1002 | maybe.doi.link.prepend 1003 | crossref missing$ 1004 | { format.journal "journal" output.check.nocomma 1005 | format.vol.num.pages output.skipempty.nocomma 1006 | } 1007 | { format.article.crossref 1008 | output.nonnull.nocomma 1009 | format.pages output.skipempty.nocomma 1010 | } 1011 | if$ 1012 | format.journal.pages 1013 | maybe.doi.link.end 1014 | format.eprint output.skipempty.comma 1015 | format.note output.skipempty.comma 1016 | finish.entry 1017 | } 1018 | 1019 | FUNCTION {book} 1020 | { output.bibitem 1021 | author empty$ 1022 | { format.editors "author and editor" output.check.nocomma 1023 | editor format.key output.skipempty.nocomma 1024 | } 1025 | { format.authors output.nonnull.nocomma 1026 | crossref missing$ 1027 | { "author and editor" editor either.or.check } 1028 | 'skip$ 1029 | if$ 1030 | } 1031 | if$ 1032 | format.date "year" output.check.nocomma 1033 | maybe.doi.link.prepend 1034 | title format.full.book.spec 1035 | maybe.doi.link.end output.skipempty.nocomma 1036 | format.publisher 1037 | format.pages output.skipempty.nocomma 1038 | format.eprint output.skipempty.comma 1039 | format.note output.skipempty.nocomma 1040 | finish.entry 1041 | } 1042 | 1043 | FUNCTION {incollection} 1044 | { output.bibitem 1045 | format.authors "author" output.check.nocomma 1046 | author format.key output.skipempty.nocomma 1047 | format.date "year" output.check.nocomma 1048 | maybe.doi.link.prepend 1049 | bbl.in " " * booktitle format.full.book.spec * 1050 | maybe.doi.link.end output.skipempty.nocomma 1051 | format.publisher 1052 | format.pages "pages" output.skipempty.nocomma 1053 | format.eprint output.skipempty.comma 1054 | format.note output.skipempty.nocomma 1055 | finish.entry 1056 | } 1057 | 1058 | FUNCTION {inproceedings} 1059 | { output.bibitem 1060 | format.authors "author" output.check.nocomma 1061 | author format.key output.skipempty.nocomma % added 1062 | format.date "year" output.check.nocomma 1063 | maybe.doi.link.prepend 1064 | bbl.in " " * booktitle format.full.book.spec * 1065 | maybe.doi.link.end output.skipempty.nocomma 1066 | publisher empty$ 1067 | { organization output.skipempty.nocomma 1068 | address output.skipempty.nocomma 1069 | } 1070 | { organization output.skipempty.nocomma 1071 | format.publisher 1072 | } 1073 | if$ 1074 | format.pages output.skipempty.nocomma 1075 | format.eprint output.skipempty.comma 1076 | format.note output.skipempty.nocomma 1077 | finish.entry 1078 | } 1079 | 1080 | FUNCTION {misc} 1081 | { output.bibitem 1082 | format.authors output.skipempty.nocomma 1083 | author format.key output.skipempty.nocomma 1084 | format.date "year" output.check.nocomma 1085 | format.title output.skipempty.nocomma 1086 | howpublished output.skipempty.nocomma 1087 | format.eprint output.skipempty.comma 1088 | format.note output.skipempty.nocomma 1089 | finish.entry 1090 | } 1091 | 1092 | FUNCTION {default.type} { misc } 1093 | 1094 | READ 1095 | 1096 | FUNCTION {sortify} 1097 | { purify$ 1098 | "l" change.case$ 1099 | } 1100 | 1101 | INTEGERS { len } 1102 | 1103 | FUNCTION {chop.word} 1104 | { 's := 1105 | 'len := 1106 | s #1 len substring$ = 1107 | { s len #1 + global.max$ substring$ } 1108 | 's 1109 | if$ 1110 | } 1111 | 1112 | FUNCTION {format.lab.names} 1113 | { 's := 1114 | s #1 "{vv~}{ll}" format.name$ 1115 | s num.names$ duplicate$ 1116 | #2 > 1117 | { pop$ 1118 | " et~al." * 1119 | } 1120 | { #2 < 1121 | 'skip$ 1122 | { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 1123 | { 1124 | " et~al." * 1125 | } 1126 | { " \& " * s #2 "{vv~}{ll}" format.name$ 1127 | * } 1128 | if$ 1129 | } 1130 | if$ 1131 | } 1132 | if$ 1133 | } 1134 | 1135 | FUNCTION {author.key.label} 1136 | { author empty$ 1137 | { key empty$ 1138 | { cite$ #1 #3 substring$ } 1139 | 'key 1140 | if$ 1141 | } 1142 | { author format.lab.names } 1143 | if$ 1144 | } 1145 | 1146 | FUNCTION {author.editor.key.label} 1147 | { author empty$ 1148 | { editor empty$ 1149 | { key empty$ 1150 | { cite$ #1 #3 substring$ } 1151 | 'key 1152 | if$ 1153 | } 1154 | { editor format.lab.names } 1155 | if$ 1156 | } 1157 | { author format.lab.names } 1158 | if$ 1159 | } 1160 | 1161 | FUNCTION {editor.key.label} 1162 | { editor empty$ 1163 | { key empty$ 1164 | { cite$ #1 #3 substring$ } 1165 | 'key 1166 | if$ 1167 | } 1168 | { editor format.lab.names } 1169 | if$ 1170 | } 1171 | 1172 | FUNCTION {calc.short.authors} 1173 | { type$ "book" = 1174 | type$ "inbook" = 1175 | or 1176 | 'author.editor.key.label 1177 | { type$ "proceedings" = 1178 | 'editor.key.label 1179 | 'author.key.label 1180 | if$ 1181 | } 1182 | if$ 1183 | 'short.list := 1184 | } 1185 | 1186 | FUNCTION {calc.label} 1187 | { calc.short.authors 1188 | short.list 1189 | "(" 1190 | * 1191 | year duplicate$ empty$ 1192 | { pop$ "????" } 1193 | 'skip$ 1194 | if$ 1195 | * 1196 | 'label := 1197 | } 1198 | 1199 | FUNCTION {sort.format.names} 1200 | { 's := 1201 | #1 'nameptr := 1202 | "" 1203 | s num.names$ 'numnames := 1204 | numnames #8 > 1205 | { s nameptr 1206 | "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" 1207 | format.name$ 't := 1208 | t sortify * 1209 | " " * 1210 | "zzzzz" * 1211 | } 1212 | { numnames 'namesleft := 1213 | { namesleft #0 > } 1214 | { s nameptr 1215 | "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" 1216 | format.name$ 't := 1217 | nameptr #1 > 1218 | { 1219 | " " * 1220 | namesleft #1 = t "others" = and 1221 | { "zzzzz" * } 1222 | { t sortify * } 1223 | if$ 1224 | } 1225 | { t sortify * } 1226 | if$ 1227 | nameptr #1 + 'nameptr := 1228 | namesleft #1 - 'namesleft := 1229 | } 1230 | while$ 1231 | } 1232 | if$ 1233 | } 1234 | 1235 | FUNCTION {sort.format.title} 1236 | { 't := 1237 | "A " #2 1238 | "An " #3 1239 | "The " #4 t chop.word 1240 | chop.word 1241 | chop.word 1242 | sortify 1243 | #1 global.max$ substring$ 1244 | } 1245 | 1246 | FUNCTION {author.sort} 1247 | { author empty$ 1248 | { key empty$ 1249 | { "to sort, need author or key in " cite$ * warning$ 1250 | "" 1251 | } 1252 | { key sortify } 1253 | if$ 1254 | } 1255 | { author sort.format.names } 1256 | if$ 1257 | } 1258 | 1259 | FUNCTION {author.editor.sort} 1260 | { author empty$ 1261 | { editor empty$ 1262 | { key empty$ 1263 | { "to sort, need author, editor, or key in " cite$ * warning$ 1264 | "" 1265 | } 1266 | { key sortify } 1267 | if$ 1268 | } 1269 | { editor sort.format.names } 1270 | if$ 1271 | } 1272 | { author sort.format.names } 1273 | if$ 1274 | } 1275 | 1276 | FUNCTION {editor.sort} 1277 | { editor empty$ 1278 | { key empty$ 1279 | { "to sort, need editor or key in " cite$ * warning$ 1280 | "" 1281 | } 1282 | { key sortify } 1283 | if$ 1284 | } 1285 | { editor sort.format.names } 1286 | if$ 1287 | } 1288 | 1289 | FUNCTION {presort} 1290 | { calc.label 1291 | label sortify 1292 | " " 1293 | * 1294 | type$ "book" = 1295 | type$ "inbook" = 1296 | or 1297 | 'author.editor.sort 1298 | { type$ "proceedings" = 1299 | 'editor.sort 1300 | 'author.sort 1301 | if$ 1302 | } 1303 | if$ 1304 | #1 entry.max$ substring$ 1305 | 'sort.label := 1306 | sort.label 1307 | * 1308 | " " 1309 | * 1310 | title field.or.null 1311 | sort.format.title 1312 | * 1313 | #1 entry.max$ substring$ 1314 | 'sort.key$ := 1315 | } 1316 | 1317 | ITERATE {presort} 1318 | 1319 | SORT 1320 | 1321 | STRINGS { last.label next.extra } 1322 | 1323 | INTEGERS { last.extra.num number.label } 1324 | 1325 | FUNCTION {initialize.extra.label.stuff} 1326 | { #0 int.to.chr$ 'last.label := 1327 | "" 'next.extra := 1328 | #0 'last.extra.num := 1329 | #0 'number.label := 1330 | } 1331 | 1332 | FUNCTION {forward.pass} 1333 | { last.label label = 1334 | { last.extra.num #1 + 'last.extra.num := 1335 | last.extra.num int.to.chr$ 'extra.label := 1336 | } 1337 | { "a" chr.to.int$ 'last.extra.num := 1338 | "" 'extra.label := 1339 | label 'last.label := 1340 | } 1341 | if$ 1342 | number.label #1 + 'number.label := 1343 | } 1344 | 1345 | FUNCTION {reverse.pass} 1346 | { next.extra "b" = 1347 | { "a" 'extra.label := } 1348 | 'skip$ 1349 | if$ 1350 | extra.label 'next.extra := 1351 | extra.label 1352 | duplicate$ empty$ 1353 | 'skip$ 1354 | { "{\natexlab{" swap$ * "}}" * } 1355 | if$ 1356 | 'extra.label := 1357 | label extra.label * 'label := 1358 | } 1359 | 1360 | EXECUTE {initialize.extra.label.stuff} 1361 | 1362 | ITERATE {forward.pass} 1363 | 1364 | REVERSE {reverse.pass} 1365 | 1366 | FUNCTION {bib.sort.order} 1367 | { sort.label 1368 | " " 1369 | * 1370 | year field.or.null sortify 1371 | * 1372 | " " 1373 | * 1374 | title field.or.null 1375 | sort.format.title 1376 | * 1377 | #1 entry.max$ substring$ 1378 | 'sort.key$ := 1379 | } 1380 | 1381 | ITERATE {bib.sort.order} 1382 | 1383 | SORT 1384 | 1385 | FUNCTION {begin.bib} 1386 | { preamble$ empty$ 1387 | 'skip$ 1388 | { preamble$ write$ newline$ } 1389 | if$ 1390 | "\begin{thebibliography}{" number.label int.to.str$ * "}" * 1391 | write$ newline$ 1392 | "\providecommand\natexlab[1]{#1}" 1393 | write$ newline$ 1394 | "\providecommand\JournalTitle[1]{#1}" 1395 | write$ newline$ 1396 | } 1397 | 1398 | EXECUTE {begin.bib} 1399 | 1400 | EXECUTE {init.state.consts} 1401 | 1402 | ITERATE {call.type$} 1403 | 1404 | FUNCTION {end.bib} 1405 | { newline$ 1406 | "\end{thebibliography}" write$ newline$ 1407 | } 1408 | 1409 | EXECUTE {end.bib} 1410 | -------------------------------------------------------------------------------- /pwterse.bst: -------------------------------------------------------------------------------- 1 | % Terse bibliography for proposals. Based on bibtex 'abbrv'. 2 | 3 | ENTRY { 4 | address 5 | archive 6 | archivePrefix 7 | author 8 | booktitle 9 | chapter 10 | doi 11 | edition 12 | editor 13 | eprint 14 | howpublished 15 | institution 16 | journal 17 | key 18 | month 19 | note 20 | number 21 | organization 22 | pages 23 | primaryClass 24 | publisher 25 | school 26 | series 27 | title 28 | type 29 | url 30 | volume 31 | year 32 | } {} { 33 | label 34 | } 35 | 36 | 37 | % Basic boolean helpers. 38 | 39 | FUNCTION {not} 40 | { { #0 } 41 | { #1 } 42 | if$ 43 | } 44 | 45 | FUNCTION {and} 46 | { 'skip$ 47 | { pop$ #0 } 48 | if$ 49 | } 50 | 51 | FUNCTION {or} 52 | { { pop$ #1 } 53 | 'skip$ 54 | if$ 55 | } 56 | 57 | 58 | % Sentence-building infrastructure. 59 | 60 | INTEGERS { output.state before.all mid.sentence after.sentence } 61 | 62 | STRINGS { s t } 63 | 64 | FUNCTION {init.state.consts} 65 | { #0 'before.all := 66 | #1 'mid.sentence := 67 | #2 'after.sentence := 68 | } 69 | 70 | FUNCTION {output.nonnull.comma} 71 | % input: stack -1: string (assumed nonempty) 72 | % input: stack -2: string 73 | % output: stack -1: same as on input 74 | % write -2, possibly following it with "," or ".". 75 | % state is mid.sentence when done. 76 | { 's := 77 | output.state mid.sentence = 78 | { ", " * write$ } 79 | { output.state after.sentence = 80 | { add.period$ write$ 81 | newline$ 82 | } 83 | 'write$ % <- before.all case 84 | if$ 85 | mid.sentence 'output.state := 86 | } 87 | if$ 88 | s 89 | } 90 | 91 | FUNCTION {output.nonnull.nocomma} 92 | % as above, except no comma if mid.sentence. 93 | { 's := 94 | output.state mid.sentence = 95 | { " " * write$ } 96 | { output.state after.sentence = 97 | { add.period$ write$ 98 | newline$ 99 | } 100 | 'write$ % <- before.all case 101 | if$ 102 | mid.sentence 'output.state := 103 | } 104 | if$ 105 | s 106 | } 107 | 108 | FUNCTION {output.skipempty.comma} 109 | % input: stack -1: string 110 | % input: stack -2: string 111 | % output: stack -1: same as on input 112 | % Do nothing if -1 is empty. Otherwise, write -2, possibly following it with "," or ".". 113 | % If -1 is not empty, state is mid.sentence when done. 114 | { duplicate$ empty$ 115 | 'pop$ 116 | 'output.nonnull.comma 117 | if$ 118 | } 119 | 120 | FUNCTION {output.skipempty.nocomma} 121 | % as above, except no comma if mid.sentence 122 | { duplicate$ empty$ 123 | 'pop$ 124 | 'output.nonnull.nocomma 125 | if$ 126 | } 127 | 128 | FUNCTION {output.check.comma} 129 | % input: stack -1: description of item 130 | % input: stack -2: string (shouldn't be empty; warns if yes) 131 | % input: stack -3: string 132 | % output: stack -1: = input -3 133 | % like output, but warns if empty. 134 | { 't := 135 | duplicate$ empty$ 136 | { pop$ "empty " t * " in " * cite$ * warning$ } 137 | 'output.nonnull.comma 138 | if$ 139 | } 140 | 141 | FUNCTION {output.check.nocomma} 142 | % as above, except no comma if mid.sentence 143 | { 't := 144 | duplicate$ empty$ 145 | { pop$ "empty " t * " in " * cite$ * warning$ } 146 | 'output.nonnull.nocomma 147 | if$ 148 | } 149 | 150 | FUNCTION {new.sentence} 151 | % stack-agnostic 152 | % set output state to after.sentence, unless it is before.all 153 | { output.state before.all = 154 | 'skip$ 155 | { after.sentence 'output.state := } 156 | if$ 157 | } 158 | 159 | FUNCTION {begin.entry} 160 | % input: nothing on stack 161 | % output: stack -1: "" 162 | % sets output state to before.all. 163 | { newline$ 164 | "\bibitem{" write$ 165 | cite$ write$ 166 | "}" write$ 167 | newline$ 168 | "" 169 | before.all 'output.state := 170 | } 171 | 172 | FUNCTION {finish.entry} 173 | % input: stack -1: string 174 | % output: empty stack 175 | { add.period$ 176 | write$ 177 | newline$ 178 | } 179 | 180 | 181 | % Text manipulation utilities 182 | 183 | FUNCTION {emphasize} 184 | % input: stack -1: string, empty ok 185 | % output: stack -1: input -1 wrapped in \emph{}, or "". 186 | { duplicate$ empty$ 187 | { pop$ "" } 188 | { "\emph{" swap$ * "}" * } 189 | if$ 190 | } 191 | 192 | FUNCTION {tie.or.space.connect} 193 | % input: stack -1: string 194 | % input: stack -2: string 195 | % output: stack -1: (-2) + X + (-1), where X is "~" or " " 196 | % depending on if (-1) is less than 3 characters long. 197 | { duplicate$ text.length$ #3 < 198 | { "~" } 199 | { " " } 200 | if$ 201 | swap$ * * 202 | } 203 | 204 | INTEGERS { work.strlen } 205 | 206 | FUNCTION {string.length} 207 | % input: stack -1: string 208 | % output: stack -1: the length of input -1 209 | { % Copied from "Taming the BeaST", by Nicolas Markey, Fig 4 210 | #1 'work.strlen := 211 | { duplicate$ duplicate$ #1 work.strlen substring$ = not } 212 | { work.strlen #1 + 'work.strlen := } 213 | while$ 214 | pop$ work.strlen 215 | } 216 | 217 | 218 | % Name formatting 219 | 220 | INTEGERS { nameptr namesleft numnames numtrunc } 221 | 222 | FUNCTION {format.names} 223 | { 's := 224 | #0 'numtrunc := 225 | #1 'nameptr := 226 | s num.names$ 'numnames := 227 | numnames 'namesleft := 228 | numnames #2 > 229 | { #1 'numtrunc := } 230 | {} 231 | if$ 232 | { namesleft #0 > } 233 | { s nameptr 234 | "{vv~}{ll}{~jj}{~f{}}" format.name$ 235 | 't := 236 | nameptr #1 > 237 | { 238 | nameptr #1 - numtrunc = 239 | { 240 | #1 'namesleft := 241 | "others" 't := 242 | } 243 | {} 244 | if$ 245 | 246 | namesleft #1 > 247 | { ", " * t * } 248 | { s nameptr "{ll}" format.name$ duplicate$ "others" = 249 | { 't := } 250 | { pop$ } 251 | if$ 252 | t "others" = 253 | { 254 | " \textit{et~al.}" * 255 | } 256 | { " \& " * t * } 257 | if$ 258 | } 259 | if$ 260 | } 261 | 't 262 | if$ 263 | nameptr #1 + 'nameptr := 264 | namesleft #1 - 'namesleft := 265 | } 266 | while$ 267 | } 268 | 269 | FUNCTION {format.authors} 270 | % input: agnostic 271 | % output: stack -1: formatted author names (or "") 272 | { author empty$ 273 | { "" } 274 | { author format.names } 275 | if$ 276 | } 277 | 278 | FUNCTION {format.editors} 279 | % input: agnostic 280 | % output: stack -1: formatted editor names (or "") 281 | { editor empty$ 282 | { "" } 283 | { editor format.names 284 | editor num.names$ #1 > 285 | { ", eds." * } 286 | { ", ed." * } 287 | if$ 288 | } 289 | if$ 290 | } 291 | 292 | 293 | % Other bibliography info formatting 294 | 295 | FUNCTION {either.or.check} 296 | { empty$ 297 | 'pop$ 298 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 299 | if$ 300 | } 301 | 302 | FUNCTION {format.title} 303 | { title empty$ 304 | { "" } 305 | { title "t" change.case$ } 306 | if$ 307 | } 308 | 309 | FUNCTION {format.volume.wordy} 310 | { volume empty$ 311 | { "" } 312 | { "volume" volume tie.or.space.connect 313 | series empty$ 314 | 'skip$ 315 | { " of " * series emphasize * } 316 | if$ 317 | "volume and number" number either.or.check 318 | } 319 | if$ 320 | } 321 | 322 | FUNCTION {format.edition} 323 | { edition empty$ 324 | { "" } 325 | { output.state mid.sentence = 326 | { edition "l" change.case$ " edition" * } 327 | { edition "t" change.case$ " edition" * } 328 | if$ 329 | } 330 | if$ 331 | } 332 | 333 | INTEGERS { multiresult } 334 | 335 | FUNCTION {multi.page.check} 336 | { 't := 337 | #0 'multiresult := 338 | { multiresult not 339 | t empty$ not 340 | and 341 | } 342 | { t #1 #1 substring$ 343 | duplicate$ "-" = 344 | swap$ duplicate$ "," = 345 | swap$ "+" = 346 | or or 347 | { #1 'multiresult := } 348 | { t #2 global.max$ substring$ 't := } 349 | if$ 350 | } 351 | while$ 352 | multiresult 353 | } 354 | 355 | FUNCTION {first.page} 356 | { 't := 357 | "" 358 | { t empty$ not t #1 #1 substring$ "-" = not and } 359 | { t #1 #1 substring$ * 360 | t #2 global.max$ substring$ 't := 361 | } 362 | while$ 363 | % remove possible trailing plus sign 364 | duplicate$ duplicate$ string.length #1 substring$ "+" = 365 | { duplicate$ string.length #1 - #1 swap$ substring$ } 366 | { } 367 | if$ 368 | } 369 | 370 | FUNCTION {format.pages} 371 | { pages empty$ 372 | { "" } 373 | { pages first.page } 374 | if$ 375 | } 376 | 377 | FUNCTION {format.in.ed.booktitle} 378 | { booktitle empty$ 379 | { "" } 380 | { editor empty$ 381 | { "in " booktitle emphasize * } 382 | { "in " format.editors * ", " * booktitle emphasize * } 383 | if$ 384 | } 385 | if$ 386 | } 387 | 388 | FUNCTION {empty.misc.check} 389 | { author empty$ title empty$ howpublished empty$ 390 | month empty$ year empty$ note empty$ 391 | and and and and and 392 | key empty$ not and 393 | { "all relevant fields are empty in " cite$ * warning$ } 394 | 'skip$ 395 | if$ 396 | } 397 | 398 | FUNCTION {format.archive} 399 | { archivePrefix empty$ 400 | { "" } 401 | { archivePrefix ":" *} 402 | if$ 403 | } 404 | 405 | FUNCTION {format.primaryClass} 406 | { primaryClass empty$ 407 | { "" } 408 | { " [" primaryClass * "]" *} 409 | if$ 410 | } 411 | 412 | FUNCTION {format.eprint} 413 | % Only print eprint info if no page info and no booktitle info -- 414 | % what we're really going for is print the eprint info only if there's 415 | % no "official" reference info to work with. 416 | { eprint empty$ 417 | pages empty$ not 418 | booktitle empty$ not or or 419 | { "" } 420 | { archive empty$ 421 | { "\href{http://arxiv.org/abs/" eprint * "}" * 422 | "{\textsf{" * format.archive * eprint * 423 | format.primaryClass * "}}" * } 424 | { "\href{" archive * "/" * eprint * "}" * 425 | "{\textsf{" * format.archive * eprint * 426 | format.primaryClass * "}}" * 427 | } 428 | if$ 429 | } 430 | if$ 431 | } 432 | 433 | FUNCTION {maybe.doi.link.prepend} 434 | { % Expects some citation text to be on the stack 435 | doi empty$ 436 | { url empty$ 437 | { } 438 | { "\href{" url * "}{" * swap$ * } 439 | if$ 440 | } 441 | { "\href{http://dx.doi.org/" doi * "}{" * swap$ * } 442 | if$ 443 | } 444 | 445 | FUNCTION {maybe.doi.link.end} 446 | { % Expects some citation text to be on the stack 447 | doi empty$ url empty$ and 448 | { } 449 | { "}" * } 450 | if$ 451 | } 452 | 453 | 454 | % Support for the actual items we're going to output. 455 | 456 | FUNCTION {article} 457 | { begin.entry 458 | format.authors "author" output.check.comma 459 | 460 | new.sentence 461 | year 462 | maybe.doi.link.prepend "year" output.check.nocomma 463 | journal "journal" output.check.nocomma 464 | volume missing$ % if no volume, assume it's a preprint without full pub info yet. 465 | { format.eprint output.skipempty.comma } 466 | { volume output.skipempty.nocomma 467 | pages first.page "page" output.check.nocomma } 468 | if$ 469 | maybe.doi.link.end 470 | 471 | new.sentence 472 | note output.skipempty.comma 473 | finish.entry 474 | } 475 | 476 | FUNCTION {book} 477 | { begin.entry 478 | author empty$ 479 | { format.editors "author and editor" output.check.comma } 480 | { format.authors output.nonnull.comma 481 | "author and editor" editor either.or.check 482 | } 483 | if$ 484 | 485 | new.sentence 486 | year maybe.doi.link.prepend "year" output.check.comma 487 | title emphasize "title" output.check.comma 488 | format.volume.wordy output.skipempty.comma 489 | format.edition output.skipempty.comma 490 | "(" publisher * ")" * "publisher" output.check.nocomma 491 | maybe.doi.link.end 492 | 493 | new.sentence 494 | note output.skipempty.comma 495 | finish.entry 496 | } 497 | 498 | FUNCTION {incollection} 499 | { begin.entry 500 | format.authors "author" output.check.comma 501 | 502 | new.sentence 503 | year maybe.doi.link.prepend "year" output.check.comma 504 | format.in.ed.booktitle "booktitle" output.check.comma 505 | format.volume.wordy output.skipempty.comma 506 | format.edition output.skipempty.comma 507 | "(" publisher * ")" * "publisher" output.check.nocomma 508 | format.pages output.skipempty.comma 509 | maybe.doi.link.end 510 | 511 | new.sentence 512 | note output.skipempty.comma 513 | finish.entry 514 | } 515 | 516 | FUNCTION {inproceedings} 517 | { begin.entry 518 | format.authors "author" output.check.comma 519 | 520 | new.sentence 521 | year maybe.doi.link.prepend "year" output.check.comma 522 | format.in.ed.booktitle "booktitle" output.check.comma 523 | format.volume.wordy output.skipempty.comma 524 | format.edition output.skipempty.comma 525 | "(" publisher * ")" * "publisher" output.check.nocomma 526 | format.pages output.skipempty.comma 527 | maybe.doi.link.end 528 | 529 | new.sentence 530 | note output.skipempty.comma 531 | finish.entry 532 | } 533 | 534 | FUNCTION {conference} { inproceedings } 535 | 536 | FUNCTION {misc} 537 | { begin.entry 538 | format.authors "author" output.check.comma 539 | 540 | new.sentence 541 | year maybe.doi.link.prepend output.skipempty.comma 542 | format.title output.skipempty.comma 543 | maybe.doi.link.end 544 | 545 | new.sentence 546 | note output.skipempty.comma 547 | finish.entry 548 | 549 | empty.misc.check 550 | } 551 | 552 | FUNCTION {phdthesis} 553 | { begin.entry 554 | format.authors "author" output.check.comma 555 | 556 | new.sentence 557 | year "year" output.check.comma 558 | title emphasize "title" output.check.comma 559 | "PhD thesis" output.nonnull.comma 560 | school "school" output.check.comma 561 | 562 | new.sentence 563 | note output.skipempty.comma 564 | finish.entry 565 | } 566 | 567 | FUNCTION {default.type} { misc } 568 | 569 | 570 | % The "longest label" pass. Not sure if this is relevant at all 571 | % in numbers mode. 572 | 573 | STRINGS { longest.label } 574 | 575 | INTEGERS { number.label longest.label.width } 576 | 577 | FUNCTION {init.longest.label} 578 | { "" 'longest.label := 579 | #1 'number.label := 580 | #0 'longest.label.width := 581 | } 582 | 583 | FUNCTION {longest.label.pass} 584 | { number.label int.to.str$ 'label := 585 | number.label #1 + 'number.label := 586 | label width$ longest.label.width > 587 | { label 'longest.label := 588 | label width$ 'longest.label.width := 589 | } 590 | 'skip$ 591 | if$ 592 | } 593 | 594 | 595 | % Go, go, go! 596 | 597 | READ 598 | 599 | EXECUTE {init.longest.label} 600 | 601 | ITERATE {longest.label.pass} 602 | 603 | FUNCTION {begin.bib} 604 | { preamble$ empty$ 605 | 'skip$ 606 | { preamble$ write$ newline$ } 607 | if$ 608 | "\begin{thebibliography}{" longest.label * "}" * write$ newline$ 609 | } 610 | 611 | EXECUTE {begin.bib} 612 | 613 | EXECUTE {init.state.consts} 614 | 615 | ITERATE {call.type$} 616 | 617 | FUNCTION {end.bib} 618 | { newline$ 619 | "\end{thebibliography}" write$ newline$ 620 | } 621 | 622 | EXECUTE {end.bib} 623 | -------------------------------------------------------------------------------- /scgraphic.sty: -------------------------------------------------------------------------------- 1 | % Copyright 2014-2015 Peter Williams 2 | % 3 | % This work may be distributed and/or modified under the conditions of the 4 | % LaTeX Project Public License, either version 1.3 of this license or (at your 5 | % option) any later version. The latest version of this license is in 6 | % http://www.latex-project.org/lppl.txt and version 1.3 or later is part of 7 | % all distributions of LaTeX version 2005/12/01 or later. This work has the 8 | % LPPL maintenance status "maintained". The Current Maintainer of this work is 9 | % Peter Williams. This work consists of the file scgraphic.sty. 10 | 11 | 12 | % scgraphic.sty, inspired by sidecap.sty. Quick way to create a figure float 13 | % containing an image and a caption placed to its right side. 14 | % 15 | % \scgraphic[frac=0.7,label=f.foo]{image-path}{Caption text.} 16 | % 17 | % is approximately equivalent to: 18 | % 19 | % \begin{figure*} 20 | % \includegraphics{image-path} 21 | % \caption{Caption text.} 22 | % \label{f.foo} 23 | % \end{figure*} 24 | % 25 | % except that special things are done to place the image and caption 26 | % side-by-side, in this case giving the image 0.7 of the available width. 27 | % 28 | % The key parameter is 'frac', which determines how much of the horizontal 29 | % space is allocated to the image. Usually you want to adjust it until the 30 | % image and caption are about the same height. 31 | % 32 | % If the document is being set in a multi-column mode (specifically, 33 | % \columnwidth is less than \textwidth), a regular 'figure' will be created 34 | % with no special effects. This allows you to switch between one-column and 35 | % two-column layouts relatively painlessly, assuming 'frac' is about 0.5. 36 | % 37 | % Keywords to \scgraphic are: 38 | % 39 | % altcap - Passed as the optional arg to \caption: \caption[altcap]{main cap...} 40 | % frac - Fraction of the available width to be allocated to the image 41 | % gutter - Size of the gutter between image and caption. Defaults to \marginparsep 42 | % label - \label{} of the figure. 43 | % pos - Postioning of the resulting float. Defaults to "tb". 44 | 45 | \NeedsTeXFormat{LaTeX2e} 46 | \ProvidesPackage{scgraphic}[2014/11/03 v0.1 scgraphic (PKGW)] 47 | 48 | \RequirePackage{keyval}[1997/11/10] 49 | \RequirePackage{graphicx}[1999/02/16] 50 | \RequirePackage[NewParameters]{ragged2e} 51 | 52 | \newdimen\scg@gutter 53 | \newdimen\scg@figwidth 54 | \newdimen\scg@capwidth 55 | \newdimen\scg@figheight 56 | 57 | \def\scgDefaultAltCap{} 58 | \def\scgDefaultPos{tb} 59 | \def\scgDefaultFrac{0.5} 60 | \def\scgDefaultGutter{\marginparsep} 61 | 62 | \newcommand*{\scg@debuglen}[1]{} % noop; activated by 'debug' option 63 | \newcommand{\scg@debugbox}[1]{#1} % passthrough; activated by 'debug' option 64 | 65 | 66 | % Option processing 67 | 68 | \DeclareOption{debug}{% 69 | \renewcommand*{\scg@debuglen}[1]{% 70 | \PackageInfo{scgraphic}{\string#1 \the#1}% 71 | }% 72 | \renewcommand{\scg@debugbox}[1]{% 73 | {\setlength{\fboxsep}{0pt}% 74 | \setlength{\fboxrule}{1pt}% 75 | \fbox{#1}% 76 | }% 77 | }% 78 | }% 79 | 80 | \ExecuteOptions{} 81 | \ProcessOptions\relax 82 | 83 | 84 | % The rest 85 | 86 | \def\scgraphic{\@ifnextchar[\scgraphic@@a{\scgraphic@@a[]}} 87 | \def\scgraphic@@a[#1]#2#3{% 88 | % #1 - keyword args 89 | % #2 - image path 90 | % #3 - caption text 91 | % 92 | % Default the keywords 93 | \edef\scg@kw@altcap{\scgDefaultAltCap}% 94 | \edef\scg@kw@frac{\scgDefaultFrac}% 95 | \setlength{\scg@gutter}{\scgDefaultGutter}% 96 | \let\scg@kw@label=\@undefined% 97 | \edef\scg@kw@pos{\scgDefaultPos}% 98 | % 99 | % Process keywords 100 | \setkeys{scg}{#1}% 101 | \scg@debuglen{\scg@gutter}% 102 | % 103 | \ifdim\columnwidth<\textwidth 104 | % We're in multi-column mode! Just make a regular figure, ignoring most 105 | % of our features. 106 | \begin{figure}[htb]% 107 | \includegraphics[width=\columnwidth]{#2}% 108 | \caption[\scg@kw@altcap]{#3}% 109 | \ifx\scg@kw@label\@undefined\else 110 | \label{\scg@kw@label}% 111 | \fi 112 | \end{figure}% 113 | \else 114 | % We need to do a fancy sidecap. \@xdblfloat needs to see the value of 115 | % \scg@kw@pos after expansion; I'm sure there's a non-ridiculous way to do 116 | % this, but this is all I can manage right now. 117 | \def\@tempa{{figure}[}% 118 | \def\@tempb{]}% 119 | \edef\@tempc{\noexpand\@xdblfloat\@tempa\scg@kw@pos\@tempb}% 120 | \@tempc% 121 | % Calculate the widths of the image and the caption 122 | \setlength{\scg@capwidth}{\textwidth}% temporarily: full item width 123 | \advance\scg@capwidth -\scg@gutter \relax% temporarily: full width minus gutter 124 | \edef\@tempa{\scg@kw@frac\noexpand\scg@capwidth}% 125 | \setlength{\scg@figwidth}\@tempa\relax% 126 | \advance\scg@capwidth -\scg@figwidth% final value 127 | \scg@debuglen{\textwidth}% 128 | \scg@debuglen{\scg@figwidth}% 129 | \scg@debuglen{\scg@capwidth}% 130 | % 131 | \makebox[\textwidth][c]{% 132 | \settoheight{\scg@figheight}{% 133 | \includegraphics[width=\scg@figwidth]{#2}% 134 | }% 135 | \scg@debuglen{\scg@figheight}% 136 | \scg@debugbox{\includegraphics[width=\scg@figwidth]{#2}}% 137 | \hspace{\scg@gutter}% 138 | \scg@debugbox{\minipage[b][\scg@figheight][c]{\scg@capwidth}% 139 | \hrule \@height\z@ \@depth\z@% 140 | \let\@arrayparboxrestore\relax% 141 | \let\usecaptionmargin\relax% 142 | \abovecaptionskip\z@skip% 143 | \belowcaptionskip\z@skip% 144 | \caption[\scg@kw@altcap]{% 145 | \RaggedRight% 146 | \strut\ignorespaces#3\unskip\strut% 147 | }% 148 | \unskip% 149 | \ifx\scg@kw@label\@undefined\else% 150 | \label{\scg@kw@label}% 151 | \fi% 152 | \hrule \@height\z@ \@depth\z@% 153 | \endminipage}% 154 | }% 155 | \end@dblfloat 156 | \fi 157 | } 158 | 159 | \define@key{scg}{altcap}{\def\scg@kw@altcap{#1}} 160 | \define@key{scg}{frac}{\def\scg@kw@frac{#1}} 161 | \define@key{scg}{gutter}{\setlength{\scg@gutter}{#1}} 162 | \define@key{scg}{label}{\def\scg@kw@label{#1}} 163 | \define@key{scg}{pos}{\def\scg@kw@pos{#1}} 164 | 165 | \endinput 166 | -------------------------------------------------------------------------------- /tests/run-all.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Copyright 2019 Peter Williams 3 | # Licensed under the MIT License 4 | 5 | # Run our "test suite". 6 | 7 | base="$(dirname "$0")" 8 | ec=0 9 | 10 | for runner in $base/*/test.sh ; do 11 | name="$(basename "$(dirname "$runner")")" 12 | echo -n "$name ... " 13 | (cd "$(dirname "$runner")" && ./test.sh) 14 | if [ $? -eq 0 ] ; then 15 | echo "ok" 16 | else 17 | ec=1 18 | fi 19 | done 20 | 21 | exit $ec 22 | -------------------------------------------------------------------------------- /tests/yahapj/.gitignore: -------------------------------------------------------------------------------- 1 | /scaffold.aux 2 | /scaffold.bbl 3 | /scaffold.pdf 4 | /scaffold.xdv 5 | -------------------------------------------------------------------------------- /tests/yahapj/expected.bbl: -------------------------------------------------------------------------------- 1 | \begin{thebibliography}{} 2 | \providecommand\natexlab[1]{#1} 3 | \providecommand\JournalTitle[1]{#1} 4 | 5 | \bibitem[{{Noordam}(2004{\natexlab{a}})}]{issue11a} 6 | {Noordam}, J.~E. 2004{\natexlab{a}}, 7 | \href{http://dx.doi.org/10.1117/12.544262}{\JournalTitle{Proc. SPIE}, 5489, 8 | 817} 9 | 10 | \bibitem[{{Noordam}(2004{\natexlab{b}})}]{issue11b} 11 | {Noordam}, J.~E. 2004{\natexlab{b}}, 12 | \href{http://dx.doi.org/10.1117/12.544262}{\JournalTitle{Duplicated Proc. 13 | SPIE}, 5489, 817} 14 | 15 | \end{thebibliography} 16 | -------------------------------------------------------------------------------- /tests/yahapj/samples.bib: -------------------------------------------------------------------------------- 1 | @article{issue11a, 2 | author = {{Noordam}, Jan E.}, 3 | doi = {10.1117/12.544262}, 4 | journal = {Proc. SPIE}, 5 | pages = {817}, 6 | url = {http://dx.doi.org/10.1117/12.544262}, 7 | volume = {5489}, 8 | year = {2004} 9 | } 10 | 11 | @article{issue11b, 12 | author = {{Noordam}, Jan E.}, 13 | doi = {10.1117/12.544262}, 14 | journal = {Duplicated Proc. SPIE}, 15 | pages = {817}, 16 | url = {http://dx.doi.org/10.1117/12.544262}, 17 | volume = {5489}, 18 | year = {2004} 19 | } 20 | -------------------------------------------------------------------------------- /tests/yahapj/scaffold.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage{natbib} 3 | \usepackage[breaklinks,colorlinks,urlcolor=blue,citecolor=blue,linkcolor=blue]{hyperref} 4 | \bibliographystyle{../../yahapj} 5 | \begin{document} 6 | \cite{*} 7 | \bibliography{samples}{} 8 | \end{document} 9 | -------------------------------------------------------------------------------- /tests/yahapj/test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Copyright 2019 Peter Williams 3 | # Licensed under the MIT License 4 | 5 | # Test the yahapj style file. We use Tectonic to process some refs and compare 6 | # the BBL output to what's expected. The goal is to print nothing if everything 7 | # is OK. 8 | 9 | set -e 10 | tectonic -c minimal --outfmt=xdv --keep-intermediates scaffold.tex 11 | cmp scaffold.bbl expected.bbl 12 | rm -f scaffold.{aux,bbl,xdv} 13 | -------------------------------------------------------------------------------- /yahapj.bst: -------------------------------------------------------------------------------- 1 | % yahapj.bst -- yet another ApJ bibtex style file 2 | % Git SHA1 hash: $Id: 0f4c2127b1541077b3712edd55a91630faafbf90 $ 3 | % Reference repository: https://github.com/pkgw/tex-stuff/ 4 | % 5 | % The main features compared to other ApJ style files is that ArXiV 6 | % and DOI links are added. ArXiV information is only shown for those 7 | % entries that don't have more formal reference information. There are 8 | % other improvements too. 9 | % 10 | % Because this style file embeds links, your LaTeX file must use the 11 | % hyperref package. For non-butt-ugly links, try: 12 | % 13 | % \usepackage[breaklinks,colorlinks,urlcolor=blue,citecolor=blue,linkcolor=blue]{hyperref} 14 | % 15 | % Copyright notice: This work is dedicated to the public domain. You 16 | % have unlimited permission to copy, distribute, and modify it. 17 | % 18 | % For more information about this file and its provenance, consult 19 | % README.md in the Git repository from which it was obtained. You can 20 | % track these down using the SHA1 hash listed at the top of this file. 21 | % (Googling for the hash value should hopefully be sufficient.) 22 | % 23 | % This file is in the "BST" language, a unique reverse-polish-notation 24 | % language. The best and only reference of which I am aware is Part 4 of the 25 | % document "Tame the BeaST", by Nicolas Markey: 26 | % https://ctan.org/pkg/tamethebeast/ 27 | 28 | ENTRY 29 | { address 30 | archive 31 | archivePrefix 32 | author 33 | booktitle 34 | chapter 35 | doi 36 | edition 37 | editor 38 | eprint 39 | howpublished 40 | institution 41 | isbn 42 | journal 43 | key 44 | month 45 | note 46 | number 47 | organization 48 | pages 49 | primaryClass 50 | publisher 51 | school 52 | series 53 | title 54 | type 55 | url 56 | volume 57 | year 58 | } 59 | {} 60 | { label extra.label sort.label short.list } 61 | 62 | INTEGERS { output.state before.all mid.sentence after.sentence after.block work.strlen } 63 | 64 | FUNCTION {init.state.consts} 65 | { #0 'before.all := 66 | #1 'mid.sentence := 67 | #2 'after.sentence := 68 | #3 'after.block := 69 | } 70 | 71 | STRINGS { s t } 72 | 73 | FUNCTION {output.nonnull} 74 | { 's := 75 | output.state mid.sentence = 76 | { ", " * write$ } 77 | { output.state after.block = 78 | { add.period$ write$ 79 | newline$ 80 | "\newblock " write$ 81 | } 82 | { output.state before.all = 83 | 'write$ 84 | { add.period$ " " * write$ } 85 | if$ 86 | } 87 | if$ 88 | mid.sentence 'output.state := 89 | } 90 | if$ 91 | s 92 | } 93 | 94 | FUNCTION {output} 95 | { duplicate$ empty$ 96 | 'pop$ 97 | 'output.nonnull 98 | if$ 99 | } 100 | 101 | FUNCTION {output.check} 102 | { 't := 103 | duplicate$ empty$ 104 | { pop$ "empty " t * " in " * cite$ * warning$ } 105 | 'output.nonnull 106 | if$ 107 | } 108 | 109 | FUNCTION {fin.entry} 110 | { duplicate$ empty$ 111 | 'pop$ 112 | 'write$ 113 | if$ 114 | newline$ 115 | } 116 | 117 | FUNCTION {new.block} 118 | { output.state before.all = 119 | 'skip$ 120 | { after.block 'output.state := } 121 | if$ 122 | } 123 | 124 | FUNCTION {new.sentence} 125 | { output.state after.block = 126 | 'skip$ 127 | { output.state before.all = 128 | 'skip$ 129 | { after.sentence 'output.state := } 130 | if$ 131 | } 132 | if$ 133 | } 134 | 135 | FUNCTION {add.blank} 136 | { " " * before.all 'output.state := 137 | } 138 | 139 | FUNCTION {not} 140 | { { #0 } 141 | { #1 } 142 | if$ 143 | } 144 | 145 | FUNCTION {and} 146 | { 'skip$ 147 | { pop$ #0 } 148 | if$ 149 | } 150 | 151 | FUNCTION {or} 152 | { { pop$ #1 } 153 | 'skip$ 154 | if$ 155 | } 156 | 157 | FUNCTION {new.block.checkb} 158 | { empty$ 159 | swap$ empty$ 160 | and 161 | 'skip$ 162 | 'new.block 163 | if$ 164 | } 165 | 166 | FUNCTION {field.or.null} 167 | { duplicate$ empty$ 168 | { pop$ "" } 169 | 'skip$ 170 | if$ 171 | } 172 | 173 | FUNCTION {capitalize} 174 | { "u" change.case$ "t" change.case$ } 175 | 176 | FUNCTION {space.word} 177 | { " " swap$ * " " * } 178 | 179 | % Here's how BibTeX does internationalization: 180 | 181 | FUNCTION {bbl.and} 182 | { "and"} 183 | 184 | FUNCTION {bbl.editors} 185 | { "eds." } 186 | 187 | FUNCTION {bbl.editor} 188 | { "ed." } 189 | 190 | FUNCTION {bbl.edby} 191 | { "edited by" } 192 | 193 | FUNCTION {bbl.edition} 194 | { "edn." } 195 | 196 | FUNCTION {bbl.volume} 197 | { "Vol." } 198 | 199 | FUNCTION {bbl.of} 200 | { "of" } 201 | 202 | FUNCTION {bbl.number} 203 | { "no." } 204 | 205 | FUNCTION {bbl.nr} 206 | { "no." } 207 | 208 | FUNCTION {bbl.in} 209 | { "in" } 210 | 211 | FUNCTION {bbl.pages} 212 | { "" } 213 | 214 | FUNCTION {bbl.page} 215 | { "" } 216 | 217 | FUNCTION {bbl.chapter} 218 | { "Ch." } 219 | 220 | FUNCTION {bbl.techrep} 221 | { "Tech. Rep." } 222 | 223 | FUNCTION {bbl.mthesis} 224 | { "Master's thesis" } 225 | 226 | FUNCTION {bbl.phdthesis} 227 | { "PhD thesis" } 228 | 229 | FUNCTION {bbl.first} 230 | { "1st" } 231 | 232 | FUNCTION {bbl.second} 233 | { "2nd" } 234 | 235 | FUNCTION {bbl.third} 236 | { "3rd" } 237 | 238 | FUNCTION {bbl.fourth} 239 | { "4th" } 240 | 241 | FUNCTION {bbl.fifth} 242 | { "5th" } 243 | 244 | FUNCTION {bbl.st} 245 | { "st" } 246 | 247 | FUNCTION {bbl.nd} 248 | { "nd" } 249 | 250 | FUNCTION {bbl.rd} 251 | { "rd" } 252 | 253 | FUNCTION {bbl.th} 254 | { "th" } 255 | 256 | MACRO {jan} {"Jan."} 257 | 258 | MACRO {feb} {"Feb."} 259 | 260 | MACRO {mar} {"Mar."} 261 | 262 | MACRO {apr} {"Apr."} 263 | 264 | MACRO {may} {"May"} 265 | 266 | MACRO {jun} {"Jun."} 267 | 268 | MACRO {jul} {"Jul."} 269 | 270 | MACRO {aug} {"Aug."} 271 | 272 | MACRO {sep} {"Sep."} 273 | 274 | MACRO {oct} {"Oct."} 275 | 276 | MACRO {nov} {"Nov."} 277 | 278 | MACRO {dec} {"Dec."} 279 | 280 | FUNCTION {eng.ord} 281 | { duplicate$ "1" swap$ * 282 | #-2 #1 substring$ "1" = 283 | { bbl.th * } 284 | { duplicate$ #-1 #1 substring$ 285 | duplicate$ "1" = 286 | { pop$ bbl.st * } 287 | { duplicate$ "2" = 288 | { pop$ bbl.nd * } 289 | { "3" = 290 | { bbl.rd * } 291 | { bbl.th * } 292 | if$ 293 | } 294 | if$ 295 | } 296 | if$ 297 | } 298 | if$ 299 | } 300 | 301 | INTEGERS { nameptr namesleft numnames numtrunc } 302 | 303 | FUNCTION {format.names} 304 | { 's := 305 | #0 'numtrunc := 306 | #1 'nameptr := 307 | s num.names$ 'numnames := 308 | numnames 'namesleft := 309 | numnames #5 > 310 | { #3 'numtrunc := } 311 | {} 312 | if$ 313 | { namesleft #0 > } 314 | { s nameptr 315 | "{vv~}{ll}{, jj}{, f.}" format.name$ 316 | 't := 317 | nameptr #1 > 318 | { 319 | nameptr #1 - numtrunc = 320 | { 321 | #1 'namesleft := 322 | "others" 't := 323 | } 324 | {} 325 | if$ 326 | 327 | namesleft #1 > 328 | { ", " * t * } 329 | { 330 | numnames #2 > 331 | { "," * } 332 | 'skip$ 333 | if$ 334 | s nameptr "{ll}" format.name$ duplicate$ "others" = 335 | { 't := } 336 | { pop$ } 337 | if$ 338 | t "others" = 339 | { 340 | " {et~al.}" * 341 | } 342 | { " \& " * t * } 343 | if$ 344 | } 345 | if$ 346 | } 347 | 't 348 | if$ 349 | nameptr #1 + 'nameptr := 350 | namesleft #1 - 'namesleft := 351 | } 352 | while$ 353 | } 354 | 355 | FUNCTION {format.names.ed} 356 | { 's := 357 | #1 'nameptr := 358 | s num.names$ 'numnames := 359 | numnames 'namesleft := 360 | { namesleft #0 > } 361 | { s nameptr 362 | "{f.~}{vv~}{ll}{, jj}" 363 | format.name$ 364 | 't := 365 | nameptr #1 > 366 | { 367 | namesleft #1 > 368 | { ", " * t * } 369 | { 370 | numnames #2 > 371 | { "," * } 372 | 'skip$ 373 | if$ 374 | s nameptr "{ll}" format.name$ duplicate$ "others" = 375 | { 't := } 376 | { pop$ } 377 | if$ 378 | t "others" = 379 | { 380 | " {et~al.}" * 381 | } 382 | { " \& " * t * } 383 | if$ 384 | } 385 | if$ 386 | } 387 | 't 388 | if$ 389 | nameptr #1 + 'nameptr := 390 | namesleft #1 - 'namesleft := 391 | } 392 | while$ 393 | } 394 | 395 | FUNCTION {format.key} 396 | { empty$ 397 | { key field.or.null } 398 | { "" } 399 | if$ 400 | } 401 | 402 | FUNCTION {format.authors} 403 | { author empty$ 404 | { "" } 405 | { author format.names } 406 | if$ 407 | } 408 | 409 | FUNCTION {format.editors} 410 | { editor empty$ 411 | { "" } 412 | { editor format.names 413 | editor num.names$ #1 > 414 | { ", " * bbl.editors * } 415 | { ", " * bbl.editor * } 416 | if$ 417 | } 418 | if$ 419 | } 420 | 421 | FUNCTION {format.in.editors} 422 | { editor empty$ 423 | { "" } 424 | { editor format.names.ed 425 | } 426 | if$ 427 | } 428 | 429 | FUNCTION {format.note} 430 | { note empty$ 431 | { "" } 432 | { note #1 #1 substring$ 433 | duplicate$ "{" = 434 | 'skip$ 435 | { output.state mid.sentence = 436 | { "l" } 437 | { "u" } 438 | if$ 439 | change.case$ 440 | } 441 | if$ 442 | note #2 global.max$ substring$ * 443 | } 444 | if$ 445 | } 446 | 447 | FUNCTION {format.title} 448 | { title empty$ 449 | { "" } 450 | { title 451 | } 452 | if$ 453 | } 454 | 455 | FUNCTION {format.full.names} 456 | {'s := 457 | #1 'nameptr := 458 | s num.names$ 'numnames := 459 | numnames 'namesleft := 460 | { namesleft #0 > } 461 | { s nameptr 462 | "{vv~}{ll}" format.name$ 463 | 't := 464 | nameptr #1 > 465 | { 466 | namesleft #1 > 467 | { ", " * t * } 468 | { 469 | numnames #2 > 470 | { "," * } 471 | 'skip$ 472 | if$ 473 | s nameptr "{ll}" format.name$ duplicate$ "others" = 474 | { 't := } 475 | { pop$ } 476 | if$ 477 | t "others" = 478 | { 479 | " {et~al.}" * 480 | } 481 | { " \& " * t * } 482 | if$ 483 | } 484 | if$ 485 | } 486 | 't 487 | if$ 488 | nameptr #1 + 'nameptr := 489 | namesleft #1 - 'namesleft := 490 | } 491 | while$ 492 | } 493 | 494 | FUNCTION {author.editor.key.full} 495 | { author empty$ 496 | { editor empty$ 497 | { key empty$ 498 | { cite$ #1 #3 substring$ } 499 | 'key 500 | if$ 501 | } 502 | { editor format.full.names } 503 | if$ 504 | } 505 | { author format.full.names } 506 | if$ 507 | } 508 | 509 | FUNCTION {author.key.full} 510 | { author empty$ 511 | { key empty$ 512 | { cite$ #1 #3 substring$ } 513 | 'key 514 | if$ 515 | } 516 | { author format.full.names } 517 | if$ 518 | } 519 | 520 | FUNCTION {editor.key.full} 521 | { editor empty$ 522 | { key empty$ 523 | { cite$ #1 #3 substring$ } 524 | 'key 525 | if$ 526 | } 527 | { editor format.full.names } 528 | if$ 529 | } 530 | 531 | FUNCTION {make.full.names} 532 | { type$ "book" = 533 | type$ "inbook" = 534 | or 535 | 'author.editor.key.full 536 | { type$ "proceedings" = 537 | 'editor.key.full 538 | 'author.key.full 539 | if$ 540 | } 541 | if$ 542 | } 543 | 544 | FUNCTION {output.bibitem} 545 | { newline$ 546 | "\bibitem[{" write$ 547 | label write$ 548 | ")" make.full.names duplicate$ short.list = 549 | { pop$ } 550 | { * } 551 | if$ 552 | "}]{" * write$ 553 | cite$ write$ 554 | "}" write$ 555 | newline$ 556 | "" 557 | before.all 'output.state := 558 | } 559 | 560 | FUNCTION {format.archive} 561 | { archivePrefix empty$ 562 | { "" } 563 | { archivePrefix ":" *} 564 | if$ 565 | } 566 | 567 | FUNCTION {format.primaryClass} 568 | { primaryClass empty$ 569 | { "" } 570 | { " [" primaryClass * "]" *} 571 | if$ 572 | } 573 | 574 | FUNCTION {format.eprint} 575 | % Only print eprint info if no page info and no booktitle info -- 576 | % what we're really going for is print the eprint info only if there's 577 | % no "official" reference info to work with. 578 | { eprint empty$ 579 | pages empty$ not 580 | booktitle empty$ not or or 581 | { "" } 582 | { archive empty$ 583 | {"\href{http://arxiv.org/abs/" eprint * "}" * 584 | "{{\sffamily " * format.archive * eprint * 585 | format.primaryClass * "}}" *} 586 | {"\href{" archive * "/" * eprint * "}" * 587 | "{{\sffamily " * format.archive * eprint * 588 | format.primaryClass * "}}" *} 589 | if$ 590 | } 591 | if$ 592 | } 593 | 594 | 595 | FUNCTION {n.dashify} 596 | { 597 | 't := 598 | "" 599 | { t empty$ not } 600 | { t #1 #1 substring$ "-" = 601 | { t #1 #2 substring$ "--" = not 602 | { "--" * 603 | t #2 global.max$ substring$ 't := 604 | } 605 | { { t #1 #1 substring$ "-" = } 606 | { "-" * 607 | t #2 global.max$ substring$ 't := 608 | } 609 | while$ 610 | } 611 | if$ 612 | } 613 | { t #1 #1 substring$ * 614 | t #2 global.max$ substring$ 't := 615 | } 616 | if$ 617 | } 618 | while$ 619 | } 620 | 621 | FUNCTION {word.in} 622 | { bbl.in 623 | " " * } 624 | 625 | FUNCTION {format.date} 626 | { year duplicate$ empty$ 627 | { "empty year in " cite$ * "; set to ????" * warning$ 628 | pop$ "????" } 629 | 'skip$ 630 | if$ 631 | extra.label * 632 | before.all 'output.state := 633 | after.sentence 'output.state := 634 | } 635 | 636 | FUNCTION {format.btitle} 637 | { title 638 | } 639 | 640 | FUNCTION {tie.or.space.connect} 641 | { duplicate$ text.length$ #3 < 642 | { "~" } 643 | { " " } 644 | if$ 645 | swap$ * * 646 | } 647 | 648 | FUNCTION {either.or.check} 649 | { empty$ 650 | 'pop$ 651 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 652 | if$ 653 | } 654 | 655 | FUNCTION {format.bvolume} 656 | { volume empty$ 657 | { "" } 658 | { bbl.volume volume tie.or.space.connect 659 | series empty$ 660 | 'skip$ 661 | { bbl.of space.word * series * } 662 | if$ 663 | "volume and number" number either.or.check 664 | } 665 | if$ 666 | } 667 | 668 | FUNCTION {format.number.series} 669 | { volume empty$ 670 | { number empty$ 671 | { series field.or.null } 672 | { output.state mid.sentence = 673 | { bbl.number } 674 | { bbl.number capitalize } 675 | if$ 676 | number tie.or.space.connect 677 | series empty$ 678 | { "there's a number but no series in " cite$ * warning$ } 679 | { bbl.in space.word * series * } 680 | if$ 681 | } 682 | if$ 683 | } 684 | { "" } 685 | if$ 686 | } 687 | 688 | FUNCTION {is.num} 689 | { chr.to.int$ 690 | duplicate$ "0" chr.to.int$ < not 691 | swap$ "9" chr.to.int$ > not and 692 | } 693 | 694 | FUNCTION {extract.num} 695 | { duplicate$ 't := 696 | "" 's := 697 | { t empty$ not } 698 | { t #1 #1 substring$ 699 | t #2 global.max$ substring$ 't := 700 | duplicate$ is.num 701 | { s swap$ * 's := } 702 | { pop$ "" 't := } 703 | if$ 704 | } 705 | while$ 706 | s empty$ 707 | 'skip$ 708 | { pop$ s } 709 | if$ 710 | } 711 | 712 | FUNCTION {convert.edition} 713 | { edition extract.num "l" change.case$ 's := 714 | s "first" = s "1" = or 715 | { bbl.first 't := } 716 | { s "second" = s "2" = or 717 | { bbl.second 't := } 718 | { s "third" = s "3" = or 719 | { bbl.third 't := } 720 | { s "fourth" = s "4" = or 721 | { bbl.fourth 't := } 722 | { s "fifth" = s "5" = or 723 | { bbl.fifth 't := } 724 | { s #1 #1 substring$ is.num 725 | { s eng.ord 't := } 726 | { edition 't := } 727 | if$ 728 | } 729 | if$ 730 | } 731 | if$ 732 | } 733 | if$ 734 | } 735 | if$ 736 | } 737 | if$ 738 | t 739 | } 740 | 741 | FUNCTION {format.edition} 742 | { edition empty$ 743 | { "" } 744 | { output.state mid.sentence = 745 | { convert.edition "l" change.case$ " " * bbl.edition * } 746 | { convert.edition "t" change.case$ " " * bbl.edition * } 747 | if$ 748 | } 749 | if$ 750 | } 751 | 752 | INTEGERS { multiresult } 753 | 754 | FUNCTION {multi.page.check} 755 | { 't := 756 | #0 'multiresult := 757 | { multiresult not 758 | t empty$ not 759 | and 760 | } 761 | { t #1 #1 substring$ 762 | duplicate$ "-" = 763 | swap$ duplicate$ "," = 764 | swap$ "+" = 765 | or or 766 | { #1 'multiresult := } 767 | { t #2 global.max$ substring$ 't := } 768 | if$ 769 | } 770 | while$ 771 | multiresult 772 | } 773 | 774 | FUNCTION {string.length} 775 | { % Copied from "Taming the BeaST", by Nicolas Markey, Fig 4 776 | #1 'work.strlen := 777 | { duplicate$ duplicate$ #1 work.strlen substring$ = not } 778 | { work.strlen #1 + 'work.strlen := } 779 | while$ 780 | pop$ work.strlen 781 | } 782 | 783 | FUNCTION {first.page} 784 | { 't := 785 | "" 786 | { t empty$ not t #1 #1 substring$ "-" = not and } 787 | { t #1 #1 substring$ * 788 | t #2 global.max$ substring$ 't := 789 | } 790 | while$ 791 | % remove possible trailing plus sign 792 | duplicate$ duplicate$ string.length #1 substring$ "+" = 793 | { duplicate$ string.length #1 - #1 swap$ substring$ } 794 | { } 795 | if$ 796 | } 797 | 798 | FUNCTION {format.pages} 799 | { pages empty$ 800 | { "" } 801 | { pages first.page } 802 | if$ 803 | } 804 | 805 | FUNCTION {format.journal.pages} 806 | { pages empty$ 807 | 'skip$ 808 | { duplicate$ empty$ 809 | { pop$ format.pages } 810 | { 811 | ", " * 812 | pages first.page * 813 | } 814 | if$ 815 | } 816 | if$ 817 | } 818 | 819 | FUNCTION {format.vol.num.pages} 820 | { volume field.or.null 821 | } 822 | 823 | FUNCTION {format.chapter.pages} 824 | { chapter empty$ 825 | { "" } 826 | { type empty$ 827 | { bbl.chapter } 828 | { type "l" change.case$ } 829 | if$ 830 | chapter tie.or.space.connect 831 | } 832 | if$ 833 | } 834 | 835 | FUNCTION {format.in.ed.booktitle} 836 | { booktitle empty$ 837 | { "" } 838 | { editor empty$ 839 | { word.in booktitle * } 840 | { word.in booktitle * 841 | ", " * 842 | editor num.names$ #1 > 843 | { bbl.editors } 844 | { bbl.editor } 845 | if$ 846 | * " " * 847 | format.in.editors * 848 | } 849 | if$ 850 | } 851 | if$ 852 | } 853 | 854 | FUNCTION {format.thesis.type} 855 | { type empty$ 856 | 'skip$ 857 | { pop$ 858 | type "t" change.case$ 859 | } 860 | if$ 861 | } 862 | 863 | FUNCTION {format.tr.number} 864 | { type empty$ 865 | { bbl.techrep } 866 | 'type 867 | if$ 868 | number empty$ 869 | { "t" change.case$ } 870 | { number tie.or.space.connect } 871 | if$ 872 | } 873 | 874 | FUNCTION {format.article.crossref} 875 | { 876 | word.in 877 | " \cite{" * crossref * "}" * 878 | } 879 | 880 | FUNCTION {format.book.crossref} 881 | { volume empty$ 882 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 883 | word.in 884 | } 885 | { bbl.volume volume tie.or.space.connect 886 | bbl.of space.word * 887 | } 888 | if$ 889 | " \cite{" * crossref * "}" * 890 | } 891 | 892 | FUNCTION {format.incoll.inproc.crossref} 893 | { 894 | word.in 895 | " \cite{" * crossref * "}" * 896 | } 897 | 898 | FUNCTION {format.publisher} 899 | { publisher empty$ 900 | { "empty publisher in " cite$ * warning$ } 901 | 'skip$ 902 | if$ 903 | "" 904 | address empty$ publisher empty$ and 905 | 'skip$ 906 | { 907 | add.blank "(" * 908 | address empty$ 909 | 'skip$ 910 | { address * } 911 | if$ 912 | publisher empty$ 913 | 'skip$ 914 | { address empty$ 915 | 'skip$ 916 | { ": " * } 917 | if$ 918 | publisher * 919 | } 920 | if$ 921 | ")" * 922 | } 923 | if$ 924 | output 925 | } 926 | 927 | FUNCTION {format.edn.btitle} % Title should be on stack. 928 | { duplicate$ empty$ edition empty$ or 929 | 'skip$ 930 | { ", " * format.edition * } 931 | if$ 932 | } 933 | 934 | FUNCTION {format.ed.booktitle} % The title should be on the stack. 935 | { duplicate$ empty$ 936 | { "no book title in " cite$ * warning$ "" pop$ } 937 | { editor empty$ 938 | author empty$ or % Empty author means editor already given. 939 | 'format.edn.btitle 940 | { format.edn.btitle ", " * bbl.editor * " " * format.in.editors * } 941 | if$ 942 | } 943 | if$ 944 | } 945 | 946 | FUNCTION {format.full.book.spec} % The title should be on the stack. 947 | { series empty$ 948 | { format.ed.booktitle 949 | volume empty$ 950 | { number empty$ 951 | 'skip$ 952 | { " there's a number but no series in " cite$ * warning$ 953 | " No." number tie.or.space.connect * } 954 | if$ 955 | } 956 | { ", Vol." volume tie.or.space.connect * 957 | number empty$ 958 | 'skip$ 959 | {"Both volume and number fields in " * cite$ * warning$ } 960 | if$ 961 | } 962 | if$ 963 | } 964 | { volume empty$ 965 | { format.ed.booktitle ", " * series * 966 | number empty$ 967 | 'skip$ 968 | { " No." number tie.or.space.connect * } 969 | if$ 970 | } 971 | { series ", Vol." volume tie.or.space.connect * 972 | ", " * swap$ format.ed.booktitle * 973 | number empty$ 974 | 'skip$ 975 | {"Both volume and number fields in " * cite$ * warning$ } 976 | if$ 977 | } 978 | if$ 979 | } 980 | if$ 981 | } 982 | 983 | FUNCTION {maybe.doi.link.prepend} 984 | { % Expects some citation text to be on the stack 985 | doi empty$ 986 | { url empty$ 987 | { } 988 | { "\href{" url * "}{" * swap$ * } 989 | if$ 990 | } 991 | { "\href{http://dx.doi.org/" doi * "}{" * swap$ * } 992 | if$ 993 | } 994 | 995 | FUNCTION {maybe.doi.link.end} 996 | { % Expects some citation text to be on the stack 997 | doi empty$ url empty$ and 998 | { } 999 | { "}" * } 1000 | if$ 1001 | } 1002 | 1003 | FUNCTION {format.journal} 1004 | { 1005 | journal empty$ 1006 | { "" } % warning will be issued by output.check 1007 | { "\JournalTitle{" journal * "}" * } 1008 | if$ 1009 | } 1010 | 1011 | FUNCTION {article} 1012 | { output.bibitem 1013 | format.authors "author" output.check 1014 | author format.key output 1015 | format.date "year" output.check 1016 | crossref missing$ 1017 | { format.journal "journal" output.check 1018 | maybe.doi.link.prepend 1019 | format.vol.num.pages output 1020 | } 1021 | { format.article.crossref 1022 | maybe.doi.link.prepend 1023 | output.nonnull 1024 | format.pages output 1025 | } 1026 | if$ 1027 | format.journal.pages 1028 | maybe.doi.link.end 1029 | format.eprint output 1030 | format.note output 1031 | fin.entry 1032 | } 1033 | 1034 | FUNCTION {book} 1035 | { output.bibitem 1036 | author empty$ 1037 | { format.editors "author and editor" output.check 1038 | editor format.key output 1039 | } 1040 | { format.authors output.nonnull 1041 | crossref missing$ 1042 | { "author and editor" editor either.or.check } 1043 | 'skip$ 1044 | if$ 1045 | } 1046 | if$ 1047 | format.date "year" output.check 1048 | title format.full.book.spec output 1049 | format.publisher 1050 | format.pages output 1051 | format.eprint output 1052 | format.note output 1053 | fin.entry 1054 | } 1055 | 1056 | FUNCTION {booklet} 1057 | { output.bibitem 1058 | format.authors output 1059 | author format.key output 1060 | format.date "year" output.check 1061 | format.title "title" output.check 1062 | howpublished output 1063 | address output 1064 | format.eprint output 1065 | format.note output 1066 | fin.entry 1067 | } 1068 | 1069 | FUNCTION {inbook} 1070 | { output.bibitem 1071 | author empty$ 1072 | { format.editors "author and editor" output.check 1073 | editor format.key output 1074 | } 1075 | { format.authors output.nonnull 1076 | crossref missing$ 1077 | { "author and editor" editor either.or.check } 1078 | 'skip$ 1079 | if$ 1080 | } 1081 | if$ 1082 | format.date "year" output.check 1083 | title format.full.book.spec output 1084 | format.publisher 1085 | format.pages "pages" output.check 1086 | format.eprint output 1087 | format.note output 1088 | fin.entry 1089 | } 1090 | 1091 | FUNCTION {incollection} 1092 | { output.bibitem 1093 | format.authors "author" output.check 1094 | author format.key output 1095 | format.date "year" output.check 1096 | bbl.in " " * booktitle format.full.book.spec * 1097 | maybe.doi.link.prepend maybe.doi.link.end output 1098 | format.publisher 1099 | format.pages "pages" output.check 1100 | format.eprint output 1101 | format.note output 1102 | fin.entry 1103 | } 1104 | 1105 | FUNCTION {inproceedings} 1106 | { output.bibitem 1107 | format.authors "author" output.check 1108 | author format.key output % added 1109 | format.date "year" output.check 1110 | bbl.in " " * booktitle format.full.book.spec * 1111 | maybe.doi.link.prepend maybe.doi.link.end output 1112 | publisher empty$ 1113 | { organization output 1114 | address output 1115 | } 1116 | { organization output 1117 | format.publisher 1118 | } 1119 | if$ 1120 | format.pages output 1121 | format.eprint output 1122 | format.note output 1123 | fin.entry 1124 | } 1125 | 1126 | FUNCTION {conference} { inproceedings } 1127 | 1128 | FUNCTION {manual} 1129 | { output.bibitem 1130 | format.authors output 1131 | author format.key output 1132 | format.date "year" output.check 1133 | format.btitle "title" output.check 1134 | format.edition output 1135 | organization output 1136 | address output 1137 | format.eprint output 1138 | format.note output 1139 | fin.entry 1140 | } 1141 | 1142 | FUNCTION {mastersthesis} 1143 | { output.bibitem 1144 | format.authors "author" output.check 1145 | author format.key output 1146 | format.date "year" output.check 1147 | bbl.mthesis format.thesis.type output.nonnull 1148 | school "school" output.check 1149 | address output 1150 | format.eprint output 1151 | format.note output 1152 | fin.entry 1153 | } 1154 | 1155 | FUNCTION {misc} 1156 | { output.bibitem 1157 | format.authors output 1158 | author format.key output 1159 | format.date "year" output.check 1160 | format.title output 1161 | howpublished output 1162 | format.eprint output 1163 | format.note output 1164 | fin.entry 1165 | } 1166 | 1167 | FUNCTION {phdthesis} 1168 | { output.bibitem 1169 | format.authors "author" output.check 1170 | author format.key output 1171 | format.date "year" output.check 1172 | bbl.phdthesis format.thesis.type output.nonnull 1173 | school "school" output.check 1174 | address output 1175 | format.eprint output 1176 | format.note output 1177 | fin.entry 1178 | } 1179 | 1180 | FUNCTION {proceedings} 1181 | { output.bibitem 1182 | editor empty$ 1183 | { organization output 1184 | organization format.key output } 1185 | { format.editors output } 1186 | if$ 1187 | format.date "year" output.check 1188 | title format.full.book.spec output 1189 | publisher empty$ not % No need for warning if no pub. 1190 | { format.publisher } 1191 | { editor empty$ % For empty editor, organization was already given. 1192 | 'skip$ 1193 | { organization output } 1194 | if$ 1195 | address output 1196 | } 1197 | if$ 1198 | format.pages output 1199 | format.eprint output 1200 | format.note output 1201 | fin.entry 1202 | } 1203 | 1204 | FUNCTION {techreport} 1205 | { output.bibitem 1206 | format.authors "author" output.check 1207 | author format.key output 1208 | format.date "year" output.check 1209 | format.title "title" output.check 1210 | format.tr.number output.nonnull 1211 | institution "institution" output.check 1212 | address output 1213 | format.eprint output 1214 | format.note output 1215 | fin.entry 1216 | } 1217 | 1218 | FUNCTION {unpublished} 1219 | { output.bibitem 1220 | format.authors "author" output.check 1221 | author format.key output 1222 | format.date "year" output.check 1223 | format.eprint output 1224 | format.note "note" output.check 1225 | fin.entry 1226 | } 1227 | 1228 | FUNCTION {default.type} { misc } 1229 | 1230 | READ 1231 | 1232 | FUNCTION {sortify} 1233 | { purify$ 1234 | "l" change.case$ 1235 | } 1236 | 1237 | INTEGERS { len } 1238 | 1239 | FUNCTION {chop.word} 1240 | { 's := 1241 | 'len := 1242 | s #1 len substring$ = 1243 | { s len #1 + global.max$ substring$ } 1244 | 's 1245 | if$ 1246 | } 1247 | 1248 | FUNCTION {format.lab.names} 1249 | { 's := 1250 | s #1 "{vv~}{ll}" format.name$ 1251 | s num.names$ duplicate$ 1252 | #2 > 1253 | { pop$ 1254 | " {et~al.}" * 1255 | } 1256 | { #2 < 1257 | 'skip$ 1258 | { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 1259 | { 1260 | " {et~al.}" * 1261 | } 1262 | { " \& " * s #2 "{vv~}{ll}" format.name$ 1263 | * } 1264 | if$ 1265 | } 1266 | if$ 1267 | } 1268 | if$ 1269 | } 1270 | 1271 | FUNCTION {author.key.label} 1272 | { author empty$ 1273 | { key empty$ 1274 | { cite$ #1 #3 substring$ } 1275 | 'key 1276 | if$ 1277 | } 1278 | { author format.lab.names } 1279 | if$ 1280 | } 1281 | 1282 | FUNCTION {author.editor.key.label} 1283 | { author empty$ 1284 | { editor empty$ 1285 | { key empty$ 1286 | { cite$ #1 #3 substring$ } 1287 | 'key 1288 | if$ 1289 | } 1290 | { editor format.lab.names } 1291 | if$ 1292 | } 1293 | { author format.lab.names } 1294 | if$ 1295 | } 1296 | 1297 | FUNCTION {editor.key.label} 1298 | { editor empty$ 1299 | { key empty$ 1300 | { cite$ #1 #3 substring$ } 1301 | 'key 1302 | if$ 1303 | } 1304 | { editor format.lab.names } 1305 | if$ 1306 | } 1307 | 1308 | FUNCTION {calc.short.authors} 1309 | { type$ "book" = 1310 | type$ "inbook" = 1311 | or 1312 | 'author.editor.key.label 1313 | { type$ "proceedings" = 1314 | 'editor.key.label 1315 | 'author.key.label 1316 | if$ 1317 | } 1318 | if$ 1319 | 'short.list := 1320 | } 1321 | 1322 | FUNCTION {calc.label} 1323 | { calc.short.authors 1324 | short.list 1325 | "(" 1326 | * 1327 | year duplicate$ empty$ 1328 | { pop$ "????" } 1329 | 'skip$ 1330 | if$ 1331 | * 1332 | 'label := 1333 | } 1334 | 1335 | FUNCTION {sort.format.names} 1336 | { 's := 1337 | #1 'nameptr := 1338 | "" 1339 | s num.names$ 'numnames := 1340 | numnames #8 > 1341 | { s nameptr 1342 | "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" 1343 | format.name$ 't := 1344 | t sortify * 1345 | " " * 1346 | "zzzzz" * 1347 | } 1348 | { numnames 'namesleft := 1349 | { namesleft #0 > } 1350 | { s nameptr 1351 | "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" 1352 | format.name$ 't := 1353 | nameptr #1 > 1354 | { 1355 | " " * 1356 | namesleft #1 = t "others" = and 1357 | { "zzzzz" * } 1358 | { t sortify * } 1359 | if$ 1360 | } 1361 | { t sortify * } 1362 | if$ 1363 | nameptr #1 + 'nameptr := 1364 | namesleft #1 - 'namesleft := 1365 | } 1366 | while$ 1367 | } 1368 | if$ 1369 | } 1370 | 1371 | FUNCTION {sort.format.title} 1372 | { 't := 1373 | "A " #2 1374 | "An " #3 1375 | "The " #4 t chop.word 1376 | chop.word 1377 | chop.word 1378 | sortify 1379 | #1 global.max$ substring$ 1380 | } 1381 | 1382 | FUNCTION {author.sort} 1383 | { author empty$ 1384 | { key empty$ 1385 | { "to sort, need author or key in " cite$ * warning$ 1386 | "" 1387 | } 1388 | { key sortify } 1389 | if$ 1390 | } 1391 | { author sort.format.names } 1392 | if$ 1393 | } 1394 | 1395 | FUNCTION {author.editor.sort} 1396 | { author empty$ 1397 | { editor empty$ 1398 | { key empty$ 1399 | { "to sort, need author, editor, or key in " cite$ * warning$ 1400 | "" 1401 | } 1402 | { key sortify } 1403 | if$ 1404 | } 1405 | { editor sort.format.names } 1406 | if$ 1407 | } 1408 | { author sort.format.names } 1409 | if$ 1410 | } 1411 | 1412 | FUNCTION {editor.sort} 1413 | { editor empty$ 1414 | { key empty$ 1415 | { "to sort, need editor or key in " cite$ * warning$ 1416 | "" 1417 | } 1418 | { key sortify } 1419 | if$ 1420 | } 1421 | { editor sort.format.names } 1422 | if$ 1423 | } 1424 | 1425 | FUNCTION {presort} 1426 | { calc.label 1427 | label sortify 1428 | " " 1429 | * 1430 | type$ "book" = 1431 | type$ "inbook" = 1432 | or 1433 | 'author.editor.sort 1434 | { type$ "proceedings" = 1435 | 'editor.sort 1436 | 'author.sort 1437 | if$ 1438 | } 1439 | if$ 1440 | #1 entry.max$ substring$ 1441 | 'sort.label := 1442 | sort.label 1443 | * 1444 | " " 1445 | * 1446 | title field.or.null 1447 | sort.format.title 1448 | * 1449 | #1 entry.max$ substring$ 1450 | 'sort.key$ := 1451 | } 1452 | 1453 | ITERATE {presort} 1454 | 1455 | SORT 1456 | 1457 | STRINGS { last.label next.extra } 1458 | 1459 | INTEGERS { last.extra.num number.label } 1460 | 1461 | FUNCTION {initialize.extra.label.stuff} 1462 | { #0 int.to.chr$ 'last.label := 1463 | "" 'next.extra := 1464 | #0 'last.extra.num := 1465 | #0 'number.label := 1466 | } 1467 | 1468 | FUNCTION {forward.pass} 1469 | { last.label label = 1470 | { last.extra.num #1 + 'last.extra.num := 1471 | last.extra.num int.to.chr$ 'extra.label := 1472 | } 1473 | { "a" chr.to.int$ 'last.extra.num := 1474 | "" 'extra.label := 1475 | label 'last.label := 1476 | } 1477 | if$ 1478 | number.label #1 + 'number.label := 1479 | } 1480 | 1481 | FUNCTION {reverse.pass} 1482 | { next.extra "b" = 1483 | { "a" 'extra.label := } 1484 | 'skip$ 1485 | if$ 1486 | extra.label 'next.extra := 1487 | extra.label 1488 | duplicate$ empty$ 1489 | 'skip$ 1490 | { "{\natexlab{" swap$ * "}}" * } 1491 | if$ 1492 | 'extra.label := 1493 | label extra.label * 'label := 1494 | } 1495 | 1496 | EXECUTE {initialize.extra.label.stuff} 1497 | 1498 | ITERATE {forward.pass} 1499 | 1500 | REVERSE {reverse.pass} 1501 | 1502 | FUNCTION {bib.sort.order} 1503 | { sort.label 1504 | " " 1505 | * 1506 | year field.or.null sortify 1507 | * 1508 | " " 1509 | * 1510 | title field.or.null 1511 | sort.format.title 1512 | * 1513 | #1 entry.max$ substring$ 1514 | 'sort.key$ := 1515 | } 1516 | 1517 | ITERATE {bib.sort.order} 1518 | 1519 | SORT 1520 | 1521 | FUNCTION {begin.bib} 1522 | { preamble$ empty$ 1523 | 'skip$ 1524 | { preamble$ write$ newline$ } 1525 | if$ 1526 | "\begin{thebibliography}{}" 1527 | write$ newline$ 1528 | "\providecommand\natexlab[1]{#1}" 1529 | write$ newline$ 1530 | "\providecommand\JournalTitle[1]{#1}" 1531 | write$ newline$ 1532 | } 1533 | 1534 | EXECUTE {begin.bib} 1535 | 1536 | EXECUTE {init.state.consts} 1537 | 1538 | ITERATE {call.type$} 1539 | 1540 | FUNCTION {end.bib} 1541 | { newline$ 1542 | "\end{thebibliography}" write$ newline$ 1543 | } 1544 | 1545 | EXECUTE {end.bib} 1546 | -------------------------------------------------------------------------------- /yansf.bst: -------------------------------------------------------------------------------- 1 | % yansf.bst -- yet another NSF bibtex style file 2 | % Git SHA1 hash: $Id$ 3 | % Reference repository: https://github.com/pkgw/yahapj/ 4 | % 5 | % Based on the 2012/10/29 version Jonathan Irwin's nsf.bst [1], which in turn 6 | % came from jponew.bst [2] (Stefn LLewellyn Smith, Sarah Gille), which came 7 | % from Patrick Daly's AGU bibliography style, which was derived from 8 | % merlin.mbs. 9 | % 10 | % [1] https://www.cfa.harvard.edu/~jirwin/tex/nsf.bst 11 | % [2] http://www-pord.ucsd.edu/~sgille/how_to/proposal_prep.html 12 | % 13 | % Because this style file embeds links, your LaTeX file must use the 14 | % hyperref package. For non-butt-ugly links, try: 15 | % 16 | % \usepackage[breaklinks,colorlinks,urlcolor=blue,citecolor=blue,linkcolor=blue]{hyperref} 17 | % 18 | % Copyright notice: This work is dedicated to the public domain. You 19 | % have unlimited permission to copy, distribute, and modify it. 20 | % 21 | % For more information about this file and its provenance, consult 22 | % README.md in the Git repository from which it was obtained. You can 23 | % track these down using the SHA1 hash listed at the top of this file. 24 | % (Googling for the hash value should hopefully be sufficient.) 25 | 26 | ENTRY 27 | { address 28 | author 29 | archiveprefix 30 | booktitle 31 | chapter 32 | doi 33 | edition 34 | editor 35 | eprint 36 | howpublished 37 | institution 38 | isbn 39 | journal 40 | key 41 | month 42 | note 43 | number 44 | organization 45 | pages 46 | primaryClass 47 | publisher 48 | school 49 | series 50 | title 51 | type 52 | url 53 | volume 54 | year 55 | } 56 | {} 57 | { label extra.label sort.label short.list } 58 | 59 | INTEGERS { output.state before.all mid.sentence after.sentence after.block } 60 | 61 | FUNCTION {init.state.consts} 62 | { #0 'before.all := 63 | #1 'mid.sentence := 64 | #2 'after.sentence := 65 | #3 'after.block := 66 | } 67 | 68 | STRINGS { s t } 69 | 70 | FUNCTION {output.nonnull} 71 | { 's := 72 | output.state mid.sentence = 73 | { duplicate$ #-1 #2 substring$ "''" = 74 | { #-3 global.max$ substring$ 75 | ",'' " * write$ 76 | } 77 | { ", " * write$ } 78 | if$ 79 | } 80 | { output.state after.block = 81 | { add.period$ write$ 82 | newline$ 83 | "\newblock " write$ 84 | } 85 | { output.state before.all = 86 | 'write$ 87 | { add.period$ " " * write$ } 88 | if$ 89 | } 90 | if$ 91 | mid.sentence 'output.state := 92 | } 93 | if$ 94 | s 95 | } 96 | 97 | FUNCTION {output} 98 | { duplicate$ empty$ 99 | 'pop$ 100 | 'output.nonnull 101 | if$ 102 | } 103 | 104 | FUNCTION {output.check} 105 | { 't := 106 | duplicate$ empty$ 107 | { pop$ "empty " t * " in " * cite$ * warning$ } 108 | 'output.nonnull 109 | if$ 110 | } 111 | 112 | FUNCTION {fin.entry} 113 | { write$ 114 | newline$ 115 | } 116 | 117 | FUNCTION {new.block} 118 | { output.state before.all = 119 | 'skip$ 120 | { after.block 'output.state := } 121 | if$ 122 | } 123 | 124 | FUNCTION {new.sentence} 125 | { output.state after.block = 126 | 'skip$ 127 | { output.state before.all = 128 | 'skip$ 129 | { after.sentence 'output.state := } 130 | if$ 131 | } 132 | if$ 133 | } 134 | 135 | FUNCTION {add.blank} 136 | { " " * before.all 'output.state := 137 | } 138 | 139 | FUNCTION {not} 140 | { { #0 } 141 | { #1 } 142 | if$ 143 | } 144 | 145 | FUNCTION {and} 146 | { 'skip$ 147 | { pop$ #0 } 148 | if$ 149 | } 150 | 151 | FUNCTION {or} 152 | { { pop$ #1 } 153 | 'skip$ 154 | if$ 155 | } 156 | 157 | FUNCTION {new.block.checkb} 158 | { empty$ 159 | swap$ empty$ 160 | and 161 | 'skip$ 162 | 'new.block 163 | if$ 164 | } 165 | 166 | FUNCTION {field.or.null} 167 | { duplicate$ empty$ 168 | { pop$ "" } 169 | 'skip$ 170 | if$ 171 | } 172 | 173 | FUNCTION {emphasize} 174 | { duplicate$ empty$ 175 | { pop$ "" } 176 | { "{\em " swap$ * "\/}" * } 177 | if$ 178 | } 179 | 180 | FUNCTION {bolden} 181 | { duplicate$ empty$ 182 | { pop$ "" } 183 | { "{\bf " swap$ * "}" * } 184 | if$ 185 | } 186 | 187 | FUNCTION {capitalize} 188 | { "u" change.case$ "t" change.case$ } 189 | 190 | FUNCTION {space.word} 191 | { " " swap$ * " " * } 192 | 193 | % Here's how BibTeX does internationalization: 194 | 195 | FUNCTION {bbl.and} 196 | { "and"} 197 | 198 | FUNCTION {bbl.editors} 199 | { "eds." } 200 | 201 | FUNCTION {bbl.editor} 202 | { "ed." } 203 | 204 | FUNCTION {bbl.edby} 205 | { "edited by" } 206 | 207 | FUNCTION {bbl.edition} 208 | { "ed." } 209 | 210 | FUNCTION {bbl.volume} 211 | { "v." } 212 | 213 | FUNCTION {bbl.of} 214 | { "of" } 215 | 216 | FUNCTION {bbl.number} 217 | { "no." } 218 | 219 | FUNCTION {bbl.nr} 220 | { "no." } 221 | 222 | FUNCTION {bbl.in} 223 | { "in" } 224 | 225 | FUNCTION {bbl.pages} 226 | { "p." } 227 | 228 | FUNCTION {bbl.page} 229 | { "p." } 230 | 231 | FUNCTION {bbl.chapter} 232 | { "chap." } 233 | 234 | FUNCTION {bbl.techrep} 235 | { "Tech. Rep." } 236 | 237 | FUNCTION {bbl.mthesis} 238 | { "Master's thesis" } 239 | 240 | FUNCTION {bbl.phdthesis} 241 | { "Ph.D. thesis" } 242 | 243 | FUNCTION {bbl.first} 244 | { "1st" } 245 | 246 | FUNCTION {bbl.second} 247 | { "2nd" } 248 | 249 | FUNCTION {bbl.third} 250 | { "3rd" } 251 | 252 | FUNCTION {bbl.fourth} 253 | { "4th" } 254 | 255 | FUNCTION {bbl.fifth} 256 | { "5th" } 257 | 258 | FUNCTION {bbl.st} 259 | { "st" } 260 | 261 | FUNCTION {bbl.nd} 262 | { "nd" } 263 | 264 | FUNCTION {bbl.rd} 265 | { "rd" } 266 | 267 | FUNCTION {bbl.th} 268 | { "th" } 269 | 270 | MACRO {jan} {"Jan."} 271 | 272 | MACRO {feb} {"Feb."} 273 | 274 | MACRO {mar} {"Mar."} 275 | 276 | MACRO {apr} {"Apr."} 277 | 278 | MACRO {may} {"May"} 279 | 280 | MACRO {jun} {"Jun."} 281 | 282 | MACRO {jul} {"Jul."} 283 | 284 | MACRO {aug} {"Aug."} 285 | 286 | MACRO {sep} {"Sep."} 287 | 288 | MACRO {oct} {"Oct."} 289 | 290 | MACRO {nov} {"Nov."} 291 | 292 | MACRO {dec} {"Dec."} 293 | 294 | FUNCTION {eng.ord} 295 | { duplicate$ "1" swap$ * 296 | #-2 #1 substring$ "1" = 297 | { bbl.th * } 298 | { duplicate$ #-1 #1 substring$ 299 | duplicate$ "1" = 300 | { pop$ bbl.st * } 301 | { duplicate$ "2" = 302 | { pop$ bbl.nd * } 303 | { "3" = 304 | { bbl.rd * } 305 | { bbl.th * } 306 | if$ 307 | } 308 | if$ 309 | } 310 | if$ 311 | } 312 | if$ 313 | } 314 | 315 | INTEGERS { nameptr namesleft numnames } 316 | 317 | FUNCTION {format.names} 318 | { 's := 319 | #1 'nameptr := 320 | s num.names$ 'numnames := 321 | numnames 'namesleft := 322 | { namesleft #0 > } 323 | { s nameptr "{vv~}{ll}{, f{}}{, jj}" format.name$ 't := 324 | nameptr #1 > 325 | { 326 | namesleft #1 > 327 | { "; " * t * } 328 | { ";" * 329 | t "others" = 330 | { " et~al." * 331 | "et al. found in " cite$ * warning$ 332 | } 333 | { " " * t * } 334 | if$ 335 | } 336 | if$ 337 | } 338 | 't 339 | if$ 340 | nameptr #1 + 'nameptr := 341 | namesleft #1 - 'namesleft := 342 | } 343 | while$ 344 | } 345 | 346 | FUNCTION {format.names.ed} 347 | { format.names } 348 | FUNCTION {format.key} 349 | { empty$ 350 | { key field.or.null } 351 | { "" } 352 | if$ 353 | } 354 | 355 | FUNCTION {format.authors} 356 | { author empty$ 357 | { "" } 358 | { 359 | author format.names 360 | } 361 | if$ 362 | } 363 | 364 | FUNCTION {format.editors} 365 | { editor empty$ 366 | { "" } 367 | { 368 | editor format.names 369 | editor num.names$ #1 > 370 | { ", " * bbl.editors * } 371 | { ", " * bbl.editor * } 372 | if$ 373 | } 374 | if$ 375 | } 376 | 377 | FUNCTION {format.in.editors} 378 | { editor empty$ 379 | { "" } 380 | { editor format.names.ed 381 | editor num.names$ #1 > 382 | { ", " * bbl.editors * } 383 | { ", " * bbl.editor * } 384 | if$ 385 | } 386 | if$ 387 | } 388 | 389 | FUNCTION {format.isbn} 390 | { isbn empty$ 391 | { "" } 392 | { 393 | "ISBN " isbn * } 394 | if$ 395 | } 396 | 397 | FUNCTION {format.note} 398 | { note empty$ 399 | { "" } 400 | { note #1 #1 substring$ 401 | duplicate$ "{" = 402 | 'skip$ 403 | { output.state mid.sentence = 404 | { "l" } 405 | { "u" } 406 | if$ 407 | change.case$ 408 | } 409 | if$ 410 | note #2 global.max$ substring$ * 411 | } 412 | if$ 413 | } 414 | 415 | FUNCTION {format.title} 416 | { title empty$ 417 | { "" } 418 | { "``" title * "''" * 419 | } 420 | if$ 421 | } 422 | 423 | FUNCTION {format.full.names} 424 | {'s := 425 | #1 'nameptr := 426 | s num.names$ 'numnames := 427 | numnames 'namesleft := 428 | { namesleft #0 > } 429 | { s nameptr 430 | "{vv~}{ll}" format.name$ 't := 431 | nameptr #1 > 432 | { 433 | namesleft #1 > 434 | { ", " * t * } 435 | { 436 | numnames #2 > 437 | { "," * } 438 | 'skip$ 439 | if$ 440 | t "others" = 441 | { " et~al." * } 442 | { bbl.and space.word * t * } 443 | if$ 444 | } 445 | if$ 446 | } 447 | 't 448 | if$ 449 | nameptr #1 + 'nameptr := 450 | namesleft #1 - 'namesleft := 451 | } 452 | while$ 453 | } 454 | 455 | FUNCTION {format.url} 456 | { url empty$ 457 | { "" } 458 | { "\url{" url * "}" * } 459 | if$ 460 | } 461 | 462 | FUNCTION {author.editor.key.full} 463 | { author empty$ 464 | { editor empty$ 465 | { key empty$ 466 | { cite$ #1 #3 substring$ } 467 | 'key 468 | if$ 469 | } 470 | { editor format.full.names } 471 | if$ 472 | } 473 | { author format.full.names } 474 | if$ 475 | } 476 | 477 | FUNCTION {author.key.full} 478 | { author empty$ 479 | { key empty$ 480 | { cite$ #1 #3 substring$ } 481 | 'key 482 | if$ 483 | } 484 | { author format.full.names } 485 | if$ 486 | } 487 | 488 | FUNCTION {editor.key.full} 489 | { editor empty$ 490 | { key empty$ 491 | { cite$ #1 #3 substring$ } 492 | 'key 493 | if$ 494 | } 495 | { editor format.full.names } 496 | if$ 497 | } 498 | 499 | FUNCTION {make.full.names} 500 | { type$ "book" = 501 | type$ "inbook" = 502 | or 503 | 'author.editor.key.full 504 | { type$ "proceedings" = 505 | 'editor.key.full 506 | 'author.key.full 507 | if$ 508 | } 509 | if$ 510 | } 511 | 512 | FUNCTION {output.bibitem} 513 | { newline$ 514 | "\bibitem[" write$ 515 | label write$ 516 | ")" make.full.names duplicate$ short.list = 517 | { pop$ } 518 | { * } 519 | if$ 520 | "]{" * write$ 521 | cite$ write$ 522 | "}" write$ 523 | newline$ 524 | "" 525 | before.all 'output.state := 526 | } 527 | 528 | FUNCTION {n.dashify} 529 | { 't := 530 | "" 531 | { t empty$ not } 532 | { t #1 #1 substring$ "-" = 533 | { t #1 #2 substring$ "--" = not 534 | { "--" * 535 | t #2 global.max$ substring$ 't := 536 | } 537 | { { t #1 #1 substring$ "-" = } 538 | { "-" * 539 | t #2 global.max$ substring$ 't := 540 | } 541 | while$ 542 | } 543 | if$ 544 | } 545 | { t #1 #1 substring$ * 546 | t #2 global.max$ substring$ 't := 547 | } 548 | if$ 549 | } 550 | while$ 551 | } 552 | 553 | FUNCTION {word.in} 554 | { bbl.in capitalize 555 | " " * } 556 | 557 | FUNCTION {format.date} 558 | { year duplicate$ empty$ 559 | { "empty year in " cite$ * "; set to ????" * warning$ 560 | pop$ "????" } 561 | 'skip$ 562 | if$ 563 | extra.label * 564 | before.all 'output.state := 565 | ", " swap$ * 566 | } 567 | 568 | FUNCTION {format.btitle} 569 | { title emphasize 570 | } 571 | 572 | FUNCTION {tie.or.space.connect} 573 | { duplicate$ text.length$ #3 < 574 | { "~" } 575 | { " " } 576 | if$ 577 | swap$ * * 578 | } 579 | 580 | FUNCTION {either.or.check} 581 | { empty$ 582 | 'pop$ 583 | { "can't use both " swap$ * " fields in " * cite$ * warning$ } 584 | if$ 585 | } 586 | 587 | FUNCTION {format.bvolume} 588 | { volume empty$ 589 | { "" } 590 | { bbl.volume volume tie.or.space.connect 591 | series empty$ 592 | 'skip$ 593 | { bbl.of space.word * series emphasize * } 594 | if$ 595 | "volume and number" number either.or.check 596 | } 597 | if$ 598 | } 599 | 600 | FUNCTION {format.number.series} 601 | { volume empty$ 602 | { number empty$ 603 | { series field.or.null } 604 | { output.state mid.sentence = 605 | { bbl.number } 606 | { bbl.number capitalize } 607 | if$ 608 | number tie.or.space.connect 609 | series empty$ 610 | { "there's a number but no series in " cite$ * warning$ } 611 | { bbl.in space.word * series * } 612 | if$ 613 | } 614 | if$ 615 | } 616 | { "" } 617 | if$ 618 | } 619 | 620 | FUNCTION {is.num} 621 | { chr.to.int$ 622 | duplicate$ "0" chr.to.int$ < not 623 | swap$ "9" chr.to.int$ > not and 624 | } 625 | 626 | FUNCTION {extract.num} 627 | { duplicate$ 't := 628 | "" 's := 629 | { t empty$ not } 630 | { t #1 #1 substring$ 631 | t #2 global.max$ substring$ 't := 632 | duplicate$ is.num 633 | { s swap$ * 's := } 634 | { pop$ "" 't := } 635 | if$ 636 | } 637 | while$ 638 | s empty$ 639 | 'skip$ 640 | { pop$ s } 641 | if$ 642 | } 643 | 644 | FUNCTION {convert.edition} 645 | { edition extract.num "l" change.case$ 's := 646 | s "first" = s "1" = or 647 | { bbl.first 't := } 648 | { s "second" = s "2" = or 649 | { bbl.second 't := } 650 | { s "third" = s "3" = or 651 | { bbl.third 't := } 652 | { s "fourth" = s "4" = or 653 | { bbl.fourth 't := } 654 | { s "fifth" = s "5" = or 655 | { bbl.fifth 't := } 656 | { s #1 #1 substring$ is.num 657 | { s eng.ord 't := } 658 | { edition 't := } 659 | if$ 660 | } 661 | if$ 662 | } 663 | if$ 664 | } 665 | if$ 666 | } 667 | if$ 668 | } 669 | if$ 670 | t 671 | } 672 | 673 | FUNCTION {format.edition} 674 | { edition empty$ 675 | { "" } 676 | { output.state mid.sentence = 677 | { convert.edition "l" change.case$ " " * bbl.edition * } 678 | { convert.edition "t" change.case$ " " * bbl.edition * } 679 | if$ 680 | } 681 | if$ 682 | } 683 | 684 | INTEGERS { multiresult } 685 | 686 | FUNCTION {multi.page.check} 687 | { 't := 688 | #0 'multiresult := 689 | { multiresult not 690 | t empty$ not 691 | and 692 | } 693 | { t #1 #1 substring$ 694 | duplicate$ "-" = 695 | swap$ duplicate$ "," = 696 | swap$ "+" = 697 | or or 698 | { #1 'multiresult := } 699 | { t #2 global.max$ substring$ 't := } 700 | if$ 701 | } 702 | while$ 703 | multiresult 704 | } 705 | 706 | FUNCTION {format.pages} 707 | { pages empty$ 708 | { "" } 709 | { pages multi.page.check 710 | { bbl.pages pages n.dashify tie.or.space.connect } 711 | { bbl.page pages tie.or.space.connect } 712 | if$ 713 | } 714 | if$ 715 | } 716 | 717 | FUNCTION {format.journal.pages} 718 | { 719 | pages empty$ 720 | 'skip$ 721 | { duplicate$ empty$ 722 | { pop$ format.pages } 723 | { ", " * format.pages * } 724 | if$ 725 | } 726 | if$ 727 | } 728 | 729 | FUNCTION {format.vol.num.pages} 730 | { volume empty$ 731 | { "" } 732 | { bbl.volume volume tie.or.space.connect } 733 | if$ 734 | number empty$ 735 | 'skip$ 736 | { 737 | "(" number * ")" * * 738 | volume empty$ 739 | { "there's a number but no volume in " cite$ * warning$ } 740 | 'skip$ 741 | if$ 742 | } 743 | if$ 744 | } 745 | 746 | FUNCTION {format.chapter.pages} 747 | { chapter empty$ 748 | { "" } 749 | { type empty$ 750 | { bbl.chapter } 751 | { type "l" change.case$ } 752 | if$ 753 | chapter tie.or.space.connect 754 | } 755 | if$ 756 | } 757 | 758 | FUNCTION {format.in.ed.booktitle} 759 | { booktitle empty$ 760 | { "" } 761 | { editor empty$ 762 | { word.in booktitle emphasize * } 763 | { word.in format.in.editors * ", " * 764 | booktitle emphasize * } 765 | if$ 766 | } 767 | if$ 768 | } 769 | 770 | FUNCTION {format.thesis.type} 771 | { type empty$ 772 | 'skip$ 773 | { pop$ 774 | type "t" change.case$ 775 | } 776 | if$ 777 | } 778 | 779 | FUNCTION {format.tr.number} 780 | { type empty$ 781 | { bbl.techrep } 782 | 'type 783 | if$ 784 | number empty$ 785 | { "t" change.case$ } 786 | { number tie.or.space.connect } 787 | if$ 788 | } 789 | 790 | FUNCTION {format.article.crossref} 791 | { 792 | word.in 793 | " \cite{" * crossref * "}" * 794 | } 795 | 796 | FUNCTION {format.book.crossref} 797 | { volume empty$ 798 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ 799 | word.in 800 | } 801 | { bbl.volume capitalize 802 | volume tie.or.space.connect 803 | bbl.of space.word * 804 | } 805 | if$ 806 | " \cite{" * crossref * "}" * 807 | } 808 | 809 | FUNCTION {format.incoll.inproc.crossref} 810 | { 811 | word.in 812 | " \cite{" * crossref * "}" * 813 | } 814 | 815 | FUNCTION {format.publisher} 816 | { publisher empty$ 817 | { "empty publisher in " cite$ * warning$ } 818 | 'skip$ 819 | if$ 820 | "" 821 | address empty$ publisher empty$ and 822 | 'skip$ 823 | { 824 | publisher empty$ 825 | { address empty$ 826 | 'skip$ 827 | { address * } 828 | if$ 829 | } 830 | { publisher * 831 | address empty$ 832 | 'skip$ 833 | { ", " * address * } 834 | if$ 835 | } 836 | if$ 837 | } 838 | if$ 839 | output 840 | } 841 | 842 | STRINGS {oldname} 843 | 844 | FUNCTION {name.or.dash} 845 | { 's := 846 | oldname empty$ 847 | { s 'oldname := s } 848 | { s oldname = 849 | { "---" } 850 | { s 'oldname := s } 851 | if$ 852 | } 853 | if$ 854 | } 855 | 856 | FUNCTION {article} 857 | { output.bibitem 858 | format.authors "author" output.check 859 | author format.key output 860 | name.or.dash 861 | new.sentence 862 | format.title "title" output.check 863 | crossref missing$ 864 | { journal 865 | emphasize 866 | "journal" output.check 867 | format.vol.num.pages output 868 | format.date "year" output.check 869 | } 870 | { format.article.crossref output.nonnull 871 | format.date "year" output.check 872 | format.pages output 873 | } 874 | if$ 875 | format.journal.pages 876 | format.note output 877 | new.sentence 878 | format.url output 879 | fin.entry 880 | } 881 | 882 | FUNCTION {book} 883 | { output.bibitem 884 | author empty$ 885 | { format.editors "author and editor" output.check 886 | editor format.key output 887 | name.or.dash 888 | } 889 | { format.authors output.nonnull 890 | name.or.dash 891 | crossref missing$ 892 | { "author and editor" editor either.or.check } 893 | 'skip$ 894 | if$ 895 | } 896 | if$ 897 | new.sentence 898 | format.btitle "title" output.check 899 | crossref missing$ 900 | { format.bvolume output 901 | format.number.series output 902 | format.publisher 903 | } 904 | { 905 | format.book.crossref output.nonnull 906 | } 907 | if$ 908 | format.edition output 909 | format.isbn output 910 | format.date "year" output.check 911 | format.note output 912 | new.sentence 913 | format.url output 914 | fin.entry 915 | } 916 | 917 | FUNCTION {booklet} 918 | { output.bibitem 919 | format.authors output 920 | author format.key output 921 | name.or.dash 922 | new.sentence 923 | format.title "title" output.check 924 | howpublished output 925 | address output 926 | format.date "year" output.check 927 | format.note output 928 | new.sentence 929 | format.url output 930 | fin.entry 931 | } 932 | 933 | FUNCTION {inbook} 934 | { output.bibitem 935 | author empty$ 936 | { format.editors "author and editor" output.check 937 | editor format.key output 938 | name.or.dash 939 | } 940 | { format.authors output.nonnull 941 | name.or.dash 942 | crossref missing$ 943 | { "author and editor" editor either.or.check } 944 | 'skip$ 945 | if$ 946 | } 947 | if$ 948 | new.sentence 949 | format.btitle "title" output.check 950 | crossref missing$ 951 | { 952 | format.publisher 953 | format.bvolume output 954 | format.chapter.pages "chapter and pages" output.check 955 | format.number.series output 956 | } 957 | { 958 | format.chapter.pages "chapter and pages" output.check 959 | format.book.crossref output.nonnull 960 | } 961 | if$ 962 | format.edition output 963 | format.isbn output 964 | format.date "year" output.check 965 | format.pages "pages" output.check 966 | format.note output 967 | new.sentence 968 | format.url output 969 | fin.entry 970 | } 971 | 972 | FUNCTION {incollection} 973 | { output.bibitem 974 | format.authors "author" output.check 975 | author format.key output 976 | name.or.dash 977 | new.sentence 978 | format.title "title" output.check 979 | crossref missing$ 980 | { format.in.ed.booktitle "booktitle" output.check 981 | format.publisher 982 | format.bvolume output 983 | format.number.series output 984 | format.chapter.pages output 985 | format.edition output 986 | } 987 | { format.incoll.inproc.crossref output.nonnull 988 | format.chapter.pages output 989 | } 990 | if$ 991 | format.isbn output 992 | format.date "year" output.check 993 | format.pages "pages" output.check 994 | format.note output 995 | new.sentence 996 | format.url output 997 | fin.entry 998 | } 999 | 1000 | FUNCTION {inproceedings} 1001 | { output.bibitem 1002 | format.authors "author" output.check 1003 | author format.key output 1004 | name.or.dash 1005 | new.sentence 1006 | format.title "title" output.check 1007 | crossref missing$ 1008 | { format.in.ed.booktitle "booktitle" output.check 1009 | publisher empty$ 1010 | { organization output 1011 | address output 1012 | } 1013 | { organization output 1014 | format.publisher 1015 | } 1016 | if$ 1017 | format.bvolume output 1018 | format.number.series output 1019 | } 1020 | { format.incoll.inproc.crossref output.nonnull 1021 | } 1022 | if$ 1023 | format.isbn output 1024 | format.date "year" output.check 1025 | format.pages "pages" output.check 1026 | format.note output 1027 | new.sentence 1028 | format.url output 1029 | fin.entry 1030 | } 1031 | 1032 | FUNCTION {conference} { inproceedings } 1033 | 1034 | FUNCTION {manual} 1035 | { output.bibitem 1036 | format.authors output 1037 | author format.key output 1038 | name.or.dash 1039 | new.sentence 1040 | format.btitle "title" output.check 1041 | organization output 1042 | address output 1043 | format.edition output 1044 | format.date "year" output.check 1045 | format.note output 1046 | new.sentence 1047 | format.url output 1048 | fin.entry 1049 | } 1050 | 1051 | FUNCTION {mastersthesis} 1052 | { output.bibitem 1053 | format.authors "author" output.check 1054 | author format.key output 1055 | name.or.dash 1056 | new.sentence 1057 | format.btitle "title" output.check 1058 | bbl.mthesis format.thesis.type output.nonnull 1059 | school "school" output.check 1060 | address output 1061 | format.date "year" output.check 1062 | format.note output 1063 | new.sentence 1064 | format.url output 1065 | fin.entry 1066 | } 1067 | 1068 | FUNCTION {misc} 1069 | { output.bibitem 1070 | format.authors output 1071 | author format.key output 1072 | name.or.dash 1073 | new.sentence 1074 | format.title output 1075 | howpublished output 1076 | format.date "year" output.check 1077 | format.note output 1078 | new.sentence 1079 | format.url output 1080 | fin.entry 1081 | } 1082 | 1083 | FUNCTION {phdthesis} 1084 | { output.bibitem 1085 | format.authors "author" output.check 1086 | author format.key output 1087 | name.or.dash 1088 | new.sentence 1089 | format.btitle "title" output.check 1090 | bbl.phdthesis format.thesis.type output.nonnull 1091 | school "school" output.check 1092 | address output 1093 | format.date "year" output.check 1094 | format.note output 1095 | new.sentence 1096 | format.url output 1097 | fin.entry 1098 | } 1099 | 1100 | FUNCTION {proceedings} 1101 | { output.bibitem 1102 | format.editors output 1103 | editor format.key output 1104 | name.or.dash 1105 | new.sentence 1106 | format.btitle "title" output.check 1107 | format.bvolume output 1108 | format.number.series output 1109 | address output 1110 | organization output 1111 | publisher output 1112 | format.isbn output 1113 | format.date "year" output.check 1114 | format.note output 1115 | new.sentence 1116 | format.url output 1117 | fin.entry 1118 | } 1119 | 1120 | FUNCTION {techreport} 1121 | { output.bibitem 1122 | format.authors "author" output.check 1123 | author format.key output 1124 | name.or.dash 1125 | new.sentence 1126 | format.title "title" output.check 1127 | format.tr.number output.nonnull 1128 | institution "institution" output.check 1129 | address output 1130 | format.date "year" output.check 1131 | format.note output 1132 | new.sentence 1133 | format.url output 1134 | fin.entry 1135 | } 1136 | 1137 | FUNCTION {unpublished} 1138 | { output.bibitem 1139 | format.authors "author" output.check 1140 | author format.key output 1141 | name.or.dash 1142 | new.sentence 1143 | format.title "title" output.check 1144 | format.date "year" output.check 1145 | format.note "note" output.check 1146 | new.sentence 1147 | format.url output 1148 | fin.entry 1149 | } 1150 | 1151 | FUNCTION {default.type} { misc } 1152 | 1153 | READ 1154 | 1155 | FUNCTION {sortify} 1156 | { purify$ 1157 | "l" change.case$ 1158 | } 1159 | 1160 | INTEGERS { len } 1161 | 1162 | FUNCTION {chop.word} 1163 | { 's := 1164 | 'len := 1165 | s #1 len substring$ = 1166 | { s len #1 + global.max$ substring$ } 1167 | 's 1168 | if$ 1169 | } 1170 | 1171 | FUNCTION {format.lab.names} 1172 | { 's := 1173 | s #1 "{vv~}{ll}" format.name$ 1174 | s num.names$ duplicate$ 1175 | #2 > 1176 | { pop$ " et~al." * } 1177 | { #2 < 1178 | 'skip$ 1179 | { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = 1180 | { " et~al." * } 1181 | { "\&" 1182 | space.word * s #2 "{vv~}{ll}" format.name$ * } 1183 | if$ 1184 | } 1185 | if$ 1186 | } 1187 | if$ 1188 | } 1189 | 1190 | FUNCTION {author.key.label} 1191 | { author empty$ 1192 | { key empty$ 1193 | { cite$ #1 #3 substring$ } 1194 | 'key 1195 | if$ 1196 | } 1197 | { author format.lab.names } 1198 | if$ 1199 | } 1200 | 1201 | FUNCTION {author.editor.key.label} 1202 | { author empty$ 1203 | { editor empty$ 1204 | { key empty$ 1205 | { cite$ #1 #3 substring$ } 1206 | 'key 1207 | if$ 1208 | } 1209 | { editor format.lab.names } 1210 | if$ 1211 | } 1212 | { author format.lab.names } 1213 | if$ 1214 | } 1215 | 1216 | FUNCTION {editor.key.label} 1217 | { editor empty$ 1218 | { key empty$ 1219 | { cite$ #1 #3 substring$ } 1220 | 'key 1221 | if$ 1222 | } 1223 | { editor format.lab.names } 1224 | if$ 1225 | } 1226 | 1227 | FUNCTION {calc.short.authors} 1228 | { type$ "book" = 1229 | type$ "inbook" = 1230 | or 1231 | 'author.editor.key.label 1232 | { type$ "proceedings" = 1233 | 'editor.key.label 1234 | 'author.key.label 1235 | if$ 1236 | } 1237 | if$ 1238 | 'short.list := 1239 | } 1240 | 1241 | FUNCTION {calc.label} 1242 | { calc.short.authors 1243 | short.list 1244 | "(" 1245 | * 1246 | year duplicate$ empty$ 1247 | { pop$ "????" } 1248 | 'skip$ 1249 | if$ 1250 | * 1251 | 'label := 1252 | } 1253 | 1254 | FUNCTION {sort.format.names} 1255 | { 's := 1256 | #1 'nameptr := 1257 | "" 1258 | s num.names$ 'numnames := 1259 | numnames 'namesleft := 1260 | { namesleft #0 > } 1261 | { s nameptr 1262 | "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" 1263 | format.name$ 't := 1264 | nameptr #1 > 1265 | { 1266 | " " * 1267 | namesleft #1 = t "others" = and 1268 | { "zzzzz" * } 1269 | { t sortify * } 1270 | if$ 1271 | } 1272 | { t sortify * } 1273 | if$ 1274 | nameptr #1 + 'nameptr := 1275 | namesleft #1 - 'namesleft := 1276 | } 1277 | while$ 1278 | } 1279 | 1280 | FUNCTION {sort.format.title} 1281 | { 't := 1282 | "A " #2 1283 | "An " #3 1284 | "The " #4 t chop.word 1285 | chop.word 1286 | chop.word 1287 | sortify 1288 | #1 global.max$ substring$ 1289 | } 1290 | 1291 | FUNCTION {author.sort} 1292 | { author empty$ 1293 | { key empty$ 1294 | { "to sort, need author or key in " cite$ * warning$ 1295 | "" 1296 | } 1297 | { key sortify } 1298 | if$ 1299 | } 1300 | { author sort.format.names } 1301 | if$ 1302 | } 1303 | 1304 | FUNCTION {author.editor.sort} 1305 | { author empty$ 1306 | { editor empty$ 1307 | { key empty$ 1308 | { "to sort, need author, editor, or key in " cite$ * warning$ 1309 | "" 1310 | } 1311 | { key sortify } 1312 | if$ 1313 | } 1314 | { editor sort.format.names } 1315 | if$ 1316 | } 1317 | { author sort.format.names } 1318 | if$ 1319 | } 1320 | 1321 | FUNCTION {editor.sort} 1322 | { editor empty$ 1323 | { key empty$ 1324 | { "to sort, need editor or key in " cite$ * warning$ 1325 | "" 1326 | } 1327 | { key sortify } 1328 | if$ 1329 | } 1330 | { editor sort.format.names } 1331 | if$ 1332 | } 1333 | 1334 | FUNCTION {presort} 1335 | { calc.label 1336 | label sortify 1337 | " " 1338 | * 1339 | type$ "book" = 1340 | type$ "inbook" = 1341 | or 1342 | 'author.editor.sort 1343 | { type$ "proceedings" = 1344 | 'editor.sort 1345 | 'author.sort 1346 | if$ 1347 | } 1348 | if$ 1349 | #1 entry.max$ substring$ 1350 | 'sort.label := 1351 | sort.label 1352 | * 1353 | " " 1354 | * 1355 | title field.or.null 1356 | sort.format.title 1357 | * 1358 | #1 entry.max$ substring$ 1359 | 'sort.key$ := 1360 | } 1361 | 1362 | ITERATE {presort} 1363 | 1364 | SORT 1365 | 1366 | STRINGS { last.label next.extra } 1367 | 1368 | INTEGERS { last.extra.num number.label } 1369 | 1370 | FUNCTION {initialize.extra.label.stuff} 1371 | { #0 int.to.chr$ 'last.label := 1372 | "" 'next.extra := 1373 | #0 'last.extra.num := 1374 | #0 'number.label := 1375 | } 1376 | 1377 | FUNCTION {forward.pass} 1378 | { last.label label = 1379 | { last.extra.num #1 + 'last.extra.num := 1380 | last.extra.num int.to.chr$ 'extra.label := 1381 | } 1382 | { "a" chr.to.int$ 'last.extra.num := 1383 | "" 'extra.label := 1384 | label 'last.label := 1385 | } 1386 | if$ 1387 | number.label #1 + 'number.label := 1388 | } 1389 | 1390 | FUNCTION {reverse.pass} 1391 | { next.extra "b" = 1392 | { "a" 'extra.label := } 1393 | 'skip$ 1394 | if$ 1395 | extra.label 'next.extra := 1396 | extra.label 1397 | duplicate$ empty$ 1398 | 'skip$ 1399 | { "{\natexlab{" swap$ * "}}" * } 1400 | if$ 1401 | 'extra.label := 1402 | label extra.label * 'label := 1403 | } 1404 | 1405 | EXECUTE {initialize.extra.label.stuff} 1406 | 1407 | ITERATE {forward.pass} 1408 | 1409 | REVERSE {reverse.pass} 1410 | 1411 | FUNCTION {bib.sort.order} 1412 | { sort.label 1413 | " " 1414 | * 1415 | year field.or.null sortify 1416 | * 1417 | " " 1418 | * 1419 | title field.or.null 1420 | sort.format.title 1421 | * 1422 | #1 entry.max$ substring$ 1423 | 'sort.key$ := 1424 | } 1425 | 1426 | ITERATE {bib.sort.order} 1427 | 1428 | SORT 1429 | 1430 | FUNCTION {begin.bib} 1431 | { preamble$ empty$ 1432 | 'skip$ 1433 | { preamble$ write$ newline$ } 1434 | if$ 1435 | "\begin{thebibliography}{" number.label int.to.str$ * "}" * 1436 | write$ newline$ 1437 | "\providecommand\natexlab[1]{#1}" 1438 | write$ newline$ 1439 | "\providecommand\JournalTitle[1]{#1}" 1440 | write$ newline$ 1441 | } 1442 | 1443 | EXECUTE {begin.bib} 1444 | 1445 | EXECUTE {init.state.consts} 1446 | 1447 | ITERATE {call.type$} 1448 | 1449 | FUNCTION {end.bib} 1450 | { newline$ 1451 | "\end{thebibliography}" write$ newline$ 1452 | } 1453 | 1454 | EXECUTE {end.bib} 1455 | --------------------------------------------------------------------------------