Doxygen
Loading...
Searching...
No Matches
latexgen.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2023 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <cstdlib>
17
18#include "latexgen.h"
19#include "config.h"
20#include "message.h"
21#include "doxygen.h"
22#include "util.h"
23#include "diagram.h"
24#include "language.h"
25#include "version.h"
26#include "dot.h"
27#include "dotcallgraph.h"
28#include "dotclassgraph.h"
29#include "dotdirdeps.h"
31#include "dotincldepgraph.h"
32#include "pagedef.h"
33#include "docparser.h"
34#include "docnode.h"
35#include "latexdocvisitor.h"
36#include "dirdef.h"
37#include "cite.h"
38#include "groupdef.h"
39#include "classlist.h"
40#include "namespacedef.h"
41#include "filename.h"
42#include "resourcemgr.h"
43#include "portable.h"
44#include "fileinfo.h"
45#include "utf8.h"
46#include "datetime.h"
47#include "portable.h"
48#include "outputlist.h"
49#include "moduledef.h"
50
55static const SelectionMarkerInfo latexMarkerInfo = { '%', "%%BEGIN ",8 ,"%%END ",6, "",0 };
56
57static QCString substituteLatexKeywords(const QCString &file, const QCString &str, const QCString &title);
58
60 : m_t(t), m_relPath(relPath), m_sourceFileName(sourceFileName)
61{
62}
63
67
69{
70 m_relPath = path;
71}
72
77
79{
80 if (!str.isEmpty())
81 {
82 const char *p=str.data();
83 char c = 0;
84 //char cs[5];
85 int tabSize = Config_getInt(TAB_SIZE);
86 static THREAD_LOCAL char *result = nullptr;
87 static THREAD_LOCAL int lresult = 0;
88 if (m_hide) // only update column count
89 {
91 }
92 else // actually output content and keep track of m_col
93 {
94 while ((c=*p))
95 {
96 switch(c)
97 {
98 case 0x0c: p++; // remove ^L
99 break;
100 case ' ': if (m_col>=m_stripIndentAmount)
101 {
102 *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
103 }
104 m_col++;
105 p++;
106 break;
107 case '^': *m_t <<"\\string^";
108 m_col++;
109 p++;
110 break;
111 case '`': *m_t <<"\\`{}";
112 m_col++;
113 p++;
114 break;
115 case '\t': {
116 int spacesToNextTabStop = tabSize - (m_col%tabSize);
117 while (spacesToNextTabStop--)
118 {
120 {
121 *m_t << (m_doxyCodeLineOpen ? "\\ " : " ");
122 }
123 m_col++;
124 }
125 p++;
126 }
127 break;
128 case '\n': *m_t << '\n';
129 m_col=0;
130 p++;
131 break;
132 default:
133 {
134 int i=0;
135
136#undef COPYCHAR
137// helper macro to copy a single utf8 character, dealing with multibyte chars.
138#define COPYCHAR() do { \
139 int bytes = getUTF8CharNumBytes(c); \
140 if (lresult < (i + bytes + 1)) \
141 { \
142 lresult += 512; \
143 result = static_cast<char *>(realloc(result, lresult)); \
144 } \
145 for (int j=0; j<bytes && *p; j++) \
146 { \
147 result[i++]=*p++; \
148 } \
149 m_col++; \
150 } while(0)
151
152 // gather characters until we find whitespace or another special character
153 COPYCHAR();
154 while ((c=*p) &&
155 c!=0x0c && c!='\t' && c!='\n' && c!=' ' && c!='^'
156 )
157 {
158 COPYCHAR();
159 }
160 result[i]=0; // add terminator
161 filterLatexString(*m_t,result,
162 m_insideTabbing, // insideTabbing
163 true, // insidePre
164 false, // insideItem
165 m_usedTableLevel>0, // insideTable
166 false // keepSpaces
167 );
168 }
169 break;
170 }
171 }
172 }
173 }
174}
175
180
185
187{
188 m_hide = false;
189}
190
192{
193 m_stripIndentAmount = amount;
194}
195
197 const QCString &ref,const QCString &f,
198 const QCString &anchor,const QCString &name,
199 const QCString &)
200{
201 if (m_hide) return;
202 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
203 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
204 size_t l = name.length();
205 if (ref.isEmpty() && usePDFLatex && pdfHyperlinks)
206 {
207 *m_t << "\\mbox{\\hyperlink{";
208 if (!f.isEmpty()) *m_t << stripPath(f);
209 if (!f.isEmpty() && !anchor.isEmpty()) *m_t << "_";
210 if (!anchor.isEmpty()) *m_t << anchor;
211 *m_t << "}{";
212 codify(name);
213 *m_t << "}}";
214 }
215 else
216 {
217 codify(name);
218 }
219 m_col+=l;
220}
221
222void LatexCodeGenerator::writeLineNumber(const QCString &ref,const QCString &fileName,const QCString &anchor,int l,bool writeLineAnchor)
223{
224 if (m_hide) return;
225 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
226 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
228 {
229 *m_t << "\\DoxyCodeLine{";
231 }
232 if (Config_getBool(SOURCE_BROWSER))
233 {
234 QCString lineNumber;
235 lineNumber.sprintf("%05d",l);
236
237 QCString lineAnchor;
238 if (!m_sourceFileName.isEmpty())
239 {
240 lineAnchor.sprintf("_l%05d",l);
242 }
243 bool showTarget = usePDFLatex && pdfHyperlinks && !lineAnchor.isEmpty() && writeLineAnchor;
244 if (showTarget)
245 {
246 *m_t << "\\Hypertarget{" << stripPath(lineAnchor) << "}";
247 }
248 if (!fileName.isEmpty())
249 {
250 writeCodeLink(CodeSymbolType::Default,ref,fileName,anchor,lineNumber,QCString());
251 }
252 else
253 {
254 codify(lineNumber);
255 }
256 *m_t << "\\ ";
257 }
258 else
259 {
260 QCString lineNumber;
261 lineNumber.sprintf("%05d",l);
262 codify(lineNumber);
263 *m_t << "\\ ";
264 }
265 m_col=0;
266}
267
268
270{
271 if (m_hide) return;
272 m_col=0;
274 {
275 *m_t << "\\DoxyCodeLine{";
277 }
278}
279
281{
282 if (m_hide) return;
284 {
285 *m_t << "}";
287 }
288 codify("\n");
289}
290
292{
293 if (m_hide) return;
294 *m_t << "\\textcolor{" << name << "}{";
295}
296
298{
299 if (m_hide) return;
300 *m_t << "}";
301}
302
304{
305 *m_t << "\n\\begin{" << style << "}{" << m_usedTableLevel << "}\n";
306}
307
309{
310 //endCodeLine checks is there is still an open code line, if so closes it.
311 bool wasHidden = m_hide;
312 m_hide = false;
313 endCodeLine();
314 m_hide = wasHidden;
315
316 *m_t << "\\end{" << style << "}\n";
317}
318
319
320//-------------------------------
321
328
341
343{
344 if (this!=&og)
345 {
346 m_dir = og.m_dir;
347 m_codeList = std::make_unique<OutputCodeList>(*og.m_codeList);
349 m_codeGen->setTextStream(&m_t);
352 m_relPath = og.m_relPath;
353 m_indent = og.m_indent;
356 }
357 return *this;
358}
359
361
366
368{
369 bool generateBib = !CitationManager::instance().isEmpty();
370 QCString fileName=Config_getString(LATEX_OUTPUT)+"/Makefile";
371 std::ofstream f = Portable::openOutputStream(fileName);
372 if (!f.is_open())
373 {
374 term("Could not open file {} for writing\n",fileName);
375 }
376 TextStream t(&f);
377 // inserted by KONNO Akihisa <konno@researchers.jp> 2002-03-05
378 QCString latex_command = theTranslator->latexCommandName().quoted();
379 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
380 QCString bibtex_command = "bibtex";
381 QCString manual_file = "refman";
382 const int latex_count = 8;
383 // end insertion by KONNO Akihisa <konno@researchers.jp> 2002-03-05
384 t << "LATEX_CMD?=" << latex_command << "\n"
385 << "MKIDX_CMD?=" << mkidx_command << "\n"
386 << "BIBTEX_CMD?=" << bibtex_command << "\n"
387 << "LATEX_COUNT?=" << latex_count << "\n"
388 << "MANUAL_FILE?=" << manual_file << "\n"
389 << "\n";
390 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
391 {
392 t << "all: $(MANUAL_FILE).dvi\n"
393 << "\n"
394 << "ps: $(MANUAL_FILE).ps\n"
395 << "\n"
396 << "pdf: $(MANUAL_FILE).pdf\n"
397 << "\n"
398 << "ps_2on1: $(MANUAL_FILE).ps\n"
399 << "\n"
400 << "pdf_2on1: $(MANUAL_FILE).pdf\n"
401 << "\n"
402 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).dvi\n"
403 << "\tdvips -o $(MANUAL_FILE).ps $(MANUAL_FILE).dvi\n"
404 << "\n";
405 t << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n";
406 t << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n\n";
407 t << "$(MANUAL_FILE).dvi: clean $(MANUAL_FILE).tex doxygen.sty\n"
408 << "\techo \"Running latex...\"\n"
409 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
410 << "\tif [ $$? != 0 ] ; then \\\n"
411 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
412 << "\t false; \\\n"
413 << "\tfi\n"
414 << "\techo \"Running makeindex...\"\n"
415 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
416 if (generateBib)
417 {
418 t << "\techo \"Running bibtex...\"\n";
419 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
420 t << "\techo \"Rerunning latex....\"\n";
421 t << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
422 << "\tif [ $$? != 0 ] ; then \\\n"
423 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
424 << "\t false; \\\n"
425 << "\tfi\n";
426 }
427 t << "\techo \"Rerunning latex....\"\n"
428 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex\n"
429 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
430 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
431 << "\t do \\\n"
432 << "\t echo \"Rerunning latex....\" ;\\\n"
433 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex ; \\\n"
434 << "\t $(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
435 << "\t if [ $$? != 0 ] ; then \\\n"
436 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
437 << "\t false; \\\n"
438 << "\t fi; \\\n"
439 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
440 << "\t done\n"
441 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
442 << "\t$(LATEX_CMD) $(MANUAL_FILE).tex || \\\n"
443 << "\tif [ $$? != 0 ] ; then \\\n"
444 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
445 << "\t false; \\\n"
446 << "\tfi\n"
447 << "$(MANUAL_FILE).ps: $(MANUAL_FILE).ps\n"
448 << "\tpsnup -2 $(MANUAL_FILE).ps >$(MANUAL_FILE).ps\n"
449 << "\n"
450 << "$(MANUAL_FILE).pdf: $(MANUAL_FILE).ps\n"
451 << "\tps2pdf $(MANUAL_FILE).ps $(MANUAL_FILE).pdf\n";
452 }
453 else // use pdflatex for higher quality output
454 {
455 t << "all: $(MANUAL_FILE).pdf\n\n"
456 << "pdf: $(MANUAL_FILE).pdf\n\n";
457 t << "$(MANUAL_FILE).pdf: clean $(MANUAL_FILE).tex\n";
458 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
459 << "\tif [ $$? != 0 ] ; then \\\n"
460 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
461 << "\t false; \\\n"
462 << "\tfi\n";
463 t << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n";
464 if (generateBib)
465 {
466 t << "\t$(BIBTEX_CMD) $(MANUAL_FILE)\n";
467 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
468 << "\tif [ $$? != 0 ] ; then \\\n"
469 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
470 << "\t false; \\\n"
471 << "\tfi\n";
472 }
473 t << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
474 << "\tif [ $$? != 0 ] ; then \\\n"
475 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
476 << "\t false; \\\n"
477 << "\tfi\n"
478 << "\tlatex_count=$(LATEX_COUNT) ; \\\n"
479 << "\twhile grep -E -s 'Rerun (LaTeX|to get cross-references right|to get bibliographical references right)' $(MANUAL_FILE).log && [ $$latex_count -gt 0 ] ;\\\n"
480 << "\t do \\\n"
481 << "\t echo \"Rerunning latex....\" ;\\\n"
482 << "\t $(LATEX_CMD) $(MANUAL_FILE) || \\\n"
483 << "\t if [ $$? != 0 ] ; then \\\n"
484 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
485 << "\t false; \\\n"
486 << "\t fi; \\\n"
487 << "\t latex_count=`expr $$latex_count - 1` ;\\\n"
488 << "\t done\n"
489 << "\t$(MKIDX_CMD) $(MANUAL_FILE).idx\n"
490 << "\t$(LATEX_CMD) $(MANUAL_FILE) || \\\n"
491 << "\tif [ $$? != 0 ] ; then \\\n"
492 << "\t \\echo \"Please consult $(MANUAL_FILE).log to see the error messages\" ; \\\n"
493 << "\t false; \\\n"
494 << "\tfi\n";
495 }
496
497 t << "\n"
498 << "clean:\n"
499 << "\trm -f "
500 << "*.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl $(MANUAL_FILE).pdf\n";
501}
502
503static void writeMakeBat()
504{
505#if defined(_MSC_VER)
506 QCString dir=Config_getString(LATEX_OUTPUT);
507 QCString fileName=dir+"/make.bat";
508 QCString latex_command = theTranslator->latexCommandName().quoted();
509 QCString mkidx_command = Config_getString(MAKEINDEX_CMD_NAME).quoted();
510 QCString bibtex_command = "bibtex";
511 QCString manual_file = "refman";
512 const int latex_count = 8;
513 bool generateBib = !CitationManager::instance().isEmpty();
514 std::ofstream t = Portable::openOutputStream(fileName);
515 if (!t.is_open())
516 {
517 term("Could not open file {} for writing\n",fileName);
518 }
519 t << "pushd %~dp0\r\n";
520 t << "if not %errorlevel% == 0 goto :end1\r\n";
521 t << "\r\n";
522 t << "set ORG_LATEX_CMD=%LATEX_CMD%\r\n";
523 t << "set ORG_MKIDX_CMD=%MKIDX_CMD%\r\n";
524 t << "set ORG_BIBTEX_CMD=%BIBTEX_CMD%\r\n";
525 t << "set ORG_LATEX_COUNT=%LATEX_COUNT%\r\n";
526 t << "set ORG_MANUAL_FILE=%MANUAL_FILE%\r\n";
527 t << "if \"X\"%LATEX_CMD% == \"X\" set LATEX_CMD=" << latex_command << "\r\n";
528 t << "if \"X\"%MKIDX_CMD% == \"X\" set MKIDX_CMD=" << mkidx_command << "\r\n";
529 t << "if \"X\"%BIBTEX_CMD% == \"X\" set BIBTEX_CMD=" << bibtex_command << "\r\n";
530 t << "if \"X\"%LATEX_COUNT% == \"X\" set LATEX_COUNT=" << latex_count << "\r\n";
531 t << "if \"X\"%MANUAL_FILE% == \"X\" set MANUAL_FILE=" << manual_file << "\r\n";
532 t << "\r\n";
533 t << "del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl %MANUAL_FILE%.pdf\r\n\r\n";
534 t << "\r\n";
535 if (!Config_getBool(USE_PDFLATEX)) // use plain old latex
536 {
537 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
538 t << "@if ERRORLEVEL 1 goto :error\r\n";
539 t << "echo ----\r\n";
540 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
541 if (generateBib)
542 {
543 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
544 t << "echo ----\r\n";
545 t << "\t%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
546 t << "@if ERRORLEVEL 1 goto :error\r\n";
547 }
548 t << "setlocal enabledelayedexpansion\r\n";
549 t << "set count=%LAT#EX_COUNT%\r\n";
550 t << ":repeat\r\n";
551 t << "set content=X\r\n";
552 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
553 t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
554 t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get bibliographical references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
555 t << "if !content! == X goto :skip\r\n";
556 t << "set /a count-=1\r\n";
557 t << "if !count! EQU 0 goto :skip\r\n\r\n";
558 t << "echo ----\r\n";
559 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
560 t << "@if ERRORLEVEL 1 goto :error\r\n";
561 t << "goto :repeat\r\n";
562 t << ":skip\r\n";
563 t << "endlocal\r\n";
564 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
565 t << "%LATEX_CMD% %MANUAL_FILE%.tex\r\n";
566 t << "@if ERRORLEVEL 1 goto :error\r\n";
567 t << "dvips -o %MANUAL_FILE%.ps %MANUAL_FILE%.dvi\r\n";
569 t << " -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "
570 "-sOutputFile=%MANUAL_FILE%.pdf -c save pop -f %MANUAL_FILE%.ps\r\n";
571 }
572 else // use pdflatex
573 {
574 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
575 t << "@if ERRORLEVEL 1 goto :error\r\n";
576 t << "echo ----\r\n";
577 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
578 if (generateBib)
579 {
580 t << "%BIBTEX_CMD% %MANUAL_FILE%\r\n";
581 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
582 t << "@if ERRORLEVEL 1 goto :error\r\n";
583 }
584 t << "echo ----\r\n";
585 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
586 t << "@if ERRORLEVEL 1 goto :error\r\n";
587 t << "\r\n";
588 t << "setlocal enabledelayedexpansion\r\n";
589 t << "set count=%LATEX_COUNT%\r\n";
590 t << ":repeat\r\n";
591 t << "set content=X\r\n";
592 t << "for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun LaTeX\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
593 t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get cross-references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
594 t << "if !content! == X for /F \"tokens=*\" %%T in ( 'findstr /C:\"Rerun to get bibliographical references right\" %MANUAL_FILE%.log' ) do set content=\"%%~T\"\r\n";
595 t << "if !content! == X goto :skip\r\n";
596 t << "set /a count-=1\r\n";
597 t << "if !count! EQU 0 goto :skip\r\n\r\n";
598 t << "echo ----\r\n";
599 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
600 t << "@if ERRORLEVEL 1 goto :error\r\n";
601 t << "goto :repeat\r\n";
602 t << ":skip\r\n";
603 t << "endlocal\r\n";
604 t << "%MKIDX_CMD% %MANUAL_FILE%.idx\r\n";
605 t << "%LATEX_CMD% %MANUAL_FILE%\r\n";
606 t << "@if ERRORLEVEL 1 goto :error\r\n";
607 }
608 t<< "\r\n";
609 t << "goto :end\r\n";
610 t << ":error\r\n";
611 t << "@echo ===============\r\n";
612 t << "@echo Please consult %MANUAL_FILE%.log to see the error messages\r\n";
613 t << "@echo ===============\r\n";
614 t<< "\r\n";
615 t<< ":end\r\n";
616 t<< "@REM reset environment\r\n";
617 t<< "popd\r\n";
618 t<< "set LATEX_CMD=%ORG_LATEX_CMD%\r\n";
619 t<< "set ORG_LATEX_CMD=\r\n";
620 t<< "set MKIDX_CMD=%ORG_MKIDX_CMD%\r\n";
621 t<< "set ORG_MKIDX_CMD=\r\n";
622 t<< "set BIBTEX_CMD=%ORG_BIBTEX_CMD%\r\n";
623 t<< "set ORG_BIBTEX_CMD=\r\n";
624 t<< "set MANUAL_FILE=%ORG_MANUAL_FILE%\r\n";
625 t<< "set ORG_MANUAL_FILE=\r\n";
626 t<< "set LATEX_COUNT=%ORG_LATEX_COUNT%\r\n";
627 t<< "set ORG_LATEX_COUNT=\r\n";
628 t<< "\r\n";
629 t<< ":end1\r\n";
630#endif
631}
632
634{
635 QCString dname = Config_getString(LATEX_OUTPUT);
636 Dir d(dname.str());
637 if (!d.exists() && !d.mkdir(dname.str()))
638 {
639 term("Could not create output directory {}\n",dname);
640 }
641
642 if (!Config_getString(LATEX_HEADER).isEmpty())
643 {
644 g_header_file=Config_getString(LATEX_HEADER);
646 //printf("g_header='%s'\n",qPrint(g_header));
649 }
650 else
651 {
652 g_header_file = "header.tex";
655 checkBlocks(result,"<default header.tex>",latexMarkerInfo);
656 }
657 if (!Config_getString(LATEX_FOOTER).isEmpty())
658 {
659 g_footer_file=Config_getString(LATEX_FOOTER);
661 //printf("g_footer='%s'\n",qPrint(g_footer));
664 }
665 else
666 {
667 g_footer_file = "footer.tex";
670 checkBlocks(result,"<default footer.tex>",latexMarkerInfo);
671 }
672
674 writeMakeBat();
675
676 createSubDirs(d);
677}
678
680{
681 QCString dname = Config_getString(LATEX_OUTPUT);
682 Dir d(dname.str());
683 clearSubDirs(d);
684}
685
687{
688 t << ResourceMgr::instance().getAsString("doxygen.sty");
689}
690
692{
693 t << "% Latex header for doxygen " << getDoxygenVersion() << "\n";
694 t << ResourceMgr::instance().getAsString("header.tex");
695}
696
698{
699 t << "% Latex footer for doxygen " << getDoxygenVersion() << "\n";
700 t << ResourceMgr::instance().getAsString("footer.tex");
701}
702
704{
705 t << "% stylesheet for doxygen " << getDoxygenVersion() << "\n";
707}
708
709void LatexGenerator::startFile(const QCString &name,const QCString &,const QCString &,int,int hierarchyLevel)
710{
711#if 0
712 setEncoding(Config_getString(LATEX_OUTPUT_ENCODING));
713#endif
714 QCString fileName=name;
715 m_hierarchyLevel = hierarchyLevel;
717 if (!fileName.endsWith(".tex") && !fileName.endsWith(".sty")) fileName+=".tex";
719 m_codeGen->setRelativePath(m_relPath);
720 m_codeGen->setSourceFileName(stripPath(fileName));
721}
722
724{
725 endPlainFile();
726 m_codeGen->setSourceFileName("");
727}
728
729//void LatexGenerator::writeIndex()
730//{
731// startFile("refman.tex");
732//}
733
735{
736 m_t << "\\\\[1ex]\\large ";
737}
738
740{
741 QCString result;
742 const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET);
743 for (const auto &fileName : extraLatexStyles)
744 {
745 if (!fileName.empty())
746 {
747 FileInfo fi(fileName);
748 if (fi.exists())
749 {
750 result += "\\usepackage{";
752 {
753 // strip the extension, it will be added by the usepackage in the tex conversion process
755 }
756 else
757 {
758 result += fi.fileName();
759 }
760 result += "}\n";
761 }
762 }
763 }
764 return result;
765}
766
768{
769 QCString result;
770 QCString latex_mkidx_command = Config_getString(LATEX_MAKEINDEX_CMD);
771 if (!latex_mkidx_command.isEmpty())
772 {
773 if (latex_mkidx_command[0] == '\\')
774 result += latex_mkidx_command;
775 else
776 result += "\\"+latex_mkidx_command;
777 }
778 else
779 {
780 result += "\\makeindex";
781 }
782 return result;
783}
784
786{
787 switch (Config_getEnum(LATEX_BATCHMODE))
788 {
789 case LATEX_BATCHMODE_t::NO: return "";
790 case LATEX_BATCHMODE_t::YES: return "\\batchmode";
791 case LATEX_BATCHMODE_t::BATCH: return "\\batchmode";
792 case LATEX_BATCHMODE_t::NON_STOP: return "\\nonstopmode";
793 case LATEX_BATCHMODE_t::SCROLL: return "\\scrollmode";
794 case LATEX_BATCHMODE_t::ERROR_STOP: return "\\errorstopmode";
795 }
796 return "";
797}
798
800 const QCString &str,
801 const QCString &title)
802{
803 bool compactLatex = Config_getBool(COMPACT_LATEX);
804 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
805 bool usePdfLatex = Config_getBool(USE_PDFLATEX);
806 QCString paperType = Config_getEnumAsString(PAPER_TYPE);
807
808 QCString style = Config_getString(LATEX_BIB_STYLE);
809 if (style.isEmpty())
810 {
811 style="plainnat";
812 }
813
814 TextStream tg;
815 QCString generatedBy;
816 auto timeStamp = Config_getEnum(TIMESTAMP);
817 switch (timeStamp)
818 {
819 case TIMESTAMP_t::YES:
820 case TIMESTAMP_t::DATETIME:
821 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::DateTime),
822 Config_getString(PROJECT_NAME));
823 break;
824 case TIMESTAMP_t::DATE:
825 generatedBy = theTranslator->trGeneratedAt(dateToString(DateTimeType::Date),
826 Config_getString(PROJECT_NAME));
827 break;
828 case TIMESTAMP_t::NO:
829 generatedBy = theTranslator->trGeneratedBy();
830 break;
831 }
832 filterLatexString(tg, generatedBy,
833 false, // insideTabbing
834 false, // insidePre
835 false, // insideItem
836 false, // insideTable
837 false // keepSpaces
838 );
839 generatedBy = tg.str();
840
841 QCString latexFontenc = theTranslator->latexFontenc();
842
843 QCString latexEmojiDirectory = Config_getString(LATEX_EMOJI_DIRECTORY);
844 if (latexEmojiDirectory.isEmpty()) latexEmojiDirectory = ".";
845 latexEmojiDirectory = substitute(latexEmojiDirectory,"\\","/");
846
847 TextStream tg1;
849 QCString extraLatexPackages = tg1.str();
850
851 TextStream tg2;
853 QCString latexSpecialFormulaChars = tg2.str();
854
855 QCString formulaMacrofile = Config_getString(FORMULA_MACROFILE);
856 QCString stripMacroFile;
857 if (!formulaMacrofile.isEmpty())
858 {
859 FileInfo fi(formulaMacrofile.str());
860 formulaMacrofile=fi.absFilePath();
861 stripMacroFile = fi.fileName();
862 copyFile(formulaMacrofile,Config_getString(LATEX_OUTPUT) + "/" + stripMacroFile);
863 }
864
865 QCString projectNumber = Config_getString(PROJECT_NUMBER);
866
867 // first substitute generic keywords
868 QCString result = substituteKeywords(file,str,title,
869 convertToLaTeX(Config_getString(PROJECT_NAME),false),
870 convertToLaTeX(projectNumber,false),
871 convertToLaTeX(Config_getString(PROJECT_BRIEF),false));
872
873 // additional LaTeX only keywords
874 result = substituteKeywords(file,result,
875 {
876 // keyword value getter
877 { "$datetime", [&]() { return dateToString(DateTimeType::DateTime); } },
878 { "$date", [&]() { return dateToString(DateTimeType::Date); } },
879 { "$time", [&]() { return dateToString(DateTimeType::Time); } },
880 { "$year", [&]() { return yearToString(); } },
881 { "$latexdocumentpre", [&]() { return theTranslator->latexDocumentPre(); } },
882 { "$latexdocumentpost", [&]() { return theTranslator->latexDocumentPost(); } },
883 { "$generatedby", [&]() { return generatedBy; } },
884 { "$latexbibstyle", [&]() { return style; } },
885 { "$latexcitereference", [&]() { return theTranslator->trCiteReferences(); } },
886 { "$latexbibfiles", [&]() { return CitationManager::instance().latexBibFiles(); } },
887 { "$papertype", [&]() { return paperType+"paper"; } },
888 { "$extralatexstylesheet", [&]() { return extraLatexStyleSheet(); } },
889 { "$languagesupport", [&]() { return theTranslator->latexLanguageSupportCommand(); } },
890 { "$latexfontenc", [&]() { return latexFontenc; } },
891 { "$latexfont", [&]() { return theTranslator->latexFont(); } },
892 { "$latexemojidirectory", [&]() { return latexEmojiDirectory; } },
893 { "$makeindex", [&]() { return makeIndex(); } },
894 { "$extralatexpackages", [&]() { return extraLatexPackages; } },
895 { "$latexspecialformulachars", [&]() { return latexSpecialFormulaChars; } },
896 { "$formulamacrofile", [&]() { return stripMacroFile; } },
897 { "$latex_batchmode", [&]() { return latex_batchmode(); } }
898 });
899
900 // remove conditional blocks
901 result = selectBlocks(result,
902 {
903 // marker is enabled
904 { "CITATIONS_PRESENT", !CitationManager::instance().isEmpty() },
905 { "COMPACT_LATEX", compactLatex },
906 { "PDF_HYPERLINKS", pdfHyperlinks },
907 { "USE_PDFLATEX", usePdfLatex },
908 { "TIMESTAMP", timeStamp!=TIMESTAMP_t::NO },
909 { "LATEX_FONTENC", !latexFontenc.isEmpty() },
910 { "FORMULA_MACROFILE", !formulaMacrofile.isEmpty() },
911 { "PROJECT_NUMBER", !projectNumber.isEmpty() }
913
914 result = removeEmptyLines(result);
915
916 return result;
917}
918
920{
921 bool compactLatex = Config_getBool(COMPACT_LATEX);
922 switch (is)
923 {
926 break;
928 break;
930 break;
932 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
933 m_t << "{"; //Module Index}\n"
934 break;
936 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
937 m_t << "{"; //Topic Index}\n"
938 break;
940 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
941 m_t << "{"; //Directory Index}\n"
942 break;
944 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
945 m_t << "{"; //Namespace Index}\n"
946 break;
948 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
949 m_t << "{"; //Concept Index}\n"
950 break;
952 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
953 m_t << "{"; //Hierarchical Index}\n"
954 break;
956 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
957 m_t << "{"; //Annotated Compound Index}\n"
958 break;
960 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
961 m_t << "{"; //Annotated File Index}\n"
962 break;
964 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
965 m_t << "{"; //Annotated Page Index}\n"
966 break;
968 {
969 for (const auto &gd : *Doxygen::groupLinkedMap)
970 {
971 if (!gd->isReference())
972 {
973 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
974 m_t << "{"; //Topic Documentation}\n";
975 break;
976 }
977 }
978 }
979 break;
981 {
982 for (const auto &mod : ModuleManager::instance().modules())
983 {
984 if (!mod->isReference() && mod->isPrimaryInterface())
985 {
986 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
987 m_t << "{"; //Topic Documentation}\n";
988 break;
989 }
990 }
991 }
992 break;
994 {
995 for (const auto &dd : *Doxygen::dirLinkedMap)
996 {
997 if (dd->isLinkableInProject())
998 {
999 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1000 m_t << "{"; //Dir Documentation}\n";
1001 break;
1002 }
1003 }
1004 }
1005 break;
1007 {
1008 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1009 {
1010 if (nd->isLinkableInProject() && !nd->isAlias())
1011 {
1012 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1013 m_t << "{"; // Namespace Documentation}\n":
1014 break;
1015 }
1016 }
1017 }
1018 break;
1020 {
1021 for (const auto &cd : *Doxygen::conceptLinkedMap)
1022 {
1023 if (cd->isLinkableInProject() && !cd->isAlias())
1024 {
1025 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1026 m_t << "{"; // Concept Documentation}\n":
1027 break;
1028 }
1029 }
1030 }
1031 break;
1033 {
1034 for (const auto &cd : *Doxygen::classLinkedMap)
1035 {
1036 if (cd->isLinkableInProject() &&
1037 !cd->isImplicitTemplateInstance() &&
1038 !cd->isEmbeddedInOuterScope() &&
1039 !cd->isAlias()
1040 )
1041 {
1042 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1043 m_t << "{"; //Compound Documentation}\n";
1044 break;
1045 }
1046 }
1047 }
1048 break;
1050 {
1051 bool isFirst=TRUE;
1052 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1053 {
1054 for (const auto &fd : *fn)
1055 {
1056 if (fd->isLinkableInProject() || fd->generateSourceFile())
1057 {
1058 if (isFirst)
1059 {
1060 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1061 m_t << "{"; //File Documentation}\n";
1062 isFirst=FALSE;
1063 break;
1064 }
1065 }
1066 }
1067 }
1068 }
1069 break;
1071 {
1072 if (compactLatex) m_t << "\\doxysection"; else m_t << "\\chapter";
1073 m_t << "{"; //Example Documentation}\n";
1074 }
1075 break;
1077 break;
1079 break;
1081 break;
1082 }
1083}
1084
1086{
1087 switch (is)
1088 {
1090 break;
1092 break;
1094 {
1096 {
1097 writePageLink(Doxygen::mainPage->getOutputFileBase(), FALSE);
1098 }
1099 }
1100 break;
1102 m_t << "}\n\\input{modules}\n";
1103 break;
1105 m_t << "}\n\\input{topics}\n";
1106 break;
1108 m_t << "}\n\\input{dirs}\n";
1109 break;
1111 m_t << "}\n\\input{namespaces}\n";
1112 break;
1114 m_t << "}\n\\input{concepts}\n";
1115 break;
1117 m_t << "}\n\\input{hierarchy}\n";
1118 break;
1120 m_t << "}\n\\input{annotated}\n";
1121 break;
1123 m_t << "}\n\\input{files}\n";
1124 break;
1126 m_t << "}\n\\input{pages}\n";
1127 break;
1129 {
1130 m_t << "}\n";
1131 for (const auto &gd : *Doxygen::groupLinkedMap)
1132 {
1133 if (!gd->isReference() && !gd->isASubGroup())
1134 {
1135 writePageLink(gd->getOutputFileBase(), FALSE);
1136 }
1137 }
1138 }
1139 break;
1141 {
1142 m_t << "}\n";
1143 for (const auto &mod : ModuleManager::instance().modules())
1144 {
1145 if (!mod->isReference() && mod->isPrimaryInterface())
1146 {
1147 writePageLink(mod->getOutputFileBase(), FALSE);
1148 }
1149 }
1150 }
1151 break;
1153 {
1154 bool found=FALSE;
1155 for (const auto &dd : *Doxygen::dirLinkedMap)
1156 {
1157 if (dd->isLinkableInProject())
1158 {
1159 if (!found)
1160 {
1161 m_t << "}\n";
1162 found = TRUE;
1163 }
1164 m_t << "\\input{" << dd->getOutputFileBase() << "}\n";
1165 }
1166 }
1167 }
1168 break;
1170 {
1171 bool found=FALSE;
1172 for (const auto &nd : *Doxygen::namespaceLinkedMap)
1173 {
1174 if (nd->isLinkableInProject() && !nd->isAlias())
1175 {
1176 if (!found)
1177 {
1178 m_t << "}\n";
1179 found=true;
1180 }
1181 m_t << "\\input{" << nd->getOutputFileBase() << "}\n";
1182 }
1183 }
1184 }
1185 break;
1187 {
1188 bool found=FALSE;
1189 for (const auto &cd : *Doxygen::conceptLinkedMap)
1190 {
1191 if (cd->isLinkableInProject() && !cd->isAlias())
1192 {
1193 if (!found)
1194 {
1195 m_t << "}\n";
1196 found=true;
1197 }
1198 m_t << "\\input{" << cd->getOutputFileBase() << "}\n";
1199 }
1200 }
1201 }
1202 break;
1204 {
1205 bool found=FALSE;
1206 for (const auto &cd : *Doxygen::classLinkedMap)
1207 {
1208 if (cd->isLinkableInProject() &&
1209 !cd->isImplicitTemplateInstance() &&
1210 !cd->isEmbeddedInOuterScope() &&
1211 !cd->isAlias()
1212 )
1213 {
1214 if (!found)
1215 {
1216 m_t << "}\n"; // end doxysection or chapter title
1217 found=TRUE;
1218 }
1219 m_t << "\\input{" << cd->getOutputFileBase() << "}\n";
1220 }
1221 }
1222 }
1223 break;
1225 {
1226 bool isFirst=TRUE;
1227 for (const auto &fn : *Doxygen::inputNameLinkedMap)
1228 {
1229 for (const auto &fd : *fn)
1230 {
1231 if (fd->isLinkableInProject())
1232 {
1233 if (isFirst)
1234 {
1235 m_t << "}\n"; // end doxysection or chapter title
1236 }
1237 isFirst=FALSE;
1238 m_t << "\\input{" << fd->getOutputFileBase() << "}\n";
1239 }
1240 if (fd->generateSourceFile())
1241 {
1242 if (isFirst)
1243 {
1244 m_t << "}\n"; // end doxysection or chapter title
1245 }
1246 isFirst=FALSE;
1247 m_t << "\\input{" << fd->getSourceFileBase() << "}\n";
1248 }
1249 }
1250 }
1251 }
1252 break;
1254 {
1255 m_t << "}\n";
1256 for (const auto &pd : *Doxygen::exampleLinkedMap)
1257 {
1258 m_t << "\\input{" << pd->getOutputFileBase() << "}\n";
1259 }
1260 }
1261 break;
1263 {
1264 for (const auto &pd : *Doxygen::pageLinkedMap)
1265 {
1266 if (!pd->getGroupDef() && !pd->isReference() && !pd->hasParentPage()
1267 && pd->name() != "citelist" && Doxygen::mainPage.get() != pd.get())
1268 {
1269 writePageLink(pd->getOutputFileBase(), FALSE);
1270 }
1271 }
1272 }
1273 break;
1275 break;
1278 break;
1279 }
1280}
1281
1282void LatexGenerator::writePageLink(const QCString &name, bool /*first*/)
1283{
1284 //bool &compactLatex = Config_getBool(COMPACT_LATEX);
1285 // next is remove for bug615957
1286 //if (compactLatex || first) m_t << "\\input" ; else m_t << "\\include";
1287 m_t << "\\input" ;
1288 m_t << "{" << name << "}\n";
1289}
1290
1292{
1293 if (part > 0)
1294 return;
1295
1296 startPlainFile("doxygen.sty");
1298 endPlainFile();
1299
1300 // workaround for the problem caused by change in LaTeX in version 2019
1301 // in the unmaintained tabu package
1302 startPlainFile("tabu_doxygen.sty");
1303 m_t << ResourceMgr::instance().getAsString("tabu_doxygen.sty");
1304 endPlainFile();
1305 startPlainFile("longtable_doxygen.sty");
1306 m_t << ResourceMgr::instance().getAsString("longtable_doxygen.sty");
1307 endPlainFile();
1308 /// an extension of the etoc package is required that is only available in the
1309 /// newer version. Providing the updated version to be used with older versions
1310 /// of LaTeX
1311 startPlainFile("etoc_doxygen.sty");
1312 m_t << ResourceMgr::instance().getAsString("etoc_doxygen.sty");
1313 endPlainFile();
1314}
1315
1317{
1318 m_t << "\n" << "\n";
1319}
1320
1322{
1323 m_t << "\n" << "\n";
1324}
1325
1327{
1328 m_t << text;
1329}
1330
1332{
1333 m_t << "\\item ";
1334 if (ref.isEmpty() && !fn.isEmpty())
1335 {
1336 m_t << "\\contentsline{section}{";
1337 }
1338}
1339
1341{
1342 if (ref.isEmpty() && !fn.isEmpty())
1343 {
1344 m_t << "}{\\pageref{" << stripPath(fn) << "}}{}\n";
1345 }
1346}
1347
1349 const QCString &path,const QCString &name)
1350{
1351 m_t << "\\item\\contentsline{section}\\textbf{ ";
1352 if (!path.isEmpty()) docify(path);
1353 docify(name);
1354 m_t << "} ";
1355}
1356
1358{
1359 m_t << "\\item\\contentsline{section}{";
1360}
1361
1365
1367{
1368 m_t << " ";
1369 if (hasBrief) m_t << "\\\\*";
1370}
1371
1372void LatexGenerator::endIndexValue(const QCString &name,bool /*hasBrief*/)
1373{
1374 //if (hasBrief) m_t << ")";
1375 m_t << "}{\\pageref{" << stripPath(name) << "}}{}\n";
1376}
1377
1378//void LatexGenerator::writeClassLink(const QCString &,const QCString &,
1379// const QCString &,const QCString &name)
1380//{
1381// m_t << "\\textbf{ ";
1382// docify(name);
1383// m_t << "}";
1384//}
1385
1387{
1388 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1389 if (!m_disableLinks && pdfHyperlinks)
1390 {
1391 m_t << "\\mbox{\\hyperlink{";
1392 if (!f.isEmpty()) m_t << stripPath(f);
1393 if (!anchor.isEmpty()) m_t << "_" << anchor;
1394 m_t << "}{";
1395 }
1396 else
1397 {
1398 m_t << "\\textbf{ ";
1399 }
1400}
1401
1403{
1404 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1405 if (!m_disableLinks && pdfHyperlinks)
1406 {
1407 m_t << "}";
1408 }
1409 m_t << "}";
1410}
1411
1412static QCString objectLinkToString(const QCString &ref, const QCString &f,
1413 const QCString &anchor, const QCString &text,
1414 bool insideTabbing,bool disableLinks)
1415{
1416 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1417 QCString result;
1418 if (!disableLinks && ref.isEmpty() && pdfHyperlinks)
1419 {
1420 result += "\\mbox{\\hyperlink{";
1421 if (!f.isEmpty()) result += stripPath(f);
1422 if (!f.isEmpty() && !anchor.isEmpty()) result += "_";
1423 if (!anchor.isEmpty()) result += anchor;
1424 result += "}{";
1425 result += convertToLaTeX(text,insideTabbing);
1426 result += "}}";
1427 }
1428 else
1429 {
1430 result += "\\textbf{ ";
1431 result += convertToLaTeX(text,insideTabbing);
1432 result += "}";
1433 }
1434 return result;
1435}
1436
1437static void processEntity(TextStream &t, bool pdfHyperlinks, const char *strForm, const char *strRepl)
1438{
1439 if (pdfHyperlinks)
1440 {
1441 t << "\\texorpdfstring{";
1442 }
1443 t << strForm;
1444 if (pdfHyperlinks)
1445 {
1446 t << "}{" << strRepl << "}";
1447 }
1448}
1449
1451 const QCString &anchor, const QCString &text)
1452{
1453 m_t << objectLinkToString(ref,f,anchor,text,m_codeGen->insideTabbing(),m_disableLinks);
1454}
1455
1457{
1458 m_t << " \\doxyref{}{";
1459}
1460
1461void LatexGenerator::endPageRef(const QCString &clname, const QCString &anchor)
1462{
1463 m_t << "}{";
1464 if (!clname.isEmpty()) m_t << clname;
1465 if (!anchor.isEmpty()) m_t << "_" << anchor;
1466 m_t << "}";
1467}
1468
1469
1471{
1472 int hierarchyLevel = m_hierarchyLevel;
1473 if (Config_getBool(COMPACT_LATEX))
1474 {
1475 ++hierarchyLevel;
1476 }
1477
1478 if (hierarchyLevel < 0)
1479 m_t << "\\chapter{";
1480 else
1481 m_t << "\\doxy" << QCString("sub").repeat(hierarchyLevel) << "section{";
1482}
1483
1485{
1486 m_t << "}\n";
1487
1488 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1489 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1490 if (usePDFLatex && pdfHyperlinks && !fileName.isEmpty())
1491 {
1492 m_t << "\\hypertarget{" << stripPath(fileName) << "}{}";
1493 }
1494
1496 if (!fn.isEmpty())
1497 {
1498 m_t << "\\label{" << fn << "}";
1499 }
1500 if (!name.isEmpty())
1501 {
1502 m_t << "\\index{";
1503 m_t << latexEscapeLabelName(name);
1504 m_t << "@{";
1505 m_t << latexEscapeIndexChars(name);
1506 m_t << "}}\n";
1507 }
1508}
1509
1511{
1512 if (Config_getBool(COMPACT_LATEX))
1513 {
1514 m_t << "\\doxysubsection{";
1515 }
1516 else
1517 {
1518 m_t << "\\doxysection{";
1519 }
1520}
1521
1522void LatexGenerator::startGroupHeader(const QCString &,int extraIndentLevel)
1523{
1524 if (Config_getBool(COMPACT_LATEX))
1525 {
1526 extraIndentLevel++;
1527 }
1528
1529 if (extraIndentLevel>=3)
1530 {
1531 m_t << "\\doxysubparagraph*{";
1532 }
1533 else if (extraIndentLevel==2)
1534 {
1535 m_t << "\\doxyparagraph{";
1536 }
1537 else
1538 {
1539 extraIndentLevel += m_hierarchyLevel + 1;
1540 m_t << "\\doxy" << QCString("sub").repeat(extraIndentLevel) << "section{";
1541 }
1543}
1544
1546{
1548 m_t << "}\n";
1549}
1550
1552{
1553 int l = m_hierarchyLevel + 1;
1554 if (Config_getBool(COMPACT_LATEX))
1555 {
1556 ++l;
1557 }
1558
1559 m_t << "\\doxysub" << QCString("sub").repeat(l) << "section*{";
1561}
1562
1564{
1566 m_t << "}\n";
1567}
1568
1570 const QCString &memname,
1571 const QCString &,
1572 const QCString &title,
1573 int memCount,
1574 int memTotal,
1575 bool showInline)
1576{
1577 if (!memname.isEmpty() && memname[0]!='@')
1578 {
1579 m_t << "\\index{";
1580 if (!clname.isEmpty())
1581 {
1582 m_t << latexEscapeLabelName(clname);
1583 m_t << "@{";
1584 m_t << latexEscapeIndexChars(clname);
1585 m_t << "}!";
1586 }
1587 m_t << latexEscapeLabelName(memname);
1588 m_t << "@{";
1589 m_t << latexEscapeIndexChars(memname);
1590 m_t << "}}\n";
1591
1592 m_t << "\\index{";
1593 m_t << latexEscapeLabelName(memname);
1594 m_t << "@{";
1595 m_t << latexEscapeIndexChars(memname);
1596 m_t << "}";
1597 if (!clname.isEmpty())
1598 {
1599 m_t << "!";
1600 m_t << latexEscapeLabelName(clname);
1601 m_t << "@{";
1602 m_t << latexEscapeIndexChars(clname);
1603 m_t << "}";
1604 }
1605 m_t << "}\n";
1606 }
1607 bool compactLatex = Config_getBool(COMPACT_LATEX);
1608 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1609 if (showInline)
1610 {
1611 m_t << "\\doxysubparagraph";
1612 }
1613 else if (compactLatex)
1614 {
1615 m_t << "\\doxyparagraph";
1616 }
1617 else
1618 {
1619 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 2) << "section";
1620 }
1621
1622 m_t << "{";
1623 if (pdfHyperlinks)
1624 {
1625 m_t << "\\texorpdfstring{";
1626 }
1627 m_t << latexEscapeIndexChars(title);
1628 if (pdfHyperlinks)
1629 {
1630 m_t << "}{" << latexEscapePDFString(title) << "}";
1631 }
1632 if (memTotal>1)
1633 {
1634 m_t << "\\hspace{0.1cm}{\\footnotesize\\ttfamily [" << memCount << "/" << memTotal << "]}";
1635 }
1636 m_t << "}";
1637 m_t << "\n{\\footnotesize\\ttfamily ";
1638 //m_disableLinks=TRUE;
1639}
1640
1642{
1644 m_t << "}\n\n";
1645 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\hfill";
1646}
1647
1649 const QCString &anchor, const QCString &,
1650 const QCString &)
1651{
1652 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1653 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1654 if (m_insideTableEnv) m_t << "\\mbox{"; // see issue #6093
1655 if (usePDFLatex && pdfHyperlinks)
1656 {
1657 m_t << "\\Hypertarget{";
1658 if (!fName.isEmpty()) m_t << stripPath(fName);
1659 if (!anchor.isEmpty()) m_t << "_" << anchor;
1660 m_t << "}";
1661 }
1662}
1663
1664void LatexGenerator::endDoxyAnchor(const QCString &/* fName */,const QCString &/* anchor */)
1665{
1666}
1667
1668void LatexGenerator::addLabel(const QCString &fName, const QCString &anchor)
1669{
1670 m_t << "\\label{";
1671 if (!fName.isEmpty()) m_t << stripPath(fName);
1672 if (!anchor.isEmpty()) m_t << "_" << anchor;
1673 if (m_insideTableEnv) m_t << "}";
1674 m_t << "} \n";
1675}
1676
1677void LatexGenerator::writeAnchor(const QCString &fName,const QCString &name)
1678{
1679 //printf("LatexGenerator::writeAnchor(%s,%s)\n",fName,name);
1680 m_t << "\\label{" << stripPath(name) << "}\n";
1681 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1682 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1683 if (usePDFLatex && pdfHyperlinks)
1684 {
1685 if (!fName.isEmpty())
1686 {
1687 m_t << "\\Hypertarget{" << stripPath(fName) << "_" << stripPath(name) << "}\n";
1688 }
1689 else
1690 {
1691 m_t << "\\Hypertarget{" << stripPath(name) << "}\n";
1692 }
1693 }
1694}
1695
1696
1697//void LatexGenerator::writeLatexLabel(const QCString &clName,const QCString &anchor)
1698//{
1699// writeDoxyAnchor(0,clName,anchor,0);
1700//}
1701
1703{
1704 if (!s1.isEmpty())
1705 {
1706 m_t << "\\index{";
1708 m_t << "@{";
1710 m_t << "}";
1711 if (!s2.isEmpty())
1712 {
1713 m_t << "!";
1715 m_t << "@{";
1717 m_t << "}";
1718 }
1719 m_t << "}";
1720 }
1721}
1722
1723
1725{
1726 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1727 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1728 if (usePDFLatex && pdfHyperlinks)
1729 {
1730 m_t << "\\hypertarget{" << stripPath(lab) << "}{}";
1731 }
1732 m_t << "\\";
1733 if (Config_getBool(COMPACT_LATEX))
1734 {
1735 switch(type.level())
1736 {
1737 case SectionType::Page: m_t << "doxysubsection"; break;
1738 case SectionType::Section: m_t << "doxysubsubsection"; break;
1739 case SectionType::Subsection: m_t << "doxysubsubsubsection"; break;
1740 case SectionType::Subsubsection: m_t << "doxysubsubsubsubsection"; break;
1741 case SectionType::Paragraph: m_t << "doxysubsubsubsubsubsection"; break;
1742 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1743 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1744 default: ASSERT(0); break;
1745 }
1746 m_t << "{";
1747 }
1748 else
1749 {
1750 switch(type.level())
1751 {
1752 case SectionType::Page: m_t << "doxysection"; break;
1753 case SectionType::Section: m_t << "doxysubsection"; break;
1754 case SectionType::Subsection: m_t << "doxysubsubsection"; break;
1755 case SectionType::Subsubsection: m_t << "doxysubsubsubsection"; break;
1756 case SectionType::Paragraph: m_t << "doxysubsubsubsubsection"; break;
1757 case SectionType::Subparagraph: m_t << "doxysubsubsubsubsubsection"; break;
1758 case SectionType::Subsubparagraph: m_t << "doxysubsubsubsubsubsubsection"; break;
1759 default: ASSERT(0); break;
1760 }
1761 m_t << "{";
1762 }
1763}
1764
1766{
1767 m_t << "}\\label{" << lab << "}\n";
1768}
1769
1770
1772{
1774 m_codeGen->insideTabbing(), // insideTabbing
1775 false, // insidePre
1776 false, // insideItem
1777 m_codeGen->usedTableLevel()>0, // insideTable
1778 false // keepSpaces
1779 );
1780}
1781
1783{
1784 char cs[2];
1785 cs[0]=c;
1786 cs[1]=0;
1787 docify(cs);
1788}
1789
1791{
1792 //if (Config_getBool(COMPACT_LATEX)) m_t << "\\doxysubsubsection"; else m_t << "\\doxysubsection";
1793 //m_t << "{";
1794}
1795
1797 const QCString &fileName,const QCString &)
1798{
1800}
1801
1802
1804{
1805 if (indent==0)
1806 {
1807 m_t << "\\begin{tabbing}\n";
1808 m_t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill\n";
1809 m_codeGen->setInsideTabbing(true);
1810 }
1811 m_indent=indent;
1812}
1813
1815{
1816 if (indent==0)
1817 {
1818 m_t << "\n" << "\\end{tabbing}";
1819 m_codeGen->setInsideTabbing(false);
1820 }
1821 m_indent=indent;
1822}
1823
1825{
1827 {
1828 m_t << "{\\footnotesize ";
1829 }
1830}
1831
1833{
1835 {
1836 m_t << "}\\\\";
1837 }
1838}
1839
1841{
1842 //printf("LatexGenerator::startMemberItem(%d)\n",annType);
1843 if (!m_codeGen->insideTabbing())
1844 {
1845 m_t << "\\item \n";
1847 }
1848}
1849
1851{
1852 if (m_codeGen->insideTabbing())
1853 {
1854 m_t << "\\\\";
1855 }
1857 m_t << "\n";
1858}
1859
1861{
1862 if (!m_codeGen->insideTabbing())
1863 {
1864 m_t << "\\begin{DoxyCompactList}\\small\\item\\em ";
1865 }
1866 else
1867 {
1868 for (int i=0;i<m_indent+2;i++) m_t << "\\>";
1869 m_t << "{\\em ";
1870 }
1871}
1872
1874{
1875 if (!m_codeGen->insideTabbing())
1876 {
1877 //m_t << "\\item\\end{DoxyCompactList}";
1878 m_t << "\\end{DoxyCompactList}";
1879 }
1880 else
1881 {
1882 m_t << "}\\\\\n";
1883 }
1884}
1885
1886
1888{
1889 //printf("writeNonBreakableSpace()\n");
1890 if (m_codeGen->insideTabbing())
1891 {
1892 m_t << "\\>";
1893 }
1894 else
1895 {
1896 m_t << "~";
1897 }
1898}
1899
1900// ----------------------------------------------
1901// nesting of functions below:
1902// startDescTable()
1903// - startDescTableRow()
1904// - startDescTableTitle()
1905// - endDescTableTitle()
1906// - startDescTableData()
1907// - endDescTableData()
1908// - endDescTableRow()
1909// - startDescTableRow()
1910// - ...
1911// - endDescTableRow()
1912// endDescTable()
1913
1914void LatexGenerator::startDescTable(const QCString &title,const bool hasInits)
1915{
1916 m_codeGen->incUsedTableLevel();
1917 m_t << "\\begin{DoxyEnumFields}[" << (hasInits?3:2) << "]{" << title << "}\n";
1918}
1919
1921{
1922 m_codeGen->decUsedTableLevel();
1923 m_t << "\\end{DoxyEnumFields}\n";
1924}
1925
1927{
1928 // this is needed to prevent the \hypertarget, \label, and \index commands from messing up
1929 // the row height (based on http://tex.stackexchange.com/a/186102)
1930 m_t << "\\raisebox{\\heightof{T}}[0pt][0pt]{";
1931}
1932
1936
1938{
1939 m_t << "}";
1940}
1941
1945
1947{
1948 m_t << "&";
1949}
1950
1954
1956{
1957 m_t << "&";
1958}
1959
1961{
1962 m_t << "\\\\\n\\hline\n\n";
1963}
1964
1968
1969
1971{
1972 if (!m_codeGen->insideTabbing())
1973 {
1974 m_t << "\\begin{DoxyCompactItemize}\n";
1975 }
1976}
1977
1979{
1980 //printf("LatexGenerator::endMemberList(%d)\n",m_codeGen->InsideTabbing());
1981 if (!m_codeGen->insideTabbing())
1982 {
1983 m_t << "\\end{DoxyCompactItemize}\n";
1984 }
1985}
1986
1987
1989{
1990 if (hasHeader) m_t << "\\begin{Indent}";
1991 m_t << "\\textbf{ ";
1992 // changed back to rev 756 due to bug 660501
1993 //if (Config_getBool(COMPACT_LATEX))
1994 //{
1995 // m_t << "\\doxysubparagraph*{";
1996 //}
1997 //else
1998 //{
1999 // m_t << "\\doxyparagraph*{";
2000 //}
2001}
2002
2004{
2005 // changed back to rev 756 due to bug 660501
2006 m_t << "}\\par\n";
2007 //m_t << "}\n";
2008}
2009
2011{
2012 m_t << "{\\em ";
2013}
2014
2016{
2017 m_t << "}";
2018}
2019
2023
2025{
2026 if (hasHeader)m_t << "\\end{Indent}";
2027 m_t << "\n";
2028}
2029
2031{
2032 m_t << "\n" << "\n";
2033}
2034
2039
2043
2048
2052
2057
2061
2066
2070
2075
2077{
2078 m_t << "\\begin{Desc}\n\\item[";
2079 docify(theTranslator->trExamples());
2080 m_t << "]";
2081}
2082
2084{
2085 m_t << "\\end{Desc}\n";
2086}
2087
2089{
2090 /* start of ParameterType ParameterName list */
2091 if (openBracket) m_t << "(";
2092 m_t << "\\begin{DoxyParamCaption}";
2093}
2094
2098
2100{
2101 m_t << "\\item[{";
2102 if (!first && !key.isEmpty()) docify(key);
2103}
2104
2106{
2107 m_t << "}]";
2108}
2109
2110void LatexGenerator::startParameterName(bool /*oneArgOnly*/)
2111{
2112 m_t << "{";
2113}
2114
2116{
2117 m_t << "}";
2118}
2119
2121{
2122 m_t << "{";
2123}
2124
2125void LatexGenerator::endParameterExtra(bool last,bool /*emptyList*/,bool closeBracket)
2126{
2127 m_t << "}";
2128 if (last)
2129 {
2130 m_t << "\\end{DoxyParamCaption}";
2131 if (closeBracket) m_t << ")";
2132 }
2133}
2134
2135void LatexGenerator::exceptionEntry(const QCString &prefix,bool closeBracket)
2136{
2137 if (!prefix.isEmpty())
2138 {
2139 m_t << " " << prefix << "(";
2140 }
2141 else if (closeBracket)
2142 {
2143 m_t << ")";
2144 }
2145 m_t << " ";
2146}
2147
2148void LatexGenerator::writeDoc(const IDocNodeAST *ast,const Definition *ctx,const MemberDef *,int)
2149{
2150 const DocNodeAST *astImpl = dynamic_cast<const DocNodeAST*>(ast);
2151 if (astImpl)
2152 {
2154 ctx?ctx->getDefFileExtension():QCString(""),
2156 std::visit(visitor,astImpl->root);
2157 }
2158}
2159
2161{
2162 m_t << "\\begin{Desc}\n\\item[";
2163 docify(header);
2164 m_t << "]";
2165 m_t << "\\begin{description}\n";
2166}
2167
2169{
2170 m_t << "\\item[{\\em ";
2171}
2172
2176
2178{
2179 m_t << "} : {\\em ";
2180}
2181
2183{
2184 m_t << "}]";
2185}
2186
2190
2194
2196{
2197 m_t << "\\end{description}\n";
2198 m_t << "\\end{Desc}\n";
2199}
2200
2202{
2203 if (Config_getBool(COMPACT_LATEX))
2204 {
2205 m_t << "\\doxyparagraph*{";
2206 }
2207 else
2208 {
2209 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2210 }
2211}
2212
2214{
2215 m_t << "}\n";
2216}
2217
2219{
2220 if (m_codeGen->insideTabbing())
2221 {
2222 m_t << "\\\\\n";
2223 }
2224 else
2225 {
2226 m_t << "\\newline\n";
2227 }
2228}
2229
2231{
2232 m_codeGen->incUsedTableLevel();
2233 if (isEnum)
2234 {
2235 m_t << "\\begin{DoxyEnumFields}{";
2236 docify(theTranslator->trEnumerationValues());
2237 }
2238 else
2239 {
2240 m_t << "\\begin{DoxyFields}{";
2241 docify(theTranslator->trCompoundMembers());
2242 }
2243 m_t << "}\n";
2244 m_insideTableEnv=true;
2245}
2246
2248{
2249 m_insideTableEnv=false;
2250 m_codeGen->decUsedTableLevel();
2251 if (isEnum)
2252 {
2253 m_t << "\\end{DoxyEnumFields}\n";
2254 }
2255 else
2256 {
2257 m_t << "\\end{DoxyFields}\n";
2258 }
2259}
2260
2262{
2263 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2264}
2265
2267{
2268 m_t << "&\n";
2269 m_codeGen->setInsideTabbing(false);
2270}
2271
2273{
2274 m_codeGen->setInsideTabbing(true); // to prevent \+ from causing unwanted breaks
2275}
2276
2278{
2279 m_t << "&\n";
2280 m_codeGen->setInsideTabbing(false);
2281}
2282
2286
2288{
2289 m_t << "\\\\\n\\hline\n\n";
2290}
2291
2293{
2294 m_t << "\\hspace{0.3cm}";
2295}
2296
2297void LatexGenerator::writeLabel(const QCString &l,bool isLast)
2298{
2299 m_t << "{\\ttfamily [" << l << "]}";
2300 if (!isLast) m_t << ", ";
2301}
2302
2304{
2305}
2306
2308 const QCString &/*id*/,const QCString &ref,
2309 const QCString &file, const QCString &anchor,
2310 const QCString &title, const QCString &name)
2311{
2312 if (Config_getBool(COMPACT_LATEX))
2313 {
2314 m_t << "\\doxyparagraph*{";
2315 }
2316 else
2317 {
2318 m_t << "\\doxy" << QCString("sub").repeat(m_hierarchyLevel + 1) << "section*{";
2319 }
2320 m_t << theTranslator->trInheritedFrom(convertToLaTeX(title,m_codeGen->insideTabbing()),
2321 objectLinkToString(ref, file, anchor, name, m_codeGen->insideTabbing(), m_disableLinks));
2322 m_t << "}\n";
2323}
2324
2326{
2327 int maxLevel = level + m_hierarchyLevel;
2328 m_t << "\\etocsetnexttocdepth{" << maxLevel << "}\n";
2329 m_t << "\\localtableofcontents\n";
2330}
2331
2332//--------------------------------------------------------------------------------------------------
2333
2335{
2336 // User-specified packages
2337 const StringVector &extraPackages = Config_getList(EXTRA_PACKAGES);
2338 if (!extraPackages.empty())
2339 {
2340 t << "% Packages requested by user\n";
2341 for (const auto &pkgName : extraPackages)
2342 {
2343 if ((pkgName[0] == '[') || (pkgName[0] == '{'))
2344 t << "\\usepackage" << pkgName.c_str() << "\n";
2345 else
2346 t << "\\usepackage{" << pkgName.c_str() << "}\n";
2347 }
2348 t << "\n";
2349 }
2350}
2351
2353{
2354 unsigned char minus[4]; // Superscript minus
2355 unsigned char sup2[3]; // Superscript two
2356 unsigned char sup3[3];
2357 minus[0]= 0xE2;
2358 minus[1]= 0x81;
2359 minus[2]= 0xBB;
2360 minus[3]= 0;
2361 sup2[0]= 0xC2;
2362 sup2[1]= 0xB2;
2363 sup2[2]= 0;
2364 sup3[0]= 0xC2;
2365 sup3[1]= 0xB3;
2366 sup3[2]= 0;
2367
2368 t << "\\ifPDFTeX\n";
2369 t << "\\usepackage{newunicodechar}\n";
2370 // taken from the newunicodechar package and removed the warning message
2371 // actually forcing to redefine the unicode character
2372 t << " \\makeatletter\n"
2373 " \\def\\doxynewunicodechar#1#2{%\n"
2374 " \\@tempswafalse\n"
2375 " \\edef\\nuc@tempa{\\detokenize{#1}}%\n"
2376 " \\if\\relax\\nuc@tempa\\relax\n"
2377 " \\nuc@emptyargerr\n"
2378 " \\else\n"
2379 " \\edef\\@tempb{\\expandafter\\@car\\nuc@tempa\\@nil}%\n"
2380 " \\nuc@check\n"
2381 " \\if@tempswa\n"
2382 " \\@namedef{u8:\\nuc@tempa}{#2}%\n"
2383 " \\fi\n"
2384 " \\fi\n"
2385 " }\n"
2386 " \\makeatother\n";
2387
2388 t << " \\doxynewunicodechar{" << minus << "}{${}^{-}$}% Superscript minus\n"
2389 " \\doxynewunicodechar{" << sup2 << "}{${}^{2}$}% Superscript two\n"
2390 " \\doxynewunicodechar{" << sup3 << "}{${}^{3}$}% Superscript three\n"
2391 "\n";
2392 t << "\\fi\n";
2393}
2394
2396 bool insideTabbing,bool insidePre,bool insideItem,bool insideTable,bool keepSpaces, const bool retainNewline)
2397{
2398 if (str.isEmpty()) return;
2399 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
2400 //printf("filterLatexString(%s) insideTabbing=%d\n",qPrint(str),insideTabbing);
2401 const char *p = str.data();
2402 const char *q = nullptr;
2403 unsigned char pc='\0';
2404
2405 while (*p)
2406 {
2407 unsigned char c=static_cast<unsigned char>(*p++);
2408
2409 if (insidePre)
2410 {
2411 switch(c)
2412 {
2413 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2414 // the LaTeX command \ucr has been defined in doxygen.sty
2415 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2416 {
2417 t << "{\\ucr}";
2418 p += 2;
2419 }
2420 else
2421 t << static_cast<char>(c);
2422 break;
2423 case '\\': t << "\\(\\backslash\\)"; break;
2424 case '{': t << "\\{"; break;
2425 case '}': t << "\\}"; break;
2426 case '_': t << "\\_"; break;
2427 case '&': t << "\\&"; break;
2428 case '%': t << "\\%"; break;
2429 case '#': t << "\\#"; break;
2430 case '$': t << "\\$"; break;
2431 case '"': t << "\"{}"; break;
2432 case '-': t << "-\\/"; break;
2433 case '^': insideTable ? t << "\\string^" : t << static_cast<char>(c); break;
2434 case '~': t << "\\string~"; break;
2435 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2436 break;
2437 case ' ': if (keepSpaces) t << "~"; else t << ' ';
2438 break;
2439 default:
2440 if (c<32) t << ' '; // non printable control character
2441 else t << static_cast<char>(c);
2442 break;
2443 }
2444 }
2445 else
2446 {
2447 switch(c)
2448 {
2449 case 0xef: // handle U+FFFD i.e. "Replacement character" caused by octal: 357 277 275 / hexadecimal 0xef 0xbf 0xbd
2450 // the LaTeX command \ucr has been defined in doxygen.sty
2451 if (static_cast<unsigned char>(*(p)) == 0xbf && static_cast<unsigned char>(*(p+1)) == 0xbd)
2452 {
2453 t << "{\\ucr}";
2454 p += 2;
2455 }
2456 else
2457 t << static_cast<char>(c);
2458 break;
2459 case '#': t << "\\#"; break;
2460 case '$': t << "\\$"; break;
2461 case '%': t << "\\%"; break;
2462 case '^': processEntity(t,pdfHyperlinks,"$^\\wedge$","\\string^"); break;
2463 case '&': {
2464 // possibility to have a special symbol
2465 q = p;
2466 int cnt = 2; // we have to count & and ; as well
2467 while ((*q >= 'a' && *q <= 'z') || (*q >= 'A' && *q <= 'Z') || (*q >= '0' && *q <= '9'))
2468 {
2469 cnt++;
2470 q++;
2471 }
2472 if (*q == ';')
2473 {
2474 --p; // we need & as well
2477 {
2478 p++;
2479 t << "\\&";
2480 }
2481 else
2482 {
2484 q++;
2485 p = q;
2486 }
2487 }
2488 else
2489 {
2490 t << "\\&";
2491 }
2492 }
2493 break;
2494 case '*': processEntity(t,pdfHyperlinks,"$\\ast$","*"); break;
2495 case '_': if (!insideTabbing) t << "\\+";
2496 t << "\\_";
2497 if (!insideTabbing) t << "\\+";
2498 break;
2499 case '{': t << "\\{"; break;
2500 case '}': t << "\\}"; break;
2501 case '<': t << "$<$"; break;
2502 case '>': t << "$>$"; break;
2503 case '|': processEntity(t,pdfHyperlinks,"$\\vert$","|"); break;
2504 case '~': processEntity(t,pdfHyperlinks,"$\\sim$","\\string~"); break;
2505 case '[': if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2506 t << "\\mbox{[}";
2507 else
2508 t << "[";
2509 break;
2510 case ']': if (pc=='[') t << "$\\,$";
2511 if (Config_getBool(PDF_HYPERLINKS) || insideItem)
2512 t << "\\mbox{]}";
2513 else
2514 t << "]";
2515 break;
2516 case '-': t << "-\\/";
2517 break;
2518 case '\\': t << "\\textbackslash{}";
2519 break;
2520 case '"': t << "\"{}";
2521 break;
2522 case '`': t << "\\`{}";
2523 break;
2524 case '\'': t << "\\textquotesingle{}";
2525 break;
2526 case '\n': if (retainNewline) t << "\\newline"; else t << ' ';
2527 break;
2528 case ' ': if (keepSpaces) { if (insideTabbing) t << "\\>"; else t << '~'; } else t << ' ';
2529 break;
2530
2531 default:
2532 //if (!insideTabbing && forceBreaks && c!=' ' && *p!=' ')
2533 if (!insideTabbing &&
2534 ((c>='A' && c<='Z' && pc!=' ' && !(pc>='A' && pc <= 'Z') && pc!='\0' && *p) || (c==':' && pc!=':') || (pc=='.' && isId(c)))
2535 )
2536 {
2537 t << "\\+";
2538 }
2539 if (c<32)
2540 {
2541 t << ' '; // non-printable control character
2542 }
2543 else
2544 {
2545 t << static_cast<char>(c);
2546 }
2547 }
2548 }
2549 pc = c;
2550 }
2551}
2552
2553QCString convertToLaTeX(const QCString &s,bool insideTabbing,bool keepSpaces)
2554{
2555 TextStream t;
2556 filterLatexString(t,s,insideTabbing,false,false,false,keepSpaces);
2557 return t.str();
2558}
2559
2561{
2562 //printf("latexEscapeLabelName(%s)\n",qPrint(s));
2563 if (s.isEmpty()) return s;
2565 TextStream t;
2566 const char *p=s.data();
2567 char c = 0;
2568 while ((c=*p++))
2569 {
2570 switch (c)
2571 {
2572 case '|': t << "\\texttt{\"|}"; break;
2573 case '!': t << "\"!"; break;
2574 case '@': t << "\"@"; break;
2575 case '%': t << "\\%"; break;
2576 case '{': t << "\\lcurly{}"; break;
2577 case '}': t << "\\rcurly{}"; break;
2578 case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
2579 // NOTE: adding a case here, means adding it to while below as well!
2580 default:
2581 {
2582 int i=0;
2583 // collect as long string as possible, before handing it to docify
2584 tmp[i++]=c;
2585 while ((c=*p) && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2586 {
2587 tmp[i++]=c;
2588 p++;
2589 }
2590 tmp[i]=0;
2591 filterLatexString(t,tmp,
2592 true, // insideTabbing
2593 false, // insidePre
2594 false, // insideItem
2595 false, // insideTable
2596 false // keepSpaces
2597 );
2598 }
2599 break;
2600 }
2601 }
2602 return t.str();
2603}
2604
2606{
2607 //printf("latexEscapeIndexChars(%s)\n",qPrint(s));
2608 if (s.isEmpty()) return s;
2610 TextStream t;
2611 const char *p=s.data();
2612 char c = 0;
2613 while ((c=*p++))
2614 {
2615 switch (c)
2616 {
2617 case '!': t << "\"!"; break;
2618 case '"': t << "\"\""; break;
2619 case '@': t << "\"@"; break;
2620 case '|': t << "\\texttt{\"|}"; break;
2621 case '[': t << "["; break;
2622 case ']': t << "]"; break;
2623 case '{': t << "\\lcurly{}"; break;
2624 case '}': t << "\\rcurly{}"; break;
2625 // NOTE: adding a case here, means adding it to while below as well!
2626 default:
2627 {
2628 int i=0;
2629 // collect as long string as possible, before handing it to docify
2630 tmp[i++]=c;
2631 while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
2632 {
2633 tmp[i++]=c;
2634 p++;
2635 }
2636 tmp[i]=0;
2637 filterLatexString(t,tmp,
2638 true, // insideTabbing
2639 false, // insidePre
2640 false, // insideItem
2641 false, // insideTable
2642 false // keepSpaces
2643 );
2644 }
2645 break;
2646 }
2647 }
2648 return t.str();
2649}
2650
2652{
2653 if (s.isEmpty()) return s;
2654 TextStream t;
2655 const char *p=s.data();
2656 char c = 0;
2657 while ((c=*p++))
2658 {
2659 switch (c)
2660 {
2661 case '\\': t << "\\textbackslash{}"; break;
2662 case '{': t << "\\{"; break;
2663 case '}': t << "\\}"; break;
2664 case '_': t << "\\_"; break;
2665 case '%': t << "\\%"; break;
2666 case '&': t << "\\&"; break;
2667 case '#': t << "\\#"; break;
2668 case '$': t << "\\$"; break;
2669 case '^': t << "\\string^"; break;
2670 case '~': t << "\\string~"; break;
2671 default:
2672 t << c;
2673 break;
2674 }
2675 }
2676 return t.str();
2677}
2678
2680{
2681 constexpr auto hex = "0123456789ABCDEF";
2682 if (s.isEmpty()) return s;
2683 TextStream t;
2684 const char *p=s.data();
2685 char c = 0;
2686 while ((c=*p++))
2687 {
2688 switch (c)
2689 {
2690 case '#': t << "\\#"; break;
2691 case '%': t << "\\%"; break;
2692 case '\\': t << "\\\\"; break;
2693 default:
2694 if (c<0)
2695 {
2696 unsigned char id = static_cast<unsigned char>(c);
2697 t << "\\%" << hex[id>>4] << hex[id&0xF];
2698 }
2699 else
2700 {
2701 t << c;
2702 }
2703 break;
2704 }
2705 }
2706 return t.str();
2707}
2708
2709
constexpr auto prefix
Definition anchor.cpp:44
QCString latexBibFiles()
lists the bibtex cite files in a comma separated list
Definition cite.cpp:577
static CitationManager & instance()
Definition cite.cpp:86
bool isEmpty() const
return TRUE if there are no citations.
Definition cite.cpp:117
Class representing a built-in class diagram.
Definition diagram.h:31
void writeFigure(TextStream &t, const QCString &path, const QCString &file) const
Definition diagram.cpp:1073
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual QCString getDefFileExtension() const =0
Class representing a directory in the file system.
Definition dir.h:75
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:295
bool exists() const
Definition dir.cpp:257
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1466
DocNodeVariant root
Definition docnode.h:1491
Representation of an call graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
Representation of a class inheritance or dependency graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool TBRank=TRUE, bool imageMap=TRUE, int graphId=-1)
Representation of an directory dependency graph.
Definition dotdirdeps.h:26
QCString writeGraph(TextStream &out, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1, bool linkRelations=TRUE)
Representation of a group collaboration graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
Representation of an include dependency graph.
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
static ConceptLinkedMap * conceptLinkedMap
Definition doxygen.h:98
static std::unique_ptr< PageDef > mainPage
Definition doxygen.h:101
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:96
static PageLinkedMap * exampleLinkedMap
Definition doxygen.h:99
static PageLinkedMap * pageLinkedMap
Definition doxygen.h:100
static DirLinkedMap * dirLinkedMap
Definition doxygen.h:129
static GroupLinkedMap * groupLinkedMap
Definition doxygen.h:114
Minimal replacement for QFileInfo.
Definition fileinfo.h:23
bool exists() const
Definition fileinfo.cpp:30
std::string fileName() const
Definition fileinfo.cpp:118
std::string absFilePath() const
Definition fileinfo.cpp:101
const char * latex(SymType symb) const
Access routine to the LaTeX code of the HTML entity.
static HtmlEntityMapper & instance()
Returns the one and only instance of the HTML entity mapper.
SymType name2sym(const QCString &symName) const
Give code of the requested HTML entity name.
opaque representation of the abstract syntax tree (AST)
Definition docparser.h:50
Generator for LaTeX code fragments.
Definition latexgen.h:28
bool m_stripCodeComments
Definition latexgen.h:87
TextStream * m_t
Definition latexgen.h:80
void setStripIndentAmount(size_t amount) override
Definition latexgen.cpp:191
void endFontClass() override
Definition latexgen.cpp:297
void writeLineNumber(const QCString &, const QCString &, const QCString &, int, bool) override
Definition latexgen.cpp:222
void setSourceFileName(const QCString &sourceFileName)
Definition latexgen.cpp:73
void setRelativePath(const QCString &path)
Definition latexgen.cpp:68
void startFontClass(const QCString &) override
Definition latexgen.cpp:291
void endSpecialComment() override
Definition latexgen.cpp:186
void stripCodeComments(bool b) override
Definition latexgen.cpp:176
void startCodeFragment(const QCString &style) override
Definition latexgen.cpp:303
size_t m_stripIndentAmount
Definition latexgen.h:89
void startCodeLine(int) override
Definition latexgen.cpp:269
LatexCodeGenerator(TextStream *t, const QCString &relPath, const QCString &sourceFile)
Definition latexgen.cpp:59
void startSpecialComment() override
Definition latexgen.cpp:181
void endCodeFragment(const QCString &style) override
Definition latexgen.cpp:308
QCString m_sourceFileName
Definition latexgen.h:82
void codify(const QCString &text) override
Definition latexgen.cpp:78
void endCodeLine() override
Definition latexgen.cpp:280
QCString m_relPath
Definition latexgen.h:81
void writeCodeLink(CodeSymbolType type, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip) override
Definition latexgen.cpp:196
bool m_doxyCodeLineOpen
Definition latexgen.h:84
Concrete visitor implementation for LaTeX output.
void endMemberItem(MemberItemType) override
void addCodeGen(OutputCodeList &list) override
Definition latexgen.cpp:362
void endIndexKey() override
void endInlineMemberDoc() override
void startProjectNumber() override
Definition latexgen.cpp:734
void cleanup() override
Definition latexgen.cpp:679
void endPageRef(const QCString &, const QCString &) override
void endSection(const QCString &, SectionType) override
void startIndexSection(IndexSection) override
Definition latexgen.cpp:919
void endParameterList() override
void endMemberDescription() override
std::unique_ptr< OutputCodeList > m_codeList
Definition latexgen.h:332
void endDirDepGraph(DotDirDeps &g) override
void endDescTable() override
void startParameterType(bool, const QCString &) override
void startMemberGroup() override
void endInlineHeader() override
void endGroupHeader(int) override
void startMemberDoc(const QCString &, const QCString &, const QCString &, const QCString &, int, int, bool) override
void writeChar(char c) override
void endDescTableInit() override
void startParameterName(bool) override
void endMemberTemplateParams(const QCString &, const QCString &) override
void endParameterType() override
void startPageRef() override
void writeInheritedSectionTitle(const QCString &, const QCString &, const QCString &, const QCString &, const QCString &, const QCString &) override
void endLabels() override
void startParagraph(const QCString &classDef) override
void endIndexSection(IndexSection) override
void startConstraintType() override
void startClassDiagram() override
void endInlineMemberType() override
void startDescTableTitle() override
void startSection(const QCString &, const QCString &, SectionType) override
void writeString(const QCString &text) override
void endInclDepGraph(DotInclDepGraph &) override
void writeNonBreakableSpace(int) override
void startMemberGroupDocs() override
void endDescTableTitle() override
void startInclDepGraph() override
void lastIndexPage() override
void endExamples() override
void startLocalToc(int level) override
void endMemberGroupHeader() override
void docify(const QCString &text) override
void startAnonTypeScope(int) override
void endPlainFile() override
Definition latexgen.h:320
void startDoxyAnchor(const QCString &, const QCString &, const QCString &, const QCString &, const QCString &) override
static void writeFooterFile(TextStream &t)
Definition latexgen.cpp:697
void startParameterList(bool) override
void endMemberDoc(bool) override
void endConstraintType() override
void startDescTableRow() override
void endAnonTypeScope(int) override
QCString m_relPath
Definition latexgen.h:329
void startMemberHeader(const QCString &, int) override
void endConstraintList() override
void startDotGraph() override
void endParameterExtra(bool last, bool one, bool bracket) override
void endDescTableData() override
void writeLabel(const QCString &l, bool isLast) override
void startTextLink(const QCString &, const QCString &) override
void startConstraintList(const QCString &) override
void startGroupCollaboration() override
void startLabels() override
static void writeStyleSheetFile(TextStream &t)
Definition latexgen.cpp:703
void endTitleHead(const QCString &, const QCString &name) override
void endMemberHeader() override
OutputType type() const override
Definition latexgen.h:114
void endIndexItem(const QCString &ref, const QCString &file) override
void startGroupHeader(const QCString &, int) override
void startDescTable(const QCString &title, const bool hasInits) override
void endConstraintDocs() override
void startIndexKey() override
void writeDoc(const IDocNodeAST *node, const Definition *ctx, const MemberDef *, int id) override
void startConstraintParam() override
void lineBreak(const QCString &style=QCString()) override
void endInlineMemberName() override
void startMemberTemplateParams() override
void startInlineMemberType() override
int m_hierarchyLevel
Definition latexgen.h:335
void startInlineMemberDoc() override
void writeAnchor(const QCString &fileName, const QCString &name) override
void startCallGraph() override
void endMemberList() override
void endFile() override
Definition latexgen.cpp:723
void startExamples() override
LatexGenerator & operator=(const LatexGenerator &)
Definition latexgen.cpp:342
void startDirDepGraph() override
void endTextLink() override
void writeStartAnnoItem(const QCString &type, const QCString &file, const QCString &path, const QCString &name) override
void startMemberList() override
void startDescTableData() override
void endDescTableRow() override
void startConstraintDocs() override
void endMemberGroupDocs() override
void endClassDiagram(const ClassDiagram &, const QCString &, const QCString &) override
void startDescTableInit() override
void endMemberDocSimple(bool) override
void addIndexItem(const QCString &, const QCString &) override
void endParameterName() override
void endIndexValue(const QCString &, bool) override
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name) override
void startMemberDocSimple(bool) override
void startPlainFile(const QCString &name) override
Definition latexgen.h:319
void exceptionEntry(const QCString &, bool) override
void endCallGraph(DotCallGraph &) override
void endGroupCollaboration(DotGroupCollaboration &g) override
void startIndexItem(const QCString &ref, const QCString &file) override
bool m_disableLinks
Definition latexgen.h:328
void startFile(const QCString &name, const QCString &manName, const QCString &title, int id, int hierarchyLevel) override
Definition latexgen.cpp:709
void startTitleHead(const QCString &) override
void startInlineHeader() override
void endConstraintParam() override
void endDotGraph(DotClassGraph &) override
void writePageLink(const QCString &, bool) override
void startParameterExtra() override
LatexCodeGenerator * m_codeGen
Definition latexgen.h:333
void endMemberGroup(bool) override
void startMemberGroupHeader(const QCString &, bool) override
void startMemberDescription(const QCString &, const QCString &, bool) override
void startMemberItem(const QCString &, MemberItemType, const QCString &) override
bool m_firstDescItem
Definition latexgen.h:327
static void writeHeaderFile(TextStream &t)
Definition latexgen.cpp:691
void endParagraph() override
void addLabel(const QCString &, const QCString &) override
bool m_insideTableEnv
Definition latexgen.h:334
void writeStyleInfo(int part) override
void endDoxyAnchor(const QCString &, const QCString &) override
void startIndexValue(bool) override
void startInlineMemberName() override
static void init()
Definition latexgen.cpp:633
bool m_templateMemberItem
Definition latexgen.h:331
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
static ModuleManager & instance()
Class representing a list of different code generators.
Definition outputlist.h:164
void add(OutputCodeIntfPtr &&p)
Definition outputlist.h:194
Abstract interface for output generators.
Definition outputgen.h:127
QCString dir() const
Definition outputgen.cpp:52
QCString m_dir
Definition outputgen.h:117
TextStream m_t
Definition outputgen.h:116
QCString fileName() const
Definition outputgen.cpp:57
This is an alternative implementation of QCString.
Definition qcstring.h:101
QCString & prepend(const char *s)
Definition qcstring.h:407
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
QCString repeat(unsigned int n) const
Definition qcstring.h:306
const std::string & str() const
Definition qcstring.h:537
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
@ ExplicitSize
Definition qcstring.h:133
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
QCString quoted() const
Definition qcstring.h:260
static ResourceMgr & instance()
Returns the one and only instance of this class.
QCString getAsString(const QCString &name) const
Gets the resource data as a C string.
static constexpr int Section
Definition section.h:33
static constexpr int Subsection
Definition section.h:34
static constexpr int Subsubsection
Definition section.h:35
static constexpr int Page
Definition section.h:31
static constexpr int Paragraph
Definition section.h:36
static constexpr int Subsubparagraph
Definition section.h:38
static constexpr int Subparagraph
Definition section.h:37
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
#define Config_getInt(name)
Definition config.h:34
#define Config_getList(name)
Definition config.h:38
#define Config_getEnumAsString(name)
Definition config.h:36
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
std::vector< std::string > StringVector
Definition containers.h:33
QCString dateToString(DateTimeType includeTime)
Returns the current date, when includeTime is set also the time is provided.
Definition datetime.cpp:63
QCString yearToString()
Returns the current year as a string.
Definition datetime.cpp:76
static constexpr auto hex
static QCString objectLinkToString(const QCString &, const QCString &f, const QCString &anchor, const QCString &text)
bool insideTable(const DocNodeVariant *n)
#define THREAD_LOCAL
Definition doxygen.h:30
static QCString g_header
Definition htmlgen.cpp:64
static QCString g_header_file
Definition htmlgen.cpp:65
static QCString g_footer
Definition htmlgen.cpp:67
static QCString g_footer_file
Definition htmlgen.cpp:66
static void writeDefaultStyleSheet(TextStream &t)
Definition htmlgen.cpp:1365
IndexSection
Definition index.h:32
@ isMainPage
Definition index.h:35
@ isTitlePageAuthor
Definition index.h:34
@ isFileIndex
Definition index.h:43
@ isFileDocumentation
Definition index.h:51
@ isPageDocumentation
Definition index.h:53
@ isDirDocumentation
Definition index.h:47
@ isModuleDocumentation
Definition index.h:45
@ isClassHierarchyIndex
Definition index.h:41
@ isModuleIndex
Definition index.h:36
@ isTopicIndex
Definition index.h:37
@ isConceptIndex
Definition index.h:40
@ isExampleDocumentation
Definition index.h:52
@ isClassDocumentation
Definition index.h:49
@ isPageIndex
Definition index.h:44
@ isCompoundIndex
Definition index.h:42
@ isEndIndex
Definition index.h:55
@ isConceptDocumentation
Definition index.h:50
@ isDirIndex
Definition index.h:38
@ isNamespaceIndex
Definition index.h:39
@ isNamespaceDocumentation
Definition index.h:48
@ isTitlePageStart
Definition index.h:33
@ isTopicDocumentation
Definition index.h:46
@ isPageDocumentation2
Definition index.h:54
Translator * theTranslator
Definition language.cpp:71
static QCString latex_batchmode()
Definition latexgen.cpp:785
QCString latexEscapePDFString(const QCString &s)
QCString convertToLaTeX(const QCString &s, bool insideTabbing, bool keepSpaces)
static QCString makeIndex()
Definition latexgen.cpp:767
QCString latexFilterURL(const QCString &s)
static void writeLatexMakefile()
Definition latexgen.cpp:367
static const SelectionMarkerInfo latexMarkerInfo
Definition latexgen.cpp:55
static QCString extraLatexStyleSheet()
Definition latexgen.cpp:739
void filterLatexString(TextStream &t, const QCString &str, bool insideTabbing, bool insidePre, bool insideItem, bool insideTable, bool keepSpaces, const bool retainNewline)
#define COPYCHAR()
static void processEntity(TextStream &t, bool pdfHyperlinks, const char *strForm, const char *strRepl)
static void writeMakeBat()
Definition latexgen.cpp:503
static void writeDefaultStyleSheet(TextStream &t)
Definition latexgen.cpp:686
void writeExtraLatexPackages(TextStream &t)
static QCString substituteLatexKeywords(const QCString &file, const QCString &str, const QCString &title)
Definition latexgen.cpp:799
QCString latexEscapeIndexChars(const QCString &s)
static QCString objectLinkToString(const QCString &ref, const QCString &f, const QCString &anchor, const QCString &text, bool insideTabbing, bool disableLinks)
void writeLatexSpecialFormulaChars(TextStream &t)
QCString latexEscapeLabelName(const QCString &s)
QCString latexEscapePDFString(const QCString &s)
void filterLatexString(TextStream &t, const QCString &str, bool insideTabbing, bool insidePre, bool insideItem, bool insideTable, bool keepSpaces, const bool retainNewline=false)
#define LATEX_STYLE_EXTENSION
Definition latexgen.h:22
QCString convertToLaTeX(const QCString &s, bool insideTabbing, bool keepSpaces=FALSE)
QCString latexEscapeIndexChars(const QCString &s)
QCString latexEscapeLabelName(const QCString &s)
#define term(fmt,...)
Definition message.h:137
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
const char * ghostScriptCommand()
Definition portable.cpp:454
OutputCodeDefer< LatexCodeGenerator > LatexCodeGeneratorDefer
Definition outputlist.h:102
Portable versions of functions that are platform dependent.
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
#define ASSERT(x)
Definition qcstring.h:39
CodeSymbolType
Definition types.h:481
Various UTF8 related helper functions.
size_t updateColumnCount(const char *s, size_t col)
Definition util.cpp:7391
void checkBlocks(const QCString &s, const QCString fileName, const SelectionMarkerInfo &markerInfo)
Definition util.cpp:7033
QCString stripPath(const QCString &s)
Definition util.cpp:5461
QCString removeEmptyLines(const QCString &s)
Definition util.cpp:7097
QCString selectBlocks(const QCString &s, const SelectionBlockList &blockList, const SelectionMarkerInfo &markerInfo)
remove disabled blocks and all block markers from s and return the result as a string
Definition util.cpp:6920
QCString substituteKeywords(const QCString &file, const QCString &s, const KeywordSubstitutionList &keywords)
Definition util.cpp:3572
QCString relativePathToRoot(const QCString &name)
Definition util.cpp:4092
void clearSubDirs(const Dir &d)
Definition util.cpp:4180
QCString fileToString(const QCString &name, bool filter, bool isSourceCode)
Definition util.cpp:1442
QCString stripExtensionGeneral(const QCString &fName, const QCString &ext)
Definition util.cpp:5424
void createSubDirs(const Dir &d)
Definition util.cpp:4153
bool checkExtension(const QCString &fName, const QCString &ext)
Definition util.cpp:5407
bool copyFile(const QCString &src, const QCString &dest)
Copies the contents of file with name src to the newly created file with name dest.
Definition util.cpp:6370
A bunch of utility functions.
bool isId(int c)
Definition util.h:208