Reverse numbering in biblatex with customized bibchecks

biblatex

I would like to show bibliographies of different categories (e.g., conference papers, journal papers, etc.) in my CV. In each category, the bibliography entries are sorted by the published date. To allow permanent indices for increments in the future, I would have these indices reversely numbered, so that newer works get larger indices. Meanwhile, I would like to mark some of my works as "selected works", in which I set up a new field of "selected" and print the entries using a customized check filter.

I have tried the solution here but it does not work. In my system, the following MWE produces the normal numbering not the reversed.

\documentclass[10pt, a4paper]{article}
\usepackage[czech,english]{babel}  
\usepackage[backend=biber,style=ieee,defernumbers=true,sorting=keysort]{biblatex}

\makeatletter
\newcounter{bibenvcounter}
\newcounter{bibitemcounter}[bibenvcounter]

\newcommand*{\auxkacz@envmax}[2]{%
  \csgdef{blxkacz@envmax@#1}{#2}}

\defbibenvironment{bibliography}
  {\stepcounter{bibenvcounter}%
   \list
     {\ifcsundef{blxkacz@envmax@\the\value{bibenvcounter}}
        {}
        {\numdef\abx@field@localnumber{%
           \csuse{blxkacz@envmax@\the\value{bibenvcounter}}%
             -\value{bibitemcounter}}%
         \csundef{blx@defer@\the\c@refsection
            @\blx@refcontext@context
            @\abx@field@entrykey}%
         \blx@thelabelnumber}%
      \stepcounter{bibitemcounter}%
      \printtext[labelnumberwidth]{%
        \printfield{labelprefix}%
        \printfield{labelnumber}}}
     {\setlength{\labelwidth}{\labelnumberwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}}%
      \renewcommand*{\makelabel}[1]{\hss##1}}
  {\endlist
   \blx@auxwrite\@mainaux{}{%
     \string\auxkacz@envmax
       {\the\value{bibenvcounter}}
       {\the\value{bibitemcounter}}}}
  {\item}
\makeatother

\defbibcheck{confnoyear}{ \ifentrytype{inproceedings} {\iffieldundef{year}{}{\skipentry}} {\skipentry} }
\defbibcheck{journoyear}{ \ifentrytype{article}       {\iffieldundef{year}{}{\skipentry}} {\skipentry} }
\defbibcheck{confwyear}{  \ifentrytype{inproceedings} {\iffieldundef{year}{\skipentry}{}} {\skipentry} }
\defbibcheck{jourwyear}{  \ifentrytype{article}       {\iffieldundef{year}{\skipentry}{}} {\skipentry} }

\DeclareSortingScheme{keysort}{
  \sort[direction=descending]{\field{entrykey}}
}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@inproceedings{a,
  author  = {Author, A.},
  title   = {A Title},
  date    = {1980},
}
@inproceedings{b,
  author  = {Buthor, B.},
  title   = {B Title},
  date    = {1980},
}
@inproceedings{c,
  author  = {Buthor, C.},
  title   = {C Title},
  date    = {1980},
}
@inproceedings{d,
  author  = {Duthor, D.},
  title   = {A Title},
}
@inproceedings{e,
  author  = {Euthor, E.},
  title   = {B Title},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\begin{document}
\newrefcontext[labelprefix=CS,sorting=keysort]
\printbibliography[check=confnoyear] \nocite{*}

\newrefcontext[labelprefix=C,sorting=keysort]
\printbibliography[check=confwyear] \nocite{*}
\end{document}

Is there any problem with my configuration? Any help is appreciated!

Best Answer

The answer to Separate biblatex biblios, descending numbering, 'check' filters was written for an older version of biblatex.

With the current v3.16 I recommend the following variation of the answer that uses the same idea, but tries to change localnumber directly.

\documentclass[10pt, a4paper]{article}
\usepackage[english]{babel}
\usepackage{csquotes}
\usepackage[backend=biber,style=ieee,defernumbers=true,sorting=keysort]{biblatex}

\makeatletter
\newcounter{bibenvcounter}
\newcounter{bibitemcounter}[bibenvcounter]

\newcommand*{\auxkacz@envmax}[2]{%
  \csgdef{blxkacz@envmax@#1}{#2}}

\def\blx@thelabelnumber{%
  \begingroup
  \nottoggle{blx@skiplab}
    {\iftoggle{blx@labelnumber}
       {\ifundef\abx@field@shorthand
         % Need to know if we set any localnumber from .aux file, not
         % just current item. Otherwise, we may just write new
         % localnumbers but not existing ones
         % Also, don't want to regenerate localnumber for any key in a
         % refsection which we've already seen because this has the nasty
         % side-effect of incrementing the localnum counter
         % Also, have to create localnumber again if \nocite{*} as items
         % could have been added to the .bib file without changing the cite
         % information in the .tex
         {\ifboolexpr { (not togl {blx@localnumber}
                         or
                         test {\ifinlist{*}\blx@nocites})
                         and
                         not test {\ifcsdef{blx@defer@\the\c@refsection @\blx@refcontext@context @\abx@field@entrykey}} }
            {\iftoggle{blx@omitnumbers}
               {\let\abx@field@localnumber\@empty}
               {\ifcsundef{blxkacz@envmax@\the\value{bibenvcounter}}
                  {\blx@rerun@latex
                   \csdef{blxkacz@envmax@\the\value{bibenvcounter}}{0}}
                  {\csnumgdef{blx@labelnumber@\the\c@refsection}{%
                   \csuse{blxkacz@envmax@\the\value{bibenvcounter}}%
                      -\value{bibitemcounter}}%
                   \edef\abx@field@localnumber{%
                    \csuse{blx@labelnumber@\the\c@refsection}}%
                  \blx@bbl@addentryfield{\abx@field@entrykey}{\the\c@refsection}%
                  {localnumber}{\blx@refcontext@context}{\abx@field@localnumber}}}}
            {}%
          % Issue re-run message if there was no localnumber in the .aux and
          % \nocite{*} was used because this means that an entry was added to the .bib
          % and was not yet recorded in the .aux. We will have generated a localnumber
          % for such a case above and now we need to re-run to make sure it's in the .aux
          % for the next run
          \ifboolexpr { test {\ifinlist{*}\blx@nocites}
                        and
                        not test {\ifcsdef{blx@localnumber@\the\c@refsection @\abx@field@entrykey}} }
            {\blx@rerun@latex}
            {}%
          % If localnumbers were already in the .aux, add them
          % again from the .aux. This prevents some cycling
          % problems where pagebreaks change after localnumber
          % settles down and then we need another run which then
          % regenerates localnumber requiring another run but then
          % the pagebreaks change back again ... etc.
          \ifcsundef{blx@defer@\the\c@refsection @\blx@refcontext@context @\abx@field@entrykey}
            {\ifundef\abx@field@localnumber
               {}
               {\listxadd\blx@localnumaux{%
                  \string\abx@aux@number%
                     {\the\c@instcount}%
                     {\abx@field@entrykey}%
                     {\the\c@refsection}%
                     {\blx@refcontext@context}%
                     {\abx@field@localnumber}}%
                   % record that we have already generated and output localnum
                   % for this key in this refsection/refcontext
                   \global\cslet{blx@defer@\the\c@refsection @\blx@refcontext@context @\abx@field@entrykey}\@empty}}
           {}}
         {}}%
       {}}
    {}%
  \endgroup}

\defbibenvironment{bibliography}
  {\stepcounter{bibenvcounter}%
   \list
     {\stepcounter{bibitemcounter}%
      \printtext[labelnumberwidth]{%
        \printfield{labelprefix}%
        \printfield{labelnumber}}}
     {\setlength{\labelwidth}{\labelnumberwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}}%
      \renewcommand*{\makelabel}[1]{\hss##1}}
  {\endlist
   \blx@auxwrite\@mainaux{}{%
     \string\auxkacz@envmax
       {\the\value{bibenvcounter}}
       {\the\value{bibitemcounter}}}}
  {\item}
\makeatother

\defbibcheck{confnoyear}{ \ifentrytype{inproceedings} {\iffieldundef{year}{}{\skipentry}} {\skipentry} }
\defbibcheck{journoyear}{ \ifentrytype{article}       {\iffieldundef{year}{}{\skipentry}} {\skipentry} }
\defbibcheck{confwyear}{  \ifentrytype{inproceedings} {\iffieldundef{year}{\skipentry}{}} {\skipentry} }
\defbibcheck{jourwyear}{  \ifentrytype{article}       {\iffieldundef{year}{\skipentry}{}} {\skipentry} }

\DeclareSortingTemplate{keysort}{
  \sort[direction=descending]{\field{entrykey}}
}

\begin{filecontents}{\jobname.bib}
@inproceedings{a,
  author  = {Author, A.},
  title   = {A Title},
  date    = {1980},
}
@inproceedings{b,
  author  = {Buthor, B.},
  title   = {B Title},
  date    = {1980},
}
@inproceedings{c,
  author  = {Cuthor, C.},
  title   = {C Title},
  date    = {1980},
}
@inproceedings{d,
  author  = {Duthor, D.},
  title   = {A Title},
}
@inproceedings{e,
  author  = {Euthor, E.},
  title   = {B Title},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}

\cite{a}

\cite{b}

\cite{c}

\cite{d}

\cite{e}

\newrefcontext[labelprefix=CS,sorting=keysort]
\printbibliography[check=confnoyear]

\newrefcontext[labelprefix=C,sorting=keysort]
\printbibliography[check=confwyear]
\end{document}

CS2/CS1/C3/C2/C1