summaryrefslogtreecommitdiffstats
path: root/src/cite.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cite.cpp')
-rw-r--r--src/cite.cpp277
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,"&ndash;","--"),"&mdash;","---");
- 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";
}