Doxygen
Loading...
Searching...
No Matches
CitationManager Class Reference

Citation manager class. More...

#include <src/cite.h>

Classes

struct  Private

Public Member Functions

void insert (const DString &label)
 Insert a citation identified by label into the database.
const CiteInfofind (const DString &label) const
 Return the citation info for a given label.
void generatePage ()
 Generate the citations page.
void clear ()
 clears the database
bool empty () const
 return true if there are no citations.
DString latexBibFiles ()
 lists the bibtex cite files in a comma separated list
DString fileName () const
DString anchorPrefix () const

Static Public Member Functions

static CitationManagerinstance ()

Private Member Functions

 CitationManager ()
 Create the database, with an expected maximum of size entries.
 ~CitationManager ()=default
void insertCrossReferencesForBibFile (const DString &bibFile)
DString getFormulas (const DString &s)
DString replaceFormulas (const DString &s)

Private Attributes

std::unique_ptr< Privatep

Detailed Description

Citation manager class.

This class provides access do the database of bibliographic references through the bibtex backend.

Definition at line 84 of file cite.h.

Constructor & Destructor Documentation

◆ CitationManager()

CitationManager::CitationManager ( )
private

Create the database, with an expected maximum of size entries.

Definition at line 96 of file cite.cpp.

96 : p(new Private)
97{
98}
std::unique_ptr< Private > p
Definition cite.h:123

References p.

Referenced by instance(), and ~CitationManager().

◆ ~CitationManager()

CitationManager::~CitationManager ( )
privatedefault

Member Function Documentation

◆ anchorPrefix()

DString CitationManager::anchorPrefix ( ) const

Definition at line 131 of file cite.cpp.

132{
133 return "CITEREF_";
134}

Referenced by DocAnchor::DocAnchor(), DocCite::DocCite(), LatexDocVisitor::operator()(), and TextDocVisitor::operator()().

◆ clear()

void CitationManager::clear ( )

clears the database

Definition at line 115 of file cite.cpp.

116{
117 p->entries.clear();
118}

References p.

Referenced by clearAll().

◆ empty()

bool CitationManager::empty ( ) const

return true if there are no citations.

Definition at line 120 of file cite.cpp.

121{
122 size_t numFiles = Config_getList(CITE_BIB_FILES).size();
123 return (numFiles==0 || p->entries.empty());
124}
#define Config_getList(name)
Definition config.h:38

References Config_getList, and p.

Referenced by generatePage(), substituteLatexKeywords(), writeLatexMakefile(), and writeMakeBat().

◆ fileName()

DString CitationManager::fileName ( ) const

Definition at line 126 of file cite.cpp.

127{
128 return "citelist";
129}

Referenced by DocAnchor::DocAnchor(), DocCite::DocCite(), and generatePage().

◆ find()

const CiteInfo * CitationManager::find ( const DString & label) const

Return the citation info for a given label.

Ownership of the info stays with the manager.

Definition at line 106 of file cite.cpp.

107{
108 if (auto it = p->entries.find(label.lower().str()); it != p->entries.end())
109 {
110 return it->second.get();
111 }
112 return nullptr;
113}
DString lower() const
Definition dstring.h:326
const std::string & str() const
Definition dstring.h:645

References DString::lower(), p, and DString::str().

Referenced by DocAnchor::DocAnchor(), DocCite::DocCite(), DocCite::getText(), and insertCrossReferencesForBibFile().

◆ generatePage()

void CitationManager::generatePage ( )

Generate the citations page.

Definition at line 336 of file cite.cpp.

