\ProvidesFile{numeric-comp.cbx} [\abx@cbxid] \newtoggle{cbx:subentrycomp} \DeclareBiblatexOption{global,type,entry}[boolean]{subentrycomp}[true]{% \settoggle{cbx:subentrycomp}{#1}} \ExecuteBibliographyOptions{labelnumber,sortcites,autocite=inline, subentrycomp=true} \renewcommand*{\multicitedelim}{\addcomma\space} \renewcommand*{\iffinalcitedelim}{% \ifnumequal{\value{textcitecount}}{\value{textcitetotal}-1}} \providebool{bbx:subentry} \newbool{cbx:parens} \newcounter{cbx@tempcnta}% no. of labelnumbers skipped \newcounter{cbx@tempcntb}% 'predicted' labelnumber for current cite \newcounter{cbx@tempcntc}% no. of entrysetcounts we skipped \newcounter{cbx@tempcntd}% 'predicted' entrysetcount \DeclareFieldFormat{entrysetcount}{\mknumalph{#1}} \newcommand*{\cbx@iflabelnumberequalslast}{% \iffieldequals{labelnumber}{\cbx@lastnumber}} % \iffieldequals is false even if both are empty/undef % so we need a special test for that case % this test is optimised for performance and laziness % rather than prettiness, not that it would matter a lot... \newcommand*{\cbx@iflabelprefixequalslast}{% \ifundef\cbx@lastprefix {\iffieldundef{labelprefix}} {\iffieldequals{labelprefix}{\cbx@lastprefix}}} % \cbx@iflabelnumberequalslast and \cbx@iflabelprefixequalslast \newcommand*{\cbx@iflabelnumberandprefixequallast}{% \cbx@iflabelnumberequalslast {\cbx@iflabelprefixequalslast} {\@secondoftwo}} \newbibmacro*{cite:init}{% \global\boolfalse{cbx:parens}% \global\undef\cbx@lasthash \global\undef\cbx@lastnumber \global\undef\cbx@lastprefix \global\undef\cbx@lastentrysetcount \setcounter{cbx@tempcnta}{0}% \setcounter{cbx@tempcntb}{-2}% \setcounter{cbx@tempcntc}{0}% \setcounter{cbx@tempcntd}{-1}} \newbibmacro*{cite:comp}{% \stepcounter{cbx@tempcntb}% \iffieldundef{shorthand} {\ifbool{bbx:subentry} {\iffieldundef{entrysetcount} {\usebibmacro{cite:comp:comp}} {\usebibmacro{cite:comp:inset}}} {\usebibmacro{cite:comp:comp}}} {\usebibmacro{cite:comp:shand}}} % we externalise printing the citations to % cite:print:... macros for easier customisation \newbibmacro*{cite:comp:comp}{% \cbx@iflabelprefixequalslast {\ifnumequal{\thefield{labelnumber}}{\value{cbx@tempcntb}} {\savefield{entrykey}{\cbx@lastkey}% \savefield{labelnumber}{\cbx@lastnumber}% \stepcounter{cbx@tempcnta}} {\ifnumequal{\thefield{labelnumber}}{\value{cbx@tempcntb}-1} {% current cite is *exactly* the same a previous source % this can only happen if the same source is cited twice % and sortcites is turned off % print nothing } {\usebibmacro{cite:comp:end}}}} {\usebibmacro{cite:comp:end}}% \setcounter{cbx@tempcntb}{\thefield{labelnumber}}% \savefield{labelprefix}{\cbx@lastprefix}} \newbibmacro*{cite:comp:end}{% \usebibmacro{cite:dump}% \ifnumgreater{\value{cbx@tempcntb}}{-1} {\setunit{\multicitedelim}} {}% \usebibmacro{cite:print:labelnumber}} \newbibmacro*{cite:comp:inset}{% \stepcounter{cbx@tempcntd}% \ifboolexpr{ togl {cbx:subentrycomp} and test {\cbx@iflabelnumberandprefixequallast}} {\ifnumequal{\thefield{entrysetcount}}{\value{cbx@tempcntd}} {\savefield{entrykey}{\cbx@lastkey}% \savefield{entrysetcount}{\cbx@lastentrysetcount}% \stepcounter{cbx@tempcntc}} {\ifnumequal{\thefield{entrysetcount}}{\value{cbx@tempcntd}-1} {% current cite is *exactly* the same a previous source % this can only happen if the same source is cited twice % and sortcites is turned off % print nothing } {\usebibmacro{cite:dump:inset}% \ifnumgreater{\value{cbx@tempcntd}}{-1} {\setunit{\multicitesubentrydelim}} {}% \usebibmacro{cite:print:subentry:comp}}}} {\usebibmacro{cite:dump}% \ifnumgreater{\value{cbx@tempcntb}}{-1} {\multicitedelim} {}% \setcounter{cbx@tempcntd}{-1}% \usebibmacro{cite:print:subentry:full}% \savefield{labelprefix}{\cbx@lastprefix}% \savefield{labelnumber}{\cbx@lastnumber}}% \setcounter{cbx@tempcntd}{\thefield{entrysetcount}}% \setcounter{cbx@tempcntb}{-1}} \newbibmacro*{cite:comp:shand}{% \usebibmacro{cite:dump}% \ifnumgreater{\value{cbx@tempcntb}}{-1} {\setunit{\multicitedelim}} {}% \usebibmacro{cite:print:shorthand}% \setcounter{cbx@tempcntb}{-1}} \newbibmacro{cite:dump:inset}{% % dump subentry \ifnumgreater{\value{cbx@tempcntc}}{0} {\ifnumgreater{\value{cbx@tempcntc}}{1} {\setunit{\multicitesubentryrangedelim}} {\setunit{\multicitesubentrydelim}}% \usebibmacro{cite:print:last:subentry:comp}% \global\undef\cbx@lastentrysetcount} {}% \setcounter{cbx@tempcntc}{0}% } \newbibmacro*{cite:dump}{% \usebibmacro{cite:dump:inset}% % dump labelnumber (+labelprefix) \ifnumgreater{\value{cbx@tempcnta}}{0} {\ifnumgreater{\value{cbx@tempcnta}}{1} {\setunit{\multiciterangedelim}} {\setunit{\multicitedelim}}% \usebibmacro{cite:print:last:labelnumber}% \global\undef\cbx@lastprefix} {}% \setcounter{cbx@tempcnta}{0}% } % these macros do the actual printing \newbibmacro*{cite:print:shorthand}{% \printtext[bibhyperref]{\printfield{shorthand}}} \newbibmacro*{cite:print:labelnumber}{% \printtext[bibhyperref]{% \printfield{labelprefix}% \printfield{labelnumber}}} \newbibmacro*{cite:print:subentry:comp}{% \printtext[bibhyperref]{\printfield{entrysetcount}}} \newbibmacro*{cite:print:subentry:full}{% \printtext[bibhyperref]{% \printfield{labelprefix}% \printfield{labelnumber}% \printfield{entrysetcount}}} \DeclareFieldFormat{bibhyperref:lastkey}{\bibhyperref[\cbx@lastkey]{#1}} \newbibmacro*{cite:print:last:subentry:comp}{% \printtext[bibhyperref:lastkey]{% \printtext[entrysetcount]{\cbx@lastentrysetcount}}} \newbibmacro*{cite:print:last:labelnumber}{% \printtext[bibhyperref:lastkey]{% \ifdef\cbx@lastprefix {\printtext[labelprefix]{\cbx@lastprefix}} {}% \printtext[labelnumber]{\cbx@lastnumber}}} \newbibmacro*{textcite}{% \iffieldequals{namehash}{\cbx@lasthash} {\usebibmacro{cite:comp}} {\usebibmacro{cite:dump}% \ifbool{cbx:parens} {\printtext{\bibclosebracket}\global\boolfalse{cbx:parens}} {}% \iffirstcitekey {} {\setunit{\textcitedelim}}% \usebibmacro{cite:init}% \ifnameundef{labelname} {\printfield[citetitle]{labeltitle}} {\printnames{labelname}}% \setunit*{\printdelim{namelabeldelim}}% \printtext{\bibopenbracket}\global\booltrue{cbx:parens}% \ifnumequal{\value{citecount}}{1} {\usebibmacro{prenote}} {}% \usebibmacro{cite:comp}% \stepcounter{textcitecount}% \savefield{namehash}{\cbx@lasthash}}} \DeclareCiteCommand{\cite}[\mkbibbrackets] {\usebibmacro{cite:init}% \usebibmacro{prenote}} {\usebibmacro{citeindex}% \usebibmacro{cite:comp}} {} {\usebibmacro{cite:dump}% \usebibmacro{postnote}} \DeclareCiteCommand{\parencite}[\mkbibbrackets] {\usebibmacro{cite:init}% \usebibmacro{prenote}} {\usebibmacro{citeindex}% \usebibmacro{cite:comp}} {} {\usebibmacro{cite:dump}% \usebibmacro{postnote}} \DeclareCiteCommand{\footcite}[\mkbibfootnote] {\usebibmacro{cite:init}% \usebibmacro{prenote}} {\usebibmacro{citeindex}% \usebibmacro{cite:comp}} {} {\usebibmacro{cite:dump}% \usebibmacro{postnote}} \DeclareCiteCommand{\footcitetext}[\mkbibfootnotetext] {\usebibmacro{cite:init}% \usebibmacro{prenote}} {\usebibmacro{citeindex}% \usebibmacro{cite:comp}} {} {\usebibmacro{cite:dump}% \usebibmacro{postnote}} \DeclareCiteCommand{\smartcite}[\iffootnote\mkbibbrackets\mkbibfootnote] {\usebibmacro{cite:init}% \usebibmacro{prenote}} {\usebibmacro{citeindex}% \usebibmacro{cite:comp}} {} {\usebibmacro{cite:dump}% \usebibmacro{postnote}} \DeclareCiteCommand{\supercite}[\mkbibsuperscript] {\usebibmacro{cite:init}% \let\multicitedelim=\supercitedelim \let\multicitesubentrydelim=\supercitesubentrydelim \let\multiciterangedelim=\superciterangedelim \let\multicitesubentryrangedelim=\supercitesubentryrangedelim \iffieldundef{prenote} {} {\BibliographyWarning{Ignoring prenote argument}}% \iffieldundef{postnote} {} {\BibliographyWarning{Ignoring postnote argument}}} {\usebibmacro{citeindex}% \usebibmacro{cite:comp}} {} {\usebibmacro{cite:dump}} \DeclareCiteCommand{\cbx@textcite} {\usebibmacro{cite:init}} {\usebibmacro{citeindex}% \usebibmacro{textcite}} {} {\usebibmacro{cite:dump}% \usebibmacro{postnote}% \ifbool{cbx:parens} {\bibclosebracket\global\boolfalse{cbx:parens}} {}} \DeclareCiteCommand{\textcite}[\cbx@textcite@init\cbx@textcite] {\gdef\cbx@savedkeys{}% \citetrackerfalse% \pagetrackerfalse% \DeferNextCitekeyHook% \usebibmacro{cite:init}} {\ifthenelse{\iffirstcitekey\AND\value{multicitetotal}>0} {\protected@xappto\cbx@savedcites{()(\thefield{multipostnote})}% \global\clearfield{multipostnote}} {}% \xappto\cbx@savedkeys{\thefield{entrykey},}% \iffieldequals{namehash}{\cbx@lasthash} {} {\stepcounter{textcitetotal}% \savefield{namehash}{\cbx@lasthash}}} {} {\protected@xappto\cbx@savedcites{% [\thefield{prenote}][\thefield{postnote}]{\cbx@savedkeys}}} % textcite has nested \DeclareCiteCommand definitions for textcite and we want to use % the normal textcite context \DeclareDelimcontextAlias{cbx@textcite}{textcite} \newrobustcmd{\cbx@textcite@init}[2]{% \setcounter{textcitetotal}{0}% \setcounter{textcitecount}{0}% \def\cbx@savedcites{#1}#2\cbx@savedcites\empty} \DeclareMultiCiteCommand{\cbx@textcites}{\cbx@textcite}{} \DeclareMultiCiteCommand{\textcites}[\cbx@textcites@init\cbx@textcites]{\textcite}{} \let\cbx@textcites@init\cbx@textcite@init \pretocmd{\cbx@textcites@init}{\UseNextMultiCiteHook}{}{} \DeclareMultiCiteCommand{\cites}[\mkbibbrackets]{\cite}{\multicitedelim} \DeclareMultiCiteCommand{\parencites}[\mkbibbrackets]{\parencite}{\multicitedelim} \DeclareMultiCiteCommand{\smartcites}[\iffootnote\mkbibbrackets\mkbibfootnote] {\smartcite}{\multicitedelim} \endinput