larsgw / citation.js

Citation.js converts formats like BibTeX, Wikidata JSON and ContentMine JSON to CSL-JSON to convert to other formats like APA, Vancouver and back to BibTeX.
https://citation.js.org/
MIT License
219 stars 30 forks source link

Sorting entries by year #199

Closed seannyD closed 3 years ago

seannyD commented 4 years ago

I have a list of citations and I want them to appear by year. Or I can order them myself by year and I want to turn off internal sorting. The docs suggest there's a 'nosort' option, but I can't get it to work.

Here is a string with three bibtex papers. I want them to appear in year order, which is also the order they appear in:

var bibSource = '@article{de2012modelling,\
  title={First paper},\
  author={De Vos, Connie and Roberts, Sean G and Thompson, Bill},\
  journal={Journal of Language Evolution},\
  year={2012}\
}\
\
@article{tamariz2014generation,\
  title={Second paper},\
  author={Tamariz, M and Cornish, H and Roberts, S and Kirby, S},\
  journal={A journal},\
  pages={555--556},\
  year={2014}\
}\
\
@article{everett2016response,\
  title={Third Paper},\
  author={Everett, Caleb and Roberts, Sean},\
  journal={Journal of Language Evolution},\
  volume={1},\
  number={1},\
  pages={83--87},\
  year={2016},\
}';

I can try rendering them with:

    cite.set(bibSource)
    cite.get({format:"string",type:"html",style:"citation-apa",nosort:true});

But this reorders the output I also try to sorting the input with a custom function:

    var sorted = cite.sort(function (entryA, entryB) {
         return parseInt(entryA["issued"]["date-parts"][0][0]) -
          parseInt(entryB["issued"]["date-parts"][0][0])
    });

The object 'sorted' now holds the entries in the correct order. But when I try to output them, they get re-ordered again:

sorted.get({format:"string",type:"html",style:"citation-apa",nosort:true})

The only way I could figure to do this was to convert each entry individually and put them into an object, then sort that object. Horrible:

var makeCite = function(sourceID,destID){

    var bib = $(sourceID).html();
    bib = bib.split("@");
    var htmlParts = {};
    for(var i=0;i<bib.length;++i){
        if(bib[i].length > 4){
            var b = "@"+bib[i];
            cite.set(b);
            var year = cite.data[0]["issued"]["date-parts"][0][0]
            var htmlText = cite.get({format:"string",type:"html",style:"citation-apa"})+'\n';
            if(htmlParts[year]){
                htmlParts[year].push(htmlText);
            } else{
                htmlParts[year] = [htmlText];
            }
        }
    }
    htmlOut = "";
    var years = Object.keys(htmlParts).reverse();
    for (i = 0; i< years.length;++i) {
        htmlOut += htmlParts[years[i]].join("\n");
    }
    $(destID).html(htmlOut);
    $(destID).html(Autolinker.link($(destID).html()));

}

What am I doing wrong?

larsgw commented 4 years ago

Using .get() is deprecated, and the function does not support nosort. Use this instead:

cite.format('bibliography', {format:"html",template:"apa",nosort:true})

Demo: https://runkit.com/larsgw/citation-js-nosort-custom-sort