337{
338 //printf("** CitationManager::generatePage() count=%d\n",m_ordering.count());
339
340 // do not generate an empty citations page
341 if (empty()) return; // nothing to cite
342
343 bool citeDebug = Debug::isFlagSet(Debug::Cite);
344
345 // 0. add cross references from the bib files to the cite dictionary
346 StringVector citeDataList = Config_getList(CITE_BIB_FILES);
347 for (const auto &bibdata : citeDataList)
348 {
349 DString bibFile = getBibFile(bibdata);
351 }
352
353 // 1. generate file with markers and citations to OUTPUT_DIRECTORY
354 DString outputDir = Config_getString(OUTPUT_DIRECTORY);
355 DString citeListFile = outputDir+"/citelist.doc";
356 {
357 std::ofstream t = Portable::openOutputStream(citeListFile);
358 if (!t.is_open())
359 {
360 err("could not open file {} for writing\n",citeListFile);
361 }
362 t << "<!-- BEGIN CITATIONS -->\n";
363 t << "<!--\n";
364 for (const auto &it : p->entries)
365 {
366 t << "\\citation{" << it.second->label() << "}\n";
367 }
368 t << "-->\n";
369 t << "<!-- END CITATIONS -->\n";
370 t << "<!-- BEGIN BIBLIOGRAPHY -->\n";
371 t << "<!-- END BIBLIOGRAPHY -->\n";
372 t.close();
373 }
374
375 // 2. generate bib2xhtml
376 DString bib2xhtmlFile = outputDir+"/bib2xhtml.pl";
377 ResourceMgr::instance().copyResource("bib2xhtml.pl",outputDir);
378
379 // 3. generate doxygen.bst
380 DString doxygenBstFile = outputDir+"/doxygen.bst";
381 ResourceMgr::instance().copyResource("doxygen.bst",outputDir);
382
383 // 4. for all formats we just copy the bib files to as special output directory
384 // so bibtex can find them without path (bibtex doesn't support paths or
385 // filenames with spaces!)
386 // Strictly not required when only latex is generated
387 DString bibOutputDir = outputDir+"/"+bibTmpDir;
388 DString bibOutputFiles = "";
389 Dir thisDir;
390 if (!thisDir.exists(bibOutputDir.str()) && !thisDir.mkdir(bibOutputDir.str()))
391 {
392 err("Failed to create temporary output directory '{}', skipping citations\n",bibOutputDir);
393 return;
394 }
395 size_t i = 0;
396 for (const auto &bibdata : citeDataList)
397 {
398 DString bibFile = getBibFile(bibdata);
399 FileInfo fi(bibFile.str());
400 if (fi.exists())
401 {
402 if (!bibFile.empty())
403 {
404 ++i;
405 std::ifstream f_org = Portable::openInputStream(bibFile);
406 if (!f_org.is_open())
407 {
408 err("could not open file {} for reading\n",bibFile);
409 }
410 std::ofstream f_out = Portable::openOutputStream(bibOutputDir + bibTmpFile + DString().setNum(i) + ".bib");
411 if (!f_out.is_open())
412 {
413 err("could not open file {}{}{:d}{} for reading\n",bibOutputDir,bibTmpFile,i,".bib");
414 }
415 DString docs;
416 std::string lineStr;
417 while (getline(f_org,lineStr))
418 {
419 docs += lineStr + "\n";
420 }
421 docs = getFormulas(docs);
422 f_out << docs;
423 if (f_org.is_open()) f_org.close();
424 if (f_out.is_open()) f_out.close();
425 bibOutputFiles = bibOutputFiles + " " + bibTmpDir + bibTmpFile + DString().setNum(i) + ".bib";
426 }
427 }
428 }
429
430 std::string oldDir = Dir::currentDirPath();
431 Dir::setCurrent(outputDir.str());
432
433 // 5. run bib2xhtml perl script on the generated file which will insert the
434 // bibliography in citelist.doc
435 DString perlArgs = "\""+bib2xhtmlFile+"\" "+bibOutputFiles+" \""+ citeListFile+"\"";
436 if (citeDebug) perlArgs+=" -d";
437 int exitCode = Portable::system("perl",perlArgs);
438 if (exitCode!=0)
439 {
440 err("Problems running bibtex. Verify that the command 'perl --version' works from the command line. Exit code: {}\n",
441 exitCode);
442 }
443
444 Dir::setCurrent(oldDir);
445
446 // 6. read back the file
447 DString doc;
448 {
449 std::ifstream f = Portable::openInputStream(citeListFile);
450 if (!f.is_open())
451 {
452 err("could not open file {} for reading\n",citeListFile);
453 }
454
455 bool insideBib=false;
456 //printf("input=[%s]\n",qPrint(input));
457 std::string lineStr;
458 while (getline(f,lineStr))
459 {
460 DString line(lineStr);
461 //printf("pos=%d s=%d line=[%s]\n",pos,s,qPrint(line));
462
463 if (line.find("<!-- BEGIN BIBLIOGRAPHY")!=DString::npos) insideBib=true;
464 else if (line.find("<!-- END BIBLIOGRAPH")!=DString::npos) insideBib=false;
465 // determine text to use at the location of the @cite command
466 if (insideBib && ((i=line.find("name=\"CITEREF_"))!=DString::npos || (i=line.find("name=\"#CITEREF_"))!=DString::npos))
467 {
468 size_t j=line.find("\">[");
469 size_t j1=line.find("<!--[");
470 size_t k=line.find("]<!--");
471 size_t k1=line.find("]-->");
472 if (j!=DString::npos && k!=DString::npos)
473 {
474 DString label = line.mid(i+14,j-i-14);
475 StringVector optList = split(line.mid(j1+5,k1-j1-5).str(),",");
476 DString number = optList[0];
477 DString shortAuthor = optList[1];
478 DString year;
479 if (optList.size() == 3)
480 {
481 year = optList[2];
482 }
483 line = line.left(i+14) + label + line.mid(j);
484 auto it = p->entries.find(label.lower().str());
485 //printf("label='%s' number='%s' => %p\n",qPrint(label),qPrint(number),it->second.get());
486 if (it!=p->entries.end())
487 {
488 it->second->setText(number);
489 it->second->setShortAuthor(shortAuthor);
490 it->second->setYear(year.stripWhiteSpace());
491 }
492 }
493 }
494 if (insideBib) doc+=line+"\n";
495 }
496 //printf("doc=[%s]\n",qPrint(doc));
497 }
498
499 // 7. place formulas back and run the conversion of \f$ ... \f$ to the internal required format
500 {
501 doc = replaceFormulas(doc);
502 Entry current;
503 bool needsEntry = false;
504 CommentScanner commentScanner;
505 int lineNr = 0;
506 int pos = 0;
507 GuardedSectionStack guards;
508 Protection prot = Protection::Public;
509 commentScanner.parseCommentBlock(
510 nullptr,
511 &current,
512 doc, // text
513 fileName(), // file
514 lineNr, // line of block start
515 false, // isBrief
516 false, // isJavaDocStyle
517 false, // isInBody
518 prot, // protection
519 pos, // position,
520 needsEntry,
521 false,
522 &guards
523 );
524 doc = current.doc;
525 }
526
527 // 8. add it as a page
529
530 // 9. for latex we just copy the bib files to the output and let
531 // latex do this work.
532 if (Config_getBool(GENERATE_LATEX))
533 {
534 // copy bib files to the latex output dir
535 DString latexOutputDir = Config_getString(LATEX_OUTPUT)+"/";
536 i = 0;
537 for (const auto &bibdata : citeDataList)
538 {
539 DString bibFile = getBibFile(bibdata);
540 FileInfo fi(bibFile.str());
541 if (fi.exists())
542 {
543 if (!bibFile.empty())
544 {
545 // bug_700510, multiple times the same name were overwriting; creating new names
546 // also for names with spaces
547 ++i;
548 copyFile(bibFile,latexOutputDir + bibTmpFile + DString().setNum(i) + ".bib");
549 }
550 }
551 else
552 {
553 err("bib file {} not found!\n",bibFile);
554 }
555 }
556 }
557
558 // 10. Remove temporary files
559 if (!citeDebug)
560 {
561 thisDir.remove(citeListFile.str());
562 thisDir.remove(doxygenBstFile.str());
563 thisDir.remove(bib2xhtmlFile.str());
564 // we might try to remove too many files as empty files didn't get a corresponding new file
565 // but the remove function does not emit an error for it and we don't catch the error return
566 // so no problem.
567 for (size_t j = 1; j <= citeDataList.size(); j++)
568 {
569 DString bibFile = bibOutputDir + bibTmpFile + DString().setNum(static_cast<int>(j)) + ".bib";
570 thisDir.remove(bibFile.str());
571 }
572 thisDir.rmdir(bibOutputDir.str());
573 }
574}
const char * bibTmpFile
Definition cite.cpp:41
const char * bibTmpDir
Definition cite.cpp:42
static DString getBibFile(const DString &inFile)
Definition cite.cpp:54
bool empty() const
return true if there are no citations.
Definition cite.cpp:120
void insertCrossReferencesForBibFile(const DString &bibFile)
Definition cite.cpp:136
DString fileName() const
Definition cite.cpp:126
DString replaceFormulas(const DString &s)
Definition cite.cpp:316
DString getFormulas(const DString &s)
Definition cite.cpp:241
bool parseCommentBlock(OutlineParserInterface *parser, Entry *curEntry, const DString &comment, const DString &fileName, int &lineNr, bool isBrief, bool isJavadocStyle, bool isInbody, Protection &prot, int &position, bool &newEntryNeeded, bool markdownEnabled, GuardedSectionStack *guards)
Invokes the comment block parser with the request to parse a single comment block.
DString & setNum(short n)
Definition dstring.h:552
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:318
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:148
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:178
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:337
@ Cite
Definition debug.h:42
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
static std::string currentDirPath()
Definition dir.cpp:348
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:301
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:320
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:315
static bool setCurrent(const std::string &path)
Definition dir.cpp:356
bool exists() const
Definition dir.cpp:263
DString doc
documentation block (partly parsed)
Definition entry.h:200
static ResourceMgr & instance()
Returns the one and only instance of this class.
bool copyResource(const DString &name, const DString &targetDir) const
Copies a registered resource to a given target directory.
virtual DString trCiteReferences()=0
std::stack< GuardedSection > GuardedSectionStack
Definition commentscan.h:48
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
std::vector< std::string > StringVector
Definition containers.h:33
Translator * theTranslator
Definition language.cpp:76
#define err(fmt,...)
Definition message.h:127
std::ifstream openInputStream(const DString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:692
int system(const DString &command, const DString &args, bool commandHasConsole=true)
Definition portable.cpp:121
std::ofstream openOutputStream(const DString &name, bool append=false)
Definition portable.cpp:681
PageDef * addRelatedPage(const DString &name, const DString &ptitle, const DString &doc, const DString &fileName, int docLine, int startLine, const RefItemVector &sli, GroupDef *gd, const TagInfo *tagInfo, bool xref, SrcLangExt lang)
Definition pagedef.cpp:524
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
Definition stringutil.h:117
Protection
Definition types.h:32
bool copyFile(const DString &src, const DString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:4619

References addRelatedPage(), bibTmpDir, bibTmpFile, Debug::Cite, Config_getBool, Config_getList, Config_getString, copyFile(), ResourceMgr::copyResource(), Dir::currentDirPath(), Entry::doc, empty(), DString::empty(), err, Dir::exists(), FileInfo::exists(), fileName(), DString::find(), getBibFile(), getFormulas(), insertCrossReferencesForBibFile(), ResourceMgr::instance(), Debug::isFlagSet(), DString::left(), DString::lower(), DString::mid(), Dir::mkdir(), DString::npos, Portable::openInputStream(), Portable::openOutputStream(), p, CommentScanner::parseCommentBlock(), Dir::remove(), replaceFormulas(), Dir::rmdir(), Dir::setCurrent(), DString::setNum(), split(), DString::str(), DString::stripWhiteSpace(), Portable::system(), theTranslator, and Translator::trCiteReferences().

Referenced by parseInput().

◆ getFormulas()

DString CitationManager::getFormulas ( const DString & s)
private

Definition at line 241 of file cite.cpp.

242{
243 if (s.empty()) return s;
244 DString result;
245 result.reserve(s.length()+32);
246 DString formula;
247 formula.reserve(256);
248 bool insideFormula = false;
249 int citeFormulaCnt = 1;
250 const char *ps=s.data();
251 char c = 0;
252 while ((c=*ps++))
253 {
254 if (insideFormula)
255 {
256 switch (c)
257 {
258 case '\\':
259 formula+=c;
260 c = *ps++;
261 formula+=c;
262 break;
263 case '\n':
264 formula+=c;
265 result+='$';
266 result+=formula;
267 insideFormula = false;
268 formula.clear();
269 break;
270 case '$':
271 {
272 const size_t idLen = 30;
273 char id[idLen];
274 snprintf(id,idLen,"%s%06d",g_formulaMarker.c_str(),citeFormulaCnt);
275 p->formulaCite.emplace(citeFormulaCnt,std::string("\\f$") + formula.str() + "\\f$");
276 citeFormulaCnt++;
277 // need { and } due to the capitalization rules of bibtex.
278 result+='{';
279 result+=id;
280 result+='}';
281 insideFormula = false;
282 formula.clear();
283 }
284 break;
285 default:
286 formula+=c;
287 break;
288 }
289 }
290 else
291 {
292 switch (c)
293 {
294 case '\\':
295 result+=c;
296 c = *ps++;
297 result+=c;
298 break;
299 case '$':
300 insideFormula = true;
301 break;
302 default:
303 result+=c;
304 break;
305 }
306 }
307 }
308 if (insideFormula)
309 {
310 result+=formula;
311 formula.clear();
312 }
313 return result;
314}
static const std::string g_formulaMarker
Definition cite.cpp:239
void clear()
Definition dstring.h:214
void reserve(size_t size)
Reserve space for size bytes without changing the string contents.
Definition dstring.h:217
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:157
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:151

References DString::clear(), DString::data(), DString::empty(), g_formulaMarker, DString::length(), p, DString::reserve(), and DString::str().

Referenced by generatePage(), and ~CitationManager().

◆ insert()

void CitationManager::insert ( const DString & label)

Insert a citation identified by label into the database.

Definition at line 100 of file cite.cpp.

101{
102 DString lowerCaseLabel = label.lower();
103 p->entries.emplace(lowerCaseLabel.str(),std::make_unique<CiteInfoImpl>(lowerCaseLabel));
104}

References DString::lower(), p, and DString::str().

Referenced by addCite(), and insertCrossReferencesForBibFile().

◆ insertCrossReferencesForBibFile()

void CitationManager::insertCrossReferencesForBibFile ( const DString & bibFile)
private

Definition at line 136 of file cite.cpp.

137{
138 // sanity checks
139 if (bibFile.empty())
140 {
141 return;
142 }
143 FileInfo fi(bibFile.str());
144 if (!fi.exists())
145 {
146 err("bib file {} not found!\n",bibFile);
147 return;
148 }
149 std::ifstream f = Portable::openInputStream(bibFile);
150 if (!f.is_open())
151 {
152 err("could not open file {} for reading\n",bibFile);
153 return;
154 }
155
156 // search for citation cross references
157 DString citeName;
158
159 std::string lineStr;
160 int lineCount = 0;
161 while (getline(f,lineStr))
162 {
163 size_t i = DString::npos;
164 DString line(lineStr);
165 lineCount++;
166 if (line.stripWhiteSpace().startsWith("@"))
167 {
168 // assumption entry like: "@book { name," or "@book { name" (spaces optional)
169 size_t j = line.find('{');
170 // when no {, go hunting for it
171 while (j==DString::npos && getline(f,lineStr))
172 {
173 line = lineStr;
174 lineCount++;
175 j = line.find('{');
176 }
177 // search for the name
178 citeName = "";
179 if (!f.eof() && j!=DString::npos) // to prevent something like "@manual ," and no { found
180 {
181 size_t k = line.find(',',j);
182 j++;
183 // found a line "@....{.....,...." or "@.....{....."
184 // ^=j ^=k ^=j k=-1
185 while (!f.eof() && citeName.empty())
186 {
187 if (k!=DString::npos)
188 {
189 citeName = line.mid(j,k-j);
190 }
191 else
192 {
193 citeName = line.mid(j);
194 }
195 citeName = citeName.stripWhiteSpace();
196 j = 0;
197 if (citeName.empty() && getline(f,lineStr))
198 {
199 line = lineStr;
200 lineCount++;
201 k = line.find(',');
202 }
203 }
204 }
205 //printf("citeName = #%s#\n",qPrint(citeName));
206 if (!citeName.empty())
207 {
208 std::string lCiteName = citeName.lower().str();
209 auto it = p->citePosition.find(lCiteName);
210 if (it != p->citePosition.end())
211 {
212 warn(bibFile,lineCount,"multiple use of citation name '{}', (first occurrence: {}, line {})",
213 lCiteName,it->second.fileName,it->second.lineNr);
214 }
215 else
216 {
217 p->citePosition.emplace(lCiteName,CitePosition(bibFile,lineCount));
218 }
219 }
220 }
221 else if ((i=line.find("crossref"))!=DString::npos && !citeName.empty()) /* assumption cross reference is on one line and the only item */
222 {
223 size_t j = line.find('{',i);
224 size_t k = line.find('}',i);
225 if (j!=DString::npos && k!=DString::npos && j>i && k>j)
226 {
227 DString crossrefName = line.mid(j+1,k-j-1);
228 // check if the reference with the cross reference is used
229 // insert cross reference when cross reference has not yet been added.
230 if (find(citeName) && !find(crossrefName)) // not found yet
231 {
232 insert(crossrefName);
233 }
234 }
235 }
236 }
237}
void insert(const DString &label)
Insert a citation identified by label into the database.
Definition cite.cpp:100
const CiteInfo * find(const DString &label) const
Return the citation info for a given label.
Definition cite.cpp:106
#define lineCount(s, len)
#define warn(file, line, fmt,...)
Definition message.h:97

References DString::empty(), err, FileInfo::exists(), find(), DString::find(), insert(), lineCount, DString::lower(), DString::mid(), DString::npos, Portable::openInputStream(), p, DString::startsWith(), DString::str(), DString::stripWhiteSpace(), and warn.

Referenced by generatePage(), and ~CitationManager().

◆ instance()

CitationManager & CitationManager::instance ( )
static

Definition at line 90 of file cite.cpp.

91{
92 static CitationManager ct;
93 return ct;
94}
CitationManager()
Create the database, with an expected maximum of size entries.
Definition cite.cpp:96

References CitationManager().

Referenced by addCite(), clearAll(), DocAnchor::DocAnchor(), DocCite::DocCite(), DocCite::getText(), LatexDocVisitor::operator()(), TextDocVisitor::operator()(), parseInput(), substituteLatexKeywords(), writeLatexMakefile(), and writeMakeBat().

◆ latexBibFiles()

DString CitationManager::latexBibFiles ( )

lists the bibtex cite files in a comma separated list

Definition at line 576 of file cite.cpp.

577{
578 DString result;
579 StringVector citeDataList = Config_getList(CITE_BIB_FILES);
580 int i = 0;
581 for (const auto &bibdata : citeDataList)
582 {
583 DString bibFile = getBibFile(bibdata);
584 FileInfo fi(bibFile.str());
585 if (fi.exists() && !bibFile.empty())
586 {
587 if (i) result += ",";
588 i++;
589 result += bibTmpFile;
590 result += DString().setNum(i);
591 }
592 }
593 return result;
594}

References bibTmpFile, Config_getList, DString::empty(), FileInfo::exists(), getBibFile(), DString::setNum(), and DString::str().

Referenced by substituteLatexKeywords().

◆ replaceFormulas()

DString CitationManager::replaceFormulas ( const DString & s)
private

Definition at line 316 of file cite.cpp.

317{
318 if (s.empty()) return s;
319 DString t;
320 size_t pos=0;
321 size_t i = DString::npos;
322 while ((i=s.find(g_formulaMarker,pos))!=DString::npos)
323 {
324 t += s.mid(pos,i-pos);
325 int markerSize = static_cast<int>( g_formulaMarker.length());
326 int markerId = atoi(s.mid(i+markerSize,6).data());
327 auto it = p->formulaCite.find(markerId);
328 if (it != p->formulaCite.end()) t += it->second;
329 pos = i + markerSize+6;
330 }
331 t += s.mid(pos);
332 //printf("replaceFormulas(%s)=%s\n",qPrint(s),qPrint(t));
333 return t;
334}
size_t find(char c, size_t pos=0) const
Definition dstring.h:239

References DString::data(), DString::empty(), DString::find(), g_formulaMarker, DString::mid(), DString::npos, and p.

Referenced by generatePage(), and ~CitationManager().

Member Data Documentation

◆ p

std::unique_ptr<Private> CitationManager::p
private

The documentation for this class was generated from the following files: