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 92 of file cite.cpp.

92 : p(new Private)
93{
94}
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 127 of file cite.cpp.

128{
129 return "CITEREF_";
130}

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

◆ clear()

void CitationManager::clear ( )

clears the database

Definition at line 111 of file cite.cpp.

112{
113 p->entries.clear();
114}

References p.

Referenced by clearAll().

◆ empty()

bool CitationManager::empty ( ) const

return true if there are no citations.

Definition at line 116 of file cite.cpp.

117{
118 size_t numFiles = Config_getList(CITE_BIB_FILES).size();
119 return (numFiles==0 || p->entries.empty());
120}
#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 122 of file cite.cpp.

123{
124 return "citelist";
125}

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 102 of file cite.cpp.

103{
104 if (auto it = p->entries.find(label.lower().str()); it != p->entries.end())
105 {
106 return it->second.get();
107 }
108 return nullptr;
109}
DString lower() const
Definition dstring.h:331
const std::string & str() const
Definition dstring.h:634

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 332 of file cite.cpp.

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

References addRelatedPage(), bibTmpDir, bibTmpFile, Debug::Cite, Config_getBool, Config_getList, Config_getString, copyFile(), ResourceMgr::copyResource(), Dir::currentDirPath(), Entry::doc, DString::DString(), 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(), 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 237 of file cite.cpp.

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

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 96 of file cite.cpp.

97{
98 DString lowerCaseLabel = label.lower();
99 p->entries.emplace(lowerCaseLabel.str(),std::make_unique<CiteInfoImpl>(lowerCaseLabel));
100}

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

Referenced by addCite(), and insertCrossReferencesForBibFile().

◆ insertCrossReferencesForBibFile()

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

Definition at line 132 of file cite.cpp.

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

References CitePosition::CitePosition(), 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 86 of file cite.cpp.

87{
88 static CitationManager ct;
89 return ct;
90}
CitationManager()
Create the database, with an expected maximum of size entries.
Definition cite.cpp:92

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 572 of file cite.cpp.

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

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

Referenced by substituteLatexKeywords().

◆ replaceFormulas()

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

Definition at line 312 of file cite.cpp.

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

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: