diff options
Diffstat (limited to 'src/cite.cpp')
-rw-r--r-- | src/cite.cpp | 277 |
1 files changed, 164 insertions, 113 deletions
diff --git a/src/cite.cpp b/src/cite.cpp index 797881f..612ddc1 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2011 by Dimitri van Heesch + * Copyright (C) 2020 by Dimitri van Heesch * Based on a patch by David Munger * * Permission to use, copy, modify, and distribute this software and its @@ -15,116 +15,112 @@ */ #include "cite.h" -#include "portable.h" #include "config.h" -#include "message.h" -#include "util.h" -#include "language.h" #include "ftextstream.h" +#include "language.h" +#include "message.h" +#include "portable.h" #include "resourcemgr.h" -#include "doxygen.h" +#include "util.h" + +#include <qfile.h> +#include <qfileinfo.h> #include <qdir.h> -//-------------------------------------------------------------------------- +#include <map> +#include <string> + +// Remove the temporary files +#define RM_TMP_FILES (true) +//#define RM_TMP_FILES (false) + +const char *bibTmpFile = "bibTmpFile_"; +const char *bibTmpDir = "bibTmpDir/"; + +class CiteInfoImpl : public CiteInfo +{ + public: + CiteInfoImpl(const char *label, const char *text=0) + : m_label(label), m_text(text) { } + + virtual QCString label() const { return m_label; } + virtual QCString text() const { return m_text; } + + void setText(const char *s) { m_text = s; } -const QCString CiteConsts::fileName("citelist"); -/* when changing this also take doxygen.bst into account */ -const QCString CiteConsts::anchorPrefix("CITEREF_"); -const QCString bibTmpFile("bibTmpFile_"); -const QCString bibTmpDir("bibTmpDir/"); + private: + QCString m_label; + QCString m_text; +}; -//-------------------------------------------------------------------------- +struct CitationManager::Private +{ + std::map< std::string,std::unique_ptr<CiteInfoImpl> > entries; +}; -CiteDict::CiteDict(int size) : m_entries(size, FALSE) -{ - m_entries.setAutoDelete(TRUE); +CitationManager &CitationManager::instance() +{ + static CitationManager ct; + return ct; } -void CiteDict::writeLatexBibliography(FTextStream &t) +CitationManager::CitationManager() : p(new Private) { - if (m_entries.isEmpty()) - return; +} - QCString style = Config_getString(LATEX_BIB_STYLE); - if (style.isEmpty()) - style="plain"; - QCString unit; - if (Config_getBool(COMPACT_LATEX)) - unit = "section"; - else - unit = "chapter"; - t << "% Bibliography\n" - "\\newpage\n" - "\\phantomsection\n"; - bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); - if (!pdfHyperlinks) - { - t << "\\clearemptydoublepage\n"; - t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; - } - t << "\\bibliographystyle{" << style << "}\n" - "\\bibliography{"; - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); - int i = 0; - const char *bibdata = citeDataList.first(); - while (bibdata) - { - QCString bibFile = bibdata; - // Note: file can now have multiple dots - if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; - QFileInfo fi(bibFile); - if (fi.exists()) - { - if (!bibFile.isEmpty()) - { - if (i) t << ","; - i++; - t << bibTmpFile << QCString().setNum(i); - } - } - bibdata = citeDataList.next(); - } - t << "}\n"; - if (pdfHyperlinks) +void CitationManager::insert(const char *label) +{ + p->entries.insert( + std::make_pair( + std::string(label), + std::make_unique<CiteInfoImpl>(label) + )); +} + +const CiteInfo *CitationManager::find(const char *label) const +{ + auto it = p->entries.find(label); + if (it!=p->entries.end()) { - t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; + return it->second.get(); } - t << "\n"; + return 0; } -void CiteDict::insert(const char *label) +void CitationManager::clear() { - m_entries.insert(label,new CiteInfo(label)); + p->entries.clear(); } -CiteInfo *CiteDict::find(const char *label) const +bool CitationManager::isEmpty() const { - return label ? m_entries.find(label) : 0; + int numFiles = Config_getList(CITE_BIB_FILES).count(); + return (numFiles==0 || p->entries.empty()); } -void CiteDict::clear() +const char *CitationManager::fileName() const { - m_entries.clear(); + return "citelist"; } -bool CiteDict::isEmpty() const +const char *CitationManager::anchorPrefix() const { - QStrList &citeBibFiles = Config_getList(CITE_BIB_FILES); - return (citeBibFiles.count()==0 || m_entries.isEmpty()); + return "CITEREF_"; } -void CiteDict::generatePage() const +void CitationManager::generatePage() { - //printf("** CiteDict::generatePage() count=%d\n",m_ordering.count()); + //printf("** CitationManager::generatePage() count=%d\n",m_ordering.count()); // do not generate an empty citations page if (isEmpty()) return; // nothing to cite // 0. add cross references from the bib files to the cite dictionary QFile f; - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); - const char *bibdata = citeDataList.first(); - while (bibdata) + const QStrList &citeDataList = Config_getList(CITE_BIB_FILES); + QStrListIterator li(citeDataList); + const char *bibdata = 0; + for (li.toFirst() ; (bibdata = li.current()) ; ++li) { QCString bibFile = bibdata; if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; @@ -144,11 +140,11 @@ void CiteDict::generatePage() const f.readBlock(input.rawData(),fi.size()); f.close(); input.at(fi.size())='\0'; - int p=0,s; - while ((s=input.find('\n',p))!=-1) + int pos=0,s; + while ((s=input.find('\n',pos))!=-1) { - QCString line = input.mid(p,s-p); - p=s+1; + QCString line = input.mid(pos,s-pos); + pos=s+1; int i; if ((i = line.find("crossref")) != -1) /* assumption cross reference is on one line and the only item */ @@ -158,7 +154,10 @@ void CiteDict::generatePage() const if (j!=-1 && k!=-1) { QCString label = line.mid(j+1,k-j-1); - if (!m_entries.find(label)) Doxygen::citeDict->insert(label.data()); + if (p->entries.find(label.data())==p->entries.end()) // not found yet + { + insert(label); + } } } } @@ -168,7 +167,6 @@ void CiteDict::generatePage() const { err("bib file %s not found!\n",bibFile.data()); } - bibdata = citeDataList.next(); } // 1. generate file with markers and citations to OUTPUT_DIRECTORY @@ -182,11 +180,9 @@ void CiteDict::generatePage() const FTextStream t(&f); t << "<!-- BEGIN CITATIONS -->" << endl; t << "<!--" << endl; - QDictIterator<CiteInfo> it(m_entries); - CiteInfo *ci; - for (it.toFirst();(ci=it.current());++it) + for (const auto &it : p->entries) { - t << "\\citation{" << ci->label << "}" << endl; + t << "\\citation{" << it.second->label() << "}" << endl; } t << "-->" << endl; t << "<!-- END CITATIONS -->" << endl; @@ -210,9 +206,8 @@ void CiteDict::generatePage() const QCString bibOutputFiles = ""; QDir thisDir; thisDir.mkdir(bibOutputDir); - bibdata = citeDataList.first(); int i = 0; - while (bibdata) + for (li.toFirst() ; (bibdata = li.current()) ; ++li) { QCString bibFile = bibdata; if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; @@ -226,7 +221,6 @@ void CiteDict::generatePage() const bibOutputFiles = bibOutputFiles + " " + bibTmpDir + bibTmpFile + QCString().setNum(i) + ".bib"; } } - bibdata = citeDataList.next(); } QString oldDir = QDir::currentDirPath(); @@ -260,13 +254,13 @@ void CiteDict::generatePage() const f.readBlock(input.rawData(),fi.size()); f.close(); input.at(fi.size())='\0'; - int p=0,s; + int pos=0,s; //printf("input=[%s]\n",input.data()); - while ((s=input.find('\n',p))!=-1) + while ((s=input.find('\n',pos))!=-1) { - QCString line = input.mid(p,s-p); - //printf("p=%d s=%d line=[%s]\n",p,s,line.data()); - p=s+1; + QCString line = input.mid(pos,s-pos); + //printf("pos=%d s=%d line=[%s]\n",pos,s,line.data()); + pos=s+1; if (line.find("<!-- BEGIN BIBLIOGRAPHY")!=-1) insideBib=TRUE; else if (line.find("<!-- END BIBLIOGRAPH")!=-1) insideBib=FALSE; @@ -281,12 +275,12 @@ void CiteDict::generatePage() const QCString label = line.mid(i+14,j-i-14); QCString number = line.mid(j+2,k-j-1); label = substitute(substitute(label,"–","--"),"—","---"); - CiteInfo *ci = m_entries.find(label); - //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),ci); line = line.left(i+14) + label + line.right(line.length()-j); - if (ci) + auto it = p->entries.find(label.data()); + //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),it->second.get()); + if (it!=p->entries.end()) { - ci->text = number; + it->second->setText(number); } } } @@ -295,19 +289,17 @@ void CiteDict::generatePage() const //printf("doc=[%s]\n",doc.data()); // 7. add it as a page - addRelatedPage(CiteConsts::fileName, - theTranslator->trCiteReferences(),doc,CiteConsts::fileName,1); + addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1); // 8. for latex we just copy the bib files to the output and let // latex do this work. if (Config_getBool(GENERATE_LATEX)) { // copy bib files to the latex output dir - QStrList &citeDataList = Config_getList(CITE_BIB_FILES); + const QStrList &citeDataList = Config_getList(CITE_BIB_FILES); QCString latexOutputDir = Config_getString(LATEX_OUTPUT)+"/"; int i = 0; - const char *bibdata = citeDataList.first(); - while (bibdata) + for (li.toFirst() ; (bibdata = li.current()) ; ++li) { QCString bibFile = bibdata; // Note: file can now have multiple dots @@ -327,21 +319,80 @@ void CiteDict::generatePage() const { err("bib file %s not found!\n",bibFile.data()); } - bibdata = citeDataList.next(); } } // 9. Remove temporary files - thisDir.remove(citeListFile); - thisDir.remove(doxygenBstFile); - thisDir.remove(bib2xhtmlFile); - // we might try to remove too many files as empty files didn't get a corresponding new file - // but the remove function does not emit an error for it and we don't catch the error return - // so no problem. - for (unsigned int j = 1; j <= citeDataList.count(); j++) + if (RM_TMP_FILES) + { + thisDir.remove(citeListFile); + thisDir.remove(doxygenBstFile); + thisDir.remove(bib2xhtmlFile); + // we might try to remove too many files as empty files didn't get a corresponding new file + // but the remove function does not emit an error for it and we don't catch the error return + // so no problem. + for (unsigned int j = 1; j <= citeDataList.count(); j++) + { + thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(j) + ".bib"); + } + thisDir.rmdir(bibOutputDir); + } +} + +void CitationManager::writeLatexBibliography(FTextStream &t) const +{ + if (p->entries.empty()) return; + + QCString style = Config_getString(LATEX_BIB_STYLE); + if (style.isEmpty()) + { + style="plain"; + } + QCString unit; + if (Config_getBool(COMPACT_LATEX)) + { + unit = "section"; + } + else + { + unit = "chapter"; + } + t << "% Bibliography\n" + "\\newpage\n" + "\\phantomsection\n"; + bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS); + if (!pdfHyperlinks) { - thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(j) + ".bib"); + t << "\\clearemptydoublepage\n"; + t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; } - thisDir.rmdir(bibOutputDir); + t << "\\bibliographystyle{" << style << "}\n" + "\\bibliography{"; + QStrList &citeDataList = Config_getList(CITE_BIB_FILES); + int i = 0; + QStrListIterator li(citeDataList); + const char *bibdata = 0; + for (li.toFirst() ; (bibdata = li.current()) ; ++li) + { + QCString bibFile = bibdata; + // Note: file can now have multiple dots + if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; + QFileInfo fi(bibFile); + if (fi.exists()) + { + if (!bibFile.isEmpty()) + { + if (i) t << ","; + i++; + t << bibTmpFile << QCString().setNum(i); + } + } + } + t << "}\n"; + if (pdfHyperlinks) + { + t << "\\addcontentsline{toc}{" << unit << "}{" << theTranslator->trCiteReferences() << "}\n"; + } + t << "\n"; } |