diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-07-31 18:23:27 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-07-31 18:56:26 (GMT) |
commit | f8c1c09b5f25489223530bb73b9d7b173562b3ff (patch) | |
tree | 2dc37c3f931baefb549a343c074382d023d786b9 /src/cite.cpp | |
parent | 710117ba1c88da13f1cabf9f65bf780412395d56 (diff) | |
download | Doxygen-f8c1c09b5f25489223530bb73b9d7b173562b3ff.zip Doxygen-f8c1c09b5f25489223530bb73b9d7b173562b3ff.tar.gz Doxygen-f8c1c09b5f25489223530bb73b9d7b173562b3ff.tar.bz2 |
Moved citation cross reference searching to a separate function
Diffstat (limited to 'src/cite.cpp')
-rw-r--r-- | src/cite.cpp | 200 |
1 files changed, 116 insertions, 84 deletions
diff --git a/src/cite.cpp b/src/cite.cpp index f9af2b4..044651b 100644 --- a/src/cite.cpp +++ b/src/cite.cpp @@ -108,107 +108,139 @@ const char *CitationManager::anchorPrefix() const return "CITEREF_"; } -void CitationManager::generatePage() +void CitationManager::insertCrossReferencesForBibFile(const QCString &bibFile) { - //printf("** CitationManager::generatePage() count=%d\n",m_ordering.count()); + // sanity checks + if (bibFile.isEmpty()) + { + return; + } + QFileInfo fi(bibFile); + if (!fi.exists()) + { + err("bib file %s not found!\n",bibFile.data()); + return; + } + QFile f(bibFile); + if (!f.open(IO_ReadOnly)) + { + err("could not open file %s for reading\n",bibFile.data()); + return; + } - // do not generate an empty citations page - if (isEmpty()) return; // nothing to cite + // convert file to string + QCString doc; + QCString input(fi.size()+1); + f.readBlock(input.rawData(),fi.size()); + f.close(); + input.at(fi.size())='\0'; - // 0. add cross references from the bib files to the cite dictionary - QFile f; - const StringVector &citeDataList = Config_getList(CITE_BIB_FILES); - for (const auto &bibdata : citeDataList) + int pos=0; + int s; + + // helper lambda function to get the next line of input and update pos accordingly + auto get_next_line = [&input,&pos,&s]() { - QCString bibFile = bibdata.c_str(); - if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; - QFileInfo fi(bibFile); - if (fi.exists()) + uint prevPos = (uint)pos; + pos=s+1; + return input.mid(prevPos,(uint)(s-prevPos)); + }; + + // helper lambda function to return if the end of the input has reached + auto end_of_input = [&s]() + { + return s==-1; + }; + + // helper lambda function to proceed to the next line in the input, and update s + // to point to the start of the line. Return true as long as there is a new line. + auto has_next_line = [&input,&pos,&s]() + { + s=input.find('\n',pos); + return s!=-1; + }; + + // search for citation cross references + QCString citeName; + while (has_next_line()) + { + QCString line = get_next_line(); + + int i; + if (line.stripWhiteSpace().startsWith("@")) { - if (!bibFile.isEmpty()) + // assumption entry like: "@book { name," or "@book { name" (spaces optional) + int j = line.find('{'); + // when no {, go hunting for it + while (j==-1 && has_next_line()) { - f.setName(bibFile); - if (!f.open(IO_ReadOnly)) - { - err("could not open file %s for reading\n",bibFile.data()); - } - QCString doc; - QCString input(fi.size()+1); - f.readBlock(input.rawData(),fi.size()); - f.close(); - input.at(fi.size())='\0'; - int pos=0; - int s; - QCString citeName; - while ((s=input.find('\n',pos))!=-1) + line = get_next_line(); + j = line.find('{'); + } + // search for the name + citeName = ""; + if (!end_of_input() && j!=-1) // to prevent something like "@manual ," and no { found + { + int k = line.find(',',j); + j++; + // found a line "@....{.....,...." or "@.....{....." + // ^=j ^=k ^=j k=-1 + while (!end_of_input() && citeName.isEmpty()) { - QCString line = input.mid((uint)pos,(uint)(s-pos)); - pos=s+1; - - int i; - if ((i = line.find("crossref")) != -1) /* assumption cross reference is on one line and the only item */ + if (k!=-1) + { + citeName = line.mid((uint)(j),(uint)(k-j)); + } + else { - int j=line.find("{",i); - int k=line.find("}",i); - if (j!=-1 && k!=-1) - { - QCString crossrefName = line.mid((uint)(j+1),(uint)(k-j-1)); - // check if the reference with the cross reference is used - // insert cross refererence when cross reference has not yet been added. - if ((p->entries.find(citeName.data())!=p->entries.end()) && - (p->entries.find(crossrefName.data())==p->entries.end())) // not found yet - { - insert(crossrefName); - } - } + citeName = line.mid((uint)(j)); } - else if (line.stripWhiteSpace().startsWith("@")) + citeName = citeName.stripWhiteSpace(); + j = 0; + if (citeName.isEmpty() && has_next_line()) { - // assumption entry like: "@book { name," or "@book { name" (spaces optional) - int j=line.find("{"); - // when no {, go hunting for it - while (j==-1 && (s=input.find('\n',pos))!=-1) - { - line = input.mid((uint)pos,(uint)(s-pos)); - j=line.find("{"); - pos=s+1; - } - // search for the name - citeName = ""; - if (s != -1 && j!= -1) // to prevent something like "@manual ," and no { found - { - int k=line.find(",",j); - j++; - while (s != -1 && citeName.isEmpty()) - { - if (k != -1) - { - citeName = line.mid((uint)(j),(uint)(k-j)); - } - else - { - citeName = line.mid((uint)(j)); - } - citeName = citeName.stripWhiteSpace(); - j = 0; - if (citeName.isEmpty() && (s=input.find('\n',pos))!=-1) - { - line = input.mid((uint)pos,(uint)(s-pos)); - pos=s+1; - k=line.find(","); - } - } - } - //printf("citeName = #%s#\n",citeName.data()); + line = get_next_line(); + k = line.find(','); } } } + //printf("citeName = #%s#\n",citeName.data()); } - else if (!fi.exists()) + else if ((i=line.find("crossref"))!=-1 && !citeName.isEmpty()) /* assumption cross reference is on one line and the only item */ { - err("bib file %s not found!\n",bibFile.data()); + int j = line.find('{',i); + int k = line.find('}',i); + if (j>i && k>j) + { + QCString crossrefName = line.mid((uint)(j+1),(uint)(k-j-1)); + // check if the reference with the cross reference is used + // insert cross refererence when cross reference has not yet been added. + if ((p->entries.find(citeName.data())!=p->entries.end()) && + (p->entries.find(crossrefName.data())==p->entries.end())) // not found yet + { + insert(crossrefName); + } + } } } +} + +void CitationManager::generatePage() +{ + //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; + const StringVector &citeDataList = Config_getList(CITE_BIB_FILES); + for (const auto &bibdata : citeDataList) + { + QCString bibFile = bibdata.c_str(); + if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib"; + insertCrossReferencesForBibFile(bibFile); + } // 1. generate file with markers and citations to OUTPUT_DIRECTORY QCString outputDir = Config_getString(OUTPUT_DIRECTORY); |