1 /******************************************************************************
3 * Copyright (C) 2011 by Dimitri van Heesch
4 * Based on a patch by David Munger
6 * Permission to use, copy, modify, and distribute this software and its
7 * documentation under the terms of the GNU General Public License is hereby
8 * granted. No representations are made about the suitability of this software
9 * for any purpose. It is provided "as is" without express or implied warranty.
10 * See the GNU General Public License for more details.
12 * Documents produced by Doxygen are derivative works derived from the
13 * input used in their production; they are not affected by this license.
23 #include "ftextstream.h"
26 //--------------------------------------------------------------------------
28 static const char *doxygen_bst =
29 #include "doxygen_bst.h"
32 static const char *bib2xhtml_pl =
33 #include "bib2xhtml.h"
36 //--------------------------------------------------------------------------
38 const QCString CiteConsts::fileName("citelist");
39 const QCString CiteConsts::anchorPrefix("CITEREF_");
41 //--------------------------------------------------------------------------
43 CiteDict::CiteDict(int size) : m_entries(size, FALSE)
45 m_entries.setAutoDelete(TRUE);
48 static QCString getListOfBibFiles(const QCString &sep,bool stripExtension)
51 QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
52 const char *bibdata = citeDataList.first();
56 QCString bibFile = bibdata;
57 if (stripExtension && bibFile.right(4)==".bib")
59 bibFile = bibFile.left(bibFile.length()-4);
61 if (stripExtension && (i=bibFile.findRev('/'))!=-1)
63 bibFile = bibFile.mid(i+1);
65 if (!bibFile.isEmpty())
68 bibdata = citeDataList.next();
76 bibdata = citeDataList.next();
82 void CiteDict::writeLatexBibliography(FTextStream &t)
84 if (m_entries.count()==0) return;
85 QCString style = Config_getString("LATEX_BIB_STYLE");
86 if (style.isEmpty()) style="plain";
87 t << "\\newpage \\bibliographystyle{" << style << "}" << endl;
88 t << "\\bibliography{" << getListOfBibFiles(",",TRUE) << "}" << endl;
91 void CiteDict::insert(const char *label)
93 m_entries.insert(label,new CiteInfo(label));
96 CiteInfo *CiteDict::find(const char *label) const
98 return label ? m_entries.find(label) : 0;
101 void CiteDict::clear()
106 bool CiteDict::isEmpty() const
108 QStrList &citeBibFiles = Config_getList("CITE_BIB_FILES");
109 return (citeBibFiles.count()==0 || m_entries.isEmpty());
112 void CiteDict::generatePage() const
114 //printf("** CiteDict::generatePage() count=%d\n",m_ordering.count());
116 // do not generate an empty citations page
117 if (isEmpty()) return; // nothing to cite
119 // 1. generate file with markers and citations to OUTPUT_DIRECTORY
121 QCString outputDir = Config_getString("OUTPUT_DIRECTORY");
122 QCString citeListFile = outputDir+"/citelist.doc";
123 f.setName(citeListFile);
124 if (!f.open(IO_WriteOnly))
126 err("error: could not open file %s for writing\n",citeListFile.data());
129 t << "<!-- BEGIN CITATIONS -->" << endl;
131 QDictIterator<CiteInfo> it(m_entries);
133 for (it.toFirst();(ci=it.current());++it)
135 t << "\\citation{" << ci->label << "}" << endl;
138 t << "<!-- END CITATIONS -->" << endl;
139 t << "<!-- BEGIN BIBLIOGRAPHY -->" << endl;
140 t << "<!-- END BIBLIOGRAPHY -->" << endl;
143 // 2. generate bib2xhtml
144 QCString bib2xhtmlFile = outputDir+"/bib2xhtml.pl";
145 f.setName(bib2xhtmlFile);
146 QCString bib2xhtml = bib2xhtml_pl;
147 if (!f.open(IO_WriteOnly))
149 err("error: could not open file %s for writing\n",bib2xhtmlFile.data());
151 f.writeBlock(bib2xhtml, bib2xhtml.length());
154 // 3. generate doxygen.bst
155 QCString doxygenBstFile = outputDir+"/doxygen.bst";
156 QCString bstData = doxygen_bst;
157 f.setName(doxygenBstFile);
158 if (!f.open(IO_WriteOnly))
160 err("error: could not open file %s for writing\n",doxygenBstFile.data());
162 f.writeBlock(bstData, bstData.length());
165 // 4. run bib2xhtml perl script on the generated file which will insert the
166 // bibliography in citelist.doc
167 portable_system("perl",bib2xhtmlFile+" "+getListOfBibFiles(" ",FALSE)+" "+
170 // 5. read back the file
171 f.setName(citeListFile);
172 if (!f.open(IO_ReadOnly))
174 err("error: could not open file %s/citelist.doc for reading\n",outputDir.data());
176 bool insideBib=FALSE;
179 QFileInfo fi(citeListFile);
180 QCString input(fi.size()+1);
181 f.readBlock(input.data(),fi.size());
182 input.at(fi.size())='\0';
184 //printf("input=[%s]\n",input.data());
185 while ((s=input.find('\n',p))!=-1)
187 QCString line = input.mid(p,s-p);
188 //printf("p=%d s=%d line=[%s]\n",p,s,line.data());
191 if (line.find("<!-- BEGIN BIBLIOGRAPHY")!=-1) insideBib=TRUE;
192 else if (line.find("<!-- END BIBLIOGRAPH")!=-1) insideBib=FALSE;
193 else if (insideBib) doc+=line+"\n";
195 // determine text to use at the location of the @cite command
196 if (insideBib && (i=line.find("<a name=\"CITEREF_"))!=-1)
198 int j=line.find("\">[");
199 int k=line.find("]</a>");
202 QCString label = line.mid(i+17,j-i-17);
203 QCString number = line.mid(j+2,k-j-1);
204 CiteInfo *ci = m_entries.find(label);
205 //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),ci);
213 //printf("doc=[%s]\n",doc.data());
215 // 6. add it as a page
216 addRelatedPage(CiteConsts::fileName,
217 theTranslator->trCiteReferences(),doc,0,CiteConsts::fileName,1,0,0,0);
219 // 7. for latex we just copy the bib files to the output and let
220 // latex do this work.
221 if (Config_getBool("GENERATE_LATEX"))
223 // copy bib files to the latex output dir
224 QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
225 QCString latexOutputDir = Config_getString("LATEX_OUTPUT")+"/";
226 const char *bibdata = citeDataList.first();
229 QCString bibFile = bibdata;
230 if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
231 QFileInfo fi(bibFile);
234 if (!bibFile.isEmpty())
236 copyFile(bibFile,latexOutputDir+fi.fileName().data());
241 err("Error: bib file %s not found!\n",bibFile.data());
243 bibdata = citeDataList.next();
247 // 8. Remove temporary files
249 thisDir.remove(citeListFile);
250 thisDir.remove(doxygenBstFile);
251 thisDir.remove(bib2xhtmlFile);