#include #include #include #include #include #include //#define NOCASE /* * bibsorter * * Reads a bibtex file with multiple entries and sorts them and writes back all unique entries. * You may change the priority list to change the rules to reject double entries. bibsorter * prefers labels with lower case. * E.g. 'book' comes before 'unpublished' and 'Wind95' before 'WIND95' CC -LANG:std -O2 bibsorter.C -o bibsorter g++ -O2 bibsorter.C -o bibsorter */ void usage(char* name); const std::string copyright="BiBTeX Sorter, (C) 2002, matthey@ii.uib.no, "+std::string(__DATE__)+"."; const std::string priorityList[] = { "book", "inbook", "booklet", "incollection", "article", "narticle", "phdthesis", "mastersthesis", "conference", "proceedings", "inproceeding", "inproceedings", "techreport", "manual", "misc", "unpublished", "END" }; const std::string a="@string"; const std::string b="@"; const std::string c="%"; std::string getline(std::istream& in); bool equal(const std::string& s1, const std::string& s2); std::string removeBlanks(std::string s); std::string removeAllBlanks(std::string s); std::string uppercase(std::string word); std::string lowercase(std::string word); int priority(const std::string& s1, const std::string& s2); struct ltstrNocase { bool operator()(const std::string& s1, const std::string& s2) const{ #ifdef NOCASE return strcmp(uppercase(s1).c_str(),uppercase(s2).c_str()) < 0; #else return strcmp(s1.c_str(),s2.c_str()) < 0; #endif } }; int main (int argc, char* argv[]){ std::cerr < strings; //std::set forms; std::multiset stringsRest; std::map,std::string>,ltstrNocase> entries; std::multimap > entriesRest; std::string str; str = removeBlanks(getline(input)); while(!input.eof()){ if(str.size() > a.size() && equal(str,a)){ std::set::iterator itr = strings.find(str); if(itr == strings.end()){ //std::cerr<< "Found @string (\""< b.size()&& equal(str,b)){ std::vector entry; str = removeAllBlanks(str); entry.push_back(str); std::string mykey = ""; std::string form = ""; bool start = false; for(unsigned int i=0;i a.size() && equal(str,a)) || (str.size() > b.size()&& equal(str,b))){ break; } else if((!(str.size() >= c.size() && equal(str,c))) && str.size()>0){ entry.push_back(tmp); } } std::map,std::string>,ltstrNocase>::iterator itr = entries.find(mykey); if(itr == entries.end()){ entries.insert(std::pair,std::string> >(mykey,std::pair,std::string>(entry,form))); } else{ //std::cerr<< "Dublicate\n"; int p = priority(itr->second.second,form); if(p < 0 || (p == 0 && (mykey < itr->first))){ //std::cerr<< "Found dublicate (\""<second.second<<"\",\""< >(mykey,entry)); } else { //std::cerr<< "Found dublicate with higher priority (\""<second.second<<"\",\""< >(itr->first,itr->second.first)); // erase to remove the old key. entries.erase(itr); entries.insert(std::pair,std::string> >(mykey,std::pair,std::string>(entry,form))); } } } else{ //std::cerr<< "Found comments (\""<::iterator itr = forms.begin(); // itr != forms.end(); itr++) // std::cerr<< (*itr)<<"\n"; // Output std::string outputname = std::string(argv[2]); std::ofstream output; output.open(outputname.c_str(), std::ios::out); for(std::set::iterator itr = strings.begin(); itr != strings.end(); itr++){ output <<(*itr)<<"\n"; } for(std::map,std::string>,ltstrNocase>::iterator itr = entries.begin(); itr != entries.end(); itr++){ output <<"\n"; const std::vector& entry = itr->second.first; for(int i=0;i::iterator itr = stringsRest.begin(); itr != stringsRest.end(); itr++){ outputRest <<(*itr)<<"\n"; } for(std::multimap >::iterator itr = entriesRest.begin(); itr != entriesRest.end(); itr++){ outputRest <<"\n"; const std::vector& entry = itr->second; for(int i=0;i "<=i;j--){ if(s[j] != ' ' && s[j] != '\t'){ return s.substr(i,j+1-i); } } } } return ""; } std::string removeAllBlanks(std::string s){ std::string tmp = ""; for(int i=0;i