diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-02-16 15:37:28 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-02-16 15:37:28 (GMT) |
commit | 77d5346f4866429b240b96a146381e770e5e0788 (patch) | |
tree | 043c82a512292122b24140cc0ab921543684c19b /src | |
parent | 47f449c5f94b14cc6fe9081212a5ecdb61964233 (diff) | |
parent | fa520f975a0893c0d123c1cafec63206bf737794 (diff) | |
download | Doxygen-77d5346f4866429b240b96a146381e770e5e0788.zip Doxygen-77d5346f4866429b240b96a146381e770e5e0788.tar.gz Doxygen-77d5346f4866429b240b96a146381e770e5e0788.tar.bz2 |
Merge branch 'citations'
Diffstat (limited to 'src')
-rw-r--r-- | src/cite.cpp | 277 | ||||
-rw-r--r-- | src/cite.h | 81 | ||||
-rw-r--r-- | src/commentscan.l | 2 | ||||
-rw-r--r-- | src/docparser.cpp | 23 | ||||
-rw-r--r-- | src/doxygen.cpp | 9 | ||||
-rw-r--r-- | src/doxygen.h | 1 | ||||
-rw-r--r-- | src/latexdocvisitor.cpp | 3 | ||||
-rw-r--r-- | src/latexgen.cpp | 4 |
8 files changed, 214 insertions, 186 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"; } @@ -1,8 +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 @@ -16,83 +14,64 @@ * */ -#ifndef CITEDB_H -#define CITEDB_H +#ifndef CITE_H +#define CITE_H -#include <qdict.h> +#include <memory> -class FTextStream; +#include <qcstring.h> -/// String constants for citations -struct CiteConsts -{ - static const QCString fileName; - static const QCString anchorPrefix; -}; +class FTextStream; /// Citation-related data. struct CiteInfo { - CiteInfo(const char *label_, const char *text_=0, const char *fullText_=0, - const char *ref_=0) : - label(label_), text(text_), fullText(fullText_), ref(ref_) - { } - - CiteInfo(const CiteInfo &o) - { label=o.label.copy(); text=o.text.copy(); fullText=o.fullText.copy(); ref=o.ref.copy(); } - - QCString label; - QCString text; - QCString fullText; - QCString ref; - + virtual ~CiteInfo() {} + virtual QCString label() const = 0; + virtual QCString text() const = 0; }; /** - * @brief Cite database access class. - * @details This class provides access do the database of bibliographic + * @brief Citation manager class. + * @details This class provides access do the database of bibliographic * references through the bibtex backend. */ -class CiteDict +class CitationManager { public: - /** Create the database, with an expected maximum of \a size entries */ - CiteDict(int size); - -// /** Resolve references to citations */ -// void resolve(); + static CitationManager &instance(); /** Insert a citation identified by \a label into the database */ void insert(const char *label); - /** Return the citation info for a given \a label */ - CiteInfo *find(const char *label) const; + /** Return the citation info for a given \a label. + * Ownership of the info stays with the manager. + */ + const CiteInfo *find(const char *label) const; /** Generate the citations page */ - void generatePage() const; + void generatePage(); /** clears the database */ void clear(); - /** return TRUE if there are no citations. - * Only valid after calling resolve() + /** return TRUE if there are no citations. */ bool isEmpty() const; - /** writes the latex code for the standard bibliography - * section to text stream \a t + /** writes the latex code for the standard bibliography + * section to text stream \a t */ - void writeLatexBibliography(FTextStream &t); + void writeLatexBibliography(FTextStream &t) const; + + const char *fileName() const; + const char *anchorPrefix() const; private: -// bool writeAux(); -// bool writeBst(); -// bool execute(); -// void parse(); -// void clean(); - QDict<CiteInfo> m_entries; -// QList<QCString> m_ordering; - QCString m_baseFileName; + /** Create the database, with an expected maximum of \a size entries */ + CitationManager(); + struct Private; + std::unique_ptr<Private> p; }; -#endif +#endif // CITE_H diff --git a/src/commentscan.l b/src/commentscan.l index 597246e..e1b2f13 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -2923,7 +2923,7 @@ static void addCite(yyscan_t yyscanner) name=yytext+1; name=name.left(yyleng-2); } - Doxygen::citeDict->insert(name.data()); + CitationManager::instance().insert(name.data()); } //----------------------------------------------------------------------------- diff --git a/src/docparser.cpp b/src/docparser.cpp index b3ae6bd..c5eb9e9 100644 --- a/src/docparser.cpp +++ b/src/docparser.cpp @@ -1919,12 +1919,14 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor) return; } - if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix) + const CitationManager &ct = CitationManager::instance(); + QCString anchorPrefix = ct.anchorPrefix(); + if (id.left(anchorPrefix.length()) == anchorPrefix) { - CiteInfo *cite = Doxygen::citeDict->find(id.mid(CiteConsts::anchorPrefix.length())); - if (cite) + const CiteInfo *cite = ct.find(id.mid(anchorPrefix.length())); + if (cite) { - m_file = convertNameToFile(CiteConsts::fileName,FALSE,TRUE); + m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); m_anchor = id; } else @@ -2585,14 +2587,15 @@ DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //cont //printf("DocCite::DocCite(target=%s)\n",target.data()); ASSERT(!target.isEmpty()); m_relPath = g_relPath; - CiteInfo *cite = Doxygen::citeDict->find(target); + const CitationManager &ct = CitationManager::instance(); + const CiteInfo *cite = ct.find(target); //printf("cite=%p text='%s' numBibFiles=%d\n",cite,cite?cite->text.data():"<null>",numBibFiles); - if (numBibFiles>0 && cite && !cite->text.isEmpty()) // ref to citation + if (numBibFiles>0 && cite && !cite->text().isEmpty()) // ref to citation { - m_text = cite->text; - m_ref = cite->ref; - m_anchor = CiteConsts::anchorPrefix+cite->label; - m_file = convertNameToFile(CiteConsts::fileName,FALSE,TRUE); + m_text = cite->text(); + m_ref = ""; + m_anchor = ct.anchorPrefix()+cite->label(); + m_file = convertNameToFile(ct.fileName(),FALSE,TRUE); //printf("CITE ==> m_text=%s,m_ref=%s,m_file=%s,m_anchor=%s\n", // m_text.data(),m_ref.data(),m_file.data(),m_anchor.data()); return; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 5f5d3ce..cb667cb 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -129,7 +129,6 @@ GroupSDict *Doxygen::groupSDict = 0; PageSDict *Doxygen::pageSDict = 0; PageSDict *Doxygen::exampleSDict = 0; SectionDict *Doxygen::sectionDict = 0; // all page sections -CiteDict *Doxygen::citeDict=0; // database of bibliographic references StringDict Doxygen::aliasDict(257); // aliases QDict<void> Doxygen::inputPaths(1009); FileNameDict *Doxygen::includeNameDict = 0; // include names @@ -202,7 +201,7 @@ void clearAll() Doxygen::mscFileNameDict->clear(); Doxygen::diaFileNameDict->clear(); Doxygen::tagDestinationDict.clear(); - delete Doxygen::citeDict; + CitationManager::instance().clear(); delete Doxygen::mainPage; Doxygen::mainPage=0; FormulaManager::instance().clear(); } @@ -9862,7 +9861,6 @@ void initDoxygen() Doxygen::memGrpInfoDict.setAutoDelete(TRUE); Doxygen::tagDestinationDict.setAutoDelete(TRUE); Doxygen::dirRelations.setAutoDelete(TRUE); - Doxygen::citeDict = new CiteDict(257); Doxygen::genericsDict = new GenericsSDict; Doxygen::indexList = new IndexList; Doxygen::sectionDict = new SectionDict(257); @@ -11252,11 +11250,8 @@ void parseInput() g_s.end(); } - //g_s.begin("Resolving citations...\n"); - //Doxygen::citeDict->resolve(); - g_s.begin("Generating citations page...\n"); - Doxygen::citeDict->generatePage(); + CitationManager::instance().generatePage(); g_s.end(); g_s.begin("Counting members...\n"); diff --git a/src/doxygen.h b/src/doxygen.h index f08be86..2833611 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -139,7 +139,6 @@ class Doxygen static QCString objDBFileName; static QCString entryDBFileName; static QCString filterDBFileName; - static CiteDict *citeDict; static bool userComments; static IndexList *indexList; static int subpageNestingLevel; diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index b9ce963..b899935 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -657,7 +657,8 @@ void LatexDocVisitor::visit(DocCite *cite) { //startLink(cite->ref(),cite->file(),cite->anchor()); QCString anchor = cite->anchor(); - anchor = anchor.mid(CiteConsts::anchorPrefix.length()); // strip prefix + QCString anchorPrefix = CitationManager::instance().anchorPrefix(); + anchor = anchor.mid(anchorPrefix.length()); // strip prefix m_t << "\\cite{" << anchor << "}"; } else diff --git a/src/latexgen.cpp b/src/latexgen.cpp index b8cac2f..79ba44f 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -283,7 +283,7 @@ LatexGenerator::~LatexGenerator() static void writeLatexMakefile() { - bool generateBib = !Doxygen::citeDict->isEmpty(); + bool generateBib = !CitationManager::instance().isEmpty(); QCString dir=Config_getString(LATEX_OUTPUT); QCString fileName=dir+"/Makefile"; QFile file(fileName); @@ -829,7 +829,7 @@ static void writeDefaultFooter(FTextStream &t) "\n"; // Bibliography - Doxygen::citeDict->writeLatexBibliography(t); + CitationManager::instance().writeLatexBibliography(t); // Index t << "% Index\n"; |