% Copyright (c) 2006-2011 Philipp Lehman. % 2012-2018 Philip Kime, Audrey Boruvka, Joseph Wright % % Permission is granted to copy, distribute and/or modify this % software under the terms of the LaTeX Project Public License % (LPPL), version 1.3c. % % This software is provided 'as is', without warranty of any kind, % either expressed or implied, including, but not limited to, the % implied warranties of merchantability and fitness for a % particular purpose. % ------------------------------------------------------------------- % Initialization % ------------------------------------------------------------------- ENTRY { % special fields fakeset entryset entrysubtype execute hyphenation keywords label langid langidopts options presort shorthand sortkey sortname sorttitle sortyear xref % data fields abstract addendum address afterword annotation annote annotator author authortype bookauthor booksubtitle booktitle booktitleaddon chapter commentator date doi edition editor editora editorb editorc editortype editoratype editorbtype editorctype eid eprint eprintclass eprinttype eventdate eventtitle eventtitleaddon file foreword gender howpublished indexsorttitle indextitle institution introduction isan isbn ismn isrn issn issue issuetitle issuesubtitle iswc journal journaltitle journalsubtitle language library location bookpagination mainsubtitle maintitle maintitleaddon month nameaddon note number organization origlanguage origlocation origpublisher origtitle origdate pages pagetotal pagination part pdf pubstate reprinttitle holder publisher school series shortauthor shorteditor shorthandintro shortjournal shortseries shorttitle subtitle title titleaddon translator type url urldate venue version volume volumes year % aliases archiveprefix primaryclass % custom fields namea nameb namec nameatype namebtype namectype lista listb listc listd liste listf usera userb userc userd usere userf verba verbb verbc } { skipbib skiplos skiplab useauthor useeditor usetranslator useprefix singletitle } { entryoptions labelhash namehash fullhash dateyear dateendyear extradate labelalpha extraalpha label.name label.year sortinit sortkey.nosort sortkey.name sortkey.year sortkey.title sortkey.alpha sort.year sort.alph warningmsg } INTEGERS { ctrl.debug ctrl.bibtex8 ctrl.maxline ctrl.sorting ctrl.cssort ctrl.maxcitenames ctrl.mincitenames ctrl.maxsortnames ctrl.minsortnames ctrl.nohashothers ctrl.nosortothers ctrl.maxalphanames ctrl.minalphanames ctrl.useauthor ctrl.useeditor ctrl.usetranslator ctrl.useprefix ctrl.labelalpha ctrl.singletitle ctrl.labeldate citecount tempctra tempctrb tempctrc resvctra resvctrb resvctrc last.extra.num } STRINGS { ctrl.alphaothers ctrl.sortalphaothers ctrl.sortstr templist tempstrga tempstrgb resvstrga resvstrgb resvstrgc last.name last.hash last.year last.extra } FUNCTION {initialize} { "$Revision: 3.20 $" #12 entry.max$ substring$ #-3 entry.max$ substring$ "Biblatex version: " swap$ * top$ #0 'ctrl.debug := #0 'ctrl.labelalpha := #0 'ctrl.labeldate := #0 'ctrl.singletitle := #0 'ctrl.sorting := #1 'ctrl.useauthor := #1 'ctrl.useeditor := #0 'ctrl.usetranslator := #0 'ctrl.useprefix := #99 'ctrl.maxcitenames := #1 'ctrl.mincitenames := #99 'ctrl.maxsortnames := #1 'ctrl.minsortnames := #0 'ctrl.nohashothers := #0 'ctrl.nosortothers := #1 'ctrl.minalphanames := #3 'ctrl.maxalphanames := #79 'ctrl.maxline := "+" 'ctrl.alphaothers := " " 'ctrl.sortalphaothers := "nty" 'ctrl.sortstr := } % ------------------------------------------------------------------- % Strings % ------------------------------------------------------------------- MACRO {jan} { "01" } MACRO {feb} { "02" } MACRO {mar} { "03" } MACRO {apr} { "04" } MACRO {may} { "05" } MACRO {jun} { "06" } MACRO {jul} { "07" } MACRO {aug} { "08" } MACRO {sep} { "09" } MACRO {oct} { "10" } MACRO {nov} { "11" } MACRO {dec} { "12" } % ------------------------------------------------------------------- % Generic functions % ------------------------------------------------------------------- FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {ctrl:control} { type$ "control" = } FUNCTION {ctrl:set} { type$ "set" = } FUNCTION {ctrl:skiplab} { ctrl:control skiplab or ctrl:set % fakeset empty$ and or } FUNCTION {ctrl:labelalpha} { ctrl.labelalpha ctrl:skiplab not and } FUNCTION {ctrl:labeldate} { ctrl.labeldate ctrl:skiplab not and } FUNCTION {wrap:braces} { duplicate$ empty$ { pop$ "{}" } { "{" swap$ * "}" * } if$ } FUNCTION {combine:key:value} { "=" * swap$ wrap:braces * "," * } FUNCTION {delimiter.1} { ctrl.bibtex8 { "0" } { " " } if$ } FUNCTION {delimiter.2} { ctrl.bibtex8 { "1" } { " " } if$ } FUNCTION {delimiter.3} { ctrl.bibtex8 { "2" } { " " } if$ } FUNCTION {open.ended} { "9999" } FUNCTION {maxline} { duplicate$ empty$ 'skip$ { #1 ctrl.maxline substring$ } if$ } FUNCTION {truncate} { duplicate$ empty$ { pop$ "" } { #1 entry.max$ substring$ } if$ } FUNCTION {purify} { duplicate$ empty$ { pop$ "" } { purify$ ctrl.bibtex8 ctrl.cssort and 'skip$ { "l" change.case$ } if$ truncate } if$ } FUNCTION {normalize} { duplicate$ empty$ { pop$ "" } { ctrl.bibtex8 ctrl.cssort and 'skip$ { "l" change.case$ } if$ truncate } if$ } FUNCTION {enquote} { "'" swap$ * "'" * } FUNCTION {str:length} { #1 'resvctra := { duplicate$ duplicate$ #1 resvctra substring$ = not } { resvctra #1 + 'resvctra := } while$ pop$ resvctra } FUNCTION {str:replace} { 'resvstrga := 'resvstrgb := 'resvstrgc := resvstrgb str:length 'resvctra := "" { resvstrgc empty$ not } { resvstrgc #1 resvctra substring$ resvstrgb = { resvstrga * resvstrgc #1 resvctra + global.max$ substring$ 'resvstrgc := } { resvstrgc #1 #1 substring$ * resvstrgc #2 global.max$ substring$ 'resvstrgc := } if$ } while$ } FUNCTION {bol.to.int} { "true" = { #1 } { #0 } if$ } FUNCTION {str.to.int} { 'resvstrga := resvstrga text.length$ 'resvctra := #1 'resvctrb := #0 { resvctrb resvctra > not } { 'resvctrc := resvstrga resvctrb #1 substring$ chr.to.int$ "0" chr.to.int$ - #0 { resvctrc #0 > } { resvctrc #1 - 'resvctrc := #10 + } while$ + resvctrb #1 + 'resvctrb := } while$ } FUNCTION {andothers} { duplicate$ num.names$ "{ff}{vv}{ll}{jj}" format.name$ "others" = } FUNCTION {push} { duplicate$ empty$ { pop$ "" } { truncate } if$ } FUNCTION {push:cite} { cite$ empty$ { "Missing citation key" warning$ "" } { cite$ } if$ } FUNCTION {push:presort} { presort empty$ { "mm" } { presort purify #1 #2 substring$ "l" change.case$ } if$ } FUNCTION {push:fullname} { author empty$ not useauthor and { author } { editor empty$ not useeditor and { editor } { translator empty$ not usetranslator and { translator } { "" } if$ } if$ } if$ } FUNCTION {push:labelname:translator} { translator empty$ not usetranslator and { "translator" } { "" } if$ } FUNCTION {push:labelname:editor} { useeditor { shorteditor empty$ { editor empty$ { push:labelname:translator } { "editor" } if$ } { "shorteditor" } if$ } { push:labelname:translator } if$ } FUNCTION {push:shortname:translator} { translator empty$ not usetranslator and { translator } { "" } if$ } FUNCTION {push:shortname:editor} { useeditor { shorteditor empty$ { editor empty$ { push:shortname:translator } { editor } if$ } { shorteditor } if$ } { push:shortname:translator } if$ } FUNCTION {push:shortname} { useauthor { shortauthor empty$ { author empty$ { push:shortname:editor } { author } if$ } { shortauthor } if$ } { push:shortname:editor } if$ } FUNCTION {push:sorttitle} { sorttitle empty$ { title empty$ { "" } { title } if$ } { sorttitle } if$ push } FUNCTION {shortname:hash} { 'tempctrc := 'templist := #1 'tempctra := templist num.names$ 'tempctrb := templist andothers { tempctrb #1 - 'tempctrb := } 'skip$ if$ tempctrc #0 = { tempctrb 'tempctrc := } { tempctrb tempctrc > { ctrl.mincitenames 'tempctrc := } { ctrl.maxcitenames 'tempctrc := } if$ } if$ "" { tempctra tempctrc > not tempctrb #0 > and } { templist tempctra "{vv{}}{ll{}}{ff{}}{jj{}}" format.name$ * tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ templist andothers tempctrb #0 > or ctrl.nohashothers not and { "+" * } 'skip$ if$ } FUNCTION {push:name:namehash} { push:shortname duplicate$ empty$ { pop$ push:sorttitle duplicate$ empty$ { pop$ push:cite purify } 'skip$ if$ } { ctrl.maxcitenames shortname:hash } if$ } FUNCTION {push:name:fullhash} { push:fullname duplicate$ empty$ { pop$ push:sorttitle duplicate$ empty$ { pop$ push:cite purify } 'skip$ if$ } { #0 shortname:hash } if$ } FUNCTION {push:labelname} { useauthor { shortauthor empty$ { author empty$ { push:labelname:editor } { "author" } if$ } { "shortauthor" } if$ } { push:labelname:editor } if$ } FUNCTION {check:sortname} { sortname empty$ 'skip$ { pop$ sortname } if$ } FUNCTION {warning} { "\item " swap$ * warningmsg empty$ 'skip$ { warningmsg " " * swap$ * } if$ 'warningmsg := } FUNCTION {warning:invalid} { "Invalid format of field " swap$ enquote * warning } FUNCTION {warning:duplicate} { "Can't use " swap$ enquote * " + " * swap$ enquote * warning } FUNCTION {pad.number} { 'tempctra := duplicate$ empty$ { pop$ "" } 'skip$ if$ { duplicate$ text.length$ tempctra < } { "0" swap$ * } while$ } FUNCTION {extract.number} { purify$ 'tempstrga := "" { tempstrga empty$ not } { tempstrga #1 #1 substring$ chr.to.int$ duplicate$ #47 > swap$ #58 < and { tempstrga #1 #1 substring$ * } 'skip$ if$ tempstrga #2 global.max$ substring$ 'tempstrga := } while$ #1 #9 substring$ } FUNCTION {format.range} { 'tempstrga := "" { tempstrga empty$ not } { tempstrga #1 #1 substring$ "-" = { "\bibrangedash " * tempstrga #2 global.max$ substring$ 'tempstrga := { tempstrga #1 #1 substring$ "-" = } { tempstrga #2 global.max$ substring$ 'tempstrga := } while$ } { tempstrga #1 #1 substring$ * tempstrga #2 global.max$ substring$ 'tempstrga := } if$ } while$ } FUNCTION {format:name:part} { "\~" "[[[TILDE ACCENT]]]" str:replace "~" "\bibnamedelima " str:replace "[[[TILDE ACCENT]]]" "\~" str:replace } FUNCTION {format:name:initials} { "\." "[[[DOT ACCENT]]]" str:replace ".-" "\bibinithyphendelim " str:replace ".~" "\bibinitperiod\bibinitdelim " str:replace ". " "\bibinitperiod\bibinitdelim " str:replace "." "\bibinitperiod" str:replace "[[[DOT ACCENT]]]" "\." str:replace } FUNCTION {is.number} { #1 { #0 > } { duplicate$ #1 #1 substring$ chr.to.int$ duplicate$ #47 > swap$ #58 < and { #2 global.max$ substring$ duplicate$ empty$ { #0 } { #1 } if$ } { #0 } if$ } while$ empty$ } FUNCTION {split.date:invalid} { #0 'tempctra := } FUNCTION {split.date:check.day} { duplicate$ empty$ 'skip$ { duplicate$ is.number { duplicate$ str.to.int duplicate$ #0 > swap$ #32 < and { duplicate$ text.length$ #2 < { "0" swap$ * } 'skip$ if$ } { pop$ "" split.date:invalid } if$ } { pop$ "" split.date:invalid } if$ } if$ } FUNCTION {split.date:check.month} { duplicate$ empty$ 'skip$ { duplicate$ is.number { duplicate$ str.to.int duplicate$ #0 > swap$ #13 < and { duplicate$ text.length$ #2 < { "0" swap$ * } 'skip$ if$ } { pop$ "" split.date:invalid } if$ } { pop$ "" split.date:invalid } if$ } if$ } FUNCTION {split.date:check.year} { duplicate$ empty$ 'skip$ { duplicate$ is.number { duplicate$ "0" = 'skip$ { duplicate$ duplicate$ str.to.int #0 > swap$ text.length$ #5 < and 'skip$ { pop$ "" split.date:invalid } if$ } if$ } { pop$ "" split.date:invalid } if$ } if$ } FUNCTION {split.date:check.date} { duplicate$ empty$ 'skip$ { duplicate$ duplicate$ text.length$ #0 > swap$ text.length$ #11 < and 'skip$ { pop$ "" split.date:invalid } if$ } if$ } FUNCTION {split.date:check.range} { duplicate$ empty$ 'skip$ { duplicate$ duplicate$ text.length$ #0 > swap$ text.length$ #22 < and 'skip$ { pop$ "" split.date:invalid } if$ } if$ } FUNCTION {split.date:date:part} { 'tempstrgb := "" { tempstrgb #1 #1 substring$ duplicate$ empty$ { pop$ #0 } { "-" = not } if$ } { tempstrgb #1 #1 substring$ * tempstrgb #2 global.max$ substring$ 'tempstrgb := } while$ tempstrgb #2 global.max$ substring$ } FUNCTION {split.date:date} { duplicate$ empty$ { pop$ "" "" "" } { split.date:date:part swap$ split.date:check.year swap$ split.date:date:part swap$ split.date:check.month swap$ split.date:date:part pop$ split.date:check.day } if$ } FUNCTION {split.date:range} { duplicate$ empty$ { pop$ "" "" } { 'tempstrgb := "" #0 'tempctrb := { tempstrgb #1 #1 substring$ duplicate$ empty$ { pop$ #0 } { "/" = { #1 'tempctrb := #0 } { #1 } if$ } if$ } { tempstrgb #1 #1 substring$ * tempstrgb #2 global.max$ substring$ 'tempstrgb := } while$ split.date:check.date tempstrgb #2 global.max$ substring$ duplicate$ empty$ tempctrb #1 = and { pop$ open.ended } 'skip$ if$ split.date:check.date } if$ } FUNCTION {split.date} { duplicate$ empty$ { pop$ pop$ "" "" "" "" "" "" } { swap$ 'templist := #1 'tempctra := split.date:check.range split.date:range swap$ 'tempstrga := split.date:date tempstrga split.date:date tempctra 'skip$ { pop$ pop$ pop$ pop$ pop$ pop$ "" "" "" "" "" "" templist warning:invalid } if$ } if$ } % ------------------------------------------------------------------- % Sorting % ------------------------------------------------------------------- FUNCTION {sortkey:name:format} { 'templist := #1 'tempctra := templist num.names$ 'tempctrb := templist andothers { tempctrb #1 - 'tempctrb := } 'skip$ if$ tempctrb ctrl.maxsortnames > { ctrl.minsortnames 'tempctrc := } { ctrl.maxsortnames 'tempctrc := } if$ "" { duplicate$ text.length$ entry.max$ #50 - < tempctra tempctrc > not and tempctrb #0 > and } { useprefix { templist tempctra "{vv}" format.name$ duplicate$ empty$ { pop$ "" } { "u" change.case$ "t" change.case$ delimiter.3 * } if$ templist tempctra "{ll}{" delimiter.3 * "ff}{" delimiter.3 * * "jj}" * format.name$ * } { templist tempctra "{ll}{" delimiter.3 * "ff}{" delimiter.3 * * "vv}{" delimiter.3 * * "jj}" * format.name$ } if$ tempctra #1 > { delimiter.2 swap$ * } 'skip$ if$ * tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ templist andothers tempctrb #0 > or ctrl.nosortothers not and { delimiter.2 * "zzzz" * } 'skip$ if$ } FUNCTION {sortkey:init:label} { push:shortname duplicate$ empty$ { pop$ push:sorttitle } { check:sortname sortkey:name:format } if$ purify 'sortkey.name := sortyear empty$ { dateyear dateendyear empty$ 'skip$ { dateyear dateendyear = 'skip$ { dateendyear open.ended = 'skip$ { "-" * dateendyear * } if$ } if$ } if$ } { sortyear } if$ purify 'sortkey.year := push:sorttitle purify 'sortkey.title := } FUNCTION {sortkey:init:main} { push:fullname duplicate$ empty$ { pop$ push:sorttitle } { check:sortname sortkey:name:format } if$ purify 'sortkey.name := } FUNCTION {sortkey:main:string} { duplicate$ #1 = { pop$ sortkey.name delimiter.1 * sortkey.title * delimiter.1 * sortkey.year * delimiter.1 * volume purify #4 pad.number * delimiter.1 * } { duplicate$ #2 = { pop$ sortkey.name delimiter.1 * sortkey.year * delimiter.1 * sortkey.title * delimiter.1 * volume purify #4 pad.number * delimiter.1 * } { #3 = { sortkey.name delimiter.1 * sortkey.year * delimiter.1 * volume purify #4 pad.number * delimiter.1 * sortkey.title * } { "" } if$ } if$ } if$ } FUNCTION {sortkey:main:date:year} { duplicate$ empty$ { pop$ } { extract.number #1 #4 substring$ duplicate$ empty$ { pop$ } { swap$ pop$ } if$ } if$ } FUNCTION {sortkey:main:date} { duplicate$ #1 = { pop$ sortyear empty$ { "9999" dateyear sortkey:main:date:year } { sortyear purify } if$ } { #2 = { sortyear empty$ { "0" dateyear sortkey:main:date:year } { sortyear purify } if$ str.to.int #9999 swap$ - int.to.str$ } { "" } if$ } if$ sortkey.name * delimiter.1 * sortkey.title * delimiter.1 * volume purify #4 pad.number * delimiter.1 * } FUNCTION {sortkey:main} { ctrl.sorting #0 = { sortkey.nosort } { sortkey:init:main "" ctrl.sorting #10 < { sortkey empty$ { ctrl.sorting sortkey:main:string } { sortkey } if$ } { ctrl.sorting #20 < { shorthand empty$ { sortkey.alpha * } { shorthand purify * } if$ duplicate$ empty$ 'skip$ { delimiter.1 * } if$ ctrl.sorting #10 - sortkey:main:string } { ctrl.sorting #30 < { sortkey empty$ { ctrl.sorting #20 - sortkey:main:date } { sortkey } if$ } { push:cite purify } if$ } if$ } if$ * duplicate$ #1 text.prefix$ "u" change.case$ 'sortinit := push:presort delimiter.1 * swap$ * } if$ truncate } % ------------------------------------------------------------------- % Output % ------------------------------------------------------------------- FUNCTION {output:indent:field} { duplicate$ empty$ 'skip$ { " " swap$ * write$ newline$ } if$ } FUNCTION {output:indent:subfield} { duplicate$ empty$ 'skip$ { " " swap$ * write$ newline$ } if$ } FUNCTION {output:indent:subfield:keyval} { duplicate$ empty$ 'skip$ { " " swap$ * write$ newline$ } if$ } FUNCTION {output:write:field:maybeempty} { swap$ "\field" swap$ wrap:braces * swap$ wrap:braces * output:indent:field } FUNCTION {output:write:field} { duplicate$ empty$ { pop$ pop$ } { output:write:field:maybeempty } if$ } FUNCTION {output:write:year} { duplicate$ empty$ { pop$ pop$ } { duplicate$ open.ended = { pop$ "" } 'skip$ if$ swap$ "\field" swap$ wrap:braces * swap$ wrap:braces * output:indent:field } if$ } FUNCTION {output:write:multi} { duplicate$ empty$ { pop$ pop$ } { swap$ "\field" swap$ wrap:braces * "{%" * output:indent:field "%" * output:indent:field "}" output:indent:field } if$ } FUNCTION {output:write:bool} { #0 > { "\true" } { "\false" } if$ swap$ wrap:braces * output:indent:field } FUNCTION {output:write:count} { int.to.str$ swap$ "\count" swap$ wrap:braces * swap$ wrap:braces * output:indent:field } FUNCTION {output:write:string} { duplicate$ empty$ { pop$ pop$ } { swap$ "\strng" swap$ wrap:braces * swap$ wrap:braces * output:indent:field } if$ } FUNCTION {output:write:range} { duplicate$ empty$ { pop$ pop$ } { format.range output:write:field } if$ } FUNCTION {output:write:number} { duplicate$ empty$ { pop$ pop$ } { duplicate$ is.number 'skip$ { swap$ warning:invalid "" } if$ output:write:field } if$ } FUNCTION {output:write:gender} { duplicate$ empty$ { pop$ pop$ } { 'tempstrga := tempstrga "sf" = tempstrga "sm" = or tempstrga "sn" = or tempstrga "pf" = or tempstrga "pm" = or tempstrga "pn" = or tempstrga "pp" = or { tempstrga output:write:field } { warning:invalid } if$ } if$ } FUNCTION {output:write:verb} { duplicate$ empty$ { pop$ pop$ } { 'tempstrga := "\verb" swap$ wrap:braces * output:indent:field { tempstrga empty$ not } { "\verb " tempstrga #1 ctrl.maxline #10 - substring$ * output:indent:field tempstrga ctrl.maxline #9 - global.max$ substring$ 'tempstrga := } while$ "\endverb" output:indent:field } if$ } FUNCTION {output:write:name:hash} { templist tempctra "{v{}}{l{}}{f{}}{j{}}" format.name$ purify$ } FUNCTION {output:write:name:last} { templist tempctra "{ll}" format.name$ duplicate$ 'tempstrga := duplicate$ empty$ 'pop$ { format:name:part "family" combine:key:value output:indent:subfield:keyval templist tempctra "{l.}" format.name$ duplicate$ tempstrga "." * = { duplicate$ text.length$ #1 - text.prefix$ } 'skip$ if$ format:name:initials "familyi" combine:key:value output:indent:subfield:keyval } if$ } FUNCTION {output:write:name:first} { templist tempctra "{ff}" format.name$ duplicate$ 'tempstrga := duplicate$ empty$ 'pop$ { format:name:part "given" combine:key:value output:indent:subfield:keyval templist tempctra "{f.}" format.name$ duplicate$ tempstrga "." * = { duplicate$ text.length$ #1 - text.prefix$ } 'skip$ if$ format:name:initials "giveni" combine:key:value output:indent:subfield:keyval } if$ } FUNCTION {output:write:name:prefix} { templist tempctra "{vv}" format.name$ duplicate$ 'tempstrga := duplicate$ duplicate$ text.length$ duplicate$ substring$ "'" = { #1 'tempctrc := } { #0 'tempctrc := } if$ duplicate$ empty$ 'pop$ { format:name:part "prefix" combine:key:value output:indent:subfield:keyval templist tempctra "{v.}" format.name$ tempctrc { duplicate$ text.length$ #1 - text.prefix$ "'" * } { duplicate$ tempstrga "." * = { duplicate$ text.length$ #1 - text.prefix$ } 'skip$ if$ } if$ format:name:initials "prefixi" combine:key:value output:indent:subfield:keyval } if$ } FUNCTION {output:write:name:suffix} { templist tempctra "{jj}" format.name$ duplicate$ 'tempstrga := duplicate$ empty$ 'pop$ { format:name:part "suffix" combine:key:value output:indent:subfield:keyval templist tempctra "{j.}" format.name$ duplicate$ tempstrga "." * = { duplicate$ text.length$ #1 - text.prefix$ } 'skip$ if$ format:name:initials "suffixi" combine:key:value output:indent:subfield:keyval } if$ } FUNCTION {output:write:name} { duplicate$ empty$ { pop$ pop$ } { 'templist := 'tempstrga := #1 'tempctra := templist num.names$ 'tempctrb := templist andothers { tempctrb #1 - 'tempctrb := "more" tempstrga * #1 output:write:bool % not actually required, biblatex should resolve this tempstrga push:labelname = { "morelabelname" #1 output:write:bool } 'skip$ if$ } 'skip$ if$ "\name" tempstrga wrap:braces * tempctrb int.to.str$ wrap:braces * "" wrap:braces * "{%" * output:indent:field { tempctrb #0 > } { "{{hash=" output:write:name:hash * "}{%" * output:indent:subfield output:write:name:prefix output:write:name:last output:write:name:suffix output:write:name:first "}}%" output:indent:subfield tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ "}" output:indent:field } if$ } FUNCTION {output:write:list} { duplicate$ empty$ { pop$ pop$ } { 'templist := 'tempstrga := templist num.names$ 'tempctra := templist andothers { tempctra #1 - 'tempctra := "more" tempstrga * #1 output:write:bool } 'skip$ if$ "\list" tempstrga wrap:braces * tempctra int.to.str$ wrap:braces * "{%" * output:indent:field #1 'tempctra := #1 'tempctrb := #0 'tempctrc := { templist purify tempctrb global.max$ substring$ num.names$ #0 > } { templist tempctrb #1 substring$ "{" = { tempctrc #1 + 'tempctrc := tempctrb #1 + 'tempctrb := } { templist tempctrb #1 substring$ "}" = { tempctrc #1 - 'tempctrc := tempctrb #1 + 'tempctrb := } { templist tempctrb #5 substring$ duplicate$ " AND " = swap$ " and " = or tempctrc #1 < and { templist tempctra tempctrb tempctra - substring$ wrap:braces "%" * output:indent:subfield tempctrb #5 + duplicate$ 'tempctra := 'tempctrb := } { tempctrb #1 + 'tempctrb := } if$ } if$ } if$ } while$ templist tempctra global.max$ substring$ duplicate$ "others" = { pop$ } { wrap:braces "%" * output:indent:subfield } if$ "}" output:indent:field } if$ } FUNCTION {output:specials} { fakeset empty$ 'skip$ { ctrl:set { "\fakeset" fakeset wrap:braces * output:indent:field } { "fakeset can only be used for @set entries" warning * } if$ } if$ entryset empty$ 'skip$ { ctrl:set { "\set" } { "\inset" } if$ entryset wrap:braces * output:indent:field } if$ xref empty$ 'skip$ { "\xref" xref wrap:braces * output:indent:field } if$ keywords empty$ 'skip$ { "\keyw" keywords wrap:braces * output:indent:field } if$ "entrysubtype" entrysubtype output:write:field "crossref" crossref output:write:string "execute" execute output:write:field "namehash" namehash output:write:string "fullhash" fullhash output:write:string "gender" gender output:write:gender "shorthand" shorthand output:write:field shorthand empty$ { label } { shorthand } if$ "label" swap$ output:write:field "labelnamesource" push:labelname output:write:field shorttitle empty$ { title empty$ { "" } { "title" } if$ } { "shorttitle" } if$ "labeltitlesource" swap$ output:write:field ctrl.labelalpha { "labelalpha" labelalpha output:write:field "extraalpha" extraalpha output:write:field } 'skip$ if$ ctrl:labeldate { dateyear empty$ not { "labelyear" dateyear output:write:field dateendyear empty$ 'skip$ { dateyear dateendyear = 'skip$ { dateendyear open.ended = 'skip$ { "labelendyear" dateendyear output:write:field } if$ } if$ } if$ "extradate" extradate output:write:field "labeldatesource" "" output:write:field:maybeempty } { "extradate" extradate output:write:field "labeldatesource" "nodate" output:write:field } if$ } 'skip$ if$ "sortinit" sortinit output:write:field "sortinithash" sortinit output:write:field singletitle { "singletitle" #1 output:write:bool } 'skip$ if$ } FUNCTION {output:names} { "author" author output:write:name "authortype" authortype output:write:field "shortauthor" shortauthor output:write:name "bookauthor" bookauthor output:write:name "editor" editor output:write:name "editortype" editortype output:write:field "editora" editora output:write:name "editoratype" editoratype output:write:field "editorb" editorb output:write:name "editorbtype" editorbtype output:write:field "editorc" editorc output:write:name "editorctype" editorctype output:write:field "shorteditor" shorteditor output:write:name "translator" translator output:write:name "annotator" annotator output:write:name "commentator" commentator output:write:name "introduction" introduction output:write:name "foreword" foreword output:write:name "afterword" afterword output:write:name "holder" holder output:write:name } FUNCTION {output:lists} { "language" language output:write:list "organization" organization output:write:list "origlanguage" origlanguage output:write:list "origlocation" origlocation output:write:list "origpublisher" origpublisher output:write:list "publisher" publisher output:write:list } FUNCTION {output:fields.1} { "abstract" abstract output:write:multi "addendum" addendum output:write:field "bookpagination" bookpagination output:write:field "booksubtitle" booksubtitle output:write:field "booktitleaddon" booktitleaddon output:write:field "booktitle" booktitle output:write:field "chapter" chapter output:write:field "doi" doi output:write:verb "edition" edition output:write:field "eid" eid output:write:field "eprint" eprint output:write:verb "eventtitle" eventtitle output:write:field "eventtitleaddon" eventtitleaddon output:write:field "howpublished" howpublished output:write:field "indexsorttitle" indexsorttitle output:write:field "indextitle" indextitle output:write:field "isan" isan output:write:field "isbn" isbn output:write:field "ismn" ismn output:write:field } FUNCTION {output:fields.2} { "isrn" isrn output:write:field "issn" issn output:write:field "issue" issue output:write:field "issuesubtitle" issuesubtitle output:write:field "issuetitle" issuetitle output:write:field "iswc" iswc output:write:field "journalsubtitle" journalsubtitle output:write:field "langidopts" langidopts output:write:field "library" library output:write:field "mainsubtitle" mainsubtitle output:write:field "maintitleaddon" maintitleaddon output:write:field "maintitle" maintitle output:write:field "nameaddon" nameaddon output:write:field "note" note output:write:field "number" number output:write:field "origtitle" origtitle output:write:field "pages" pages output:write:range "pagetotal" pagetotal output:write:range "pagination" pagination output:write:field "part" part output:write:range } FUNCTION {output:fields.3} { "pubstate" pubstate output:write:field "reprinttitle" reprinttitle output:write:field "series" series output:write:field "shorthandintro" shorthandintro output:write:field "shortjournal" shortjournal output:write:field "shortseries" shortseries output:write:field "shorttitle" shorttitle output:write:field "subtitle" subtitle output:write:field "titleaddon" titleaddon output:write:field "title" title output:write:field "url" url output:write:verb "venue" venue output:write:field "version" version output:write:field "volumes" volumes output:write:field "volume" volume output:write:field } FUNCTION {output:dates.1} { "date" date split.date "day" swap$ output:write:field duplicate$ empty$ { month empty$ 'skip$ { month is.number { month str.to.int duplicate$ #0 > swap$ #13 < and { pop$ month #2 pad.number } { "month" warning:invalid } if$ } { "month" warning:invalid } if$ } if$ } { month empty$ 'skip$ { "month" "date" warning:duplicate } if$ } if$ "month" swap$ output:write:field duplicate$ empty$ { year empty$ 'skip$ { pop$ year } if$ } { year empty$ 'skip$ { "year" "date" warning:duplicate } if$ } if$ "year" swap$ output:write:field "endday" swap$ output:write:field "endmonth" swap$ output:write:field "endyear" swap$ output:write:year } FUNCTION {output:dates.2} { "origdate" origdate split.date "origday" swap$ output:write:field "origmonth" swap$ output:write:field "origyear" swap$ output:write:field "origendday" swap$ output:write:field "origendmonth" swap$ output:write:field "origendyear" swap$ output:write:year "eventdate" eventdate split.date "eventday" swap$ output:write:field "eventmonth" swap$ output:write:field "eventyear" swap$ output:write:field "eventendday" swap$ output:write:field "eventendmonth" swap$ output:write:field "eventendyear" swap$ output:write:year "urldate" urldate split.date "urlday" swap$ output:write:field "urlmonth" swap$ output:write:field "urlyear" swap$ output:write:field "urlendday" swap$ output:write:field "urlendmonth" swap$ output:write:field "urlendyear" swap$ output:write:year } FUNCTION {output:user} { "namea" namea output:write:name "nameatype" nameatype output:write:field "nameb" nameb output:write:name "namebtype" namebtype output:write:field "namec" namec output:write:name "namectype" namectype output:write:field "lista" lista output:write:list "listb" listb output:write:list "listc" listc output:write:list "listd" listd output:write:list "liste" liste output:write:list "listf" listf output:write:list "usera" usera output:write:field "userb" userb output:write:field "userc" userc output:write:field "userd" userd output:write:field "usere" usere output:write:field "userf" userf output:write:field "verba" verba output:write:verb "verbb" verbb output:write:verb "verbc" verbc output:write:verb } FUNCTION {output:warning} { warningmsg empty$ 'skip$ { "\warn" warningmsg wrap:braces * output:indent:field } if$ } FUNCTION {output:compat.1} { "langid" langid duplicate$ empty$ { pop$ hyphenation } { hyphenation empty$ 'skip$ { "hyphenation" "langid" warning:duplicate } if$ } if$ output:write:field "location" location duplicate$ empty$ { pop$ address } { address empty$ 'skip$ { "address" "location" warning:duplicate } if$ } if$ output:write:list "institution" institution duplicate$ empty$ { pop$ school } { school empty$ 'skip$ { "school" "institution" warning:duplicate } if$ } if$ output:write:list "file" file duplicate$ empty$ { pop$ pdf } { pdf empty$ 'skip$ { "pdf" "file" warning:duplicate } if$ } if$ output:write:verb } FUNCTION {output:compat.2} { "type" type duplicate$ empty$ { type$ "patent" = type$ "techreport" = or type$ "phdthesis" = or { pop$ type$ } { type$ "mastersthesis" = { pop$ "mathesis" } 'skip$ if$ } if$ } 'skip$ if$ output:write:field "journaltitle" journaltitle duplicate$ empty$ { pop$ journal } { journal empty$ 'skip$ { "journal" "journaltitle" warning:duplicate } if$ } if$ output:write:field "annotation" annotation duplicate$ empty$ { pop$ annote } { annote empty$ 'skip$ { "annote" "annotation" warning:duplicate } if$ } if$ output:write:multi } FUNCTION {output:compat.3} { "eprinttype" eprinttype duplicate$ empty$ { pop$ archiveprefix } { archiveprefix empty$ 'skip$ { "archiveprefix" "eprinttype" warning:duplicate } if$ } if$ output:write:field "eprintclass" eprintclass duplicate$ empty$ { pop$ primaryclass } { primaryclass empty$ 'skip$ { "primaryclass" "eprintclass" warning:duplicate } if$ } if$ output:write:field } FUNCTION {output:debug} { "% sort.key$ = " sort.key$ * maxline write$ newline$ sort.year empty$ 'skip$ { "% sort.year = " sort.year * maxline write$ newline$ } if$ sort.alph empty$ 'skip$ { "% sort.alph = " sort.alph * maxline write$ newline$ } if$ } FUNCTION {output:entry} { 'tempstrga := newline$ ctrl.debug { output:debug } 'skip$ if$ " \entry" push:cite wrap:braces * tempstrga wrap:braces * entryoptions wrap:braces * "" wrap:braces * write$ newline$ output:names output:lists output:specials output:fields.1 output:fields.2 output:fields.3 output:compat.1 output:compat.2 output:compat.3 output:dates.1 output:dates.2 output:user output:warning " \endentry" write$ newline$ } FUNCTION {control} { skip$ } FUNCTION {set} { type$ output:entry } FUNCTION {article} { type$ output:entry } FUNCTION {bibnote} { type$ output:entry } FUNCTION {book} { type$ output:entry } FUNCTION {mvbook} { type$ output:entry } FUNCTION {inbook} { type$ output:entry } FUNCTION {bookinbook} { type$ output:entry } FUNCTION {booklet} { type$ output:entry } FUNCTION {collection} { type$ output:entry } FUNCTION {mvcollection} { type$ output:entry } FUNCTION {incollection} { type$ output:entry } FUNCTION {manual} { type$ output:entry } FUNCTION {misc} { type$ output:entry } FUNCTION {online} { type$ output:entry } FUNCTION {patent} { type$ output:entry } FUNCTION {periodical} { type$ output:entry } FUNCTION {proceedings} { type$ output:entry } FUNCTION {mvproceedings} { type$ output:entry } FUNCTION {inproceedings} { type$ output:entry } FUNCTION {reference} { type$ output:entry } FUNCTION {mvreference} { type$ output:entry } FUNCTION {inreference} { type$ output:entry } FUNCTION {report} { type$ output:entry } FUNCTION {suppbook} { type$ output:entry } FUNCTION {suppcollection} { type$ output:entry } FUNCTION {suppperiodical} { type$ output:entry } FUNCTION {thesis} { type$ output:entry } FUNCTION {unpublished} { type$ output:entry } FUNCTION {artwork} { type$ output:entry } FUNCTION {audio} { type$ output:entry } FUNCTION {commentary} { type$ output:entry } FUNCTION {image} { type$ output:entry } FUNCTION {jurisdiction} { type$ output:entry } FUNCTION {legal} { type$ output:entry } FUNCTION {legislation} { type$ output:entry } FUNCTION {letter} { type$ output:entry } FUNCTION {movie} { type$ output:entry } FUNCTION {music} { type$ output:entry } FUNCTION {performance} { type$ output:entry } FUNCTION {review} { type$ output:entry } FUNCTION {software} { type$ output:entry } FUNCTION {standard} { type$ output:entry } FUNCTION {video} { type$ output:entry } FUNCTION {customa} { type$ output:entry } FUNCTION {customb} { type$ output:entry } FUNCTION {customc} { type$ output:entry } FUNCTION {customd} { type$ output:entry } FUNCTION {custome} { type$ output:entry } FUNCTION {customf} { type$ output:entry } FUNCTION {conference} { "inproceedings" output:entry } FUNCTION {electronic} { "online" output:entry } FUNCTION {mastersthesis} { "thesis" output:entry } FUNCTION {other} { "misc" output:entry } FUNCTION {phdthesis} { "thesis" output:entry } FUNCTION {techreport} { "report" output:entry } FUNCTION {www} { "online" output:entry } FUNCTION {default.type} { "misc" output:entry } % ------------------------------------------------------------------- % Input % ------------------------------------------------------------------- FUNCTION {input:control:parse} { 'tempstrga := "" 'tempstrgb := #1 'tempctra := { tempstrga empty$ not tempctra and } { tempstrga #1 #1 substring$ ":" = { #0 'tempctra := } { tempstrgb tempstrga #1 #1 substring$ * 'tempstrgb := } if$ tempstrga #2 global.max$ substring$ 'tempstrga := } while$ tempstrga tempstrgb } FUNCTION {input:control:options} { input:control:parse str.to.int } % This version corresponds to the .bcf version, *not* the biblatex version! FUNCTION {input:control:version} { input:control:parse "$Revision: 3.11 $" #12 entry.max$ substring$ #-3 entry.max$ substring$ 'tempstrga := duplicate$ tempstrga = { pop$ } { "bcf version mismatch: biblatex.bst has " tempstrga * ", but biblatex.sty has " * swap$ * warning$ " The bcf version need not be the same as the biblatex version." top$ pop$ "" } if$ } FUNCTION {input:control} { options empty$ 'skip$ { options input:control:version duplicate$ empty$ { pop$ } { input:control:options 'ctrl.debug := input:control:options 'ctrl.bibtex8 := input:control:options 'ctrl.cssort := input:control:options 'ctrl.useprefix := input:control:options 'ctrl.useauthor := input:control:options 'ctrl.useeditor := input:control:options 'ctrl.usetranslator := input:control:options 'ctrl.labelalpha := input:control:options 'ctrl.labeldate := input:control:options 'ctrl.singletitle := input:control:options 'ctrl.sorting := input:control:options 'ctrl.maxcitenames := input:control:options 'ctrl.mincitenames := input:control:options 'ctrl.maxsortnames := input:control:options 'ctrl.minsortnames := input:control:options 'ctrl.nohashothers := input:control:options 'ctrl.nosortothers := input:control:options 'ctrl.maxalphanames := input:control:options 'ctrl.minalphanames := input:control:options 'ctrl.maxline := input:control:parse 'ctrl.alphaothers := input:control:parse 'ctrl.sortalphaothers := 'ctrl.sortstr := } if$ ctrl.maxline #49 < { #49 'ctrl.maxline := } { ctrl.maxline #79 > { #79 'ctrl.maxline := } 'skip$ if$ } if$ } if$ } FUNCTION {input:options:add} { entryoptions empty$ 'skip$ { entryoptions ", " * 'entryoptions := } if$ entryoptions swap$ * 'entryoptions := duplicate$ empty$ { pop$ } { "=" swap$ * entryoptions swap$ * 'entryoptions := } if$ } FUNCTION {input:options:known} { duplicate$ empty$ { tempstrgb input:options:add #1 } { duplicate$ "true" = { pop$ "" tempstrgb input:options:add #1 } { duplicate$ tempstrgb input:options:add bol.to.int } if$ } if$ } FUNCTION {input:options:parse} { 'tempstrgb := tempstrgb "useprefix" = { input:options:known 'useprefix := } { tempstrgb "useauthor" = { input:options:known 'useauthor := } { tempstrgb "useeditor" = { input:options:known 'useeditor := } { tempstrgb "usetranslator" = { input:options:known 'usetranslator := } { tempstrgb "skipbib" = { input:options:known 'skipbib := } { tempstrgb "skiplos" = { input:options:known 'skiplos := } { tempstrgb "skiplab" = { input:options:known 'skiplab := } { tempstrgb "dataonly" = { input:options:known duplicate$ 'skipbib := duplicate$ 'skiplos := 'skiplab := } { tempstrgb input:options:add } if$ } if$ } if$ } if$ } if$ } if$ } if$ } if$ } FUNCTION {input:options:extract} { 'tempstrgb := #1 'tempctrb := { tempstrgb text.length$ #0 > } { tempstrgb tempctrb #1 substring$ "=" = { tempstrgb tempctrb #1 + global.max$ substring$ tempstrgb #1 tempctrb #1 - substring$ input:options:parse "" 'tempstrgb := } { tempstrgb text.length$ tempctrb = { "" tempstrgb input:options:parse "" 'tempstrgb := } { tempctrb #1 + 'tempctrb := } if$ } if$ } while$ } FUNCTION {input:options} { options 'tempstrga := #1 'tempctra := { tempstrga text.length$ #0 > } { tempstrga tempctra #1 substring$ "," = { tempstrga #1 tempctra #1 - substring$ input:options:extract tempctra #1 + 'tempctra := { tempstrga tempctra #1 substring$ " " = tempctra tempstrga text.length$ > not and } { tempctra #1 + 'tempctra := } while$ tempstrga tempctra global.max$ substring$ 'tempstrga := #1 'tempctra := } { tempstrga text.length$ tempctra = { tempstrga input:options:extract "" 'tempstrga := } { tempctra #1 + 'tempctra := } if$ } if$ } while$ } FUNCTION {input:iterate} { ctrl:control { input:control } { citecount #1 + 'citecount := citecount int.to.str$ #9 pad.number 'sortkey.nosort := ctrl.useprefix 'useprefix := ctrl.useauthor 'useauthor := ctrl.useeditor 'useeditor := ctrl.usetranslator 'usetranslator := ctrl.singletitle { #1 'singletitle := } 'skip$ if$ options empty$ 'skip$ { input:options } if$ ctrl:set entryset empty$ or 'skip$ { #1 'skipbib := #1 'skiplos := #1 'skiplab := } if$ "date" date split.date pop$ pop$ 'dateyear := pop$ pop$ 'dateendyear := dateyear empty$ { year empty$ 'skip$ { year 'dateyear := } if$ } 'skip$ if$ } if$ } READ EXECUTE {initialize} ITERATE {input:iterate} % ------------------------------------------------------------------- % Generate labels % ------------------------------------------------------------------- FUNCTION {makelabel:name:format} { 'templist := #1 'tempctra := templist num.names$ 'tempctrb := templist andothers { tempctrb #1 - 'tempctrb := } 'skip$ if$ tempctrb ctrl.maxcitenames > { ctrl.mincitenames 'tempctrc := } { ctrl.maxcitenames 'tempctrc := } if$ "" { duplicate$ text.length$ entry.max$ #50 - < tempctra tempctrc > not and tempctrb #0 > and } { useprefix { templist tempctra "{vv}" format.name$ duplicate$ empty$ { pop$ "" } { "u" change.case$ "t" change.case$ delimiter.3 * } if$ } { "" } if$ templist tempctra "{ll}" format.name$ * tempctra #1 > { delimiter.2 swap$ * } 'skip$ if$ * tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ templist andothers tempctrb #0 > or ctrl.nohashothers not and { delimiter.2 * "zzzz" * } 'skip$ if$ } FUNCTION {makelabel:name:full} { duplicate$ num.names$ #1 = { #1 "{ll}{" delimiter.3 * "ff}{" delimiter.3 * * "vv}{" delimiter.3 * * "jj}" * format.name$ } { pop$ "" } if$ } FUNCTION {makelabel:alpha:format} { duplicate$ empty$ { pop$ "" } { 'templist := #1 'tempctra := templist andothers { templist num.names$ #1 - 'tempctrb := } { templist num.names$ 'tempctrb := } if$ tempctrb ctrl.maxalphanames > { ctrl.minalphanames 'tempctrb := } 'skip$ if$ tempctrb #1 > { "" { tempctrb #0 > } { templist tempctra "{l{}}" format.name$ * tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ } { templist #1 "{l{}}" format.name$ } if$ duplicate$ text.length$ #2 < { pop$ useprefix { templist #1 "{v{}}" format.name$ #2 text.prefix$ templist #1 "{ll}" format.name$ * } { templist #1 "{ll}" format.name$ } if$ #3 text.prefix$ } 'skip$ if$ } if$ templist num.names$ ctrl.maxalphanames > templist andothers or { ctrl.alphaothers * } 'skip$ if$ } FUNCTION {makelabel:alpha:year} { dateyear purify #1 #4 substring$ #-1 #2 substring$ } FUNCTION {makelabel:hash:format} { 'templist := #1 'tempctra := templist num.names$ 'tempctrb := templist andothers { tempctrb #1 - 'tempctrb := } 'skip$ if$ tempctrb ctrl.maxcitenames > { ctrl.mincitenames 'tempctrc := } { ctrl.maxcitenames 'tempctrc := } if$ "" { tempctra tempctrc > not tempctrb #0 > and } { templist tempctra useprefix { "{v{}}{l{}}{j{}}{f{}}" } { "{l{}}{j{}}{f{}}{v{}}" } if$ format.name$ purify$ * tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ templist andothers tempctrb #0 > or ctrl.nohashothers not and { "+" * } 'skip$ if$ } FUNCTION {makelabel:hash:format:full} { 'templist := #1 'tempctra := templist num.names$ 'tempctrb := templist andothers { tempctrb #1 - 'tempctrb := } 'skip$ if$ "" { tempctrb #0 > } { templist tempctra useprefix { "{v{}}{l{}}{j{}}{f{}}" } { "{l{}}{j{}}{f{}}{v{}}" } if$ format.name$ purify$ * tempctra #1 + 'tempctra := tempctrb #1 - 'tempctrb := } while$ templist andothers ctrl.nohashothers not and { "+" * } 'skip$ if$ } FUNCTION {makelabel:ctrl:alpha} { ctrl:labelalpha { shorthand empty$ { label empty$ { push:cite purify #1 #3 substring$ "u" change.case$ "t" change.case$ } { label makelabel:alpha:year * } if$ } { shorthand } if$ } { "" } if$ } FUNCTION {makelabel:ctrl:alpha:format} { ctrl:labelalpha { shorthand empty$ { label empty$ { makelabel:alpha:format } { pop$ label } if$ makelabel:alpha:year * } { pop$ shorthand } if$ } { pop$ "" } if$ } FUNCTION {makelabel:label} { push:shortname empty$ { push:sorttitle 'label.name := makelabel:ctrl:alpha 'labelalpha := } { push:shortname duplicate$ makelabel:name:format 'label.name := duplicate$ makelabel:hash:format 'namehash := makelabel:ctrl:alpha:format 'labelalpha := } if$ push:fullname empty$ 'skip$ { push:fullname makelabel:hash:format:full 'fullhash := } if$ } % ------------------------------------------------------------------- % Sort labels % ------------------------------------------------------------------- FUNCTION {labelsort:label} { sortkey:init:label makelabel:label } FUNCTION {labelsort:main} { ctrl:skiplab not ctrl.singletitle ctrl.labeldate or and { label.name purify delimiter.1 * sortkey.year * delimiter.1 * push:presort * delimiter.1 * sortkey empty$ { sortkey.name * delimiter.1 * sortkey.title } { sortkey } if$ * truncate } { "" } if$ duplicate$ 'sort.key$ := 'sort.year := } FUNCTION {labelsort:alph} { ctrl:labelalpha { labelalpha ctrl.alphaothers ctrl.sortalphaothers str:replace purify delimiter.1 * push:presort * delimiter.1 * sortkey empty$ { ctrl.sorting #10 > ctrl.sorting #20 < and { ctrl.sorting #10 - } { #2 } if$ sortkey:main:string } { sortkey } if$ * truncate } { "" } if$ duplicate$ 'sort.key$ := 'sort.alph := } FUNCTION {labelsort:hash} { ctrl:control namehash empty$ or { "zzzz" 'sort.key$ := } { namehash purify delimiter.1 * push:shortname duplicate$ empty$ { pop$ "zzzz" * } { sortkey:name:format purify * } if$ truncate 'sort.key$ := } if$ } FUNCTION {labelsort:fullhash} { ctrl:control fullhash empty$ or { "zzzz" 'sort.key$ := } { fullhash purify delimiter.1 * push:shortname duplicate$ empty$ { pop$ "zzzz" * } { sortkey:name:format purify * } if$ truncate 'sort.key$ := } if$ } % ------------------------------------------------------------------- FUNCTION {labelsort:init} { "" 'last.name := "" 'last.year := "" 'last.hash := "" 'last.extra := #1 'last.extra.num := } FUNCTION {labelsort:main:init} { "" 'last.name := } FUNCTION {labelsort:hash:init} { "" 'last.name := #1 'last.extra.num := } FUNCTION {labelsort:namehash:iterate} { ctrl:control namehash empty$ or 'skip$ { namehash last.hash = { push:name:namehash last.name = 'skip$ { last.extra.num #1 + 'last.extra.num := } if$ last.extra.num int.to.str$ 'labelhash := } { #1 'last.extra.num := "1" 'labelhash := } if$ namehash 'last.hash := push:name:namehash 'last.name := } if$ } FUNCTION {labelsort:namehash:reverse} { ctrl:control namehash empty$ or 'skip$ { push:name:namehash last.name = { last.extra "1" = { "1" 'labelhash := } 'skip$ if$ } { last.extra "2" = { "1" 'labelhash := } 'skip$ if$ } if$ labelhash 'last.extra := push:name:namehash 'last.name := namehash labelhash * 'namehash := } if$ } FUNCTION {labelsort:fullhash:iterate} { ctrl:control fullhash empty$ or 'skip$ { fullhash last.hash = { push:name:fullhash last.name = 'skip$ { last.extra.num #1 + 'last.extra.num := } if$ last.extra.num int.to.str$ 'labelhash := } { #1 'last.extra.num := "1" 'labelhash := } if$ fullhash 'last.hash := push:name:fullhash 'last.name := } if$ } FUNCTION {labelsort:fullhash:reverse} { ctrl:control fullhash empty$ or 'skip$ { push:name:fullhash last.name = { last.extra "1" = { "1" 'labelhash := } 'skip$ if$ } { last.extra "2" = { "1" 'labelhash := } 'skip$ if$ } if$ labelhash 'last.extra := push:name:fullhash 'last.name := fullhash labelhash * 'fullhash := } if$ } FUNCTION {labelsort:main:singletitle} { ctrl.singletitle { label.name last.name = { #0 'singletitle := } 'skip$ if$ label.name 'last.name := } 'skip$ if$ } FUNCTION {labelsort:main:year:iterate} { ctrl:labeldate { label.name dateyear empty$ 'skip$ { " " * dateyear * dateendyear empty$ 'skip$ { dateyear dateendyear = 'skip$ { dateendyear open.ended = 'skip$ { "-" * dateendyear * } if$ } if$ } if$ } if$ 'label.year := label.year last.year = { last.extra.num #1 + 'last.extra.num := last.extra.num int.to.str$ 'extradate := } { #1 'last.extra.num := "" 'extradate := label.year 'last.year := } if$ } 'skip$ if$ } FUNCTION {labelsort:main:year:reverse} { ctrl:labeldate { last.extra "2" = { "1" 'extradate := } 'skip$ if$ extradate 'last.extra := } 'skip$ if$ } FUNCTION {labelsort:main:iterate} { ctrl:skiplab 'skip$ { labelsort:main:singletitle labelsort:main:year:iterate } if$ } FUNCTION {labelsort:main:reverse} { ctrl:skiplab 'skip$ { labelsort:main:singletitle labelsort:main:year:reverse } if$ } FUNCTION {labelsort:alph:iterate} { ctrl:labelalpha { labelalpha last.year = { last.extra.num #1 + 'last.extra.num := last.extra.num int.to.str$ 'extraalpha := } { #1 'last.extra.num := "" 'extraalpha := } if$ labelalpha 'last.year := } 'skip$ if$ } FUNCTION {labelsort:alph:reverse} { ctrl:labelalpha { last.extra "2" = { "1" 'extraalpha := } 'skip$ if$ extraalpha 'last.extra := labelalpha empty$ 'skip$ { extraalpha empty$ { labelalpha ctrl.alphaothers ctrl.sortalphaothers str:replace purify 'sortkey.alpha := } { labelalpha ctrl.alphaothers ctrl.sortalphaothers str:replace purify extraalpha #4 pad.number * 'sortkey.alpha := } if$ } if$ } 'skip$ if$ } ITERATE {labelsort:label} EXECUTE {labelsort:init} ITERATE {labelsort:hash} SORT EXECUTE {labelsort:hash:init} ITERATE {labelsort:namehash:iterate} EXECUTE {labelsort:hash:init} REVERSE {labelsort:namehash:reverse} EXECUTE {labelsort:init} ITERATE {labelsort:fullhash} SORT EXECUTE {labelsort:hash:init} ITERATE {labelsort:fullhash:iterate} EXECUTE {labelsort:hash:init} REVERSE {labelsort:fullhash:reverse} EXECUTE {labelsort:init} ITERATE {labelsort:main} SORT EXECUTE {labelsort:init} EXECUTE {labelsort:main:init} ITERATE {labelsort:main:iterate} EXECUTE {labelsort:main:init} REVERSE {labelsort:main:reverse} EXECUTE {labelsort:init} ITERATE {labelsort:alph} SORT ITERATE {labelsort:alph:iterate} REVERSE {labelsort:alph:reverse} % ------------------------------------------------------------------- % Sort bibliography, write .bbl file % ------------------------------------------------------------------- FUNCTION {mainsort} { ctrl:control { "" } { sortkey:main } if$ 'sort.key$ := } ITERATE {mainsort} SORT % This version corresponds to the .bbl version, *not* the biblatex version! FUNCTION {output:main:begin} { "% $ biblatex auxiliary file $" write$ newline$ "% $ biblatex bbl format version " "$Revision: 3.3 $" #12 entry.max$ substring$ #-3 entry.max$ substring$ * " $" * write$ newline$ "% Do not modify the above lines!" write$ newline$ "%" write$ newline$ "% This is an auxiliary file used by the 'biblatex' package." write$ newline$ "% This file may safely be deleted. It will be recreated as" write$ newline$ "% required." write$ newline$ "%" write$ newline$ "\begingroup" write$ newline$ "\makeatletter" write$ newline$ "\@ifundefined{ver@biblatex.sty}" write$ newline$ " {\@latex@error" write$ newline$ " {Missing 'biblatex' package}" write$ newline$ " {The bibliography requires the 'biblatex' package.}" write$ newline$ " \aftergroup\endinput}" write$ newline$ " {}" write$ newline$ "\endgroup" write$ newline$ newline$ "\datalist[entry]{" ctrl.sortstr * "/global//global/global/global}" * write$ } FUNCTION {output:main:preamble} { preamble$ empty$ 'skip$ { newline$ "\preamble{%" write$ newline$ preamble$ write$ newline$ "}" write$ newline$ } if$ } FUNCTION {output:main:end} { "\enddatalist" write$ newline$ "\endinput" write$ newline$ } EXECUTE {output:main:begin} EXECUTE {output:main:preamble} ITERATE {call.type$} EXECUTE {output:main:end} % -------------------------------------------------------------------